Reuse & logic
Constants, conditionals, repetition, templates, presets, includes and comments — the directives.
#Constants
@let declares named constants, spliced as text with {{name}} wherever they are used — prose, attribute values, code bodies. The attribute group is the bindings, so has no attributes of its own and no head shorthand (@let:x is an error).
@let(source-note: Johnson & Raven (1973))
As reported in {{source-note}}.#Conditionals
@if compiles its body only when every condition holds. Conditions test constants by exact value, the group is the conditions, and naming an undeclared constant is a compile error:
@let(audience: teacher)
@if(audience: teacher){
note{
Answers are collected in the closing scene.
}
}#Repetition
@for repeats its body. The implicit attribute n is a non-negative count (:3) or an inclusive ascending range (:0..6), and {{i}} splices the counter:
@for:0..4{
point(x: {{i}}; y: {{i}})
}as: renames the counter — as: k makes the splice {{k}} — which is how nested loops tell their counters apart:
@for(n: 0..2; as: row){
@for(n: 0..2; as: col){
point(x: {{row}}; y: {{col}})
}
}#Templates
@define declares a template — a node shape written once and stamped out wherever its name is used. The head names the type (:swatch — the implicit attribute is node), the group declares the template's parameters with their defaults, and {{param}} splices each one verbatim into the body:
@define:swatch{
square(x: 0; y: 0; size: 1; colour: {{colour}})
}(
colour: blue
)
swatch(colour: red)node is the implicit attribute of both @define and @preset, no template parameter may be called node, and no preset can set an attribute of that name. Circular template expansion is a compile error.#Presets
@preset bundles attributes for reuse. Three forms: :text(size: 24) is anonymous and applies to every text node; #accent(...) is named and applied by hand with preset: #accent; #accent:text(...) is both named and scoped to one type. Presets apply to block nodes only, must be declared before use, cannot reference other presets, and share the one document-wide #id namespace.
#Includes
@include splices a partial — a .part.chalk attachment — into the document at compile time, exactly where the directive is written: :overview.part.chalk. A dataset or constant declared in an included file is visible to the whole document, and circular includes are a compile error.
#Comments
@ignore is the block comment: its body is discarded before parsing — drafts, notes to self, content taken out of circulation without deleting it. Braces inside still need to balance; it takes no attributes and no implicit value.