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

@microflash/remark-callout-directives

v4.3.2

Published

remark plugin to render callouts and admonitions with directives

Downloads

5,664

Readme

remark-callout-directives

npm regression license

remark plugin to render callouts and admonitions with directives

What’s this?

This package is a unified (remark) plugin to add support for callouts and admonitions using the directives. It depends on remark-directive which must be included before this plugin.

When should I use this?

Callouts and admonitions are used to provide additional information related to a topic under discussion or draw out attention to potential possibilities. They are widely used in documentation by popular libraries, frameworks, and applications (for example, Docusaurus, Obsidian, etc). Use this plugin if you need something similar.

Prerequisites

You should import remark-directive before this plugin for callouts to work.

Install

This package is ESM only.

In Node.js (version 16.0+), install with npm:

npm install @microflash/remark-callout-directives

In Deno, with esm.sh:

import remarkCalloutDirectives from "https://esm.sh/@microflash/remark-callout-directives"

In browsers, with esm.sh:

<script type="module">
  import remarkCalloutDirectives from "https://esm.sh/@microflash/remark-callout-directives?bundle"
</script>

Use

Say we have the following file example.md:

:::note
Some **content** with _Markdown_ `syntax`.
:::

And our module example.js looks as follows:

import { read } from "to-vfile"
import { unified } from "unified"
import remarkParse from "remark-parse"
import remarkDirective from "remark-directive"
import remarkCalloutDirectives from "@microflash/remark-callout-directives"
import remarkRehype from "remark-rehype"
import rehypeStringify from "rehype-stringify"

main()

async function main() {
  const file = await unified()
    .use(remarkParse)
    .use(remarkDirective)
    .use(remarkCalloutDirectives)
    .use(remarkRehype, { allowDangerousHtml: true })
    .use(rehypeStringify, { allowDangerousHtml: true })
    .process(await read("example.md"))

  console.log(String(file))
}

Running that with node example.js yields:

<aside class="callout callout-note">
  <div class="callout-indicator">
    <div class="callout-hint">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
        <path d="M12 8h.01M12 12v4"/>
        <circle cx="12" cy="12" r="10"/>
      </svg>
    </div>
    <div class="callout-title">Note</div>
  </div>
  <div class="callout-content">
    <p>Some <strong>content</strong> with <em>Markdown</em> <code>syntax</code>.
    </p>
  </div>
</aside>

API

The default export is remarkCalloutDirectives.

Options

The following options are available. All of them are optional.

  • aliases: a list of aliases for the callouts
  • callouts: an object containing the callout definitions
  • tagName: global custom element type. If specified, it'll override the default aside element type. This can be overridden by callout specific configuration (callouts.<calloutName>.tagName).

Default options

By default, the following callouts and aliases are preconfigured.

{
  aliases: {},
  callouts: {
    note: {
      title: "Note",
      hint: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M12 8h.01M12 12v4"/><circle cx="12" cy="12" r="10"/></svg>`
    },
    commend: {
      title: "Success",
      hint: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m8 12 2.7 2.7L16 9.3"/><circle cx="12" cy="12" r="10"/></svg>`
    },
    warn: {
      title: "Warning",
      hint: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M12 9v4m0 4h.01M8.681 4.082C9.351 2.797 10.621 2 12 2s2.649.797 3.319 2.082l6.203 11.904a4.28 4.28 0 0 1-.046 4.019C20.793 21.241 19.549 22 18.203 22H5.797c-1.346 0-2.59-.759-3.273-1.995a4.28 4.28 0 0 1-.046-4.019L8.681 4.082Z"/></svg>`
    },
    deter: {
      title: "Danger",
      hint: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M12 12s-5.6 4.6-3.6 8c1.6 2.6 5.7 2.7 7.2 0 2-3.7-3.6-8-3.6-8Z"/><path d="M13.004 2 8.5 9 6.001 6s-4.268 7.206-1.629 11.8c3.016 5.5 11.964 5.7 15.08 0C23.876 10 13.004 2 13.004 2Z"/></svg>`
    },
    assert: {
      title: "Info",
      hint: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M12.5 7.5h.01m-.01 4v4m-7.926.685L2 21l6.136-1.949c1.307.606 2.791.949 4.364.949 5.243 0 9.5-3.809 9.5-8.5S17.743 3 12.5 3 3 6.809 3 11.5c0 1.731.579 3.341 1.574 4.685"/></svg>`
    }
  }
}

