Tolerant on input
Accepts the Markdown people actually write — irregular spacing, mixed emphasis markers, the usual GFM extensions — and models it in a strict, unambiguous AST. Forward-only scanning, bounded lookahead, no backtracking.
Markdown stays nice, and becomes reliable. Markanto reads familiar Markdown tolerantly, gives it a strict semantic structure, and writes it back in exactly one canonical form per meaning.
# Release notesWritten with *emphasis*, a[link](/spec/), and one**strong** marker to fix.
01 / What it is
Read tolerantly, model strictly, serialise canonically. CommonMark standardises how Markdown is read; Markanto also standardises how it is written — it keeps the loose input authors expect and removes the loose output.
Accepts the Markdown people actually write — irregular spacing, mixed emphasis markers, the usual GFM extensions — and models it in a strict, unambiguous AST. Forward-only scanning, bounded lookahead, no backtracking.
One way to write each construct back out. Reformatting is idempotent; two authors who mean the same thing produce identical bytes.
Undefined footnote references, ID uniqueness, resource-attribute allowlists, quote nesting, table shape, the inline structural invariants — a function over the AST, independent of the parser.
Why not just Markdown? Markdown standardises how a document is read — never one way to write it back. Markanto adds a strict semantic structure and exactly one canonical form, so tools, pipelines, and agents transform a document and get the same bytes every time — and it stays Markdown you write by hand. A library models Markdown for one tool; Markanto makes that model a shared contract.
02 / The laws
The canonical form is not a style preference. It is the property the parser, formatter, and validator are built to guarantee.
parse(format(doc)) is semantically equal to doc. Formatting never changes meaning.
format run twice changes nothing the first run didn’t. The canonical form is a fixed point.
Non-canonical and canonical spellings of the same meaning parse to the same AST — and format to the same bytes.
03 / Degradation
Markanto-specific syntax is designed to degrade gracefully: in a plain Markdown renderer it should lose its meaning, never its readability. The canonical form stays machine-friendly without becoming machine-first — it is still Markdown a person writes by hand.
<m> <i> <b>
The whole reserved vocabulary is <m> (metadata / resources), <i> and <b> (emphasis fallbacks) — the mnemonic is MIB.
They are Markanto syntax, not a general HTML passthrough. Canonical output still prefers
*em* and **strong**.
No plugin semantics
No added syntax, no compatibility aliases, no parser profiles that alter meaning, no heuristic media typing. An external profile must not change how identical source text is interpreted.
04 / Numbers
Idempotent reformatting, stable diffs, and safe automated rewrites are only worth as much as the guarantees behind them. What those rest on, counted.
verify:node
The language design and specification were independently audited (2026-08-30); an independent whole-repo
review of the implementation returned a
SHIP / FREEZE
verdict — 0 blockers, 0 retained major findings. The full gate list is in the
changelog,
and every v0.5.3 → 0.1.0 language delta is in
EVOLUTION_V053_TO_010.md.
05 / Resource safety
Formatting, validation, and automated rewrites stay predictable because meaning, canonical output, and
resource limits are separate contracts. Every operation returns a tagged
status union; a resource budget being exceeded is always distinct from the document being invalid.
status: "resource"
The Grid occupancy matrix is bounded by a caller-tunable default (DEFAULT_MAX_MATRIX_SLOTS, 100 000) and an absolute, non-overridable ceiling (HARD_MAX_MATRIX_SLOTS, 1 000 000). An over-budget matrix returns resource, never a native RangeError.
O(n) target
A monotonic cursor, no backtracking over competing interpretations. The property gate includes a parser-linearity probe. The architecture is written to port mechanically to safe, idiomatic Rust.
06 / Implementation
TypeScript defines the AST, the canonical serialisation, and the conformance corpus any other implementation would be checked against. A Rust port is a deliberately kept-open option, not a current commitment.