npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@ljoss/rehype-figure-caption

v1.0.0

Published

A Rehype plugin to transform images into <figure> elements with optional captions.

Downloads

74

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:

  1. Traverse the Syntax Tree: The plugin visits each node in the HTML syntax tree (HAST), specifically looking for <img> elements.

  2. Skip Images Inside Links: If an image is inside an <a> tag, it is skipped to avoid breaking the link structure.

  3. Check Alt Text: The plugin checks the alt attribute of the image.

    • If alt text exists, or allowEmptyCaption is true, it proceeds.
    • Otherwise, the image is left unaltered.
  4. Add Class Names: If provided in the options, class names are added to the <img>, <figure>, and <figcaption> elements.

  5. Create <figure> and <figcaption> Elements:

    • A <figure> element is created to wrap the image.
    • If alt text exists, a <figcaption> element is created with the alt text as its content.
  6. 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>.
    • If the parent is not a <p> element:

      • The <img> is replaced with the <figure>.
  7. 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

  1. Clone the repository

    git clone https://github.com/Ljoss-Studios/rehype-figure-caption.git
  2. Navigate to the project directory

    cd rehype-figure-caption
  3. Install dependencies

    Using npm:

    npm install

    Using Yarn:

    yarn install
  4. Run tests

    Using npm:

    npm test

    Using Yarn:

    yarn test
  5. 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 and rehype-raw to parse any raw HTML within your Markdown content.

  • Processing Pipeline: Ensure your processing pipeline includes the necessary steps:

    1. Parse Markdown to MDAST: Using remark-parse.
    2. Convert MDAST to HAST: Using remark-rehype.
      • Set allowDangerousHtml: true if processing raw HTML.
    3. Parse Raw HTML to HAST Nodes: Using rehype-raw (if needed).
    4. Apply rehype-figure-caption Plugin: To transform images.
    5. Stringify HAST to HTML: Using rehype-stringify.
  • 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.