reamkit 1.21.0 → 1.23.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/converter/ream.d.ts +16 -0
- package/dist/esm/core/converter/ream.js +59 -9
- package/dist/esm/core/document-model/types.d.ts +78 -0
- package/dist/esm/core/drawingml/chart-geometry.js +11 -5
- 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 +30 -4
- package/dist/esm/core/drawingml/colors.js +45 -6
- package/dist/esm/core/drawingml/preset-geometry.js +236 -0
- package/dist/esm/core/drawingml/theme-parser.d.ts +38 -0
- package/dist/esm/core/drawingml/theme-parser.js +64 -1
- package/dist/esm/core/fonts/families.d.ts +10 -0
- package/dist/esm/core/fonts/families.js +44 -0
- package/dist/esm/core/fonts/index.d.ts +3 -2
- package/dist/esm/core/fonts/remote-fonts.d.ts +50 -0
- package/dist/esm/core/fonts/remote-fonts.js +114 -8
- package/dist/esm/core/fonts/scripts.d.ts +26 -0
- package/dist/esm/core/fonts/scripts.js +177 -0
- package/dist/esm/core/metafile/blit.d.ts +33 -0
- package/dist/esm/core/metafile/blit.js +67 -0
- package/dist/esm/core/metafile/dib.d.ts +61 -0
- package/dist/esm/core/metafile/dib.js +205 -0
- package/dist/esm/core/metafile/emf.js +139 -24
- package/dist/esm/core/metafile/picture.d.ts +12 -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 +183 -10
- package/dist/esm/core/ole/escher-blip.d.ts +12 -0
- package/dist/esm/core/ole/escher-blip.js +88 -0
- package/dist/esm/{pdf-reader → core}/png-encode.js +1 -1
- package/dist/esm/core/vector.d.ts +5 -0
- package/dist/esm/excel/print-model.js +3 -1
- package/dist/esm/excel/sheet-shape-parser.js +1 -12
- package/dist/esm/excel/styles-parser.js +1 -1
- package/dist/esm/excel/xls/biff-reader.js +53 -18
- package/dist/esm/excel/xls/biff-styles.d.ts +5 -2
- package/dist/esm/excel/xls/biff-styles.js +9 -7
- package/dist/esm/excel/xls/escher.js +90 -24
- package/dist/esm/excel/xlsx-reader.d.ts +1 -1
- package/dist/esm/excel/xlsx-reader.js +3 -3
- package/dist/esm/layout/page-doc.d.ts +77 -0
- package/dist/esm/layout/page-doc.js +34 -18
- package/dist/esm/layout/styled-layout.d.ts +2 -2
- package/dist/esm/layout/styled-layout.js +467 -76
- 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 +647 -444
- package/dist/esm/pdf-reader/image-decode.js +1 -1
- package/dist/esm/pptx/embedded-fonts.d.ts +31 -0
- package/dist/esm/pptx/embedded-fonts.js +104 -0
- 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 +136 -5
- package/dist/esm/pptx/placeholder-cascade.js +260 -27
- package/dist/esm/pptx/ppt/ppt-reader.js +120 -10
- package/dist/esm/pptx/ppt/ppt-text.d.ts +66 -1
- package/dist/esm/pptx/ppt/ppt-text.js +576 -137
- package/dist/esm/pptx/pptx-reader.d.ts +8 -0
- package/dist/esm/pptx/pptx-reader.js +271 -41
- package/dist/esm/pptx/preset-table-styles.d.ts +9 -0
- package/dist/esm/pptx/preset-table-styles.js +27 -0
- package/dist/esm/pptx/slide-parser.d.ts +78 -10
- package/dist/esm/pptx/slide-parser.js +396 -95
- package/dist/esm/pptx/sp-helpers.d.ts +2 -1
- package/dist/esm/pptx/sp-helpers.js +22 -6
- package/dist/esm/pptx/table-style.d.ts +64 -0
- package/dist/esm/pptx/table-style.js +203 -0
- package/dist/esm/svg/svg-writer.js +53 -5
- package/dist/esm/word/document-parser.d.ts +7 -1
- package/dist/esm/word/document-parser.js +6 -6
- package/dist/esm/word/docx-reader.js +8 -5
- package/dist/esm/word/docx-to-pdf.d.ts +8 -7
- package/dist/esm/word/docx-to-pdf.js +25 -7
- package/dist/esm/word/drawing-parser.d.ts +34 -0
- package/dist/esm/word/drawing-parser.js +173 -15
- package/dist/esm/word/numbering-parser.d.ts +2 -1
- package/dist/esm/word/numbering-parser.js +6 -6
- package/dist/esm/word/paragraph-properties.d.ts +2 -1
- package/dist/esm/word/paragraph-properties.js +2 -2
- package/dist/esm/word/run-properties.d.ts +5 -2
- package/dist/esm/word/run-properties.js +13 -8
- package/dist/esm/word/styles-parser.d.ts +2 -1
- package/dist/esm/word/styles-parser.js +12 -12
- package/dist/esm/word/table-parser.js +3 -3
- package/dist/esm/word/theme-fonts.d.ts +10 -0
- package/dist/esm/word/theme-fonts.js +28 -0
- package/package.json +1 -1
- /package/dist/esm/{pdf-reader → core}/png-encode.d.ts +0 -0
|
@@ -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 { lineSpacing, parseBullet, spacingFractions, spacingFromLineFraction } 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,50 @@ 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, ctx.themeFonts) : void 0;
|
|
120
|
+
const protos = ph && ctx.cascade ? ctx.cascade.shapePropsFor(ph) : [];
|
|
121
|
+
const from = (states) => spPr && states(spPr) ? spPr : protos.find(states) ?? spPr;
|
|
122
|
+
/** What the shape states ITSELF, before anything is inherited. */
|
|
123
|
+
const stated = (states) => spPr && states(spPr) ? spPr : void 0;
|
|
124
|
+
/** …and what a prototype lends it, nearest first. */
|
|
125
|
+
const lent = (states) => protos.find(states);
|
|
126
|
+
const geometry = parseGeometry(from(statesGeometry));
|
|
127
|
+
const useBgFill = poAttr(sp, "useBgFill") === "1";
|
|
128
|
+
const themeStyles = ctx.themeFills ? {
|
|
129
|
+
fills: ctx.themeFills.fills,
|
|
130
|
+
bgFills: ctx.themeFills.backgrounds
|
|
131
|
+
} : void 0;
|
|
132
|
+
const ownFill = stated(statesFill);
|
|
133
|
+
const styleFill = style ? styleRefFill(style, colors, themeStyles) : void 0;
|
|
134
|
+
const lentFill = lent(statesFill);
|
|
135
|
+
const styled = useBgFill ? backgroundThrough(ctx.backgroundFill, box, ctx.slideSize) : ownFill ? parseFill(ownFill, colors, ctx.resolveImage) : styleFill && styleFill.kind !== "none" ? styleFill : lentFill ? parseFill(lentFill, colors, ctx.resolveImage) : spPr ? parseFill(spPr, colors, ctx.resolveImage) : { kind: "none" };
|
|
136
|
+
const lineFrom = from((n) => poChildren(n).some((c) => poIs(c, "a:ln")));
|
|
137
|
+
let line = lineFrom ? parseLine(lineFrom, colors) : void 0;
|
|
138
|
+
if (style) {
|
|
139
|
+
const fromStyle = styleRefLine(style, colors, ctx.themeLineWidths);
|
|
140
|
+
if (fromStyle) line = line ? {
|
|
141
|
+
...fromStyle,
|
|
142
|
+
...Object.fromEntries(Object.entries(line).filter(([, v]) => v !== void 0))
|
|
143
|
+
} : fromStyle;
|
|
144
|
+
}
|
|
145
|
+
const shadowFrom = from((n) => poChildren(n).some((c) => poIs(c, "a:effectLst")));
|
|
146
|
+
const shadow = shadowFrom ? parseShadow(shadowFrom, colors) : void 0;
|
|
105
147
|
const visibleLine = line !== void 0 && line.fill !== "none";
|
|
106
|
-
if (!text &&
|
|
148
|
+
if (!text && styled.kind === "none" && !visibleLine) return void 0;
|
|
149
|
+
const xfrm = spPr ? poChildren(spPr).find((c) => poIs(c, "a:xfrm")) : void 0;
|
|
150
|
+
const spin = xfrm ? parseXfrm(xfrm) : void 0;
|
|
107
151
|
return {
|
|
108
152
|
float: floatAt(box),
|
|
109
153
|
width: emuToPt(box.cx),
|
|
110
154
|
height: emuToPt(box.cy),
|
|
111
155
|
geometry,
|
|
112
|
-
fill,
|
|
156
|
+
fill: styled,
|
|
113
157
|
...line ? { line } : {},
|
|
158
|
+
...shadow ? { shadow } : {},
|
|
159
|
+
...spin && Object.keys(spin).length > 0 ? { transform: spin } : {},
|
|
114
160
|
...text ? { text } : {},
|
|
115
161
|
paragraphProperties: {}
|
|
116
162
|
};
|
|
@@ -139,10 +185,53 @@ function parseGraphicFrame(gf, ctx, transform) {
|
|
|
139
185
|
}
|
|
140
186
|
if (uri === TABLE_URI) {
|
|
141
187
|
const tbl = poFindDescendant(gf, "a:tbl");
|
|
142
|
-
|
|
188
|
+
if (!tbl) return [];
|
|
189
|
+
const table = parseTable(tbl, ctx.colors ?? defaultColorResolver, ctx.resolveTableStyle, {
|
|
190
|
+
...ctx.themeFills ? { fills: ctx.themeFills.fills } : {},
|
|
191
|
+
...ctx.themeLineWidths ? { lineWidths: ctx.themeLineWidths } : {}
|
|
192
|
+
});
|
|
193
|
+
return [{
|
|
143
194
|
kind: "table",
|
|
144
|
-
table:
|
|
145
|
-
|
|
195
|
+
table: {
|
|
196
|
+
...table,
|
|
197
|
+
properties: {
|
|
198
|
+
...table.properties,
|
|
199
|
+
float: floatAt(box)
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}];
|
|
203
|
+
}
|
|
204
|
+
if (uri === OLE_URI) {
|
|
205
|
+
const oleObj = poFindDescendant(gf, "p:oleObj");
|
|
206
|
+
if (!oleObj) return [];
|
|
207
|
+
const pic = poChildren(oleObj).find((c) => poIs(c, "p:pic"));
|
|
208
|
+
if (pic) {
|
|
209
|
+
const image = parsePic(pic, ctx, transform);
|
|
210
|
+
return image ? [{
|
|
211
|
+
kind: "image",
|
|
212
|
+
image
|
|
213
|
+
}] : [];
|
|
214
|
+
}
|
|
215
|
+
const spid = poAttr(oleObj, "spid");
|
|
216
|
+
const resource = spid !== void 0 ? ctx.resolveOlePreview?.(spid) : void 0;
|
|
217
|
+
if (resource === void 0) {
|
|
218
|
+
ctx.onLoss?.({
|
|
219
|
+
severity: "dropped",
|
|
220
|
+
feature: FEATURES.images,
|
|
221
|
+
detail: "embedded object with no preview picture — the object is not drawn"
|
|
222
|
+
});
|
|
223
|
+
return [];
|
|
224
|
+
}
|
|
225
|
+
return [{
|
|
226
|
+
kind: "image",
|
|
227
|
+
image: {
|
|
228
|
+
float: floatAt(box),
|
|
229
|
+
resource,
|
|
230
|
+
width: emuToPt(box.cx),
|
|
231
|
+
height: emuToPt(box.cy),
|
|
232
|
+
paragraphProperties: {}
|
|
233
|
+
}
|
|
234
|
+
}];
|
|
146
235
|
}
|
|
147
236
|
if (uri === DIAGRAM_URI) {
|
|
148
237
|
const relIds = poFindDescendant(gf, "dgm:relIds");
|
|
@@ -152,7 +241,9 @@ function parseGraphicFrame(gf, ctx, transform) {
|
|
|
152
241
|
if (dmRelId !== void 0) ctx.onLoss?.(noDiagramOverrideLoss());
|
|
153
242
|
return [];
|
|
154
243
|
}
|
|
155
|
-
|
|
244
|
+
const drawn = parseDiagramDrawing(spTree, diagramTransform(spTree, box), floatAt, ctx.colors ?? defaultColorResolver, ctx.resolveHyperlink);
|
|
245
|
+
if (drawn.length === 0) ctx.onLoss?.(noDiagramOverrideLoss());
|
|
246
|
+
return drawn.map((shape) => ({
|
|
156
247
|
kind: "shape",
|
|
157
248
|
shape
|
|
158
249
|
}));
|
|
@@ -229,9 +320,9 @@ function parseDiagramNodes(spTree, transform, colors, resolveLink, resolveImage)
|
|
|
229
320
|
const box = transform(own);
|
|
230
321
|
const txBody = poChildren(sp).find((c) => poIs(c, "dsp:txBody"));
|
|
231
322
|
const parsed = txBody ? parseTxBody(txBody, void 0, void 0, colors, resolveLink) : void 0;
|
|
232
|
-
const text = parsed ? withDiagramFontColor(parsed, sp, colors) : void 0;
|
|
233
323
|
const geometry = parseGeometry(spPr);
|
|
234
324
|
const fill = spPr ? parseFill(spPr, colors, resolveImage) : { kind: "none" };
|
|
325
|
+
const text = parsed ? withDiagramFontColor(parsed, sp, colors, fill) : void 0;
|
|
235
326
|
const line = spPr ? parseLine(spPr, colors) : void 0;
|
|
236
327
|
const shadow = spPr ? parseShadow(spPr, colors) : void 0;
|
|
237
328
|
const visibleLine = line !== void 0 && line.fill !== "none";
|
|
@@ -287,12 +378,13 @@ function parseDiagramDrawing(spTree, transform, makeFloat, colors, resolveLink)
|
|
|
287
378
|
float: makeFloat(box)
|
|
288
379
|
}));
|
|
289
380
|
}
|
|
290
|
-
function withDiagramFontColor(text, sp, colors) {
|
|
381
|
+
function withDiagramFontColor(text, sp, colors, fill) {
|
|
291
382
|
const style = poChildren(sp).find((c) => poIs(c, "dsp:style"));
|
|
292
383
|
const ref = style ? poChildren(style).find((c) => poIs(c, "a:fontRef")) : void 0;
|
|
293
384
|
const child = ref ? poChildren(ref).find((c) => poTag(c) !== void 0) : void 0;
|
|
294
385
|
const colorHex = child ? resolveColorNode(child, colors) : void 0;
|
|
295
386
|
if (colorHex === void 0) return text;
|
|
387
|
+
if (fill.kind === "solid" && fill.colorHex === colorHex) return text;
|
|
296
388
|
return {
|
|
297
389
|
...text,
|
|
298
390
|
content: text.content.map((block) => block.kind === "paragraph" ? {
|
|
@@ -311,26 +403,45 @@ function withDiagramFontColor(text, sp, colors) {
|
|
|
311
403
|
};
|
|
312
404
|
}
|
|
313
405
|
/**
|
|
314
|
-
* `p:bg` → the background fill, or `undefined` when none
|
|
315
|
-
*
|
|
316
|
-
* `
|
|
317
|
-
*
|
|
406
|
+
* `p:bg` → the background fill, or `undefined` when it declares none.
|
|
407
|
+
*
|
|
408
|
+
* Two spellings. `p:bgPr` carries the fill itself — solid, gradient, or a
|
|
409
|
+
* PICTURE, which needs the owning part's image resolver since the blip's
|
|
410
|
+
* relationship is scoped to the part the background is written in. `p:bgRef`
|
|
411
|
+
* (§19.3.1.2) carries no fill at all: an index into the theme's style lists and
|
|
412
|
+
* the colour to put wherever that style says `phClr`. Read as its colour alone
|
|
413
|
+
* — which is all this did — a deck whose theme opens with a black-to-grey
|
|
414
|
+
* gradient came out flat, and one whose first background slot is a picture came
|
|
415
|
+
* out a single colour.
|
|
416
|
+
*
|
|
318
417
|
* Used for the slide's own background and the inherited layout/master one (PX5b).
|
|
418
|
+
*
|
|
419
|
+
* @param bg The `p:bg` node.
|
|
420
|
+
* @param colors The deck's colour resolver.
|
|
421
|
+
* @param resolveImage Resolver for a picture background's relationship, scoped
|
|
422
|
+
* to the part this `p:bg` is written in.
|
|
423
|
+
* @param theme The theme's fill style lists, for a `p:bgRef`.
|
|
319
424
|
*/
|
|
320
|
-
function parseBackgroundFill(bg, colors) {
|
|
425
|
+
function parseBackgroundFill(bg, colors, resolveImage, theme) {
|
|
321
426
|
const bgPr = poChildren(bg).find((c) => poIs(c, "p:bgPr"));
|
|
322
427
|
if (bgPr) {
|
|
323
|
-
const fill = parseFill(bgPr, colors);
|
|
428
|
+
const fill = parseFill(bgPr, colors, resolveImage);
|
|
324
429
|
return fill.kind !== "none" ? fill : void 0;
|
|
325
430
|
}
|
|
326
431
|
const bgRef = poChildren(bg).find((c) => poIs(c, "p:bgRef"));
|
|
327
|
-
if (bgRef)
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
432
|
+
if (!bgRef) return void 0;
|
|
433
|
+
const child = poChildren(bgRef).find((c) => poTag(c) !== void 0);
|
|
434
|
+
const hex = child ? resolveColorNode(child, colors) : void 0;
|
|
435
|
+
const idx = poIntAttr(bgRef, "idx");
|
|
436
|
+
const slot = idx === void 0 ? void 0 : idx > 1e3 ? theme?.backgrounds[idx - 1001] : theme?.fills[idx - 1];
|
|
437
|
+
if (slot) {
|
|
438
|
+
const themed = parseFill({ "a:spPr": [slot] }, hex === void 0 ? colors : placeholderColors(colors, hex), theme?.resolveImage ?? resolveImage);
|
|
439
|
+
if (themed.kind !== "none") return themed;
|
|
333
440
|
}
|
|
441
|
+
return hex === void 0 ? void 0 : {
|
|
442
|
+
kind: "solid",
|
|
443
|
+
colorHex: hex
|
|
444
|
+
};
|
|
334
445
|
}
|
|
335
446
|
/**
|
|
336
447
|
* A full-slide backdrop element for a background fill: a rectangle covering the
|
|
@@ -364,11 +475,73 @@ function backdropElement(fill, widthPt, heightPt) {
|
|
|
364
475
|
}
|
|
365
476
|
};
|
|
366
477
|
}
|
|
478
|
+
function backgroundThrough(bg, box, slide) {
|
|
479
|
+
if (!bg) return { kind: "none" };
|
|
480
|
+
if (bg.kind !== "picture" || !slide || box.cx <= 0 || box.cy <= 0) return bg;
|
|
481
|
+
const [x, y] = [emuToPt(box.x), emuToPt(box.y)];
|
|
482
|
+
const [w, h] = [emuToPt(box.cx), emuToPt(box.cy)];
|
|
483
|
+
return {
|
|
484
|
+
...bg,
|
|
485
|
+
imageFillRect: {
|
|
486
|
+
left: -x / w,
|
|
487
|
+
top: -y / h,
|
|
488
|
+
right: -(slide.widthPt - x - w) / w,
|
|
489
|
+
bottom: -(slide.heightPt - y - h) / h
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* The same element, painted BEHIND the slide's own content.
|
|
495
|
+
*
|
|
496
|
+
* §19.3.1 — a slide's shape tree is drawn over its layout's, and that over the
|
|
497
|
+
* master's; nothing a deck states once can bury what a slide puts on it. Our
|
|
498
|
+
* page paints by KIND (every image, then every shape), so without this a
|
|
499
|
+
* layout's white card landed on top of the photograph the slide is made of —
|
|
500
|
+
* themes.pptx's fifth slide is one picture and it vanished under the card.
|
|
501
|
+
*
|
|
502
|
+
* @param el The inherited element.
|
|
503
|
+
* @returns The element with its float sunk to the backdrop layer.
|
|
504
|
+
*/
|
|
505
|
+
function asBackdrop(el) {
|
|
506
|
+
const sink = (item) => item.float ? {
|
|
507
|
+
...item,
|
|
508
|
+
float: {
|
|
509
|
+
...item.float,
|
|
510
|
+
behind: true
|
|
511
|
+
}
|
|
512
|
+
} : item;
|
|
513
|
+
switch (el.kind) {
|
|
514
|
+
case "shape": return {
|
|
515
|
+
...el,
|
|
516
|
+
shape: sink(el.shape)
|
|
517
|
+
};
|
|
518
|
+
case "image": return {
|
|
519
|
+
...el,
|
|
520
|
+
image: sink(el.image)
|
|
521
|
+
};
|
|
522
|
+
case "table": return {
|
|
523
|
+
...el,
|
|
524
|
+
table: {
|
|
525
|
+
...el.table,
|
|
526
|
+
properties: sink(el.table.properties)
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
case "chart": return {
|
|
530
|
+
...el,
|
|
531
|
+
chart: sink(el.chart)
|
|
532
|
+
};
|
|
533
|
+
default: return el;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
367
536
|
/**
|
|
368
537
|
* `p:spPr` geometry: `a:prstGeom` (preset) or `a:custGeom` (custom path), default
|
|
369
538
|
* rect. Exported for sheet shapes (E-SHEET W2), whose `xdr:spPr` carries the same
|
|
370
539
|
* `a:` children.
|
|
371
540
|
*/
|
|
541
|
+
/** Whether an `spPr` states a geometry of its own, rather than inheriting one. */
|
|
542
|
+
function statesGeometry(spPr) {
|
|
543
|
+
return poChildren(spPr).some((c) => poIs(c, "a:prstGeom") || poIs(c, "a:custGeom"));
|
|
544
|
+
}
|
|
372
545
|
function parseGeometry(spPr) {
|
|
373
546
|
if (!spPr) return RECT_GEOMETRY;
|
|
374
547
|
const prst = poChildren(spPr).find((c) => poIs(c, "a:prstGeom"));
|
|
@@ -385,10 +558,16 @@ function parsePic(pic, ctx, transform) {
|
|
|
385
558
|
const blip = blipFill ? poChildren(blipFill).find((c) => poIs(c, "a:blip")) : void 0;
|
|
386
559
|
const relId = blip ? poAttr(blip, "embed") : void 0;
|
|
387
560
|
const resource = relId !== void 0 ? ctx.resolveImage?.(relId) : void 0;
|
|
561
|
+
const colorChange = blip ? colorChangeOf(blip, ctx.colors ?? defaultColorResolver) : void 0;
|
|
562
|
+
const fixed = blip ? poChildren(blip).find((c) => poIs(c, "a:alphaModFix")) : void 0;
|
|
563
|
+
const amt = fixed ? poIntAttr(fixed, "amt") : void 0;
|
|
564
|
+
const alpha = amt === void 0 ? void 0 : Math.min(1, Math.max(0, amt / 1e5));
|
|
388
565
|
const altText = picAltText(pic);
|
|
389
566
|
return {
|
|
390
567
|
float: floatAt(box),
|
|
391
568
|
...resource !== void 0 ? { resource } : {},
|
|
569
|
+
...colorChange ? { colorChange } : {},
|
|
570
|
+
...alpha !== void 0 && alpha < 1 ? { alpha } : {},
|
|
392
571
|
width: emuToPt(box.cx),
|
|
393
572
|
height: emuToPt(box.cy),
|
|
394
573
|
paragraphProperties: {},
|
|
@@ -402,14 +581,14 @@ function picAltText(pic) {
|
|
|
402
581
|
const title = cNvPr ? poAttr(cNvPr, "title") : void 0;
|
|
403
582
|
return (descr ?? title)?.trim() || void 0;
|
|
404
583
|
}
|
|
405
|
-
function txBodyParagraphs(txBody, ph, cascade, colors, resolveLink) {
|
|
584
|
+
function txBodyParagraphs(txBody, ph, cascade, colors, resolveLink, styleColor, themeFonts) {
|
|
406
585
|
const content = [];
|
|
407
586
|
const counters = [];
|
|
408
587
|
for (const child of poChildren(txBody)) {
|
|
409
588
|
if (!poIs(child, "a:p")) continue;
|
|
410
589
|
content.push({
|
|
411
590
|
kind: "paragraph",
|
|
412
|
-
paragraph: parseSlideParagraph(child, ph, cascade, colors, resolveLink, counters)
|
|
591
|
+
paragraph: parseSlideParagraph(child, ph, cascade, colors, resolveLink, counters, styleColor, themeFonts)
|
|
413
592
|
});
|
|
414
593
|
}
|
|
415
594
|
return content;
|
|
@@ -427,18 +606,19 @@ function txBodyParagraphs(txBody, ph, cascade, colors, resolveLink) {
|
|
|
427
606
|
* @param resolveLink A run hyperlink resolver, or `undefined`.
|
|
428
607
|
* @returns The text body, or `undefined` when it holds no paragraphs.
|
|
429
608
|
*/
|
|
430
|
-
function parseTxBody(txBody, ph, cascade, colors, resolveLink) {
|
|
431
|
-
const content = txBodyParagraphs(txBody, ph, cascade, colors, resolveLink);
|
|
609
|
+
function parseTxBody(txBody, ph, cascade, colors, resolveLink, styleColor, themeFonts) {
|
|
610
|
+
const content = txBodyParagraphs(txBody, ph, cascade, colors, resolveLink, styleColor, themeFonts);
|
|
432
611
|
if (content.length === 0) return void 0;
|
|
433
612
|
const bodyPr = poChildren(txBody).find((c) => poIs(c, "a:bodyPr"));
|
|
613
|
+
const fitted = fitToBody(content, bodyPr);
|
|
434
614
|
const lIns = bodyPr ? poIntAttr(bodyPr, "lIns") : void 0;
|
|
435
615
|
const tIns = bodyPr ? poIntAttr(bodyPr, "tIns") : void 0;
|
|
436
616
|
const rIns = bodyPr ? poIntAttr(bodyPr, "rIns") : void 0;
|
|
437
617
|
const bIns = bodyPr ? poIntAttr(bodyPr, "bIns") : void 0;
|
|
438
618
|
const a = bodyPr ? poAttr(bodyPr, "anchor") : void 0;
|
|
439
|
-
const anchor = a === "ctr"
|
|
619
|
+
const anchor = a === "ctr" || a === "b" || a === "t" ? a : ph && cascade ? cascade.anchorFor(ph) : void 0;
|
|
440
620
|
return {
|
|
441
|
-
content,
|
|
621
|
+
content: fitted,
|
|
442
622
|
...lIns !== void 0 ? { insetLeft: emuToPt(lIns) } : {},
|
|
443
623
|
...tIns !== void 0 ? { insetTop: emuToPt(tIns) } : {},
|
|
444
624
|
...rIns !== void 0 ? { insetRight: emuToPt(rIns) } : {},
|
|
@@ -446,67 +626,142 @@ function parseTxBody(txBody, ph, cascade, colors, resolveLink) {
|
|
|
446
626
|
...anchor ? { anchor } : {}
|
|
447
627
|
};
|
|
448
628
|
}
|
|
449
|
-
|
|
629
|
+
/**
|
|
630
|
+
* §21.1.2.1.2 — the body's text at the size the autofit settled on.
|
|
631
|
+
*
|
|
632
|
+
* The scale is a property of the BODY that reaches every run in it, so it is
|
|
633
|
+
* applied here rather than carried down: a run in the model already holds the
|
|
634
|
+
* size it inherited, and the shrink multiplies exactly that. Unread, the text
|
|
635
|
+
* PowerPoint squeezed to 62% of its style overflowed the placeholder it was
|
|
636
|
+
* squeezed to fit.
|
|
637
|
+
*
|
|
638
|
+
* @param content The body's paragraphs.
|
|
639
|
+
* @param bodyPr The body's `a:bodyPr`, which carries the autofit.
|
|
640
|
+
* @returns The paragraphs, scaled; the same array when nothing is stated.
|
|
641
|
+
*/
|
|
642
|
+
function fitToBody(content, bodyPr) {
|
|
643
|
+
const fit = bodyPr ? poChildren(bodyPr).find((c) => poIs(c, "a:normAutofit")) : void 0;
|
|
644
|
+
const scale = fit ? poIntAttr(fit, "fontScale") : void 0;
|
|
645
|
+
const reduction = fit ? poIntAttr(fit, "lnSpcReduction") : void 0;
|
|
646
|
+
const fontScale = scale !== void 0 && scale > 0 ? scale / 1e5 : void 0;
|
|
647
|
+
const lineScale = reduction !== void 0 && reduction > 0 ? 1 - Math.min(reduction, 1e5) / 1e5 : void 0;
|
|
648
|
+
if (fontScale === void 0 && lineScale === void 0) return content;
|
|
649
|
+
return content.map((el) => {
|
|
650
|
+
if (el.kind !== "paragraph") return el;
|
|
651
|
+
const p = el.paragraph;
|
|
652
|
+
const line = lineScale === void 0 ? void 0 : pt((p.properties.spacingLine ?? 12) * lineScale);
|
|
653
|
+
return {
|
|
654
|
+
...el,
|
|
655
|
+
paragraph: {
|
|
656
|
+
...p,
|
|
657
|
+
properties: {
|
|
658
|
+
...p.properties,
|
|
659
|
+
...line !== void 0 ? {
|
|
660
|
+
spacingLine: line,
|
|
661
|
+
spacingLineRule: "auto"
|
|
662
|
+
} : {}
|
|
663
|
+
},
|
|
664
|
+
runs: fontScale === void 0 ? p.runs : p.runs.map((run) => run.properties.fontSizePt === void 0 ? run : {
|
|
665
|
+
...run,
|
|
666
|
+
properties: {
|
|
667
|
+
...run.properties,
|
|
668
|
+
fontSizePt: pt(run.properties.fontSizePt * fontScale)
|
|
669
|
+
}
|
|
670
|
+
})
|
|
671
|
+
}
|
|
672
|
+
};
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
function parseSlideParagraph(aP, ph, cascade, colors, resolveLink, counters, styleColor, themeFonts) {
|
|
450
676
|
const pPr = poChildren(aP).find((c) => poIs(c, "a:pPr"));
|
|
451
677
|
const level = (pPr ? poIntAttr(pPr, "lvl") : void 0) ?? 0;
|
|
452
|
-
const defaults =
|
|
678
|
+
const defaults = {
|
|
679
|
+
...cascade ? cascade.defaultsFor(ph, level) : {},
|
|
680
|
+
...styleColor !== void 0 ? { colorHex: styleColor } : {}
|
|
681
|
+
};
|
|
682
|
+
const inherited = cascade ? cascade.paragraphDefaultsFor(ph, level) : {};
|
|
453
683
|
const algn = pPr ? poAttr(pPr, "algn") : void 0;
|
|
454
684
|
const alignment = algn !== void 0 ? ALGN_TO_ALIGNMENT[algn] : void 0;
|
|
455
685
|
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
686
|
for (const child of poChildren(aP)) if (poIs(child, "a:r") || poIs(child, "a:fld")) {
|
|
463
|
-
const run = parseSlideRun(child, defaults, colors, resolveLink);
|
|
687
|
+
const run = parseSlideRun(child, defaults, colors, resolveLink, themeFonts);
|
|
464
688
|
if (run) runs.push(run);
|
|
465
689
|
}
|
|
466
|
-
if (runs.length === 0) {
|
|
467
|
-
const endRPr = poChildren(aP).find((c) => poIs(c, "a:endParaRPr"));
|
|
468
|
-
const sz = endRPr ? poIntAttr(endRPr, "sz") : void 0;
|
|
469
|
-
if (sz !== void 0 && sz > 0) runs.push({
|
|
470
|
-
text: "",
|
|
471
|
-
properties: {
|
|
472
|
-
...defaults,
|
|
473
|
-
fontSizePt: pt(sz / 100)
|
|
474
|
-
}
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
690
|
const marL = pPr ? poIntAttr(pPr, "marL") : void 0;
|
|
478
691
|
const indent = pPr ? poIntAttr(pPr, "indent") : void 0;
|
|
479
692
|
const indentLeft = marL !== void 0 ? emuToPt(marL) : level > 0 ? emuToPt(level * 457200) : void 0;
|
|
693
|
+
const hanging = (indent !== void 0 ? emuToPt(indent) : inherited.indentFirstLine ?? 0) < 0;
|
|
694
|
+
const bullet = {
|
|
695
|
+
...cascade?.bulletFor(ph, level),
|
|
696
|
+
...parseBullet(pPr, colors)
|
|
697
|
+
};
|
|
698
|
+
const marker = bulletMarker(bullet, level, counters);
|
|
699
|
+
if (marker !== void 0) {
|
|
700
|
+
const base = runs[0]?.properties ?? defaults;
|
|
701
|
+
runs.unshift({
|
|
702
|
+
text: marker + (hanging ? " " : " "),
|
|
703
|
+
properties: bulletProps(base, bullet),
|
|
704
|
+
listMarker: true
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
const endRPr = poChildren(aP).find((c) => poIs(c, "a:endParaRPr"));
|
|
708
|
+
const endSz = endRPr ? poIntAttr(endRPr, "sz") : void 0;
|
|
709
|
+
const markProps = runs.length > 0 ? void 0 : {
|
|
710
|
+
...defaults,
|
|
711
|
+
...endSz !== void 0 && endSz > 0 ? { fontSizePt: pt(endSz / 100) } : {}
|
|
712
|
+
};
|
|
480
713
|
return {
|
|
481
714
|
properties: {
|
|
715
|
+
...inherited,
|
|
482
716
|
...alignment ? { alignment } : {},
|
|
483
717
|
...indentLeft !== void 0 ? { indentLeft } : {},
|
|
484
|
-
...indent !== void 0 ? { indentFirstLine: emuToPt(indent) } : {}
|
|
718
|
+
...indent !== void 0 ? { indentFirstLine: emuToPt(indent) } : {},
|
|
719
|
+
...lineSpacing(pPr),
|
|
720
|
+
...ownSpacing(pPr, runs[0]?.properties.fontSizePt ?? defaults.fontSizePt),
|
|
721
|
+
...markProps && markProps.fontSizePt !== void 0 ? { runProperties: markProps } : {}
|
|
485
722
|
},
|
|
486
723
|
runs
|
|
487
724
|
};
|
|
488
725
|
}
|
|
489
|
-
function
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
const
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
726
|
+
function ownSpacing(pPr, sizePt) {
|
|
727
|
+
const fractions = spacingFractions(pPr);
|
|
728
|
+
const before = spacingFromLineFraction(fractions?.before, sizePt);
|
|
729
|
+
const after = spacingFromLineFraction(fractions?.after, sizePt);
|
|
730
|
+
const points = (tag) => {
|
|
731
|
+
const holder = pPr ? poChildren(pPr).find((c) => poIs(c, tag)) : void 0;
|
|
732
|
+
const node = holder ? poChildren(holder).find((c) => poIs(c, "a:spcPts")) : void 0;
|
|
733
|
+
const val = node ? poIntAttr(node, "val") : void 0;
|
|
734
|
+
return val === void 0 ? void 0 : pt(val / 100);
|
|
735
|
+
};
|
|
736
|
+
const [beforePt, afterPt] = [points("a:spcBef") ?? before, points("a:spcAft") ?? after];
|
|
737
|
+
return {
|
|
738
|
+
...beforePt !== void 0 ? { spacingBefore: beforePt } : {},
|
|
739
|
+
...afterPt !== void 0 ? { spacingAfter: afterPt } : {}
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
function bulletProps(base, bullet) {
|
|
743
|
+
const sizePt = bullet.sizePts ?? (bullet.sizePct !== void 0 && base.fontSizePt !== void 0 ? base.fontSizePt * bullet.sizePct : void 0);
|
|
744
|
+
return {
|
|
745
|
+
...base,
|
|
746
|
+
...sizePt !== void 0 ? { fontSizePt: pt(sizePt) } : {},
|
|
747
|
+
...bullet.colorHex !== void 0 ? { colorHex: bullet.colorHex } : {}
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
function bulletMarker(bullet, level, counters) {
|
|
751
|
+
if (!bullet || bullet.kind === "none" || bullet.kind === void 0) return void 0;
|
|
752
|
+
if (bullet.kind === "char") return bullet.char ?? "•";
|
|
498
753
|
const prev = counters[level];
|
|
499
|
-
const n = (prev === void 0 ? startAt - 1 : prev) + 1;
|
|
754
|
+
const n = (prev === void 0 ? (bullet.startAt ?? 1) - 1 : prev) + 1;
|
|
500
755
|
counters[level] = n;
|
|
501
756
|
counters.length = level + 1;
|
|
502
|
-
return `${n}${autoNumSuffix(type)}
|
|
757
|
+
return `${n}${autoNumSuffix(bullet.type ?? "arabicPeriod")}`;
|
|
503
758
|
}
|
|
504
759
|
function autoNumSuffix(type) {
|
|
505
760
|
if (type.endsWith("ParenR") || type.endsWith("ParenBoth")) return ")";
|
|
506
761
|
if (type.endsWith("Period")) return ".";
|
|
507
762
|
return "";
|
|
508
763
|
}
|
|
509
|
-
function parseSlideRun(node, defaults, colors, resolveLink) {
|
|
764
|
+
function parseSlideRun(node, defaults, colors, resolveLink, themeFonts) {
|
|
510
765
|
const t = poChildren(node).find((c) => poIs(c, "a:t"));
|
|
511
766
|
const text = t ? poText(t) : "";
|
|
512
767
|
if (text.length === 0) return void 0;
|
|
@@ -518,36 +773,62 @@ function parseSlideRun(node, defaults, colors, resolveLink) {
|
|
|
518
773
|
text,
|
|
519
774
|
properties: {
|
|
520
775
|
...defaults,
|
|
521
|
-
...rPrToRunProps(rPr, colors)
|
|
776
|
+
...rPrToRunProps(rPr, colors, themeFonts)
|
|
522
777
|
},
|
|
523
778
|
...href ? { href } : {}
|
|
524
779
|
};
|
|
525
780
|
}
|
|
526
|
-
function parseTable(tbl, colors) {
|
|
781
|
+
function parseTable(tbl, colors, resolveTableStyle, theme) {
|
|
527
782
|
const grid = [];
|
|
528
783
|
const tblGrid = poChildren(tbl).find((c) => poIs(c, "a:tblGrid"));
|
|
529
784
|
if (tblGrid) {
|
|
530
785
|
for (const col of poChildren(tblGrid)) if (poIs(col, "a:gridCol")) grid.push(emuToPt(poIntAttr(col, "w") ?? 0));
|
|
531
786
|
}
|
|
532
787
|
const rows = [];
|
|
533
|
-
|
|
534
|
-
|
|
788
|
+
const sources = [];
|
|
789
|
+
for (const tr of poChildren(tbl)) {
|
|
790
|
+
if (!poIs(tr, "a:tr")) continue;
|
|
791
|
+
const cells = rowCells(tr);
|
|
792
|
+
sources.push(cells);
|
|
793
|
+
rows.push(parseTableRow(tr, cells, colors));
|
|
794
|
+
}
|
|
795
|
+
const tblPr = poChildren(tbl).find((c) => poIs(c, "a:tblPr"));
|
|
796
|
+
const style = resolveTableStyle?.(tableStyleId(tblPr));
|
|
797
|
+
if (!style) return {
|
|
535
798
|
properties: {},
|
|
536
799
|
grid,
|
|
537
800
|
rows
|
|
538
801
|
};
|
|
802
|
+
const flags = tableStyleFlags(tblPr);
|
|
803
|
+
return {
|
|
804
|
+
properties: {},
|
|
805
|
+
grid,
|
|
806
|
+
rows: rows.map((row, r) => ({
|
|
807
|
+
...row,
|
|
808
|
+
cells: row.cells.map((cell, c) => {
|
|
809
|
+
const part = cellStyle(style, flags, {
|
|
810
|
+
row: r,
|
|
811
|
+
rowCount: rows.length,
|
|
812
|
+
col: c,
|
|
813
|
+
colCount: grid.length
|
|
814
|
+
}, colors, theme);
|
|
815
|
+
const tc = sources[r]?.[c];
|
|
816
|
+
return withCellStyle(cell, tc && cellSaysNoFill(tc) ? withoutFill(part) : part);
|
|
817
|
+
})
|
|
818
|
+
}))
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
function rowCells(tr) {
|
|
822
|
+
return poChildren(tr).filter((tc) => poIs(tc, "a:tc") && poAttr(tc, "hMerge") !== "1");
|
|
539
823
|
}
|
|
540
|
-
function parseTableRow(tr, colors) {
|
|
824
|
+
function parseTableRow(tr, cells, colors) {
|
|
541
825
|
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
826
|
return {
|
|
549
|
-
properties: { ...h !== void 0 ? {
|
|
550
|
-
|
|
827
|
+
properties: { ...h !== void 0 ? {
|
|
828
|
+
height: emuToPt(h),
|
|
829
|
+
heightRule: "atLeast"
|
|
830
|
+
} : {} },
|
|
831
|
+
cells: cells.map((tc) => parseTableCell(tc, colors))
|
|
551
832
|
};
|
|
552
833
|
}
|
|
553
834
|
function parseTableCell(tc, colors) {
|
|
@@ -558,15 +839,35 @@ function parseTableCell(tc, colors) {
|
|
|
558
839
|
const merge = rowSpan !== void 0 && rowSpan > 1 ? "start" : poAttr(tc, "vMerge") === "1" ? "middle" : void 0;
|
|
559
840
|
const tcPr = poChildren(tc).find((c) => poIs(c, "a:tcPr"));
|
|
560
841
|
const shadingHex = tcPr ? cellFillHex(tcPr, colors) : void 0;
|
|
842
|
+
const borders = tcPr ? cellOwnBorders(tcPr, colors) : void 0;
|
|
561
843
|
return {
|
|
562
844
|
properties: {
|
|
563
845
|
...gridSpan !== void 0 && gridSpan > 1 ? { colSpan: gridSpan } : {},
|
|
564
846
|
...merge ? { merge } : {},
|
|
565
|
-
...shadingHex ? { shading: { colorHex: shadingHex } } : {}
|
|
847
|
+
...shadingHex ? { shading: { colorHex: shadingHex } } : {},
|
|
848
|
+
...borders ? { borders } : {}
|
|
566
849
|
},
|
|
567
850
|
content
|
|
568
851
|
};
|
|
569
852
|
}
|
|
853
|
+
var CELL_LINES = [
|
|
854
|
+
["a:lnL", "left"],
|
|
855
|
+
["a:lnR", "right"],
|
|
856
|
+
["a:lnT", "top"],
|
|
857
|
+
["a:lnB", "bottom"]
|
|
858
|
+
];
|
|
859
|
+
function cellOwnBorders(tcPr, colors) {
|
|
860
|
+
const out = {};
|
|
861
|
+
for (const [tag, side] of CELL_LINES) {
|
|
862
|
+
const ln = poChildren(tcPr).find((c) => poIs(c, tag));
|
|
863
|
+
if (ln) out[side] = lineBorder(ln, colors);
|
|
864
|
+
}
|
|
865
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
866
|
+
}
|
|
867
|
+
function cellSaysNoFill(tc) {
|
|
868
|
+
const tcPr = poChildren(tc).find((c) => poIs(c, "a:tcPr"));
|
|
869
|
+
return tcPr !== void 0 && poChildren(tcPr).some((c) => poIs(c, "a:noFill"));
|
|
870
|
+
}
|
|
570
871
|
function cellFillHex(tcPr, colors) {
|
|
571
872
|
const solidFill = poChildren(tcPr).find((c) => poIs(c, "a:solidFill"));
|
|
572
873
|
if (!solidFill) return void 0;
|
|
@@ -576,4 +877,4 @@ function cellFillHex(tcPr, colors) {
|
|
|
576
877
|
}
|
|
577
878
|
}
|
|
578
879
|
//#endregion
|
|
579
|
-
export { backdropElement, diagramTransform, noDiagramOverrideLoss, parseBackgroundFill, parseDiagramNodes, parseGeometry, parseSlideShapes, parseTxBody };
|
|
880
|
+
export { asBackdrop, backdropElement, diagramTransform, noDiagramOverrideLoss, parseBackgroundFill, parseDiagramNodes, parseGeometry, parseSlideShapes, parseTxBody };
|