Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@digitalocean/do-markdownit

digitalocean2.8kApache-2.01.16.1TypeScript support: included

Markdown-It plugin for the DigitalOcean Community.

markdown, markdown-it, markdown-it-plugin, digitalocean, highlight, caption, figure, columns, details, collapse, spoiler, asciinema, codepen, glitch, caniuse, youtube, underline, heading, anchor, prism

readme

do-markdownit

Markdown-It plugin for the DigitalOcean Community.

This plugin is what we use across the DigitalOcean Community site to extend the standard functionality of Markdown with additional features, such as automatic code syntax highlighting, video embeds, and more.

You can see this plugin in action and try it out on our Markdown sandbox page.

Getting Started

Install Markdown-It and the plugin:

npm install markdown-it @digitalocean/do-markdownit

Instantiate Markdown-It and the plugin, and render some Markdown:

const md = require('markdown-it')({}).use(require('@digitalocean/do-markdownit'), {});

md.render('# Hello, world!\n\n<$>[info]do-markdownit is loaded!<$>');

Plugin Features & Options

do-markdownit is composed of a set of individual plugins, with the ability to disable each if needed, and many having specific options that can be set. All plugins are enabled by default, except limit_tokens.

highlight

<summary>Add support for highlight markup across all Markdown, including inside code.</summary>

The syntax for highlighting text is <^>. E.g. <^>hello world<^>. This syntax is treated as regular inline syntax, similar to bold or italics. However, when used within code the opening and closing tags must be on the same line.

Example Markdown input:

<^>test<^>

```
hello
world
<^>test<^>
```

Example HTML output:

<p><mark>test</mark></p>

<pre><code>hello
world
<mark>test</mark>
</code></pre>

Options:

Pass options for this plugin as the highlight property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

user_mention

<summary>Add support for mentioning users, using an `@` symbol. Wraps the mention in a link to the user.</summary>

By default, any characters that are not a space or newline after an @ symbol will be treated as a mention.

Example Markdown input:

Hello @test

Example HTML output:

<p>Hello <a href="/users/test">@test</a></p>

Options:

Pass options for this plugin as the user_mention property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • pattern (RexExp, optional): A pattern to match user mentions, applied to the string after the @ symbol.
  • path (function(string): string, optional): A function to get the URL path for a user mention.

html_comment

<summary>Removes all HTML comments from Markdown.</summary>

This treats HTML comments as Markdown syntax, so expects them to either be inline, or a full block. Comments that start inline and then span a block will not be removed.

By default, removal is loose, meaning that it does not need to explicitly find the end of a comment to remove it. If no closing mark is found, the end of the line or block is assumed. This behaviour can be disabled with the strict setting, which will require finding the end of the comment.

Example Markdown input:

Hello <!-- comment --> world

Example HTML output:

<p>Hello  world</p>

Options:

Pass options for this plugin as the html_comment property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • strict (boolean, optional, defaults to false): If the end of a comment must be explicitly found.

image_caption

<summary>Wrap singleton images that have title text in a figure with a rendered caption.</summary>

Example Markdown input:

![alt text](test.png "title text")

![alt text](test.png "title text _with Markdown_")

Example HTML output:

<figure><img src="test.png" alt="alt text"><figcaption>title text</figcaption></figure>

<figure><img src="test.png" alt="alt text"><figcaption>title text <em>with Markdown</em></figcaption></figure>

Options:

Pass options for this plugin as the image_caption property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

table_wrapper

<summary>Add wrapper element around Markdown `tables` for better controlled overflow.</summary>

No new syntax added. This just wraps normal Markdown | a | tables with a div that has a default class of table-wrapper.

Example Markdown input:

| a |
|---|

Example HTML output:

<div class="table-wrapper">
    <table>
        <thead>
            <tr>
                <th>a</th>
            </tr>
        </thead>
    </table>
</div>

Options:

Pass options for this plugin as the table_wrapper property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • className (string, optional, defaults to 'table-wrapper'): Class to use for the table wrapper.

collapsible_heading

<summary>Wrap specific headings in detail tag and make the content collapsible</summary>

If an array of heading tags is provided, all those tags and the related content will be wrapped in a details tag, with the heading as the summary.

Nesting multiple collapsible sections is supported.

Example Markdown input:

# H1 header
Test row

Example HTML output:

<details class="collapsible">
    <summary>
        <h1>H1 header</h1>
    </summary>
    <p>Test row</p>
</details>

Options:

Pass options for this plugin as the collapsible_heading property of the do-markdownit plugin options. This plugin is disabled by default, pass an object to enable it.

  • levels (number[], optional, defaults to [ 1, 2, 3, 4, 5, 6 ]): List of heading tags to wrap (ex: 2).
  • open (boolean, optional, defaults to true): Flag indicating if the wrapped sections should be expanded by default.
  • className (string, optional, defaults to 'collapsible'): Class name to use on the collapsed section.

callout

<summary>Add support for callout embeds in Markdown, as block syntax.</summary>

The basic syntax is <$>[<class>]<text><$>. E.g. <$>[hello]world<$>. The class must be in square brackets, and must come immediately after the opening <$>. Newlines are allowed in the text, as is any other Markdown syntax (both block and inline).

Callouts can also have a label set within them. The label should be in the format [label <text>]. The label must be on the first newline after the opening <$>. The label cannot contain any newlines, but does support inline Markdown syntax.

Example Markdown input:

<$>[info]
test
<$>

<$>[info]
[label hello]
world
<$>

Example HTML output:

<div class="callout info">
<p>test</p>
</div>

<div class="callout info">
<p class="callout-label">hello</p>
<p>world</p>
</div>

Options:

Pass options for this plugin as the callout property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • allowedClasses (string[], optional): List of case-sensitive classes that are allowed. If not an array, all classes are allowed.
  • extraClasses (string[], optional, defaults to ['callout']): List of extra classes to apply to a callout div, alongside the given class.
  • labelClass (string, optional, defaults to 'callout-label'): Class to use for the label.

rsvp_button

