Mermaid import and export
Archdocs can convert a supported subset of Mermaid into archdocs/v1 YAML and
export representable canvas elements as Mermaid. Conversion is intentionally
limited: diagnostics identify supported fidelity losses, parse errors block an
import, and a Mermaid round-trip is not lossless.
Supported diagram types
The first non-blank line selects the importer. Header matching is case-insensitive.
| Mermaid header | Archdocs result |
|---|---|
erDiagram | erd-entity nodes plus relationships |
sequenceDiagram | One sequence-diagram node |
flowchart | Positioned shape nodes plus relationships |
flowchart-elk | The same result as flowchart |
graph | The same result as flowchart |
Import accepts one diagram at a time. If pasted text contains fenced Mermaid
blocks, the first block is used and additional blocks produce a
multiple-fences note. Mermaid %% comments are removed. Theme and init
directives are removed with an init-directive-ignored note.
erDiagram
Each entity becomes an erd-entity. Attributes become rows with label and
valueType; Mermaid PK, FK, and UK markers become pk, fk, and
unique. Comma-separated key markers are accepted. An entity used only in a
relationship is still created with no rows, and an entity declaration such as
CUSTOMER["Retail Customer"] uses the alias as its title.
Archdocs cardinality records one or many at each end. The importer maps the Mermaid end tokens as follows:
| End position | Mermaid token | Archdocs cardinality end | Fidelity note |
|---|---|---|---|
| Left | || | one | None |
| Left | |o | one | Optional zero is lost |
| Left | }| | many | None |
| Left | }o | many | Optional zero is lost |
| Right | || | one | None |
| Right | o| | one | Optional zero is lost |
| Right | |{ | many | None |
| Right | o{ | many | Optional zero is lost |
The two imported ends form one-to-one, one-to-many, many-to-one, or
many-to-many. A -- relationship becomes style: solid; .. becomes
style: dashed. direction TB and direction TD map to down, BT maps to
up, LR maps to right, and RL maps to left.
Fidelity limits:
- Zero-or-one and zero-or-many collapse to one and many. The importer emits one
optionality-lostnote when this occurs. - Attribute comments have no ERD row field and are dropped with one
attribute-comment-droppednote. - Lines or attributes outside the accepted syntax are errors and block the import instead of being ignored.
sequenceDiagram
participant, actor, and as aliases are supported. Participants first
seen in messages or notes are created implicitly. Actors retain kind: actor;
other participants use kind: object. title becomes the sequence node title,
and self-directed messages become msgType: self regardless of their arrow.
The arrow table is evaluated from longest token to shortest token:
| Mermaid arrow | Archdocs msgType | Fidelity limit |
|---|---|---|
-->> | return | None |
--) | async | Dashed styling is not retained |
--x | async | The cross endpoint is not retained |
--> | return | The Mermaid arrow spelling is not retained |
->> | sync | None |
-) | async | None |
-x | async | The cross endpoint is not retained |
-> | sync | The Mermaid arrow spelling is not retained |
-- | return | The Mermaid arrow spelling is not retained |
Note over A,B, Note left of A, and Note right of A become note steps
anchored to the first named participant. The block keywords loop, alt,
else, opt, par, and, critical, option, break, and rect become
divider steps. An associated end also becomes a divider.
Fidelity limits:
- Blocks are flattened into dividers. Nesting and frames are lost, with one
blocks-flattenednote. activate,deactivate, and message activation suffixes are dropped with anactivation-droppednote.autonumberis dropped with anautonumber-droppednote.box ... endparticipant grouping is dropped with abox-droppednote.link,links, andpropertiesparticipant metadata is dropped with oneparticipant-metadata-droppednote.- Other sequence statements are parse errors.
flowchart and graph
Header directions TD and TB map to down, BT to up, LR to right,
and RL to left. A missing or unrecognized header direction defaults to
down. A direction statement inside the body is accepted but does not change
the document direction.
Archdocs shapes are limited to rectangle, ellipse, and diamond:
| Mermaid node syntax | Archdocs shape | Rounded | Approximated |
|---|---|---|---|
id[text] | rectangle | no | no |
id(text) | rectangle | yes | no |
id([text]) | rectangle | yes | no |
id{text} | diamond | no | no |
id((text)) | ellipse | no | no |
id(((text))) | ellipse | no | yes |
id[[text]] | rectangle | no | yes |
id[(text)] | rectangle | no | yes |
id{{text}} | diamond | no | yes |
id[/text/] | rectangle | no | yes |
id[\text\] | rectangle | no | yes |
id[/text\] | rectangle | no | yes |
id[\text/] | rectangle | no | yes |
id>text] | rectangle | no | yes |
id@{ shape: ... } | rectangle | no | yes |
Bare id | rectangle labeled id | no | no |
All v11 @{ ... } shape declarations use the same rectangle approximation;
the declared shape name is not interpreted. Approximations are combined into
one shape-approximated note whose message gives the number encountered.
Quoted labels and markdown-string backticks are unwrapped. #quot; becomes a
double quote, #35; becomes #, and <br> or <br/> becomes a newline.
Edge mapping follows the implemented link token table:
| Mermaid link | Relationship style | Fidelity note |
|---|---|---|
--> | solid | None |
--- | solid | arrowhead-added |
==> | solid | None |
=== | solid | arrowhead-added |
-.-> | dotted | None |
-.- | dotted | arrowhead-added |
--o, --x | solid | link-endpoint-approximated |
<->, <--> | solid | bidirectional-flattened |
The unidirectional solid, thick, and arrowless patterns also accept longer runs
of hyphens or equals signs. Links can use A -->|text| B or
A -- text --> B labels. Chained links and ampersand node groups expand into
individual relationships.
The importer ignores style, classDef, class, linkStyle, click,
accTitle, and accDescr directives and emits one directive-ignored note
naming the directive kinds encountered. A :::class suffix on a node is
removed without a note. Other unreadable statements are blocking parse errors.
subgraph id [Title] ... end supports nesting. Each subgraph becomes a rounded,
dashed, transparent rectangle and a separate title text node at 12 pixels from
the left and 8 pixels from the top. The rectangle and title are emitted before
members so they sit behind the members. Membership is recorded when a node is
first created inside the subgraph; referring inside a subgraph to a node that
was already created elsewhere does not move it into that subgraph. Unmatched or
unclosed end statements are blocking errors.
Layout
ERD and sequence imports do not provide coordinates. Their constructs are laid
out by the normal Archdocs compiler. Flowcharts need explicit positions because
their shape and text nodes are pinned, so the importer measures each shape
with the same construct sizing logic used by the compiler and runs a layered
ELK layout. Header direction drives ELK. Subgraphs are hierarchical ELK nodes,
and edge labels are included in the layout input. The resulting positions and
sizes are written into the YAML so the imported flowchart arrives laid out
instead of placing every shape at the origin.
Unsupported diagram types
The following known Mermaid headers are refused by name:
classDiagram-v2classDiagramstateDiagram-v2stateDiagramganttpiejourneygitGraphmindmaptimelinequadrantChartrequirementDiagramC4ContextC4ContainerC4ComponentC4DynamicC4Deploymentsankey-betaxychart-betablock-betapacket-betaarchitecture-betazenumlkanbanradartreemap
classDiagram, classDiagram-v2, stateDiagram, and stateDiagram-v2 receive
a specific error explaining that they have no matching Archdocs construct yet.
The other entries receive a named unsupported-type error. Unknown headers are
reported as not Mermaid. Unsupported and unknown inputs produce no YAML.
Export
Export returns unfenced Mermaid blocks because one Archdocs document can mix
diagram kinds. Blocks are ordered as one erDiagram block, one
sequenceDiagram block for each sequence element, then one flowchart block,
omitting any group that is absent. The editor can copy an individual block or
wrap all blocks in Markdown Mermaid fences.
Export supports a wider set of Archdocs constructs than import:
- ERD entities become one
erDiagram. Missing row types default tostringwith avalue-type-defaultednote. Row-label whitespace becomes underscores. Cardinalities export as||--||,||--o{,}o--||, or}o--o{; an unrecognized arrowhead combination defaults to one-to-one. Relationship labels default torelatesand have whitespace replaced by underscores. Dashed ERD relationship style is not retained. - Sequence elements each become a block.
syncandcreateuse->>,returnuses-->>,asyncuses-),selfuses->>with identical endpoints, anddestroyuses-x. Notes becomeNote overstatements. Dividers become%% divider:comments with onedivider-unrepresentablenote. - Shapes become a fixed
flowchart TD: rectangle uses[...], ellipse uses((...)), and diamond uses{...}. Rectangle roundness is not retained. Solid relationships use-->; both dashed and dotted relationships use-.->. Positions and layout direction are not exported. c4-nodeis exported as a rectangle using only its C4 label. Its kind, technology, and description are omitted without a separate note.c4-boundaryis exported as a subgraph. Membership is inferred from geometry by choosing the smallest boundary that contains each exported shape or C4 node. Boundaries themselves are emitted as separate top-level subgraphs, so nested C4 boundaries are not reproduced as nested subgraphs.
ERD identifiers prefer the entity title, then its DSL key or element id.
Flowchart identifiers prefer the DSL key, then the element id. Imported
subgraph rectangles are recognized by their dashed transparent styling and
exported as subgraphs when they geometrically contain another exported node.
Their separate title text supplies the subgraph title. Sequence participant
identifiers come from participant ids. Each is reduced to letters, digits, and
underscores, prefixed with n if it starts with a digit, and given numeric
suffixes after collisions. Double quotes and non-quot hash signs in labels
are escaped; newlines become <br/>.
There is no fixed skip allowlist. When a flowchart block exists, its exporter
counts every unconsumed runtime element kind in one element-skipped note. For
current DSL constructs this includes api-endpoint, cloud-resource,
cloud-container, reference, and unbound text; raw elements are named by
their runtime kind, such as image or freedraw, rather than as raw. ERD
entities and sequence elements are excluded from this note because their own
blocks handle them. Bound text is treated as part of its container. Arrows are
treated as consumed, but an arrow whose endpoints cannot be resolved to
exported nodes is omitted without a note. If no block can be produced, a
nothing-to-export note is returned without an element-kind breakdown.
Round-trip
Import followed by export is not lossless. ERD optionality, attribute comments, dashed relationship style, aliases, and direction can be lost or normalized. Sequence block structure, activations, numbering, participant boxes, arrow spelling, and cross endpoints can be lost or flattened. Flowchart shape details, styling directives, arrowless and bidirectional link semantics, special link endpoints, rounded rectangles, coordinates, and direction can be lost or normalized. Imported Mermaid subgraphs export as subgraphs with their titles and geometrically contained nodes. Nested imported subgraphs and nested C4 boundaries become separate top-level subgraphs rather than retaining their nesting. C4 export keeps labels and geometric grouping but omits other C4 metadata. Export can also sanitize or deduplicate identifiers. Treat Mermaid as a conversion format, not as a persistent source that will reproduce the original text.