callout
GitHub-style alerts with optional title and fold.
> [!WARNING] Breaking change in v3
> The `render()` signature changed.
Markset, running in your browser: the same parser and the same HTML writer the command line calls, bundled and handed to you. Nothing you type leaves this page.
The whole vocabulary, and it is closed: these eight and no others. A directive with any other name is an error rather than markup that quietly passes through.
calloutGitHub-style alerts with optional title and fold.
> [!WARNING] Breaking change in v3
> The `render()` signature changed.
cardA titled surface around any content.
:::card[Pricing tiers]{tone=info}
Content here.
:::
gridA list whose items become cards.
:::grid{cols=3 gap=md}
- **Fast** — sub-50 ms cold start
- **Small** — 4 kB gzipped
- **Typed** — no `any` in the public API
:::
columnsSide-by-side regions with an optional ratio.
::::columns{ratio="2:1"}
The main argument, at full paragraph length.
::col
:::card{tone=neutral}
A supporting sidebar.
:::
::::
tabsHeadings become tab labels; no JavaScript.
:::tabs
### macOS
`brew install markset`
### Windows
`winget install markset`
:::
stepsA numbered procedure from an ordered list.
:::steps
1. Install the CLI.
2. Run `markset init`.
3. Edit `markset.toml`.
:::
metricsBig numbers with deltas from a table.
:::metrics
| Metric | Value | Δ |
|---------|-------|-------|
| Revenue | $4.2M | +12% |
| Churn | 2.1% | -0.4% |
:::
figureAn image, table, or code block with a caption.
:::figure[Sizes]
| a | b |
|---|---|
| 1 | 2 |
:::
Neither is a construct. Both are a figure — one holding a code fence, one holding a table — which is why a picture needs no ninth name.
diagramAn ASCII fence inside a captioned figure, drawn as a picture.
:::figure[How a request reaches a handler]{#fig-flow}
```ascii
+-------+ +--------+
| Start |---->| Finish |
+-------+ +--------+
```
:::
chartA figure's table drawn as a line, bar or column chart.
:::figure[Requests per second by region]{#fig-rps chart=line}
| Quarter | us-east | eu-west |
|---|---|---|
| Q1 | 120 | 64 |
| Q2 | 140 | 71 |
:::
The three pieces that are not blocks. Each is borrowed unchanged from Pandoc, djot or MyST — Markset invented no spelling of its own.
{.lead}A line of attributes above a block, to style the block below it.
{.lead}
Opening paragraph, larger.
[text]{.class}An inline run carrying attributes, for a badge or a keyword.
[Beta]{.badge tone=warn}
frontmatterThe version key and the seven theme tokens, at the top of the document.
---
markset: 0
theme:
preset: editorial # editorial | technical | deck | report
accent: "#2563eb"
density: comfortable # compact | comfortable | spacious
radius: md # none | sm | md | lg
type:
body: "Source Serif 4"
heading: "Inter"
scale: 1.25
---
# Title
The four tabs beside the result are the four things markset can hand you from a file — html, downgrade, ast and check — and each answers a different question about the document in the editor. They are worth switching between at least once.
ms- one and every variant is a data- attribute, which is what a second implementation has to agree with.remark-markset plugin hands to a unified pipeline.markset check reports. The vocabulary is closed, so an unknown directive name is an error here rather than markup that quietly passes through. Load An invalid document to see it.Nobody wrote that list. The names are the parser's own closed vocabulary, so the palette cannot offer a construct the parser rejects or leave one out; the descriptions are the ones the reference index prints; and every snippet is a case from the conformance suite — usually the one the suite calls canonical, which is its word for the minimal correct form. So each is a document that is already proven valid, by the same tests that prove the renderer.
Where a snippet lands is read off the tree rather than counted in lines. A construct always goes in at the top level, never between another construct's fences, and an inline span goes in only where the document actually has inline content — not into your frontmatter and not into a code fence. A test inserts every entry at every offset of a document and requires the result to still parse.
The share button puts the whole document in the URL fragment. A fragment is never sent to a server, so a link is a complete bug report that reveals the document to nobody but the person you send it to.
Everything here runs from the same library the command line uses, so anything the playground renders, a build renders the same way.