@ljoss/rehype-figure-caption
v1.0.0
Published
A Rehype plugin to transform images into <figure> elements with optional captions.
Downloads
74
Maintainers
Readme
@ljoss/rehype-figure-caption
Transform your images into semantic and accessible <figure>
elements with optional <figcaption>
using this Rehype plugin. It handles images in both Markdown and raw HTML, enhancing your content's structure and presentation.
Installation
Install the plugin and its required dependencies:
Using npm:
npm install @ljoss/rehype-figure-caption unified remark-parse remark-rehype rehype-raw rehype-stringify unist-util-visit-parents
Using Yarn:
yarn add @ljoss/rehype-figure-caption unified remark-parse remark-rehype rehype-raw rehype-stringify unist-util-visit-parents
Note: This plugin operates at the Rehype (HTML) level and depends on the following packages:
unified
: Core of the Unified framework.remark-parse
: Parses Markdown to MDAST (Markdown Abstract Syntax Tree).remark-rehype
: Converts MDAST to HAST (HTML Abstract Syntax Tree).rehype-raw
: Parses raw HTML within Markdown (needed if you have raw HTML).rehype-stringify
: Serializes HAST to HTML.unist-util-visit-parents
: Utility for traversing the syntax tree with access to parent nodes.
Usage
Integrate the plugin into your Unified processing pipeline.
Example: Converting Markdown to HTML
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeRaw from 'rehype-raw'; // Needed if processing raw HTML
import rehypeStringify from 'rehype-stringify';
import rehypeFigureCaption from '@ljoss/rehype-figure-caption';
const processor = unified()
.use(remarkParse) // Parses Markdown to MDAST
.use(remarkRehype, { allowDangerousHtml: true }) // Converts MDAST to HAST, allows raw HTML
.use(rehypeRaw) // Parses raw HTML in Markdown to HAST
.use(rehypeFigureCaption, {
figureClassName: 'custom-figure',
imageClassName: 'custom-image',
captionClassName: 'custom-caption',
allowEmptyCaption: true, // Wraps images without alt text
})
.use(rehypeStringify); // Converts HAST to HTML
const markdown = `
![Alt Text](path-to-image.jpg)
<img src="path-to-image.jpg" alt="Alt Text" class="test">
![](path-to-image.jpg)
Some text before ![Image in text](image-in-text.jpg) some text after.
<p>Some text and <img src="inline-image.jpg" alt="Inline Image"> more text.</p>
`;
processor.process(markdown).then((file) => {
console.log(String(file));
});
Expected Output
<figure class="custom-figure">
<img src="path-to-image.jpg" alt="Alt Text" class="custom-image">
<figcaption class="custom-caption">Alt Text</figcaption>
</figure>
<figure>
<img src="path-to-image.jpg" alt="Alt Text" class="test">
<figcaption>Alt Text</figcaption>
</figure>
<figure>
<img src="path-to-image.jpg" alt="">
</figure>
<p>Some text before </p>
<figure>
<img src="image-in-text.jpg" alt="Image in text">
<figcaption>Image in text</figcaption>
</figure>
<p> some text after.</p>
<p>Some text and </p>
<figure>
<img src="inline-image.jpg" alt="Inline Image">
<figcaption>Inline Image</figcaption>
</figure>
<p> more text.</p>
Simplified Usage Without Raw HTML
If your Markdown content does not contain raw HTML, you can omit rehype-raw
and the allowDangerousHtml
option:
const processor = unified()
.use(remarkParse)
.use(remarkRehype)
.use(rehypeFigureCaption)
.use(rehypeStringify);
Options
Customize the plugin's behavior using the following options:
| Option | Type | Description | Default |
| ------------------- | --------- | ----------------------------------------------------------------------------- | ----------- |
| figureClassName
| string
| CSS class to add to <figure>
elements | undefined
|
| imageClassName
| string
| CSS class to add to <img>
elements | undefined
|
| captionClassName
| string
| CSS class to add to <figcaption>
elements | undefined
|
| allowEmptyCaption
| boolean
| If true
, wraps images without alt text in <figure>
without <figcaption>
| false
|
Processing Flow
The plugin processes your content through the following steps:
Traverse the Syntax Tree: The plugin visits each node in the HTML syntax tree (HAST), specifically looking for
<img>
elements.Skip Images Inside Links: If an image is inside an
<a>
tag, it is skipped to avoid breaking the link structure.Check Alt Text: The plugin checks the
alt
attribute of the image.- If
alt
text exists, orallowEmptyCaption
istrue
, it proceeds. - Otherwise, the image is left unaltered.
- If
Add Class Names: If provided in the options, class names are added to the
<img>
,<figure>
, and<figcaption>
elements.Create
<figure>
and<figcaption>
Elements:- A
<figure>
element is created to wrap the image. - If
alt
text exists, a<figcaption>
element is created with thealt
text as its content.
- A
Replace or Restructure Nodes:
If the parent is a
<p>
element:- With only the
<img>
: The<p>
is replaced with the<figure>
. - With additional content: The
<p>
is split into separate nodes before and after the<img>
.- Content before the image remains in a
<p>
. - The
<figure>
is inserted after. - Content after the image is placed in a new
<p>
.
- Content before the image remains in a
- With only the
If the parent is not a
<p>
element:- The
<img>
is replaced with the<figure>
.
- The
Result: The syntax tree is updated, and when stringified, produces HTML with images wrapped in
<figure>
elements and captions added where appropriate.
Contributing
We welcome contributions!
Development Setup
Clone the repository
git clone https://github.com/Ljoss-Studios/rehype-figure-caption.git
Navigate to the project directory
cd rehype-figure-caption
Install dependencies
Using npm:
npm install
Using Yarn:
yarn install
Run tests
Using npm:
npm test
Using Yarn:
yarn test
Start development server (if applicable)
If the project has a development server or watch mode:
npm run dev
Or with Yarn:
yarn dev
Submitting Changes
- Fork the repository and create a new branch.
- Write tests to cover your changes.
- Ensure all tests pass before submitting.
- Submit a pull request detailing your changes.
License
This project is licensed under the MIT License.
Thank you for your interest and contributions!
Important Notes
Dependency on Rehype: This plugin operates at the Rehype level, manipulating the HTML syntax tree (HAST). It requires
remark-rehype
to convert Markdown to HTML andrehype-raw
to parse any raw HTML within your Markdown content.Processing Pipeline: Ensure your processing pipeline includes the necessary steps:
- Parse Markdown to MDAST: Using
remark-parse
. - Convert MDAST to HAST: Using
remark-rehype
.- Set
allowDangerousHtml: true
if processing raw HTML.
- Set
- Parse Raw HTML to HAST Nodes: Using
rehype-raw
(if needed). - Apply
rehype-figure-caption
Plugin: To transform images. - Stringify HAST to HTML: Using
rehype-stringify
.
- Parse Markdown to MDAST: Using
Raw HTML Support: Include
rehype-raw
in your pipeline to process raw HTML<img>
elements embedded in your Markdown.
Frequently Asked Questions
Q1: Can I use this plugin with Remark directly?
A: No, this plugin is designed to work with Rehype, not Remark. It manipulates the HTML AST (HAST), which is available after converting Markdown to HTML using remark-rehype
.
Q2: What if I only have Markdown images and no raw HTML?
A: Even if your content only contains Markdown images, you can still use this plugin. Just ensure your pipeline includes remark-rehype
to convert the Markdown to HTML before applying the plugin.
Q3: Do I need to set allowDangerousHtml: true
if I don't have raw HTML in my Markdown?
A: No, if your Markdown does not contain raw HTML, you can omit the allowDangerousHtml: true
option and the rehype-raw
plugin.
Acknowledgments
We thank all contributors and users who have provided feedback and suggestions to improve this plugin.
For any questions or suggestions, feel free to open an issue on the GitHub repository or contact us directly.