mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-09 20:26:33 +00:00
Every role README carries a ```mermaid flowchart and the documentation showed it as source. A post-transform now replaces those literal blocks with <pre class="mermaid"> in html builds, which the runtime picks up; every other builder keeps the fence as it was. sphinxcontrib-mermaid injects an inline init script, which this deployment's CSP refuses, so the runtime and its initialisation are two linked files instead: mermaid-init.js calls mermaid.initialize with securityLevel strict and follows the reader's colour scheme. The diagram source is html-escaped before it is embedded, or an & or < in a node label would break the page. The runtime is fetched at image build time through ADD --checksum, so a changed upstream file fails the build rather than shipping. Version and digest are not ARG defaults, which test_arg_without_default forbids; they travel meta/services.yml -> vars/main.yml -> compose.yml.j2 the way DOCS_IMAGE and DOCS_VERSION already do, and an update block registers the pin with the npm version watcher instead of exempting it. Verified by building a page with sphinx: the diagram arrives as <pre class="mermaid"> with its source escaped, a bash fence stays a highlighted block, and both scripts are linked. A missing mermaid.min.js does not fail that build, so a local run without the image stays green. scripts/lint/mermaid.sh keeps validating diagram syntax through mmdc, which npm installs unpinned. It therefore checks against a newer mermaid than the 11.4.1 readers get, and a diagram using syntax from in between would pass the lint and render blank. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
41 lines
1.2 KiB
Python
41 lines
1.2 KiB
Python
"""Render ```` ```mermaid ```` fences as diagrams instead of code blocks.
|
|
|
|
The fence is replaced by a ``<pre class="mermaid">`` that the self-hosted
|
|
``mermaid.min.js`` picks up, so no directive and no inline script are needed
|
|
and the fence keeps rendering as source in every non-HTML builder.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import html
|
|
|
|
from docutils import nodes
|
|
from sphinx.transforms.post_transforms import SphinxPostTransform
|
|
|
|
LANGUAGE = "mermaid"
|
|
|
|
|
|
class MermaidFences(SphinxPostTransform):
|
|
"""Turn every mermaid literal block of an HTML page into a raw diagram."""
|
|
|
|
default_priority = 400
|
|
formats = ("html",)
|
|
|
|
def run(self, **kwargs) -> None:
|
|
for node in list(self.document.findall(nodes.literal_block)):
|
|
if node.get("language") != LANGUAGE:
|
|
continue
|
|
diagram = nodes.raw(
|
|
"",
|
|
f'<pre class="mermaid">{html.escape(node.astext())}</pre>',
|
|
format="html",
|
|
)
|
|
node.replace_self(diagram)
|
|
|
|
|
|
def setup(app):
|
|
app.add_post_transform(MermaidFences)
|
|
app.add_js_file("js/mermaid.min.js")
|
|
app.add_js_file("js/mermaid-init.js")
|
|
return {"version": "1.0", "parallel_read_safe": True}
|