Serialize

Turn a tree back into markup or text. Each renderer takes one configuration object: Node.serialize() and Node.encode() produce HTML under an Html config (a Formatter picks the escape policy and an Indent or Minify picks the whitespace), and Node.serialize_iter() streams the same HTML in bounded str chunks for a large page (every layout but Minify, which needs the whole tree); Node.to_markdown() takes a Markdown config; and Node.to_text() and Node.to_annotated_text() take a PlainText config. escape() and unescape() are the standalone string helpers; annotation_surface() and annotation_tags() post-process the annotated-text result. A JSMinify passed to Minify extends HTML minification into inline <script> content; the standalone minify_js() lives with the other minifiers in turbohtml.clean.

turbohtml.escape(s: str, quote: bool = ...) str

Replace special characters “&”, “<” and “>” with HTML-safe sequences.

Parameters:
  • s – text to escape.

  • quote – also translate the double (”) and single (’) quotation marks, so the result is safe inside an attribute value.

Returns:

the escaped text.

Raises:

TypeError – if s is not a str.

turbohtml.unescape(s: str, /) str

Convert all named and numeric character references in s to the corresponding Unicode characters, following the HTML5 rules.

Parameters:

s – text containing character references.

Returns:

the text with every reference resolved.

Raises:

TypeError – if s is not a str.

class turbohtml.Html(formatter=Formatter.WHATWG, layout=None, sort_attributes=False, meta_charset=False)

How Node.serialize() and Node.encode() render a subtree as HTML.

Parameters:
  • formatter (Formatter) – the escape policy for text and attribute values.

  • layout (Indent | Minify | None) – None emits the compact WHATWG form, an Indent pretty-prints, a Minify minifies.

  • sort_attributes (bool) – emit each element’s attributes in name order rather than source order.

  • meta_charset (bool) – normalize (or inject) the <meta charset> declaration to the output encoding.

class turbohtml.Formatter(*values)

The character-escaping policy serialize()/encode() apply, passed as formatter.

WHATWG escapes exactly what the HTML serialization algorithm requires (the default); MINIMAL escapes only the characters that would otherwise change the markup; NAMED_ENTITIES prefers named character references where one exists.

class turbohtml.Indent(indent: int | str = 2)

A serialize(layout=…)/encode(layout=…) mode that pretty-prints. It adds whitespace, so unlike the compact default it does not preserve meaning.

Parameters:

indent – the per-level unit: an int for that many spaces, or a string used verbatim.

unit: str

the whitespace inserted per nesting level

class turbohtml.Minify(*, collapse_whitespace: bool = ..., omit_optional_tags: bool = ..., unquote_attributes: bool = ..., strip_comments: bool = ..., minify_js: JSMinify | None = ..., minify_css: CSSMinify | None = ...)

A serialize(layout=…)/encode(layout=…) mode that shrinks the output. Each markup flag toggles one round-trip-safe transform: the minified output always reparses to the same tree.

Parameters:
  • collapse_whitespace – collapse runs of insignificant whitespace.

  • omit_optional_tags – drop start/end tags the parser can infer.

  • unquote_attributes – remove quotes around attribute values that allow it.

  • strip_comments – remove comments.

  • minify_js – a JSMinify to also minify inline <script> JavaScript, or None (the default) to leave scripts untouched. A script that fails to parse is emitted verbatim, so one bad script never breaks serialization.

  • minify_css – a CSSMinify to also minify <style> element bodies and style attribute values through the value-safe CSS minifier, or None (the default) to leave CSS untouched. Its baseline bounds how new the output syntax may be.

collapse_whitespace: bool

fold insignificant whitespace runs to a single space

minify_css: CSSMinify | None

the CSSMinify config for <style>/style=””, or None when off

minify_js: JSMinify | None

the JSMinify config for inline <script>, or None when off

omit_optional_tags: bool

drop the start/end tags the WHATWG rules make optional

strip_comments: bool

