reamkit 1.16.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/esm/core/bidi/segments.js +1 -2
  2. package/dist/esm/core/converter/project.js +5 -1
  3. package/dist/esm/core/document-model/index.d.ts +1 -1
  4. package/dist/esm/core/document-model/types.d.ts +473 -7
  5. package/dist/esm/core/drawingml/chart-geometry.d.ts +8 -12
  6. package/dist/esm/core/drawingml/chart-geometry.js +58 -9
  7. package/dist/esm/core/drawingml/chart-parser.js +44 -5
  8. package/dist/esm/core/drawingml/colors.d.ts +1 -1
  9. package/dist/esm/core/drawingml/colors.js +27 -1
  10. package/dist/esm/core/drawingml/preset-geometry.js +233 -0
  11. package/dist/esm/core/drawingml/shape-render.d.ts +12 -0
  12. package/dist/esm/core/drawingml/shape-render.js +116 -3
  13. package/dist/esm/core/drawingml/theme-parser.d.ts +10 -0
  14. package/dist/esm/core/drawingml/theme-parser.js +19 -1
  15. package/dist/esm/core/font/measure.d.ts +5 -0
  16. package/dist/esm/core/font/measure.js +21 -1
  17. package/dist/esm/core/images.d.ts +2 -2
  18. package/dist/esm/core/images.js +181 -0
  19. package/dist/esm/core/ir/flow.d.ts +23 -1
  20. package/dist/esm/core/numbering/apply.d.ts +5 -3
  21. package/dist/esm/core/numbering/apply.js +42 -11
  22. package/dist/esm/core/numbering/index.js +2 -0
  23. package/dist/esm/core/numbering/state.d.ts +13 -1
  24. package/dist/esm/core/numbering/state.js +256 -15
  25. package/dist/esm/core/po-helpers.js +16 -1
  26. package/dist/esm/core/style-cascade/resolver.js +66 -11
  27. package/dist/esm/core/style-cascade/table.js +35 -11
  28. package/dist/esm/core/style-cascade/types.d.ts +42 -1
  29. package/dist/esm/core/style-cascade/types.js +4 -0
  30. package/dist/esm/core/vector.d.ts +17 -0
  31. package/dist/esm/excel/print-model.js +1 -1
  32. package/dist/esm/excel/sheet-to-flow.js +10 -8
  33. package/dist/esm/excel/worksheet-parser.js +1 -1
  34. package/dist/esm/html/html-writer.js +18 -4
  35. package/dist/esm/layout/page-doc.d.ts +62 -2
  36. package/dist/esm/layout/styled-layout.d.ts +44 -2
  37. package/dist/esm/layout/styled-layout.js +1870 -228
  38. package/dist/esm/pdf/shading.js +76 -6
  39. package/dist/esm/pdf/styled-page-emitter.js +217 -43
  40. package/dist/esm/pdf/vector-graphics.d.ts +28 -1
  41. package/dist/esm/pdf/vector-graphics.js +94 -11
  42. package/dist/esm/pptx/pptx-reader.js +1 -0
  43. package/dist/esm/pptx/slide-parser.d.ts +21 -4
  44. package/dist/esm/pptx/slide-parser.js +86 -23
  45. package/dist/esm/svg/svg-writer.js +1 -1
  46. package/dist/esm/word/document-parser.d.ts +96 -7
  47. package/dist/esm/word/document-parser.js +537 -116
  48. package/dist/esm/word/docx-reader.js +135 -43
  49. package/dist/esm/word/docx-writer.js +6 -1
  50. package/dist/esm/word/drawing-parser.d.ts +53 -5
  51. package/dist/esm/word/drawing-parser.js +1540 -54
  52. package/dist/esm/word/index.d.ts +4 -4
  53. package/dist/esm/word/numbering-parser.d.ts +2 -1
  54. package/dist/esm/word/numbering-parser.js +107 -21
  55. package/dist/esm/word/paragraph-properties.d.ts +11 -1
  56. package/dist/esm/word/paragraph-properties.js +219 -10
  57. package/dist/esm/word/run-properties.js +45 -1
  58. package/dist/esm/word/settings-parser.d.ts +24 -0
  59. package/dist/esm/word/settings-parser.js +31 -5
  60. package/dist/esm/word/shading.d.ts +11 -0
  61. package/dist/esm/word/shading.js +64 -0
  62. package/dist/esm/word/styles-parser.js +8 -2
  63. package/dist/esm/word/table-parser.d.ts +9 -1
  64. package/dist/esm/word/table-parser.js +182 -30
  65. package/package.json +1 -1
