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
@@ -14,23 +14,78 @@ import "../core/vector.js";
14
14
  * named `/ExtGState` (its constant alpha) from the page's resources.
15
15
  * @returns The content-stream operator lines.
16
16
  */
17
+ /**
18
+ * §20.1.8.40 `blurRad` — how a blurred shadow is drawn: as `count` copies of
19
+ * the silhouette, each at `alpha` transparency, growing through the blur's
20
+ * width. Shared with the emitter that registers the /ExtGState for it, so the
21
+ * alpha it registers is the one the layers are drawn at.
22
+ *
23
+ * @param shadow The shadow (its `blurPt` and `alpha` are read).
24
+ * @returns The number of layers and the transparency of each.
25
+ */
26
+ function shadowBlurLayers(shadow) {
27
+ if (!(shadow.blurPt > 0)) return {
28
+ count: 1,
29
+ alpha: shadow.alpha
30
+ };
31
+ const count = Math.min(8, Math.max(2, Math.round(shadow.blurPt / 2)));
32
+ return {
33
+ count,
34
+ alpha: shadow.alpha / count
35
+ };
36
+ }
37
+ function shadowBbox(shape) {
38
+ let minX = Infinity;
39
+ let minY = Infinity;
40
+ let maxX = -Infinity;
41
+ let maxY = -Infinity;
42
+ for (const path of shape.paths) for (const seg of path.segments) {
43
+ if (seg.op === "close") continue;
44
+ minX = Math.min(minX, seg.x);
45
+ minY = Math.min(minY, seg.y);
46
+ maxX = Math.max(maxX, seg.x);
47
+ maxY = Math.max(maxY, seg.y);
48
+ }
49
+ return Number.isFinite(minX) && maxX > minX && maxY > minY ? {
50
+ minX,
51
+ minY,
52
+ maxX,
53
+ maxY
54
+ } : void 0;
55
+ }
17
56
  function emitVectorShape(shape, patternName, alphaStateName) {
18
57
  const out = [];
19
58
  const [a, b, c, d, e, f] = shape.transform;
20
59
  const shadow = shape.shadow;
21
60
  if (shadow) {
22
- out.push("q");
23
- if (alphaStateName !== void 0) out.push(`/${alphaStateName} gs`);
24
- out.push(`${num(a)} ${num(b)} ${num(c)} ${num(d)} ${num(e + shadow.dxPt)} ${num(f - shadow.dyPt)} cm`);
25
61
  const [sr, sg, sb] = hexToRgb01(shadow.colorHex);
26
- out.push(`${num(sr)} ${num(sg)} ${num(sb)} rg`);
27
- let shadowEvenodd = false;
28
- for (const path of shape.paths) {
29
- if (path.fillRule === "evenodd") shadowEvenodd = true;
30
- for (const seg of path.segments) out.push(emitSegment(seg));
62
+ const bbox = shadowBbox(shape);
63
+ const scale = Math.sqrt(Math.abs(a * d - b * c)) || 1;
64
+ const { count } = shadowBlurLayers(shadow);
65
+ for (let i = 0; i < count; i++) {
66
+ out.push("q");
67
+ if (alphaStateName !== void 0) out.push(`/${alphaStateName} gs`);
68
+ out.push(`${num(a)} ${num(b)} ${num(c)} ${num(d)} ${num(e + shadow.dxPt)} ${num(f - shadow.dyPt)} cm`);
69
+ if (count > 1 && bbox) {
70
+ const local = shadow.blurPt / scale;
71
+ const grow = -local / 2 + (i + .5) * local / count;
72
+ const halfW = Math.max((bbox.maxX - bbox.minX) / 2, 1e-6);
73
+ const halfH = Math.max((bbox.maxY - bbox.minY) / 2, 1e-6);
74
+ const cx = (bbox.minX + bbox.maxX) / 2;
75
+ const cy = (bbox.minY + bbox.maxY) / 2;
76
+ const sx = Math.max((halfW + grow) / halfW, 0);
77
+ const sy = Math.max((halfH + grow) / halfH, 0);
78
+ out.push(`${num(sx)} 0 0 ${num(sy)} ${num(cx * (1 - sx))} ${num(cy * (1 - sy))} cm`);
79
+ }
80
+ out.push(`${num(sr)} ${num(sg)} ${num(sb)} rg`);
81
+ let shadowEvenodd = false;
82
+ for (const path of shape.paths) {
83
+ if (path.fillRule === "evenodd") shadowEvenodd = true;
84
+ for (const seg of path.segments) out.push(emitSegment(seg));
85
+ }
86
+ out.push(shadowEvenodd ? "f*" : "f");
87
+ out.push("Q");
31
88
  }
32
- out.push(shadowEvenodd ? "f*" : "f");
33
- out.push("Q");
34
89
  }
35
90
  out.push("q");
36
91
  out.push(`${num(a)} ${num(b)} ${num(c)} ${num(d)} ${num(e)} ${num(f)} cm`);
@@ -58,6 +113,34 @@ function emitVectorShape(shape, patternName, alphaStateName) {
58
113
  out.push("Q");
59
114
  return out;
60
115
  }
116
+ /**
117
+ * The operators that make `paths` the current CLIP, under `transform` — the
118
+ * same local→y-up-page matrix {@link emitVectorShape} takes. Emitted inside the
119
+ * caller's own `q`…`Q`, and followed by the inverse matrix so what comes after
120
+ * is back in page coordinates.
121
+ *
122
+ * @param paths The clip outline, in the shape's local frame.
123
+ * @param transform The local→page matrix.
124
+ * @returns The operators: `cm`, the path, `W n`, and the inverse `cm`.
125
+ */
126
+ function emitClipPath(paths, transform) {
127
+ const [a, b, c, d, e, f] = transform;
128
+ const det = a * d - b * c;
129
+ if (det === 0) return [];
130
+ const out = [`${num(a)} ${num(b)} ${num(c)} ${num(d)} ${num(e)} ${num(f)} cm`];
131
+ let evenodd = false;
132
+ for (const path of paths) {
133
+ if (path.fillRule === "evenodd") evenodd = true;
134
+ for (const seg of path.segments) out.push(emitSegment(seg));
135
+ }
136
+ out.push(evenodd ? "W* n" : "W n");
137
+ const ia = d / det;
138
+ const ib = -b / det;
139
+ const ic = -c / det;
140
+ const id = a / det;
141
+ out.push(`${num(ia)} ${num(ib)} ${num(ic)} ${num(id)} ${num(-(e * ia + f * ic))} ${num(-(e * ib + f * id))} cm`);
142
+ return out;
143
+ }
61
144
  function emitSegment(seg) {
62
145
  switch (seg.op) {
63
146
  case "move": return `${num(seg.x)} ${num(seg.y)} m`;
@@ -87,4 +170,4 @@ function hexToRgb01(hex) {
87
170
  ];
88
171
  }
89
172
  //#endregion
90
- export { emitVectorShape };
173
+ export { emitClipPath, emitVectorShape, shadowBlurLayers };
@@ -22,6 +22,7 @@ var parser = new XMLParser({
22
22
  htmlEntities: true,
23
23
  ignoreAttributes: false,
24
24
  attributeNamePrefix: "@_",
25
+ maxNestedTags: 1e3,
25
26
  preserveOrder: true,
26
27
  parseAttributeValue: false,
27
28
  parseTagValue: false,
@@ -73,16 +73,33 @@ export declare function diagramTransform(spTree: PoNode, frame: ShapeBoxEmu): Gr
73
73
  * @param where Optional location tag for the loss report (e.g. `slide 3`).
74
74
  */
75
75
  export declare function noDiagramOverrideLoss(where?: string): Loss;
76
+ /** One SmartArt node: the box it occupies in the target space, and its shape. */
77
+ export interface DiagramNode {
78
+ readonly box: ShapeBoxEmu;
79
+ readonly shape: ShapeBlock;
80
+ }
76
81
  /**
77
- * Render a SmartArt drawing override (a `dsp:spTree`) into floating shapes. The
78
- * `dsp:` wrapper holds an ordinary `a:` `spPr`/`txBody`, so the shared DrawingML
82
+ * Read a SmartArt drawing override (a `dsp:spTree`) into its nodes. The `dsp:`
83
+ * wrapper holds an ordinary `a:` `spPr`/`txBody`, so the shared DrawingML
79
84
  * readers apply unchanged. Shared by pptx and docx (E-SMARTART); diagrams carry
80
85
  * no placeholder cascade.
81
86
  *
87
+ * @param spTree The diagram drawing's `dsp:spTree`.
88
+ * @param transform Maps each shape's diagram-space box to the target space.
89
+ * @param colors The colour resolver for the shapes' fills/strokes/text.
90
+ * @param resolveLink A run hyperlink resolver, or `undefined`.
91
+ * @param resolveImage Resolves a picture fill's `r:embed` against the DRAWING
92
+ * part's own relationships, or `undefined`.
93
+ * @returns The diagram's visible nodes, in drawing order.
94
+ */
95
+ export declare function parseDiagramNodes(spTree: PoNode, transform: GroupTransform, colors: ColorResolver, resolveLink: LinkResolver, resolveImage?: (relId: string) => ResourceId | undefined): Array<DiagramNode>;
96
+ /**
97
+ * The same nodes as free-standing floating shapes — what a slide wants, where
98
+ * every shape is anchored to the page.
99
+ *
82
100
  * @param spTree The diagram drawing's `dsp:spTree`.
83
101
  * @param transform Maps each shape's diagram-space box to the target space.
84
- * @param makeFloat Anchors a box — page-relative for a slide, column/paragraph-
85
- * relative for an inline docx diagram.
102
+ * @param makeFloat Anchors a node's box.
86
103
  * @param colors The colour resolver for the shapes' fills/strokes/text.
87
104
  * @param resolveLink A run hyperlink resolver, or `undefined`.
88
105
  * @returns The diagram's visible shapes as positioned {@link ShapeBlock}s.
@@ -1,9 +1,9 @@
1
1
  import { emuToPt, pt } from "../core/ir/units.js";
2
2
  import { FEATURES } from "../core/ir/features.js";
3
- import { poAttr, poChildren, poFindDescendant, poIntAttr, poIs, poText } from "../core/po-helpers.js";
3
+ import { poAttr, poChildren, poFindDescendant, poIntAttr, poIs, poTag, poText } from "../core/po-helpers.js";
4
4
  import { defaultColorResolver, resolveColorNode } from "../core/drawingml/colors.js";
5
5
  import { boxFromXfrm, parsePh, parseXfrmBox, rPrToRunProps } from "./sp-helpers.js";
6
- import { parseCustGeom, parseFill, parseLine, parsePrstGeom } from "../word/drawing-parser.js";
6
+ import { parseCustGeom, parseFill, parseLine, parsePrstGeom, parseShadow, parseXfrm } from "../word/drawing-parser.js";
7
7
  //#region src/pptx/slide-parser.ts
8
8
  var CHART_URI = "http://schemas.openxmlformats.org/drawingml/2006/chart";
9
9
  var TABLE_URI = "http://schemas.openxmlformats.org/drawingml/2006/table";
@@ -206,20 +206,20 @@ function noDiagramOverrideLoss(where) {
206
206
  };
207
207
  }
208
208
  /**
209
- * Render a SmartArt drawing override (a `dsp:spTree`) into floating shapes. The
210
- * `dsp:` wrapper holds an ordinary `a:` `spPr`/`txBody`, so the shared DrawingML
209
+ * Read a SmartArt drawing override (a `dsp:spTree`) into its nodes. The `dsp:`
210
+ * wrapper holds an ordinary `a:` `spPr`/`txBody`, so the shared DrawingML
211
211
  * readers apply unchanged. Shared by pptx and docx (E-SMARTART); diagrams carry
212
212
  * no placeholder cascade.
213
213
  *
214
- * @param spTree The diagram drawing's `dsp:spTree`.
215
- * @param transform Maps each shape's diagram-space box to the target space.
216
- * @param makeFloat Anchors a box — page-relative for a slide, column/paragraph-
217
- * relative for an inline docx diagram.
218
- * @param colors The colour resolver for the shapes' fills/strokes/text.
219
- * @param resolveLink A run hyperlink resolver, or `undefined`.
220
- * @returns The diagram's visible shapes as positioned {@link ShapeBlock}s.
214
+ * @param spTree The diagram drawing's `dsp:spTree`.
215
+ * @param transform Maps each shape's diagram-space box to the target space.
216
+ * @param colors The colour resolver for the shapes' fills/strokes/text.
217
+ * @param resolveLink A run hyperlink resolver, or `undefined`.
218
+ * @param resolveImage Resolves a picture fill's `r:embed` against the DRAWING
219
+ * part's own relationships, or `undefined`.
220
+ * @returns The diagram's visible nodes, in drawing order.
221
221
  */
222
- function parseDiagramDrawing(spTree, transform, makeFloat, colors, resolveLink) {
222
+ function parseDiagramNodes(spTree, transform, colors, resolveLink, resolveImage) {
223
223
  const out = [];
224
224
  for (const sp of poChildren(spTree)) {
225
225
  if (!poIs(sp, "dsp:sp")) continue;
@@ -228,26 +228,89 @@ function parseDiagramDrawing(spTree, transform, makeFloat, colors, resolveLink)
228
228
  if (!own) continue;
229
229
  const box = transform(own);
230
230
  const txBody = poChildren(sp).find((c) => poIs(c, "dsp:txBody"));
231
- const text = txBody ? parseTxBody(txBody, void 0, void 0, colors, resolveLink) : void 0;
231
+ const parsed = txBody ? parseTxBody(txBody, void 0, void 0, colors, resolveLink) : void 0;
232
+ const text = parsed ? withDiagramFontColor(parsed, sp, colors) : void 0;
232
233
  const geometry = parseGeometry(spPr);
233
- const fill = spPr ? parseFill(spPr, colors) : { kind: "none" };
234
+ const fill = spPr ? parseFill(spPr, colors, resolveImage) : { kind: "none" };
234
235
  const line = spPr ? parseLine(spPr, colors) : void 0;
236
+ const shadow = spPr ? parseShadow(spPr, colors) : void 0;
235
237
  const visibleLine = line !== void 0 && line.fill !== "none";
236
238
  if (!text && fill.kind === "none" && !visibleLine) continue;
239
+ const xfrm = spPr ? poChildren(spPr).find((c) => poIs(c, "a:xfrm")) : void 0;
240
+ const spin = xfrm ? parseXfrm(xfrm) : void 0;
241
+ const txBox = (spin?.rotation60k ?? 0) % 216e5 !== 0 ? boxFromXfrm(poChildren(sp).find((c) => poIs(c, "dsp:txXfrm"))) : void 0;
237
242
  out.push({
238
- float: makeFloat(box),
239
- width: emuToPt(box.cx),
240
- height: emuToPt(box.cy),
241
- geometry,
242
- fill,
243
- ...line ? { line } : {},
244
- ...text ? { text } : {},
245
- paragraphProperties: {}
243
+ box,
244
+ shape: {
245
+ width: emuToPt(box.cx),
246
+ height: emuToPt(box.cy),
247
+ geometry,
248
+ fill,
249
+ ...line ? { line } : {},
250
+ ...text && !txBox ? { text } : {},
251
+ ...spin && Object.keys(spin).length > 0 ? { transform: spin } : {},
252
+ ...shadow ? { shadow } : {},
253
+ paragraphProperties: {}
254
+ }
246
255
  });
256
+ if (text && txBox) {
257
+ const placed = transform(txBox);
258
+ out.push({
259
+ box: placed,
260
+ shape: {
261
+ width: emuToPt(placed.cx),
262
+ height: emuToPt(placed.cy),
263
+ geometry: RECT_GEOMETRY,
264
+ fill: { kind: "none" },
265
+ text,
266
+ paragraphProperties: {}
267
+ }
268
+ });
269
+ }
247
270
  }
248
271
  return out;
249
272
  }
250
273
  /**
274
+ * The same nodes as free-standing floating shapes — what a slide wants, where
275
+ * every shape is anchored to the page.
276
+ *
277
+ * @param spTree The diagram drawing's `dsp:spTree`.
278
+ * @param transform Maps each shape's diagram-space box to the target space.
279
+ * @param makeFloat Anchors a node's box.
280
+ * @param colors The colour resolver for the shapes' fills/strokes/text.
281
+ * @param resolveLink A run hyperlink resolver, or `undefined`.
282
+ * @returns The diagram's visible shapes as positioned {@link ShapeBlock}s.
283
+ */
284
+ function parseDiagramDrawing(spTree, transform, makeFloat, colors, resolveLink) {
285
+ return parseDiagramNodes(spTree, transform, colors, resolveLink).map(({ box, shape }) => ({
286
+ ...shape,
287
+ float: makeFloat(box)
288
+ }));
289
+ }
290
+ function withDiagramFontColor(text, sp, colors) {
291
+ const style = poChildren(sp).find((c) => poIs(c, "dsp:style"));
292
+ const ref = style ? poChildren(style).find((c) => poIs(c, "a:fontRef")) : void 0;
293
+ const child = ref ? poChildren(ref).find((c) => poTag(c) !== void 0) : void 0;
294
+ const colorHex = child ? resolveColorNode(child, colors) : void 0;
295
+ if (colorHex === void 0) return text;
296
+ return {
297
+ ...text,
298
+ content: text.content.map((block) => block.kind === "paragraph" ? {
299
+ ...block,
300
+ paragraph: {
301
+ ...block.paragraph,
302
+ runs: block.paragraph.runs.map((run) => run.properties.colorHex === void 0 ? {
303
+ ...run,
304
+ properties: {
305
+ ...run.properties,
306
+ colorHex
307
+ }
308
+ } : run)
309
+ }
310
+ } : block)
311
+ };
312
+ }
313
+ /**
251
314
  * `p:bg` → the background fill, or `undefined` when none/unsupported. `p:bgPr`
252
315
  * carries the fill directly (`a:solidFill`/`a:gradFill` — the same children
253
316
  * `parseFill` reads; a picture background is not yet supported); `p:bgRef` (a
@@ -513,4 +576,4 @@ function cellFillHex(tcPr, colors) {
513
576
  }
514
577
  }
515
578
  //#endregion
516
- export { backdropElement, diagramTransform, noDiagramOverrideLoss, parseBackgroundFill, parseDiagramDrawing, parseGeometry, parseSlideShapes, parseTxBody };
579
+ export { backdropElement, diagramTransform, noDiagramOverrideLoss, parseBackgroundFill, parseDiagramNodes, parseGeometry, parseSlideShapes, parseTxBody };
@@ -87,7 +87,7 @@ function emitPage(out, page, laid, losses, idc) {
87
87
  x2,
88
88
  yBottom
89
89
  ];
90
- out.push(`<line x1="${fmt(ax)}" y1="${fmt(ay)}" x2="${fmt(bx)}" y2="${fmt(by)}" stroke="#${b.borderColorHex}" stroke-width="${fmt(b.borderSizePt)}"${b.borderStyle === "dashed" ? ` stroke-dasharray="${fmt(b.borderSizePt * 4)} ${fmt(b.borderSizePt * 1.33)}"` : b.borderStyle === "dotted" ? ` stroke-dasharray="${fmt(b.borderSizePt)} ${fmt(b.borderSizePt * 1.33)}"` : ""}/>`);
90
+ out.push(`<line x1="${fmt(ax)}" y1="${fmt(ay)}" x2="${fmt(bx)}" y2="${fmt(by)}" stroke="#${b.borderColorHex}" stroke-width="${fmt(b.borderSizePt)}"${b.borderStyle === "dashed" ? " stroke-dasharray=\"8 2.5\"" : b.borderStyle === "dashSmallGap" ? " stroke-dasharray=\"3 1\"" : b.borderStyle === "dotted" ? " stroke-dasharray=\"0.5 1\"" : ""}/>`);
91
91
  }
92
92
  for (const sh of plan.shapes) emitShape(out, sh.shape, idc);
93
93
  for (const t of plan.lines) emitTextLine(out, t, losses, idc);
@@ -1,7 +1,8 @@
1
- import { BodyElement, Comment, Section, SectionProperties } from '../core/document-model/index.js';
1
+ import { BodyElement, Comment, RunProperties, Section, SectionProperties, ShapeFill } from '../core/document-model/index.js';
2
2
  import { ColorResolver } from '../core/drawingml/colors.js';
3
3
  import { Loss, ResourceId } from '../core/ir/index.js';
4
4
  import { PoNode } from '../core/po-helpers.js';
5
+ import { ThemeStyles } from './drawing-parser.js';
5
6
  /**
6
7
  * Resolves a drawing relationship id to a content-addressed `ResourceId` —
7
8
  * supplied by the converter (which owns the OPC package and the `ResourceStore`).
@@ -9,6 +10,15 @@ import { PoNode } from '../core/po-helpers.js';
9
10
  export type ImageResolver = (relId: string) => ResourceId | undefined;
10
11
  /** Resolves a `w:hyperlink` `r:id` to its external target URL. */
11
12
  export type HyperlinkResolver = (relId: string) => string | undefined;
13
+ /**
14
+ * A SmartArt diagram's pre-rendered drawing override: its `dsp:spTree`, plus a
15
+ * resolver for the picture fills its nodes name — those relationships belong to
16
+ * the drawing part, not to the part that references the diagram.
17
+ */
18
+ export interface ResolvedDiagram {
19
+ readonly spTree: PoNode;
20
+ readonly resolveImage?: ImageResolver;
21
+ }
12
22
  /**
13
23
  * Document-wide resolvers every nested parser needs — one context object instead
14
24
  * of threading a parameter pair through ten signatures (oop-design §8).
@@ -25,10 +35,28 @@ export interface ParseContext {
25
35
  readonly resolveHyperlink?: HyperlinkResolver;
26
36
  /**
27
37
  * SmartArt: a data relationship id (`dgm:relIds` `@r:dm`) → the diagram's
28
- * pre-rendered drawing override (its `dsp:spTree`), or `undefined` when the file
29
- * ships none (E-SMARTART SA2).
38
+ * pre-rendered drawing override, or `undefined` when the file ships none
39
+ * (E-SMARTART SA2).
40
+ */
41
+ readonly resolveDiagram?: (relId: string) => ResolvedDiagram | undefined;
42
+ /**
43
+ * §21.2 a `c:chart` `@r:id` → the chart part's path, the key the reader files
44
+ * parsed charts under. Relationship ids are scoped to their owning part, so a
45
+ * footer's `rId1` and the body's `rId1` are different charts. Absent ⇒ the
46
+ * raw rel id is kept.
47
+ */
48
+ readonly resolveChartPart?: (relId: string) => string | undefined;
49
+ /**
50
+ * §20.1.4.2.19 — the theme's `a:lnStyleLst` widths in points, which a
51
+ * gallery-styled shape's `a:lnRef idx` indexes for its outline weight.
30
52
  */
31
- readonly resolveDiagram?: (relId: string) => PoNode | undefined;
53
+ readonly themeLineWidths?: ReadonlyArray<number>;
54
+ /**
55
+ * §20.1.4.1.14/§20.1.4.1.15 — the theme's format scheme: the fill, background
56
+ * fill and effect styles a `<wps:style>` reference indexes for the fill and
57
+ * the shadow a gallery-drawn shape wears.
58
+ */
59
+ readonly themeStyles?: ThemeStyles;
32
60
  /**
33
61
  * Sink for graceful-degradation notices (E-SMARTART SA3): a SmartArt with no
34
62
  * drawing override records a dropped-feature {@link Loss} rather than vanishing.
@@ -41,6 +69,12 @@ export interface ParseContext {
41
69
  * reference is readonly; its contents mutate during the walk (CM2c).
42
70
  */
43
71
  readonly openCommentRanges?: Set<string>;
72
+ /**
73
+ * §17.3.1.1/§17.3.1.3 — what `w:beforeAutospacing`/`w:afterAutospacing`
74
+ * resolve to for THIS document: 14pt when it states no compatibility mode,
75
+ * and nothing (the default) for every Word 2007-or-later one.
76
+ */
77
+ readonly autoSpacingPt?: number;
44
78
  }
45
79
  /** The default {@link ParseContext} — just the default colour resolver. */
46
80
  export declare const DEFAULT_PARSE_CONTEXT: ParseContext;
@@ -53,8 +87,55 @@ export declare const DEFAULT_PARSE_CONTEXT: ParseContext;
53
87
  * @param ctx The document-wide parse context.
54
88
  * @returns The body elements; empty when the `w:body` is absent.
55
89
  */
56
- export declare function parseDocument(documentXml: Uint8Array, ctx?: ParseContext): Array<BodyElement>;
57
- /** The empty {@link SectionProperties} fallback (no headers/footers). */
90
+ export declare function parseDocument(documentXml: Uint8Array, ctx?: ParseContext, blocks?: BlockCounter): Array<BodyElement>;
91
+ /**
92
+ * §17.2.1 `w:background` — the colour the whole page is painted, as a six-digit
93
+ * hex. Read from `@w:color` (Word's own attribute), falling back to the VML
94
+ * `v:background @fillcolor` beside it. `auto` and a gradient-only background
95
+ * (which carries no flat colour of its own) both come back undefined.
96
+ *
97
+ * @param documentXml The raw `document.xml` bytes.
98
+ * @returns The colour, or undefined when the document names none.
99
+ */
100
+ export declare function parseBackgroundColor(documentXml: Uint8Array): string | undefined;
101
+ /**
102
+ * §17.2.1 — the page background as the FILL it is. `@w:color` is only the flat
103
+ * fallback: the `v:background` beside it carries the gradient or the picture
104
+ * Word actually paints, and both references draw those. fill.docx runs a
105
+ * five-stop radial sweep where we painted its fallback navy, and
106
+ * tdf126533_pageBitmap.docx papers the page with an image.
107
+ *
108
+ * @param documentXml The raw `document.xml` bytes.
109
+ * @param resolveImage Resolver for a picture background's `r:id`.
110
+ * @returns The fill, or undefined when the document names no background.
111
+ */
112
+ export declare function parseBackgroundFill(documentXml: Uint8Array, resolveImage?: (relId: string) => ResourceId | undefined): ShapeFill | undefined;
113
+ /**
114
+ * Lines a parsed body up with anything counted in SOURCE blocks. `index[i]` is
115
+ * the ordinal of the `w:p`/`w:tbl` that produced body element `i`; `next` is the
116
+ * running count. A paragraph carrying anchored drawings produces several
117
+ * elements, so the two counts diverge — and {@link parseSections} counts blocks.
118
+ */
119
+ export interface BlockCounter {
120
+ readonly index: Array<number>;
121
+ next: number;
122
+ }
123
+ /** A fresh {@link BlockCounter}. */
124
+ export declare function newBlockCounter(): BlockCounter;
125
+ /**
126
+ * Translate a section boundary counted in source blocks into one counted in body
127
+ * elements: the number of elements that came from a block before `blockEnd`.
128
+ *
129
+ * @param blocks The counter filled while parsing the body.
130
+ * @param blockEnd The section's `endIndex`, in source blocks.
131
+ * @returns The matching body-element index.
132
+ */
133
+ export declare function bodyIndexForBlock(blocks: BlockCounter, blockEnd: number): number;
134
+ /**
135
+ * The empty {@link SectionProperties} fallback (no headers/footers). §17.6.13 —
136
+ * on the page a document with no `w:sectPr` of its own is made on, which is the
137
+ * same US Letter a section with no `w:pgSz` gets.
138
+ */
58
139
  export declare const EMPTY_SECTION: SectionProperties;
59
140
  /**
60
141
  * Parse the document's final section properties (ECMA-376 Part 1 §17.6.17 — the
@@ -96,7 +177,15 @@ export declare function parseHeaderFooter(xml: Uint8Array, ctx?: ParseContext):
96
177
  * @param ctx The document-wide parse context.
97
178
  * @returns The parsed body elements.
98
179
  */
99
- export declare function parseBodyElements(children: ReadonlyArray<PoNode>, ctx?: ParseContext): Array<BodyElement>;
180
+ export declare function parseBodyElements(children: ReadonlyArray<PoNode>, ctx?: ParseContext, blocks?: BlockCounter, sdtRunProps?: RunProperties): Array<BodyElement>;
181
+ /**
182
+ * §17.5.2.28 `w:sdt/w:sdtPr/w:rPr` — the run properties a content control
183
+ * lends what it holds, when it states any.
184
+ *
185
+ * @param sdt The `w:sdt` element.
186
+ * @returns The properties, or `undefined` when the control states none.
187
+ */
188
+ export declare function sdtRunProperties(sdt: PoNode): RunProperties | undefined;
100
189
  /**
101
190
  * Parse `footnotes.xml` / `endnotes.xml` (§17.11) into note content by id. The
102
191
  * separator / continuationSeparator / continuationNotice stubs (negative ids or