Exclude a language from processing (mermaid use case)
LunaticMuch opened this issue · comments
I am wondering if it's possible to completely exclude a language from parsing.
I am using Astro and my installation also uses rehype-mermaidjs
. The plugin expects to see a either <pre class="mermaid">
or <code class="language-mermaid">
but the output coming out is, even removing mermaid
from the list of languages, looks like below.
So I am wondering how I could potentially fix this as they seem incompatible with one taking over the other.
<pre tabindex="0">
<code><div class="ec-line">
<span style="--0:#FF79C6;--1:#5B6900">graph</span>
<span style="--0:#F8F8F2;--1:#54666C"> </span>
<span style="--0:#50FA7B;--1:#1D689E">TD</span><span style="--0:#F8F8F2;--1:#54666C">;</span></div><div class="ec-line"><span style="--0:#F8F8F2;--1:#54666C"> A</span><span style="--0:#FF79C6;--1:#5B6900">--></span><span style="--0:#F8F8F2;--1:#54666C">B;</span></div>
<div class="ec-line"><span style="--0:#F8F8F2;--1:#54666C"> A</span>
<span style="--0:#FF79C6;--1:#5B6900">--></span><span style="--0:#F8F8F2;--1:#54666C">C;</span>
</div><div class="ec-line"><span style="--0:#F8F8F2;--1:#54666C"> B</span><span style="--0:#FF79C6;--1:#5B6900">--></span><span style="--0:#F8F8F2;--1:#54666C">D;</span>
</div><div class="ec-line"><span style="--0:#F8F8F2;--1:#54666C"> C</span>
<span style="--0:#FF79C6;--1:#5B6900">--></span>
<span style="--0:#F8F8F2;--1:#54666C">D;</span></div>
</code>
</pre>
Hmm, this is currently not possible out of the box. I think it's not a good idea of the mermaid plugin author to depend on a particular HTML output of rendered code blocks - it probably would have been better to make this a remark plugin instead of a rehype plugin. This way, it could run before Expressive Code and do its custom processing on code blocks with the mermaid
language only.
I've seen that there is actually a remark version of this plugin, but it seems to have fewer options and there even is a warning in its docs that recommends using the rehype version instead.
A quick solution to get the specific HTML output this plugin expects is by writing a custom remark plugin that runs before Expressive Code and renders mermaid
code blocks to plain HTML. This is how it could look like:
// ./plugins/remark-mermaid-to-html.mjs
import { visit } from 'unist-util-visit';
import { toHast } from 'mdast-util-to-hast';
import { toHtml } from 'hast-util-to-html';
const remarkMermaidToHtml = () => {
const transformer = async (tree, file) => {
visit(tree, 'code', (code, index, parent) => {
if (index === null || parent === null) return;
if (code.lang === 'mermaid') {
const hast = toHast(code);
const html = toHtml(hast);
parent.children.splice(parent.children.indexOf(code), 1, {
type: 'html',
value: html,
});
}
});
};
return transformer;
};
export default remarkMermaidToHtml;
If you install unist-util-visit
, mdast-util-to-hast
, and hast-util-to-html
using your package manager, add this little remark plugin into a file like ./plugins/remark-mermaid-to-html.mjs
, the only thing you then need to do is adding the plugin to your Astro config:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import remarkMermaidToHtml from './plugins/remark-mermaid-to-html.mjs';
// https://astro.build/config
export default defineConfig({
// ...
markdown: {
remarkPlugins: [remarkMermaidToHtml],
},
// ...
});
Here's a quick preview on StackBlitz to see that this actually renders plain code blocks for mermaid
now: https://stackblitz.com/edit/github-n7kyh4-ianbcr?file=src%2Fcontent%2Fdocs%2Findex.mdx,plugins%2Fremark-mermaid-to-html.mjs
Hope that helps!
@hippotastic I am actually trying the remark and it seems to work. According the maintainer, it's limited in functionalities compared to the rehype version, but I am yet to discover which those limits are and if they are relevant to me.
And thanks for your option too, it's a viable one 🎉
@LunaticMuch did you end-up with a good support for Mermaid? do you have an example I can try? 😊