Tiptapex.Renderer.Markup (Tiptapex v0.1.2)

Copy Markdown View Source

A small allow-listed HTML subset, for the one place the document's own JSON→HTML pipeline does not reach: header and footer slots, which are typed as text rather than edited as a Tiptap document.

iex> Tiptapex.Renderer.Markup.to_html("<b>Acme</b> S.A.") |> IO.iodata_to_binary()
"<b>Acme</b> S.A."

It follows the same rule as the rest of Tiptapex.Renderer: nothing from the input is ever emitted verbatim. The string is tokenised, each tag is matched against a closed allow-list, and the output is rebuilt with Tiptapex.Renderer.HTML. Anything unrecognised — an unknown tag, a malformed one, a stray attribute — becomes escaped text, so the worst a mis-parse can do is show the user their own markup:

iex> Tiptapex.Renderer.Markup.to_html("<script>alert(1)</script>") |> IO.iodata_to_binary()
"&lt;script&gt;alert(1)&lt;/script&gt;"

What is allowed

  • inline — b, strong, i, em, u, s, small, sub, sup, span, a, br, img
  • block — p, div, h1h6

Attributes: style (each declaration's property must be in the allow-list and its value must pass Tiptapex.Renderer.URL.safe_css_value/1), href on a, src/alt/width/height on img, and title. Everything else is dropped.

Unclosed tags are closed at the end; a closing tag that doesn't match the innermost open one is dropped.

Summary

Functions

The tag names this module renders.

True when text contains at least one tag this module would render.

Renders the allow-listed subset of text as escaped, rebuilt iodata.

Functions

allowed_tags()

@spec allowed_tags() :: [binary()]

The tag names this module renders.

markup?(text)

@spec markup?(term()) :: boolean()

True when text contains at least one tag this module would render.

Callers use it to decide whether a plain-text channel is enough — wkhtmltopdf's --header-left takes text, not markup, so a slot with markup has to go through --header-html instead.

iex> Tiptapex.Renderer.Markup.markup?("Page {page}")
false
iex> Tiptapex.Renderer.Markup.markup?("Page <b>{page}</b>")
true

to_html(text)

@spec to_html(term()) :: iodata()

Renders the allow-listed subset of text as escaped, rebuilt iodata.

Non-binaries render as "".