Skip to content
Genom
API reference

@genomdev/office-core

The parts only Word, Excel and PowerPoint need: OPC, DrawingML, Office Art, OLE2, the Excel formula language

327 exported symbols across 6 entry points

@genomdev/office-core

Classes

MediaResolver
class MediaResolver

Resolves package parts into URLs usable by `<img>` and CSS, and owns their lifetime. Two problems are solved here that every naive implementation gets wrong. First, leaks: an object URL is a document-lifetime handle to the underlying blob. A viewer that creates one per image render and never revokes it keeps every version of every image alive for as long as the page lives. The resolver hands out URLs and revokes all of them on {@link dispose}. Second, duplication: the same image is routinely referenced from many places (a logo in a header repeated on every page). Caching by part name means the bytes are inflated once and the browser decodes one image instead of dozens. How a URL is minted is not decided here — see {@link MediaUrlFactory}. That indirection is what lets this class, which sits under every parser, be loaded on a server.

bytes
(partName: string) => Promise<{ bytes: Uint8Array; contentType: string; } | undefined>
The raw bytes of a media part, with the type they claim to be. What extraction wants: an OCR handler is given an image to read, not a URL to fetch, and minting a URL to hand to something that will immediately decode it back into bytes is pure waste. Uncached on purpose — the caller is about to hold the bytes itself.
resolve
(partName: string) => Promise<string | undefined>
Returns a URL for a media part, creating it on first use. Concurrent calls for the same part share one inflate: the pending promise is cached, not just the result. Without that, a page with the same image in twenty places would inflate it twenty times in parallel.
inlineSvg
(partName: string) => Promise<string | undefined>
The SVG source of a metafile, for a renderer that means to inline it. A translated metafile handed out as a URL is drawn correctly and is, as far as the page is concerned, a picture: its words cannot be selected, copied, found by the browser's search or read by a screen reader, because they are not in the document. That is a real loss and not a small one — a metafile on a slide is usually a diagram, a chart pasted from Excel or a table of figures, which is to say the content, not the decoration. Inlined, the same SVG puts every one of those words in the DOM. Only worth it for the ones that have words. See {@link worthInlining}: the rest stay pictures, which is what they are. Measured on the presentation corpus, where 163 decks of 1697 carry a metafile: inlining is worth 1211 lines of the 134389 compared, the largest single gain of the loop so far. It moves `placed` by 35, and that is expected — the drawing was already on the screen and in the right place; what changed is that its words are now in the document.
size
number
Number of live object URLs; exposed for diagnostics and leak tests.
dispose
() => void
Revokes every URL handed out by this resolver.
OpcPackage
class OpcPackage

An OPC package (Open Packaging Conventions, ECMA-376 part 2). The shared container of docx, xlsx and pptx: a ZIP archive in which `[Content_Types].xml` assigns MIME types to parts and `.rels` files link parts to each other. Parsing this layer is identical for all three formats, so it lives apart from the format-specific packages.

open
(source: ByteSource, options?: ZipArchiveOptions) => Promise<OpcPackage>
archive
ZipArchive
Direct access to the archive, for cases where the OPC layer gets in the way.
parts
() => ZipEntry[]
All package parts, excluding directories and `.rels` bookkeeping files.
has
(partName: string) => boolean
partSize
(partName: string) => number
Size of a part after decompression, without reading it.
contentType
(partName: string) => string | undefined
MIME type of a part. An exact override is checked first, then the extension default. That order is mandated by the specification: `Override` always beats `Default`.
contentTypeDefaults
() => ReadonlyMap<string, string>
The content-type table as the package states it, for whoever rewrites it. Two maps rather than one because the specification treats them differently: a `Default` covers an extension and an `Override` covers a part, and a writer that collapsed them would turn every picture in a package into its own line of `[Content_Types].xml`.
contentTypeOverrides
() => ReadonlyMap<string, string>
contentTypes
() => string[]
Every MIME type present in the package; used to identify the format.
findPartByContentType
(contentType: string) => string | undefined
Finds a part by its MIME type. For main parts the result is unique.
readPart
(partName: string) => Promise<Uint8Array>
readPartText
(partName: string) => Promise<string>
readPartXml
(partName: string) => Promise<XmlElement>
Reads a part and parses it as an XML tree.
openPartStream
(partName: string) => Promise<XmlPullParser>
Opens a part as a streaming XML parser. The right entry point for large parts — `document.xml`, worksheets, slides — where building a node tree would cost far more than the parse itself. The part is read uncached, because a streamed part is consumed exactly once.
relationships
(partName?: string) => Promise<Relationship[]>
Relationships of a part. An empty string means package-level relationships (`_rels/.rels`), where the parsing of any OOXML document starts: that is where the pointer to the main part lives.
relationshipMap
(partName?: string) => Promise<ReadonlyMap<string, Relationship>>
Builds an id → relationship index for a part. Resolving relationships by scanning the array is fine for a handful of lookups, but a document with thousands of hyperlinks and images turns that into quadratic work, so the renderer uses the map instead.
relationshipOfType
(type: string, partName?: string) => Promise<Relationship | undefined>
First relationship of the given type; used for single-instance parts.
relationshipsOfType
(type: string, partName?: string) => Promise<Relationship[]>
resolveTarget
(relationship: Relationship, ownerPartName?: string) => string
Resolves a relationship target into an absolute part path. External targets (hyperlinks, linked images) are returned unchanged, since they cannot be turned into an internal path.
mainPart
(relationshipType: string) => Promise<string | undefined>
The main document part, pointed at by a package-level relationship.
OpcPackageWriter
class OpcPackageWriter
setPart
(partName: string, content: Uint8Array | string, contentType?: string) => this
Writes a part, replacing whatever the source package held under that name.
has
(partName: string) => boolean
Whether a part will be in the package, from the source or from this writer. What a caller adding a part needs before it chooses a name: `word/media/ image1.png` is the convention and a package copied from a source may already hold one.
removePart
(partName: string) => this
Drops a part. Its relationships are the caller's business, not this one's.
setDefault
(extension: string, contentType: string) => this
Declares the content type of every part with an extension.
setOverride
(partName: string, contentType: string) => this
Declares the content type of one part, which beats any default.
setRelationships
(ownerPart: string, relationships: readonly Relationship[]) => this
Replaces the relationships of a part; `''` names the package's own. Whole rather than incremental, because a relationship file is small and a caller that has decided to change one has the others in hand anyway.
relationshipsOf
(ownerPart: string) => Promise<readonly Relationship[]>
The relationships a part will be saved with, source or replacement.
addRelationship
(ownerPart: string, relationship: Omit<Relationship, "id"> & { readonly id?: string; }) => Promise<string>
Adds a relationship to a part and answers the id it was given. The id is minted here rather than by the caller because it has to be unique within the part's own relationship file and nothing outside can see the others.
toBytes
() => Promise<Uint8Array>
The finished package.

Functions

applyThemeStyle
function applyThemeStyle(look: ShapeLook, style: ShapeStyleReference | undefined, theme: Theme): ShapeLook

Fills in what a shape leaves to the theme. What the shape states itself always wins: `p:style` is the default, and `p:spPr` is the override. A shape that turns its fill off states that too, and `filled: false` is respected rather than overwritten.

canonicalNamespace
function canonicalNamespace(uri: string): string
chartBlock
function chartBlock(chart: ChartDefinition, locator: Locator, options: ResolvedOptions): ChartBlock | undefined

A chart, as the table it is. The single largest thing this package does that the alternatives do not, and the reason is not cleverness — it is that the parser already has the numbers. `c:chartSpace` stores every series with its cached values and its category labels, because that is how a chart survives being opened on a machine that cannot reach the workbook it came from. To every other extractor in this space a chart is a picture and a picture is a hole, so the figures behind a quarterly report's headline are simply absent from the text. One converter for all three formats, because `c:chartSpace` is the same part in a document, a workbook and a deck.

childArt
function childArt(record: ArtRecord, type: number): ArtRecord | undefined

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

colorOf
function colorOf(container: XmlElement | undefined): DiagramColor | undefined

The colour inside a container such as `a:solidFill` or `a:fillRef`.

columnWidthToPixels
function columnWidthToPixels(width: number, maxDigitWidth?: number): number

Excel column width in "characters" converted to pixels. Excel measures width in multiples of the width of the "0" glyph of the Normal style font and adds 5 pixels of cell padding (MS-OI29500, Column Width): `px = trunc(width * mdw) + 5`, where `mdw` is the digit width in pixels (7 for the default Calibri 11pt). This is where Excel's well-known default comes from: 8.43 characters is exactly 64 pixels.

dashArray
function dashArray(dash: string | undefined, strokeWidth: number): string | undefined
dataUrlFactory
function dataUrlFactory(): MediaUrlFactory

Data URIs: work everywhere, cost a third more memory, need no revoking.

defaultMediaUrlFactory
function defaultMediaUrlFactory(): MediaUrlFactory

Object URLs where the host has them, data URIs otherwise.

detectOoxmlFormat
function detectOoxmlFormat(pkg: OpcPackage): FormatId | undefined

Determines the concrete OOXML format from the type of the main part. This is the refinement the core cannot make: docx, xlsx and pptx are the same ZIP with the same signature, and only `[Content_Types].xml` tells them apart. File extensions are unreliable — renamed files turn up constantly — so the decision is made from the contents.

diagramNodes
function diagramNodes(shapes: readonly { text: string; depth?: number; }[]): DiagramNodeData[]

SmartArt, as the nesting it draws. A diagram is stored twice over: as the data it was built from and as the shapes the application laid out. The shapes are what the viewer draws, and they carry the words — so the text comes out of the drawing, and the nesting out of the frames it puts them in.

eighthPointsToPoints
function eighthPointsToPoints(eighths: number): number

Eighths of a point: the unit of `w:sz` on border elements.

emuToInches
function emuToInches(emu: number): number
emuToPixels
function emuToPixels(emu: number): number
emuToPoints
function emuToPoints(emu: number): number
encodeBase64
function encodeBase64(bytes: Uint8Array): string

Base64, by hand. `btoa` is a browser function and `Buffer` is a Node one, and this package has a hard rule against needing either. Three bytes to four characters is twenty lines and no dependency; the alternative is a runtime check on the hot path of every image in a workbook.

fillCss
function fillCss(fill: DiagramFill | undefined, themeColor: ThemeColorLookup): string | undefined

A fill as a CSS background. A gradient becomes a gradient, a pattern becomes a repeating one — CSS has no hatch, and a striped background at the right density and angle reads as the same texture — and a picture returns nothing, because the caller has to resolve the part before it can name a URL.

fillOf
function fillOf(properties: XmlElement | undefined): DiagramFill | undefined

Reads whichever fill a shape's properties carry. The five are alternatives in the schema and the first one found wins, which is also what the schema says: a shape has one fill.

findArt
function findArt(records: readonly ArtRecord[], type: number): Generator<ArtRecord>

Every record of a type, at any depth.

geometryOf
function geometryOf(properties: XmlElement | undefined): DiagramGeometry | undefined

Reads `p:spPr`/`xdr:spPr`: what shape the shape is. `a:prstGeom` names one of the specification's shapes and adjusts it; `a:custGeom` writes the outline out. Both are read here, into one type, so that a slide and a worksheet describe an arrow the same way and the renderer that draws one draws the other.

geometryPath
function geometryPath(geometry: DiagramGeometry | undefined, box: GeometryBox): ShapeOutlinePath | undefined

The path a geometry describes, or nothing when it is one CSS handles. A zero-sized box has no path: a shape whose frame the file never stated would otherwise produce `M 0 0 Z`, which paints a dot at the corner of the slide.

grayscale
function grayscale(color: Rgba): Rgba

`a:gray`: the colour rendered in shades of grey, by perceived brightness.

guessImageType
function guessImageType(bytes: Uint8Array): string

Infers an image MIME type from its magic bytes. `[Content_Types].xml` usually declares media types, but files written by third-party generators often omit the entry for an extension, and a blob with the wrong type simply fails to render.

halfPointsToPoints
function halfPointsToPoints(halfPoints: number): number

Half-points: the unit Word uses for font sizes (`w:sz w:val="24"` is 12pt).

hasPreset
function hasPreset(preset: string | undefined): boolean

Whether a preset is one this library can draw.

invert
function invert(color: Rgba): Rgba

`a:inv`: every channel inverted.

isCssGeometry
function isCssGeometry(preset: string | undefined): boolean

The three shapes CSS draws better than an SVG path would. A rectangle is a div, a rounded rectangle is a border-radius, and an ellipse is a fifty-per-cent one. Those three are 2 568 of the corpus's 4 311 shapes, and routing them through a path would trade working code for a redraw.

isSymbolFont
function isSymbolFont(font: string | undefined): boolean

Whether a font is a symbol font, whose every byte means a glyph. A document writes a Wingdings character either as the raw byte or as `0xF000` plus it, and both mean the same picture — so the private-use range is not the test for whether a character needs mapping. The *font* is. `de-2b4d48b05715` bullets its lists with `<w:lvlText w:val="è"/>` in Wingdings, a plain `U+00E8`, and Word draws the arrow the font has there.

isUnrenderableImageType
function isUnrenderableImageType(contentType: string): boolean

Image types that no browser can render natively.

loadDiagramDrawing
function loadDiagramDrawing(pkg: OpcPackage, owner: string, dataRelationshipId: string): Promise<DiagramDrawing | undefined>

Loads the drawing behind a diagram.

mapSymbolCharacter
function mapSymbolCharacter(font: string, char: number): { text: string; keepFont: boolean; }
mathText
function mathText(nodes: readonly MathNode[]): string

Every letter of an equation, in reading order; for a text extractor.

modulateHue
function modulateHue(color: Rgba, hueMod?: number, hueOff?: number): Rgba

Applies the `hueMod`/`hueOff` hue rotation of DrawingML; both wrap.

modulateLuminance
function modulateLuminance(color: Rgba, lumMod?: number, lumOff?: number): Rgba

Applies the `lumMod`/`lumOff` luminance modulation used by DrawingML themes. Word writes theme colour variations this way, e.g. "Accent 1, lighter 40%" becomes `lumMod 60000` + `lumOff 40000` (values are thousandths of a percent).

modulateSaturation
function modulateSaturation(color: Rgba, satMod?: number, satOff?: number): Rgba

Applies the `satMod`/`satOff` saturation modulation of DrawingML. The other half of the pair Office writes for a theme variation. Every theme Word ships states its fills as a scheme colour with both a luminance and a saturation modifier on it — a heading colour is `accent1` at 110% saturation and 75% luminance — and applying only the first paints a colour that is the right lightness and visibly the wrong intensity.

namespacePrefix
function namespacePrefix(uri: string): string
normalizePartName
function normalizePartName(partName: string): string

Normalises a part name: no leading slash, forward slashes only.

objectUrlFactory
function objectUrlFactory(): MediaUrlFactory | undefined

Object URLs: a handle to the bytes, revoked on dispose. Returns `undefined` where the host has no `URL.createObjectURL`, so a caller that specifically wants object URLs can tell that it did not get them rather than discovering it later through memory that never comes back.

ooxmlParser
function ooxmlParser(input: string | Uint8Array): XmlPullParser

A pull parser that canonicalises Strict namespaces to Transitional.

outlineOf
function outlineOf(line: XmlElement | undefined): DiagramOutline | undefined

`a:ln`: the width, the dash pattern and the colour it is stroked with.

parseArtProperties
function parseArtProperties(record: ArtRecord | undefined): Map<number, ArtProperty>
parseArtRecords
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.

parseChart
function parseChart(parser: XmlPullParser): ChartDefinition

Parses a whole chart part.

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

parseMath
function parseMath(element: XmlElement): MathNode[]

Reads `m:oMath` or `m:oMathPara`: the equation, whole.

parseOfficeArtContent
function parseOfficeArtContent(bytes: Uint8Array | undefined): OfficeArtContent
parseOoxml
function parseOoxml(input: string | Uint8Array): XmlElement

The same rule for a part read as a tree. Both halves of the reader need it and only the streaming half had it. A slide, a layout, a master and a theme are all read into trees, so a Strict deck arrived with every element in `http://purl.oclc.org/ooxml/…` and every lookup against `NS_PRESENTATION` returned nothing: 87 decks of the corpus — the whole `O14ISOStrict` half of Microsoft's own test set — rendered as no slides at all, and reported not as an error but as an empty presentation. The relationships were already canonicalised, which is why the packages opened and the failure looked like a parse and not like a namespace.

parseTheme
function parseTheme(root: XmlElement): Theme

Reads a theme part whole.

pixelsToColumnWidth
function pixelsToColumnWidth(pixels: number, maxDigitWidth?: number): number

Inverse of {@link columnWidthToPixels}.

pixelsToTwips
function pixelsToTwips(pixels: number): number
pointsToEmu
function pointsToEmu(points: number): number
presetGeometryPath
function presetGeometryPath(geometry: PresetGeometry): string | undefined

Builds the outline of a preset shape.

presetOf
function presetOf(geometry: string | DiagramGeometry | undefined): string | undefined

The preset's name, whichever of the two forms the look carries.

presetTextRectangle
function presetTextRectangle(preset: string | undefined, width: number, height: number, adjustments?: Readonly<Record<string, number>>): { left: number; top: number; right: number; bottom: number; } | undefined

The text rectangle of a preset geometry: where a shape's words go. Every preset in ECMA-376 Part 1 §20.1.10.56 states an `a:rect` beside its outline, and it is not the frame: an ellipse keeps its text inside the square inscribed in it, a diamond inside the middle quarter, a triangle off its point. Laid out across the frame instead, the words of a round badge run to the very edge of its box and break at other places — `educational- 195ca7de1415` heads its sheet with `2. 2. DÔKAZY EXISTENCIE BOHA` in a circle and Word breaks it on four lines where the frame held three. The formulas are the specification's `presetShapeDefinitions.xml`, with the default adjust values it states. A preset not listed here keeps the frame, which is what it had before and what most of them are.

propertyValue
function propertyValue(properties: ReadonlyMap<number, ArtProperty>, id: number): number | undefined
readColorContainer
function readColorContainer(parser: XmlPullParser): DiagramColor | undefined

Reads the colour inside a container such as `a:solidFill`. Every colour model shares one shape: an element that names the colour, with the transforms applied to it as its children.

readCoreProperties
function readCoreProperties(pkg: OpcPackage): Promise<DocumentMetadata>

Reads document metadata from `docProps/core.xml`, `app.xml` and `custom.xml`. Parsing is identical for docx, xlsx and pptx because this is part of OPC, not of any specific format. All three parts are optional: files produced by third-party generators frequently omit them, and their absence must not stop the document from opening.

readGeometry
function readGeometry(parser: XmlPullParser): DiagramGeometry

Reads `a:prstGeom` or `a:custGeom` from a stream. The DOM reader in `element.ts` answers the same question for the formats that parse a drawing into a tree first. A document does not: `word/document.xml` is read once, in order, and so the shape of a shape has to be taken as it goes past. The parser must be positioned on the geometry element itself; it is consumed whole.

readOutline
function readOutline(parser: XmlPullParser): DiagramOutline

Reads `a:ln`: width, dash pattern and the colour it is stroked with.

rectanglePath
function rectanglePath(width: number, height: number): string

An axis-aligned rectangle path, the fallback for an unknown preset.

relationshipsPathFor
function relationshipsPathFor(partName: string): string

Path of a part's `.rels` file: `word/document.xml` → `word/_rels/document.xml.rels`.

relationshipsXml
function relationshipsXml(relationships: readonly Relationship[]): string

One `.rels` part, as the package format states it.

resolveColor
function resolveColor(themeColor: ThemeColorLookup, color: DiagramColor | undefined): string | undefined

Turns a DrawingML colour into CSS. The transforms are applied in the order they were written, because they compose: SmartArt colour lists shift hue, saturation and luminance together to derive one node's colour from the previous one, and applying them in a fixed order of our own choosing produces a different palette.

resolvePartPath
function resolvePartPath(ownerPartName: string, target: string): string

Resolves a relationship target relative to its owning part. Targets come both absolute (`/word/media/image1.png`) and relative (`../media/image1.png`); both forms appear in files written by real Word.

rowHeightToPixels
function rowHeightToPixels(heightInPoints: number): number

Excel row heights are expressed in points.

shade
function shade(color: Rgba, amount: number): Rgba

Darkening (`shade`): mixes towards black, in linear light as {@link tint}. Probe `drawing-tint-shade`: `4F81BD` at `a:shade val="40000"` is `31547D` in Word, `20344C` by the sRGB product. The duotone of `educational- 39666b1eceab`'s pictures — `accent1` shaded to 45% — was drawn a navy where Word draws a mid blue.

shadowCss
function shadowCss(shadow: DiagramShadow | undefined, themeColor: ThemeColorLookup): string | undefined

A shadow as CSS. The file states a distance and a direction; CSS wants two offsets, so the angle is resolved into them. The blur radius is DrawingML's, which is twice what CSS calls one — a `blurRad` of 40 000 EMUs is a soft edge four pixels wide, not eight.

shadowOf
function shadowOf(properties: XmlElement | undefined): DiagramShadow | undefined

Reads `a:effectLst`: what the shape does beyond its own outline. Only the shadow, and only the first one: a shape may state a glow, a reflection and a soft edge as well, and of the corpus's 1 044 effect lists 784 hold a shadow while three hold a glow. The shadow is what shows.

shapeCss
function shapeCss(shape: ShapeLook, box: { width: number; height: number; }, themeColor: ThemeColorLookup): ShapeCss

