Skip to content

Configuration Notes and References

Ignacio Ferro Picón edited this page Oct 16, 2026 · 8 revisions

Configuration: notes, line numbers, references, contents and index

Part of the Configuration reference.

Generated from docs/configuration-notes-references-en.mdx (updated 2026-10-10). Read it on postext.dev, where it is also available in Spanish, Catalan, Portuguese, French, German, Italian, Chinese, Japanese and Arabic. To change this page, edit the MDX and run pnpm wiki in apps/web.

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.

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.
  wordBreak?: 'normal' | 'keep-all'; // The document's cjk.wordBreak 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.
wordBreak 'normal' | 'keep-all' cjk.wordBreak Where the notes break between Chinese, Japanese and Korean characters, apart from the body (see cjk.wordBreak). 'keep-all' keeps a run of such characters whole: the readings an English note quotes (看月光) no longer need a word joiner between every two characters, while the poems of the page go on breaking between any two. 'normal' does the reverse under a document that sets 'keep-all'. Notes at the foot of the column, at the end of the chapter and beside a spread take it. Since postext 1.28.
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.
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.

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 VDTBlocks 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:

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.

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 ('lower-roman', 'arabic-indic', '一'…). Decimal numbers are written in the document's digits (numerals). An unknown name numbers in decimal, with an unknownNumberFormat warning.
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).
  • 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 and :::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:

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 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.

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=.
  breakLabels?: boolean; // A label of words breaks at its spaces.
}
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.
breakLabels boolean true Let a line break at the spaces of a reference whose label is words: the text of a [words]{#id} anchor, the title of a heading or a box, a text="…" override (on a reference to a figure or a table too). The label's spaces then stretch and shrink with the line, and the reference stays one link; its words are not hyphenated. A number, a Roman numeral or a single letter inside such a label keeps to the word before it (Fig. 1a, plate IV). A label with a number or a page (section 3.2, p. 112, Fig. 1.7, Theorem 2) never breaks, even when its template holds an ordinary space. false sets every label as one word no line breaks inside, as up to postext 1.27. A configuration stored before configVersion 12 whose text holds a reference reads with false, so its lines stay where they were (see Bundles written by postext 1.4 or earlier).

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; the style is applied by the postext-citeproc package.

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';
  hyphenateNames?: boolean; // false: the cited authors' names are never divided
  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) 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.
hyphenateNames boolean true Let the dictionary divide the names of the cited authors. false keeps whole the family name of every person in the references (authors, editors, translators) and every name given as one string, wherever it stands with its capital: in a citation, in the running text and in the list, so no line ends on (Lup-. A double name is read part by part, and an author called Baker does not keep the word baker whole. See Words kept whole.
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). 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.

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.
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. {leader} sets the contents' leader between the text before it and the text after it, in one text element: {number} {titleText}{leader}{pageNumber} puts the title at the row's start, the page number at its end and the dots between, flush with the number and gap from either text, as an entry row sets them. The element then takes the row's whole width (an auto width fills to the container's edge); a title too long for the row is cut, never the number, and a leader turned off (leader.enabled: false) leaves the room blank. Outside a part row, and on a vertical page, {leader} prints nothing. In a tagged PDF and in HTML the dots are left out of the text read.
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).
groups.keepTogether boolean false Keep each block of the contents on one column and page: a head row (see groups.head) and every entry under it, down to the next head of the same or a higher rank. A block that does not fit in the room left in its column opens the next column or page, its head row with it, and the column it leaves ends short. The headings right above the contents (its own title) go with the first block when it moves. A block taller than a full column is cut: it starts where its head and groups.minEntriesAfterHead entries fit, and each column it goes on in opens with its head row again (groups.continuation). Every block cut between columns is reported as a tocGroupSplit warning (see Warnings in the document). A :::toc{keep="…"} overrides it for one contents (see Document format). Since postext 1.34.
groups.head 'part' | 1…6 'part' What heads a block: a part row ('part': a part and its chapters), or the entry of a heading level (1: a chapter and its sections, which needs levels or :::toc{levels="1-2"} to list the sections). With a heading level, a part row right above the head goes with its block, so a part row is never left alone at the foot of a column; entries of a higher rank than the head (a chapter when the head is 2) stand alone. A head with no entry under it makes no block. Any other value is read as 'part' and reported.
groups.minEntriesAfterHead number 2 The fewest entries a cut block keeps with its head row: when the head and that many entries do not fit in the room left, the block starts in the next column. 0 lets a head close a column on its own.
groups.continuation object { enabled: true } The head row repeated at the top of each column a cut block goes on in: its number and title followed by mark, in italics, with no leader and no page number (in a part row the mark is part of {titleText}, set in the design's own typography, and {pageNumber} prints nothing). mark defaults to the continued-table suffix of the document's language: (cont.) in English, Spanish, Catalan and Portuguese, (suite) in French, (Forts.) in German, (segue) in Italian, (续) in Chinese, (続き) in Japanese, (تابع) in Arabic. A mark that opens with a wide character is set solid after the title. The repeat is left out of the EPUB navigation and of the reflowable contents. enabled: false cuts the block with no repeat.

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): 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.

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?, separator? } 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。见贾政.
see.separator string '. ' by language What is printed before a cross-reference. A full stop in English, Spanish and Arabic, as The Chicago Manual of Style sets it (Firearms. See weapons); a comma in French, Italian and German (pierrier, voir éboulis, Geröllhalde, siehe Schutthalde); a space in Portuguese, as ABNT NBR 6034 asks (Aviação ver Aeronáutica), and in Catalan, as the IEC's Manual d'estil does; '。' in Chinese and an ideographic space in Japanese. The index's own locale decides, else the document's. A built-in label takes the case the separator asks for: a capital after a full stop, ! or ?, a small letter after anything else (scree, see talus with ', ' in English). A label of your own prints as written.
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.splitMinEntries number 2 When a column or a page ends inside a group, the fewest entries of the group left at the foot of the column and the fewest carried to the head of the next. With 2 no entry stands alone under its head at a column's foot and none opens a column alone before the next group: a group of two or three entries moves whole, and one of four or more is divided only where two stay and two go. An entry is one entry block (a main entry or a sub-entry, with the head and the page-less entries set above it); a group taller than a column is divided where it must be. The level cut of a closing band follows the rule too, so a last group that cannot be shared can leave the columns uneven by its lines. 1 lets a column end between any two entries, as up to postext 1.27. Since postext 1.28; documents stored earlier that print an index keep 1 (pinLegacyIndexGroupSplit).
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).


← Configuration: lists and maths · Configuration: East Asian typography →

Clone this wiki locally