Skip to content

Commit

Permalink
Add a new parameter javascript to the mermaid config
Browse files Browse the repository at this point in the history
  - it contains a url or local javascript file (relative to docs dir)
  - extra_javascript still allowed (and bypasses the new mechanism),
    but is now DEPRECATED
  • Loading branch information
Laurent Franceschetti committed Aug 30, 2023
1 parent 70b52d0 commit e48544e
Show file tree
Hide file tree
Showing 11 changed files with 3,531 additions and 58 deletions.
122 changes: 73 additions & 49 deletions mermaid2/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
# Constants and utilities
# ------------------------
# the default (recommended) mermaid lib
MERMAID_LIB_VERSION = '10.1.0'
# MERMAID_LIB = "https://unpkg.com/mermaid@%s/dist/mermaid.min.js"
MERMAID_LIB_PRE_10 = "https://unpkg.com/mermaid@%s/dist/mermaid.min.js"
MERMAID_LIB = "https://unpkg.com/mermaid@%s/dist/mermaid.esm.min.mjs"
JAVASCRIPT_VERSION = '10.1.0'
JAVASCRIPT_PRE_10 = "https://unpkg.com/mermaid@%s/dist/mermaid.min.js"
JAVASCRIPT = "https://unpkg.com/mermaid@%s/dist/mermaid.esm.min.mjs"



Expand All @@ -40,7 +39,8 @@ class MarkdownMermaidPlugin(BasePlugin):
"""
config_scheme = (

('version', PluginType(str, default=MERMAID_LIB_VERSION)),
('version', PluginType(str, default=JAVASCRIPT_VERSION)),
('javascript', PluginType(str, default=None)),
('arguments', PluginType(dict, default={})),
# ('custom_loader', PluginType(bool, default=False))
)
Expand Down Expand Up @@ -70,9 +70,9 @@ def mermaid_version(self) -> str:
"""
The version of mermaid
This information comes from the YAML file parameter,
or, if empty, from MERMAID_LIB_VERSION.
or, if empty, from JAVASCRIPT_VERSION.
"""
version = self.config['version']
version = self.config['version'] or JAVASCRIPT_VERSION
assert version, "No correct version of mermaid is provided!"
return version

Expand All @@ -89,41 +89,60 @@ def mermaid_major_version(self) -> int:


@property
def extra_mermaid_lib(self) -> str:
def extra_javascript(self) -> str:
"""
Provides the mermaid library defined in mkdocs.yml (if any)
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.
"""
# 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:
# get the actual library name
if libname(lib) == 'mermaid':
return lib
return ''
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 mermaid_lib(self) -> str:
def javascript(self) -> str:
"""
Provides the url of mermaid library according to version
(distinction between version < 10 and after)
Provides the url/pathanme of mermaid library according to version
(distinction on the default, between version < 10 and after)
"""
if not hasattr(self, '_mermaid_lib'):
if self.mermaid_major_version < 10:
mermaid_lib = MERMAID_LIB_PRE_10 % self.mermaid_version
else:
# newer versions
mermaid_lib = MERMAID_LIB % self.mermaid_version
# make checks
if not url_exists(mermaid_lib):
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" %
mermaid_lib)
self._mermaid_lib = mermaid_lib
return self._mermaid_lib
javascript)
self._javascript = javascript
return self._javascript


@property
Expand Down Expand Up @@ -186,13 +205,18 @@ def on_config(self, config):
assert isinstance(self.mermaid_args, dict)
info("Initialization arguments:", self.mermaid_args)
# info on the javascript library:
if self.extra_mermaid_lib:
info("Explicit mermaid javascript library:\n ",
self.extra_mermaid_lib)
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.mermaid_lib)
self.javascript)

def on_post_page(self, output_content, config, page, **kwargs):
"""
Expand Down Expand Up @@ -239,23 +263,23 @@ def on_post_page(self, output_content, config, page, **kwargs):
# insertion of the <script> tag, with the initialization arguments
new_tag = soup.new_tag("script")
js_code = [] # the code lines
if not self.extra_mermaid_lib:
if not self.extra_javascript:
# if no extra library mentioned,
# add the <SCRIPT> tag needed for mermaid
info("Adding call to script for version"
f"{self.mermaid_version}.")
if self.mermaid_major_version < 10:
# <script src="...">
new_tag['src'] = self.mermaid_lib
# it's necessary to close and reopen the tag:
soup.body.append(new_tag)
new_tag = soup.new_tag("script")
else:
if self.javascript.endswith('.mjs'):
# <script type="module">
# import mermaid from ...
new_tag['type'] = "module"
js_code.append('import mermaid from "%s";'
% self.mermaid_lib)
% self.javascript)
else:
# <script src="...">
# generally for self.mermaid_major_version < 10:
new_tag['src'] = self.javascript
# it's necessary to close and reopen the tag:
soup.body.append(new_tag)
new_tag = soup.new_tag("script")

