An MkDocs plugin that renders textual graph descriptions into Mermaid graphs (flow charts, sequence diagrams, pie charts, etc.).
This is a fork from Laurent Franceschetti's excellent project, which in turn picked up where a prior project left off. This verion is cut down to serve the more limited needs of the OUH mkdocs-material theme, which more tightly integrates components for secure local hosting.
- How it works
- Installation
- Configuration
- Usage
- Tips and Tricks
- Troubleshooting: the mermaid diagram is not being displayed
- Using the mermaid2.dumps() function
If you do not wish to learn the details under the hood, skip to the Installation section.
Normally mkdocs 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 :
<script>
mermaid.initialize(...)
</script>
The Mermaid library is included as part of the OUH Material theme.
The user's browser will then read this code and render it on the fly.
No svg/png images were harmed during the rendering of that graph.
TBC - this is handled by the OUH Material theme
To enable this plugin, you need to declare it in your config file (mkdocs.yml
).
In order to work, the plugin also requires the mermaid javascript library (in our use case, this is already part of the OUH Material theme build process).
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.)
By design, the theme build selects a version of the Mermaid javascript library that is known to work (some versions work better than others).
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 n00bs' introduction to mermaid.
- In case of doubt, you will want to test your diagrams in the Mermaid Live Editor.
By default, the plugin automatically inserts the 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'
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
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:
- 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 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.
In order to work, the proper javascript library must called from the html page.
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).
- As a first step, set the security level to 'loose'.
- Make sure you use a compatible version of the javascript library
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
}