PlantUML flowcharts

The PlantUML module reads modern and legacy activity diagrams inside one @startuml block. Both dialects convert to the shared flowchart model and use its themed SVG, structural route queries and offline player. The compatibility baseline is PlantUML 1.2026.9.

activity Flowchart with 10 nodes and 11 structural connections. Playback illustrates structure and does not execute a workflow. yes no Review request Retry? Save Notify

Use moonrockz/diagrams-plantuml to read a block, inspect diagnostics, write canonical source and convert its typed document. Document::Activity contains an editable moonrockz/diagrams-plantuml/activity.Document. Its dialect is Modern or Legacy; its statements contain typed control values and source spans. tree.text() reproduces the original source, including invalid regions. Recoverable activity errors can retain a partial document. Check diagnostics before conversion; the SVG convenience operation returns no output on errors. plantuml.print writes a complete block from the typed values. The body printer writes only the body. Canonical equality ignores source spans and trivia.

For an explicit body call, use read_body(Activity, body, dialect=Modern) or dialect=Legacy. The generic block reader selects the dialect from activity statements. Strings, comments and notes do not select a dialect. Other UML families and unsupported mixed dialects give errors.

Syntax and model

Modern syntax includes actions and lists, final forms, if/elseif/else, switch/case, repeat/backward/break, while, fork/end fork/end merge, split, kill/detach, connectors, label/goto, partitions, groups, lanes and notes. Legacy syntax includes quoted or bare activities, aliases, implicit previous activities, directional arrows, branch controls, synchronization bars, partitions and notes. Nested constructs retain their order and source bindings.

Modern equal-label actions are separate occurrences. Legacy aliases and repeated activity names follow PlantUML's reuse rules. Generated IDs use deterministic source order and avoid authored names. Do not use labels as occurrence IDs.

PlantUML partitions remain nested groups. Pipe declarations create explicit responsibility lanes. A partition can span several lanes. A note attaches to its declared node or connection and does not become a control-flow edge. note on link uses the connection identity in the model's separate connection attachment namespace.

Legacy endif does not create an implicit merge. An arrow without a source after endif starts at the last active branch action, as the pinned reader does. Use explicit aliases and arrows when both branch tails must reach one common action. Direction hints such as -up-> and -left-> remain separate from the connection's authored source and target.

Rendering and playback

Convert with to_diagram and pass the resulting Flowchart variant to the shared SVG or animated renderer. The model retains actions, decisions, merges, forks, joins, starts, distinct final forms, branch labels and loop regions. The source grammar stays in the reader module; the immutable model has no PlantUML runtime or UI dependency.

SVG uses the library's vector symbols and adaptive or fixed light/dark themes. It does not reproduce PlantUML's coordinates or skins. Source styles and colors remain printable data and produce findings when the renderer does not apply them. External images produce activity/external-asset during conversion. The library does not load files, use Java, call Graphviz or make network requests.

Animation illustrates structure. Default plans are finite, including cyclic models. Explicit scenarios choose occurrences, loop repetitions, durations and concurrent groups. Routes follow declared connections; they do not evaluate conditions, execute actions or synchronize workflow tokens. The offline player uses the existing controls, keyboard access, reduced motion, hidden-page and print behavior. SVG download excludes playback overlays and retains the direct static rendering.

Compatibility evidence

The frozen corpus in tests/corpus/plantuml-activity contains every unique example from the captured modern and legacy documentation pages and independent branch, loop and parallel fixtures. provenance.json identifies the pages, upstream source commit and licenses. SHA256SUMS binds all inputs and metadata. The feature/refusal records distinguish native behavior and library limits.

The test-only Java adapter reads PlantUML's modern instruction tree and legacy ordered entities and links directly. It does not use MoonBit conversion to construct expected values. Source and canonical output are both checked against the pinned JAR. Two documentation examples repeat @enduml; the library reports that trailing marker under its existing single-block contract. External-image examples remain readable and printable but conversion refuses asset loading.

Run these commands from the repository root:

mise run activity-corpus:reference -- --check
mise run activity-corpus:generate
mise run validate:activity-corpus

Only the reference task needs the pinned JAR and JDK. Normal acceptance tests read committed reference data on wasm, wasm-gc, js and native.

Adding Activity and Flowchart variants requires downstream exhaustive matches over PlantUML document/kind values and the shared renderer enum to handle those cases. Existing regex, EBNF, JSON and YAML entry points keep their contracts.

View source on GitHub