Mkdocs-material: Native Mermaid.js integration (currently experimental)

Created on 1 Jan 2021  ยท  17Comments  ยท  Source: squidfunk/mkdocs-material

__Experimental support has been released as part of Insiders 1.15.0!__

Many users have problems setting up Mermaid for drawing graphs. Material for MkDocs wants to make drawing graphs as simple as adding the relevant graph definition to a Markdown file with everything else automatically being taken care of.

Goals

I'm working on a native Mermaid.js integration as part of Insiders, which will have the following nice properties:

  • [x] The theme will automatically set up Mermaid.js as soon as it sees a .mermaid block
  • [x] This will work perfectly with instant loading and only load the rather bulky mermaid.js when necessary
  • [x] It works with dark mode and is easily customizable through CSS variables
  • [ ] The colors and fonts will adapt to those chosen by the author in mkdocs.yml
  • [ ] Omit common problems with Mermaid (i.e. duplicate IDs)
  • [ ] Consider offline support

While all graph types are supported, not all of them will adapt to the chosen colors and fonts (yet). The progress so far:

  • [x] Flow charts
  • [x] Class diagrams
  • [x] State diagrams
  • [ ] Sequence diagrams
  • [ ] Entity-Relationship diagrams
  • [ ] User Journeys
  • [ ] Gantt charts
  • [ ] Pie charts

Usage

Support is currently experimental and can be enabled by adding the following configuration to mkdocs.yml:

markdown_extensions:
  - pymdownx.superfences:
      custom_fences:
        - name: mermaid
          class: mermaid-experimental
          format: !!python/name:pymdownx.superfences.fence_code_format

Material for MkDocs will take care of the rest, only initializing Mermaid.js when necessary. Furthermore, Instant Loading and Mermaid will work perfectly together, so the setup is only necessary once.


Preview

Bildschirmfoto 2021-01-01 um 16 50 46
Bildschirmfoto 2021-01-01 um 16 51 02

enhancement insiders

Most helpful comment

The documentation is incorrect. The config snippet includes:

format: !!pymdownx.superfences.fence_code_format

but it should be (as stated above):

format: !!python/name:pymdownx.superfences.fence_code_format

With that change, it runs fine. Looks great, now I have to learn Mermaid ๐Ÿ˜„

All 17 comments

This is pretty exciting, and when you get something testable, if you want, I'd love to test it out as I currently have a vested interest and would like to confirm this won't exhibit any of the issues I've experienced in the past with Mermaid, mainly: https://github.com/mermaid-js/mermaid/issues/1318.

My current solution actually mitigates all known issues (mainly related to leaky IDs) I've dealt with when using Mermaid by using Shadow DOMs, and I'd love to help make sure Material's approach (even if different) doesn't introduce any of those issues. I'd love to migrate to this new solution. I spent a good amount of time getting Mermaid working great in my docs, and would love to never do it again ๐Ÿ˜….

I just added the experimental Mermaid integration to Insiders. If Insiders now sees an element with the .mermaid-experimental class, the Mermaid environment is initialized and the graphs are automatically rendered. Note that I choose this class name, so users need to opt-in into this experimental feature. This is essentially equivalent to a feature flag and will be renamed to .mermaid as soon as we're out of experimental state, supporting both for a period of transition. While all graphs should work, I haven't yet added styling support to all types of them. I'll add some more information to the original post to keep track of the progress.

Thus, to enable the Mermaid integration, just configure Superfences as follows:

markdown_extensions:
  - pymdownx.superfences:
      custom_fences:
        - name: mermaid
          class: mermaid-experimental
          format: !!python/name:pymdownx.superfences.fence_code_format

Note that the Mermaid JavaScript should not be added to extra JS, it's automatically done so by the theme.

The documentation is incorrect. The config snippet includes:

format: !!pymdownx.superfences.fence_code_format

but it should be (as stated above):

format: !!python/name:pymdownx.superfences.fence_code_format

With that change, it runs fine. Looks great, now I have to learn Mermaid ๐Ÿ˜„

@wilhelmer thanks for noting โ€“ fixed in 0c7055fa. All feedback appreciated ๐Ÿ˜Š

Thanks! Initial thoughts:

1) mermaid.min.js is fetched dynamically and only if needed, which is nice to reduce the footprint on pages without diagrams. However, since it fetches from unpkg.com, this doesn't work when working offline. In this case, the original Mermaid code is displayed instead of the diagram, which is a little weird. I know offline browsing is considered an edge case, but if it's not too complicated, you could
1) ... add a note to the docs that this feature only works online.
2) ... find a better fallback solution, i.e., display placeholder text.
2) The font family for diagrams is set to "trebuchet ms", verdana, arial, sans-serif (tested on Windows with FF and Chrome), I guess that should be Roboto
3) Some rendering issues in Chrome:
grafik
Firefox:
grafik

