# html

URL: /patitas/api/renderers/html/
Section: renderers
Description: HTML renderer using StringBuilder pattern.

Renders typed AST to HTML with O(n) performance using StringBuilder.

Thread Safety:
All per-render state is encapsulated in RenderContext, created fresh for each
render() call. Multiple threads can safely share a single HtmlRenderer instance
and call render() concurrently without synchronization.

Single-Pass Heading Decoration:
Heading IDs are generated during the AST walk, eliminating the need for
regex-based post-processing. TOC data is collected during rendering.

---

> For a complete page index, fetch /patitas/llms.txt.

Open LLM text
(/patitas/api/renderers/html/index.txt)

Share with AI

Ask Claude
(https://claude.ai/new?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpatitas%2Fapi%2Frenderers%2Fhtml%2Findex.txt)

Ask ChatGPT
(https://chatgpt.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpatitas%2Fapi%2Frenderers%2Fhtml%2Findex.txt)

Ask Gemini
(https://gemini.google.com/app?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpatitas%2Fapi%2Frenderers%2Fhtml%2Findex.txt)

Ask Copilot
(https://copilot.microsoft.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpatitas%2Fapi%2Frenderers%2Fhtml%2Findex.txt)

Module

#
`renderers.html`

HTML renderer using StringBuilder pattern.

Renders typed AST to HTML with O(n) performance using StringBuilder.

Thread Safety:

All per-render state is encapsulated in RenderContext, created fresh for each
render() call. Multiple threads can safely share a single HtmlRenderer instance
and call render() concurrently without synchronization.

Single-Pass Heading Decoration:
Heading IDs are generated during the AST walk, eliminating the need for
regex-based post-processing. TOC data is collected during rendering.

3Classes2Functions

## Classes

`HeadingInfo`

3

▼

Heading metadata collected during rendering.

Used to build TOC without post-render regex scanning.…

Heading metadata collected during rendering.

Used to build TOC without post-render regex scanning.
Collected by HtmlRenderer during the AST walk.

#### Attributes

Name
Type
Description

`level`

`int`

—

`text`

`str`

—

`slug`

`str`

—

`RenderContext`

4

▼

Per-render mutable state.

Encapsulates all state that changes during a single render() call.
Creat…

Per-render mutable state.

Encapsulates all state that changes during a single render() call.
Created fresh for each render, ensuring thread safety when sharing
HtmlRenderer instances across threads.

Thread Safety:

```
Each render() call creates its own RenderContext instance.
No shared mutable state between concurrent renders.
```

#### Attributes

Name
Type
Description

`headings`

`list[HeadingInfo (/patitas/api/renderers/html/#HeadingInfo)]`

—

`seen_slugs`

`set[str]`

—

`footnote_defs`

`dict[str, FootnoteDef (/patitas/api/nodes/#FootnoteDef)]`

—

`footnote_refs`

`list[str]`

—

`HtmlRenderer`

20

▼

Render AST to HTML using StringBuilder pattern.

O(n) rendering using StringBuilder for string accu…

Render AST to HTML using StringBuilder pattern.

O(n) rendering using StringBuilder for string accumulation.
All per-render state is encapsulated in RenderContext.

Usage:

```
>>> from patitas.parser import Parser
>>> parser = Parser()
>>> doc = parser.parse("# Hello **World**")
>>> renderer = HtmlRenderer()
>>> html = renderer.render(doc)
'<h1>Hello <strong>World</strong></h1>\n'
```

Thread Safety:

```
Multiple threads can safely share a single HtmlRenderer instance.
Each render() call creates an independent RenderContext, ensuring
no shared mutable state between concurrent renders.
```

#### Methods

`render`

1

`str`

▼

Render document AST to HTML string.

**Thread Safety:**
Creates independent Ren…

`def render(self, node: Document) -> str`

Render document AST to HTML string.

Thread Safety:
Creates independent RenderContext per call.
Safe for concurrent execution from multiple threads.

##### Parameters

Name
Type
Description

`node`
`—`

Document AST root

##### Returns

`str`

HTML string

`get_headings`

0

`list[HeadingInfo (/patitas/api/renderers/html/#HeadingInfo)]`

▼

Get heading info collected during last render.

**Thread Safety:**
Uses Context…

`def get_headings(self) -> list[HeadingInfo]`

Get heading info collected during last render.

Thread Safety:
Uses ContextVar to store per-thread/task render context.
Safe to call from concurrent threads sharing a single renderer.

##### Returns

`list[HeadingInfo (/patitas/api/renderers/html/#HeadingInfo)]`

List of HeadingInfo from the last render() call.
Empty if render() hasn't been called.

Internal Methods
18

▼

`__init__`

6

▼

Initialize renderer.

`def __init__(self, source: str = '', *, highlight: bool = False, directive_registry: DirectiveRegistry | None = None, role_registry: RoleRegistry | None = None, text_transformer: Callable[[str], str] | None = None, slugify: Callable[[str], str] | None = None) -> None`

##### Parameters

Name
Type
Description

`source`
`—`

Original source buffer for zero-copy extraction

Default:`''`

`highlight`
`—`

Enable syntax highlighting for code blocks

Default:`False`

`directive_registry`
`—`

Optional registry for custom directive rendering

Default:`None`

`role_registry`
`—`

Optional registry for custom role rendering

Default:`None`

`text_transformer`
`—`

Optional callback to transform plain text nodes

Default:`None`

`slugify`
`—`

Optional custom slugify function for heading IDs

Default:`None`

`_render_block`

3

▼

Render a block node.

`def _render_block(self, block: Block, sb: StringBuilder, ctx: RenderContext) -> None`

##### Parameters

Name
Type
Description

`block`
`—`

`sb`
`—`

`ctx`
`—`

`_render_heading`

3

▼

Render heading with ID for anchoring.

`def _render_heading(self, heading: Heading, sb: StringBuilder, ctx: RenderContext) -> None`

##### Parameters

Name
Type
Description

`heading`
`—`

`sb`
`—`

`ctx`
`—`

`_render_paragraph`

3

▼

Render paragraph.

`def _render_paragraph(self, para: Paragraph, sb: StringBuilder, ctx: RenderContext) -> None`

##### Parameters

Name
Type
Description

`para`
`—`

`sb`
`—`

`ctx`
`—`

`_render_fenced_code`

2

▼

Render fenced code block.

`def _render_fenced_code(self, code: FencedCode, sb: StringBuilder) -> None`

##### Parameters

Name
Type
Description

`code`
`—`

`sb`
`—`

`_render_indented_code`

2

▼

Render indented code block.

`def _render_indented_code(self, code: IndentedCode, sb: StringBuilder) -> None`

##### Parameters

Name
Type
Description

`code`
`—`

`sb`
`—`

`_render_blockquote`

3

▼

Render block quote.

`def _render_blockquote(self, quote: BlockQuote, sb: StringBuilder, ctx: RenderContext) -> None`

##### Parameters

Name
Type
Description

`quote`
`—`

`sb`
`—`

`ctx`
`—`

`_render_list`

3

▼

Render ordered or unordered list.

`def _render_list(self, lst: List, sb: StringBuilder, ctx: RenderContext) -> None`

##### Parameters

Name
Type
Description

`lst`
`—`

`sb`
`—`

`ctx`
`—`

`_render_list_item`

4

▼

Render list item.

CommonMark:
- Tight lists: Single paragraph items render as …

`def _render_list_item(self, item: ListItem, sb: StringBuilder, ctx: RenderContext, tight: bool) -> None`

Render list item.

CommonMark:

- Tight lists: Single paragraph items render as text (no
tags)

- Loose lists: All paragraphs wrapped in
tags

##### Parameters

Name
Type
Description

`item`
`—`

`sb`
`—`

`ctx`
`—`

`tight`
`—`

`_render_table`

3

▼

Render GFM-style table.

`def _render_table(self, table: Table, sb: StringBuilder, ctx: RenderContext) -> None`

##### Parameters

Name
Type
Description

`table`
`—`

`sb`
`—`

`ctx`
`—`

`_render_table_row`

5

▼

Render table row.

`def _render_table_row(self, row: TableRow, sb: StringBuilder, ctx: RenderContext, is_header: bool, alignments: tuple[str | None, ...]) -> None`

##### Parameters

Name
Type
Description

`row`
`—`

`sb`
`—`

`ctx`
`—`

`is_header`
`—`

`alignments`
`—`

`_render_math_block`

2

▼

Render block math.

`def _render_math_block(self, math: MathBlock, sb: StringBuilder) -> None`

##### Parameters

Name
Type
Description

`math`
`—`

`sb`
`—`

`_render_directive`

3

▼

Render directive block.

If a directive registry is configured and has a handle…

`def _render_directive(self, directive: Directive[Any], sb: StringBuilder, ctx: RenderContext) -> None`

Render directive block.

If a directive registry is configured and has a handler for this
directive, delegate to the handler per the `DirectiveHandler` (/patitas/api/directives/protocol/#DirectiveHandler)
contract:`render(node, rendered_children, sb) -> None`. Children
are rendered first and passed as a string. Unknown (unregistered)
directive names fall back to a generic container.

Handler exceptions are intentionally NOT swallowed: a broken handler
must surface loudly rather than silently emit wrong-but-plausible HTML.

##### Parameters

Name
Type
Description

`directive`
`—`

`sb`
`—`

`ctx`
`—`

`_render_inlines`

3

▼

Render a sequence of inline nodes.

`def _render_inlines(self, inlines: tuple[Inline, ...], sb: StringBuilder, ctx: RenderContext) -> None`

##### Parameters

Name
Type
Description

`inlines`
`—`

`sb`
`—`

`ctx`
`—`

`_render_inline`

3

▼

Render an inline node.

`def _render_inline(self, inline: Inline, sb: StringBuilder, ctx: RenderContext) -> None`

##### Parameters

Name
Type
Description

`inline`
`—`

`sb`
`—`

`ctx`
`—`

`_render_role`

2

▼

Render inline role.

`def _render_role(self, role: Role, sb: StringBuilder) -> None`

##### Parameters

Name
Type
Description

`role`
`—`

`sb`
`—`

`_collect_footnotes`

2

▼

Collect footnote definitions from document.

`def _collect_footnotes(self, doc: Document, ctx: RenderContext) -> None`

##### Parameters

Name
Type
Description

`doc`
`—`

`ctx`
`—`

`_render_footnotes_section`

2

▼

Render footnotes section at end of document.

`def _render_footnotes_section(self, sb: StringBuilder, ctx: RenderContext) -> None`

##### Parameters

Name
Type
Description

`sb`
`—`

`ctx`
`—`

## Functions

`html_escape`

1

`str`

▼

Escape HTML special characters.

CommonMark-compliant: escapes , &, " but NOT s…

`def html_escape(s: str) -> str`

Escape HTML special characters.

CommonMark-compliant: escapes <, >, &, " but NOT single quotes.
Uses str.translate for speed; fast path when no escaping needed.

##### Parameters

Name
Type
Description

`s`
`str`

##### Returns

`str`

`_encode_url`

1

`str`

▼

Encode URL for CommonMark compliance.

CommonMark requires:
1. Decode HTML enti…

`def _encode_url(url: str) -> str`

Encode URL for CommonMark compliance.

CommonMark requires:

- Decode HTML entities (e.g., ä → ä)

- Percent-encode special characters (spaces, backslashes, non-ASCII)

Returns URL safe for href attribute (still needs html_escape for quotes).

##### Parameters

Name
Type
Description

`url`
`str`

##### Returns

`str`
