Playground
Type Carve on the left, see the rendered HTML on the right (and the raw HTML below). Everything runs client-side, no network round-trip — the same reference parser that backs the spec corpus.
Carve Feature Demo ¶
A single document touching every core construct, plus a few renderer-dependent extensions at the end.
Headings and attributes ¶
Level 1 ¶
Level 2 ¶
Level 3 ¶
Level 4 ¶
Level 5 ¶
Level 6 ¶
A heading carries an explicit id and classes from a block-attribute line on the line directly above it:
{#install .lead}
## Setup
Inline formatting ¶
italic, bold, bold italic, underline, strikethrough, highlight,
superscript and subscript. Inline code span, and raw inline passthrough
HTML emitted verbatim.
Editorial markup: added text , deleted text ,
old phrase new phrase , and an editorial note .
Escapes keep specials literal: *not bold*, /not italic/, #not-a-tag.
Links and images ¶
Inline link, titled link, autolink https://example.com, email autolink hello@example.com, and a reference link.
A collapsed reference site reuses the label as the reference.
Cross-reference to a heading by id: jump to Carve Feature Demo.
Lists ¶
Unordered:
- apples
- oranges
- clementines
- blood oranges
- pears
Ordered:
- clone the repo
- install dependencies
- run the build
- run the tests
- ship it
Tasks:
- write the grammar
- write the corpus
- write more demos
Definition list:
- Carve
- A post-Markdown lightweight markup language.
- Djot
- The markup language Carve evolves from.
Blockquotes ¶
The best way to predict the future is to invent it.
Tables ¶
| Fruit | Price | Stock |
|---|---|---|
| Apple | 1.20 | In |
| Banana | 0.50 | In |
| Dragon fruit | 4.00 | Out |
Code and raw blocks ¶
A fenced code block with a language:
def greet(name: str) -> str:
return f"Hello, {name}!"
A quoted “header” after the language sets the block’s title (rendered as the
title attribute on the <pre> - a filename bar or hover tooltip):
def greet(name: str) -> str:
return f"Hello, {name}!"
A tilde fence works too:
key: value
list:
- one
- two
A raw block passes content through to a named format unchanged:
Native HTML
Rendered as-is.Math ¶
Inline math uses a dollar before a code span: \(e = mc^2\).
Display math uses a double dollar:
\[e^{i\pi} + 1 = 0\]
A fenced math block is the GFM-style block form (mathBlock extension):
Admonitions and divs ¶
A bare ::: fence with no admonition type is a generic styled container, not a
colored callout. Its id and classes go on a block-attribute line directly above
the fence:
This block has only an id and classes, so it renders as a plain
<div id="callout" class="highlight"> wrapper you can target with your own CSS.
Footnotes ¶
Carve supports footnotes1 with definitions collected anywhere.2
Smart typography ¶
Dashes and ellipsis: an em dash — an en range 10–20 … and so on. Arrows and comparisons: → ← ↔ ⇒ , ≠ ≤ ≥ , © ® ™.
List tables (Tier-3 extension) ¶
| Region | Notes |
|---|---|
| EMEA | Strong quarter. Drivers:
|
| APAC | |
Code groups (Tier-3 extension) ¶
npm install @markup-carve/carve
pnpm add @markup-carve/carve
yarn add @markup-carve/carve
Mermaid (Tier-3 extension) ¶
graph TD
A[Write Carve] --> B{LSP diagnostics}
B -->|clean| C[Preview]
B -->|warnings| D[Quick fix]
D --> A
C --> E[Publish]
sequenceDiagram
Author->>Editor: type Carve
Editor->>LSP: textDocument/didChange
LSP-->>Editor: diagnostics + semantic tokens
Editor-->>Author: live preview
Charts (Tier-3 extension) ¶
Spoilers (Tier-3 extension) ¶
The killer is the lighthouse keeper - click the blur to reveal.
Plot ending
Everyone makes it home. The dog lives too.
<section id="top">
<h1>Carve Feature Demo <a href="#top" class="permalink" aria-label="Permalink">¶</a></h1>
<p>A single document touching every core construct, plus a few renderer-dependent
extensions at the end.</p>
<section id="headings">
<h2 class="featured">Headings and attributes <a href="#headings" class="permalink" aria-label="Permalink">¶</a></h2>
</section>
</section>
<section id="Level-1">
<h1>Level 1 <a href="#Level-1" class="permalink" aria-label="Permalink">¶</a></h1>
<section id="Level-2">
<h2>Level 2 <a href="#Level-2" class="permalink" aria-label="Permalink">¶</a></h2>
<section id="Level-3">
<h3>Level 3 <a href="#Level-3" class="permalink" aria-label="Permalink">¶</a></h3>
<section id="Level-4">
<h4>Level 4 <a href="#Level-4" class="permalink" aria-label="Permalink">¶</a></h4>
<section id="Level-5">
<h5>Level 5 <a href="#Level-5" class="permalink" aria-label="Permalink">¶</a></h5>
<section id="Level-6">
<h6>Level 6 <a href="#Level-6" class="permalink" aria-label="Permalink">¶</a></h6>
<p>A heading carries an explicit id and classes from a block-attribute line on
the line directly above it:</p>
<pre><code class="language-carve">{#install .lead}
## Setup
</code></pre>
</section>
</section>
</section>
</section>
</section>
<section id="Inline-formatting">
<h2>Inline formatting <a href="#Inline-formatting" class="permalink" aria-label="Permalink">¶</a></h2>
<p><em>italic</em>, <strong>bold</strong>, <strong><em>bold italic</em></strong>, <u>underline</u>, <s>strikethrough</s>, <mark>highlight</mark>,
super<sup>script</sup> and sub<sub>script</sub>. Inline <code>code span</code>, and raw inline passthrough
<abbr>HTML</abbr> emitted verbatim.</p>
<p>Editorial markup: <ins> added text </ins>, <del> deleted text </del>,
<del> old phrase </del><ins> new phrase </ins>, and an <span class="critic-comment"> editorial note </span>.</p>
<p>Escapes keep specials literal: *not bold*, /not italic/, #not-a-tag.</p>
</section>
<section id="Links-and-images">
<h2>Links and images <a href="#Links-and-images" class="permalink" aria-label="Permalink">¶</a></h2>
<p>Inline <a href="https://example.com" target="_blank" rel="noopener noreferrer">link</a>, titled
<a href="https://example.com" title="Hover title" target="_blank" rel="noopener noreferrer">link</a>, autolink <a href="https://example.com" target="_blank" rel="noopener noreferrer">https://example.com</a>,
email autolink <a href="mailto:hello@example.com">hello@example.com</a>, and a reference <a href="https://example.com" title="Reference definition" target="_blank" rel="noopener noreferrer">link</a>.</p>
<p>A collapsed reference <a href="https://example.com" title="Reference definition" target="_blank" rel="noopener noreferrer">site</a> reuses the label as the reference.</p>
<p>Cross-reference to a heading by id: jump to <a href="#top">Carve Feature Demo</a>.</p>
<figure>
<img src="/carve/images/diagram.png" alt="A descriptive alt text">
<figcaption>Figure 1: images may carry a caption line.</figcaption>
</figure>
</section>
<section id="Lists">
<h2>Lists <a href="#Lists" class="permalink" aria-label="Permalink">¶</a></h2>
<p>Unordered:</p>
<ul>
<li>apples</li>
<li>oranges
<ul>
<li>clementines</li>
<li>blood oranges</li>
</ul>
</li>
<li>pears</li>
</ul>
<p>Ordered:</p>
<ol>
<li>clone the repo</li>
<li>install dependencies
<ul>
<li>run the build</li>
<li>run the tests</li>
</ul>
</li>
<li>ship it</li>
</ol>
<p>Tasks:</p>
<ul>
<li><input type="checkbox" checked disabled> write the grammar</li>
<li><input type="checkbox" checked disabled> write the corpus</li>
<li><input type="checkbox" disabled> write more demos</li>
</ul>
<p>Definition list:</p>
<dl>
<dt>Carve</dt>
<dd>A post-Markdown lightweight markup language.</dd>
<dt>Djot</dt>
<dd>The markup language Carve evolves from.</dd>
</dl>
</section>
<section id="Blockquotes">
<h2>Blockquotes <a href="#Blockquotes" class="permalink" aria-label="Permalink">¶</a></h2>
<figure>
<blockquote><p>The best way to predict the future is to invent it.</p></blockquote>
<figcaption>Alan Kay</figcaption>
</figure>
</section>
<section id="Tables">
<h2>Tables <a href="#Tables" class="permalink" aria-label="Permalink">¶</a></h2>
<table>
<caption>Table 1: column alignment - left, right, center.</caption>
<thead><tr><th>Fruit</th><th style="text-align: right;">Price</th><th style="text-align: center;">Stock</th></tr></thead>
<tbody>
<tr><td>Apple</td><td style="text-align: right;">1.20</td><td style="text-align: center;">In</td></tr>
<tr><td>Banana</td><td style="text-align: right;">0.50</td><td style="text-align: center;">In</td></tr>
<tr><td>Dragon fruit</td><td style="text-align: right;">4.00</td><td style="text-align: center;">Out</td></tr>
</tbody>
</table>
</section>
<section id="Code-and-raw-blocks">
<h2>Code and raw blocks <a href="#Code-and-raw-blocks" class="permalink" aria-label="Permalink">¶</a></h2>
<p>A fenced code block with a language:</p>
<pre><code class="language-python">def greet(name: str) -> str:
return f"Hello, {name}!"
</code></pre>
<p>A quoted “header” after the language sets the block’s title (rendered as the
<code>title</code> attribute on the <code><pre></code> - a filename bar or hover tooltip):</p>
<pre title="greet.py"><code class="language-python">def greet(name: str) -> str:
return f"Hello, {name}!"
</code></pre>
<p>A tilde fence works too:</p>
<pre><code class="language-yaml">key: value
list:
- one
- two
</code></pre>
<p>A raw block passes content through to a named format unchanged:</p>
<details><summary>Native HTML</summary>Rendered as-is.</details>
</section>
<section id="Math">
<h2>Math <a href="#Math" class="permalink" aria-label="Permalink">¶</a></h2>
<p>Inline math uses a dollar before a code span: <span class="math inline">\(e = mc^2\)</span>.</p>
<p>Display math uses a double dollar:</p>
<p><span class="math display">\[e^{i\pi} + 1 = 0\]</span></p>
<p>A fenced <code>math</code> block is the GFM-style block form (mathBlock extension):</p>
<div class="math display">\[\sum_{k=1}^{n} k = \frac{n(n+1)}{2}\]</div>
</section>
<section id="Admonitions-and-divs">
<h2>Admonitions and divs <a href="#Admonitions-and-divs" class="permalink" aria-label="Permalink">¶</a></h2>
<aside class="admonition note">
<p>A plain note callout.</p>
</aside>
<aside class="admonition tip">
<p class="admonition-title">With a title</p>
<p>Admonitions accept an optional quoted title.</p>
</aside>
<aside class="admonition warning">
<p>Heed this warning.</p>
</aside>
<aside class="admonition danger">
<p>Critical information.</p>
</aside>
<p>A bare <code>:::</code> fence with no admonition type is a generic styled container, not a
colored callout. Its id and classes go on a block-attribute line directly above
the fence:</p>
<div id="callout" class="highlight">
<p>This block has only an id and classes, so it renders as a plain
<code><div id="callout" class="highlight"></code> wrapper you can target with your own CSS.</p>
</div>
</section>
<section id="Mentions-tags-and-inline-extensions">
<h2>Mentions, tags, and inline extensions <a href="#Mentions-tags-and-inline-extensions" class="permalink" aria-label="Permalink">¶</a></h2>
<p>Mention a person with <span class="mention"><strong>@alice</strong></span> and reference a tag like <span class="tag"><strong>#release-1.0</strong></span>.
An inline extension names a role: press <kbd>Ctrl+C</kbd> to copy.</p>
</section>
<section id="Footnotes">
<h2>Footnotes <a href="#Footnotes" class="permalink" aria-label="Permalink">¶</a></h2>
<p>Carve supports footnotes<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a> with definitions collected anywhere.<a id="fnref2" href="#fn2" role="doc-noteref"><sup>2</sup></a></p>
</section>
<section id="Smart-typography">
<h2>Smart typography <a href="#Smart-typography" class="permalink" aria-label="Permalink">¶</a></h2>
<p>Dashes and ellipsis: an em dash — an en range 10–20 … and so on.
Arrows and comparisons: → ← ↔ ⇒ , ≠ ≤ ≥ , © ® ™.</p>
<hr>
</section>
<section id="List-tables-Tier-3-extension">
<h2>List tables (Tier-3 extension) <a href="#List-tables-Tier-3-extension" class="permalink" aria-label="Permalink">¶</a></h2>
<table>
<caption>Quarterly results</caption>
<thead><tr><th>Region</th><th>Notes</th></tr></thead>
<tbody>
<tr><td>EMEA</td><td><p>Strong quarter.</p>
<p>Drivers:</p>
<ul>
<li>new logos</li>
<li>renewals</li>
</ul></td></tr>
<tr><td colspan="2">APAC</td></tr>
</tbody>
</table>
</section>
<section id="Code-groups-Tier-3-extension">
<h2>Code groups (Tier-3 extension) <a href="#Code-groups-Tier-3-extension" class="permalink" aria-label="Permalink">¶</a></h2>
<div class="code-group">
<input type="radio" name="codegroup-1" id="codegroup-1-tab-1" class="code-group-radio" checked>
<label for="codegroup-1-tab-1" class="code-group-label">npm</label>
<input type="radio" name="codegroup-1" id="codegroup-1-tab-2" class="code-group-radio">
<label for="codegroup-1-tab-2" class="code-group-label">pnpm</label>
<input type="radio" name="codegroup-1" id="codegroup-1-tab-3" class="code-group-radio">
<label for="codegroup-1-tab-3" class="code-group-label">yarn</label>
<div class="code-group-panel"><pre><code class="language-bash">npm install @markup-carve/carve
</code></pre>
</div>
<div class="code-group-panel"><pre><code class="language-bash">pnpm add @markup-carve/carve
</code></pre>
</div>
<div class="code-group-panel"><pre><code class="language-bash">yarn add @markup-carve/carve
</code></pre>
</div>
</div>
</section>
<section id="Mermaid-Tier-3-extension">
<h2>Mermaid (Tier-3 extension) <a href="#Mermaid-Tier-3-extension" class="permalink" aria-label="Permalink">¶</a></h2>
<pre class="mermaid">graph TD
A[Write Carve] --> B{LSP diagnostics}
B -->|clean| C[Preview]
B -->|warnings| D[Quick fix]
D --> A
C --> E[Publish]</pre>
<pre class="mermaid">sequenceDiagram
Author->>Editor: type Carve
Editor->>LSP: textDocument/didChange
LSP-->>Editor: diagnostics + semantic tokens
Editor-->>Author: live preview</pre>
</section>
<section id="Charts-Tier-3-extension">
<h2>Charts (Tier-3 extension) <a href="#Charts-Tier-3-extension" class="permalink" aria-label="Permalink">¶</a></h2>
<div class="chart"><script type="application/json">{"type":"bar","data":{"labels":["Q1","Q2","Q3","Q4"],"datasets":[{"label":"Revenue","data":[12,19,14,23]}]}}</script></div>
</section>
<section id="Spoilers-Tier-3-extension">
<h2>Spoilers (Tier-3 extension) <a href="#Spoilers-Tier-3-extension" class="permalink" aria-label="Permalink">¶</a></h2>
<p>The killer is <span class="spoiler">the lighthouse keeper</span> - click the blur to reveal.</p>
<details class="spoiler">
<summary>Plot ending</summary>
<p>Everyone makes it home. The dog lives too.</p>
</details>
</section>
</section>
<section role="doc-endnotes">
<hr>
<ol>
<li id="fn1">
<p>The reference and its definition are linked by label.<a href="#fnref1" role="doc-backlink">↩</a></p>
</li>
<li id="fn2">
<p>Definitions can appear in any order.<a href="#fnref2" role="doc-backlink">↩</a></p>
</li>
</ol>
</section>Vite Plugin Dogfood
The docs build also imports a .crv file through @markup-carve/vite-plugin-carve and renders the generated HTML during the VitePress build.
Imported Carve
# Plugin Dogfood
This snippet is rendered from a `.crv` import by *vite-plugin-carve*.
Inline math like $`E = mc^2` and a display equation render with KaTeX:
$$`\int_0^\infty e^{-x^2}\,dx = \frac{\sqrt{\pi}}{2}`
Rendered HTML
Plugin Dogfood ¶
This snippet is rendered from a .crv import by vite-plugin-carve.
Inline math like \(E = mc^2\) and a display equation render with KaTeX:
\[\int_0^\infty e^{-x^2}\,dx = \frac{\sqrt{\pi}}{2}\]
What this proves
- Every construct in the Quick Reference and every pair in the Examples flows through the same parser → AST → renderer pipeline you see here.
- Edits round-trip in single-digit milliseconds. Carve's linear-time parsing is the reason.
- The current build comes from
@markup-carve/carve, pinned to an exact carve-js commit in the repo'spackage.json.