<summary>Add support for RSVP buttons in Markdown, as inline syntax.</summary>

The basic syntax is [rsvp_button <marketo id>]. E.g. [rsvp_button 12345]. Optionally, a title can be set for the button in double quotes after the id. E.g. [rsvp_button 12345 "My Button"]. The button title is limited to 50 characters, and can contain spaces.

The buttons are disabled by default and do not have any event listeners. Once rendered, you should bind your own event listeners and enable the buttons.

You can find all the buttons in the DOM by looking for the data-js attribute being set to rsvp-button. The Marketo form Id will be set as the data-form-id attribute.

Example Markdown input:

[rsvp_button 12345 "button title"]

Example HTML output:

<p><button data-js="rsvp-button" data-form-id="12345" disabled="disabled" class="rsvp">button title</button></p>

Options:

Pass options for this plugin as the rsvp_button property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • className (string, optional, defaults to 'rsvp'): Class to use for the button.

terminal_button

<summary>Add support for terminal buttons in Markdown, as block syntax.</summary>

The basic syntax is [terminal <image name>]. E.g. [terminal ubuntu:focal]. An optional button title can be provided after the image name. E.g. [terminal ubuntu:focal Start Terminal].

The buttons are disabled by default and do not have any event listeners. Once rendered, you should bind your own event listeners and enable the buttons.

You can find all the buttons in the DOM by looking for the data-js attribute being set to terminal. The image name will be set as the data-docker-image attribute.

Example Markdown input:

[terminal ubuntu:focal button title]

Example HTML output:

<button data-js="terminal" data-docker-image="ubuntu:focal" disabled="disabled" class="terminal">
    button title
</button>

Options:

Pass options for this plugin as the terminal_button property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

columns

<summary>Add support for columns in Markdown, as block syntax.</summary>

To declare a column, wrap content with [column on the line before, and ] on a new line at the end. Two or more columns must be adjacent to each other to be parsed as a set of columns.

Example Markdown input:

[column
Content for the first column
]
[column
Content for the second column
]

Example HTML output:

<div class="columns">
<div class="column">
<p>Content for the first column</p>
</div>
<div class="column">
<p>Content for the second column</p>
</div>
</div>

Options:

Pass options for this plugin as the columns property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • outerClassName (string, optional, defaults to 'columns'): Class to use for the outer columns container.
  • innerClassName (string, optional, defaults to 'column'): Class to use for the inner column container.

details

<summary>Add support for expandable details in Markdown, as block syntax.</summary>

To create an expandable details section, use [details followed by a summary. Content for the expanded section should be provided on lines after, closed with ] on a new line.

Example Markdown input:

[details This is hidden content
Content for inside the expanded section
]

[details open This section is *open* by default
Content for inside the expanded section
]

Example HTML output:

<details>
<summary>This is hidden content</summary>
<p>Content for inside the expanded section</p>
</details>

<details open>
<summary>This section is <em>open</em> by default</summary>
<p>Content for inside the expanded section</p>
</details>

Options:

Pass options for this plugin as the details property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

glob

<summary>Add support for glob embeds in Markdown, as block syntax.</summary>

The basic syntax is [glob <pattern> <strings>]. E.g. [glob *.js a.js b.js c.css]. After the pattern, strings can be provided on a single line, or each separated by a newline. If a newline is included, the full first line will be treated as the pattern, including any spaces.

Example Markdown input:

[glob *.js /]

[glob * test.js
/a
/b]

Example HTML output:

<div data-glob-tool-embed data-glob-string="*.js" data-glob-test-0="/">
    <a href="https://www.digitalocean.com/community/tools/glob?glob=*.js&tests=%2F" target="_blank">
        Explore <code>*.js</code> as a glob string in our glob testing tool
    </a>
</div>

<div data-glob-tool-embed data-glob-string="* test.js" data-glob-test-0="/a" data-glob-test-1="/b">
    <a href="https://www.digitalocean.com/community/tools/glob?glob=*+test.js&tests=%2Fa&tests=%2Fb" target="_blank">
        Explore <code>* test.js</code> as a glob string in our glob testing tool
    </a>
</div>
<script async defer src="https://do-community.github.io/glob-tool-embed/bundle.js" type="text/javascript" onload="window.GlobToolEmbeds()"></script>

Options:

Pass options for this plugin as the glob property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

dns

<summary>Add support for DNS lookup embeds in Markdown, as block syntax.</summary>

The basic syntax is [dns <domain>]. E.g. [dns digitalocean.com]. After the domain, one or more space-separated DNS record types can be added. The default type is A.

Example Markdown input:

[dns digitalocean.com]

[dns digitalocean.com A AAAA]

Example HTML output:

<div data-dns-tool-embed data-dns-domain="digitalocean.com" data-dns-types="A">
    <a href="https://www.digitalocean.com/community/tools/dns?domain=digitalocean.com" target="_blank">
        Perform a full DNS lookup for digitalocean.com
    </a>
</div>

<div data-dns-tool-embed data-dns-domain="digitalocean.com" data-dns-types="A,AAAA">
    <a href="https://www.digitalocean.com/community/tools/dns?domain=digitalocean.com" target="_blank">
        Perform a full DNS lookup for digitalocean.com
    </a>
</div>
<script async defer src="https://do-community.github.io/dns-tool-embed/bundle.js" type="text/javascript" onload="window.DNSToolEmbeds()"></script>

Options:

Pass options for this plugin as the dns property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

asciinema

<summary>Add support for Asciinema embeds in Markdown, as block syntax.</summary>

The basic syntax is [asciinema <id>]. E.g. [asciinema 325730]. The cols and rows can optionally be set using [asciinema <id> [cols] [rows]]. E.g. [asciinema 325730 100 50]. The default value for cols is 80, and for rows is 24.

Example Markdown input:

[asciinema 325730]

Example HTML output:

<script src="https://asciinema.org/a/325730.js" id="asciicast-325730" async data-cols="80" data-rows="24"></script>
<noscript>
    <a href="https://asciinema.org/a/325730" target="_blank">View asciinema recording</a>
