Reference implementation
The markset command
One executable with five commands. It validates a document, renders it to HTML, lowers it to plain CommonMark, prints the parsed tree, or writes the default stylesheet. There is no build step and no configuration file.
Getting it
Installing it
Node 22.18 or newer, and one package.
npm i -g @markset-lang/cli
markset --help
A project that renders as part of its own build wants it as a dev dependency instead — npm i -D @markset-lang/cli puts markset on the path inside npm scripts. To try it without installing anything, npx @markset-lang/cli html doc.md.
Working on Markset rather than with it? Clone the repository and run node packages/cli/src/markset.ts, which is the same program before packaging: the sources are TypeScript that Node runs by stripping the types, so there is no build step between an edit and running it.
Commands
What each one does
markset check
Reads one or more documents and reports every diagnostic with a file, line and column. Exits with status 1 if any diagnostic is an error, which is what makes it usable in continuous integration. Add --json to get the diagnostics as structured data instead of text.
markset html
Renders a complete HTML page with the default stylesheet inlined, so the output is one self-contained file. Add --fragment for the body content alone, --theme <file> to append a theme stylesheet, and --title to set the page title. ASCII diagram fences are drawn automatically (spec §10), and --diagram adds other languages or turns drawing off. What draws a fence is an engine: a function built into the renderer, or a command you name.
markset css
Writes the default stylesheet — tokens, the eight constructs, print rules, light and dark. A site that renders more than one page links it once instead of inlining it into every file, which is the difference between a 24 KB page and a 0.5 KB one. Takes no input file. See publishing to GitHub Pages.
markset downgrade
Lowers every construct to the plain CommonMark it is defined to fall back to. The output is a fixed point: downgrading it again changes nothing, and it parses with no diagnostics. This is the degradation contract, executable.
markset ast
Prints the parsed tree as JSON. The tree is mdast plus the Markset node types, so any tool in the unified ecosystem can consume it. Add --positions to keep source offsets.
A single - in place of a filename reads the document from standard input.
Options
Every flag
| Flag | Applies to | Effect |
|---|---|---|
-o, --out <path> |
all | Write to a file instead of standard output. |
| (no file) | css |
css is the one command that takes no input document. |
--fragment |
html |
Emit the body content only, with no page shell or stylesheet. |
--css <mode> |
html |
inline inlines the default stylesheet and is the default. none omits it. Any other value is treated as a URL and linked. |
--theme <file> |
html |
Append a theme stylesheet after the default one, so it can style author classes and override tokens. See spec §6. |
--diagram <spec> |
html |
Diagram code fences. ascii is drawn by default; none turns drawing off; <lang>=<command> adds a language, running a command with the fence on stdin and SVG on stdout. Repeatable. Only a fence inside a captioned figure is drawn, and an engine that fails leaves the code block in place. See spec §10 and the diagrams reference. |
--title <text> |
html |
Page title. Defaults to the first level-one heading. |
--json |
check |
Emit diagnostics as JSON rather than as lines of text. |
--positions |
ast |
Keep the position field on every node. |
-h, --help |
all | Print usage and exit. |
In practice
Three things worth knowing
-
An invalid document still renders
checkis the gate, not the renderer.htmlanddowngradereport diagnostics on standard error and then produce their output anyway, because a document with one bad directive is still mostly a document. Nothing is silently dropped. -
Validation is the point of a closed vocabulary
A misspelled
:::cardsis an error rather than a passthrough, so it fails in your editor rather than in someone's browser. Runmarkset check docs/*.mdin continuous integration and a typo cannot reach a published page. -
The downgrade is how you leave
Nothing here locks a document in.
markset downgradegives back ordinary CommonMark that any renderer on earth handles, which is the same content a viewer that has never heard of Markset would show.
See it work
markset check examples/showcase.md
markset html examples/showcase.md -o showcase.html
markset html examples/strategy-read.md --theme examples/memo.css -o memo.html
markset downgrade examples/showcase.md
markset html doc.md --diagram none -o doc.html