Skip to content
Genom
API reference

@genomdev/docx

Word documents (.docx and .doc) — parser, model, content adapter and viewer

470 exported symbols across 2 entry points

@genomdev/docx

Classes

BodyParser
class BodyParser
ids
NodeIds
The identities this parser mints, for whoever continues the document.
bodySection
SectionProperties | undefined
Section properties of the final section, if the parsed part had any.
stats
{ runFormats: number; paragraphFormats: number; }
Distinct run and paragraph formats seen; exposed for diagnostics.
parseBlocks
(parser: XmlPullParser) => BlockNode[]
Parses the children of a `w:body`, `w:hdr`, `w:ftr`, `w:footnote` or `w:tc`. Must be called positioned on the container start tag.
ComposeCache
class ComposeCache
stats
ComposeCacheStats
begin
(token: object) => void
Begins a composition of a document, dropping work that belonged to another.
composeOnce
(node: object, key: string, compute: () => ParagraphInput | string | undefined) => ParagraphInput | string | undefined
The composition of a paragraph, computed once for a given context. `key` is everything about the surroundings that changes the answer: the measure the paragraph is set in and the margin it is set against. A paragraph in a document whose section changed is composed again, which is correct — the column it is set in is a different width.
declined
() => void
Records that a paragraph was composed without being cached.
DocumentBuilder
class DocumentBuilder
session
EditSession
The session underneath, for anything the builder does not wrap.
paragraph
(text?: string, properties?: ParagraphProperties) => ParagraphRef
Adds a paragraph and answers a reference to it.
heading
(text: string, level?: 1 | 2 | 3) => ParagraphRef
Adds a heading at the given level. A heading is a paragraph in a heading style, and the style is what carries the outline level — which is what a table of contents, a navigation pane and this library's own `outline()` read. Setting the size and the weight directly would look the same and be nothing.
picture
(bytes: Uint8Array, options?: PictureOptions) => ParagraphRef
Adds a picture in a paragraph of its own, and answers a reference to it. The bytes are held until the document is saved, and then written into the package as a media part with a relationship pointing at it — see `write/media.ts`. Nothing is decoded: a picture this library cannot read is still a picture Word can, and sniffing the type is only to name the part correctly.
chart
(options: ChartOptions) => ParagraphRef
Adds a chart in a paragraph of its own. The chart becomes a part of the package when the document is saved — see `write/chart.ts` — and the drawing here is the frame that points at it, which is exactly what a chart in a Word document is. What is written is the values, cached, and no workbook behind them: Word draws the chart and its *Edit Data* has nothing to open. That is stated in `write/chart.ts`, and it is the one thing this cannot do.
runs
(runs: readonly { text: string; format?: RunProperties; }[]) => ParagraphRef
Adds a paragraph of runs, each with its own formatting.
listItem
(text: string, level?: number) => ParagraphRef
Adds a bulleted item. A real list: the paragraph carries a `w:numPr` naming a level of a numbering instance, and the instance is written into `numbering.xml` when the document is saved. That is what makes it a list rather than an indented paragraph with a character in front — it renumbers when items are inserted, it collapses in the navigation pane, and Word's own list commands work on it. The indent comes from the level rather than from the paragraph, which is why none is set here: a list whose items each state their own indent is one that stops lining up the moment a level is changed.
numberedItem
(text: string, level?: number) => ParagraphRef
Adds a numbered item; the counterpart of {@link listItem}.
pageBreak
() => ParagraphRef
Adds a page break, which is a paragraph holding one.
table
(rows: readonly (readonly string[])[], options?: TableOptions) => number
Adds a table of plain text cells. The grid is stated even when the widths are not, because Word lays a table out from `w:tblGrid` and a table without one is drawn with every column the same width whatever the cells hold — which for a two-column table of a label and a number is the wrong shape every time.
document
() => DocxDocument
The document as it stands, for a viewer or for another pass of editing.
save
() => Promise<SaveResult>
The finished package.
EditSession
class EditSession
body
readonly BlockNode[]
The body as it now stands.
header
(relationshipId: string) => Promise<StoryRef | undefined>
Opens a running head or foot for editing, by the relationship a section names. Asynchronous because a head is a part of its own and is read when it is asked for — a document with fifteen of them pays for the ones that are used. The reference that comes back edits like any other; what it changes is written back into that part and into no other.
footer
(relationshipId: string) => Promise<StoryRef | undefined>
footnote
(id: string) => Promise<StoryRef | undefined>
Opens a footnote for editing, by the id its reference names. A footnote is a story inside a part shared with every other note, which is why its content span matters: saving one rewrites those characters and leaves the rest of the part exactly as it was.
endnote
(id: string) => Promise<StoryRef | undefined>
storyEdits
(options?: { readonly all?: boolean; }) => readonly StoryEdit[]
The stories this session changed, for a save that must write them back. The part each belongs to is looked up from its span rather than remembered beside it; see {@link Story.content }. A story whose part cannot be named — a document opened without preservation — is left out here and reported by the save as something it could not carry. `all` asks for every story that has been *opened*, changed or not. It is what a caller normalising a document wants: a running head that nobody edited is otherwise never written from the model, so nothing would ever check that it could be.
openEveryStory
() => Promise<number>
Opens every story the document holds, and answers how many there are. A convenience over the four openers, for a caller that wants the whole document rather than one running head — normalising it, checking it, or walking every flow of text it contains rather than only the body.
changed
boolean
Whether anything has been changed since the document was opened.
bodyChanged
boolean
Whether the *body* was changed, which is what decides how it is written.
blocksOf
(story: string) => readonly BlockNode[]
The blocks of one story, for whoever holds its key.
touched
ReadonlySet<number>
The ids of every node an edit has replaced; see `layout` and `write`.
canUndo
boolean
canRedo
boolean
mintId
() => number
Mints an identity for a node this session is about to build.
apply
(step: Step, story?: string) => boolean
Applies a step and records how to undo it. The one door every change goes through, the facade's included. A caller that has a step of its own — one that arrived over a wire, one replayed from a log — puts it through here and gets the same undo behaviour as everything else.
undo
() => boolean
Undoes the last edit, in whichever story it was made. One stack across every story rather than one each: a reader who changed a header and then a paragraph and then pressed undo means the paragraph, and a per-story stack would have to be told which story to undo in — which is a question nobody asking for "undo" has an answer to.
redo
() => boolean
paragraphs
(story?: string) => ParagraphRef[]
Every paragraph of a story, in document order, as references.
tables
(story?: string) => TableRef[]
Every table of a story, in document order.
paragraph
(id: number, story?: string) => ParagraphRef
A reference to a paragraph by id; it need not exist yet.
table
(id: number, story?: string) => TableRef
node
(id: number, story?: string) => IdentifiedNode | undefined
The node an id names in the current version of a story, or nothing.
appendParagraph
(text?: string, properties?: ParagraphProperties, story?: string) => ParagraphRef
Adds a paragraph at the end of the body and answers a reference to it.
document
() => SavableDocument
The document as something that can be saved. A view over the original rather than a copy of it: the styles, the numbering, the theme, the package and every span the reader recorded are the reader's, and the body is this session's. That is what lets a save of an edited document copy every part it did not touch — see `write/save.ts`.
save
(options?: SaveOptions) => Promise<SaveResult>
Saves the document, rebuilding only what an edit reached.
MediaStore
class MediaStore
read
(drawingGroup: ArtRecord | undefined, delayStream: Uint8Array, data: Uint8Array | undefined, spans: readonly ChpxSpan[]) => Promise<MediaStore>
Reads the document's pictures.
forRun
(grpprl: Uint8Array) => PicturePlacement | undefined
The picture a run shows, if it shows one.
forStoreIndex
(index: number) => string | undefined
The picture a shape names by its place in the document's store.
size
number
pictures
() => Iterable<{ id: string; mimeType: string; bytes: Uint8Array; }>
Every picture the store holds, for a save that has to carry them. A `.doc` keeps its pictures in the file's own store rather than as parts of a package, so converting one to `.docx` has to put them somewhere — and until it did, every drawing was written pointing at a relationship that did not exist. See `write/media.ts`.
url
(id: string) => string | undefined
A URL for a picture, made once and kept. An object URL where the host has them, because a photograph as a data URL is a third larger and is copied into every place it is used; a data URL otherwise, which is what a server rendering to HTML needs.
dispose
() => void
NodeIds
class NodeIds

Mints the identity a node keeps for as long as the document is open. Numbers rather than strings: they are compared and hashed on every edit and every incremental relayout, and a document of a million paragraphs would pay for a million strings. Unique within one document and meaningless outside it — an address that survives a file is a different thing, and lives in `@genomdev/core`'s locators. This is all that is left of what was once `model/source.ts`. The model used to carry, beside every node, three numbers saying where in the original file that node stood, so that a save could copy those characters back verbatim. That bought a byte-for-byte round trip and cost the one thing that mattered more: **the document was not a value.** It could not be saved without the file it came from, could not be handed to another process, and held a claim on bytes nobody else could see. The model now holds what it understands and nothing else, and a save is a serialisation of that and nothing else.

mint
() => number
next
number
Where the counter stands, so a document made by editing another continues it.
next
number
Where the counter stands, so a document made by editing another continues it.
NumberingCounter
class NumberingCounter

Computes list numbers by walking the document in order. Deliberately *not* implemented with CSS counters, which is how most web-based DOCX viewers do it. CSS counters break in exactly the situations this viewer is built for: they cannot produce Word's `%1.%2` multi-level patterns without generating a rule per level, they are computed by the browser in document order and therefore give wrong numbers as soon as pages are virtualised and only part of the document exists in the DOM, and they cannot express `startOverride` on a per-instance basis. Computing the numbers here makes them plain text: correct under virtualisation, correct when printing, selectable, and searchable.

next
(reference: NumberingReference) => NumberLabel | undefined
Advances the counters for a numbered paragraph and returns its label. Must be called once per numbered paragraph, in document order.
peek
(reference: NumberingReference) => NumberLabel | undefined
Peeks at what the next label would be without advancing counters. Used by the layout engine when it needs to measure a paragraph that may end up on a different page than where it was first considered.
snapshot
() => NumberingCounterState
Snapshot of the counter state, so layout can rewind and replay.
restore
(state: NumberingCounterState) => void
reset
() => void
ParagraphRef
class ParagraphRef

A handle on a paragraph, which is an id and not a node. Every method reads the current version, so a reference taken before an edit still names the same paragraph after it — including after an edit to that paragraph, which replaced the node the caller would otherwise be holding.

id
number
story
string
Which story the paragraph belongs to; see {@link EditSession}. Carried rather than looked up, because an id is unique across the document and a *search* for it across every open story would be a walk of everything for every read of a paragraph's text.
node
import("/repo/packages/docx/src/index").ParagraphNode | undefined
The node as it now stands, or nothing where it has been removed.
exists
boolean
Whether the paragraph is still in the document.
text
string
The paragraph's text, with fields and links expanded.
setText
(text: string) => this
Replaces the text, keeping the paragraph's own formatting.
appendText
(text: string, properties?: RunProperties) => this
Adds text at the end of the paragraph, in the given formatting.
setProperties
(properties: ParagraphProperties) => this
Replaces the paragraph's properties outright.
format
(properties: ParagraphProperties) => this
Merges properties into the ones the paragraph already has.
setStyle
(style: string) => this
Puts the paragraph in a named style.
formatRuns
(change: (properties: RunProperties) => RunProperties) => this
Applies run formatting to everything in the paragraph.
setBold
(bold?: boolean) => this
setItalic
(italic?: boolean) => this
insertParagraph
(text: string, where?: "before" | "after") => ParagraphRef
Adds a paragraph before or after this one and answers a reference to it.
remove
() => boolean
Removes the paragraph.
StoryRef
class StoryRef

A handle on a story other than the body: a running head, a foot, a note. Everything a story can be asked is what the session can be asked of the body, with the story named — so anything written against the body works against a header by taking one of these instead.

key
string
paragraphs
() => ParagraphRef[]
tables
() => TableRef[]
appendParagraph
(text?: string, properties?: ParagraphProperties) => ParagraphRef
Adds a paragraph at the end of the story.
text
string
The story's text, for a caller that only wants to look.
StyleResolver
class StyleResolver
styleSheet
StyleSheet
numberingDefinitions
NumberingDefinitions
style
(styleId: string | undefined) => Style | undefined
Looks up a style by id, Word's built-in definitions included.
styleByName
(name: string) => Style | undefined
Looks up a style by its display name, as numbering definitions reference it.
resolveStyleChain
(styleId: string | undefined) => ResolvedStyle
Resolves the full property set contributed by a style chain. Walks `w:basedOn` to the root, then applies the styles from the root downwards so that the most derived style wins. Cycles in malformed files are broken by a visited set rather than by a depth limit, so a legitimate deep chain still resolves completely.
resolveRun
(direct: RunProperties, paragraphStyleId: string | undefined, tableContext?: TableStyleContext) => RunProperties
Resolves effective run formatting.
resolveTable
(direct: TableProperties) => TableProperties
Resolves effective table formatting. A table that names no style is not a table without a style: it takes the one marked `w:default="1"`, exactly as a paragraph does. That matters more for tables than for anything else, because the default table style is where the cell margins live — Word's familiar eight hundredths of an inch on the left and right of every cell is a value in `Normal Table`, not a constant in the layout engine. A package that carries no such style really does draw its cell text flush with the page margin, which is not a thing anyone guesses; it has to be measured.
resolveParagraph
(direct: ParagraphProperties, tableContext?: TableStyleContext) => ParagraphProperties
Resolves effective paragraph formatting.
resolveNumberingRun
(paragraphProperties: ParagraphProperties, markRunProperties: RunProperties | undefined) => RunProperties
Resolves the run formatting of a list number. The number is not part of the paragraph text and takes its formatting from the level definition layered over the paragraph's own run properties, which is why a bulleted heading shows a bold bullet.
tableContext
(tableProperties: TableProperties, position: TableCellPosition) => TableStyleContext | undefined
Builds the conditional formatting context for a table cell. The table style supplies up to thirteen property blocks and they compose in a defined order: whole table, then bands, then edge rows and columns, then corner cells. Later blocks win, which is why a header row keeps its formatting even inside a banded table.
clearCaches
() => void
Clears every cache; used when the document is disposed.
TableRef
class TableRef

A handle on a table; the same contract as {@link ParagraphRef}.

id
number
story
string
Which story the table belongs to; see {@link ParagraphRef.story}.
node
import("/repo/packages/docx/src/index").TableNode | undefined
rowCount
number
addParagraph
(row: number, column: number, text?: string) => ParagraphRef | undefined
Adds a paragraph to a cell and answers a reference to it. Through the tree's own append rather than by replacing the cell, so the row, the table and everything beside them are carried by reference and only the path down to the cell is rebuilt — see `edit/tree.ts`.
cell
(row: number, column: number) => ParagraphRef[]
A cell's paragraphs, as references.
remove
() => boolean
TextSource
class TextSource

The document's text, addressed by character position. Deliberately not a string. Building one would mean choosing a code page for the whole document up front, and a document with a Cyrillic quotation in a Greek report has two. It would also cost the memory of the text twice over for documents where only a page is ever looked at.

length
number
pieceAt
(cp: number) => Piece | undefined
The piece covering a character position.
codeUnitAt
(cp: number) => number
The character at a position, as a code unit. For an eight-bit piece this is the raw byte, which is what every structural scan wants: the marks Word puts in the text — the paragraph mark, the cell mark, the field delimiters — are the same byte in every code page, and decoding first would only risk turning one of them into something else.
decode
(from: number, to: number, codePage: number) => string
Decodes `[from, to)` as text, using `codePage` for eight-bit pieces.
ThemeResolver
class ThemeResolver

Resolves theme colour and font references into concrete values. Word rarely writes a literal colour. It writes "accent1, 40% lighter", encoded as a theme slot plus `themeTint`/`themeShade` modifiers, and the actual RGB lives in `theme1.xml`. A viewer that reads only `w:color/@w:val` renders every themed document in black, which is the single most visible difference between a correct DOCX renderer and an approximate one.

runColor
(properties: RunProperties) => string | undefined
Resolves the effective text colour of a run. `w:color/@w:val` wins when it is a literal; otherwise the theme slot is looked up and the tint or shade modifier applied.
themeColor
(slot: string, tintHex?: string, shadeHex?: string) => string | undefined
Resolves a theme colour slot with optional tint or shade.
drawingThemeColor
(slot: string, lumMod?: number, lumOff?: number) => string | undefined
Resolves a DrawingML theme colour with luminance modulation. DrawingML expresses variations as `lumMod`/`lumOff` in thousandths of a percent rather than as the tint/shade bytes used by WordprocessingML.
drawingColor
(reference: ColorReference | undefined) => string | undefined
Resolves a DrawingML colour reference, modifiers and all. A shape's colour is almost never a literal. It is a theme slot with a stack of modifiers on it — `accent1` at 60% luminance with a 40% offset is the pale panel behind a cover headline, and `accent1` with `shade 50000` is the dark one under it. Resolving the slot and dropping the stack paints both of them the same saturated accent, which is worse than the right colour and more obvious than none. The order is DrawingML's: shade and tint act on the colour, then the luminance modulation, then alpha turns it translucent.
drawingRgba
(reference: ColorReference | undefined) => Rgba | undefined
The same, as a colour rather than as CSS, for callers that must compare it.
themeFont
(slot: string) => string | undefined
Resolves a theme font slot such as `minorHAnsi` to a font family name. Word writes `w:asciiTheme="minorHAnsi"` instead of a family name so the document follows the theme; without resolution every run falls back to the browser default.
cssVariables
() => Record<string, string>
CSS custom properties exposing the theme to stylesheets and to the host app.

Functions

absoluteTabWidth
function absoluteTabWidth(kind: string, currentX: number, following: number, room: TabRoom): number

`w:ptab`: a place in the column rather than a stop on the ruler. It is how a running head puts a title on the left and a page number on the right with no stop declared anywhere — and treated as an ordinary tab it advances by the default interval instead, which leaves the page number a third of the way across. The width it returns may be negative, and deliberately: the place it names is a place, not an advance, and a paragraph whose indent has already spent the line is exactly where that matters. An academic report's footer indents past the right margin and then asks for a right-hand `w:ptab`, and Word answers by setting the page number ending at the margin — one line, where clamping the tab to a pixel gives two and takes six pixels off the text area of every page. A width cannot be negative, so the caller makes the distance up with a negative margin, which moves what follows without giving the line a box it has to find room for.

anchorLeftOf
function anchorLeftOf(base: HorizontalAnchorBase | undefined, placement: { readonly offset?: number; readonly align?: HorizontalAlign; }, width: number, origins: HorizontalOrigins): number

Where the left edge of an anchored box lands, in points across the sheet. The same shape as the vertical rule with one thing more: the anchor may state an *alignment* rather than an offset, and then the box is put against an edge of its base or centred in it. `float-across-*` puts a square inch of picture two inches along — five documents, one page each — and the text says where it landed: stated box left which is from page, 192 192 the sheet's left edge, plus 192 from margin, 192 288 the text area's left edge (96), plus 192 from column, 192 288 the same, in a section of one column align right 601.7 the box's right edge on the text area's right align centre 348.9 the box centred in the text area `column` and `margin` came out identical and had to: the probe's section has one column, so the two are the same span. What a column anchor does in a two-column section is not measured. `inside` and `outside` — of both the bases and the alignments — are about which side of a spread the page is on, and are answered here as `left` and `right`, which is right for a document printed one side and a guess for one printed two.

anchorTopOf
function anchorTopOf(base: VerticalAnchorBase | undefined, offset: number, origins: AnchorOrigins): number

Where the top of an anchored box lands, in points down the sheet. The base and the offset, and nothing else — which sounds too simple to need measuring and was not: nothing in the corpus had ever put `relativeFrom` to Word, every probe until now anchoring from the paragraph where one base looks like another. `float-anchored-from-page`, `-margin`, `-paragraph` and `-line` put the same square inch of picture at the same half inch of offset and differ in nothing else. Which lines Word shortens says where the box landed: base box which is page 48 … 144 the top of the sheet, plus 48 margin 144 … 240 the top of the text area (96), plus 48 paragraph 197.7 … 293.7 the top of the anchoring paragraph (149.7), plus 48 `line` came out identical to `paragraph`, and had to: the anchor sits in the first line of its paragraph, so the two origins are the same point. What a `line` anchor does in the *second* line of a paragraph is not measured. The margin bases other than `margin` itself — `topMargin`, `bottomMargin`, `insideMargin`, `outsideMargin` — are not measured either, and are answered here from the text area, which is right for `topMargin` and a guess for the rest.

appendTo
function appendTo(blocks: readonly BlockNode[], containerId: number | undefined, appended: readonly BlockNode[]): readonly BlockNode[]

Appends blocks to the end of a container: the body, a cell or a content block.

applyCharacterSprms
function applyCharacterSprms(grpprl: Uint8Array, base: RunProperties, context: ConvertContext): RunProperties

Applies a character `grpprl`. `base` is what is already in force, and it matters for more than convenience: a toggle's operand can say "invert whatever you inherited", which cannot be answered without it.

applyParagraphSprms
function applyParagraphSprms(grpprl: Uint8Array, base: ParagraphProperties, context: ConvertContext): ParagraphProperties

Applies a paragraph `grpprl`.

applySectionSprms
function applySectionSprms(grpprl: Uint8Array, base?: SectionProperties): SectionProperties
applyStep
function applyStep(blocks: readonly BlockNode[], step: Step): StepResult
asInt16
function asInt16(sprm: Sprm): number

The operand as a signed sixteen-bit value: every measurement in twips is one.

asInt32
function asInt32(sprm: Sprm): number

The operand as a signed thirty-two-bit value.

attributeKey
function attributeKey(namespace: string, localName: string, attribute: string): string
baselineStepOf
function baselineStepOf(previous: LineBox, next: LineBox): number

From one baseline to the next, in points. The quantity a PDF actually shows, and the one a line height is mistaken for. What separates two baselines is the room left under the first and the room taken above the second, so two lines of different heights are not the height of either.

bookmarkMarks
function bookmarkMarks(bookmarks: readonly DocBookmark[]): BookmarkMarks
borderGapOf
function borderGapOf(previous: ParagraphSpacing, next: ParagraphSpacing): number

What the borders add at a seam, in points — and nothing where they meet. Two paragraphs carrying the *same* border are one bordered block to Word: it draws no rule between them and adds no space. `paragraph-borders-that-meet` steps a bare 17.92px between three paragraphs that all state `w:sz="4"` with a point of space, and 4.64px more than a line between a border of four and one of eight — which is the first's bottom and the second's top, both. Compared on the width and the space alone, which is what this carries. Two borders alike in those and different in colour would be merged here and drawn apart by Word; no probe asks, and the corpus has not been read for it.

borderSpaceOf
function borderSpaceOf(border: ParagraphBorder | undefined): number

What a paragraph's border adds above or below its text, in points. The rule itself and the space it asks for, both outside the text. A border `w:val="none"` is not one and states no size; a size of zero is a hairline Word still draws, and the corpus has both.

breakPoints
function breakPoints(text: string): number[]

Every offset in a string at which a line may start.

breaksAfter
function breaksAfter(character: string | undefined): boolean

Whether a line may begin after this character, whatever follows it. Asked of the character before an object, where what follows is not text at all. `U+FFFC` is the object replacement character, whose line-break class is `CB` — the standard's own way of saying "an object stands here" — so the question is put to the algorithm exactly as the algorithm expects it.

breaksBetween
function breaksBetween(left: string, right: string): boolean

Whether a line may end after `left` and begin with `right`. Kept for the callers that hold two characters and no more — a seam between two spans in the browser path. It is a **weaker** question than the one the algorithm answers, because the rules that need context cannot see any: a pair is asked as if it were the whole of the text, so `sot` and `eot` stand either side of it. Prefer {@link breakPoints} over the whole string wherever the whole string is to hand.

buildBlocks
function buildBlocks(context: BodyContext, from: number, to: number): BlockNode[]

Builds the blocks of one story.

cellContentWidthOf
function cellContentWidthOf(columnWidth: number, margins: CellSideMargins | undefined): number

How wide a cell's content may be, in twips. The column it occupies less the margins beside it, which is the width the lines of the cell are broken to. `table-cell-text-width` states 108 twips on both sides of a 2500-twip column: Word begins the first cell's text at 103.2 pixels against a table edge of 96.0, and the second cell's at 270.0 — the edge, the column, and the margin again.

childArtfrom @genomdev/office-core
function childArt(record: ArtRecord, type: number): ArtRecord | undefined

The first record of a type among a record's immediate children.

chooseLines
function chooseLines(pieces: readonly Piece[], roomOf: (index: number) => LineRoom, justified: boolean, hyphenation?: { readonly zone: number; readonly consecutiveLimit: number; }): Line[]
columnOffsetsOf
function columnOffsetsOf(grid: readonly number[]): number[]

Where the columns of a row begin, in twips from the table's left edge. The running sum of the grid, which is what a cell's `w:gridSpan` is counted against and what says which column a cell of a short row belongs to.

columnWidthsOf
function columnWidthsOf(grid: readonly number[], layout: TableLayout | undefined, textAreaTwips: number, statedTwips?: number, minimums?: readonly number[]): number[]

The width of each column, in twips.

columnWidthsPx
function columnWidthsPx(grid: readonly number[], layout: TableLayout | undefined, textAreaTwips: number, statedTwips?: number): number[]

The same widths in CSS pixels, which is what a comparison is read in.

columnWidthTwips
function columnWidthTwips(section: SectionProperties, columnIndex: number): number

Width available to one column, accounting for the gaps between columns. Unequal columns declare their own widths; equal ones split the remaining space. `max(0, …)` rather than the raw arithmetic: `columns-space-12000` asks for a gap wider than the text area, and Word answers with columns of no width at all — one character to the line — rather than with columns that overlap.

composeDocument
function composeDocument(document: DocxDocument, options: ComposeOptions): Promise<ComposedDocument>

A document turned into what the engine takes, and the engine's answer. Exported because more than one tool needs it and a second copy would drift: `geometry-view.mjs` draws what this returns, and drawing something other than what was measured would be worse than drawing nothing.

contentHeightTwips
function contentHeightTwips(section: SectionProperties): number

Height of the text area, i.e. the page minus its vertical margins.

contentWidthTwips
function contentWidthTwips(section: SectionProperties): number

Width of the text area, i.e. the page minus its horizontal margins.

coveringFace
function coveringFace(faces: Faces, family: string | undefined, text: string, bold: boolean, italic: boolean): string | undefined

The face nearest a character's own where its own has no glyph for it. Word draws a character its face lacks in something that has it, and the difference is not decorative: `.notdef` is half an em in Calibri, and a line of them holds twice the text it should.

createDocument
function createDocument(options?: CreateDocumentOptions): DocumentBuilder
cutOverlong
function cutOverlong(pieces: readonly Piece[], room: number): Piece[]

Cuts a piece too wide for the room into pieces that fit. Word's one break inside a word. It offers no opportunity there and would not take one if it did — but a token wider than the column has to end somewhere, and Word ends it at the column's edge: `break-inside-a-token` sets ten twenty-six character tokens in a 2000-twip column and Word answers `aaaaaaaa/bbbbbbbb/cc` and `cccccc` — a cut in the middle of a run of the same letter, at no punctuation and no boundary of any kind. The slash, the stop, the comma, the colon, the bracket and the underscore all read alike, which is what says the cut is the column and not the character. Never less than a character, or a column narrower than one letter would take for ever. **Cutting the word rather than the piece was built and refused.** A token is not always one piece — `nl-09a49d274e30` writes 252 ellipses as three runs — and cut piece by piece their three tails stand on one line together: 1344px of text in a 672px column, which `tools/compare/overrun.mjs` sees and the page count cannot. Pouring the whole run of pieces through the column instead mends that document's lines exactly (39 and 33, Word's own) and costs `legal-91fd8fe7b274` its page count: 1606 exact against 1607. Grouping by `breakBefore` alone also cost `it-dc1d8d29bc77`; grouping by "no break and no space" fixed that and not the other. What decided it is that the repair is worth almost nothing on the axis it was built for: three lines of the corpus's 2841 that stand past the paper. The rest come from elsewhere — pictures and tables wider than their column — so this is not where that problem lives. **Measured again at 1744 exact page counts**, carrying the width from one piece to the next and resetting it wherever a line may begin: the same two documents change hands — `nl-09a49d274e30` won, `legal-91fd8fe7b274` lost — and `pl-063a569635f2` goes from nine pages to ten against Word's eight. 1744 exact either way, 44 pages of error against 43. And that document says where the real fault is. Its dotted rule comes out 1375.5px on a 632px line even after the cut, because the cut sizes a piece to the *whole* room while the line it lands on already holds 481px of text. What is missing is not a wider notion of the token but the emergency cut being made where the remaining room is known, which is `chooseLines` and not here.

defaultCodePageOf
function defaultCodePageOf(lid: number): number

The document language's code page, for a document with no font information.

defaultListNumbering
function defaultListNumbering(options: { readonly bulleted: number; readonly numbered: number; }): NumberingDefinitions

A bulleted or numbered list a builder can actually make. Word's own defaults, because they are what a reader expects a list to look like and because a builder that asked for them would be asking a caller to know the format. Three levels, which is as deep as a generated document goes in practice; a caller wanting more supplies its own definitions. The indents are Word's: 720 twips a level, with the marker hanging 360 back from the text — which is what makes the text of every item line up whatever the marker's width.

defaultStyleSheet
function defaultStyleSheet(): StyleSheet

The styles a generated document actually uses, and nothing beyond them.

distributeColumns
function distributeColumns(given: readonly ColumnDemand[], assignable: number, fixed?: boolean): number[]

The used width of every column, in the same unit the demands were given in.

documentFaces
function documentFaces(options: DocumentFacesOptions): Faces

The faces of one document, resolved by name against the written tables.

eastAsianSlotIsUnset
function eastAsianSlotIsUnset(context: FontSlotContext): boolean

Whether the run's East Asian slot is Times New Roman over an even pair. §2.1.88 b's second bullet and §2.1.88 d, which are the same rule written twice. Compared case-insensitively because a document may write `Times New Roman` in any casing and Word matches families that way.

elementKey
function elementKey(namespace: string, localName: string): string

How markup is named in the register, in reports and in error messages. `w:spacing in pPr` for an element, `w:spacing@w:beforeAutospacing` for an attribute. The prefix is the canonical one of the specification rather than the one the file happened to use, so that the same gap in two documents is one line and not two.

everyBlock
function everyBlock(blocks: readonly BlockNode[]): Generator<BlockNode>

Every block of a tree, in document order, descending into tables.

extensionFor
function extensionFor(mimeType: string): string

The file extension a media part should carry, from its content type. The extension matters more than it looks: `[Content_Types].xml` declares types **by extension**, so a part named `.bin` and declared `image/png` is a part Word will not render. The list is what the corpus actually holds.

extractDocx
function extractDocx(input: ByteSourceInput | DocxDocument, options?: ExtractOptions): Promise<ContentDocument>

Содержимое документа Word — без зонтика и без чужих форматов в графе. Для того, кто знает, какой у него файл. Принимает и уже открытый документ: вьюверу незачем разбирать файл второй раз, чтобы поискать в нём.

familiesNamedBy
function familiesNamedBy(named: Iterable<string>, fonts?: DocumentFonts): readonly string[]

The families a document might ask for, so a caller can load their tables. Every name the walk could reach, for the names the document actually uses: the name itself, its measured stand-ins, its codepage-stripped form, its family, the script's stand-ins, the alternative the file names, the document's default, the shape's stand-ins and the last resorts. A superset, deliberately — loading a table nobody asks for costs a fetch, and missing one costs the deterministic path.

fcLcb
function fcLcb(fib: Fib, index: number): FcLcb

Reads a pair by name, or a zero-length one when the document has no such part.

fieldTypeOf
function fieldTypeOf(instruction: string): string

Extracts the field type — the first token of the instruction — in upper case.

findArtfrom @genomdev/office-core
function findArt(records: readonly ArtRecord[], type: number): Generator<ArtRecord>

Every record of a type, at any depth.

flattenContentControls
function flattenContentControls(blocks: readonly BlockNode[]): readonly BlockNode[]

Removes structured document tags, lifting their content to where they stood. A content control is a wrapper, not content: `w:sdt` marks a region as a date picker or a drop-down or a bound field, and what a reader sees is the `w:sdtContent` inside it. Nothing that consumes the document — the renderer, the extractor, the search index — has any use for the wrapper. It lives here rather than in either consumer because both of them number the blocks they walk, and those numbers are addresses. A renderer that flattens and an extractor that nests produce two different numbering schemes for the same document, and every address minted by one lands somewhere else in the other — silently, and only in the documents that happen to use a content control. One function with two callers cannot drift.

foldFontName
function foldFontName(name: string): string

The key a family name is looked up by: quotes off, spaces out, lower case. The same fold `wordLineRatio` uses, and deliberately no more than that. NFKC would fold `MS 明朝` onto `MS 明朝`, which is tidier and wrong: the full-width spelling is a *different* name to Windows, and the whole point of the alias is that the two names have to be told apart to be joined.

fontSlotFor
function fontSlotFor(code: number, context: FontSlotContext): FontSlot

The slot a code point takes, by [MS-OI29500] §2.1.88 b. Astral characters are answered as the table's fallthrough answers everything it does not list — `hAnsi` — rather than by their surrogate halves: a caller that hands over a whole code point is asking about the character, and the surrogate rows are about UTF-16 units.

formatNumber
function formatNumber(value: number, format: NumberFormat, language?: string): string

The text a counter shows in a given format.

gridFromCells
function gridFromCells(rows: readonly (readonly { readonly width?: TableWidth; readonly span?: number; }[])[], tableTwips: number): number[]

The column widths of a table that states no `w:tblGrid`. The grid is optional, and a table without one is not a table without columns: the cells say how wide they are, in `w:tcW`, and Word reads the columns off them. `administrative-a6c03313c613` is one — no grid at all, `w:tblW` of 5000 `pct` and one cell a row saying the same — and read as a grid of nothing its every column came out nought wide, so every word in it wrapped and its 107 pages became 215. The widest row decides how many columns there are, which is what a grid would have said. A cell that states no width of its own takes an equal share of whatever the ones that do have left.

hangingSetFor
function hangingSetFor(language: KinsokuLanguage): ReadonlySet<string>

What `w:overflowPunct` lets hang, for a run written in this language. Nothing hangs outside the four: Word's own dialog offers the setting beside the other East Asian typography options, and a Latin paragraph has no hanging punctuation whatever `w:overflowPunct` says. Which of the four actually hangs is a separate question, measured rather than documented — see `hangsPunctuation` in `line-break.ts`.

ignoredAttributeReason
function ignoredAttributeReason(key: string, parent: string): string | undefined

Four spellings, from the most specific to the least. `w:spacing@w:line in pPr` names one attribute of one element in one place; `@w:rsidR` names one that hangs off half the elements in the format; and `w:lsdException@*` names an element whose every attribute is bookkeeping — without which the register would need a line for each of the five hundred that a `latentStyles` block writes.

ignoredElementReason
function ignoredElementReason(key: string, parent: string): string | undefined

The reason this markup is passed over, or `undefined` when there is none.

inlineText
function inlineText(nodes: readonly InlineNode[]): string

Concatenates the text of inline nodes, expanding links, fields and revisions.

inSchemaOrder
function inSchemaOrder(names: readonly string[], order: readonly string[]): { readonly ok: boolean; readonly offender?: string; }

Whether a run of element names is in the order the schema states. The check the writers are held to. Names the schema does not list are refused rather than ignored: an element nobody put in the order is an element whose position nobody has checked.

insertBlocks
function insertBlocks(blocks: readonly BlockNode[], id: number, inserted: readonly BlockNode[], where: "before" | "after"): readonly BlockNode[]

Inserts blocks before or after a node. Before and after rather than "at an index", because an index is a position in an array the caller cannot see and a neighbour is a thing it can name.

intervalAt
function intervalAt<T>(plex: Plex<T>, position: number): number

The index of the interval containing `position`. Binary search rather than a scan: a document of any size has thousands of character-formatting runs, and every character of text asks this question.

isGroupFrame
function isGroupFrame(drawing: DrawingNode): boolean

Whether a node is the frame of a group and says how many members follow it.

isIdentifiedBlock
function isIdentifiedBlock(block: BlockNode): block is IdentifiedBlock
isParagraph
function isParagraph(node: BlockNode): node is ParagraphNode
isSelfContained
function isSelfContained(paragraph: ParagraphNode): boolean

Whether a paragraph's composition depends only on the paragraph. The three kinds of sequential state named in this file's note, detected by looking: a list membership, a note reference, or a field. Anything else is a function of its own contents and can be reused.

isTable
function isTable(node: BlockNode): node is TableNode
isWritableChart
function isWritableChart(drawing: DrawingNode): boolean

Whether this drawing is a chart frame the writer can point back at its part.

isWritableDiagram
function isWritableDiagram(drawing: DrawingNode): boolean

Whether this drawing is a SmartArt frame with all four of its parts named. All four, because `dgm:relIds` requires all four. A diagram read before the model kept the other three — or one written by a producer that left an attribute out — cannot be written back as a diagram, and saying so is better than writing a frame Word offers to repair.

isWritableDrawing
function isWritableDrawing(drawing: DrawingNode): boolean

Whether the model holds enough of a drawing to write it back at all.

isWritablePicture
function isWritablePicture(drawing: DrawingNode): boolean

Whether the model holds enough of this drawing to write it back. A relationship to a media part and an extent, and nothing standing in the way — a text box, a diagram, a chart or a shape is more than a picture and the model does not hold the rest of it.

isWritableShape
function isWritableShape(drawing: DrawingNode): boolean

Whether the model holds enough of this drawing to write it as a shape. An extent and either something to draw or something to say. A drawing with neither a look nor a text box is a frame around nothing, and writing an invisible empty rectangle is worse than reporting that it was dropped: it takes room on the page and shows nothing.

isWritableVml
function isWritableVml(shape: VmlShapeNode): boolean

Whether the model holds enough of this shape to write it back. Almost always. A VML shape carries its own style string, and a shape with a style has a place and a size; one without has neither and there is nothing to write. A group is judged by its own box for the same reason — its children's coordinates mean nothing without it.

kinsokuLanguageOf
function kinsokuLanguageOf(tag: string | undefined): KinsokuLanguage | undefined

Which of the four languages a `w:lang/@w:eastAsia` tag names, if any. Chinese is split by script and not by country: `zh-TW`, `zh-HK` and `zh-MO` are written in traditional characters and take the traditional list; `zh-CN` and `zh-SG` take the simplified one. A tag naming the script outright — `zh-Hant`, which Word writes for some templates — says so directly.

kinsokuSetFor
function kinsokuSetFor(language: KinsokuLanguage, overrides?: KinsokuOverrides): KinsokuSet

The set actually in force for a language, given what the document says. See the note at the head of the file for the order of precedence, which is [MS-OI29500]'s and not the standard's.

