Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

wire.normalize

import wire

wire exposes this as wire.normalize, so import wire is enough and the names are called as wire.normalize.*. import wire.normalize reaches the same definitions directly.

Rewriting Wire’s pseudo elements into something HTML’s own tree construction will not move, drop or reshape.

Why this exists

<include>, <extend>, <declare> and <define> are not HTML elements, and a standards-following parser has firm opinions about elements it does not know. Inside <head> one is pushed out into <body>. Inside a table one is foster parented out in front of the table. Inside a <select> one is dropped on the floor. And written as <include path="x" />, the trailing slash means nothing on an unknown element, so it swallows the whole rest of the document as its children.

All four of those are places a template genuinely wants an include: a shared block of <meta> tags, a partial holding table rows, a partial holding options. So Wire does not hand its own tag names to the parser at all. While the source is being tokenized, every pseudo element is turned into a <template> carrying the directive it means, and <template> is the one element the standard lets through untouched everywhere.

The rewrite happens on the token stream rather than on the text, so it inherits the tokenizer’s own understanding of comments, of raw text inside <script> and <style>, and of quoting. A <include> written inside a comment or inside a script stays exactly where it was.

What else it notices

A template may be a whole page or a fragment of one, and the tree builder gives you <html>, <head> and <body> either way. Telling the two apart afterwards is guesswork, so the flags are collected here while the real tokens go past: whether the source actually spelled a doctype, an <html>, a <head> or a <body>. The compiler emits each of those only when the author wrote it.

Functions

parse()

wire.normalize.parse(source: string, context: ?string) -> dict

Parses source into a tree with Wire’s pseudo elements already rewritten.

context names the element the source is being parsed inside. Pass nil to parse it as a whole document, which is what a template being rendered on its own is; pass a tag name to parse it as a fragment, so that a partial holding table rows keeps its rows when it is included inside a table.

Returns a dictionary of:

  • root: the Document for a document parse, or the DocumentFragment holding the parsed nodes for a fragment parse.
  • document: true when the parse was a document parse.
  • saw_doctype, saw_html, saw_head, saw_body: whether the source really contained each, as opposed to the parser having supplied it.
  • errors: the parse errors the tokenizer and tree builder found.
import wire

var parsed = wire.normalize.parse('<include path="nav.html" />', nil)
echo parsed.root.body().inner_html()
# <template x-include="nav.html"></template>

Parameters

  • source (string)
  • context (?string)

Returns dict

Classes

Normalizer

class wire.normalize.Normalizer

A tokenizer that rewrites Wire’s pseudo elements on the way past.

This stands where a html.Tokenizer normally stands and answers everything the tree builder asks of one, so html.TreeBuilder cannot tell the difference.

Fields

FieldTypeDescription
cdata_okWhether the tree builder will accept a CDATA section at the current insertion point.
errorsThe parse errors the underlying tokenizer has collected.
saw_doctypeTrue once a <!DOCTYPE> has gone past.
saw_htmlTrue once an <html> start tag has gone past.
saw_headTrue once a <head> start tag has gone past.
saw_bodyTrue once a <body> start tag has gone past.

Constructor

wire.normalize.Normalizer(source)

Parameters

  • source (Tokenizer)

Normalizer.next_token()

wire.normalize.Normalizer.next_token() -> Token

The next token, rewritten when it names a pseudo element.

Returns Token

Normalizer.set_state()

wire.normalize.Normalizer.set_state(state: string)

Passes the tree builder’s tokenizer state change along.

Parameters

  • state (string)

Normalizer.set_last_start_tag()

wire.normalize.Normalizer.set_last_start_tag(name: string)

Passes the tree builder’s record of the last start tag along, which is how the tokenizer knows whether a </script> it is looking at closes the script it is inside.

Parameters

  • name (string)

2026, Richard Ore and The Zuri Contributors