From 281dc458acf60a689dc41c3218af09dd4b585660 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 4 May 2026 09:18:42 +0000
Subject: [PATCH 1/7] Initial plan
From 119b6134a1943467ac956b99eebc4efba09a39e7 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 4 May 2026 09:23:46 +0000
Subject: [PATCH 2/7] add mermaid sphinx extension with tests and docs
Agent-Logs-Url: https://github.com/sdpython/sphinx-runpython/sessions/d8720735-e1ac-42f5-8f74-5cb189420a5e
Co-authored-by: xadupre <22452781+xadupre@users.noreply.github.com>
---
_doc/api/index.rst | 1 +
_doc/api/mermaid.rst | 77 ++++++
_doc/conf.py | 2 +
.../ut_mermaid/test_mermaid_extension.py | 127 +++++++++
sphinx_runpython/mermaid/__init__.py | 3 +
.../mermaid/sphinx_mermaid_extension.py | 245 ++++++++++++++++++
6 files changed, 455 insertions(+)
create mode 100644 _doc/api/mermaid.rst
create mode 100644 _unittests/ut_mermaid/test_mermaid_extension.py
create mode 100644 sphinx_runpython/mermaid/__init__.py
create mode 100644 sphinx_runpython/mermaid/sphinx_mermaid_extension.py
diff --git a/_doc/api/index.rst b/_doc/api/index.rst
index c386747..92ed542 100644
--- a/_doc/api/index.rst
+++ b/_doc/api/index.rst
@@ -15,6 +15,7 @@ Extensions
docassert
epkg
gdot
+ mermaid
quote
runpython
tools
diff --git a/_doc/api/mermaid.rst b/_doc/api/mermaid.rst
new file mode 100644
index 0000000..98fa1fb
--- /dev/null
+++ b/_doc/api/mermaid.rst
@@ -0,0 +1,77 @@
+=======
+mermaid
+=======
+
+This directive displays `Mermaid
element."""
+ content = """
+before
+
+.. mermaid::
+
+ graph LR
+ A --> B
+
+after
+"""
+ html = rst2html(
+ content, writer_name="html", new_extensions=["sphinx_runpython.mermaid"]
+ )
+ self.assertIn('class="mermaid"', html)
+ self.assertIn("graph LR", html)
+ self.assertIn("A --> B", html)
+
+ @ignore_warnings(PendingDeprecationWarning)
+ def test_mermaid_script(self):
+ """Script-generated mermaid diagram is included in the RST output."""
+ content = """
+before
+
+.. mermaid::
+ :script:
+
+ print(\"\"\"graph LR
+ X --> Y\"\"\")
+
+after
+"""
+ content = rst2html(
+ content, writer_name="rst", new_extensions=["sphinx_runpython.mermaid"]
+ )
+ self.assertIn("graph LR", content)
+ self.assertIn("X --> Y", content)
+
+ @ignore_warnings(PendingDeprecationWarning)
+ def test_mermaid_script_split(self):
+ """When :script: has a value it is used as a split token."""
+ content = """
+before
+
+.. mermaid::
+ :script: BEGIN
+
+ print("preamble")
+ print("BEGIN")
+ print("graph TD")
+ print(" P --> Q")
+
+after
+"""
+ content = rst2html(
+ content, writer_name="rst", new_extensions=["sphinx_runpython.mermaid"]
+ )
+ self.assertNotIn("preamble", content)
+ self.assertNotIn("BEGIN", content)
+ self.assertIn("graph TD", content)
+ self.assertIn("P --> Q", content)
+
+ @ignore_warnings(PendingDeprecationWarning)
+ def test_mermaid_script_cache(self):
+ """Identical scripts produce the same output and are cached."""
+ script_body = 'print("graph LR\\n A --> B")'
+ content = f"""
+before
+
+.. mermaid::
+ :script:
+
+ {script_body}
+
+middle
+
+.. mermaid::
+ :script:
+
+ {script_body}
+
+after
+"""
+ content = rst2html(
+ content, writer_name="rst", new_extensions=["sphinx_runpython.mermaid"]
+ )
+ count = content.count("graph LR")
+ self.assertEqual(count, 2, f"Expected diagram code twice, got {count}")
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/sphinx_runpython/mermaid/__init__.py b/sphinx_runpython/mermaid/__init__.py
new file mode 100644
index 0000000..d5cc656
--- /dev/null
+++ b/sphinx_runpython/mermaid/__init__.py
@@ -0,0 +1,3 @@
+from .sphinx_mermaid_extension import setup
+
+__all__ = ["setup"]
diff --git a/sphinx_runpython/mermaid/sphinx_mermaid_extension.py b/sphinx_runpython/mermaid/sphinx_mermaid_extension.py
new file mode 100644
index 0000000..721c739
--- /dev/null
+++ b/sphinx_runpython/mermaid/sphinx_mermaid_extension.py
@@ -0,0 +1,245 @@
+import hashlib
+import logging
+from docutils import nodes
+from docutils.parsers.rst import directives, Directive
+import sphinx
+from ..ext_helper import get_env_state_info
+from ..runpython.sphinx_runpython_extension import run_python_script
+
+logger = logging.getLogger("mermaid")
+
+#: Default CDN URL for the mermaid JavaScript library.
+_MERMAID_JS_URL = "https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"
+
+
+class mermaid_node(nodes.General, nodes.Element):
+ """
+ Defines ``mermaid`` node.
+ """
+
+ pass
+
+
+class MermaidDirective(Directive):
+ """
+ A ``mermaid`` node displays a `Mermaid `_ diagram.
+
+ For *HTML* output the diagram is rendered client-side by embedding the
+ Mermaid JavaScript library (loaded from a CDN or a local copy).
+ For *LaTeX* / *text* / *RST* output the raw Mermaid source is included.
+
+ Supported options:
+
+ * *script*: boolean or a string that marks the beginning of the Mermaid
+ source in the standard output of the embedded Python script. When this
+ option is present the directive body is interpreted as Python code whose
+ ``stdout`` contains the diagram definition.
+ * *process*: run the Python script in a separate process.
+
+ Example – inline diagram::
+
+ .. mermaid::
+
+ graph LR
+ A --> B --> C
+
+ Which gives:
+
+ .. mermaid::
+
+ graph LR
+ A --> B --> C
+
+ Example – script-generated diagram::
+
+ .. mermaid::
+ :script:
+
+ print(\"\"\"
+ graph LR
+ A --> B
+ \"\"\")
+
+ .. mermaid::
+ :script:
+
+ print(\"\"\"
+ graph LR
+ A --> B
+ \"\"\")
+ """
+
+ node_class = mermaid_node
+ has_content = True
+ required_arguments = 0
+ optional_arguments = 0
+ final_argument_whitespace = False
+ option_spec = {
+ "script": directives.unchanged,
+ "process": directives.unchanged,
+ }
+
+ def run(self):
+ """Build the mermaid node."""
+ bool_set_ = (True, 1, "True", "1", "true", "")
+ process = "process" in self.options and self.options["process"] in bool_set_
+
+ info = get_env_state_info(self)
+ docname = info["docname"]
+
+ if "script" in self.options:
+ script = self.options["script"]
+ if script in (0, "0", "False", "false"):
+ script = None
+ elif script in (1, "1", "True", "true", ""):
+ script = ""
+ elif len(script) == 0:
+ raise RuntimeError(
+ "script should be a string to indicate"
+ " the beginning of the Mermaid diagram."
+ )
+ else:
+ script = False
+
+ # Execute the script and use its stdout as diagram source, if requested.
+ content = "\n".join(self.content)
+ if script or script == "":
+ env = info.get("env")
+ doc_prefix = docname.split("/")[-1] if docname else ""
+ cache_key = (
+ f"{doc_prefix}:"
+ + hashlib.sha256(f"{content}:{process}".encode()).hexdigest()
+ )
+ if env is not None:
+ if not hasattr(env, "mermaid_script_cache"):
+ env.mermaid_script_cache = {}
+ cached = env.mermaid_script_cache.get(cache_key, None)
+ else:
+ cached = None
+
+ if cached is not None:
+ stdout, stderr = cached
+ else:
+ stdout, stderr, _ = run_python_script(content, process=process)
+ if env is not None:
+ env.mermaid_script_cache[cache_key] = (stdout, stderr)
+
+ if stderr:
+ logger.warning(
+ "[mermaid] a diagram cannot be drawn due to %s", stderr
+ )
+ content = stdout
+ if script:
+ spl = content.split(script)
+ if len(spl) > 2:
+ logger.warning("[mermaid] too many output lines %s", content)
+ content = spl[-1]
+
+ node = mermaid_node(code=content, options={"docname": docname})
+ return [node]
+
+
+# ---------------------------------------------------------------------------
+# Visitor helpers
+# ---------------------------------------------------------------------------
+
+
+def visit_mermaid_node_html(self, node):
+ """Render the mermaid node in HTML output."""
+ code = node["code"].strip()
+ # Emit a block; mermaid.js will replace it at runtime.
+ self.body.append(
+ f''
+ f'{self.encode(code)}'
+ f"\n"
+ )
+ raise nodes.SkipNode
+
+
+def depart_mermaid_node_html(self, node):
+ """depart – not called because visit raises SkipNode."""
+
+
+def visit_mermaid_node_rst(self, node):
+ """Render the mermaid node in RST output."""
+ self.new_state(0)
+ self.add_text(".. mermaid::" + self.nl)
+ self.new_state(self.indent)
+ for row in node["code"].split("\n"):
+ self.add_text(row + self.nl)
+
+
+def depart_mermaid_node_rst(self, node):
+ """depart mermaid node in RST output."""
+ self.end_state()
+ self.end_state(wrap=False)
+
+
+def visit_mermaid_node_text(self, node):
+ """Render the mermaid node in plain-text output."""
+ self.new_state(0)
+ self.add_text("[mermaid diagram]\n")
+ self.new_state(self.indent)
+ for row in node["code"].split("\n"):
+ self.add_text(row + self.nl)
+
+
+def depart_mermaid_node_text(self, node):
+ """depart mermaid node in text output."""
+ self.end_state()
+ self.end_state(wrap=False)
+
+
+def visit_mermaid_node_latex(self, node):
+ """Render the mermaid node in LaTeX output (verbatim source)."""
+ code = node["code"].strip()
+ self.body.append("\n\\begin{verbatim}\n")
+ self.body.append(code)
+ self.body.append("\n\\end{verbatim}\n")
+ raise nodes.SkipNode
+
+
+def depart_mermaid_node_latex(self, node):
+ """depart – not called because visit raises SkipNode."""
+
+
+# ---------------------------------------------------------------------------
+# JS injection
+# ---------------------------------------------------------------------------
+
+
+def add_mermaid_js(app):
+ """Inject the Mermaid JS library into HTML pages."""
+ if app.builder.format != "html":
+ return
+ app.add_js_file(_MERMAID_JS_URL, **{"loading_method": "async"})
+ # Initialise mermaid after the DOM is ready.
+ app.add_js_file(
+ None,
+ body="document.addEventListener('DOMContentLoaded', function() { mermaid.initialize({startOnLoad: true}); });",
+ )
+
+
+# ---------------------------------------------------------------------------
+# Extension setup
+# ---------------------------------------------------------------------------
+
+
+def setup(app):
+ """
+ setup for ``mermaid`` (sphinx)
+ """
+ app.connect("builder-inited", add_mermaid_js)
+
+ app.add_node(
+ mermaid_node,
+ html=(visit_mermaid_node_html, depart_mermaid_node_html),
+ epub=(visit_mermaid_node_html, depart_mermaid_node_html),
+ latex=(visit_mermaid_node_latex, depart_mermaid_node_latex),
+ text=(visit_mermaid_node_text, depart_mermaid_node_text),
+ rst=(visit_mermaid_node_rst, depart_mermaid_node_rst),
+ md=(visit_mermaid_node_text, depart_mermaid_node_text),
+ )
+
+ app.add_directive("mermaid", MermaidDirective)
+ return {"version": sphinx.__display_version__, "parallel_read_safe": True}
From a58837a89b04c5cbc9c7b55bb1efc173410b9724 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 4 May 2026 09:25:41 +0000
Subject: [PATCH 3/7] fix unreachable branch and improve docstrings in mermaid
extension
Agent-Logs-Url: https://github.com/sdpython/sphinx-runpython/sessions/d8720735-e1ac-42f5-8f74-5cb189420a5e
Co-authored-by: xadupre <22452781+xadupre@users.noreply.github.com>
---
sphinx_runpython/mermaid/sphinx_mermaid_extension.py | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/sphinx_runpython/mermaid/sphinx_mermaid_extension.py b/sphinx_runpython/mermaid/sphinx_mermaid_extension.py
index 721c739..9a9af03 100644
--- a/sphinx_runpython/mermaid/sphinx_mermaid_extension.py
+++ b/sphinx_runpython/mermaid/sphinx_mermaid_extension.py
@@ -93,11 +93,7 @@ def run(self):
script = None
elif script in (1, "1", "True", "true", ""):
script = ""
- elif len(script) == 0:
- raise RuntimeError(
- "script should be a string to indicate"
- " the beginning of the Mermaid diagram."
- )
+ # else: keep script as-is to use it as a split token
else:
script = False
@@ -157,7 +153,7 @@ def visit_mermaid_node_html(self, node):
def depart_mermaid_node_html(self, node):
- """depart – not called because visit raises SkipNode."""
+ """Depart the mermaid HTML node. Not called because the visitor raises SkipNode."""
def visit_mermaid_node_rst(self, node):
@@ -200,7 +196,7 @@ def visit_mermaid_node_latex(self, node):
def depart_mermaid_node_latex(self, node):
- """depart – not called because visit raises SkipNode."""
+ """Depart the mermaid LaTeX node. Not called because the visitor raises SkipNode."""
# ---------------------------------------------------------------------------
From 975cd5561d01a962eab1d6f7b8256a33bc103123 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 4 May 2026 09:34:05 +0000
Subject: [PATCH 4/7] rename mermaid to mermaidjs to avoid conflicts with
existing packages
Agent-Logs-Url: https://github.com/sdpython/sphinx-runpython/sessions/0b9e316d-85dd-491f-a8fe-fcb57e2c1479
Co-authored-by: xadupre <22452781+xadupre@users.noreply.github.com>
---
_doc/api/index.rst | 2 +-
_doc/api/{mermaid.rst => mermaidjs.rst} | 20 ++---
_doc/conf.py | 2 +-
.../test_mermaidjs_extension.py} | 42 ++++-----
sphinx_runpython/mermaid/__init__.py | 3 -
sphinx_runpython/mermaidjs/__init__.py | 3 +
.../sphinx_mermaidjs_extension.py} | 88 +++++++++----------
7 files changed, 80 insertions(+), 80 deletions(-)
rename _doc/api/{mermaid.rst => mermaidjs.rst} (81%)
rename _unittests/{ut_mermaid/test_mermaid_extension.py => ut_mermaidjs/test_mermaidjs_extension.py} (76%)
delete mode 100644 sphinx_runpython/mermaid/__init__.py
create mode 100644 sphinx_runpython/mermaidjs/__init__.py
rename sphinx_runpython/{mermaid/sphinx_mermaid_extension.py => mermaidjs/sphinx_mermaidjs_extension.py} (68%)
diff --git a/_doc/api/index.rst b/_doc/api/index.rst
index 92ed542..35d8aa1 100644
--- a/_doc/api/index.rst
+++ b/_doc/api/index.rst
@@ -15,7 +15,7 @@ Extensions
docassert
epkg
gdot
- mermaid
+ mermaidjs
quote
runpython
tools
diff --git a/_doc/api/mermaid.rst b/_doc/api/mermaidjs.rst
similarity index 81%
rename from _doc/api/mermaid.rst
rename to _doc/api/mermaidjs.rst
index 98fa1fb..c6d5d79 100644
--- a/_doc/api/mermaid.rst
+++ b/_doc/api/mermaidjs.rst
@@ -1,6 +1,6 @@
-=======
-mermaid
-=======
+=========
+mermaidjs
+=========
This directive displays `Mermaid `_ diagrams in the documentation.
Diagrams are rendered client-side in *HTML* output via the Mermaid JavaScript library
@@ -14,21 +14,21 @@ In *conf.py*:
::
extensions = [ ...
- 'sphinx_runpython.mermaid',
+ 'sphinx_runpython.mermaidjs',
]
One example:
::
- .. mermaid::
+ .. mermaidjs::
graph LR
A --> B --> C
Which gives:
-.. mermaid::
+.. mermaidjs::
graph LR
A --> B --> C
@@ -38,7 +38,7 @@ Option *script* must be specified:
::
- .. mermaid::
+ .. mermaidjs::
:script:
print("""
@@ -46,7 +46,7 @@ Option *script* must be specified:
A --> B
""")
-.. mermaid::
+.. mermaidjs::
:script:
print("""
@@ -60,7 +60,7 @@ as Mermaid source:
::
- .. mermaid::
+ .. mermaidjs::
:script: AFTER-THIS
print("preamble")
@@ -74,4 +74,4 @@ a separate process.
Directive
=========
-.. autoclass:: sphinx_runpython.mermaid.sphinx_mermaid_extension.MermaidDirective
+.. autoclass:: sphinx_runpython.mermaidjs.sphinx_mermaidjs_extension.MermaidDirective
diff --git a/_doc/conf.py b/_doc/conf.py
index b87a8b3..53e13f6 100644
--- a/_doc/conf.py
+++ b/_doc/conf.py
@@ -25,7 +25,7 @@
"sphinx_runpython.docassert",
"sphinx_runpython.gdot",
"sphinx_runpython.epkg",
- "sphinx_runpython.mermaid",
+ "sphinx_runpython.mermaidjs",
"sphinx_runpython.quote",
"sphinx_runpython.runpython",
"sphinx_runpython.sphinx_rst_builder",
diff --git a/_unittests/ut_mermaid/test_mermaid_extension.py b/_unittests/ut_mermaidjs/test_mermaidjs_extension.py
similarity index 76%
rename from _unittests/ut_mermaid/test_mermaid_extension.py
rename to _unittests/ut_mermaidjs/test_mermaidjs_extension.py
index edcded2..9610d9a 100644
--- a/_unittests/ut_mermaid/test_mermaid_extension.py
+++ b/_unittests/ut_mermaidjs/test_mermaidjs_extension.py
@@ -7,18 +7,18 @@
)
-class TestMermaidExtension(ExtTestCase):
+class TestMermaidJsExtension(ExtTestCase):
def setUp(self):
- logger = logging.getLogger("mermaid")
+ logger = logging.getLogger("mermaidjs")
logger.disabled = True
@ignore_warnings(PendingDeprecationWarning)
- def test_mermaid_inline_rst(self):
- """Inline mermaid diagram is round-tripped through the RST writer."""
+ def test_mermaidjs_inline_rst(self):
+ """Inline mermaidjs diagram is round-tripped through the RST writer."""
content = """
before
-.. mermaid::
+.. mermaidjs::
graph LR
A --> B --> C
@@ -26,18 +26,18 @@ def test_mermaid_inline_rst(self):
after
"""
content = rst2html(
- content, writer_name="rst", new_extensions=["sphinx_runpython.mermaid"]
+ content, writer_name="rst", new_extensions=["sphinx_runpython.mermaidjs"]
)
self.assertIn("graph LR", content)
self.assertIn("A --> B --> C", content)
@ignore_warnings(PendingDeprecationWarning)
- def test_mermaid_inline_html(self):
- """Inline mermaid diagram produces a element."""
+ def test_mermaidjs_inline_html(self):
+ """Inline mermaidjs diagram produces a element."""
content = """
before
-.. mermaid::
+.. mermaidjs::
graph LR
A --> B
@@ -45,19 +45,19 @@ def test_mermaid_inline_html(self):
after
"""
html = rst2html(
- content, writer_name="html", new_extensions=["sphinx_runpython.mermaid"]
+ content, writer_name="html", new_extensions=["sphinx_runpython.mermaidjs"]
)
self.assertIn('class="mermaid"', html)
self.assertIn("graph LR", html)
self.assertIn("A --> B", html)
@ignore_warnings(PendingDeprecationWarning)
- def test_mermaid_script(self):
- """Script-generated mermaid diagram is included in the RST output."""
+ def test_mermaidjs_script(self):
+ """Script-generated mermaidjs diagram is included in the RST output."""
content = """
before
-.. mermaid::
+.. mermaidjs::
:script:
print(\"\"\"graph LR
@@ -66,18 +66,18 @@ def test_mermaid_script(self):
after
"""
content = rst2html(
- content, writer_name="rst", new_extensions=["sphinx_runpython.mermaid"]
+ content, writer_name="rst", new_extensions=["sphinx_runpython.mermaidjs"]
)
self.assertIn("graph LR", content)
self.assertIn("X --> Y", content)
@ignore_warnings(PendingDeprecationWarning)
- def test_mermaid_script_split(self):
+ def test_mermaidjs_script_split(self):
"""When :script: has a value it is used as a split token."""
content = """
before
-.. mermaid::
+.. mermaidjs::
:script: BEGIN
print("preamble")
@@ -88,7 +88,7 @@ def test_mermaid_script_split(self):
after
"""
content = rst2html(
- content, writer_name="rst", new_extensions=["sphinx_runpython.mermaid"]
+ content, writer_name="rst", new_extensions=["sphinx_runpython.mermaidjs"]
)
self.assertNotIn("preamble", content)
self.assertNotIn("BEGIN", content)
@@ -96,20 +96,20 @@ def test_mermaid_script_split(self):
self.assertIn("P --> Q", content)
@ignore_warnings(PendingDeprecationWarning)
- def test_mermaid_script_cache(self):
+ def test_mermaidjs_script_cache(self):
"""Identical scripts produce the same output and are cached."""
script_body = 'print("graph LR\\n A --> B")'
content = f"""
before
-.. mermaid::
+.. mermaidjs::
:script:
{script_body}
middle
-.. mermaid::
+.. mermaidjs::
:script:
{script_body}
@@ -117,7 +117,7 @@ def test_mermaid_script_cache(self):
after
"""
content = rst2html(
- content, writer_name="rst", new_extensions=["sphinx_runpython.mermaid"]
+ content, writer_name="rst", new_extensions=["sphinx_runpython.mermaidjs"]
)
count = content.count("graph LR")
self.assertEqual(count, 2, f"Expected diagram code twice, got {count}")
diff --git a/sphinx_runpython/mermaid/__init__.py b/sphinx_runpython/mermaid/__init__.py
deleted file mode 100644
index d5cc656..0000000
--- a/sphinx_runpython/mermaid/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from .sphinx_mermaid_extension import setup
-
-__all__ = ["setup"]
diff --git a/sphinx_runpython/mermaidjs/__init__.py b/sphinx_runpython/mermaidjs/__init__.py
new file mode 100644
index 0000000..b843779
--- /dev/null
+++ b/sphinx_runpython/mermaidjs/__init__.py
@@ -0,0 +1,3 @@
+from .sphinx_mermaidjs_extension import setup
+
+__all__ = ["setup"]
diff --git a/sphinx_runpython/mermaid/sphinx_mermaid_extension.py b/sphinx_runpython/mermaidjs/sphinx_mermaidjs_extension.py
similarity index 68%
rename from sphinx_runpython/mermaid/sphinx_mermaid_extension.py
rename to sphinx_runpython/mermaidjs/sphinx_mermaidjs_extension.py
index 9a9af03..44dfe2b 100644
--- a/sphinx_runpython/mermaid/sphinx_mermaid_extension.py
+++ b/sphinx_runpython/mermaidjs/sphinx_mermaidjs_extension.py
@@ -6,15 +6,15 @@
from ..ext_helper import get_env_state_info
from ..runpython.sphinx_runpython_extension import run_python_script
-logger = logging.getLogger("mermaid")
+logger = logging.getLogger("mermaidjs")
#: Default CDN URL for the mermaid JavaScript library.
_MERMAID_JS_URL = "https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"
-class mermaid_node(nodes.General, nodes.Element):
+class mermaidjs_node(nodes.General, nodes.Element):
"""
- Defines ``mermaid`` node.
+ Defines ``mermaidjs`` node.
"""
pass
@@ -22,7 +22,7 @@ class mermaid_node(nodes.General, nodes.Element):
class MermaidDirective(Directive):
"""
- A ``mermaid`` node displays a `Mermaid `_ diagram.
+ A ``mermaidjs`` node displays a `Mermaid `_ diagram.
For *HTML* output the diagram is rendered client-side by embedding the
Mermaid JavaScript library (loaded from a CDN or a local copy).
@@ -38,21 +38,21 @@ class MermaidDirective(Directive):
Example – inline diagram::
- .. mermaid::
+ .. mermaidjs::
graph LR
A --> B --> C
Which gives:
- .. mermaid::
+ .. mermaidjs::
graph LR
A --> B --> C
Example – script-generated diagram::
- .. mermaid::
+ .. mermaidjs::
:script:
print(\"\"\"
@@ -60,7 +60,7 @@ class MermaidDirective(Directive):
A --> B
\"\"\")
- .. mermaid::
+ .. mermaidjs::
:script:
print(\"\"\"
@@ -69,7 +69,7 @@ class MermaidDirective(Directive):
\"\"\")
"""
- node_class = mermaid_node
+ node_class = mermaidjs_node
has_content = True
required_arguments = 0
optional_arguments = 0
@@ -80,7 +80,7 @@ class MermaidDirective(Directive):
}
def run(self):
- """Build the mermaid node."""
+ """Build the mermaidjs node."""
bool_set_ = (True, 1, "True", "1", "true", "")
process = "process" in self.options and self.options["process"] in bool_set_
@@ -107,9 +107,9 @@ def run(self):
+ hashlib.sha256(f"{content}:{process}".encode()).hexdigest()
)
if env is not None:
- if not hasattr(env, "mermaid_script_cache"):
- env.mermaid_script_cache = {}
- cached = env.mermaid_script_cache.get(cache_key, None)
+ if not hasattr(env, "mermaidjs_script_cache"):
+ env.mermaidjs_script_cache = {}
+ cached = env.mermaidjs_script_cache.get(cache_key, None)
else:
cached = None
@@ -118,20 +118,20 @@ def run(self):
else:
stdout, stderr, _ = run_python_script(content, process=process)
if env is not None:
- env.mermaid_script_cache[cache_key] = (stdout, stderr)
+ env.mermaidjs_script_cache[cache_key] = (stdout, stderr)
if stderr:
logger.warning(
- "[mermaid] a diagram cannot be drawn due to %s", stderr
+ "[mermaidjs] a diagram cannot be drawn due to %s", stderr
)
content = stdout
if script:
spl = content.split(script)
if len(spl) > 2:
- logger.warning("[mermaid] too many output lines %s", content)
+ logger.warning("[mermaidjs] too many output lines %s", content)
content = spl[-1]
- node = mermaid_node(code=content, options={"docname": docname})
+ node = mermaidjs_node(code=content, options={"docname": docname})
return [node]
@@ -140,8 +140,8 @@ def run(self):
# ---------------------------------------------------------------------------
-def visit_mermaid_node_html(self, node):
- """Render the mermaid node in HTML output."""
+def visit_mermaidjs_node_html(self, node):
+ """Render the mermaidjs node in HTML output."""
code = node["code"].strip()
# Emit a block; mermaid.js will replace it at runtime.
self.body.append(
@@ -152,42 +152,42 @@ def visit_mermaid_node_html(self, node):
raise nodes.SkipNode
-def depart_mermaid_node_html(self, node):
- """Depart the mermaid HTML node. Not called because the visitor raises SkipNode."""
+def depart_mermaidjs_node_html(self, node):
+ """Depart the mermaidjs HTML node. Not called because the visitor raises SkipNode."""
-def visit_mermaid_node_rst(self, node):
- """Render the mermaid node in RST output."""
+def visit_mermaidjs_node_rst(self, node):
+ """Render the mermaidjs node in RST output."""
self.new_state(0)
- self.add_text(".. mermaid::" + self.nl)
+ self.add_text(".. mermaidjs::" + self.nl)
self.new_state(self.indent)
for row in node["code"].split("\n"):
self.add_text(row + self.nl)
-def depart_mermaid_node_rst(self, node):
- """depart mermaid node in RST output."""
+def depart_mermaidjs_node_rst(self, node):
+ """Depart mermaidjs node in RST output."""
self.end_state()
self.end_state(wrap=False)
-def visit_mermaid_node_text(self, node):
- """Render the mermaid node in plain-text output."""
+def visit_mermaidjs_node_text(self, node):
+ """Render the mermaidjs node in plain-text output."""
self.new_state(0)
- self.add_text("[mermaid diagram]\n")
+ self.add_text("[mermaidjs diagram]\n")
self.new_state(self.indent)
for row in node["code"].split("\n"):
self.add_text(row + self.nl)
-def depart_mermaid_node_text(self, node):
- """depart mermaid node in text output."""
+def depart_mermaidjs_node_text(self, node):
+ """Depart mermaidjs node in text output."""
self.end_state()
self.end_state(wrap=False)
-def visit_mermaid_node_latex(self, node):
- """Render the mermaid node in LaTeX output (verbatim source)."""
+def visit_mermaidjs_node_latex(self, node):
+ """Render the mermaidjs node in LaTeX output (verbatim source)."""
code = node["code"].strip()
self.body.append("\n\\begin{verbatim}\n")
self.body.append(code)
@@ -195,8 +195,8 @@ def visit_mermaid_node_latex(self, node):
raise nodes.SkipNode
-def depart_mermaid_node_latex(self, node):
- """Depart the mermaid LaTeX node. Not called because the visitor raises SkipNode."""
+def depart_mermaidjs_node_latex(self, node):
+ """Depart the mermaidjs LaTeX node. Not called because the visitor raises SkipNode."""
# ---------------------------------------------------------------------------
@@ -223,19 +223,19 @@ def add_mermaid_js(app):
def setup(app):
"""
- setup for ``mermaid`` (sphinx)
+ setup for ``mermaidjs`` (sphinx)
"""
app.connect("builder-inited", add_mermaid_js)
app.add_node(
- mermaid_node,
- html=(visit_mermaid_node_html, depart_mermaid_node_html),
- epub=(visit_mermaid_node_html, depart_mermaid_node_html),
- latex=(visit_mermaid_node_latex, depart_mermaid_node_latex),
- text=(visit_mermaid_node_text, depart_mermaid_node_text),
- rst=(visit_mermaid_node_rst, depart_mermaid_node_rst),
- md=(visit_mermaid_node_text, depart_mermaid_node_text),
+ mermaidjs_node,
+ html=(visit_mermaidjs_node_html, depart_mermaidjs_node_html),
+ epub=(visit_mermaidjs_node_html, depart_mermaidjs_node_html),
+ latex=(visit_mermaidjs_node_latex, depart_mermaidjs_node_latex),
+ text=(visit_mermaidjs_node_text, depart_mermaidjs_node_text),
+ rst=(visit_mermaidjs_node_rst, depart_mermaidjs_node_rst),
+ md=(visit_mermaidjs_node_text, depart_mermaidjs_node_text),
)
- app.add_directive("mermaid", MermaidDirective)
+ app.add_directive("mermaidjs", MermaidDirective)
return {"version": sphinx.__display_version__, "parallel_read_safe": True}
From 0a7c4b813bf48922ffd14159328966a2cb3e3979 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 4 May 2026 09:46:03 +0000
Subject: [PATCH 5/7] rename mermaidjs to runmermaid
Agent-Logs-Url: https://github.com/sdpython/sphinx-runpython/sessions/d779d538-fb95-4f79-ba03-95dfc33cf6e0
Co-authored-by: xadupre <22452781+xadupre@users.noreply.github.com>
---
_doc/api/index.rst | 2 +-
_doc/api/{mermaidjs.rst => runmermaid.rst} | 20 ++---
_doc/conf.py | 2 +-
.../test_runmermaid_extension.py} | 42 ++++-----
sphinx_runpython/mermaidjs/__init__.py | 3 -
sphinx_runpython/runmermaid/__init__.py | 3 +
.../sphinx_runmermaid_extension.py} | 90 +++++++++----------
7 files changed, 81 insertions(+), 81 deletions(-)
rename _doc/api/{mermaidjs.rst => runmermaid.rst} (80%)
rename _unittests/{ut_mermaidjs/test_mermaidjs_extension.py => ut_runmermaid/test_runmermaid_extension.py} (75%)
delete mode 100644 sphinx_runpython/mermaidjs/__init__.py
create mode 100644 sphinx_runpython/runmermaid/__init__.py
rename sphinx_runpython/{mermaidjs/sphinx_mermaidjs_extension.py => runmermaid/sphinx_runmermaid_extension.py} (68%)
diff --git a/_doc/api/index.rst b/_doc/api/index.rst
index 35d8aa1..f382c62 100644
--- a/_doc/api/index.rst
+++ b/_doc/api/index.rst
@@ -15,7 +15,7 @@ Extensions
docassert
epkg
gdot
- mermaidjs
+ runmermaid
quote
runpython
tools
diff --git a/_doc/api/mermaidjs.rst b/_doc/api/runmermaid.rst
similarity index 80%
rename from _doc/api/mermaidjs.rst
rename to _doc/api/runmermaid.rst
index c6d5d79..678fa4b 100644
--- a/_doc/api/mermaidjs.rst
+++ b/_doc/api/runmermaid.rst
@@ -1,6 +1,6 @@
-=========
-mermaidjs
-=========
+==========
+runmermaid
+==========
This directive displays `Mermaid `_ diagrams in the documentation.
Diagrams are rendered client-side in *HTML* output via the Mermaid JavaScript library
@@ -14,21 +14,21 @@ In *conf.py*:
::
extensions = [ ...
- 'sphinx_runpython.mermaidjs',
+ 'sphinx_runpython.runmermaid',
]
One example:
::
- .. mermaidjs::
+ .. runmermaid::
graph LR
A --> B --> C
Which gives:
-.. mermaidjs::
+.. runmermaid::
graph LR
A --> B --> C
@@ -38,7 +38,7 @@ Option *script* must be specified:
::
- .. mermaidjs::
+ .. runmermaid::
:script:
print("""
@@ -46,7 +46,7 @@ Option *script* must be specified:
A --> B
""")
-.. mermaidjs::
+.. runmermaid::
:script:
print("""
@@ -60,7 +60,7 @@ as Mermaid source:
::
- .. mermaidjs::
+ .. runmermaid::
:script: AFTER-THIS
print("preamble")
@@ -74,4 +74,4 @@ a separate process.
Directive
=========
-.. autoclass:: sphinx_runpython.mermaidjs.sphinx_mermaidjs_extension.MermaidDirective
+.. autoclass:: sphinx_runpython.runmermaid.sphinx_runmermaid_extension.RunMermaidDirective
diff --git a/_doc/conf.py b/_doc/conf.py
index 53e13f6..81756aa 100644
--- a/_doc/conf.py
+++ b/_doc/conf.py
@@ -25,7 +25,7 @@
"sphinx_runpython.docassert",
"sphinx_runpython.gdot",
"sphinx_runpython.epkg",
- "sphinx_runpython.mermaidjs",
+ "sphinx_runpython.runmermaid",
"sphinx_runpython.quote",
"sphinx_runpython.runpython",
"sphinx_runpython.sphinx_rst_builder",
diff --git a/_unittests/ut_mermaidjs/test_mermaidjs_extension.py b/_unittests/ut_runmermaid/test_runmermaid_extension.py
similarity index 75%
rename from _unittests/ut_mermaidjs/test_mermaidjs_extension.py
rename to _unittests/ut_runmermaid/test_runmermaid_extension.py
index 9610d9a..d6fa250 100644
--- a/_unittests/ut_mermaidjs/test_mermaidjs_extension.py
+++ b/_unittests/ut_runmermaid/test_runmermaid_extension.py
@@ -7,18 +7,18 @@
)
-class TestMermaidJsExtension(ExtTestCase):
+class TestRunMermaidExtension(ExtTestCase):
def setUp(self):
- logger = logging.getLogger("mermaidjs")
+ logger = logging.getLogger("runmermaid")
logger.disabled = True
@ignore_warnings(PendingDeprecationWarning)
- def test_mermaidjs_inline_rst(self):
- """Inline mermaidjs diagram is round-tripped through the RST writer."""
+ def test_runmermaid_inline_rst(self):
+ """Inline runmermaid diagram is round-tripped through the RST writer."""
content = """
before
-.. mermaidjs::
+.. runmermaid::
graph LR
A --> B --> C
@@ -26,18 +26,18 @@ def test_mermaidjs_inline_rst(self):
after
"""
content = rst2html(
- content, writer_name="rst", new_extensions=["sphinx_runpython.mermaidjs"]
+ content, writer_name="rst", new_extensions=["sphinx_runpython.runmermaid"]
)
self.assertIn("graph LR", content)
self.assertIn("A --> B --> C", content)
@ignore_warnings(PendingDeprecationWarning)
- def test_mermaidjs_inline_html(self):
- """Inline mermaidjs diagram produces a element."""
+ def test_runmermaid_inline_html(self):
+ """Inline runmermaid diagram produces a element."""
content = """
before
-.. mermaidjs::
+.. runmermaid::
graph LR
A --> B
@@ -45,19 +45,19 @@ def test_mermaidjs_inline_html(self):
after
"""
html = rst2html(
- content, writer_name="html", new_extensions=["sphinx_runpython.mermaidjs"]
+ content, writer_name="html", new_extensions=["sphinx_runpython.runmermaid"]
)
self.assertIn('class="mermaid"', html)
self.assertIn("graph LR", html)
self.assertIn("A --> B", html)
@ignore_warnings(PendingDeprecationWarning)
- def test_mermaidjs_script(self):
- """Script-generated mermaidjs diagram is included in the RST output."""
+ def test_runmermaid_script(self):
+ """Script-generated runmermaid diagram is included in the RST output."""
content = """
before
-.. mermaidjs::
+.. runmermaid::
:script:
print(\"\"\"graph LR
@@ -66,18 +66,18 @@ def test_mermaidjs_script(self):
after
"""
content = rst2html(
- content, writer_name="rst", new_extensions=["sphinx_runpython.mermaidjs"]
+ content, writer_name="rst", new_extensions=["sphinx_runpython.runmermaid"]
)
self.assertIn("graph LR", content)
self.assertIn("X --> Y", content)
@ignore_warnings(PendingDeprecationWarning)
- def test_mermaidjs_script_split(self):
+ def test_runmermaid_script_split(self):
"""When :script: has a value it is used as a split token."""
content = """
before
-.. mermaidjs::
+.. runmermaid::
:script: BEGIN
print("preamble")
@@ -88,7 +88,7 @@ def test_mermaidjs_script_split(self):
after
"""
content = rst2html(
- content, writer_name="rst", new_extensions=["sphinx_runpython.mermaidjs"]
+ content, writer_name="rst", new_extensions=["sphinx_runpython.runmermaid"]
)
self.assertNotIn("preamble", content)
self.assertNotIn("BEGIN", content)
@@ -96,20 +96,20 @@ def test_mermaidjs_script_split(self):
self.assertIn("P --> Q", content)
@ignore_warnings(PendingDeprecationWarning)
- def test_mermaidjs_script_cache(self):
+ def test_runmermaid_script_cache(self):
"""Identical scripts produce the same output and are cached."""
script_body = 'print("graph LR\\n A --> B")'
content = f"""
before
-.. mermaidjs::
+.. runmermaid::
:script:
{script_body}
middle
-.. mermaidjs::
+.. runmermaid::
:script:
{script_body}
@@ -117,7 +117,7 @@ def test_mermaidjs_script_cache(self):
after
"""
content = rst2html(
- content, writer_name="rst", new_extensions=["sphinx_runpython.mermaidjs"]
+ content, writer_name="rst", new_extensions=["sphinx_runpython.runmermaid"]
)
count = content.count("graph LR")
self.assertEqual(count, 2, f"Expected diagram code twice, got {count}")
diff --git a/sphinx_runpython/mermaidjs/__init__.py b/sphinx_runpython/mermaidjs/__init__.py
deleted file mode 100644
index b843779..0000000
--- a/sphinx_runpython/mermaidjs/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from .sphinx_mermaidjs_extension import setup
-
-__all__ = ["setup"]
diff --git a/sphinx_runpython/runmermaid/__init__.py b/sphinx_runpython/runmermaid/__init__.py
new file mode 100644
index 0000000..185687f
--- /dev/null
+++ b/sphinx_runpython/runmermaid/__init__.py
@@ -0,0 +1,3 @@
+from .sphinx_runmermaid_extension import setup
+
+__all__ = ["setup"]
diff --git a/sphinx_runpython/mermaidjs/sphinx_mermaidjs_extension.py b/sphinx_runpython/runmermaid/sphinx_runmermaid_extension.py
similarity index 68%
rename from sphinx_runpython/mermaidjs/sphinx_mermaidjs_extension.py
rename to sphinx_runpython/runmermaid/sphinx_runmermaid_extension.py
index 44dfe2b..87b806a 100644
--- a/sphinx_runpython/mermaidjs/sphinx_mermaidjs_extension.py
+++ b/sphinx_runpython/runmermaid/sphinx_runmermaid_extension.py
@@ -6,23 +6,23 @@
from ..ext_helper import get_env_state_info
from ..runpython.sphinx_runpython_extension import run_python_script
-logger = logging.getLogger("mermaidjs")
+logger = logging.getLogger("runmermaid")
#: Default CDN URL for the mermaid JavaScript library.
_MERMAID_JS_URL = "https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"
-class mermaidjs_node(nodes.General, nodes.Element):
+class runmermaid_node(nodes.General, nodes.Element):
"""
- Defines ``mermaidjs`` node.
+ Defines ``runmermaid`` node.
"""
pass
-class MermaidDirective(Directive):
+class RunMermaidDirective(Directive):
"""
- A ``mermaidjs`` node displays a `Mermaid `_ diagram.
+ A ``runmermaid`` node displays a `Mermaid `_ diagram.
For *HTML* output the diagram is rendered client-side by embedding the
Mermaid JavaScript library (loaded from a CDN or a local copy).
@@ -38,21 +38,21 @@ class MermaidDirective(Directive):
Example – inline diagram::
- .. mermaidjs::
+ .. runmermaid::
graph LR
A --> B --> C
Which gives:
- .. mermaidjs::
+ .. runmermaid::
graph LR
A --> B --> C
Example – script-generated diagram::
- .. mermaidjs::
+ .. runmermaid::
:script:
print(\"\"\"
@@ -60,7 +60,7 @@ class MermaidDirective(Directive):
A --> B
\"\"\")
- .. mermaidjs::
+ .. runmermaid::
:script:
print(\"\"\"
@@ -69,7 +69,7 @@ class MermaidDirective(Directive):
\"\"\")
"""
- node_class = mermaidjs_node
+ node_class = runmermaid_node
has_content = True
required_arguments = 0
optional_arguments = 0
@@ -80,7 +80,7 @@ class MermaidDirective(Directive):
}
def run(self):
- """Build the mermaidjs node."""
+ """Build the runmermaid node."""
bool_set_ = (True, 1, "True", "1", "true", "")
process = "process" in self.options and self.options["process"] in bool_set_
@@ -107,9 +107,9 @@ def run(self):
+ hashlib.sha256(f"{content}:{process}".encode()).hexdigest()
)
if env is not None:
- if not hasattr(env, "mermaidjs_script_cache"):
- env.mermaidjs_script_cache = {}
- cached = env.mermaidjs_script_cache.get(cache_key, None)
+ if not hasattr(env, "runmermaid_script_cache"):
+ env.runmermaid_script_cache = {}
+ cached = env.runmermaid_script_cache.get(cache_key, None)
else:
cached = None
@@ -118,20 +118,20 @@ def run(self):
else:
stdout, stderr, _ = run_python_script(content, process=process)
if env is not None:
- env.mermaidjs_script_cache[cache_key] = (stdout, stderr)
+ env.runmermaid_script_cache[cache_key] = (stdout, stderr)
if stderr:
logger.warning(
- "[mermaidjs] a diagram cannot be drawn due to %s", stderr
+ "[runmermaid] a diagram cannot be drawn due to %s", stderr
)
content = stdout
if script:
spl = content.split(script)
if len(spl) > 2:
- logger.warning("[mermaidjs] too many output lines %s", content)
+ logger.warning("[runmermaid] too many output lines %s", content)
content = spl[-1]
- node = mermaidjs_node(code=content, options={"docname": docname})
+ node = runmermaid_node(code=content, options={"docname": docname})
return [node]
@@ -140,8 +140,8 @@ def run(self):
# ---------------------------------------------------------------------------
-def visit_mermaidjs_node_html(self, node):
- """Render the mermaidjs node in HTML output."""
+def visit_runmermaid_node_html(self, node):
+ """Render the runmermaid node in HTML output."""
code = node["code"].strip()
# Emit a block; mermaid.js will replace it at runtime.
self.body.append(
@@ -152,42 +152,42 @@ def visit_mermaidjs_node_html(self, node):
raise nodes.SkipNode
-def depart_mermaidjs_node_html(self, node):
- """Depart the mermaidjs HTML node. Not called because the visitor raises SkipNode."""
+def depart_runmermaid_node_html(self, node):
+ """Depart the runmermaid HTML node. Not called because the visitor raises SkipNode."""
-def visit_mermaidjs_node_rst(self, node):
- """Render the mermaidjs node in RST output."""
+def visit_runmermaid_node_rst(self, node):
+ """Render the runmermaid node in RST output."""
self.new_state(0)
- self.add_text(".. mermaidjs::" + self.nl)
+ self.add_text(".. runmermaid::" + self.nl)
self.new_state(self.indent)
for row in node["code"].split("\n"):
self.add_text(row + self.nl)
-def depart_mermaidjs_node_rst(self, node):
- """Depart mermaidjs node in RST output."""
+def depart_runmermaid_node_rst(self, node):
+ """Depart runmermaid node in RST output."""
self.end_state()
self.end_state(wrap=False)
-def visit_mermaidjs_node_text(self, node):
- """Render the mermaidjs node in plain-text output."""
+def visit_runmermaid_node_text(self, node):
+ """Render the runmermaid node in plain-text output."""
self.new_state(0)
- self.add_text("[mermaidjs diagram]\n")
+ self.add_text("[runmermaid diagram]\n")
self.new_state(self.indent)
for row in node["code"].split("\n"):
self.add_text(row + self.nl)
-def depart_mermaidjs_node_text(self, node):
- """Depart mermaidjs node in text output."""
+def depart_runmermaid_node_text(self, node):
+ """Depart runmermaid node in text output."""
self.end_state()
self.end_state(wrap=False)
-def visit_mermaidjs_node_latex(self, node):
- """Render the mermaidjs node in LaTeX output (verbatim source)."""
+def visit_runmermaid_node_latex(self, node):
+ """Render the runmermaid node in LaTeX output (verbatim source)."""
code = node["code"].strip()
self.body.append("\n\\begin{verbatim}\n")
self.body.append(code)
@@ -195,8 +195,8 @@ def visit_mermaidjs_node_latex(self, node):
raise nodes.SkipNode
-def depart_mermaidjs_node_latex(self, node):
- """Depart the mermaidjs LaTeX node. Not called because the visitor raises SkipNode."""
+def depart_runmermaid_node_latex(self, node):
+ """Depart the runmermaid LaTeX node. Not called because the visitor raises SkipNode."""
# ---------------------------------------------------------------------------
@@ -223,19 +223,19 @@ def add_mermaid_js(app):
def setup(app):
"""
- setup for ``mermaidjs`` (sphinx)
+ setup for ``runmermaid`` (sphinx)
"""
app.connect("builder-inited", add_mermaid_js)
app.add_node(
- mermaidjs_node,
- html=(visit_mermaidjs_node_html, depart_mermaidjs_node_html),
- epub=(visit_mermaidjs_node_html, depart_mermaidjs_node_html),
- latex=(visit_mermaidjs_node_latex, depart_mermaidjs_node_latex),
- text=(visit_mermaidjs_node_text, depart_mermaidjs_node_text),
- rst=(visit_mermaidjs_node_rst, depart_mermaidjs_node_rst),
- md=(visit_mermaidjs_node_text, depart_mermaidjs_node_text),
+ runmermaid_node,
+ html=(visit_runmermaid_node_html, depart_runmermaid_node_html),
+ epub=(visit_runmermaid_node_html, depart_runmermaid_node_html),
+ latex=(visit_runmermaid_node_latex, depart_runmermaid_node_latex),
+ text=(visit_runmermaid_node_text, depart_runmermaid_node_text),
+ rst=(visit_runmermaid_node_rst, depart_runmermaid_node_rst),
+ md=(visit_runmermaid_node_text, depart_runmermaid_node_text),
)
- app.add_directive("mermaidjs", MermaidDirective)
+ app.add_directive("runmermaid", RunMermaidDirective)
return {"version": sphinx.__display_version__, "parallel_read_safe": True}
From ac99a8b47893b60ea427cdb8d21c3a9b426a6703 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 4 May 2026 09:51:30 +0000
Subject: [PATCH 6/7] move runmermaid after quote in api index
Agent-Logs-Url: https://github.com/sdpython/sphinx-runpython/sessions/08981185-c76f-49f9-bc90-02ba60e6c5ac
Co-authored-by: xadupre <22452781+xadupre@users.noreply.github.com>
---
_doc/api/index.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/_doc/api/index.rst b/_doc/api/index.rst
index f382c62..3bbee13 100644
--- a/_doc/api/index.rst
+++ b/_doc/api/index.rst
@@ -15,8 +15,8 @@ Extensions
docassert
epkg
gdot
- runmermaid
quote
+ runmermaid
runpython
tools
rst_builder
From 6eef81e853a5d9e7e3dc28ed7cf9ed5969f623b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Xavier=20Dupr=C3=A9?=
Date: Mon, 4 May 2026 13:02:01 +0200
Subject: [PATCH 7/7] fix
---
.../runmermaid/sphinx_runmermaid_extension.py | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/sphinx_runpython/runmermaid/sphinx_runmermaid_extension.py b/sphinx_runpython/runmermaid/sphinx_runmermaid_extension.py
index 87b806a..11f19b9 100644
--- a/sphinx_runpython/runmermaid/sphinx_runmermaid_extension.py
+++ b/sphinx_runpython/runmermaid/sphinx_runmermaid_extension.py
@@ -36,7 +36,7 @@ class RunMermaidDirective(Directive):
``stdout`` contains the diagram definition.
* *process*: run the Python script in a separate process.
- Example – inline diagram::
+ Example - inline diagram::
.. runmermaid::
@@ -50,7 +50,7 @@ class RunMermaidDirective(Directive):
graph LR
A --> B --> C
- Example – script-generated diagram::
+ Example - script-generated diagram::
.. runmermaid::
:script:
@@ -208,11 +208,12 @@ def add_mermaid_js(app):
"""Inject the Mermaid JS library into HTML pages."""
if app.builder.format != "html":
return
- app.add_js_file(_MERMAID_JS_URL, **{"loading_method": "async"})
+ app.add_js_file(_MERMAID_JS_URL, loading_method="async")
# Initialise mermaid after the DOM is ready.
app.add_js_file(
None,
- body="document.addEventListener('DOMContentLoaded', function() { mermaid.initialize({startOnLoad: true}); });",
+ body="document.addEventListener('DOMContentLoaded', function() "
+ "{ mermaid.initialize({startOnLoad: true}); });",
)