languageTag
function languageTag(lid: number): string | undefined
layoutDocument
function layoutDocument(blocks: readonly BlockInput[], page: PageSetup, faces: Faces, running?: RunningInput, options?: LayoutOptions): LayoutResult

Lays the blocks out on pages. Greedy, one block at a time, which is what Word does: a block is broken into lines at the column's width, the lines are dropped onto the page until it is full, and what is left starts the next page. Nothing an earlier page holds is revisited when a later one fills up.

layoutMath
function layoutMath(nodes: readonly MathElement[], face: MathFace, sizePx: number, display?: boolean): MathBox

Lays an equation out. `display` is `m:oMathPara` — an equation on a line of its own, which takes the roomier of every pair of constants the table states. An inline equation takes the tighter, so that a fraction in a sentence does not open the line.

lineBoxOf
function lineBoxOf(runs: readonly LineRun[], statedSpacing: LineSpacing, grid?: DocumentGrid, compat?: LineCompat, paragraphType?: LineRun): LineBox
lineHeightOf
function lineHeightOf(runs: readonly LineRun[], spacing: LineSpacing, grid?: DocumentGrid): number

The height of one line, in points.

locate
function locate(blocks: readonly BlockNode[], id: number): { readonly node: IdentifiedNode; readonly path: NodePath; } | undefined

Finds a block by id, anywhere in the tree, with the path that reaches it.

mathToText
function mathToText(node: MathNode | MathElement): string

Extracts the plain text of a math expression. Used for text extraction and search, where an equation should contribute its symbols rather than being silently dropped.

mediaPartName
function mediaPartName(taken: (name: string) => boolean, extension: string): string

A part name for a picture, and it must not collide with one already there. `word/media/image1.png` is the convention, and a package being written may already hold `image1.png` — copied through from the source — so the number walks until it finds a name nobody has taken.

meetsFloat
function meetsFloat(band: Band, column: Span, floats: readonly (FloatBox & { readonly wrap?: WrapSide; })[]): boolean

Whether a box would take room from a line, without working out how much. The question a paragraph asks before it decides to break its lines itself: one that meets no float can be broken to a single width, and one that does cannot.

mergeBorders
function mergeBorders(base: Borders, override: Borders): Borders

Merges border sets edge by edge.

mergeTextBoxRanges
function mergeTextBoxRanges(first: TextBoxRanges, second: TextBoxRanges): TextBoxRanges

Merges the header story's text boxes into the body's, keeping both indexes.

naturalLineOf
function naturalLineOf(runs: readonly LineRun[], grid?: DocumentGrid): number

The line the type needs before `w:spacing` has its say, in points.

observeMarkup
function observeMarkup(observe: (sighting: MarkupSighting) => void): () => void

Watches everything the readers pass over until the returned function is called. The hooks are static on the parser — the readers are hot loops and threading an option through every one of them would cost more than the feature is worth — so this is process-wide and must be undone.

openDoc
function openDoc(source: ByteSource, options?: OpenDocOptions): Promise<DocxDocument>
openDocx
function openDocx(source: ByteSource, options?: OpenDocxOptions): Promise<DocxDocument>

Opens a Word document. The main part is parsed in a single streaming pass, while the supporting parts that a given rendering may not need — headers, footers, footnotes, comments — are left to be loaded on demand. That matters more than it sounds: a document with fifteen section-specific headers pays for the two that are actually displayed.

paragraphGapOf
function paragraphGapOf(previous: ParagraphSpacing, next: ParagraphSpacing, lineTwips?: number): number

The space between two paragraphs, in points. **The larger of the two, not their sum.** Three probes settle it, each ruling out one reading the others cannot: - `contextual-spacing` states `before` and `after` both at 240 twips and Word puts 16.00px between the lines — 240 twips exactly, where the sum would be 32px. That disposes of adding them. - `empty-paragraph-height` has a separator with `before` 400 and `after` 0, and Word gives it its 400 twips. That disposes of reading only `after`. - `line-spacing-default-two-paragraphs` has `after` 160 and `before` 0, and Word gives it its 160. That disposes of reading only `before`. A table cell is no exception, and neither is a blank paragraph in one. This once summed the seam where a written paragraph met a blank one in a cell, on a reading of two drifting rows of `forms-99782b65f187`, and `educational-57592f55761a` contradicted it: its title cell puts 105 twips after the title and 240 before a blank line, Word opens 240, and the sum made the row 7px tall and floated the page's table off by as much. `cell-blank-paragraph-seam` asks directly — written to blank and blank to written, 40 against 40, 105 against 240 and the reverse, at single and at one-and-a-half lines — and every seam is the larger of the two. `w:contextualSpacing` then suppresses a paragraph's own space where its neighbour names the same style — and only the same style: the probe puts two different contextual styles next to each other and Word keeps the space between them.

paragraphStepOf
function paragraphStepOf(previous: LineBox, next: LineBox, gap: number): number

From the last baseline of one paragraph to the first of the next, in points. The same arithmetic as {@link baselineStepOf} with the space between them added, which is what a reference shows at a paragraph boundary and what makes such a step useless as a reading of a line's height.

parseArtPropertiesfrom @genomdev/office-core
function parseArtProperties(record: ArtRecord | undefined): Map<number, ArtProperty>
parseArtRecordsfrom @genomdev/office-core
function parseArtRecords(bytes: Uint8Array, from?: number, to?: number): ArtRecord[]

Reads a sequence of records. Stops at the first header it cannot believe rather than continuing, because a wrong length here does not lose one record — it puts the reader in the middle of somebody's pixel data, where every eight bytes look like a header.

parseBorders
function parseBorders(parser: XmlPullParser): Borders

Parses a border container: `w:pBdr`, `w:tblBorders`, `w:tcBorders`, `w:pgBorders`. `w:start` and `w:left` name the same edge, and a file may carry both: the first is what the strict standard writes and the second what the transitional one kept from Word 2007. Where both are present the logical spelling wins, whichever came first in the file — [MS-OI29500] §2.1.1758 through §2.1.1765 say it eight times over, once for each of the four containers' two edges. Reading them into one case, as this did, made the answer depend on the order a writer happened to emit them in.

parseCellProperties
function parseCellProperties(parser: XmlPullParser): CellProperties

Parses `w:tcPr`.

parseChartfrom @genomdev/office-core
function parseChart(parser: XmlPullParser): ChartDefinition

Parses a whole chart part.

parseDiagramDrawingfrom @genomdev/office-core
function parseDiagramDrawing(parser: XmlPullParser): DiagramDrawing

Parses the drawing Word cached for a SmartArt diagram. The part is a flat shape tree with absolute geometry, so it needs no knowledge of the diagram algorithm that produced it.

parseFib
function parseFib(bytes: Uint8Array): Fib
parseFontTable
function parseFontTable(parser: XmlPullParser): FontDefinition[]

Parses `fontTable.xml`.

parseNumbering
function parseNumbering(parser: XmlPullParser): NumberingDefinitions

Parses `numbering.xml`. The part has three kinds of top-level content: abstract definitions holding the actual level formatting, concrete instances that paragraphs reference and which may override individual levels, and picture bullets. Keeping the indirection intact matters — two lists sharing an abstract definition must still number independently.

parseOfficeArtContentfrom @genomdev/office-core
function parseOfficeArtContent(bytes: Uint8Array | undefined): OfficeArtContent
parseParagraphProperties
function parseParagraphProperties(parser: XmlPullParser, onSectionProperties?: (parser: XmlPullParser) => void): ParagraphProperties

Parses `w:pPr`.

parsePieceTable
function parsePieceTable(clx: Uint8Array | undefined, fib: Fib): Piece[]

Reads the piece table out of the `Clx`. The `Clx` is a sequence of blocks: any number of `Prc` blocks, which carry formatting for the pieces and are of no use to a reader, and then exactly one `Pcdt` holding the table itself. Walking rather than seeking is what makes the `Prc` blocks skippable, and they do occur.

parsePlex
function parsePlex<T>(bytes: Uint8Array | undefined, structSize: number, readStruct: (reader: ByteReader, index: number) => T): Plex<T>

Reads a plex.

parsePositionPlex
function parsePositionPlex(bytes: Uint8Array | undefined): Plex<never>

A plex with no elements, only boundaries.

parseRowProperties
function parseRowProperties(parser: XmlPullParser): RowProperties

Parses `w:trPr`.

parseRunProperties
function parseRunProperties(parser: XmlPullParser): RunProperties

Parses `w:rPr`. Must be called positioned on the `w:rPr` start tag; returns with the parser on the matching end tag.

parseSectionProperties
function parseSectionProperties(parser: XmlPullParser, over?: SectionProperties): SectionProperties
parseSettings
function parseSettings(parser: XmlPullParser): DocumentSettings

Parses `settings.xml`.

parseSttb
function parseSttb(bytes: Uint8Array | undefined, codePage?: number): SttbEntry[]
parseStyles
function parseStyles(parser: XmlPullParser): StyleSheet

Parses `styles.xml`. Styles are stored exactly as written, with no inheritance resolved. Flattening `w:basedOn` chains at parse time is tempting but wrong: the resolution order differs between paragraph properties, run properties and the thirteen conditional table blocks, and a flattened style can no longer answer "was this value set here or inherited", which the table style cascade needs. Resolution lives in {@link StyleResolver }, where it is memoised per style id.

parseStylesheet
function parseStylesheet(bytes: Uint8Array | undefined, fonts: readonly DocFont[]): { styles: StyleSheet; styleIdOf(istd: number): string | undefined; }

Reads the stylesheet and resolves it into the shared model. Resolution happens here rather than being left to the style resolver because the two formats disagree about what a style stores. WordprocessingML stores the *difference* from the parent, and so does this — but a `grpprl` is applied to a starting point, and for a style that starting point is its parent's resolved properties. Applying each style's modifiers to nothing gives a document whose headings lose everything they inherited.

parseTableProperties
function parseTableProperties(parser: XmlPullParser): TableProperties

Parses `w:tblPr` or `w:tblPrEx`.

parseTheme
function parseTheme(parser: XmlPullParser): Theme

Parses `theme1.xml`.

piecesOf
function piecesOf(spans: readonly LineSpan[], perCharacter?: boolean, hyphenation?: Hyphenating): Piece[]
propertyValuefrom @genomdev/office-core
function propertyValue(properties: ReadonlyMap<number, ArtProperty>, id: number): number | undefined
readAnchors
function readAnchors(bytes: Uint8Array | undefined, inHeader: boolean): Plex<ShapeAnchor>

Reads the anchors of one story. The plex is keyed by character position, so the result is looked up with the position of the `0x08` that stands for the shape.

readBookmarks
function readBookmarks(names: Uint8Array | undefined, starts: Uint8Array | undefined, ends: Uint8Array | undefined, codePage: number): DocBookmark[]
readChpxSpans
function readChpxSpans(binTable: Uint8Array | undefined, stream: Uint8Array, entrySize?: number): ChpxSpan[]

Reads every character-formatting page the bin table points at. Eagerly rather than on demand, and deliberately: the pages are a few hundred for a large document, they are scattered so reading them one at a time is the slowest possible access pattern, and every one of them will be needed by the time the document has been laid out once.

readInlinePicture
function readInlinePicture(data: Uint8Array, location: number): Promise<InlinePicture | undefined>
readPapxSpans
function readPapxSpans(binTable: Uint8Array | undefined, stream: Uint8Array, entrySize?: number, dataStream?: Uint8Array): PapxSpan[]

Reads every paragraph-formatting page. Each entry is one paragraph, which makes this plex the document's paragraph list as much as its formatting: the boundaries it gives are exactly the ones the paragraph marks in the text imply, and having both is how a reader can tell a paragraph mark from a byte that merely looks like one.

readPictures
function readPictures(drawingGroup: ArtRecord | undefined, delayStream?: Uint8Array): Promise<DocPicture[]>

Reads every picture the document's store lists. The store holds one entry per picture and, in Word, almost never the picture itself: the entry carries an offset into a *delay stream*, and the delay stream is `WordDocument`. So the pictures sit among the text, in the one place a reader of the drawing layer would not think to look, and a store that appears to hold nothing is the normal case rather than an empty document.

readSepx
function readSepx(stream: Uint8Array, fc: number): Uint8Array | undefined

Reads a section's `grpprl` out of `WordDocument`. A `SED` points at it rather than holding it, and the pointer is `FFFFFFFF` when the section carries no properties of its own at all.

readShapes
function readShapes(content: OfficeArtContent, textBoxes: TextBoxRanges): Map<number, DocShape>

Indexes every shape in the document by its identifier. Both drawings are walked — the body's and the headers' — into one index, because an anchor names a shape and says nothing about which drawing it is in, and the two identifier spaces do not overlap.

readTextBoxRanges
function readTextBoxRanges(bytes: Uint8Array | undefined, from: number): TextBoxRanges

Reads which stretch of the text box story belongs to which shape. The entries carry an identifier, and it took a corpus to establish what that identifier is: not the shape's `lTxid` property, which is what the name suggests and which turns out to be an index shifted sixteen bits, but the shape's own **identifier**. A document with one text box has a shape numbered 1026 and an entry saying 1026; the shape's `lTxid` says 65536.

removeNode
function removeNode(blocks: readonly BlockNode[], id: number): readonly BlockNode[]

Removes a node by id.

repeatedHeaderRows
function repeatedHeaderRows(rows: readonly { readonly header?: boolean; }[]): number

How many rows repeat at the top of every page the table reaches. `w:tblHeader` marks a row as a heading, and Word repeats **all** of the marked ones, not the first alone — but only while they run unbroken from the top of the table: a row marked in the middle of one is not a heading and Word draws it where it stands. `table-header-row-repeats` marks two rows of a table a hundred and twenty long. Word opens page two with `Header first` at the very top of the text area and `Header second` a line below it, and page three the same — both rows, in order, with no space above them beyond the table's own.

replaceNode
function replaceNode(blocks: readonly BlockNode[], id: number, replacement: IdentifiedNode): readonly BlockNode[]

Replaces a node by id, rebuilding only the path down to it. Answers the same array when the id is not there, so a caller can tell a change that did nothing from one that did.

resolveLevel
function resolveLevel(numbering: NumberingDefinitions, numberingId: number | undefined, level: number | undefined, styleLinkResolver?: (styleId: string) => number | undefined): NumberingLevel | undefined

Resolves the effective definition of a list level. Walks instance → override → abstract definition, following `numStyleLink` indirection when an instance points at a numbering style rather than at a concrete definition.

roomBeside
function roomBeside(band: Band, column: Span, floats: readonly (FloatBox & { readonly wrap?: WrapSide; })[]): Span[]

The room left for one line beside the floats it meets, as the runs it may use. **Several runs, not one.** A box in the middle of a column leaves room on both sides of it and Word uses both: `float-wrap-side-bothsides` puts a square inch in the middle of a 601.7-pixel column and Word sets one line as two fragments, 96.0 to 223.4 and 404.1 to 661.7. `bothSides` is also the default, so this is the ordinary case and not the exotic one. The sweep says what each value does, on the same picture in the same place: wrapText where the text goes bothSides 96…223 *and* 404…694 — both, on one line left 96…270 only right 404…694 only largest 404…694 — the same as right, the right being the wider An earlier reading of this took the wider side always, which is right for a box against a margin — where the narrow side is nothing — and wrong for one in the middle, which is what the default does most.

rowHeightOf
function rowHeightOf(content: number, height: RowHeight | undefined, margins: RowMargins | undefined): number

The height of one row, in points.

saveDocx
function saveDocx(document: SavableDocument, options?: SaveOptions): Promise<SaveResult>
scaffoldParts
function scaffoldParts(options: { readonly styles?: StyleSheet; readonly numbering?: NumberingDefinitions; readonly metadata?: DocumentMetadata; }): Scaffold
shapePropertiesfrom @genomdev/office-core
function shapeProperties(container: ArtRecord): Map<number, ArtProperty>

All three property tables of a shape, merged in the order they override.

spanAt
function spanAt<T extends { fcStart: number; fcEnd: number; }>(spans: readonly T[], fc: number): T | undefined

Binary search for the span covering a file offset.

spanWidthOf
function spanWidthOf(grid: readonly number[], from: number, span?: number): number

The width of a cell that spans several columns of the grid, in twips. The sum of the columns it covers, and nothing taken off for the rules between them. `table-grid-span` puts a cell over the first two of three 2000-twip columns and an ordinary row of three beneath it as a ruler: the ruler's cells begin at 96.7, 230.1 and 363.4 pixels — 133.3 apart, which is 2000 twips — and the cell after the span begins at 363.4 exactly, where the third column does. The vertical rule between the merged columns costs the span nothing.

spreadMergedHeight
function spreadMergedHeight(rows: readonly number[], merged: number): number[]

The heights of a run of rows a cell is merged down, in points. A vertically merged cell is not in any one of its rows: its text runs through all of them, and the rows together have to be tall enough to hold it. Where they already are, nothing moves; where they are not, the shortfall lands on the **last** row of the run. `table-vertical-merge` shows both halves. A cell of five words is merged down three rows beside three cells of one line each, and Word sets its three lines 17.92px apart — one line, continuously, paying no attention to the rows — while the neighbours sit at 129.15, 147.07 and 167.71. The first two rows are exactly a line tall, and the third is not: it carries what is left.

sprms
function sprms(grpprl: Uint8Array, from?: number): Generator<Sprm>

Walks a `grpprl`. Stops at the first opcode it cannot size rather than guessing, because a misread length does not produce one wrong property — it desynchronises the stream and every property after it is read out of the middle of an operand.

stopAfter
function stopAfter(currentX: number, stops: readonly PlacedStop[]): PlacedStop | undefined

The declared stop a tab at `currentX` reaches, or nothing where it falls through to the default interval. The first stop strictly to the right of the current position wins. The margin is a shade wider than the guard a right-aligned stop leaves behind it, so that the stop a tab has just reached is never chosen again — which would ask the same text to end twice at the same place and collapse the tab to nothing.

storyRanges
function storyRanges(fib: Fib): StoryRanges
strictMarkup
function strictMarkup(options?: StrictMarkupOptions): () => void

Makes unaccounted markup an error for the duration of the returned handle. For development runs and tests, never for a viewer: against real files this throws constantly, and that is the point — it is a search for the gaps, not a way to read documents.

substitutesFor
function substitutesFor(name: string): string[]

Faces to fall back on when the one the document names is not installed. Word does this itself and calls it font substitution: it keeps a table of metric-compatible pairs and, finding neither the named face nor a mapping, picks something of the right shape. A viewer that passes the name straight to CSS and stops gets the browser's last-resort face instead, which has neither the metrics nor the look — every line comes out a different width, and the comparison reports it in the same shape as a real defect. Two rules, both of which the corpus asks for by name: - The metric-compatible clones. Liberation Serif is Times New Roman's metrics to the glyph and is what LibreOffice writes when it saves a document that used one; five documents in the corpus name it and none of them means a different typeface. - A weight or a slope carried in the family name. `Arial Bold` is not a family and no system has it — it is Arial, and the boldness is already on the run. Dropping the trailing style word finds the family that exists.

tabAdvance
function tabAdvance(currentX: number, following: () => number, stops: readonly PlacedStop[], room: TabRoom, decimalHead?: () => number): TabAdvance

What a tab at `currentX` advances by. `following` is the width of the text between this tab and the next. It is a function and not a number because only a stop that *ends* its text at the stop needs it, and measuring it is the expensive half of laying out a tab: the browser walks the nodes after the tab with a `Range`. Most tabs are left-aligned and never ask.

tableTopOf
function tableTopOf(anchor: TableVerticalAnchor | undefined, yTwips: number, origins: { readonly page: number; readonly margin: number; readonly text: number; }): number

Where the top of a floating table lands, in points down the sheet. `w:tblpPr` takes a table out of the flow and puts it where its anchors say, with the text running around it — the same idea as an anchored drawing, a separate implementation in Word, and its own vocabulary: `text` where a drawing says `paragraph`, and `w:tblpY` in twips where a drawing has EMU. `float-table-from-page`, `-margin` and `-text` put the same two-inch table two inches down and differ in nothing else: vertAnchor table top which is page 192 the top of the sheet, plus 192 margin 287.8 the top of the text area (96), plus 192 text 341.8 where the table stood in the flow (149.7), plus 192 The text wraps around it as it does around a drawing: the table occupies 96 to 288 and the lines beside it begin at 289.

tallestOf
function tallestOf(runs: readonly LineRun[]): LineRun | undefined

The run that decides the line, or nothing where the line has none. Tallest is not largest: a face's line is a multiple of its size and the multiples differ by six per cent between the faces of an ordinary document, so eleven-point Calibri needs 13.42 points where twelve-point Times needs 13.8 — the *smaller* run is the taller line. `line-height-owner-plus-smaller- calibri` puts that pair to Word and Word answers with the Times line.

toggle
function toggle(sprm: Sprm, inherited: boolean | undefined): boolean | undefined

A toggle's operand. Bold, italic and their nineteen relatives are stored as a byte with four meanings, not two: off, on, and the two that make sense only against something inherited — leave as inherited, and invert it. A style that turns bold on and a paragraph inside it that says "invert" is how Word writes a heading whose emphasised words are set roman.

walkBlocks
function walkBlocks(blocks: readonly BlockNode[]): Generator<BlockNode>

Walks every block in a subtree, descending into tables and content blocks. A generator rather than an array: callers usually stop early (finding the first section break, locating a bookmark) and materialising the whole document as a flat list would defeat the point of a streaming parser.

walkDocx
function walkDocx(document: DocxDocument, hash: string, options: ResolvedOptions): Promise<{ blocks: Block[]; annotations: Annotation[]; }>

Reading a Word document as content. The hard parts, in the order they bite: A Word document is not one stream. The body, each header, each footer, each footnote and each comment are separate flows, and numbering them as if they were one would make every address after the first footnote wrong. So each gets its own locator flow and its own walk. A list is not a list. Word stores a paragraph with a numbering reference, not a nested structure, and the number itself is nowhere in the file — it is the paragraph's position among its neighbours, resolved through a definition that may restart partway down. So the numbers are computed here, in document order, and the flat sequence of numbered paragraphs is folded back into the tree it was drawn as. A heading is a claim, not a fact. `w:outlineLevel` and the built-in heading styles both say so and they disagree; a document whose author never used a heading style has no headings, and inventing them from type size gives a table of contents made of pull quotes.

walkInline
function walkInline(nodes: readonly InlineNode[]): Generator<InlineNode>

Walks every inline node, descending into hyperlinks, fields and revisions.

widenForSpans
function widenForSpans(columns: ColumnDemand[], spans: readonly { readonly from: number; readonly span: number; readonly minContent: number; readonly maxContent: number; }[]): void

A cell spanning several columns, widening them until they hold it. CSS 2.1: "For each cell that spans more than one column, increase the minimum widths of the columns it spans so that together, they are at least as wide as the cell. Do the same for the maximum widths." The same ladder as above decides which of the spanned columns grows, which is why it is one function. Applied after every single-column cell has had its say, and in order of increasing span, so that a cell over two columns settles before one over three has to reason about them.

widestRoom
function widestRoom(band: Band, column: Span, floats: readonly (FloatBox & { readonly wrap?: WrapSide; })[]): Span | undefined

The widest run of room a line has, or nothing where it has none. For a caller that sets one run of words to a line and does not divide it — which is every caller until the line breaker learns to.

widthOf
function widthOf(width: TableWidth | undefined, ofTwips: number): number | undefined

The width a `w:tblW` or `w:tcW` means, in twips. `pct` is in fiftieths of a per cent — 5000 is the whole of it — and what it is a per cent *of* is what the caller passes: the text area for a table, the table for a cell.

withHangingStop
function withHangingStop(stops: readonly PlacedStop[], hanging: number, indentX: number, listItem?: boolean): readonly PlacedStop[]

The paragraph's own left indent, as a stop, where the paragraph hangs. That is what a hanging indent is *for*: the label sits out in the margin, a tab carries the reader to the indent, and every line after the first starts there. Legal drafting and anything converted from it writes list items exactly so — a tab, `(a)`, a tab, the text — and without the implicit stop the second tab falls through to the default interval or, when the declared stop lies just behind it, to nothing at all. The text then abuts the label: `(a)be made in writing`. Left-aligned, and only when the paragraph hangs: an indent with no hanging part is where the text already begins, so a stop there would advance by nothing. ## `w:doNotUseIndentAsNumberingTabStop` is not honoured, and neither is it by Word ECMA-376 Part 4 §14.8.3 declares a flag for exactly this stop — "specifies that applications shall not use the custom tab stop generated by the hanging indent when advancing the text after the numbering" — and 53 documents of the corpus set it, more than any other compatibility flag we do not read. Implementing it makes no difference because Word does not implement it. `compat-indent-as-numbering-gap-{on,off}` are the same document but for the flag, numbered `w:ind w:left="1000" w:hanging="360"`: the number is drawn at 640 twips, the implied stop is at 1000, and the first default stop past the number is at 720 — the two readings are 280 twips apart and cannot be confused. Word draws the text at 1002 twips in both. `-mode12-` asks the question again of a document that declares itself Word 2007, in case the transitional flag were honoured only in a transitional mode: 1002 twips again. `-stop-` is the calibration pair at `left="360"`, where both readings would land in the same place, and it agrees with itself. So Word does not place the text after a number by finding a tab stop at all where the indent is one — it places it at the indent, and the flag has nothing to switch off. The stop below stays unconditional.

withInheritedRunningParts
function withInheritedRunningParts(section: SectionProperties, previous: SectionProperties | undefined): SectionProperties

Carries the running parts of one section forward into the next. Headers and footers are the one part of a section that is *not* self contained. Word writes a complete `w:sectPr` for everything else — page size, margins, columns — but a header reference is written only where the header changes. Everywhere else the section is linked to the one before it, which is exactly what the "Link to Previous" button in Word's header editor controls, and what its absence from the file means. The link is per type. A section may replace the default header and keep inheriting the first-page and even-page ones, and a report that changes its running title at each chapter while keeping one title page does precisely that. Inheriting all-or-nothing puts the wrong title on every chapter after the first. There is no way to declare "no header here": to break the link and show nothing, Word references a header part that is empty. Absence therefore always means inherit, never means none — a distinction that matters, because a section that reserved no room for an inherited header would run its text under it.

wordLineRatio
function wordLineRatio(fontFamily: string | undefined): number | undefined

Word's ratio for the first family of a stack that has one. The stack is read left to right, as CSS resolves it: the first family the table knows is the one the text will actually be set in, and a fallback named after it never gets the chance to decide the line.

writeBlock
function writeBlock(context: WriteContext, block: BlockNode): void
writeBlocks
function writeBlocks(context: WriteContext, blocks: readonly BlockNode[]): void

Writes a run of blocks: the contents of a `w:body`, a cell or a header.

writeCellProperties
function writeCellProperties(writer: XmlWriter, properties: CellProperties | undefined): void

`w:tcPr`, in `CT_TcPrBase` order.

writeChartGraphicData
function writeChartGraphicData(writer: XmlWriter, drawing: DrawingNode): void

`a:graphicData` holding the one element that names a chart part.

writeChartPart
function writeChartPart(chart: ChartDefinition): string
writeDiagramGraphicData
function writeDiagramGraphicData(writer: XmlWriter, drawing: DrawingNode): void

`a:graphicData` holding the four relationships a diagram is reached by.

writeDocumentPart
function writeDocumentPart(input: DocumentPartInput, lost?: Map<string, number>): { readonly xml: string; readonly lost: Map<string, number>; }
writeDrawing
function writeDrawing(writer: XmlWriter, drawing: DrawingNode, naming: PictureNaming, content?: ShapeContent): void
writeGroupDrawing
function writeGroupDrawing(writer: XmlWriter, frame: DrawingNode, members: readonly DrawingNode[], naming: PictureNaming, content: ShapeContent): readonly DrawingNode[]

Writes a group and returns the members it could not write. The return is not an error: a group holding a chart is a group whose other shapes are still worth drawing, and the caller reports what was dropped by the same route it reports everything else. An empty array is a whole group.

writeInlines
function writeInlines(context: WriteContext, nodes: readonly InlineNode[]): void

Inline content, grouped back into the runs it came from. The model flattens a `w:r` into the nodes it produced — a run holding text, a tab and a break becomes three nodes — so writing one node per element would turn one run into three, each with its own copy of the formatting. That is valid and it is not what the file said, and on a document of a million runs it is three times the size. So nodes are regrouped: consecutive nodes sharing one formatting object go back into one `w:r`.

writeMath
function writeMath(writer: XmlWriter, node: MathNode, content: MathContent): void

Writes an equation as `m:oMath`, or as `m:oMathPara` where it stood alone. Never inside a `w:r`. `m:oMath` is paragraph content in the schema — a sibling of the runs, not a child of one — and an equation written inside a run is a document Word offers to repair. See `writeRun`, which closes the run around it.

writeNumberingPart
function writeNumberingPart(numbering: NumberingDefinitions): string
writeParagraph
function writeParagraph(context: WriteContext, paragraph: ParagraphNode): void

A paragraph, built from the model. The section properties of a paragraph that ends a section are written inside `w:pPr`, which is where the format puts them and which is the one part of a paragraph's properties that is not formatting.

writeParagraphProperties
function writeParagraphProperties(writer: XmlWriter, properties: ParagraphProperties | undefined, writeSection?: () => void): void

`w:pPr`, in `CT_PPrBase` order.

writeRowProperties
function writeRowProperties(writer: XmlWriter, properties: RowProperties | undefined): void

`w:trPr`, in `CT_TrPrBase` order.

writeRunProperties
function writeRunProperties(writer: XmlWriter, properties: RunProperties | undefined, element?: string, markRevision?: RevisionInfo): void

`w:rPr`, in `EG_RPrBase` order. Written even when it holds nothing only if the caller asks: an empty `w:rPr` is legal, Word writes them, and a run whose properties are empty is better off with no element at all.

writeSectionProperties
function writeSectionProperties(writer: XmlWriter, section: SectionProperties): void

`w:sectPr`, in `EG_SectPrContents` order. The one property element whose *absence* is not the same as its default. A section states its page, its margins and its columns whether or not they differ from anything, because a `w:sectPr` is what makes a section — and the references to its running heads and its page numbering are the parts a reader notices missing first: a report whose letterhead is gone, a chapter that starts numbering at one. Everything here was written because a comparison of two *models* said it was being lost. Nothing about the text of those documents changed, which is why `tools/write/model.mjs` exists.

writeShapeElement
function writeShapeElement(writer: XmlWriter, drawing: DrawingNode, content: ShapeContent, place?: { readonly x: number; readonly y: number; readonly id: number; readonly name: string; }): void

The `wps:wsp` itself, without the graphic data around it. Written under `a:graphicData` for a shape standing on its own, and directly inside `wpg:wgp` for one that is a member of a group. `place` gives the member its rectangle in the group's coordinate space; a shape on its own sits at the origin of a space its frame has already positioned.

writeShapeGraphicData
function writeShapeGraphicData(writer: XmlWriter, drawing: DrawingNode, content: ShapeContent): void

The graphic data of a shape, for the frame `drawing.ts` puts around it. Called with the writer positioned inside `a:graphic`, which is where every kind of drawing becomes its own kind.

writeStylesPart
function writeStylesPart(sheet: StyleSheet): string
writeTable
function writeTable(context: WriteContext, table: TableNode): void

A table, and the two things about writing one that are easy to get wrong. `w:tblGrid` is not optional in practice: Word lays a table out from the grid, and a table written without one is drawn with every column the same width whatever the cells say. And `w:tblPr` comes before it, before the rows, and nothing may come between them.

writeTableProperties
function writeTableProperties(writer: XmlWriter, properties: TableProperties | undefined, element?: string): void

`w:tblPr`, in `CT_TblPrBase` order.

writeVmlPicture
function writeVmlPicture(writer: XmlWriter, shape: VmlShapeNode, content: VmlContent): void

Writes a `w:pict` holding one VML shape or group.

Interfaces

AbstractNumbering
interface AbstractNumbering

An abstract list definition, `w:abstractNum`.

id
number
nsid
string | undefined
`w:nsid`: the identity of the list, shared by every copy of it. Two documents pasted together keep their lists apart by this, and Word matches a list against the one in its own gallery by it. A hex word.
template
string | undefined
`w:tmpl`: the gallery entry the definition was made from.
restartAfterBreak
boolean | undefined
The list starts again at the first item after a section break, `w15:restartNumberingAfterBreak`. Word 2013 added it and writes it into every list it saves. A numbered list that runs on across a chapter boundary and one that restarts at each chapter are the same markup apart from this. Three-valued on purpose: a list that says nothing is not a list that says no. Word's default is to restart, so writing `0` where the file wrote nothing would change the document.
multiLevelType
string | undefined
`singleLevel`, `multilevel` or `hybridMultilevel`.
name
string | undefined
styleLink
string | undefined
Identifier shared by lists created from the same gallery entry.
numStyleLink
string | undefined
Numbering style that this definition implements.
levels
ReadonlyMap<number, NumberingLevel>
AltChunkNode
interface AltChunkNode

External content embedded by reference, `w:altChunk`.

kind
NodeKind.AltChunk
id
number
Identity, for as long as the document is open. What an edit names and what an incremental relayout compares. Not an index: inserting a paragraph renumbers every index after it and leaves every id alone, which is the entire reason this is here. See `model/ids.ts`.
relationshipId
string | undefined
AnchorOrigins
interface AnchorOrigins

The places an anchor may be counted from, in points down the sheet.

page
number
The top of the sheet, which is nought by definition and named for clarity.
margin
number
The top of the text area — the page less its top margin.
paragraph
number
The top of the paragraph the anchor sits in.
line
number
The top of the line the anchor sits on.
Annotation
interface Annotation

What one placeholder character in the text refers to.

kind
"footnote" | "endnote" | "comment"
id
string
ArtPropertyfrom @genomdev/office-core
interface ArtProperty

One entry of a shape's property table. The table is two lists in one record, and that is the whole subtlety of it. First a fixed-size array of (identifier, value) pairs; then, appended after the array in the same order, the payloads of whichever of those pairs said their value was a length rather than a value. Reading only the array gives a shape whose picture is "eighteen bytes" instead of a picture.

id
number
value
number
The value, or the length of {@link complex} when the property is one.
isBlipId
boolean
True when the value names a blip rather than being one.
complex
Uint8Array<ArrayBufferLike> | undefined
ArtRecordfrom @genomdev/office-core
interface ArtRecord

One record: its header, and either its bytes or its children.

type
number
version
number
instance
number
data
Uint8Array<ArrayBufferLike>
The record's payload, a container's included. A view rather than a copy, so keeping it for a record that also has children costs nothing — and there are records where it is the only way through. PowerPoint marks `msofbtClientData` and `msofbtClientTextbox` as containers and then fills them with records of *its own* language, which happen to share this eight-byte header exactly. Walked as Office Art they produce a plausible tree of the wrong thing; the reader that knows better needs the bytes.
children
readonly ArtRecord[]
Band
interface Band

A line's own vertical extent, which is what decides whether a box touches it.

top
number
bottom
number
BlockGeometry
interface BlockGeometry

One block, placed, with its lines.

index
number
Which block of the flow this is, or `-1` for something that is not one. A running head, a running foot and the footnote area belong to the *page* rather than to the flow, and they were all reported as `-1` — which was enough for a comparison, which only wants to know where a line is, and not nearly enough for a painter, which has to draw a head differently from a foot. {@link BlockGeometry.furniture} says which.
furniture?
"footer" | "header" | "notes" | "lineNumbers" | undefined
What this is, where it is not a block of the flow. Absent for the flow itself, which is the overwhelming majority.
frame?
{ readonly x: number; readonly width: number; } | undefined
The column the block was set in: its left edge and its width, in pixels. Not derivable from the lines. A paragraph's shading and its rules fill the *measure*, not the ink — an empty paragraph with a grey background is a grey band the width of the column, and a short line in a shaded paragraph is still shaded to the right margin. Absent where the block is not of the flow.
lines
readonly LineGeometry[]
cells?
readonly CellGeometry[] | undefined
The cells of a table, where this block is one. In the page's frame, like everything else here. A table divided over two pages reports on each page the cells that page draws.
bands?
readonly BandGeometry[] | undefined
The paragraph bands of a box, where this block is one. A block of the flow has none: its band is its {@link BlockGeometry.frame} and the ref the painter already holds. See {@link BandGeometry}.
BodyContext
interface BodyContext extends ConvertContext

Everything the builder needs that is not the text itself.

ids
NodeIds
The identities the nodes of this document are given. Identity is all a node carries beside what it means, whichever generation it came from — which is why `.doc` opens into the same model as `.docx` and can be saved as one.
text
TextSource
chpx
readonly ChpxSpan[]
papx
readonly PapxSpan[]
fonts
readonly DocFont[]
The font table: character properties name a font by its index in it.
defaultCodePage
number
The document's language, which decides how eight-bit text with no font decodes.
legacyProperties?
boolean | undefined
The property modifiers are Word 6/95's, whose opcodes are a byte wide. Set for a document old enough that its formatting cannot be read with the decoder here. The text, the paragraphs and the tables still can, so such a document is read without formatting rather than not read — and reading the old opcodes with the new decoder would not degrade, it would invent: the same bytes mean different properties, so the paragraphs would come out confidently wrong rather than plain.
keepDeletedContent?
boolean | undefined
Show text that a tracked change deleted. Off by default, which is what a reader means by "open this document": the deleted words are not part of it. Leaving them in does not merely add text — it makes the document state the opposite of what its author left behind, and nothing on the page says which sentence is which.
sectionEnds?
ReadonlyMap<number, SectionProperties> | undefined
Section properties keyed by the character position the section ends at.
annotations?
ReadonlyMap<number, Annotation> | undefined
What the placeholder characters stand for, keyed by character position. A footnote reference, an endnote reference and a comment reference are all one character in the text with nothing in it to say which — the tables that list them are the only thing that does, and without this map every one of them is dropped as an unreadable control character.
fcOf
(cp: number) => number
Character position to file offset, which the formatting tables are keyed by.
media?
MediaStore | undefined
The pictures the document holds, already read and named.
shapesAt?
((cp: number) => readonly AnchoredShape[]) | undefined
The shapes anchored at a character position; a group contributes several.
bookmarks?
BookmarkMarks | undefined
Where each bookmark opens and closes, by character position.
BodyParserOptions
interface BodyParserOptions

Options controlling which optional content the body parser keeps.

keepDeletedContent?
boolean | undefined
Keep content marked as deleted by revision tracking. Off by default, which renders the document as if all changes were accepted — what a reader expects to see. The viewer can turn it on to show markup.
parseMath?
boolean | undefined
Parse OMML equations. On by default.
onProgress?
((fraction: number) => void) | undefined
Report progress as a fraction of the part consumed.
ids?
NodeIds | undefined
The identity minter of the document being read. Shared across every part, because a header's paragraphs and the body's are paragraphs of one document and an edit names one of them without caring which part it came from. A parser given none mints its own, which is what a test that parses a fragment wants.
preserve?
boolean | undefined
Whether to record where each node stood, and to keep what is not modelled. On by default. Off, the parser behaves exactly as it did before spans existed: no `source`, no `Raw` nodes, nothing kept that nothing draws. The cost of leaving it on is twelve bytes a block and one node per unmodelled element; the cost of turning it off is that saving the document loses them.
BookmarkEndNode
interface BookmarkEndNode
kind
NodeKind.BookmarkEnd
id
string
BookmarkMarks
interface BookmarkMarks

