rehype-grouping-figure
v0.1.0
Published
rehype plugin that groups images followed by blockquote into a figure and figcaption
Maintainers
Readme
rehype-grouping-figure
rehype plugin that groups one or more images into a <figure> when they are immediately followed by a <blockquote>, turning that blockquote into a <figcaption>.
Contents
- What is this?
- When should I use this?
- Install
- Use
- API
unified().use(rehypeGroupingFigure[, options])
- Examples
- Types
- Compatibility
- Security
- License
What is this?
This is a unified (rehype) plugin.
It walks the hast tree and looks for this pattern:
- A paragraph (
<p>) that contains only image elements (<img>) and optional whitespace text nodes - Immediately followed by a blockquote (
<blockquote>) (whitespace text nodes between them are ignored)
When found, it rewrites both nodes into:
<figure class="group">- all matched
<img>elements inside the figure <figcaption>containing the original blockquote children
When should I use this?
Use this plugin when your markdown/HTML authoring style places captions in blockquotes after image-only paragraphs, and you want semantic figure markup in output HTML.
You probably shouldn't use it if:
- your captions are not represented as blockquotes
- you need configurable class names or matching rules (the current API is intentionally minimal)
Install
This package is ESM only. In Node.js (version 20.19+):
npm install rehype-grouping-figurepnpm add rehype-grouping-figureUse
Say we have the following markdown:

> This is a caption for the cat image...and a script example.js:
import {unified} from 'unified'
import remarkParse from 'remark-parse'
import remarkRehype from 'remark-rehype'
import rehypeStringify from 'rehype-stringify'
import rehypeGroupingFigure from 'rehype-grouping-figure'
const file = await unified()
.use(remarkParse)
.use(remarkRehype)
.use(rehypeGroupingFigure)
.use(rehypeStringify)
.process('\n\n> This is a caption for the cat image')
console.log(String(file))...running node example.js yields:
<figure class="group"><img src="./cat.jpg" alt="A beautiful cat"><figcaption><p>This is a caption for the cat image</p></figcaption></figure>API
This package exports:
- the default identifier
rehypeGroupingFigure - the named schema export
rehypeGroupingFigureSanitizeSchema - the TypeScript type
Options
unified().use(rehypeGroupingFigure[, options])
Groups image-only paragraphs followed by blockquotes into figure/figcaption markup.
Parameters
options(Options, optional) — currently empty; reserved for future configuration
Returns
Transformer function.
rehypeGroupingFigureSanitizeSchema
Schema extension object for rehype-sanitize so generated figure / figcaption markup and figure.group are allowed.
Examples
Two images + caption
Input:


> These are our beloved petsOutput:
<figure class="group">
<img src="./cat.jpg" alt="A beautiful cat">
<img src="./dog.jpg" alt="A playful dog">
<figcaption>
<p>These are our beloved pets</p>
</figcaption>
</figure>Multi-paragraph captions are preserved
Input:

> This is a multi-line caption.
>
> It spans multiple paragraphs and provides
> detailed information about the image.
>
> **Bold text** and *italic text* are also supported.Output figcaption keeps all blockquote content structure.
Not grouped when content appears in between
If any non-whitespace content appears between the image paragraph and blockquote, no grouping happens.
Types
This package is fully typed with TypeScript.
Compatibility
- Node.js 20.19+
unified11+
Security
This plugin only reshapes existing HTML structure (p + img + blockquote -> figure + figcaption) and does not fetch external data or execute code.
If you sanitize downstream with rehype-sanitize, merge in the exported schema:
import rehypeSanitize, {defaultSchema} from 'rehype-sanitize'
import rehypeGroupingFigure, {
rehypeGroupingFigureSanitizeSchema
} from 'rehype-grouping-figure'
unified()
.use(rehypeGroupingFigure)
.use(rehypeSanitize, {
...defaultSchema,
tagNames: [
...(defaultSchema.tagNames || []),
...rehypeGroupingFigureSanitizeSchema.tagNames
],
attributes: {
...defaultSchema.attributes,
...rehypeGroupingFigureSanitizeSchema.attributes
},
ancestors: {
...defaultSchema.ancestors,
...rehypeGroupingFigureSanitizeSchema.ancestors
}
})License
MIT © Ari Palo
