Skip to content

Commit ea23a51

Browse files
committed
feat: add configurability for drawio diagram and url handling
1 parent a09d1f1 commit ea23a51

File tree

9 files changed

+131
-32
lines changed

9 files changed

+131
-32
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,20 @@ Sergey ([onixpro](https://github.com/onixpro)) is the original creator of this p
1010
This plugin enables you to embed interactive drawio diagrams in your documentation. Simply add your diagrams like you would any other image:
1111

1212
```markdown
13+
You can either use diagrams hosted within your own docs. Absolute as well as relative paths are allowed:
14+
15+
Absolute path:
16+
![](/assets/my-diagram.drawio)
17+
18+
Same directory as the markdown file:
1319
![](my-diagram.drawio)
20+
21+
Relative directory to the markdown file:
22+
![](../my-diagram.drawio)
23+
24+
25+
Or you can use external urls:
26+
![](https://example.com/diagram.drawio)
1427
```
1528

1629
Additionally this plugin supports multi page diagrams by using the `alt` text to select the pages by name:
@@ -47,6 +60,16 @@ plugins:
4760
viewer_js: "https://viewer.diagrams.net/js/viewer-static.min.js"
4861
```
4962
63+
Further options are:
64+
65+
```yaml
66+
plugins:
67+
- drawio:
68+
toolbar: true # control if hovering on a diagram shows a toolbar for zooming or not (default: true)
69+
tooltips: true # control if tooltips will be shown (default: true)
70+
border: 10 # increase or decrease the border / margin around your diagrams (default: 5)
71+
```
72+
5073
## Material Integration
5174
5275
If you are using the Material Theme and want to use the [instant-loading](https://squidfunk.github.io/mkdocs-material/setup/setting-up-navigation/?h=instant#instant-loading) feature. You will have to configure the following:
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Test config settings
2+
3+
You should be able to use the `tooltips: true|false` config flag in your `mkdocs.yml` to control if tooltips should be shown or not:
4+
![](tooltips.drawio)
5+
6+
You should be able to see a mathematical expressions properly rendered:
7+
![](math.drawio)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" version="24.7.7">
2+
<diagram id="sWgCjdYztQFh1ezxrF-R" name="Page-1">
3+
<mxGraphModel dx="963" dy="1401" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0">
4+
<root>
5+
<mxCell id="0" />
6+
<mxCell id="1" parent="0" />
7+
<mxCell id="cVhbZjsc7NjAtHNjXZGz-10" value="&lt;span style=&quot;color: rgb(232, 62, 140); font-family: SFMono-Regular, Menlo, Monaco, Consolas, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;&quot;&gt;LaTeX \(\sqrt{3×-1}+(1+x)^2\) and AsciiMath `a^b + b^2 = c^2`&lt;/span&gt;" style="text;whiteSpace=wrap;html=1;" vertex="1" parent="1">
8+
<mxGeometry x="110" y="100" width="210" height="50" as="geometry" />
9+
</mxCell>
10+
</root>
11+
</mxGraphModel>
12+
</diagram>
13+
</mxfile>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" version="24.7.7">
2+
<diagram id="sWgCjdYztQFh1ezxrF-R" name="Page-1">
3+
<mxGraphModel dx="963" dy="1401" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
4+
<root>
5+
<mxCell id="0" />
6+
<mxCell id="1" parent="0" />
7+
<mxCell id="2" value="a" style="whiteSpace=wrap;html=1;aspect=fixed;" parent="1" vertex="1">
8+
<mxGeometry x="80" y="60" width="80" height="80" as="geometry" />
9+
</mxCell>
10+
<mxCell id="3" value="" style="endArrow=classic;startArrow=classic;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="2" target="4" edge="1">
11+
<mxGeometry width="50" height="50" relative="1" as="geometry">
12+
<mxPoint x="320" y="160" as="sourcePoint" />
13+
<mxPoint x="380" y="140" as="targetPoint" />
14+
</mxGeometry>
15+
</mxCell>
16+
<mxCell id="4" value="c" style="ellipse;whiteSpace=wrap;html=1;" parent="1" vertex="1">
17+
<mxGeometry x="310" y="60" width="120" height="80" as="geometry" />
18+
</mxCell>
19+
<mxCell id="5" value="" style="whiteSpace=wrap;html=1;aspect=fixed;" parent="1" vertex="1">
20+
<mxGeometry x="360" y="250" width="80" height="80" as="geometry" />
21+
</mxCell>
22+
<mxCell id="6" value="" style="triangle;whiteSpace=wrap;html=1;" parent="1" vertex="1">
23+
<mxGeometry x="110" y="250" width="60" height="80" as="geometry" />
24+
</mxCell>
25+
<UserObject label="Hover over me." tooltip="Hello I&#39;m a tooltip." id="cVhbZjsc7NjAtHNjXZGz-8">
26+
<mxCell style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
27+
<mxGeometry x="210" y="190" width="110" height="30" as="geometry" />
28+
</mxCell>
29+
</UserObject>
30+
</root>
31+
</mxGraphModel>
32+
</diagram>
33+
</mxfile>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Test to use url instead of file path
2+
3+
![](http://127.0.0.1:8000/tests/assets/test.drawio)

example/mkdocs-material.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ nav:
66
- Tests:
77
- Simple Diagram: 'tests/simple-diagram/index.md'
88
- Error Handling: 'tests/error-handling/index.md'
9+
- Configuration: 'tests/configuration/index.md'
910
- Code Blocks: 'tests/code-blocks/index.md'
1011
- Relative Paths (a): 'tests/relative-paths/index.md'
1112
- Relative Paths (b): 'tests/relative-paths/example.md'
1213
- Pagging: 'tests/pagging/index.md'
14+
- External URL: 'tests/external-url/index.md'
1315

1416
theme:
1517
name: material
@@ -22,7 +24,9 @@ extra_javascript:
2224

2325
plugins:
2426
- search
25-
- drawio
27+
- drawio:
28+
tooltips: true
29+
border: 20
2630
- print-site
2731

2832
repo_url: https://github.com/tuunit/mkdocs-drawio

example/mkdocs.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,19 @@ nav:
66
- Tests:
77
- Simple Diagram: 'tests/simple-diagram/index.md'
88
- Error Handling: 'tests/error-handling/index.md'
9+
- Configuration: 'tests/configuration/index.md'
910
- Code Blocks: 'tests/code-blocks/index.md'
1011
- Relative Paths (a): 'tests/relative-paths/index.md'
1112
- Relative Paths (b): 'tests/relative-paths/example.md'
1213
- Pagging: 'tests/pagging/index.md'
14+
- External URL: 'tests/external-url/index.md'
1315

1416
plugins:
1517
- search
16-
- drawio
18+
- drawio:
19+
toolbar: true
20+
tooltips: true
21+
border: 20
1722
- print-site
1823

1924
repo_url: https://github.com/tuunit/mkdocs-drawio

mkdocs_drawio/plugin.py

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import re
2+
import json
23
import mkdocs
34
import string
45
import logging
56
from lxml import etree
7+
from typing import Dict
8+
from html import escape
69
from pathlib import Path
710
from bs4 import BeautifulSoup
811
from mkdocs.plugins import BasePlugin
@@ -11,7 +14,7 @@
1114
# Constants and utilities
1215
# ------------------------
1316
SUB_TEMPLATE = string.Template(
14-
'<div class="mxgraph" style="max-width:100%;border:1px solid transparent;" data-mxgraph="{&quot;highlight&quot;:&quot;#0000ff&quot;,&quot;nav&quot;:true,&quot;resize&quot;:true,&quot;toolbar&quot;:&quot;zoom layers tags lightbox&quot;,&quot;edit&quot;:&quot;_blank&quot;,&quot;xml&quot;:&quot;$xml_drawio&quot;}"></div>'
17+
'<div class="mxgraph" style="max-width:100%;border:1px solid transparent;" data-mxgraph="$config"></div>'
1518
)
1619

1720
LOGGER = logging.getLogger("mkdocs.plugins.diagrams")
@@ -25,26 +28,31 @@ class DrawioPlugin(BasePlugin):
2528
"""
2629

2730
config_scheme = (
28-
(
29-
"viewer_js",
30-
mkdocs.config.config_options.Type(
31-
str, default="https://viewer.diagrams.net/js/viewer-static.min.js"
32-
),
33-
),
31+
("viewer_js",mkdocs.config.config_options.Type(str, default="https://viewer.diagrams.net/js/viewer-static.min.js")),
32+
("toolbar",mkdocs.config.config_options.Type(bool, default=True)),
33+
("tooltips",mkdocs.config.config_options.Type(bool, default=True)),
34+
("border",mkdocs.config.config_options.Type(int, default=0)),
3435
)
3536

3637
def on_post_page(self, output_content, config, page, **kwargs):
3738
return self.render_drawio_diagrams(output_content, page)
3839

3940
def render_drawio_diagrams(self, output_content, page):
4041
if ".drawio" not in output_content.lower():
41-
# Skip unecessary HTML parsing
4242
return output_content
4343

4444
plugin_config = self.config.copy()
4545

4646
soup = BeautifulSoup(output_content, "html.parser")
4747

48+
diagram_config = {
49+
"toolbar": "zoom" if plugin_config["toolbar"] else None,
50+
"tooltips": "1" if plugin_config["tooltips"] else "0",
51+
"border": plugin_config["border"] + 5,
52+
"resize": "1",
53+
"edit": "_blank",
54+
}
55+
4856
# search for images using drawio extension
4957
diagrams = soup.findAll("img", src=re.compile(r".*\.drawio$", re.IGNORECASE))
5058
if len(diagrams) == 0:
@@ -57,31 +65,44 @@ def render_drawio_diagrams(self, output_content, page):
5765
# substitute images with embedded drawio diagram
5866
path = Path(page.file.abs_dest_path).parent
5967

68+
6069
for diagram in diagrams:
61-
diagram.replace_with(
62-
BeautifulSoup(
63-
DrawioPlugin.substitute_image(path, diagram["src"], diagram["alt"]),
70+
if re.search("^https?://", diagram["src"]):
71+
mxgraph = BeautifulSoup(
72+
DrawioPlugin.substitute_with_url(diagram_config, diagram["src"]),
6473
"html.parser",
6574
)
66-
)
75+
else:
76+
mxgraph = BeautifulSoup(
77+
DrawioPlugin.substitute_with_file(diagram_config, path, diagram["src"], diagram["alt"]),
78+
"html.parser",
79+
)
80+
81+
diagram.replace_with(mxgraph)
6782

6883
return str(soup)
6984

7085
@staticmethod
71-
def substitute_image(path: Path, src: str, alt: str):
86+
def substitute_with_url(config: Dict, url: str) -> str:
87+
config["url"] = url
88+
89+
return SUB_TEMPLATE.substitute(config=escape(json.dumps(config)))
90+
91+
@staticmethod
92+
def substitute_with_file(config: Dict, path: Path, src: str, alt: str) -> str:
7293
try:
7394
diagram_xml = etree.parse(path.joinpath(src).resolve())
7495
except Exception:
7596
LOGGER.error(f"Error: Provided diagram file '{src}' on path '{path}' is not a valid diagram")
7697
diagram_xml = etree.fromstring('<invalid/>')
7798

78-
diagram = DrawioPlugin.parse_diagram(diagram_xml, alt, src, path)
79-
escaped_xml = DrawioPlugin.escape_diagram(diagram)
99+
diagram = DrawioPlugin.parse_diagram(diagram_xml, alt)
100+
config["xml"]=diagram
80101

81-
return SUB_TEMPLATE.substitute(xml_drawio=escaped_xml)
102+
return SUB_TEMPLATE.substitute(config=escape(json.dumps(config)))
82103

83104
@staticmethod
84-
def parse_diagram(data, alt, src="", path=None):
105+
def parse_diagram(data, alt, src="", path=None) -> str:
85106
if alt is None or len(alt) == 0:
86107
return etree.tostring(data, encoding=str)
87108

@@ -104,13 +125,3 @@ def parse_diagram(data, alt, src="", path=None):
104125
except Exception:
105126
LOGGER.error(f"Error: Could not properly parse page name '{alt}' for diagram '{src}' on path '{path}'")
106127
return ""
107-
108-
@staticmethod
109-
def escape_diagram(str_xml: str):
110-
str_xml = str_xml.replace("&", r"&amp;")
111-
str_xml = str_xml.replace("<", r"&lt;")
112-
str_xml = str_xml.replace(">", r"&gt;")
113-
str_xml = str_xml.replace('"', r"\&quot;")
114-
str_xml = str_xml.replace("'", r"&apos;")
115-
str_xml = str_xml.replace("\n", r"")
116-
return str_xml

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
[tool.poetry]
22
name = "mkdocs-drawio"
3-
version = "1.6.5"
3+
version = "1.7.0"
44
description = "MkDocs plugin for embedding Drawio files"
55
authors = [
6-
"Sergey Lukin <onixpro@gmail.com>",
7-
"Jan Larwig <jan@larwig.com>"
6+
"Jan Larwig <jan@larwig.com>",
7+
"Sergey Lukin <onixpro@gmail.com>"
88
]
99
license = "MIT"
1010
readme = "README.md"

0 commit comments

Comments
 (0)