@olets/markdown-it-wrapperless-fence-rule

markdown-it plugin for opting out of wrapping fenced code in <pre><code>
null

Tech: TS

Developed primarily in 2024

Links:

markdown-it wraps rendered fenced code in <pre><code>:

md
```js

```

renders as

html
<pre>
  <code>

  </code>
</pre>

That’s not the behavior you want if you’re using a fenced code processor which adds the <pre><code> wrappers for you, or if you don’t want <pre><code> wrappers at all.

As of this writing, I use this plugin on this site as part of my custom codeblock markup. It boils down to

js
import markdownItWrapperlessFenceRule from '@olets/markdown-it-wrapperless-fence-rule';
import Shiki from '@shikijs/markdown-it';

let md = markdownIt();

md.use(
  await Shiki({
    themes: {
      dark: /* … */,
      light: /* … */,
    },
    transformers: [
      {
        postprocess(html, options) {
          return shikiPostprocessTransform(html, options);
        },
      },
    ],
  })
);

function shikiPostprocessTransform(html, options) {
  return // e.g. `<div data-my-wrapper>${html}</div>`
}

/**
 * With this, the final codeblock markup is e.g.
 *   <div data-my-wrapper><pre><code>…</code></pre></div>
 * Without it, the final codeblock markup would be e.g.
 *   <pre><code><div data-my-wrapper><pre><code>…</code></pre></div></code></pre>
 */
md.renderer.rules.fence = markdownItWrapperlessFenceRule;

Here’s an interactive example: https://stackblitz.com/edit/oletsmarkdown-it-wrapperless-fence-rule-shiki-demo?file=main.js