MDExNative.Comrak (MDExNative v0.2.2)

Copy Markdown View Source

Markdown parsing and rendering powered by the Rust comrak crate.

Elixir bindings for Comrak's parser and renderers.

Options follow Rust comrak::Options and use keyword lists. MDExNative also accepts :sanitize and :syntax_highlight.

Examples

iex> MDExNative.Comrak.markdown_to_html("# Hello")
"<h1>Hello</h1>\n"

iex> MDExNative.Comrak.markdown_to_html("- [x] done", extension: [tasklist: true])
"<ul>\n<li><input type=\"checkbox\" checked=\"\" disabled=\"\" /> done</li>\n</ul>\n"

iex> MDExNative.Comrak.anchorize("Hello World")
"hello-world"

Summary

Types

Parsed MDExNative.Comrak AST node.

Parsed fenced code block info string.

Comrak Extension options.

Rendered HTML.

Markdown source text.

Comrak Options, plus :syntax_highlight and :sanitize.

Comrak Parse options.

Comrak Render options.

Rendered CommonMark XML.

Functions

Converts text to a heading anchor.

Returns whether a URL is considered dangerous or not.

Converts a generic MDExNative.Comrak document to CommonMark.

Converts a generic MDExNative.Comrak document to HTML.

Converts a generic MDExNative.Comrak document to XML.

Converts Markdown to HTML.

Converts Markdown to XML.

Parses a fenced code block info string into generic parts.

Parses Markdown into a generic MDExNative.Comrak AST.

Types

ast_node()

@type ast_node() :: struct()

Parsed MDExNative.Comrak AST node.

code_fence_info()

@type code_fence_info() :: %{
  language: String.t(),
  metadata: String.t(),
  attributes: %{required(String.t()) => String.t() | true}
}

Parsed fenced code block info string.

extension_options()

@type extension_options() :: keyword()

Comrak Extension options.

html()

@type html() :: String.t()

Rendered HTML.

markdown()

@type markdown() :: String.t()

Markdown source text.

options()

@type options() :: keyword()

Comrak Options, plus :syntax_highlight and :sanitize.

parse_options()

@type parse_options() :: keyword()

Comrak Parse options.

render_options()

@type render_options() :: keyword()

Comrak Render options.

xml()

@type xml() :: String.t()

Rendered CommonMark XML.

Functions

anchorize(text)

@spec anchorize(String.t()) :: String.t()

Converts text to a heading anchor.

Examples

iex> MDExNative.Comrak.anchorize("Hello World")
"hello-world"

dangerous_url?(url)

@spec dangerous_url?(String.t()) :: boolean()

Returns whether a URL is considered dangerous or not.

Calls comrak::html::dangerous_url/1.

Examples

iex> MDExNative.Comrak.dangerous_url?("javascript:alert(1)")
true

iex> MDExNative.Comrak.dangerous_url?("https://elixir-lang.org")
false

iex> MDExNative.Comrak.dangerous_url?("data:image/png;base64,AAAA")
false

document_to_commonmark(document, options \\ [])

@spec document_to_commonmark(MDExNative.Comrak.Document.t(), options()) :: markdown()

Converts a generic MDExNative.Comrak document to CommonMark.

document_to_html(document, options \\ [])

@spec document_to_html(MDExNative.Comrak.Document.t(), options()) :: html()

Converts a generic MDExNative.Comrak document to HTML.

document_to_xml(document, options \\ [])

@spec document_to_xml(MDExNative.Comrak.Document.t(), options()) :: xml()

Converts a generic MDExNative.Comrak document to XML.

markdown_to_html(markdown, options \\ [])

@spec markdown_to_html(markdown(), options()) :: html()

Converts Markdown to HTML.

Options