Themes

To style the callouts, import a theme from themes folder.

GitHub

GitHub theme

VitePress

VitePress theme

Microflash

Microflash theme

For more advanced customizations, take a look at the existing themes and remix your own.

Examples

Example: callout with custom title

Say we have the following file example.md:

:::warn{title="Hold on there"}
Some **content** with _Markdown_ `syntax`.
:::

Running example.js will yield:

<aside class="callout callout-warn">
  <div class="callout-indicator">
    <div class="callout-hint">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
        <path d="M12 9v4m0 4h.01M8.681 4.082C9.351 2.797 10.621 2 12 2s2.649.797 3.319 2.082l6.203 11.904a4.28 4.28 0 0 1-.046 4.019C20.793 21.241 19.549 22 18.203 22H5.797c-1.346 0-2.59-.759-3.273-1.995a4.28 4.28 0 0 1-.046-4.019L8.681 4.082Z"/>
      </svg>
    </div>
    <div class="callout-title">Hold on there</div>
  </div>
  <div class="callout-content">
    <p>Some <strong>content</strong> with <em>Markdown</em> <code>syntax</code>.</p>
  </div>
</aside>

Example: callout with markdown title

Say we have the following file example.md:

:::warn{title="**Hold** on _there_!"}
Some **content** with _Markdown_ `syntax`.
:::

Running example.js will yield:

<aside class="callout callout-warn">
  <div class="callout-indicator">
    <div class="callout-hint">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
        <path d="M12 9v4m0 4h.01M8.681 4.082C9.351 2.797 10.621 2 12 2s2.649.797 3.319 2.082l6.203 11.904a4.28 4.28 0 0 1-.046 4.019C20.793 21.241 19.549 22 18.203 22H5.797c-1.346 0-2.59-.759-3.273-1.995a4.28 4.28 0 0 1-.046-4.019L8.681 4.082Z"/>
      </svg>
    </div>
    <div class="callout-title">
      <strong>Hold</strong> on <em>there</em>!
    </div>
  </div>
  <div class="callout-content">
    <p>Some <strong>content</strong> with <em>Markdown</em> <code>syntax</code>.</p>
  </div>
</aside>

Example: custom callouts

You can add your own callouts as well. Say we have the following file example.md:

:::shoutout{title="Well done!"}
Some **content** with _Markdown_ `syntax`.
:::

And our module example.js looks as follows:

import { read } from "to-vfile"
import { unified } from "unified"
import remarkParse from "remark-parse"
import remarkDirective from "remark-directive"
import remarkCalloutDirectives from "@microflash/remark-callout-directives"
import remarkRehype from "remark-rehype"
import rehypeStringify from "rehype-stringify"

main()

async function main() {
  const file = await unified()
    .use(remarkParse)
    .use(remarkDirective)
    .use(remarkCalloutDirectives, {
      callouts: {
        shoutout: {
          title: "Shoutout",
          hint: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M4.7 6.5h.01m8.49-2.8h.01m4.29 15.6h.01m2.79-8.5h.01m-6.41-.7 2.2-.7V6.5h2.8V3.7L21 3m-6.253 10.767c1.676-.175 2.93-.38 3.739-.064 1.234.483 1.497 1.529 1.409 3.008m-9.723-7.519c.175-1.676.38-2.93.064-3.739-.483-1.234-1.529-1.497-3.008-1.409M6.5 10.4l7.1 7.1L3 21z"/></svg>`
        }
      }
    })
    .use(remarkRehype, { allowDangerousHtml: true })
    .use(rehypeStringify, { allowDangerousHtml: true })
    .process(await read("example.md"))

  console.log(String(file))
}

Running example.js will yield:

<aside class="callout callout-shoutout">
  <div class="callout-indicator">
    <div class="callout-hint">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
        <path d="M4.7 6.5h.01m8.49-2.8h.01m4.29 15.6h.01m2.79-8.5h.01m-6.41-.7 2.2-.7V6.5h2.8V3.7L21 3m-6.253 10.767c1.676-.175 2.93-.38 3.739-.064 1.234.483 1.497 1.529 1.409 3.008m-9.723-7.519c.175-1.676.38-2.93.064-3.739-.483-1.234-1.529-1.497-3.008-1.409M6.5 10.4l7.1 7.1L3 21z"/>
      </svg>
    </div>
    <div class="callout-title">Well done!</div>
  </div>
  <div class="callout-content">
    <p>Some <strong>content</strong> with <em>Markdown</em> <code>syntax</code>.</p>
  </div>
</aside>

Example: configure aliases

Say we have the following file example.md:

:::danger
Some **content** with _Markdown_ `syntax`.
:::

And our module example.js looks as follows:

import { read } from "to-vfile"
import { unified } from "unified"
import remarkParse from "remark-parse"
import remarkDirective from "remark-directive"
import remarkCalloutDirectives from "@microflash/remark-callout-directives"
import remarkRehype from "remark-rehype"
import rehypeStringify from "rehype-stringify"

main()

async function main() {
  const file = await unified()
    .use(remarkParse)
    .use(remarkDirective)
    .use(remarkCalloutDirectives, {
      aliases: {
        danger: "deter"
      }
    })
    .use(remarkRehype, { allowDangerousHtml: true })
    .use(rehypeStringify, { allowDangerousHtml: true })
    .process(await read("example.md"))

  console.log(String(file))
}

Running that with node example.js yields:

<aside class="callout callout-deter">
  <div class="callout-indicator">
    <div class="callout-hint">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
        <path d="M12 12s-5.6 4.6-3.6 8c1.6 2.6 5.7 2.7 7.2 0 2-3.7-3.6-8-3.6-8Z"/>
        <path d="M13.004 2 8.5 9 6.001 6s-4.268 7.206-1.629 11.8c3.016 5.5 11.964 5.7 15.08 0C23.876 10 13.004 2 13.004 2Z"/>
      </svg>
    </div>
    <div class="callout-title">Danger</div>
  </div>
  <div class="callout-content">
    <p>Some <strong>content</strong> with <em>Markdown</em> <code>syntax</code>.</p>
  </div>
</aside>

Example: configure element type

By default, a callout is rendered as an aside. You can override this behavior by providing a tagName for the callout.

Say we have the following file example.md:

:::assert
Some **content** with _Markdown_ `syntax`.
:::

And our module example.js looks as follows:

import { read } from "to-vfile"
import { unified } from "unified"
import remarkParse from "remark-parse"
import remarkDirective from "remark-directive"
import remarkCalloutDirectives from "@microflash/remark-callout-directives"
import remarkRehype from "remark-rehype"
import rehypeStringify from "rehype-stringify"

main()

async function main() {
  const file = await unified()
    .use(remarkParse)
    .use(remarkDirective)
    .use(remarkCalloutDirectives, {
      callouts: {
        assert: {
          tagName: "div"
        }
      }
    })
    .use(remarkRehype, { allowDangerousHtml: true })
    .use(rehypeStringify, { allowDangerousHtml: true })
    .process(await read("example.md"))

  console.log(String(file))
}

Running that with node example.js yields:

<div class="callout callout-assert">
  <div class="callout-indicator">
    <div class="callout-hint">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
        <path d="M12.5 7.5h.01m-.01 4v4m-7.926.685L2 21l6.136-1.949c1.307.606 2.791.949 4.364.949 5.243 0 9.5-3.809 9.5-8.5S17.743 3 12.5 3 3 6.809 3 11.5c0 1.731.579 3.341 1.574 4.685"/>
      </svg>
    </div>
    <div class="callout-title">Info</div>
  </div>
  <div class="callout-content">
    <p>Some <strong>content</strong> with <em>Markdown</em> <code>syntax</code>.</p>
  </div>