remove comment nodes

unquote_attributes: bool

drop redundant attribute quotes and empty values

class turbohtml.Markdown(headings=<factory>, lists=<factory>, inline=<factory>, code=<factory>, links=<factory>, images=<factory>, tables=<factory>, escaping=<factory>, wrapping=<factory>, document=<factory>, google=<factory>, strip=None, convert=None, converters=None)

How Node.to_markdown() renders a subtree as Markdown.

Build one and reuse it across threads; every field has a GitHub-Flavored-Markdown default, so Markdown() reproduces the no-argument rendering. The many knobs are grouped into themed sub-configs to keep any one object small – Markdown(links=Markdown.Links(style="reference")) rather than a flat link_style="reference".

Parameters:
  • headings (Headings) – how headings are written (ATX, closed ATX, or setext).

  • lists (Lists) – the unordered-list markers.

  • inline (Inline) – inline emphasis, strike, sub/sup, and quote wrappers.

  • code (Code) – fenced vs indented code blocks and their language.

  • links (Links) – link style and which links are kept.

  • images (Images) – how images render and their fallback alt text.

  • tables (Tables) – table rendering and header detection.

  • escaping (Escaping) – which Markdown-significant characters are escaped.

  • wrapping (Wrapping) – word-wrapping of prose and constructs.

  • document (Document) – line breaks, block spacing, trimming, and transliteration.

  • google (GoogleDoc) – reading inline-CSS styling the way a Google Docs export encodes it.

  • strip (Iterable[str] | None) – tags rendered as their text only, dropping the markup; mutually exclusive with convert.

  • convert (Iterable[str] | None) – the only tags to render as Markdown, every other tag dropped to text; mutually exclusive with strip.

  • converters (Mapping[str, Callable[[Element, str], str]] | None) – per-tag overrides, each a callable receiving the element and its rendered child Markdown.

Raises:

ValueError – if both strip and convert are given, since they are mutually exclusive.

class Headings(style='atx')

How headings are written.

Parameters:

