@@ -27,7 +27,6 @@ sudo apt install graphviz
2727
2828For other systems, see the [ Graphviz downloads page] ( https://graphviz.org/download/ ) .
2929
30-
3130## Generating diagrams
3231
3332Every state machine instance exposes a ` _graph() ` method that returns a
@@ -77,8 +76,7 @@ For higher resolution PNGs, set the DPI before exporting:
7776
7877``` python
7978graph = sm._graph()
80- graph.set_dpi(300 )
81- graph.write_png(" order_control_300dpi.png" )
79+ graph.set_dpi(300 ).write_png(" order_control_300dpi.png" )
8280```
8381
8482``` {note}
@@ -89,52 +87,24 @@ complete list.
8987```
9088
9189
92- ## Command line
93-
94- You can generate diagrams without writing Python code:
95-
96- ``` bash
97- python -m statemachine.contrib.diagram < classpath> < output_file>
98- ```
99-
100- The output format is inferred from the file extension:
101-
102- ``` bash
103- python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine diagram.png
104- ```
90+ ## Text representations
10591
106- To highlight the current state, use ` --events ` to instantiate the machine and
107- send events before rendering:
92+ State machines support multiple text-based output formats, all accessible
93+ through Python's built-in ` format() ` protocol, the ` formatter ` API, or
94+ the command line.
10895
109- ``` bash
110- python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine diagram.png --events cycle cycle cycle
111- ```
96+ | Format | Aliases | Description | Dependencies |
97+ | --------| ---------| -------------| --------------|
98+ | ` mermaid ` | | [ Mermaid stateDiagram-v2] ( https://mermaid.js.org/syntax/stateDiagram.html ) source | None |
99+ | ` md ` | ` markdown ` | Transition table (pipe-delimited Markdown) | None |
100+ | ` rst ` | | Transition table (RST grid table) | None |
101+ | ` dot ` | | [ Graphviz DOT] ( https://graphviz.org/doc/info/lang.html ) language source | pydot |
102+ | ` svg ` | | SVG markup (generated via DOT) | pydot, Graphviz |
112103
113- Use ` --format ` to produce ** Mermaid source** or a ** transition table** instead
114- of a Graphviz image:
115-
116- ``` bash
117- # Mermaid stateDiagram-v2
118- python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine output.mmd --format mermaid
119-
120- # Markdown transition table
121- python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine output.md --format md
122-
123- # RST transition table
124- python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine output.rst --format rst
125- ```
126-
127- Use ` - ` as the output file to write to stdout (handy for piping):
128-
129- ``` bash
130- python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine - --format mermaid
131- ```
132104
105+ ### Using ` format() `
133106
134- ## Text representations with ` format() `
135-
136- State machines support Python's built-in ` format() ` protocol for quick text
137- output — no diagram imports needed:
107+ Use f-strings or the built-in ` format() ` function — no diagram imports needed:
138108
139109``` py
140110>> > from tests.examples.traffic_light_machine import TrafficLightMachine
@@ -181,11 +151,7 @@ stateDiagram-v2
181151
182152```
183153
184- Supported format specs: ` dot ` , ` svg ` , ` mermaid ` , ` md ` (or ` markdown ` ), ` rst ` .
185- An empty spec falls back to ` repr() ` .
186-
187- The ` dot ` format returns the Graphviz DOT language source (same output as
188- ` sm._graph().to_string() ` ):
154+ The ` dot ` format returns the Graphviz DOT language source:
189155
190156``` py
191157>> > print (f " { sm:dot} " ) # doctest: +ELLIPSIS
@@ -195,6 +161,101 @@ digraph TrafficLightMachine {
195161
196162```
197163
164+ An empty format spec (e.g., ` f"{sm:}" ` ) falls back to ` repr() ` .
165+
166+
167+ ### Using the ` formatter ` API
168+
169+ The ` formatter ` object is the programmatic entry point for rendering
170+ state machines in any registered text format:
171+
172+ ``` py
173+ >> > from statemachine.contrib.diagram import formatter
174+ >> > from tests.examples.traffic_light_machine import TrafficLightMachine
175+
176+ >> > print (formatter.render(TrafficLightMachine, " mermaid" ))
177+ stateDiagram- v2
178+ direction LR
179+ state " Green" as green
180+ state " Yellow" as yellow
181+ state " Red" as red
182+ [* ] -- > green
183+ green -- > yellow : cycle
184+ yellow -- > red : cycle
185+ red -- > green : cycle
186+ < BLANKLINE >
187+
188+ >> > formatter.supported_formats()
189+ [' dot' , ' markdown' , ' md' , ' mermaid' , ' rst' , ' svg' ]
190+
191+ ```
192+
193+ Both ` format() ` and the Sphinx directive delegate to this same ` formatter `
194+ under the hood.
195+
196+
197+ #### Registering custom formats
198+
199+ The ` formatter ` is extensible — register your own format with a
200+ decorator and it becomes available everywhere (` format() ` , CLI,
201+ Sphinx directive):
202+
203+ ``` python
204+ from statemachine.contrib.diagram import formatter
205+
206+ @formatter.register_format (" plantuml" , " puml" )
207+ def _render_plantuml (machine_or_class ):
208+ # your PlantUML renderer here
209+ ...
210+ ```
211+
212+ After registration, ` f"{sm:plantuml}" ` and ` --format plantuml ` work
213+ immediately.
214+
215+
216+ ### Command line
217+
218+ You can generate diagrams without writing Python code:
219+
220+ ``` bash
221+ python -m statemachine.contrib.diagram < classpath> < output_file>
222+ ```
223+
224+ The output format is inferred from the file extension:
225+
226+ ``` bash
227+ python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine diagram.png
228+ ```
229+
230+ To highlight the current state, use ` --events ` to instantiate the machine and
231+ send events before rendering:
232+
233+ ``` bash
234+ python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine diagram.png --events cycle cycle cycle
235+ ```
236+
237+ Use ` --format ` to produce a text format instead of a Graphviz image:
238+
239+ ``` bash
240+ # Mermaid stateDiagram-v2
241+ python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine output.mmd --format mermaid
242+
243+ # DOT source
244+ python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine output.dot --format dot
245+
246+ # Markdown transition table
247+ python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine output.md --format md
248+
249+ # RST transition table
250+ python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine output.rst --format rst
251+ ```
252+
253+ Use ` - ` as the output file to write to stdout (handy for piping):
254+
255+ ``` bash
256+ python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine - --format mermaid
257+ ```
258+
198259
199260## Auto-expanding docstrings
200261
@@ -261,33 +322,6 @@ And here is the rendered autodoc output:
261322```
262323
263324
264- ## Mermaid output
265-
266- The ` MermaidGraphMachine ` facade generates
267- [ Mermaid ` stateDiagram-v2 ` ] ( https://mermaid.js.org/syntax/stateDiagram.html )
268- source text from any state machine — no external dependencies required:
269-
270- ``` py
271- >> > from statemachine.contrib.diagram import MermaidGraphMachine
272- >> > from tests.examples.traffic_light_machine import TrafficLightMachine
273- >> > print (MermaidGraphMachine(TrafficLightMachine).get_mermaid())
274- stateDiagram- v2
275- direction LR
276- state " Green" as green
277- state " Yellow" as yellow
278- state " Red" as red
279- [* ] -- > green
280- green -- > yellow : cycle
281- yellow -- > red : cycle
282- red -- > green : cycle
283- < BLANKLINE >
284-
285- ```
286-
287- Compound states, parallel regions, history pseudo-states, guards, and
288- active-state highlighting are all supported.
289-
290-
291325## Sphinx directive
292326
293327If you use [ Sphinx] ( https://www.sphinx-doc.org/ ) to build your documentation, the
@@ -356,6 +390,26 @@ zoom and pan freely:
356390:align: center
357391```
358392
393+ ### Mermaid format
394+
395+ Use ` :format: mermaid ` to render via
396+ [ sphinxcontrib-mermaid] ( https://github.com/mgaitan/sphinxcontrib-mermaid )
397+ instead of Graphviz SVG — useful when you don't want to install Graphviz
398+ in your docs build environment:
399+
400+ ```` markdown
401+ ``` {statemachine-diagram} myproject.machines.TrafficLight
402+ :format: mermaid
403+ :caption: Rendered as Mermaid
404+ ```
405+ ````
406+
407+ ``` {statemachine-diagram} tests.examples.traffic_light_machine.TrafficLightMachine
408+ :format: mermaid
409+ :caption: TrafficLightMachine (Mermaid)
410+ :align: center
411+ ```
412+
359413### Directive options
360414
361415The directive supports the same layout options as the standard ` image ` and
@@ -368,8 +422,7 @@ The directive supports the same layout options as the standard `image` and
368422 each event is sent before rendering.
369423
370424` :format: ` * (string)*
371- : Output format. Use ` mermaid ` to render via
372- [ sphinxcontrib-mermaid] ( https://github.com/mgaitan/sphinxcontrib-mermaid )
425+ : Output format. Use ` mermaid ` to render via sphinxcontrib-mermaid
373426 instead of Graphviz SVG. Default: DOT/SVG.
374427
375428** Image/figure options:**
0 commit comments