Can you post diagram?

I used the example from the documentation:

graph LR
  A[Start] --> B{Error?};
  B -->|Yes| C[Hmm...];
  C --> D[Debug];
  D --> B;
  B ---->|No| E[Yay!];

@wilhelmer thanks for test driving!

mermaid.min.js is fetched dynamically and only if needed, which is nice to reduce the footprint on pages without diagrams. However, since it fetches from unpkg.com, this doesn't work when working offline. In this case, the original Mermaid code is displayed instead of the diagram, which is a little weird. I know offline browsing is considered an edge case, but if it's not too complicated, you could
... add a note to the docs that this feature only works online.
... find a better fallback solution, i.e., display placeholder text.

It should actually be not that hard to add offline support. You'd have to add Mermaid to extra_javascript and the theme could detect that it has already been added. The only paintpoint of Mermaid is that it "runs away" when you don't stop it, i.e. it will self-initialize unless told otherwise, so there might be some extra JavaScript necessary. I really hate Mermaid's library design, you have to fight against it on so many levels, yet it seems to be the standard solution. We can add offline support when the integration stabilizes, but it's good to keep it in mind from the start.

The font family for diagrams is set to "trebuchet ms", verdana, arial, sans-serif (tested on Windows with FF and Chrome), I guess that should be Roboto

Some rendering issues in Chrome:

I cannot reproduce the rendering errors. Here, on macOS, everything looks fine on Safari, Firefox and Chrome. Furthermore, the correct font (as set in mkdocs.yml is used for the three diagram types that are already supported). Are you using Windows?

Yes, I'm using Windows. The font issue seems to be caused by my local config, so ignore that. But the rendering issue is definitely a thing, tested it with a minimum setup on Chrome 87 Windows:

mkdocs.yml

site_name: My Docs
use_directory_urls: false
theme:
    name: material
markdown_extensions:
    - pymdownx.superfences:
          custom_fences:
            - name: mermaid
              class: mermaid-experimental
              format: !!python/name:pymdownx.superfences.fence_code_format

grafik

I'll try to get my hands on a Windows machine anytime soon. Until then, if somebody feels like debugging - any help is appreciated. Do the flow charts in the Mermaid documentation look correct on your machine?

Yes, the charts in the documentation look fine.

Important observation: I've set the resolution to 2x on my Windows monitor (= "200%" setting in control panel). When I change it to 1x (= 100%), the drawing is rendered correctly! So it must have something to do with the 2x rendering in Windows Chrome. Maybe you can ignore this issue because it will only affect a small fraction of users.

This could come from the use of ems (i.e. relative font units) in Material and for the Mermaid integration and Mermaid hard coding 16px for the SVG image:

Bildschirmfoto 2021-01-06 um 11 46 11

On your machine, did you increase resolution (= zoom) or font-size? It's interesting that it works in the official Mermaid docs, but that shows that there's definitely a way around.

Checked again, the Mermaid docs are also messed up. Sorry for the confusion. So it's a bug on their side.

@wilhelmer, @squidfunk
In my current solution, I do not have this problem in my current implementation:

chrome_Qck50t7xq8

I may do some things different than Material though, for instance, I turn off HTML labels which can cause the above issue:

    flowchart: {
      htmlLabels: false
    },

You can see when I turn it on, I get the same issue:

image

I am not currently using Material's implementation yet. I worked through all of the common issues I ran into when using Mermaid in my own docs, and I haven't yet taken time to identify which issues Material does not workaround. My config is here if it helps as there may be other things that fix minor issues: https://github.com/facelessuser/pymdown-extensions/blob/master/docs/src/markdown/_snippets/uml.txt.

I agree that the Mermaid library is not as well implemented as I would like, but it is the most powerful in-browser UML library that I known of. You can render UML offline with 3rd party, non Python apps like PlantUML and generate images to include.

I think with Mermaid, you have to understand what it does well and stick to that.

@facelessuser Interesting, I'll play around with the htmlLabels configuration. Note that this integration is still experimental and needs some work, especially the encapsulation problem. I'll continue to work on it as soon as possible.

Not a problem. This is also one of the things I documented in my Mermaid guide: https://facelessuser.github.io/pymdown-extensions/extras/mermaid/#configuration. Just an FYI. Most known issues I've worked around and am more than happy to explain if you run into trouble.

Was this page helpful?
0 / 5 - 0 ratings