The language
Six forms, and that is the whole syntax. Every page after this one adds a layout — a new way to arrange children. None of them adds a rule.
One line draws
draft -> review -> publish
Nothing was declared there. A link to a name nobody declared creates a box for it, labelled with the name.
A chain marks every hop, so that line is exactly draft -> review and
review -> publish.
Declare a node when you have more to say about it
|oval#visitor| "Visitor"
|box#api| "API"
|cyl#db| "Postgres"
visitor -> api -> db
The bars carry the identity — a type, and an id after #. The quoted
string is the label.
Only the bars are required, and both halves inside them are optional:
|box#api|is a box namedapiwith no label — a blank card, not a card reading “api”.|#api|is that same box. A node with no type is a|box|.|oval|is an oval nothing can link to, because an id is the one thing you reference.
Style is a block on the node
|box#edge| "Edge"
|box#core| "Core" { fill: --rose-wash; stroke: --rose-deep; radius: 14; }
edge -> core
A { } after the label is that node’s style: key: value; declarations,
and the vocabulary is the same everywhere in the language.
Children go in brackets
{ gap: 76; }
|box#web| "Web" { fill: --rose-wash; stroke: --rose-deep; color: --rose-ink; }
|box#api| "API" { fill: --purple-wash; stroke: --purple-deep; color: --purple-ink; }
|group#store| "Store" { direction: column; gap: 26; padding: 22; } [
|box#cache| "Cache" { fill: --purple-wash; stroke: --purple-deep; color: --purple-ink; }
|cyl#db| "Postgres" { fill: --purple-wash; stroke: --purple-deep; color: --purple-ink; }
]
web -> api
api -> store.cache
api --> store.db
A [ ] holds content — children, in the order written.
A named container gives its children a path, which is how store.cache and
store.db reach them from outside. There is no search: cache alone at the
root would make a new box rather than find that one.
Four nodes here carry the same three declarations. That is the itch the next section scratches.
The stylesheet on top
Everything so far styled one node at a time. A { } block standing before
any drawn statement is the stylesheet: it draws nothing, and it says what
whole kinds of thing look like.
{
gap: 80;
|box| { radius: 4; }
|-| { stroke: --gray-deep; font-size: 12; }
.hot { fill: --rose-wash; stroke: --rose-deep; }
|svc::box| { fill: --purple-wash; stroke: --purple-deep; }
}
|svc#web| "Web"
|svc#api| "API" .hot
web -> api "HTTPS"
Four kinds of entry, each reaching a different way:
|box| { }is a rule — every node of that type.|-|is the link type, so that line styles every link on the page..hot { }is a class, worn after the label:|svc#api| "API" .hot.|svc::box| { }is a define — a new type carrying its own defaults over a base one.gap: 80is a bare declaration, and belongs to the root. The file is the body of an implicit root container, so its children are your top-level nodes.
An #id { } rule reaches exactly one node. When several of these touch the
same property, the more specific one wins; the style page walks
the ladder.
The six forms
Everything above is built from these, and there are no others:
| Form | Means |
|---|---|
|type#id| | Identity — a type and an optional id, always in bars. |
"…" | The label. Each type decides where it goes: centred in a box, the caption of a group, the title of a chart. |
{ … } | Style — declarations. On a node it is that node’s; before any statement it is the root’s stylesheet. |
[ … ] | Content — children, in the order written. |
.name | A class, defined once and worn after the label. |
a -> b | A link — two ids and an operator. The operator is the look. |
A drawn node is |type#id| "label" .class { style } [ children ], and a link
is the same tail on a different head: a -> b "label" .class { style }. A name
goes bare only when it is being referenced, and the one thing you reference is
an id — which is why types and classes always carry their sigil.
Where each family starts
A layout: on any container — the root, or any node — picks the family:
| Write | Get | Tour |
|---|---|---|
layout: flow (default) · grid | boxes in a row, a column or a grid | Diagrams |
layout: tree · |mindmap| | a hierarchy from nesting alone | Trees & mindmaps |
|table| · |entity| | ruled grids and ER cards | Tables & entities |
layout: sequence | participants, lifelines and messages on a time axis | Sequences |
layout: chart · pie | bars, lines, areas, dots, slices | Charts |
layout: drawing | a dimensioned engineering sheet | Drawings |
layout: floorplan | walls, openings and fixtures | Floor plans |
layout: schematic | parts, pins and routed wires | Schematics |
The nodes, links, cascade and colours are identical in every one. A layout only decides where its children go, and what its links mean.