What starts and what ends at each character position.

starts
ReadonlyMap<number, readonly string[]>
ends
ReadonlyMap<number, readonly string[]>
BookmarkStartNode
interface BookmarkStartNode
kind
NodeKind.BookmarkStart
id
string
name
string
Border
interface Border
style
BorderStyle
sizeEighths
number | undefined
Width in eighths of a point, as stored in `w:sz`.
spacePoints
number | undefined
Distance from the text in points, `w:space`.
color
string | undefined
Colour as `RRGGBB`, or `auto`.
themeColor
string | undefined
Theme colour reference, `w:themeColor`.
themeTint
string | undefined
Lightening applied to `themeColor`, `w:themeTint`.
themeShade
string | undefined
Darkening applied to `themeColor`, `w:themeShade`.
shadow
boolean | undefined
Borders
interface Borders
top?
Border | undefined
left?
Border | undefined
bottom?
Border | undefined
right?
Border | undefined
tl2br?
Border | undefined
Diagonal borders, table cells only.
tr2bl?
Border | undefined
between?
Border | undefined
Borders between paragraphs sharing a border set.
bar?
Border | undefined
BoxSpan
interface BoxSpan

Anything on a line that is not text the breaker may cut: a picture, a tab already sized against its stop, a numbering label, or the padding and border of a boxed run. Its width is given, not measured. What differs between them is only what a break may do around them, which is what the two flags say.

kind
"box"
width
number
label?
boolean | undefined
Part of a list's label rather than of its text; see {@link Piece.label}.
mayBegin
boolean
Whether a line may begin at the box, if what precedes it allows one. False for a tab — a tab that began a line would be advancing to a stop behind it — and for the insets of an inline box, which are not breakable material at all but a widening of the text around them.
opensLine
boolean
Whether a line may begin *after* the box, whatever preceded it. True for an object, which is a thing on the line and ends a word the way a space does. False for an inset, which must leave the text on both sides of it reading as one word.
widthAt?
((x: number) => number) | undefined
The width, where it depends on where the box lands. A tab is exactly this and nothing else is: its advance is not a width but the distance to the next stop, so it cannot be known until the line has been filled as far as the tab. Given, it replaces {@link BoxSpan.width}. The `x` it is handed is measured from where a *continuation* line of the paragraph begins — its left indent — so a caller with the column's ruler in hand adds that indent and no more. The first line's own indent is already in it: `chooseLines` knows how much narrower the first line is, and both lines end at the same right edge.
hangAt?
((x: number) => number) | undefined
How far the text after the box hangs past the edge the line was broken to. A tab stop is a position on the *column's* ruler and may sit past the paragraph's own right indent; Word honours it there, and the page number of a table-of-contents entry hangs into the indent while the title above it still wraps at it. See {@link TabAdvance.beyond }. A shift and not a width, deliberately: the line is broken and aligned at the indent — which is what keeps the *wrap* Word's — and what follows the tab is then painted out over it. Given, everything after the box on the line moves right by this much, and the leader fills the room as well.
leaderAt?
((x: number) => { readonly glyph: string; readonly width: number; readonly run?: unknown; } | undefined) | undefined
The character a tab draws across the room it takes, and its advance. `w:tabs/w:tab/@w:leader` — the dots of a table of contents. They are text on the line as far as anything reading the page is concerned, and a line whose leader is dropped does not match the line Word drew.
endsLine?
boolean | undefined
Whether the line must end here — an explicit `<w:br/>`. It ends the word as well, so that no pair straddles it, but it opens no line: what follows begins one because the break did, not because a break opportunity was found.
fillsLineAt?
((x: number) => boolean) | undefined
Whether the box ends its line, given the abscissa it lands at.
endsLineAt?
((x: number) => boolean) | undefined
wrapsAt?
((x: number) => boolean) | undefined
fontSize
number
BreakNode
interface BreakNode
kind
NodeKind.Break
breakType
BreakType
clear
"all" | "none" | "left" | "right" | undefined
Text wrapping around a floating object, `w:br/@w:clear`.
properties
RunProperties
BreakPiece
interface BreakPiece

An explicit line break, `<w:br/>`: the line ends here and the next begins. Not a paragraph boundary — the spacing around a paragraph is not paid — and not a space either. A paragraph that writes one and has it dropped comes out as one long line, which fits several of Word's on each of ours and gives a document a third of the pages it should have.

ref?
unknown
See {@link PieceRef}.
lineBreak
true
family?
string | undefined
The type the break is written in, which rules a line holding nothing else. See the note below this interface for what was refused; what is carried now is narrower: only a line with no other run on it is ruled by its break.
sizeHalfPoints?
number | undefined
bold?
boolean | undefined
italic?
boolean | undefined
CellInput
interface CellInput

One cell of a row, with whatever it holds.

ref?
unknown
What whoever built this wants back when it is drawn; see {@link PieceRef}. Borders, shading, the address a citation uses — none of them changes where anything goes, so none of them is the engine's, and this is how they reach the painter without the engine learning what a border is.
align?
"center" | "top" | "bottom" | undefined
`w:vAlign`: where the content sits in a cell taller than it is.
vMerge?
"restart" | "continue" | undefined
`w:vMerge`: whether the cell begins a vertical merge or continues one. A continuation draws nothing of its own — its text belongs to the cell that began the run — and it makes its row no taller; the run's height is spread over the rows it covers by {@link spreadMergedHeight}.
vertical?
boolean | undefined
`w:textDirection`: the cell's text runs up or down rather than across. A rotated cell is as tall as its text is long, and as wide as its text is tall — the two measurements change places. Its lines are not placed: where they would be drawn is a matter for the painter, and a rotated line's words are nowhere a comparison by baseline would look for them. What matters to the page is the height, and that is a length of text.
direction?
"tbRl" | "btLr" | undefined
Which way a vertical cell's text runs: `tbRl` top to bottom with its lines stacked from the right, `btLr` bottom to top with its lines from the left.
upright?
boolean | undefined
`tbRlV`: East Asian vertical; see {@link LineGeometry.upright}.
span?
number | undefined
`w:gridSpan`: how many columns of the grid the cell covers.
width?
TableWidth | undefined
`w:tcW`: the width this cell would prefer, where it states one. Read only by the content-driven autofit, which needs to know whether a column is a length, a percentage or nothing at all; the width a cell is *given* comes from the grid. See `table-width.ts`.
noWrap?
boolean | undefined
`w:noWrap`: the cell's content is measured as if it could not be broken. ECMA-376 §17.4.29 in as many words — "the contents of that this table cell shall be treated as though they have no breaking characters" — which makes the cell's minimum content width equal to its maximum. It bears only on the autofit; a cell under a stated grid wraps as it must.
margins?
CellSideMargins | undefined
The cell's own margins where it states them, the table's otherwise.
hideMark?
boolean | undefined
`w:hideMark`: the end-of-cell glyph does not rule the row. An empty cell is still a line tall, because the mark Word draws in it is a line — unless the cell says this, and then it is nothing at all. `table-hide-mark-plain` puts four rows of empty cells between two markers and Word spends 67.5px on them, four lines; `-hidden` writes `w:hideMark` on every cell of the same four rows and Word spends **nought** — the marker under the table sits one ordinary line below the one over it. `-sized` states eighteen points on the hidden mark and Word still spends nothing, so it is not a smaller line but no line; `-mixed` puts a line of text beside a hidden empty cell and the row is that line, so the cell that holds something still rules. 86 documents of the corpus write it, and 11.6 % of them disagree with Word about their page count where the corpus as a whole disagrees about 5.0 %.
blocks
readonly BlockInput[]
CellMargins
interface CellMargins
top?
Measurement | undefined
left?
Measurement | undefined
bottom?
Measurement | undefined
right?
Measurement | undefined
CellProperties
interface CellProperties

Cell-level formatting, `w:tcPr`.

width?
Measurement | undefined
gridSpan?
number | undefined
Number of grid columns the cell spans, `w:gridSpan`.
verticalMerge?
"restart" | "continue" | undefined
Vertical merge state, `w:vMerge`.
horizontalMerge?
"restart" | "continue" | undefined
Horizontal merge state, `w:hMerge`; the legacy form of `gridSpan`.
borders?
Borders | undefined
shading?
Shading | undefined
margins?
CellMargins | undefined
verticalAlignment?
"both" | "center" | "top" | "bottom" | undefined
textDirection?
string | undefined
noWrap?
boolean | undefined
fitText?
boolean | undefined
hideMark?
boolean | undefined
conditionalFormatting?
ConditionalFormatting | undefined
CellSideMargins
interface CellSideMargins

The room a cell keeps beside its content, in twips.

left?
number | undefined
right?
number | undefined
top?
number | undefined
`w:tcMar/@w:top` and `@w:bottom`, which Word defaults to nought. They take no width off the line, which is why the pair beside them is enough for {@link cellContentWidthOf} — but a cell that states them is taller by them, and its content begins that far down.
bottom?
number | undefined
ChartAxisfrom @genomdev/office-core
interface ChartAxis
id
string
position
"b" | "t" | "r" | "l"
`c:axPos`: `l`, `r`, `b` or `t`.
kind
"value" | "category" | "date" | "series"
Whether the axis is a category axis, a value axis or a date axis.
deleted
boolean
`c:delete`, an axis that is present in the file and not on the page.
min
number | undefined
max
number | undefined
majorUnit
number | undefined
majorGridlines
boolean
minorGridlines
boolean
reversed
boolean
`c:scaling/c:orientation`; `maxMin` reverses the axis.
numberFormat
string | undefined
`c:numFmt/@formatCode`, the format the tick labels are printed in.
labelled
boolean
Whether tick labels are drawn at all, from `c:tickLblPos`.
title
string | undefined
titleSize
number | undefined
The size the title states, `c:title//a:defRPr/@sz`, in points.
line
DiagramOutline | undefined
The axis line itself, `c:spPr/a:ln`.
text
ChartTextStyle | undefined
`c:txPr`: the type its tick labels are set in.
majorTickMark
string | undefined
`c:majorTickMark`: `none`, `in`, `out` or `cross`.
crossBetween
string | undefined
`c:crossBetween`: whether the marks sit between the ticks or on them. `between` puts a bar in the middle of its band, which is what a bar chart wants; `midCat` puts a line's first point on the axis itself, which is what a line chart wants and what makes its curve start at the left edge instead of half a band in.
ChartDefinitionfrom @genomdev/office-core
interface ChartDefinition
titleAutomatic?
boolean | undefined
Whether the title is one the file wrote out or one the application makes. `<c:title/>` with no `c:tx` is not a chart without a title: it is a chart whose title the application supplies. Both applications name it after the one series where there is one — see `automaticTitle` — and where there is more than one PowerPoint leaves it blank while Word writes the words `Chart Title`. This is that case, and the host fills it in through `ChartRenderContext.blankTitle`.
title
string | undefined
plots
readonly ChartPlot[]
axes
readonly ChartAxis[]
legend
ChartLegendPosition | undefined
legendText
ChartTextStyle | undefined
`c:legend/c:txPr`: the type the legend's own entries are set in.
legendLayout?
ChartManualLayout | undefined
`c:legend/c:layout/c:manualLayout`: where the author dragged the legend.
legendOverlay?
boolean | undefined
`c:legend/c:overlay`: whether the legend sits over the plot rather than beside it.
fill
DiagramColor | undefined
Fill of the whole chart area, `c:chartSpace/c:spPr`.
fillGradient?
ChartGradient | undefined
...where that fill is a gradient rather than one colour. A chart flooded with a gradient and lettered in white is unreadable drawn on white paper: `tdf128207` has a black-to-grey bar chart whose every label, tick and title disappeared. Kept as the stops and the angle, which is what a gradient is; a reader that can only manage one colour takes the first stop.
fillPattern?
ChartPattern | undefined
...or a hatching, `a:pattFill`. `tdf128207` stands its pie on a dark downward diagonal; drawn as plain white the chart loses the one thing that told it apart from its neighbour.
outline
DiagramOutline | undefined
plotFill
DiagramColor | undefined
Fill of the plot area, which is usually absent and then transparent.
plotOutline
DiagramOutline | undefined
`c:plotArea/c:spPr/a:ln`: the frame drawn around the plot itself. Not the axes — those are two rules and this is four — and a chart that states one is framed by Word whatever its axes do.
blanks
"span" | "gap" | "zero"
`c:dispBlanksAs`: what a plot does where its data has a hole. `gap` leaves the mark out, `zero` draws it on the floor, `span` joins across it. Word's own default is `gap`, and a series of measurements taken weekly with a fortnight missing looks entirely different under each of the three.
text
ChartTextStyle | undefined
`c:chartSpace/c:txPr`: the type the whole chart is set in. The one every real chart states, and the one nothing read. A chart written by PowerPoint puts its size here once and leaves each axis silent, so a renderer looking only at the axes falls back to its own default: eighteen points of stated type drawn at ten, and a title at fourteen. It is not a subtle error — it is every label of every chart at three quarters of its size, therefore at three quarters of its width, therefore centred over a different part of the bar it labels.
plotArea
ChartManualLayout | undefined
Where the author put the plot area, if the file says; see {@link ChartManualLayout}.
language
string | undefined
`c:lang`: the language the chart states its numbers were written in. Read and kept, and *not* what decides the decimal separator: a chart stating `en-US` has its labels drawn `3,3` on a German machine, so the application writes the separator of whoever opens the file. See `chart-render`'s `separators`.
titleSize
number | undefined
`c:title`'s own size in points, where it states one.
titleStyle?
ChartTextStyle | undefined
The weight, the slant, the colour and the face the title states.
titleLines?
readonly ChartTitleLine[] | undefined
The title's paragraphs, each with the size it states. A chart title is a text body: `aascu.org…` heads three of its charts with a line of 18.72 px over a parenthesis of 16, and one string at one size folds into different words on different lines. Empty for a title the application generated (see `automaticTitle`), which is one line by construction.
titleLayout?
ChartManualLayout | undefined
`c:title/c:layout/c:manualLayout`: where the author dragged the title. Three charts side by side on slide 16 of `aascu.org…` and two of them state one; ignored, their headings sit eight pixels below PowerPoint's while the third — which states nothing — lands to a quarter of a pixel.
fonts?
{ readonly major: string | undefined; readonly minor: string | undefined; } | undefined
The typefaces of the theme the chart part carries of its own. A chart is related to a `themeOverride` part as often as not — Excel writes one whenever the workbook's theme differs from the document's — and it is that theme, not the presentation's, that the chart's unstated fonts resolve against. Slide 8 of `aascu.org…` is the case: the deck is set in Lucida Sans Unicode, the chart's override says Calibri, and a title drawn in the deck's face is wide enough to fold into three lines where PowerPoint folds it into two. Filled in by whoever read the part, since the chart XML cannot see its own relationships.
ChartOptions
interface ChartOptions

A chart to put in a document, said in the least a chart can be said in. The full `ChartDefinition` is what a chart *read from a file* comes back as — axes with ids, plots with gap widths, every colour of every series — and almost none of it is what somebody inserting a chart wants to type. This is the short form: what kind, what the categories are called, and one or more named series of numbers. {@link DocumentBuilder.chart} fills in the rest with what Word own Insert Chart produces.

kind?
"column" | "area" | "bar" | "line" | "pie" | "doughnut" | undefined
title?
string | undefined
categories
readonly string[]
One label per point, shared by every series.
series
readonly { readonly name?: string; readonly values: readonly (number | undefined)[]; readonly color?: string; }[]
legend?
"b" | "t" | "r" | "tr" | "l" | undefined
Where the key goes; absent means no key at all.
showValues?
boolean | undefined
Print the value beside every mark.
width?
number | undefined
height?
number | undefined
widthEmu?
number | undefined
heightEmu?
number | undefined
description?
string | undefined
ChartPlotfrom @genomdev/office-core
interface ChartPlot

One `c:*Chart` inside the plot area.

kind
ChartKind
direction
"col" | "bar"
`c:barDir`: `col` for vertical bars, `bar` for horizontal ones.
grouping
ChartGrouping
gapWidth
number
Space between category groups as a percentage of bar width, `c:gapWidth`.
overlap
number
How far bars of one category overlap, as a percentage, `c:overlap`.
holeSize
number
Hole of a doughnut as a percentage of its diameter, `c:holeSize`.
markers
boolean
Whether a line plot draws markers at its points.
varyColors
boolean
`c:varyColors`: paint each point of the plot differently. What makes a one-series bar chart a row of coloured bars rather than a row of identical ones, and it is on by default for a pie — where it is the only thing that tells one slice from the next.
scatterStyle
string | undefined
`c:scatterStyle`: whether a scatter plot joins its points, and with what. `marker` is a cloud of points with no line; `line` and `lineMarker` join them with segments; `smooth` and `smoothMarker` with a curve.
radarStyle?
string | undefined
`c:radarStyle`: `standard` joins the points, `marker` marks them too and `filled` floods the shape they enclose.
showValues
boolean
Whether the plot asks for its values to be printed beside every mark.
axisIds
readonly string[]
Axis ids this plot is drawn against, in the order they were declared.
series
readonly ChartSeries[]
ChartPointfrom @genomdev/office-core
interface ChartPoint

One value of a series, with the point it belongs to.

index
number
value
number
ChartSeriesfrom @genomdev/office-core
interface ChartSeries
name
string | undefined
`c:tx`, the cached series name.
categories
readonly (string | undefined)[]
Category labels, from `c:cat`; sparse points are `undefined`.
values
readonly (number | undefined)[]
Values, from `c:val` or `c:yVal`.
xValues
readonly (number | undefined)[] | undefined
Horizontal values of a scatter or bubble plot, from `c:xVal`.
sizes
readonly (number | undefined)[] | undefined
Bubble sizes, from `c:bubbleSize`.
fill
DiagramColor | undefined
outline
DiagramOutline | undefined
invertIfNegative
boolean
`c:invertIfNegative`, a bar below zero drawn in the inverse of its fill.
pointFills
ReadonlyMap<number, DiagramColor>
`c:dPt`, one point painted differently from the rest of its series.
pointMarkers
ReadonlyMap<number, ChartPointMarker>
`c:dPt/c:marker`: the symbol one point carries where its series carries none. A survival curve marks its censored observations this way — the line says `c:symbol val="none"` and every censored point states a `plus` of its own — and drawn without them the chart loses the very thing it is about.
smooth
boolean
`c:smooth`, a line drawn as a spline rather than as segments.
marker
string | undefined
`c:marker/c:symbol`; `none` when the series asks for no marker.
categoryFormat?
string | undefined
`c:cat//c:formatCode`: how the cached category numbers are to be printed. Absent on the ordinary chart, whose categories are words. A date axis caches serial numbers and names the format beside them.
markerStyle
ChartPointMarker | undefined
`c:marker` whole: the symbol with the size and the paint stated beside it. A series states its markers once and its points may each restate them, so the two carry the same shape.
showValues
boolean
Whether the series asked for its values to be printed beside the marks.
labelledPoints?
ReadonlySet<number> | undefined
The points that carry a label of their own, where the series carries none. `c:dLbls` may delete the series' labels outright and then give three of its points a `c:dLbl` apiece, which is what PowerPoint writes when a label is dragged or typed over: the pies of `7317951-ICON-BITS` state `<c:delete val="1"/>` and label every slice. Undefined means the series' own answer covers every point.
customLabels?
ReadonlyMap<number, readonly string[]> | undefined
`c:dLbl/c:tx/c:rich`: what a point's label says, where somebody typed over it. One string per paragraph, with `{{VALUE}}`, `{{CATEGORYNAME}}` and the other fields left for the renderer to fill in. The text stands in for the value, and a point that carries one is labelled whether or not the series shows its values.
labelText?
ChartTextStyle | undefined
`c:dLbls/c:txPr`: the type the series' own labels are set in. A chart states its type on `c:chartSpace`, on an axis, or here — and here is the only place `aascu.org…` states it, so its values were drawn at the renderer's default of ten points against PowerPoint's fourteen.
showCategories?
boolean | undefined
`c:dLbls/c:showCatName`: the label says the point's category, not its value. Word's label is the concatenation of whatever `c:dLbls` turns on — series name, category, value, percentage — and a pie is the chart that usually turns the category on and the value off. `tdf137154` is eight slices of `long data label N` labelled that way, and reading only `c:showVal` drew the number behind each of them instead.
labelsStated?
boolean | undefined
Whether the series wrote a `c:dLbls` of its own. The plot's group is a default the series inherit, and a series that states its own is not one of them. `tdf137154` states both — the series asks for the category and not the value, the plot for the value and not the category — and merging the two labels every slice `long data label 8, 2`.
labelPosition?
string | undefined
`c:dLbls/c:dLblPos`: where the label sits against its point.
order
number
Order the series is drawn and listed in, `c:order`.
ChpxSpan
interface ChpxSpan

Character formatting for one stretch of the file.

fcStart
number
fcEnd
number
grpprl
Uint8Array<ArrayBufferLike>
ColorReference
interface ColorReference

A colour as DrawingML writes it: a source plus modifiers on it.

srgb
string | undefined
Literal `RRGGBB`, from `a:srgbClr`.
scheme
string | undefined
Theme slot, from `a:schemeClr`.
luminanceModulation?
number | undefined
`a:lumMod`, in thousandths of a percent.
luminanceOffset?
number | undefined
`a:lumOff`, in thousandths of a percent.
alpha?
number | undefined
`a:alpha`, in thousandths of a percent; absent means opaque.
shade?
number | undefined
`a:shade`, in thousandths of a percent.
tint?
number | undefined
`a:tint`, in thousandths of a percent.
saturationModulation?
number | undefined
`a:satMod`, in thousandths of a percent.
saturationOffset?
number | undefined
`a:satOff`, in thousandths of a percent.
hueModulation?
number | undefined
`a:hueMod`, in thousandths of a percent.
hueOffset?
number | undefined
`a:hueOff`, in sixtieths of a thousandth of a degree.
grayscale?
boolean | undefined
`a:gray`: painted in shades of grey.
inverted?
boolean | undefined
`a:inv`: every channel inverted.
ColumnDemand
interface ColumnDemand

One column, as the distribution needs to see it.

minContent
number
The narrowest the column may be without its content overflowing. CSS calls it the minimum content width; Word arrives at the same thing through `w:noWrap`, which asks for a cell "treated as though [its contents] have no breaking characters" and so raises this to the maximum.
maxContent
number
The width the content takes when only its explicit breaks are honoured.
constraint
ColumnConstraint
originates
boolean
Whether any cell begins in this column; a column of spans alone has none.
Columns
interface Columns
count
number
spaceTwips
number
separator
boolean
equalWidth
boolean
columns
readonly TextColumn[]
Comment
interface Comment

A comment from `comments.xml`.

id
string
author
string | undefined
initials
string | undefined
date
string | undefined
children
readonly BlockNode[]
parentId
string | undefined
Id of the comment this one replies to, from `commentsExtended.xml`.
resolved
boolean
CommentRangeNode
interface CommentRangeNode
kind
NodeKind.CommentRangeStart | NodeKind.CommentRangeEnd
id
string
CommentReferenceNode
interface CommentReferenceNode
kind
NodeKind.CommentReference
id
string
ComposeCacheStats
interface ComposeCacheStats

What a second composition of the same document need not do again. `composeDocument` turns a parsed document into what the layout engine takes, and for a document of a thousand pages that is the most expensive thing the viewer does after parsing: every run resolved through the style cascade, every family resolved through the substitution chain, every piece of text cut into the spans the line breaker works on. Doing it again after a keystroke changed one paragraph is doing it again for the other two hundred thousand. The cache is keyed on the **node object**, which is what makes it work at all: the edit layer replaces a node rather than mutating one — see `edit/tree.ts` — so after an edit every paragraph but the one that changed is the very same object it was, and identity answers "did this change?" exactly and in one comparison. ## What is not cached, and why that is not a compromise A composition is not a pure function of a paragraph. Three things carry state along the walk: - **a list's number**, which depends on every numbered paragraph before it; - **a footnote's mark**, which is counted from one over the document; - **a `LISTNUM` field**, which advances a counter of its own. A paragraph that touches any of them is composed afresh. That is not a limitation worked around but the honest reading of what those paragraphs are: their composition depends on their neighbours, so their composition cannot be reused when their neighbours may have moved. Everything else — which is the great majority of every document measured — is a function of the paragraph, the width it is set in and the margin it is set against, and those three are the key.

hits
number
Compositions answered from the cache.
misses
number
Compositions the cache had no answer for.
ineligible
number
Paragraphs the cache declined to hold; see the note above.
ComposedDocument
interface ComposedDocument

The blocks, the first section's page, and what is drawn on every page.

blocks
readonly BlockInput[]
nodeOfBlock
readonly (BlockNode | undefined)[]
The body node each composed block came from, where it came from one. The way back from the engine's numbering to the document's, and the only one there is. The two do not correspond: a section is announced as a block of its own, a paragraph broken over a page arrives as two, a content-block wrapper is flattened away and a marker is dropped — so the *n*th composed block is not the *n*th anything the reader could name. Nothing else can be reconstructed from the outside, and every caller that tried arithmetic instead got a wrong page or none: an outline is a list of paragraphs, and the question "which page is this paragraph on" has to be asked with the paragraph. Nothing for a block the engine was given rather than the body — a section, an endnote appended after the last of it.
setup
PageSetup
running
RunningInput
faces
Faces
The faces the caller's resolver returned, so it need not build them twice.
missing
ReadonlyMap<string, number>
What the walk left out, and how often, by its own name for it. A running head it cannot read is one entry here; there is nothing else it declines to compose. Empty over the whole corpus, and kept because a walk that silently drops a head moves every page of the document that has one.
ComposeOptions
interface ComposeOptions

What the caller has to supply because a pure function cannot know it.

faces
(context: { defaultFamily: () => string | undefined; }) => Faces
How a family name becomes something measurable. Called once, after the document's theme and default face are known — which is why it is a function and not a value: the resolution chain wants the document's own default as its next-to-last resort, and that default is not known until the theme has been read.
cache?
ComposeCache | undefined
Work kept from an earlier composition of the same document. What makes composing a document a second time cost a walk rather than a composition. Nothing is required and nothing changes without it; with it, a paragraph the edit layer did not replace is the same object it was and its composition is reused. See `layout/compose-cache.ts` for what is kept and what deliberately is not.
chartText?
((chart: ChartDefinition, widthPx: number, heightPx: number, themeColor: (slot: string) => string | undefined) => readonly ObjectGlyph[]) | undefined
Where a chart's words go, for a caller that can work it out. A chart is stored only as its definition, and turning one into places is what `@genomdev/office-core`'s chart drawing does — the scale, the room the ticks need, where that leaves the plot. That drawing is the browser half, and this engine is below it: dependencies point downwards. So the answer is *supplied*, exactly as {@link faces} supplies measurement, and `@genomdev/docx/view`'s `chartGlyphs` is the implementation a host passes. Without it a chart is a box with nothing in it, which is what this engine drew for the thirteen documents of the corpus that are a page and a chart. A host that *draws* the chart itself — the viewer paints the real thing, marks and all — leaves this unset: the words would then be drawn twice. It is for whoever reads the computed page as text: a comparison, an extractor, a search index.
hyphenates?
((language: string) => boolean) | undefined
Which of the document's languages may be hyphenated, where the caller knows. **Word hyphenates a language only where its proofing tools are installed**, and that is a property of the machine rather than of the file: the same document opened on two computers paginates differently. `auto-hyphenation-by-language` is the probe — the same four long words in six languages, in a column narrow enough that every line has to choose — and the Word that draws this corpus's references breaks the German, the English and the French and leaves the Portuguese, the Swedish and the Russian whole. The six `MSHY7*.LEX` modules beside it say which: EN, ES, FR, GE, IT, NL. Left unset, every language the patterns cover is hyphenated, which is what a viewer should do: a reader has no proofing tools to install, and the Word the author wrote in almost certainly had the module for the language he was writing. It is set by the *comparison*, which must ask this engine for the page the reference Word drew and not for the page Word ought to draw.
ComposeState
interface ComposeState

What one document's walk carries with it. Every field is settled once, from the document, before the first block is built; none of them changes because of anything the walk finds, except {@link ComposeState.sheet}, which follows the section in force. It is a parameter and not a module variable, and that is the difference between a tool and a package. The tool it came from wrote in as many words that it "reads one document at a time, and never two at once" — true of a corpus run, false of a viewer with two tabs open. Held in the module, the second document to start would take the first's page size halfway through.

sheet
{ heightPx: number; marginTopPx: number; marginBottomPx: number; widthPx: number; marginLeftPx: number; marginRightPx: number; }
The sheet the blocks being walked belong to, in pixels.
part?
string | undefined
The part the walk is inside, where it is not the document's own. A relationship id is resolved against the part that wrote it: `rId5` in `word/header1.xml` is a different picture from `rId5` in `word/document.xml`, and often no picture at all. The reader takes the part as an argument and defaults to the main one, so a header's letterhead looked up in `document.xml.rels` came back as nothing and drew a broken image at the corner of the sheet. Carried on the piece — see {@link PieceRef} — because whoever draws it is a long way from this walk by then.
numberingByName
Map<string, AbstractNumbering>
The document's abstract numbering by name, for a `LISTNUM` field.
noteCount
number
How many footnote references the walk has passed, and what number each got. Word numbers the marks from one over the document, in the order the references are met, and the note's own `w:footnoteRef` shows the same number. The tool this came from kept the count *on the map of notes* — a counter stashed on somebody else's object, which works exactly as long as one document is being read at a time.
noteNumbers
Map<string, number>
facesOfDocument
Faces | undefined
The faces of this document, for the script fallbacks that need to ask.
kinsokuOverrides
KinsokuOverrides
`w:kinsoku` and the document's own lists, memoised by language.
kinsokuSets
Map<string, KinsokuSet | undefined>
compressesJustified
boolean
`w:compat` and `w:settings`, read once; see where each is used.
wordWrapHonoured
boolean
Whether `w:wordWrap="0"` is honoured here; see where it is set.
gridCharTwips
number
What the section's character grid adds to every character, in twips.
keepsBreakLinesRagged
boolean
indentsToText
boolean
ideographWords
boolean
Whether a run of ideographs that follows a space is one word to the line breaker: Word 2007 and earlier, `compatibilityMode` 12 or none. See `LineSpan.ideographWords`.
compressesPunctuation
boolean
`w:characterSpacingControl` says `compressPunctuation` or `compressPunctuationAndJapaneseKana`: a mark may give back its blank half. Absent is `doNotCompress`, ECMA-376's default.
mathJustification?
string | undefined
`m:mathPr/m:defJc`, where the document states one; see `mathAlignmentOf`.
hyphenates
boolean
`w:autoHyphenation` and what goes with it. Word breaks a word at the foot of a line only where the document asks for it, in the language the *run* declares, and never in a paragraph that says `w:suppressAutoHyphens`. The zone is how much white it will leave at the right rather than break a word; the limit is how many lines in a row may end in a hyphen. See `Hyphenation` and where the pieces are built.
hyphenationZoneTwips
number
consecutiveHyphenLimit
number
hyphenatesCaps
boolean
kernsPunctuation
boolean
`w:noPunctuationKerning` the other way round; see `kernsPunctuation`.
languages
Set<string>
Every `w:lang` the walk saw, so the patterns can be fetched for them.
hyphenation
Hyphenation
The patterns themselves, which arrive after the walk and before the layout. A module per language and a dynamic import each, so they cannot be had while a piece is being built; the walk collects the languages, this object is handed to every `PageSetup` as it is made, and `composeDocument` fills it in before it returns. The engine is synchronous and asks it then.
fillHyphenation
(loaded: Hyphenation) => void
hyphenatesLanguage
(language: string) => boolean
{@link ComposeOptions.hyphenates}, or everything the patterns cover.
rulesTableLines
boolean
decimalSymbol
string
noExtraLineSpacing
boolean
suppressTopSpacing
boolean
underlinesTrailingSpace
boolean
`w:ulTrailSpace`: the spaces that end a line are underlined too.
spacesInTable
boolean
fixedAutoSpacing
boolean
splitsMarkAfterBreak
boolean
bookmarks?
ReadonlySet<string> | undefined
Every bookmark the body writes, gathered before a piece is built. `PAGEREF` needs it at composition and not at the end: a reference to a bookmark that is gone draws `Error! Bookmark not defined.`, and that is twenty-eight characters the line has to be measured with. Marked and resolved last like a page number, the tab before it would reach for a right stop with one character's width in hand, and the sentence would run past the stop.
styleIds?
ReadonlyMap<string, string> | undefined
Every style by the name a `STYLEREF` instruction may call it, lowercased. The instruction names the style as a reader does — `STYLEREF "Heading 1"` against a style whose id is `Heading1` — so both the name and the id are keys, and the comparison is case-blind because writers are not consistent about it.
resolveHyperlink?
((relationshipId: string) => string | undefined) | undefined
A hyperlink relationship's address; see where an empty link is shown.
chartOf?
((relationshipId: string, ownerPart?: string) => ChartDefinition | undefined) | undefined
A chart part, by the relationship id the drawing names it with. Loaded before anything is composed, so that a chart's text can be placed while the piece that holds it is built; see `chart-text.ts`.
themeColorOf?
((slot: string) => string | undefined) | undefined
The theme's answer for a colour slot, which the chart drawing asks for.
chartText?
((chart: ChartDefinition, widthPx: number, heightPx: number, themeColor: (slot: string) => string | undefined) => readonly ObjectGlyph[]) | undefined
{@link ComposeOptions.chartText}, carried to where the piece is built.
ConditionalFormatting
interface ConditionalFormatting

Which conditional table-style formats apply to a row, cell or paragraph. Word encodes this as a bit string in `w:cnfStyle`; the decoded flags are what the style resolver needs in order to layer `firstRow`, `band1Horz` and the rest on top of the base table style.

firstRow?
boolean | undefined
lastRow?
boolean | undefined
firstColumn?
boolean | undefined
lastColumn?
boolean | undefined
oddHorizontalBand?
boolean | undefined
evenHorizontalBand?
boolean | undefined
oddVerticalBand?
boolean | undefined
evenVerticalBand?
boolean | undefined
firstRowFirstColumn?
boolean | undefined
firstRowLastColumn?
boolean | undefined
lastRowFirstColumn?
boolean | undefined
lastRowLastColumn?
boolean | undefined
ContentBlockNode
interface ContentBlockNode

A grouping node produced by flattening a structured document tag. Content controls carry semantics (a date picker, a repeating section) that the viewer does not act on, but discarding the wrapper entirely would lose the tag name that documents and tooling rely on for navigation.

kind
NodeKind.ContentBlock
id
number
Identity, for as long as the document is open. What an edit names and what an incremental relayout compares. Not an index: inserting a paragraph renumbers every index after it and leaves every id alone, which is the entire reason this is here. See `model/ids.ts`.
tag
string | undefined
alias
string | undefined
controlId?
number | undefined
`w:sdtPr/w:id`: the control's own identity, a signed 32-bit number. Not {@link id} — that one is minted per read. This is written into the file and is what a data binding, a repeating section and Word's own document part gallery name the control by, so a control that comes back without it is a control nothing points at any more.
children
readonly BlockNode[]
ConvertContext
interface ConvertContext

What the converters need to know about the document around them.

fonts
readonly DocFont[]
The font table: character properties name a font by its index in it.
styleIdOf
(istd: number) => string | undefined
Style index to style identifier, which for these documents is its name.
CreateDocumentOptions
interface CreateDocumentOptions

A Word document, built from nothing. The shortest path from data to a `.docx`, and the reason the whole write side exists in the shape it does: ```ts const document = createDocument({ title: 'Quarterly report' }); document.heading('Quarterly report'); document.paragraph('Revenue rose by eleven per cent.'); document.table([ ['Region', 'Revenue'], ['North', '1 204'], ], { header: true }); await writeFile('report.docx', (await document.save()).bytes); ``` It is a thin arrangement over {@link EditSession}: every method builds nodes and puts them through a step, so a document being generated and a document being edited are the same object with the same undo, and code written against one works against the other. That is not symmetry for its own sake — the common real task is *neither* of them alone but both: open a template, fill in its content controls, append a table, save.

metadata?
DocumentMetadata | undefined
section?
SectionProperties | undefined
The section every page is set on; A4 with Word's own margins by default.
styles?
StyleSheet | undefined
The style table to write; the built-in set by default.
DiagramColorfrom @genomdev/office-core
interface DiagramColor
kind
"srgb" | "scheme" | "system"
`srgb` is literal, `scheme` refers to the theme, `system` to the host.
value
string
Hex digits, a theme slot name, or the last colour Word saw for a system slot.
transforms
readonly DiagramColorTransform[]
DiagramColorTransformfrom @genomdev/office-core
interface DiagramColorTransform

One transform applied to a colour, `a:lumMod` and its siblings. Kept as a list rather than resolved fields because the transforms compose in document order, and SmartArt relies on that: a colour list shifts hue, saturation and luminance together to spread one accent colour across the nodes of a diagram.

name
string
Local name, such as `lumMod`, `satOff`, `hueOff`, `alpha`, `tint`.
value
number
Percentages as a fraction; `hueMod` and `hueOff` in degrees.
DiagramDrawingfrom @genomdev/office-core
interface DiagramDrawing
shapes
readonly DiagramShape[]
DiagramFramefrom @genomdev/office-core
interface DiagramFrame

A position and size in EMU, with the rotation applied about its centre.

xEmu
number
yEmu
number
widthEmu
number
heightEmu
number
rotation
number
Clockwise rotation in degrees.
flipHorizontal
boolean
flipVertical
boolean
DiagramOutlinefrom @genomdev/office-core
interface DiagramOutline
color
DiagramColor | undefined
widthEmu
number | undefined
dash
string | undefined
`a:prstDash/@val`, such as `dash` or `sysDot`.
cap?
"round" | "square" | "flat" | undefined
`a:ln/@cap`: how the line ends, `rnd`, `sq` or flat.
join?
"round" | "bevel" | "miter" | undefined
`a:round`/`a:bevel`/`a:miter`: how two segments meet.
headEnd?
DiagramLineEnd | undefined
`a:headEnd` and `a:tailEnd`: what the line carries at each end. An arrow is the difference between a diagram that says "A causes B" and one that says the two are related: 185 lines of the corpus carry one, and drawn without it a flow chart loses its direction.
tailEnd?
DiagramLineEnd | undefined
DiagramParagraphfrom @genomdev/office-core
interface DiagramParagraph
align
"left" | "center" | "right" | "justify" | undefined
level
number
Outline level, `a:pPr/@lvl`; zero for a top-level paragraph.
bullet
string | undefined
`a:buChar/@char`, or undefined when the paragraph is not bulleted.
marginLeftEmu
number | undefined
indentEmu
number | undefined
First-line indent, negative for a hanging indent.
lineSpacing
number | undefined
`a:lnSpc/a:spcPct` as a fraction of a single line.
spaceBefore
number | undefined
`a:spcBef`/`a:spcAft` as a fraction of a line.
spaceAfter
number | undefined
runs
readonly DiagramRun[]
DiagramRunfrom @genomdev/office-core
interface DiagramRun

