Converts between %Artefact{} structs and Mermaid legacy graph source.
Two public functions:
export/2— artefact → Mermaid stringfrom_mmd!/2— Mermaid string → artefact
Round-trip fidelity
export/2 followed by from_mmd!/2 followed by export/2 produces
identical Mermaid source. The preserved fields are: title, description,
node name and description properties, node labels, and relationship
types. See Lossy below for what is not preserved.
Export format
Uses the legacy graph syntax for broad renderer compatibility (GitHub,
Notion, mdBook, Livebook). Nodes render as circles (id(("..."))) — the
property-graph convention, and a closer match to the vis-network ellipses in
the ArtefactKino heartside panel. Labels mirror that panel: the name
property (or node id, when no name is set) on top, semantic labels joined
with a space below, separated by <br/>.
When artefact.title is set, a YAML front-matter block carries the title
(rendered as a heading by Mermaid 9.4+) and an accTitle: line is emitted
for screen readers. A nil title produces neither — the export starts at
graph <direction>.
When artefact.description is set, an accDescr: line follows the
accTitle: line. Multi-line descriptions use the block form
(accDescr { ... }); single-line descriptions use the inline form. A nil
description is omitted. Like accTitle, the description is screen-reader
only — Mermaid does not render it visually.
Node description properties are emitted as click id "description" tooltip lines —
present in source, visible on hover, and parseable by from_mmd!/2.
Lossy
position, style, properties beyond name and description, and the
artefact-level base_label (collapsed into per-node labels at output time)
are not represented in Mermaid source and are not recovered on import.
Summary
Functions
Emit a Mermaid source string for the artefact.
Parse a Mermaid graph source string into an %Artefact{}.
Functions
Emit a Mermaid source string for the artefact.
Options
:direction— flow direction. One of:LR,:RL,:TB,:BT,:TD. Defaults to:LR.
Example
For the us_two artefact:
---
title: UsTwo
---
graph LR
accTitle: UsTwo
n0(("Matt<br/>Agent Me"))
n1(("Claude<br/>Agent You"))
n0 -->|US_TWO| n1
Parse a Mermaid graph source string into an %Artefact{}.
Accepts both the round-trip format produced by export/2 and the broader
Mermaid legacy graph syntax used by tools like Confluence and GitHub.
Node content conventions
Three label formats are recognised inside node shapes:
name<br/>Label1 Label2— our export format: name on top, space-joined semantic labels belowLABEL · name— yarn convention: a single label and name separated by·- plain text — treated as the name with no labels
click id "text" lines become the node description property.
UUID identity
Each node's UUID is derived deterministically from its Mermaid node id
(the w+ identifier, e.g. val_0, std_ulogic) via
Artefact.UUID.from_name/1. The display name inside the shape label is not
used. This means:
- The same diagram imported twice produces the same artefact — safe to repeat.
- Two diagrams that share a node id will bind via
combine!/2without any manual UUID management. - Renaming a node id changes its UUID and breaks bindings. Keep ids stable.
Inline edge + node syntax
When a node's shape is declared on the same line as an edge
(A["label"] -->|TYPE| B["label"]), only the edge is registered; the
node label is not captured. Use a separate declaration line to preserve
labels and names:
graph LR
val_0["VALUE · 0"]
val_0 -->|ENUMERATES| valueThe round-trip format produced by export/2 always emits separate node and
edge lines, so this limitation does not affect round-trips.
Options
:title— overrides the title parsed from YAML front matter:description— overrides the description parsed fromaccDescr::base_label— sets the artefact base label (not inferred from source)
Example
iex> source = """
...> ---
...> title: Us Two
...> ---
...> graph LR
...> n0(("Matt<br/>Agent Me"))
...> n1(("Claude<br/>Agent You"))
...> n0 -->|US_TWO| n1
...> """
iex> artefact = Artefact.Mermaid.from_mmd!(source)
iex> artefact.title
"Us Two"
iex> length(artefact.graph.nodes)
2