</noscript>

Options:

Pass options for this plugin as the asciinema property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

codepen

<summary>Add support for CodePen embeds in Markdown, as block syntax.</summary>

The basic syntax is [codepen <user> <hash>]. E.g. [codepen AlbertFeynman gjpgjN]. After the user and hash, assorted space-separated flags can be added (in any combination/order):

  • Add lazy to set the CodePen embed to not run until the user interacts with it.
  • Add light or dark to set the CodePen embed theme (default is light).
  • Add html, css, or js to set the default tab for the CodePen embed.
  • Add result to set the CodePen embed to default to the Result tab (default, can be combined with other tabs).
  • Add editable to set the CodePen embed to allow the code to be edited (requires the embedded user to be Pro).
  • Add any set of digits to set the height of the embed (in pixels).

If two or more tabs are selected (excluding result), html will be preferred, followed by css, then js. If the result tab is selected, it can be combined with any other tab to generate a split view.

If both light and dark are selected, dark will be preferred.

Example Markdown input:

[codepen AlbertFeynman gjpgjN]

[codepen AlbertFeynman gjpgjN lazy dark 512 html]

Example HTML output:

<p class="codepen" data-height="256" data-theme-id="light" data-default-tab="result" data-user="AlbertFeynman" data-slug-hash="gjpgjN" style="height: 256px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
    <span>See the Pen <a href="https://codepen.io/AlbertFeynman/pen/gjpgjN">gjpgjN by AlbertFeynman</a> (<a href="https://codepen.io/AlbertFeynman">@AlbertFeynman</a>) on <a href='https://codepen.io'>CodePen</a>.</span>
</p>

<p class="codepen" data-height="512" data-theme-id="dark" data-default-tab="html" data-user="AlbertFeynman" data-slug-hash="gjpgjN" data-preview="true" style="height: 512px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
    <span>See the Pen <a href="https://codepen.io/AlbertFeynman/pen/gjpgjN">gjpgjN by AlbertFeynman</a> (<a href="https://codepen.io/AlbertFeynman">@AlbertFeynman</a>) on <a href='https://codepen.io'>CodePen</a>.</span>
</p>
<script async defer src="https://static.codepen.io/assets/embed/ei.js" type="text/javascript"></script>

Options:

Pass options for this plugin as the codepen property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

glitch

<summary>Add support for Glitch embeds in Markdown, as block syntax.</summary>

The basic syntax is [glitch <slug>]. E.g. [glitch hello-digitalocean]. After the slug, some space-separated flags can be added (in any combination/order):

  • Add noattr to tell Glitch to not show the authors of the project.
  • Add code to set the Glitch embed to show the project code by default.
  • Add notree to set the Glitch embed to collapse the file tree by default.
  • Add path= followed by a file path to set the Glitch embed to show a specific file by default.
  • Add highlights= followed by a comma-separated list of line numbers to tell Glitch to highlight those lines.
  • Add any set of digits to set the height of the embed (in pixels).

Example Markdown input:

[glitch hello-digitalocean]

[glitch hello-digitalocean code 512 notree path=src/app.jsx]

Example HTML output:

<div class="glitch-embed-wrap" style="height: 256px; width: 100%;">
    <iframe src="https://glitch.com/embed/#!/embed/hello-digitalocean?previewSize=100" title="hello-digitalocean on Glitch" allow="geolocation; microphone; camera; midi; encrypted-media; xr-spatial-tracking; fullscreen" allowFullScreen style="height: 100%; width: 100%; border: 0;">
        <a href="https://glitch.com/edit/#!/hello-digitalocean" target="_blank">View hello-digitalocean on Glitch</a>
    </iframe>
</div>

<div class="glitch-embed-wrap" style="height: 512px; width: 100%;">
    <iframe src="https://glitch.com/embed/#!/embed/hello-digitalocean?previewSize=0&sidebarCollapsed=true&path=src%2Fapp.jsx" title="hello-digitalocean on Glitch" allow="geolocation; microphone; camera; midi; encrypted-media; xr-spatial-tracking; fullscreen" allowFullScreen style="height: 100%; width: 100%; border: 0;">
        <a href="https://glitch.com/edit/#!/hello-digitalocean" target="_blank">View hello-digitalocean on Glitch</a>
    </iframe>
</div>

Options:

Pass options for this plugin as the glitch property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

caniuse

<summary>Add support for CanIUse embeds in Markdown, as block syntax.</summary>

Uses https://caniuse.bitsofco.de/ to provide interactive embeds from CanIUse data.

The basic syntax is [caniuse <feature>]. E.g. [caniuse css-grid]. After the slug, some space-separated flags can be added (in any combination/order):

  • Add past= followed by a number to control how many previous browser versions to include (default is 1, supported 0-5).
  • Add future= followed by a number to control how many previous browser versions to include (default is 1, supported 0-3).
  • Add accessible to set the default color scheme for the CanIUse embed to be accessible colors.

Example Markdown input:

[caniuse css-grid]

[caniuse css-grid past=5 future=3 accessible]

Example HTML output:

<p class="ciu_embed" data-feature="css-grid" data-periods="future_1,current,past_1" data-accessible-colours="false">
    <picture>
        <source type="image/webp" srcset="https://caniuse.bitsofco.de/image/css-grid.webp" />
        <source type="image/png" srcset="https://caniuse.bitsofco.de/image/css-grid.png" />
        <img src="https://caniuse.bitsofco.de/image/css-grid.jpg" alt="Data on support for the css-grid feature across the major browsers from caniuse.com" />
    </picture>
</p>

<p class="ciu_embed" data-periods="future_3,future_2,future_1,current,past_1,past_2,past_3,past_4,past_5" data-accessible-colours="true">
    <picture>
        <source type="image/webp" srcset="https://caniuse.bitsofco.de/image/ambient-light.webp" />
        <source type="image/png" srcset="https://caniuse.bitsofco.de/image/ambient-light.png" />
        <img src="https://caniuse.bitsofco.de/image/ambient-light.jpg" alt="Data on support for the ambient-light feature across the major browsers from caniuse.com" />
    </picture>