A run of text inside a diagram shape. Properties come from `a:rPr`.

text
string
bold
boolean
italic
boolean
underline
boolean
sizePoints
number | undefined
Size in points; `a:rPr/@sz` is in hundredths of a point.
color
DiagramColor | undefined
font
string | undefined
DiagramShapefrom @genomdev/office-core
interface DiagramShape
frame
DiagramFrame
preset
string
`a:prstGeom/@prst`, defaulting to `rect`.
adjust
ReadonlyMap<string, number>
Adjust values, `a:avLst/a:gd`, keyed by name and in their raw units.
fill
DiagramColor | undefined
Solid fill colour; undefined for `a:noFill` and for fills not yet read.
outline
DiagramOutline | undefined
text
DiagramTextBody | undefined
fontSlot?
"major" | "minor" | undefined
`dsp:style/a:fontRef/@idx`: the theme typeface of runs that name none.
fontColor?
DiagramColor | undefined
...and the colour `a:fontRef` gives them.
DiagramTextBodyfrom @genomdev/office-core
interface DiagramTextBody
frame
DiagramFrame
Where the text goes, `dsp:txXfrm`. Separate from the shape's own frame because a preset shape rarely gives its text the whole box: a chevron reserves the point, a callout the tail. Word writes the solved rectangle so the reader does not have to know the geometry of every preset.
anchor
"center" | "top" | "bottom"
insetLeftEmu
number
insetTopEmu
number
insetRightEmu
number
insetBottomEmu
number
paragraphs
readonly DiagramParagraph[]
DocBookmark
interface DocBookmark

A bookmark, in character positions.

name
string
start
number
end
number
DocFont
interface DocFont

A font as the document declares it.

name
string
alternateName
string | undefined
The font Word substitutes when this one is missing.
charset
number
Character set identifier, which is what says how eight-bit text decodes.
codePage
number | undefined
The code page implied by that character set.
family
string | undefined
Font family: roman, swiss, modern, script, decorative.
pitch
string | undefined
Fixed or variable pitch.
DocShape
interface DocShape

What a shape turns out to be.

spid
number
storeIndex
number | undefined
The picture it shows, as a place in the document's store.
textRange
readonly [number, number] | undefined
Or the text box story it shows, as a character range within that story.
look
ShapeLook | undefined
Or, failing both, how it is drawn.
rotation
number | undefined
Clockwise rotation in degrees.
name
string | undefined
The name the author gave it, which is what alt text usually is here.
description
string | undefined
hidden
boolean
The shape is not drawn at all.
group
{ readonly space: Rect; readonly members: readonly DocShape[]; } | undefined
The members of a group, and the coordinate space they are stated in. A group is anchored to the text as one shape and holds its members in a space of its own — often a hundred thousand units across, so that a member can be placed finely inside a box of any size on the page. Putting them down means mapping that space onto the rectangle the anchor gives, which is the whole of what a group is: 1,424 shapes of the corpus are inside one, and without the mapping every one of them is in the top-left corner.
childRect
Rect | undefined
Where a member sits inside its group's space.
DocumentFacesOptions
interface DocumentFacesOptions extends DocumentFonts
tables
ReadonlyMap<string, AdvanceCuts>
The advances the caller has loaded, by folded family name. Loaded rather than looked up, because loading is asynchronous and measuring is not: a document names two to five families, and {@link familiesNamedBy} says which before the walk starts.
embedded?
((family: string, bold: boolean, italic: boolean) => FaceMetrics | undefined) | undefined
A face read out of the document's own bytes, where it carries one. `w:embedRegular` and its three siblings. The best source there is — it is the very file the document was written against — and the only one that answers for kerning and for joined scripts, which no table of widths can.
shapedWidth?
((family: string, bold: boolean, italic: boolean, text: string, sizePx: number) => number | undefined) | undefined
The width of text whose letters join, from whoever can shape it. A table of advances holds the width of each character standing alone, and in Arabic that is not the width of the word: `GSUB` gives the letters initial, medial and final forms and the forms are narrower. Summed as isolates, `tdf104649` comes out at 66 pages against Word's 56 and `reports-cb3783573860` at four against three — the only two documents of 2062 that the tables move at all. So the one question the written advances cannot answer is asked of whoever can: the font program in Node, the browser's own shaper in a browser. It is the single place the two sides do not share a number, and it is a parameter so that the fact is visible rather than buried.
kernedWidth?
((family: string, bold: boolean, italic: boolean, text: string, sizePx: number) => number | undefined) | undefined
The width of text with the face's own kerning pairs applied. The second and last question the written advances cannot answer, and for the same kind of reason as the first: `kern` is thousands of pairs — 26 706 in Calibri, 29 715 in Cambria — and writing them down would be several megabytes of table to buy 99 lines of 171 739 and not one page count. Word kerns only at or above the size `w:kern` names, and 1303 of the corpus's 1672 documents name none. So it is asked of whoever has the font: the font program in Node, the browser's own `font-kerning` in a browser — which is the face it will actually draw with, and therefore the right answer for what the reader sees.
used?
Map<string, number> | undefined
How often each family was asked for, so a caller can report it.
missing?
Map<string, number> | undefined
What could not be resolved, and how often.
DocumentFonts
interface DocumentFonts

What the document itself knows about the faces it names.

shapeOf?
((family: string) => string | undefined) | undefined
`w:family`: `roman`, `swiss`, `modern`, `script` or `decorative`.
alternativeOf?
((family: string) => string | undefined) | undefined
`w:altName`: the name the file says this face may be drawn as.
ownDefault?
(() => string | undefined) | undefined
The document's own default face, as a thunk: the theme decides it.
DocumentGrid
interface DocumentGrid

A ruled page: `w:docGrid`, which lines snap to.

linePitchTwips
number
`w:linePitch`, in twips: the distance between two rules.
type?
string | undefined
`w:type`, which decides whether the page is ruled at all.
DocumentMedia
interface DocumentMedia

What a document exposes about the pictures it holds outside a package.

pictures
() => Iterable<DocumentPicture>
Every picture, for a save that has to carry them all.
DocumentPartInput
interface DocumentPartInput
blocks
readonly BlockNode[]
finalSection
SectionProperties | undefined
The section that closes the body, `w:body/w:sectPr`.
background?
DocumentBackground | undefined
`w:background`: the colour behind every page, which stands before the body.
DocumentPicture
interface DocumentPicture

The pictures a document holds, and how they reach a package being written. A `.docx` saved back to a `.docx` needs none of this: the media parts are in the package already and are copied through as the compressed bytes they were. Two cases are not that: - **`.doc` converted to `.docx`.** The pictures live in the binary file's own store, keyed by names like `doc-picture-3`, and the package being written has no such parts and no relationships pointing at them. Without this, the drawings are written referring to relationships that do not exist — which Word draws as an empty frame with a red cross, and which no comparison of the extracted *text* would ever notice. - **a picture a caller added**, which has bytes and nothing else. The contract is deliberately small: name the pictures, and hand over the bytes of one. Everything else — the part name, the extension, the content type, the relationship — is the writer's arithmetic.

id
string
The id a drawing's `r:embed` names it by.
mimeType
string
bytes
Uint8Array<ArrayBufferLike>
DocumentSettings
interface DocumentSettings

Selected values from `settings.xml` that affect rendering.

defaultTabStopTwips
number
Default tab stop interval in twips, `w:defaultTabStop`.
evenAndOddHeaders
boolean
Even and odd pages use different headers, `w:evenAndOddHeaders`.
autoHyphenation
boolean
Automatic hyphenation is enabled for the document.
characterSpacing?
string | undefined
`w:characterSpacingControl`: how far East Asian punctuation may be squeezed. `compressPunctuation` — the default, and what Word writes unless told otherwise — lets a line take back the blank half of a full-width mark when it needs the room; `doNotCompress` keeps it. See `Piece.squeezableEm`.
consecutiveHyphenLimit
number | undefined
hyphenationZoneTwips
number | undefined
doNotHyphenateCaps
boolean
`w:doNotHyphenateCaps`: leave words written in capitals whole. Word's own default is to hyphenate them, and the checkbox in the hyphenation dialog is the other way round from this element.
noPunctuationKerning
boolean
`w:noPunctuationKerning`: two adjacent full-width marks keep their own ems. Word kerns them into one half em between the inks unless this says not to, and it only ever kerns a run that asks to be kerned at all — see `kernsPunctuation` in `layout/line-break.ts`.
mirrorMargins
boolean
Mirror margins for double-sided printing, `w:mirrorMargins`.
trackRevisions
boolean
Whether tracked changes are being recorded.
footnoteNumberStart
number | undefined
Starting number of footnotes and endnotes.
endnoteNumberStart
number | undefined
footnotePosition
string | undefined
Where footnotes are placed, `w:footnotePr/w:pos`.
endnotePosition
string | undefined
footnoteNumberFormat
string | undefined
`w:numFmt`: what the note marks are numbered with, document-wide.
endnoteNumberFormat
string | undefined
footnoteRestart
string | undefined
`w:numRestart`: continuous, each page, or each section.
endnoteRestart
string | undefined
compatibility
ReadonlyMap<string, string>
Compatibility flags that change layout, `w:compat`. The lookup the layout engine asks, and derived rather than read: the flags of `w:compat` and the `w:compatSetting`s beside them, merged by name, because `compatibilityMode` is a setting and `noExtraLineSpacing` is a flag and a caller asking "what does this document say about spacing" should not have to know which is which. What is written back comes from {@link compatibilityFlags} and {@link compatibilitySettings}.
strictFirstAndLastChars
boolean
`w:strictFirstAndLastChars`: the strict kinsoku pair for Japanese. The default Japanese list does not hold the small kana back from beginning a line and the strict one does — which is why a probe asked of a document without this setting saw Word let `っ` open a line. See `layout/kinsoku.ts`.
noLineBreaksBefore
ReadonlyMap<string, string>
`w:noLineBreaksBefore`: the characters this document will not begin a line with, by the `w:lang` each element names. Supersedes the standard's list.
noLineBreaksAfter
ReadonlyMap<string, string>
`w:noLineBreaksAfter`, likewise, for the characters that may not end one.
decimalSymbol
string | undefined
Character used as the decimal separator in fields.
listSeparator
string | undefined
documentProtection
string | undefined
The document is protected; the viewer surfaces this as read-only.
colorSchemeMapping
ReadonlyMap<string, string>
Which theme slot each document colour slot actually names, `w:clrSchemeMapping`. A document says `w:themeColor="text1"` and the theme has no `text1`: it has `dk1`, `lt1`, `dk2` and `lt2`, and this element is the map between them. The identity mapping is the common case, which is why an implementation without it looks right — until a document swaps them, as every template with a dark background does, and then every heading is painted in the colour of the paper it stands on.
themeFontLanguages
{ latin: string | undefined; eastAsia: string | undefined; complex: string | undefined; } | undefined
The languages the theme's font slots are chosen for, `w:themeFontLang`. Word resolves `minorHAnsi` differently depending on which of the three scripts the run is in, and this is what says which language each script is.
bordersSurroundHeader
boolean
Page borders are drawn around the header and the footer as well as the body. `w:bordersDoNotSurroundHeader` and `w:bordersDoNotSurroundFooter`, inverted so that the field reads as what happens rather than as what does not. Word's default is that the border does surround them.
bordersSurroundFooter
boolean
displayBackgroundShape
boolean
`w:displayBackgroundShape`: whether `w:background` is painted at all.
simple
ReadonlyMap<string, string>
Every child of `w:settings` whose whole content is a `w:val`, by name. Two thirds of `CT_Settings` is switches of exactly this shape — an element that is on by being present — and a field apiece would be sixty fields no reader of this library would ever name. The map keys are element names and the values are what `w:val` said, or the empty string for an element written bare. `w:compat` has been read this way since it was first read at all; this is the same decision one level up. A setting that gets a field of its own is not in here: the parser routes each name once. Extension elements are keyed by their prefix, `w15:docId`.
zoom
{ readonly value?: string; readonly percent?: string; } | undefined
`w:zoom`: what the document opens at.
proofState
{ readonly spelling?: string; readonly grammar?: string; } | undefined
`w:proofState`: how far the spell- and grammar-checker had got.
attachedTemplate
string | undefined
`w:attachedTemplate/@r:id`: the relationship naming the template.
documentProtectionSettings
ReadonlyMap<string, string> | undefined
`w:documentProtection`, whole. The `edit` attribute alone is in {@link documentProtection}, which is what the viewer asks. This is the element as written, hash and salt included — a save that dropped the hash would unprotect the document.
writeProtection
ReadonlyMap<string, string> | undefined
`w:writeProtection`: the password to modify, and whether to recommend it.
stylePaneFilter
ReadonlyMap<string, string> | undefined
`w:stylePaneFormatFilter`: which styles the pane offers.
activeWritingStyles
readonly ReadonlyMap<string, string>[]
`w:activeWritingStyle`: a grammar checker registered per language.
documentVariables
ReadonlyMap<string, string>
`w:docVars`: named variables a field or a macro reads.
mathProperties
ReadonlyMap<string, string> | undefined
`m:mathPr`: how equations are set. The same shape as {@link simple} and for the same reason: sixteen children, every one of them a `m:val`, none of which this engine lays out.
attachedSchemas
readonly string[]
`w:attachedSchema`: the custom XML schemas the document declares.
footnoteSeparators
readonly number[]
`w:footnotePr/w:footnote/@w:id`: the notes that are separators, not notes.
endnoteSeparators
readonly number[]
shapeDefaults
ShapeDefaults | undefined
`w:shapeDefaults` and `w:hdrShapeDefaults`: the VML drawing defaults.
headerShapeDefaults
ShapeDefaults | undefined
smartTagTypes
readonly ReadonlyMap<string, string>[]
`w:smartTagType`: the smart-tag vocabularies the document declares.
mailMerge
MailMerge | undefined
`w:mailMerge`: the data source a merge document is bound to.
compatibilityFlags
ReadonlyMap<string, string>
`w:compat`'s own children, as against the `w:compatSetting`s beside them.
compatibilitySettings
readonly CompatibilitySetting[]
`w:compatSetting`: a named setting with the namespace that defines it.
DocxDocument
interface DocxDocument extends GenomDocument

A parsed Word document. Everything needed to render, search or convert the document, and nothing that depends on how it will be displayed. Headers, footers, footnotes and comments are loaded lazily: a document may carry dozens of header parts of which a given rendering uses two.

format
"docx" | "doc"
`docx`, or `doc` for the binary generation. Word 97-2003 is read into this same model rather than converted into an OOXML package first, so a document of either generation is one of these and the viewer, the extractor and the addressing scheme need no branch for it. The format is still reported truthfully, because a caller choosing a renderer, naming a download or reporting a failure does need to know.
kind
"text-document"
metadata
DocumentMetadata
body
readonly BlockNode[]
Body content in document order.
finalSection
SectionProperties
Section properties of the final section, `w:body/w:sectPr`.
styles
StyleSheet
numbering
NumberingDefinitions
settings
DocumentSettings
background
DocumentBackground | undefined
`w:background`: the colour behind every page. A sibling of `w:body` rather than a property of a section, because it is the document's and not the page's. Whether it is painted at all is `w:displayBackgroundShape` in the settings — Word writes the colour into every document saved from a template with one and paints it only for the screen unless told otherwise.
theme
Theme | undefined
fonts
readonly FontDefinition[]
styleResolver
StyleResolver
The style resolver bound to this document. On the interface and not only on the class that implements it: composing a document for the layout engine needs it, and that composition is part of the package rather than of one implementation. Declaring it here is what says the document *has* a resolver, rather than that one particular reader happens to expose one.
loadHeader
(relationshipId: string) => Promise<HeaderFooter | undefined>
Loads a header part by relationship id.
loadFooter
(relationshipId: string) => Promise<HeaderFooter | undefined>
loadFootnotes
() => Promise<ReadonlyMap<string, Note>>
Footnotes keyed by id; parsed on first access.
loadEndnotes
() => Promise<ReadonlyMap<string, Note>>
loadComments
() => Promise<ReadonlyMap<string, Comment>>
detach
() => Promise<void>
Stops the document depending on the file it was opened from. Everything this library models is already a value — no node refers to any byte — but the parts it does not model are read from the source on demand: the theme, the pictures, the macro project, whatever an application put in `customXml`. Calling this reads the source once and holds it, after which the document can be saved, drawn and searched with the original gone. Not done at open time on purpose: most callers open a document, draw it and drop it, and reading the whole file for that is a cost with nothing on the other side of it.
detached
boolean
Whether {@link detach} has been called and the source is no longer needed.
loadDiagram
(dataRelationshipId: string, ownerPart?: string) => Promise<DiagramDrawing | undefined>
Loads the shapes Word laid out for a SmartArt diagram, by its data part id.
diagram
(dataRelationshipId: string, ownerPart?: string) => DiagramDrawing | undefined
Returns a diagram already loaded, for use during synchronous rendering.
preloadDiagrams
(blocks: readonly BlockNode[], ownerPart?: string) => Promise<void>
Loads every diagram reachable from a set of blocks.
loadChart
(relationshipId: string, ownerPart?: string) => Promise<ChartDefinition | undefined>
Loads a chart part by the relationship id the drawing names it with.
chart
(relationshipId: string, ownerPart?: string) => ChartDefinition | undefined
Returns a chart already loaded, for use during synchronous rendering.
preloadCharts
(blocks: readonly BlockNode[], ownerPart?: string) => Promise<void>
Loads every chart reachable from a set of blocks.
resolveImage
(relationshipId: string, ownerPart?: string) => Promise<string | undefined>
Resolves a relationship id into an image URL.
resolveImageSvg?
((relationshipId: string, ownerPart?: string) => Promise<string | undefined>) | undefined
The same picture as an SVG the document can hold, where that is better. Answers `undefined` for a picture that is a picture; see the implementation.
resolveHyperlink
(relationshipId: string, ownerPart?: string) => string | undefined
Resolves a hyperlink relationship id into a URL.
outline
() => readonly OutlineEntry[]
Headings of the document, for a navigation pane.
bookmarks
() => ReadonlyMap<string, number>
Bookmark name → index of the block that contains it.
DrawingNode
interface DrawingNode

An image or shape produced by DrawingML, `w:drawing`.

kind
NodeKind.Drawing
relationshipId
string | undefined
Relationship id of the embedded image, `r:embed`.
linkRelationshipId
string | undefined
Relationship id of a linked (external) image, `r:link`.
widthEmu
number | undefined
heightEmu
number | undefined
description
string | undefined
Alt text for accessibility.
name
string | undefined
placement
"inline" | "anchor"
`inline` flows with text; `anchor` is positioned and wrapped.
wrap
DrawingWrap | undefined
Text wrapping mode of an anchored drawing.
rotation
number | undefined
Clockwise rotation in degrees.
flipHorizontal
boolean | undefined
flipVertical
boolean | undefined
crop
{ left: number; top: number; right: number; bottom: number; } | undefined
Source rectangle crop, as fractions of the image size.
pictureEffects?
PictureEffects | undefined
What `a:blip` does to the picture's pixels before it is drawn; see {@link PictureEffects}.
textBox
readonly BlockNode[] | undefined
Content of a drawing that holds a text box rather than a picture.
diagramDataId
string | undefined
Relationship id of a SmartArt data part, `dgm:relIds/@r:dm`. The shapes are not in this part; it is only the handle from which they can be reached, so it is kept rather than the drawing itself, which lives in a separate part and is loaded on demand.
diagramLayoutId?
string | undefined
The other three parts `dgm:relIds` names: layout, style and colours. Nothing reads them — the shapes a viewer draws come through the data part — and they are kept because `dgm:relIds` requires all four attributes. A SmartArt frame written with the data part alone is a frame Word reports as corrupt, so a reader that keeps one id can preserve a diagram it opens and not one it writes.
diagramStyleId?
string | undefined
diagramColorsId?
string | undefined
chartId
string | undefined
Relationship id of the chart part, `c:chart/@r:id`. A chart is stored only as its definition, so this is the whole of what the drawing says about it: the frame's size, and the part that fills it.
effectExtent
{ left: number; top: number; right: number; bottom: number; } | undefined
Space reserved around the drawing for its effects, `wp:effectExtent`, in EMU. Word adds it to the extent when it reserves room in the flow, so a drawing with an effect extent starts that far inside the box the paragraph gave it.
shape
ShapeStyle | undefined
Fill, outline and geometry of a shape, `wps:spPr` composed with `wps:style`.
isGroupFrame?
boolean | undefined
The box a group keeps for itself, holding no content of its own. A group's members are placed absolutely inside it, so none of them reserves the space the drawing occupies or gives the text something to flow around. This node does both, and draws nothing: it is the group's frame, not a picture that failed to load.
groupMembers?
number | undefined
How many of the nodes after this frame are its members. A group is read into a flat list — the frame and then its shapes — and the view needs to know where the group ends to put the shapes back inside it. An inline group has to: its members are placed against the group's own box, and the group only knows where that is once the text has flowed.
sizeRelH?
RelativeSize | undefined
`wp14:sizeRelH` and `wp14:sizeRelV`: the extent stated as a share of something else. A banner across the top of a page is written this way — "one hundred per cent of the margin" — and the `wp:extent` beside it is the size Word happened to draw last, not the size it means. Dropping them turns a shape that follows the page into one that is frozen at whatever width the page was when it was saved. Named after the elements and not expanded, because the obvious expansion is taken: `wp:anchor/@relativeHeight` is the drawing's **z-order**, on the same element, and a field called `relativeHeight` meaning a share of the page is a trap laid for the next reader.
sizeRelV?
RelativeSize | undefined
anchorId?
string | undefined
`wp14:anchorId` and `wp14:editId`: Word's own identity for the anchor. Eight hex digits apiece, the same kind of thing as a paragraph's `w14:paraId` — written into the file, meaningful across it, and not to be confused with anything this library mints.
editId?
string | undefined
layoutInCell?
boolean | undefined
`wp:anchor/@layoutInCell`: the object is placed inside the cell it is in. Off, it floats against the page and the table is laid out as if it were not there. Word writes it on every anchor; it is read and held rather than drawn, because this engine places an anchored object against the column it is in either way.
pictureName?
string | undefined
`pic:cNvPr/@name`: what the author called the picture inside the frame. Not {@link name}, which is `wp:docPr/@name` — the *drawing's* name, one level up. The format gives the same attribute name to two elements of one anchor, and a single field called `name` would mean whichever the last reader thought. See `tools/spec/names.mjs`.
properties
RunProperties
DrawingWrap
interface DrawingWrap
type
"none" | "square" | "tight" | "through" | "topAndBottom"
outline?
readonly WrapPoint[] | undefined
`wp:wrapPolygon`: the outline the text follows instead of the box. Present only under `wp:wrapTight` and `wp:wrapThrough`, and written in a square of 21 600 units mapped onto the drawing's extent — the same space VML's `wrapcoords` uses, which [MS-OI29500] §2.1.1790 ww states outright for that attribute. Values reach outside the square: a picture whose polygon runs from −284 to 21 600 wraps a little wider than it is drawn. Word writes one for every tight-wrapped drawing, and for most of them it traces the bounding box and says nothing new. It is the other kind that matters: of the corpus's 49 documents with a polygon, 16 carry one that is not a rectangle, and there the text goes into the shape's concavities.
side
"both" | "left" | "right" | "largest" | undefined
offsetXEmu
number | undefined
offsetYEmu
number | undefined
relativeFromH
string | undefined
relativeFromV
string | undefined
alignH
string | undefined
alignV
string | undefined
behindText
boolean
zIndex
number | undefined
distanceTopEmu
number
Distance Word keeps between the drawing and the text beside it, in EMU. `distL` and `distR` default to a tenth of an inch for a wrapped drawing — twelve pixels, not the nine a reader would get by rounding an eighth. Three pixels sounds like nothing until every line beside every figure starts three pixels off.
distanceBottomEmu
number
distanceLeftEmu
number
distanceRightEmu
number
EditOptions
interface EditOptions

A document open for editing. The public shape is the ordinary one — `edit.paragraph(id).setText(...)`, `edit.undo()`, `edit.save()` — and underneath every one of those is a step over an immutable tree. The two halves are worth stating separately because choosing them together is the whole design: **Why the surface is mutable-looking.** Anyone who has written this kind of code before has written it against Aspose, DocIO or python-docx, and in all three a document is an object you change. A functional surface — `document = edit(document, step)` — is honest and nobody wants it for generating a report: it turns four lines into fourteen and every one of them threads a variable. **Why the inside is not.** Undo, redo, knowing what changed, replaying an edit that arrived from somewhere else, and re-laying out only the paragraphs that moved are five different things and they are all the same thing: they need the version before and the version after to both exist. A tree that was mutated has only one. The reference a caller holds is a {@link ParagraphRef}, which is an id and not a node. It never goes stale: the node it names is looked up in the current version each time, so an edit somewhere else does not invalidate it — and neither does an edit to the paragraph itself.

ids?
NodeIds | undefined
Where new identities come from; defaults to the document's own minter.
EmbeddedFontReference
interface EmbeddedFontReference
type
"regular" | "bold" | "italic" | "boldItalic"
relationshipId
string
fontKey
string | undefined
Obfuscation key; embedded fonts are XOR-scrambled with it.
FaceMetrics
interface FaceMetrics

A face, as far as placing text on a page is concerned.

family?
string | undefined
The family these numbers were actually taken from. Not always the one the run names. A document may name a face nobody has — `tdf157096` is set in `Noto Sans`, which this machine has never had — and the widths then come from whatever the substitution chain settled on. A painter that names the *document's* family in its CSS hands the browser a font it cannot find, and the browser answers with its own default: the page is drawn in a serif at widths measured on a sans, and every run of every line stands at an abscissa its own glyphs do not reach. So the face says what it is, and the painter names *that*. It is the same rule the whole of this engine rests on — one measurement, one source — applied to the last step, where the browser finally draws something. Absent where the caller cannot say.
ascent
number
Ascent above the baseline, as a fraction of the em.
descent
number
Descent below it, positive, as a fraction of the em.
lineGap
number
The gap the font asks for above the ascent, as a fraction of the em.
widthOf
(text: string, sizePx: number) => number
The width of a string at a given size, in the same units as the size.
covers?
((code: number) => boolean) | undefined
Whether the face has a glyph for a code point at all. Not the same question as its width. A face asked for a character it does not have answers with `.notdef` — half an em in Calibri — and a line measured on that is a line of a face nobody will draw in: Word substitutes another face for the character, and the substitute is a different width. `zh-98a5dfd0b39a` came to hold twice the text a line of it should for exactly this reason. Absent where the caller cannot say, in which case whoever asks must treat every character as covered.
kernedWidthOf?
((text: string, sizePx: number) => number) | undefined
The same with the face's own kerning pairs applied. Word kerns above the size `w:kern` names, and 369 of the corpus's 1672 documents name one. Absent where the caller cannot kern, in which case {@link TextPiece.kerns} is ignored.
math?
MathConstants | undefined
What the face states about setting mathematics, divided by its em. Absent for the great majority of faces, which carry no `MATH` table; `layout/math-box.ts` falls back to the classical numbers for those.
Faces
interface Faces
of
(family: string | undefined, bold: boolean, italic: boolean) => FaceMetrics | undefined
The face a run is set in, or nothing where the machine has none.
genericOf?
((family: string | undefined) => string | undefined) | undefined
The CSS generic the document's `w:fontTable` puts this family on, if any. Nothing to do with measuring — the engine never reaches a generic, because a generic has no advances. It is for the painter, whose browser may not have the face the engine measured with; see `cssGenericFor`.
Fib
interface Fib
nFib
number
Format version. 193 and up is Word 97; below 105 is Word 6/95.
isOldFormat
boolean
Word 6.0 or Word 95 rather than Word 97. Three things change with it: two extra reserved longs before the story sizes, bin table entries of two bytes rather than four, and — the one that cannot be worked around — property modifiers with single-byte opcodes. The first two are read; the third is why formatting is not.
lid
number
Language the document was written in, used when nothing names a code page.
isTemplate
boolean
The document is a template (`.dot`).
isComplex
boolean
The text is stored in pieces rather than as one run.
isEncrypted
boolean
The document is encrypted or obfuscated; nothing below it can be read.
tableStreamName
"0Table" | "1Table"
Which table stream this save wrote: `1Table` when set, `0Table` when not.
fcMin
number
Where the text starts in `WordDocument`, for a document with no piece table.
fcMac
number
ccpText
number
Character counts, story by story. They partition the text end to end.
ccpFtn
number
ccpHdd
number
ccpAtn
number
ccpEdn
number
ccpTxbx
number
ccpHdrTxbx
number
pairs
readonly FcLcb[]
The (offset, length) pairs, indexed by {@link Fc}.
FieldNode
interface FieldNode

A field: `PAGE`, `NUMPAGES`, `TOC`, `REF`, `HYPERLINK`, and so on. Both the simple form (`w:fldSimple`) and the complex form (a `w:fldChar` begin/separate/end sequence) are normalised into this single node, because the distinction is a serialisation detail that no consumer should have to know about. `result` holds the text Word last computed, which is what gets displayed for any field the viewer does not evaluate itself.

kind
NodeKind.Field
instruction
string
The full instruction text, e.g. `PAGE \\* MERGEFORMAT`.
fieldType
string
Field type in upper case, e.g. `PAGE`; the first token of the instruction.
result
readonly InlineNode[]
Cached result as computed by Word.
instructionFields?
readonly FieldNode[] | undefined
Fields written inside this field's *instruction*, in the order they appear. `IF <STYLEREF CharPartNo> = 0 "..." "..."` is an argument, not something to draw, so the instruction keeps its place with a marker — `U+0001`, the index, `U+0001` — and the field itself is kept here. A consumer that evaluates the outer field can then put the right one back; one that does not can ignore both, which is what the instruction text alone would have given it anyway.
properties
RunProperties
form?
{ readonly checkBox?: { readonly checked: boolean; readonly sizeHalfPoints?: number; }; } | undefined
`w:fldChar/w:ffData`: what a legacy form field is, where the field is one. Only the check box is read. Its result is empty in the file — Word draws the box itself — so without this a form of `FORMCHECKBOX` fields is a form of gaps.
FloatBox
interface FloatBox

A rectangle on the page, in points from the top-left of the text area.

top
number
bottom
number
left
number
right
number
outline?
readonly { readonly x: number; readonly y: number; }[] | undefined
`wp:wrapPolygon`: the outline the text follows instead of the rectangle. Points in a square of 21 600 units mapped onto the box, which is how Word writes them and how VML's `wrapcoords` is read ([MS-OI29500] §2.1.1790 ww). They are not clamped to that square — a polygon may reach outside the drawing it belongs to, and Word lets it. A box with an outline still obstructs the same *rows*; what changes is how far into each row it reaches. A triangle takes the whole width of the line that crosses its base and almost none of the line that crosses its apex, and text set against its rectangle loses that room on every line but one.
outlineLeft?
number | undefined
The drawing's own left edge and width, which the outline is measured against. `left` and `right` above are the *gapped* box — the drawing plus the room `distL` and `distR` keep beside it — and the polygon is written against the drawing alone. Keeping the drawing's own span here is what lets the gap be put back on afterwards: the outline is narrowed to the line and then widened by whatever the two edges differ by, which is the gap.
outlineWidth?
number | undefined
FontDefinition
interface FontDefinition

A font declared in `fontTable.xml`.

name
string
family
string | undefined
pitch
string | undefined
Pitch: `fixed`, `variable` or `default`.
altName
string | undefined
Fonts Word will substitute if this one is unavailable.
charset
string | undefined
`w:charset` value, needed to interpret symbol fonts.
characterSet
string | undefined
`w:charset/@w:characterSet`: the IANA name of the same character set. Written beside the numeric one by Word itself — `w:val="80"` and `w:characterSet="SHIFTJIS"` are the same statement twice — and kept because a producer that writes only the name has said the same thing.
panose
string | undefined
`w:panose1`: the face's own description, as twenty hex digits. Ten numbers — family kind, serif style, weight, proportion, contrast, stroke variation, arm style, letterform, midline, x-height — and what Word matches against the machine's fonts when the named one is missing.
notTrueType
boolean
`w:notTrueType`: the face is not a TrueType font. Which is to say it is a bitmap or a printer font, and Word will not embed it, scale it smoothly or hint it. Almost nothing is any more; the flag is still written by converters of documents that once were.
signature
ReadonlyMap<string, string> | undefined
`w:sig`: which Unicode ranges and code pages the face covers. Four `usb` words for the Unicode subsets and two `csb` for the code pages, as hex. It is what Word matches when it has to find a face that can draw a character the named one cannot, so a document that loses it loses the fallback the author's machine would have chosen.
embedded
readonly EmbeddedFontReference[]
Embedded font references keyed by style.
FontReference
interface FontReference

The four script slots Word resolves a font family from.

ascii
string | undefined
Font for Latin text.
hAnsi
string | undefined
Font for high-ANSI text; usually equal to `ascii`.
eastAsia
string | undefined
Font for East Asian text.
cs
string | undefined
Font for complex-script text, which includes Arabic and Hebrew.
asciiTheme
string | undefined
Theme slots: `minorHAnsi`, `majorHAnsi`, and so on.
hAnsiTheme
string | undefined
eastAsiaTheme
string | undefined
csTheme
string | undefined
hint
"default" | "eastAsia" | "cs" | undefined
How the font of a symbol run is chosen, `w:hint`.
FontSlotContext
interface FontSlotContext

What the run says about itself, as far as the slot is concerned.

hint?
string | undefined
`w:rFonts/@w:hint`, which decides the ambiguous blocks.
complexScript?
boolean | undefined
`w:cs` — the run is set in a complex script.
rtl?
boolean | undefined
`w:rtl` — the run runs right to left.
eastAsianLanguage?
string | undefined
`w:lang/@w:eastAsia`, for the clauses that name Chinese.
eastAsia?
string | undefined
`w:rFonts/@w:eastAsia`, for the Times New Roman rule.
ascii?
string | undefined
`w:rFonts/@w:ascii`.
hAnsi?
string | undefined
`w:rFonts/@w:hAnsi`.
FrameProperties
interface FrameProperties
widthTwips
number | undefined
heightTwips
number | undefined
`w:h`, where the frame states one; a height of nought is no height stated.
heightRule?
"auto" | "exact" | "atLeast" | undefined
`w:hRule`, defaulted the way Word defaults it. [MS-OI29500] §2.1.45(f): `atLeast` where a height is stated and `auto` where none is, rather than the `auto` the standard names in both cases.
lines?
number | undefined
`w:lines`: how many lines of the paragraph the frame is drawn around.
horizontalAnchor
string | undefined
`w:hAnchor` and `w:vAnchor`, both defaulting to `text`. The standard says `page` for either; [MS-OI29500] §2.1.43 e and g say Word uses `text`, which is the difference between a frame beside its paragraph and one in the corner of the sheet. (§2.1.45 is `w:jc`; the citation here named it for a while and was wrong.)
verticalAnchor
string | undefined
x
number | undefined
y
number | undefined
xAlign
string | undefined
yAlign
string | undefined
wrap
string | undefined
dropCap
string | undefined
`w:dropCap`: `drop` or `margin` for an initial the text runs beside.
horizontalSpaceTwips
number | undefined
`w:hSpace`: what the frame keeps between itself and the text beside it.
HeaderFooter
interface HeaderFooter

A header or footer part.

relationshipId
string
partName
string
children
readonly BlockNode[]
HeaderFooterReference
interface HeaderFooterReference

A header or footer reference, `w:headerReference` / `w:footerReference`.

relationshipId
string
type
"first" | "default" | "even"
HorizontalOrigins
interface HorizontalOrigins

The places a horizontal anchor may be counted from, in points across the sheet.

page
number
The left edge of the sheet, nought by definition and named for clarity.
margin
Span
The text area: its left edge and its right.
column
Span
The column the anchor is in, which is the text area outside a multi-column section.
sheetRight?
number | undefined
The right edge of the sheet, where the caller knows it. `relativeFrom="page"` with `wp:align="right"` puts a drawing against the paper's edge, not the text's: `es-1fb59f6f5ac1` hangs a full-page letterhead that way and it stood the right margin's width to the left, the crest cut off and a white strip down the sheet. Absent, the page's right is taken as the text area's, which is what every caller said before.
HyperlinkNode
interface HyperlinkNode
kind
NodeKind.Hyperlink
relationshipId
string | undefined
Relationship id pointing at an external URL.
anchor
string | undefined
Bookmark name for an internal link.
tooltip
string | undefined
children
readonly InlineNode[]
InlinePicture
interface InlinePicture

A picture placed in the text, as the character that stands for it says. Word puts one character in the flow — `0x01` — and everything about the picture is somewhere else: a modifier on the character gives an offset into the `Data` stream, and at that offset is a header saying how big the picture is, followed by a drawing container holding the picture itself. The size is two numbers, not one. `dxaGoal` is the picture's natural size and `mx` is what the author scaled it to, so a photograph dragged to half its size has an unchanged `dxaGoal` and an `mx` of five hundred. Using the first alone puts every resized picture on the page at the size it was before somebody resized it.

location
number
Where in the `Data` stream this was found, which is how a run names it.
widthTwips
number
Displayed width in twips: the natural size with the author's scaling applied.
heightTwips
number
crop
{ left: number; top: number; right: number; bottom: number; } | undefined
Cropping as fractions of the picture, from the shape's own properties.
picture
StoredPicture | undefined
The picture, when it is stored inside the container.
storeIndex
number | undefined
Or its place in the document's store, when the shape names one instead.
look
ShapeLook | undefined
Or how it is drawn, when it is not a picture at all. The character that stands for a picture also stands for a *shape* placed in the line — a grey rectangle, a rule, a coloured panel — with the same header in front of it and a shape container instead of a picture behind. A reader that insists on finding bytes there finds none and drops the shape.
KinsokuOverrides
interface KinsokuOverrides

What a document says in `settings.xml` about the sets.

strict?
boolean | undefined
`w:strictFirstAndLastChars`, which changes the Japanese pair.
noStart?
ReadonlyMap<string, string> | undefined
`w:noLineBreaksBefore`, by the `w:lang` it names.
noEnd?
ReadonlyMap<string, string> | undefined
`w:noLineBreaksAfter`, likewise.
KinsokuSet
interface KinsokuSet

One language's two lists.

noStart
ReadonlySet<string>
Characters that may not begin a line — Word's "first characters".
noEnd
ReadonlySet<string>
Characters that may not end one — Word's "last characters".
LayoutOptions
interface LayoutOptions

What a caller may ask of a layout beyond its blocks. All three are about *not holding the whole document at once*. A page of dense text is some hundreds of lines and some thousands of spans; a thousand pages of it is millions of objects, and a viewer that draws three of them at a time has no use for the other nine hundred and ninety-seven. The engine still lays the document out from the beginning — where a page ends depends on every page before it, and no arrangement of options changes that — but what it *keeps* is the caller's to decide.

