Manual
Overview
Language
IntroductionScenes & structureText & inlineGraphsCode panesAnimationDataReuse & logicExpressions & parameters
Elements
Text
ParagraphHeading 1Heading 2Heading 3Heading 4Unordered ListDivider
Media
ImageTableEquation
Callouts
NoteDefinitionExampleTask
Graph
GraphLinePolygonCurveIntegralScatterHistogramPointSegmentVectorCircleSquareRectangleTriangleStarDiamondHexagonTextAxis labelAxis BraceFitResidualsContourHeatmapParameter
Code
Code canvasLines
Animation
CueDraw cueTrace cueHighlight cueSpotlight cueType cue
Structure
SceneStep
Reference
Internote Reference
Inline
Formatting
BoldItalicsInline CodeHighlightLink
Text colour
Red textOrange textYellow textGreen textTeal textBlue textPurple textPink textGrey text
Maths
Maths
Reference
Internote ReferenceValueConstant
Other
FootnoteIcon
Directives
DatasetIncludeConstantsTemplatePresetConditionalForIgnore
Keyframes
KeyframeZoom keyframe
Attribute types
?
  1. Language
  2. Reuse & logic

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 @let 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 @let 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 (@for:3) or an inclusive ascending range (@for: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 (@define: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)
Because 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: @preset:text(size: 24) is anonymous and applies to every text node; @preset#accent(...) is named and applied by hand with preset: #accent; @preset#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: @include: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.

On this page
ConstantsConditionalsRepetitionTemplatesPresetsIncludesComments
Reuse & logic · Internote