MDEx.Sigil (MDEx v0.11.0)
View SourceSigils for parsing and formatting Markdown between different formats.
Examples
With no modifier, ~MD defaults to converting 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"The HEEX modifier can render component and Elixir expressions:
iex> import MDEx.Sigil
iex> assigns = %{lang: "Elixir"}
iex> rendered = ~MD|Learn <Phoenix.Component.link href="https://elixir-lang.org">{@lang}</Phoenix.Component.link>|HEEX
%Phoenix.LiveView.Rendered{...}
iex> rendered |> Phoenix.HTML.Safe.to_iodata() |> IO.iodata_to_binary()
"<p>Learn <a href="https://elixir-lang.org">Elixir</a></p>"Modifiers
HTML- converts Markdown orMDEx.Documentto HTML
Use EEx.SmartEngine to convert 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).
Prefer using the HEEX modifier if you need full Phoenix LiveView support with components and expressions.
HEEX- converts Markdown to Phoenix HEEx for LiveView templates
Enables LiveView components, phx-* bindings, and Elixir expressions inside Markdown.
Requires Phoenix LiveView and an assigns variable in scope.
See Phoenix LiveView HEEx example for a demo.
JSON- converts Markdown orMDEx.Documentto JSONXML- converts Markdown orMDEx.Documentto XMLMD- convertsMDEx.Documentto Markdown and can interpolate assigns in Markdown stringsDELTA- converts Markdown orMDEx.Documentto Quill Delta formatNo modifier (default) - parses a Markdown string into a
MDEx.Documentstruct
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
The HTML and HEEX modifiers evaluate assigns and expressions at runtime.
Other modifiers preserve them as literal text in the output.
Expressions inside code blocks are preserved
Expressions like <%= ... %> or { ... } inside code blocks are escaped, not evaluated:
assigns = %{title: "Hello"}
~MD"`{@title}`"HTML
#=> "<p><code>{@title}</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,
highlight: false,
subtext: false,
greentext: false,
subscript: false,
wikilinks_title_before_pipe: false,
wikilinks_title_after_pipe: false,
front_matter_delimiter: nil,
inline_footnotes: false,
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,
phoenix_heex: true
],
parse: [
escaped_char_spans: false,
leave_footnote_definitions: false,
tasklist_in_table: false,
ignore_setext: false,
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,
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
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>"