flowchart
A flowchart environment on the scene's canvas: a flowchart, a tree or an entity–relationship schema. It is written as what connects to what, never as coordinates: boxes and the arrows between them, arranged by the environment in layers along direction:, its implicit attribute — flowchart:right{…} runs left to right. Only what a step has on show is arranged, inside a structure taken from the whole environment, so as cues bring boxes in the rest glide to make room and nothing is rearranged. The frame is a camera: focus: (#id of a box) and zoom: (a multiplier over the fitted frame) are both animatable with !cue.to, so one keyframe on each glides into one part of a large chart as the narrative reaches it. A logic circuit is a logic.
flowchart

#The flowchart environment
flowchart holds a flowchart, a tree or an entity–relationship schema. Its implicit attribute is direction, the way the arrangement runs: flowchart:right{…} reads left to right, and with nothing written it runs down. A logic circuit is drawn the same way, but in its own environment, logic, where the reader can operate it.
#Boxes and arrows
A flowchart is written as what connects to what, never as coordinates. box declares the things and arrow the relations between them — endpoints are #ids of boxes in the same environment — and the environment arranges the result in layers along direction: — down by default, up, right or left. A tree is the same arrangement with the arrows all pointing one way. Chains that share no arrow are arranged apart, each ranked on its own, and stand side by side across the flow — columns under down, rows under right — so a wide box in one never moves a box in the other.
The arrows run through the space between the layers, never across a box and never along one another. Each leaves and arrives at the middle of a face: one arrow at its centre, several evenly spaced about it in the order of where they are going. The boxes are placed so those points line up, and an arrow whose two ends line up is a straight line; one whose ends cannot turns once, cleanly, on a track of its own. An arrow that skips layers runs straight down the gap beside the layers it passes. Every arrow leaves the front of its box and lands on the back of the next, whichever way it runs, so an arrow back up the flow loops round: out of the later box, up beside the layers between, and down into the earlier box from behind. An arrow back to its own box loops round its side.
An arrow's label: is set in a small chip on its own straight run, near where it leaves, so the words stand clear of every line. Where arrows leave a face too close together for that, the chip sits just beside its line.
head: says which ends point: end (the default, at to:), none for a plain line, both, or start. The boxes are ranked from from: to to: whichever it is. from-label: and to-label: set words beside the line where it leaves its first box and where it meets its second.
A chart longer than the environment has room for wraps rather than shrinking, so a box keeps the size its text needs. Plain, it snakes: the next line reads back the other way, and the arrows across the fold drop past the ends of both lines and turn up into the next. A strictly- direction — strictly-down, strictly-up, strictly-right, strictly-left — keeps every line reading the one way: each starts again at the beginning beside the last, the way lines of text do, and the arrows across a fold are carried back along the gap between the lines.


