reamkit 1.30.0 → 1.32.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 (147) hide show
  1. package/README.md +70 -24
  2. package/dist/esm/core/bidi/index.d.ts +10 -0
  3. package/dist/esm/core/bidi/index.js +18 -2
  4. package/dist/esm/core/converter/facade.js +10 -5
  5. package/dist/esm/core/converter/project.js +4 -1
  6. package/dist/esm/core/converter/ream.js +17 -6
  7. package/dist/esm/core/converter/sheet-images.d.ts +17 -0
  8. package/dist/esm/core/converter/sheet-images.js +33 -0
  9. package/dist/esm/core/crypto/offcrypto.js +1 -1
  10. package/dist/esm/core/document-model/index.d.ts +1 -1
  11. package/dist/esm/core/document-model/types.d.ts +175 -0
  12. package/dist/esm/core/drawingml/chart-geometry.d.ts +21 -8
  13. package/dist/esm/core/drawingml/chart-geometry.js +198 -108
  14. package/dist/esm/core/drawingml/chart-parser.js +73 -2
  15. package/dist/esm/core/drawingml/colors.d.ts +6 -0
  16. package/dist/esm/core/drawingml/colors.js +23 -3
  17. package/dist/esm/core/drawingml/shape-render.d.ts +3 -1
  18. package/dist/esm/core/drawingml/shape-render.js +4 -2
  19. package/dist/esm/core/font/index.d.ts +2 -0
  20. package/dist/esm/core/font/measure.d.ts +9 -0
  21. package/dist/esm/core/font/measure.js +9 -1
  22. package/dist/esm/core/font/ttf-build.d.ts +113 -0
  23. package/dist/esm/core/font/ttf-build.js +1224 -0
  24. package/dist/esm/core/font/ttf-subset.d.ts +19 -0
  25. package/dist/esm/core/font/ttf-subset.js +14 -1
  26. package/dist/esm/core/fonts/families.js +4 -2
  27. package/dist/esm/core/fonts/provider.d.ts +17 -0
  28. package/dist/esm/core/fonts/provider.js +27 -2
  29. package/dist/esm/core/fonts/remote-fonts.js +8 -1
  30. package/dist/esm/core/fonts/scripts.js +4 -2
  31. package/dist/esm/core/ir/flow.d.ts +77 -1
  32. package/dist/esm/core/ir/sheet.d.ts +43 -0
  33. package/dist/esm/core/number-format.js +16 -11
  34. package/dist/esm/core/numbering/index.d.ts +1 -1
  35. package/dist/esm/core/numbering/state.d.ts +11 -1
  36. package/dist/esm/core/numbering/state.js +10 -1
  37. package/dist/esm/core/spreadsheet-model/index.d.ts +1 -1
  38. package/dist/esm/core/spreadsheet-model/types.d.ts +96 -0
  39. package/dist/esm/core/style-cascade/resolver.js +39 -6
  40. package/dist/esm/core/style-cascade/types.d.ts +19 -1
  41. package/dist/esm/core/style-cascade/types.js +3 -0
  42. package/dist/esm/excel/column-bands.d.ts +39 -6
  43. package/dist/esm/excel/column-bands.js +41 -17
  44. package/dist/esm/excel/comments-parser.js +19 -0
  45. package/dist/esm/excel/conditional-format.d.ts +7 -3
  46. package/dist/esm/excel/conditional-format.js +77 -39
  47. package/dist/esm/excel/formula/context.d.ts +18 -0
  48. package/dist/esm/excel/formula/eval.js +51 -0
  49. package/dist/esm/excel/formula/index.d.ts +2 -2
  50. package/dist/esm/excel/formula/lexer.d.ts +1 -1
  51. package/dist/esm/excel/formula/lexer.js +41 -0
  52. package/dist/esm/excel/formula/parser.d.ts +25 -0
  53. package/dist/esm/excel/formula/parser.js +95 -0
  54. package/dist/esm/excel/print-model.d.ts +38 -1
  55. package/dist/esm/excel/print-model.js +522 -80
  56. package/dist/esm/excel/shared-strings-parser.d.ts +9 -0
  57. package/dist/esm/excel/shared-strings-parser.js +11 -1
  58. package/dist/esm/excel/sheet-drawing.d.ts +38 -2
  59. package/dist/esm/excel/sheet-drawing.js +47 -13
  60. package/dist/esm/excel/sheet-shape-parser.d.ts +6 -2
  61. package/dist/esm/excel/sheet-shape-parser.js +18 -6
  62. package/dist/esm/excel/sheet-to-flow.d.ts +17 -0
  63. package/dist/esm/excel/sheet-to-flow.js +434 -47
  64. package/dist/esm/excel/styles-parser.d.ts +9 -0
  65. package/dist/esm/excel/styles-parser.js +80 -26
  66. package/dist/esm/excel/table-parser.js +5 -0
  67. package/dist/esm/excel/table-style-presets.d.ts +26 -0
  68. package/dist/esm/excel/table-style-presets.js +1555 -0
  69. package/dist/esm/excel/table-style.d.ts +13 -0
  70. package/dist/esm/excel/table-style.js +75 -0
  71. package/dist/esm/excel/tint.d.ts +10 -0
  72. package/dist/esm/excel/tint.js +75 -0
  73. package/dist/esm/excel/vml-drawing.d.ts +41 -3
  74. package/dist/esm/excel/vml-drawing.js +143 -10
  75. package/dist/esm/excel/worksheet-parser.js +89 -15
  76. package/dist/esm/excel/xls/biff-reader.js +10 -2
  77. package/dist/esm/excel/xlsx-reader.js +195 -14
  78. package/dist/esm/excel/xlsx-writer.js +8 -7
  79. package/dist/esm/html/html-writer.js +202 -20
  80. package/dist/esm/index.d.ts +2 -2
  81. package/dist/esm/layout/fit-pages.d.ts +11 -0
  82. package/dist/esm/layout/fit-pages.js +86 -0
  83. package/dist/esm/layout/line-paint.d.ts +58 -0
  84. package/dist/esm/layout/line-paint.js +107 -0
  85. package/dist/esm/layout/page-doc.d.ts +61 -3
  86. package/dist/esm/layout/page-doc.js +141 -1
  87. package/dist/esm/layout/styled-layout.d.ts +55 -7
  88. package/dist/esm/layout/styled-layout.js +1154 -169
  89. package/dist/esm/layout/turned-section.d.ts +38 -0
  90. package/dist/esm/layout/turned-section.js +205 -0
  91. package/dist/esm/markdown/markdown-writer.js +17 -6
  92. package/dist/esm/pdf/styled-page-emitter.js +114 -60
  93. package/dist/esm/pdf/styled-page-renderer.js +1 -1
  94. package/dist/esm/pdf-reader/cff-outline.d.ts +27 -0
  95. package/dist/esm/pdf-reader/cff-outline.js +169 -21
  96. package/dist/esm/pdf-reader/content.d.ts +53 -0
  97. package/dist/esm/pdf-reader/content.js +9 -1
  98. package/dist/esm/pdf-reader/display.d.ts +36 -0
  99. package/dist/esm/pdf-reader/display.js +66 -1
  100. package/dist/esm/pdf-reader/document.js +5 -1
  101. package/dist/esm/pdf-reader/embedded-fonts.d.ts +2 -1
  102. package/dist/esm/pdf-reader/embedded-fonts.js +32 -2
  103. package/dist/esm/pdf-reader/encodings.d.ts +8 -0
  104. package/dist/esm/pdf-reader/encodings.js +25 -3
  105. package/dist/esm/pdf-reader/face-outlines.d.ts +78 -0
  106. package/dist/esm/pdf-reader/face-outlines.js +362 -0
  107. package/dist/esm/pdf-reader/figures.d.ts +52 -0
  108. package/dist/esm/pdf-reader/figures.js +433 -0
  109. package/dist/esm/pdf-reader/flow-build.d.ts +131 -5
  110. package/dist/esm/pdf-reader/flow-build.js +345 -26
  111. package/dist/esm/pdf-reader/font.js +321 -36
  112. package/dist/esm/pdf-reader/glyf-outline.d.ts +33 -0
  113. package/dist/esm/pdf-reader/glyf-outline.js +135 -1
  114. package/dist/esm/pdf-reader/glyph-names.js +154 -1
  115. package/dist/esm/pdf-reader/layout.d.ts +93 -0
  116. package/dist/esm/pdf-reader/layout.js +1703 -214
  117. package/dist/esm/pdf-reader/page-numbers.d.ts +53 -0
  118. package/dist/esm/pdf-reader/page-numbers.js +167 -0
  119. package/dist/esm/pdf-reader/tagged.js +182 -23
  120. package/dist/esm/pdf-reader/text.d.ts +6 -3
  121. package/dist/esm/pdf-reader/text.js +98 -9
  122. package/dist/esm/pdf-reader/type1-outline.d.ts +11 -0
  123. package/dist/esm/pdf-reader/type1-outline.js +63 -8
  124. package/dist/esm/pdf-reader/vector.js +71 -1
  125. package/dist/esm/svg/svg-text.d.ts +58 -0
  126. package/dist/esm/svg/svg-text.js +322 -0
  127. package/dist/esm/svg/svg-writer.js +135 -71
  128. package/dist/esm/word/doc/doc-reader.js +6 -2
  129. package/dist/esm/word/doc/doc-text.d.ts +6 -0
  130. package/dist/esm/word/doc/doc-text.js +19 -1
  131. package/dist/esm/word/document-parser.d.ts +2 -2
  132. package/dist/esm/word/document-parser.js +11 -1
  133. package/dist/esm/word/docx-reader.js +5 -3
  134. package/dist/esm/word/docx-writer.js +218 -23
  135. package/dist/esm/word/drawing-parser.d.ts +5 -3
  136. package/dist/esm/word/drawing-parser.js +49 -8
  137. package/dist/esm/word/font-embed.d.ts +30 -0
  138. package/dist/esm/word/font-embed.js +173 -0
  139. package/dist/esm/word/font-table.d.ts +10 -0
  140. package/dist/esm/word/font-table.js +13 -1
  141. package/dist/esm/word/index.js +1 -1
  142. package/dist/esm/word/numbering-parser.d.ts +3 -1
  143. package/dist/esm/word/numbering-parser.js +2 -1
  144. package/dist/esm/word/paragraph-properties.d.ts +7 -6
  145. package/dist/esm/word/paragraph-properties.js +14 -2
  146. package/dist/esm/word/run-properties.js +26 -0
  147. package/package.json +12 -3
