Text variables
The document-level TextVariable definition in IDML, its VariableType kinds, and the frozen ResultText each TextVariableInstance carries.
A text variable is a named, computed string — like a file name or chapter number — that IDML splits into a TextVariable definition under Document and a TextVariableInstance carrying the baked value where it appears.
In short A text variable is a named, computed string — a file name, a chapter
number, a running header, a date — that InDesign places into the flowing text and
re-derives whenever the document changes. IDML records it at two altitudes: a
TextVariable definition that lives once under Document in the design map, and
one or more TextVariableInstance instances that sit in the stories where the
value actually appears. Each instance carries its evaluated value frozen in a
ResultText attribute — a snapshot from the last export. This page is the
document-level reference for the definition, the VariableType kinds it can take,
and the shape of the value an instance carries; our parser records the definition
and inlines the instance's ResultText verbatim without ever recomputing it.
A text variable is a named, computed string — a file name, a chapter number, a
running header, a date — that InDesign places into the flowing text and re-derives
whenever the document changes. IDML splits it into two parts at two altitudes: a
definition that lives once under Document in the design map, and one or more
instances that sit in the stories where the value actually appears.
This page is the document-level reference: the TextVariable definition and the
shape of the value an instance carries. The run-level mechanics — how an instance
becomes characters inside a CharacterStyleRange, and how page-number markers
differ — are documented once in
stories & text → text variables. This page
links there rather than repeating it.
The definition: TextVariable
Each text variable is declared by a TextVariable element directly under
Document in designmap.xml. The parser records three things from it — the id, the
display name, and the kind — at paged-parse/src/designmap.rs:227.
| Attribute · TextVariable (designmap.xml) | Type / values | Support | Notes |
|---|---|---|---|
| Self | string id (TextVariable/…) | Supported | The id an instance references back to via AssociatedTextVariable. |
| Name | string | Supported | The variable’s display name in InDesign, e.g. "Chapter Number" or "File Name". |
| VariableType | VariableTypes enumeration | Parsed, not rendered | What kind of variable it is. Recorded, but not used to recompute a value — the baked ResultText is trusted instead. |
VariableType kinds
VariableType names the rule InDesign would run to produce the value. The
enumeration covers the variable families InDesign offers:
| Attribute · VariableType values | Type / values | Support | Notes |
|---|---|---|---|
| CustomTextType | enum | Supported | A fixed user-supplied string (TextBefore + Contents + TextAfter), re-composed at render. |
| FileNameType | enum | Supported | The document’s file name, taken from the document Name. |
| ChapterNumberType | enum | Supported | The section’s chapter number, styled per the <Section> numbering rules. |
| PageCountType / LastPageNumberType | enum | Supported | The real total body-page count — e.g. for "page 3 of 12" footers. |
| OutputDateType / CreationDateType / ModificationDateType | enum | Supported | A date stamp (output, creation, or last-modified), formatted from a deterministic render-time clock. |
| MatchParagraphStyleType / MatchCharacterStyleType | enum | Supported | Running header / footer: the text of the nearest paragraph or character run in a named style on the same page, resolved post-layout. |
| XrefPageNumberType / XrefChapterNumberType | enum | Parsed, not rendered | The page or chapter number of a cross-reference target. Falls back to the baked value. |
| LiveCaptionType | enum | Parsed, not rendered | A caption derived from a placed image’s metadata. Falls back to the baked value. |
For most kinds the renderer now runs the rule at emit time instead of trusting
the baked snapshot: a ChapterNumberType re-derives the section's chapter number,
a date stamp re-formats from a deterministic clock, and a running-header variable
picks up the live heading text on its page. The remaining kinds (cross-reference
page/chapter numbers, live captions) fall back to the baked ResultText.
The instance: TextVariableInstance and ResultText
Where the variable's value appears in the text, the story carries a
TextVariableInstance element inside a CharacterStyleRange's Content. It holds
the value verbatim in ResultText and points back at its definition through
AssociatedTextVariable. When the parser reaches one, it appends ResultText to the
current run — paged-parse/src/story.rs:1643 — so by the time you hold a run string,
the variable is just more characters.
| Attribute · TextVariableInstance (inside a CharacterStyleRange) | Type / values | Support | Notes |
|---|---|---|---|
| ResultText | string | Supported | The computed value as of the last export, inlined into the run text exactly as written. |
| AssociatedTextVariable | string ref (TextVariable/…) | Parsed, not rendered | Back-reference to the definition. Read, but not used to recompute the value. |
| Self / Name | string id / string | Parsed, not rendered | Identity of the instance; not needed to produce the run text. |
ResultText is the snapshot InDesign computed the last time it composed the
document — but the renderer no longer trusts it blindly. For the kinds it knows
how to run (above), it re-derives the value from the current model and layout and
substitutes that for the snapshot, so a running header does update when you move
the paragraph it tracks, and a chapter number reflects the current section. The
baked ResultText survives only as the fallback for kinds the renderer does not
yet recompute.
What this means in practice
- Re-display is faithful, recomputation is not. Because the value is baked, a consumer reproduces exactly what InDesign last showed — but it will not catch up to edits made outside InDesign.
- The page-number variable is a separate path. The current- and next-page
numbers are not stored as
TextVariableInstance; they are processing instructions (<?ACE 18?>/<?ACE 19?>) that resolve to the live page label at render time. That mechanism — and the private-use marker codepoints it uses — is detailed in stories & text → text variables, and the labels it resolves to are explained in sections and numbering. - For extraction, a
TextVariableInstancecontributes itsResultTextlike any other characters; see extract all text.
Frequently asked questions
What is a text variable in IDML?
A text variable is a named, computed string — such as a file name, chapter number,
running header, or date — that InDesign places into the flowing text. IDML stores it
as a TextVariable definition under Document plus a TextVariableInstance in each
story where the value appears.
What does the ResultText attribute hold?
ResultText holds the variable's value as a literal string, computed as of the last
export and inlined into the run text exactly as written. It is a frozen snapshot, so
our renderer reproduces what InDesign last showed but never re-derives the value from
the current layout.
Does the renderer recompute a chapter number or running header?
No. The VariableType is recorded so a consumer can tell what kind of variable it
is, but the rule it names is never executed — the parsed value is always the frozen
ResultText, not a recomputed chapter count or a re-tracked header.
Is the current page number stored as a text variable?
No. The current- and next-page numbers are not TextVariableInstance elements; they
are processing instructions (<?ACE 18?> / <?ACE 19?>) that resolve to the live
page label at render time. That separate path is detailed in
stories & text → text variables.
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 and numbering
How the resolved Page.Name attribute drives the displayed page number in IDML, what the unparsed Section element would add, and the naive fallback when no name is present.