Structure & layout
Headings give a document its outline; sectioning wrappers give it a skeleton; lists, quotes, and rules set pieces apart; rows and columns place blocks side by side. Every one is a node — no CSS, no floats.
Headings
Six levels, @h1 through @h6. Level one is the
title; deeper levels nest under it to trace your argument.
@h1 Coastal survey 2024 h1@ @h2 Methods h2@ @h3 Tide-gauge calibration h3@
Coastal survey 2024
Methods
Tide-gauge calibration
Each renders straight into its tag — <h1>Coastal survey 2024</h1> —
with no paragraph around the text. Don't skip a level for a smaller heading; the
jump breaks the outline, and size is a rendering concern.
Sectioning wrappers
Semantic containers describe the shape of the page. Each maps to the same-named HTML element that a screen reader, print engine, or search index looks for:
@article … article@ a self-contained piece @section … section@ a thematic division @header … header@ an opening block (title, byline) @footer … footer@ a closing block (date, credits) @nav … nav@ navigation links @aside … aside@ supporting or marginal content @main … main@ the primary content region
Nest them and the document gains real structure:
@article @header @h1 A survey of the northern reef h1@ header@ @section The season opened early this year. section@ @footer @small Published 2024. small@ footer@ article@
A survey of the northern reef
The season opened early this year.
That builds an <article> holding a <header>, <section>, and <footer>. A @section already paragraph-wraps its prose, so don't add an inner @p … p@.
Generic containers
When you need a box to style or label and no semantic wrapper fits, use the
block @div or inline @span. Both accept and to hook them for CSS:
@div |class callout-card| A boxed note, grouped for styling. div@ An @span |id lede| opening clause span@ inside a sentence.
A boxed note, grouped for styling.
An opening clause inside a sentence.
The block becomes a <div>, the inline one a <span>. Rendering covers how a
class name reaches your stylesheet.
Bulleted & numbered lists
A list is a list node holding one @li per item. The theme draws
the markers — never type a dash or a number yourself.
@ul @li Salt marsh li@ @li Mud flat li@ @li Shingle bank li@ ul@
- Salt marsh
- Mud flat
- Shingle bank
Swap @ul for @ol and the numbers come
automatically; reorder items and they renumber for free:
@ol @li Record the water level. li@ @li Note wind direction. li@ @li Photograph the transect. li@ ol@
- Record the water level.
- Note wind direction.
- Photograph the transect.
Definition lists
A @dl pairs a term (@dt) with its description
(@dd) — a glossary, a field key, a set of parameters:
@dl @dt Transect dt@ @dd A fixed line along which measurements are repeated. dd@ @dt Datum dt@ @dd The reference level all heights are measured from. dd@ dl@
- Transect
- A fixed line along which measurements are repeated.
- Datum
- The reference level all heights are measured from.
Items hold rich content
An item is inline-context: a one-line item flattens to just its text, with no inner paragraph. But it can still carry marks, links, or a nested list — drop a whole list node inside an item's body to nest:
@ul @li The _daily_ readings, taken at dawn. li@ @li Supplies aboard the tender: @ul @li spare batteries li@ @li calibration weights li@ ul@ li@ ul@
- The daily readings, taken at dawn.
- Supplies aboard the
Block quotations
A @blockquote lifts a passage off the page — an epigraph, a
pulled quote, a cited paragraph. The theme adds a left rule and muted colour:
@blockquote "The sea, once it casts its spell, holds one in its net of wonder forever." — Jacques Cousteau blockquote@
"The sea, once it casts its spell, holds one in its net of wonder forever." — Jacques Cousteau
For a short quoted phrase inside a sentence, plain quotation marks are enough.
Preformatted text
A @pre block renders monospaced — a code sample, a data
fragment, anything shown in a fixed-width face:
@pre gauge.read() -> 2.41 m pre@
gauge.read() -> 2.41 m
Horizontal rule
A self-closing divider — a visual break with no heading. It takes no body:
The first movement ends here.
@hr
The second begins.The first movement ends here.
The second begins.
That produces a plain <hr>.
Side-by-side: rows & columns
A @row is an invisible flexbox that lays its columns out
horizontally. A @col |size 260| fixes a column's width; a bare @col fills whatever space is left. Put anything in a column —
prose, an image, a table:
@row @col |size 260| @img |src ./gauge.png| |alt The tide gauge| col@ @col The gauge logged every hour of every tide, its readings the backbone of the season's survey. col@ row@
The fixed-plus-flexible pair is the workhorse for an image beside its explanation. Two bare columns split the row evenly — here it is live:
The lamp room. Glass on every side and a lens that threw the beam twenty miles out to the shipping lanes.
The watch room. Below the light, a desk, a barometer, and the log where every hour of every night was accounted for.
A size takes a named preset (small, medium, large — 220, 380, 600 pixels), a pixel number, or a percentage; several bare columns share the leftover equally. The row wraps: when the viewport or printed page is too narrow, the columns stack — two columns on a wide screen, one readable column on a phone, no media query. Separate a row from surrounding prose with blank lines so it stays top-level.
See also
- Writing prose — text, emphasis, and the inline marks these blocks hold.
- Tables — a captioned table to place inside a column.
- Images & media — sizing a figure in a fixed column.