@@ -198,12 +198,19 @@ export interface Line {
198
198
  readonly mathAscentPt?: number;
199
199
  readonly mathDescentPt?: number;
200
200
  /**
201
- * E-PARITY: metric-derived single-line height and descent (Pt), the max over
202
- * the line's text-token fonts under a non-default `layoutProfile`. Absent under
203
- * `'ream'`, where leading stays the flat 1.2×/0.2 model (byte-identical).
201
+ * §17.3.1.33 — the line's single height and descent (Pt) from the faces on
202
+ * it, pictures included, where the line model reads faces (a Word document,
203
+ * or a renderer-compat `layoutProfile`). Absent under the flat 1.2×/0.2
204
+ * model.
204
205
  */
205
206
  readonly metricHeightPt?: number;
206
207
  readonly metricDescentPt?: number;
208
+ /**
209
+ * The line of its TEXT alone (the paragraph mark's, on a line with none):
210
+ * what a spacing of more lines adds per line, where a picture on the line
211
+ * adds nothing.
212
+ */
213
+ readonly metricTextHeightPt?: number;
207
214
  }
208
215
  /** An image bound into a {@link LaidOutDocument}: its resource name plus the decoded/validated bytes. */
209
216
  /**
@@ -289,6 +296,21 @@ export interface PageItemBase {
289
296
  * photograph the slide is made of (corpus: tdf156808, tdf157635, tdf156856).
290
297
  */
