Source style

The conventions that keep a .chalk file legible to the next person editing it by hand.

#The shape of the source

#Multiline nodes and multiline attribute groups

A .chalk file is read and edited by hand, and the two forms of an attribute group are chosen to match the node carrying them. A node written on one line takes semicolons. A node whose body or detail spans lines takes a group that spans lines too, one attribute per line — even with only one attribute — so the closing brackets of a nested construct always read the same way.

curve(expression: sin(x); colour: blue; dashed)

cue{
    curve(expression: sin(x); colour: blue)
}(
    in: 1
)

#Bare booleans, written last

Booleans take the bare-word shorthand — runnable, dashed, !fill, !show ticks — rather than : true or : false, and come last in every group, the document header included, so a group reads as values and then flags.

#Spaced names in attribute groups

A hyphenated attribute name is written with spaces inside a group — x domain, y axis label, in duration, show background — which reads as English in a group that is already one key per line.

Warning
The spacing is for keys only; inside a {{…}} expression a name is written as it is declared.

#Values

#Seconds and milliseconds

A duration of a second or more is written in seconds — 1.4s, 2s — and anything shorter in milliseconds — 400ms, 900ms. Both suffixes are accepted wherever a time is written; the convention lets a scene's timings be compared down a column without converting them first.

#Bulk data and repeated expressions

Rows of data live in a @data block, even where they are read once. A hundred readings written inline turn the environment holding them into a wall of digits, and the structure of the graph disappears behind its own numbers; the block is also where a reader looks to find what a document's numbers are.

A long expression, and anything written more than once, is declared in @let and spliced back with {{name}}, so a number appearing in two places — a curve and the code beside it — cannot be edited in one and missed in the other.

@data#samples{
    x     | y
    0.31  | 0.18
    0.52  | -0.09
    -0.66 | 0.76
}

@let(
    gaussian: exp(-(x^2 + y^2) / 2) / (2 * pi)
)

scene{
    A standard bivariate normal, and three draws from it.
}[
    graph{
        surface(expression: {{gaussian}}; colour: temperature)
        scatter(x: #samples.x; y: #samples.y; colour: grey)
    }
]

#What a comment is for

// at the start of a line keeps it out of the output, and @ignore does the same for a block. The comment worth writing says where a constant came from — the source of a rate, the reason for a cutoff, the year a survey was run — because that is the one fact the source cannot recover on its own.

Last updated