Specification · v1 Working Draft
anvil·md

Appendix  ·  Playground

Type it. Watch it parse.

The left pane is an ANVIL fence. The right pane is what the reference renderer makes of it, redrawn as you type. Underneath, every complaint the parser had.

RUNS IN
This tab. No request leaves the page, and nothing you type is stored.
USING
@anvil-md/parser and @anvil-md/render-html, unmodified, from source.
DISPLAY
Controls are inert by design - this draws a block, it does not run one.

Examples

streaming passes false as the second argument to renderAnvilFence, which is the state a fence is in while the model is still typing it: rendered, visibly provisional, and never answerable.

Source

Rendered

An agent writes one of these inside a fenced anvil block, mid-sentence.

Edit the source on the left. The right-hand pane redraws as you type.

Where should I ship this?
Staging is wiped nightly. Nothing there is permanent.
preview
Set the dials
Formal Playful
Dense Airy
Quiet Loud
preview

Parse report

The parser never throws. It complains.

A fence arrives token by token, so every prefix of every block is a real input. Malformed input degrades to a renderable block plus a warning - try the malformed example above.

3 blocks · 0 warnings · fence closed

BlockKindDiagnostics
a49b3ab81 derived @note accepted, no warnings
deploy-target @choice accepted, no warnings
tone @scale accepted, no warnings

Wiring

Nothing on this page is special.

// the playground is these three lines, in a keyup handler
out.innerHTML = renderAnvilFence(textarea.value, fenceIsClosed)
const doc = parseAnvil(textarea.value, { partial: !fenceIsClosed })
// doc.blocks[n].warnings is what the report below is reading

Both packages are zero-dependency and DOM-free, so they run in a browser tab, in a Worker, or in whatever renders your transcript. The blocks above were drawn at build time by the same call, from the same string, which is why the page works with JavaScript off. Back to the specification.