defmodule Cmark do @moduledoc """ Converts Markdown to supported target formats. All functions below support the following options: - `:sourcepos` - Include a `data-sourcepos` attribute on all block elements. - `:hardbreaks` Render `softbreak` elements as hard line breaks. - `:nobreaks` Render `softbreak` elements as spaces. - `:normalize` Normalize tree by consolidating adjacent text nodes. - `:smart` Convert straight quotes to curly, --- to em dashes, -- to en dashes. - `:validate_utf8` Validate UTF-8 in the input before parsing, replacing illegal sequences with the replacement character U+FFFD. - `:unsafe` Allow raw HTML and unsafe links (`javascript:`, `vbscript:`, `file:`, and `data:`, except for `image/png`, `image/gif`, `image/jpeg`, or `image/webp` mime types). The default is to treat everything as unsafe, which replaces invalid nodes by a placeholder HTML comment and unsafe links by empty strings. """ @html_id 1 @xml_id 2 @man_id 3 @commonmark_id 4 @latex_id 5 # c_src/cmark.h -> CMARK_OPT_* @flags %{ # (1 <<< 1) sourcepos: 2, # (1 <<< 2) hardbreaks: 4, # (1 <<< 4) nobreaks: 16, # (1 <<< 8) normalize: 256, # (1 <<< 9) validate_utf8: 512, # (1 <<< 10) smart: 1024, # (1 <<< 17) unsafe: 131_072 } @typedoc "A list of atoms describing the options to use (see module docs)" @type options_list :: [:sourcepos | :hardbreaks | :nobreaks | :normalize | :validate_utf8 | :smart | :unsafe] @doc ~S""" Converts the Markdown document to HTML. See `Cmark` module docs for all options. ## Examples iex> Cmark.to_html("test") "

test

\n" """ @spec to_html(String.t(), options_list) :: String.t() def to_html(document, options_list \\ []) when is_binary(document) and is_list(options_list) do convert(document, options_list, @html_id) end @doc ~S""" Converts the Markdown document to XML. See `Cmark` module docs for all options. ## Examples iex> Cmark.to_xml("test") "\n\n\n \n test\n \n\n" """ @spec to_xml(String.t(), options_list) :: String.t() def to_xml(document, options_list \\ []) when is_binary(document) and is_list(options_list) do convert(document, options_list, @xml_id) end @doc ~S""" Converts the Markdown document to Manpage. See `Cmark` module docs for all options. ## Examples iex> Cmark.to_man("test") ".PP\ntest\n" """ @spec to_man(String.t(), options_list) :: String.t() def to_man(document, options_list \\ []) when is_binary(document) and is_list(options_list) do convert(document, options_list, @man_id) end @doc ~S""" Converts the Markdown document to Commonmark. See `Cmark` module docs for all options. ## Examples iex> Cmark.to_commonmark("test") "test\n" """ @spec to_commonmark(String.t(), options_list) :: String.t() def to_commonmark(document, options_list \\ []) when is_binary(document) and is_list(options_list) do convert(document, options_list, @commonmark_id) end @doc ~S""" Converts the Markdown document to LaTeX. See `Cmark` module docs for all options. ## Examples iex> Cmark.to_latex("test") "test\n" """ @spec to_latex(String.t(), options_list) :: String.t() def to_latex(document, options_list \\ []) when is_binary(document) and is_list(options_list) do convert(document, options_list, @latex_id) end defp convert(document, options_list, format_id) when is_integer(format_id) do bitflag = Enum.reduce(options_list, 0, fn flag, acc -> Map.fetch!(@flags, flag) + acc end) Cmark.Nif.render(document, bitflag, format_id) end end