From 5032ab8016b86995c15a8c2170b845f16b4adc96 Mon Sep 17 00:00:00 2001 From: Christian Grett Date: Mon, 29 Jul 2024 14:57:25 +0200 Subject: [PATCH] feat: support node name for non-captioned --- README.rst | 2 ++ sphinxcontrib/mermaid.py | 53 ++++++++++++++++-------------- tests/roots/test-basic/index.rst | 1 + tests/roots/test-basic/zoom.rst | 1 + tests/roots/test-markdown/index.md | 6 +++- tests/test_html.py | 24 ++++---------- 6 files changed, 44 insertions(+), 43 deletions(-) diff --git a/README.rst b/README.rst index 382a85a..1cc33fe 100644 --- a/README.rst +++ b/README.rst @@ -119,6 +119,8 @@ Then add ``sphinxcontrib.mermaid`` in ``extensions`` list of your project's ``co Directive options ------------------ +``:name:``: determines the image's name (id) for HTML output. + ``:alt:``: determines the image's alternate text for HTML output. If not given, the alternate text defaults to the mermaid code. ``:align:``: determines the image's position. Valid options are ``'left'``, ``'center'``, ``'right'`` diff --git a/sphinxcontrib/mermaid.py b/sphinxcontrib/mermaid.py index 971c18a..62dde4b 100644 --- a/sphinxcontrib/mermaid.py +++ b/sphinxcontrib/mermaid.py @@ -13,14 +13,14 @@ import codecs import errno import os -import shlex import posixpath import re +import shlex +import uuid from hashlib import sha1 from json import loads from subprocess import PIPE, Popen from tempfile import TemporaryDirectory -import uuid import sphinx from docutils import nodes @@ -115,6 +115,7 @@ class Mermaid(Directive): final_argument_whitespace = False option_spec = { # Sphinx directives + "name": directives.unchanged, "alt": directives.unchanged, "align": align_spec, "caption": directives.unchanged, @@ -200,9 +201,10 @@ def run(self, **kwargs): node["code"] = mm_config + node["code"] caption = self.options.get("caption") - if caption: + if caption is not None: node = figure_wrapper(self, node, caption) + self.add_name(node) return [node] @@ -298,28 +300,29 @@ def render_mm(self, code, options, _fmt, prefix="mermaid"): def _render_mm_html_raw( self, node, code, options, prefix="mermaid", imgcls=None, alt=None ): - if "align" in node and "zoom_id" in node: - tag_template = """
-            {code}
-        
- """ - elif "align" in node and "zoom_id" not in node: - tag_template = """
-            {code}
-        
- """ - elif "align" not in node and "zoom_id" in node: - tag_template = """
-            {code}
-        
- """ - else: - tag_template = """
-            {code}
-        
""" + classes = ["mermaid"] + attrs = {} + + if "align" in node: + classes.append(f"align-{node['align']}") + attrs["align"] = node["align"] + if "zoom_id" in node: + attrs["data-zoom-id"] = node["zoom_id"] + + if "ids" in node and len(node["ids"]) == 1: + attrs["id"] = node["ids"][0] + + tag_template = """
+        {code}
+    
""" + attr_defs = ["{}=\"{}\"".format(k, v) for k, v in attrs.items()] self.body.append( - tag_template.format(align=node.get("align"), zoom_id=node.get("zoom_id"), code=self.encode(code)) + tag_template.format( + attr_defs=" ".join(attr_defs), + classes=" ".join(classes), + code=self.encode(code) + ) ) raise nodes.SkipNode @@ -540,9 +543,9 @@ def install_js( if "zoom_id" in mermaid_node: _zoom_id = mermaid_node["zoom_id"] if _d3_selector == "": - _d3_selector += f".mermaid#{_zoom_id} svg" + _d3_selector += f".mermaid[data-zoom-id={_zoom_id}] svg" else: - _d3_selector += f", .mermaid#{_zoom_id} svg" + _d3_selector += f", .mermaid[data-zoom-id={_zoom_id}] svg" count += 1 if _d3_selector != "": _d3_js_script = _MERMAID_RUN_D3_ZOOM.format(d3_selector=_d3_selector, d3_node_count=count, mermaid_js_url=_mermaid_js_url) diff --git a/tests/roots/test-basic/index.rst b/tests/roots/test-basic/index.rst index b2954a7..ead2621 100644 --- a/tests/roots/test-basic/index.rst +++ b/tests/roots/test-basic/index.rst @@ -2,6 +2,7 @@ Hi, basic test -------------- .. mermaid:: + :name: participants sequenceDiagram participant Alice diff --git a/tests/roots/test-basic/zoom.rst b/tests/roots/test-basic/zoom.rst index 093ef3d..20189a4 100644 --- a/tests/roots/test-basic/zoom.rst +++ b/tests/roots/test-basic/zoom.rst @@ -3,6 +3,7 @@ Zooming ------- .. mermaid:: + :name: participants sequenceDiagram participant Alice diff --git a/tests/roots/test-markdown/index.md b/tests/roots/test-markdown/index.md index dabd04a..322f02c 100644 --- a/tests/roots/test-markdown/index.md +++ b/tests/roots/test-markdown/index.md @@ -1,7 +1,11 @@ # Hi from Markdown! ```{mermaid} -:align: center +--- +align: center +name: participants +--- + sequenceDiagram participant Alice participant Bob diff --git a/tests/test_html.py b/tests/test_html.py index 9ff1501..b881bb9 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -1,6 +1,7 @@ -import pytest import re +import pytest + @pytest.fixture def build_all(app): @@ -22,12 +23,7 @@ def test_html_raw(index): ) assert '' in index assert ( - """
-            sequenceDiagram
-   participant Alice
-   participant Bob
-   Alice->John: Hello John, how are you?
-        
""" + '
\n        sequenceDiagram\n   participant Alice\n   participant Bob\n   Alice->John: Hello John, how are you?\n    
' in index ) @@ -40,13 +36,13 @@ def test_html_zoom_option(index, app): assert "svg.call(zoom);" in zoom_page # the first diagram has no id - assert '
\n            sequenceDiagram' in zoom_page
+    assert '
\n        sequenceDiagram' in zoom_page
 
     # the second has id and its loaded in the zooming code.
     pre_id = re.findall(
-        r'
\n\s+flowchart TD', zoom_page
+        r'
\n\s+flowchart TD', zoom_page
     )
-    assert f'var svgs = d3.selectAll(".mermaid#{pre_id[0]} svg")' in zoom_page
+    assert f'var svgs = d3.selectAll(".mermaid[data-zoom-id={pre_id[0]}] svg")' in zoom_page
 
 
 @pytest.mark.sphinx("html", testroot="basic", confoverrides={"mermaid_d3_zoom": True})
@@ -126,12 +122,6 @@ def test_html_raw_from_markdown(index):
     )
     assert '' in index
     assert (
-        """
-
-                sequenceDiagram
-      participant Alice
-      participant Bob
-      Alice->John: Hello John, how are you?
-        
""" + '
\n            sequenceDiagram\n      participant Alice\n      participant Bob\n      Alice->John: Hello John, how are you?\n    
' in index )