flowchart{
box#sample:terminal{Sample collected}
box#pcr{
PCR amplify
30 cycles
}
box#check:decision{Enough DNA?}
arrow(from: #sample; to: #pcr)
arrow(from: #pcr; to: #check)
arrow(from: #check; to: #pcr; label: no; dashed)
}(
direction: down
)hidden: at the step, takes no room; when a cue brings one in, the rest glide to make room for it, and the newcomer fades in once they have. cue.draw strokes an arrow in along its own length, and draws several boxes and arrows along the flow, each a little after the one before; a dashed: arrow fades instead, since a dash pattern and the draw reveal cannot share one stroke.#Shapes
shape: carries the flowchart conventions a reader already knows: box (the default rounded rectangle), decision (the diamond), terminal (the pill) and ellipse. It is the implicit attribute, so box#check:decision{Enough DNA?} reads as the diamond it draws. A box's text is its body, rich inline — maths, bold and {{…}} all work — and the body keeps its source lines: the first is the label, every further line a smaller muted line beneath it. Text wider than the widest box wraps rather than spilling.
Entity–relationship diagrams take Chen's shapes: entity and weak-entity (rectangle, double rectangle), relationship and identifying-relationship (diamond, double diamond), and attribute, multivalued-attribute (double ellipse) and key-attribute (its name underlined). Chen's links are plain lines, head: none, and a cardinality sits beside the entity it qualifies as the arrow's from-label: or to-label:.


flowchart{
box#emp:entity{Employee}
box#id:key-attribute{Employee ID}
box#phones:multivalued-attribute{Phone numbers}
box#has:identifying-relationship{Has}
box#dependant:weak-entity{Dependant}
box#works:relationship{Works for}
box#dept:entity{Department}
arrow(from: #emp; to: #id; head: none)
arrow(from: #emp; to: #phones; head: none)
arrow(from: #emp; to: #has; head: none; from-label: 1)
arrow(from: #has; to: #dependant; head: none; to-label: $N$)
arrow(from: #emp; to: #works; head: none; from-label: $N$)
arrow(from: #works; to: #dept; head: none; to-label: 1)
}(
direction: down
)A box says what kind of thing it is with group:, never what colour to be. Boxes of one group share a hue, and the footer keys each group beside a box in its colour. The environment's hues: pins the groups whose colour means something — hues: Quantitative = blue, Qualitative = teal — and any other group is dealt the next hue no pin has taken. A box's own colour: still wins, and !legend turns the key off.
#focus, zoom and the glide
The frame is a camera. focus: takes #id naming a box the environment draws, and zoom: multiplies over the fitted frame — omitted, the content fits the environment. Both are animatable, so one !cue.to on each glides into one part of a large chart as the narrative reaches it; interactive additionally hands the reader wheel-zoom and drag, with a double-click back to the authored frame.
flowchart:down{
box#sample:terminal{Sample collected}
box#pcr{PCR amplify}
box#check:decision{Enough DNA?}
arrow(from: #sample; to: #pcr)
arrow(from: #pcr; to: #check)
}(
focus: #sample !cue.to{#check}(at: 1; over: 800ms)
zoom: 2
)#Attributes
directiondown, up, right or left. A chart longer than the environment wraps rather than shrinking, so boxes keep the size their text needs. Plain, it snakes: the next line reads back the other way. A strictly- direction keeps every line reading the one way — each starts again at the beginning beside the last, the way lines of text do — and the arrows across a fold are carried back along the gap between the lines.downuprightleftstrictly-downstrictly-upstrictly-rightstrictly-leftflowchart:valuedowntitlehues=, its colour — hues: Quantitative = blue, Theory = purple. Any group not pinned here is dealt the next hue no pin has taken.flowchart-hueslegendgroup:. !legend turns it off.truefocus#id naming a box this environment draws. Animatable with !cue.to; absent, the frame centres.zoom!cue.to. NO default: an omitted zoom is auto — the content fits the environment — and zoom: 1 written out means exactly the fit.interactivefalsecontinuecontinue: #that-environment. The reader's explored camera carries forward; every authored attribute is the new environment's own.#Allowed content
#Allowed in
#Examples


flowchart{
box#sample:terminal{Sample collected}
box#pcr{
PCR amplify
30 cycles
}
box#check:decision{Enough DNA?}
arrow(from: #sample; to: #pcr)
arrow(from: #pcr; to: #check)
arrow(from: #check; to: #pcr; label: no)
}(
direction: down
)

flowchart{
box#question:terminal{Question}
box#hypothesis{Hypothesis}
box#experiment{Experiment}(colour: teal)
arrow(from: #question; to: #hypothesis)
arrow(from: #hypothesis; to: #experiment)
arrow(from: #experiment; to: #hypothesis; label: revise; dashed: true)
}(
direction: right
title: The scientific method
)

flowchart{
box#dna{DNA}
box#rna{RNA}
cue.draw{
arrow(from: #dna; to: #rna; label: transcription)
}(
in: 1
)
}(
direction: right
)