Index Generation¶
In static site generators such as MkDocs, every build emits a search_index.json
file consumed by Lunr.js or Wasabi directly in the browser. It lists every word
encountered in the documentation along with its locations, enabling instant
client-side search. That automation works wonderfully for HTML, but printed
documents require a static index compiled ahead of time.
Traditional LaTeX editing relies on \index{term} commands sprinkled throughout
the source. After compilation you run makeindex or xindy, which produces the
final index file included near the end of the document. TeXSmith mirrors that
workflow: it turns Markdown annotations into LaTeX \index{...} calls and
triggers makeindex/xindy while building the PDF.
That run is the build driver's, not imakeidx's: the package can only call the
index program through shell-escape, which TeXSmith does not enable. Between two
engine passes the driver runs the program over every .idx the document wrote
— its own and one per named registry — and the engine's next pass reads the
.ind back. It picks xindy when one is installed — a printed index sorts
accented terms by the document's language, which makeindex cannot — and
makeindex otherwise. texsmith doc.md --build and texsmith site build run
the same step, so a book's index is a book's index.
The LaTeX form still looks familiar:
\index{term!subterm}
\index{another term}
\index{\textbf{important term}}
\index{\emph{emphasized term}}
Thus, index entries can:
- be nested up to 3 levels,
- be rendered in bold, italic, or both,
- appear multiple times in the document, with all page numbers listed.
TMark spells an index entry with the index role, and #[…] is its shorthand —
# defines, and the term is content, hence the brackets. The two spellings
are one node.
{index}[endianness] one level, default registry
#[endianness] the same thing, shorthand
#[byte order][endianness] nested (three levels at most)
{index main=true}[endianness] main topic: a bold page number
#[**endianness**] the same thing, shorthand
#[*endianness*] emphasis is content markup
{index registry=physics}[Foo][Bar] nested twice under a named registry
#[cake] #[chocolate] several entries in one place
A registry other than the default is named by registry=; it is created on
first use and each produces its own index at the position the template chooses.
{index:reg} and the {b} / {i} suffixes are deprecated
The 0.6 spellings {index:registry}[…] and {index}[…]{b} / {i} are
still parsed with a deprecation warning. tmark lint --fix rewrites them to
{index registry=…}[…] and {index main=true}[…]; italics become content
markup. See Migrating to TMark.
Emphasis and Formatting¶
Printed indexes often differentiate how important an entry is within a section:
- Normal text: the term is discussed in that section (default).
- Bold: the term is the main topic of that section.
- Italic: the term is mentioned but not deeply discussed.
- Bold italic: the term is the main topic and also referenced elsewhere in the same section.
Emphasis inside the term is content markup, so wrap the indexed term in the
appropriate markers (#[*topic*]); "main topic" is the main=true attribute,
for which #[**topic**] is the shorthand.
Nested Entries¶
Consider a cooking book where you want to index the recipe for "Chocolate Cake". You might want to add an index entry for "Cake" with a sub-entry for "Chocolate" and also in "Chocolate Cake":
## Chocolate Cake
#[cake][**chocolate**] #[chocolate cake]
LaTeX only supports up to 3 levels of nesting:
#[cake]
#[cake][**chocolate**]
#[dessert][cake][chocolate]
Tags¶
In MkDocs, search powered by Lunr.js automatically adds tags on headings to
improve searchability. An index entry is a zero-width node: the whitespace
on both sides collapses to one space and disappears before punctuation, so it
never shows in the flow. The LaTeX writer emits \tsindex[registry=r,
main]{sort@formatted!sub} from the ts-index fragment, and the MkDocs plugin
collects the same entries to enrich Lunr's search index. This keeps the PDF
index and the interactive site search in sync even though they are generated
through different pipelines.