Markdown Captions
Adds ~: captions for any block (images, quotes, code, tables, lists) to VSCode's markdown preview, as <figure> and <figcaption>.
Overview
The caption plugin captions a block with a line starting ~: written right after it. The block goes in a <figure>, and the caption becomes its <figcaption>:
<figure class="markdown-caption">
<img src="https://github.com/mirrordown/mirrordown/raw/HEAD/fuji.jpg" alt="Mount Fuji at dawn">
<figcaption>Mount Fuji from Lake Kawaguchi.</figcaption>
</figure>
Any block can take a caption: an image, a paragraph, a quote, code, a table, a list, and the blocks other plugins add, such as tabs, steps, alerts, definition lists and diagrams.
The marker follows the ~ that definition lists use, with a colon, so it can't be mistaken for one: a term followed by ~ definition stays a definition list. In renderers without the plugin, the caption stays a line of text.
Syntax
Write ~:, a space and the caption on the line right after the block, with no blank line between them. The caption runs to the end of its paragraph and can hold inline markdown.
Images
An image alone in its paragraph becomes the figure's content. Its alt text stays its alt text, which describes the image to people who can't see it; the caption is for everyone.

~: Mount Fuji from Lake Kawaguchi, *at dawn*.
A lightbox image (!) works the same: its trigger is the figure's content, and the lightbox can show the caption in its dialog too. Several images in one paragraph make one figure. An image inside a sentence isn't a figure of its own, so a caption after it captions the paragraph.
Quotes
A caption written after a quote, without its >, attributes it.
> Simple is better than complex.
~: Tim Peters, *The Zen of Python*
Code
```sh
npm install @mirrordown/remd-caption
```
~: Installing the remark plugin
Tables
| Engine | Plugin |
| ----------- | --------------------------- |
| markdown-it | `@mirrordown/mdit-caption` |
| remark | `@mirrordown/remd-caption` |
| Sätteri | `@mirrordown/sat-caption` |
~: One plugin per engine
A table reads the caption line as a row of its own, so a table's caption can't contain a | (write \|).
Any other block
1. Measure twice.
2. Cut once.
~: A carpenter's rule
Which block a caption goes on
A caption goes on the block it's written after, at the level its > markers and indentation put it, the same rule attrs uses for a line of attributes. Written inside a quote or list item, it captions the block before it there; written outside, it captions the quote or the whole list.
> A quote in a quote
~: Captions the inner quote
~: Captions the outer quote
- An item
~: Captions the item's paragraph
- Another item
~: Captions the list
The caption runs to the end of its paragraph, so a ~: on a later line at the same level is part of it. A caption doesn't attach to a heading, a thematic break, raw HTML, or another caption, and a ~: after a blank line is text, so a caption always touches its block.
Attributes
With the attrs plugin, attributes written at the end of a caption go on the figure, which gives it an id to link to. A block keeps its own attributes.
{.photo}
~: Wild rice in late summer {#fig-rice}
<figure class="markdown-caption" id="fig-rice">
<img src="https://github.com/mirrordown/mirrordown/raw/HEAD/wild-rice.jpg" alt="Wild rice growing in a marsh" class="photo">
<figcaption>Wild rice in late summer</figcaption>
</figure>
Customization
The stylesheet keeps its rules in @layer markdown-caption, so any unlayered CSS you write overrides them. It removes the browser's default figure indent (40px on each side, which would narrow tables and code) and sets the caption a little smaller and lighter than the text around it.
.markdown-caption > figcaption {
font-style: italic;
text-align: center;
}
Number figures with a CSS counter:
.content {
counter-reset: figure;
}
.markdown-caption > figcaption::before {
counter-increment: figure;
content: "Figure " counter(figure) ": ";
}
remark-captions uses a word for each kind of block (Figure:, Source:, Code:, Table:) and captions only the kinds it's configured for. This plugin has one marker for every block. Its table captions also work with today's GFM tables, where remark-captions' Table: line becomes a row.
Styling
This extension ships default styles for the rendered output in the preview. To
customize them, point VSCode's markdown.styles setting at your own CSS file:
// .vscode/settings.json
{
"markdown.styles": ["./my-preview-styles.css"]
}
About
Part of Markdown Preview Extended Syntax — a pack of Markdown preview syntax extensions you can install all at once.
Powered by @mirrordown/mdit-caption · Source on GitHub.