# (self.mermaid_args), as found in the config file.
if self.activate_custom_loader:
# if the superfences extension is present, use the specific loader
Expand Down
9 changes: 6 additions & 3 deletions mermaid2/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,21 @@ def info(*args) -> str:
# Paths and URLs
# -------------------
def libname(lib:str) -> str:
"Get the library name from a path"
"Get the library name from a path -- not used"
basename = os.path.basename(lib)
# remove extension three times, e.g. mermaid.min.js => mermaid
t = basename
for _ in range(3):
t = os.path.splitext(t)[0]
return t

def url_exists(url:str) -> bool:


def url_exists(url:str, local_base_dir:str='') -> bool:
"Checks that a url exists"
if url.startswith('http'):
request = requests.get(url)
return request.status_code == 200
else:
os.path.exists(url)
pathname = os.path.join(local_base_dir, url)
return os.path.exists(pathname)
10 changes: 4 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from setuptools import setup, find_packages


VERSION = '1.0.8'
VERSION = '1.0.9'

# required if you want to run tests
# pip install 'mkdocs-mermaid2-plugin[test]'
Expand All @@ -16,9 +16,7 @@ def readme():

LONG_DESCRIPTION = (
"An Mkdocs plugin that renders Mermaid graphs in the markdown file. "
"To install, please follow instructions in the Readme file.\n"
"This is a fork of the Pugong Liu's excellent project, "
"which is no longer maintained."
"To install, please follow instructions in the README file."
)

setup(
Expand All @@ -28,8 +26,8 @@ def readme():
long_description=LONG_DESCRIPTION,
keywords='mkdocs python markdown mermaid',
url='https://github.com/fralau/mkdocs-mermaid2-plugin',
author='pugong, Fralau',
author_email='pugong.liu@gmail.com, fralau2035@yahoo.com',
author='Fralau',
author_email='fralau@bluewin.ch',
license='MIT',
python_requires='>=3.6',
install_requires=[
Expand Down
39 changes: 39 additions & 0 deletions test/extra_javascript/docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Mermaid test (simple)

## Mermaid usual
This is a test of Mermaid:

```mermaid
graph TD
hello --> world
world --> world2
```

> If you don't see a graph here, it's broken.
## Git Graph
This is a test of Git Graph:

```mermaid
gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit
```


## Normal fences
This is usual fenced code (with no highlighting)

```python
for page in pages:
page.read()
```

1,642 changes: 1,642 additions & 0 deletions test/extra_javascript/docs/js/mermaid.min.js

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions test/extra_javascript/docs/second.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Second page
Testing special cases

## Wrong diagram

```mermaid
graph FG
A[Client]
```

## Correct

```mermaid
graph TD
A[Client] --> B[Load Balancer]
```

## Other

```mermaid
graph TD
A[Client] --> B[Load Balancer]
B --> C[Server01]
B --> D[Server02]
```
19 changes: 19 additions & 0 deletions test/extra_javascript/mkdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
site_name: Mermaid test (simple, extra_javascript)
site_description: Test for mermaid
docs_dir: docs # indispensable or readthedocs will fail
theme: readthedocs # you may want to try windmill?


nav:
- Main: index.md
- Second: second.md

plugins:
- search
- mermaid2

extra_javascript:
- js/mermaid.min.js



39 changes: 39 additions & 0 deletions test/local_lib/docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Mermaid test (simple)

## Mermaid usual
This is a test of Mermaid:

```mermaid
graph TD
hello --> world
world --> world2
```

> If you don't see a graph here, it's broken.
## Git Graph
This is a test of Git Graph:

```mermaid
gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit
```


## Normal fences
This is usual fenced code (with no highlighting)

```python
for page in pages:
page.read()
```

1,642 changes: 1,642 additions & 0 deletions test/local_lib/docs/js/mermaid.min.js

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions test/local_lib/docs/second.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Second page
Testing special cases

## Wrong diagram

```mermaid
graph FG
A[Client]
```

## Correct

```mermaid
graph TD
A[Client] --> B[Load Balancer]
```

## Other

```mermaid
graph TD
A[Client] --> B[Load Balancer]
B --> C[Server01]
B --> D[Server02]
```
Loading

0 comments on commit e48544e

Please sign in to comment.