@@ -29,7 +29,16 @@ export interface RunProperties {
29
29
  readonly bold?: boolean;
30
30
  readonly italic?: boolean;
31
31
  readonly underline?: UnderlineStyle;
32
+ /** §17.3.2.40 `w:u @w:color` — the underline's own colour, when it has one. */
33
+ readonly underlineColorHex?: string;
32
34
  readonly strike?: boolean;
35
+ /** §17.3.2.5 `w:caps` — the run is DISPLAYED in capitals, whatever it stores. */
36
+ readonly caps?: boolean;
37
+ /**
38
+ * §17.3.2.33 `w:smallCaps` — displayed in capitals, with the letters that
39
+ * were lower case set smaller.
40
+ */
41
+ readonly smallCaps?: boolean;
33
42
  readonly fontSizePt?: Pt;
34
43
  readonly colorHex?: string;
35
44
  readonly fontFamily?: FontFamilyMap;
@@ -44,6 +53,16 @@ export interface RunProperties {
44
53
  * the tagged-PDF per-element `/Lang`; does not affect visual layout.
45
54
  */
46
55
  readonly lang?: string;
56
+ /**
57
+ * §17.3.2.32 `w:rPr/w:shd` — the background painted behind the run's own
58
+ * glyphs, already blended from the pattern, its colour and the fill.
59
+ */
60
+ readonly shadingColorHex?: string;
61
+ /**
62
+ * §17.3.2.35 `w:rPr/w:spacing` — extra space between the run's characters
63
+ * (negative tightens). Word states it in twentieths of a point.
64
+ */
65
+ readonly letterSpacingPt?: Pt;
47
66
  }
48
67
  /**
49
68
  * ECMA-376 Part 1 §17.3.1 — Paragraph Properties (`pPr`). All lengths in
@@ -55,19 +74,136 @@ export interface RunProperties {
55
74
  * indent of 360 twips becomes `indentFirstLine = -18pt` — the first line ends up
56
75
  * 360 twips to the left of `indentLeft`).
57
76
  */
77
+ /**
78
+ * §17.3.1.38 `w:tab` — one stop in a paragraph's tab list: where the text after
79
+ * a tab character goes, how it sits against that position, and what fills the
80
+ * gap on the way there.
81
+ */
82
+ export interface TabStop {
83
+ /**
84
+ * Distance from the text margin, in points (`w:pos`, twips). Ignored when
85
+ * {@link relativeTo} names an edge — a §17.3.3.15 `w:ptab` positions against
86
+ * the column itself, whose width only the layout knows.
87
+ */
88
+ readonly positionPt: Pt;
89
+ /**
90
+ * §17.3.3.15 `w:ptab` — an ABSOLUTE position tab, which goes to the middle
91
+ * or the far side of the text column rather than to a stated distance.
92
+ */
93
+ readonly relativeTo?: 'center' | 'right';
94
+ /** §17.18.90 ST_TabJc — how the text after the tab sits against the stop. */
95
+ readonly alignment: 'left' | 'center' | 'right' | 'decimal';
96
+ /** §17.18.89 ST_TabTlc — the character drawn across the gap. */
97
+ readonly leader?: 'dot' | 'hyphen' | 'underscore' | 'middleDot';
98
+ }
99
+ /**
100
+ * §17.3.1.11 `w:framePr` — the paragraph is a floating TEXT FRAME: it leaves
101
+ * the flow, takes the box this describes, and the body text wraps around it.
102
+ * Consecutive paragraphs carrying the same frame are one frame together.
103
+ */
104
+ export interface FrameProperties {
105
+ /** `w:w` — the frame's width. Absent ⇒ as wide as the text needs. */
106
+ readonly widthPt?: Pt;
107
+ /** `w:h` with `w:hRule` — `exact` pins the height, anything else fits the text. */
108
+ readonly heightPt?: Pt;
109
+ readonly heightRule?: 'auto' | 'exact' | 'atLeast';
110
+ /** `w:x`/`w:y` — the offset from whatever `hAnchor`/`vAnchor` names. */
111
+ readonly xPt?: Pt;
112
+ readonly yPt?: Pt;
113
+ /** `w:xAlign`/`w:yAlign` — an alignment instead of an offset. */
114
+ readonly xAlign?: 'left' | 'center' | 'right' | 'inside' | 'outside';
115
+ readonly yAlign?: 'top' | 'center' | 'bottom' | 'inside' | 'outside';
116
+ readonly hAnchor?: 'text' | 'margin' | 'page';
117
+ readonly vAnchor?: 'text' | 'margin' | 'page';
118
+ /** §17.18.104 ST_Wrap — how the body text runs past the frame. */
119
+ readonly wrap?: 'auto' | 'around' | 'none' | 'notBeside' | 'tight' | 'through';
120
+ readonly hSpacePt?: Pt;
121
+ readonly vSpacePt?: Pt;
122
+ }
58
123
  export interface ParagraphProperties {
59
124
  readonly styleId?: string;
125
+ /**
126
+ * §17.7.2 — the `w:pPr` of the TABLE STYLE the paragraph's cell is formatted
127
+ * by. It is not the paragraph's own formatting: the cascade puts it under the
128
+ * paragraph's style (docDefaults < table style < numbering < paragraph style
129
+ * < character style < direct), so it is carried apart from the direct
130
+ * properties rather than merged into them.
131
+ */
132
+ readonly tableStyle?: ParagraphProperties;
133
+ /**
134
+ * §17.7.2 — a run layer that ranks BELOW the paragraph's own style and below
135
+ * the character style a run names: the `w:rPr` of the table style the cell is
136
+ * formatted by, or the `a:fontRef` colour a gallery-drawn shape lends the
137
+ * text inside it (§20.1.4.2.14). Carried on the paragraph because every run
138
+ * of it — and its MARK — reads the same layer.
139
+ */
140
+ readonly inheritedRun?: RunProperties;
141
+ /**
142
+ * §17.6.17 — the paragraph's mark carries a `w:sectPr`: it is the last
143
+ * paragraph of its section, and the mark IS the section break. One with no
144
+ * content of its own therefore prints nothing, not an empty line.
145
+ */
146
+ readonly sectionBreak?: boolean;
147
+ /** §17.3.1.11 — the paragraph floats as a text frame. */
148
+ readonly frame?: FrameProperties;
149
+ /**
150
+ * §17.3.1.41 `w:textDirection` — which way the paragraph's lines run.
151
+ * `btLr` reads bottom-to-top, `tbRl` top-to-bottom; `lrTb` is the default
152
+ * and is not recorded.
153
+ */
154
+ readonly textDirection?: 'btLr' | 'tbRl';
155
+ /**
156
+ * §17.3.1.32 `w:snapToGrid` — whether the paragraph's lines stand on the
157
+ * section's document grid (§17.6.5). Absent ⇒ they do; Word's header and
158
+ * footer styles are what usually says otherwise.
159
+ */
160
+ readonly snapToGrid?: boolean;
60
161
  readonly alignment?: Alignment;
61
162
  readonly spacingBefore?: Pt;
62
163
  readonly spacingAfter?: Pt;
63
164
  readonly spacingLine?: Pt;
64
165
  readonly spacingLineRule?: 'auto' | 'exact' | 'atLeast';
166
+ /**
167
+ * ECMA-376 Part 1 §17.3.1.9 — `w:contextualSpacing`. The space before and
168
+ * after is dropped where the neighbour is a paragraph of the SAME style: a
169
+ * list is written this way, so its items sit together while the list as a
170
+ * whole keeps its space from the text around it.
171
+ */
172
+ readonly contextualSpacing?: boolean;
173
+ /** ECMA-376 Part 1 §17.3.1.37 — the paragraph's own `w:tabs` stops. */
174
+ readonly tabs?: ReadonlyArray<TabStop>;
175
+ /**
176
+ * §17.3.1.24 `w:pBdr` — rules drawn around the paragraph. `w:space` is the
177
+ * gap each keeps from the text, carried on the {@link Border} as `spacePt`.
178
+ */
179
+ readonly borders?: CellBorders;
180
+ /** §17.3.1.31 `w:pPr/w:shd` — the paragraph's own background fill. */
181
+ readonly shading?: CellShading;
65
182
  readonly indentLeft?: Pt;
66
183
  readonly indentRight?: Pt;
67
184
  readonly indentFirstLine?: Pt;
68
185
  /** The implicit default run properties for runs in this paragraph (`w:pPr/w:rPr`). */
69
186
  readonly runProperties?: RunProperties;
187
+ /**
188
+ * §17.3.1.3/§17.3.1.1 — the gap `w:beforeAutospacing`/`w:afterAutospacing`
189
+ * asks the consumer for, already resolved to a length by the reader (it
190
+ * depends on the document's compatibility mode). Present only when the
191
+ * autospacing flag is ON, and it beats the `w:before`/`w:after` beside it.
192
+ * A separate property because style inheritance is per ATTRIBUTE: a style
193
+ * based on one that says `beforeAutospacing` inherits the flag even when it
194
+ * states a `w:before` of its own — which is how tdf104354_firstParaInSection
195
+ * gets its 75pt before, and taking that literally spread one page over four.
196
+ */
197
+ readonly spacingBeforeAuto?: Pt;
198
+ readonly spacingAfterAuto?: Pt;
70
199
  readonly numbering?: NumberingReference;
200
+ /**
201
+ * §17.9.4 — a `w:numPr` that names a LEVEL and no `w:numId`: the instance is
202
+ * whatever the style this one is based on refers to. Word's own Heading 2
203
+ * says exactly this, and dropped it numbered num-parent-style.docx's headings
204
+ * 1, 2, 3, 4 where its own text says they should read 1, 1.1, 2, 2.1.
205
+ */
206
+ readonly numberingLevel?: number;
71
207
  /**
72
208
  * ECMA-376 Part 1 §17.3.1.21 — `w:pageBreakBefore`. When true, the paragraph
73
209
  * starts on a fresh page even if there is room on the current one.
@@ -89,14 +225,49 @@ export interface ParagraphProperties {
89
225
  * {@link Run} alongside (or instead of) `text` so layout can position the image
90
226
  * as if it were a glyph in the line box.
91
227
  */
228
+ /**
229
+ * §20.1.2.2.24 `a:ln` on a `pic:spPr` (VML: `@stroked`/`v:stroke`) — the frame
230
+ * a picture is drawn with. Word's "Picture Border": a rule around the picture
231
+ * box, not part of the image itself.
232
+ */
233
+ export interface PictureOutline {
234
+ readonly colorHex: string;
235
+ readonly widthPt: Pt;
236
+ }
92
237
  export interface InlineImage {
93
238
  /**
94
239
  * Content-addressed bytes in the document's `ResourceStore`; absent when the
95
240
  * source relationship did not resolve (the layout box still reserves space).
96
241
  */
97
242
  readonly resource?: ResourceId;
243
+ /** The picture's own frame, when it has one (see {@link PictureOutline}). */
244
+ readonly outline?: PictureOutline;
245
+ /**
246
+ * §20.1.8.40 `a:outerShdw` — the drop shadow under the picture. Word writes
247
+ * one on every screenshot pasted with a style; drawn nowhere, imgshadow.docx's
248
+ * six stood flat on the page where both references lift them off it.
249
+ */
250
+ readonly shadow?: ShapeShadow;
98
251
  readonly width: Pt;
99
252
  readonly height: Pt;
253
+ /** §20.1.8.55 `a:srcRect` — the part of the source the frame shows. */
254
+ readonly crop?: ImageCrop;
255
+ /** §20.1.7.6 `a:xfrm @rot` — the picture's own rotation (1/60000°, clockwise). */
256
+ readonly rotation60k?: number;
257
+ /** §20.1.7.6 `a:xfrm @flipH/@flipV` — the picture drawn mirrored. */
258
+ readonly flipH?: boolean;
259
+ readonly flipV?: boolean;
260
+ /**
261
+ * §20.4.2.6 `wp:effectExtent` — space the drawing needs BEYOND its extent,
262
+ * for what a rotation or an effect throws outside the frame. The line box
263
+ * reserves it; the picture itself is drawn inset by it.
264
+ */
265
+ readonly effectExtent?: {
266
+ readonly leftPt: Pt;
267
+ readonly topPt: Pt;
268
+ readonly rightPt: Pt;
269
+ readonly bottomPt: Pt;
270
+ };
100
271
  }
101
272
  /**
102
273
  * ECMA-376 Part 1 §22 — OfficeMathML (OMML). A recursive math element tree.
@@ -263,6 +434,11 @@ export interface Run {
263
434
  * paragraph's following content starts on a new page.
264
435
  */
265
436
  readonly pageBreak?: boolean;
437
+ /**
438
+ * §17.3.3.1 `w:br w:type="column"` — the text after this run continues in the
439
+ * NEXT column of the section (or, past the last, on the next page).
440
+ */
441
+ readonly columnBreak?: boolean;
266
442
  }
267
443
  /** ECMA-376 Part 1 §17.3.1 — a paragraph: its {@link ParagraphProperties} and runs. */
268
444
  export interface Paragraph {
@@ -302,7 +478,23 @@ export interface Comment {
302
478
  readonly done?: boolean;
303
479
  }
304
480
  /** ECMA-376 Part 1 §17.9 — `w:numFmt` list marker format. */
305
- export type NumberingFormat = 'decimal' | 'lowerLetter' | 'upperLetter' | 'lowerRoman' | 'upperRoman' | 'bullet' | 'none';
481
+ export type NumberingFormat = 'decimal' | 'decimalZero' | 'decimalFullWidth' | 'ordinal' | 'lowerLetter' | 'upperLetter' | 'lowerRoman' | 'upperRoman'
482
+ /** §17.18.59 — the ten heavenly stems 甲乙丙…, then plain digits. */
483
+ | 'ideographTraditional'
484
+ /** The twelve earthly branches 子丑寅…, then plain digits. */
485
+ | 'ideographZodiac'
486
+ /** The formal (anti-fraud) numerals 壹貳參…, composed with 拾佰仟. */
487
+ | 'ideographLegalTraditional'
488
+ /** Digit-by-digit ideographs: 10 is 一零, not 十. */
489
+ | 'ideographDigital' | 'koreanDigital2'
490
+ /** Counting ideographs: 10 is 十, 11 is 十一, 21 is 二十一. */
491
+ | 'chineseCounting' | 'chineseCountingThousand' | 'japaneseCounting' | 'koreanCounting' | 'taiwaneseCounting' | 'taiwaneseCountingThousand'
492
+ /** §17.18.59 — Hebrew numerals (gematria): א, ב, … ט״ו, ט״ז, י״ז … */
493
+ | 'hebrew1'
494
+ /** The Hebrew alphabet as a plain sequence, cycling past ת. */
495
+ | 'hebrew2'
496
+ /** ①②③… up to twenty, then plain digits. */
497
+ | 'decimalEnclosedCircle' | 'chicago' | 'bullet' | 'none';
306
498
  /** A paragraph's list reference (`w:numPr`): the numbering instance id + level. */
307
499
  export interface NumberingReference {
308
500
  readonly numId: string;
@@ -315,9 +507,28 @@ export interface NumberingLevel {
315
507
  readonly format: NumberingFormat;
316
508
  /** §17.9.11 `w:lvlText` — the marker template (e.g. `"%1."`). */
317
509
  readonly lvlText: string;
510
+ /**
511
+ * §17.9.9 `w:lvlPicBulletId` → §17.9.21 `w:numPicBullet` — the level's bullet
512
+ * is a PICTURE, not a character, and the `w:lvlText` is only the fallback
513
+ * glyph Word writes beside it.
514
+ */
515
+ readonly picBullet?: PictureBullet;
516
+ /**
517
+ * §17.9.10 `w:isLgl` — every level of this level's marker is printed in
518
+ * DECIMAL, whatever format the level it names asks for. Word calls it legal
519
+ * numbering: "Sect I.01" becomes "Sect 1.01".
520
+ */
521
+ readonly isLegal?: boolean;
318
522
  readonly paragraphProperties: ParagraphProperties;
319
523
  readonly runProperties: RunProperties;
320
524
  }
525
+ /** §17.9.21 `w:numPicBullet` — the image a level uses in place of a bullet. */
526
+ export interface PictureBullet {
527
+ /** Content-addressed bytes. A bullet whose picture does not resolve is not one. */
528
+ readonly resource: ResourceId;
529
+ readonly widthPt: Pt;
530
+ readonly heightPt: Pt;
531
+ }
321
532
  /** §17.9.1 `w:abstractNum` — a reusable list definition keyed by level. */
322
533
  export interface AbstractNumbering {
323
534
  readonly id: string;
@@ -327,6 +538,18 @@ export interface AbstractNumbering {
327
538
  export interface NumberingInstance {
328
539
  readonly numId: string;
329
540
  readonly abstractNumId: string;
541
+ /**
542
+ * §17.9.27/§17.9.28 `w:lvlOverride/w:startOverride` — where THIS instance
543
+ * starts a level, by `w:ilvl`, whatever the abstract definition says. Absent
544
+ * when the instance takes the abstract starts unchanged.
545
+ */
546
+ readonly startOverrides?: ReadonlyMap<number, number>;
547
+ /**
548
+ * §17.9.27 `w:lvlOverride/w:lvl` — a level this instance REDEFINES whole,
549
+ * shadowing the abstract definition's. NumberingWOverrides.docx rewrites all
550
+ * nine levels of one instance this way.
551
+ */
552
+ readonly levelOverrides?: ReadonlyMap<number, NumberingLevel>;
330
553
  }
331
554
  /** The parsed `word/numbering.xml`: abstract definitions + their instances. */
332
555
  export interface Numbering {
@@ -344,6 +567,8 @@ export type StyleType = 'paragraph' | 'character' | 'table' | 'numbering';
344
567
  export interface TableStyleLayer {
345
568
  readonly borders?: CellBorders;
346
569
  readonly cellMargins?: CellMargins;
570
+ /** §17.4.65 `w:tblInd` — the table indent a whole-table layer declares. */
571
+ readonly indentPt?: Pt;
347
572
  readonly shading?: CellShading;
348
573
  readonly runProperties?: RunProperties;
349
574
  readonly paragraphProperties?: ParagraphProperties;
@@ -385,12 +610,14 @@ export interface StyleSheet {
385
610
  readonly styles: ReadonlyMap<string, Style>;
386
611
  }
387
612
  /** §17.18.2 ST_Border — a cell-border line style (the subset Ream renders). */
388
- export type BorderStyle = 'none' | 'single' | 'double' | 'thick' | 'dotted' | 'dashed' | 'dashDot' | 'dashDotDot';
613
+ export type BorderStyle = 'none' | 'single' | 'double' | 'thick' | 'dotted' | 'dashed' | 'dashSmallGap' | 'dashDot' | 'dashDotDot';
389
614
  /** One border edge: its line style plus optional width and colour. */
390
615
  export interface Border {
391
616
  readonly style: BorderStyle;
392
617
  readonly width?: Pt;
393
618
  readonly colorHex?: string;
619
+ /** §17.3.1.24 `w:space` — how far a paragraph rule stands off its text. */
620
+ readonly spacePt?: Pt;
394
621
  }
395
622
  /** §17.4.39 `w:tcBorders` — the per-edge borders of a cell (or table). */
396
623
  export interface CellBorders {
@@ -480,6 +707,14 @@ export type CellMerge = 'start' | 'middle' | 'end';
480
707
  /** §17.4.30 `w:tcPr` — a cell's properties: span/merge, chrome, and CF overlays. */
481
708
  export interface CellProperties {
482
709
  readonly width?: Pt;
710
+ /**
711
+ * §17.4.72 `w:tcW w:type="pct"` — the cell's preferred width as a share of
712
+ * the table (`w`/5000). Held apart from {@link width} because a percentage
713
+ * cannot be resolved until the table's own width is known.
714
+ */
715
+ readonly widthFraction?: number;
716
+ /** §17.18.90 ST_TblWidth — which of the two above the cell actually declared. */
717
+ readonly widthType?: 'auto' | 'dxa' | 'pct' | 'nil';
483
718
  readonly colSpan?: number;
484
719
  readonly merge?: CellMerge;
485
720
  readonly borders?: CellBorders;
@@ -512,6 +747,11 @@ export interface CellProperties {
512
747
  * to clip against and lets the browser decide.
513
748
  */
514
749
  readonly noWrap?: boolean;
750
+ /**
751
+ * §17.4.20 `w:hideMark` — the cell's end-of-cell mark is not counted when the
752
+ * row's height is measured, so an EMPTY cell that says so adds nothing at all.
753
+ */
754
+ readonly hideMark?: boolean;
515
755
  /**
516
756
  * The cell holds a NUMBER under a format of its own, so it may not be shown
517
757
  * truncated: a date cut to "4/30/201" is not a shorter date, it is the wrong
@@ -534,11 +774,27 @@ export interface RowProperties {
534
774
  readonly heightRule?: 'auto' | 'atLeast' | 'exact';
535
775
  readonly cantSplit?: boolean;
536
776
  readonly isHeader?: boolean;
777
+ /**
778
+ * §17.4.14 `w:gridBefore` — how many grid columns the row leaves empty
779
+ * before its first cell, which is how a row starts part-way across a table.
780
+ */
781
+ readonly gridBefore?: number;
537
782
  /**
538
783
  * Force this row to begin a new page (xlsx manual `<rowBreaks>`). The renderer
539
784
  * flushes the page before the row, then repeats any leading header rows.
540
785
  */
541
786
  readonly pageBreakBefore?: boolean;
787
+ /**
788
+ * §17.4.7 `w:cnfStyle` — the conditional formats of the table style this row
789
+ * takes, whatever its position says. Word's calendar templates give a SECOND
790
+ * header row `w:firstRow="1"` so it is painted like the first.
791
+ */
792
+ readonly conditional?: RowConditionalFormat;
793
+ }
794
+ /** §17.4.7 — the row-level conditional-format flags a `w:cnfStyle` declares. */
795
+ export interface RowConditionalFormat {
796
+ readonly firstRow?: boolean;
797
+ readonly lastRow?: boolean;
542
798
  }
543
799
  /**
544
800
  * §17.4.62 `w:tblLook` — which of the table style's conditional formats apply.
@@ -572,6 +828,18 @@ export interface TableProperties {
572
828
  * Centers or right-aligns a table narrower than the content width; absent ⇒ left.
573
829
  */
574
830
  readonly alignment?: 'left' | 'center' | 'right';
831
+ /**
832
+ * §17.4.65 `w:tblInd` — how far the table's leading edge stands in from the
833
+ * text margin. Distinct from {@link alignment}, which shares out the slack a
834
+ * narrow table leaves.
835
+ */
836
+ readonly indentPt?: Pt;
837
+ /**
838
+ * §17.4.58 `w:tblpPr` — the table FLOATS: it is placed at an anchor of its
839
+ * own and the text runs past it, exactly as an anchored drawing does. Read
840
+ * into the same {@link FloatAnchor} the drawings use.
841
+ */
842
+ readonly float?: FloatAnchor;
575
843
  /**
576
844
  * A sticky-pane hint from a frozen worksheet view (E-SHEET SE3): the first
577
845
  * `rows` rows / `cols` columns stay pinned while the rest scrolls. Consumed
@@ -606,12 +874,42 @@ export interface Table {
606
874
  * ECMA-376 Part 1 §20.4.2.8 — a block-level image (`wp:inline` picture extent).
607
875
  * EMU = English Metric Units: 914400 per inch (1 pt = 12700 EMU).
608
876
  */
877
+ /**
878
+ * §20.1.8.55 `a:srcRect` — how much of each edge of the source picture is cut
879
+ * away before it is fitted to its frame, as a fraction of the source (so 0.25
880
+ * on `left` drops its left quarter). Absent edges are zero.
881
+ */
882
+ export interface ImageCrop {
883
+ readonly left: number;
884
+ readonly top: number;
885
+ readonly right: number;
886
+ readonly bottom: number;
887
+ }
609
888
  export interface ImageBlock {
610
889
  /** §20.4.2.3 — present when the drawing is anchored (floating). */
611
890
  readonly float?: FloatAnchor;
612
891
  readonly resource?: ResourceId;
892
+ /** The picture's own frame, when it has one (see {@link PictureOutline}). */
893
+ readonly outline?: PictureOutline;
894
+ /**
895
+ * §20.1.8.40 `a:outerShdw` — the drop shadow under the picture. Word writes
896
+ * one on every screenshot pasted with a style; drawn nowhere, imgshadow.docx's
897
+ * six stood flat on the page where both references lift them off it.
898
+ */
899
+ readonly shadow?: ShapeShadow;
613
900
  readonly width: Pt;
614
901
  readonly height: Pt;
902
+ /** §20.1.8.55 `a:srcRect` — the part of the source the frame shows. */
903
+ readonly crop?: ImageCrop;
904
+ /** §20.1.7.6 `a:xfrm @rot` — the picture's own rotation (1/60000°, clockwise). */
905
+ readonly rotation60k?: number;
906
+ /** §20.1.7.6 `a:xfrm @flipH/@flipV` — the picture drawn mirrored. */
907
+ readonly flipH?: boolean;
908
+ readonly flipV?: boolean;
909
+ /** `wp14:sizeRelH/V` — a size stated as a share of the page or margins. */
910
+ readonly relativeSize?: RelativeSize;
911
+ /** §20.4.2.6 `wp:effectExtent` — space reserved around the picture (see {@link InlineImage}). */
912
+ readonly effectExtent?: InlineImage['effectExtent'];
615
913
  readonly paragraphProperties: ParagraphProperties;
616
914
  /** `wp:docPr @descr/@title` — alternate text for the tagged-PDF Figure (`/Alt`). */
617
915
  readonly altText?: string;
@@ -669,13 +967,24 @@ export interface ShapeGeometry {
669
967
  readonly adjust?: ReadonlyMap<string, number>;
670
968
  readonly custom?: CustomGeometry;
671
969
  }
672
- /** A shape's fill mode (`a:noFill`/`a:solidFill`/`a:gradFill`). */
673
- export type ShapeFillKind = 'none' | 'solid' | 'gradient';
674
- /** A shape's fill: none, a solid colour, or a {@link ShapeGradient}. */
970
+ /** A shape's fill mode (`a:noFill`/`a:solidFill`/`a:gradFill`/`a:blipFill`). */
971
+ export type ShapeFillKind = 'none' | 'solid' | 'gradient' | 'picture';
972
+ /** A shape's fill: none, a solid colour, a {@link ShapeGradient}, or a picture. */
675
973
  export interface ShapeFill {
676
974
  readonly kind: ShapeFillKind;
677
975
  readonly colorHex?: string;
678
976
  readonly gradient?: ShapeGradient;
977
+ /**
978
+ * §20.1.8.14 `a:blipFill` — the picture painted across the shape's box. A
979
+ * DrawingML picture IS a shape with one of these, which is how a `pic:pic`
980
+ * inside a group reaches the page.
981
+ */
982
+ readonly imageResource?: ResourceId;
983
+ /**
984
+ * §20.1.8.30 `a:stretch/a:fillRect` (or an `a:srcRect` beside it) — the part
985
+ * of the picture the box shows, as the fractions cut from each side.
986
+ */
987
+ readonly imageCrop?: ImageCrop;
679
988
  }
680
989
  /** §20.1.10.49 ST_PresetLineDashVal — a shape outline's preset dash pattern. */
681
990
  export type ShapeDash = 'solid' | 'dot' | 'dash' | 'dashDot' | 'lgDash' | 'lgDashDot' | 'sysDash' | 'sysDot';
@@ -684,8 +993,45 @@ export interface ShapeLine {
684
993
  readonly width?: Pt;
685
994
  readonly colorHex?: string;
686
995
  readonly dash?: ShapeDash;
996
+ /**
997
+ * §20.1.8.21 `a:custDash` — the author's own pattern: dash/space lengths as
998
+ * MULTIPLES of the line width, in the order they are drawn.
999
+ */
1000
+ readonly customDash?: ReadonlyArray<number>;
687
1001
  readonly cap?: 'flat' | 'round' | 'square';
688
1002
  readonly fill?: 'solid' | 'none';
1003
+ /** §20.1.8.24 `a:headEnd` — the decoration at the line's first point. */
1004
+ readonly headEnd?: LineEnd;
1005
+ /** §20.1.8.42 `a:tailEnd` — the decoration at the line's last point. */
1006
+ readonly tailEnd?: LineEnd;
1007
+ }
1008
+ /**
1009
+ * §20.1.8.24 / §20.1.8.42 — an arrowhead (or other decoration) at one end of a
1010
+ * line: its shape plus the width and length steps `ST_LineEndWidth` /
1011
+ * `ST_LineEndLength` name.
1012
+ */
1013
+ export interface LineEnd {
1014
+ readonly type: 'triangle' | 'stealth' | 'diamond' | 'oval' | 'arrow';
1015
+ readonly width?: 'sm' | 'med' | 'lg';
1016
+ readonly length?: 'sm' | 'med' | 'lg';
1017
+ }
1018
+ /**
1019
+ * `wp14:sizeRelH` / `wp14:sizeRelV` — the drawing's size as a PERCENTAGE of
1020
+ * the page or the margins rather than the extent beside it. Word 2010 writes
1021
+ * it in the `wp14` namespace, with the extent as the fallback for readers that
1022
+ * do not know it.
1023
+ */
1024
+ export interface RelativeSize {
1025
+ readonly widthPct?: number;
1026
+ /**
1027
+ * §20.4.3.6 ST_SizeRelFromH — what the percentage is OF. `margin` is the text
1028
+ * area; the rest are the bands around it, and a drawing sized against one is
1029
+ * a fraction of that band alone (tdf123324 asks for 150% of the top margin).
1030
+ */
1031
+ readonly widthFrom?: 'margin' | 'page' | 'leftMargin' | 'rightMargin';
1032
+ readonly heightPct?: number;
1033
+ /** §20.4.3.7 ST_SizeRelFromV — the vertical twin. */
1034
+ readonly heightFrom?: 'margin' | 'page' | 'topMargin' | 'bottomMargin';
689
1035
  }
690
1036
  /** §20.1.7.6 `a:xfrm` — a shape's rotation (1/60000°, clockwise) + flips. */
691
1037
  export interface ShapeTransform {
@@ -701,6 +1047,22 @@ export interface ShapeTextBody {
701
1047
  readonly insetRight?: Pt;
702
1048
  readonly insetBottom?: Pt;
703
1049
  readonly anchor?: 't' | 'ctr' | 'b';
1050
+ /**
1051
+ * §20.1.10.83 ST_TextVerticalType (`a:bodyPr @vert`) — text set along the
1052
+ * box's long axis rather than across it. `vert` reads top-to-bottom (turned a
1053
+ * quarter clockwise), `vert270` bottom-to-top.
1054
+ */
1055
+ readonly vertical?: 'vert' | 'vert270';
1056
+ /**
1057
+ * §20.1.10.28 `a:spAutoFit` — the SHAPE follows its text: its height is
1058
+ * whatever the text needs, whatever the stated box says.
1059
+ */
1060
+ readonly autoFit?: boolean;
1061
+ /**
1062
+ * §14.1.2.22 `v:textpath @fitshape` — the TEXT follows the shape: legacy
1063
+ * WordArt is set at whatever size fills the box it was drawn in.
1064
+ */
1065
+ readonly fitToBox?: boolean;
704
1066
  }
705
1067
  /**
706
1068
  * A block-level DrawingML shape (§20.1): its size, {@link ShapeGeometry}, fill,
@@ -723,15 +1085,29 @@ export interface ShapeShadow {
723
1085
  /** 0..1, from the shadow colour's `a:alpha` (absent ⇒ opaque). */
724
1086
  readonly alpha: number;
725
1087
  }
1088
+ /**
1089
+ * §20.5.2.17 `wpg:wgp` — one member of a drawing group, and where it sits: the
1090
+ * offsets are from the group's own top-left corner, already mapped out of the
1091
+ * group's child coordinate space.
1092
+ */
1093
+ export interface ShapeGroupChild {
1094
+ readonly shape: ShapeBlock;
1095
+ readonly xPt: Pt;
1096
+ readonly yPt: Pt;
1097
+ }
726
1098
  export interface ShapeBlock {
727
1099
  /** §20.4.2.3 — present when the drawing is anchored (floating). */
728
1100
  readonly float?: FloatAnchor;
729
1101
  readonly width: Pt;
730
1102
  readonly height: Pt;
1103
+ /** §20.5.2.17 — the shapes a group holds, drawn inside its own box. */
1104
+ readonly children?: ReadonlyArray<ShapeGroupChild>;
731
1105
  readonly geometry: ShapeGeometry;
732
1106
  readonly fill: ShapeFill;
733
1107
  readonly line?: ShapeLine;
734
1108
  readonly transform?: ShapeTransform;
1109
+ /** `wp14:sizeRelH/V` — a size stated as a share of the page or margins. */
1110
+ readonly relativeSize?: RelativeSize;
735
1111
  readonly text?: ShapeTextBody;
736
1112
  /** §20.1.8.40 — the shape's drop shadow, direct or from its style reference. */
737
1113
  readonly shadow?: ShapeShadow;
@@ -833,6 +1209,8 @@ export interface ChartLineStyle {
833
1209
  readonly none?: boolean;
834
1210
  readonly colorHex?: string;
835
1211
  readonly widthPt?: number;
1212
+ /** §20.1.10.49 `a:prstDash` — the rule's dash pattern, when it names one. */
1213
+ readonly dash?: ShapeDash;
836
1214
  }
837
1215
  /** A parsed chart (§21.2): its type, title, categories, series and rendering options. */
838
1216
  export interface Chart {
@@ -898,6 +1276,16 @@ export interface Chart {
898
1276
  */
899
1277
  readonly frameFillHex?: string;
900
1278
  readonly frameLineHex?: string;
1279
+ /** The frame rule's width and dash, when it states them. */
1280
+ readonly frameLineWidthPt?: number;
1281
+ readonly frameLineDash?: ShapeDash;
1282
+ /**
1283
+ * §21.2.2.145 `c:plotArea/c:spPr` — the plot rectangle's own fill and rule,
1284
+ * which sit inside the frame. Chart_Plot_BorderLine_Style.docx rules its plot
1285
+ * in a heavy orange dash-dot.
1286
+ */
1287
+ readonly plotFillHex?: string;
1288
+ readonly plotLine?: ChartLineStyle;
901
1289
  /**
902
1290
  * §21.2.2.121 `c:valAx/c:numFmt@formatCode` — the number format the value
903
1291
  * axis's tick labels and the data labels are drawn in, in the same code
@@ -952,6 +1340,11 @@ export interface PageMargins {
952
1340
  readonly left: Pt;
953
1341
  readonly header?: Pt;
954
1342
  readonly footer?: Pt;
1343
+ /**
1344
+ * §17.6.11 `w:gutter` — the binding space, added to the left margin (or to
1345
+ * the top, when `w:settings/w:gutterAtTop` says so).
1346
+ */
1347
+ readonly gutter?: Pt;
955
1348
  }
956
1349
  /** §17.10 — which page class a header/footer reference applies to. */
957
1350
  export type HeaderFooterType = 'default' | 'first' | 'even';
@@ -971,6 +1364,22 @@ export interface SectionProperties {
971
1364
  * of the section uses the `first` header/footer references.
972
1365
  */
973
1366
  readonly titlePg?: boolean;
1367
+ /**
1368
+ * §17.6.12 `w:pgNumType w:start` — the number the section's first page is
1369
+ * printed with. Absent ⇒ the count carries on from the section before.
1370
+ */
1371
+ readonly pageNumberStart?: number;
1372
+ /** §17.6.8 `w:lnNumType` — line numbers printed in the margin beside the text. */
1373
+ readonly lineNumbering?: {
1374
+ /** Print every `countBy`-th line (default 1). */
1375
+ readonly countBy: number;
1376
+ /** The number the count starts at (default 1). */
1377
+ readonly start: number;
1378
+ /** How far the number stands off the text (`w:distance`); absent ⇒ Word's quarter inch. */
1379
+ readonly distancePt?: Pt;
1380
+ /** §17.18.55 — where the count restarts. */
1381
+ readonly restart: 'newPage' | 'newSection' | 'continuous';
1382
+ };
974
1383
  /**
975
1384
  * ECMA-376 §17.15.1.36 — `w:evenAndOddHeaders` toggle in `word/settings.xml`
976
1385
  * (document-wide, not per-section). When true even-numbered pages use the
@@ -979,6 +1388,28 @@ export interface SectionProperties {
979
1388
  readonly evenAndOddHeaders?: boolean;
980
1389
  /** §17.6.4 `w:cols` — multi-column section layout. */
981
1390
  readonly columns?: SectionColumns;
1391
+ /**
1392
+ * §17.6.10 `w:pgBorders` — the rules drawn around the page. `offsetFrom`
1393
+ * says what each edge's `spacePt` is measured from: the paper's edge, or the
1394
+ * text margin it stands outside of.
1395
+ */
1396
+ readonly pageBorders?: {
1397
+ readonly borders: CellBorders;
1398
+ readonly offsetFrom: 'page' | 'text';
1399
+ };
1400
+ /**
1401
+ * §17.6.22 `w:type` — where the section starts. `continuous` starts it on the
1402
+ * page already in hand rather than a fresh one; everything else (nextPage,
1403
+ * and the odd/even/column variants we do not distinguish) starts a page.
1404
+ */
1405
+ readonly sectionStart?: 'continuous' | 'nextPage';
1406
+ /**
1407
+ * §17.6.5 `w:docGrid` — the line grid a `lines`/`linesAndChars` section rules
1408
+ * its text onto, as the pitch in points. Every line of the section's text is
1409
+ * as tall as a whole number of these, however tall its own font makes it.
1410
+ * Absent ⇒ no grid (`w:type="default"`, or none stated).
1411
+ */
1412
+ readonly gridLinePitchPt?: Pt;
982
1413
  }
983
1414
  /**
984
1415
  * §20.4.2.3 `wp:anchor` — a floating drawing's placement. v1 honours
@@ -988,14 +1419,47 @@ export interface SectionProperties {
988
1419
  export interface FloatAnchor {
989
1420
  readonly wrap: 'none' | 'square' | 'tight' | 'through' | 'topAndBottom';
990
1421
  readonly behind?: boolean;
1422
+ /**
1423
+ * §20.4.2.3 `wp:anchor @relativeHeight` — the z-order among the floats on the
1424
+ * page: the higher number is drawn over the lower, whatever their order in
1425
+ * the document.
1426
+ */
1427
+ readonly zOrder?: number;
991
1428
  readonly posH?: {
992
- readonly relativeFrom: 'margin' | 'page' | 'column';
1429
+ /**
1430
+ * §20.4.3.3 ST_RelFromH. `leftMargin`/`rightMargin` are the margin BANDS
1431
+ * beside the text area, which is where a marginal note is placed:
1432
+ * tdf103573.docx centres one box in each, and read as plain `margin` they
1433
+ * both landed in the middle of the text and printed over each other.
1434
+ */
1435
+ readonly relativeFrom: 'margin' | 'page' | 'column' | 'leftMargin' | 'rightMargin';
993
1436
  readonly offsetPt?: Pt;
994
1437
  readonly align?: 'left' | 'center' | 'right';
995
1438
  };
996
1439
  readonly posV?: {
997
- readonly relativeFrom: 'margin' | 'page' | 'paragraph' | 'line';
1440
+ /**
1441
+ * §20.4.3.4 ST_RelFromV. `topMargin`/`bottomMargin` measure from the top
1442
+ * edge of the margin BAND they name — page-content-bottom.docx hangs a
1443
+ * square 312pt above the bottom margin, and read as plain `margin` it went
1444
+ * off the top of the page.
1445
+ */
1446
+ readonly relativeFrom: 'margin' | 'page' | 'paragraph' | 'line' | 'topMargin' | 'bottomMargin';
998
1447
  readonly offsetPt?: Pt;
1448
+ /**
1449
+ * §20.4.3.1 `wp:align` (VML: `mso-position-vertical`) — a KEYWORD rather
1450
+ * than an offset, which is how Word centres a watermark in its page.
1451
+ */
1452
+ readonly align?: 'top' | 'center' | 'bottom';
1453
+ };
1454
+ /**
1455
+ * §20.4.2.3 `wp:anchor @distT/@distB/@distL/@distR` — how far the wrapped
1456
+ * text stands off each edge of the drawing. Absent sides are 0.
1457
+ */
1458
+ readonly wrapDist?: {
1459
+ readonly topPt: Pt;
1460
+ readonly bottomPt: Pt;
1461
+ readonly leftPt: Pt;
1462
+ readonly rightPt: Pt;
999
1463
  };
1000
1464
  }
1001
1465
  /**
@@ -1009,6 +1473,8 @@ export interface SectionColumns {
1009
1473
  readonly widthPt: number;
1010
1474
  readonly spacePt: number;
1011
1475
  }>;
1476
+ /** §17.6.4 `w:sep` — a vertical rule drawn down the middle of every gutter. */
1477
+ readonly separator?: boolean;
1012
1478
  }
1013
1479
  /**
1014
1480
  * One section descriptor for a multi-section document (ECMA-376 §17.6.17). Each