onPage?
((page: PageGeometry, index: number) => void) | undefined
Called as each page closes, with the page and its index. The page is handed over before anything else sees it and is not held afterwards unless {@link retain} says so, which is what makes a streamed layout constant in memory.
retain?
{ readonly from: number; readonly count: number; } | undefined
Which pages to keep in the result. Absent keeps all of them, which is what every existing caller expects. A range keeps that window; an empty window keeps none, and the result is then the page count and the sizes — enough for a scrollbar and a page number, and nothing that has to be drawn.
stopAfter?
number | undefined
Stop once this many pages have been produced. For a caller that wants page forty and does not care what follows it. A **lower bound, not an exact count**: the check is made between blocks, so a table or a long paragraph that was being placed is finished rather than abandoned, and the result may hold a page or two more. What is guaranteed is the part that matters: every page but the last is exactly the page the full layout produces, in order, from the first. A page is what it is because of everything above it, and stopping early cannot change what is above. The last page is the one the stop cut short — it holds what had been placed on it and is closed as `end` — so a caller that needs page forty asks for forty-one and takes the fortieth. {@link LayoutResult.pageCount} is then the count of what was laid out rather than of the document.
LayoutResult
interface LayoutResult
pages
readonly PageGeometry[]
The pages, as far as the caller asked to keep them. Every page by default. A caller that gave {@link LayoutOptions.retain} gets the window it asked for and no more; see {@link sizes}, which is what a scrollbar needs and costs two numbers a page rather than a page's worth of geometry.
sizes
readonly { readonly width: number; readonly height: number; }[]
Every page's extent, whether or not its geometry was kept. The whole of what a virtualiser needs to be correct before a single page has been drawn — and for a document of a thousand pages it is sixteen kilobytes against the hundreds of megabytes the geometry would be.
from
number
Where the retained window begins, as a page index.
pageCount
number
How many pages the document came to, retained or not.
unsupported
Readonly<Record<string, number>>
How many blocks were refused, by reason.
Line
interface Line

One chosen line, as a half-open range of pieces.

start
number
end
number
offset
number
Where the line begins, from {@link LineRoom.offset}.
width
number
Advance of everything on it, the spaces that end it included.
ink
number
The same without those spaces: where the ink actually ends.
spaces
number
Spaces on it, and how many of them lie between two pieces of ink.
inkSpaces
number
forced
boolean
hyphen?
boolean | undefined
The line ends in the middle of a word and draws a hyphen for it. Its width is already in {@link Line.width} and {@link Line.ink} — the mark is part of the line, and both the alignment and the justification are measured with it — so a caller that only places lines need not read this. A caller that *draws* one must: the letters are the word's and the mark is not among them.
fontSize
number
squeeze
number
What the spaces on it promised the fit test, in pixels. A justified line keeps a word that overruns by less than its spaces can give back between them, and the giving back is the caller's — see `page.ts`. Stated so the caller can spend *this* and no more: a line wider than its room for some other reason — a token cut at the column's edge, a picture nothing can shrink — was never promised anything, and squeezing its spaces to pull it back would move words Word leaves where they are.
LineBox
interface LineBox

One line: how tall it is and how far down it the baseline sits, in points.

height
number
baseline
number
ink?
number | undefined
How much of the box has to fit on the page, where that is less than all of it. A ruled page centres the type in its step, and the empty half-step under the last line of a page may hang past the bottom margin: the twenty-fourth line of `doc-grid-auto-multiple` has a box ending 4.9px below the margin and Word draws it on that page all the same, while the type's own line ends 3.5px above it. Absent everywhere else, where the box is the measure.
LineEnd
interface LineEnd

An arrowhead at one end of a line, `a:headEnd` and `a:tailEnd`.

type
string
`triangle`, `stealth`, `diamond`, `oval`, `arrow`, or `none`.
width
string | undefined
`sm`, `med` or `lg`; absent means medium.
length
string | undefined
LineGeometry
interface LineGeometry

One line, placed.

rotation?
90 | -90 | undefined
A line of a cell whose text runs down (`90`) or up (`-90`) the page. `x` and `y` are then the corner the line box turns about: the painter places the box there and rotates it, so the spans inside keep their positions along the line. See where a vertical cell is set.
upright?
boolean | undefined
...set in East Asian vertical, `tbRlV`: ideographs stand upright down the column and only Latin lies on its side, where plain `tbRl` turns the whole line. The painter draws such a line in a vertical writing mode rather than turning it.
wordSpacing?
number | undefined
`w:jc="both"`: the extra room every space on this line was given. The line breaker stretches a justified line by widening the *pieces* it holds — see `chooseLines` — which puts every word where Word puts it and leaves each word's own glyphs drawn at their natural width inside a wider slot. That is enough while a piece is one word, and it is not enough where a piece holds spaces of its own: the browser draws those at their natural width and the words after them stand short. So the stretch is stated as well, in the unit CSS has for it. Absent on a line the breaker had nothing left to give, which is most of them. Negative on a line that overruns: justification takes back from the spaces what the breaker promised when it kept the word that overran.
letterSpacing?
number | undefined
`w:jc="distribute"`: the room a line leaves, dealt out between its characters rather than its spaces, and on the last line as on the rest.
merged?
boolean | undefined
A line of a cell that is merged down past this row. Such a line is placed against the **run** — `w:vAlign` centres a merged cell's words between the top of the first row and the bottom of the last — so it may sit far below the row that carries it, and it is not the row's own depth. Where a page ends inside the run, the divider would otherwise cut the row at that line: `educational-5fdff3d8253d` labels four rows `Knowledge and Skills` down the side, and the second word of the label, 348px into a row 150px tall, sent everything after it to the next page.
alignment?
"center" | "right" | undefined
`w:jc`, where it put the line anywhere but at its start. What moves the line again when a field's answer changes its width after the line was placed. A page number is laid out as a one-character mark — measured as that face's `.notdef`, twelve and a half pixels of Times New Roman at twelve point against eight for a digit — and a footer centred on the mark drew `1` two pixels right of the middle and `10` three pixels left of it: 282 of the 344 page-number lines in the ink sample were off, and drawn from where the mark stood. See `realignedTabs`.
x
number
Left edge, in pixels from the page's left edge.
y
number
Top of the line box, in pixels from the page's top edge.
baseline
number
The baseline, in the same frame — what Word's own PDF states.
width
number
height
number
size
number
The type the line is set in, in pixels: the size of its tallest run. Not the height, which is the whole line box and a sixth larger. Anything that draws the line needs it, and nothing else on the geometry states it.
text
string
spaceAfter?
number | undefined
The space the paragraph asks after itself, on the paragraph's last line inside a box; see where a row is divided.
paragraph?
{ readonly id: number; readonly widows: boolean; } | undefined
Which paragraph of a box the line belongs to, and whether that paragraph keeps widows and orphans; see where a row is divided.
aligned?
{ readonly align: "center" | "bottom"; readonly by: number; } | undefined
The cell this line was moved down inside by `w:vAlign`, and which way. Only where the cell is shorter than its row and so had room to be moved — a cell that fills its row is aligned by having nowhere to go. Carried because a row divided between two pages is aligned again on each of them: see where a row is divided, and `row-split-valign-center`. **One object per cell, shared by its lines, and that is how they are grouped again**: a column number is not an identity — a table nested in a cell numbers its own columns, and a vertically merged run folded into one row holds the cells of every row it covers. Grouped by column, `reports-8a5682f91fe7` gathered thirteen hundred lines of a 13767px row into one "cell" and drew them on a single sheet: ten pages against Word's twenty-five.
spans?
readonly SpanGeometry[] | undefined
What is actually on the line, run by run, for whoever draws it. {@link LineGeometry.text} is the line as one string, which is what a comparison against Word's own PDF pairs on. It is not enough to draw with: a line is a sequence of runs, each with its own face, colour and decorations, and each landing at an abscissa this engine worked out. The two are the same characters said twice, once for measuring and once for painting.
row?
number | undefined
Which row of its table the line stands in, where it stands in one. The painter needs it — a cell's rules and shading are the row's — and so does any measurement that wants to say *which* row came out wrong rather than which document did. A line of the flow has none.
LineNumbering
interface LineNumbering

Line numbering in the margin, `w:lnNumType`.

countBy
number | undefined
start
number | undefined
distanceTwips
number | undefined
restart
"continuous" | "newPage" | "newSection" | undefined
LineRoom
interface LineRoom

The room one line of a paragraph has: where it begins and how wide it is. Two numbers and not one, because the things that narrow a line do not all narrow it from the right. A first-line indent moves its left edge in; a hanging indent moves it out; a floating object on the left of the column moves every line beside it in and the ones above and below it back. The offset is measured from where a *continuation* line of the paragraph begins, so an ordinary paragraph's later lines have an offset of nought.

offset
number
width
number
LineRun
interface LineRun

A run, as far as the line it sits on is concerned.

sizeHalfPoints
number
Resolved size in half-points, as `w:sz` states it.
ascent
number
Ascent above the baseline, as a fraction of the em.
descent
number
Descent below it, positive, as a fraction of the em.
lineGap
number
The gap the font asks for above the ascent, as a fraction of the em.
emRatio?
number | undefined
The line this face rules at, in ems, where Word's own answer is known. Overrides everything else: the metrics, which are the browser's reading of the font, and the East Asian constant, which is what most such faces measure and not what all of them do. `wordLineRatio` in `view/css/theme.ts` is where the answers are kept — most East Asian faces are the 1.3 below, and DFKai-SB is 1.71, a fifth taller than its neighbours. The model holds no table of its own on purpose. A constant it believes is a constant nobody can correct from outside; a number it is handed is one the caller can measure.
object?
boolean | undefined
Whether the run is an inline object rather than type. A picture rules the line by standing on the baseline, and a line multiple does not multiply it: see the `auto` branch of {@link lineBoxOf}.
label?
boolean | undefined
Whether the run is a list's label rather than its text. A label is set at the head of the first line and is not content of its own; whether it rules that line the way text does is measured under {@link lineBoxOf}.
blank?
boolean | undefined
Whether the run holds nothing but whitespace; see {@link tallestOf}.
raisePoints?
number | undefined
`w:position`: how far the run is moved off the baseline, in points, up being positive. The line grows by the movement — upward into its ascent, downward into its descent. `run-position-up-6`, `-up-20` and `-down-6` measure it: a run raised three points makes its line 4.0px taller and its baseline 4.0px lower, one raised ten points 13.5px, and one lowered three points 4.2px taller with the baseline where it was.
mark?
boolean | undefined
Whether the run is the paragraph mark rather than anything typed. The mark rules a line only where nothing else can — see {@link tallestOf}. A run of seventy-two point spaces is *not* nothing else in the sense the blank rule means, so the two flags are separate: `blank` says the run has no ink, `mark` says there was nothing to have ink.
eastAsian?
boolean | undefined
Whether the run is East Asian text, whose line the face does not decide. Word rules a line of ideographs at {@link EAST_ASIAN_LINE} times the size and pays no attention to the font: `east-asian-natural-line-height` sets twelve-point SimSun, NSimSun, FangSong, MingLiU, DFKai-SB and Microsoft JhengHei one after another, and Word rules every one of them 20.80px apart — 1.30 em exactly — where the faces' own lines run from 1.2 to 1.5.
LineSpacing
interface LineSpacing

`w:spacing`, as far as the line is concerned.

rule
"auto" | "exact" | "atLeast"
line?
number | undefined
`w:line`: 240ths of the natural line under `auto`, twips under the others. Absent is single spacing, which is `auto` at 240 and is what a paragraph that says nothing at all gets.
MarkupSighting
interface MarkupSighting

One piece of markup nothing read, as the observer receives it.

key
string
`w:zoom`, or `w:spacing@w:beforeAutospacing`.
parent
string
Local name of the element it was found in.
kind
"element" | "attribute"
reason
string | undefined
Why it is passed over, when the register says so.
MathBox
interface MathBox

An equation's box, and what stands inside it.

width
number
ascent
number
Above the baseline.
descent
number
Below it.
glyphs
readonly MathGlyphRun[]
MathContent
interface MathContent
writeRunProperties
(properties: RunProperties | undefined) => void
Writes a `w:rPr` for the face the equation is set in, where it has one.
MathElement
interface MathElement

A node of the OMML tree, kept close to the source markup.

name
string
Local name of the OMML element, e.g. `f` for a fraction.
text?
string | undefined
Text content for `m:t` nodes.
children?
readonly MathElement[] | undefined
attributes?
Readonly<Record<string, string>> | undefined
Selected attributes needed for rendering, e.g. delimiter characters.
properties?
RunProperties | undefined
MathFace
interface MathFace

What the face can say about itself, in em fractions and pixels.

widthOf
(text: string, sizePx: number) => number
The advance of a string at a type size, in the same units as the size.
ascent
number
How far the face reaches above the baseline, as a fraction of the em.
descent
number
...and below it.
constants?
MathConstants | undefined
The face's own constants, **divided by its em**, or none. Optional so that the unit cannot be got wrong at the seam. `MATH` is a table nearly no face carries, so nearly every equation is set by the classical set — and that set is published *per thousand*, which is the form `classicalMathConstants` answers in by default. Handed over so, and multiplied here by the type size, every length in an equation came out a thousand times too big: one sum in the project's own demo document was given a box 933 pixels tall and the page after it was blank paper. A caller that has the face's table hands it over; one that has not hands over nothing, and the fallback below is in the units this file works in because this file chose them.
MathGlyphRun
interface MathGlyphRun

One run of text inside an equation, placed against the box's baseline.

text
string
dx
number
From the box's left edge.
dy
number
From the box's baseline, positive downwards.
sizePx
number
italic
boolean
bold?
boolean | undefined
rule?
{ readonly width: number; readonly height: number; } | undefined
A rule rather than text: a fraction's bar, a radical's overline. Drawn as a filled rectangle of `width` by `height` with its top at `dy`; `text` is empty for these.
scaleY?
number | undefined
Drawn this many times its height, about its own baseline: a delimiter grown to the height of what it encloses. See `case 'd'`.
MathNode
interface MathNode

An Office Math (OMML) expression, converted to MathML by the renderer.

kind
NodeKind.Math
display
"inline" | "block"
`inline` for `m:oMath`, `block` for `m:oMathPara`.
children
readonly MathElement[]
properties?
RunProperties | undefined
The face and size the equation is set in, read from the first `w:rPr` inside it — the only place a file states them. Weight and slope are not kept: [MS-OI29500] §22.1.2.87 a says Word ignores them there.
Measurement
interface Measurement

A measurement together with the unit it was declared in, `ST_TblWidth`.

value
number
type
"auto" | "nil" | "dxa" | "pct"
`dxa` twips, `pct` fiftieths of a percent, `auto`, `nil`.
Note
interface Note

A footnote or endnote.

id
string
type
"normal" | "separator" | "continuationSeparator" | "continuationNotice"
`normal` is a real note; `separator` and `continuationSeparator` are chrome.
children
readonly BlockNode[]
NoteInput
interface NoteInput

A footnote, as far as the page is concerned: the blocks it is made of. Where it goes is not stated because it is not the note's to state — Word sets every note referenced on a page at the foot of that page, in order, upwards from the bottom margin.

blocks
readonly BlockInput[]
at?
number | undefined
Where the note's mark stands, as an index into the paragraph's pieces. A note belongs to the page its *mark* lands on, not to the page its paragraph began on. `policies-b2c6929e77b7` is the document that says so: a paragraph straddles pages one and two, its mark falls on the line that goes over, and Word sets the note at the foot of page two — where this engine, binding the note to the paragraph, set it at the foot of page one and gave page two an extra line of body for the room it had not spent. Three pages short over fifty-four, and 2361 lines on the wrong one. Absent, the note is bound to the paragraph as before.
NoteReferenceNode
interface NoteReferenceNode
kind
NodeKind.FootnoteReference | NodeKind.EndnoteReference
id
string
customMark
boolean
A custom mark suppresses automatic numbering.
properties
RunProperties
mark?
boolean | undefined
The number printed at the head of the note itself, `w:footnoteRef`. The same number as the reference in the body, in the place and the type the note's own text puts it — which is not always at the very start, and is never in the type the body used. It carries no id: the note it belongs to is the one it is written inside.
NumberingCounterState
interface NumberingCounterState
counters
ReadonlyMap<string, number>
started
ReadonlySet<string>
NumberingDefinitions
interface NumberingDefinitions

The parsed contents of `numbering.xml`.

abstract
ReadonlyMap<number, AbstractNumbering>
instances
ReadonlyMap<number, NumberingInstance>
pictureBullets
ReadonlyMap<number, PictureBullet>
partName?
string | undefined
The part these definitions were read from, usually `word/numbering.xml`. A picture bullet names its image by a relationship id, and a relationship id means nothing without the part it was written in: `rId1` in `numbering.xml` is a different picture from `rId1` in `document.xml`, and usually no picture at all.
numIdMacAtCleanup
number | undefined
`w:numIdMacAtCleanup`: the highest `w:numId` Word for Mac had reached. A counter one implementation keeps so that it does not reuse an id another has handed out. Nothing reads it here; it is written back because a document that loses it can be given a duplicate list id by the next editor.
NumberingInstance
interface NumberingInstance

A concrete list instance, `w:num`. Paragraphs reference instances, not abstract definitions. The indirection exists so two lists can share formatting while numbering independently, and it is also where per-instance level overrides live.

id
number
abstractId
number
durableId
string | undefined
`@w16cid:durableId`: an identity for the instance that survives renumbering. `w:numId` is a position in this document's table and changes when lists are added or merged; the durable id does not, which is how a comment or a cross-reference made in one editing session still points at the same list in the next.
overrides
ReadonlyMap<number, NumberingLevelOverride>
Level overrides applied on top of the abstract definition.
NumberingLevel
interface NumberingLevel

One level of a list definition, `w:lvl`.

level
number
Zero-based level index, 0..8.
start
number
format
NumberFormat
text
string
Number text pattern, `w:lvlText`. Placeholders `%1`..`%9` are substituted with the counter of the corresponding level, which is what produces "1.2.3" style numbering.
suffix
NumberSuffix
templateCode
string | undefined
`@w:tplc`: which entry of Word's list gallery this level came from. Opaque to everyone but Word, which uses it to recognise a list the user picked from the gallery and to offer the same one again.
tentative
boolean
`@w:tentative`: a level Word invented rather than the author defining it. A list defined to three levels is written with nine, and the six nobody asked for are marked. Word discards a tentative level the moment the author defines one, and keeps it invisible until then.
alignment
"left" | "center" | "right" | undefined
style
string | undefined
`w:pStyle`: the paragraph style this level is attached to.
paragraph
ParagraphProperties | undefined
Indentation and tab settings for the level.
run
RunProperties | undefined
Formatting of the number itself.
restart
number | undefined
Level after which the counter restarts, `w:lvlRestart`.
pictureBulletId
number | undefined
Picture bullet id, `w:lvlPicBulletId`.
isLegal
boolean
The level is a legal-numbering variant, `w:isLgl`.
legacy
LegacyNumbering | undefined
Word 6 numbering compatibility, `w:legacy`. A list converted from a document old enough to predate `w:numPr` keeps its original geometry: the number sits in a box of a stated width and the text is indented by a stated amount, rather than the number hanging in the paragraph's own indent. Ignoring it moves every line of such a list.
NumberingLevelOverride
interface NumberingLevelOverride
level
number
startOverride
number | undefined
Restart value, `w:startOverride`.
definition
NumberingLevel | undefined
A fully redefined level.
NumberingReference
interface NumberingReference

`w:numPr`: which list a paragraph belongs to, and how deep in it. Both halves are optional and separately so, because a style states them separately. `Heading2` says `<w:ilvl w:val="1"/>` and no `w:numId` at all — "whatever list applies to me, I am its second level" — and reading that as "no numbering" drops the level of every outline-numbered heading in the document. The pair is absent only where the paragraph stated neither.

id
number | undefined
`w:numId`, referencing an instance in `numbering.xml`.
level
number | undefined
Zero-based list level, `w:ilvl`.
NumberLabel
interface NumberLabel

The computed label of one numbered paragraph.

text
string
The rendered text, e.g. `2.3.` or `•`.
suffix
"tab" | "space" | "nothing"
What separates the label from the paragraph text.
level
NumberingLevel
The level definition the label came from.
value
number
The raw counter value, useful for cross references.
pictureBullet?
{ readonly relationshipId: string; readonly widthEmu: number | undefined; readonly heightEmu: number | undefined; readonly part: string | undefined; } | undefined
`w:lvlPicBulletId`: the picture Word draws in place of the bullet. The level still states a character — `` in Symbol — and Word draws the picture over it, so a reader that takes the text draws a dot where the document has a tick, a flower or a logo.
OfficeArtContentfrom @genomdev/office-core
interface OfficeArtContent

What Word puts in `fcDggInfo`. The drawing group first — which holds the store every picture in the document lives in — and then up to two drawings, one for the body and one for the headers. Each is introduced by a single byte saying which it is, and that byte is the thing to trust: documents exist whose two drawings are in the other order, and reading them by position puts the header's shapes in the body.

drawingGroup
ArtRecord | undefined
bodyDrawing
ArtRecord | undefined
headerDrawing
ArtRecord | undefined
OpaqueInput
interface OpaqueInput

A block this engine will not place, and will not pretend to.

kind
"opaque"
reason
string
Why, so a comparison can say what it skipped.
OpenDocOptions
interface OpenDocOptions extends OpenOptions

Opening a Word 97-2003 document. The result is a {@link DocxDocument} — the same object `.docx` produces, and deliberately so. The alternative, and the one most projects take, is to convert the binary file into an OOXML package and hand that to the existing reader; it is easier to start and worse to finish, because everything the document says then has to survive being written out in a second format and read back. Producing the model directly means the viewer, the extractor and the addressing scheme work on a 1997 document with no code that knows it is one.

keepDeletedContent?
boolean | undefined
Keep content marked deleted by revision tracking. Off by default.
OpenDocxOptions
interface OpenDocxOptions extends OpenOptions

Options accepted when opening a Word document.

keepDeletedContent?
boolean | undefined
Keep content marked deleted by revision tracking. Off by default.
parseMath?
boolean | undefined
Parse OMML equations. On by default.
preserve?
boolean | undefined
Record where every node was read from, and keep what is not modelled. On by default, and what makes saving lossless: see `model/source.ts`. Off, the document is read exactly as it was before spans existed — nothing is recorded, nothing unmodelled is kept, and saving can only write what the model understands.
maxCacheBytes?
number | undefined
Maximum bytes of inflated package parts held in memory. Defaults to 64 MB. Raising it speeds up documents whose images are viewed repeatedly; lowering it bounds memory on very large files.
Outline
interface Outline

How the edge of a shape is drawn, `a:ln`.

widthEmu
number | undefined
Line width in EMU, `a:ln/@w`; absent means the theme's.
fill
Fill | undefined
dashed?
boolean | undefined
dash?
string | undefined
`a:prstDash/@val`, the pattern by name: `dash`, `sysDot`, `lgDashDot`…
cap?
"round" | "square" | "flat" | undefined
`a:ln/@cap`: how the line ends.
join?
"round" | "bevel" | "miter" | undefined
The corner treatment: `a:miter`, `a:round` or `a:bevel`.
miterLimit?
number | undefined
`a:miter/@lim`: how far a sharp corner may extend before it is cut off. In thousandths of a percent of the line width. Nothing draws it — a border has no corner sharp enough to matter and CSS has no way to state one — and it is the whole of what the element says, so a miter written back without it is a different miter.
headEnd?
LineEnd | undefined
tailEnd?
LineEnd | undefined
OutlineEntry
interface OutlineEntry

An entry of the document outline, derived from heading paragraphs.

level
number
Heading level, 1..9.
text
string
node?
BlockNode | undefined
The heading paragraph itself, which is what a viewer navigates by. Identity rather than position, and that is the whole point of it. There is no one numbering of a document's blocks: this walk counts paragraphs inside table cells and the layout does not, the layout inserts a block where a section begins and this does not, and a paragraph broken across a page becomes two blocks there and stays one here. On a fourteen-page report the two numberings ran to 466 and 278, so more than half the headings named a block the layout had never heard of and the rest named the wrong one — an outline whose later entries did nothing at all and whose earlier ones went quietly to the wrong page. A node is the same object on both sides, and cannot drift.
blockIndex
number
Index of the paragraph in the flattened body. A position in *this* walk — paragraphs inside table cells included — which is not the layout's numbering and cannot be used to find a page. Kept because it identifies the entry within an outline; navigate by {@link node}.
bookmark
string | undefined
Bookmark name when the heading carries one.
PageBorders
interface PageBorders

The frame Word draws round a page, `w:pgBorders`. Where it sits is as much a part of it as which edges are drawn: the same border set measured from the paper and measured from the text is two different frames, one round the sheet and one round the type area.

borders
Borders
offsetFrom
"text" | "page"
`page` measures each edge's `w:space` from the paper, `text` from the type area.
display
"allPages" | "firstPage" | "notFirstPage"
Which pages get the frame, `w:display`. The names mean what they say, and the standard's own gloss of the second one does not: [MS-OI29500] §2.1.549 records that ISO/IEC 29500 defines `notFirstPage` as "displayed on only the first page in the parent section" while Word displays it "on all pages except the first page in the parent section". Read as Word reads it, and against the first page **of the section** rather than of the document — see `#mountPageBorder`.
PageGeometry
interface PageGeometry

One page, placed.

width
number
height
number
blocks
readonly BlockGeometry[]
floats?
readonly FloatGeometry[] | undefined
The floating objects this page carries; see {@link FloatGeometry}.
noteRule?
{ readonly x: number; readonly y: number; readonly width: number; } | undefined
The rule above the footnotes, where the page has any. `<w:separator/>` is a run that draws no glyph, so the note area's own geometry cannot carry it: the engine already pays for its line — see `separatorLine` — and until this was here the line was paid for and left blank, which is a footnote hanging in the middle of the page under nothing. Stated as a rectangle rather than as a flag because only the engine knows where the note area begins.
ended?
string | undefined
Why the page ended, for the instruments rather than for the painter. A page that ends because a line would not fit is a different defect from one that ends because a heading asked for a new page, and a comparison that sees only *where* the two engines part cannot tell them apart. Named at the moment the page is closed: `full`, `break`, `section`, `row`, `column`, `keep`, `end`.
section?
number | undefined
Which section of the document the page belongs to, counted from nought. Recorded so that `SECTIONPAGES` has something to count, and because a comparison that knows where the sections fall can say whether a page went astray at a break or in the middle of a stretch.
border?
{ readonly ref: PieceRef; readonly firstOfSection: boolean; readonly margins: { readonly top: number; readonly right: number; readonly bottom: number; readonly left: number; }; } | undefined
The frame round the sheet, where the section in force draws one. Drawn by the viewer before the engine switch and by nobody after it: the model kept `w:pgBorders`, the writer kept writing it, and every page of the twelve corpus documents that ask for a frame came out without one. The engine says only what it alone knows — whether this sheet opens its section, which `w:display` turns on, and where the section's margins are, which a frame measured from the text is drawn against.
PageMargins
interface PageMargins
topTwips
number
rightTwips
number
bottomTwips
number
leftTwips
number
headerTwips
number
Distance from the page edge to the header, `w:header`.
footerTwips
number
gutterTwips
number
Extra binding margin, `w:gutter`.
PageNumbering
interface PageNumbering

Page number format for the section, `w:pgNumType`.

start
number | undefined
format
string | undefined
chapterStyle
string | undefined
chapterSeparator
string | undefined
PageSetup
interface PageSetup

The page, as the section states it.

widthTwips
number
heightTwips
number
marginTopTwips
number
marginRightTwips
number
marginBottomTwips
number
marginLeftTwips
number
pageBorder?
unknown
`w:pgBorders`: the frame the section draws round its sheets. Carried and not read — which sides, how far in and on which pages is the painter's business, like every other {@link PieceRef} — and put on the setup because the setup is the one thing that already changes exactly where a section does. See {@link PageGeometry.border}.
grid?
DocumentGrid | undefined
kernsPunctuation?
boolean | undefined
`w:noPunctuationKerning` the other way round: whether two adjacent full-width marks share one half em. On unless a document turns it off, and it does nothing unless the run also asks to be kerned — see {@link TextPiece.kerns} and `kernsPunctuation`.
hyphenation?
{ readonly points: Hyphenation; readonly zoneTwips: number; readonly consecutiveLimit: number; readonly caps: boolean; } | undefined
`w:autoHyphenation`: the document breaks words at the end of a line. Absent where it does not, which is the common case and the whole of why this is one optional object rather than four fields: the engine asks once. - `points` answers where a word of a given language may break. It is fetched asynchronously by the composer and filled in before the layout runs, so it answers nothing until then and the engine never waits. - `zoneTwips` is `w:hyphenationZone`: the white Word tolerates at the end of a line before it reaches for a hyphen. A word is broken only where leaving it whole would leave more than this empty. - `consecutiveLimit` is `w:consecutiveHyphenLimit`: how many lines in a row may end in a hyphen, nought meaning no limit. - `caps` is the other way round from `w:doNotHyphenateCaps`: false leaves a word written wholly in capitals whole.
rulesTableLines?
boolean | undefined
`w:adjustLineHeightInTable`: the document grid rules lines inside a table. [MS-OI29500] states the rule outright — the grid's line pitch **shall not be added to any line inside a table cell unless this flag is present in the document's compatibility settings**. Without it a cell's lines are set at their natural height however fine or coarse the section's `w:docGrid`; with it they are stepped like any other line on the page. 67 of the corpus's 1151 documents with a settings part declare it.
noExtraLineSpacing?
boolean | undefined
`w:noExtraLineSpacing`: an `exact` line's surplus stands below the text. ECMA-376 Part 4 §14.8.3.28, and Word honours it — see the `exact` branch of {@link lineBoxOf}, which is where it is read.
suppressTopSpacing?
boolean | undefined
`w:suppressTopSpacing`: the first line of a page loses the room its rule would keep over it. ECMA-376 Part 4 §14.8.3.43, and Word honours it — by a narrower rule than the sentence describes, measured at {@link topSpacingShiftOf}, which is where the amount comes from.
compresses?
boolean | undefined
keepsBreakLinesRagged?
boolean | undefined
`w:doNotExpandShiftReturn`: a justified line a `<w:br/>` ended is left ragged. Off by default, and then Word stretches that line across the column like any other it justifies: probes `compat-shift-return-*` draw `A short first line` at 72–526pt without the flag and at 72–146pt with it.
indentsToText?
boolean | undefined
Whether `w:tblInd` is measured to the first cell's text rather than to the table's edge. The older of two layouts, and `w:compatSetting compatibilityMode` names it again: `table-indent-stated-zero` and `table-indent-in-compatibility-mode-15` are the same document but for that setting, and Word begins the first cell's text at 96.0 — the margin, the table's edge a cell margin outside it — in the first and at 103.2 — the edge at the margin — in the second.
inCell?
boolean | undefined
The text is laid out inside a table cell, where Word hangs no mark past the edge: `east-asian-squeeze-for-kinsoku-cell` is the paragraphs that hang one on the page, in a cell as wide as the column, and every one of them takes the ideograph before the mark down instead.
defaultTabTwips?
number | undefined
`w:defaultTabStop`: the interval between the stops nobody declared.
notesBeneathText?
boolean | undefined
`w:footnotePr/w:pos`: the notes follow the text instead of hanging from the foot of the page. `pageBottom` is the default and is what almost every document takes. The other three values all come to the same thing: `footnote-position-{beneathtext,sectend,docend}` put six lines, a note reference and four more on a page a third full, and Word draws the note at 243.6 points down in all three — one line under the last line of text, with the separator between — where `footnote-position-pagebottom` draws it at 767. So `sectEnd` is `beneathText` ([MS-OI29500] §2.1.541 b), and so in practice is the `docEnd` that same note says Word does not support. Five documents of the corpus ask for one of the three.
decimalSymbol?
string | undefined
`w:decimalSymbol`: the character a `decimal` tab stop aligns on. ECMA-376 §17.15.1.29 defaults it to the full stop. Word reads its own locale here and not the document — see the `decimal` branch of {@link tabAdvance} — and a viewer has no locale to read, so the document's statement is what is honoured.
headerTwips?
number | undefined
`w:pgMar/@w:header`: from the top edge of the page to the running head.
footerTwips?
number | undefined
`w:pgMar/@w:footer`: from the bottom edge to the running foot.
pageNumberStart?
number | undefined
`w:pgNumType/@w:start`: the number the section's first page carries. Not decoration. The number a `PAGE` field prints is this one, and so is the parity that decides which of an odd-and-even pair a sheet carries: a document whose body restarts at one after four pages of front matter has its left-hand pages on the other side from where the sheet count would put them.
lineNumbering?
{ readonly countBy: number; readonly start: number; readonly distanceTwips?: number | undefined; readonly restart: "newPage" | "newSection" | "continuous"; } | undefined
`w:lnNumType`: the numbers Word rules down the left of the text. Absent where the section asks for none — see `setupOf`, which reads `w:countBy` as the standard writes it: nought multiples is no numbering.
verticalAlign?
"both" | "center" | "top" | "bottom" | undefined
`w:vAlign`: where the body sits between the margins of a page it does not fill. A title page is the case, and it is not decoration: a page centred puts its first line halfway down the sheet, so every line of it is compared against a line of Word's that is nowhere near. `both` is Word's justified setting, which spreads the paragraphs rather than moving them, and is left alone.
columns?
{ readonly count: number; readonly spaceTwips?: number; readonly widths?: readonly { readonly widthTwips: number; readonly spaceTwips?: number; }[]; } | undefined
`w:cols`: how many columns the text area is divided into, and the gutter between them. The text fills the first column to its foot, then the second, and the page ends when the last is full. A section that states none is one column, which is the same thing said differently.
PageSize
interface PageSize
widthTwips
number
heightTwips
number
orientation
"portrait" | "landscape"
code?
number | undefined
`w:code`: the paper Word asks the printer for. A number out of the Windows `DEVMODE` table — 9 is A4, 1 is Letter — and nothing on the page depends on it. It is what a printer driver is handed, so a document that loses it is one that comes out of the tray it was not meant to. Fifty-one documents in three hundred state it.
PapxSpan
interface PapxSpan

Paragraph formatting for one paragraph, and the style it is based on.

fcStart
number
fcEnd
number
istd
number
grpprl
Uint8Array<ArrayBufferLike>
ParagraphBorder
interface ParagraphBorder

A rule drawn above or below a paragraph.

sizeEighths?
number | undefined
`w:sz`, in eighths of a point.
spacePoints?
number | undefined
`w:space`, in points, between the rule and the text.
ParagraphInput
interface ParagraphInput

A paragraph, resolved: everything the geometry needs and nothing else.

kind
"paragraph"
suppressLineNumbers?
boolean | undefined
`w:suppressLineNumbers`: the paragraph takes no part in line numbering.
bookmarks?
readonly string[] | undefined
The bookmarks that begin in this paragraph, or just above it. What a `PAGEREF` resolves against: the page this paragraph landed on is the page those bookmarks are on. Named rather than positioned, because a bookmark takes no room and the page is all a reference wants.
styleId?
string | undefined
The paragraph's style id, which `STYLEREF` looks its text up by. Carried for that one field and nothing else: the cascade is resolved by the time a paragraph reaches the engine, so the id is not otherwise wanted.
ref?
unknown
What whoever built this wants back when it is drawn; see {@link PieceRef}. Borders, shading, the address a citation uses — none of them changes where anything goes, so none of them is the engine's, and this is how they reach the painter without the engine learning what a border is.
pieces
readonly (TextPiece | TabPiece | ObjectPiece | BreakPiece)[]
tabs?
readonly { positionTwips: number; alignment: string; leader?: string; }[] | undefined
The paragraph's own tab stops, `w:tabs`, in twips.
spacing
ParagraphSpacing
line
LineSpacing
indentLeftTwips?
number | undefined
Left, right and first-line indents, in twips.
indentRightTwips?
number | undefined
indentFirstLineTwips?
number | undefined
indentHangingTwips?
number | undefined
alignment?
string | undefined
labelAlignment?
"left" | "center" | "right" | undefined
`w:lvlJc`: where the numbering label sits against its position.
rightToLeft?
boolean | undefined
keepNext?
boolean | undefined
`w:keepNext`: this paragraph stays with the one after it.
pageBreakBefore?
boolean | undefined
`w:pageBreakBefore`.
ownPageBreak?
boolean | undefined
`w:pageBreakBefore` written on this paragraph, and nothing else. The two differ where a break in a run put the paragraph at the top of a page: that paragraph opens a page and did not ask to. Only the one that asked keeps its space above — see where `fill` acts on this.
columnBreakBefore?
boolean | undefined
A `<w:br w:type="column"/>` ended the paragraph above this one. The column's break, not the page's: the text goes on at the top of the next column and only reaches the next page when there is no next column. `section-start-nextcolumn` and `column-break-in-the-last-column` are the two that ask, and the second is what says the difference matters — three groups and two column breaks on a two-column sheet come back from Word two pages long.
keepLines?
boolean | undefined
`w:keepLines`: every line of the paragraph on one page. A heading of two lines split across a page boundary is what it forbids. Where the whole of it will not fit in the room left, the whole of it goes down — and where it will not fit on a page of its own either, it is set where it falls, because there is nowhere better.
snapToGrid?
boolean | undefined
`w:snapToGrid`: whether the document's grid rules this paragraph's lines.
widowControl?
boolean | undefined
`w:widowControl`, which Word turns on by default.
lineless?
boolean | undefined
A paragraph whose floats are placed and which takes no line itself: the empty carrier of a continuous section break. See where it is built.
notes?
readonly NoteInput[] | undefined
The footnotes whose references this paragraph carries. Their text is set at the foot of the page the reference lands on, and the room it takes comes off the body — which is why they are the engine's business and not the painter's.
floats?
readonly FloatInput[] | undefined
The floating objects anchored in this paragraph. They obstruct this paragraph and the ones after it, for as far down the page as they reach. Anchored *in* a paragraph is where the format puts them; where they land on the page is the caller's answer.
frame?
FrameInput | undefined
`w:framePr`: the paragraph is drawn where it says, not where the flow ends. A text frame is the older half of what `w:drawing` does for a picture — a paragraph given a width, an anchor and an offset — and Word takes it out of the flow entirely: it costs the page no height, and the text around it runs *beside* it rather than under. The browser path can only do the first half of that, because CSS has no way to say "keep out of this box" for a box that is not a float, and doing the first half alone lets a page accept content it has no room for — measured there at 875 matched lines gained against 4241 words lost. This engine has real obstacles, so it can do both, and both is what Word does.
ParagraphNode
interface ParagraphNode
kind
NodeKind.Paragraph
id
number
Identity, for as long as the document is open. What an edit names and what an incremental relayout compares. Not an index: inserting a paragraph renumbers every index after it and leaves every id alone, which is the entire reason this is here. See `model/ids.ts`.
properties
ParagraphProperties
children
readonly InlineNode[]
sectionProperties
SectionProperties | undefined
Section properties attached to this paragraph mark. Present only on the last paragraph of a section; it defines the page setup of the section that *ends* here, which is the part of the format that most often trips up implementations.
paraId?
string | undefined
`w14:paraId`: the identity Word gives this paragraph, eight hex digits. Not {@link id}, and the difference matters. `id` is minted by whoever read the document and means nothing outside this process; `paraId` is written into the file, survives it, and is what the rest of the package points at — `w15:commentEx` names the paragraph a comment is anchored to by its `paraId`, and co-authoring tells two edits of one paragraph apart by it. A document that loses them is one whose comments no longer resolve.
textId?
string | undefined
`w14:textId`: Word's hash of the paragraph's text, used to spot changes.
openFields?
readonly string[] | undefined
The complex fields an earlier paragraph began and had not ended when this one begins, by type, outermost first. A field is a flat run of `w:fldChar` marks, and nothing keeps it inside one paragraph: a table of contents opens in its first entry and closes after its last, a hundred paragraphs on. Each paragraph reads its own fields and closes whatever is still open at its end, so without this every entry after the first stood outside the field that made it. And that is a difference Word draws. Inside a `TOC` field an entry's hyperlink does not take the `Hyperlink` style: `toc-hyperlink-*`, four probes of one contents page, print the entries black and plain with the field and blue and underlined without it — whether or not a content control is wrapped round them.
ParagraphProperties
interface ParagraphProperties

Paragraph-level formatting, `w:pPr`.

style?
string | undefined
`w:pStyle`: the paragraph style this paragraph is written against.
alignment?
Alignment | undefined
indentLeftTwips?
number | undefined
Left indent in twips; `w:start` in newer files.
indentRightTwips?
number | undefined
indentFirstLineTwips?
number | undefined
First-line indent in twips. Mutually exclusive with {@link indentHangingTwips}: Word writes one or the other, and a hanging indent is a negative first-line indent applied together with a matching left indent.
indentHangingTwips?
number | undefined
indentLeftChars?
number | undefined
The same four indents in hundredths of a character, `w:leftChars` and kin. A character is as wide as the paragraph's font makes it, which is why East Asian documents measure indents this way: two characters must stay two characters at any size. Word prefers this form where both are written, and only the renderer knows the font size that turns it into a length.
indentRightChars?
number | undefined
indentFirstLineChars?
number | undefined
indentHangingChars?
number | undefined
spaceBeforeTwips?
number | undefined
spaceAfterTwips?
number | undefined
spaceBeforeLines?
number | undefined
The same space stated in hundredths of a line, `w:beforeLines`. A "line" is Word's nominal one — 240 twentieths of a point — not the height the paragraph's own type happens to need, and the line units win over the points where a paragraph states both.
spaceAfterLines?
number | undefined
spaceBeforeAuto?
boolean | undefined
Automatic spacing overrides the explicit value when set.
spaceAfterAuto?
boolean | undefined
lineSpacing?
number | undefined
Line spacing; interpretation depends on {@link lineSpacingRule}.
lineSpacingRule?
LineSpacingRule | undefined
contextualSpacing?
boolean | undefined
Suppress spacing between paragraphs of the same style, `w:contextualSpacing`.
keepNext?
boolean | undefined
wordWrap?
boolean | undefined
Whether a line may break only between words, `w:wordWrap`. On by default and interesting only when a paragraph turns it off: Word then breaks a line inside a word rather than let it hang past the margin. A narrow column of a URL, a table cell holding a long identifier, and East Asian text set in a measure narrower than one of its words all rely on it — without it the word overhangs the column and the page reads as one whose text does not fit its own frame.
autoSpaceLatin?
boolean | undefined
Space automatically inserted between East Asian and Latin text, `w:autoSpaceDE`; and between East Asian text and digits, `w:autoSpaceDN`. Both are on unless the paragraph turns them off, which is why they are modelled as "off when false" rather than "on when true".
autoSpaceNumeric?
boolean | undefined
snapToGrid?
boolean | undefined
Whether the paragraph's lines sit on the document grid, `w:snapToGrid`. On unless the paragraph says otherwise, and only meaningful where the section declares a grid.
keepLines?
boolean | undefined
pageBreakBefore?
boolean | undefined
widowControl?
boolean | undefined
suppressAutoHyphens?
boolean | undefined
suppressLineNumbers?
boolean | undefined
bidi?
boolean | undefined
kinsoku?
boolean | undefined
East Asian line-breaking rules, `w:kinsoku`. On by default, and what stops a line from ending in an opening bracket or beginning with a full stop. CSS says the same thing as `line-break`, so the rule reaches the page rather than only the model.
overflowPunctuation?
boolean | undefined
`w:overflowPunct`: punctuation may hang past the margin rather than wrap.
topLinePunctuation?
boolean | undefined
`w:topLinePunct`: punctuation is compressed at the start of a line.
adjustRightIndent?
boolean | undefined
`w:adjustRightInd`: the right indent is adjusted to the document grid. Only meaningful with `w:docGrid`, which is what makes it an East Asian setting written into western documents by every converter that has ever touched one.
suppressOverlap?
boolean | undefined
`w:suppressOverlap`: a framed paragraph may not overlap another.
borders?
Borders | undefined
shading?
Shading | undefined
tabs?
readonly TabStop[] | undefined
numbering?
NumberingReference | undefined
List membership, `w:numPr`.
outlineLevel?
number | undefined
Outline level 0..8 as stored; 9 means body text.
markRunProperties?
RunProperties | undefined
Formatting of the paragraph mark itself, `w:pPr/w:rPr`.
conditionalFormatting?
ConditionalFormatting | undefined
Conditional formatting flags inherited from the table style.
textAlignment?
"auto" | "center" | "top" | "bottom" | "baseline" | undefined
revision?
RevisionInfo | undefined
Set when the paragraph mark is part of a tracked change.
frame?
FrameProperties | undefined
Frame properties for a text frame, `w:framePr`.
ParagraphSpacing
interface ParagraphSpacing

A paragraph, as far as the space around it is concerned.

before?
number | undefined
`w:spacing/@w:before`, in twips.
after?
number | undefined
`w:spacing/@w:after`, in twips.
beforeLines?
number | undefined
The same space in hundredths of a line, `w:beforeLines`, which wins. The line is Word's nominal one — {@link NOMINAL_LINE_TWIPS} — and not the one the paragraph's type needs. `spacing-in-line-units` says both halves of that outright: eleven-point Calibri, whose own line is 17.92px, is given 16.03px for `w:beforeLines="100"` — 240 twips — and the same 16.00px again where the paragraph is set in twenty-two point. A paragraph stating a hundred lines *and* 1200 twips is given the lines.
afterLines?
number | undefined
beforeAuto?
boolean | undefined
`w:beforeAutospacing`, which overrides whatever the paragraph stated. Word's HTML spacing: {@link AUTO_SPACING_TWIPS} whatever the type and whatever `w:before` says. `autospacing-between-paragraphs` states 100 twips beside the flag and Word gives 18.7px — fourteen points.
afterAuto?
boolean | undefined
autoIsFixed?
boolean | undefined
`w:doNotUseHTMLParagraphAutoSpacing`: the paragraph's own twips instead, and both spaces of a seam paid rather than the larger; see {@link paragraphGapOf}. "Use fixed paragraph spacing for the HTML auto setting" — the document says that {@link ParagraphSpacing.beforeAuto} is to be read as whatever `w:before` states rather than as Word's HTML fourteen points. 24 documents of the corpus declare it, and none of them turns on it: 1608 exact page counts and 45 pages of error either way. Carried because it is a rule, not because the corpus asked.
numberingId?
number | undefined
The list this paragraph is an item of, where it is one. Automatic spacing is dropped *between* items of one list and kept at its edges: `autospacing-in-a-list` steps 36.5px into the first item, 17.92px — a bare line — between the items, and 36.6px out of the last.
borderTop?
ParagraphBorder | undefined
The paragraph's own top and bottom borders, where it draws them. A border is drawn outside the text and takes its own width plus the space it asks for. `paragraph-border-space` puts three of them at 0, 11 and 31 points of space under one `w:sz="12"` rule — an eighth-point unit, so a line 1.5pt wide — and Word steps 1.95px, 16.64px and 43.36px more than a bare line, which is that width plus that space each time.
borderBottom?
ParagraphBorder | undefined
contextual?
boolean | undefined
`w:contextualSpacing`: suppress this paragraph's own space beside its like.
style?
string | undefined
The style it names, which is what "the same style" is decided on.
PictureBullet
interface PictureBullet

A picture used as a bullet, `w:numPicBullet`.

id
number
relationshipId
string | undefined
Relationship id of the image.
widthEmu
number | undefined
heightEmu
number | undefined
title
string | undefined
`v:imagedata/@o:title`: the picture's own name, which Word shows as a tip.
PictureFill
interface PictureFill

A picture used as a fill rather than drawn as itself, `a:blipFill`.

kind
"picture"
relationshipId
string
crop
{ left: number; top: number; right: number; bottom: number; } | undefined
`a:srcRect`, as fractions of the source size.
mode
"stretch" | "tile"
`a:stretch` fills the box with one copy; `a:tile` repeats the picture. The distinction is not decoration: a tiled logo at its natural size and the same logo stretched over a full-width banner are different pictures on the page, and the tiled one is what a watermark and every textured panel use.
tileScaleX
number | undefined
Scale of one tile, from `a:tile/@sx` and `@sy`, as a fraction.
tileScaleY
number | undefined
PictureNaming
interface PictureNaming
next
() => number
A number unique within the part, for `wp:docPr/@id`. Word will open a document whose drawings share an id, and its own repair dialogue will offer to fix it; a counter costs nothing and avoids the question. The caller holds it because it has to be unique across the part and this function sees one drawing.
PictureOptions
interface PictureOptions
width?
number | undefined
How wide and tall to draw it, in **points**. Points because that is the unit the rest of this model states type and spacing in, and because the format's own unit — the English Metric Unit, 914 400 to the inch — is not one anybody wants to type. Give {@link widthEmu} instead where an exact value matters.
height?
number | undefined
widthEmu?
number | undefined
heightEmu?
number | undefined
description?
string | undefined
The alternative text, which is the one part of a picture a person writes. Strongly worth giving: it is what a reader with a screen reader gets instead of the picture, and what a search finds.
mimeType?
string | undefined
The content type; sniffed from the bytes when it is not given.
PicturePlacement
interface PicturePlacement

What a run's picture is and how big it should be drawn.

id
string
The name {@link MediaStore.url} resolves.
widthTwips
number
heightTwips
number
crop
{ left: number; top: number; right: number; bottom: number; } | undefined
look
ShapeLook | undefined
How to draw it, when what is in the line is a shape rather than a picture.
Piece
interface Piece
span
number
Which span of the paragraph the piece was cut from, and where in it. The rules here need neither, and carry them so that the caller can put a chosen line back where it came from: the browser path turns them into a DOM position, a layout computed in Node into an offset in the model. A box spans no text and reports `from === to === 0`.
from
number
to
number
label?
boolean | undefined
The piece is part of a list's label, not of its text. A label is set at the head of the paragraph's first line and the text follows it there; a line holding the label and nothing else is not a line Word draws. `chooseLines` will not close one.
eastAsianSeam?
boolean | undefined
The break before the piece is one between two characters, either of them East Asian, and not one a space or a Latin rule opened. Word does not take such a break on a line that could end at a space instead; see where `chunk` is built in {@link chooseLines}.
width
number
Advance in pixels, including the spaces that end it.
widthAt?
((x: number) => number) | undefined
The advance, where the box's is decided by where it lands. See {@link BoxSpan.widthAt}.
hangAt?
((x: number) => number) | undefined
How far what follows the box is painted past the line's edge. See {@link BoxSpan.hangAt}.
leaderAt?
((x: number) => { readonly glyph: string; readonly width: number; readonly run?: unknown; } | undefined) | undefined
What the box draws across itself, where it draws anything.
inkWidth
number
Advance without those spaces: what a line's fit is judged on.
hangWidth?
number | undefined
How much of the ink at the piece's end could hang outside the column. Kept and not used, because the corpus refused it. `w:overflowPunct` — "allow punctuation to extend past the right margin" — is on unless a document turns it off, and it looked like the explanation for Word's own lines being wider than the column they are set in, which the justification allowance is otherwise standing in for. It is not. Let the stops and commas hang *and* keep the allowance and this engine fits more than ever — 715 lines broken late against 650. Let them hang *instead* of the allowance and it is worse still: 1228 exact page counts against 1244, 107 420 lines on their page against 110 302, and the early breaks more than double. So whatever Word is doing when it sets a line past its column, it is neither hanging its punctuation nor doing it to every line that ends in a comma. The measured allowance stays, and this stays measured and unused.
sliceWidth?
((from: number, to: number) => number) | undefined
How wide a part of this piece's own text is, for the one break Word makes inside a word: see the emergency cut in {@link chooseLines}.
endsLineAt?
((x: number) => boolean) | undefined
Whether this piece ends the line it lands on, given where it lands. A tab sent to a stop outside the column does: Word cannot honour the stop on this line and does not try again on the next — it ends the line there. See {@link TabAdvance.unreachable }.
wrapsAt?
((x: number) => boolean) | undefined
Whether the piece begins the next line instead, given where it would land.
fillsLineAt?
((x: number) => boolean) | undefined
Whether the piece fills its line to the margin, leaving the mark nowhere.
spaceWidth?
number | undefined
kernBefore?
number | undefined
The kerning between the last character before this piece and its first. A piece is measured on its own, and a canvas kerns only inside the string it is given, so the pair that straddles the seam is lost. Over a line of thirty words that is most of a pixel — small, but it lands exactly where it hurts: a line Word fills to the margin comes out wider than the column and gives up its last word. Charged to the piece on the right of the seam, and dropped when that piece begins a line, where there is no pair to kern. Absent where there is no seam to speak of: an object, a break, an inset.
gapBefore?
number | undefined
The East Asian gap before this piece; see {@link LineSpan.gapAt }.
wideCount?
number | undefined
How many full-width characters the piece holds; see `SQUEEZE_OF_EAST_ASIAN`.
spaces
number
Spaces inside it that justification may stretch or squeeze.
trailingSpaces
number
How many of those spaces end it, and so hang past the margin.
breakBefore
boolean
Whether a line may begin here.
breakAfter
boolean
Whether the line must end here — an explicit `<w:br/>`.
fontSize
number
Type size of the text, which bounds how far a line may be compressed.
squeezableEm?
number | undefined
How much of the piece is the blank half of an East Asian punctuation mark. **Nothing sets it, because Word does not take that half back to fit another character on the line.** A full-width comma, stop or bracket is a half-width glyph drawn inside a full em, the other half is the space the composition rules put beside it, and `w:characterSpacingControl` — whose default is `compressPunctuation` — reads as if Word reclaimed it when a line needed the room. Twelve probes say it does not. `punctuation-compress-*` set MS 明朝 at twelve point — a fixed-width face, 240 twips to the character, marks included — in a column exactly twenty characters wide, and hand it twenty-one characters of which two are marks. Half an em apiece would bring the line back to exactly twenty ems and the twenty-first character would fit. Word puts **twenty** characters on the line and sends the twenty-first down, in every configuration asked: two commas, two stops, two brackets, a comma and a bracket, two middle dots; `doNotCompress` and `compressPunctuationAndJapaneseKana` beside the default; with the run declared Japanese and without; flush left, justified and distributed. `-one-comma` asks it once more in a column half a character wider, where a single mark's half is the whole of the difference, and the answer is the same. `-plain` is the calibration and reads twenty. So the setting is about how the marks are *drawn* — Word's own description is "compress punctuation", not "compress the line" — and not about where a line ends. The corpus had suggested otherwise, and every reading built on it split three documents won against three lost; see the git history for the five that were tried. Kept as a field because the fit still honours it: anything that finds a case where Word does reclaim the half has somewhere to put it.
punctuationCap?
number | undefined
The most a line holding this piece may take back from its marks, in all.
hangOrSqueeze?
boolean | undefined
A line holding this piece may hang its last mark or squeeze its marks, not both.
hyphenAfter?
number | undefined
What a line ending here owes for the hyphen it would draw, in pixels. Set on the piece *before* a hyphenation point and nowhere else, so its presence is the whole statement: the next piece is the rest of a word this one began, a line that stops here draws a hyphen, and a line that runs through draws nothing. See where the points are found in {@link piecesOf}. The width is the face's own hyphen at the run's size, which is the face the mark is drawn in — the fragment before the break is what carries it, and a word that changes face mid-way changes it after the mark.
PlacedStop
interface PlacedStop

A tab stop placed on the column's ruler.

x
number
Position on the ruler, in pixels from the column's left edge.
alignment
string
leader?
string | undefined
Plex
interface Plex<T>

A plex: the one container the binary format uses for everything positional. Sections, fields, bookmarks, footnotes, the bin tables — all of them are the same shape. A run of `n + 1` positions in ascending order, and then `n` fixed-size structures, one for each of the intervals the positions cut the document into. Nothing in the file says how many elements there are: the count follows from the total length and the size of one structure, which is knowledge the reader has to bring. positions: 0 120 400 400 980 data: [0] [1] [2] [3] Two of these intervals in the illustration are worth noticing. `[2]` is empty, which happens and is not corruption; and the last position is the end of the last interval, not the start of a further one.

positions
readonly number[]
`n + 1` boundaries, in the units the plex is addressed by.
data
readonly T[]
`n` structures, one per interval.
length
number
Rect
interface Rect

A rectangle, in whatever coordinate space its owner counts in.

left
number
top
number
right
number
bottom
number
ResolvedStyle
interface ResolvedStyle

The fully resolved property sets of a style chain.

paragraph
ParagraphProperties
run
RunProperties
table
TableProperties
row
RowProperties
cell
CellProperties
chain
readonly Style[]
The chain itself, from the requested style up to the root.
RevisionInfo
interface RevisionInfo

Tracked-change metadata attached to a run, paragraph mark, row or cell.

type
"inserted" | "deleted" | "formatChange" | "moveFrom" | "moveTo"
id
string | undefined
author
string | undefined
date
string | undefined
RevisionNode
interface RevisionNode

A tracked insertion or deletion wrapping inline content.

kind
NodeKind.Revision
revision
RevisionInfo
children
readonly InlineNode[]
RowHeight
interface RowHeight

`w:trHeight`: how tall a row is, and how strictly. One object, because the element is replaced whole: a row that states a height cancels the style's rule along with the style's height, and two flat fields would let the rule survive the value it belongs to.

twips?
number | undefined
`w:val`, in twips.
rule?
"auto" | "exact" | "atLeast" | undefined
`w:hRule`, where the row states one. Absent is `atLeast` and not the `auto` the specification names — see `layout/table-row.ts`, where that is measured rather than assumed.
RowInput
interface RowInput
ref?
unknown
What whoever built this wants back when it is drawn; see {@link PieceRef}.
cells
readonly CellInput[]
align?
"left" | "center" | "right" | undefined
`w:trPr/w:jc`: where this row stands, where it differs from the table.
cantSplit?
boolean | undefined
`w:cantSplit`: the row may not be divided between two pages.
height?
RowHeight | undefined
`w:trHeight`.
margins?
RowMargins | undefined
The room the cells keep above and below their content, in twips. Word's own default is nothing at all — `table-row-height-bare` rules a row of one line at exactly the height of that line — so a table that states no vertical cell margin gets none.
header?
boolean | undefined
`w:tblHeader`: the row repeats at the top of every page the table reaches.
gridBefore?
number | undefined
`w:gridBefore`: grid columns the row leaves empty before its first cell. A row that begins part-way across the table. Read as nought its first cell took the first column's width, which in `table_gridbefore` is 73 twips against the 2272 the cell states — five pixels of room for a paragraph, and with a word cut to fit it the document came out five pages against one.
widthBeforeTwips?
number | undefined
`w:wBefore`: how wide those skipped columns are, in twips. The standard attaches the element to `w:gridAfter`; [MS-OI29500] §2.1.184 a says Word reads it against `w:gridBefore`, which is the only reading under which a row that starts short starts where the file says. Absent, the grid decides.
ruleAbovePoints?
number | undefined
The horizontal rule drawn above this row, in points. A row is taller than its content by the width of the rule above it, and the content sits below that rule. `table-row-height-rule-4/8/12/24/48` measures it and the answer is exactly linear: a table of eight one-line rows in eleven-point Times steps 253 twips a row bare, and 253 plus the stated width with a rule — half a point for `w:sz="4"`, six points for `w:sz="48"`, and the three between them on the same line. The first baseline moves down by the table's own top rule by the same amount. `w:sz` is in eighths of a point; this is points, because that is what the geometry is in and a conversion belongs to whoever reads the document.
RowMargins
interface RowMargins

The room a cell keeps above and below its content, in twips.

top?
number | undefined
bottom?
number | undefined
RowProperties
interface RowProperties

Row-level formatting, `w:trPr`.

height?
RowHeight | undefined
header?
boolean | undefined
`w:tblHeader`: repeat this row as a header on every page.
cantSplit?
boolean | undefined
Forbid splitting the row across pages, `w:cantSplit`.
gridBefore?
number | undefined
Grid cells skipped before the first cell, `w:gridBefore`.
gridAfter?
number | undefined
widthBefore?
Measurement | undefined
widthAfter?
Measurement | undefined
alignment?
Alignment | undefined
cellSpacing?
Measurement | undefined
hidden?
boolean | undefined
conditionalFormatting?
ConditionalFormatting | undefined
revision?
RevisionInfo | undefined
tableExceptions?
TableProperties | undefined
Table properties this row overrides, `w:tblPrEx`. Word writes them when rows of one table came from two tables that were joined: the second keeps its own borders, cell margins and indent, and the table's own `w:tblPr` no longer describes it. Read as the table's, such a row draws the wrong rules and sits at the wrong indent — and since the overrides are almost always borders, the visible result is a table whose lower half is gridded and whose upper half is not.
RunningInput
interface RunningInput

What is drawn on every page: the running head and foot. They are the page's, not the flow's, and they decide how much of the page the flow gets. Word's body begins at the *later* of the top margin and the foot of the head, and ends at the earlier of the bottom margin and the head of the foot — so a head taller than its margin pushes the text down and takes a line off every page of the document.

header?
readonly BlockInput[] | undefined
footer?
readonly BlockInput[] | undefined
titlePage?
boolean | undefined
`w:titlePg`: the first page of the section carries its own pair. Where the section declares a `first` header this is that header; where it declares none — which is the commoner half of the corpus — the first page carries **nothing**, and its body begins at the top margin rather than below a head that is not there. A title page given the ordinary head loses a line at the top of every page that follows it, because the section's first page break then falls in the wrong place.
firstHeader?
readonly BlockInput[] | undefined
firstFooter?
readonly BlockInput[] | undefined
evenAndOdd?
boolean | undefined
`w:evenAndOddHeaders`: the left-hand pages carry their own pair. A document setting rather than a section one, but it is answered here because it is the same question — which of the section's heads this sheet carries. Page one is odd, and the parity is counted over the document and not over the section: Word numbers the sheets, not the parts.
evenHeader?
readonly BlockInput[] | undefined
evenFooter?
readonly BlockInput[] | undefined
noteSeparator?
readonly BlockInput[] | undefined
An empty paragraph in the document's own default type. The footnote separator is a paragraph holding a rule and it costs the page one line — but a line of *which* type is not obvious, and the probes `footnote-separator-taller` and `-shorter` answer: the document's default, neither the notes' type nor the separator paragraph's own. This engine is given resolved paragraphs and cannot ask what the default is, so whoever builds the blocks says it here.
noteSeparatorDeclared?
boolean | undefined
{@link RunningInput.noteSeparator} is the document's own separator, named in its settings, and costs its whole height — spacing and every line — not one line of it.
noteNotice?
boolean | undefined
`w:footnotePr/w:footnote`: the document declares a continuation notice. Word keeps a line for it at the foot of every page that carries notes, whether or not a note runs on — the notes are drawn a line higher and the body gets a line less. `footnote-notice-declared` puts its note at 1004.77 where `-undeclared` and `-absent` put theirs at 1022.69, and a notice written into `footnotes.xml` that the settings do not name costs nothing.
RunProperties
interface RunProperties

Character-level formatting, `w:rPr`.

style?
string | undefined
`w:rStyle`: the character style this run is written against.
fonts?
FontReference | undefined
bold?
boolean | undefined
boldComplex?
boolean | undefined
italic?
boolean | undefined
italicComplex?
boolean | undefined
caps?
boolean | undefined
smallCaps?
boolean | undefined
strike?
boolean | undefined
doubleStrike?
boolean | undefined
outline?
boolean | undefined
shadow?
boolean | undefined
emboss?
boolean | undefined
imprint?
boolean | undefined
hidden?
boolean | undefined
Hidden text, `w:vanish`.
webHidden?
boolean | undefined
color?
Color | undefined
sizeHalfPoints?
number | undefined
Font size in half-points, `w:sz`.
sizeComplexHalfPoints?
number | undefined
underline?
Underline | undefined
highlight?
string | undefined
Named highlight colour, `w:highlight`.
shading?
Shading | undefined
border?
Border | undefined
spacingTwips?
number | undefined
Character spacing in twips, `w:spacing`; may be negative.
scalePercent?
number | undefined
Horizontal scaling as a percentage, `w:w`.
positionHalfPoints?
number | undefined
Baseline offset in half-points, `w:position`; positive raises the text.
kerningHalfPoints?
number | undefined
Minimum size in half-points at which kerning applies, `w:kern`.
verticalAlign?
"baseline" | "superscript" | "subscript" | undefined
rtl?
boolean | undefined
Right-to-left run, `w:rtl`.
emphasisMark?
"none" | "dot" | "comma" | "circle" | "underDot" | undefined
Emphasis mark placed above or below the text, `w:em`.
language?
string | undefined
Language tags, used for spell-check and for correct hyphenation.
languageEastAsia?
string | undefined
languageComplex?
string | undefined
fitTextTwips?
number | undefined
Text is stretched to fit the given width in twips, `w:fitText`.
snapToGrid?
boolean | undefined
`w:snapToGrid`: the run's characters sit on the document grid.
textOutline?
TextOutline | undefined
`w14:textOutline`: the glyphs are drawn as outlines. A heading set in outline and one set solid are the same markup apart from this element, and dropping it paints a hollow title in solid black.
textFill?
Fill | undefined
`w14:textFill`: what the inside of the glyphs is painted with.
textShadow?
ShapeShadow | undefined
`w14:shadow`: the one text effect a page draws without a filter.
glow?
TextGlow | undefined
`w14:glow`: a coloured halo around the glyphs.
reflection?
TextReflection | undefined
`w14:reflection`: a mirrored copy of the text below it.
properties3d?
TextProperties3D | undefined
`w14:props3d`: the bevels and the material the glyphs are extruded in.
scene3d?
TextScene3D | undefined
`w14:scene3d`: the camera and the lighting the extrusion is seen under.
ligatures?
string | undefined
`w14:ligatures`: which OpenType ligature sets the run asks for. `none`, `standard`, `contextual`, `historical`, `discretional` and the combinations of them. It only shows in a face that ships the feature, which is why nothing draws it — and why a document that asks for it must not come back having stopped asking.
numberForm?
string | undefined
`w14:numForm`: `lining` or `oldStyle` figures.
numberSpacing?
string | undefined
`w14:numSpacing`: `tabular` or `proportional` figures.
stylisticSets?
readonly number[] | undefined
`w14:stylisticSets`: the `ss01`..`ss20` sets asked for, by number.
contextualAlternates?
boolean | undefined
`w14:cntxtAlts`: contextual alternates, on unless the run says otherwise.
effect?
string | undefined
`w:effect`: the animated text effects of Word 6. `blinkBackground`, `lights`, `antsBlack`, `antsRed`, `shimmer`, `sparkle`. Word stopped drawing them in 2007 and still reads and writes them.
noProof?
boolean | undefined
`w:noProof`: the run is not to be spell-checked.
complexScript?
boolean | undefined
`w:cs`: the run is set in a complex script. Which of two sets of properties applies to it — `w:bCs` and `w:iCs` rather than `w:b` and `w:i`, and the complex-script size rather than `w:sz`.
revision?
RevisionInfo | undefined
Set when the run is inside a tracked insertion or deletion.
propertiesChange?
PropertiesChange | undefined
`w:rPrChange`: what the run looked like before somebody reformatted it. A tracked *formatting* change, which is neither an insertion nor a deletion: the words are the same and the properties are not. The element carries who changed them and when, and the whole of the previous `w:rPr` inside it — which is what "reject this change" puts back. Nothing draws it: the page shows the formatting that applies now. It is held because a document saved without it has silently accepted every formatting change in it.
SavableDocument
interface SavableDocument extends DocxDocument

What a save needs of a document, beyond the model. Stated as a structural type rather than taken from the class, so that a document produced by an edit — which is not that class — can be saved by the same code.

media?
DocumentMedia | undefined
The pictures the document holds outside a package, where it holds any. A `.docx` has none — its media are parts, and parts are copied through. A `.doc` keeps its pictures in the binary file's own store, and a document built by a caller keeps them wherever the caller put them. See `write/media.ts`.
charts?
ReadonlyMap<string, ChartDefinition> | undefined
Charts the package does not hold, by the relationship id their frames name. A chart read from a `.docx` is a part that a save copies through, and none of it reaches here. This is for the other case: a chart a caller *made*, which has a definition and no part, and where the whole of `chart1.xml` has to be produced. See `write/chart.ts`.
package?
OpcPackage | undefined
mainPartName?
string | undefined
SaveOptions
interface SaveOptions
bodyChanged?
boolean | undefined
Whether the body was changed since it was read. The default is to work it out: a document nobody has edited still holds the span of its own body, and copying it is both exact and instant. An edit layer that knows better says so.
compress?
boolean | undefined
Compress the parts this save produces. On by default.
stories?
readonly StoryEdit[] | undefined
Stories other than the body that were changed; see {@link StoryEdit}. Absent, a save writes the main part and copies every other. Given, the parts those stories live in are rewritten whole from the model — a notes part holds every note of the document, so changing one writes all of them.
SaveResult
interface SaveResult
bytes
Uint8Array<ArrayBufferLike>
lost
ReadonlyMap<string, number>
What had to be written from the model although it came from the file. Empty on every save of an unedited document. An entry means a node carried a span that could not be read back — a package that has been disposed, or a document opened with preservation off — and what it held may not have survived.
SectionProperties
interface SectionProperties
start
SectionStart
pageSize
PageSize
margins
PageMargins
columns
Columns
pageBorders
PageBorders | undefined
pageNumbering
PageNumbering | undefined
lineNumbering
LineNumbering | undefined
headers
readonly HeaderFooterReference[]
footers
readonly HeaderFooterReference[]
titlePage
boolean
The first page uses a distinct header and footer, `w:titlePg`.
verticalAlignment
"both" | "center" | "top" | "bottom" | undefined
Vertical alignment of text on the page, `w:vAlign`.
rtl
boolean
Right-to-left section, `w:bidi`.
documentGrid
DocumentGrid | undefined
`w:docGrid`: the grid East Asian setting places its characters on.
textDirection?
string | undefined
The direction the section's text runs in, `w:textDirection`. `tbRl` and `tbRlV` are vertical setting: the lines run top to bottom and the columns right to left, so the page's width and height swap roles. It is a property of the section rather than of any paragraph in it.
footnoteProperties?
SectionNoteProperties | undefined
Footnote and endnote numbering stated for this section alone.
endnoteProperties?
SectionNoteProperties | undefined
suppressEndnotes?
boolean | undefined
`w:noEndnote`: endnotes are suppressed in this section.
formProtection?
boolean | undefined
`w:formProt`: everything in the section but its form fields is locked. Nothing on the page shows it and everything about editing the document does: a section that loses it is a form whose text a reader can now type over. Fifty-seven documents in three hundred state it.
rtlGutter?
boolean | undefined
`w:rtlGutter`: the binding gutter is on the right edge, not the left.
Shading
interface Shading
pattern
ShadingPattern | undefined
fill
string | undefined
Background colour as `RRGGBB`, or `auto`.
color
string | undefined
Pattern foreground colour.
themeFill
string | undefined
themeFillTint
string | undefined
Lightening applied to `themeFill`, `w:themeFillTint`; `FF` means none.
themeFillShade
string | undefined
Darkening applied to `themeFill`, `w:themeFillShade`; `FF` means none.
themeColor
string | undefined
themeTint
string | undefined
Lightening applied to `themeColor`, `w:themeTint`.
themeShade
string | undefined
Darkening applied to `themeColor`, `w:themeShade`.
ShapeAnchor
interface ShapeAnchor

An anchor: where a shape sits, and how the text behaves around it.

spid
number
Which shape, by the identifier the drawing gives it.
left
number
The rectangle it occupies, in twips.
top
number
right
number
bottom
number
wrap
"none" | "square" | "tight" | "through" | "topAndBottom"
How text flows around it.
relativeFromH
"page" | "column" | "margin"
What the horizontal position is measured from.
relativeFromV
"page" | "paragraph" | "margin"
And the vertical, which has a different set of answers.
behindText
boolean
The shape is painted under the text rather than over it.
inHeader
boolean
The anchor is in a header story rather than the body.
ShapeContent
interface ShapeContent
writeBlocks
(blocks: DrawingNode["textBox"]) => void
Writes the blocks of a text box into the writer, where the shape has one.
ShapeLook
interface ShapeLook

How a shape is painted, when it is a shape rather than a picture.

geometry
string
The geometry, named the way DrawingML names it.
fill
string | undefined
Fill colour as `RRGGBB`, or nothing when the shape is unfilled.
lineColor
string | undefined
Outline colour, or nothing when there is no outline.
lineWidthEmu
number | undefined
Outline width in EMU.
ShapeShadow
interface ShapeShadow

An outer shadow cast by a shape, `a:effectLst/a:outerShdw`.

blurRadiusEmu
number
distanceEmu
number
directionDegrees
number
Degrees clockwise from east, the direction the shadow falls in.
color
ColorReference | undefined
scaleX?
number | undefined
`@sx`, `@sy`: the shadow scaled, in thousandths of a percent. A perspective shadow is one squashed to a fraction of its height and skewed; the four together are a matrix, and a `box-shadow` has none. Held because the file states it, drawn by nothing yet.
scaleY?
number | undefined
skewX?
number | undefined
`@kx`, `@ky`: skewed, in sixtieths of a thousandth of a degree.
skewY?
number | undefined
alignment?
string | undefined
`@algn`: which corner of the box the shadow is anchored to.
rotateWithShape?
boolean | undefined
`@rotWithShape`: the shadow turns when the shape does.
ShapeStyle
interface ShapeStyle

The visual style of a DrawingML shape.

geometry
string | undefined
`a:prstGeom/@prst`, or `custom` for a `a:custGeom`.
geometryDetail?
DiagramGeometry | undefined
The geometry as DrawingML states it: adjust values, or the outline itself. The name alone says a shape is not a rectangle; this says what it is, and it is the same record a slide and a worksheet carry, drawn by the same code. Before it, a chevron in a document was a box.
fill
Fill | undefined
outline
Outline | undefined
shadow?
ShapeShadow | undefined
`a:effectLst/a:outerShdw`, the only effect a page shows without a filter.
blackAndWhiteMode?
string | undefined
`@bwMode`: what the shape becomes when the document is printed in black. `auto`, `gray`, `ltGray`, `clr`, `black`, `white`, `hidden` and the rest of the twelve. Nothing here prints, so nothing draws it; Word writes it on almost every shape it saves and a shape that loses it has lost the author's answer to a question nobody asked yet.
extent?
{ readonly widthEmu: number; readonly heightEmu: number; } | undefined
`a:xfrm/a:ext` of a *turned* shape, which is not the drawing's extent. For an upright shape the two agree and the field is absent. For a turned one they cannot agree: `wp:extent` is the bounding box the drawing occupies *after* the rotation and `a:xfrm/a:ext` is the box the shape is drawn in before it — a tall label rotated ninety degrees states one as the other's transpose. Written back from the drawing's extent, a rotated shape comes back the wrong shape. Held only where the drawing is turned, and that is not tidiness: a member of a group holds its size in the *frame's* space — the reader maps it there and the writer declares the child space identical — while the extent it arrived with is in the group's own. Keeping both would be keeping one number in two coordinate systems and calling them the same thing.
locks?
ReadonlyMap<string, string> | undefined
`a:spLocks` or `a:picLocks`: what an editor may not do to this shape. Held as the attributes the element carried, because that is what it is: a row of switches whose names are the operations. None of them changes a pixel, and an editor that drops them lets the user resize a logo that was locked against it.
insets
{ left: number; top: number; right: number; bottom: number; } | undefined
Text insets of `wps:bodyPr`, in EMU.
wraps?
boolean | undefined
`wps:bodyPr@wrap`: false where the text of the box is not broken at all.
autoFits?
boolean | undefined
`a:spAutoFit`: the box fits itself to its text, and its stated extent is a leftover rather than a size.
verticalAlignment
"center" | "top" | "bottom" | undefined
Vertical anchor of the text inside the shape, `wps:bodyPr/@anchor`.
textDirection?
string | undefined
`wps:bodyPr/@vert`: the direction the text in the box is set in. A writing mode rather than a rotation — the lines still stack, they stack across the box instead of down it — which is what a title down the edge of a cover page is, and what a rotated `div` would get wrong.
fontColor
ColorReference | undefined
Colour the shape's theme reference gives its text, `a:fontRef`.
textBody?
TextBodyProperties | undefined
The rest of `wps:bodyPr`: the columns, the overflow, the odd compatibility switch. Read and thrown away until a census of the corpus counted the documents that state them.
themeStyle?
ShapeThemeStyle | undefined
`wps:style`: which slots of the theme's format scheme the shape takes.
Span
interface Span

The horizontal room a line has, in points.

left
number
right
number
Sprm
interface Sprm

One decoded property modifier.

opcode
number
The full sixteen-bit opcode, which is what a switch matches on.
kind
number
value
number
The operand as an unsigned integer, for the fixed-width forms.
operand
Uint8Array<ArrayBufferLike>
The operand's bytes, which is what the variable-width forms need.
StepResult
interface StepResult

What a step did, and how to undo it.

blocks
readonly BlockNode[]
inverse
Step
The step that puts things back exactly as they were.
touched
readonly number[]
The ids the step touched, for whoever memoises per node.
changed
boolean
Whether the tree actually changed.
StoryEdit
interface StoryEdit

One story of a document, changed, and which flow of text it is. A Word document is several flows and only one of them is the body: a running head is a part of its own, a footnote is one of many inside a part they share. Both are named rather than located — a relationship id for a running part, the note's own id for a note — because there is no longer any offset to locate them by. See `edit/session.ts`, which is where these come from.

kind
"footnote" | "endnote" | "footer" | "header"
id
string
The relationship id of a running part, or the id of a note.
blocks
readonly BlockNode[]
StoryRanges
interface StoryRanges

Where each story begins, in characters. The text of a document is one sequence of characters, and the stories are consecutive slices of it in a fixed order. Nothing marks the boundaries in the text itself: the counts in the header are the only thing that says where the body ends and the footnotes start.