Pass Comrak options as keyword lists matching comrak::Options or the extra :syntax_highlight and :sanitize options: MDExNative adds two top-level options:

  • :extension - mapper to Comrak's Extension options.

  • :parse - mapper to Comrak's Parse options.

  • :render - mapper to Comrak's Render options.

  • :syntax_highlight - highlights fenced code blocks. Disabled by default.

    Defaults to syntax_highlight: nil.

    To highlight code, compile MDExNative with a highlighter and choose the engine:

    Lumis

      config :mdex_native, syntax_highlighter: :lumis
    
      [engine: :lumis, opts: [formatter: {:html_inline, theme: "catppuccin_macchiato"}]]

    Syntect

      config :mdex_native, syntax_highlighter: :syntect
    
      [engine: :syntect, opts: [theme: "Catppuccin Macchiato"]]

    See the Syntax highlighting guide for complete examples.

  • :sanitize - cleans rendered HTML. Defaults to nil.

    See the Sanitization guide for more info.

Examples

iex> MDExNative.Comrak.markdown_to_html("**bold**")
"<p><strong>bold</strong></p>\n"

iex> MDExNative.Comrak.markdown_to_html("- [x] done", extension: [tasklist: true])
"<ul>\n<li><input type=\"checkbox\" checked=\"\" disabled=\"\" /> done</li>\n</ul>\n"

iex> MDExNative.Comrak.markdown_to_html("<h1>Title</h1><p>Content</p>", render: [unsafe: true], sanitize: [rm_tags: ["h1"]])
"Title<p>Content</p>\n"

# default disabled syntax highlighter
iex> markdown = "```rust\nfn main() {}\n```"
iex> MDExNative.Comrak.markdown_to_html(markdown)
"<pre><code class=\"language-rust\">fn main() &lbrace;&rbrace;\n</code></pre>\n"

markdown_to_xml(markdown, options \\ [])

@spec markdown_to_xml(markdown(), options()) :: xml()

Converts Markdown to XML.

Examples

iex> MDExNative.Comrak.markdown_to_xml("# Hello")
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE document SYSTEM \"CommonMark.dtd\">\n<document xmlns=\"http://commonmark.org/xml/1.0\">\n  <heading level=\"1\">\n    <text xml:space=\"preserve\">Hello</text>\n  </heading>\n</document>\n"

iex> MDExNative.Comrak.markdown_to_xml("# Hello", render: [sourcepos: true])
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE document SYSTEM \"CommonMark.dtd\">\n<document sourcepos=\"1:1-1:7\" xmlns=\"http://commonmark.org/xml/1.0\">\n  <heading sourcepos=\"1:1-1:7\" level=\"1\">\n    <text sourcepos=\"1:3-1:7\" xml:space=\"preserve\">Hello</text>\n  </heading>\n</document>\n"

parse_code_fence_info(info)

@spec parse_code_fence_info(String.t() | nil) :: code_fence_info()

Parses a fenced code block info string into generic parts.

The first word is returned as the language, the remaining text is preserved as metadata, and shell-like tokens in the metadata are exposed as attributes.

Examples

iex> MDExNative.Comrak.parse_code_fence_info(~s(elixir pre_class="demo" highlight_lines=2 include_highlights))
%{
  language: "elixir",
  metadata: ~s(pre_class="demo" highlight_lines=2 include_highlights),
  attributes: %{
    "pre_class" => "demo",
    "highlight_lines" => "2",
    "include_highlights" => true
  }
}

iex> MDExNative.Comrak.parse_code_fence_info("")
%{language: "", metadata: "", attributes: %{}}

parse_document(markdown, options \\ [])

@spec parse_document(markdown(), options()) :: MDExNative.Comrak.Document.t()

Parses Markdown into a generic MDExNative.Comrak AST.

Examples

iex> MDExNative.Comrak.parse_document("# Hello")
%MDExNative.Comrak.Document{
  nodes: [
    %MDExNative.Comrak.Heading{
      nodes: [
        %MDExNative.Comrak.Text{literal: "Hello", sourcepos: %MDExNative.Comrak.Sourcepos{start: {1, 3}, end: {1, 7}}}
      ],
      level: 1,
      setext: false,
      sourcepos: %MDExNative.Comrak.Sourcepos{start: {1, 1}, end: {1, 7}}
    }
  ],
  sourcepos: %MDExNative.Comrak.Sourcepos{start: {1, 1}, end: {1, 7}}
}