Figures
A figure is a block-level wrapper that adds a caption and optional numbering to content — typically an image, but figures can contain any block content. Figures are essential for technical reports, academic documents, and any content where readers need to reference visual elements by number.
Basic syntax
Wrap content in a :::figure container. The last paragraph inside becomes the caption:
::: figure

The high-level architecture showing how services communicate.
:::The renderer displays this as a captioned figure — the image above, the caption below (or above, depending on renderer conventions). Without the :::figure wrapper, an image is just an inline media embed with no caption or numbering.
Figure numbering
Figures are automatically numbered in document order. The renderer prefixes the caption with a label like "Figure 1:", "Figure 2:", etc. The exact label text and format (Arabic numerals, Roman numerals, chapter-relative numbering) is up to the renderer.
::: figure

Entity-relationship diagram for the user management module.
:::
Some text discussing the schema...
::: figure

Authentication flow between client, gateway, and identity provider.
:::→ Rendered as:
Figure 1: Entity-relationship diagram for the user management module.
...
Figure 2: Authentication flow between client, gateway, and identity provider.
Numbering is automatic — rearranging figures updates the numbers without any manual changes.
Figure IDs
Add {#id} after figure to assign a stable ID for cross-referencing:
::: figure {#arch-diagram}

The high-level architecture showing how services communicate.
:::
See {@fig:arch-diagram} for the full architecture overview.The cross-reference {@fig:arch-diagram} resolves to the figure's number (e.g. "Figure 1"). Cross-references are covered in detail on the Cross-References page.
Without an explicit ID, figures are still numbered but cannot be referenced by ID from elsewhere in the document.
ID rules
- The ID can contain letters, numbers, hyphens, and underscores.
- IDs must be unique within the document. Duplicate figure IDs emit a warning — the second occurrence gets a
-2suffix. - The
{#id}is placed directly afterfigureon the opening line, before any content.
Captions
The caption is the last paragraph inside the figure container. Everything before it is the figure's content (typically an image or other media).
::: figure {#performance}

Response time comparison across three configurations.
Measured on a 4-core VM with 8 GB RAM.
:::Captions support inline formatting — emphasis, links, inline code, math, badges, and emoji all work:
::: figure {#formula}

Derivation of $E = mc^2$ from the **Lorentz transformation**. See [Wikipedia](https://en.wikipedia.org/wiki/Mass%E2%80%93energy_equivalence) for background.
:::Figures without captions
If a figure container has no trailing paragraph, it has no caption. The figure is still numbered but displays no caption text:
::: figure {#logo}

:::This is useful when you need a numbered, referenceable figure but the image is self-explanatory.
Unnumbered figures
If you want a caption but no "Figure X:" label, add unnumbered to the opening line:
::: figure {unnumbered}

The BachMark core team at the 2025 offsite.
:::This produces a captioned image without a number prefix. Unnumbered figures do not participate in the numbering sequence — they don't consume a number or affect the count of subsequent figures.
You can combine unnumbered with an ID:
::: figure {#team-photo unnumbered}

The BachMark core team at the 2025 offsite.
:::An unnumbered figure with an ID can still be linked to via its anchor, but cross-references cannot resolve it to a number — a warning is emitted if you try.
Rich figure content
Figures aren't limited to images. Any block content can go inside a figure — code blocks, tables, block math, even multiple images:
Code listing
::: figure {#listing-parser}
```rust
fn parse(input: &str) -> Result<Ast, Error> {
let tokens = tokenize(input)?;
let ast = build_tree(tokens)?;
Ok(ast)
}
```
Core parsing function — tokenizes the input, then builds the AST.
:::Block math
::: figure {#gauss-integral}
$$
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
$$
The Gaussian integral, fundamental to probability theory and statistics.
:::Multiple images
::: figure {#comparison}


Performance dashboard before and after the optimization. Left: original, right: optimized.
:::How multiple images are laid out (side by side, stacked, grid) is a renderer decision. If you need explicit control over layout, use a row inside the figure:
::: figure {#side-by-side}
:::: row
::: col

:::
::: col

:::
::::
Side-by-side comparison of the dashboard.
:::Note the increased colon count — the ::::row must use more colons than the :::col children, and the outer :::figure uses the same count as the cols since it's not nesting inside them. If this gets confusing, a simpler structure with two separate figures may be clearer.
Figures vs. plain media embeds
| Feature | ![]() media embed | :::figure |
|---|---|---|
| Displays the content | ✅ | ✅ |
| Caption | ❌ | ✅ |
| Auto-numbered | ❌ | ✅ |
| Referenceable by ID | ❌ | ✅ |
| Block-level wrapper | ❌ | ✅ |
| Supports any content | Media only | Any blocks |
Use plain ![]() for inline images that don't need captions or numbering — icons, decorative images, quick screenshots. Use :::figure when the content is a meaningful part of the document that readers may need to reference.
Figures in PDF output
Figures are particularly important for PDF and paged output. Renderers should:
- Display figures where they appear in the source. The author controls the document's structure — if a figure is placed between two paragraphs, it stays between those paragraphs.
- Add "Figure X" labels to the caption automatically (unless the figure is
unnumbered). - Include figures in a List of Figures (if the renderer supports it).
If a figure is too large to fit on the current page, the renderer may push it to the next page and continue with the following text. But the figure's position in the reading order must match its position in the source — renderers should not float figures to the top or bottom of unrelated pages.
Parsing rules
- A figure is a
:::figurecontainer block. It follows the same nesting rules as other container blocks. - The optional
{#id}and/or{unnumbered}attributes must appear on the same line as:::figure, separated by spaces. They can appear in any order::::figure {#my-id unnumbered}and:::figure {unnumbered #my-id}are equivalent. - The caption is identified as the last paragraph directly inside the figure container. If the last block inside the figure is not a paragraph (e.g. it's a code block or an image with no trailing text), the figure has no caption.
- Numbered figures are counted sequentially in document order, starting from 1. Only figures inside
:::figurecontainers participate in numbering — plain![]()embeds do not. Figures markedunnumberedare excluded from the count. - Figures cannot be nested inside other figures. If a
:::figureappears inside another:::figure, a warning is emitted and the inner figure is treated as a generic container.