</p>
<script async defer src="https://cdn.jsdelivr.net/gh/ireade/caniuse-embed@v1.3.0/public/caniuse-embed.min.js" type="text/javascript"></script>

Options:

Pass options for this plugin as the caniuse property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

youtube

<summary>Add support for YouTube embeds in Markdown, as block syntax.</summary>

The basic syntax is [youtube <id>]. E.g. [youtube iom_nhYQIYk]. Height and width can optionally be set using [youtube <id> [height] [width]]. E.g. [youtube iom_nhYQIYk 380 560]. The default value for height is 270, and for width is 480.

Example Markdown input:

[youtube iom_nhYQIYk]

Example HTML output:

<iframe src="https://www.youtube.com/embed/iom_nhYQIYk" class="youtube" height="270" width="480" style="aspect-ratio: 16/9" frameborder="0" allowfullscreen>
    <a href="https://www.youtube.com/watch?v=iom_nhYQIYk" target="_blank">View YouTube video</a>
</iframe>

Options:

Pass options for this plugin as the youtube property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

wistia

<summary>Add support for Wistia embeds in Markdown, as block syntax.</summary>

The basic syntax is [wistia <id>]. E.g. [wistia 7ld71zbvi6]. Height and width can optionally be set using [wistia <id> [height] [width]]. E.g. [wistia 7ld71zbvi6 380 560]. The default value for height is 270, and for width is 480.

Example Markdown input:

[wistia 7ld71zbvi6]

Example HTML output:

<iframe src="http://fast.wistia.net/embed/iframe/7ld71zbvi6" class="wistia" height="270" width="480" style="aspect-ratio: 16/9" frameborder="0" allowfullscreen>
    <a href="http://fast.wistia.net/embed/iframe/7ld71zbvi6" target="_blank">View Wistia video</a>
</iframe>

Options:

Pass options for this plugin as the wistia property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

vimeo

<summary>Add support for Vimeo embeds in Markdown, as block syntax.</summary>

