Core vocabulary
The 52 reserved node names that need no definition — the resolver skips binding
lookup for them and every renderer ships a handler. Grouped below by category,
one entry per node, each with the HTML it emits, the parameters it honours, and
its context. Also here: the node opaque container and the two
special-cased renderers (table, bibliography).
Unresolved fallbacks
When a name binds to nothing, the renderer emits a marker span rather than failing silently.
| Input | Emits |
|---|---|
| @name binds nothing | <span class="wit-unresolved">@name</span> |
| dotted @a.b unresolved | <span class="wit-unresolved">@a.b</span> |
| stray capture | <span class="wit-unresolved">::name::</span> |
| bare data-def reference | <span class="wit-node" data-wit-name="name"></span> |
Headings — 6
| Node | Emits | Context | Params |
|---|---|---|---|
| h1 | <h1>…</h1> | inline-context | id / class |
| h2 | <h2>…</h2> | inline-context | id / class |
| h3 | <h3>…</h3> | inline-context | id / class |
| h4 | <h4>…</h4> | inline-context | id / class |
| h5 | <h5>…</h5> | inline-context | id / class |
| h6 | <h6>…</h6> | inline-context | id / class |
@h1 Title h1@ → <h1>Title</h1> @h2(id sec) A h2@ → <h2 id="sec">A</h2>
Any level is legal at any nesting depth; the theme styles h1 through h6. Fixture: 18-core-vocab/headings.wit.
Inline marks — 10
Each wraps its body in the same-named tag. All are inline-context and take id / class only — except br, which is void
(no body, no params).
| Node | Emits | Context |
|---|---|---|
| em | <em>…</em> | inline-context |
| strong | <strong>…</strong> | inline-context |
| code | <code>…</code> | inline-context |
| u | <u>…</u> | inline-context |
| s | <s>…</s> | inline-context |
| sub | <sub>…</sub> | inline-context |
| sup | <sup>…</sup> | inline-context |
| mark | <mark>…</mark> | inline-context |
| small | <small>…</small> | inline-context |
| br | <br> | void |
@strong Bold strong@ → <strong>Bold</strong> @code x < y code@ → <code>x < y</code> Line one@br break → Line one<br>break
em and strong are the explicit form of _italic_ and *bold* — identical HTML, useful when
the token-wrap rule of the marks gets in the way. codeescapes its body; it is not a raw node — for
verbatim text use @@code … code@@. Fixture:18-core-vocab/inline-marks.wit.
Lists — 6
| Node | Emits | Context |
|---|---|---|
| ul | <ul>…</ul> | block |
| ol | <ol>…</ol> | block |
| li | <li>…</li> | inline-context |
| dl | <dl>…</dl> | block |
| dt | <dt>…</dt> | inline-context |
| dd | <dd>…</dd> | inline-context |
@ul @li First li@ @li Second li@ ul@ @dl @dt Term dt@ @dd Definition dd@ dl@
- First
- Second
- Term
- Definition
These are hand-authored lists. For data-driven lists prefer a collection def
plus (each) — see data
model. Fixture: 18-core-vocab/lists.wit.
Links and media — 6
Typed renderers: each has its own param set, not the id/class allowlist.
a
@a |href /x| Go a@ → <a href="/x">Go</a> @a |href /x| |target _blank| Go a@ → <a href="/x" target="_blank">Go</a>
| Param | Meaning | Default |
|---|---|---|
| href | link address | # |
| target | browsing context | none |
Only href and target survive; id / class are not emitted for anchors. Inline-context.
img
Void. src / alt / width / height are raw attributes; size and aligncompile to an inline style.
| Param | Effect |
|---|---|
| src | image URL — escaped |
| alt | alt text — escaped |
| width | width attribute |
| height | height attribute |
| size | sizing style — see below |
| align | block alignment — center / left / right |
| size value | Compiles to |
|---|---|
| full | width:100% |
| a percent | width:N% |
| small | max-width:220px |
| medium | max-width:380px |
| large | max-width:600px |
| a bare number | max-width:Npx |
| Npx | max-width:Npx |
@img |src p.jpg| |alt A| |size medium| |align center|
Emits:
<img src="p.jpg" alt="A" style="max-width:380px;height:auto;display:block;margin-left:auto;margin-right:auto">
align center → block-centred; right / left→ block with the opposite auto-margin. Presets and pixel values cap (max-width); full and percents fill (width). Fixture:18-core-vocab/links-and-media.wit.
figure
Block. align sets text-align on the figure's contents (image and caption together); a capped sizecentres the figure box.
@figure |align center| @img |src p.jpg| |alt A| @figcaption Cap figcaption@ figure@
Emits:
<figure style="text-align:center"><img src="p.jpg" alt="A"><figcaption>Cap</figcaption></figure>
figcaption / audio / video
| Node | Emits | Context | Params |
|---|---|---|---|
| figcaption | <figcaption>…</figcaption> | inline-context | id / class |
| audio | <audio>…</audio> | block | src / controls flag |
| video | <video>…</video> | block | src / controls flag |
@audio |src clip.mp3| |controls!| audio@ → <audio src="clip.mp3" controls></audio>
The body of audio / video renders inside for fallback
text or source elements. Fixture:18-core-vocab/links-and-media.wit.
Tables — 8
tableis dispatched to the complex renderer (see the tables reference); the core-vocab branch is only a fallback. The other seven are hand-authored table parts.
| Node | Emits | Context |
|---|---|---|
| table | <table>…</table> | block — special renderer |
| thead | <thead>…</thead> | block |
| tbody | <tbody>…</tbody> | block |
| tfoot | <tfoot>…</tfoot> | block |
| tr | <tr>…</tr> | block |
| th | <th>…</th> | inline-context |
| td | <td>…</td> | inline-context |
| caption | <caption>…</caption> | inline-context |
Most authors use @table |rows …| rather than assembling parts by
hand. Fixture: 19-tables/*.
Blocks — 4
| Node | Emits | Context | Params |
|---|---|---|---|
| p | <p>…</p> | block | id / class |
| blockquote | <blockquote>…</blockquote> | block | id / class |
| pre | <pre>…</pre> | block | id / class |
| hr | <hr> | void | none |
@blockquote A quote blockquote@ → <blockquote><p>A quote</p></blockquote> @hr → <hr>
pre escapes its body (whitespace preserved by the
theme); for unescaped raw text use @@pre … pre@@. Fixture: 18-core-vocab/blocks.wit.
Sectioning — 7
Each emits its same-named HTML element (block; id / class).
Pure semantic containers — the theme adds no styling beyond block flow. Good
targets for @@style.
| Node | Emits |
|---|---|
| section | <section>…</section> |
| article | <article>…</article> |
| aside | <aside>…</aside> |
| header | <header>…</header> |
| footer | <footer>…</footer> |
| nav | <nav>…</nav> |
| main | <main>…</main> |
@nav(class toc) … nav@ → <nav class="toc">…</nav>
Generic containers — 2
| Node | Emits | Context | Params |
|---|---|---|---|
| div | <div>…</div> | block | id / class |
| span | <span>…</span> | inline | id / class |
@div(class card) Body div@ → <div class="card"><p>Body</p></div> @span note span@ → <span>note</span>
The building blocks for author-defined layout. Fixture: seeded from a built snippet (not in fixture 18).
Layout — 2
An invisible flex band and its columns — side-by-side content without floats.
row
Emits a fixed-style flex container; no params honoured beyond the body.
<div style="display:flex;gap:1.5rem;align-items:flex-start;flex-wrap:wrap;margin:1.2em 0">…</div>
col
A flex child. size sets its width; no size fills the
remaining space.
| size value | Basis |
|---|---|
| small | flex:0 0 220px |
| medium | flex:0 0 380px |
| large | flex:0 0 600px |
| a bare number | flex:0 0 Npx |
| Npx | flex:0 0 Npx |
| a percent | flex:0 0 N% |
| no size | flex:1 1 0 — fills |
@row @col |size 220| Left col@ @col Right col@ row@
Left
Right
Emits:
<div style="display:flex;…"><div style="flex:0 0 220px;min-width:0"><p>Left</p></div><div style="flex:1 1 0;min-width:0"><p>Right</p></div></div>
Columns wrap (stack) when the row is too narrow. Put an image in one column and prose in another for a side-by-side. Fixture: built snippet.
Other — 1
| Node | Emits | Context | Params |
|---|---|---|---|
| cite | <cite>…</cite> | inline-context | id / class |
@cite The Book cite@ → <cite>The Book</cite>
Cross-cutting entries
node — opaque dispatch
If type names a core-vocab node, render as that element; otherwise
emit a div carrying every named param as a data-* attribute (the key is sanitised).
@node(type h2) T node@ → <h2>T</h2> @node(type box, role note) Hi node@ → <div data-type="box" data-role="note"><p>Hi</p></div>Fixture:
20-opaque-node/*.
bibliography — special renderer
Not core vocab and has no HTML element of its own. Entries are contributed with
additive +#bibliography: value-blocks; a bare @bibliography then expands them, each contribution on its own
line. The dedicated renderer wraps a literal bibliography body in <div class="wit-bibliography"> and gives each entry its own
paragraph (stripping one wrapping paragraph so APA runs do not collide).
#reference_entry ||author, year, title|| ::author:: (::year::). ::title::. reference_entry# +#bibliography: @reference_entry author: Boud, D. year: 2001 title: Using journal writing reference_entry@ !! @bibliography
Boud, D. (2001). Using journal writing.
23-form-fill/bibliography-style.wit.
Raw-text elements
@@style … style@@ and @@script … script@@ emit
their body verbatim (unescaped; guarded against a nested closing
tag). Every other @@@ raw node escapes its Text body.
@@style .lead { color: red } style@@ → <style>.lead { color: red }</style>
Standalone record / collection
A node use whose body is exactly one record or collection
literal renders as <table class="wit-record"> / <ul class="wit-collection">. Ordinary record-arg syntax attaches
records as params, so normal authoring rarely reaches this
legacy path.
See also
Syntax· Tables · Data model · Errors · Limitations.