π Part of the VMPrint Ecosystem
A transmuter converts a source format into VMPrint's native intermediate representation β DocumentInput β without touching the layout engine.
The VMPrint engine speaks exactly one language: DocumentInput JSON. This is intentional. The engine has no knowledge of Markdown, DOCX, LaTeX, or any other authoring format. That separation keeps the layout core deterministic and format-agnostic.
Transmuters are the bridge. Each one takes a human-authored source and produces a DocumentInput object the engine can ingest directly. They are deliberately kept thin:
- No file access. No
fs, no I/O. Input and output are plain in-memory values. - No engine dependency. Transmuters do not import
@vmprint/engine. Types are declared locally and kept structurally compatible. - Embeddable anywhere. Browser, Node.js, edge worker, build plugin β the same package works in all of them.
Directories follow {source}-{target} where both sides use short format identifiers:
| Identifier | Meaning |
|---|---|
mkd |
Markdown (CommonMark + GFM extensions) |
So mkd-mkd is the Markdown β DocumentInput transmuter. The second mkd here refers not to a different Markdown dialect but to the vmprint IR whose semantic elements (heading-1, paragraph, blockquote, β¦) mirror the block-level vocabulary of Markdown β it is the natural structural target for markdown source.
| Directory | Package | Source |
|---|---|---|
markdown-core/ |
@vmprint/markdown-core |
Shared Markdown β DocumentInput compiler core |
mkd-mkd/ |
@vmprint/mkd-mkd |
Markdown β DocumentInput |
mkd-academic/ |
@vmprint/mkd-academic |
Markdown β DocumentInput (academic defaults) |
mkd-literature/ |
@vmprint/mkd-literature |
Markdown β DocumentInput (literature defaults) |
mkd-manuscript/ |
@vmprint/mkd-manuscript |
Markdown β DocumentInput (manuscript defaults) |
mkd-screenplay/ |
@vmprint/mkd-screenplay |
Markdown β DocumentInput (screenplay defaults) |
draft2final is now a thin, transmuter-first orchestrator. It selects a transmuter, loads user-editable config defaults, resolves optional themes, and then renders either PDF or AST JSON output.
Transmuters remain the lower-level primitives: source text in, DocumentInput AST out. They are where source-format semantics and default conventions live. This keeps heavy regression coverage at the transmuter level while the CLI stays lightweight.
Shared transmuter contract types live in @vmprint/contracts.
A transmuter should satisfy the shared Transmuter<Input, Output, Options> contract and may also export a convenience function:
interface Transmuter<Input, Output, Options> {
transmute(source: Input, options?: Options): Output;
}It should have no runtime dependency on @vmprint/engine and no file-system access. Themes and config are passed as strings or plain objects by the caller.