# Configuration: notes and references

> Footnotes, line numbers, cross-references and citations, the table of contents and the back-of-book index

- HTML version: https://postext.dev/en/docs/configuration-notes-references
- Last updated: 2026-10-10
- Reading time: 4 min
- Other languages: [es](https://postext.dev/es/docs/configuration-notes-references.md), [ca](https://postext.dev/ca/docs/configuration-notes-references.md), [pt](https://postext.dev/pt/docs/configuration-notes-references.md), [zh](https://postext.dev/zh/docs/configuration-notes-references.md), [ja](https://postext.dev/ja/docs/configuration-notes-references.md), [ar](https://postext.dev/ar/docs/configuration-notes-references.md)

## In short

This page covers the settings for the parts of a book that point somewhere else. Footnotes sit at the bottom of the page, and line numbers stand in the margin. Cross-references name a figure, a section or a page, and citations name the works you quote. The table of contents lists the chapters, and the index at the back lists terms with their pages. Each section says how these pieces look and how they are numbered.

## Footnotes

The `footnotes` property sets where the notes cited with `[^id]` go, how they are numbered and how they look. The markup is described in [Document format](https://postext.dev/en/docs/document-format.md#footnotes).

```ts
interface FootnotesConfig {
  placement?: 'column' | 'chapterEnd' | 'spread'; // Foot of the citing column, after the chapter, or beside the text of a spread.
  numbering?: 'chapter' | 'document' | 'page' | 'column' | 'spread'; // Start again at each chapter, run on, or start again on each page / column / spread.
  numberFormat?: string;      // decimal, lower-roman, circled-decimal (①)…
  symbols?: string[];         // The note symbols of numberFormat: 'symbols'.
  markerPosition?: 'auto' | 'superscript' | 'inline' | 'side' | 'right'; // Raised, on the baseline, beside the word, or right of a vertical line.
  markerSize?: Dimension;     // Inline, side or right marker size; em is the text around it.
  numberGap?: 'en' | 'em';    // Space after the note's own number.
  chapterEndAlign?: 'foot' | 'text';   // chapterEnd: notes at the column foot, or under the text.
  fontSize?: Dimension;       // Note size; em is the body size.
  lineHeight?: Dimension;     // Note leading; em is the note size.
  color?: ColorValue;         // Note colour; the body colour when unset.
  textAlign?: TextAlign;      // The body alignment when unset.
  hangingIndent?: Dimension;  // Indent of a note's turnover lines.
  spaceBetween?: Dimension;   // Space between two notes.
  spaceAbove?: Dimension;     // Space between the text and the rule; em is the body size.
  spaceBelowRule?: Dimension; // Space between the rule and the first note.
  separator?: {
    enabled?: boolean;        // Draw the rule.
    width?: number;           // Rule length, a fraction of the column width.
    lineWidth?: Dimension;    // Rule thickness.
    color?: ColorValue;       // The note colour when unset.
  };
}
```

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `placement` | `'column' \| 'chapterEnd' \| 'spread'` | `'column'` (Japanese vertical books: `'chapterEnd'`) | `'column'` sets each note at the foot of the column that holds the line citing it, under a short rule; in a one-column layout that is the foot of the page. `'chapterEnd'` sets every note of a chapter after its last block, in citation order. `'spread'` (傍注, vertical text only) sets the notes cited on both pages of a spread at the end of its odd page, the left page of a right-bound book, under the rule: notes cited on the even page wait for it, a note that would leave the odd page less than one line of text stays at the foot of the even page with the ones after it, and a chapter that ends on an even page keeps its waiting notes there. In horizontal text it falls back to `'column'` with an `unknownConfigValue` warning. Since postext 1.16. |
| `numbering` | `'chapter' \| 'document' \| 'page' \| 'column' \| 'spread'` | `'chapter'` (Japanese horizontal books: `'page'`; with `placement: 'spread'`: `'spread'`; with `numberFormat: 'symbols'` at the column foot: `'page'`) | `'chapter'` starts again at 1 under each level-1 heading and at the start of each document. `'document'` runs on through the document and, in a book laid out chapter by chapter, from one chapter to the next (`continuationAfter` carries the last number as `continuation.footnoteNumber`). `'page'` starts again at 1 on every page and `'column'` in every column, counting the notes where the layout sets them (the columns of a page in reading order): the usual 页下注 of a Chinese book. The document is laid out, numbered where its notes landed and laid out again until the numbers hold (at most three more builds). Both apply to notes at the column foot: with `placement: 'chapterEnd'` the notes are numbered by chapter. `'spread'` starts again on every spread (pages 2–3, 4–5…), in citation order, for `placement: 'spread'`. |
| `numberFormat` | `string` | `'decimal'` | How the numbers are written, in any spelling the numbering settings take: `'decimal'`, `'lower-roman'`, `'lower-alpha'`, `'circled-decimal'` (or `'①'`), `'cjk-decimal'`, `'一'`… The marker and the number that opens the note both use it. `circled-decimal` writes numbers past 50 in decimal. An unknown name numbers in decimal, with an `unknownNumberFormat` warning. `'symbols'` (or `'*'`) marks the notes with reference symbols, `symbols` in turn: * † ‡ § ‖ ¶, then doubled (** †† ‡‡…) and tripled; the notes are then counted again on every page unless `numbering` is set. Since postext 1.19. |
| `symbols` | `string[]` | `['*', '†', '‡', '§', '‖', '¶']` | The sequence `numberFormat: 'symbols'` writes, doubled and then tripled once it runs out. The Latin files of Google Fonts and Fontsource carry * † § ¶ (the dagger in `latin-ext`) but neither ‡ nor ‖, which the PDF then draws as the face's `.notdef` glyph with a `missingGlyph` warning: with such a face, leave them out (`['*', '†', '§', '¶']`) or set the notes in a face that has them. Empty strings are dropped and an empty list keeps the default. Since postext 1.19. |
| `markerPosition` | `'auto' \| 'superscript' \| 'inline' \| 'side' \| 'right'` | `'auto'` | `'superscript'` raises the marker in the text and the number that opens the note, at a reduced size. `'inline'` sets them on the baseline: the marker at `markerSize`, the note's number at the note size; in vertical text an inline circled marker stands upright in a cell of its own. `'right'` sets a reduced marker flush with the right side of a vertical line, as Japanese vertical books set （1）; in horizontal text it is a superscript. `'side'` (合印) sets a small marker beside the marked word, on the side of its ruby, ending where the word's last character ends; it takes no room in the line, which breaks and justifies as if it were not there, and a line gap too narrow for it is reported as `rubyExceedsLeading`. `'auto'` is inline for `circled-decimal`, `'right'` in a Japanese vertical book, and superscript otherwise. Either way the marker stays with the character before it and never opens a line. |
| `markerSize` | `Dimension` | `1em`; `0.6em` for `'side'`, `0.7em` for `'right'` | Size of an inline, side or right marker; `em` is the size of the text around it (`0.75em` is a common reduction). No effect on a superscript marker. |
| `numberGap` | `'en' \| 'em'` | `'en'` (Japanese notes after the chapter: `'em'`) | The space after the number that opens a note: an en space, or a full note em (an ideographic space when the number or the note holds CJK text), never stretched or broken. Since postext 1.16. |
| `markerTemplate` | `string` | `'{n}'` (Japanese vertical books: `'（{n}）'`) | How a note's number is written, `{n}` standing for it in the number format and the document's digits: `'({n})'` gives the parenthesised markers of Arabic books, «(١)». It writes the marker in the text and the number that opens the note alike. A template without `{n}` is read as the default. |
| `noteNumberPosition` | `'auto' \| 'superscript' \| 'inline'` | `'auto'` | Where the number that opens the note stands, raised or on the line at the note size. `'auto'` follows `markerPosition`. Arabic books raise the marker in the text and set the note's own number on the line. |
| `chapterEndAlign` | `'foot' \| 'text'` | `'foot'` | With `placement: 'chapterEnd'`: `'foot'` sets the notes that close a column at its foot, the lines left over staying between the text and the notes, as notes at the column foot stand. `'text'` sets them right under the text. |
| `fontSize` | `Dimension` | `0.8em` | Size of the note text. `em` and `rem` are the body size. The notes use the body family and weights. |
| `lineHeight` | `Dimension` | `1.25em` | Leading of the note text; `em` is the note size. The notes are off the baseline grid: they stack up from the foot of the column, and the text above them stays on the grid. |
| `color` | `ColorValue` | body colour | Colour of the note text. |
| `textAlign` | `TextAlign` | body alignment | Alignment of the note text. |
| `hangingIndent` | `Dimension` | `0` | Indent of a note's second and later lines, so they align past its number. |
| `spaceBetween` | `Dimension` | `0` | Space between two notes. |
| `spaceAbove` | `Dimension` | `0.5em` | Space between the last line of text and the rule; `em` is the body size. With `'chapterEnd'` and `chapterEndAlign: 'text'`, `spaceAbove` + `spaceBelowRule` is the space between the text and the first note. |
| `spaceBelowRule` | `Dimension` | `0.4em` | Space between the rule and the first note. |
| `separator.enabled` | `boolean` | `true` | Draw the rule above the notes of each column. With `false` the spaces above stay. |
| `separator.width` | `number` | `0.3` | Length of the rule as a fraction of the column width (0–1), from the column's left edge. |
| `separator.lineWidth` | `Dimension` | `0.5pt` | Thickness of the rule. |
| `separator.color` | `ColorValue` | note colour | Colour of the rule. |

```ts
footnotes: {
  fontSize: { value: 7.5, unit: 'pt' },
  lineHeight: { value: 9.5, unit: 'pt' },
  hangingIndent: { value: 0.8, unit: 'em' },
  separator: { width: 0.25, lineWidth: { value: 0.4, unit: 'pt' } },
}
```

**Japanese books.** A Japanese document (`locale: 'ja'`, since postext 1.16) gives the fields it leaves unset the values of JLReq §4.2. A vertical book sets its notes after the chapter (`placement: 'chapterEnd'`, 後注), numbered by chapter, with markers `（{n}）` right of the line (`markerPosition: 'right'`, digits upright by `cjk.uprightDigits`); a horizontal one sets them at the foot of the page, numbered per page, with superscript markers. Both draw the rule a third of the measure long (`separator.width: 1/3`), and notes after the chapter take `numberGap: 'em'` and a two-em hanging indent. An explicit value wins and is kept on save (`stripFootnotesDefaults` compares with the document's own defaults); Chinese, Arabic and Latin documents resolve as before. `footnoteDocumentDefaults(locale, writingMode, placement?)` returns these values. Write a marker before a sentence-final 。 (`先生[^1]。`): it stays with the character before it, and 。 never opens a line. See [Japanese layout › Notes](https://postext.dev/en/docs/japanese-layout.md#notes).

How the notes are laid out at the column foot:

- **Note and citation share a column.** Before it places a line, the layout adds the height of the notes that line cites for the first time (and the rule, for the first note of the column). A line whose notes do not fit under it goes to the next column with the rest of its paragraph, under the orphan and widow rules. The column's text area shrinks by the notes' height, so the column balancing and the closing band of a chapter count only the text.
- **Several notes** in one column stack in citation order under one rule. A note cited again later keeps its number and is not set again.
- **Bottom floats.** A figure that takes the foot of a column after its notes were set goes above them; notes set after the figure go above it.
- **Boxes.** A note cited inside a callout (inline, floated or fixed) goes to the foot of the column where the text after the box goes on, usually the same column. A box that closes the document leaves its notes at the foot of the column the text ended in.
- **Limits.** A note is never split: one taller than a column overflows it. Markers in captions, table cells and headings are not read (they print as written).
- **Output.** Canvas, HTML and PDF paint the notes, the markers (a superscript number) and the rule. In the PDF each marker links to its note, and a tagged PDF sets each note as a `Note` element with a unique `/ID` listed in the structure tree's `/IDTree` (PDF/UA-1). The notes are `VDTBlock`s with `footnoteNote` set, in `page.floats`; the rules are in `page.footnoteAreas`.
- **Warnings.** `undefinedFootnote` (a marker with no definition: the number prints over an empty note) and `unusedFootnote` (a definition no marker cites: it is not set).

Resolver and stripper match the other sections:

```ts
import { DEFAULT_FOOTNOTES_CONFIG, resolveFootnotesConfig, stripFootnotesDefaults, footnoteDocumentDefaults } from 'postext';

resolveFootnotesConfig(config.footnotes, 'ja', 'vertical-rl'); // unset fields take the Japanese vertical defaults
```

## Line numbers

The `lineNumbers` property prints the number of every fifth line (or every Nth) in the margin beside it, as critical editions, anthologies of poetry, legal texts and school editions do. It counts the lines of `:::verse` poems, or every line of the text. It is off by default. Each number is painted on the baseline of its line, in a size of its own, and never moves a line: the page is laid out exactly as it would be without numbers. Since postext 1.23.

```ts
interface LineNumbersConfig {
  enabled?: boolean;        // Off by default.
  count?: 'verse' | 'all';  // The lines of poems, or every line of the text.
  interval?: number;        // Print the multiples of N.
  numberFirst?: boolean;    // Also print the first line after each restart.
  restart?: 'document' | 'chapter' | 'section' | 'page' | 'poem'; // Where the count starts again.
  startAt?: number;         // The number of the first line after a restart.
  position?: 'outer' | 'inner' | 'left' | 'right' | 'start' | 'end' | 'side';
  multiColumn?: 'each' | 'gutter' | 'outer-edges'; // Pages of two or more columns.
  gap?: Dimension;          // From the text to the number; em is the number's size.
  align?: 'auto' | 'left' | 'right';
  fontFamily?: string;      // The body family when unset.
  fontSize?: Dimension;     // em is the body size.
  fontWeight?: number;      // The body weight when unset.
  italic?: boolean;
  color?: ColorValue;       // The body colour when unset.
  format?: string;          // decimal, lower-roman, arabic-indic, 一…
}
```

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `enabled` | `boolean` | `false` | Print line numbers. A vertical document (`layout.writingMode: 'vertical-rl'`) gets none, and `true` there is reported as `lineNumbersUnsupported`. |
| `count` | `'verse' \| 'all'` | `'verse'` | `'verse'` counts the lines of `:::verse` poems, each line of verse once: a turnover (the rest of a line too long for the measure, set on the next line) takes no number, and the space between stanzas is not counted. A poem in the classical Arabic layout counts one line per bayt; the second line of a staggered bayt is not counted. `'all'` counts every line of body paragraphs, list items, blockquotes and verse, in reading order: page by page, column by column, top to bottom. |
| `interval` | `number` | `5` | Print the number of every line that is a multiple of this one (5, 10, 15…). A poem whose first line is 37 prints 40, 45… A poem's fence may set its own (`interval=N`). |
| `numberFirst` | `boolean` | `false` | Also print the number of the first counted line after each restart. |
| `restart` | `'document' \| 'chapter' \| 'section' \| 'page' \| 'poem'` | `'poem'` with `count: 'verse'`, `'page'` with `count: 'all'` | Where the count starts again: never (`'document'`, which runs on through the chapters of a book), at every level-1 heading (`'chapter'`), at every level-1 or level-2 heading (`'section'`), on every page (`'page'`) or at every `:::verse` poem (`'poem'`). A poem's `lineStart=N` and the `:::numbering` directive's `lines=N` restart it anywhere, in any mode. |
| `startAt` | `number` | `1` | The number of the first line after a restart. |
| `position` | `'outer' \| 'inner' \| 'left' \| 'right' \| 'start' \| 'end' \| 'side'` | `'outer'` | The side the numbers stand on. `'outer'` is away from the spine: the right of an odd page and the left of an even one, the other way round in a book bound on the right. `'inner'` is the spine side. `'left'` and `'right'` are the same on every page. `'start'` and `'end'` follow the document's direction: `'start'` is the right in a right-to-left book. `'side'` sets them in the side column of a `'oneAndHalf'` layout with `layout.sideColumnRole: 'floats'`, flush with the side column's edge next to the text (`gap` is not used); on a page with no side column it falls back to `'outer'`. |
| `multiColumn` | `'each' \| 'gutter' \| 'outer-edges'` | `'outer-edges'` | Pages with two or more text columns side by side. `'outer-edges'` puts the first column's numbers on its left and the last column's on its right; the columns between them follow `'each'`. `'gutter'` puts them in the gutters: the first column's on its right, the others' on their left. `'each'` puts every column's numbers on the `position` side. |
| `gap` | `Dimension` | `1em` | The distance from the edge of the column to the number; `em` is the number's own size. |
| `align` | `'auto' \| 'left' \| 'right'` | `'auto'` | `'auto'` sets each number flush toward the text: right-aligned in a left margin, left-aligned in a right one. `'left'` and `'right'` align the numbers within the width of the widest number on the page. |
| `fontFamily` | `string` | body family | Typeface of the numbers. It is loaded and embedded like any other family. |
| `fontSize` | `Dimension` | `0.8em` | Size of the numbers; `em` is the body size. |
| `fontWeight` | `number` | body weight | Weight of the numbers. |
| `italic` | `boolean` | `false` | Set the numbers in italics. |
| `color` | `ColorValue` | body colour | Colour of the numbers. A colour linked to the palette follows the palettes of parts and sections. |
| `format` | `string` | decimal | How the numbers are written, in any of the [numbering format spellings](https://postext.dev/en/docs/configuration-page-layout.md#numbering-format-spellings) (`'lower-roman'`, `'arabic-indic'`, `'一'`…). Decimal numbers are written in the document's digits (`numerals`). An unknown name numbers in decimal, with an `unknownNumberFormat` warning. |

```ts
lineNumbers: {
  enabled: true,
  count: 'verse',
  interval: 5,
  restart: 'document',          // one count through the whole book
  position: 'outer',
  fontSize: { value: 0.75, unit: 'em' },
  italic: true,
}
```

What is counted, and what is not:

- **Never counted**: headings, captions, tables and pictures, display formulas, design text (openers, running heads), footnotes and chapter-end notes, the contents, the entries of the index and of the bibliography, and blank pages.
- **Boxes and prose.** The text of a callout is not counted, and under `count: 'verse'` neither is prose, unless the paragraph style it is set in says `lineNumbers: true`; a style with `lineNumbers: false` is never counted (see [Paragraph styles](https://postext.dev/en/docs/configuration-styles.md#paragraph-styles)).
- **One poem.** A poem's fence takes `numbered=false` (its lines are not counted), `lineStart=N` (its first line is N, and the count starts again there) and `interval=N`. `:::numbering{lines=N}` numbers the next counted line N, wherever it stands. See [Document format › `:::verse`](https://postext.dev/en/docs/document-format.md#verse) and [`:::numbering`](https://postext.dev/en/docs/document-format.md#numbering).

In a book laid out chapter by chapter, `restart: 'document'` carries the count from one chapter to the next through `continuation.lineNumber`. `continuationAfter` counts the lines of verse from the text; with `count: 'all'` the count depends on the layout, so the host passes on the `lastLineNumber` of the previous chapter's document, as the Sandbox does.

With `position: 'side'` the numbers share the side column with side boxes, side captions and side figures. A number that overlaps one of them is painted anyway, neither of them moves, and the build reports a `lineNumberOverlap` content warning that points at the numbered line.

**Output.** The canvas, the PDF, the HTML viewer and the fixed-layout EPUB paint the numbers. In a tagged PDF they are layout artifacts and each one carries an empty `/ActualText`, so copied or extracted text runs from line to line without them. The HTML output hides them from assistive technology (`aria-hidden`), from selection and from copied text. The reflowable EPUB, whose lines are set by the reading system, keeps the numbers of verse only: a `pt-line-number` span (also `aria-hidden`) in the start margin of the stanza, beside each line that carries a number in print. In the VDT the numbers are a design slot of each page (`page.lineNumbers`, its text blocks flagged `artifact`) and a list of marks (`page.lineNumberMarks`: `number`, `label`, `columnIndex`, `blockId`, `lineIndex`); the document records `lastLineNumber`.

**Not supported**: line numbers in vertical text, a cross-reference that prints the number of a line, notes keyed to line numbers, and numbers for the lines of table cells, captions or code listings.

In the Sandbox these settings are the **Line numbers** section of the Design panel. Resolver and stripper match the other sections; the font, the weight and the colour come from the body text:

```ts
import { DEFAULT_LINE_NUMBERS_CONFIG, resolveLineNumbersConfig, stripLineNumbersDefaults } from 'postext';

resolveLineNumbersConfig(config.lineNumbers, resolvedBodyText); // unset font, weight and colour follow the body
```

## Cross-references

The `crossRefs` property sets the words a [cross-reference](https://postext.dev/en/docs/document-format.md#cross-references-and-anchors) prints around a number or a page, and the style a `:ref` takes when it sets none. Each template holds `{n}` where the number goes; one without it gets the number after a no-break space (`"§"` prints *§ 3.2*). An unset template follows the document language: *chapter / section / p.* in English, *capítulo / sección / pág.* in Spanish, `第{n}章` / `第{n}节` / `第{n}页` in Chinese, and so on for French, German, Italian, Portuguese, Catalan and Dutch.

```ts
interface CrossRefsConfig {
  chapter?: string;  // Words around a level-1 heading's number: "chapter {n}".
  section?: string;  // Around any other heading's number: "section {n}".
  page?: string;     // Around a page number: "p. {n}".
  defaultStyle?: 'default' | 'number' | 'title' | 'page'; // A :ref without style=.
}
```

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `chapter` | `string` | by language | A reference to a level-1 heading: `"chapter {n}"`. A heading number whose template already spells the word (`Chapter {1}`, `第{1:一}章`) prints as it is. |
| `section` | `string` | by language | A reference to a heading of level 2 to 6: `"section {n}"`, `"§ {n}"`. |
| `page` | `string` | by language | A page reference (`style=page`): `"p. {n}"`, `"page {n}"`. |
| `defaultStyle` | `'default' \| 'number' \| 'title' \| 'page'` | `'default'` | What a `:ref` to a heading or an anchor prints without `style=`. `'default'`: a numbered heading by its word and number, an unnumbered one by its title, an anchor by its text. A reference that sets `style` keeps it, and references to figures and tables are not affected. |

References take the colour, weight and slant of every reference (`bodyText.referenceColor`, `referenceBold`, `referenceItalic`).

## Citations

The `citations` property chooses the citation style and how citations and the bibliography look. The markup is described in [Citations and bibliography](https://postext.dev/en/docs/document-format.md#citations-and-bibliography); the style is applied by the `postext-citeproc` package.

```ts
interface CitationsConfig {
  style?: string;          // 'apa', 'ieee', 'chicago-notes-bibliography'… or 'custom'
  customStyle?: string;    // a whole CSL style (.csl XML), used with style: 'custom'
  locale?: string;         // CSL locale; the document language when unset
  link?: boolean;          // citations link to their entries
  marker?: 'style' | 'brackets' | 'parentheses' | 'superscript' | 'corner';
  collapseRanges?: boolean;
  notes?: 'footnote' | 'warichu';
  numbering?: 'book' | 'chapter';
  bibliography?: {
    title?: string;        // unset: the document language's word; '' or ' ': none
    scope?: 'book' | 'chapter';
    auto?: boolean;
    fontSize?: Dimension;
    lineHeight?: Dimension;
    hangingIndent?: Dimension;
    entrySpacing?: Dimension;
    labelWidth?: Dimension;
    labelAlign?: 'left' | 'right';
    doi?: 'link' | 'text' | 'hide';
    includeUncited?: boolean;
    groupByLanguage?: boolean;
  };
}
```

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `style` | `string` | `'apa'` | A bundled style id (see [Styles](https://postext.dev/en/docs/document-format.md#styles)) or `'custom'`. The style decides what citations and entries say: names, dates, order, punctuation, and whether citations are notes. |
| `customStyle` | `string` | — | A whole CSL style, the XML of a `.csl` file, used when `style` is `'custom'`. The Sandbox loads it from a file. |
| `locale` | `string` | document language | The CSL locale the style writes its words in (`en-US`, `es-ES`, `zh-CN`, `zh-TW`, `ja-JP`…). A Japanese document reads as `ja-JP`: narrative citations join two authors with と and shorten more with ほか. |
| `link` | `boolean` | `true` | A citation links to its entry in the bibliography (PDF link, HTML anchor, Sandbox click). |
| `marker` | `'style' \| 'brackets' \| 'parentheses' \| 'superscript' \| 'corner'` | `'style'` | How a numbered style marks a citation: as the style writes it, `[1]`, `(1)`, a superscript, or `〔1〕` (upright in vertical text). A locator follows the number. |
| `collapseRanges` | `boolean` | `true` | Consecutive numbers as a range: `1–3` in a marker of its own, `[2]–[4]` in IEEE's. `false` keeps them apart. |
| `notes` | `'footnote' \| 'warichu'` | `'footnote'` | Where a note style sets its citations: footnotes (placed and numbered as `footnotes` says), or two-row notes inside the line (夹注). |
| `numbering` | `'book' \| 'chapter'` | `'book'` | Citations through the book, or each chapter on its own (each document, and each level-1 heading after a citation): a numbered style numbers each chapter from 1 and a work cited in two chapters takes each chapter's number; a note style writes a work in full at its first citation in each chapter. Meant with `bibliography.scope: 'chapter'`, whose lists then take the chapter's numbers. |
| `bibliography.title` | `string` | by language | Title above the list, a bold paragraph. Blank: none. A heading of your own goes above `:::bibliography`. |
| `bibliography.scope` | `'book' \| 'chapter'` | `'book'` | One list of every work the book cites, or one per chapter with the works it cites. In a document of several chapters each H1 starts a new chapter list; with `auto` a chapter that places no `:::bibliography` gets its list at its end. |
| `bibliography.auto` | `boolean` | `true` | Set the list after the text (the last chapter, for a book-wide list) when no `:::bibliography` places it. |
| `bibliography.fontSize` | `Dimension` | `0.9em` | Size of the entries; em is the body size. |
| `bibliography.lineHeight` | `Dimension` | body leading | Leading of the entries. |
| `bibliography.hangingIndent` | `Dimension` | `2em` | Indent of the turnover lines of an unnumbered entry. |
| `bibliography.entrySpacing` | `Dimension` | `0.3em` | Space between two entries. |
| `bibliography.labelWidth` | `Dimension` | longest label | Width of the column the numbers of a numbered list stand in: every entry’s text starts this far in, on its first line as on its turnover lines, so `9.` and `10.` share the column. The label stays part of the entry’s text. |
| `bibliography.labelAlign` | `'left' \| 'right'` | `'left'` | Where a label sits in its column: against its left edge, or against the text (`9.` and `10.` end together). |
| `bibliography.doi` | `'link' \| 'text' \| 'hide'` | `'link'` | DOIs and URLs as links, as plain text, or left out. |
| `bibliography.includeUncited` | `boolean` | `false` | List every reference, cited or not (like `nocite: "@*"`). |
| `bibliography.groupByLanguage` | `boolean` | `false` | Works in Chinese, Japanese and Korean first, then the others. Author-date and author-page styles only: a numbered list keeps the order of its numbers. |

## Table of contents

The `toc` property configures what a `:::toc` directive prints (see [Document format](https://postext.dev/en/docs/document-format.md#toc)). The contents are assembled from the document's **outline** — every heading with its number and page label, every `:::part` — so they follow the chapters: rename one, move it to another part, change its authors, and the entries change with it. An entry is the heading's number in a column of its own, the title, a leader and the page label at the right edge, then an optional subtitle line; a part is a row designed by `parts.design`.

```ts
const config: PostextConfig = {
  toc: {
    levels: [{ level: 1, fontWeight: 700, color: { hex: '#00507b', model: 'hex' }, numberWidth: { value: 7.4, unit: 'mm' } }],
    unnumbered: { color: { hex: '#000000', model: 'hex' } },
    pageNumber: { fontWeight: 400, width: { value: 8, unit: 'mm' } },
    leader: { char: '.', gap: { value: 1, unit: 'mm' } },
    subtitle: { enabled: true, attr: 'author', italic: true, fontSize: { value: 8.5, unit: 'pt' } },
    parts: {
      height: { value: 23, unit: 'pt' },
      marginTop: { value: 11.5, unit: 'pt' },
      design: { elements: [/* a band box, 'SECTION {number}', '{titleText}', '{pageNumber}' */] },
    },
  },
};
```

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `levels` | `TocLevelConfig[]` | level 1 | Heading levels listed, each with its entry typography: `fontFamily`, `fontSize`, `lineHeight` (defaults to the body leading, so the contents sit on the grid), `fontWeight`, `italic`, `color`, `indent` (of the whole entry), `numberWidth` / `numberGap` (the number column the title starts after; numbers are right-aligned in it, and a number wider than `numberWidth`, such as `الفصل الحادي عشر` or `Chapter 12`, widens the column of its level to the widest one), `numberFontFamily`, `numberFontSize`, `numberFontWeight`, `numberColor`, `marginTop`, `marginBottom`. Unset fields inherit the body text. The number sits on the baseline of the title's first line, whatever its face and size, on canvas, in HTML and in the PDF (up to postext 1.4 it was centred on the x-height like a list bullet, so a display face or a larger size rode above the title). A renderer of your own finds that baseline in the entry block's `bulletBaselineY`; `bulletY` is still the number's em-box midpoint, as in 1.4, so a renderer that predates the new field draws the numbers where it always did. |
| `unnumbered` | `TocEntryStyleConfig` | — | Overrides for headings whose style has `numbered: false` (a preface): they print no number and start flush at the level's `indent`. |
| `pageNumber` | object | level-1 face, body weight | `fontFamily`, `fontSize`, `fontWeight`, `italic`, `color` of the page label, and `width` (default `2em`): the column reserved for it at the right edge, where it is right-aligned. |
| `leader` | object | `{ enabled: true, char: '.', gap: 0.5em }` | `char` is repeated across the gap between the title and the page number, right-aligned so the dots of consecutive entries line up (`'. '` spaces them out); `gap` is the least room kept between the title and the leader. The leader takes as many characters as fit, measured as a whole run in its face, so a face that kerns consecutive full stops apart gets fewer dots rather than dots that reach the page number. (Up to postext 1.4 the count was taken from one dot, and in such a face the leader ran from the title into the number.) A title that would leave the label no room wraps a little earlier. A leader is set with three characters or more: where only one or two fit, the row has none, since a lone dot before the page number reads as a full stop. In a tagged PDF the dots are artifacts, left out of the extracted text. Body text sets the same leaders at its [tab stops](https://postext.dev/en/docs/configuration-text.md#tab-stops). |
| `subtitle` | object | `{ enabled: false, attr: 'author' }` | A second line under the entry taken from a heading attribute (`attr`) — the chapter authors — with its own `fontFamily`, `fontSize`, `fontWeight`, `italic` (default `true`), `color` and extra `indent`. The line shares the entry's leading and never separates from its title. |
| `parts.enabled` | `boolean` | `true` | Whether part dividers get a row. |
| `parts.breakBefore` | `boolean` | `false` | Open a fresh page before every part row but the first, so each part's chapters are listed on a page of their own. |
| `parts.design` | `DesignSlot` | empty | Row design; its container is the row (column width × `height`). Placeholders: `{number}`, `{numberDecimal}`, `{numberRoman}`…, `{titleText}` and `{pageNumber}` (the part page's label; with `parts.page: false`, which opens no part page, the label of the page the part's content starts on, where its running heads switch to it; in a book laid out chapter by chapter, a fence that closes its chapter points at the first content page of the next chapter). Palette-linked colours take the part's own `palette`, so each section's row comes in its colour. When empty, `{number} {titleText}` (the H1's `numberSeparator` between them) and the page number are set in the level-1 entry typography. |
| `parts.height`, `marginTop`, `marginBottom` | `Dimension` | `2em`, `0`, `0` | Row height and the space around it. `em` is the body text size, so the default row is twice the body size tall, not two body lines: with a 9.5/13.5 pt body it is 19 pt. For a row of two body lines, give the height in `pt` (`27pt` there). |

The page labels are the ones the document prints. `buildDocument()` lays a document with a `:::toc` out again with the labels of the previous pass until they settle (at most three extra passes); a host laying a book out chapter by chapter supplies the whole book's outline as `PostextContent.outline` instead, assembled from `contentOutline()` (headings and parts from the text alone) and `outlineFromDoc()` (the same entries with the page labels of a layout), and lays the contents chapter out again whenever `outlineKey()` of that outline changes. Each heading entry carries the `number` the contents print and, for a numbered heading, its `counter`: the level's running count after any `startAt`, whatever the template prints — what a host shows beside a chapter in its own lists.

## Back-of-book index

The `index` property configures what a `:::index` directive prints (see [Document format](https://postext.dev/en/docs/document-format.md#back-of-book-index)): the terms marked with `:index[…]` and `:index{term="…"}` in the text, sorted, grouped by first letter (by pinyin initial or stroke count in Chinese, by gojūon row in Japanese, see `groupBy`), each with the pages it falls on. An entry is its term, a separator and its page numbers; its sub-entries follow, one indent step per level, and wrapped lines hang by `turnoverIndent` so they never line up with a sub-entry.

```ts
const config: PostextConfig = {
  headingStyles: [
    // The index in two columns, under its own heading.
    { id: 'index', numbered: false, layout: { layoutType: 'double', gutterWidth: { value: 6, unit: 'mm' } } },
  ],
  index: {
    fontSize: { value: 8.5, unit: 'pt' },
    lineHeight: { value: 11, unit: 'pt' },
    rangeFormat: 'chicago',
    groups: { fontFamily: 'Source Sans 3', fontWeight: 700, color: { hex: '#8a1c1c', model: 'hex' } },
  },
};
```

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `fontFamily`, `fontSize`, `lineHeight`, `fontWeight`, `color` | — | the body text | Entry typography. Every line of the index, letter heads included, is set on `lineHeight`; the index keeps its own rhythm and does not snap to the baseline grid. |
| `indent` | `Dimension` | `1em` | Indent of each sub-entry level. |
| `turnoverIndent` | `Dimension` | `2em` | Extra indent of an entry's wrapped lines, beyond its own level. |
| `entrySpacing` | `Dimension` | `0` | Space above each main entry. |
| `separator`, `locatorSeparator`, `rangeSeparator` | `string` | `', '`, `', '`, `'–'`; the first two `'، '` in Arabic script | What is printed between the term and its first page, between two pages, and between the ends of a range. |
| `mergeRanges` | `boolean` | `true` | Join consecutive pages of one numbering format into a range: `12, 13, 14` prints `12–14`. Main pages are never joined. |
| `rangeFormat` | `'full' \| 'chicago'` | `'full'` | How the second number of a range is written: in full (`234–237`) or with the digits it shares with the first dropped, as *The Chicago Manual of Style* (9.64) asks: `71–72`, `100–104`, `101–8`, `321–28`, `1496–500`. Roman labels are always written in full. |
| `main` | `{ bold?, italic? }` | bold | How a principal page (`main` on the mark) is set. |
| `see` | `{ label?, alsoLabel?, italic? }` | by language, italic (upright in Arabic script) | The words before a cross-reference. Unset, they follow the document language: *See* / *See also*, *Véase* / *Véase también*, *Voir* / *Voir aussi*, 见 / 另见 (見 / 另見 in Traditional Chinese)… A Chinese index sets the reference after a full stop, with no space: `贾琏 12。见贾政`. |
| `locale` | `string` | the document's | The language whose alphabetical order sorts the entries (a BCP 47 tag, read by `Intl.Collator`). In Spanish *ñ* sorts after *n* and heads a group of its own; accents never change the order. |
| `groupBy` | `'auto' \| 'letter' \| 'pinyin' \| 'stroke' \| 'gojuon' \| 'kana' \| 'none'` | `'auto'` | What the group heads are. `'letter'`: the first letter of the sort key. `'pinyin'`: an entry that starts with a Han character files under the Latin initial of its pinyin reading (贾宝玉 under `J`), and a Latin sort key under its letter, after that letter's Chinese entries (the collator sets Latin letters after Chinese characters): `sort="jia mu"` ends the `J`. `'stroke'`: under the stroke count of the first character, `一畫`, `二畫`… (`一画`… in Simplified Chinese). `'gojuon'`: a kana entry files under its gojūon row, あ行, か行 … わ行, and `'kana'` under its first kana (katakana and hiragana sharing heads), in the JIS X 4061 order of a Japanese index: by the reading (`yomi` of the mark, else the kana reading of its ruby, else `sort`, else the text), katakana as hiragana, small kana as large ones, ー as the vowel before it, 清 before 濁 before 半濁; symbols, then numbers by value, then Latin words under their letters, then kana; an entry still headed by a kanji is reported as `indexReadingMissing` and set after the kana under no head. `'none'`: no heads; symbols, numbers and words are set apart by `groups.marginTop` only. `'auto'` groups a Japanese index (`ja`, `ja-*`) by gojūon row, a Simplified Chinese index (`zh`, `zh-Hans`, `zh-CN`) by pinyin, a Traditional one (`zh-Hant`, `zh-TW`, `zh-HK`) by strokes, and every other language by letter. The entries sort in the collation the heads come from: a `zh-Hant` index grouped by pinyin sorts by pinyin. The readings and stroke counts are the collator's (CLDR); where it reads a character wrongly (重 as *zhòng* in 重阳, 行 as *xíng* in 行业), give the mark a `sort` key in characters that have only the reading you want, which sorts in place: `sort="崇阳"` for 重阳, `sort="航业"` for 行业. A browser without Chinese collation data prints a pinyin or stroke index with no heads. |
| `ignoreArticle` | `boolean` | `true` in Arabic | Sort and group Arabic entries as if a leading article `ال` (`ٱل`) were not there: البصرة files under ب, between بدر and بغداد, and prints as written. `الله` keeps its article, and an entry with its own `sort` key sorts by that key as given. Whatever this says, an Arabic index ignores the vowel signs and the tatweel, files أ إ آ ٱ under ا, and sorts ؤ as و, ئ and ى as ي, ة as ه. |
| `groups.enabled` | `boolean` | `true` | Print a head above each group of entries (`A`, `B`…, or the stroke count, `0–9` for numbers, `Symbols` for the rest; `数字` / `數字` and `符号` / `符號` in Chinese). |
| `groups.fontFamily`, `fontSize`, `fontWeight`, `italic`, `color` | — | the entries', weight `700` | The letter head's face. It is set on the entries' line pitch. |
| `groups.marginTop` | `Dimension` | one line of the index | Space above each group, with or without a head; none above the first group, whose distance from the heading is the heading's, and none at the top of a column. |
| `groups.symbolsLabel`, `numbersLabel` | `string` | by language; `'0–9'`, `'数字'` / `'數字'` in Chinese | The heads of the entries that start with a symbol and with a digit. |

The page numbers come from the book's outline, as the contents' do: `computeOutline()` and `contentOutline()` list the index marks of a text as entries of kind `'indexMark'` (with `indexMark.path`, `sort`, `see`, `seeAlso`, `main`, `range` and `index`), and `outlineFromDoc()` gives each the page it landed on, which the build records in `doc.indexMarks` (`{ sourceStart, pageIndex }` per mark). `buildDocument()` lays a document that prints its own index out again until the numbers settle; a host laying out a book chapter by chapter hands the chapter holding `:::index` the whole book's outline as `PostextContent.outline`. `tocOutline()` and `indexOutline()` split an outline into what the contents and the index read, so a host can key each chapter to the part it prints: the Sandbox lays the index chapter out again only when a mark moves, and the contents chapter only when a heading does. `contentOutline()` also says whether a text prints an index (`hasIndex`).