The basic syntax is [vimeo <url>]. E.g. [vimeo https://player.vimeo.com/video/329272793]. Height and width can optionally be set using [vimeo <url> [height] [width]]. E.g. [vimeo https://player.vimeo.com/video/329272793 380 560]. The default value for height is 270, and for width is 480.

Example Markdown input:

[vimeo https://player.vimeo.com/video/329272793]

Example HTML output:

<iframe src="https://player.vimeo.com/video/329272793" class="vimeo" height="270" width="480" style="aspect-ratio: 16/9" frameborder="0" allowfullscreen>
    <a href="https://player.vimeo.com/video/329272793" target="_blank">View vimeo video</a>
</iframe>

Options:

Pass options for this plugin as the vimeo property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

twitter

<summary>Add support for Twitter embeds in Markdown, as block syntax.</summary>

The basic syntax is [twitter <tweet>]. E.g. [twitter https://twitter.com/MattIPv4/status/1576415168426573825]. After the tweet, assorted space-separated flags can be added (in any combination/order):

  • Add light or dark to set the card theme (default is light).
  • Add left, center, or right to set the alignment of the embed (default is left).
  • Add any set of digits to set the width of the embed (in pixels, between 250 and 550, default is 550).

If two or more alignments are selected, left will be preferred, followed by center, then right.

If both light and dark are selected, dark will be preferred.

If a width outside the range of 250-550 is selected, a clamped value will be used.

Example Markdown input:

[twitter https://twitter.com/MattIPv4/status/1576415168426573825]

[twitter https://twitter.com/MattIPv4/status/1576415168426573825 left 400 dark]

Example HTML output:

<div class="twitter">
    <blockquote class="twitter-tweet" data-dnt="true" data-width="550" data-theme="light">
        <a href="https://twitter.com/MattIPv4/status/1576415168426573825">View tweet by @MattIPv4</a>
    </blockquote>
</div>

<div class="twitter" align="left">
    <blockquote class="twitter-tweet" data-dnt="true" data-width="400" data-theme="dark">
        <a href="https://twitter.com/MattIPv4/status/1576415168426573825">View tweet by @MattIPv4</a>
    </blockquote>
</div>
<script async defer src="https://platform.twitter.com/widgets.js" type="text/javascript"></script>

Options:

Pass options for this plugin as the twitter property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

instagram

<summary>Add support for Instagram embeds in Markdown, as block syntax.</summary>

The basic syntax is [instagram <post>]. E.g. [instagram https://www.instagram.com/p/CkQuv3_LRgS]. After the post, assorted space-separated flags can be added (in any combination/order):

  • Add caption to include caption under the post.
  • Add left, center, or right to set the alignment of the embed (default is left).
  • Add any set of digits to set the width of the embed (in pixels, between 326 and 550, default is 326 as set by Instagram's embed.js).

If two or more alignments are selected, left will be preferred, followed by center, then right.

If a width outside the range of 326-550 is selected, a clamped value will be used.

Example Markdown input:

[instagram https://www.instagram.com/p/CkQuv3_LRgS]

[instagram https://www.instagram.com/p/CkQuv3_LRgS left caption 400]

Example HTML output:

<div class="instagram">
    <blockquote class="instagram-media"
        data-instgrm-permalink="https://www.instagram.com/p/CkQuv3_LRgS"
        data-instgrm-version="14">
            <a href="https://instagram.com/p/CkQuv3_LRgS">View post</a>
    </blockquote>
</div>

<div class="instagram" align="left">
    <blockquote class="instagram-media"
        style="width: 400px;"
        data-instgrm-permalink="https://www.instagram.com/p/CkQuv3_LRgS"
        data-instgrm-version="14"
        data-instgrm-captioned>
            <a href="https://instagram.com/p/CkQuv3_LRgS">View post</a>
    </blockquote>
</div>
<script async defer src="https://www.instagram.com/embed.js" type="text/javascript" onload="window.instgrm && window.instgrm.Embeds.process()"></script>

Options:

Pass options for this plugin as the instagram property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

slideshow

<summary>Add support for Slideshow in Markdown, as block syntax.</summary>

The basic syntax is [slideshow <url1> <url2> <...urls>]. E.g., [slideshow https://assets.digitalocean.com/banners/python.png https://assets.digitalocean.com/banners/javascript.png https://assets.digitalocean.com/banners/nodejs.png]. Height and width can optionally be set using [slideshow <url1> <url2> <...urls> [height] [width]]. E.g., [slideshow https://assets.digitalocean.com/banners/python.png https://assets.digitalocean.com/banners/javascript.png https://assets.digitalocean.com/banners/nodejs.png 380 560]. The default value for height is 270 and for width is 480.

Example Markdown input:

[slideshow https://assets.digitalocean.com/banners/python.png https://assets.digitalocean.com/banners/javascript.png https://assets.digitalocean.com/banners/nodejs.png]

Example HTML output:

<div class="slideshow" style="height: 270px; width: 480px;">
    <div class="action left" onclick="(() => this.parentNode.getElementsByClassName('slides')[0].scrollLeft -= 480)()">&#8249;</div>
    <div class="action right" onclick="(() => this.parentNode.getElementsByClassName('slides')[0].scrollLeft += 480)()">&#8250;</div>
    <div class="slides"><img src="https://assets.digitalocean.com/banners/python.png" alt="Slide #1" /><img src="https://assets.digitalocean.com/banners/javascript.png" alt="Slide #2" /><img src="https://assets.digitalocean.com/banners/nodejs.png" alt="Slide #3" /></div>
</div>

Options:

Pass options for this plugin as the slideshow property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

compare

<summary>Add support for Image Comparison in Markdown, as block syntax.</summary>

The basic syntax is [compare <url1> <url2>]. E.g., [compare https://assets.digitalocean.com/banners/python.png https://assets.digitalocean.com/banners/javascript.png]. Height and width can optionally be set using [compare <url1> <url2> [height] [width]]. E.g., [compare https://assets.digitalocean.com/banners/python.png https://assets.digitalocean.com/banners/javascript.png 500 560]. The default value for height is 270 and for width is 480.

Example Markdown input:

[compare https://assets.digitalocean.com/banners/python.png https://assets.digitalocean.com/banners/javascript.png]

Example HTML output:

<div class="image-compare" style="--value:50%; height: 270px; width: 480px;">
    <img class="image-left" src="https://assets.digitalocean.com/banners/python.png" alt="Image left"/>
    <img class="image-right" src="https://assets.digitalocean.com/banners/javascript.png" alt="Image right"/>
    <input type="range" class="control" min="0" max="100" value="50" oninput="this.parentNode.style.setProperty('--value', `${this.value}%`)" />
    <svg class="control-arrow" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M504.3 273.6c4.9-4.5 7.7-10.9 7.7-17.6s-2.8-13-7.7-17.6l-112-104c-7-6.5-17.2-8.2-25.9-4.4s-14.4 12.5-14.4 22l0 56-192 0 0-56c0-9.5-5.7-18.2-14.4-22s-18.9-2.1-25.9 4.4l-112 104C2.8 243 0 249.3 0 256s2.8 13 7.7 17.6l112 104c7 6.5 17.2 8.2 25.9 4.4s14.4-12.5 14.4-22l0-56 192 0 0 56c0 9.5 5.7 18.2 14.4 22s18.9 2.1 25.9-4.4l112-104z"/></svg>
</div>

Options:

Pass options for this plugin as the compare property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

underline

<summary>Add support for underline markup across all Markdown.</summary>

The syntax for underline text is __. E.g. __hello world__. This replaces the default behaviour for the syntax, which would be bold. This syntax is treated as regular inline syntax, similar to bold or italics.

Example Markdown input:

__test__

Example HTML output:

<p><u>test</u></p>

Options:

Pass options for this plugin as the underline property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

fence_label

<summary>Add support for label markup at the start of a fence, translating to a label div before the fence if there is a toolbar rendered or a label defined..</summary>

Markup must be at the start of the fence, though may be preceded by other metadata markup using square brackets.

Example Markdown input:

```
[label test]
hello
world
```

Example HTML output:

<div class="code-label" title="test">test</div>
<pre><code>hello
world
</code></pre>

Options:

Pass options for this plugin as the fence_label property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • className (string, optional, defaults to 'code-label'): Class name to use on the label div.

fence_secondary_label

<summary>Add support for secondary label markup at the start of a fence, translating to a label div inside the fence.</summary>

Markup must be at the start of the fence, though may be preceded by other metadata markup using square brackets.

Example Markdown input:

```
[secondary_label test]
hello
world
```

Example HTML output:

<pre><code><div class="secondary-code-label" title="test">test</div>hello
world
</code></pre>

Options:

Pass options for this plugin as the fence_secondary_label property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • className (string, optional, defaults to 'secondary-code-label'): Class name to use on the label div.

fence_environment

<summary>Add support for environment markup at the start of a fence, translating to a class.</summary>

Markup must be at the start of the fence, though may be preceded by other metadata markup using square brackets.

Example Markdown input:

```
[environment test]
hello
world
```

Example HTML output:

<pre><code class="environment-test">hello
world
</code></pre>

Options:

Pass options for this plugin as the fence_environment property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • allowedEnvironments (string[], optional): List of case-sensitive environments that are allowed. If not an array, all environments are allowed.
  • extraClasses (string, optional, defaults to ''): String of extra classes to set when an environment is used.

fence_prefix

<summary>Add support for a prefix to be set for each line on a fenced code block.</summary>

The prefix is set as part of the 'info' provided immediately after the opening fence.

The custom prefix can be set by:

  • Adding the 'line_numbers' flag to the info. This will set each line's prefix to be incrementing line numbers.

  • Adding the 'command' flag to the info. This will set each line's prefix to be a '$' character. This will also add the 'bash' flag to the info, which can be used for language highlighting.

  • Adding the 'super_user' flag to the info. This will set each line's prefix to be a '#' character. This will also add the 'bash' flag to the info, which can be used for language highlighting.

  • Adding the 'custom_prefix(<prefix>)' flag to the info. <prefix> can be any string that does not contain spaces. Use \s to represent spaces. This will also add the 'bash' flag to the info, which can be used for language highlighting.

Example Markdown input:

```custom_prefix(test)
hello
world
```

Example HTML output:

<pre><code class="prefixed custom_prefix language-bash"><ol><li data-prefix="test">hello
</li><li data-prefix="test">world
</li></ol>
</code></pre>

Options:

Pass options for this plugin as the fence_prefix property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • delimiter (string, optional, defaults to ','): String to split fence information on.

fence_pre_attrs

<summary>Move all attributes from the opening `code` tag of a fenced code block to the `pre` tag.</summary>

Example Markdown input:

```js
hello
world
```

Example HTML output:

<pre class="language-js"><code>hello
world
</code></pre>

Options:

Pass options for this plugin as the fence_pre_attrs property of the do-markdownit plugin options. Set this property to false to disable this plugin.

No options are available for this plugin.

fence_classes

<summary>Filters classes on code and pre tags in fences.</summary>

Example Markdown input:

```test
hello
world
```

```bad
hello
world
```

Example HTML output:

<pre><code class="language-test">hello
world
</code></pre>

<pre><code class="">hello
world
</code></pre>

Options:

Pass options for this plugin as the fence_classes property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • allowedClasses (string[], optional): List of case-sensitive classes that are allowed. If not an array, all classes are allowed.

heading_id

<summary>Apply Ids to all rendered headings and generate an array of headings.</summary>

Headings are available after a render via md.headings. Each item in the array is an object with the following properties:

  • slug: The slug Id given to the heading (e.g. my-heading).
  • content: The raw Markdown content of the heading (e.g. My **Heading**).
  • text: The plain-text content of the heading (e.g. My Heading).
  • rendered: The rendered HTML content of the heading (e.g. My <strong>Heading</strong>).
  • level: The heading level (e.g. 1).

Example Markdown input:

# Hello World!

Example HTML output:

<h1 id="hello-world"><a class="hash-anchor" href="#hello-world" aria-hidden="true"></a>Hello World!</h1>

Options:

Pass options for this plugin as the heading_id property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • sluggify (function(string): string, optional): Custom function to convert heading content to a slug Id.
  • hashLink Set this property to false to disable this feature.
    • maxLevel (number, optional, defaults to 3): Max heading level to generate hash links for.
    • class (string, optional, defaults to hash-anchor): Class name to use on the anchor tag.
    • position ('before'|'after', optional, defaults to before): Position of the anchor tag relative to the heading.
    • linkHeading (boolean, optional, defaults to true): Whether to link the heading text to the hash link.
    • clipboard (boolean, optional, defaults to true): Whether to write the hash link to the clipboard on click.

image_settings

<summary>Add support for defining settings on images, such as size and alignment.</summary>

The syntax for this is { width=<width> height=<height> align=<alignment> }, at the end of the image markup. E.g. ![alt](test.png "title"){ width=100 height=200 align=left }. All settings are optional, and the order does not matter.

By default, the width and height can be plain number (100), pixels (100px), or percentage (100%). Other units can be supported by passing an array of unit strings via the sizeUnits option.

Alignment can be left unset, which will center the image, or can be set to either left or right.

Example Markdown input:

![alt](test.png "title"){ width=100 height=200 align=left }

Example HTML output:

<p><img src="test.png" alt="alt" title="title" width="100" height="200" align="left"></p>

Options:

Pass options for this plugin as the image_settings property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • sizeUnits (string[], optional, defaults to ['', 'px', '%']): Image size units to allow.
<summary>Apply custom attributes to all links in the Markdown content.</summary>

If an object is provided, the provided attributes are merged with the existing attributes.

If a function is provided, the existing attributes are passed to it, and the existing attributes are replaced (not merged) with the return value.

Options:

Pass options for this plugin as the link_attributes property of the do-markdownit plugin options. This plugin is disabled by default, pass an object to enable it.

  • attributes (Object<string, string>|function(Object<string, string>): Object<string, string>): Object or function to generate attributes for links.

prismjs

<summary>Apply PrismJS syntax highlighting to fenced code blocks, based on the language set in the fence info.</summary>

This loads a custom PrismJS plugin to ensure that any existing HTML markup inside the code block is preserved. This plugin is similar to the default keep-markup plugin, but works in a non-browser environment.

Example Markdown input:

```nginx
server {
    try_files test =404;
}
```

Example HTML output:

<pre class="language-nginx"><code class="language-nginx"><span class="token directive"><span class="token keyword">server</span></span> <span class="token punctuation">{</span>
    <span class="token directive"><span class="token keyword">try_files</span> test =404</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>

Options:

Pass options for this plugin as the prismjs property of the do-markdownit plugin options. Set this property to false to disable this plugin.

  • delimiter (string, optional, defaults to ','): String to split fence information on.
  • logging (boolean, optional, defaults to false): Whether to log errors to the console.

limit_tokens

<summary>Filters and transforms tokens in the token stream.</summary>

Options:

Pass options for this plugin as the limit_tokens property of the do-markdownit plugin options. This plugin is disabled by default, pass an object to enable it.

  • allowedTokens (string[]): A list of Markdown tokens that should render
  • transformTokens (Object<string, function(Token): Token>): An object where the keys are Markdown tokens that should be transformed. The transformation is done based on the value which is a function that expects a Markdown token as a param and returns the transformed token.

PrismJS

As well as this plugin being for Markdown-It, we also include a modified version of PrismJS as part of the package, wrapped and modified in such a way that it will avoid polluting the global or window scopes with a Prism instance. Instead, each plugin or component for Prism expects to be called with a Prism instance passed to it.

const Prism = require('@digitalocean/do-markdownit/vendor/prismjs');

require('@digitalocean/do-markdownit/vendor/prismjs/plugins/toolbar/prism-toolbar')(Prism);
require('@digitalocean/do-markdownit/vendor/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard')(Prism);

Prism.highlightAll();

Reducing bundle size

PrismJS is a large library that includes a lot of language definitions. By default, we use a dynamic require statement that allows for any language to be loaded for Prism. For bundlers like Webpack, this will result in a very large chunk being generated that contains all the possible languages that could be used -- these will all be in a single chunk as they need to be consumed synchronously in the plugin, so a dynamic async import is not possible.

To reduce the size of the bundle you generate, you may wish to restrict what language definitions are included. You can do this by restricting what files from @digitalocean/do-markdownit/vendor/prismjs/components are included in the bundle -- prism-core.js is the only "required" file, all others are language definitions.

We expose two utilities to help with this. First is the getDependencies method in util/prism_util.js which takes a PrismJS language and will return all the language dependencies that also need to be loaded for it. For Webpack users specifically, we also expose a method in util/prism_webpack.js that takes an array of PrismJS languages to include and returns a Webpack plugin you can include to restrict the paths included in the bundle.

const { getDependencies } = require('@digitalocean/do-markdownit/util/prism_util');

console.log(getDependencies('javascript')); // [ 'clike', 'regex', 'markup' ]
console.log(getDependencies('javascript', false)); // [ 'clike', 'markup' ]
const restrictWebpack = require('@digitalocean/do-markdownit/util/prism_webpack');

module.exports = {
  // ...
  plugins: [
    restrictWebpack([ 'javascript', 'nginx' ]),
  ],
};

Keep HTML plugin

Alongside the modified version of Prism, this package also includes a custom Prism plugin designed to preserve HTML within code that is highlighted by Prism. This is similar to Prism's default Keep Markdown plugin, but has no dependency on being run in a browser context with the DOM available.

When this plugin is enabled, it will handle preserving any HTML that is present within the code when Prism highlights it, including the lower-level Prism.highlight method that takes a string of code. Enabling this plugin will also ensure that the standard Keep Markdown plugin is disabled, so that it does not conflict with this plugin.

const Prism = require('@digitalocean/do-markdownit/vendor/prismjs');

require('@digitalocean/do-markdownit/util/prism_keep_html')(Prism);

Prism.highlight('console.log("<mark>Hello, world!</mark>");', Prism.languages.javascript, 'javascript');

Styles

This package also includes a set of SCSS stylesheets aimed at providing standard styles for our usage of Markdown within the DigitalOcean community, styling the features provided by this package as well as styling for standard Markdown.

These are broken up by component, and can be found in the styles directory. There is also a subdirectory within for DigitalOcean-specific styles (e.g. specific callout classes that we use).

Example usage:

.markdown {
    @import "@digitalocean/do-markdownit/styles";
}

Note that if you're planning to use this in a way that will ultimately pass through Webpack's css-loader to produce CSS modules (such as Next.js SCSS module), you may need to wrap the import in a block using the :global pseudo-selector to ensure the classes inside aren't exported as well:

.markdown {
    :global {
        @import "@digitalocean/do-markdownit/styles";
    }
}

If you're importing this as a context where there will be no parent selector, you will need to set $root-text-styles to false to prevent the default text styling that uses a & { selector from being loaded:

Importing the styles globally is not recommended, as these Markdown styles may collide with other parts of your document.

$root-text-styles: false;
@import "@digitalocean/do-markdownit/styles";

SCSS Variables

Variable Default Usage File
$callouts-class (string) callout The class name used for the callout plugin. _callouts.scss
$callouts-label-class (string) callout-label The class name used for labels in the callout plugin. _callouts.scss
$code-label-class (string) code-label The class name used for the fence_label plugin. _code_label.scss
$code-secondary-label-class (string) secondary-code-label The class name used for the fence_secondary_label plugin. _code_secondary_label.scss
$collapsible-heading-class (string) collapsible The class name used for the collapsible_heading plugin. _collapsible.scss
$columns-inner-class (string) column The inner class name used for the columns plugin. _columns.scss
$columns-outer-class (string) columns The outer class name used for the columns plugin. _columns.scss
$hash-anchor-class (string) hash-anchor The anchor class name used for the heading_id plugin. _heading-id.scss
$rsvp-button-class (string) rsvp The class name used for the rsvp_button plugin. _rsvp_button.scss
$table-wrapper-class (string) table-wrapper The class name used for the table_wrapper plugin. _table_wrapper.scss
$terminal-button-class (string) terminal The class name used for the terminal_button plugin. _terminal_button.scss
$root-text-styles (boolean) true Enable or disable the & { selector for root text styles. _typography.scss

Alongside these variables used for controlling specific styles, there is also the _theme.scss file that contains all the colors used by the package.

Contributing

Development

To get started working with this repository, clone it locally first. Ensure that you have the correct version of Node.js as specified in the .nvmrc file, and then install the dependencies following the lockfile by running npm ci.

You can then start up the demo server by running npm run dev. This runs a barebones instance of Webpack with hot-reload enabled that provides a real-time input that renders to Markdown, using the plugins in this package as well as the SCSS styling.

We have two key directories that contain plugins in this repository -- modifiers and rules.

The modifiers directory contains plugins that modify the output of existing Markdown-It render functions, manipulating the rendered HTML results or wrapping existing parsing and rendering rules in the core library.

The rules directory contains plugins that add net-new syntax rules to the Markdown-It parser, both inline and block. Within this is the embeds subdirectory, which contains plugins that add what we call embed extensions to Markdown, such as embedding a CodePen, YouTube video, etc.

Every plugin that is written should also have tests written for it, ensuring that it functions as expected. As well as isolated tests, example usage of the plugin should be added to fixtures/full-input.md to test the plugin when integrated into the main package (the plugin should be loaded in index.js).

This repo makes use of Jest to run all the tests, and you can run the full suite with npm test.

We also have the styles directory, which contains the SCSS files provided by the package to style all the custom functionality this plugin provides, as well as core Markdown styles.

We also make use of ESLint and Stylelint to enforce a consistent style of code, as well as checking that JSDoc comments are present with valid types and descriptions. You can run the linter for both JS and SCSS with npm run lint, or using npm run lint:js and npm run lint:scss respectively.

Both linters also support auto-fixing some issues, and this can be invoked with npm run lint:fix, or by using npm run lint:fix:js and npm run lint:fix:scss for the relevant files.

Pull Requests & Issues

We welcome contributions to this repository in the form of pull requests or issues -- requesting or adding new features, reporting or fixing bugs in existing plugins, cleaning up code, adding more tests, etc.

However, please keep in mind that ultimately this plugin is built for the DigitalOcean Community, and so we may not be able to accept every new feature that is proposed. We recommend opening an issue first if you're interested in contributing a new feature, so that we can check it would be in scope for the plugin before you put time into the development of it.

When opening a pull request, please make sure to fill out the provided template, making it clear what your pull request is changing and why it is doing that. Include examples of how your changes behave in the pull request, through example Markdown syntax and what the resultant HTML is.

License

This plugin is licensed under the Apache License 2.0.

Copyright 2023 DigitalOcean.

changelog

Changelog

do-markdownit follows Semantic Versioning. Note that any new features to the plugin will be shipped as minor releases, in that they are adding new functionality to the plugin. New features will be enabled by default, and may change how your input Markdown is parsed. Any breaking changes to the options supported by the plugin will be shipped as a breaking change.

Unreleased changes

v1.16.1 - de50141

  • (patch) Dependency updates

v1.16.0 - 1fdedd3

  • (minor) Make Collapsible Heading plugin not enabled by default

v1.15.0 - c5d8617

  • (minor) Add Collapsible Heading plugin

v1.14.0 - 3a842c4

  • (minor) Use shared toolbar for code block label + buttons

v1.13.0 - 6056063

  • (patch) Dependency updates
  • (minor) Add link attributes plugin

v1.12.6 - b59f604

  • (patch) Fix multi-line inline code styling

v1.12.5 - fc90098

  • (patch) Fix inline code styling when in a link

v1.12.4 - 12a3af3

  • (patch) Dependency updates

v1.12.3 - 29b268b

  • (docs) Update PUBLISH + CHANGELOG instructions for new versions
  • (patch) Align code-block line numbers to the right

v1.12.2 - 081867e

  • (patch) Avoid slowdown from URL#searchParams in glob embed

v1.12.1 - 39a3836

  • (patch) Fix ReDoS in glob embed rule regex
  • (patch) Dependency updates
  • (patch) Mark markdown-it as a peer dependency

v1.12.0 - d1542c7

  • (minor) Add border to code block

v1.11.0 - 900599c

  • (minor) New design system colors

v1.10.0 - 578e09b

  • (patch) Dependency updates
  • (minor) Generate TypeScript definitions for package
  • (patch) Dependency updates

v1.9.0 - 5515d0c

  • (minor) Allow logging for Prism to be toggled
  • (patch) Manually track loaded Prism components

v1.8.0 - aaf8532

  • (patch) Dependency updates
  • (patch) Isolate Prism webpack logic in own file
  • (minor) Add util to restrict Prism bundle in Webpack

v1.7.1 - ddeb4ff6

  • (patch) Fix clipboard write in heading_id hash links

v1.7.0 - 4847d9ae

  • (docs) Fix README heading ordering, add missing heading_id opts
  • (minor) Hash link position, heading link + clipboard settings

v1.6.1 - 2a2cda5

  • (patch) Dependency updates
  • (patch) Replace Slimdom with htmlparser2-related packages

v1.6.0 - 03138f3

  • (minor) Add Limit tokens plugin
  • (minor) Add Image Compare embeds
  • (minor) Add Slideshow embeds
  • (minor) Add Instagram embeds
  • (minor) Add Vimeo embeds

v1.5.1 - 2f1f346

  • (patch) Dependency updates

v1.5.0 - c7be411

  • (minor) Add Twitter embeds
  • (minor) Add result tab flag to CodePen embeds
  • (docs) Update CHANGELOG notes, add keywords, ignore Jest config for NPM
  • (minor) Add hash links to heading_id plugin
  • (minor) Add syntax for defining settings on images, such as size and alignment
  • (patch) Dependency updates

v1.4.0 - 1d4c368

  • (patch) Reduce embed count in demo content, list supported flags
  • (minor) Add modifier to enable underline syntax

v1.3.3 - 21ac6ca

  • (patch) Set aspect-ratio on YouTube/Wistia, responsiveness fixes
  • (patch) Remove minified versions of patched Prism files

v1.3.2 - a395a43

  • (patch) Set position relative on root styles for z-index

v1.3.1 - c3b57ee

  • (patch) Fix styling of inline code within a link

v1.3.0 - 5daa1ad

  • (minor) Expose heading levels in heading_id
  • (minor) Add Wistia embeds

v1.2.1 - b4f0f23

  • (patch) Fix block detection with links at start of line

v1.2.0 - e4f2907

  • (minor) Add syntax for expandable details
  • (patch) Dependency updates
  • (minor) Add styling for Markdown tables
  • (minor) Add syntax for columns to customise layout
  • (minor) Render captions for singleton images with titles

v1.1.0 - 3cc7209

  • (minor) Provide SCSS styling for Markdown
  • (patch) Add development setup using Webpack
  • (minor) Add support for embedding CanIUse data
  • (minor) Add support for embedding Glitch projects

v1.0.3 - 93d59c0

  • (patch) Update jsdoc to mark @modules and @privates
  • (patch) Fix issue with HTML preservation inside a multi-line token
  • (patch) Don't inject user mentions inside links

v1.0.2 - 149f660

  • (patch) Dependency updates
  • (patch) Fix heading_id plugin when encountering inline code
  • (patch) Add Actions workflows to repo for linting/testing

v1.0.1 - 599e553

  • (patch) Use require.resolve to locate Prism for patching

v1.0.0 - 94361b5

  • (major) Initial open-source release