Sections, numbering & variables
How an IDML document labels its pages with sections and bakes computed text into TextVariable instances — and why those two things are entangled at export.
Sections decide what a page is called; text variables are computed strings placed in the text — and IDML writes down the answers to both, already resolved.
In short: Sections and text variables are the two mechanisms an IDML document uses to label its pages and to embed computed text. A section breaks the page range into runs with their own start number, numbering style, and prefix, so front matter can run in lowercase Roman while the body restarts at Arabic 1. A text variable is a computed string — a file name, a chapter number, a running header, the current page number — placed directly into the flowing text. The two are entangled because a page-number variable depends on the section that owns the page, and InDesign resolves both at export time and writes the answers into the package rather than the recipes. This chapter explains what those baked answers are, which of them stay true and which can go stale, and how our parser and renderer treat each one.
A finished document rarely numbers its pages "1, 2, 3" from cover to colophon. Front matter runs in lowercase Roman, the body restarts at Arabic 1, an appendix carries a "B-" prefix. And the text itself often quotes those numbers — a footer that says "page iv", a cross-reference that says "see page 42", a running header that repeats the current chapter title. None of that is typed by hand. InDesign computes it, and IDML has to write it down so the document round-trips.
Two mechanisms do that work, and this chapter is about the seam between them at the document level:
- Sections decide what a page is called. A
Sectionelement breaks the page range into runs with their own start number, numbering style, and prefix. - Text variables are computed strings that get placed in the flowing text — a file name, a chapter number, the current page number, a running header.
They are entangled because a variable like the page number depends on the section that owns the page. InDesign resolves both at export time and writes the answers into the package. Understanding which answers are durable facts in the IDML and which are stale snapshots is the whole point of reading this chapter.
What the package actually carries
When InDesign exports, it has already laid the document out. So it does not store a recipe that a reader has to re-run; it stores the result:
- Every
Pageelement carries aName— the label the page showed in InDesign, with the section's numbering style and prefix already applied. Page four of the front matter isName="iv", notName="4"plus a "make this Roman" instruction. - Every placed variable is written as a
TextVariableInstancewhoseResultTextattribute is the literal string the variable evaluated to.
This is good news and bad news. The good news: a reader (our parser included) can
display a faithful copy of the document without implementing InDesign's numbering
engine. The bad news: those baked answers can drift. Move a paragraph and the
running header's ResultText is now wrong; repaginate and a baked page label no
longer matches where the page lands. InDesign fixes drift by recomposing. A reader
that only consumes the IDML sees the snapshot.
How our renderer treats each piece
The parser and renderer lean into the "answers are already here" design, and they are honest about what they do not reconstruct:
- Page labels are trusted. The renderer uses each page's
Nameas its user-visible label and substitutes that label wherever an auto-page-number marker appears. See sections and numbering. - The
Sectionelement itself is not parsed. We never read the numbering rules — because we never need to recompute a label thatPage.Namealready carries. The cost is that a document with noPage.Name(rare; mostly synthetic fixtures) falls back to plain 1-based counting with no section awareness. - Variable values are inlined verbatim. A
TextVariableInstancecontributes itsResultTextto the run text exactly as written; the value is never recomputed. See text variables.
Two altitudes of "text variable"
This chapter documents the document-level view: where a variable is defined
(the TextVariable element under Document) and how its baked value rides along in
a story (ResultText). That is enough to extract or re-display a document.
The run-level mechanics — how a TextVariableInstance and the
<?ACE 18?> / <?ACE 19?> page-number markers turn into characters inside a
specific CharacterStyleRange, and which private-use codepoints stand in for the
live page number — are covered once, in
stories & text → text variables. Read that page
for the marker codepoints and the extraction details; read this chapter for where the
definitions live and how sections shape the numbers the variables quote.
Where to go next
- Text variables — the
TextVariabledefinition, itsVariableTypekinds, and how an instance carries its frozenResultText. - Sections and numbering
— how
Page.Namedrives the displayed number, whatSectionwould add, and the naive fallback when no name is present.
Frequently asked questions
What is the difference between a section and a text variable in IDML? A section controls what a page is called — it breaks the page range into runs with their own start number, numbering style, and prefix. A text variable is a computed string placed in the flowing text, such as a file name, chapter number, or running header. They overlap only where a variable quotes a section-controlled value, like the current page number.
Why are page numbers and text variables stored as values instead of formulas?
Because InDesign has already laid the document out at export time, so it writes the
result rather than a recipe a reader would have to re-run. Each Page carries a
resolved Name label, and each placed variable carries its evaluated string in
ResultText — which is what lets a reader display a faithful copy without
reimplementing InDesign's numbering engine.
Can these baked values become stale?
Yes. The labels and ResultText values are snapshots from the last export, so they
can drift if the document is edited outside InDesign — moving a paragraph can leave a
running header's ResultText wrong, and repaginating can make a baked page label no
longer match where the page lands. InDesign fixes drift by recomposing; a reader that
only consumes the IDML sees the snapshot.
Does the renderer parse the Section element?
No. The renderer trusts each page's Name, which already carries the section's
numbering style and prefix, so it never needs to read the Section numbering rules.
The only cost is that a document missing Page.Name — rare, mostly synthetic
fixtures — falls back to plain 1-based counting with no section awareness.
Visibility and printing
An item is drawn only when its layer is both Visible and Printable — how those two switches gate the renderer, why Locked does not, and the layer features the model leaves flat.
Text variables
The document-level TextVariable definition in IDML, its VariableType kinds, and the frozen ResultText each TextVariableInstance carries.