expressive-code / expressive-code

A text marking & annotation engine for presenting source code on the web.

Home Page:https://expressive-code.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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">--&gt;</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">--&gt;</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">--&gt;</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">--&gt;</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? 😊