DOT mapping

How markup-dot-writer maps the Graph model to Graphviz DOT source text.

Graph structure

Model element Produced DOT Notes

Graph header

digraph Pipeline {

digraph for directed graphs, graph for undirected; the name follows only when set (quoted per the ID rule below), followed by a space and {.

graph attrs

  rankdir=LR;

one indented key=value; line per entry, in insertion order, directly after the header.

Node

  parse [shape=box];

` id [attrs];` — the bracket list is omitted entirely when the node has no attributes: ` parse;`.

Edge

  parse -> write [label=model];

in directed graphs, -- in undirected. The bracket list is omitted when the edge has no attributes.

closing

}

always the final line.

Attribute order

Within a node’s or edge’s […​] list, attributes are comma-separated and ordered:

Element Typed style properties (first, in this order) Then

Node

shape, color, label (from NodeStyle, only when set)

attr() map entries in insertion order

Edge

style, color, label (from EdgeStyle, only when set)

attr() map entries in insertion order

ID quoting

Every identifier position — node/edge ids, the graph name, attribute names, and attribute values — is written bare when it matches the DOT ID grammar, and double-quoted otherwise:

  • Bare — matches [A-Za-z_] (alphanumeric/underscore, not starting with a digit) or a numeral (-?(\.|[0-9](\.[0-9])?)).

  • Quoted — everything else is wrapped in double quotes, with backslashes escaped as \\ and double quotes as \".

Input Written as

parse

parse

3.14

3.14

two words

"two words"

say "hi"

"say \"hi\""

Flow chunking

dotFlow() emits chunks in this order (concatenation equals toDot() exactly; boundaries are an implementation detail):

  1. the graph {/digraph { header including graph attribute lines — one chunk

  2. one chunk per node

  3. one chunk per edge

  4. the closing } — one chunk

See also