291
298
  readonly behind?: boolean;
299
+ /**
300
+ * The item stands IN FRONT of the page's text and covers it — a drawing
301
+ * floating over a spreadsheet's cells. A page paints its text after its
302
+ * shapes, so such items are painted as a second layer, every pass again,
303
+ * once the first layer's text is down.
304
+ */
305
+ readonly over?: boolean;
306
+ /**
307
+ * The part of the page the item may paint, when it is cut off — a
308
+ * spreadsheet's drawing printed in pieces, each piece seen only over the
309
+ * rows and columns of its own page (TableOverlay). Top-left frame, like the
310
+ * item itself. Items sharing a window paint together, in their own order,
311
+ * after the rest of their layer.
312
+ */
313
+ readonly window?: PageWindow;
292
314
  /**
293
315
  * The picture this item belongs to, when it is part of one. A metafile is a
294
316
  * list of drawing orders, and text among them is BOTH over what came before
@@ -306,6 +328,13 @@ export interface PageItemBase {
306
328
  */
307
329
  readonly artifact?: 'pagination';
308
330
  }
331
+ /** A rectangle of the page, top-left frame: what a {@link PageItemBase.window} lets through. */
332
+ export interface PageWindow {
333
+ readonly x: Pt;
334
+ readonly y: Pt;
335
+ readonly width: Pt;
336
+ readonly height: Pt;
337
+ }
309
338
  /** A laid-out line of text (tokens carry their fonts/sizes/positions). */
