An MkDocs plugin that renders textual graph descriptions into Mermaid graphs (flow charts, sequence diagrams, pie charts, etc.).
As of version 1.0.0, this plugin works with versions of the Mermaid library > 10, and with lower versions.
- Introduction
- Installation
- How it works
- Configuration
- Usage
- Tips and Tricks
- Setting the security level to "loose"
- Formatting text in diagrams
- Adding Hyperlinks to a Diagram (versions of Mermaid javascript >~ 8.5.0)
- Adding Hyperlinks to a Diagram (versions of Mermaid javascript <~ 8.5.0)
- Auto-configure dark mode based on Host OS
- Material Theme: Switching the Mermaid diagram on the fly between light and dark mode
- Compatibility
- Troubleshooting
- The mermaid diagram is not displayed (or displayed incorrectly)
- Seeing an error message at the place of the diagram?
- The mermaid source code appears as-is (not read)?
- Using another theme than material ?
- Using superfences, but no diagram is displayed?
- Is mkdocs' version up to date (>= 1.1) ?
- Is the javascript library properly called?
- A certain type of diagram (e.g. mindmap, etc.) is not displayed, or the syntax is incorrectly interpreted?
- Other issues
- The mermaid diagram is not displayed (or displayed incorrectly)
- Using the mermaid2.dumps() function
- How to contribute
- Credits
Mermaid2 allows you to insert mermaid markup in the markdown of your mkdocs pages.
For example, a markdown page containing the following diagram:
```mermaid
graph LR
hello --> world
world --> again
again --> hello
```
will then be displayed in the final HTML page as:
graph LR
hello --> world
world --> again
again --> hello
The diagram will be rendered on the fly by the web browser, with the use of the mermaid javascript library. mkdocs-mermaid2 takes care of inserting the javascript library into the html page.
You can use all the diagrams types supported by the version of the Mermaid javascript library that you are using (flowchart, class, state, timeline, etc.).
pip install mkdocs-mermaid2-plugin
Clone this repository in a local directory and install the package:
python setup.py install
For running the examples the test
directory,
you will also need the mkdocs-material theme. You may
install it directly,
or use the following command to install the whole package:
pip install mkdocs-mermaid2-plugin[test]
When converting the markdown into HTML, mkdocs normally inserts the
Mermaid code (text) describing the diagram
into segments <pre><code class='mermaid>
:
<pre><div class="mermaid">
...
</div></pre>
To make the HTML/css page more robust, the mermaid plugin converts
those segments into <div>
elements in the final HTML page:
<div class="mermaid">
...
</div>
It also inserts a call to the javascript library :
From version 1.0 of mkdocs-mermaid2:
For versions from 10.0.0 of the Mermaid javascript library, the plugin uses the ESM format, since it is the only one available. This requires a specific call from the HTML page e.g.:
<script type="module">
import mermaid from "https://unpkg.com/mermaid@10.0.2/dist/mermaid.esm.min.mjs"
</script>
For an earlier version of the library, the plugin uses the traditional call from HTML:
<script src="https://unpkg.com/mermaid@8.8.2/dist/mermaid.min.js">
</script>
To start displaying of the diagrams, the plugin then automatically inserts a separate call to initialize the Mermaid library:
<script>
mermaid.initialize()
</script>
The user's browser will then read this code and render it on the fly.
No svg/png images are produced during the rendering of that graph.
To enable this plugin, you need to declare it in your mkdocs config file
(mkdocs.yml
).
In order to work, the plugin also requires the mermaid javascript library (in the example below, it fetched from the last version from the unpkg repository; change the version no as needed).
plugins:
- search
- mermaid2
Note: If you declare plugins, you need to declare all of them, including
search
(which would otherwise have been installed by default.)
Important: If you use another theme than material you must use a version of the plugin >= 0.5.0.
For plugin version >= 0.4
By default, the plugin selects a version of the Mermaid javascript library that is known to work (some versions work better than others).
You may specify a different version of the Mermaid library, like so:
plugins:
- search
- mermaid2:
version: 10.0.2
The plugin will insert the correct call to the javascript library inside the final HTML page.
You may specify the mermaid library explicitly, as long as it is call mermaid (independently of extension):
extra_javascript:
- https://unpkg.com/mermaid@8.7.0/dist/mermaid.min.js
This will be translated in the final HTML page as:
<script src="https://unpkg.com/mermaid@8.7.0/dist/mermaid.min.js">
This will work only for versions of the Mermaid javascript library that can be called in that way, i.e. that do not use the ES Module standard (ESM). Above version 10.0.0 only ESM format libraries are available.
As a workaround you could declare a local script file:
extra_javascript:
- js/mermaidloader.js
Where js
is a subdirectory of the document directory (docs
).
If you are using a local javascript file, it is up to you to write the import, with a version of the Mermaid library > 10 e.g.:
import mermaid from "https://unpkg.com/mermaid@10.0.2/dist/mermaid.esm.min.mjs"
No explicit call to mermaid.initialize()
is required, since it is
automatically inserted by the plugin.
In order to insert a Mermaid diagram in a markdown page, simply type it using the mermaid syntax, and surround it with the code fence for Mermaid:
```mermaid
graph TD
A[Client] --> B[Load Balancer]
B --> C[Server01]
B --> D[Server02]
```
- For instructions on how to make a diagram, see the official website.
- If you are not familiar, see the Mermaid Overview for Beginners.
- In case of doubt, you will want to test your diagrams in the Mermaid Live Editor.
By default, the plugin automatically inserts
a Javascript command mermaid.initialize();
in the HTML pages, which starts the interpretation.
Sometimes, however, you may want to add some
initialization commands (see full list).
For example, you could change the theme of the diagram, using 'dark' instead of the default one. Simply add those arguments in the config file, e.g.
plugins:
- search
- mermaid2:
arguments:
theme: 'dark'
extra_javascript:
- https://unpkg.com/mermaid/dist/mermaid.min.js
To test your website with a diagram, restart the mkdocs server:
mkdocs serve
In your browser, open the webpage on the localhost
(by default: https://localhost:8000
)
New in 0.3.0
CAUTION: As of the [version 10.0.0 of the javascript Library(https://github.com/mermaid-js/mermaid/blob/develop/CHANGELOG.md#changelog)], callbacks are no longer accepted. If you wish to use callbacks, specify a lower version of the library in the config file.
To make modifications that are not possible with css, it can be useful to insert a callback function (Javascript) into the target HTML page.
This can be done using the standard pattern, e.g.:
<script src="js/extra.js">
<script>mermaid.initialize({
theme: "dark",
mermaid: {
callback: myMermaidCallbackFunction
}
});</script>
In this case, myMermaidCallbackFunction
is located in
the js/extra.js
on the site's root directory.
Here is a simplistic example:
// js/extra.js
function myMermaidCallbackFunction(id) {
console.log('myMermaidCallbackFunction', id);
You will see the results if you display the browser's console.
This can be translated into the config (mkdocs.yaml
) file as:
plugins:
- mermaid2:
arguments:
theme: dark
mermaid:
callback: ^myMermaidCallbackFunction
extra_javascript:
- https://unpkg.com/mermaid/dist/mermaid.min.js
- js/extra.js
- Note that the name of the function must be preceded by a ^ (caret) to signify it's a literal and not a string.
- Consider the directory path for the script
as relative to the document directory (
docs
). Mkdocs will then put it in the proper place in the hierarchy of the html pages.
To access these functions, you need to relax mermaid's security level, (since version 8.2).
This requires, of course, your application taking responsibility for the security of the diagram source.
If that is OK with you, you can set the argument in the configuration of the plugin:
- mermaid2:
arguments:
securityLevel: 'loose'
To enable this function, you need to relax mermaid's security level to 'loose'.
You may use HTML in the diagram.
Note: This is guaranteed to work with Mermaid 8.6.4, but does not work e.g. on 8.7.0.
graph LR
hello["<b>Hello</b>"] --> world["<big><i>World</i></big>"]
world --> mermaid[mermaid web site]
Use this in the config file:
extra_javascript:
- https://unpkg.com/mermaid@8.6.4/dist/mermaid.min.js
To enable this function, you need to relax mermaid's security level to 'loose'.
Use the click directive in the language (for more information, see Interaction on the official mermaid website).
graph LR
hello --> world
world --> mermaid[mermaid web site]
click mermaid "https://mermaid-js.github.io/mermaid" "Website"
To enable this function, you need to relax mermaid's security level to 'loose'.
It is possible to add hyperlinks to a diagram, e.g.:
box1[An <b>important</b> <a href="https://google.com">link</a>]
Using a combination of the unquote (^
) functionality of this plugin and the
prefers-color-scheme
CSS media feature, one can have the plugin automatically enable dark mode.
plugins:
- search
- mermaid2:
arguments:
theme: |
^(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light'
This works well with the scheme: preference
option in
mkdocs-material and referenced in their documentation.
The Material theme for MkDocs allows toggling between colors. Unfortunately the Mermaid diagram will not switch out of the box from light to dark or vice versa.
This solution is similar to switch the theme according to the OS color, though that earlier, simpler solution cannot toggle dynamically.
A workable solution has been proposed by elgalu (for more information see Issue 39).
mkdocs.yml
(The palette is an example, where primary color, accent, icons, toggle message, etc. can be adapted to your needs.)
theme:
name: material
# https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#color-palette
palette:
- media: "(prefers-color-scheme: light)"
scheme: default
primary: indigo
accent: light-blue
toggle:
icon: material/toggle-switch-off-outline
name: Switch to dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: black
accent: deep orange
toggle:
icon: material/toggle-switch
name: Switch to light mode
# https://facelessuser.github.io/pymdown-extensions/extensions/superfences/
pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:mermaid2.fence_mermaid
plugins:
- mermaid2:
arguments:
# test if its __palette_1 (dark) or __palette_2 (light)
# for mkdocs-material >=8.0.0
theme: |
^(JSON.parse(__md_get("__palette").index == 1)) ? 'dark' : 'light'
# for mkdocs-material <8.0.0
# ^(JSON.parse(window.localStorage.getItem(__prefix('__palette'))).index == 1) ? 'dark' : 'light'
extra_javascript:
- extra/refresh_on_toggle_dark_light.js
The caret operator (
^
) means "unquote". It is used here to insert Javascript code into the initialization code ofmermaid.initialize()
.
docs/extra/refresh_on_toggle_dark_light.js
To avoid refreshing the page after switching between dark/light modes so that Mermaid diagram can be updated, two listeners must be installed, which are instructed to reload the page, whenever they detect a change.
That is the function of the additional script
(refresh_on_toggle_dark_light.js
):
var paletteSwitcher1 = document.getElementById("__palette_1");
var paletteSwitcher2 = document.getElementById("__palette_2");
paletteSwitcher1.addEventListener("change", function () {
location.reload();
});
paletteSwitcher2.addEventListener("change", function () {
location.reload();
});
Here is a short list of compatibilities and incompatibilities for the mermaid plugin:
Item | Type | Status | Note |
---|---|---|---|
mkdocs | theme | YES | (default) plugin version >= 0.5 |
material | theme | YES | |
windmill | theme | YES | plugin version >= 0.5 |
admonition | extension | YES | |
footnotes | extension | YES | |
minify | plugin | NO | Breaks the mermaid diagrams. |
pymdownx.highlight | extension | NO | Use pymdownx.superfences |
pymdownx.superfences | extension | OK | see paragraph |
search | plugin | OK | Do not forget to declare it in config.yml . |
IMPORTANT Do NOT use Superfences unless you want code highlighting.
It is quite natural that we want to display mermaid diagrams, while having usual code highlighting (for bash, python, etc.).
Symptom: The mermaid code is not transformed into a diagram, but processed as code to be displayed (colors, etc.).
The likely reason is that you have a markdown extension that interprets all fenced code as code to display, and it prevents the mkdocs-mermaid2 plugin from doing its job.
Do not use the codehilite markdown extension.
Instead, use facelessusers's splendid PyMdown's superfences; and use the custom fences facility.
In the config file (mkdocs.yaml
):
markdown_extensions:
- pymdownx.superfences:
# make exceptions to highlighting of code:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:mermaid2.fence_mermaid
It means:
- Take the fenced parts marked with mermaid
- Turn them into
class='mermaid'
. - To format those pieces, use the function
fence_mermaid
, from the mermaid2 package.
There are two functions:
fence_mermaid
for the general case.fence_mermaid_custom
for the Material theme (note the use of the custom suffix)
Hence, for the Material theme (only):
markdown_extensions:
- pymdownx.superfences:
# make exceptions to highlighting of code:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:mermaid2.fence_mermaid_custom
IMPORTANT: Note that the superfences will be slightly more demanding with HTML tags inside a mermaid diagram: take care to always close the HTML tags that require it (e.g.
<small>
must have its corresponding</small>
tag). Otherwise, the extension system will attempt to close those tags and it will break the diagram.
To start with, use a simple diagram that you know is syntactically correct.
e.g.
```mermaid
graph TD
A[Client] --> B[Load Balancer]
B --> C[Server01]
B --> D[Server02]
```
In recent versions of the javascript library (> 8.6.0), a pretty error message is displayed in case of incorrect syntax:
In earlier versions, the library displays nothing, which can be confusing.
If you see the error message, it is at least an indication that the mermaid javascript library was called.
In that case, the javascript library was probably not called. See the next questions.
If you are using the superfences extension, but you see the source code, you probably forgot to declare the custom_fences. Se more explanations under Declaring the superfences extension
Use mkdocs -v
.
If not, update it:
pip install mkdocs --upgrade
Or, if you cloned this repo:
python setup.py install
In order to work, the proper javascript library must called from the html page (this is done automatically). If necessary check the link used in the HTML page generated, e.g.:
<script type="module">import mermaid from "https://unpkg.com/mermaid@10.0.2/dist/mermaid.esm.min.mjs"</script>
Every diagram should start with a valid preamble, e.g. graph TD
.
In case of doubt, you may want to test your diagram in the Mermaid Live Editor.
Note, however, that the Mermaid Live Editor does not support loose mode (with HTML code in the mermaid code).
A certain type of diagram (e.g. mindmap, etc.) is not displayed, or the syntax is incorrectly interpreted?
Check the version of the javascript mermaid library you are using (it's indicated in the error message; as a last resort, check in the html page). You can change the library version if needed.
- As a first step, set the security level to 'loose'.
- Make sure you use a compatible version of the javascript library
(8.6.4, 8.8.0,
8.7.0). In principle, the version used by the plugin is compatible (see instructions to change the version).
This fix is experimental (it has been tested once and it worked).
If you declared pymdownx.details
in config.yml
(under markdown_extensions
), you may notice that a diagram will not
display correctly in that case:
???- note "Collapsed"
```mermaid
graph TD
A[Client] --> B[Load Balancer]
```
This is additional text.
Depending on the browser, you may have a dot, or nothing, etc.
In that case, use the following declaration in your markdown_extensions
:
- pymdownx.superfences:
# make exceptions to highlighting of code:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:mermaid2.fence_mermaid_custom
The use of this function will trigger a custom behavior, with two effects:
- It will create custom HTML tags,
<pre class='mermaid'><code>
. - It will deactivate the auto-load.
You must then use a special custom javascript loader for the diagram, developed by facelessuser:
- Copy the code from the website of PyMdown Extension.
- Paste it in a file in your project:
docs/js/loader.js
- Declare this script in the
config.yml
file:
extra_javascript:
- js/loader.js
As a bonus, mermaid2 exports the function dumps()
which produces a string
describing a JavaScript object.
It can be used to help generate JavaScript code from Python
(this is typically needed, when generating an HTML page that contains
JavaScript).
A JavaScript object is not exactly the same as a JSON object. The reason why this why introduced is that sometimes one needs to produce a key/value pair as:
foo = MyFunctioName
where the value is not a string but an identifier (in this case: a function name).
Here is an example:
import mermaid2
obj = { "hello": "world",
"barbaz": "^bazbar",
"foo": {"bar": 2},
"bar": True}
s = mermaid2.dumps(obj)
The purpose of the caret is to specify that the value should be an identifier and not a string. The result will be:
{
hello: "world",
barbaz: bazbar,
foo: {
bar: 2
},
bar: true
}
Contributions are welcome.
Use the Issues to signal a bug or propose a feature you believe is necessary.
If this is a usage question, prefer the discussions.
Always open an Issue and consider the answers, before submitting a PR.
mkdocs-mermaid2 is a fork from Pugong Liu's excellent project, which is no longer maintained. This new plugin offers expanded documentation as well as new functions.
It is also compatible with versions of the mermaid library > 10.0.
Thanks to all the members of the community who participated to the improvement of this project with ideas and PRs.