feat: Mermaid diagrams, transition tables, and format() support#595
Merged
feat: Mermaid diagrams, transition tables, and format() support#595
Conversation
- Add MermaidRenderer that converts DiagramGraph IR to Mermaid stateDiagram-v2 source (compound, parallel, history, guards, etc.) - Add TransitionTableRenderer for markdown and RST table output - Add MermaidGraphMachine facade mirroring DotGraphMachine - Add __format__ to StateChart and StateMachineMetaclass supporting dot, mermaid, md/markdown, and rst format specs - Extend CLI with --format option (mermaid, md, rst) and stdout support - Add :format: option to Sphinx statemachine-diagram directive with sphinxcontrib-mermaid integration - Update docs with new sections and doctests
…stry Replace duplicated if/elif chains in StateChart.__format__ and StateMachineMetaclass.__format__ with a Formatter class that uses a decorator-based registry following the Open/Closed Principle. Adding a new format now requires only a decorated function — no changes to __format__, factory.py, or statemachine.py.
- Register "svg" format in Formatter (DOT → SVG decoded as str) - Refactor Sphinx directive to use formatter.render() for both SVG and Mermaid instead of calling DotGraphMachine/MermaidGraphMachine directly - Update _prepare_svg and _resolve_target to work with str (not bytes)
The metaclass now detects {statechart:FORMAT} placeholders in docstrings
and replaces them at class definition time with the rendered output.
The docstring always stays in sync with the actual states and transitions.
Any registered format works: md, rst, mermaid, dot, etc.
Indentation of the placeholder line is preserved in the output.
- Reorganize into unified "Text representations" section with format table (name, aliases, description, dependencies) - Add formatter API section with render(), supported_formats(), and custom format registration example - Add live Mermaid directive example in Sphinx section - Add --format dot to CLI examples - Replace MermaidGraphMachine usage with formatter - Add autodoc integration example with SimpleSC - Add auto-expanding docstrings section with format recommendations - Update release notes
Mermaid's stateDiagram-v2 crashes when a transition targets or originates from a compound state inside a parallel region (mermaid-js/mermaid#4052). The MermaidRenderer now redirects such endpoints to the compound's initial child state. Also filter dot-form event aliases (e.g. done.invoke.X) from diagram output — the fix lives in the extractor so all renderers benefit. Closes #594
…workaround to parallel regions The Mermaid renderer had two issues: 1. Cross-scope transitions (e.g., an outer state targeting a history pseudo-state inside a compound) were silently dropped because `_render_scope_transitions` only rendered transitions where both endpoints were direct members of the same scope. Now the scope check expands to include descendants of compound states, while skipping transitions fully internal to a single compound (handled by the inner scope). 2. The compound→initial-child redirect (workaround for mermaid-js/mermaid#4052) was applied universally, but the bug only affects compound states inside parallel regions. Now the redirect is restricted to parallel descendants, leaving compound states outside parallel regions unchanged. Adds a ParallelCompoundSC showcase that exercises the Mermaid bug pattern (transition targeting a compound inside a parallel region), with Graphviz vs Mermaid comparison in the visual showcase docs.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #595 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 39 42 +3
Lines 4597 5007 +410
Branches 734 813 +79
==========================================
+ Hits 4597 5007 +410
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Add tests for the :name: directive option on Mermaid format (with and without caption). Mark the defensive dedup guard in _format_event_names as pragma: no branch since Events already deduplicates at the container level.
|
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
Mermaid renderer — new
MermaidRendererproducesstateDiagram-v2source from the diagram IR, with a workaround for mermaid-js/mermaid#4052 (compound states inside parallel regions). Cross-boundary transitions (e.g., targeting a history pseudo-state inside a compound) are correctly rendered at the parent scope.Transition table renderer —
TransitionTableRendererproduces Markdown or reStructuredText tables from the diagram IR.Formatter facade — decorator-based format registry with built-in formats:
mermaid,md/markdown,rst,dot,svg. Powers bothformat(sm, "mermaid")/f"{sm:mermaid}"and the CLI.StateChart.__format__— delegates to Formatter, enabling f-string andformat()usage.Docstring auto-expansion —
{statechart:FORMAT}placeholders in class docstrings are replaced at class creation time (via the metaclass) with the rendered diagram text.Sphinx directive —
:format: mermaidoption onstatemachine-diagramemits a Mermaid node (viasphinxcontrib-mermaid).CLI enhancements —
--format mermaid|md|rstand stdout output (-).Visual showcase — every showcase section in
docs/diagram.mdnow includes both Graphviz and Mermaid renderings side by side, plus a new "Parallel with cross-boundary transitions" section.Documentation — revised
diagram.md, tutorial, and 3.1.0 release notes.Examples
f-string / format()
Docstring auto-expansion
At class creation time,
{statechart:rst}is replaced with the rendered table:Mermaid workaround for parallel regions
Transitions targeting a compound state inside a parallel region crash Mermaid (mermaid-js/mermaid#4052). The renderer redirects them to the compound's initial child:
In the Mermaid output,
rebuildis redirected from the compound to its initial child:Graphviz renders the arrow to the Build compound border; Mermaid redirects it to Compile.
CLI
Sphinx directive