The declarations that draw a shape. The geometry is honoured as far as CSS can take it: a rectangle is a rectangle, rounded corners are a radius, an ellipse is a radius of half. Everything else is drawn as its bounding rectangle — which the corpus says is a fair trade, since of the 2 862 shapes in it 2 827 are plain rectangles and 34 are rounded ones.

shapeProperties
function shapeProperties(container: ArtRecord): Map<number, ArtProperty>

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

styleOf
function styleOf(style: XmlElement | undefined): ShapeStyleReference | undefined

Reads `p:style`, `xdr:style` or `wps:style`: how the theme paints the shape. The element is in the format's own namespace but everything inside it is DrawingML, which is why one reader serves all three.

supportsObjectUrls
function supportsObjectUrls(): boolean

True when the host can mint object URLs.

symbolCodeOf
function symbolCodeOf(font: string | undefined, text: string): number | undefined

The code a symbol font's character was written as, from what it was mapped to. The inverse of {@link mapSymbolCharacter}, for whoever holds the mapped text and needs the glyph back — a painter drawing the bullet the font draws rather than the character it stands for. A private-use character is its own code; a byte the table does not map is kept as the byte, so it is its own code too.

symbolShape
function symbolShape(font: string | undefined, code: number): SymbolShape | undefined

The shape a symbol font draws for a code, or nothing. The code as a document writes it: the byte, or `0xF000` plus it, which mean the same glyph.

themeColors
function themeColors(root: XmlElement): ThemeColorLookup

Builds a lookup from a theme part. The pairs are aliases: `tx1` is `dk1` and `bg1` is `lt1`, which is how a chart and a cell can name the same colour differently.

themeFill
function themeFill(reference: StyleReference | undefined, theme: Theme): DiagramColor | undefined

The colour of the theme entry a fill reference names.

themeLine
function themeLine(reference: StyleReference | undefined, theme: Theme): DiagramOutline | undefined

The line of the theme entry a line reference names.

themeShade
function themeShade(color: Rgba, amount: number): Rgba

`w:themeShade`: WordprocessingML's darkening, which is not DrawingML's. [MS-OI29500] §2.1.72 a says so outright — "The standard specifies an algorithm for themeShade calculations that is **different from themeShade calculations in other subclauses**" — and then gives it: convert the colour to HSL, multiply the **luminance**, convert back. {@link shade} above is the DrawingML operation, a mix towards black in RGB, and the two are not close: the specification's own example, `accent2` = `C0504D` at `w:themeShade="BF"`, comes out `943634` by luminance and `A94543` by DrawingML's linear-light mix. The arithmetic is Word's own, on integers of 0..255 rather than on the unit interval, because that is what reproduces the example to the byte: hue and saturation rounded, luminance **truncated** — `C0504D` has a luminance of exactly 134.5 and Word takes 134 — the shade applied as `L × themeShade / 255` and rounded, and the conversion back rounded. The tint example of §2.1.72 c, `4F81BD` at `w:themeTint="99"`, comes out `95B2D7` here against the `95B3D7` printed there: **one unit of green**, on a boundary where the conversion back lands on 178.48. No arrangement of rounding over both examples was found that answers each of them exactly, and a unit of 255 in one channel is below what a reader can see; the RGB mix it replaces is out by tens.

themeTint
function themeTint(color: Rgba, amount: number): Rgba

`w:themeTint`: the same, lightening. `L' = L × themeTint / 255 + (255 − themeTint)`, which is the luminance moved that share of the way to white. See {@link themeShade} for why this is not {@link tint}.

tint
function tint(color: Rgba, amount: number): Rgba

Lightening (`tint` in DrawingML): mixes towards white, **in linear light**. Not in sRGB. Probe `drawing-tint-shade` fills a square of `4F81BD` at `a:tint val="40000"` and Word paints `D0D8E8`, where the sRGB mix would be `B9CDE5`; black at half a tint comes out `BCBCBC`, not `808080`. LibreOffice's `oox` reads it the same way, by way of its `crgb` model.

twips
function twips(value: number): Length

A twips measurement as a {@link Length}, converted to points on the way.

twipsToPixels
function twipsToPixels(twips: number): number
twipsToPoints
function twipsToPoints(twips: number): number
vmlPreviewRelationship
function vmlPreviewRelationship(xml: string, shapeId: string): string | undefined

The picture a legacy embedded object was saved with, out of the VML drawing that holds it. An embedded object — a worksheet, a document, a chart of another application — is drawn by its own program, which no reader has. What every reader draws instead is the picture of it the file was saved with. Modern files put that picture where it can be found, in the `mc:Fallback` beside the object. Older ones do not: the object carries an `spid` and nothing else, and the picture is a VML shape of that id in a separate drawing part, related to the slide. That is not a historical curiosity. Of the 146 embedded objects in the presentation corpus, 45 are of this shape, and every one of them has the picture in the VML — so a reader that stops at `mc:Fallback` draws a third of the embedded objects it meets as nothing at all. Worth 121 lines of the 134389 the corpus compares, against a ceiling of about a thousand, and the gap between those two numbers has a cause worth knowing: PowerPoint does not always draw these as text either. `npoi/45541_Footer` embeds a slide whose preview holds a hundred words; PowerPoint's own export rasterises it and writes two. Drawing the preview is right for a reader — the words are on the screen and can be selected — and the reference happens not to reward it.

Interfaces

ArtProperty
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
ArtRecord
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[]
ChartAxis
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.
ChartDefinition
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.
ChartPlot
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[]
ChartPoint
interface ChartPoint

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

index
number
value
number
ChartSeries
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`.
ChartTextStyle
interface ChartTextStyle

The text of one part of a chart, `c:txPr/a:pPr/a:defRPr`. A chart states its type sizes rather than inheriting them from the page: an axis whose labels are 9pt says so, and drawing them at the renderer's own default is a chart whose every label is the wrong size — which is what `long_legendentry` measures as 13.33px against Word's 12.

sizePoints
number | undefined
`a:defRPr/@sz`, in points.
bold
boolean | undefined
italic
boolean | undefined
color
DiagramColor | undefined
typeface
string | undefined
`a:defRPr/a:latin/@typeface`: the face this part of the chart is set in. A chart carries its own type as well as its own sizes — an axis that says `Calibri` is drawn in Calibri whatever the page around it inherits — and the face is also what the width of a label is measured from, so reading it moves the plot's edge as well as the letters.
CustomGeometry
interface CustomGeometry

`a:custGeom`: one or more outlines, each in its own coordinate space.

paths
readonly GeometryPath[]
width
number
The shape's own extent in EMUs, which is the space a path that declares none is written in. Without it such a path is drawn in EMUs against a box measured in pixels — ten thousand times too large, and what reaches the screen is a few stray strokes where a rounded box should be.
height
number
textRectangle?
{ readonly left: number; readonly top: number; readonly right: number; readonly bottom: number; } | undefined
`a:custGeom/a:rect`: where the *text* goes, in the shape's own EMUs. A custom outline says where its words sit as well as where its edges are, and the two are not the same rectangle — a banner or a chevron keeps its text clear of the point. Every `a:custGeom` of the corpus states one: 334 of 334 in eighty decks.
DiagramColor
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[]
DiagramColorTransform
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.
DiagramDrawing
interface DiagramDrawing
shapes
readonly DiagramShape[]
DiagramFrame
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
DiagramGeometry
interface DiagramGeometry

What shape a shape is: a named preset with its adjustments, or an outline written out point by point. The two are alternatives in the file (`a:prstGeom` or `a:custGeom`) and are kept as alternatives here. The preset's name matters even when the renderer cannot draw it — a `rect` is a div and needs no path at all — so the name is carried rather than resolved at parse time.

preset
string | undefined
`a:prstGeom/@prst`, or `undefined` for a custom outline.
adjustments
Readonly<Record<string, number>>
`a:avLst`: the preset's adjust values, by name, as the file states them.
custom
CustomGeometry | undefined
DiagramLineEnd
interface DiagramLineEnd

One end of a line: an arrowhead, a diamond, an oval, and how big.

type
string
`@type`: `triangle`, `stealth`, `arrow`, `diamond`, `oval`.
width
"small" | "medium" | "large"
`@w` and `@len`: `sm`, `med` or `lg`.
length
"small" | "medium" | "large"
DiagramOutline
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
DiagramParagraph
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[]
DiagramRun
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
DiagramShadow
interface DiagramShadow

`a:outerShdw`: the shadow a shape casts. Stated as a distance and a direction rather than as two offsets, because that is how a drawing application asks for one: "ten points, down and to the right". Seven hundred and eighty-four shapes of the corpus cast one, and a panel drawn without its shadow sits flat against the slide behind it.

blurEmu
number
`@blurRad`, in EMUs.
distanceEmu
number
`@dist`, in EMUs: how far the shadow is thrown.
directionDegrees
number
`@dir`, in degrees clockwise from the positive x axis.
color
DiagramColor | undefined
inner
boolean
`a:innerShdw` rather than `a:outerShdw`.
DiagramShape
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.
DiagramTextBody
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[]
GeometryBox
interface GeometryBox

The box a shape is drawn in, in pixels.

width
number
height
number
GeometryPath
interface GeometryPath
width
number
`a:path/@w` and `@h`; zero means the coordinates are the shape's own.
height
number
filled
boolean
`@fill="none"` draws an open figure — a squiggle rather than a blob.
stroked
boolean
commands
readonly GeometryCommand[]
GradientStop
interface GradientStop
position
number
`@pos`, as a fraction of the way along.
color
DiagramColor | undefined
MediaResolverOptions
interface MediaResolverOptions
urls?
MediaUrlFactory | undefined
How bytes become URLs. Defaults to object URLs in a browser, data URIs elsewhere. Worth overriding when the URLs outlive the resolver — a server writing images to disk and referencing them by path, say — or when a page wants data URIs so that the markup it produces is self-contained.
MediaUrlFactory
interface MediaUrlFactory

Mints and releases URLs for media parts.

create
(bytes: Uint8Array, contentType: string) => string
revoke
(url: string) => void
OfficeArtContent
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
OpcWriteOptions
interface OpcWriteOptions
compress?
boolean | undefined
Compress parts this writer produces. On by default. Off makes every produced part stored, which is what a test comparing generated XML against expected XML wants, and what a runtime without `CompressionStream` gets regardless.
PresetGeometry
interface PresetGeometry

Everything a preset needs to produce its path.

preset
string
`a:prstGeom/@prst`.
width
number
height
number
adjust?
ReadonlyMap<string, number> | undefined
`a:avLst` values by name, in their raw units.
Relationship
interface Relationship

A relationship between package parts (`.rels`).

id
string
type
string
Relationship type URI; see the `REL_*` constants.
target
string
Target path: relative to the owning part, or absolute from the package root.
targetMode
"Internal" | "External"
ShapeLook
interface ShapeLook

The look of a shape, as much of it as the format states. Every field is optional because the formats state different amounts: a spreadsheet shape carries text insets and a wrap flag, a slide shape carries neither, and both carry a geometry, a fill and an outline.

geometry?
string | DiagramGeometry | undefined
The shape's geometry: its preset name, or the whole record. Both are accepted because both are useful. The CSS below needs only the name — a rounded rectangle is a border-radius — while an arrow needs the adjust values and a freeform needs its points, and those live on the record that {@link geometryPath } turns into a path.
fill?
DiagramColor | undefined
filled?
boolean | undefined
outline?
DiagramOutline | undefined
textColor?
DiagramColor | undefined
shadow?
DiagramShadow | undefined
`a:effectLst/a:outerShdw`, when the shape casts one.
paint?
DiagramFill | undefined
The fill as the file states it, when it is not a flat colour. `fill` above is the solid case, which is what most shapes have and what every caller already reads. This carries the other four — gradient, pattern, picture, none — and wins over `fill` when it is present.
typeface?
string | undefined
The typeface the shape's `a:fontRef` resolves to, if any.
fontSize?
number | undefined
Point size in hundredths, as `a:rPr/@sz` states it.
bold?
boolean | undefined
textBox?
boolean | undefined
insets?
{ left: number; top: number; right: number; bottom: number; } | undefined
wrap?
boolean | undefined
horizontalAlignment?
"left" | "center" | "right" | "justify" | undefined
verticalAlignment?
"center" | "top" | "bottom" | undefined
ShapeOutlinePath
interface ShapeOutlinePath

Where a shape's outline is drawn and how it is painted.

d
string
The `d` attribute of an SVG path, in the box's pixel space.
fillRule
"nonzero" | "evenodd"
`evenodd` for shapes with a hole in them: a ring, a frame, a donut.
filled
boolean
Whether the path encloses an area at all, or is a stroke such as a brace.
ShapeStyleReference
interface ShapeStyleReference

`p:style`: the four references a shape is painted by.

fill
StyleReference | undefined
line
StyleReference | undefined
effect
StyleReference | undefined
font
{ readonly typeface: "major" | "minor" | "none"; readonly color: DiagramColor | undefined; } | undefined
`a:fontRef`, whose `@idx` is `major`, `minor` or `none`.
StyleReference
interface StyleReference

One `a:fillRef`/`a:lnRef`/`a:effectRef`/`a:fontRef`.

index
number
`@idx`: which entry of the theme's list, one-based. Zero means none.
color
DiagramColor | undefined
The colour that replaces the entry's `phClr` placeholder.
SymbolShape
interface SymbolShape

One bullet: its advance and the path that draws it, in thousandths of an em.

advance
number
The advance the glyph takes, which is where the next character begins.
path
string
An SVG path in font units: *x* rightwards from the pen, *y* upwards from the baseline. Filled with the even-odd rule, so a ring is two circles.
Theme
interface Theme

The whole theme, not just its colours. A shape rarely states how it is painted. It states a *reference* — "the second fill of the theme, in accent 1" — and the theme's `a:fmtScheme` holds the three fills, the three lines and the three effect sets that every shape in the deck is drawn from. Thirty per cent of the corpus's slides have shapes like that, and without the format scheme they are drawn with no fill at all, which is how a SmartArt diagram comes out as invisible text on white.

color
ThemeColorLookup
A theme colour by its slot name.
fills
readonly ThemeFill[]
`a:fillStyleLst`: the subtle, moderate and intense fills, in order.
lines
readonly DiagramOutline[]
`a:lnStyleLst`, in the same order.
backgrounds
readonly ThemeFill[]
`a:bgFillStyleLst`: the same three, for backgrounds.
fonts
{ readonly major: string | undefined; readonly minor: string | undefined; }
`a:fontScheme`: the deck's two typefaces.
ThemeFill
interface ThemeFill

One entry of the theme's fill list. Every colour in it is `phClr` — the placeholder the referring shape fills in — carrying the transforms that make the entry what it is: the "moderate" fill is the shape's own colour tinted and lightened. Only the first colour is kept, because a gradient drawn as its first stop is much closer than a gradient drawn as nothing.

color
DiagramColor | undefined
gradient
boolean
Whether the entry was a gradient rather than a flat colour.
picture?
string | undefined
`a:blipFill`: the picture this entry paints with, by relationship id. Office themes carry their textured backgrounds here — the third entry of `a:bgFillStyleLst` is a photograph in a good many of them — and a master that names it with `p:bgRef idx="1003"` is asking for that photograph and nothing else. Resolved against the *theme* part, which is where the relationship lives.

Type aliases

ChartGrouping
type ChartGrouping = 'clustered' | 'stacked' | 'percentStacked' | 'standard'

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

ChartKind
type ChartKind = | 'bar' | 'line' | 'pie' | 'doughnut' | 'area' | 'scatter' | 'bubble' | 'radar' | 'stock' | 'surface'

How the marks of one plot are laid out.

ChartLegendPosition
type ChartLegendPosition = 'l' | 'r' | 't' | 'b' | 'tr'

Where the legend goes, `c:legendPos`.

DiagramFill
type DiagramFill = | { readonly kind: 'solid'; readonly color: DiagramColor | undefined } | { readonly kind: 'gradient'; readonly stops: readonly GradientStop[]; /** `a:lin/@ang` in degrees clockwise; a path gradient has no angle. */ readonly angleDegrees: number; /** `a:path`: the gradient radiates rather than sweeps. */ readonly radial: boolean; } | { readonly kind: 'pattern'; /** `@prst`: `pct25`, `ltDnDiag`, `narVert` and seven dozen others. */ readonly preset: string; readonly foreground: DiagramColor | undefined; readonly background: DiagramColor | undefined; } | { readonly kind: 'picture'; /** `a:blip/@r:embed`: the part holding the image. */ readonly relationshipId: string | undefined; readonly tile: boolean; } | { readonly kind: 'none' }

How a shape is filled, when a flat colour is not the answer. `a:solidFill` is one of five, and the other four were all drawn as nothing: a gradient panel, a hatched box, a shape filled with a photograph and a shape explicitly filled with nothing came out identical — unpainted.

GeometryCommand
type GeometryCommand = | { readonly kind: 'move'; readonly x: number; readonly y: number } | { readonly kind: 'line'; readonly x: number; readonly y: number } | { readonly kind: 'cubic'; readonly x1: number; readonly y1: number; readonly x2: number; readonly y2: number; readonly x: number; readonly y: number; } | { readonly kind: 'quadratic'; readonly x1: number; readonly y1: number; readonly x: number; readonly y: number; } | { /** `a:arcTo`: two radii and a turn, rather than a destination. */ readonly kind: 'arc'; readonly radiusX: number; readonly radiusY: number; /** Sixtieths of a degree, as the file states them. */ readonly startAngle: number; readonly swingAngle: number; } | { readonly kind: 'close' }
MathNode
type MathNode = | { readonly kind: 'run'; readonly text: string; readonly upright: boolean; /** * `a:rPr/@sz` on the run, in points. * * An equation states its type on every run — DrawingML's own `a:rPr` * inside the maths namespace — and a reader that takes only `m:rPr` draws * the whole equation at whatever the paragraph's default happens to be. * `13923071-Slides-Traceability` sets Planck's constant in 28 points and * it came out at 18: two thirds of the size, and not one of its lines * pairs. */ readonly sizePoints?: number; } /** `m:f`: a fraction, or a slash where the file says `lin`. */ | { readonly kind: 'fraction'; readonly numerator: readonly MathNode[]; readonly denominator: readonly MathNode[]; /** `m:type`: `bar` (the default), `lin`, `noBar` or `skw`. */ readonly bar: boolean; } /** `m:sSup`, `m:sSub`, `m:sSubSup`: a base with what hangs off it. */ | { readonly kind: 'scripts'; readonly base: readonly MathNode[]; readonly sub: readonly MathNode[] | undefined; readonly sup: readonly MathNode[] | undefined; } /** `m:rad`: a root, with the degree it states. */ | { readonly kind: 'radical'; readonly degree: readonly MathNode[] | undefined; readonly radicand: readonly MathNode[]; } /** `m:d`: a delimited group — brackets, and the items between them. */ | { readonly kind: 'delimited'; readonly open: string; readonly close: string; readonly separator: string; readonly items: readonly (readonly MathNode[])[]; } /** `m:nary`: a sum, an integral or a product, with its limits. */ | { readonly kind: 'nary'; readonly symbol: string; readonly sub: readonly MathNode[] | undefined; readonly sup: readonly MathNode[] | undefined; readonly body: readonly MathNode[]; /** `m:limLoc`: whether the limits sit under and over, or beside. */ readonly stacked: boolean; } /** `m:limLow`, `m:limUpp`: a limit under or over its base. */ | { readonly kind: 'limit'; readonly base: readonly MathNode[]; readonly limit: readonly MathNode[]; readonly above: boolean; } /** `m:acc`, `m:bar`, `m:groupChr`: a mark over or under a base. */ | { readonly kind: 'marked'; readonly base: readonly MathNode[]; readonly mark: string; readonly above: boolean; } /** `m:m`: a matrix, row by row. */ | { readonly kind: 'matrix'; readonly rows: readonly (readonly (readonly MathNode[])[])[] } /** Anything not read yet, and the sequence it held. */ | { readonly kind: 'group'; readonly items: readonly MathNode[] }

One node of an equation; a sequence of them is an equation.

ShapeCss
type ShapeCss = Partial<Record<string, string>>
ThemeColorLookup
type ThemeColorLookup = (slot: string) => string | undefined

How a chart finds out what a theme slot is worth.

Values

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

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

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

CONTENT_TYPE_DOCX
CONTENT_TYPE_DOCX: "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"

Content types of main parts; used to identify the document format.

CONTENT_TYPE_DOCX_TEMPLATE
CONTENT_TYPE_DOCX_TEMPLATE: "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml"
CONTENT_TYPE_PPTX
CONTENT_TYPE_PPTX: "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"
CONTENT_TYPE_PPTX_SLIDESHOW
CONTENT_TYPE_PPTX_SLIDESHOW: "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml"
CONTENT_TYPE_PPTX_TEMPLATE
CONTENT_TYPE_PPTX_TEMPLATE: "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml"
CONTENT_TYPE_XLSX
CONTENT_TYPE_XLSX: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"
CONTENT_TYPE_XLSX_TEMPLATE
CONTENT_TYPE_XLSX_TEMPLATE: "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml"
EIGHTHS_PER_POINT
EIGHTHS_PER_POINT: 8

Eighths of a point: the unit of border widths in WordprocessingML.

EMPTY_THEME
EMPTY_THEME: Theme

An empty theme, for the documents that carry none.

EMU_PER_CM
EMU_PER_CM: 360000

EMUs per centimetre.

EMU_PER_INCH
EMU_PER_INCH: 914400

English Metric Units: 914400 per inch. The base unit of DrawingML.

EMU_PER_POINT
EMU_PER_POINT: 12700

EMUs per point: 914400 / 72.

HIGHLIGHT_COLORS
HIGHLIGHT_COLORS: Readonly<Record<string, string>>

Named `ST_HighlightColor` values from WordprocessingML.

NS_CONTENT_TYPES
NS_CONTENT_TYPES: "http://schemas.openxmlformats.org/package/2006/content-types"

OPC package parts: content types and relationships.

NS_CORE_PROPERTIES
NS_CORE_PROPERTIES: "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"

Document metadata.

NS_CUSTOM_PROPERTIES
NS_CUSTOM_PROPERTIES: "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"
NS_DC
NS_DC: "http://purl.org/dc/elements/1.1/"
NS_DC_TERMS
NS_DC_TERMS: "http://purl.org/dc/terms/"
NS_DOC_PROPS_VTYPES
NS_DOC_PROPS_VTYPES: "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
NS_DRAWING
NS_DRAWING: "http://schemas.openxmlformats.org/drawingml/2006/main"

DrawingML — shared graphics for all three formats.

NS_DRAWING_CHART
NS_DRAWING_CHART: "http://schemas.openxmlformats.org/drawingml/2006/chart"
NS_DRAWING_DIAGRAM
NS_DRAWING_DIAGRAM: "http://schemas.openxmlformats.org/drawingml/2006/diagram"

SmartArt: the diagram definition, and the shapes Word laid out from it. The definition namespace is part of the standard, but the laid-out result is not: Word writes it under a Microsoft namespace as an extension. That drawing is what makes SmartArt viewable at all without reimplementing the diagram layout algorithms, so a reader that ignores extension parts renders nothing.

NS_DRAWING_DIAGRAM_SHAPE
NS_DRAWING_DIAGRAM_SHAPE: "http://schemas.microsoft.com/office/drawing/2008/diagram"
NS_DRAWING_PICTURE
NS_DRAWING_PICTURE: "http://schemas.openxmlformats.org/drawingml/2006/picture"
NS_DRAWING_SPREADSHEET
NS_DRAWING_SPREADSHEET: "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
NS_DRAWING_WORDPROCESSING
NS_DRAWING_WORDPROCESSING: "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
NS_EXTENDED_PROPERTIES
NS_EXTENDED_PROPERTIES: "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
NS_MARKUP_COMPATIBILITY
NS_MARKUP_COMPATIBILITY: "http://schemas.openxmlformats.org/markup-compatibility/2006"

Markup Compatibility and Extensibility: `mc:AlternateContent` fallbacks.

NS_MATH
NS_MATH: "http://schemas.openxmlformats.org/officeDocument/2006/math"

Office Math Markup Language, used for equations.

NS_OFFICE_EXCEL_MAIN
NS_OFFICE_EXCEL_MAIN: "http://schemas.microsoft.com/office/excel/2006/main"
NS_OFFICE_RELATIONSHIPS
NS_OFFICE_RELATIONSHIPS: "http://schemas.openxmlformats.org/officeDocument/2006/relationships"

The `r:id` reference namespace used inside document parts.

NS_PACKAGE_RELATIONSHIPS
NS_PACKAGE_RELATIONSHIPS: "http://schemas.openxmlformats.org/package/2006/relationships"
NS_PRESENTATION
NS_PRESENTATION: "http://schemas.openxmlformats.org/presentationml/2006/main"

PresentationML — pptx.

NS_SPREADSHEET
NS_SPREADSHEET: "http://schemas.openxmlformats.org/spreadsheetml/2006/main"

SpreadsheetML — xlsx.

NS_SPREADSHEET_X14
NS_SPREADSHEET_X14: "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"

The two namespaces Excel's own extensions live in. Everything added after the schema was published — sparklines, the newer conditional formats, slicers — is written inside an `extLst` under these, so that a reader of the published schema steps over what it cannot know.

NS_VML
NS_VML: "urn:schemas-microsoft-com:vml"

VML: the legacy vector format still emitted by Word for text boxes and shapes.

NS_VML_OFFICE
NS_VML_OFFICE: "urn:schemas-microsoft-com:office:office"
NS_VML_WORD
NS_VML_WORD: "urn:schemas-microsoft-com:office:word"
NS_WORD_2006
NS_WORD_2006: "http://schemas.microsoft.com/office/word/2006/wordml"

Word 2006 extensions, which carry a text box's content in a strict file. The namespace's usual load is key mappings and mail-merge state in `settings.xml`, where it is written `wne:`. It has one other use, and it is not one a reader can skip: [MS-OI29500] §2.1.1779 b says that a strict file saved by Word puts the `txbxContent` of a VML text box inside an `mc:Choice`, and writes it in *this* namespace rather than in WordprocessingML. Matching the element on `NS_WORDPROCESSING` alone loses the text of every text box in such a file, silently.

NS_WORD_2010
NS_WORD_2010: "http://schemas.microsoft.com/office/word/2010/wordml"

Word 2010+ extensions, where later features such as `w14:` live.

NS_WORD_2012
NS_WORD_2012: "http://schemas.microsoft.com/office/word/2012/wordml"
NS_WORD_2016_CID
NS_WORD_2016_CID: "http://schemas.microsoft.com/office/word/2016/wordml/cid"

Word 2016's comment and list identities, `w16cid:`. A `w:numId` is a position in this document's table and changes when lists are merged; `w16cid:durableId` is the identity that does not.

NS_WORD_DRAWING_2010
NS_WORD_DRAWING_2010: "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"
NS_WORD_SHAPE
NS_WORD_SHAPE: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape"

Shapes and text boxes as Word has written them since 2010. These appear only inside `mc:AlternateContent`, paired with a VML fallback for readers that predate them. The modern branch is the one that carries the text of a text box as ordinary WordprocessingML.

NS_WORD_SHAPE_GROUP
NS_WORD_SHAPE_GROUP: "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"
NS_WORDPROCESSING
NS_WORDPROCESSING: "http://schemas.openxmlformats.org/wordprocessingml/2006/main"

WordprocessingML — docx.

NS_XML
NS_XML: "http://www.w3.org/XML/1998/namespace"

The reserved `xml:` namespace, needed for `xml:space="preserve"`.

REL_ALT_CHUNK
REL_ALT_CHUNK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk"
REL_CHART
REL_CHART: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"
REL_COMMENTS
REL_COMMENTS: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"
REL_COMMENTS_EXTENDED
REL_COMMENTS_EXTENDED: "http://schemas.microsoft.com/office/2011/relationships/commentsExtended"
REL_CORE_PROPERTIES
REL_CORE_PROPERTIES: "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"
REL_CUSTOM_PROPERTIES
REL_CUSTOM_PROPERTIES: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties"
REL_DRAWING
REL_DRAWING: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"
REL_ENDNOTES
REL_ENDNOTES: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes"
REL_EXTENDED_PROPERTIES
REL_EXTENDED_PROPERTIES: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties"
REL_FONT
REL_FONT: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/font"
REL_FONT_TABLE
REL_FONT_TABLE: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable"
REL_FOOTER
REL_FOOTER: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer"
REL_FOOTNOTES
REL_FOOTNOTES: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes"
REL_HEADER
REL_HEADER: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header"
REL_HYPERLINK
REL_HYPERLINK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
REL_IMAGE
REL_IMAGE: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
REL_NUMBERING
REL_NUMBERING: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering"
REL_OFFICE_DOCUMENT
REL_OFFICE_DOCUMENT: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"

Relationship types used to locate the key parts of a document.

REL_SETTINGS
REL_SETTINGS: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings"
REL_SHARED_STRINGS
REL_SHARED_STRINGS: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"
REL_SLIDE
REL_SLIDE: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide"
REL_SLIDE_LAYOUT
REL_SLIDE_LAYOUT: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"
REL_SLIDE_MASTER
REL_SLIDE_MASTER: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"
REL_STYLES
REL_STYLES: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
REL_TABLE
REL_TABLE: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table"
REL_THEME
REL_THEME: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"
REL_WORKSHEET
REL_WORKSHEET: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"
TWIPS_PER_INCH
TWIPS_PER_INCH: 1440

Twentieths of a point: 1440 per inch. The unit of WordprocessingML.

TWIPS_PER_POINT
TWIPS_PER_POINT: 20

@genomdev/office-core/ole

Classes

CompoundFile
class CompoundFile
open
(source: ByteSource) => Promise<CompoundFile>
Reads the header, the allocation tables and the directory.
looksLikeOne
(source: ByteSource) => Promise<boolean>
Whether the first bytes of a source carry the compound file signature.
entries
() => readonly DirectoryEntry[]
Every entry of the directory, the root excluded, in tree order.
rootClsid
string | undefined
Class id of the root storage; for a Word document it names the writer.
entry
(path: string) => DirectoryEntry | undefined
Finds an entry by path. The exact name is tried first and a case-insensitive match second. Word always writes `WordDocument`, but the streams inside embedded objects come from whatever produced them, and matching case-sensitively there loses parts of documents that open everywhere else.
has
(path: string) => boolean
read
(entryOrPath: DirectoryEntry | string) => Promise<Uint8Array>
Reads a stream in full.
readIfPresent
(path: string) => Promise<Uint8Array | undefined>
Reads a stream if it exists, rather than throwing when it does not.
dispose
() => void

Functions

codePageForCharset
function codePageForCharset(charset: number): number | undefined

The code page implied by a font's character set.

codePageForLanguage
function codePageForLanguage(lid: number): number

The code page implied by a language identifier. The fallback when nothing else says: a document with no font table, or a run whose font declares the default character set. Only the primary language — the low ten bits of the LID — decides.

decodeCodePage
function decodeCodePage(bytes: Uint8Array, codePage: number): string

Decodes eight-bit text in the given code page. Unknown pages fall back to 1252.

isKnownCodePage
function isKnownCodePage(codePage: number): boolean

Whether a code page has a decoder of its own rather than the 1252 fallback.

isWindowsAnsiCodePage
function isWindowsAnsiCodePage(codePage: number): boolean
parsePropertySet
function parsePropertySet(bytes: Uint8Array): PropertySection[]

Reads every section of a property set stream.

readOleCodePage
function readOleCodePage(file: CompoundFile): Promise<number | undefined>

The Windows code page the file's own metadata was written in. Worth asking because it is the ANSI code page of the machine that saved the document, and that is what the document's eight-bit text is in. A document whose language says English and whose characters are Cyrillic is not a contradiction — the language identifier describes the *typing*, the code page describes the *bytes* — and this is the only field that states the latter outright. Two kinds of answer are refused rather than returned. Unicode, because a property set may be UTF-8 while the body of the document is not; and Macintosh, because a document saved by Word for Mac has MacRoman metadata and a Windows-encoded body, and taking the first answer for the second turns every quotation mark into an accented letter.

readOleMetadata
function readOleMetadata(file: CompoundFile): Promise<DocumentMetadata>

Reads both summary streams and maps them onto the common metadata shape. Absent streams are not an error: a document produced by something other than Word often has neither, and a file with no author is still a file.

Interfaces

DirectoryEntry
interface DirectoryEntry

One entry of the directory: a stream, a storage, or the root of the tree.

name
string
Name as stored, without the terminating NUL.
path
string
Slash-separated path from the root, the root itself excluded.
type
EntryType
byteLength
number
Size of the stream in bytes; zero for a storage.
clsid
string | undefined
Class id of a storage, `undefined` when all zero.
index
number
Index in the directory, which is how OLE references name an entry.
startSector
number
First sector of the stream, in the FAT or the mini FAT depending on size.
PropertySection
interface PropertySection

One section of a property set, keyed by property id.

formatId
string
Format id: which set of property ids applies.
codePage
number
properties
ReadonlyMap<number, PropertyValue>

Type aliases

EntryType
type EntryType = 'root' | 'storage' | 'stream'

What a directory entry describes.

PropertyValue
type PropertyValue = string | number | boolean | Date | Uint8Array

A value read out of a property set.

Values

DOCUMENT_SUMMARY_INFORMATION
DOCUMENT_SUMMARY_INFORMATION: "\u0005DocumentSummaryInformation"
DocumentSummaryProperty
DocumentSummaryProperty: { readonly Category: 2; readonly PresentationFormat: 3; readonly ByteCount: 4; readonly LineCount: 5; readonly ParagraphCount: 6; readonly SlideCount: 7; readonly Company: 15; readonly Manager: 14; readonly ContentType: 26; readonly ContentStatus: 27; readonly Language: 28; }

`DocumentSummaryInformation` property ids.

END_OF_CHAIN
END_OF_CHAIN: 4294967294
FREE_SECTOR
FREE_SECTOR: 4294967295
MAX_REGULAR_SECTOR
MAX_REGULAR_SECTOR: 4294967290

Anything above this is a marker rather than a sector number.

SUMMARY_INFORMATION
SUMMARY_INFORMATION: "\u0005SummaryInformation"

Stream names, spelled with the control character that really starts them.

SummaryProperty
SummaryProperty: { readonly Title: 2; readonly Subject: 3; readonly Author: 4; readonly Keywords: 5; readonly Comments: 6; readonly Template: 7; readonly LastAuthor: 8; readonly RevisionNumber: 9; readonly EditingTime: 10; readonly LastPrinted: 11; readonly CreatedAt: 12; readonly ModifiedAt: 13; readonly PageCount: 14; readonly WordCount: 15; readonly CharacterCount: 16; readonly Application: 18; readonly Security: 19; }

`SummaryInformation` property ids.

@genomdev/office-core/formula

Classes

Evaluator
class Evaluator
missingFunctions
Set<string>
Functions the workbook used and this engine does not have.
workbook
WorkbookContext
evaluateFormula
(formula: string, position: CellPosition, options?: EvaluateOptions) => FormulaValue
Parses and evaluates a formula in the scope of one cell.
parse
(formula: string) => Node | FormulaError
Parses with a cache; a syntax error becomes `#NAME?`, as in Excel.
evaluate
(node: Node, position: CellPosition, options?: EvaluateOptions) => FormulaValue
materialize
(value: FormulaValue) => Matrix
Reads every value behind a value, whatever shape it arrived in.
referenceToMatrix
(reference: Reference) => Matrix
areaToMatrix
(area: Area) => Matrix
boundArea
(area: Area) => Area
Clips a reference to what the sheet actually holds. `SUM(A:A)` must not read a million cells. Excel bounds the same way, which is why a value far down a column is what makes such a formula slow rather than the reference itself.
lookupBinding
(name: string) => FormulaValue | undefined
The innermost binding of a name, if any scope holds one.
withBindings
<T>(bindings: ReadonlyMap<string, FormulaValue>, run: () => T) => T
Runs a function with extra bindings in scope.
captureScope
() => Map<string, FormulaValue>
The bindings currently in scope, flattened, for a lambda to close over.
callLambda
(lambda: Lambda, values: readonly FormulaValue[], position: CellPosition) => FormulaValue
Applies a lambda to arguments. The closure is restored first and the parameters bound over it, so that a lambda written inside a `LET` still sees that `LET`'s names when it is called from somewhere else entirely.
applyFunction
(definition: FunctionDefinition, values: readonly FormulaValue[], position: CellPosition, array: boolean) => FormulaValue
Calls a built-in with values already computed. The ordinary path wraps syntax nodes, because an argument is evaluated lazily and some functions never look at all of theirs. A function reached through `_xleta.` has no nodes behind it — its arguments arrive as values — so they are wrapped as arguments that are already done.
valueArgument
(value: FormulaValue, position: CellPosition, array: boolean) => Argument
Wraps a value that is already computed as an argument.
argument
(node: Node, position: CellPosition, array: boolean) => Argument
Wraps a node as a lazily evaluated argument.
toScalarContext
(value: FormulaValue, position: CellPosition, array?: boolean) => FormulaValue
Public form of the intersection rule, for functions that need it.
FormulaError
class FormulaError

An Excel error value. Interned, so identity comparison works.

null
FormulaError
divideByZero
FormulaError
value
FormulaError
reference
FormulaError
name
FormulaError
number
FormulaError
notAvailable
FormulaError
gettingData
FormulaError
spill
FormulaError
calc
FormulaError
all
readonly FormulaError[]
parse
(text: string) => FormulaError | undefined
Parses `#REF!` and friends; `undefined` when the text is not an error.
toString
() => string
FormulaSyntaxError
class FormulaSyntaxError extends Error
Reference
class Reference

A reference. Kept as a value in its own right rather than resolved to numbers on sight, because a dozen functions care *where* their argument is and not only what is in it: `ROW`, `COLUMN`, `OFFSET`, `INDEX` (which returns a reference), `CELL`, `ISREF`, and every function whose criteria argument is a range. More than one area happens through the union operator: `SUM((A1:A5,C1:C5))`.

cell
(sheet: number, row: number, column: number) => Reference
single
Area | undefined
isSingleCell
boolean
rowCount
number
columnCount
number

Functions

buildMatrix
function buildMatrix(rows: number, columns: number, produce: (row: number, column: number) => Scalar): Matrix

Builds a matrix of the given shape.

builtinFormatCode
function builtinFormatCode(id: number): string | undefined

The format code of a built-in id, or `undefined` when the id is not reserved.

columnFromLetters
function columnFromLetters(letters: string): number
compareScalars
function compareScalars(left: Scalar, right: Scalar): number

Compares two scalars the way `<` and `MATCH` do. Returns a negative number, zero or a positive number. Blanks are compared as the zero or empty text of whatever they meet, which is why `A1=0` and `A1=""` are both true when A1 is empty.

compileCriterion
function compileCriterion(raw: Scalar): Criterion

Compiles a `COUNTIF`-style criterion. The grammar: an optional comparison operator, then a value. Without an operator it is equality — and equality against text applies wildcards, which is why `COUNTIF(A:A,"a*")` counts everything beginning with an `a`.

compileFormat
function compileFormat(code: string): CompiledFormat

Compiles a format code, or returns the cached compilation.

constantValue
function constantValue(node: Node): Scalar | undefined

A constant node's value, for the few places that only accept constants.

dateToSerial
function dateToSerial(date: Date, date1904?: boolean): number

The inverse: a `Date` as the serial number Excel would store for it.

defineFunction
function defineFunction(names: string | readonly string[], definition: FunctionDefinition): void
emptyContext
function emptyContext(overrides?: Partial<WorkbookContext>): WorkbookContext

A workbook context with nothing in it, for evaluating a bare expression.

firstError
function firstError(value: FormulaValue): FormulaError | undefined

The first error anywhere in a value, which is what propagates.

formatNumberGeneral
function formatGeneral(value: number, widthCharacters?: number): string

Excel's `General`. Not "the number as JavaScript prints it": Excel keeps about eleven significant digits and falls back to scientific notation outside a fixed range, which is why `0.1 + 0.2` shows as `0.3` in a spreadsheet and as something longer in a console.

formatNumberGenerally
function formatNumberGenerally(value: number): string

A number as `General` renders it. Fifteen significant digits, which is the precision Excel keeps and the reason a spreadsheet shows `0.3` where a console shows the rounding error.

formatValue
function formatValue(value: string | number | boolean | Date | null, code: string | undefined, options?: FormatOptions): FormattedValue

Formats a value the way Excel would with the given code. `code` is the format string, not the id: resolving an id through the workbook's `numFmts` and the built-in table happens in the style layer, which is the only place that knows both.

indexedColor
function indexedColor(index: number, palette?: readonly string[]): string | undefined

Looks up an indexed colour, falling back to the default palette.

isDateFormat
function isDateFormat(code: string | undefined): boolean

Whether a format code shows a date or a time rather than a number.

isError
function isError(value: unknown): value is FormulaError
isMatrix
function isMatrix(value: unknown): value is Matrix
isReference
function isReference(value: unknown): value is Reference
isScalar
function isScalar(value: FormulaValue): value is Scalar
isTextFormat
function isTextFormat(code: string | undefined): boolean

Whether the code contains a text section, which is what makes it apply to strings.

lettersFromColumn
function lettersFromColumn(index: number): string
matrixAt
function matrixAt(matrix: Matrix, row: number, column: number): Scalar

Reads a matrix with Excel's broadcast rules: a single row or column repeats.

matrixSize
function matrixSize(matrix: Matrix): { rows: number; columns: number; }
normalizeFunctionName
function normalizeFunctionName(name: string): string

Strips the `_xlfn.` prefix. Functions added after 2007 are stored with it so that older versions fail predictably instead of silently. `_xlfn.IFS` and `IFS` are the same function and the library should only have to know one name. The `_xlws.` prefix, for worksheet-only functions, works the same way.

parseFormula
function parseFormula(input: string): Node
parseNumericText
function parseNumericText(text: string): number | undefined

Text that Excel accepts as a number. Deliberately stricter than `Number()`: `"1e5"` and `"0x10"` are numbers to JavaScript and text to Excel, and `""` is zero to `Number()` and an error here. Percentages, leading currency symbols and thousands separators are accepted, because Excel accepts them.

roundHalfAwayFromZero
function roundHalfAwayFromZero(value: number, digits: number): number

Rounds the way a spreadsheet does: half away from zero, at a decimal place.

serialToDate
function serialToDate(serial: number, date1904?: boolean): Date | undefined

Converts a serial number to a JavaScript `Date` in UTC.

serialToDateParts
function serialToDateParts(serial: number, date1904?: boolean): DateParts | undefined

Converts a serial number to calendar parts. Returns `undefined` for values Excel itself refuses to show as a date: negative serials in the 1900 system produce `#####`, not a date before the epoch.

supportedFunctions
function supportedFunctions(): string[]
toBoolean
function toBoolean(value: Scalar): boolean | FormulaError
toCellValue
function toCellValue(value: FormulaValue, evaluator?: Evaluator): Scalar

The single value a cell shows for a computed result.

