Chapter 5.1 · Part II · The craft
Document format: directives
The ::: directives: containers, columns, paper, page breaks, numbering, space, verse, contents and index, line breaks, and the markup of comic pages
In short
A directive is a block that starts with three colons, such as :::callout or :::columns. This page lists every directive and what it does. Some put text in a box, set it in columns or print it on another kind of paper. Others start a new page, change the numbering, add space, set a poem line by line, or print the table of contents and the index. The last section covers the marks for comic pages, panels and the words of the characters.
#Directives
Directives are single-line control tags written as :::name or :::name{attrs} on their own line. They produce no visible output — they drive the placement and numbering pipeline.
| Syntax | Effect |
|---|---|
:::pagebreak | Force the next block to open on a new page. |
:::pagebreak{parity="odd"} | Same, plus ensure the new page is odd (right-hand). Inserts a blank padding page when needed. |
:::pagebreak{parity="even"} | Same, but targeting an even (left-hand) page. |
:::pagebreak{parity="always-odd"} | Guarantee at least one mandatory blank separator page before landing on an odd page. The separator blank belongs to the preceding content; any further parity padding belongs to what follows. Useful when every chapter must start on a fresh spread. |
:::pagebreak{parity="always-even"} | Same, but targeting an even page. |
:::numbering{format="decimal" startAt=1} | At the next page boundary, switch the page-numbering sequence. Both attributes are optional — omit format to keep the format, omit startAt to continue the counter. |
:::columnbreak | End the current column here: the next block opens in the next column of the same page (or on a new page when the directive lands in the last column). A no-op in an empty column, so it never produces a blank column or page. The column it ends keeps its bottom gap — column balancing does not stretch it. |
:::space | Leave one blank body line here — the explicit way to add a little air between two blocks. :::space{lines=2} leaves two (fractions such as 0.5 work too). It adds to the margin between the blocks and is dropped at the top of a column or page. See below. |
:::toc | Print the table of contents here: one entry per heading of the listed levels (title, number, page number, optionally the chapter authors) and one row per part divider, typeset per the toc configuration. The entries follow the document — rename, move or renumber a chapter and the contents follow. |
:::index | Print the back-of-book index here: every term marked with :index in the book, sorted and grouped by letter, with the pages it falls on, typeset per the index configuration. :::index{index="names"} prints a named index. See Back-of-book index. |
:::page{…} … ::: | A comic page: its ::panel lines and their script lines, laid out as panels and lettered balloons on a page of its own. See Comics. |
:::strip{…} … ::: | A comic strip in the text flow, a column or a page wide. See :::strip. |
:::verse … ::: | A poem, set line by line as written (each line a line of verse, blank lines between stanzas, leading spaces an indent), or in the classical Arabic layout when its lines part their hemistichs with ||. See below. |
Attribute values may be double-quoted ("…"), single-quoted ('…'), or bare (startAt=17). A bare key without = is treated as a present-but-empty flag.
Only pagebreak, numbering, columnbreak, space, toc and index are recognized as single-line directives today (and references, verse, page and strip as fenced blocks) — any other :::name line that is not a container (below) is parsed as a paragraph and surfaces an Unknown directive warning in the sandbox. The engine records it too, as an unknownDirective entry in the document's contentWarnings (see Configuration › Warnings in the document).
#Attribute values
The same key="value" syntax is read by heading attributes, directive and container fences (:::name{…}), inline references (:ref{…}), chips (:chip[…]{…}), swatches (:swatch{…}) and index marks (:index[…]{…}). Its rules:
- Keys start with an ASCII letter or
_and go on with ASCII letters, digits,_or-. Spaces around=are fine, the fullwidth=a Chinese input method types works as=, a repeated key keeps its last value, and a key without=is a flag with an empty value. A key in another script (作者=曹雪芹) is not read and raises anattributeKeyInvalidwarning; the other keys of the block still apply. Values may be in any script. - Quoted values. A double-quoted value may hold anything but
", single quotes included; a single-quoted one anything but'. So a value with double quotes goes in single quotes:lead='He said "hi"'. There are no escapes — a backslash is an ordinary character — so a value that needs both ASCII quotes takes typographic ones (“…”,’). A value may also open with the curly“or the corner bracket「a Chinese input method types, and then runs to the matching”or」, spaces included:title=“甲戌本 眉批”,title=「脂批」. - Bare values (
startAt=17,year=1998) run to the next space:title=Hello worldistitle="Hello"plus a flagworld. - No braces.
{and}never go in a value. The first}ends the block: a fence whose value holds one is no longer a directive but a paragraph, and inline the rest of the value spills into the text. In a heading, a brace in a value leaves the whole block in the title:# Title {note="a {b"}is set as written. (Up to postext 1.8 a{after a space started the block over andbwas read as a flag.) - Dollar signs are plain text. Attributes are read before inline maths, so
lead="from $5 to $6"is just text. - One line. An attribute block never spans lines.
# The Long Road {lead='A "road novel", they said' price="$18"}
:::callout{type="note" title='The "fast" path'}
…
:::::resource{id="…"} is stricter: the id in double quotes and no other attribute (see Resources).
#Containers
A container wraps a run of blocks in a fence: an opening line :::name or :::name{attrs}, then any ordinary content — paragraphs, headings, lists, blockquotes, formulas, even other directives — and a closing line holding a bare :::. Containers may nest; each closing ::: closes the innermost open one.
:::callout{type="note"}
Keep the lantern lit **every** night.
- Check the wick.
- Trim it at dusk.
:::
Five container names are recognized in the text flow. What each one renders is set in its own section of the configuration:
| Syntax | Effect |
|---|---|
:::callout{…} … ::: | Boxed content — a note, tip or warning set apart from the body in a bordered or tinted box. |
:::paragraphs{…} … ::: | A run of paragraphs typeset with a named paragraph style (a lead-in, an epigraph, a set of small-print notes) instead of the body style. align, indent and endIndent set the alignment and indents with or without a style: :::paragraphs{align=end endIndent=1} sets a date one character up from the end of the line (地から1字上げ). dropcap switches a drop cap on its first paragraph. |
:::part{…} … ::: | A part or section opener: the enclosed heading and prose form the opener page of a major division. |
:::paper{…} … ::: | A run of pages printed on another paper stock, such as a section of gloss plates in a matte book. Only the Folio viewer shows it. |
:::columns{…} … ::: | Blocks set in several columns of their own: inside a box, in the text column, or across a page of several columns. See :::columns below. |
The attributes accepted by each container, and how it is styled, are documented in Configuration. Attribute values follow the same grammar as directives. A :::callout fence takes type (the id of a configured callout style — unknown or missing types fall back to the first style), title (overrides the style's default title), and span / placement (column, page or side; here, top, bottom or fixed) to override the style's extent and position for that box:
:::callout{type="objectives" title="What you will learn" span="page" placement="top"}
- Name the parts of the lantern.
- Trim the wick without touching the glass.
:::
A floated box (placement auto, top or bottom) also takes columns, how many adjacent columns it spans on a page of several, as in :::callout{placement="top" columns="2"} (since postext 1.18).
A box may also run the text after it beside it: wrap (left, right, start or end), width (its share of the column, 0 to 1; layout.wrap.defaultWidth when unset) and wrapGap (a length, such as 6pt), as in :::callout{wrap="right" width=0.4} (see Text wrap; since postext 1.24).
A callout is laid out as a box — an optional title, then its content typeset with the style's own body and list typography. It keeps together by default, moving whole to the next column or page when it does not fit (a box taller than a whole column splits all the same, rather than overflow); a style with keepTogether: false lets it split between its blocks, or between lines, leaving at least splitMinLines text lines — or a figure, table, display formula or nested box — on each side of the cut (a cut inside a paragraph or list item also leaves at least layout.boxChildSplitMinLines of its lines on each side: two by default, splitMinLines when that is lower; books saved before 1.5 whose chapters hold a box are read with 1, the 1.4 cut). Each part after the first opens without the icon, though its text keeps the icon's column, and without the title unless the style repeats it (repeatTitle: "Key points (cont.)"); a style can also set a "Continued" marker under every part that goes on (continuesMarkerEnabled) — see Marks on a split box. Full-width boxes (span="page") cut the page into column bands; span="side" boxes leave the flow into the float-only side column of a one-and-a-half layout (layout.sideColumnRole: 'floats'), stacked beside the text they interrupt, and lay out as column boxes where there is no such column; placement="fixed" boxes leave the flow and are pinned to page coordinates (a self-assessment badge in the bottom-left corner of a chapter's last page, say), the columns they cover giving up that zone; floating boxes (placement="top" / "bottom") leave the flow where they occur and take the first free band after that position — the foot of the page, or the head or foot of the next — while the text after them fills the page they left. A style with floatBarrier: true (a chapter's closing "key points" box, typically) makes the box a float barrier: every figure or table referenced before it is placed before it — in the page's free slots, or on pages opened ahead of the box — so no float escapes past the end of its chapter. An unknown :::name fence is not a container — the line is treated as text, exactly like an unknown directive.
A :::part fence takes number (as you want it printed — "I", "IV", "3"; it is also parsed so the design can re-format it) and title; both are optional. A third attribute, palette="band=#hex" (several id=#hex pairs, comma-separated), recolours every design colour linked to those palette ids — running heads, opener band, part designs — and the text-flow colours that share their base value (headings, bold, references, bullets, captions, tables, boxes, chips) for the part and the chapters that follow it, until the next part; see Configuration › Parts. The container always opens a page of its own: a page break of the configured parity before it, a single body column at the parts.margins, the opener design over the whole page, and another page break after the closing fence. The body — usually the list of the chapters the part groups, or nothing at all — is typeset with parts.bodyStyle:
:::part{number="I" title="Foundations"}
1. The lantern and its parts
2. Trimming the wick
:::
# The lantern and its parts
With the default heading settings this produces the classic sequence: part page on a right-hand page, blank left-hand page, chapter on the next right-hand page. The page is reported as role: 'part' so headers and footers can skip it, and {partTitle} / {partNumber} resolve to the current part on every following page. See Parts in the configuration reference.
A fence does not need a blank line before it: an opening or closing fence glued directly under a paragraph, list or blockquote ends that block. A container left open at the end of the document is closed automatically there, and the sandbox reports an Unclosed container warning pointing at the opening line. A stray ::: with no container open is left in the text as a visible paragraph rather than dropped silently.
#:::columns
A :::columns{count=2} … ::: group sets the blocks between its fences in count columns of equal width (2 to 6), the text after it taking the full width again. Inside a :::callout the columns share the box's inner width, the style's columnGap apart, in the box's body and list typography, and the box grows to the tallest column. In the running text (since postext 1.25) they share the text column, a body line apart, and the blocks keep the text's own typography; with span="page", on a page of several columns, the group cuts the page into a band as a page-span box does: the columns above it close level, the group is set across the content width (the gutter apart) and the text goes on in every column under it. On a one-column page span="page" sets it in the column. Headings inside a group keep their style, number and entry in the contents, a footnote cited in it goes to the foot of the text column, and figures it cites float as usual.
| Attribute | Effect |
|---|---|
count | How many columns, 2 to 6. Default 2. |
gap | The space between the columns, a length (12pt, 1em, 4mm). Default: the box style's columnGap in a box, a body line in the text column, layout.gutterWidth across the page. |
rule | Draw a rule down each gap, in the colour and width of layout.columnRule: :::columns{count=3 rule}. |
breaks | The blocks that open each column after the first, instead of balancing: breaks="4" opens the second column at the group's fourth block (a comma list for more columns). See below how it counts. |
flow | How a group that does not fit goes on: snake (the default without breaks) or parallel (the default with breaks). See Splitting a group. |
span | In the running text only: column (the default) or page. |
marginTop | The space above the group, a length as gap takes. It merges with the space pending above the group; none at the head of a column, or when the group opens its box. Since postext 1.28. |
marginBottom | The space under the group, a length; 0 asks for none. In the running text it takes the place of the body's paragraph spacing; in a box it is the space before the next block. Since postext 1.28. |
A group set whole is cut where its columns level best — between blocks, or between the lines of a paragraph or list item, whose tail goes on at the head of the next column without its bullet — unless breaks fixes the column starts, with no cut inside a paragraph: a text column beside a figure column.
The space around a group. In the running text a group is followed by the body's paragraph spacing (a line with bodyText.paragraphSpacing, none without it), and inside a box by no space of its own. marginTop and marginBottom on the fence set it: :::columns{count=3 span="page" marginBottom="0.75em"}. Each is a minimum that merges with the space the block beside it keeps for itself, as a box's margins do. In the running text the flow returns to the baseline grid under the group, so the space comes out in whole lines, and a group divided between columns or pages keeps the top margin for its first part and the bottom one for its last. An em is the size of the text the group stands in; a value that is not a length, or a negative one, is ignored.
:::callout{type="summary"}
:::columns{count=2}
- Every element is one kind of atom.
- Electrons live in orbitals.
- A bond shares or transfers electrons.
:::
:::How breaks counts. breaks numbers the group's blocks in order — paragraphs, list items (one block each), display formulas, figures and tables — and a nested :::callout counts as one block however many it holds. Directives are not blocks: a :::space between two stanzas does not shift the count. A number below 2, past the group's last block, or not after the previous break is ignored. Inside a group :::space separates two blocks as anywhere else in a box, and it vanishes at the top of the group and at the head of each of its columns (a breaks position or a levelling cut) — to open the group lower, put the space before the :::columns fence. Two columns that carry the same spacing therefore line up stanza by stanza:
:::callout{type="verse"}
:::columns{count=2 breaks="4"}
The lamp is lit at dusk,
and trimmed before the dawn.
:::space
The keeper sleeps by day.
La lámpara se enciende al anochecer,
y se despabila antes del alba.
:::space
El farero duerme de día.
:::
:::Here the fourth block, "La lámpara…", opens the second column; the two :::space lines are not counted and leave the same gap in both columns.
Splitting a group
Since postext 1.25 a group that does not fit the room it has — the rest of its column in the running text, or the part of a box that splits (keepTogether: false, or a box taller than a column) — is cut between its columns and goes on in the next column or page, in a box of its own for a group in a box:
flow="snake", the default withoutbreaks: the group's blocks run as one galley, like the text of a newspaper story. A part that goes on fills its columns in turn, as level as the cuts allow, cutting between blocks or between the lines of a paragraph or list item (at leastlayout.boxChildSplitMinLineslines of it on each side, two by default); the last part is balanced as a whole group is.flow="parallel", the default withbreaks: each run the breaks start is a stream that keeps its own column. A part fills every stream down to the room it has, and each one goes on in the same column of the next part, so a poem and its translation set side by side stay level stanza by stanza. A parallel group withoutbreaksgoes on as a snake group.
A nested box in a group stays whole, moving to the next part, and a group inside a nested box is never cut. A group that fits is set exactly as before. layout.flowColumns: false keeps the rules of postext 1.24: a fence outside a box is ignored and a group is never cut; books saved before 1.25 that hold a :::columns group are read that way. The Sandbox reports a flow it does not know (Unknown column flow) and columns narrower than six ems of their text (Columns too narrow).
## Briefs
:::columns{count=3 span="page" rule}
**Harbour.** The new pier opens on Monday…
**Market.** Stall rents stay as they are…
**Weather.** Rain from the west by the evening…
:::A :::callout fence also accepts label="…": the text a style with a label tab prints on the box's top corner (:::callout{type="box" label="BOX 1-1" title="The octet rule"}).
A :::callout inside another one is a box of its own — a worksheet card holding answer boxes, say. It takes its own style (background, border, radius, padding, title, icon) at the full inner width of the outer box and stacks among its other blocks; its span and placement are ignored, since a nested box always flows inside its parent. Each fence closes the innermost box still open:
:::callout{type="card"}
The statement of the exercise.
:::callout{type="answer"}
A white answer box with its own border and padding.
:::
:::callout{type="answer"}
A second answer box.
:::
:::When the outer box splits across columns or pages (keepTogether: false, or taller than a column), a nested box moves whole to the next fragment unless its own style lets it split too; every fragment redraws the frames it holds, and a continued nested box drops its icon, and its title unless its style repeats it (repeatTitle).
#:::paper
A book can change paper stock for a run of pages: a section of plates on coated gloss paper in a book printed on uncoated wove, a card insert, a few leaves of tinted paper. Wrap that content in a :::paper container:
:::paper{type=coatedGloss grammage=130}
## Plates
::resource{id="plate-1"}
::resource{id="plate-2"}
:::A stock covers whole sheets, so the content inside the fences starts on a new page, and whatever follows the closing ::: starts on a new page too. A run that ends the document leaves no blank page after it. Figures and tables cited inside the run are placed before it closes. Every page set with content from inside the container carries the stock in the layout (VDTPage.paper, the attributes as the fence writes them); pages outside it carry nothing. The Folio viewer reads it and draws those leaves with the paper's colour, surface, thickness and stiffness. The canvas, PDF and HTML outputs ignore it: the pages are set and printed like any other.
The attributes are those of the folio.paper settings, and all of them are optional. One the fence leaves out follows the document's paper, and past that the stock's defaults:
| Attribute | Value |
|---|---|
type | The stock: uncoated, bookWove, coatedMatte, coatedSilk, coatedGloss, bible, newsprint, cardStock, board. It sets the defaults of the attributes below. |
grammage | Weight in g/m², a number above 0. Heavier paper is thicker, stiffer and more opaque. |
bulk | Thickness per weight in cm³/g, a number above 0 (caliper in µm = grammage × bulk). |
finish | The surface: auto, uncoated, matte, silk, gloss. |
texture | The relief of the surface: auto, smooth, vellum, wove, laid, linen, felt. |
textureStrength | How strongly the texture shows, from 0 to 2. |
shade | The colour of the paper: #rgb, #rrggbb or the id of a colorPalette entry. |
showThrough | true or false: whether the reverse page shows faintly through. A bare showThrough means true. |
A :::paper inside another one overrides only the attributes it sets, and it also starts and ends on a page break. Inside a :::callout the fences are ignored. A value the engine cannot read is dropped, and the sandbox lists it as an Invalid paper attribute warning (paperAttributeInvalid in the document's contentWarnings).
#:::pagebreak
The directive itself does not force parity on its own — only the next block's layout. Use it to end a preface, force a dedication onto its own page, or mark the end of a section. When both a page break and a numbering reset are wanted at the same point, compose :::pagebreak followed by :::numbering — the numbering switch applies at the fresh page the :::pagebreak just created.
A page break on a page that is still empty does nothing, so it never adds a blank page. Nor does it replace the breakBefore of a heading right after it (level 1 has one by default): the heading still applies its parity, which can add a blank page after the one the directive opened. To start a heading exactly there, turn its break off (see Configuration → Heading styles). After a cover heading that fills its page the break is optional: the cover already claims the rest of its page, in single- and multi-column layouts alike, and a :::pagebreak right after it does no harm. It is needed only after a cover whose design stops short of the page foot, when the text should still start on the next page (see Configuration → Reserved height).
The old chapter ends here.
:::pagebreak{parity="odd"}
# A new chapterThe flag center (:::pagebreak{center}, off with center=false) centres the text of the page the break opens between the head and the foot of the type area, across the page in vertical text: the ページの左右中央 of a Japanese part title or dedication. Floats, notes and running heads stay where they are, and a page already full is left alone. The flag does not end the page: close it with another :::pagebreak.
:::pagebreak{center}
# 上 先生と私
:::pagebreakParity attribute
The parity attribute accepts the same five values as headings.levels[*].breakBefore.parity:
'any'— the default: no parity constraint; the break simply opens a new page.'odd'/'even'— the new page opens on the requested side of the spread; a single blank is inserted only when the natural next page is on the wrong side.'always-odd'/'always-even'— guarantee at least one mandatory blank separator page between the previous content and the new page, then enforce parity. The separator blank belongs to the previous chapter; any further parity padding belongs to whatever follows.
Blank-page ownership
The two kinds of blank pages :::pagebreak (and breakBefore) can introduce are distinguished in the VDTPage model:
blankForParity: true— inserted to satisfy a parity constraint. In{chapterTitle}headers this page carries the upcoming chapter's title, because the blank exists only to push that chapter onto the right parity.blankForForce: true— the mandatory leading separator of an'always-*'mode. It belongs to the previous chapter — a deliberate end-of-chapter breath, not parity padding for the next chapter.
The same two rules give a blank page the running heads and palette of a styled section — see Configuration › Heading styles.
Document-start exception
When :::pagebreak is the very first construct in a document (or a heading with breakBefore would pull one in), parity enforcement is skipped while the first page is still empty. The next block lands on page 1 as written, regardless of the requested parity — no spurious leading blank.
#:::numbering
:::numbering is how you restart the page counter mid-document. The canonical book example:
---
title: "A Book With Front Matter"
---
# Preface
…
:::pagebreak{parity="odd"}
:::numbering{format="decimal" startAt=1}
# Chapter 1Preface pages are labelled i, ii, iii, …; the first chapter opens on a right-hand page labelled 1.
Format-only changes (no startAt) keep the counter flowing — useful for, say, switching from lower-alpha to upper-alpha without resetting.
format takes any spelling of a numbering format — roman-lower and i work as well as lower-roman, arabic as well as decimal, 一 and あ as well as japanese-informal and hiragana (see Configuration › Numbering format spellings). A value that is none of them leaves the format as it was, and the sandbox flags it.
lines restarts the count of line numbers, not the page counter: the next line that is counted takes the number given, whatever lineNumbers.restart says. A value that is not a whole number of 0 or more is ignored.
## Act II
:::numbering{lines=1}#:::space
:::space leaves vertical space between two blocks: to separate a closing line from the text above it, to push an epigraph or a signature down a little, or to open a space break between two runs of text. Extra blank lines in the Markdown do not do this — as in any Markdown, a run of blank lines is just one paragraph separator, which keeps a document from changing layout when an editor or formatter adds or trims whitespace.
The last paragraph of the scene.
:::space
A new scene begins one line lower.
:::space{lines=2}
Two lines lower still.lines— how much space, in body lines (the baseline grid). Default1. Whole numbers keep every line of text on the grid, so the columns still line up across the page; a fraction (lines=0.5) is honoured exactly, at the cost of that alignment until the next block that snaps to the grid. A value that is not a number greater than 0 and at most 20 falls back to one line, and the sandbox flags it (Invalid space size).- It adds up. The space is added to the margin that already separates the two blocks — a heading's top margin, a list's bottom margin — instead of collapsing into it. Two
:::spacelines in a row add two lines. - It is dropped at a break, like LaTeX's
\vspace: at the top of a column or page it vanishes, so a page never opens with a hole; and when it does not fit at the foot of a column it simply ends that column, without carrying the rest over. - The paragraph after it is set flush. When
bodyText.indentAfterHeadingis off, a paragraph right after:::spaceloses its first-line indent, as it does after a heading — the usual convention for text resuming after a blank line. - Inside a callout (or a
:::columnsgroup) it separates the box's children the same way, measured in the box's own body lines. Before the box's first block it is dropped, like at the top of a column — the padding already sets the content off the frame — except in two cases where it opens that much room: right under the box's title, and in a box that holds nothing else (an answer box, a space to write in, sized in lines). It always vanishes at the top of a:::columnsgroup, at the head of each of its columns, and at the top of the part of a split box that continues on the next column or page. Inside a:::paragraphscontainer it works as between body paragraphs. - Keep-with-next counts it: a heading followed by
:::spacemoves on when the space and the first lines of its text do not fit under it.
An answer box of a worksheet is a box whose only content is space: the question in its title, four lines of room below it.
:::callout{type="answer" title="1. Name the three parts of the lantern."}
:::space{lines=4}
:::For a fixed break rather than space, use :::columnbreak or :::pagebreak.
#:::verse
A poem. :::verse sets it in one of two layouts: line by line, as most poems are printed, or the classical Arabic layout of a qaṣīda, each bayt in two hemistichs side by side. A poem whose lines carry a hemistich separator (||, or a spaced \\) takes the Arabic layout and any other the line layout; layout=lines or layout=bayt on the fence names one.
Line by line
Write the poem as it is printed: one line of verse a line of Markdown, a blank line between stanzas, and spaces before a line to indent it.
:::verse
Whose woods these are I think I know.
His house is in the village though;
He will not see me stopping here
To watch his woods fill up with snow.
My little horse must think it queer
To stop without a farmhouse near
:::- Lines. Every non-blank line is a line of verse, read as inline Markdown on its own: italics, small capitals, notes and references all work. A run of blank lines is one stanza break.
- Indents. Each leading space is
indentStepwide, 0.5 em by default, so two spaces indent a line one em; a tab counts four spaces and an ideographic space (U+3000) two. - Turnovers. A line a little wider than the measure first tightens its word spaces, down to
bodyText.minWordSpacingof their natural width (the limit justified text shrinks to), and stays on one line;tighten=falseon the fence, orbodyText.verse.tighten: false, turns it over instead. A line still wider turns over at a word space. Withturnover=hang(the default) the rest hangs on the next line,hangin from the line's own start: thehangingIndentof the poem's paragraph style, else 2 em (bodyText.verse.hang). Withturnover=rightit is set flush with the end of the measure behind an opening bracket (turnoverMark,[by default), the custom of English and Spanish editions. Verse is not hyphenated unless its paragraph style setshyphenation: trueitself. A line and its turnover never part at a column or page break. - Stanzas. The space between two stanzas is one line of the poem's leading;
stanzaSpace=0.5makes it half a line, and a length (stanzaSpace=6pt) sets it exactly. On the baseline grid it comes out whole grid lines. Columns and pages break between stanzas first; inside a stanza they break by the orphan and widow rules, which then count the stanza's lines.keepStanzas=Nkeeps any stanza of N lines or fewer whole: a haiku takeskeepStanzas=3, a tankakeepStanzas=5. - Placement. The poem is centred in the measure on its longest line, every line flush with the poem's start (
align=center, the usual setting for a poem quoted in prose);align=startsets it flush with the start of the measure, the default in vertical text. The paragraph that introduces the poem keeps its last line with the first lines of verse. - Stepped lines. A line written
+ …starts where the line above ended, a word space on, as a line of dramatic verse shared between two speakers. Write\+for a line that opens with a plus sign. - Caesuras. With
keepSpaceson the fence, a run of two or more spaces inside a line keeps its width; without it, spaces collapse as in any paragraph. - Type and direction.
stylenames a paragraph style, which gives the face, size, leading,indent, and the space above and below the poem.dirandlangset its direction and language: a Latin poem in an Arabic book (dir=ltr) is indented from its own start side. In vertical text each line of verse is a column, indented from the head.
| Attribute | Default | Description |
|---|---|---|
layout | auto | lines, bayt, or auto: the bayt layout when a line carries a separator. |
indentStep | 0.5em | Width of one leading space. |
turnover | hang | hang or right. |
hang | the style's hangingIndent, else 2em | Indent of a hanging turnover from its line's start. |
turnoverMark | [ | The mark before a turnover set flush right. |
stanzaSpace | 1 | Space between stanzas: a bare number counts lines of the poem's leading, a length is that length. |
keepStanzas | 0 | Keep stanzas of this many lines or fewer whole; 0 is off. |
tighten | true | Tighten the word spaces of a line a little too wide, down to bodyText.minWordSpacing, before turning it over. |
keepSpaces | off | Keep runs of two or more spaces inside a line. |
align | center (start in vertical text) | Centre the poem on its longest line, or set it flush with the start. |
style, dir, lang | — | Paragraph style, direction and language of the poem. |
numbered | true | false leaves the poem out of the line numbers: its lines are not counted. |
lineStart | — | The line number of the poem's first line. The count starts again there, whatever lineNumbers.restart says. |
interval | lineNumbers.interval | The poem's own interval: print the number of every Nth line. |
bodyText.verse sets the defaults for every poem (see Configuration › Verse). The plain text keeps the poem as written, a line feed between lines and a blank line between stanzas, so a copied passage and a search read it line by line; the reflowable EPUB sets a stanza an element whose lines hang their turnovers, and the tagged PDF tags a stanza a paragraph.
Line numbers. With lineNumbers on, the lines of a poem are counted (see Configuration › Line numbers). Each line of verse counts once: a turnover takes no number, and the space between stanzas is not counted. By default every fifth line prints its number in the outer margin and the count starts again at each poem. A poem in the classical Arabic layout counts one line per bayt. The fence adjusts one poem: lineStart=N gives its first line a number, interval=N its own interval, and numbered=false leaves it out.
:::verse{lineStart=37}
…
:::With the default interval of 5, this poem prints 40, 45 and so on beside its lines.
Classical Arabic layout
A poem in the classical Arabic layout (a qaṣīda, a qiṭʿa): each verse, the bayt, on one line in two halves, the ṣadr on the start side (the right in Arabic) and the ʿajuz on the end side, with a gap between them. Write one bayt a line, its hemistichs separated by || (a \\ with a space on each side, as in Wikisource texts, works too). A line without a separator is a single hemistich, centred on the poem.
فأنشد يقول:
:::verse
يَا حُرْقَةَ الدَّهْرِ كُفِّي || إِنْ لَمْ تَكُفِّي فَعِفِّي
فَلَا بِحَظِّيَ أُعْطِي || وَلَا بِصَنْعَةِ كَفِّي
:::- One width. Every hemistich of the poem is set to one width, so each ṣadr starts on the same vertical and each ʿajuz ends on another, and the rhyme letters line up down the poem. The width is that of the widest hemistich, at most half the measure less the gap;
widthsets it (width=55mm). Each hemistich is brought to it with kashidas first (verse elongates more than prose: twicebodyText.kashidaMaxLength), then its word spaces; a hemistich of one word that cannot fill it leaves the rest in the gap. - The gap is 2 em by default;
gapsets it (gap=3em, a bare number is in ems).ornamentprints a mark in its middle (ornament="٭"), which is not part of the text. - Too wide. A hemistich wider than the common width first tightens its word spaces to
bodyText.minWordSpacing. If it still does not fit, its bayt is set staggered: the ṣadr flush with the start side on its own line, the ʿajuz flush with the end side on the next. - Placement. The poem is centred in the column;
align=startsets it flush with the start side. A bayt is never split between columns or pages, and the poem follows the orphan and widow rules of paragraphs (a poem of three bayts or fewer stays whole). The paragraph before the poem, which introduces it («فأنشد يقول:»), keeps its last line with the first bayts. - Type. The poem takes the body text's face, size and leading;
stylenames a paragraph style for it (style="verse"), which is how a vocalised poem gets the extra leading its harakat need.dir=ltrordir=rtlsets its direction like any block; a poem in Latin script in a left-to-right book has its ṣadr on the left.
The plain text of the poem keeps the hemistichs and bayts apart (a tab and a line break), so a search or a copied passage reads it as written; the kashidas and the ornament are left out.
#:::toc
:::toc prints the table of contents where it stands. It expands into ordinary blocks — one per heading of the levels toc.levels lists (level 1 by default) and one per :::part — so the contents flow through columns and pages like any other text and a click on an entry lands on the directive line. An entry shows the heading's number (its numberingTemplate output, else the chapter ordinal), its title, a dotted leader and the label of the page it starts on, and, when toc.subtitle is enabled, a second line with a heading attribute such as the chapter's {author="…"}. A part gets a row of its own, designed by toc.parts.design and coloured with the part's own palette. Headings whose style has numbered: false are listed without a number; {toc="false"} on a heading keeps it out (the contents' own heading, typically).
# Contents {style="front-matter" toc="false"}
:::tocTwo attributes change what one contents prints, whatever the configuration says. levels lists the heading levels it names: a range (levels="1-2"), one level (levels="2") or a list (levels="1,3"); a level toc.levels gives no style takes the style of the nearest level above it. keep keeps each block of the contents on one column and page, as toc.groups.keepTogether does: keep="part" keeps a part row with its chapters, keep="1" (to "6") a heading of that level with the entries under it, and keep="none" turns the configured keep off. A block that does not fit moves whole to the next column or page; one taller than a column is cut, and the column it goes on in opens with its head row again, followed by a continuation mark such as (cont.).
# Contents {style="front-matter" toc="false"}
:::toc{keep="part" levels="1-2"}The page numbers are the ones the document actually prints. A document laid out on its own is laid out again with the labels of the previous pass until they no longer move — with the numbering restarting after the front matter (the :::numbering recipe above) one extra pass settles it. A chapter laid out on its own (the sandbox previews) receives the whole book's outline from its host instead. See Table of contents in the configuration reference.
#:::index
:::index prints the back-of-book index where it stands: the terms marked with :index[…] or :index{term="…"} across the book, with their pages, which follow the text as it moves. It is described with the marks in Back-of-book index. A column never ends after the first entry of a group, nor before its last one: two entries of the group stay and two go on, or the group moves whole (index.groups.splitMinEntries).
# Index {style="index"}
:::index#Line breaks
The lines of a paragraph join with a space. To end a line inside a paragraph without starting a new one (an address, the greeting of a letter, a dedication), end the source line with a backslash, CommonMark's hard break, or write \\ followed by a space:
To the keeper of the lighthouse,\
at the end of the northern pier.
Ana Ruiz \\ Calle Mayor 4 \\ 28013 Madrid- The line before a break is set at its natural width, as the last line of a paragraph is, never stretched to the measure. The text after it opens a new line of the same paragraph, with no first-line indent and no space above; under a hanging indent it hangs like any line after the first.
- Paragraphs, quotations (
> First line\over> second line), footnotes and list items take it. A list item is one line of source, so it breaks at\\. - A backslash that ends the paragraph prints, as in CommonMark, and two breaks in a row make one: for an empty line, start a new paragraph or add a
:::space. - A
\\glued to the next character is no break:\\*prints a backslash and an escaped asterisk,C:\\Tempboth backslashes. In inline code and in a formula the backslashes belong to the code and to the formula. - Two spaces at the end of a line, CommonMark's other hard break, are not one: they cannot be seen in an editor, and many editors leave them behind, so they would break lines nobody meant to break.
- Text copied from the HTML viewer has a line feed at the break, the reflowable EPUB a
<br/>, the text of the PDF a line end, and a Word export a manual line break (Shift+Enter), which the Word import reads back as a break. - A poem keeps its lines, indents and stanzas in a
:::verseblock, with no backslash on every line.
Up to postext 1.22 the backslash printed and the lines joined with a space. A book stored then whose text ends a line with a backslash, or sets \\ before a space, keeps that reading (bodyText.hardLineBreaks: false, see Configuration › Bundles written by postext 1.4 or earlier).
#Line breaks in titles
Write \\ inside a heading (or inside a part's title attribute) to force a line break where the title is displayed as a title: the in-column heading keeps flowing and shows a space there, while an opener design's {titleText} breaks the line at that point (in every overflow mode of the text element). Running heads, {chapterTitle}, {partTitle} and the PDF outline always render the title on one line. In Chinese or Japanese the break reads as an ideographic space between two characters of the script (a couplet title); where one of them meets a digit or Latin text (关于举办 \\ 2026年…) the page sets the Han–Latin space, and the PDF bookmarks and document title join the two halves with nothing, as plain Chinese text is written.
# Concepts of health and illness. \\ Community health {author="I. Zango Martín"}#Comics
Comic pages, strips and spreads are written in two fenced blocks whose bodies the engine reads itself, line by line: :::page and :::strip. Inside them, ::panel lines start the panels and script lines letter them. The guide, with the layout rules, the lettering and the outputs, is Comics; the settings are in Configuration › Comics.
#:::page
:::page{split="30 [30 | 20 | *] / *" gutter=4mm}
::panel{art=lh-arrive}
caption: Every summer, Maya spent a week at the lighthouse.
maya: Grandpa! I'm here!
::panel{art=lh-radio focus="40% 50%"}
tomas: Just in time.
::panel{art=lh-maya}
maya{thought}: That valve looks loose…
::panel{art=lh-beam bleed}
sfx{rotate=-8}: KRAK
:::A :::page block is one comic page: it opens a fresh page, takes all of it, and the text after its closing ::: starts on the next page. Its attributes are split (how the page is cut into cells: sizes in percent separated by / for tiers and | for panels side by side, a bracketed list to cut a cell again, * for the rest, a~b for a slanted line), gutter (one length, or two: between tiers and between panels; a bare number is in millimetres), style (a named panel style), bleed, direction (ltr or rtl, also written dir) and spread (see Spreads). Without split the panels are stacked in equal tiers. Markdown blocks, containers and directives are not read inside the block; <!-- comments --> are.
#Panels
A line ::panel{…} starts a panel, which fills the next cell in reading order and runs to the next ::panel line or the closing fence:
| Attribute | Effect |
|---|---|
art=<id> | The picture: a bitmap or SVG resource. Without it the panel is empty. |
fit=cover, fit=contain | Crop the picture to fill the cell (never into its safe area), or show it whole. |
focus="x% y%" | The point to keep centred where the safe area leaves room. |
style=…, border=none, border=0.5mm, bg=#hex | A named panel style, the border, the background (a colour, a palette id or none). |
bleed, bleed="top start", bleed=false | Run the sides that touch the frame out to the trim and the bleed. |
pad="…" | Make the panel smaller than its cell: one to four lengths or percentages (top, end, bottom, start). |
inset="x y w h" | Lay the panel over the previous one, at that box in percentages of it, instead of giving it a cell. |
pop=<id> | A transparent cut-out drawn over the border with the art's crop (a broken border). |
mirror, mirror=false | Flip the picture, or keep it as drawn on a mirrored page. |
alt="…", id=… | The text alternative (else the resource's altText) and an anchor id. |
#Script lines
Each line of a panel is one balloon, caption or sound effect, written key{attributes}: text:
maya: Grandpa! I'm here!
tomas{whisper}: Shh. Listen.
caption{at=bottom-end}: Three streets away.
sfx{at="62% 40%" rotate=-8 size=1.4}: KRAK
ben{tail=start}: (from off the panel) Over here!
sfx{vertical size=2.6 font="Dela Gothic One"}: ドン
maya: This line goes on
on the next line,\
and breaks here.- The key is a speaker id (letters, digits,
_,.,-), the same in every translation;caption,sfxandnoteare reserved. The colon may be the full-width:. - A bare word in the braces is a balloon style (
thought,whisper,shout,radio,inneror one ofcomics.balloonStyles);style=says the same. atpins the balloon: a point in percentages of the panel's picture (at="62% 40%"), or a corner or edge (top-start,top-end,bottom-start,bottom-end,top,bottom).topoints the tail at a point of the picture;tail=nonedrops it andtail=top|bottom|start|end|left|rightpoints it off the panel.joinandjoin=falsejoin the balloon to the previous one of the same speaker or keep it apart;breaklets it cross the border, and the crossing is not reported as an overflow.rotate(degrees),size(a scale, for sound effects),colorandfontchange its lettering.verticalandhorizontal(ormode=vertical,mode=horizontal) set the line's writing mode over the book's: an untranslatedドンset in a column in a horizontal edition, a sign written across set in a row in a vertical one. A column in a book of another language follows the rules of its own text (with kana, those of Japanese). In a vertical book a line with no Chinese or Japanese characters is set in a row anyway.- A line indented by two spaces or a tab continues the balloon above; a backslash at the end of a line breaks the text there. Blank lines are ignored.
- The text is inline Markdown: emphasis (lettered bold italic),
:tcy,:ruby(its reading set over the base, except over a right-to-left base),:ltrand:rtl(a run kept in its own direction). Footnotes and:refmarks are not read.
#:::strip
:::strip{split="* | * | *" aspect=3 span=page placement=top}
::panel{art=pip-1}
pip: Morning, Otto!
::panel{art=pip-2}
::panel{art=pip-3}
otto: Is it?
:::A :::strip has the body of a page but sits in the text as one unbreakable box, cut into panels: span (column, the default, or page), placement (here, the default, where it is written; or top, bottom, auto, floated like a figure), and its size, either height (a length, a bare number in millimetres) or aspect (width over height: 3, 4/1, 4:1; by default the proportions that make its panels square). A page-wide strip set here on a page of several columns cuts the columns where it stands, as a page-wide box does. width makes it narrower than the measure it spans (60% of it, or a length) and align sets it at the start, center (the default) or end of that measure, along the text direction. caption="…" sets a caption under it in the caption style; with type=figure (a resource type) the caption takes the type's label and number and the strip counts in that type's sequence, and with id=… a :ref names it. Without split the panels sit side by side. Strips are read at the top level of a chapter only.
#Spreads
:::page{spread} lays one page across two facing pages: the split covers both text areas joined at the spine, without their inner margins, and a panel may cross the spine. The spread opens on an even page, after a blank page when needed. See Comics › Spreads.
#Composed pages
A composed page is laid out from a page template of the configuration (pageTemplates), its content poured into the template's frames by name. The guide, with the warnings, is Composed pages.
::::page{template="…"}…::::is the page: four or more colons, closed by a bare fence of as many. Three-colon fences inside it (:::frame,:::callout,:::figure…) work as they do everywhere, and a bare:::never closes the page. A three-colon:::pagestays a comic page.:::frame{slot="…" label="…"}…:::holds the content of the frame of that name: any Markdown.slot="…"on a heading (## Retos {slot="retos-titulo"}), on::resource{id="…" slot="…"}, on a code fence or on a:::container sends that block alone. Content with no slot goes to the template's flow frame.:::figure{resource="…" slot="…"}…:::places one resource with its::label[TEXT]{at="…" style="…"}lines,atbeing an anchor of the picture or a point"x% y%". A figure works in the running text too.