Conversation
4 tasks
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #61 +/- ##
==========================================
+ Coverage 92.43% 92.50% +0.06%
==========================================
Files 258 263 +5
Lines 20327 20846 +519
==========================================
+ Hits 18790 19283 +493
- Misses 1537 1563 +26 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
why: Build-time mermaid rendering is proven in tmuxp's docs but lives in its docs/_ext, unavailable to other gp-sphinx consumers. Scaffold the workspace package so the renderer can move in and be reused. what: - packages/sphinx-gp-mermaid: pyproject (sphinx>=8.1, hatchling), README, py.typed, skeleton setup() returning parallel-safe metadata - Root pyproject: uv source, dev group, isort first-party, pytest testpath entries - package_tools: smoke_sphinx_gp_mermaid wheel smoke runner - package_reference: assign the ux cluster - docs: landing stub + legacy extensions/ redirect - tests: add to the publishable-package set
why: The renderer is proven in tmuxp production docs; moving it into the
workspace package makes it installable by every gp-sphinx consumer.
what:
- Full pipeline: mermaid directive -> mermaid_inline node -> HTML
write-phase visitor -> mmdc subprocess -> dual light/dark inline SVG
- Content-hash SVG cache under <confdir>/_mermaid_cache, keyed on
render version, theme, full mermaid config JSON, and source; cache
key inputs unchanged from the tmuxp version so existing caches hit
- mmdc resolution (config -> confdir node_modules -> PATH), puppeteer
config generation with cached-Chrome discovery, graceful degradation
to escaped source when the renderer is missing
- Config values: mermaid_cmd, mermaid_puppeteer_config
- CSS classes join the workspace namespace: gp-sphinx-diagram,
gp-sphinx-diagram__variant--theme-{light,dark},
gp-sphinx-diagram__fallback; stylesheet ships in the package's
_static and registers at builder-inited
- Unit tests: SVG normalization, digest, palettes, visitor, fallback,
cache idempotency, setup registration, static-path idempotence
why: The HTML-only visitor left text/latex/man/texinfo builds to crash on an unhandled node, and the module-global warn-once flag contradicted the extension's parallel_write_safe declaration. what: - text/man/latex/texinfo visitors emit an "[diagram: <alt>]" stand-in (alt falling back to caption), following sphinx.ext.graphviz - Warn-once memo moves to a builder attribute (imgmath's pattern), so each writer process warns at most once and fresh builds start clean - setup() excludes _mermaid_cache from source discovery at config-inited - _render treats OSError (e.g. a resolved but non-executable command) as MermaidRendererMissing instead of crashing the build - Tests: fallback-text cases, all four visitors, per-builder memo, PermissionError degradation, and a text-builder integration scenario
why: The unit suite never exercises the fence -> directive -> subprocess -> dual-figure HTML pipeline, and the palette hexes are hand copies of gp-furo-tokens values that could drift silently. what: - Full HTML build over a stub mmdc (a python script honouring the -i/-o/-c contract) that bakes themeVariables.primaryColor into the SVG, proving both theme configs cross the subprocess boundary - Asserts both fence spellings render, SVG normalization, option passthrough (caption/alt/name), packaged CSS shipping, cache exclusion and population, and a stable figure-markup snapshot - Palette tripwire: scrapes light.ts/dark.ts custom properties and checks every non-font themeVariable against its token (black/white keywords normalized), plus a coverage guard for new palette keys
why: myst-parser snapshots myst_* config at its own config-inited, so sphinx_gp_mermaid cannot reliably register its fence routing from setup(); conf level is the deterministic place, and consumers should not need boilerplate for it. what: - merge_sphinx_config() sets myst_fence_as_directive = ["mermaid"] whenever sphinx_gp_mermaid lands in the final extension list - Explicit myst_fence_as_directive overrides still win (overrides apply last) - Tests: routing on with the extension, absent without it, override wins; docstring doctest documents the behavior
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
sphinx-gp-mermaid, a workspace package rendering MySTmermaidfences to inline SVG at build time viammdc(@mermaid-js/mermaid-cli) — no client-side mermaid runtime, no async pop-in, no layout shift, and diagrams ride SPA navigation as finished DOM.body[data-theme]. Mermaid bakes id-scoped!importantcolors into its SVGs, so a single render cannot follow the theme toggle.<confdir>/_mermaid_cache, keyed on render version + theme + full mermaid config JSON + source — styling changes bust the cache, and the cache survivesrm -rf docs/_build. The extension excludes the directory from source discovery automatically.mmdcwarns once per builder and falls back to the escaped diagram source; text/latex/man/texinfo builders emit a[diagram: <alt>]stand-in instead of crashing on the node.merge_sphinx_config()setsmyst_fence_as_directive = ["mermaid"]whenever the extension lands in the final extension list; explicit overrides still win.docs/_ext/mermaid_inline.py(Docs: build-time mermaid + tmux-layout diagram rendering tmux-python/tmuxp#1071), where it is proven in production docs. tmuxp adopts this package in the companion PR.Changes by area
New package:
packages/sphinx-gp-mermaidsphinx_gp_mermaid/__init__.py:mermaiddirective (:caption:,:alt:,:name:) → marker node → HTML write-phase visitor →mmdcsubprocess → dual normalized SVGs in a<figure>. Renderer resolution walksmermaid_cmdconfig →<confdir>/node_modules/.bin/mmdc→PATH; puppeteer config is generated with--no-sandboxand a Chrome discovered in puppeteer's cache. SVG normalization rewrites mermaid's hardcodedmy-svgid (attribute, scoped<style>,url(#…)marker refs) to a per-diagram-per-theme id, replaceswidth="100%"with explicit width/height from the root viewBox, and strips the inlinemax-width._static/css/sphinx_gp_mermaid.css: ships inside the package and registers atbuilder-inited. Classes use the workspace namespace:gp-sphinx-diagram,gp-sphinx-diagram__variant--theme-{light,dark},gp-sphinx-diagram__fallback.Coordinator:
gp_sphinx/config.pysphinx_gp_mermaidis active; documented with a doctest.Workspace wiring
pyproject.toml(uv source, dev group, isort first-party, doctest testpath), wheel smoke runner inscripts/ci/package_tools.py,uxcluster assignment indocs/_ext/package_reference.py, docs landing stub, and a legacyextensions/redirect.Tests:
tests/ext/mermaid/fake_mmdc.pythat honors the-i/-o/-ccontract and bakesthemeVariables.primaryColorinto the SVG — proving the light and dark configs each cross the subprocess boundary; plus a text-builder build asserting the alt-text stand-in.gp-furo-tokenslight.ts/dark.tsand asserts every non-fontthemeVariableequals its token value, so a token retune fails in CI instead of drifting silently.Design decisions
!important— one SVG cannot be re-themed by page CSS. Two renders share identical geometry, so the CSS display toggle never shifts layout.myst_*config at its ownconfig-inited, so an extension mutating config fromsetup()lands too late;merge_sphinx_configis the deterministic place.DEFAULT_EXTENSIONS: rendering requires a node toolchain (mermaid-cli + headless Chrome). Auto-loading would push that onto every consumer for a capability few docs use today.parallel_write_safedeclaration honest.Test plan
uv run ruff check .anduv run ruff format .— cleanuv run mypy .— strict, cleanuv run py.test --reruns 0— full suite including module doctestsjust build-docs— landing page renders;setup()replays cleanly through the package-reference recordertests/ext/mermaid/test_integration.py— both fence spellings render, dual variants carry per-theme fills, normalization holds, options pass through, packaged CSS ships, cache is excluded and populated, figure markup snapshot is stabletests/ext/mermaid/test_palette_sync.py— palettes match gp-furo tokens in both themesCompanion PR