tokenize
function tokenize(input: string): Token[]
toMatrix
function toMatrix(value: FormulaValue): Matrix
toNumber
function toNumber(value: Scalar): number | FormulaError

Coerces to a number, as an arithmetic operator would.

toText
function toText(value: Scalar): string | FormulaError

Coerces to text. A number becomes what `General` would show, not what JavaScript prints: concatenating 0.1 + 0.2 must produce `0.3`, not `0.30000000000000004`.

wildcardToRegExp
function wildcardToRegExp(text: string, anchored?: boolean): RegExp | undefined

Excel's wildcards: `*` any run, `?` one character, `~` escapes either. Returns `undefined` when the text holds no wildcard at all, so the caller can take the cheaper equality path.

Interfaces

Area
interface Area

One rectangular area of a sheet, zero-based and inclusive.

sheet
number
startRow
number
startColumn
number
endRow
number
endColumn
number
Argument
interface Argument

One argument of a function call, evaluated on demand.

node
Node
missing
boolean
value
() => FormulaValue
The value, computed once and cached.
reference
() => Reference | undefined
The reference this argument is, when it is one.
scalar
() => Scalar
A single value: a scalar, or the intersection of a reference.
matrix
() => Matrix
The rectangular values behind the argument.
values
() => Scalar[]
Every value behind the argument, in reading order. Separate from {@link matrix} because a union has no rectangular shape: `SUM((A1:A3,C1:C3))` reads six cells that no single matrix can hold.
CallContext
interface CallContext
workbook
WorkbookContext
position
CellPosition
evaluator
Evaluator
array
boolean
name
string
The name the function was called by, normalised to capitals. A handful of functions share one implementation and differ only in what their arguments mean — `BETA.DIST` reads its fourth argument as a flag where `BETADIST` reads it as a bound — and nothing but the name can tell them apart.
CellPosition
interface CellPosition

Where a formula lives. Every relative reference is resolved against it.

sheet
number
row
number
column
number
Criterion
interface Criterion
test
(value: Scalar) => boolean
DateParts
interface DateParts

Whole and fractional parts of a serial number, in calendar terms.

year
number
month
number
1..12.
day
number
1..31.
hours
number
minutes
number
seconds
number
milliseconds
number
weekday
number
0 = Sunday.
EvaluateOptions
interface EvaluateOptions
array?
boolean | undefined
Array (CSE) semantics: operands broadcast instead of intersecting, and the result may be a matrix.
FormatOptions
interface FormatOptions
date1904?
boolean | undefined
The workbook's 1904 date system flag.
locale?
string | undefined
BCP 47 locale for month and weekday names; overridden by `[$-…]` in the code.
palette?
readonly string[] | undefined
The workbook's own indexed palette, when it overrides the default.
widthCharacters?
number | undefined
How many characters the cell has room for. Only `General` uses it, and it is the reason `General` is not one format but a family: Excel shows as much of the number as fits and rounds away the rest, so the same value reads `3.337809381` in a wide column and `3.3378` in a narrow one. A caller with no column — `TEXT(x, "General")`, a text extraction — leaves it out and gets the full precision.
FormattedValue
interface FormattedValue

The result of formatting a value with a format code.

text
string
The text as Excel would display it.
color
string | undefined
Colour requested by the format code (`[Red]`), as CSS.
fill
string | undefined
The character of a `*` fill token, when the code has one. Excel repeats it until the cell is full — the usual use is `_(* #,##0_)`, the accounting format, where it pushes the number to the right edge.
kind
"number" | "boolean" | "text" | "error" | "date" | "empty"
What the value turned out to be; the renderer aligns on it.
FunctionDefinition
interface FunctionDefinition
minArgs
number
maxArgs
number
volatile?
boolean | undefined
Recomputed whenever anything changes: `TODAY`, `NOW`, `RAND`, `OFFSET`.
arrayArgs?
boolean | undefined
The arguments are arrays by nature, so they are evaluated with array semantics whether or not the formula was entered as an array. This is what makes `SUMPRODUCT((A1:A3>1)*(B1:B3))` work: without it the comparison would implicitly intersect down to one cell, and the idiom that half the spreadsheets in the world use for a conditional sum would return zero.
elementwise?
boolean | undefined
Every argument is a single value, so a range is applied element by element. `SQRT(B2:F3)` entered as an array formula is a matrix of roots, one per cell — and `SUM(B2:F3)` is not, because a sum takes the range whole. The difference is in the *arguments*, and nothing else can tell them apart, so a function that takes only single values says so here.
spreadArgs?
readonly number[] | undefined
Which arguments are single values, when the others are not. `MATCH(what, where, how)` looks one value up in a range: given an array of things to look for it answers one position for each, but the range it searches is a range in every call and must not spread. `elementwise` says "every argument is a single value"; this says which ones are.
call
(args: readonly Argument[], context: CallContext) => FormulaValue
RawReference
interface RawReference

A reference as written, before it is resolved against a workbook.

sheet
string | undefined
Sheet name, or `undefined` for the sheet the formula is on.
lastSheet
string | undefined
Last sheet of a 3D span, `Sheet1:Sheet3!A1`.
workbook
number | undefined
Index of an external workbook, `[1]Sheet1!A1`.
startColumn
number | undefined
startColumnAbsolute
boolean
startRow
number | undefined
startRowAbsolute
boolean
endColumn
number | undefined
Set for whole-column (`A:C`) and whole-row (`2:4`) references.
endColumnAbsolute
boolean
endRow
number | undefined
endRowAbsolute
boolean
broken
boolean
The reference was written as `#REF!`, so it is already broken.
TableInfo
interface TableInfo

A table, for structured references.

range
Area
headerRowCount
number
totalsRowCount
number
columns
readonly string[]
Token
interface Token
kind
TokenKind
text
string
position
number
spaceBefore
boolean
Whitespace stood before this token, which may make it an intersection.
number?
number | undefined
string?
string | undefined
error?
FormulaError | undefined
reference?
RawReference | undefined
sheet?
string | undefined
The sheet a name was qualified with, as in `Hitab!Divisor`.
structured?
{ table: string | undefined; specification: string; } | undefined
WorkbookContext
interface WorkbookContext
date1904
boolean
The 1904 date system, which shifts every date function by four years.
sheetIndex
(name: string) => number | undefined
Index of a sheet by name, case-insensitively.
sheetName
(index: number) => string | undefined
sheetCount
number
cell
(sheet: number, row: number, column: number) => Scalar
A cell's stored value. `null` for a blank cell.
formulaAt?
((sheet: number, row: number, column: number) => string | undefined) | undefined
A cell's formula, without its leading equals sign. Only `FORMULATEXT` and `ISFORMULA` ask, and both exist so that a sheet can document itself. A context that does not track formulas may leave it out.
usedRange
(sheet: number) => { rowCount: number; columnCount: number; }
The bounds of what the sheet actually contains. A whole-column reference is a million cells, and `SUM(A:A)` must not walk them. Excel bounds the same way, which is why adding a value far down a column is what makes it slow rather than the reference itself.
definedName
(name: string, sheet: number) => string | undefined
A defined name, as the formula it stands for. Names are formulas, not ranges: `Rates` is usually `Sheet1!$A$1:$B$9` but may be `OFFSET(...)` or a constant. Returning the text lets the engine evaluate it in the scope of the cell that used it, which is what makes relative names work.
table
(name: string) => TableInfo | undefined
tableAt?
((sheet: number, row: number, column: number) => TableInfo | undefined) | undefined
The table a cell stands in, for a structured reference that names none. `SUBTOTAL(101,[Column3])` is what Excel writes in a table's own totals row: inside the table the name is understood, so the formula does not repeat it. A context that does not track tables leaves this out, and such a formula is then `#REF!` — which is what it means anywhere else.
rowHidden?
((sheet: number, row: number) => boolean) | undefined
Whether a row is hidden at all, for `SUBTOTAL`'s hundred-and-something codes. `SUBTOTAL(109, …)` is `SUM` over the rows the reader can see, however they came to be invisible; a workbook that reports nothing gets the plain sum.
rowFilterHidden?
((sheet: number, row: number) => boolean) | undefined
Whether a filter is what hides a row. The distinction is not decoration: *every* `SUBTOTAL` skips the rows a filter hid — that is why a filtered table's total follows the filter — and only the hundred-and-something codes also skip the rows someone hid by hand. A context that cannot tell the two apart leaves this out, and then `SUBTOTAL(9, …)` counts everything.
workbookName?
string | undefined
The workbook's file name, for `CELL("filename")`.
columnWidth?
((sheet: number, column: number) => number | undefined) | undefined
A column's width in characters, for `CELL("width")`. The one piece of the *sheet's* appearance a formula can ask about, and a workbook that does not track widths may leave it out — the answer is then the default width, which is what Excel shows for a column nobody resized. In characters, not in the units `<col width>` is written in: the stored number carries the cell's padding as well, so a column of ten characters is written as 10.71 and `CELL("width")` still answers 10. Removing the padding is the workbook's job, because only it knows the sheet's font metrics.
now
() => Date
The clock, so that `TODAY` and `NOW` can be made deterministic in tests.
formatNumber?
((value: Scalar, code: string) => string | undefined) | undefined
Applies a number format code, for `TEXT` and `DOLLAR`. Supplied by the workbook rather than implemented here: the same codes drive how every cell is displayed, and there should be one implementation of them rather than one for the grid and another for the formula.
callUnknown?
((name: string, args: readonly unknown[]) => Scalar | undefined) | undefined
A function the engine does not implement. The hook exists for user-defined functions from a macro module: they cannot be evaluated here and never will be. Returning `undefined` produces `#NAME?`, which is what Excel itself shows when the macro is not enabled.

Type aliases

BinaryOperator
type BinaryOperator = '+' | '-' | '*' | '/' | '^' | '&' | '=' | '<>' | '<' | '>' | '<=' | '>=' | ':' | ' ' | ','
FormulaValue
type FormulaValue = Scalar | Matrix | Reference | Lambda

Everything a formula can evaluate to.

Matrix
type Matrix = Scalar[][]

A rectangular block of values, row-major. Arrays in Excel are always 2D.

Node
type Node = | { readonly kind: 'number'; readonly value: number } | { readonly kind: 'string'; readonly value: string } | { readonly kind: 'boolean'; readonly value: boolean } | { readonly kind: 'error'; readonly value: FormulaError } | { readonly kind: 'reference'; readonly reference: RawReference } | { readonly kind: 'name'; readonly name: string; readonly sheet?: string } | { readonly kind: 'structured'; readonly table: string | undefined; readonly specification: string; } | { readonly kind: 'call'; readonly name: string; readonly args: readonly Node[] } | { readonly kind: 'unary'; readonly operator: '-' | '+' | '@'; readonly operand: Node } | { readonly kind: 'percent'; readonly operand: Node } /** Calling what an expression produced: `LAMBDA(x, x + 1)(2)`. */ | { readonly kind: 'apply'; readonly callee: Node; readonly args: readonly Node[] } | { readonly kind: 'binary'; readonly operator: BinaryOperator; readonly left: Node; readonly right: Node; } | { readonly kind: 'array'; readonly rows: readonly (readonly Node[])[] } | { readonly kind: 'missing' }
Scalar
type Scalar = number | string | boolean | FormulaError | null