</div>

Example: configure element type globally

You can override the element type of all callouts by providing a tagName.

Say we have the following file example.md:

:::assert
Some **content** with _Markdown_ `syntax`.
:::

And our module example.js looks as follows:

import { read } from "to-vfile"
import { unified } from "unified"
import remarkParse from "remark-parse"
import remarkDirective from "remark-directive"
import remarkCalloutDirectives from "@microflash/remark-callout-directives"
import remarkRehype from "remark-rehype"
import rehypeStringify from "rehype-stringify"

main()

async function main() {
  const file = await unified()
    .use(remarkParse)
    .use(remarkDirective)
    .use(remarkCalloutDirectives, {
      tagName: "section"
    })
    .use(remarkRehype, { allowDangerousHtml: true })
    .use(rehypeStringify, { allowDangerousHtml: true })
    .process(await read("example.md"))

  console.log(String(file))
}

Running that with node example.js yields:

<section class="callout callout-assert">
  <div class="callout-indicator">
    <div class="callout-hint">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
        <path d="M12.5 7.5h.01m-.01 4v4m-7.926.685L2 21l6.136-1.949c1.307.606 2.791.949 4.364.949 5.243 0 9.5-3.809 9.5-8.5S17.743 3 12.5 3 3 6.809 3 11.5c0 1.731.579 3.341 1.574 4.685"/>
      </svg>
    </div>
    <div class="callout-title">Info</div>
  </div>
  <div class="callout-content">
    <p>Some <strong>content</strong> with <em>Markdown</em> <code>syntax</code>.</p>
  </div>
</section>

Example: configure element type globally as well as specifically for a callout

You can mix the tagName configurations globally and specifically for a callout.

Say we have the following file example.md:

:::assert
Some **content** with _Markdown_ `syntax`.
:::

:::note
Some **content** with _Markdown_ `syntax`.
:::

And our module example.js looks as follows:

import { read } from "to-vfile"
import { unified } from "unified"
import remarkParse from "remark-parse"
import remarkDirective from "remark-directive"
import remarkCalloutDirectives from "@microflash/remark-callout-directives"
import remarkRehype from "remark-rehype"
import rehypeStringify from "rehype-stringify"

main()

async function main() {
  const file = await unified()
    .use(remarkParse)
    .use(remarkDirective)
    .use(remarkCalloutDirectives, {
      tagName: "section",
      callouts: {
        assert: {
          tagName: "div"
        }
      }
    })
    .use(remarkRehype, { allowDangerousHtml: true })
    .use(rehypeStringify, { allowDangerousHtml: true })
    .process(await read("example.md"))

  console.log(String(file))
}

Running that with node example.js yields:

<div class="callout callout-assert">
  <div class="callout-indicator">
    <div class="callout-hint">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
        <path d="M12.5 7.5h.01m-.01 4v4m-7.926.685L2 21l6.136-1.949c1.307.606 2.791.949 4.364.949 5.243 0 9.5-3.809 9.5-8.5S17.743 3 12.5 3 3 6.809 3 11.5c0 1.731.579 3.341 1.574 4.685"/>
      </svg>
    </div>
    <div class="callout-title">Info</div>
  </div>
  <div class="callout-content">
    <p>Some <strong>content</strong> with <em>Markdown</em> <code>syntax</code>.</p>
  </div>
</div>

<section class="callout callout-note">
  <div class="callout-indicator">
    <div class="callout-hint">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
        <path d="M12 8h.01M12 12v4"/>
        <circle cx="12" cy="12" r="10"/>
      </svg>
    </div>
    <div class="callout-title">Note</div>
  </div>
  <div class="callout-content">
    <p>Some <strong>content</strong> with <em>Markdown</em> <code>syntax</code>.
    </p>
  </div>
</section>

Example: override the defaults

You can override the defaults by passing your own preferences; they will be merged on top of the default values.

Say we have the following file example.md:

:::commend
Some **content** with _Markdown_ `syntax`.
:::

