Body & detail
The two slots every construct may carry, and the policies that say what is legal in each.
#The { } body and the [ ] detail
A construct may carry two bracketed slots after its head: a { } body and a [ ] detail. Most elements use only the body. The is the one place the distinction is structural: its body is the narrative, its detail is the canvas.
scene{
The narrative — prose, headings, callouts.
}[
canvas.graph{
curve(expression: x^2)
}
]#Containment policies
What is legal inside each slot is declared per element, and every reference page prints it under Allowed content. A policy is one of four things: a list of element ids, a prose description of what the slot accepts, a declared type, or nothing at all when the element takes no such slot.
canvas.graph{
A sentence about the curve.
curve(expression: x^2)
}[content-policy]node `paragraph` is not allowed here (allowed: line, polygon, curve, circle, square, rectangle, triangle, star, diamond, hexagon, vector, segment, angle, point, text, axis.label, axis.brace, axis.band, scatter, histogram, fit, parameter, integral, residuals, contour, heatmap, cue, cue.draw, cue.trace, cue.highlight, cue.spotlight)
- A list of ids — only those elements compile there. A
canvas.graphbody accepts marks and cues, nothing else. - Prose — the slot takes content rather than elements, like a paragraph's rich text or a
lineschunk's literal code. - A type — a body may be declared as a value rather than as content, and is then parsed exactly as an attribute value is, so a wrong shape is a compile error rather than something odd on the page. Micronodes have taken one since D33, and a block node's body may too since D46 — this library types its values through attributes instead, so nothing here uses either.
- Nothing — marks take no body; a mark's text is its
label:attribute.
#Rich text and containment policy
Where a page says a slot takes inline Chalk, the contents are prose with micronodes — **bold**, $maths$, !teal{…} — not nodes. The same is true of attributes typed rich-text: a mark's label: renders formatting and maths, but cannot hold a paragraph.
Which means micronodes are not narrative-only. Every mark's label: is rich-text, as are a 's name:, a graph's x-axis-label / y-axis-label and an environment's title: — so the same formatting, maths, colour and live {{…}} values that work in a paragraph work on the canvas. Each reference page names the type of every attribute, so rich-text in the type column is the authority on where.
Every heading an element sets over its own content is the same type: a 's title:, an 's caption:, a 's term: and the title: of a , or . A table of measurements is captioned in the notation its cells are written in, and a term as much notation as word — $\epsilon$-$\delta$ continuity — sets as one.
canvas.graph{
curve#bell(expression: exp(-x^2 / 2); label: $N(\mu, \sigma^2)$)
point(x: 1; y: 2; label: !teal{turning point})
scatter#readings(x: 1, 2, 3; y: 2.0, 2.4, 3.1)
fit#f(of: #readings; model: polynomial; degree: 1)
text(x: 0; y: 4; label: slope = {{round(#f.slope, 2)}})
}What a label cannot do is hold block content. Where a canvas needs that, the scene's detail takes it directly: paragraph, the four headings, list and equation are legal in both slots, and and in the detail only. There is one content vocabulary rather than a narrative set and a canvas set; the two slots differ by a short list of narrative-only elements — the four callouts, divider, step and the internote card.
{{#f.slope}} — which works the same in a paragraph and in any rich-text attribute.#Allowed in
Every node's page carries an Allowed in section — the reverse of the policy, computed across the whole reference: which elements name this one in their body or detail. A policy list gives an element's permitted children; this gives its permitted parents.