Wit

Reuse: components & multi-file

Name a piece of content once, use it by name anywhere, and change it in one place. # defines, @ uses. This page covers your own nodes, their parameters, and splitting a document across files.

Name a value

A colon, the value, and !! to end it:

source
#year: 1965 !!

The bridge opened in @year and has not closed since.
result

The bridge opened in 1965 and has not closed since.

That renders "The bridge opened in 1965 and has not closed since." Every mention follows the definition.

A longer value runs over several lines up to a !! on its own line:

source
#epigraph:
The river keeps no record of the boats.
— dock proverb
!!

@epigraph
result

The river keeps no record of the boats. — dock proverb

Define a wrapper

A block definition opens with #name and closes with name#. Mark where the use's body goes with ::body:::

source
#notice
@aside(class: notice)
(strong Notice: strong) ::body::
aside@
notice#

(notice Deliveries pause for the harvest week. notice)
result
<aside class="notice"><p><strong>Notice:</strong> Deliveries pause for the harvest week.</p></aside>

A definition without ::body:: takes no body, so its uses need no closer:

source
#sig
— M. Finch, Keeper
sig#

Yours,
@sig
result

Yours, — M. Finch, Keeper

Definitions are hoisted: a use may come before its definition, and one definition may use another.

Parameters

List the parameters in a header after the name, and drop each into the body as ::name:::

source
#chapter(number, title)
(h2 Chapter ::number:: — ::title:: h2)
::body::
chapter#

@chapter(I, The Arrival)
The road climbed for an hour before the house appeared.
chapter@
result

Chapter I — The Arrival

The road climbed for an hour before the house appeared.

<h2>Chapter I — The Arrival</h2>
<p>The road climbed for an hour before the house appeared.</p>

Pass values by position, in header order, or by name — @chapter(number: I, title: The Arrival). A value runs until the next parameter name, so a named value may hold commas; a positional one can't, so name it when it does. With no header, Wit finds the parameters from the ::name:: holes, and you pass them by name.

A ::name:: hole works only inside a definition. To put a value in running prose, define it and use @name.

Long parameter lists

Put one parameter per line; the commas become optional:

source
#card(title, kicker)
@section(class: card)
(h3 ::title:: h3)
(small ::kicker:: small)
::body::
section@
card#

@card(
  title: Dunmore Head
  kicker: Lit 1847, automated 1981
)
The tower stands on the last rock before open water.
card@
result

Dunmore Head

Lit 1847, automated 1981

The tower stands on the last rock before open water.

When the body is long and the closing tag would be far away, end the parameters with ): and close with !! on its own line. With the same #card:

@card(title: Carrick Point, kicker: Lit 1902):
A squat tower, painted red and white.

The keeper's cottage is now a museum.
!!

Values used exactly as written

Values are read as Wit, so emphasis and references work inside them. Mark a parameter literal in the header to use its value exactly as typed — right for URLs and file names:

source
#source(literal url, label)
(a(href: ::url::) ::label:: a)
source#

See @source(url: https://x.org/raw_data_v2, label: the _raw_ data).
result

The underscores in the URL survive; the ones in the label make italics.

Split a document across files

Put shared definitions — a citation format, a schema, recurring values — in their own file, and pull them in with a reference line:

reference ./shared/sources.wit
reference ./shared/schema.wit

Everything defined in those files is now available here. The namespace is flat and definitions hoist, so the order of the lines doesn't matter. The word "reference" at the start of a line is only special when a path follows.

Wrap each chapter in a definition so it emits nothing on its own, then let a thin main file place the parts in order. Two files, shown together as a sketch:

~ chapters/one.wit
#chapter_one
(h2 One h2)
The road climbed for an hour.
chapter_one#

~ main.wit
reference ./chapters/one.wit
reference ./chapters/two.wit

@chapter_one
@chapter_two

Reorder the uses and the chapters reorder; add a third and it slots in.

The draft workflow

The source is plain text, so in git every draft is a readable diff — you see which sentences moved. Build any commit to share it:

wit build manuscript.wit -o draft.pdf

Run wit fmt manuscript.wit -w before committing to re-indent to the real structure; it parses the file first, so it doubles as a sanity check.

See also