mermaid diagrams should use pre blocks #704

Closed
opened 2026-01-29 14:43:29 +00:00 by claunia · 3 comments
Owner

Originally created by @mythz on GitHub (Oct 25, 2024).

The mermaid usage docs says mermaid diagrams should be included within <pre class="mermaid"> blocks.

Currently Markdig generates mermaid diagrams:

```mermaid
flowchart LR
    A --> B
```

Within a div block:

<div class="mermaid">
flowchart LR
    A --> B
</div>

But this fails to render with the latest version (v11) of the mermaid library:

image

But will work if it used a <pre> tag:

<pre class="mermaid">
flowchart LR
    A --> B
</pre>

Can Markdig be configured to render diagrams in <pre> blocks?

Originally created by @mythz on GitHub (Oct 25, 2024). The [mermaid usage docs](https://mermaid.js.org/config/usage.html) says mermaid diagrams should be included within `<pre class="mermaid">` blocks. Currently Markdig generates mermaid diagrams: ```mermaid flowchart LR A --> B ``` Within a div block: ```html <div class="mermaid"> flowchart LR A --> B </div> ``` But this fails to render with the latest version (v11) of the `mermaid` library: ![image](https://github.com/user-attachments/assets/3196e3cb-a539-473e-9859-e14e5c29e36f) But will work if it used a `<pre>` tag: ```html <pre class="mermaid"> flowchart LR A --> B </pre> ``` Can Markdig be configured to render diagrams in `<pre>` blocks?
claunia added the bugPR Welcome! labels 2026-01-29 14:43:29 +00:00
Author
Owner

@mythz commented on GitHub (Oct 26, 2024):

Thx for the quick PR, I've tried testing this with the latest v0.38.0 that was just released but this:

```mermaid
flowchart LR
    A --> B
```

Now generates:

<pre><code class="language-mermaid">flowchart LR
    A --&gt; B
</code></pre>

With and without highlight.js being enabled.

Not sure what the best way to implement this in the code-base would be, but I've got it working by adding this CodeBlock renderer:

public class MermaidBlockRenderer(CodeBlockRenderer? underlyingRenderer = null) : HtmlObjectRenderer<CodeBlock>
{
    private readonly CodeBlockRenderer underlyingRenderer = underlyingRenderer ?? new CodeBlockRenderer();
    protected override void Write(HtmlRenderer renderer, CodeBlock obj)
    {
        if (obj is not FencedCodeBlock fencedCodeBlock || obj.Parser is not FencedCodeBlockParser parser)
        {
            underlyingRenderer.Write(renderer, obj);
            return;
        }

        var attributes = obj.TryGetAttributes() ?? new HtmlAttributes();
        attributes.AddClass("mermaid not-prose");
        var txt = GetContent(obj);
        renderer
            .Write("<pre")
            .WriteAttributes(attributes)
            .Write(">")
            .Write(txt)
            .WriteLine("</pre>");
    }
    private static string GetContent(LeafBlock obj)
    {
        var code = new StringBuilder();
        foreach (var line in obj.Lines.Lines)
        {
            var slice = line.Slice;
            if (slice.Text == null)
                continue;

            var lineText = slice.Text.Substring(slice.Start, slice.Length);
            code.AppendLine();
            code.Append(lineText);
        }

        return code.ToString();
    }
}

We're using the .not-prose class to disable Tailwind Typography styles so we can embed mermaid charts inside @tailwindcss/typography styled docs.

@mythz commented on GitHub (Oct 26, 2024): Thx for the quick PR, I've tried testing this with the latest v0.38.0 that was just released but this: ```mermaid flowchart LR A --> B ``` Now generates: ``` <pre><code class="language-mermaid">flowchart LR A --&gt; B </code></pre> ``` With and without `highlight.js` being enabled. Not sure what the best way to implement this in the code-base would be, but I've got it working by adding this CodeBlock renderer: ```csharp public class MermaidBlockRenderer(CodeBlockRenderer? underlyingRenderer = null) : HtmlObjectRenderer<CodeBlock> { private readonly CodeBlockRenderer underlyingRenderer = underlyingRenderer ?? new CodeBlockRenderer(); protected override void Write(HtmlRenderer renderer, CodeBlock obj) { if (obj is not FencedCodeBlock fencedCodeBlock || obj.Parser is not FencedCodeBlockParser parser) { underlyingRenderer.Write(renderer, obj); return; } var attributes = obj.TryGetAttributes() ?? new HtmlAttributes(); attributes.AddClass("mermaid not-prose"); var txt = GetContent(obj); renderer .Write("<pre") .WriteAttributes(attributes) .Write(">") .Write(txt) .WriteLine("</pre>"); } private static string GetContent(LeafBlock obj) { var code = new StringBuilder(); foreach (var line in obj.Lines.Lines) { var slice = line.Slice; if (slice.Text == null) continue; var lineText = slice.Text.Substring(slice.Start, slice.Length); code.AppendLine(); code.Append(lineText); } return code.ToString(); } } ``` We're using the `.not-prose` class to disable [Tailwind Typography styles](https://github.com/tailwindlabs/tailwindcss-typography?tab=readme-ov-file#undoing-typography-styles) so we can embed mermaid charts inside `@tailwindcss/typography` styled docs.
Author
Owner

@xoofx commented on GitHub (Oct 26, 2024):

Hm, there is a unit test here so it might be a misusage on your side...

With and without highlight.js being enabled.

I'm confused, as mermaid is enabled in markdig if you use .UseDiagrams() extension method on the MarkdownPipelineBuilder (code that handles mermaid is here). How do you enable the mermaid extension method in markdig then?

@xoofx commented on GitHub (Oct 26, 2024): Hm, there is a unit test [here](https://github.com/xoofx/markdig/blob/f734e915682764162cee034aeb50a653e81cbef9/src/Markdig.Tests/Specs/DiagramsSpecs.generated.cs#L22-L44) so it might be a misusage on your side... > With and without `highlight.js` being enabled. I'm confused, as mermaid is enabled in markdig if you use `.UseDiagrams()` extension method on the MarkdownPipelineBuilder (code that handles mermaid is [here](https://github.com/xoofx/markdig/blob/f734e915682764162cee034aeb50a653e81cbef9/src/Markdig/Extensions/Diagrams/DiagramExtension.cs#L25)). How do you enable the mermaid extension method in markdig then?
Author
Owner

@mythz commented on GitHub (Oct 26, 2024):

Weird, it started working after a clean & reinstall and I can't seem to repro the behavior above. I'm using .UseAdvancedExtensions() so .UseDiagrams() was already being added.

Also looks like the not-prose class can be added with:

```mermaid{.not-prose}
flowchart LR
    A --> B
```

So replacing my temp hack with the default implementation, thx!

@mythz commented on GitHub (Oct 26, 2024): Weird, it started working after a clean & reinstall and I can't seem to repro the behavior above. I'm using `.UseAdvancedExtensions()` so `.UseDiagrams()` was already being added. Also looks like the `not-prose` class can be added with: ```mermaid{.not-prose} flowchart LR A --> B ``` So replacing my temp hack with the default implementation, thx!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/markdig#704