reamkit 1.20.0 → 1.22.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.
- package/dist/esm/core/bytes.d.ts +22 -4
- package/dist/esm/core/bytes.js +73 -5
- package/dist/esm/core/crypto/offcrypto.d.ts +1 -0
- package/dist/esm/core/crypto/offcrypto.js +2 -1
- package/dist/esm/core/document-model/types.d.ts +60 -0
- package/dist/esm/core/drawingml/chart-parser.d.ts +2 -1
- package/dist/esm/core/drawingml/chart-parser.js +23 -1
- package/dist/esm/core/drawingml/colors.d.ts +27 -3
- package/dist/esm/core/drawingml/colors.js +30 -6
- package/dist/esm/core/drawingml/preset-geometry.js +236 -0
- package/dist/esm/core/metafile/emf.js +2 -1
- package/dist/esm/core/metafile/symbol-fonts.d.ts +42 -0
- package/dist/esm/core/metafile/symbol-fonts.js +154 -0
- package/dist/esm/core/metafile/wmf.js +35 -2
- package/dist/esm/core/vector.d.ts +5 -0
- package/dist/esm/excel/sheet-shape-parser.js +1 -12
- package/dist/esm/excel/xlsx-reader.d.ts +1 -1
- package/dist/esm/excel/xlsx-reader.js +3 -3
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +2 -1
- package/dist/esm/layout/page-doc.d.ts +38 -0
- package/dist/esm/layout/page-doc.js +34 -18
- package/dist/esm/layout/styled-layout.js +174 -49
- package/dist/esm/pdf/shading.d.ts +19 -0
- package/dist/esm/pdf/shading.js +84 -11
- package/dist/esm/pdf/styled-page-emitter.js +614 -444
- package/dist/esm/pptx/ole-preview.d.ts +10 -0
- package/dist/esm/pptx/ole-preview.js +52 -0
- package/dist/esm/pptx/placeholder-cascade.d.ts +69 -5
- package/dist/esm/pptx/placeholder-cascade.js +162 -25
- package/dist/esm/pptx/pptx-reader.js +247 -39
- package/dist/esm/pptx/slide-parser.d.ts +72 -10
- package/dist/esm/pptx/slide-parser.js +310 -82
- package/dist/esm/pptx/sp-helpers.js +19 -4
- package/dist/esm/pptx/table-style.d.ts +56 -0
- package/dist/esm/pptx/table-style.js +161 -0
- package/dist/esm/svg/svg-writer.js +53 -5
- package/dist/esm/word/docx-reader.js +2 -2
- package/dist/esm/word/drawing-parser.d.ts +34 -0
- package/dist/esm/word/drawing-parser.js +159 -13
- package/package.json +1 -1
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { emuToPt, pt } from "../core/ir/units.js";
|
|
2
2
|
import { FEATURES } from "../core/ir/features.js";
|
|
3
3
|
import { poAttr, poChildren, poFindDescendant, poIntAttr, poIs, poTag, poText } from "../core/po-helpers.js";
|
|
4
|
-
import { defaultColorResolver, resolveColorNode } from "../core/drawingml/colors.js";
|
|
4
|
+
import { defaultColorResolver, placeholderColors, resolveColorNode } from "../core/drawingml/colors.js";
|
|
5
5
|
import { boxFromXfrm, parsePh, parseXfrmBox, rPrToRunProps } from "./sp-helpers.js";
|
|
6
|
-
import {
|
|
6
|
+
import { parseBullet } from "./placeholder-cascade.js";
|
|
7
|
+
import { colorChangeOf, parseCustGeom, parseFill, parseLine, parsePrstGeom, parseShadow, parseXfrm, statesFill, styleRefFill, styleRefFontColor, styleRefLine } from "../word/drawing-parser.js";
|
|
8
|
+
import { cellStyle, lineBorder, tableStyleFlags, tableStyleId, withCellStyle, withoutFill } from "./table-style.js";
|
|
7
9
|
//#region src/pptx/slide-parser.ts
|
|
8
10
|
var CHART_URI = "http://schemas.openxmlformats.org/drawingml/2006/chart";
|
|
11
|
+
var OLE_URI = "http://schemas.openxmlformats.org/presentationml/2006/ole";
|
|
9
12
|
var TABLE_URI = "http://schemas.openxmlformats.org/drawingml/2006/table";
|
|
10
13
|
var DIAGRAM_URI = "http://schemas.openxmlformats.org/drawingml/2006/diagram";
|
|
11
14
|
var ALGN_TO_ALIGNMENT = {
|
|
@@ -32,24 +35,37 @@ var IDENTITY_TRANSFORM = (box) => box;
|
|
|
32
35
|
* @param transform Maps child-space boxes to the slide (identity at the top level).
|
|
33
36
|
* @returns The container's shapes as positioned {@link BodyElement}s.
|
|
34
37
|
*/
|
|
35
|
-
function parseSlideShapes(container, ctx = {}, transform = IDENTITY_TRANSFORM) {
|
|
38
|
+
function parseSlideShapes(container, ctx = {}, transform = IDENTITY_TRANSFORM, skipPlaceholders = false) {
|
|
36
39
|
const out = [];
|
|
37
|
-
for (const child of poChildren(container))
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
shape
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (
|
|
46
|
-
|
|
47
|
-
image
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
40
|
+
for (const child of poChildren(container)) {
|
|
41
|
+
if (skipPlaceholders && isPlaceholder(child)) continue;
|
|
42
|
+
if (poIs(child, "p:sp")) {
|
|
43
|
+
const shape = parseSp(child, ctx, transform);
|
|
44
|
+
if (shape) out.push({
|
|
45
|
+
kind: "shape",
|
|
46
|
+
shape
|
|
47
|
+
});
|
|
48
|
+
} else if (poIs(child, "p:pic")) {
|
|
49
|
+
const image = parsePic(child, ctx, transform);
|
|
50
|
+
if (image) out.push({
|
|
51
|
+
kind: "image",
|
|
52
|
+
image
|
|
53
|
+
});
|
|
54
|
+
} else if (poIs(child, "p:graphicFrame")) out.push(...parseGraphicFrame(child, ctx, transform));
|
|
55
|
+
else if (poIs(child, "p:grpSp")) out.push(...parseSlideShapes(child, ctx, composeGroupTransform(child, transform), skipPlaceholders));
|
|
56
|
+
}
|
|
51
57
|
return out;
|
|
52
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Whether a shape is a placeholder — `p:ph` in its OWN non-visual properties.
|
|
61
|
+
* Read as "anywhere below", a group holding one would take the whole group
|
|
62
|
+
* with it.
|
|
63
|
+
*/
|
|
64
|
+
function isPlaceholder(shape) {
|
|
65
|
+
const nv = poChildren(shape).find((c) => poTag(c)?.startsWith("p:nv") === true);
|
|
66
|
+
const nvPr = nv ? poChildren(nv).find((c) => poIs(c, "p:nvPr")) : void 0;
|
|
67
|
+
return nvPr !== void 0 && poChildren(nvPr).some((c) => poIs(c, "p:ph"));
|
|
68
|
+
}
|
|
53
69
|
function composeGroupTransform(grpSp, parent) {
|
|
54
70
|
const grpSpPr = poChildren(grpSp).find((c) => poIs(c, "p:grpSpPr"));
|
|
55
71
|
const xfrm = grpSpPr ? poChildren(grpSpPr).find((c) => poIs(c, "a:xfrm")) : void 0;
|
|
@@ -97,20 +113,41 @@ function parseSp(sp, ctx, transform) {
|
|
|
97
113
|
if (!own && ph && ctx.cascade) own = ctx.cascade.geometryFor(ph);
|
|
98
114
|
if (!own) return void 0;
|
|
99
115
|
const box = transform(own);
|
|
116
|
+
const style = poChildren(sp).find((c) => poIs(c, "p:style"));
|
|
100
117
|
const txBody = poChildren(sp).find((c) => poIs(c, "p:txBody"));
|
|
101
|
-
const
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
const
|
|
118
|
+
const styleColor = style ? styleRefFontColor(style, colors) : void 0;
|
|
119
|
+
const text = txBody ? parseTxBody(txBody, ph, ctx.cascade, colors, ctx.resolveHyperlink, styleColor) : void 0;
|
|
120
|
+
const proto = ph && ctx.cascade ? ctx.cascade.shapePropsFor(ph) : void 0;
|
|
121
|
+
const geometry = parseGeometry(spPr && statesGeometry(spPr) ? spPr : proto ?? spPr);
|
|
122
|
+
const useBgFill = poAttr(sp, "useBgFill") === "1";
|
|
123
|
+
const fillFrom = statesFill(spPr) ? spPr : proto ?? spPr;
|
|
124
|
+
const fill = useBgFill ? backgroundThrough(ctx.backgroundFill, box, ctx.slideSize) : fillFrom ? parseFill(fillFrom, colors, ctx.resolveImage) : { kind: "none" };
|
|
125
|
+
const lineFrom = spPr && poChildren(spPr).some((c) => poIs(c, "a:ln")) ? spPr : proto ?? spPr;
|
|
126
|
+
let line = lineFrom ? parseLine(lineFrom, colors) : void 0;
|
|
127
|
+
const themeStyles = ctx.themeFills ? {
|
|
128
|
+
fills: ctx.themeFills.fills,
|
|
129
|
+
bgFills: ctx.themeFills.backgrounds
|
|
130
|
+
} : void 0;
|
|
131
|
+
const styled = style && fill.kind === "none" && !statesFill(fillFrom) ? styleRefFill(style, colors, themeStyles) : fill;
|
|
132
|
+
if (style) {
|
|
133
|
+
const fromStyle = styleRefLine(style, colors, ctx.themeLineWidths);
|
|
134
|
+
if (fromStyle) line = line ? {
|
|
135
|
+
...fromStyle,
|
|
136
|
+
...Object.fromEntries(Object.entries(line).filter(([, v]) => v !== void 0))
|
|
137
|
+
} : fromStyle;
|
|
138
|
+
}
|
|
105
139
|
const visibleLine = line !== void 0 && line.fill !== "none";
|
|
106
|
-
if (!text &&
|
|
140
|
+
if (!text && styled.kind === "none" && !visibleLine) return void 0;
|
|
141
|
+
const xfrm = spPr ? poChildren(spPr).find((c) => poIs(c, "a:xfrm")) : void 0;
|
|
142
|
+
const spin = xfrm ? parseXfrm(xfrm) : void 0;
|
|
107
143
|
return {
|
|
108
144
|
float: floatAt(box),
|
|
109
145
|
width: emuToPt(box.cx),
|
|
110
146
|
height: emuToPt(box.cy),
|
|
111
147
|
geometry,
|
|
112
|
-
fill,
|
|
148
|
+
fill: styled,
|
|
113
149
|
...line ? { line } : {},
|
|
150
|
+
...spin && Object.keys(spin).length > 0 ? { transform: spin } : {},
|
|
114
151
|
...text ? { text } : {},
|
|
115
152
|
paragraphProperties: {}
|
|
116
153
|
};
|
|
@@ -139,10 +176,50 @@ function parseGraphicFrame(gf, ctx, transform) {
|
|
|
139
176
|
}
|
|
140
177
|
if (uri === TABLE_URI) {
|
|
141
178
|
const tbl = poFindDescendant(gf, "a:tbl");
|
|
142
|
-
|
|
179
|
+
if (!tbl) return [];
|
|
180
|
+
const table = parseTable(tbl, ctx.colors ?? defaultColorResolver, ctx.resolveTableStyle);
|
|
181
|
+
return [{
|
|
143
182
|
kind: "table",
|
|
144
|
-
table:
|
|
145
|
-
|
|
183
|
+
table: {
|
|
184
|
+
...table,
|
|
185
|
+
properties: {
|
|
186
|
+
...table.properties,
|
|
187
|
+
float: floatAt(box)
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}];
|
|
191
|
+
}
|
|
192
|
+
if (uri === OLE_URI) {
|
|
193
|
+
const oleObj = poFindDescendant(gf, "p:oleObj");
|
|
194
|
+
if (!oleObj) return [];
|
|
195
|
+
const pic = poChildren(oleObj).find((c) => poIs(c, "p:pic"));
|
|
196
|
+
if (pic) {
|
|
197
|
+
const image = parsePic(pic, ctx, transform);
|
|
198
|
+
return image ? [{
|
|
199
|
+
kind: "image",
|
|
200
|
+
image
|
|
201
|
+
}] : [];
|
|
202
|
+
}
|
|
203
|
+
const spid = poAttr(oleObj, "spid");
|
|
204
|
+
const resource = spid !== void 0 ? ctx.resolveOlePreview?.(spid) : void 0;
|
|
205
|
+
if (resource === void 0) {
|
|
206
|
+
ctx.onLoss?.({
|
|
207
|
+
severity: "dropped",
|
|
208
|
+
feature: FEATURES.images,
|
|
209
|
+
detail: "embedded object with no preview picture — the object is not drawn"
|
|
210
|
+
});
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
return [{
|
|
214
|
+
kind: "image",
|
|
215
|
+
image: {
|
|
216
|
+
float: floatAt(box),
|
|
217
|
+
resource,
|
|
218
|
+
width: emuToPt(box.cx),
|
|
219
|
+
height: emuToPt(box.cy),
|
|
220
|
+
paragraphProperties: {}
|
|
221
|
+
}
|
|
222
|
+
}];
|
|
146
223
|
}
|
|
147
224
|
if (uri === DIAGRAM_URI) {
|
|
148
225
|
const relIds = poFindDescendant(gf, "dgm:relIds");
|
|
@@ -152,7 +229,9 @@ function parseGraphicFrame(gf, ctx, transform) {
|
|
|
152
229
|
if (dmRelId !== void 0) ctx.onLoss?.(noDiagramOverrideLoss());
|
|
153
230
|
return [];
|
|
154
231
|
}
|
|
155
|
-
|
|
232
|
+
const drawn = parseDiagramDrawing(spTree, diagramTransform(spTree, box), floatAt, ctx.colors ?? defaultColorResolver, ctx.resolveHyperlink);
|
|
233
|
+
if (drawn.length === 0) ctx.onLoss?.(noDiagramOverrideLoss());
|
|
234
|
+
return drawn.map((shape) => ({
|
|
156
235
|
kind: "shape",
|
|
157
236
|
shape
|
|
158
237
|
}));
|
|
@@ -229,9 +308,9 @@ function parseDiagramNodes(spTree, transform, colors, resolveLink, resolveImage)
|
|
|
229
308
|
const box = transform(own);
|
|
230
309
|
const txBody = poChildren(sp).find((c) => poIs(c, "dsp:txBody"));
|
|
231
310
|
const parsed = txBody ? parseTxBody(txBody, void 0, void 0, colors, resolveLink) : void 0;
|
|
232
|
-
const text = parsed ? withDiagramFontColor(parsed, sp, colors) : void 0;
|
|
233
311
|
const geometry = parseGeometry(spPr);
|
|
234
312
|
const fill = spPr ? parseFill(spPr, colors, resolveImage) : { kind: "none" };
|
|
313
|
+
const text = parsed ? withDiagramFontColor(parsed, sp, colors, fill) : void 0;
|
|
235
314
|
const line = spPr ? parseLine(spPr, colors) : void 0;
|
|
236
315
|
const shadow = spPr ? parseShadow(spPr, colors) : void 0;
|
|
237
316
|
const visibleLine = line !== void 0 && line.fill !== "none";
|
|
@@ -287,12 +366,13 @@ function parseDiagramDrawing(spTree, transform, makeFloat, colors, resolveLink)
|
|
|
287
366
|
float: makeFloat(box)
|
|
288
367
|
}));
|
|
289
368
|
}
|
|
290
|
-
function withDiagramFontColor(text, sp, colors) {
|
|
369
|
+
function withDiagramFontColor(text, sp, colors, fill) {
|
|
291
370
|
const style = poChildren(sp).find((c) => poIs(c, "dsp:style"));
|
|
292
371
|
const ref = style ? poChildren(style).find((c) => poIs(c, "a:fontRef")) : void 0;
|
|
293
372
|
const child = ref ? poChildren(ref).find((c) => poTag(c) !== void 0) : void 0;
|
|
294
373
|
const colorHex = child ? resolveColorNode(child, colors) : void 0;
|
|
295
374
|
if (colorHex === void 0) return text;
|
|
375
|
+
if (fill.kind === "solid" && fill.colorHex === colorHex) return text;
|
|
296
376
|
return {
|
|
297
377
|
...text,
|
|
298
378
|
content: text.content.map((block) => block.kind === "paragraph" ? {
|
|
@@ -311,26 +391,45 @@ function withDiagramFontColor(text, sp, colors) {
|
|
|
311
391
|
};
|
|
312
392
|
}
|
|
313
393
|
/**
|
|
314
|
-
* `p:bg` → the background fill, or `undefined` when none
|
|
315
|
-
*
|
|
316
|
-
* `
|
|
317
|
-
*
|
|
394
|
+
* `p:bg` → the background fill, or `undefined` when it declares none.
|
|
395
|
+
*
|
|
396
|
+
* Two spellings. `p:bgPr` carries the fill itself — solid, gradient, or a
|
|
397
|
+
* PICTURE, which needs the owning part's image resolver since the blip's
|
|
398
|
+
* relationship is scoped to the part the background is written in. `p:bgRef`
|
|
399
|
+
* (§19.3.1.2) carries no fill at all: an index into the theme's style lists and
|
|
400
|
+
* the colour to put wherever that style says `phClr`. Read as its colour alone
|
|
401
|
+
* — which is all this did — a deck whose theme opens with a black-to-grey
|
|
402
|
+
* gradient came out flat, and one whose first background slot is a picture came
|
|
403
|
+
* out a single colour.
|
|
404
|
+
*
|
|
318
405
|
* Used for the slide's own background and the inherited layout/master one (PX5b).
|
|
406
|
+
*
|
|
407
|
+
* @param bg The `p:bg` node.
|
|
408
|
+
* @param colors The deck's colour resolver.
|
|
409
|
+
* @param resolveImage Resolver for a picture background's relationship, scoped
|
|
410
|
+
* to the part this `p:bg` is written in.
|
|
411
|
+
* @param theme The theme's fill style lists, for a `p:bgRef`.
|
|
319
412
|
*/
|
|
320
|
-
function parseBackgroundFill(bg, colors) {
|
|
413
|
+
function parseBackgroundFill(bg, colors, resolveImage, theme) {
|
|
321
414
|
const bgPr = poChildren(bg).find((c) => poIs(c, "p:bgPr"));
|
|
322
415
|
if (bgPr) {
|
|
323
|
-
const fill = parseFill(bgPr, colors);
|
|
416
|
+
const fill = parseFill(bgPr, colors, resolveImage);
|
|
324
417
|
return fill.kind !== "none" ? fill : void 0;
|
|
325
418
|
}
|
|
326
419
|
const bgRef = poChildren(bg).find((c) => poIs(c, "p:bgRef"));
|
|
327
|
-
if (bgRef)
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
420
|
+
if (!bgRef) return void 0;
|
|
421
|
+
const child = poChildren(bgRef).find((c) => poTag(c) !== void 0);
|
|
422
|
+
const hex = child ? resolveColorNode(child, colors) : void 0;
|
|
423
|
+
const idx = poIntAttr(bgRef, "idx");
|
|
424
|
+
const slot = idx === void 0 ? void 0 : idx > 1e3 ? theme?.backgrounds[idx - 1001] : theme?.fills[idx - 1];
|
|
425
|
+
if (slot) {
|
|
426
|
+
const themed = parseFill({ "a:spPr": [slot] }, hex === void 0 ? colors : placeholderColors(colors, hex), theme?.resolveImage ?? resolveImage);
|
|
427
|
+
if (themed.kind !== "none") return themed;
|
|
333
428
|
}
|
|
429
|
+
return hex === void 0 ? void 0 : {
|
|
430
|
+
kind: "solid",
|
|
431
|
+
colorHex: hex
|
|
432
|
+
};
|
|
334
433
|
}
|
|
335
434
|
/**
|
|
336
435
|
* A full-slide backdrop element for a background fill: a rectangle covering the
|
|
@@ -364,11 +463,73 @@ function backdropElement(fill, widthPt, heightPt) {
|
|
|
364
463
|
}
|
|
365
464
|
};
|
|
366
465
|
}
|
|
466
|
+
function backgroundThrough(bg, box, slide) {
|
|
467
|
+
if (!bg) return { kind: "none" };
|
|
468
|
+
if (bg.kind !== "picture" || !slide || box.cx <= 0 || box.cy <= 0) return bg;
|
|
469
|
+
const [x, y] = [emuToPt(box.x), emuToPt(box.y)];
|
|
470
|
+
const [w, h] = [emuToPt(box.cx), emuToPt(box.cy)];
|
|
471
|
+
return {
|
|
472
|
+
...bg,
|
|
473
|
+
imageFillRect: {
|
|
474
|
+
left: -x / w,
|
|
475
|
+
top: -y / h,
|
|
476
|
+
right: -(slide.widthPt - x - w) / w,
|
|
477
|
+
bottom: -(slide.heightPt - y - h) / h
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* The same element, painted BEHIND the slide's own content.
|
|
483
|
+
*
|
|
484
|
+
* §19.3.1 — a slide's shape tree is drawn over its layout's, and that over the
|
|
485
|
+
* master's; nothing a deck states once can bury what a slide puts on it. Our
|
|
486
|
+
* page paints by KIND (every image, then every shape), so without this a
|
|
487
|
+
* layout's white card landed on top of the photograph the slide is made of —
|
|
488
|
+
* themes.pptx's fifth slide is one picture and it vanished under the card.
|
|
489
|
+
*
|
|
490
|
+
* @param el The inherited element.
|
|
491
|
+
* @returns The element with its float sunk to the backdrop layer.
|
|
492
|
+
*/
|
|
493
|
+
function asBackdrop(el) {
|
|
494
|
+
const sink = (item) => item.float ? {
|
|
495
|
+
...item,
|
|
496
|
+
float: {
|
|
497
|
+
...item.float,
|
|
498
|
+
behind: true
|
|
499
|
+
}
|
|
500
|
+
} : item;
|
|
501
|
+
switch (el.kind) {
|
|
502
|
+
case "shape": return {
|
|
503
|
+
...el,
|
|
504
|
+
shape: sink(el.shape)
|
|
505
|
+
};
|
|
506
|
+
case "image": return {
|
|
507
|
+
...el,
|
|
508
|
+
image: sink(el.image)
|
|
509
|
+
};
|
|
510
|
+
case "table": return {
|
|
511
|
+
...el,
|
|
512
|
+
table: {
|
|
513
|
+
...el.table,
|
|
514
|
+
properties: sink(el.table.properties)
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
case "chart": return {
|
|
518
|
+
...el,
|
|
519
|
+
chart: sink(el.chart)
|
|
520
|
+
};
|
|
521
|
+
default: return el;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
367
524
|
/**
|
|
368
525
|
* `p:spPr` geometry: `a:prstGeom` (preset) or `a:custGeom` (custom path), default
|
|
369
526
|
* rect. Exported for sheet shapes (E-SHEET W2), whose `xdr:spPr` carries the same
|
|
370
527
|
* `a:` children.
|
|
371
528
|
*/
|
|
529
|
+
/** Whether an `spPr` states a geometry of its own, rather than inheriting one. */
|
|
530
|
+
function statesGeometry(spPr) {
|
|
531
|
+
return poChildren(spPr).some((c) => poIs(c, "a:prstGeom") || poIs(c, "a:custGeom"));
|
|
532
|
+
}
|
|
372
533
|
function parseGeometry(spPr) {
|
|
373
534
|
if (!spPr) return RECT_GEOMETRY;
|
|
374
535
|
const prst = poChildren(spPr).find((c) => poIs(c, "a:prstGeom"));
|
|
@@ -385,10 +546,16 @@ function parsePic(pic, ctx, transform) {
|
|
|
385
546
|
const blip = blipFill ? poChildren(blipFill).find((c) => poIs(c, "a:blip")) : void 0;
|
|
386
547
|
const relId = blip ? poAttr(blip, "embed") : void 0;
|
|
387
548
|
const resource = relId !== void 0 ? ctx.resolveImage?.(relId) : void 0;
|
|
549
|
+
const colorChange = blip ? colorChangeOf(blip, ctx.colors ?? defaultColorResolver) : void 0;
|
|
550
|
+
const fixed = blip ? poChildren(blip).find((c) => poIs(c, "a:alphaModFix")) : void 0;
|
|
551
|
+
const amt = fixed ? poIntAttr(fixed, "amt") : void 0;
|
|
552
|
+
const alpha = amt === void 0 ? void 0 : Math.min(1, Math.max(0, amt / 1e5));
|
|
388
553
|
const altText = picAltText(pic);
|
|
389
554
|
return {
|
|
390
555
|
float: floatAt(box),
|
|
391
556
|
...resource !== void 0 ? { resource } : {},
|
|
557
|
+
...colorChange ? { colorChange } : {},
|
|
558
|
+
...alpha !== void 0 && alpha < 1 ? { alpha } : {},
|
|
392
559
|
width: emuToPt(box.cx),
|
|
393
560
|
height: emuToPt(box.cy),
|
|
394
561
|
paragraphProperties: {},
|
|
@@ -402,14 +569,14 @@ function picAltText(pic) {
|
|
|
402
569
|
const title = cNvPr ? poAttr(cNvPr, "title") : void 0;
|
|
403
570
|
return (descr ?? title)?.trim() || void 0;
|
|
404
571
|
}
|
|
405
|
-
function txBodyParagraphs(txBody, ph, cascade, colors, resolveLink) {
|
|
572
|
+
function txBodyParagraphs(txBody, ph, cascade, colors, resolveLink, styleColor) {
|
|
406
573
|
const content = [];
|
|
407
574
|
const counters = [];
|
|
408
575
|
for (const child of poChildren(txBody)) {
|
|
409
576
|
if (!poIs(child, "a:p")) continue;
|
|
410
577
|
content.push({
|
|
411
578
|
kind: "paragraph",
|
|
412
|
-
paragraph: parseSlideParagraph(child, ph, cascade, colors, resolveLink, counters)
|
|
579
|
+
paragraph: parseSlideParagraph(child, ph, cascade, colors, resolveLink, counters, styleColor)
|
|
413
580
|
});
|
|
414
581
|
}
|
|
415
582
|
return content;
|
|
@@ -427,8 +594,8 @@ function txBodyParagraphs(txBody, ph, cascade, colors, resolveLink) {
|
|
|
427
594
|
* @param resolveLink A run hyperlink resolver, or `undefined`.
|
|
428
595
|
* @returns The text body, or `undefined` when it holds no paragraphs.
|
|
429
596
|
*/
|
|
430
|
-
function parseTxBody(txBody, ph, cascade, colors, resolveLink) {
|
|
431
|
-
const content = txBodyParagraphs(txBody, ph, cascade, colors, resolveLink);
|
|
597
|
+
function parseTxBody(txBody, ph, cascade, colors, resolveLink, styleColor) {
|
|
598
|
+
const content = txBodyParagraphs(txBody, ph, cascade, colors, resolveLink, styleColor);
|
|
432
599
|
if (content.length === 0) return void 0;
|
|
433
600
|
const bodyPr = poChildren(txBody).find((c) => poIs(c, "a:bodyPr"));
|
|
434
601
|
const lIns = bodyPr ? poIntAttr(bodyPr, "lIns") : void 0;
|
|
@@ -436,7 +603,7 @@ function parseTxBody(txBody, ph, cascade, colors, resolveLink) {
|
|
|
436
603
|
const rIns = bodyPr ? poIntAttr(bodyPr, "rIns") : void 0;
|
|
437
604
|
const bIns = bodyPr ? poIntAttr(bodyPr, "bIns") : void 0;
|
|
438
605
|
const a = bodyPr ? poAttr(bodyPr, "anchor") : void 0;
|
|
439
|
-
const anchor = a === "ctr"
|
|
606
|
+
const anchor = a === "ctr" || a === "b" || a === "t" ? a : ph && cascade ? cascade.anchorFor(ph) : void 0;
|
|
440
607
|
return {
|
|
441
608
|
content,
|
|
442
609
|
...lIns !== void 0 ? { insetLeft: emuToPt(lIns) } : {},
|
|
@@ -446,23 +613,38 @@ function parseTxBody(txBody, ph, cascade, colors, resolveLink) {
|
|
|
446
613
|
...anchor ? { anchor } : {}
|
|
447
614
|
};
|
|
448
615
|
}
|
|
449
|
-
function parseSlideParagraph(aP, ph, cascade, colors, resolveLink, counters) {
|
|
616
|
+
function parseSlideParagraph(aP, ph, cascade, colors, resolveLink, counters, styleColor) {
|
|
450
617
|
const pPr = poChildren(aP).find((c) => poIs(c, "a:pPr"));
|
|
451
618
|
const level = (pPr ? poIntAttr(pPr, "lvl") : void 0) ?? 0;
|
|
452
|
-
const defaults =
|
|
619
|
+
const defaults = {
|
|
620
|
+
...cascade ? cascade.defaultsFor(ph, level) : {},
|
|
621
|
+
...styleColor !== void 0 ? { colorHex: styleColor } : {}
|
|
622
|
+
};
|
|
623
|
+
const inherited = cascade ? cascade.paragraphDefaultsFor(ph, level) : {};
|
|
453
624
|
const algn = pPr ? poAttr(pPr, "algn") : void 0;
|
|
454
625
|
const alignment = algn !== void 0 ? ALGN_TO_ALIGNMENT[algn] : void 0;
|
|
455
626
|
const runs = [];
|
|
456
|
-
const marker = bulletMarker(pPr, level, counters);
|
|
457
|
-
if (marker !== void 0) runs.push({
|
|
458
|
-
text: marker,
|
|
459
|
-
properties: defaults,
|
|
460
|
-
listMarker: true
|
|
461
|
-
});
|
|
462
627
|
for (const child of poChildren(aP)) if (poIs(child, "a:r") || poIs(child, "a:fld")) {
|
|
463
628
|
const run = parseSlideRun(child, defaults, colors, resolveLink);
|
|
464
629
|
if (run) runs.push(run);
|
|
465
630
|
}
|
|
631
|
+
const marL = pPr ? poIntAttr(pPr, "marL") : void 0;
|
|
632
|
+
const indent = pPr ? poIntAttr(pPr, "indent") : void 0;
|
|
633
|
+
const indentLeft = marL !== void 0 ? emuToPt(marL) : level > 0 ? emuToPt(level * 457200) : void 0;
|
|
634
|
+
const hanging = (indent !== void 0 ? emuToPt(indent) : inherited.indentFirstLine ?? 0) < 0;
|
|
635
|
+
const bullet = {
|
|
636
|
+
...cascade?.bulletFor(ph, level),
|
|
637
|
+
...parseBullet(pPr, colors)
|
|
638
|
+
};
|
|
639
|
+
const marker = bulletMarker(bullet, level, counters);
|
|
640
|
+
if (marker !== void 0) {
|
|
641
|
+
const base = runs[0]?.properties ?? defaults;
|
|
642
|
+
runs.unshift({
|
|
643
|
+
text: marker + (hanging ? " " : " "),
|
|
644
|
+
properties: bulletProps(base, bullet),
|
|
645
|
+
listMarker: true
|
|
646
|
+
});
|
|
647
|
+
}
|
|
466
648
|
if (runs.length === 0) {
|
|
467
649
|
const endRPr = poChildren(aP).find((c) => poIs(c, "a:endParaRPr"));
|
|
468
650
|
const sz = endRPr ? poIntAttr(endRPr, "sz") : void 0;
|
|
@@ -474,11 +656,9 @@ function parseSlideParagraph(aP, ph, cascade, colors, resolveLink, counters) {
|
|
|
474
656
|
}
|
|
475
657
|
});
|
|
476
658
|
}
|
|
477
|
-
const marL = pPr ? poIntAttr(pPr, "marL") : void 0;
|
|
478
|
-
const indent = pPr ? poIntAttr(pPr, "indent") : void 0;
|
|
479
|
-
const indentLeft = marL !== void 0 ? emuToPt(marL) : level > 0 ? emuToPt(level * 457200) : void 0;
|
|
480
659
|
return {
|
|
481
660
|
properties: {
|
|
661
|
+
...inherited,
|
|
482
662
|
...alignment ? { alignment } : {},
|
|
483
663
|
...indentLeft !== void 0 ? { indentLeft } : {},
|
|
484
664
|
...indent !== void 0 ? { indentFirstLine: emuToPt(indent) } : {}
|
|
@@ -486,20 +666,22 @@ function parseSlideParagraph(aP, ph, cascade, colors, resolveLink, counters) {
|
|
|
486
666
|
runs
|
|
487
667
|
};
|
|
488
668
|
}
|
|
489
|
-
function
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
669
|
+
function bulletProps(base, bullet) {
|
|
670
|
+
const sizePt = bullet.sizePts ?? (bullet.sizePct !== void 0 && base.fontSizePt !== void 0 ? base.fontSizePt * bullet.sizePct : void 0);
|
|
671
|
+
return {
|
|
672
|
+
...base,
|
|
673
|
+
...sizePt !== void 0 ? { fontSizePt: pt(sizePt) } : {},
|
|
674
|
+
...bullet.colorHex !== void 0 ? { colorHex: bullet.colorHex } : {}
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
function bulletMarker(bullet, level, counters) {
|
|
678
|
+
if (!bullet || bullet.kind === "none" || bullet.kind === void 0) return void 0;
|
|
679
|
+
if (bullet.kind === "char") return bullet.char ?? "•";
|
|
498
680
|
const prev = counters[level];
|
|
499
|
-
const n = (prev === void 0 ? startAt - 1 : prev) + 1;
|
|
681
|
+
const n = (prev === void 0 ? (bullet.startAt ?? 1) - 1 : prev) + 1;
|
|
500
682
|
counters[level] = n;
|
|
501
683
|
counters.length = level + 1;
|
|
502
|
-
return `${n}${autoNumSuffix(type)}
|
|
684
|
+
return `${n}${autoNumSuffix(bullet.type ?? "arabicPeriod")}`;
|
|
503
685
|
}
|
|
504
686
|
function autoNumSuffix(type) {
|
|
505
687
|
if (type.endsWith("ParenR") || type.endsWith("ParenBoth")) return ")";
|
|
@@ -523,31 +705,57 @@ function parseSlideRun(node, defaults, colors, resolveLink) {
|
|
|
523
705
|
...href ? { href } : {}
|
|
524
706
|
};
|
|
525
707
|
}
|
|
526
|
-
function parseTable(tbl, colors) {
|
|
708
|
+
function parseTable(tbl, colors, resolveTableStyle) {
|
|
527
709
|
const grid = [];
|
|
528
710
|
const tblGrid = poChildren(tbl).find((c) => poIs(c, "a:tblGrid"));
|
|
529
711
|
if (tblGrid) {
|
|
530
712
|
for (const col of poChildren(tblGrid)) if (poIs(col, "a:gridCol")) grid.push(emuToPt(poIntAttr(col, "w") ?? 0));
|
|
531
713
|
}
|
|
532
714
|
const rows = [];
|
|
533
|
-
|
|
534
|
-
|
|
715
|
+
const sources = [];
|
|
716
|
+
for (const tr of poChildren(tbl)) {
|
|
717
|
+
if (!poIs(tr, "a:tr")) continue;
|
|
718
|
+
const cells = rowCells(tr);
|
|
719
|
+
sources.push(cells);
|
|
720
|
+
rows.push(parseTableRow(tr, cells, colors));
|
|
721
|
+
}
|
|
722
|
+
const tblPr = poChildren(tbl).find((c) => poIs(c, "a:tblPr"));
|
|
723
|
+
const style = resolveTableStyle?.(tableStyleId(tblPr));
|
|
724
|
+
if (!style) return {
|
|
535
725
|
properties: {},
|
|
536
726
|
grid,
|
|
537
727
|
rows
|
|
538
728
|
};
|
|
729
|
+
const flags = tableStyleFlags(tblPr);
|
|
730
|
+
return {
|
|
731
|
+
properties: {},
|
|
732
|
+
grid,
|
|
733
|
+
rows: rows.map((row, r) => ({
|
|
734
|
+
...row,
|
|
735
|
+
cells: row.cells.map((cell, c) => {
|
|
736
|
+
const part = cellStyle(style, flags, {
|
|
737
|
+
row: r,
|
|
738
|
+
rowCount: rows.length,
|
|
739
|
+
col: c,
|
|
740
|
+
colCount: grid.length
|
|
741
|
+
}, colors);
|
|
742
|
+
const tc = sources[r]?.[c];
|
|
743
|
+
return withCellStyle(cell, tc && cellSaysNoFill(tc) ? withoutFill(part) : part);
|
|
744
|
+
})
|
|
745
|
+
}))
|
|
746
|
+
};
|
|
539
747
|
}
|
|
540
|
-
function
|
|
748
|
+
function rowCells(tr) {
|
|
749
|
+
return poChildren(tr).filter((tc) => poIs(tc, "a:tc") && poAttr(tc, "hMerge") !== "1");
|
|
750
|
+
}
|
|
751
|
+
function parseTableRow(tr, cells, colors) {
|
|
541
752
|
const h = poIntAttr(tr, "h");
|
|
542
|
-
const cells = [];
|
|
543
|
-
for (const tc of poChildren(tr)) {
|
|
544
|
-
if (!poIs(tc, "a:tc")) continue;
|
|
545
|
-
if (poAttr(tc, "hMerge") === "1") continue;
|
|
546
|
-
cells.push(parseTableCell(tc, colors));
|
|
547
|
-
}
|
|
548
753
|
return {
|
|
549
|
-
properties: { ...h !== void 0 ? {
|
|
550
|
-
|
|
754
|
+
properties: { ...h !== void 0 ? {
|
|
755
|
+
height: emuToPt(h),
|
|
756
|
+
heightRule: "atLeast"
|
|
757
|
+
} : {} },
|
|
758
|
+
cells: cells.map((tc) => parseTableCell(tc, colors))
|
|
551
759
|
};
|
|
552
760
|
}
|
|
553
761
|
function parseTableCell(tc, colors) {
|
|
@@ -558,15 +766,35 @@ function parseTableCell(tc, colors) {
|
|
|
558
766
|
const merge = rowSpan !== void 0 && rowSpan > 1 ? "start" : poAttr(tc, "vMerge") === "1" ? "middle" : void 0;
|
|
559
767
|
const tcPr = poChildren(tc).find((c) => poIs(c, "a:tcPr"));
|
|
560
768
|
const shadingHex = tcPr ? cellFillHex(tcPr, colors) : void 0;
|
|
769
|
+
const borders = tcPr ? cellOwnBorders(tcPr, colors) : void 0;
|
|
561
770
|
return {
|
|
562
771
|
properties: {
|
|
563
772
|
...gridSpan !== void 0 && gridSpan > 1 ? { colSpan: gridSpan } : {},
|
|
564
773
|
...merge ? { merge } : {},
|
|
565
|
-
...shadingHex ? { shading: { colorHex: shadingHex } } : {}
|
|
774
|
+
...shadingHex ? { shading: { colorHex: shadingHex } } : {},
|
|
775
|
+
...borders ? { borders } : {}
|
|
566
776
|
},
|
|
567
777
|
content
|
|
568
778
|
};
|
|
569
779
|
}
|
|
780
|
+
var CELL_LINES = [
|
|
781
|
+
["a:lnL", "left"],
|
|
782
|
+
["a:lnR", "right"],
|
|
783
|
+
["a:lnT", "top"],
|
|
784
|
+
["a:lnB", "bottom"]
|
|
785
|
+
];
|
|
786
|
+
function cellOwnBorders(tcPr, colors) {
|
|
787
|
+
const out = {};
|
|
788
|
+
for (const [tag, side] of CELL_LINES) {
|
|
789
|
+
const ln = poChildren(tcPr).find((c) => poIs(c, tag));
|
|
790
|
+
if (ln) out[side] = lineBorder(ln, colors);
|
|
791
|
+
}
|
|
792
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
793
|
+
}
|
|
794
|
+
function cellSaysNoFill(tc) {
|
|
795
|
+
const tcPr = poChildren(tc).find((c) => poIs(c, "a:tcPr"));
|
|
796
|
+
return tcPr !== void 0 && poChildren(tcPr).some((c) => poIs(c, "a:noFill"));
|
|
797
|
+
}
|
|
570
798
|
function cellFillHex(tcPr, colors) {
|
|
571
799
|
const solidFill = poChildren(tcPr).find((c) => poIs(c, "a:solidFill"));
|
|
572
800
|
if (!solidFill) return void 0;
|
|
@@ -576,4 +804,4 @@ function cellFillHex(tcPr, colors) {
|
|
|
576
804
|
}
|
|
577
805
|
}
|
|
578
806
|
//#endregion
|
|
579
|
-
export { backdropElement, diagramTransform, noDiagramOverrideLoss, parseBackgroundFill, parseDiagramNodes, parseGeometry, parseSlideShapes, parseTxBody };
|
|
807
|
+
export { asBackdrop, backdropElement, diagramTransform, noDiagramOverrideLoss, parseBackgroundFill, parseDiagramNodes, parseGeometry, parseSlideShapes, parseTxBody };
|
|
@@ -61,14 +61,29 @@ function rPrToRunProps(rPr, colors) {
|
|
|
61
61
|
const colorHex = solidFillColor(rPr, colors);
|
|
62
62
|
const latin = poChildren(rPr).find((c) => poIs(c, "a:latin"));
|
|
63
63
|
const typeface = latin ? poAttr(latin, "typeface")?.trim() : void 0;
|
|
64
|
+
const flag = (name) => {
|
|
65
|
+
const v = poAttr(rPr, name);
|
|
66
|
+
return v === void 0 ? void 0 : isTrue(v);
|
|
67
|
+
};
|
|
68
|
+
const [b, i] = [flag("b"), flag("i")];
|
|
64
69
|
return {
|
|
65
|
-
...
|
|
66
|
-
...
|
|
67
|
-
...u !== void 0
|
|
70
|
+
...b !== void 0 ? { bold: b } : {},
|
|
71
|
+
...i !== void 0 ? { italic: i } : {},
|
|
72
|
+
...u !== void 0 ? { underline: u === "none" ? "none" : "single" } : {},
|
|
68
73
|
...sz !== void 0 ? { fontSizePt: pt(sz / 100) } : {},
|
|
69
74
|
...colorHex ? { colorHex } : {},
|
|
70
|
-
...typeface ? { fontFamily: { ascii: typeface } } : {}
|
|
75
|
+
...typeface ? { fontFamily: { ascii: typeface } } : {},
|
|
76
|
+
...capsOf(poAttr(rPr, "cap"))
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function capsOf(cap) {
|
|
80
|
+
if (cap === "all") return { caps: true };
|
|
81
|
+
if (cap === "small") return { smallCaps: true };
|
|
82
|
+
if (cap === "none") return {
|
|
83
|
+
caps: false,
|
|
84
|
+
smallCaps: false
|
|
71
85
|
};
|
|
86
|
+
return {};
|
|
72
87
|
}
|
|
73
88
|
function solidFillColor(rPr, colors) {
|
|
74
89
|
const solidFill = poChildren(rPr).find((c) => poIs(c, "a:solidFill"));
|