scene
One of the two nodes a document holds directly, and the only one that renders where it is written. The body is the narrative — prose, headings, callouts — and the detail declares the canvas: the environments, and the block content shown beside them. A document is a sequence of scenes, read in order.
#The scene
A scene is a body of narrative and a detail that declares the canvas. A document is a sequence of scenes, read in order. The scene's own attributes govern its animation timeline — duration (its implicit attribute, auto by default), autoplay, and loop.
scene{
# A heading
Narrative prose, read top to bottom.
}[
canvas.graph{
curve(expression: sin(x))
}
]#Narrative and canvas
The body { } holds what is read: paragraphs, headings, lists, equations, callouts, dividers, references. The detail [ ] holds what is shown: canvas environments (, ) and supporting canvas content such as and .
Most of the content vocabulary is legal in both — prose, the four headings, lists and equations read the same in either slot. What is not: the four callouts (, , , ) and the reference are narrative only, and table, image, , the cues and the canvas environments are detail only. Each construct's reference page carries its own Allowed in row.
#Steps
A step — written as === on its own line in the narrative — carves the scene's timeline into steps. Everything animated anchors to those steps: a cue's in: 2 fires at step two, a !cue.to's at: 2 starts its move there. The reader's progress through the text advances the canvas.
A marker is therefore a timeline trigger rather than a paragraph break — paragraphs separate with a blank line — so a scene whose detail never changes carries none at all, and a scene with markers has something anchored to each of them. Prose and canvas state gives the check.
scene{
First the data alone.
===
Then the fitted line.
}[
canvas.graph{
scatter#points(x: 1, 2, 3; y: 2.0, 2.4, 3.1)
cue{
fit(of: #points; model: polynomial; degree: 1)
}(
in: 1
)
}
]#Environments and splits
A detail may declare two canvas environments; the scene's direction attribute arranges them — auto (the default), horizontal side by side, vertical stacked — and ratio gives the first environment's share over the second's, written as a fraction like 3/2.
auto follows the space the canvas has: stacked while the note is being read, where the canvas column is far taller than it is wide and two side-by-side halves of it are unreadable, and side by side in presentation, where the canvas has the whole screen and height is what is scarce. Leave it at auto unless the arrangement itself carries meaning.
scene{
A graph beside its code.
}[
canvas.graph#g{
curve(expression: x^2)
}
canvas.code{
lines{
y = x ** 2
}
}(
language: python
)
](
ratio: 3/2
)horizontal or vertical only when the split has a semantic reason to hold the same axis everywhere — a number line reading under the graph it indexes is vertical in presentation too, and a before/after pair stays horizontal in the reading view. A fixed direction chosen for how it happened to look in one of the two is the case auto exists for.#Continuing an environment
An environment carries an id on its node — canvas.graph#projectile{...} — and a later scene's environment can point back at it with continue: #projectile. What continues is the session state: reader-manipulated parameters, the fit degree they chose, the view they zoomed to. continue: hands off state, never markup — the content is the new environment's own.
continue: may point at an environment declared in any scene, and a collision between any two #ids anywhere is an error.#Attributes
auto#Allowed content
#Examples
scene{
# Title
Intro paragraph.
}scene{
# With Detail
Explain the concept.
}[
canvas.code{
lines{
print("hello")
}
}(
language: python
)
]