Primitive Shapes

Primitive shapes are what everything is broken down into for rendering. Higher-level blocks (flowchart nodes, charts, cards, …) all lower to these, so targeting a new backend only means re-implementing the primitives.

Every shape shares a few common fields, summarised here; the per-shape tables below reflect the full field set of each shape:

Shared fieldMeaning
idName used to connect the shape (a -> b) and to anchor others to it.
classStyle classes — text and SVG paint (fill, stroke, …) via the class system.
anchor_left / anchor_right / anchor_top / anchor_bottomFractional anchors (0–1) that pin an edge of the shape to the parent box.
connect_pointsWhich sides (:left/:right/:top/:bottom) edges attach to.
linkMake the shape a hyperlink to an in-site page (bare page name, or site:page) — see below.

The box-like shapes — rect, circle, and container — additionally accept an icon badge: icon (a pack.name), icon_size, icon_pos (:center / :top_left / …), and icon_class.

Any shape with a link is wrapped in a clickable <a> so a reader can click the box/pill to drill into that page. The target resolves exactly like a prose link — a bare page name → page.html, a cross-site site:page, and an unknown page fails the build the same way a bad markdown link does. Because diagrams are inlined SVG, the anchor navigates the page. Avoid putting link on a container whose children are also linked (<a> can't nest) — link the container's title label instead.

rect

An axis-aligned rectangle — the workhorse box.

PropertyTypeRequiredDescription
xf64noTop-left x corner, in canvas pixels.
yf64noTop-left y corner, in canvas pixels.
widthf64noBox width.
heightf64noBox height.
fillutf8noFill colour.
strokeutf8noOutline colour.
ididentifiernoName used to connect the shape (a -> b) and to anchor others to it.
classlist<utf8>noStyle classes — text and SVG paint via the class system.
anchor_leftf64noFractional anchor (0–1) pinning the left edge to the parent box.
anchor_rightf64noFractional anchor (0–1) pinning the right edge to the parent box.
anchor_topf64noFractional anchor (0–1) pinning the top edge to the parent box.
anchor_bottomf64noFractional anchor (0–1) pinning the bottom edge to the parent box.
connect_pointslist<AnchorSide>noWhich sides (:left/:right/:top/:bottom) edges attach to.
iconutf8noIcon-badge icon (a pack.name).
icon_sizef64noIcon-badge size.
icon_posIconPosnoIcon-badge position (:center / :top_left / …).
icon_classlist<utf8>noIcon-badge style classes.
linkutf8noLink the shape to an in-site page (bare page name, or site:page). Wraps it in a clickable <a>; an unknown page fails the build like a bad prose link.
diagram { width = 200  height = 90
  rect { x = 20.0  y = 15.0  width = 120.0  height = 60.0  fill = "#cce"  stroke = "#333" }
}

circle

A circle, positioned by its centre.

PropertyTypeRequiredDescription
cxf64noCentre x point.
cyf64noCentre y point.
rf64noRadius.
fillutf8noFill colour.
strokeutf8noOutline colour.
ididentifiernoName used to connect the shape (a -> b) and to anchor others to it.
classlist<utf8>noStyle classes — text and SVG paint via the class system.
anchor_leftf64noFractional anchor (0–1) pinning the left edge to the parent box.
anchor_rightf64noFractional anchor (0–1) pinning the right edge to the parent box.
anchor_topf64noFractional anchor (0–1) pinning the top edge to the parent box.
anchor_bottomf64noFractional anchor (0–1) pinning the bottom edge to the parent box.
connect_pointslist<AnchorSide>noWhich sides (:left/:right/:top/:bottom) edges attach to.
iconutf8noIcon-badge icon (a pack.name).
icon_sizef64noIcon-badge size.
icon_posIconPosnoIcon-badge position (:center / :top_left / …).
icon_classlist<utf8>noIcon-badge style classes.
linkutf8noLink the shape to an in-site page (bare page name, or site:page). Wraps it in a clickable <a>; an unknown page fails the build like a bad prose link.
diagram { width = 200  height = 100
  circle { cx = 100.0  cy = 50.0  r = 36.0  fill = "#8fbcbb"  stroke = "#333" }
}

line

A straight line segment between two points.

PropertyTypeRequiredDescription
x1f64noStart-point x.
y1f64noStart-point y.
x2f64noEnd-point x.
y2f64noEnd-point y.
strokeutf8noLine colour.
ididentifiernoName used to connect the shape (a -> b) and to anchor others to it.
classlist<utf8>noStyle classes — text and SVG paint via the class system.
anchor_leftf64noFractional anchor (0–1) pinning the left edge to the parent box.
anchor_rightf64noFractional anchor (0–1) pinning the right edge to the parent box.
anchor_topf64noFractional anchor (0–1) pinning the top edge to the parent box.
anchor_bottomf64noFractional anchor (0–1) pinning the bottom edge to the parent box.
connect_pointslist<AnchorSide>noWhich sides (:left/:right/:top/:bottom) edges attach to.
linkutf8noLink the shape to an in-site page (bare page name, or site:page). Wraps it in a clickable <a>; an unknown page fails the build like a bad prose link.
diagram { width = 200  height = 80
  line { x1 = 20.0  y1 = 60.0  x2 = 180.0  y2 = 20.0  stroke = "#bf616a" }
}

label

Hello

An SVG text label. Named label (not text) to avoid clashing with the paragraph block.

PropertyTypeRequiredDescription
contentutf8yesThe text, given as the inline label: label "halfway" { … }.
xf64noAnchor x position.
yf64noAnchor y position.
font_sizef64noExplicit font size; when omitted the text auto-fits its region.
fit_widthf64noWidth of the region the text is auto-sized to fit (when font_size is unset).
fit_heightf64noHeight of the region the text is auto-sized to fit (when font_size is unset).
fillutf8noText colour.
ididentifiernoName used to connect the shape (a -> b) and to anchor others to it.
classlist<utf8>noStyle classes — text and SVG paint via the class system.
anchor_leftf64noFractional anchor (0–1) pinning the left edge to the parent box.
anchor_rightf64noFractional anchor (0–1) pinning the right edge to the parent box.
anchor_topf64noFractional anchor (0–1) pinning the top edge to the parent box.
anchor_bottomf64noFractional anchor (0–1) pinning the bottom edge to the parent box.
connect_pointslist<AnchorSide>noWhich sides (:left/:right/:top/:bottom) edges attach to.
linkutf8noLink the shape to an in-site page (bare page name, or site:page). Wraps it in a clickable <a>; an unknown page fails the build like a bad prose link.
diagram { width = 200  height = 60
  label "Hello" { x = 100.0  y = 36.0  font_size = 22.0  fill = "#5e81ac" }
}

polygon

An arbitrary closed shape from a list of points.

PropertyTypeRequiredDescription
pointsutf8yesSpace-separated x,y pairs, e.g. "180,10 230,40 180,70".
fillutf8noFill colour.
strokeutf8noOutline colour.
ididentifiernoName used to connect the shape (a -> b) and to anchor others to it.
classlist<utf8>noStyle classes — text and SVG paint via the class system.
anchor_leftf64noFractional anchor (0–1) pinning the left edge to the parent box.
anchor_rightf64noFractional anchor (0–1) pinning the right edge to the parent box.
anchor_topf64noFractional anchor (0–1) pinning the top edge to the parent box.
anchor_bottomf64noFractional anchor (0–1) pinning the bottom edge to the parent box.
connect_pointslist<AnchorSide>noWhich sides (:left/:right/:top/:bottom) edges attach to.
linkutf8noLink the shape to an in-site page (bare page name, or site:page). Wraps it in a clickable <a>; an unknown page fails the build like a bad prose link.
diagram { width = 200  height = 100
  polygon { points = "40,80 100,15 160,80"  fill = "#ebcb8b"  stroke = "#333" }
}

container

A grouping box that holds and lays out child shapes (@children). Optional chrome makes the group visible; a layout arranges the children automatically.

PropertyTypeRequiredDescription
ididentifiernoName used to connect the shape (a -> b) and to anchor others to it.
classlist<utf8>noStyle classes — text and SVG paint via the class system.
linkutf8noLink the shape to an in-site page (bare page name, or site:page). Wraps it in a clickable <a>; an unknown page fails the build like a bad prose link.
strokeutf8noOptional chrome — outline colour of the background rect that makes the group visible.
fillutf8noOptional chrome — fill colour of the background rect that makes the group visible.
paddingf64noInset between the chrome and the child shapes.
widthf64noDeclared interior width (when no layout/anchor sizes it).
heightf64noDeclared interior height (when no layout/anchor sizes it).
layoutsymbolnoLayout mode: :free (default, manual) / :grid / :layered / :force / :radial.
columnsi64noNumber of columns for :grid layout.
cell_widthf64noGrid cell width for :grid layout.
cell_heightf64noGrid cell height for :grid layout.
gapf64noGap between cells in :grid layout.
directionsymbolnoFlow direction for :layered: :toptobottom (default) / :lefttoright.
layer_gapf64noSpacing between ranks (layers) in :layered layout.
node_gapf64noSpacing between nodes within a rank in :layered layout.
iterationsi64no:force relaxation steps (default 300).
repulsionf64no:force node repulsion strength (default 9000).
link_distancef64no:force ideal edge-to-edge length (default 60).
gravityf64no:force centering pull (default 0.05).
seedi64no:force random seed for reproducible layouts (default 1).
hubidentifierno:radial hub shape id (defaults to the highest-degree shape).
radiusf64no:radial radius of the first ring (default: auto-fit to shape sizes).
ring_gapf64no:radial added radius per successive ring (default 120).
start_anglef64no:radial angle (radians) of the first shape on each ring (default -PI/2, i.e. top).
anchor_leftf64noFractional anchor (0–1) pinning the left edge to the parent box.
anchor_rightf64noFractional anchor (0–1) pinning the right edge to the parent box.
anchor_topf64noFractional anchor (0–1) pinning the top edge to the parent box.
anchor_bottomf64noFractional anchor (0–1) pinning the bottom edge to the parent box.
connect_pointslist<AnchorSide>noWhich sides (:left/:right/:top/:bottom) edges attach to.
iconutf8noIcon-badge icon (a pack.name).
icon_sizef64noIcon-badge size.
icon_posIconPosnoIcon-badge position (:center / :top_left / …).
icon_classlist<utf8>noIcon-badge style classes.
edgeslist<Edge>yesEdges connecting child shapes (a -> b).

Child blocks

SlotAcceptsMultipleDescription
childrenSvgBlockyesThe child shapes laid out by the container.
diagram { width = 240  height = 130
  container {
    anchor_left = 10.0  anchor_top = 10.0
    fill = "#eef"  stroke = "#88a"  padding = 10.0
    layout = :grid  columns = 2  cell_width = 90.0  cell_height = 44.0  gap = 10.0
    rect { fill = "#88c0d0" }
    rect { fill = "#a3be8c" }
    rect { fill = "#ebcb8b" }
    rect { fill = "#b48ead" }
  }
}

image

A raster image placed as an SVG <image>. The source (the inline label) is a doc-relative path — copied into _wdoc/ — or a URL / data: URI passed through unchanged. (The preview above uses an inline data: URI so it renders here.)

PropertyTypeRequiredDescription
sourceutf8yesImage source (the inline label): a doc-relative path, a URL, or a data: URI.
altutf8noAlt text for the <img> (page form).
widthf64noDisplay width; the natural size is used when omitted.
heightf64noDisplay height; the natural size is used when omitted.
ididentifiernoOptional explicit HTML id.
classlist<utf8>noOptional style classes.
xf64noPlacement x when used inside a diagram (ignored on a page).
yf64noPlacement y when used inside a diagram (ignored on a page).
scalef64noExtra size multiplier (diagram form).
anchor_leftf64noDiagram anchor insets (left/right/top/bottom), like any shape.
connect_pointslist<AnchorSide>noDiagram edge-attach sides, like any shape.
diagram { width = 200  height = 90
  image "logo.png" { x = 50.0  y = 15.0  width = 100.0  height = 60.0 }
}

See Images for the page-level <img> form and asset handling.

card

Note

Rich text inside a diagram.

A box whose body is arbitrary wdoc content (paragraphs, callouts, lists, even nested diagrams), wrapped in an SVG <foreignObject> so it scales with the diagram. Timelines accept cards too, pinned to a date with on.

PropertyTypeRequiredDescription
xf64noTop-left x placement in the diagram (or use anchors).
yf64noTop-left y placement in the diagram (or use anchors).
widthf64noCard box width (default 160).
heightf64noCard box height (default 90).
anchor_leftf64noDiagram anchor insets (left/right/top/bottom), like any shape.
onutf8noISO date the card is pinned to (used only when it's a timeline child).
sidesymbolnoTimeline side: :near / :far / :auto (used only as a timeline child).
titleutf8noOptional plain-text heading.
ididentifiernoOptional explicit HTML id.
classlist<utf8>noOptional style classes.
connect_pointslist<AnchorSide>noDiagram edge-attach sides, like any shape.

Child blocks

SlotAcceptsMultipleDescription
bodyWdocBlockyesThe card's rich content (paragraphs, lists, callouts, nested diagrams…).
diagram { width = 260  height = 110
  card { x = 20.0  y = 15.0  width = 220.0  height = 80.0
    title = "Note"
    p "Rich **text** inside a diagram."
  }
}

node_table

users

id: int

email: text

orders

id: int

user_id: int

A titled box built from a stack of rows, each holding arbitrary wdoc content (like a card) and exposing its own connection point — so an edge attaches to a single row (a foreign-key column, a class field) rather than the whole box. Ideal for database / ER tables and UML class diagrams.

An edge targets a row by that row's id (ordersuserid -> users_id); the marker beside each row shows where edges land. Rows are a fixed row_height (the renderer can't measure HTML), so the table's height is derived from its rows. A row attaches on [:west, :east] by default — set a row's connect_points to change which sides expose a port.

PropertyTypeRequiredDescription
xf64noTop-left x placement in the diagram (or use anchors).
yf64noTop-left y placement in the diagram (or use anchors).
widthf64noTable width (default 200). Height is derived from the rows.
anchor_leftf64noDiagram anchor insets (left/right/top/bottom), like any shape.
titleutf8noOptional header title (table / class name). Omit for a header-less table.
header_heightf64noHeader row height when a title is set (default 28).
row_heightf64noFixed height of every row (default 30). The renderer can't measure HTML, so rows don't auto-size.
ididentifiernoOptional explicit HTML id (edge target for the whole table).
classlist<utf8>noOptional style classes (applied to the frame).
connect_pointslist<AnchorSide>noWhole-table edge-attach sides (default all four). Per-row sides come from each node_row.

Child blocks

SlotAcceptsMultipleDescription
rowsnode_rowyesThe table rows, top to bottom.
PropertyTypeRequiredDescription
ididentifiernoRow id — the edge target for connecting to this row (fk -> users_id).
classlist<utf8>noOptional style classes (applied to the row content).
connect_pointslist<AnchorSide>noSides this row exposes a connection point + marker on (default [:west, :east]).

Child blocks

SlotAcceptsMultipleDescription
bodyWdocBlockyesThe row's rich content (paragraphs, code, lists…).
diagram { width = 420  height = 170  routing = :straight
  node_table { id = users
    x = 20.0  y = 20.0  width = 150.0
    title = "users"
    node_row { id = users_id    p "id: int" }
    node_row { id = users_email p "email: text" }
  }
  node_table { id = orders
    x = 250.0  y = 20.0  width = 150.0
    title = "orders"
    node_row { id = orders_id      p "id: int" }
    node_row { id = orders_user_id p "user_id: int" }
  }
  orders_user_id -> users_id :data
}