And our module example.js looks as follows:

import { read } from "to-vfile"
import { unified } from "unified"
import remarkParse from "remark-parse"
import remarkDirective from "remark-directive"
import remarkCalloutDirectives from "@microflash/remark-callout-directives"
import remarkRehype from "remark-rehype"
import rehypeStringify from "rehype-stringify"

main()

async function main() {
  const file = await unified()
    .use(remarkParse)
    .use(remarkDirective)
    .use(remarkCalloutDirectives, {
      callouts: {
        commend: {
          title: "Tip",
          hint: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="M22 4 12 14.01l-3-3"/></svg>`
        }
      }
    })
    .use(remarkRehype, { allowDangerousHtml: true })
    .use(rehypeStringify, { allowDangerousHtml: true })
    .process(await read("example.md"))

  console.log(String(file))
}

Running that with node example.js yields:

<aside class="callout callout-commend">
  <div class="callout-indicator">
    <div class="callout-hint">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
        <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
        <path d="M22 4 12 14.01l-3-3"/>
      </svg>
    </div>
    <div class="callout-title">Tip</div>
  </div>
  <div class="callout-content">
    <p>Some <strong>content</strong> with <em>Markdown</em> <code>syntax</code>.</p>
  </div>
</aside>

Example: remove the indicator

You can remove the indicator using the showIndicator="false" property on a callout.

Say we have the following file example.md:

::note{showIndicator="false"}
Some **content** with _Markdown_ `syntax`.
:::

And our module example.js looks as follows:

import { read } from "to-vfile"
import { unified } from "unified"
import remarkParse from "remark-parse"
import remarkDirective from "remark-directive"
import remarkCalloutDirectives from "@microflash/remark-callout-directives"
import remarkRehype from "remark-rehype"
import rehypeStringify from "rehype-stringify"

main()

async function main() {
  const file = await unified()
    .use(remarkParse)
    .use(remarkDirective)
    .use(remarkCalloutDirectives)
    .use(remarkRehype, { allowDangerousHtml: true })
    .use(rehypeStringify, { allowDangerousHtml: true })
    .process(await read("example.md"))

  console.log(String(file))
}

Running that with node example.js yields:

<aside class="callout callout-note">
  <div class="callout-content">
    <p>Some <strong>content</strong> with <em>Markdown</em> <code>syntax</code>.</p>
  </div>
</aside>

Example: using a theme

Say, you want to use the GitHub theme.

First, import the options for this theme and pass it to the plugin as follows.

import { read } from "to-vfile"
import { unified } from "unified"
import remarkParse from "remark-parse"
import remarkDirective from "remark-directive"
import remarkCalloutDirectives from "@microflash/remark-callout-directives"
import githubCalloutOptions from "@microflash/remark-callout-directives/config/github"
import remarkRehype from "remark-rehype"
import rehypeStringify from "rehype-stringify"

main()

async function main() {
  const file = await unified()
    .use(remarkParse)
    .use(remarkDirective)
    .use(remarkCalloutDirectives, githubCalloutOptions)
    .use(remarkRehype, { allowDangerousHtml: true })
    .use(rehypeStringify, { allowDangerousHtml: true })
    .process(await read("example.md"))

  console.log(String(file))
}

Finally, import the CSS file. If you've an entrypoint file in your application, you can import the CSS as follows.

import "@microflash/remark-callout-directives/theme/github"
// or using URL import
import "https://unpkg.com/@microflash/remark-callout-directives/themes/github/index.css"

If you're bundling the CSS files using a bundler, you can import the CSS in your main CSS file containing other imports.

/* other imports... */
@import "@microflash/remark-callout-directives/theme/github";

If you're using Sass, you can import the CSS in your main Sass file.

// other Sass imports
@use "@microflash/remark-callout-directives/theme/github";

You can also import the CSS file directly in browsers, with unpkg.com or jsdelivr.net:

<link rel="stylesheet" href="https://unpkg.com/@microflash/remark-callout-directives/themes/github/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@microflash/remark-callout-directives/themes/github/index.css">

License

MIT