Skip to content

Draw any resource id in toMermaid and toDot (0.3.2) - #3

Merged
RegiByte merged 1 commit into
mainfrom
fix/mermaid-safe-ids
Oct 24, 2026
Merged

RegiByte merged 1 commit into
mainfrom
fix/mermaid-safe-ids

Conversation

@RegiByte

Copy link
Copy Markdown
Owner

Problem

toMermaid and toDot write resource ids raw as node ids ( core:config --> core:system, core:config -> core:system;). Ids namespaced like core:config or x/cap are natural in a consumer, and both formats give some characters meaning.

Verification

In a scratch project, Mermaid 11.17.2 (mermaid.mermaidAPI.getDiagramFromText under jsdom, and a real render with @mermaid-js/mermaid-cli on headless Chrome) and Graphviz dot:

id Mermaid (raw) DOT (raw)
core:config parses and renders fine misread: node core, port config (core:config -> core:system is a self-loop core -> core)
x/cap, x.cap fine syntax error
-cap, x-cap, a"b, a&b fine n/a
my cache parse error split into two nodes
@scope/x, user@x lexical / parse error n/a
end, graph, style, subgraph parse error n/a
x:cap(1) misread: node x:cap labelled 1 n/a
a:::b misread: node a with class b n/a
click misread: no node at all n/a

So : alone is fine in Mermaid 11, but realistic ids still break it, and DOT is broken for : itself.

With the fix, a graph over core:config, x/cap, my cache\x, end, say "hi" #1 and @scope/y renders every label exactly (mmdc SVG and dot -Tsvg).

Fix

  • toMermaid declares each resource once as n<i>, numbered in startupOrder (deterministic), labelled with its id: n0["core:config"]. " and # become #quot; and #35;, the entity codes Mermaid decodes. Edges are n0 --> n1. Signature and direction unchanged.
  • toDot quotes every id in rank groups and edges, escaping \ and ".
  • Specs: exact Mermaid output for the linear chain, quoted DOT ids, and a new block over ids with :, /, ", #, a space and a backslash.
  • README example output, CHANGELOG 0.3.2, version 0.3.2.

The output changes for every system, plain ids included (every node is now declared with a label).

Alternatives

  • Quote ids only when they need it: needs a full model of each format's lexer (keywords, @, :::, ports), which is exactly what went wrong; one rule for every id is simpler and always correct.
  • Sanitised ids derived from the name (core_config): readable, but can collide (a:b vs a_b) and still needs the label for the real name.
  • Mermaid's id["label"] with the raw id quoted is not valid; ids cannot be quoted in Mermaid, so a synthetic id is needed.

Both exporters wrote resource ids raw as node ids. Checked against Mermaid
11.17 (parse and mmdc render) and Graphviz dot: Mermaid reads `core:config`,
`x/cap` and `-cap` as plain ids, but fails on a space, an `@`, or ids such as
`end`, `graph`, `style`, and silently misreads `x:cap(1)` (label "1"),
`a:::b` (class b) and `click` (no node). DOT reads `core:config` as node
`core`, port `config` (a self-loop core -> core), and fails on `/` and `.`.

toMermaid declares each resource once as `n<i>`, numbered in startup order,
labelled with its id (`"` and `#` as `#quot;` and `#35;`), and draws edges
between those nodes. toDot quotes every id, escaping `\` and `"`.

0.3.2.
@RegiByte
RegiByte merged commit 17e2215 into main Oct 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant