Renders a Kotoba.Document as HTML, as plain text and as Markdown.
to_html/2 returns safe iodata from Phoenix.HTML. Every string in the
document is escaped, and Kotoba never passes raw HTML through. Before it
renders a node, the renderer calls Kotoba.Sanitizer.check/3. A node
that fails the check renders as an unknown node:
<span class="kotoba-unknown" data-type="..."> with no content.
HTML of the built-in nodes
| Node | HTML |
|---|---|
| paragraph | p |
| heading | h1 to h4 (h5 and h6 become h4) |
| quote | blockquote |
| list | ul, ol (with start when it is not 1), ul.kotoba-check |
| list item | li; in a check list li.kotoba-checked or li.kotoba-unchecked |
| code | pre with code.language-<language>, the text escaped |
| text | the text in strong, em, s, u, code, sub, sup, mark (mark.kotoba-highlight-<name> for a highlight color), and span.kotoba-lowercase, span.kotoba-uppercase, span.kotoba-capitalize; a text color is a span.kotoba-color-<name> around it |
| line break | br |
| horizontal rule | hr |
| table | table.kotoba-table in a div.kotoba-table-scroll, with a thead for a first row of header cells and a tbody |
| table row | tr |
| table cell | td, or th with scope="col" (header row) or scope="row" (header column); colspan and rowspan when they are more than 1 |
| link, autolink | a with rel="noopener nofollow", or the text when the URL is not safe |
| attachment | figure.kotoba-attachment with an img, an object (PDF), a video, or a download link, and a figcaption |
| gallery | div.kotoba-gallery with the figure of each attachment |
| mention | span.kotoba-mention with data-kind and data-id |
| tab | a tab character, escaped |
| unknown | span.kotoba-unknown with data-type |
Options
:policy-:defaultor:untrusted. SeeKotoba.Sanitizer. The default is:default.:schemes- the allowed link schemes. SeeKotoba.Sanitizer.link_url/2.:blank_lines-:keep(the default) or:collapse: whether the blank lines that a person typed (empty paragraphs between blocks) are in the output. SeeKotoba.Nodes.Paragraph.
The options of the render callbacks
The renderer gives the options above to each render callback of a node, with these changes:
:policy- the policy map fromKotoba.Sanitizer.policy/1.:parent- the parent node, ornilfor the root node.:index- the position of the node among the children of its parent, ornilfor the root node.
A node gives the same opts to html_children/2, text_children/2 and
markdown_children/3.
Summary
Types
An attribute of an HTML tag. A nil or false value is left out.
Functions
Escapes the Markdown characters in a plain string, for a
Kotoba.Node.render_markdown/2 callback.
Returns a URL for the destination of a Markdown link, for a
Kotoba.Node.render_markdown/2 callback. \, &, < and > get a
backslash, so that a CommonMark renderer decodes no entity, and a URL
with spaces or parentheses is in angle brackets, as it is. Check the URL
with Kotoba.Sanitizer.link_url/2 first.
Renders the children of an element node as safe HTML.
Renders the children of an element node as Markdown.
Renders each child of an element node as Markdown. Returns a list of
{child, markdown} tuples, in order.
Returns the policy map of the render options. See Kotoba.Sanitizer.policy/1.
Returns an HTML tag as safe HTML.
Renders the children of an element node as plain text.
Renders each child of an element node as plain text. Returns a list of
{child, text} tuples, in order.
Renders a document as safe HTML.
Renders a document as Markdown, as well as Markdown can show it.
Renders a document as plain text. Blocks are separated by "\n".
Returns the safe HTML of an unknown node of type.
Types
Functions
Escapes the Markdown characters in a plain string, for a
Kotoba.Node.render_markdown/2 callback.
It escapes the inline syntax everywhere (`, *, _, [, ],
~, <, & and \), and the block syntax at the start of a line: #
headings, > quotes, - and + bullets, 1. and 1) list markers,
and --- or === lines. So a node that renders its text at the start
of a block cannot make a heading or a list.
Examples
iex> Kotoba.Renderer.escape_markdown("*not* [a link]")
"\\*not\\* \\[a link\\]"
iex> Kotoba.Renderer.escape_markdown("# not a heading")
"\\# not a heading"
iex> Kotoba.Renderer.escape_markdown("1. not a list")
"1\\. not a list"
Returns a URL for the destination of a Markdown link, for a
Kotoba.Node.render_markdown/2 callback. \, &, < and > get a
backslash, so that a CommonMark renderer decodes no entity, and a URL
with spaces or parentheses is in angle brackets, as it is. Check the URL
with Kotoba.Sanitizer.link_url/2 first.
Examples
iex> Kotoba.Renderer.escape_markdown_url("/docs/a page (draft)")
"</docs/a page (draft)>"
iex> Kotoba.Renderer.escape_markdown_url("/search?q=a&b")
"/search?q=a\\&b"
@spec html_children(Kotoba.Node.t(), keyword()) :: Phoenix.HTML.safe()
Renders the children of an element node as safe HTML.
@spec markdown_children(Kotoba.Node.t(), keyword(), String.t()) :: String.t()
Renders the children of an element node as Markdown.
Consecutive inline nodes are joined. The blocks are separated by
separator (the default is a blank line). Empty blocks are left out.
@spec markdown_each(Kotoba.Node.t(), keyword()) :: [{Kotoba.Node.t(), String.t()}]
Renders each child of an element node as Markdown. Returns a list of
{child, markdown} tuples, in order.
@spec policy(keyword()) :: Kotoba.Sanitizer.policy()
Returns the policy map of the render options. See Kotoba.Sanitizer.policy/1.
@spec tag(String.t(), [attribute()], Phoenix.HTML.safe() | String.t() | :void) :: Phoenix.HTML.safe()
Returns an HTML tag as safe HTML.
The attribute values and a string content are escaped. content can
also be safe HTML. A nil or false attribute is left out, and a true
attribute has no value. When content is :void, the tag has no end tag.
Examples
iex> Kotoba.Renderer.tag("a", [href: "/x?a=1&b=2", title: nil], "A & B") |> Phoenix.HTML.safe_to_string()
~s(<a href="/x?a=1&b=2">A & B</a>)
iex> Kotoba.Renderer.tag("br", [], :void) |> Phoenix.HTML.safe_to_string()
"<br>"
@spec text_children(Kotoba.Node.t(), keyword()) :: String.t()
Renders the children of an element node as plain text.
Consecutive inline nodes are joined. Each block child gives one line, and
the lines are separated by "\n". A decorator in the root node is a
block; it gives no line when it has no text.
@spec text_each(Kotoba.Node.t(), keyword()) :: [{Kotoba.Node.t(), String.t()}]
Renders each child of an element node as plain text. Returns a list of
{child, text} tuples, in order.
@spec to_html(Kotoba.Document.t(), keyword()) :: Phoenix.HTML.safe()
Renders a document as safe HTML.
Examples
iex> {:ok, doc} =
...> Kotoba.Document.parse(%{
...> "kotoba" => 1,
...> "lexical" => "0.51",
...> "root" => %{
...> "type" => "root",
...> "children" => [
...> %{"type" => "paragraph", "children" => [%{"type" => "text", "text" => "<b>hi</b>"}]}
...> ]
...> }
...> })
iex> doc |> Kotoba.Renderer.to_html() |> Phoenix.HTML.safe_to_string()
"<p><b>hi</b></p>"
@spec to_markdown(Kotoba.Document.t(), keyword()) :: String.t()
Renders a document as Markdown, as well as Markdown can show it.
Headings, lists, code blocks, bold, italic, strikethrough, inline code, links and images become Markdown. The other nodes and formats give their plain text. Blocks are separated by a blank line.
@spec to_text(Kotoba.Document.t(), keyword()) :: String.t()
Renders a document as plain text. Blocks are separated by "\n".
@spec unknown_html(String.t()) :: Phoenix.HTML.safe()
Returns the safe HTML of an unknown node of type.