style (Literal['atx', 'atx_closed', 'setext']) – atx (# h), atx_closed (# h #), or setext (underlined).

class Lists(bullets='-')

How unordered lists are marked.

Parameters:

bullets (str) – unordered-list markers, cycled by nesting depth (e.g. -*+).

class Inline(strong='**', emphasis='*', strikethrough='keep', ignore_emphasis=False, sub='', sup='', hide_strikethrough=False, quote_open='"', quote_close='"')

Inline text formatting: emphasis, sub/sup, and quote wrappers.

Parameters:
  • strong (str) – the bold wrapper.

  • emphasis (str) – the italic wrapper.

  • strikethrough (Literal['keep', 'hide']) – keep wraps struck text, hide drops it.

  • ignore_emphasis (bool) – render bold/italic/strike content as plain text, no markup.

  • sub (str) – the <sub> wrapper (empty drops the markup).

  • sup (str) – the <sup> wrapper (empty drops the markup).

  • hide_strikethrough (bool) – in google mode, drop text a CSS line-through struck.

  • quote_open (str) – the opening <q> wrapper.

  • quote_close (str) – the closing <q> wrapper.

class Code(block_style='fenced', language='', mark=False)

How code blocks are rendered.

Parameters:
  • block_style (Literal['fenced', 'indented']) – fenced (triple-backtick) or indented (four-space).

  • language (str) – default fence language when the element declares none.

  • mark (bool) – wrap inline code in [code]/[/code] markers.

Link style and which links are kept.

Parameters:
  • style (Literal['inline', 'reference']) – inline ([t](url)) or reference (collected at the end).

  • autolink (bool) – emit <url> when the text equals an absolute href.

  • title (bool) – use the href as the title when none is given.

  • ignore (bool) – render link text only, no markup.

  • skip_internal (bool) – drop href="#..." fragment links.

  • base_url (str) – prefix resolved onto a relative link or image href.

class Images(mode='markdown', default_alt='')

How images are rendered.

Parameters:
  • mode (Literal['markdown', 'alt', 'ignore', 'html']) – markdown (![alt](src)), alt (alt text only), ignore, or html (raw <img>).

  • default_alt (str) – alt text used for an image that declares none.

class Tables(mode='markdown', header='first', pad=False)

How tables are rendered.

Parameters:
  • mode (Literal['markdown', 'strip', 'html']) – markdown (pipe table), strip (cell text only), or html (raw <table>).

  • header (Literal['first', 'detect', 'none']) – which row is the header: first, detect, or none.

  • pad (bool) – align columns to a common width.

class Escaping(mode='minimal', asterisks=True, underscores=True)

Which Markdown-significant characters are escaped.

Parameters:
  • mode (Literal['minimal', 'all']) – minimal escapes only what a parser needs, all escapes every Markdown character.

  • asterisks (bool) – escape literal * so it is not read as emphasis.

  • underscores (bool) – escape literal _ so it is not read as emphasis.

class Wrapping(width=0, list_items=False, links=True)

Word-wrapping of prose and constructs.

Parameters:
  • width (int) – word-wrap column for prose, or 0 to leave lines unwrapped.

  • list_items (bool) – extend word wrapping into list-item text.

  • links (bool) – allow a link or image construct to break across a wrap.

class Document(line_break='spaces', block_spacing='double', trim='strip', transliterate=False)

Document-level layout: line breaks, block spacing, trimming, and transliteration.

Parameters:
  • line_break (Literal['spaces', 'backslash']) – render a hard break as trailing spaces or a backslash.

  • block_spacing (Literal['double', 'single']) – a double blank line between blocks, or a single newline.

  • trim (Literal['strip', 'lstrip', 'rstrip', 'none']) – trim document edges: strip, lstrip, rstrip, or none.

  • transliterate (bool) – fold common non-ASCII typography in prose to ASCII.

class GoogleDoc(enabled=False, list_indent=36)

Reading inline-CSS styling the way a Google Docs export encodes it.

Parameters:
  • enabled (bool) – read inline-CSS styling the way a Google Docs HTML export encodes it.

  • list_indent (int) – px of margin-left per list-nesting level (at least 1).

classmethod google_doc()

Read a Google Docs HTML export: inline-CSS styling drives emphasis, and struck text is dropped.

Return type:

Markdown

Returns:

a config tuned for Google Docs export markup.

class turbohtml.PlainText(width=0, links='none', images=False, layout='extended', default_image_alt='', table_cell_separator='  ', bullet='* ')

How Node.to_text() and Node.to_annotated_text() render a subtree as layout-aware plain text.

Parameters:
  • width (int) – wrap column for prose, or 0 to leave lines unwrapped.

  • links (Literal['none', 'inline', 'footnote']) – how to render <a> targets: none drops them, inline shows them after the text, footnote collects them at the end.

  • images (bool) – render image alt text instead of skipping images.

  • layout (Literal['extended', 'strict']) – extended adds blank lines and indentation; strict keeps the output compact.

  • default_image_alt (str) – alt text used for an image that declares none.

  • table_cell_separator (str) – string placed between table cells on a row.

  • bullet (str) – marker prefixed to each list item.

turbohtml.annotation_surface(text: str, spans: Iterable[tuple[int, int, str]], /) dict[str, list[str]]

Group the annotated substrings by label, the inscriptis surface-form extractor.

Parameters:
  • text – the rendered text from Node.to_annotated_text().

  • spans – the (start, end, label) spans from the same call.

Returns:

a dict mapping each label to the list of text[start:end] slices its spans cover, in document order.

turbohtml.annotation_tags(text: str, spans: Iterable[tuple[int, int, str]], /) str

Weave the annotated spans back into the text as inline markup, the inscriptis inline-tagged (XML) exporter. The innermost span closes first, so properly nested spans stay well-formed.

Parameters:
  • text – the rendered text from Node.to_annotated_text().

  • spans – the (start, end, label) spans from the same call.

Returns:

the text with each span wrapped in <label>…</label> tags.

turbohtml.migration.markupsafe

A safe-string for composing HTML, a drop-in for markupsafe’s public surface. Import it in place of markupsafe. Markup overrides every str method that returns text so the result stays a Markup; the methods below are the turbohtml-specific ones, the rest mirror str.

turbohtml.migration.markupsafe.escape(s: object, /) str

Replace &, <, >, ‘, and “ with HTML-safe sequences and return a Markup.

An object with an __html__ method is trusted as already safe; any other object is converted to a string first. Matches markupsafe.escape, including the numeric " and ' quote references.

Parameters:

s – value to escape; an __html__ method marks it already safe.

Returns:

a Markup holding the escaped text.

turbohtml.migration.markupsafe.escape_silent(s: object, /) str

Like escape, but None becomes the empty Markup rather than ‘None’.

Parameters:

s – value to escape, or None for an empty Markup.

Returns:

a Markup holding the escaped text.

turbohtml.migration.markupsafe.soft_str(s: object, /) str

Convert s to str only if it is not already one, preserving a Markup so already-safe text is not escaped a second time.

Parameters:

s – value to coerce to text.

Returns:

s unchanged when it is already a str, otherwise str(s).

class turbohtml.migration.markupsafe.Markup(base: object = '', encoding: str | None = None, errors: str = 'strict')

Text that is already safe to embed in HTML and is not escaped again.

Wrap a value to declare it trusted. Operations that combine it with other text escape that text first, so the result stays safe. Constructing Markup directly trusts its argument without escaping, so wrap only content you control or have already escaped; call escape() to make untrusted text safe.

Parameters:
  • base – the value to trust as safe HTML; its __html__ method is used when present, and bytes is decoded with encoding.

  • encoding – the codec to decode base with when it is bytes; None leaves a str as is.

  • errors – the decoding error policy passed to bytes.decode() when encoding is given.

join(iterable, /)

Join the items, escaping each one so the result stays safe.

Parameters:

iterable (Iterable[str]) – the items to join.

Return type:

Markup

Returns:

the joined text as a Markup.

unescape()

Resolve character references back to text.

Return type:

str

Returns:

the resolved text as a plain (no longer safe) str.

striptags()

Parse the markup, drop tags and comments, collapse whitespace, and return the plain text.

This parses with turbohtml’s tokenizer rather than scanning for <, so references resolve and a comment that contains a < cannot end tag removal early.

Return type:

str

Returns:

the plain text, no longer safe markup.

classmethod escape(s, /)

Escape a value to this class, the entry point the composing operations use to make operands safe.

Parameters:

s (object) – the value to escape; an __html__ method marks it already safe.

Return type:

Markup

Returns:

a Markup holding the escaped text.

format(*args, **kwargs)

Format, escaping each field unless it renders itself through __html_format__ or __html__.

Parameters:
  • args (object) – positional values for the format fields.

  • kwargs (object) – keyword values for the format fields.

Return type:

Markup

Returns:

the formatted text as a Markup.

class turbohtml.migration.markupsafe.EscapeFormatter(escape)

A string.Formatter that escapes each field while rendering it.

Markup.format() builds on str formatting but must escape interpolated values. A field that already renders itself safely through __html_format__ or __html__ stays trusted instead of escaping again. The class is public and subclassable so a template sandbox can mix it with its own formatter, the way Jinja2 does, so its calls go through super() to cooperate with that multiple inheritance.

Parameters:

escape (Callable[[object], str]) – the function applied to each interpolated field value to make it safe.

format_field(value, format_spec)

Render one field: trust its safe-rendering protocol if present, else escape the formatted value.

Parameters:
  • value (object) – the field value to render.

  • format_spec (str) – the field’s format specification.

Return type:

str

Returns:

the rendered, escaped field text.