main
readonly [number, number]
footnotes
readonly [number, number]
headers
readonly [number, number]
comments
readonly [number, number]
endnotes
readonly [number, number]
textboxes
readonly [number, number]
headerTextboxes
readonly [number, number]
end
number
One past the last character of the last story.
StrictMarkupOptions
interface StrictMarkupOptions

What strict mode refuses to walk past.

attributes?
boolean | undefined
Stop on an unaccounted attribute as well as an unaccounted element.
SttbEntry
interface SttbEntry

One entry: its text, and whatever fixed-size record followed it.

text
string
extra
Uint8Array<ArrayBufferLike>
Style
interface Style

A named style from `styles.xml`.

id
string
name
string
Display name, `w:name`; what the user sees in the Word style gallery.
type
StyleType
basedOn
string | undefined
Parent style id, `w:basedOn`.
next
string | undefined
Style applied to the following paragraph, `w:next`.
link
string | undefined
Paired character style of a paragraph style, `w:link`.
isDefault
boolean
customStyle
boolean
`@w:customStyle`: defined by the author rather than built into Word.
semiHidden
boolean
Hidden from the UI but still applicable.
visibility
StyleVisibility
What the styles pane does with it; see {@link StyleVisibility}.
paragraph
ParagraphProperties | undefined
run
RunProperties | undefined
table
TableProperties | undefined
row
RowProperties | undefined
cell
CellProperties | undefined
tableOverrides
readonly TableStyleOverride[]
Conditional blocks; present on table styles only.
StyleSheet
interface StyleSheet

The complete style table of a document. Holds both the named styles and the document defaults, which sit at the bottom of the cascade and are the reason an empty paragraph still has a font.

styles
ReadonlyMap<string, Style>
defaultParagraph
ParagraphProperties | undefined
`w:docDefaults/w:pPrDefault`.
defaultParagraphDeclared
boolean
Whether the package wrote a `w:pPrDefault` at all, empty or not. Not the same question as whether it holds anything. An empty element is a statement — the defaults are the format's own, single spaced with no gap — where its absence leaves the question to Word, which answers with the defaults of its blank template. See `BUILT_IN_PARAGRAPH_DEFAULTS`.
defaultRun
RunProperties | undefined
`w:docDefaults/w:rPrDefault`.
defaultStyleIds
Readonly<Record<StyleType, string | undefined>>
Id of the style marked default for each type.
byName
ReadonlyMap<string, Style>
Look-up by display name, needed because numbering references styles by name.
latentStyles
LatentStyles | undefined
`w:latentStyles`: what the styles nobody defined look like in the pane.
SymbolNode
interface SymbolNode

A character from a symbol font, `w:sym`.

kind
NodeKind.Symbol
font
string
char
number
Character code, usually in the private use area (0xF000 and up).
properties
RunProperties
TabAdvance
interface TabAdvance

What a tab advances by, and how far the text after it may hang.

width
number
The advance itself, never nought: a tab that collapsed would run words together.
beyond
number
How far the text after the tab is painted out over the right indent. Clamping the stop to the paragraph's box is what keeps the *wrap* Word's, and that is not negotiable. But the clamp was paying for the wrap with the position: the page number of every entry of an Australian statute's fifteen-page table of contents sat thirty-eight pixels left of Word's, on 147 pages of it. A *relative* shift is not a wider box — the line is laid out at the indent and the trailing text is then painted out over it, which is what hanging into the right indent looks like.
stop
PlacedStop | undefined
The stop it reached, where it reached a declared one.
wraps?
boolean | undefined
An implicit stop past the text area: the tab begins the next line.
unreachable
boolean
Whether the stop it was sent to lies outside the column altogether. A stop that *starts* its text — a left one — and stands past the right edge cannot be honoured on this line or on any other, and Word ends the line at it: `hu-4fd3c254b2ea`, a Hungarian domain application form, rules its fields with `<w:tab w:val="left" w:pos="9923"/>` in a column of 9922 twips — one twip short — and sets each of them on two lines. 43 documents of the corpus declare such a stop. Worth a page of error and 514 lines on Word's page: 1607 exact page counts either way, 47 pages of error against 48, and no document won or lost. The Hungarian form itself is not among them — it needs the *tab* moved down and not the line ended, and that reading is worse everywhere else (1606/48). Only where the stop starts the text. A right or decimal stop past the edge is Word setting the text *at* the edge, which is measured and is why the clamp exists at all.
fillsLine?
boolean | undefined
Whether the tab fills the line to the margin; see `tabAdvance`.
TableCellNode
interface TableCellNode
kind
NodeKind.Cell
id
number
Identity, for as long as the document is open. What an edit names and what an incremental relayout compares. Not an index: inserting a paragraph renumbers every index after it and leaves every id alone, which is the entire reason this is here. See `model/ids.ts`.
properties
CellProperties
children
readonly BlockNode[]
TableCellPosition
interface TableCellPosition

Where a cell sits in its table, used to select conditional formats.

rowIndex
number
columnIndex
number
rowCount
number
columnCount
number
headerRowCount
number
Number of header rows, which shifts band numbering.
explicit?
ConditionalFormatting | undefined
Explicit flags from `w:cnfStyle`, which override positional inference.
TableFloatPosition
interface TableFloatPosition
horizontalAnchor
string | undefined
verticalAnchor
string | undefined
x
number | undefined
y
number | undefined
xAlign
string | undefined
yAlign
string | undefined
leftFromTextTwips
number | undefined
rightFromTextTwips
number | undefined
topFromTextTwips
number | undefined
bottomFromTextTwips
number | undefined
TableInput
interface TableInput

A table, as far as the geometry is concerned. Rows are placed whole. Word will divide a row between two pages where the document allows it, and this does not: a row that will not fit starts the next page. It is the conservative half of the rule — the page it puts the row on is right whenever the row was not going to be divided, which is most rows of most tables — and it is honest about what it does rather than guessing at where inside a row the division would fall.

ref?
unknown
What whoever built this wants back when it is drawn; see {@link PieceRef}.
gridStated?
boolean | undefined
Whether `w:tblGrid` said anything the caller could use. `false` where {@link TableInput.grid} had to be invented — no grid, or one of nought-width columns — and the content-driven autofit takes over. See `table-width.ts` and `measureTable`.
kind
"table"
anchoredToSheet?
boolean | undefined
`w:tblpPr` anchored to the sheet or the margin, inside a running part. The body ignores this — a floating table there has been measured four times and costs the corpus every time (see {@link TableInput.rows}) — but a running part is not the body. It is not paginated, it exists to be drawn at a fixed place, and Word's own running feet are built this way: the foot of `policies-30ce1bb7535e` is one table with `<w:tblpPr w:vertAnchor="page" w:horzAnchor="page" w:tblpX="1418" w:tblpY="15761"/>` and two rows of an exact 340 twips. Charged to the foot those rows made it 45.3px tall and put the body's floor at 1030.0 where Word's is the page margin, 1047.0.
floating?
boolean | undefined
`w:tblpPr`: the table is out of the flow and anchored somewhere of its own. The engine reads {@link TableInput.floats} for the box; this says *why* there is one, which is what a comparison needs to separate a document whose tables float from one whose tables do not. Stated by whoever composes the blocks, because only that half has seen `w:tblpPr`.
pageBreakBefore?
boolean | undefined
`w:pageBreakBefore`, or a page break that ended the paragraph above it.
align?
"left" | "center" | "right" | undefined
`w:tblPr/w:jc`: where a table narrower than the column stands in it. Not the alignment of the text inside it — that is each paragraph's own — but of the table as a block. Read as `left` whatever it said, every centred table stood at the margin: `technical-dbc7409f423c` begins its rows 96 pixels left of Word's, `reference-2f22e0d5b12d` 113, and a row that begins in the wrong place has every line of it in the wrong place.
grid
readonly number[]
`w:tblGrid`, in twips, as the document states it.
layout?
"fixed" | "autofit" | undefined
`w:tblLayout`; absent is `autofit`, which is Word's default.
indentTwips?
number | undefined
`w:tblInd`, in twips.
indentStated?
boolean | undefined
Whether `w:tblInd` is written on the table rather than inherited. An indent a table *style* states is not inherited: `table-indent-from-the-style-720` draws exactly where `table-indent-nowhere` draws. See {@link tableEdgeIndentTwips}.
widthTwips?
number | undefined
`w:tblW` where the table states its width in twips.
ruleBelowPoints?
number | undefined
The rule closing the table, in points, which the last row is taller by. The counterpart of {@link RowInput.ruleAbovePoints}: every row carries the rule above it, and the bottom of the table has no row below to carry it. `table-row-height-rule-8` and `-48` put a line under the table and it sits 6.7px further down in the second — the six points against one that their bottom rules differ by. Charged to the last row, so that a table divided between two pages takes it to the page the last row lands on.
frameAbovePoints?
number | undefined
The table's own frame, top and bottom, in points: `w:tblBorders/w:top` and `w:bottom` as the style and the table resolve them. Asked for where a page divides the table. `table-rule-at-page-break-*`: Word draws the frame's bottom under the last part of the table on a sheet and the frame's top over the first part on the next, and it keeps room for both — the continuation's first line stands as far under the top as the table's own first line does, and a row divided at the foot leaves the bottom rule's width free under its last line.
frameBelowPoints?
number | undefined
ruleBesideTwips?
number | undefined
The vertical rule beside a cell, in twips — half of it on each side. See where `measureTable` spends it. Stated in twips rather than points because it is taken off a width, and widths in a table are twips.
cellSpacingTwips?
number | undefined
`w:tblCellSpacing`, in twips: the gap Word leaves around every cell. Stated as a half-gap. `table-cell-spacing-60` and `-240` measure it: a row of one line steps 253 twips with no spacing, 373 with sixty and 733 with two hundred and forty — 253 plus twice the value, which is the gap under one cell and over the next. The table's own edge adds the same again, so the first row's text sits twice the value below the top.
floats?
FloatInput | undefined
`w:tblpPr`: the table is drawn where its anchors say and the text runs past. Its box, in page pixels, exactly as {@link FloatInput} states one — the caller works out the anchors because only it knows the sheet. Absent, the table is in the flow, which is what all but a few are.
rows
readonly RowInput[]
TableLook
interface TableLook
firstRow
boolean
lastRow
boolean
firstColumn
boolean
lastColumn
boolean
noHorizontalBanding
boolean
When true, row banding is suppressed.
noVerticalBanding
boolean
TableNode
interface TableNode
kind
NodeKind.Table
id
number
Identity, for as long as the document is open. What an edit names and what an incremental relayout compares. Not an index: inserting a paragraph renumbers every index after it and leaves every id alone, which is the entire reason this is here. See `model/ids.ts`.
properties
TableProperties
rows
readonly TableRowNode[]
grid
readonly number[]
Column widths in twips from `w:tblGrid`.
TableOptions
interface TableOptions
header?
boolean | undefined
The first row is a header: repeated on every page and set in bold.
style?
string | undefined
The table style, `Table Grid` by default so the cells have rules.
widths?
readonly number[] | undefined
Column widths in twips; equal columns across the text area by default.
TableProperties
interface TableProperties

Table-level formatting, `w:tblPr`.

style?
string | undefined
`w:tblStyle`: the table style this table is written against.
width?
Measurement | undefined
alignment?
Alignment | undefined
indent?
Measurement | undefined
borders?
Borders | undefined
shading?
Shading | undefined
cellMargins?
CellMargins | undefined
Default cell margins, `w:tblCellMar`.
cellSpacing?
Measurement | undefined
Spacing between cells, `w:tblCellSpacing`.
layout?
"fixed" | "autofit" | undefined
`fixed` or `autofit`, `w:tblLayout`.
look?
TableLook | undefined
Which conditional formats the table style should apply, `w:tblLook`.
rowBandSize?
number | undefined
columnBandSize?
number | undefined
bidiVisual?
boolean | undefined
Right-to-left column order, `w:bidiVisual`.
caption?
string | undefined
description?
string | undefined
floatPosition?
TableFloatPosition | undefined
Floating table position, `w:tblpPr`.
allowOverlap?
boolean | undefined
`w:tblOverlap`: whether a floating table may be overlapped by another.
TableRowNode
interface TableRowNode
kind
NodeKind.Row
id
number
Identity, for as long as the document is open. What an edit names and what an incremental relayout compares. Not an index: inserting a paragraph renumbers every index after it and leaves every id alone, which is the entire reason this is here. See `model/ids.ts`.
properties
RowProperties
cells
readonly TableCellNode[]
paraId?
string | undefined
`w14:paraId`: the identity Word gives this row, eight hex digits. Not {@link id}, and the difference matters. `id` is minted by whoever read the document and means nothing outside this process; `paraId` is written into the file, survives it, and is what the rest of the package points at — `w15:commentEx` names the row a comment is anchored to by its `paraId`, and co-authoring tells two edits of one row apart by it. A document that loses them is one whose comments no longer resolve.
textId?
string | undefined
`w14:textId`: Word's hash of the row's text, used to spot changes.
TableStyleContext
interface TableStyleContext

Formatting contributed by a table style to the content of one cell.

paragraph
ParagraphProperties
run
RunProperties
cell
CellProperties
row
RowProperties
cacheKey
string
Identifies this context for caching.
TableStyleOverride
interface TableStyleOverride

One conditional block of a table style.

type
TableStyleOverrideType
paragraph
ParagraphProperties | undefined
run
RunProperties | undefined
table
TableProperties | undefined
row
RowProperties | undefined
cell
CellProperties | undefined
TableWidth
interface TableWidth

A width as `w:tblW` and `w:tcW` state one.

value
number
type
string
`dxa` twips, `pct` fiftieths of a per cent, `auto`, `nil`.
TabNode
interface TabNode
kind
NodeKind.Tab
properties
RunProperties
position?
{ readonly alignment: "left" | "center" | "right"; readonly relativeTo: string; readonly leader: string | undefined; } | undefined
An absolute position tab, `w:ptab`, which names a place rather than a stop. Ordinary tabs advance to the next stop on the ruler; this one goes to the left, the middle or the right of the text column whatever the ruler says, which is how a running head puts a title on the left and a page number on the right without either being declared anywhere.
TabRoom
interface TabRoom

Where a tab may take the text, and by what ruler.

contentWidth
number
The column's own width: the ruler the stops are measured on.
rightEdgeX
number
The paragraph's right edge on that ruler, which text may not pass. `w:ind w:right` says where the text wraps, and a tab stop is a position on the *column's* ruler that may sit past it. Word honours it there — the page number of a table-of-contents entry hangs into the indent while the title above it still wraps at the indent. CSS has no way to say that, so the two are separated: the text is placed inside this edge, and {@link * TabAdvance.beyond} says how far it may then be painted out over the indent.
marginRight
number
How far a stop may hang past that edge: the right indent and no further. `w:ind w:right` is the only thing a tab is allowed to reach over — the text hangs into the paragraph's own indent, never out of whatever holds the paragraph. Unbounded it reaches out of a table cell as readily as out of an indent: a French household roster sets a right stop at 8278 twips inside cells a tenth that wide, and its first two columns walked off the row.
defaultWidth
number
Word's interval between the stops nobody declared.
TabStop
interface TabStop

Tab stop, `w:tab`.

alignment
"start" | "end" | "left" | "center" | "right" | "bar" | "clear" | "decimal"
positionTwips
number
Position in twips from the left text margin.
leader
"none" | "dot" | "hyphen" | "underscore" | "heavy" | "middleDot" | undefined
Leader character drawn in the space before the stop.
TextBoxRanges
interface TextBoxRanges

Where each text box's words are, looked up two ways. Two ways because neither alone finds them all. A shape's `lTxid` property is an index into the plex — one-based, in its *high* sixteen bits, which is the kind of detail no specification sentence survives — and every shape in the corpus that carries one can be resolved that way: 509 of 509. The plex's own entries also carry the shape's identifier, which resolves 496 of the same 509, so it is kept as the second answer rather than the first.

byIndex
readonly (readonly [number, number])[]
By position in the plex, which is what a shape's text id names.
bySpid
ReadonlyMap<number, readonly [number, number]>
By shape identifier, which the plex entries state.
TextColumn
interface TextColumn
widthTwips
number | undefined
spaceTwips
number | undefined
TextNode
interface TextNode
kind
NodeKind.Text
text
string
properties
RunProperties
Formatting shared with other runs; interned by the parser.
TextPiece
interface TextPiece

A run of text, resolved: what it says and what it is set in.

ref?
unknown
See {@link PieceRef}: the painter's business, carried and not read.
text
string
label?
boolean | undefined
The piece belongs to a list's label rather than to its text. A label is not content of its own: Word sets it at the head of the paragraph's first line and the text follows it there. A line holding nothing else is not a line Word draws, so the line breaker is not allowed to close one — see `chooseLines`.
eastAsianLanguage?
string | undefined
`w:lang/@w:eastAsia`: the East Asian language the run is written in. Word applies the East Asian line-breaking rules to a run that names one and to no other — see {@link LineSpan.eastAsianTypography }, where the probe that settles it is described. Carried as the tag rather than as a flag so that the rule about which tags count lives in one place.
language?
string | undefined
`w:lang/@w:val`: the language the run is written in, for hyphenation. Set by the composer exactly where the document hyphenates this run — the setting is on, the paragraph does not suppress it and the run names a language — so its presence is the whole of the decision; see {@link PageSetup.hyphenation} and {@link LineSpan.language }.
kinsoku?
KinsokuSet | undefined
The characters this run may not begin or end a line with. ECMA-376 §17.3.1.16's lists, already chosen — `kinsokuSetFor` in `layout/kinsoku.ts` does the choosing, and three things decide it: the paragraph's `w:kinsoku`, which is on unless it says otherwise; the run's `w:lang/@w:eastAsia`, without which Word does not take the text for East Asian at all; and what `settings.xml` put in place of the defaults. Resolved by the caller rather than here for the same reason {@link TextPiece.overflowPunctuation} is: the caller holds `settings.xml` and the style hierarchy, and the layout holds neither.
characterLevelBreaks?
boolean | undefined
Whether a line of this run may end **inside** a word. `w:wordWrap w:val="off"` asks for it (ECMA-376 §17.3.1.45), and [MS-OI29500] §2.1.67 narrows it twice: Word honours it only where it finds Korean in the paragraph, and only for space-delimited languages. Both gates are the caller's, as above.
ideographWords?
boolean | undefined
See `LineSpan.ideographWords`.
eastAsianDocument?
boolean | undefined
The document names an East Asian face for its default, and Word lays it out as an East Asian document: `w:autoSpaceDE`'s quarter em is opened — `autospace-default-latin` against `-simsun` — and a line's last mark hangs — `east-asian-squeeze-for-kinsoku` against `-latin-default`. See `gapAt` and `hanging` where the line spans are built.
compressesPunctuation?
boolean | undefined
The document is East Asian and says `compressPunctuation`, so on a justified line a full-width mark may give back its blank half — see `LineSpan.compressiblePunctuation`.
keepAll?
boolean | undefined
Whether a line of this run may end only between words. Korean, which Word sets `keep-all`: see the pass of that name in `line-break.ts`. Resolved by the caller, which holds the run's language.
overflowPunctuation?
boolean | undefined
`w:overflowPunct`, where the paragraph turns the hanging off.
letterSpacingTwips?
number | undefined
`w:spacing` in a run's properties: extra room after every character. Word's "expanded" and "condensed" character spacing, in twips, positive or negative. It is not a style but a width — a heading set at twenty twips a letter is a fifth of an inch wider over thirty characters, and a line measured without it holds a word Word had to send down. 129 of the corpus's 734 real documents use it, across 79 413 runs.
kerns?
boolean | undefined
`w:kern`: whether this run's type is large enough to be kerned. The attribute states a size in half-points and means "kern at this size and above", so whether it applies is the caller's arithmetic and not the layout's. Unkerned text is wider than Word's, which is what the justification allowance in `line-break.ts` has been standing in for.
scalePercent?
number | undefined
`w:w`: the glyphs drawn at a percentage of their own width. Word's character scaling — a hundred is the face as drawn, fifty is half as wide, two hundred twice. It stretches the glyphs and not the room between them, which is why it multiplies the face's advance and leaves {@link TextPiece.letterSpacingTwips} alone.
family
string | undefined
sizeHalfPoints
number
Size in half-points, as `w:sz` states it.
bold
boolean
italic
boolean
eastAsian?
boolean | undefined
East Asian text, whose line the face does not decide.
emRatio?
number | undefined
Word's own line for the face, in ems, where the project has measured one.
lineSizeHalfPoints?
number | undefined
The size the line is ruled by, where it differs from the size drawn. A raised run — `w:vertAlign` — is drawn at about two thirds of what it states and rules the line by the whole of it; see where the caller sets this. Absent, the drawn size rules.
pageRef?
string | undefined
`PAGEREF`: the bookmark whose page this run's {@link PAGEREF_FIELD} shows. Carried on the piece rather than in the text because the name is not drawn — the number is — and because the page it resolves to is not known until every page has been placed.
styleRef?
string | undefined
`STYLEREF`: the style whose paragraph this run's {@link STYLEREF_FIELD} shows. A style *id*, resolved from the name the instruction gives while the style table is still to hand.
charStyle?
string | undefined
`w:rStyle`: the character style this run is set in, for `STYLEREF`. A `STYLEREF` may name a *character* style rather than a paragraph one, and then what it shows is the nearest run in it — which is how a running head assembles "Part 1A Control of liquor" out of two runs of a heading. Carried on the piece because that is where the run survives.
styleRefLast?
boolean | undefined
`STYLEREF l`: the last such paragraph on the page rather than the first.
styleRefCached?
string | undefined
What the file was saved with, for a style no paragraph on any page carries.
pageRefCached?
string | undefined
The digits the file was saved with, for a bookmark this document has not. Word prints `Error! Bookmark not defined.` there and the cache usually already says so; where it says a number instead, the number the author last saw is a better answer than nothing. The engine does not write that sentence itself — Word localises it, and guessing the language to guess the wording would be two guesses.
raisePoints?
number | undefined
`w:position`, in points: how far off the baseline the run is moved.
shiftPoints?
number | undefined
`w:vertAlign`, in points: how far the *drawn* glyph stands off the baseline. Apart from {@link raisePoints} because the two differ in what they cost: `w:position` grows the line by what it moves, and a superscript does not — it already rules its line by its full size, so the lift fits in room the line has. Whoever draws the run adds both; whoever measures the line takes only the first.
mark?
boolean | undefined
The paragraph mark, which stands in where the paragraph has no ink. It rules the line only where nothing typed can — see `tallestOf`.
TextSpan
interface TextSpan

A stretch of a paragraph set in one face, before it is cut into pieces. Measurement is a function rather than a number because the cutting decides what to measure: a piece is a slice of the span, and where the slices fall is not known until the break opportunities have been found. The browser path hands over a canvas closure, a layout computed in Node hands over the font file's own advances, and the rules below cannot tell which.

kind
"text"
text
string
eastAsianTypography?
boolean | undefined
Whether Word applies the East Asian line-breaking rules to this text. **Kinsoku is not a property of the script but of the run's declared language.** `punctuation-kinsoku-by-lang` is twenty ideographs and a full stop in a column exactly twenty ideographs wide, and Word's answer depends on one attribute: with `w:lang w:eastAsia="ja-JP"` on the run it moves the ideograph before the stop down as well, so that no line begins with a mark — nineteen characters on the first line; with no East Asian language it fills the line and **begins the next one with the stop**. Its two neighbours say the same of the other two declarations that looked like candidates: neither `w:useFELayout` nor `w:themeFontLang` turns the rules on, and only the run's own `w:lang` does. That is what the 97 lines of the corpus beginning with a closing mark are: not Word breaking its own rule, but text Word never took for East Asian. Undeclared here means the rules apply — the browser path knows no languages, and every real East Asian document declares one.
kinsoku?
KinsokuSet | undefined
The characters this run may not begin or end a line with. ECMA-376 §17.3.1.16's own lists, chosen by the run's `w:lang/@w:eastAsia` and by what the document put in place of them; `undefined` where the rules do not apply. See `layout/kinsoku.ts`. UAX #14 already forbids most of what they name — `。` is `CL` and `「` is `OP` — and what it does not is the point of carrying them: `℃`, `°`, `‰` and the currency signs are `PO` and `PR`, which the standard breaks either side of and Word does not.
characterLevelBreaks?
boolean | undefined
Whether a line may end **inside** a word of this run. **Nothing sets this from `w:wordWrap` any more: Word ignores the element.** ECMA-376 §17.3.1.45 spells the example out — `world` broken between the `o` and the `r` — and [MS-OI29500] §2.1.67 narrows it twice, to paragraphs holding Korean and to "space-delimited languages". Six probes write it, in the place `CT_PPr` puts it, and the Word that draws the references honours none of them: - `korean-break-wordwrap-off` and `-wordwrap-on` over Korean, which is the language §2.1.67 a names. Eight syllables either way, the word level. - `korean-break-latin` writes `w:wordWrap w:val="0"` over `aaaaaaaaaaaaaaaaaaaa Supercalifragilistic` in a column that holds the first word and not the second beside it — the one geometry that tells the levels apart, a word longer than the whole column being cut whatever the setting says. Word sends the second word down whole. - `korean-break-latin-plain` is that document without the element and comes out identical, and `-latin-korean` adds `가나` to the paragraph so §2.1.67 a's condition is met. Identical again. Kept as a property because `latinBreaksAnywhere` still arrives through the same mechanism, and because a document that finds the case Word honours has one place to put it.
ideographWords?
boolean | undefined
A run of ideographs that follows a space is one word: the line may end between two of them only where the run begins the line. Word 2007's rule and not Word 2010's — see where `chunk` is built in `chooseLines`, and `han-after-latin-word-break-compat*`.
compressiblePunctuation?
"modern" | "legacy" | undefined
Each full-width mark of the run may give back its blank half to keep a character on a justified line: `east-asian-compress-punctuation`, where a comma is drawn 7.67px wide at 14px to pull the fortieth character in, and two commas 10.71 each — only as much as the line needs. See `Piece.squeezableEm`.
compressibleNakaten?
boolean | undefined
Whether this run's middle dot gives its blanks back with the other marks. Japanese only: `east-asian-compress-by-mark-ja-mode-14` compresses `・` as it compresses a comma, and `-zh-mode-14` — the same probe in SimSun under `zh-CN` — leaves it at its full em while its commas and colons give as the Japanese ones do. Resolved by the caller, which knows the run's `w:lang/@w:eastAsia`.
keepAll?
boolean | undefined
Whether a line of this run may end only between words. Korean, and nothing else: see the `keep-all` pass in {@link wordBreakActions} for the five probes. Resolved by the caller, which knows the run's `w:lang/@w:eastAsia`.
latinBreaksAnywhere?
boolean | undefined
Whether a Latin word standing among ideographs may be broken anywhere. **What Word does where the run declares no East Asian language at all.** Counted over the corpus's Chinese: of the twenty-two documents that declare `zh-CN` or `zh-TW`, not one has Word end a full line inside a Latin word; of the three that declare none — `educational-80b7c45d441f`, `zh-98a5dfd0b39a` and `zh-a691a0344d9a` — every one does, twelve lines between them. `educational-80b7c45d441f` splits `2005` across two lines twice over and `70%` once, and none of the three writes `w:wordWrap`. The reading is that Word's word breaker is chosen by the declaration, the same one kinsoku is behind, and an undeclared run holding ideographs gets no word breaker at all — so the Latin inside it is unprotected. Resolved by the caller, which knows the run's language and its text.
hanging?
ReadonlySet<string> | undefined
Whether the punctuation that ends a line may stand outside the column. `w:overflowPunct` is on unless a document turns it off, and no layout Word draws honours it: see {@link hangsPunctuation}, where seven probes and the corpus agree that nothing hangs. Kept because the mechanism is right and only its trigger is empty.
label?
boolean | undefined
Part of a list's label rather than of its text; see {@link Piece.label}.
widthOf
(from: number, to: number) => number
Advance of `text.slice(from, to)`, in pixels.
kernAt?
((at: number) => number) | undefined
What the seam before an offset costs in kerning. Omitted where the text is not kerned, which is most of a corpus: Word kerns only above the size `w:kern` names.
gapAt?
((at: number) => number) | undefined
What the seam before an offset costs in East Asian gap. Kept apart from the kerning because it behaves differently: kerning is a width, and the gap is fixed spacing — see the `fits` budget in {@link chooseLines}.
spaceWidth?
number | undefined
The advance of a space in this span's face, at its size.
language?
string | undefined
`w:lang/@w:val`: the language the run is written in, for hyphenation. Word hyphenates each run by its own language and by no other — a Ukrainian paper whose body is English is hyphenated as English — and this is that declaration, resolved by the caller. Absent where the document does not hyphenate at all, or where the run suppresses it.
hyphenWidth?
number | undefined
The advance of a hyphen in this span's face, at its size. What a line that breaks a word of this run owes for the mark it draws. Present exactly where {@link language} is: no width, no hyphenation.
fontSize
number
Type size in pixels, which bounds how far a justified line may be squeezed.
Theme
interface Theme
colorScheme
ThemeColorScheme | undefined
fontScheme
ThemeFontScheme | undefined
ThemeColorScheme
interface ThemeColorScheme

A theme colour scheme, from `theme1.xml`.

name
string
colors
ReadonlyMap<string, string>
Slot name (`accent1`, `dk1`, `lt2`, ...) → `RRGGBB`.
ThemeFontScheme
interface ThemeFontScheme
name
string
majorLatin
string | undefined
Font of the heading slot, used by `majorHAnsi` references.
minorLatin
string | undefined
majorEastAsia
string | undefined
minorEastAsia
string | undefined
majorComplex
string | undefined
minorComplex
string | undefined
majorScripts
ReadonlyMap<string, string>
The faces the scheme names for particular scripts, `a:font/@script`. A theme states its East Asian and complex-script slots twice: once as `a:ea` and `a:cs`, which are usually empty, and once as a list of faces by script — `Jpan`, `Hans`, `Arab` and two dozen more. Which of the list applies is not a property of the theme at all: `w:themeFontLang` in the settings says which language each of the three slots is chosen for, and Word looks the script up from that. Keyed by the script tag as written, so the lookup is the specification's.
minorScripts
ReadonlyMap<string, string>
Underline
interface Underline
style
UnderlineStyle | undefined
Absent where `w:val` is: the element then states only its colour, and the kind is inherited.
color
string | undefined
themeColor
string | undefined
themeTint
string | undefined
themeShade
string | undefined
VmlContent
interface VmlContent
writeBlocks
(blocks: readonly BlockNode[]) => void
Writes the blocks of a text box, which are ordinary document blocks.
next
() => number
A number unique within the part, for the shape's `id`.
VmlShapeNode
interface VmlShapeNode

A legacy VML shape, `w:pict`. Word still writes these for text boxes.

kind
NodeKind.VmlShape
shapeType
string | undefined
style
string | undefined
The CSS-like style string from the VML `style` attribute, completed. VML puts a shape's place and size in this string — and not for all of them: a `v:line` and a `v:polyline` state their rectangle in `from`, `to` and `points` instead, and their style says only that they float. The reader writes that rectangle into the string, in the spelling the shape's context uses, so that one renderer and one writer can read the geometry of every VML shape out of one place. Nothing the file stated is replaced.
fill
string | undefined
stroke
string | undefined
relationshipId
string | undefined
widthEmu
number | undefined
heightEmu
number | undefined
textBox
readonly BlockNode[] | undefined
textBoxInset
{ left: number; top: number; right: number; bottom: number; } | undefined
Padding inside the text box, `v:textbox/@inset`, in points. Word's default is a tenth of an inch at the sides and half that above and below, and a converter that wants none says so. Assuming a constant instead is not a rounding error: a badge 49 points wide whose text is indented 31 points has eighteen points to set two digits in, and ten points of invented padding leaves too few — the number then wraps one digit per line.
horizontalRule?
{ readonly percent: number | undefined; readonly align: string | undefined; } | undefined
`o:hr`: the shape is Word's *horizontal line*, not a rectangle. The classic Insert → Horizontal Line, written as `<v:rect o:hr="t" style="width:0;height:1.5pt"/>`. Its width of nought is not a shape with no size — it is the rule saying "as wide as the text", and `o:hrpct` narrows it to a share of that in thousandths. A reader of the style alone throws it away: one report rules four such lines down its last page and drew none of them.
textBoxDirection?
string | undefined
Which way the text in the box runs, from `v:textbox/@style`. VML says it with `layout-flow` and `mso-layout-flow-alt` where DrawingML says it with `wps:bodyPr/@vert`; the values are named as `w:textDirection` names them, so the view has one vocabulary to answer.
path
string | undefined
The shape's own outline, `v:shape/@path`, in its own coordinate space. A converter does not use the preset shapes: it writes every circle, rounded panel and arrow as an explicit polygon. Drawn as the rectangle it occupies, a circle is a square — which is what a page number in a round badge looks like on every page of a converted report.
pathBox
{ originX: number; originY: number; width: number; height: number; } | undefined
The coordinate space `path` is drawn in, `@coordsize` and `@coordorigin`.
textRectangle
{ left: number; top: number; right: number; bottom: number; } | undefined
`v:path/@textboxrect`: the part of the outline the words go in. In the same coordinate space as {@link VmlShapeNode.path}. A shape that states none sets its text in its whole box, which is what a rectangle does.
strokeStyle?
VmlStroke | undefined
How the outline is drawn, `v:stroke`.
crop?
{ left: number; top: number; right: number; bottom: number; } | undefined
`v:imagedata` crop fractions, the VML spelling of `a:srcRect`. A logo cropped to its wordmark and the same logo drawn whole are the same relationship id and two different pictures on the page.
shadow?
{ color: string | undefined; offsetXPoints: number; offsetYPoints: number; } | undefined
`v:shadow`, offsets in points.
wordArtText?
string | undefined
The text of a WordArt shape, `v:textpath/@string`. Not a text box: WordArt carries its text as an attribute of the shape, so a reader that walks past `v:textpath` loses the words entirely — and WordArt is what a converted document uses for its title.
wordArtStyle?
string | undefined
The font `v:textpath/@style` sets that text in, as a CSS style string.
wordArtFits?
boolean | undefined
`v:textpath/@fitshape` or `@fitpath`: the words are stretched to the shape. Which is the whole point of WordArt — the built-in `_x0000_t136` declares `fitshape="t"` and the shape that uses it adds `fitpath="t"`, and neither writes a font size, because the size *is* the box. Drawn at the size the run inherits, a masthead comes out a third of the height Word draws it.
rotationDegrees?
number | undefined
`rotation` in the style string, in degrees clockwise about the centre. Word's watermark is a WordArt shape at `rotation:315`; drawn flat it runs across the text instead of up the diagonal.
children
readonly VmlShapeNode[] | undefined
Shapes of a `v:group`, positioned inside its box. A group is a coordinate system: it declares a box on the page in real units and a grid inside it in arbitrary ones, and its children give their places in that grid. Keeping the group as a node rather than flattening it into page positions is what makes an *inline* group work — a badge sitting in a line of text is a group too, and a flattened one would be torn out of the flow and pinned to the corner of the paragraph. A child's `floating` offsets are measured from the group's own box, not from the page.
floating
VmlFloat | undefined
How the shape sits in the text, the VML counterpart of `wp:inline` and `wp:anchor`. Undefined for a shape that flows with the text. A floating shape is the common case in documents produced by converters, which use a page-sized rectangle behind the text for the background of a cover page.
properties
RunProperties
WriteContext
interface WriteContext

The body of a document, written back out. ## One path, not two Everything here is written **from the model**. There is no second path that copies characters out of the file the document came from: the model is the document, and a save is a serialisation of it. That was not always so. The writer used to carry a span on every node saying where it stood in the original part, and to copy those characters back for any node an edit had not touched — which bought a byte-for-byte round trip and cost the thing that mattered more: the document could not be saved without the file it came from. Two paths also meant every function here began by asking which one it was on. What that costs is stated plainly rather than hidden: markup the reader does not model is **not** carried through. It is read, it draws nothing, and it is gone at the next save. `lost` names what the *writer* could not express; `parser/coverage.ts` names what the *reader* walked past, and between them there is no third category.

writer
XmlWriter
lost
Map<string, number>
What the model held and the writer could not express, by name and by count. Empty on an ordinary save. An entry means a node the model has a shape for but the writer has no markup for — a drawing that is neither a picture, a shape, a group nor a frame — and the caller is told rather than left to discover it.
pictures?
{ next(): number; } | undefined
Numbers for the drawings this part writes, unique within it. `wp:docPr/@id` has to be unique across the part and a drawing does not know what else the part holds, so the counter belongs to the walk. Absent for a caller that writes fragments rather than a part; drawings then take their numbers from a counter of their own, which is enough for a fragment that holds one.

Type aliases

Alignment
type Alignment = 'left' | 'center' | 'right' | 'justify' | 'distribute' | 'start' | 'end'
BlockInput
type BlockInput = ParagraphInput | TableInput | SectionInput | OpaqueInput
BlockNode
type BlockNode = | ParagraphNode | TableNode | AltChunkNode | ContentBlockNode | BookmarkStartNode | BookmarkEndNode | CommentRangeNode | MoveRangeNode

Content that stands between paragraphs and tables. The two bookmark nodes are here as well as among the inline ones, because a bookmark is a *position* rather than content and the format allows it in both places: one that opens before a table and closes after it is written between blocks, and that is how every cross-reference to a table is anchored. Read as unmodelled markup they could be carried through a save and not written from the model, so a document rebuilt from its model lost the anchors of its own table of contents — 76 of them across 400 documents, silently.

BorderStyle
type BorderStyle = | 'none' | 'nil' | 'single' | 'thick' | 'double' | 'dotted' | 'dashed' | 'dotDash' | 'dotDotDash' | 'triple' | 'thinThickSmallGap' | 'thickThinSmallGap' | 'thinThickThinSmallGap' | 'thinThickMediumGap' | 'thickThinMediumGap' | 'thinThickThinMediumGap' | 'thinThickLargeGap' | 'thickThinLargeGap' | 'thinThickThinLargeGap' | 'wave' | 'doubleWave' | 'dashSmallGap' | 'dashDotStroked' | 'threeDEmboss' | 'threeDEngrave' | 'outset' | 'inset'

Border style, `ST_Border`.

BreakType
type BreakType = 'line' | 'page' | 'column'
ChartGroupingfrom @genomdev/office-core
type ChartGrouping = 'clustered' | 'stacked' | 'percentStacked' | 'standard'

`c:grouping`, which decides whether values stack.

ChartKindfrom @genomdev/office-core
type ChartKind = 'bar' | 'line' | 'pie' | 'doughnut' | 'area' | 'scatter' | 'bubble' | 'radar' | 'stock' | 'surface'

How the marks of one plot are laid out.

ChartLegendPositionfrom @genomdev/office-core
type ChartLegendPosition = 'l' | 'r' | 't' | 'b' | 'tr'

Where the legend goes, `c:legendPos`.

ColumnConstraint
type ColumnConstraint = | { readonly kind: 'auto' } | { readonly kind: 'length'; readonly twips: number } /** `w:tcW w:type="pct"`, as a share of the table: `5000` fiftieths is 1. */ | { readonly kind: 'percent'; readonly share: number }

What a column's own `w:tcW` asks for, before its content is measured.

