Wit

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.

Two ways to write a node

A node that fits on one line uses the parenthesis form, (name … name). A container that spans several lines uses the block form, @name on its own line and name@ to close. They mean the same thing:

source
(h2 Methods h2)

@section
The survey ran from May to September.
section@
result

Methods

The survey ran from May to September.

Parameters glue to the name in either form: (span(class: lede) … span), @div(class: card).

Headings

Six levels, h1 through h6. Level one is the title; deeper levels nest under it.

(h1 Coastal survey 2024 h1)
(h2 Methods h2)
(h3(id: calibration) Tide-gauge calibration h3)

Each renders straight into its tag — <h1>Coastal survey 2024</h1> — and an id becomes an anchor you can link to. Don't skip a level for a smaller heading; size is a styling concern.

Sectioning wrappers

Semantic containers describe the shape of the page. Each maps to the same-named HTML element: article (a self-contained piece), section (a thematic division), header and footer (opening and closing blocks), nav, aside (supporting content), and main.

source
@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@
result

A survey of the northern reef

The season opened early this year.

Published 2024.

That builds an <article> holding a <header>, <section>, and <footer>. Prose inside a container is wrapped in paragraphs for you, so don't add an inner (p … p).

Generic containers

When no semantic wrapper fits, use the block div or the inline span. Give either a class or id to hook it for CSS:

source
@div(class: callout-card)
A boxed note, grouped for styling.
div@

An (span(class: lede) opening clause span) inside a sentence.
result

A boxed note, grouped for styling.

An opening clause inside a sentence.

The block becomes <div class="callout-card">, the inline one a <span class="lede">.

Bulleted & numbered lists

A list holds one li per item. The theme draws the markers — never type a dash or a number yourself.

source
@ul
(li Salt marsh li)
(li Mud flat li)
(li Shingle bank li)
ul@
result
  • Salt marsh
  • Mud flat
  • Shingle bank

Swap ul for ol and the items are numbered; reorder them and they renumber.

Definition lists

A dl pairs a term (dt) with its description (dd) — a glossary, a field key:

source
@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@
result
Transect
A fixed line along which measurements are repeated.
Datum
The reference level all heights are measured from.

Nested lists

An item can carry marks, links, or a whole list. When an item holds a nested list it spans several lines, so write it in the block form:

source
@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@
result
  • The daily readings, taken at dawn.
  • Supplies aboard the tender:

    • spare batteries
    • calibration weights

Block quotations

A blockquote lifts a passage off the page — an epigraph, a pulled quote, a cited paragraph:

source
@blockquote
"The sea, once it casts its spell, holds one in its net of wonder forever."
— Jacques Cousteau
blockquote@
result

"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 and keeps its line breaks and indentation. Its body is still read as Wit, so _x_ would turn italic. For code, use the verbatim form @@pre … pre@@, which shows its body exactly as typed:

source
@@pre
def read():
    return gauge.level_m  # 2.41
pre@@
result
def read():
    return gauge.level_m  # 2.41

Horizontal rule

A divider — a visual break with no heading. It takes no body and no closer:

source
The first movement ends here.

@hr

The second begins.
result

The first movement ends here.


The second begins.

That produces a plain <hr> between two paragraphs.

Side-by-side: rows & columns

A row lays its columns out horizontally. @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@

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. The row wraps: when the screen or page is too narrow, the columns stack. Separate a row from surrounding prose with blank lines.

See also