A single value: a number, text, a logical, an error, or a blank.

Values

functionModules
functionModules: number

How many modules the library is built from. Reading it keeps them alive.

FUNCTIONS
FUNCTIONS: Map<string, FunctionDefinition>

The function library. Modules add to it as they are imported.

INDEX_AUTOMATIC
INDEX_AUTOMATIC: 64

Automatic colour: whatever the window text colour is.

INDEX_BACKGROUND
INDEX_BACKGROUND: 65

The window background colour.

INDEXED_COLORS
INDEXED_COLORS: readonly string[]

The legacy indexed colour palette. Before themes, a workbook referred to colours by index into a 56-entry table that lived in the file (`<indexedColors>`) and, when it did not, was assumed to be this one. Files still arrive with `indexed="10"` on a font, and number format codes still say `[Color 10]`, so the default table has to be here even though nothing has written it deliberately in twenty years. Indices 0-7 repeat as 8-15: the first eight are the "system" colours and the second eight are the same colours in the user-editable part of the palette. Index 64 is "automatic" — the window text colour — and 65 the window background; both are resolved by the renderer rather than by a table.

MAX_COLUMNS
MAX_COLUMNS: 16384
MAX_ROWS
MAX_ROWS: 1048576

Enums

TokenKind
TokenKind: typeof TokenKind

@genomdev/office-core/media

Functions

decodeBlip
function decodeBlip(blip: ArtRecord, index: number): Promise<StoredPicture | undefined>
decodeDib
function decodeDib(bytes: Uint8Array, bitsOffset?: number): DecodedBitmap | undefined

Decodes a packed DIB — header, palette and bits in one run of bytes.

findBlip
function findBlip(entry: ArtRecord, delayStream: Uint8Array | undefined): ArtRecord | undefined

The picture a store entry names, wherever it is. Three places, in the order they occur. Beside the entry as a child record; inside the entry's own bytes after its header and name — both of which some writers produce — and, in nearly every document Word saved, at the offset the entry states into the delay stream.

isBlip
function isBlip(type: number): boolean

True when an Office Art record is a picture rather than something else.

isEmf
function isEmf(bytes: Uint8Array): boolean
isWmf
function isWmf(bytes: Uint8Array): boolean
metafileToSvg
function metafileToSvg(bytes: Uint8Array): string | undefined

Converts a metafile into an SVG document.

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

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. The position is taken from the entry rather than from a running count of what was found, because an entry may name a picture that is not in the file at all — Word writes one for a picture linked from elsewhere — and the shapes count those too.

Interfaces

DecodedBitmap
interface DecodedBitmap

Device-independent bitmaps, as a metafile carries them. A DIB is what Windows called an image before there were image formats: a header, a palette when the depth needs one, and rows of pixels stored bottom to top and padded to a multiple of four bytes. Every bitmap inside an EMF or a WMF is one of these, so reading them is the difference between a diagram with its screenshots and a diagram with holes. The two headers that occur are the ancient `BITMAPCOREHEADER` and the `BITMAPINFOHEADER` everything since 1995 writes; both are read, because a metafile pasted from a twenty-year-old document really does contain the first.

width
number
height
number
rgba
Uint8Array<ArrayBufferLike>
8-bit RGBA, top row first.
StoredPicture
interface StoredPicture

A picture, as the store holds it.

index
number
One-based position in the store, which is how a shape names it.
mimeType
string
bytes
Uint8Array<ArrayBufferLike>

@genomdev/office-core/view

Functions

renderChart
function renderChart(context: ChartRenderContext, chart: ChartDefinition, widthEmu: number | undefined, heightEmu: number | undefined): HTMLElement

Renders a chart part into an element of the given frame size.

renderDiagram
function renderDiagram(context: DiagramRenderContext, drawing: DiagramDrawing, widthEmu: number | undefined, heightEmu: number | undefined): HTMLElement
renderMath
function renderMath(ownerDocument: Document, nodes: readonly MathNode[], classPrefix?: string): HTMLElement

Draws an equation into one inline box.

shapeOutlineSvg
function shapeOutlineSvg(ownerDocument: Document, shape: ShapeLook, box: GeometryBox, themeColor: ThemeColorLookup, options?: { className?: string; scale?: number; }): { element: SVGElement; path: ShapeOutlinePath; } | undefined

The shape's outline as an SVG, for the geometries CSS cannot draw. Returned rather than appended so that the caller decides where it goes; every viewer puts it behind the shape's text, which the browser lays out in the shape's own box. The path is painted with the shape's own fill and line. A path the file marks as unfilled — a brace, a connector, a freehand squiggle — is stroked only, whatever fill the shape carries, because filling it would blot the slide.

Interfaces

ChartRenderContext
interface ChartRenderContext

What drawing a chart needs from the application around it. Two things and no more: a document to create elements in, and the theme's answer for a colour slot. Deliberately this narrow — the renderer used to take the Word view's whole render context, and that is the only reason it could not be used from a spreadsheet.

ownerDocument
Document
themeColor
ThemeColorLookup
Resolves a theme colour slot such as `accent1`.
classPrefix?
string | undefined
Prefix for the generated class names, so each host keeps its own.
blankTitle?
string | undefined
What the host writes as the title of a chart that states one and names it nothing; see {@link ChartDefinition.titleAutomatic}. Word writes `Chart Title` — `tdf75659` and `tdf128996` both draw it over a single series called `1. adatsor`, so it is not the series name Word takes either. PowerPoint takes the series name, which is what the definition already resolved, so a host that says nothing keeps that.
fontFamily?
string | undefined
The face the chart's labels will be drawn in, when the host knows it. The layout is decided before anything is on the page — how much room the tick labels need is what fixes the plot's left edge — so the width of a label has to be *computed*, and a computed width needs a font. Without one the estimate below falls back to a constant, which is a guess and reads as one: on the probe `chart-geometry` a two-digit tick label is 14.4 pixels of real ink and 13.9 of estimate, and the plot's edge is out by the difference on every chart in the corpus.
headingFontFamily?
string | undefined
The theme's heading face, for the parts a chart sets in `+mj-lt`. Rare — a chart states the minor face nearly everywhere — but a title that asks for the heading font and is drawn in the body one is the wrong face at the largest size on the chart.
onText?
((piece: ChartTextPiece) => void) | undefined
Told every piece of the chart's text and where the drawing put it. A chart is stored only as its definition, so a host that cannot draw it draws nothing: the Word corpus has thirteen documents whose whole page is a chart, and Word's own export of them holds fourteen to thirty-two lines of title, ticks, categories and legend. The *computed* layout engine has no document to build elements in and so cannot use this renderer — but the places are worked out here whatever the marks are drawn into, and this hands them out. Called from {@link text}, which every label of every part goes through, with the same numbers the element is given.
ChartTextPiece
interface ChartTextPiece

A piece of a chart's text and the box the drawing put it in.

text
string
left
number
top
number
width
number
height
number
sizePx
number
align?
string | undefined
weight?
string | undefined
rotate?
number | undefined
Degrees, for a tick label the drawing turned.
part?
string | undefined
Which part of the chart it belongs to: `title`, `legend`, `tick`…
DiagramRenderContext
interface DiagramRenderContext

What drawing a diagram needs from the application around it. The same three things a chart needs and one more: SmartArt names its typefaces by scheme slot rather than by name, so a host that has a theme has to be asked. Deliberately this narrow — the renderer used to take the Word view's whole render context, and that is the only reason a workbook could not use it.

ownerDocument
Document
themeColor
ThemeColorLookup
themeFont?
((slot: string) => string | undefined) | undefined
The typeface a scheme slot names, such as the major Latin one.
classPrefix?
string | undefined
Prefix for the generated class names, so each host keeps its own.

@genomdev/office-core/testing

Functions

buildMinimalDocx
function buildMinimalDocx(bodyXml: string, spec?: MinimalDocxSpec): Promise<Uint8Array>

Builds a minimal Word document from the contents of `w:body`.

buildOoxmlPackage
function buildOoxmlPackage(spec: OoxmlPackageSpec): Promise<Uint8Array>

Builds a valid OPC package in memory. Format parser tests must run against a real ZIP archive rather than XML smuggled past the container, otherwise the entire archive-reading and relationship-resolution layer — exactly where things break most often — is left untested.

buildZipfrom @genomdev/core
function buildZip(files: readonly ZipFileSpec[], options?: { comment?: string; }): Promise<Uint8Array>
crc32from @genomdev/core
function crc32(bytes: Uint8Array): number
numberingXml
function numberingXml(inner: string): string

Wraps numbering definitions into a complete `numbering.xml` part.

stylesXml
function stylesXml(inner: string): string

Wraps style definitions into a complete `styles.xml` part.

Interfaces

MinimalDocxSpec
interface MinimalDocxSpec

Extra parts and relationships to include in a generated docx.

parts?
Record<string, string> | undefined
Additional package parts, e.g. `word/styles.xml`.
documentRelationships?
{ id: string; type: string; target: string; }[] | undefined
Additional relationships owned by `word/document.xml`.
overrides?
Record<string, string> | undefined
Additional `[Content_Types].xml` overrides.
OoxmlPackageSpec
interface OoxmlPackageSpec

Description of an OPC package to build.

parts
Record<string, string | Uint8Array<ArrayBufferLike>>
Package parts: path → contents. Bytes as well as text, because a package is not all XML: a document with a picture in it needs the picture, and a probe that asks how tall a line with a picture on it comes out cannot ask without one.
defaults?
Record<string, string> | undefined
`[Content_Types].xml` defaults, keyed by extension.
overrides?
Record<string, string> | undefined
`[Content_Types].xml` overrides, keyed by part name.
packageRelationships?
RelationshipSpec[] | undefined
Package-level relationships: the main part and metadata.
partRelationships?
Record<string, RelationshipSpec[]> | undefined
Per-part relationships: part name → its relationships.
RelationshipSpec
interface RelationshipSpec

One relationship. `targetMode` matters more than it looks: a hyperlink to the web is external and is kept as written, while an internal target is a path resolved against the owning part. A test that omits it gets a URL resolved as a file path.

id
string
type
string
target
string
targetMode?
"Internal" | "External" | undefined
ZipFileSpecfrom @genomdev/core
interface ZipFileSpec

A ZIP archive builder for tests. Simpler and more reliable than keeping binary fixtures in the repository: a test states the compression method, the archive comment and the set of parts itself, and therefore exercises exactly the reader branch it was written for.

name
string
content
string | Uint8Array<ArrayBufferLike>
compress?
boolean | undefined
Content is deflated by default.