310
339
  export interface TextLineItem extends PageItemBase {
311
340
  readonly type: 'line';
@@ -459,6 +488,35 @@ export interface PagePaintPlan {
459
488
  readonly ordered: ReadonlyArray<ReadonlyArray<PageItem>>;
460
489
  }
461
490
  export declare function paintPlan(commands: ReadonlyArray<PageItem>): PagePaintPlan;
491
+ /**
492
+ * A page's items in the layers they paint in: first the page's own, then each
493
+ * group seen through a window of its own, then the same again for the items
494
+ * that stand in front of the page's text (PageItemBase.over). Each layer is
495
+ * painted pass by pass on its own, so a writer can cut a windowed one off with
496
+ * a single clip. A page with neither comes back as one layer, its items as
497
+ * they were.
498
+ *
499
+ * @param commands The page's items, in the order the layout placed them.
500
+ * @returns The layers, in paint order; empty ones left out.
501
+ */
502
+ export declare function pageLayers(commands: ReadonlyArray<PageItem>): Array<{
503
+ readonly items: Array<PageItem>;
504
+ readonly window?: PageWindow;
505
+ }>;
506
+ /**
507
+ * The part of the page an item can paint, top-left frame — generous where it
508
+ * cannot be exact (a turned line, a turned picture), so that what falls
509
+ * outside it surely paints nothing there.
510
+ *
511
+ * @param item The item.
512
+ * @returns Its box: left, top, right and bottom edges.
513
+ */
514
+ export declare function pageItemBounds(item: PageItem): {
515
+ x0: number;
516
+ y0: number;
517
+ x1: number;
518
+ y1: number;
519
+ };
462
520
  export interface LaidOutDocument {
463
521
  readonly pages: ReadonlyArray<LaidOutPage>;
464
522
  readonly resources: ResourceStore;
@@ -60,8 +60,148 @@ function paintPlan(commands) {
60
60
  ordered: [...ordered.entries()].sort((a, b) => (orderOf.get(a[0]) ?? 0) - (orderOf.get(b[0]) ?? 0)).map(([, run]) => run)
61
61
  };
62
62
  }
63
+ /**
64
+ * A page's items in the layers they paint in: first the page's own, then each
65
+ * group seen through a window of its own, then the same again for the items
66
+ * that stand in front of the page's text (PageItemBase.over). Each layer is
67
+ * painted pass by pass on its own, so a writer can cut a windowed one off with
68
+ * a single clip. A page with neither comes back as one layer, its items as
69
+ * they were.
70
+ *
71
+ * @param commands The page's items, in the order the layout placed them.
72
+ * @returns The layers, in paint order; empty ones left out.
73
+ */
74
+ function pageLayers(commands) {
75
+ if (!commands.some((c) => c.over === true || c.window !== void 0)) return [{ items: [...commands] }];
76
+ const out = [];
77
+ for (const over of [false, true]) {
78
+ const layer = commands.filter((c) => c.over === true === over);
79
+ const plain = layer.filter((c) => c.window === void 0);
80
+ if (plain.length > 0 || !over) out.push({ items: plain });
81
+ const windows = /* @__PURE__ */ new Map();
82
+ for (const c of layer) {
83
+ const w = c.window;
84
+ if (!w) continue;
85
+ const key = `${w.x} ${w.y} ${w.width} ${w.height}`;
86
+ const group = windows.get(key);
87
+ if (group) group.items.push(c);
88
+ else windows.set(key, {
89
+ items: [c],
90
+ window: w
91
+ });
92
+ }
93
+ out.push(...windows.values());
94
+ }
95
+ return out;
96
+ }
97
+ /**
98
+ * The part of the page an item can paint, top-left frame — generous where it
99
+ * cannot be exact (a turned line, a turned picture), so that what falls
100
+ * outside it surely paints nothing there.
101
+ *
102
+ * @param item The item.
103
+ * @returns Its box: left, top, right and bottom edges.
104
+ */
105
+ function pageItemBounds(item) {
106
+ switch (item.type) {
107
+ case "fill": return {
108
+ x0: item.x,
109
+ y0: item.y,
110
+ x1: item.x + item.width,
111
+ y1: item.y + item.height
112
+ };
113
+ case "border": {
114
+ const half = item.borderSizePt / 2;
115
+ return {
116
+ x0: item.x - half,
117
+ y0: item.y - half,
118
+ x1: item.x + item.width + half,
119
+ y1: item.y + item.height + half
120
+ };
121
+ }
122
+ case "image": {
123
+ if (!item.rotationDeg) return {
124
+ x0: item.x,
125
+ y0: item.y,
126
+ x1: item.x + item.width,
127
+ y1: item.y + item.height
128
+ };
129
+ const r = Math.hypot(item.width, item.height) / 2;
130
+ const cx = item.x + item.width / 2;
131
+ const cy = item.y + item.height / 2;
132
+ return {
133
+ x0: cx - r,
134
+ y0: cy - r,
135
+ x1: cx + r,
136
+ y1: cy + r
137
+ };
138
+ }
139
+ case "line": {
140
+ if (item.clip) return {
141
+ x0: item.clip.x,
142
+ y0: item.clip.y,
143
+ x1: item.clip.x + item.clip.width,
144
+ y1: item.clip.y + item.clip.height
145
+ };
146
+ const size = item.line.maxFontSizePt;
147
+ const width = item.line.contentWidthPt;
148
+ if (item.rotationDeg || item.warp) {
149
+ const r = width + size;
150
+ return {
151
+ x0: item.originX - r,
152
+ y0: item.baselineY - r,
153
+ x1: item.originX + r,
154
+ y1: item.baselineY + r
155
+ };
156
+ }
157
+ return {
158
+ x0: item.originX,
159
+ y0: item.baselineY - size,
160
+ x1: item.originX + width,
161
+ y1: item.baselineY + (item.line.metricDescentPt ?? size * .25)
162
+ };
163
+ }
164
+ case "shape": {
165
+ const [a, b, c, d, e, f] = item.shape.transform;
166
+ let x0 = Infinity;
167
+ let y0 = Infinity;
168
+ let x1 = -Infinity;
169
+ let y1 = -Infinity;
170
+ const take = (x, y) => {
171
+ const px = a * x + c * y + e;
172
+ const py = b * x + d * y + f;
173
+ x0 = Math.min(x0, px);
174
+ y0 = Math.min(y0, py);
175
+ x1 = Math.max(x1, px);
176
+ y1 = Math.max(y1, py);
177
+ };
178
+ for (const path of item.shape.paths) for (const seg of path.segments) {
179
+ if (seg.op === "close") continue;
180
+ if (seg.op === "cubic") {
181
+ take(seg.x1, seg.y1);
182
+ take(seg.x2, seg.y2);
183
+ }
184
+ take(seg.x, seg.y);
185
+ }
186
+ if (x0 > x1) return {
187
+ x0: 0,
188
+ y0: 0,
189
+ x1: 0,
190
+ y1: 0
191
+ };
192
+ const pad = (item.shape.stroke?.widthPt ?? 0) / 2 + 1;
193
+ const sh = item.shape.shadow;
194
+ return {
195
+ x0: x0 - pad + Math.min(0, sh?.dxPt ?? 0) - (sh?.blurPt ?? 0),
196
+ y0: y0 - pad + Math.min(0, sh?.dyPt ?? 0) - (sh?.blurPt ?? 0),
197
+ x1: x1 + pad + Math.max(0, sh?.dxPt ?? 0) + (sh?.blurPt ?? 0),
198
+ y1: y1 + pad + Math.max(0, sh?.dyPt ?? 0) + (sh?.blurPt ?? 0)
199
+ };
200
+ }
201
+ }
202
+ }
63
203
  function assertNeverPageItem(item) {
64
204
  throw new Error(`Unhandled PageItem kind: ${String(item.type)}`);
65
205
  }
66
206
  //#endregion
67
- export { paintPlan };
207
+ export { pageItemBounds, pageLayers, paintPlan };
@@ -7,6 +7,7 @@ import { LaidOutDocument, PageItem } from './page-doc.js';
7
7
  import { AttachedFile } from '../pdf/embedded-file.js';
8
8
  import { SignaturePlaceholder } from '../pdf/signature.js';
9
9
  import { PdfEncryptOptions } from '../pdf/encryption.js';
10
+ import { Sheet } from './turned-section.js';
10
11
  import { StructTreeBuilder } from '../pdf/struct-tree.js';
11
12
  /**
12
13
  * PDF/A conformance string: part 1 (ISO 19005-1, PDF 1.4) / 2 (ISO 19005-2) / 3
@@ -24,15 +25,27 @@ export interface PdfAProfile {
24
25
  readonly version: '1.4' | '1.7';
25
26
  }
26
27
  /**
27
- * E-PARITY: renderer-compatibility profile for the line-height model.
28
- * `'ream'` (default) — Ream's flat 1.2× leading; byte-identical to before.
29
- * `'word'` — leading from the font's OS/2 usWin metrics (the GDI cell box).
30
- * `'libreoffice'` — leading from hhea (or OS/2 typo when USE_TYPO_METRICS is set).
28
+ * E-PARITY: renderer-compatibility profile — how lines are measured, broken
29
+ * and stacked.
30
+ * `'ream'` (default) — kerned measuring, Knuth-Plass breaking, and the line
31
+ * height the document asks for (see {@link TypesetBy}).
32
+ * `'word'` — kern-free measuring, first-fit breaking, and lines as Word sets
33
+ * them whatever the document.
34
+ * `'libreoffice'` — first-fit breaking, lines from the face in hand: hhea, or
35
+ * the OS/2 typo line when USE_TYPO_METRICS is set.
31
36
  *
32
- * Opt-in: a profile emulates that renderer's vertical rhythm for closer visual
33
- * parity. It never changes default (`'ream'`) output.
37
+ * Opt-in: a profile emulates that renderer for closer visual parity.
34
38
  */
35
39
  export type LayoutProfile = 'ream' | 'word' | 'libreoffice';
40
+ /**
41
+ * The application whose rules a document is set by: `'word'` stands its
42
+ * lines as tall as the faces on them make them (§17.3.1.33, see
43
+ * `fontLeadingPt`) rather than Ream's flat 1.2× of the size, and gives every
44
+ * horizontal table border the room it is wide (§17.4.38, see
45
+ * `withBorderBands`) rather than none. A Word document's reader asks for it
46
+ * (see `FlowDoc.typesetBy`).
47
+ */
48
+ export type TypesetBy = 'word';
36
49
  /**
37
50
  * The full option set the layout engine and PDF emitter consume: the resolved
38
51
  * font registry, the style/numbering tables, the section model and page
@@ -46,6 +59,15 @@ export interface StyledRenderOptions {
46
59
  readonly registry: FontRegistry;
47
60
  /** Renderer-compatibility profile for the line-height model (default `'ream'`). */
48
61
  readonly layoutProfile?: LayoutProfile;
62
+ /** The application whose rules the document is set by (see {@link TypesetBy}). */
63
+ readonly typesetBy?: TypesetBy;
64
+ /**
65
+ * The document's front floats COVER the text under them. A spreadsheet's
66
+ * drawings float over its cells — a note's box hides the value beside its
67
+ * cell, a chart the data it sits on — where the passes a page is painted in
68
+ * put every line of text over every shape. See `FlowDoc.floatsOverText`.
69
+ */
70
+ readonly floatsOverText?: boolean;
49
71
  /**
50
72
  * Per-run font resolution: when supplied, each text run picks the registry of
51
73
  * its declared family (sans→arimo / serif→tinos / mono→cousine via the run's
@@ -173,6 +195,12 @@ export interface StyledRenderOptions {
173
195
  * TOP margin, not the left.
174
196
  */
175
197
  readonly gutterAtTop?: boolean;
198
+ /**
199
+ * [MS-DOCX] `compatibilityMode` — the version of Word whose layout the
200
+ * document asks for; a Word document that states none is an older Word's
201
+ * (see {@link legacyTableOutdent}).
202
+ */
203
+ readonly compatibilityMode?: number;
176
204
  /**
177
205
  * §7.6 PDF encryption (AES-256, R6). Only honoured on the ASYNC conversion
178
206
  * path (WebCrypto); mutually exclusive with `pdfA` (ISO 19005 forbids
@@ -302,6 +330,12 @@ export interface SectionRenderCtx {
302
330
  }>;
303
331
  readonly headerSet: HeaderFooterSet;
304
332
  readonly footerSet: HeaderFooterSet;
333
+ /**
334
+ * §17.10 — where the body starts and ends on a page that shows each band:
335
+ * below the header band and above the footer band that page carries, each
336
+ * as tall as it is. Absent ⇒ every page takes `marginTop`/`marginBottom`.
337
+ */
338
+ readonly bandMargins?: Readonly<Record<HfBand, BodyMargins>>;
305
339
  readonly titlePg: boolean;
306
340
  readonly evenAndOddHeaders: boolean;
307
341
  /**
@@ -316,10 +350,24 @@ export interface SectionRenderCtx {
316
350
  * paragraph in it. Absent on a bare context built outside a layout run.
317
351
  */
318
352
  readonly options?: StyledRenderOptions;
353
+ /**
354
+ * §17.6.20 — the sheet a section whose lines run DOWN it prints on. Such a
355
+ * section's body is laid out in the frame its text reads in, which the
356
+ * geometry above describes — the sheet turned back a quarter — and turned
357
+ * onto this sheet page by page, while its header and footer are laid out
358
+ * on the sheet itself (see ./turned-section). Absent ⇒ the frame is the sheet.
359
+ */
360
+ readonly sheet?: Sheet;
361
+ }
362
+ type HfBand = 'default' | 'first' | 'even';
363
+ /** The distances from the paper's top and bottom edges to the body's. */
364
+ interface BodyMargins {
365
+ readonly top: number;
366
+ readonly bottom: number;
319
367
  }
320
368
  interface HfBandEntry {
321
369
  readonly commands: Array<PageItem>;
322
- readonly renderDynamic?: (pageNumber: number, totalPages: number) => Array<PageItem>;
370
+ readonly renderDynamic?: (pageText: string, totalPages: number) => Array<PageItem>;
323
371
  /** Laid-out height of the band, so the body can be kept clear of it. */
324
372
  readonly heightPt?: number;
325
373
  }