Rust + WASM + Typst reimplementation of the Ott toolchain.
- Parse a large subset of Ott’s
.ottDSL (tested against upstream Otttests/*.ott, except known negative tests). - Run basic semantic checks (duplicate grammar roots, subrules references, duplicate rule names).
- Render grammars and inference rules in Typst via a WASM plugin.
- Parse and validate object-language terms/snippets in Typst from a loaded Ott spec (
ott-file→#ott[...]).
crates/ott-core/— parser + basic checkscrates/ott-render/— Typst render IR + CBOR serializationcrates/ott-cli/— CLI (check,render-json,render-cbor)crates/ott-wasm/— WASM plugin (parse_rules)typst/ott.typ— Typst-side renderer (uses@preview/curryst)demo.typ— root demo document
Prerequisites:
- Rust toolchain with
wasm32-unknown-unknowntarget - Typst
>= 0.14(uses built-incbor(...))
Build the WASM plugin and copy it into the Typst package directory:
cargo build -p ott-wasm --release --target wasm32-unknown-unknown
cp target/wasm32-unknown-unknown/release/ott_wasm.wasm typst/plugins/ott.wasmCompile the demo:
typst compile --root . demo.typ demo.pdf#import "typst/ott.typ": render, ott-file
// Render grammar + inference rules from a spec
#render(read("path/to/spec.ott"))
// Build a term parser.
// - If `root` is omitted, it behaves like Ott's `user_syntax` (tries all roots/metavars).
// - Specify `root` only to disambiguate.
#let ott = ott-file(read("path/to/spec.ott"))
// #let ott = ott-file(read("path/to/spec.ott"), root: "t")
// Parse + typeset terms
#ott[x]
#ott[`\x.x`]
$ #ott[`[x|->x]x`] $Notes:
- Term parsing uses
{{ typst ... }}hom templates in your.ottspec to pretty-print object-language snippets into Typst math.- If a production/metavar has no
typsthom, we fall back to rendering the original source slice as math text. - In
typsthoms, use Typst math symbols (e.g.tack.r,mapsto,lambda,arrow.r) instead of LaTeX commands (\\vdash,\\mapsto, ...).
- If a production/metavar has no
- Filter-mode (
[[...]]) is not implemented; useott-file(...)+ the returnedott[...]function instead. - Proof-assistant backends are not implemented yet.
See: docs/plans/2026-03-04-ott-typst-rust-nextgen-design.md.