Repository: fralau/mkdocs-mermaid2-plugin Branch: master Commit: 59498d0c537c Files: 66 Total size: 140.1 KB Directory structure: gitextract_rndg2_6l/ ├── .github/ │ └── workflows/ │ └── greetings.yml ├── .gitignore ├── .readthedocs.yml ├── CHANGELOG.md ├── LICENSE ├── MANIFEST.in ├── README.md ├── README_old.md ├── mermaid2/ │ ├── __init__.py │ ├── fence.py │ ├── plugin.py │ ├── pyjs.py │ └── util.py ├── pyproject.toml ├── setup.py ├── test/ │ ├── __init__.py │ ├── extra_javascript/ │ │ ├── docs/ │ │ │ ├── index.md │ │ │ └── second.md │ │ └── mkdocs.yml │ ├── fixture.py │ ├── http_lib/ │ │ ├── docs/ │ │ │ ├── index.md │ │ │ └── second.md │ │ └── mkdocs.yml │ ├── local_lib/ │ │ ├── docs/ │ │ │ ├── index.md │ │ │ └── second.md │ │ └── mkdocs.yml │ ├── material/ │ │ ├── __init__.py │ │ ├── docs/ │ │ │ ├── index.md │ │ │ ├── js/ │ │ │ │ └── extra.js │ │ │ └── second.md │ │ ├── mkdocs.yml │ │ └── test_site.py │ ├── medium/ │ │ ├── docs/ │ │ │ ├── index.md │ │ │ ├── js/ │ │ │ │ └── extra.js │ │ │ └── second.md │ │ └── mkdocs.yml │ ├── simple/ │ │ ├── __init__.py │ │ ├── docs/ │ │ │ ├── index.md │ │ │ ├── js/ │ │ │ │ └── extra.js │ │ │ └── second.md │ │ ├── mkdocs.yml │ │ └── test_site.py │ ├── simple_format/ │ │ ├── docs/ │ │ │ ├── index.md │ │ │ ├── js/ │ │ │ │ └── extra.js │ │ │ └── second.md │ │ └── mkdocs.yml │ ├── simple_pre_10/ │ │ ├── docs/ │ │ │ ├── index.md │ │ │ ├── js/ │ │ │ │ └── extra.js │ │ │ └── second.md │ │ └── mkdocs.yml │ └── superfences/ │ ├── __init__.py │ ├── docs/ │ │ ├── index.md │ │ ├── js/ │ │ │ └── loader.js │ │ └── second.md │ ├── mkdocs.yml │ └── test_site.py ├── update_pypi.sh └── webdoc/ ├── docs/ │ ├── contribute.md │ ├── description.md │ ├── index.md │ ├── library.md │ ├── superfences.md │ ├── tips.md │ └── troubleshooting.md ├── extra_requirements.txt └── mkdocs.yml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/greetings.yml ================================================ name: Greetings on: [pull_request, issues] jobs: greeting: runs-on: ubuntu-latest steps: - uses: actions/first-interaction@v1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} issue-message: 'Thank you for your contribution! This is very appreciated.' pr-message: 'Message that will be displayed on users'' first pr' ================================================ FILE: .gitignore ================================================ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation site/ __test__/ # mypy .mypy_cache/ ================================================ FILE: .readthedocs.yml ================================================ # .readthedocs.yml # Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Required version: 2 # Build documentation in the docs/ directory with Sphinx # sphinx: # configuration: docs/conf.py build: os: ubuntu-22.04 tools: python: "3.11" # You can also specify other tool versions: # nodejs: "20" # rust: "1.70" # golang: "1.20" # Python environment python: install: # these are needed, because they are not part of standard setup - requirements: webdoc/extra_requirements.txt # Build documentation with MkDocs mkdocs: configuration: webdoc/mkdocs.yml fail_on_warning: false # Optionally build your docs in additional formats such as PDF and ePub formats: all ================================================ FILE: CHANGELOG.md ================================================ # Changelog: Mkdocs-Mermaid2 All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## 1.2.3, 2025-10-15 * Added: documented the use of variables and macros with MkDocs-Macros in Tips and Tricks (#123); dividing the the page into 3 sections. ## 1.2.2, 2025-08-27 * Fixed: deprecation warning by BeautifulSoup (#119, #120) ## 1.2.1, 2024-11-02 * Added: a test framework with MkDocs-Test and pytest * Changed: migrated from `setup.py` to `pyproject.toml` ## 1.1.2, 2024-09-05 * Changed: If the `javascript` parameter starts with http(s) and no Internet access is available, a WARNING is now issued (mkdocs no longer fails with an exception). ## 1.1.1, 2023-09-26 * Fixed: Bug with local javascript library ## 1.1.0, 2023-09-01 * Added: Parameter `javascript` in config file for optionally specifying the URL or path of the Mermaid javascript library. * Changed: Parameter `extra_javascript` in config file is DEPRECATED, for optionally specifying the URL or path of the Mermaid javascript library * Changed: Updated documentation. ## 1.0.8, 2023-08-09 * Fixed: Arguments of config file not taken into consideration, for mermaid.js version > 10 (#82) ## 1.0.5, 2023-07-29 * Added: A new [doc website is available on Read The Docs](https://mkdocs-mermaid2.readthedocs.io/en/latest/). ## 1.0.1, 2023-07 * Added: Now the plugin works with versions of the library > 10 and lower (#75) * Added: Added: A new [doc website is available on Read The Docs](https://mkdocs-mermaid2.readthedocs.io/en/latest/). ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 PuGong -- 2020, others Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: MANIFEST.in ================================================ include README.md include LICENSE.md ================================================ FILE: README.md ================================================
No svg/png images are produced during the rendering of that graph.
## Configuration
### Basic configuration
To enable this plugin, you need to declare it in your [mkdocs config file](https://www.mkdocs.org/user-guide/configuration/)
(`mkdocs.yml`).
In order to work, the plugin also requires the
[mermaid](https://www.npmjs.com/package/mermaid) javascript
library (in the example below, it fetched from the last version
from the [unpkg](https://unpkg.com/) repository; change the version
no as needed).
```yaml
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.
### Specifying the version of the Mermaid library
> **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:
```yaml
plugins:
- search
- mermaid2:
version: 10.0.2
```
The plugin will insert the correct call to the javascript library
inside the final HTML page.
### Explicit declaration of the Mermaid library
You _may_ specify the mermaid library explicitly, as long as it is
call mermaid (independently of extension):
```yaml
extra_javascript:
- https://unpkg.com/mermaid@8.7.0/dist/mermaid.min.js
```
This will be translated in the final HTML page as:
```html
```
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.
#### Method
This can be translated into the config (`mkdocs.yaml`) file as:
```yaml
plugins:
- mermaid2:
arguments:
theme: dark
mermaid:
callback: ^myMermaidCallbackFunction
extra_javascript:
- https://unpkg.com/mermaid/dist/mermaid.min.js
- js/extra.js
```
1. Note that **the name of the function must be preceded by a ^ (caret)**
to signify it's a literal and not a string.
2. 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.
## Tips and Tricks
### Setting the security level to "loose"
To access these functions, you need to relax mermaid's security level,
([since version 8.2](https://mermaid-js.github.io/mermaid/#/?id=special-note-regarding-version-82)).
> 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:
```yaml
- mermaid2:
arguments:
securityLevel: 'loose'
```
### Formatting text in diagrams
> To enable this function, you need to [relax mermaid's security level to 'loose'](#setting-the-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.
```mermaid
graph LR
hello["Hello"] --> world["World"]
world --> mermaid[mermaid web site]
```
Use this in the config file:
```yaml
extra_javascript:
- https://unpkg.com/mermaid@8.6.4/dist/mermaid.min.js
```
### Adding Hyperlinks to a Diagram (versions of Mermaid javascript >~ 8.5.0)
> To enable this function, you need to [relax mermaid's security level to 'loose'](#setting-the-security-level-to-loose).
Use the click directive in the language (for more information,
see [Interaction](https://mermaid-js.github.io/mermaid/#/flowchart?id=interaction) on the official mermaid website).
```mermaid
graph LR
hello --> world
world --> mermaid[mermaid web site]
click mermaid "https://mermaid-js.github.io/mermaid" "Website"
```
### Adding Hyperlinks to a Diagram (versions of Mermaid javascript <~ 8.5.0)
> To enable this function, you need to [relax mermaid's security level to 'loose'](#setting-the-security-level-to-loose).
It is possible to add hyperlinks to a diagram, e.g.:
```
box1[An important link]
```
### Auto-configure dark mode based on Host OS
Using a combination of the unquote (`^`) functionality of this plugin and the
[prefers-color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme)
CSS media feature, one can have the plugin automatically enable dark mode.
```yaml
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](https://squidfunk.github.io/mkdocs-material/) and referenced in [their documentation](https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#color-scheme).
### Material Theme: Switching the Mermaid diagram on the fly between light and dark mode
The Material theme for MkDocs allows [toggling between colors](https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#color-palette-toggle).
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](#auto-configure-dark-mode-based-on-host-os),
though that earlier, simpler solution cannot toggle dynamically.
A workable solution has been proposed by [elgalu](https://github.com/elgalu)
(for more information see [Issue 39](https://github.com/fralau/mkdocs-mermaid2-plugin/issues/39)).
**`mkdocs.yml`**
(The palette is an example, where primary color, accent, icons, toggle message, etc. can be adapted to your needs.)
```yaml
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 of `mermaid.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`):
```javascript
var paletteSwitcher1 = document.getElementById("__palette_1");
var paletteSwitcher2 = document.getElementById("__palette_2");
paletteSwitcher1.addEventListener("change", function () {
location.reload();
});
paletteSwitcher2.addEventListener("change", function () {
location.reload();
});
```
## Compatibility
### List
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](#declaring-the-superfences-extension) |
| **pymdownx.superfences** | extension | OK | [see paragraph](#declaring-the-superfences-extension) |
| **search** | plugin | OK | Do not forget to declare it in `config.yml`. |
### Using Mermaid and code highlighting at the same time
>**IMPORTANT** Do NOT use Superfences unless you want code highlighting.
#### Usage
It is quite natural that we want to display **mermaid diagrams**,
while having usual **code highlighting** (for bash, python, etc.).
#### Use of markdown extensions
**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](https://squidfunk.github.io/mkdocs-material/extensions/codehilite/) markdown extension.**
Instead, use [facelessusers](https://github.com/facelessuser)'s splendid
[PyMdown's superfences](https://facelessuser.github.io/pymdown-extensions/extensions/superfences/); and use the
**[custom fences](https://facelessuser.github.io/pymdown-extensions/extensions/superfences/#custom-fences)**
facility.
#### Declaring the superfences extension
In the config file (`mkdocs.yaml`):
```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:
1. Take the fenced parts marked with mermaid
2. Turn them into `class='mermaid'`.
3. 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):
```yaml
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. `` must have its corresponding `` tag).
> Otherwise, the extension system will attempt to close those tags
> and it will break the diagram.
## Troubleshooting
### The mermaid diagram is not displayed (or displayed incorrectly)
> 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]
```
#### Seeing an error message at the place of the diagram?
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.
#### The mermaid source code appears as-is (not read)?
In that case, the javascript library was probably not called.
See the next questions.
#### Using superfences, but no diagram is displayed?
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](#declaring-the-superfences-extension)
#### Is mkdocs' version up to date (>= 1.1) ?
Use `mkdocs -v`.
If not, update it:
pip install mkdocs --upgrade
Or, if you cloned this repo:
python setup.py install
#### Is the javascript library properly called?
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.:
```HTML
```
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](https://mermaid-js.github.io/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](#specifying-the-version-of-the-mermaid-library).
### Other issues
#### Rich text diagrams, or links are not displayed properly?
1. As a first step, [set the security level to 'loose'](#setting-the-security-level-to-loose).
2. 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](#specifying-the-version-of-the-mermaid-library)).
#### With pymdownx.details, diagrams in collapsed elements are not displayed?
**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:
```markdown
???- 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`:
```yaml
- 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:
1. It will create custom HTML tags, ``.
2. It will deactivate the auto-load.
You **must** then use a special custom javascript loader for the diagram,
developed by [facelessuser](https://github.com/facelessuser):
1. Copy the code from
the [website of PyMdown Extension](https://facelessuser.github.io/pymdown-extensions/extras/mermaid/#putting-it-all-together).
2. Paste it in a file in your project: `docs/js/loader.js`
3. Declare this script in the `config.yml` file:
```yaml
extra_javascript:
- js/loader.js
```
## Using the mermaid2.dumps() function
As a bonus, mermaid2 exports the function `dumps()` which produces a string
describing a [JavaScript object](https://javascript.info/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:
```JavaScript
foo = MyFunctioName
```
where the value is _not_ a string but an identifier (in this case:
a function name).
Here is an example:
```python
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:
```JavasScript
{
hello: "world",
barbaz: bazbar,
foo: {
bar: 2
},
bar: true
}
```
## How to contribute
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.
## Credits
mkdocs-mermaid2 is a fork from
[Pugong Liu's excellent project](https://github.com/pugong/mkdocs-mermaid-plugin),
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.
================================================
FILE: mermaid2/__init__.py
================================================
"Exports of mermaid2"
# export the dumps function (for producing a JS object)
from .pyjs import dumps
# export the fence_mermaid for pymdownx.superfences
from .fence import fence_mermaid, fence_mermaid_custom
================================================
FILE: mermaid2/fence.py
================================================
"""
Special fence for PyMdown Extensions Superfences
See: https://facelessuser.github.io/pymdown-extensions/extensions/superfences/#formatters
NOTE: SUPERFENCES AND CUSTOM_FENCES ARE NOT NEEDED UNLESS
CODE HIGHLIGHTING IS REQUIRED.
- fence_mermaid() for most Mkdocs themes
- fence_mermaid_custom() for Material theme
"""
from functools import partial
def fence_mermaid(source, language, css_class, options, md,
classes=None, id_value='', custom=False, **kwargs):
"""
For mermaid loose mode:
This function is needed for correctly displaying the mermaid
HTML in diagrams when pymdownx.superfences is activated,
so that code highlighting is activated.
Contrary to the standard fence_div_format used in
https://github.com/facelessuser/pymdown-extensions/blob/9489bd8d94eebf4a109b7dada613bc2db378e31f/pymdownx/superfences.py#L149,
this function it format sources as ... but
WITHOUT escaping the < and > characters in the HTML.
It should be called in the mkdocs.yaml file as:
markdown_extensions:
- ...
- ...
- pymdownx.superfences:
# make exceptions to highlighting of code:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:mermaid2.fence_mermaid
"""
if id_value:
id_value = ' id="{}"'.format(id_value)
classes = css_class if classes is None else ' '.join(classes + [css_class])
if custom:
html = '%s\n
' % \
(id_value, classes, source)
else:
html = '%s\n' % \
(id_value, classes, source)
# print("--- Mermaid ---\n", html, "\n------")
return html
# special custom function for Material theme
# (do not forget to specify name!)
fence_mermaid_custom = partial(fence_mermaid, custom=True)
fence_mermaid_custom.__name__ = 'fence_mermaid_custom'
================================================
FILE: mermaid2/plugin.py
================================================
"""
Main plugin module for mermaid2
"""
import os
from mkdocs.plugins import BasePlugin
from mkdocs.config.config_options import Type as PluginType
from bs4 import BeautifulSoup
from . import pyjs
from .util import info, libname, url_exists
# ------------------------
# Constants and utilities
# ------------------------
# the default (recommended) mermaid lib:
JAVASCRIPT_VERSION = '10.4.0'
JAVASCRIPT_PRE_10 = "https://unpkg.com/mermaid@%s/dist/mermaid.min.js"
# New format (ESM):
JAVASCRIPT = "https://unpkg.com/mermaid@%s/dist/mermaid.esm.min.mjs"
# Two conditions for activating custom fences:
SUPERFENCES_EXTENSION = 'pymdownx.superfences'
CUSTOM_FENCE_FN = 'fence_mermaid_custom'
# ------------------------
# Plugin
# ------------------------
class MarkdownMermaidPlugin(BasePlugin):
"""
Plugin for interpreting Mermaid code
"""
config_scheme = (
('version', PluginType(str, default=JAVASCRIPT_VERSION)),
('javascript', PluginType(str, default=None)),
('arguments', PluginType(dict, default={})),
# ('custom_loader', PluginType(bool, default=False))
)
# ------------------------
# Properties
# Do not call them before on_config was run!
# ------------------------
@property
def full_config(self):
"""
The full plugin's configuration object,
which also includes the contents of the yaml config file.
"""
return self._full_config
@property
def mermaid_args(self):
"""
The arguments for mermaid, found in the config file.
"""
return self._mermaid_args
@property
def mermaid_version(self) -> str:
"""
The version of mermaid
This information comes from the YAML file parameter,
or, if empty, from JAVASCRIPT_VERSION.
"""
version = self.config['version'] or JAVASCRIPT_VERSION
assert version, "No correct version of mermaid is provided!"
return version
@property
def mermaid_major_version(self) -> int:
"""
Major version of mermaid (e.g. 8. 9, 10) as int
"""
major = self.mermaid_version.split('.')[0]
try:
return int(major)
except:
ValueError("Mermaid version provided has incorrect format")
@property
def extra_javascript(self) -> str:
"""
Provides the mermaid.js library defined in mkdocs.yml
under extra_javascript.
To be recognized, the library must have 'mermaid' in the filename.
WARNING:
Using extra_javascript for that purpose was the original way,
but is now DEPRECATED; it bypasses the new and better mechanisms
for selecting the javascript library.
It will insert the mermaid library in all pages, regardless
of whether a mermaid diagram is present or not.
"""
if not hasattr(self, '_extra_javascript'):
# As of mkdocs 1.5, extra_javascript is a list of objects;
# no longer a string. Call to str was used.
# Patched in 1.5.1, with __fspath___ method,
# see https://github.com/mkdocs/mkdocs/issues/3310
# But we keep it, to guarantee it's a string.
extra_javascript = map(str, self.full_config.get('extra_javascript', []))
for lib in extra_javascript:
# check that 'mermaid' is in the filename, minus the extension.
basename = os.path.basename(lib)
basename, ext = os.path.splitext(basename)
if 'mermaid' in basename.lower():
self._extra_javascript = lib
return lib
self._extra_javascript = None
return self._extra_javascript
@property
def javascript(self) -> str:
"""
Provides the url/pathanme of mermaid library according to version
(distinction on the default, between version < 10 and after)
"""
if not hasattr(self, '_javascript'):
# check if a mermaid javascript parameter exists:
javascript = self.config['javascript']
if not javascript:
if self.mermaid_major_version < 10:
javascript = JAVASCRIPT_PRE_10 % self.mermaid_version
else:
# newer versions
javascript = JAVASCRIPT % self.mermaid_version
# make checks
if not url_exists(javascript,
local_base_dir=self.full_config['docs_dir']):
raise FileNotFoundError("Cannot find Mermaid library: %s" %
javascript)
self._javascript = javascript
return self._javascript
@property
def activate_custom_loader(self) -> bool:
"""
Predicate: activate the custom loader for superfences?
The rule is to activate:
1. superfences extension is activated
2. it specifies 'fence_mermaid_custom' as
as format function (instead of fence_mermaid)
"""
try:
return self._activate_custom_loader
except AttributeError:
# first call:
# superfences_installed = ('pymdownx.superfences' in
# self.full_config['markdown_extensions'])
# custom_loader = self.config['custom_loader']
# self._activate_custom_loader = (superfences_installed and
# custom_loader)
# return self._activate_custom_loader
self._activate_custom_loader = False
superfences_installed = (SUPERFENCES_EXTENSION in
self.full_config['markdown_extensions'])
if superfences_installed:
# get the config extension configs
mdx_configs = self.full_config['mdx_configs']
# get the superfences config, if exists:
superfence_config = mdx_configs.get(SUPERFENCES_EXTENSION)
if superfence_config:
info("Found superfences config: %s" % superfence_config)
custom_fences = superfence_config.get('custom_fences', [])
for fence in custom_fences:
format_fn = fence.get('format')
if format_fn.__name__ == CUSTOM_FENCE_FN:
self._activate_custom_loader = True
info("Found '%s' function: "
"activate custom loader for superfences"
% CUSTOM_FENCE_FN)
break
return self._activate_custom_loader
# ------------------------
# Event handlers
# ------------------------
def on_config(self, config):
"""
The initial configuration
store the configuration in properties
"""
# the full config info for the plugin is there
# we copy it into our own variable, to keep it accessible
self._full_config = config
# Storing the arguments to be passed to the Javascript library;
# they are found under `mermaid2:arguments` in the config file:
self._mermaid_args = self.config['arguments']
# Here we used the standard self.config property
# (this can get confusing...)
assert isinstance(self.mermaid_args, dict)
info("Initialization arguments:", self.mermaid_args)
# info on the javascript library:
if self.extra_javascript:
info("Explicit mermaid javascript library from extra_javascript:\n ",
self.extra_javascript)
info("WARNING: Using extra_javascript is now DEPRECATED; "
"use mermaid:javascript instead!")
elif self.config['javascript']:
info("Using specified javascript library: %s" %
self.config['javascript'])
else:
info("Using javascript library (%s):\n "%
self.config['version'],
self.javascript)
def on_post_page(self, output_content, config, page, **kwargs):
"""
Actions for each page:
generate the HTML code for all code items marked as 'mermaid'
"""
if "mermaid" not in output_content:
# Skip unecessary HTML parsing
return output_content
soup = BeautifulSoup(output_content, 'html.parser')
page_name = page.title
# first, determine if the page has diagrams:
if self.activate_custom_loader:
# the custom loader has its specific marking
# ...
info("Custom loader activated")
mermaids = len(soup.select("pre.mermaid code"))
else:
# standard mermaid can accept two types of marking:
# ...
# but since we want only for best compatibility,
# it needs to be replaced
# NOTE: Python-Markdown changed its representation of code blocks
# https://python-markdown.github.io/change_log/release-3.3/
pre_code_tags = (soup.select("pre code.mermaid") or
soup.select("pre code.language-mermaid"))
no_found = len(pre_code_tags)
if no_found:
info("Page '%s': found %s diagrams "
"(with ), converting to ..." %
(page_name, len(pre_code_tags)))
for tag in pre_code_tags:
content = tag.text
new_tag = soup.new_tag("div", attrs={"class": "mermaid"})
new_tag.append(content)
# replace the parent:
tag.parent.replace_with(new_tag)
# Count the diagrams ...
mermaids = len(soup.select("div.mermaid"))
# if yes, add the javascript snippets:
if mermaids:
info("Page '%s': found %s diagrams, adding scripts" %
(page_name, mermaids))
# insertion of the
```
The plugin automatically inserts this call.
=== "All-in-one Library"
For an earlier version of the Mermaid.js (<10),
the plugin continues to use the traditional version, which is an **all-in-one file**.
Those library files are recognizable because they have the `.js` extension.
The call in the HTML page is:
``` html
```
The plugin automatically inserts this call.
** This is still a valid method.** (Even though the very first versions after 10.0.0 no longer provided
this file, later versions have resumed providing it.)
## Initialization sequence
### Default sequence
To start displaying of the diagrams, the plugin then automatically inserts
a separate call to initialize the Mermaid library:
```javascript
mermaid.initialize()
```
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.
### Additional arguments to the Mermaid engine
Sometimes, however, you may want to add some
additional initialization commands (see [full list](https://github.com/knsv/mermaid/blob/master/docs/mermaidAPI.md#mermaidapi-configuration-defaults)).
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.
```yaml
plugins:
- search
- mermaid2:
version: '10.1.0'
arguments:
theme: 'dark'
themeVariables:
primaryColor: '#BB2528'
primaryTextColor: '#fff'
primaryBorderColor: '#7C0000'
lineColor: '#F8B229'
secondaryColor: '#006100'
tertiaryColor: '#fff'
```
The plugin then automatically adds the initialization sequence:
=== "ESM modules"
Both `import` and `mermaid.initialize()` must be in the same `
```
=== "Traditional modules"
For traditional (all-in-one file) javascript modules, **two** calls to the `
```
================================================
FILE: webdoc/docs/index.md
================================================
# Mkdocs-Mermaid2
A diagrams plugin for Mkdocs { align=center }
---
[](https://opensource.org/licenses/MIT)
[](https://pypi.org/project/mkdocs-mermaid2-plugin/)


## Introduction
**Mkdocs-Mermaid2** is a plugin for the [MkDocs](https://www.mkdocs.org/)
static sites generator, which allows you
to render Mermaid diagrams inserted (as text) into the markdown pages.
- [The official repository of Mermaid2 is on github.](https://github.com/fralau/mkdocs-mermaid2-plugin)
- [Mermaid2 is available from Pypi.](https://pypi.org/project/mkdocs-mermaid2-plugin/)
### What is Mermaid?
[Mermaid](https://mermaid.js.org/intro/) is two things:
1. A simple language for the creation of diagrams.
2. A [javascript library](https://github.com/mermaid-js/mermaid) (Mermaid.js)
for displaying those diagrams in an HTML page.
### General Principle
In order to insert a Mermaid diagram in a markdown page,
1. Start a new line with a [code fence](https://www.markdownguide.org/extended-syntax/#fenced-code-blocks) (triple backticks),
with the codeword `mermaid`.
2. Type the diagram using the Mermaid syntax.
2. End with a code fence.
For example, a markdown page containing the following diagram (left-right graph):
```mermaid
graph LR
hello --> world
world --> again
again --> hello
```
will then be displayed in the final HTML page as:
```mermaid
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.
The mkdocs-mermaid2 plugin takes care of inserting the javascript library into
the html page and inserting the script to start it.
!!! Note
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.).
Here is another example:
```mermaid
pie title Which animals do you prefer as pets?
"Dogs" : 386
"Cats" : 85
"Rabbits" : 53
"Hamsters" : 101
```
It will be rendered as (a pie chart):
```mermaid
pie title Which animals do you prefer as pets?
"Dogs" : 386
"Cats" : 85
"Rabbits" : 53
"Hamsters" : 101
```
### How to write Mermaid diagrams
* For instructions on how to make a diagram, see [the official website](https://mermaid.js.org).
* If you are not familiar, see the [Mermaid Overview for Beginners](https://mermaid.js.org/intro/getting-started.html).
* In case of doubt, you will want to test your diagrams in the [Mermaid Live Editor](https://mermaid.live).
## Installation
### Pre-requisites
* Python 3 >= 3.6
* [Mkdocs](https://www.mkdocs.org/user-guide/installation/)
### Automatic
The most up-to-date, stable production version of mkdocs-mermaid2 is available from the [pypi repository](https://pypi.org/project/mkdocs-mermaid2-plugin/):
```bash
pip install mkdocs-mermaid2-plugin
```
### Manual
The most up-to-date version of the package is available from [github](https://github.com/fralau/mkdocs-mermaid2-plugin).
Clone this repository in a local directory and install the package:
```bash
python setup.py install
```
### Installing and running the test examples
For running the examples the `test` directory,
you will also need the mkdocs-material theme. You may
[install it directly](https://squidfunk.github.io/mkdocs-material/getting-started/),
or use the following command to install the whole package:
```bash
pip install mkdocs-mermaid2-plugin[test]
```
## Configuration
### Basic configuration
To enable this plugin, you need to declare it in your [mkdocs config file](https://www.mkdocs.org/user-guide/configuration/)
(`mkdocs.yml`).
In order to work, the plugin also requires the
[mermaid](https://www.npmjs.com/package/mermaid) javascript
library (in the example below, it fetched from the last version
from the [unpkg](https://unpkg.com/) repository; change the version
no as needed).
```yaml
plugins:
- search
- mermaid2
```
!!! Warning "Caution"
If you declare plugins in the config file, you need to declare _all_ of them,
including `search` (which would otherwise have been installed by default.)
### Specifying the version of the Mermaid library
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:
```yaml
plugins:
- search
- mermaid2:
version: 10.0.2
```
The plugin will insert the correct call to the javascript library
inside the final HTML page.
### Specifying your own Mermaid library
By default, mkdocs-mermaid2 automatically inserts the proper calls to
Mermaid.js (according to the correct version),
so that the diagrams are correctly interpreted.
You may, however, specify your own explicit call:
```yaml
plugins:
- search
- mermaid2:
javascript: https://unpkg.com/mermaid@10.4.0/dist/mermaid.esm.min.mjs
```
For more details, [see the relative page](library.md).
### Use of the Material theme
!!! Note
The [Material theme](https://squidfunk.github.io/mkdocs-material/),
developed by [squidfunk](https://github.com/squidfunk)
is not mandatory, but recommended.
**Mermaid diagrams will automatically adapt their colors to the theme
and palette.**
Here are the recommended settings in the configuration file:
```yaml
markdown_extensions:
- pymdownx.superfences:
# make exceptions to highlighting of code:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:mermaid2.fence_mermaid_custom
```
See the [technical explanation](superfences.md/#usage-for-the-material-theme).
### Other Themes
If you don't use the Material theme, it will be up to you to define the
theme and colors of the diagrams, by adding arguments to the plugin, e.g. :
```yaml
plugins:
- search
- mermaid2:
version: '9.4.3' # only works with version < 10
arguments:
theme: 'dark'
themeVariables:
primaryColor: '#BB2528'
primaryTextColor: '#fff'
primaryBorderColor: '#7C0000'
lineColor: '#F8B229'
secondaryColor: '#006100'
tertiaryColor: '#fff'
```
The result would be as follows, for the diagrams above:


!!! Tip
As of mkdocs-mermaid2 version 1.0.8, this works also with versions of Mermaid.js >= 10.
### Testing
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`)
================================================
FILE: webdoc/docs/library.md
================================================
# Using the JavaScript Mermaid Library
> _From version 1.1.0 of Mkdocs-Mermaid2_
## Introduction
By default, MkDocs-Mermaid2 automatically inserts the proper calls to
[the Mermaid.js library, according to the correct version](description.md/#insertion-of-the-javascript-library) (all-in one file, or ESM),
so that the diagrams are correctly interpreted.
You may, however, specify your own version, using to the
`javascript` parameter of Mermaid2,
in the [config file of MkDocs](https://mkdocs.readthedocs.io/en/859/user-guide/configuration/).
```yaml
plugins:
- search
- mermaid2:
javascript: https://unpkg.com/mermaid@10.4.0/dist/mermaid.esm.min.mjs
```
The files can be found on [unpkg](https://unpkg.com/browse/mermaid@10.4.0/) or [jsdelivr.com](https://www.jsdelivr.com/package/npm/mermaid).
Mkdocs-Mermaid2 will still insert the appropriate call to the JavaScript library
into the HTML page, according to the type of library (as all-in-one
javascript function, or [ESM module](description.md/#automatic-insertion-of-the-javascript-library)),
as well as the [initialization
sequence](description.md/#initialization-sequence).
To determine which version, it will use the extension:
File extension | Type | HTML Code
--- | -- |
`.js` | All-in-one javascript file (function) | ``
!!! Warning
In that case, the `version` parameter is ignored.
## Deploying Mermaid.js with the MkDocs website
In case you wish to use local version of the Mermaid.js library,
you can do so.
```yaml
plugins:
- search
- mermaid2:
javascript: js/mermaid.min.js
```
The path is relative to the docs directory of Mkdocs. In the above example:
mkdocs.yaml
├─ docs/
│ ├─ index.md
│ ├─ ...
│ ├─ js/
│ │ ├─ mermaid.min.js
The typical way to download the library from unpkg or cdn.jsdelivr.net,
changing the version number to determine the version you want
(here: **10.2.0**):
```
https://cdn.jsdelivr.net/npm/mermaid@10.2.0/dist/mermaid.min.js
```
!!! Note
No explicit call to `mermaid.initialize()` is required, since it is
automatically inserted by the plugin.
!!! Warning "Use the .js file"
The recommended way to do this, is to work with the file that contains
the traditional, all-in-one package that ends with `.js`.
It **may** be possible to use the full ESM module (with a reference to
the script that ends with `.mjs`). That would require, however,
downloading the whole directory structure. Using the `.mjs` file
on its ownlwill definitely **not** work, since there will be broken
links.
!!! Warning "Behavior in case of incorrect URL/no Internet access"
1. An incorrect URL will cause an error that aborts MkDocs.
2. If the address starts with http(s) and no Internet access
is available at time of compile, MkDocs-Mermaid will continue and issue
a WARNING. That behavior is for containers that do not
have necessarily have Internet access at compile time
(however, if you want to abort
in that case use the strict mode: `mkdocs build --strict`.
## Using `extra_javascript`
Mkdocs, by default, provides a standard mechanism for inserting a library into the
HTML pages, which relies on the
[parameter `extra_javascript` in the config file](https://mkdocs.readthedocs.io/en/859/user-guide/configuration/#extra_javascript).
!!! Warning "DEPRECATED in default cases"
As of version 1.1.0 of Mkdocs-Mermaid2,
using `extra_javascript` in the config file
as the default solution to explictly call
the Mermaid javascript library is **DEPRECATED**.
Use instead the standard config of Mkdocs-Mermaid2 parameters.
!!! Important "Failsafe mechanism"
However, `extra_javascript` was not kept only
as a backward compatibility measure.
Its purpose is now to be a **failsafe mechanism**.
**If Mkdocs-Mermaid2 detects a name of library that contains the
word `mermaid`, it will deactivate its own automatic/manual
insertion mecanism and fall back on the standard mechanism of MkDocs.**
You can (and possibly should) use `extra_javascript` mechanism,
if the standard defaults
of MkDocs-Plugin do not match your needs.
```yaml
extra_javascript:
- https://unpkg.com/mermaid@8.8.2/dist/mermaid.min.js
```
It still works for versions > 10:
```yaml
extra_javascript:
- https://unpkg.com/mermaid@10.4.0/dist/mermaid.min.js
```
or (if using a local version):
```yaml
extra_javascript:
- js/mermaid.min.js
```
(where the path is relative to the docs directory.)
!!! Note "Going 'full manual'?"
If you feel that you need the flexibility of the `extra_javascript`
parameter,
you might start to weigh the pros and cons of using MkDocs-Mermaid2
as a plugin.
You might want to go "full manual",
**and deactivate the Mkdocs-Mermaid2 plugin.**
Or on the contrary, if you are using the **Material theme**, you might consider
[using its default config for Mermaid](https://squidfunk.github.io/mkdocs-material/reference/diagrams/)
(if it works better for you).
!!! Warning "Workaround for versions of MkDocs < 1.5"
> _Versions of MkDocs < 1.5.0 were unable to call the ESM library._
The best solution is to call the `.js` file:
```yaml
extra_javascript:
- https://unpkg.com/mermaid@10.2.0/dist/mermaid.min.js
```
If you **really** want to use the ESM module,
you could declare a local script file:
```yaml
extra_javascript:
- js/mermaidloader.js
```
(where `js` is a subdirectory of the docs directory.)
`mermaidloader.js` must contains the code for the import statement:
```javascript
import mermaid from "https://unpkg.com/mermaid@10.0.2/dist/mermaid.esm.min.mjs"
```
================================================
FILE: webdoc/docs/superfences.md
================================================
# Using the mermaid2 with Superfences
## Introduction
[Superfences](https://facelessuser.github.io/pymdown-extensions/extensions/superfences/) is a markdown extension that allows a better management
of code blocks, particularly syntax highlighting for the different languages.
!!! Warning
Do not use the [codehilite](https://python-markdown.github.io/extensions/code_hilite/) markdown extension, as it is deprecated in this context.
Hence, for a Python code block:
```python
import foo.bar
```
It belongs to the PyMdown extension package (see [installation instructions](https://facelessuser.github.io/pymdown-extensions/installation/)) created
by [facelessuser](https://github.com/facelessuser).
!!! Danger "Caution with Superfences"
The problem is that if you activate Superfences, you will deactivate
automatically the display of Mermaid diagrams (they will simply be
color-highlighted), **unless** you specify an exception for those diagrams,
called a **custom_fence**.
Hence the code:
```mermaid
graph LR
hello --> world
world --> again
again --> hello
```
Will be highlighted instead of being displayed!
See the next paragraph, for how to do that.
!!! Important
The Superfences extension is **not** mandatory, its main purpose
is to allow highlighting in code blocks.
It is, however, [**recommended** for the Material theme](#usage-for-the-material-theme).
## Specifying the Mermaid custom fence
Hence, to speciy the custom fence in the configuration file:
```yaml
markdown_extensions:
...
- pymdownx.superfences:
# make exceptions to highlighting of code:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:mermaid2.fence_mermaid
```
Each time a code block of `mermaid` type is found in the markdown,
then the code will **not** be highlighted, but transformed into a diagram.
This is done by the `fence_mermaid` function provided by mermaid2,
which encloses the Mermaid code
in the following way (in alignment with the plugin's policy):
...
!!! Note "Important"
1. For better results with the Material theme, use the `fence_mermaid_custom`
function (see below).
2. Do not use `fence_mermaid_custom` with themes other than Material, as
this will prevent the Mermaid diagrams from displaying.
3. Superfences is slightly more demanding with
HTML tags inside a mermaid diagram:
**take care to always close the HTML tags that require it**
(e.g. `` must have its corresponding `` tag).
Otherwise, the extension system will attempt to close those tags
and it will break the diagram.
## Usage for the Material theme
The [Material theme](https://squidfunk.github.io/mkdocs-material/), developed by [squidfunk](https://github.com/squidfunk), is designed out of the box
[so as to exploit the Mermaid.js library](https://squidfunk.github.io/mkdocs-material/reference/diagrams/).
A beautiful feature is that the color theme will be reflected
on the mermaid diagram, with a much better rendering of the diagrams
according to the palette.
It will also use proper colors for Mermaid diagrams if you use a **dark mode**
in the theme (`scheme: slate`) e.g., in the Config file:
```yaml
theme:
# name: readthedocs
name: material
language: en
palette:
scheme: slate
primary: red
accent: pink
```
!!! Important "Recommended usage with Material theme"
This requires, however,
1. The use of the Superfences extension.
2. To use the default `` representation, and
not the `` representation used by mkdocs-mermaid2.
**This is achieved by using the `fence_mermaid_custom` function.**
Hence in the configuration file:
```yaml
markdown_extensions:
...
- pymdownx.superfences:
# make exceptions to highlighting of code:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:mermaid2.fence_mermaid_custom
```
================================================
FILE: webdoc/docs/tips.md
================================================
# Tips and Tricks
## Advanced Mermaid Functions
### Setting the security level to "loose"
To access the following functions, you need to relax mermaid's security level,
([since version 8.2](https://mermaid-js.github.io/mermaid/#/?id=special-note-regarding-version-82)).
!!! Caution
This requires you, of course, to take the 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:
```yaml
- mermaid2:
arguments:
securityLevel: 'loose'
```
### Formatting text in diagrams
> To enable this function, you need to [relax mermaid's security level to 'loose'](#setting-the-security-level-to-loose).
You may use HTML in the diagram.
!!! Caution
This is guaranteed to work with Mermaid 8.6.4, but
does not work e.g. on 8.7.0.
It may not work on more recent versions.
Use HTML formatting:
```mermaid
graph LR
hello["Hello"] --> world["World"]
world --> mermaid[mermaid web site]
```
```mermaid
graph LR
hello["Hello"] --> world["World"]
world --> mermaid[mermaid web site]
```
Use this in the config file:
```yaml
extra_javascript:
- https://unpkg.com/mermaid@8.6.4/dist/mermaid.min.js
```
### Adding Hyperlinks to a Diagram
> To enable this function, you need to [relax mermaid's security level to 'loose'](#setting-the-security-level-to-loose).
=== "Mermaid.js >~ 8.5.0"
Use the **click** directive in the language (for more information,
see [Interaction](https://mermaid-js.github.io/mermaid/#/flowchart?id=interaction) on the official mermaid website).
```mermaid
graph LR
hello --> world
world --> mermaid[mermaid web site]
click mermaid "https://mermaid-js.github.io/mermaid" "Website"
```
```mermaid
graph LR
hello --> world
world --> mermaid[mermaid web site]
click mermaid "https://mermaid-js.github.io/mermaid" "Website"
```
=== "Mermaid.js < ~ 8.5.0"
It is possible to add hyperlinks to a diagram, e.g.:
```
box1[An important link]
```
## Using variables and macros in diagrams (MkDocs-Macros)
### Variables
What if your diagrams contain a repetitive string, such as the URL of a website
[in your hyperlinks](#adding-hyperlinks-to-a-diagram)?
Instead of writing:
```
graph TD;
Platform-->Gaming;
click Gaming "http://127.0.0.1:8000/Gaming/";
```
You might want to use a **variable**:
```
graph TD;
Platform-->Gaming;
click Gaming "{{ my_website }}/Gaming/";
```
You define that variable in your project's config file (`mkdocs.yml`):
```yaml
extra:
my_website: http://127.0.0.1:8000
```
In this way, you will be able to change that value wherever it appears in the pages,
simply by modifying the value in the config file.
To do that, you would have to use the [Mkdocs-Macros plugin](https://mkdocs-macros-plugin.readthedocs.io/).
This requires [installing the plugin](https://mkdocs-macros-plugin.readthedocs.io/en/latest/#standard-installation), and declaring it in the config file.
!!! Caution
Variables are **not** part of the Mermaid specification. The Macros plugin simply expands the variables in the
Markdown page, so that the result is a standard Mermaid diagram.
Declare the plugins in the config file, in that order:
```yaml
plugins:
- search
- macros
- mermaid2
```
!!! Tip "Uses of variables"
You can use an MkDocs-Macros variable to represent _any_ string that you need to repeat
in Mermaid diagrams, or that could change (over time, or because you have two possible configs).
Variables can be used in any part of a page, inside or outside of Mermaid diagrams.
MkDocs-Macros and Mkdocs-Mermaid2 are two plugins that work very well together.
Read the documentation of [MkDocs-Macros](https://mkdocs-macros-plugin.readthedocs.io/),
to discover all its possibilities!
### Using macros to generate Mermaid code
If you can program in Python, you could go further than that with MkDocs-Macros:
you could use a Python module (`main.py`) to define
[**macros** (functions)](https://mkdocs-macros-plugin.readthedocs.io/en/latest/macros/)
that produce hyperlinks or pieces of diagrams from data,
or even complete diagrams from a source file.
For example the macro `make_choice()` would create a full diagram from three components.
```python
def define_env(env):
@env.macro
def make_choice(start, choice1, choice2):
"""
Generate a Mermaid decision diagram with two choices from a starting point,
within a fenced code block.
"""
lines = [
"```mermaid",
"graph TD",
f" {start} -->|first| {choice1}",
f" {start} -->|second| {choice2}",
"```"
]
return "\n".join(lines)
```
Then you could write, in your markdown page:
```markdown
{{ make_choice("Start", "OptionA", "OptionB") }}
```
Which would be translated into:
```mermaid
graph TD
Start -->|first| OptionA
Start -->|second| OptionB
```
And then rendered by your browser as:
```mermaid
graph TD
Start -->|first| OptionA
Start -->|second| OptionB
```
## Switching between light and dark mode
### Auto-configure dark mode based on Host OS
Using a combination of the unquote (`^`) functionality of this plugin and the
[prefers-color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme)
CSS media feature, one can have the plugin automatically enable dark mode.
```yaml
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](https://squidfunk.github.io/mkdocs-material/) and referenced in [their documentation](https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#color-scheme).
### Material Theme: Switching on the fly between light and dark mode
The Material theme for MkDocs allows [toggling between colors](https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#color-palette-toggle).
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](#auto-configure-dark-mode-based-on-host-os),
though that earlier, simpler solution cannot toggle dynamically.
A workable solution has been proposed by [elgalu](https://github.com/elgalu)
(for more information see [Issue 39](https://github.com/fralau/mkdocs-mermaid2-plugin/issues/39)).
**`mkdocs.yml`**
(The palette is an example, where primary color, accent, icons, toggle message, etc. can be adapted to your needs.)
```yaml
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 of `mermaid.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`):
```javascript
var paletteSwitcher1 = document.getElementById("__palette_1");
var paletteSwitcher2 = document.getElementById("__palette_2");
paletteSwitcher1.addEventListener("change", function () {
location.reload();
});
paletteSwitcher2.addEventListener("change", function () {
location.reload();
});
```
================================================
FILE: webdoc/docs/troubleshooting.md
================================================
## Important notice
If mermaid diagrams are not displayed correctly, or not displayed at all
**read this section first**!
## Mermaid diagram is not displayed (or displayed incorrectly)
!!! Tip
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]
```
```mermaid
graph TD
A[Client] --> B[Load Balancer]
B --> C[Server01]
B --> D[Server02]
```
!!! Notes
1. Every diagram should start with a valid preamble, e.g. `graph TD`.
2. In case of doubt, you may want to test your diagram in the
[Mermaid Live Editor](https://mermaid-js.github.io/mermaid-live-editor)
3. Note, however, that the Mermaid Live Editor **does not
support loose mode** (with HTML code in the mermaid code).
### Seeing an error message at the place of the diagram?
In recent versions of the javascript library (> 8.6.0), a pretty
error message is displayed in case of incorrect syntax:

!!! Note
In earlier versions, the library displayed nothing, which
could be confusing.
If you see the error message, it is at least an indication that
the mermaid javascript library was called.
### The mermaid source code appears as-is (not read)?
In that case, the javascript library was probably not called.
!!! Tip
**Examine the HTML code produced in the page and see the next questions.**
### Using superfences, but no diagram is displayed?
If you are using the superfences extension, but you see the source
code, you probably forgot to declare the custom_fences, or declared the wrong
one.
See more explanations under [Declaring the superfences extension](superfences.md#specifying-the-mermaid-custom-fence)
!!! Tip
**Examine the HTML code produced in the page and see the next questions.**
### Is mkdocs' version up to date (>= 1.1) ?
!!! Note
As an absolute minimum, you should use a version of mkdocs > 1.1.
A version >= 1.5 is recommended.
To determine the version, use `mkdocs -V`.
To update mkdocs:
pip install mkdocs --upgrade
Or, if you cloned the repo:
python setup.py install
### Is the javascript library properly called?
In order to work, the proper javascript library must called from
the html page (by default, the call is inserted automatically).
Control the link used in the HTML page generated, e.g.:
```HTML
```
### 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](index.md/#specifying-the-version-of-the-mermaid-library).
### The arguments in the config file (color, etc.) do not work
For example, the following specification ([see description](index.md/#other-themes)) does not work:
```yaml
plugins:
- search
- mermaid2:
version: '10.1.0'
arguments:
theme: 'dark'
themeVariables:
primaryColor: '#BB2528'
primaryTextColor: '#fff'
primaryBorderColor: '#7C0000'
lineColor: '#F8B229'
secondaryColor: '#006100'
tertiaryColor: '#fff'
```
Due to the change of javascript library format as of mermaid.js **as of
version 10.0**, this did not work any more (but it worked for lower versions).
This was fixed in version 1.0.8 of the mkdocs-mermaid2 library
([see github issue for a full description](https://github.com/mermaid-js/mermaid/issues/4672)).
**Upgrade mkdocs-mermaid2 to the most recent version.**
### What if nothing worked?
1. Check the [test cases](https://github.com/fralau/mkdocs-mermaid2-plugin/tree/1ab72b5c6a5acf35cc702b7d85019b08678a52e2/test) on the github repository
and try to run them on your machine;
start with the `simple` website.
2. Open a question on the [discussion page for the project](https://github.com/fralau/mkdocs-mermaid2-plugin/discussions).
## Explicit calls of the Mermaid library with `extra_javascript`
> For reference information see the [`extra_javascript` section](library.md/#using-extra_javascript)
> in the JavaScript page.
!!! Tip "Easy Fix"
**Upgrade Mkdocs and Mkdocs-Macros to the latest
version and stop using `extra_javascript`. Use the [`javascript` parameter instead](library.md)**.
Otherwise, read on.
!!! Warning "Important"
If you [specify the version number in the config file](index.md/#specifying-the-version-of-the-mermaid-library),
then the mkdocs-mermaid2 will insert the correct calls for you.
Remember that explicit calls to the Mermaid.js
(through `extra_javascript` in the config file) are **optional**
and are considered a **hack** (failsafe) mecanism
for cases when the default procedure doesn't work.
**As of version 1.1 of Mkdocs-Mermaid2 the use of `extra_javascript` is DEPRECATED, as a default solution.**
Use the [`javascript` parameter instead](library.md).
### Issues with versions
**Mermaid.js**: Above version 10.0.0, [the official format for the Mermaid library is ESM](https://github.com/mermaid-js/mermaid/releases/tag/v10.0.0).
**MkDocs**: Under version 1.5.0, the `extra_javascript` directive in the config
file (`mkdocs.yml`) does not process ESM libraries correctly.
### Version of Mermaid.js < 10
All versions of mkdocs manage correctly the traditional call to javascript
code.
``` html
```
You _may_ specify the mermaid library explicitly in the config file,
as long as it is call mermaid (independently of extension):
```yaml
extra_javascript:
- https://unpkg.com/mermaid@8.8.2/dist/mermaid.min.js
```
This will be translated in the final HTML page as:
```html
```
=== "MkDocs < 1.5.0"
Versions of MkDocs < 1.5.0 translate the call into `