define
Declares a template — a node shape written once and stamped out wherever its name is used. The implicit attribute node names the type being declared (:card); the attribute group declares the template’s own attributes, each with a TYPE written name: !<type>(…), and {{name}} splices the value into the body. body and detail are reserved names that declare the template’s SECTIONS rather than attributes: {{body}} and {{detail}} splice the content of the use’s own {...} and [...]. Because the declarations make a real node type, a use is checked where it is written — a value the type cannot parse is an error at the call site, naming the template. A template may use other templates, but circular expansion is a compile error. An id written literally in the template is private to each use, so two uses never collide; an id spelt through an attribute (figure#{{fid}}) is the caller’s, document-wide.
#Attributes
#Allowed content
#Examples
@define:swatch{
square(x: 0; y: 0; size: 1; colour: {{colour}})
}(
colour: !colour(default: blue)
)
swatch(colour: red)@define:finding{
note{
{{body}}
}
}
finding{Richness scales as roughly the cube root of area.}@define:reading{
point(x: {{x}}; y: {{y}}; label: {{name}})
}(
x: !number(required; implicit)
y: !number(required)
name: !string(default: —)
)
reading:2(y: 4.1; name: Baltra)#Notes
- Each attribute is declared
name: !<type>(…), parentheses included even when empty (!string()) — a bare!nameis a value fold missing its body. Inside the group,required,default,aliasesandimplicitdescribe the ATTRIBUTE; everything else refines the type (!number(min: 0),!reference(targets: @data)). Join alternatives with|. - An attribute that is neither
requirednor given adefaultbinds nothing when a use omits it, so a template that splices it gets the ordinary undefined-constant error. Give every attribute a default unless the use must always supply it. body:anddetail:declare the template’s sections, using the same policy forms an element has:!all(),!none(),!literal(),!children(scene, figure),!inline(content: all). They default tobody: !all()anddetail: !none(), so a template that splices{{detail}}must declaredetail: !all()or every use is refused its[...]section.- A literal id in the template compiles to
id~1,id~2, … numbered by use in document order. A reference written in the template resolves to the same use’s copy first, then outward — the enclosing template’s, then the document’s; a name declared both in the template and outside it is an ambiguity error, never a shadow. - Block content passed through a slot keeps the caller’s ids:
card{ figure#mine{…} }leavesminedocument-wide. declared inside a template is private per use like any id, and canvas attributes (x: #pts.x) cannot reach a private dataset — declare theat document level, or name it through an attribute (#{{name}}).preset:does not apply to a use, and a use is not checked against its parent’s content policy — the nodes it expands to are, where they land.