DocPicture
type DocPicture = StoredPicture

A picture of this document's store. The name is the one callers know it by.

Fill
type Fill = | { readonly kind: 'none' } | { readonly kind: 'solid'; readonly color: ColorReference | undefined } | { readonly kind: 'gradient'; readonly stops: readonly { readonly position: number; readonly color: ColorReference | undefined; }[]; /** Degrees clockwise from east, from `a:lin/@ang`. */ readonly angle: number | undefined; /** `a:path/@path` for a radial or rectangular gradient; absent means linear. */ readonly path: 'circle' | 'rect' | 'shape' | undefined; /** * `a:fillToRect`: where the innermost stop of a path gradient sits. * * Four insets in thousandths of a percent of the box. A radial gradient * lit from the top left states `l="50000" t="50000"`; one that says * nothing is centred, which is what a CSS radial gradient does anyway. */ readonly fillToRect?: { readonly left: number | undefined; readonly top: number | undefined; readonly right: number | undefined; readonly bottom: number | undefined; }; } | PictureFill | { /** `a:pattFill`: a two-colour hatch named by preset. */ readonly kind: 'pattern'; readonly preset: string | undefined; readonly foreground: ColorReference | undefined; readonly background: ColorReference | undefined; } /** * `a:grpFill`: whatever the enclosing group is filled with. * * Kept rather than resolved, because the group is not in scope here — a shape * is parsed before anything knows what contains it — and because "inherit" * and "no fill" are different answers that a reader collapsing them would * paint the same. */ | { readonly kind: 'group' }

How the interior of a shape is painted.

FontSlot
type FontSlot = 'ascii' | 'hAnsi' | 'eastAsia' | 'cs'

The four faces a run may name, as `w:rFonts` spells them.

HorizontalAlign
type HorizontalAlign = 'left' | 'center' | 'right' | 'inside' | 'outside'

`wp:align`, where the anchor states one instead of an offset.

HorizontalAnchorBase
type HorizontalAnchorBase = | 'page' | 'margin' | 'column' | 'character' | 'leftMargin' | 'rightMargin' | 'insideMargin' | 'outsideMargin'

What `wp:positionH/@relativeFrom` counts its offset from.

IdentifiedBlock
type IdentifiedBlock = ParagraphNode | TableNode | AltChunkNode | ContentBlockNode

A block an edit can name: one carrying an identity of its own. Not every block has one. Unmodelled markup is a span and a name, and a bookmark is a position — neither is a thing a caller replaces, moves or removes, and neither has an `id` in the sense the edit layer means. (Both do have an `id` field of their own kind, which is exactly why the distinction is a guard here rather than a check spelled out at each of the six places that needs it.)

IdentifiedNode
type IdentifiedNode = BlockNode | TableRowNode | TableCellNode

A node of the block tree that carries an identity.

InlineNode
type InlineNode = | TextNode | BreakNode | TabNode | SymbolNode | DrawingNode | VmlShapeNode | HyperlinkNode | BookmarkStartNode | BookmarkEndNode | NoteReferenceNode | CommentReferenceNode | CommentRangeNode | FieldNode | MathNode | RubyNode | MoveRangeNode | RevisionNode
KinsokuLanguage
type KinsokuLanguage = 'zh-Hans' | 'zh-Hant' | 'ja' | 'ko'

The languages Word runs East Asian line-breaking rules for.

LineSpacingRule
type LineSpacingRule = 'auto' | 'exact' | 'atLeast'

Line spacing rule, `w:spacing/@w:lineRule`.

LineSpan
type LineSpan = TextSpan | BoxSpan
NodePath
type NodePath = readonly number[]

Where a node stands: the chain of ids from the root down to it.

NumberFormat
type NumberFormat = | 'decimal' | 'upperRoman' | 'lowerRoman' | 'upperLetter' | 'lowerLetter' | 'ordinal' | 'cardinalText' | 'ordinalText' | 'hex' | 'chicago' | 'ideographDigital' | 'japaneseCounting' | 'aiueo' | 'iroha' | 'decimalFullWidth' | 'decimalHalfWidth' | 'japaneseLegal' | 'japaneseDigitalTenThousand' | 'decimalEnclosedCircle' | 'decimalFullWidth2' | 'aiueoFullWidth' | 'irohaFullWidth' | 'decimalZero' | 'bullet' | 'ganada' | 'chosung' | 'decimalEnclosedFullstop' | 'decimalEnclosedParen' | 'decimalEnclosedCircleChinese' | 'ideographEnclosedCircle' | 'ideographTraditional' | 'ideographZodiac' | 'ideographZodiacTraditional' | 'taiwaneseCounting' | 'ideographLegalTraditional' | 'taiwaneseCountingThousand' | 'taiwaneseDigital' | 'chineseCounting' | 'chineseLegalSimplified' | 'chineseCountingThousand' | 'koreanDigital' | 'koreanCounting' | 'koreanLegal' | 'koreanDigital2' | 'vietnameseCounting' | 'russianLower' | 'russianUpper' | 'none' | 'numberInDash' | 'hebrew1' | 'hebrew2' | 'arabicAlpha' | 'arabicAbjad' | 'hindiVowels' | 'hindiConsonants' | 'hindiNumbers' | 'hindiCounting' | 'thaiLetters' | 'thaiNumbers' | 'thaiCounting' | 'bahtText' | 'dollarText' | 'custom'

Every value of `ST_NumberFormat`, `custom` included.

NumberSuffix
type NumberSuffix = 'tab' | 'space' | 'nothing'

What separates the number from the paragraph text, `w:suff`.

SectionStart
type SectionStart = 'continuous' | 'nextPage' | 'nextColumn' | 'evenPage' | 'oddPage'

How a section starts relative to the previous one, `w:type`.

ShadingPattern
type ShadingPattern = | 'nil' | 'clear' | 'solid' | 'horzStripe' | 'vertStripe' | 'reverseDiagStripe' | 'diagStripe' | 'horzCross' | 'diagCross' | 'thinHorzStripe' | 'thinVertStripe' | 'thinReverseDiagStripe' | 'thinDiagStripe' | 'thinHorzCross' | 'thinDiagCross' | 'pct5' | 'pct10' | 'pct12' | 'pct15' | 'pct20' | 'pct25' | 'pct30' | 'pct35' | 'pct37' | 'pct40' | 'pct45' | 'pct50' | 'pct55' | 'pct60' | 'pct62' | 'pct65' | 'pct70' | 'pct75' | 'pct80' | 'pct85' | 'pct87' | 'pct90' | 'pct95'

Fill pattern, `ST_Shd`.

Step
type Step = | { readonly kind: 'replace'; readonly id: number; readonly node: IdentifiedNode } | { readonly kind: 'remove'; readonly id: number } | { readonly kind: 'insert'; /** The node the insertion stands beside. */ readonly id: number; readonly where: 'before' | 'after'; readonly blocks: readonly BlockNode[]; } | { readonly kind: 'append'; readonly blocks: readonly BlockNode[] } | { readonly kind: 'setBody'; readonly blocks: readonly BlockNode[] }

An edit, as a value. Every change the facade makes becomes one of these before it touches anything. That is worth the indirection three times over: - **Undo and redo** are the inverse of a step, and the inverse is computed from the tree the step is about to change — which is the only moment it can be known exactly. - **What changed** is the step's own subject, so a layout or a resolver is told rather than having to work it out by comparison. - **Anything that has to travel** — a change made in a worker, an edit arriving from another person, an operation replayed against a later version — travels as one of these. None of that is built here, and all of it is possible only because the change has a name and a shape rather than being a mutation that already happened. Steps address nodes by id, never by position; see `tree.ts`.

StyleType
type StyleType = 'paragraph' | 'character' | 'table' | 'numbering'
TableGridLayout
type TableLayout = 'fixed' | 'autofit'

`w:tblLayout`, as far as the columns are concerned.

TableHorizontalAnchor
type TableHorizontalAnchor = 'page' | 'margin' | 'text'

What `w:tblpPr/@horzAnchor` counts `w:tblpX` from.

TableStyleOverrideType
type TableStyleOverrideType = | 'wholeTable' | 'firstRow' | 'lastRow' | 'firstCol' | 'lastCol' | 'band1Vert' | 'band2Vert' | 'band1Horz' | 'band2Horz' | 'neCell' | 'nwCell' | 'seCell' | 'swCell'

Conditional formatting slot of a table style, `w:tblStylePr/@w:type`. A table style is not one set of properties but up to thirteen, each applying to a different region of the table. Getting banding and header rows right is impossible without modelling them separately.

TableVerticalAnchor
type TableVerticalAnchor = 'page' | 'margin' | 'text'

What `w:tblpPr/@vertAnchor` counts `w:tblpY` from.

UnderlineStyle
type UnderlineStyle = | 'none' | 'single' | 'words' | 'double' | 'thick' | 'dotted' | 'dottedHeavy' | 'dash' | 'dashedHeavy' | 'dashLong' | 'dashLongHeavy' | 'dotDash' | 'dashDotHeavy' | 'dotDotDash' | 'dashDotDotHeavy' | 'wave' | 'wavyHeavy' | 'wavyDouble'

Text underline, `ST_Underline`.

VerticalAnchorBase
type VerticalAnchorBase = | 'page' | 'margin' | 'topMargin' | 'bottomMargin' | 'insideMargin' | 'outsideMargin' | 'paragraph' | 'line'

What `wp:positionV/@relativeFrom` counts its offset from.

WrapSide
type WrapSide = 'bothSides' | 'left' | 'right' | 'largest' | 'none'

Which sides of a float a line may use, `none` meaning the float is not there. `wp:wrapNone` and `w10:wrap type="none"` say the text takes no notice of the object at all — it is drawn behind or in front of the page and obstructs nothing. The object is still *drawn*: a cover page whose title sits in such a box is a page of words, and dropping the box drops the page.

Values

Artfrom @genomdev/office-core
Art: { readonly DggContainer: 61440; readonly Dgg: 61446; readonly BStoreContainer: 61441; readonly Bse: 61447; readonly DgContainer: 61442; readonly Dg: 61448; readonly SpgrContainer: 61443; readonly SpContainer: 61444; readonly Spgr: 61449; readonly Sp: 61450; readonly Opt: 61451; readonly ClientTextbox: 61453; readonly ChildAnchor: 61455; readonly ClientAnchor: 61456; readonly ClientData: 61457; readonly SecondaryOpt: 61729; readonly TertiaryOpt: 61730; }

The record types this reader acts on. Everything else is walked past.

ArtPropfrom @genomdev/office-core
ArtProp: { readonly Rotation: 4; readonly TextId: 128; readonly TextLeft: 129; readonly TextTop: 130; readonly TextRight: 131; readonly TextBottom: 132; readonly BlipIndex: 260; readonly CropTop: 256; readonly CropBottom: 257; readonly CropLeft: 258; readonly CropRight: 259; readonly FillType: 384; readonly FillColor: 385; readonly FillBlip: 390; readonly FillOpacity: 386; readonly FillBackColor: 387; readonly FillStyleFlags: 447; readonly LineColor: 448; readonly LineWidth: 459; readonly LineDashing: 462; readonly LineStyleFlags: 511; readonly GroupShapeFlags: 959; readonly ShapeName: 896; readonly ShapeDescription: 897; }

Property identifiers this reader acts on.

Blipfrom @genomdev/office-core
Blip: { readonly Emf: 61466; readonly Wmf: 61467; readonly Pict: 61468; readonly Jpeg: 61469; readonly Png: 61470; readonly Dib: 61471; readonly Tiff: 61481; readonly JpegCmyk: 61482; }

The blips, by the record type each picture format is stored under.

BODY_STORY
BODY_STORY: ""

How the body is named among the stories; see {@link Story}.

CELL_PROPERTY_ORDER
CELL_PROPERTY_ORDER: readonly string[]

`w:tcPr`, from `CT_TcPrBase`.

CHART_CONTENT_TYPE
CHART_CONTENT_TYPE: "application/vnd.openxmlformats-officedocument.drawingml.chart+xml"
DEFAULT_CELL_MARGINS
DEFAULT_CELL_MARGINS: { readonly left: 0; readonly right: 0; readonly top: 0; readonly bottom: 0; }

The margins of a cell whose table, style and all, states none: nothing. The familiar hundred and eight twips to left and right is a value in the `Normal Table` style, not a constant in a layout engine — which is what `resolveTable` says and what the corpus confirms. This held 108 while the table properties were read raw, and the style's own value never reached the grid; with the style resolved, the two together inset every cell twice. Set to nought it is 83 lines better placed and a point and a half more of the left edges within a pixel of Word's. The top and bottom were always nought, and the row probes say so: `table-row-height-bare` rules a row of one line at exactly the height of that line, with nothing added.

DEFAULT_DOCUMENT_NAMESPACES
DEFAULT_DOCUMENT_NAMESPACES: string

The declarations Word writes on a document root.

DEFAULT_PAGE
DEFAULT_PAGE: { readonly widthTwips: 11906; readonly heightTwips: 16838; readonly marginTopTwips: 1440; readonly marginRightTwips: 1440; readonly marginBottomTwips: 1440; readonly marginLeftTwips: 1440; readonly headerTwips: 708; readonly footerTwips: 708; readonly gutterTwips: 0; }

A4 at 210 by 297 millimetres, in twips, and the margins Word writes. A default has to be *some* size and this is the one most of the world prints on. A caller that wants Letter states a section; the builder takes one.

DEFAULT_SECTION
DEFAULT_SECTION: SectionProperties

A4 portrait with one-inch margins: what Word gives a document that carries no `w:sectPr` at all. Measured: the corpus's two files without one — LibreOffice's `n751117` and pandoc's `definition_list` — come back from Word at 793.6 by 1122.56 pixels. That is the machine's own default page rather than a fact about the format, and it is not the same answer Word gives a `w:sectPr` that merely omits `w:pgSz`; see `SCHEMA_PAGE_SIZE`.

DEFAULT_SETTINGS
DEFAULT_SETTINGS: DocumentSettings
docx
docx: FormatModule<DocxDocument>

Word documents, both generations, as one module. Recognition is stated as data so the registry can pick this module out of six without loading any of them: an OPC package announces its main part's content type, and that is the only thing that tells the three OOXML formats apart. The compound file is the case rules cannot settle — a `.doc`, an `.xls` and a `.ppt` share one signature — so it shortlists itself and `canOpen` reads the directory to be sure. One module rather than two because the binary reader produces the same model: nothing above here has to know which generation it was handed.

EAST_ASIAN_LINE
EAST_ASIAN_LINE: 1.3

The line Word gives East Asian text, as a multiple of the size. The same 1.3 the CSS generator uses for a ruled page, and the probe says it is not only about ruling: `east-asian-natural-line-height` carries no `w:docGrid` at all and Word still rules its six faces alike, at 20.80px on twelve-point type. What the constant describes is East Asian text, and the grid was where it was first noticed.

EMPTY_NUMBERING
EMPTY_NUMBERING: NumberingDefinitions
EMPTY_PARAGRAPH_PROPERTIES
EMPTY_PARAGRAPH_PROPERTIES: ParagraphProperties
EMPTY_RUN_PROPERTIES
EMPTY_RUN_PROPERTIES: RunProperties

An empty property object, shared so that the common case allocates nothing.

EMPTY_STYLE_SHEET
EMPTY_STYLE_SHEET: StyleSheet
Fc
Fc: { readonly Stshf: 1; readonly PlcffndRef: 2; readonly PlcffndTxt: 3; readonly PlcfandRef: 4; readonly PlcfandTxt: 5; readonly Plcfsed: 6; readonly Plcfhdd: 11; readonly PlcfbteChpx: 12; readonly PlcfbtePapx: 13; readonly Sttbfffn: 15; readonly PlcffldMom: 16; readonly PlcffldHdr: 17; readonly PlcffldFtn: 18; readonly PlcffldAtn: 19; readonly SttbfBkmk: 21; readonly Plcfbkf: 22; readonly Plcfbkl: 23; readonly Dop: 31; readonly SttbfAssoc: 32; readonly Clx: 33; readonly GrpXstAtnOwners: 36; readonly PlcSpaMom: 40; readonly PlcSpaHdr: 41; readonly PlcfendRef: 46; readonly PlcfendTxt: 47; readonly DggInfo: 50; readonly SttbfRMark: 51; readonly PlcftxbxTxt: 56; readonly PlcfHdrtxbxTxt: 58; readonly PlfLst: 73; readonly PlfLfo: 74; }

Named positions in the array of (offset, length) pairs. Only the ones this parser reads are named. The array holds around ninety entries and most of them index things Word no longer writes — the print driver's saved environment, the OLE-1 macro table, three generations of page descriptor cache.

NO_TEXT_BOXES
NO_TEXT_BOXES: TextBoxRanges
PAGE_FIELD
PAGE_FIELD: "\u0001"

What a page-number field leaves behind until the page is known. `PAGE` cannot be resolved when the running head is laid out, because the head is laid out once and drawn on every page; `NUMPAGES` cannot be resolved until the last page has been made. Both are written as a character no document holds and replaced when the answer exists, and the line is then set again for the answer's width; see `realignedTabs`.

PAGES_FIELD
PAGES_FIELD: "\u0002"
PARAGRAPH_PROPERTY_ORDER
PARAGRAPH_PROPERTY_ORDER: readonly string[]

`w:pPr`, from `CT_PPrBase` plus what `CT_PPr` adds after it.

REL_CHART_TYPE
REL_CHART_TYPE: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"
RIGHT_EDGE_GUARD_PX
RIGHT_EDGE_GUARD_PX: 0.5

Slack left behind a right-aligned stop, in pixels. It covers the fractions lost in measuring the content piece by piece: without it the text can land a hundredth of a pixel past the edge of the column, and the browser wraps its last word onto a line of its own — a page footer that reads "Seite 2" with "von 14" underneath.

ROW_PROPERTY_ORDER
ROW_PROPERTY_ORDER: readonly string[]

`w:trPr`, from `CT_TrPrBase` plus the revision elements `CT_TrPr` adds.

RUN_PROPERTY_ORDER
RUN_PROPERTY_ORDER: readonly string[]

`w:rPr`, from `EG_RPrBase` plus the change record `EG_RPrContent` adds.

SECTION_PAGES_FIELD
SECTION_PAGES_FIELD: "\u0003"

...and the third of them: how many pages the *section* holds. [MS-OI29500] §2.1.497(a) settles what `SECTIONPAGES` means — the count of pages in the section, where the standard says the number of the page within it. Resolved in the same pass as the other two, from `PageGeometry.section`.

SECTION_PROPERTY_ORDER
SECTION_PROPERTY_ORDER: readonly string[]

`w:sectPr`, from `EG_SectPrContents`.

SprmKind
SprmKind: { readonly Paragraph: 1; readonly Character: 2; readonly Picture: 3; readonly Section: 4; readonly Table: 5; }

What a property belongs to.

TABLE_PROPERTY_ORDER
TABLE_PROPERTY_ORDER: readonly string[]

`w:tblPr`, from `CT_TblPrBase`.

Enums

NodeKind
NodeKind: typeof NodeKind

Document content model. A discriminated union keyed by a numeric `kind`. Numbers rather than strings because the renderer and the layout engine switch on this field for every node of a document that may hold millions of them, and integer dispatch compiles to a jump table where string dispatch does not. The tree deliberately holds no CSS and no layout results. Those belong to the renderer and the layout engine respectively, and keeping them out is what allows the same parsed document to be laid out at several zoom levels, or used headlessly for text extraction and conversion.

@genomdev/docx/view

Classes

CssGenerator
class CssGenerator

Translates resolved WordprocessingML properties into CSS declarations. Runs after style resolution, never during parsing. Keeping the two apart is what makes it possible to lay the same document out at different zoom levels, to export it without a DOM, and to fix a rendering bug without touching the parser. Declarations are emitted as shared classes through a {@link StyleSheetBuilder} rather than as inline styles. In a document with 200 000 runs the difference is roughly 200 000 style attributes versus about fifty CSS rules, which shows up directly in style recalculation time and in memory.

faceRatio
(fontFamily: string | undefined, eastAsianText?: boolean) => number | undefined
The natural line of one face, in ems, where the view can measure one. A line box is as tall as the tallest thing on it, and how tall a run is depends on its face as much as on its size: `Cambria Math` needs 1.17 em where Arial needs 1.15. The paragraph's own ratio governs the strut and everything that inherits it; a run whose face wants more says so for itself.
runClass
(properties: RunProperties) => string | undefined
Returns the CSS class implementing a resolved run format.
runDeclarations
(properties: RunProperties) => Record<string, string | undefined>
Builds the declaration map for run formatting.
DocxView
class DocxView extends BaseDocumentView<DocxDocument>
pageMode
DocxPageMode
How the sheets are shown.
layout
DocxLayout | undefined
What the document came to: pages, sections, and where each block went.
renderContent
() => Promise<void>
Composes, lays out and draws. Asynchronous for one reason: the advance tables are fetched per family, so that a viewer opening a two-family letter downloads two families. Everything after that is synchronous — the layout is a pure function.
goToPage
(index: number, behavior?: ScrollBehavior) => void
Scrolls to a page, counted from nought. ## Why this is not `scrollIntoView`, which is what it used to be `element.scrollIntoView({ behavior: 'smooth' })` animates, and an animation across seventy pages is not a nicety — it is the viewer scrolling through every page between here and there, mounting and unmounting each one as the observer reports it. Emptying a page above the viewport is a change to the content above the scroll position, which is precisely what Chromium's scroll anchoring exists to correct, and a scroll-anchoring correction **cancels a running smooth scroll**. A short hop sweeps nothing and lands; a long one is cancelled part of the way, or at the first callback, which is a click on an outline entry that appears to do nothing at all. So nothing is animated unless it is asked for, which is also what Word and Acrobat do — an outline entry jumps, it does not travel — and the sweep stops existing rather than being survived. See {@link DocxViewOptions.scrollBehavior} for the two ways to ask. It also scrolls *the scroll parent* rather than asking the browser to scroll whatever it likes. `scrollIntoView` moves every scrollable ancestor, including the application's own page: a viewer embedded halfway down a document would drag the whole host to the top on every jump.
goToNode
(node: BlockNode | undefined, behavior?: ScrollBehavior) => boolean
Scrolls to a paragraph or a table of the document — what an outline entry names. To the block and not merely to its page: a section that starts two thirds of the way down page forty is at the top of the screen here, the way following a heading in Word puts the heading at the top. The offset comes out of the computed layout, so it costs a lookup rather than a search of the DOM — and it is right for a page that has never been drawn. ## Why this takes a node and not a number Because there is no number both sides agree on. `outline()` counts every block it walks, table cells included; the engine flattens content-block wrappers away, drops markers, announces a section as a block of its own, and splits a paragraph that crosses a page into two. Measured on a fourteen-page report: the outline's numbering reached 466 where the engine's held 278 — so half the headings named a block that did not exist and the viewer did nothing at all, and the other half named the wrong one and went quietly to the wrong page. Both halves looked like the same fault and neither was reachable by adjusting an offset. The node is the same object on both sides. See {@link ComposedDocument.nodeOfBlock}.
goToBlock
(index: number, behavior?: ScrollBehavior) => boolean
Scrolls to a block by the engine's own index, for a caller that has one. Almost nobody does — {@link goToNode} is what an outline, a search result or a cross-reference can call. This stays for a caller working from {@link DocxLayout.pageOfBlock}, which is the same numbering.
goToBookmark
(name: string, behavior?: ScrollBehavior) => boolean
Scrolls to a bookmark. Through the bookmarks the *engine* was given rather than through the document's own index of them, and for the reason above: the document's index is keyed by a position in a walk the engine does not share. The composer already hands every paragraph the bookmarks that open in it — it is how `PAGEREF` resolves — so the page a bookmark is on is recorded when that paragraph's page closes, and asking is a lookup.
pageCount
number
How many pages the document came to; nought before it is laid out.
currentPage
number
The page the viewport is mostly showing, counted from nought.
pageOfLocator
(locator: string) => number | undefined
The page a locator names, for a passage found somewhere else.
mountAllPages
() => void
Draws every page and stops taking them down again.
resumeVirtualisation
() => void
Hands the document back to the observer after {@link mountAllPages}.
update
() => void
Re-applies the current zoom. Nothing is laid out again: the layout is not the browser's. `this.zoom` and not the option it started from. The option is what the application asked for when the view was made, and it never changes again; reading it here meant every call put the zoom back to where it opened, so `setZoom` appeared to work — the field was set — and then undid itself one line later. That is the whole of "the zoom control does nothing".
setZoom
(zoom: number, anchor?: { clientX: number; clientY: number; }) => void
Changes the zoom, keeping a point on the screen where it is. The point is the middle of what the reader can see unless a gesture named one, because a zoom that keeps the top-left corner still throws away the reader's place: at 200 % the passage they were reading is somewhere below the fold and they have to find it again.
setFit
(fit: NonNullable<ViewOptions["fit"]>) => void
Fits the page to the container, and keeps fitting it as the container changes. `width` fits the width and lets the page run past the fold, which is what a reader of a document wants; `page` fits the whole sheet; `none` leaves the zoom alone. It is the one reason a viewer beside anything else is usable at all — a document in a column narrower than a sheet of paper otherwise carries a horizontal scrollbar under every page.
setPageMode
(mode: DocxPageMode) => void
Runs the sheets together, or spaces them out again.
destroy
() => void
Tear the view down and release resources. The container is left empty.
onContainerResize
() => void
The container changed size: fit again if a fit was asked for, and nothing else. The base class re-renders, which for this view would mean composing and paginating the whole document on every frame of a window drag. The layout does not depend on the container — that is the point of computing it — so the only thing a resize can change is the fit.
ThemeResolver
class ThemeResolver

Resolves theme colour and font references into concrete values. Word rarely writes a literal colour. It writes "accent1, 40% lighter", encoded as a theme slot plus `themeTint`/`themeShade` modifiers, and the actual RGB lives in `theme1.xml`. A viewer that reads only `w:color/@w:val` renders every themed document in black, which is the single most visible difference between a correct DOCX renderer and an approximate one.

runColor
(properties: RunProperties) => string | undefined
Resolves the effective text colour of a run. `w:color/@w:val` wins when it is a literal; otherwise the theme slot is looked up and the tint or shade modifier applied.
themeColor
(slot: string, tintHex?: string, shadeHex?: string) => string | undefined
Resolves a theme colour slot with optional tint or shade.
drawingThemeColor
(slot: string, lumMod?: number, lumOff?: number) => string | undefined
Resolves a DrawingML theme colour with luminance modulation. DrawingML expresses variations as `lumMod`/`lumOff` in thousandths of a percent rather than as the tint/shade bytes used by WordprocessingML.
drawingColor
(reference: ColorReference | undefined) => string | undefined
Resolves a DrawingML colour reference, modifiers and all. A shape's colour is almost never a literal. It is a theme slot with a stack of modifiers on it — `accent1` at 60% luminance with a 40% offset is the pale panel behind a cover headline, and `accent1` with `shade 50000` is the dark one under it. Resolving the slot and dropping the stack paints both of them the same saturated accent, which is worse than the right colour and more obvious than none. The order is DrawingML's: shade and tint act on the colour, then the luminance modulation, then alpha turns it translucent.
drawingRgba
(reference: ColorReference | undefined) => Rgba | undefined
The same, as a colour rather than as CSS, for callers that must compare it.
themeFont
(slot: string) => string | undefined
Resolves a theme font slot such as `minorHAnsi` to a font family name. Word writes `w:asciiTheme="minorHAnsi"` instead of a family name so the document follows the theme; without resolution every run falls back to the browser default.
cssVariables
() => Record<string, string>
CSS custom properties exposing the theme to stylesheets and to the host app.

Functions

baseStyles
function baseStyles(prefix: string): string

Base stylesheet of the DOCX renderer. Only structural rules live here: the sheet of paper, the page frame, table defaults, and the small amount of chrome the viewer adds. Everything derived from the document itself is emitted as generated classes, so this file never needs to change when format support grows.

chartGlyphs
function chartGlyphs(chart: ChartDefinition, widthPx: number, heightPx: number, themeColor: (slot: string) => string | undefined): ChartGlyph[]

The chart's text as glyphs measured from the box's baseline. {@link ObjectPiece.glyphs } places each run by `dy` from the baseline the box stands on, and a chart stands *on* the baseline with nothing below it — so a piece whose top is `top` inside the box has `dy = top - height + size`. A label of several lines arrives as one string with newlines in it, which is how the renderer folds a long category; it is cut back into lines here, stepped by the pitch the box was given.

contextFor
function contextFor(faces: Faces, page: HTMLElement, ownerDocument: Document, origin: { readonly x: number; readonly y: number; }, drawObject?: (box: HTMLElement, piece: ObjectPiece) => void, drawingColor?: DrawingColor): PaintContext

A context for drawing into one element. It used to be bound to a block, because a span named its piece by an index into that block's own pieces. It does not any more: a span carries its piece, which is the only thing that works for a line inside a cell or a running head — those belong to a paragraph the page never reports.

objectPainter
function objectPainter(options: GraphicsOptions): (box: HTMLElement, piece: ObjectPiece) => void

A drawer of objects, bound to one document. Made once and used for every object of every page: the context it builds is not cheap — a stylesheet, a metrics cache, a theme — and none of it changes between one picture and the next.

paintBands
function paintBands(bands: readonly BandGeometry[], into: HTMLElement, ownerDocument: Document, origin: { readonly x: number; readonly y: number; }): boolean

The bands a box carried with it — a running head, a foot, a note. The paragraphs of a box are not blocks of the flow, so there is no `ref` for a painter to look up and the engine hands the rectangle over already worked out; see {@link BandGeometry}. Everything about *how* it is drawn is a block's, and that is why both go through {@link paintBand}. So is the grouping: the bands come in the order the box stacked its paragraphs.

paintBlock
function paintBlock(block: BlockGeometry, input: BlockInput | undefined, into: HTMLElement, ownerDocument: Document, origin: { readonly x: number; readonly y: number; }, before?: PaintedBlock, after?: PaintedBlock): boolean

Draws the band behind one block, where it asks for one. Prepended, so it goes under the words of its own block — which is what a background is — and returns whether anything was drawn at all, so a page of plain paragraphs pays nothing. `before` and `after` are the paragraphs either side of it on the sheet, where there are any: a paragraph whose rules are its neighbour's too is one group with it, and draws only its share of the group's rules; see {@link grouped}.

paintCells
function paintCells(cells: readonly CellGeometry[], page: HTMLElement, ownerDocument: Document, origin: { readonly x: number; readonly y: number; }, seams?: ReadonlyMap<CellGeometry, ReadonlySet<"top" | "bottom" | "left" | "right">>): void

Draws every cell of a table onto the page. Behind the text: the runs were appended before this, and a fill drawn over them would hide them. Appended with `z-index` rather than reordered, because the page is built once and in the order the geometry comes.

paintLine
function paintLine(line: LineGeometry, context: PaintContext): void

Draws one line into the page element. One box per line, and the runs inside it. The box does nothing a browser would normally do with a line — it constrains no wrapping and establishes no baseline, both of which were settled before this file ran — and for a while it was left out for exactly that reason: a box per line is one more element per line for a document that may have twenty thousand. **It is there for the reader's mouse.** Every run placed straight onto the page leaves the space between the lines belonging to nothing, and a browser asked for the caret at such a point walks the page's positioned children for the nearest box. Every block's wrapper is nought by nought at the page's corner — that is what keeps it from covering the words — so *every* one of them is equally near, the first wins, and a selection dragged downwards into the gap under a paragraph jumps to the top of the sheet. Measured: dragging sixty pixels down the demo document selected upwards, to `A fast, faithful DOCX viewer`. A box at the line's own place and of the line's own height ends that: the boxes of a paragraph touch, so a point between two lines is inside one of them, and a point in the space between paragraphs is nearest the line it looks nearest. It also gives the clipboard its newlines, because a box is a block box and a browser writes one between two of those.

paintPage
function paintPage(page: PageGeometry, options: PaintPageOptions): HTMLElement

Draws a page into a fresh element and returns it. The element is the sheet: its size is the page's, in pixels, and everything inside it is positioned absolutely against its top-left corner — which is the frame every number in the geometry is stated in.

quoteFont
function quoteFont(name: string): string

Quotes a font family name when it needs it, so CSS stays valid.

Interfaces

ChartGlyph
interface ChartGlyph

A glyph run of {@link ObjectPiece.glyphs }, which is what the engine draws.

text
string
dx
number
dy
number
sizePx
number
italic
boolean
DocxLayout
interface DocxLayout

What a caller learns when the document has been laid out.

pageCount
number
sections
number
How many sections the document is divided into.
pages
readonly PageGeometry[]
The pages whose geometry is being held. Every page for a document within {@link DocxViewOptions.pageBudget}; for a larger one, the window around what the reader is looking at. The count and the extents are known for all of them either way — see {@link sizes} — because that is what a scrollbar needs and it costs two numbers a page.
sizes
readonly { readonly width: number; readonly height: number; }[]
Every page's extent, held or not.
pageOfBlock
(index: number) => number | undefined
The page a block of the flow landed on, by the engine's own index. That numbering is the engine's and nothing outside can produce one; a caller holding a paragraph of the document wants {@link pageOfNode}.
pageOfNode
(node: BlockNode | undefined) => number | undefined
The page a paragraph or table of the document landed on.
DocxViewOptions
interface DocxViewOptions extends ViewOptions
scrollParent?
HTMLElement | undefined
Element that scrolls; found by walking up from the container otherwise.
pageMode?
DocxPageMode | undefined
Sheets apart on a canvas, or run together. Apart by default.
scrollBehavior?
ScrollBehavior | "adaptive" | undefined
Whether a jump to a page or a heading is animated. It is not, by default. Word, Acrobat and a browser's own PDF viewer all land at once when a reader picks a heading, and so does CSS with nobody asking otherwise. An animation was tried here and is worse in both directions: a long one cannot be relied on at all — see {@link DocxView.goToPage} — and mixing the two by distance means one click glides and the next snaps, which reads as the viewer being unsure rather than as a nicety. `smooth` animates every jump, `adaptive` animates only the short ones.
wheelZoom?
boolean | undefined
Ctrl and the wheel zooms, and a trackpad pinch with it. On by default.
pinchZoom?
boolean | undefined
Two fingers zoom. On by default.
onZoomChange?
((zoom: number) => void) | undefined
Told when the zoom changed, whoever changed it. A gesture changes the zoom without the application having asked, so a toolbar that keeps the number has no other way to learn it. Also emitted on the viewer's bus as `zoom:change`.
onLayoutComplete?
((result: DocxLayout) => void) | undefined
Called once the pages are known.
onLayoutProgress?
((fraction: number) => void) | undefined
Called as the layout proceeds, with a fraction between nought and one.
onPageChange?
((index: number) => void) | undefined
Called when the page most of the viewport shows changes.
overscanScreens?
number | undefined
How many screens beyond the viewport to keep drawn; one by default.
locators?
boolean | { hash: string; } | undefined
Stamp every block with the address extraction gave it, as `data-loc`. Off by default: a viewer that never highlights anything should pay nothing for the machinery. On, it is what lets a passage found by a retrieval system be scrolled to and shown in the document it came from.
pageBudget?
number | undefined
How many pages of geometry to hold at once. A page of dense text is some hundreds of lines and some thousands of spans, and a document of a thousand pages held whole is millions of objects for the three the reader can see. Past this many pages the viewer keeps the extents of all of them — which is what the scrollbar and the page numbers need — and the geometry of a window around where the reader is, laying the document out again when the window moves. The default holds everything, which is right for the documents most people open and is what every existing caller already gets. Set it, and a thousand-page report opens in bounded memory at the cost of a relayout per jump.
GraphicsOptions
interface GraphicsOptions
document
DocxDocument
ownerDocument
Document
footnotes?
ReadonlyMap<string, Note> | undefined
endnotes?
ReadonlyMap<string, Note> | undefined
comments?
ReadonlyMap<string, Comment> | undefined
PaintContext
interface PaintContext
ownerDocument
Document
page
HTMLElement
The element the page is drawn into; every run is appended to it.
origin
{ readonly x: number; readonly y: number; }
Where that element's own corner is, in the page's frame. The geometry is stated against the sheet and the block is drawn into a box of its own, so everything inside it is placed against *that* box's corner. The box has a size for the reader's mouse — see `paintLine` — and a box with a size is a box with an origin.
faceOf
(piece: TextPiece) => { readonly ascent: number; widthOf?(text: string, sizePx: number): number; } | undefined
The face a piece is set in, for its ascent.
style
(element: HTMLElement, piece: TextPiece) => void
Puts the run's own appearance on the element that draws it.
drawObject?
((box: HTMLElement, piece: ObjectPiece) => void) | undefined
Fills the box an inline object was given, where the caller can. A picture, a shape, a chart, a diagram, an equation — each is a different body of drawing code, and none of it belongs to a file whose subject is *where things go*. The box is made here, at the size the line was made tall enough for; what goes inside it is the caller's.
PaintedBlock
interface PaintedBlock

A block and what it was laid out from, for {@link paintBlock}'s neighbours.

block
BlockGeometry
input
BlockInput | undefined
PaintPageOptions
interface PaintPageOptions
locators?
boolean | { hash: string; } | undefined
Stamp every block with the address extraction gave it, as `data-loc`. What lets a passage found by a retrieval system be scrolled to and shown in the document it came from. The hash must be the one extraction used, or an address minted by one half is refused by the other; pass neither and both agree on the empty string, which still works and simply cannot warn about a mismatched file. One element per block, never one per run: a document of 200 000 runs would carry 200 000 attributes, and finding a character inside a block is a matter of counting text nodes — cheap, and only done for the handful of blocks a highlight touches.
blocks
readonly BlockInput[]
The blocks the geometry was computed from; a span indexes into them.
faces
Faces
The faces the geometry was measured with — the same ones, necessarily.
ownerDocument?
Document | undefined
drawObject?
((box: HTMLElement, piece: ObjectPiece) => void) | undefined
Fills the box an inline object was given; see {@link PaintContext.drawObject }.
drawingColor?
DrawingColor | undefined
Resolves a DrawingML colour against the document's theme, for the 2010 text effects.
PaintRef
interface PaintRef

The paint attributes a piece carries; see `PieceRef` and `compose.ts`.

underlinesTrailingSpace?
boolean | undefined
`w:ulTrailSpace`: underline the spaces a line ends with as well.
run?
{ readonly positionHalfPoints?: number; readonly color?: { readonly value?: string; }; readonly underline?: { readonly style?: string; readonly color?: string; }; readonly strike?: boolean; readonly doubleStrike?: boolean; readonly highlight?: string; readonly shading?: { readonly fill?: string; readonly color?: string; readonly pattern?: string; }; readonly caps?: boolean; readonly vanish?: boolean; } | undefined
The run as the style sheet resolved it: colour, underline, the rest.

Values

docxView
docxView: ViewModule<DocxDocument>

Word documents with its renderer attached. What `@genomdev/docx/view` exports and what an application passes to the viewer. The universal half is the same object — the renderer is a field on it, not a second registration — so a format either brings a way to draw itself or it does not, and nothing has to pair them up by hand.