MDEx.Sigil (MDEx v0.9.3)

View Source

Sigils for parsing and formatting Markdown between different formats.

Examples

Defaults to parsing a Markdown string into a MDEx.Document struct:

iex> import MDEx.Sigil
iex> ~MD|# Hello from `~MD` sigil|
%MDEx.Document{
  nodes: [
    %MDEx.Heading{
      nodes: [
        %MDEx.Text{literal: "Hello from "},
        %MDEx.Code{num_backticks: 1, literal: "~MD"},
        %MDEx.Text{literal: " sigil"}
      ],
      level: 1,
      setext: false
    }
  ]
}

You can also convert Markdown to HTML, JSON or XML:

iex> import MDEx.Sigil
iex> ~MD|`~MD` also converts to HTML format|HTML
"<p><code>~MD</code> also converts to HTML format</p>"

iex> import MDEx.Sigil
iex> ~MD|and to XML as well|XML
"<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE document SYSTEM "CommonMark.dtd">\n<document xmlns="http://commonmark.org/xml/1.0">\n  <paragraph>\n    <text xml:space="preserve">and to XML as well</text>\n  </paragraph>\n</document>"

Assigns in the context can be referenced in the Markdown content using <%= ... %> syntax, which is evaluated at runtime. ~MD accepts an assigns map to pass variables to the document when rendering HTML or Markdown:

iex> import MDEx.Sigil
iex> assigns = %{lang: "Elixir"}
iex> ~MD|Running <%= @lang %>|HTML
"<p>Running Elixir</p>"

iex> import MDEx.Sigil
iex> assigns = %{lang: "Elixir"}
iex> ~MD|Running <%= @lang %>|MD
"Running Elixir"

Modifiers

Use EEx.SmartEngine to the document into HTML. It does support assigns but only the old <%= ... %> syntax, and it doesn't support components. It's useful if you want to generate static HTML from Markdown or don't need components or don't want to define an assigns variable (it's optional).

Note that you should import MDEx.Sigil to use the ~MD sigil.

HTML/EEx Format Order

In order to generate the final result, the Markdown string or MDEx.Document (initial input) is first converted into a static HTML without escaping the content, then the HTML is passed to the appropriate engine to generate the final output.

Assigns and Expressions

Only the HTML and MD modifiers support assigns, any other modifier will render the assign unmodified. That's particularly important when generating a MDEx.Document which does represent the Markdown AST because it must respect the Markdown content and also be able to convert back to a Markdown string.

Expressions inside code blocks are preserved

Expressions as <%= ... %> or { ... } inside code blocks are escaped and not evaluated, ie: they are preserved as is:

assigns = %{title: "Hello"}
~MD"""
`{@title}`
"""HTML
"<p><code>&lbrace;@title&rbrace;</code></p>"

Options

All modifiers use these options by default:

[
  streaming: false,
  sanitize: nil,
  syntax_highlight: [
    formatter: {:html_inline,
     [
       header: nil,
       highlight_lines: nil,
       include_highlights: false,
       italic: false,
       pre_class: nil,
       theme: "onedark"
     ]}
  ],
  extension: [
    cjk_friendly_emphasis: false,
    link_url_rewriter: nil,
    image_url_rewriter: nil,
    greentext: false,
    subscript: false,
    wikilinks_title_before_pipe: false,
    wikilinks_title_after_pipe: false,
    front_matter_delimiter: nil,
    header_ids: nil,
    tagfilter: false,
    strikethrough: true,
    table: true,
    autolink: false,
    tasklist: true,
    superscript: true,
    footnotes: true,
    description_lists: true,
    multiline_block_quotes: true,
    alerts: true,
    math_dollars: true,
    math_code: true,
    shortcodes: true,
    underline: true,
    spoiler: true
  ],
  parse: [
    default_info_string: nil,
    smart: false,
    relaxed_tasklist_matching: true,
    relaxed_autolinks: true
  ],
  render: [
    experimental_minimize_commonmark: false,
    ol_width: 1,
    tasklist_classes: false,
    figure_with_caption: false,
    prefer_fenced: false,
    gfm_quirks: false,
    ignore_empty_links: false,
    ignore_setext: false,
    escaped_char_spans: false,
    sourcepos: false,
    list_style: :dash,
    width: 0,
    hardbreaks: false,
    unsafe: true,
    escape: false,
    github_pre_lang: true,
    full_info_string: true
  ]
]

If you need a different set of options, you can call the regular functions in MDEx to pass the options you need.

Summary

Functions

The ~MD sigil converts a Markdown string or a %MDEx.Document{} struct to either one of these formats: MDEx.Document, Markdown (CommonMark), HTML, JSON or XML.

Functions

sigil_M(arg, modifiers)

(macro)
This macro is deprecated. Use the ~MD sigil instead.

sigil_MD(arg, modifiers)

(macro)

The ~MD sigil converts a Markdown string or a %MDEx.Document{} struct to either one of these formats: MDEx.Document, Markdown (CommonMark), HTML, JSON or XML.

Assigns

You can define a variable assigns in the context of the sigil to evaluate expressions:

iex> assigns = %{lang: ":elixir"}
iex> ~MD|`lang = <%= @lang %>`|HTML
"<p><code>lang = :elixir</code></p>"

iex> assigns = %{lang: ":elixir"}
iex> ~MD|`lang = <%= @lang %>`|MD
"`lang = :elixir`"

Note that only the HTML and MD modifiers support assigns.

Examples

Markdown to MDEx.Document

iex> ~MD[`lang = :elixir`]
%MDEx.Document{nodes: [%MDEx.Paragraph{nodes: [%MDEx.Code{num_backticks: 1, literal: "lang = :elixir"}]}]}

Markdown to HTML

iex> ~MD[`lang = :elixir`]HTML
"<p><code>lang = :elixir</code></p>\n"

Markdown to JSON

iex> ~MD[`lang = :elixir`]JSON
"{"nodes":[{"nodes":[{"literal":"lang = :elixir","num_backticks":1,"node_type":"MDEx.Code"}],"node_type":"MDEx.Paragraph"}],"node_type":"MDEx.Document"}"

Markdown to XML

iex> ~MD[`lang = :elixir`]XML
"<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document SYSTEM "CommonMark.dtd">
<document xmlns="http://commonmark.org/xml/1.0">
  <paragraph>
    <code xml:space="preserve">lang = :elixir</code>
  </paragraph>
</document>
"

MDEx.Document to Markdown

iex> ~MD|%MDEx.Document{nodes: [%MDEx.Paragraph{nodes: [%MDEx.Code{num_backticks: 1, literal: "lang = :elixir"}]}]}|MD
"`lang = :elixir`"

Markdown to Quill Delta

iex> ~MD|`lang = :elixir`|DELTA
[%{"insert" => "lang = :elixir", "attributes" => %{"code" => true}}, %{"insert" => "\n"}]

Elixir Expressions

iex> ~MD[## Section <%= 1 + 1 %>]HTML
"<h2>Section 2</h2>"

sigil_m(arg, modifiers)

(macro)
This macro is deprecated. Use the ~MD sigil instead.