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
|
@@ -17,6 +17,14 @@ export declare function readPptx(bytes: Uint8Array): ReadResult<FlowDoc>;
|
|
|
17
17
|
* Parse an OOXML part's bytes into preserve-order {@link PoNode} roots with the
|
|
18
18
|
* module's shared, presentation-tuned {@link XMLParser} (attributes kept, values
|
|
19
19
|
* not coerced, whitespace preserved). Shared with the slide-style resolvers.
|
|
20
|
+
*
|
|
21
|
+
* ISO/IEC 29500-3 §10.2 — `mc:AlternateContent` is resolved first, to the
|
|
22
|
+
* `mc:Fallback` a reader takes when it implements none of the namespaces the
|
|
23
|
+
* choices require. A deck writes the same shape twice this way, and reading the
|
|
24
|
+
* CHOICE means reading markup written for someone else: tdf143222's whole slide
|
|
25
|
+
* is an embedded worksheet whose preview picture lives in the fallback alone,
|
|
26
|
+
* and the choice — written for VML — carries no picture at all, so the slide
|
|
27
|
+
* came out blank. 82 of the corpus's decks carry such a block.
|
|
20
28
|
*/
|
|
21
29
|
export declare function parseXml(data: Uint8Array): Array<PoNode>;
|
|
22
30
|
/**
|
|
@@ -4,20 +4,25 @@ import { FEATURES } from "../core/ir/features.js";
|
|
|
4
4
|
import { EMPTY_STYLE_SHEET, resolveBodyStyles } from "../core/style-cascade/resolver.js";
|
|
5
5
|
import "../core/style-cascade/index.js";
|
|
6
6
|
import { poAttr, poChildren, poFindDescendant, poIntAttr, poIs } from "../core/po-helpers.js";
|
|
7
|
-
import {
|
|
8
|
-
import { DEFAULT_THEME_PALETTE, defaultColorResolver, makeColorResolver } from "../core/drawingml/colors.js";
|
|
7
|
+
import { packageHasPart } from "../core/bytes.js";
|
|
8
|
+
import { DEFAULT_SCHEME_ALIAS, DEFAULT_THEME_PALETTE, defaultColorResolver, makeColorResolver } from "../core/drawingml/colors.js";
|
|
9
9
|
import { parseChart, withChartColorStyle } from "../core/drawingml/chart-parser.js";
|
|
10
|
-
import { parseTheme } from "../core/drawingml/theme-parser.js";
|
|
10
|
+
import { parseTheme, parseThemeBgFillStyles, parseThemeFillStyles, parseThemeFonts, parseThemeLineWidths } from "../core/drawingml/theme-parser.js";
|
|
11
11
|
import { OpcPackage } from "../core/opc/package.js";
|
|
12
12
|
import "../core/opc/index.js";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { loadPptxEmbeddedFonts } from "./embedded-fonts.js";
|
|
14
|
+
import { presetTableStyle } from "./preset-table-styles.js";
|
|
15
|
+
import { resolveAlternateContent } from "../core/opc/alternate-content.js";
|
|
16
|
+
import { buildPlaceholderCascade, parseLevelStyles } from "./placeholder-cascade.js";
|
|
17
|
+
import { normalizeSpid, parseVmlImageRels } from "./ole-preview.js";
|
|
18
|
+
import { asBackdrop, backdropElement, parseBackgroundFill, parseSlideShapes } from "./slide-parser.js";
|
|
15
19
|
import { XMLParser } from "fast-xml-parser";
|
|
16
20
|
//#region src/pptx/pptx-reader.ts
|
|
17
21
|
var EMU_PER_PT = 12700;
|
|
18
22
|
var DEFAULT_CX = 9144e3;
|
|
19
23
|
var DEFAULT_CY = 6858e3;
|
|
20
24
|
var decoder = new TextDecoder();
|
|
25
|
+
var encoder = new TextEncoder();
|
|
21
26
|
var parser = new XMLParser({
|
|
22
27
|
htmlEntities: true,
|
|
23
28
|
ignoreAttributes: false,
|
|
@@ -47,15 +52,20 @@ function readPptx(bytes) {
|
|
|
47
52
|
const losses = [];
|
|
48
53
|
const pkg = OpcPackage.open(bytes);
|
|
49
54
|
const presPath = pkg.getMainDocumentPath();
|
|
55
|
+
const tableStyles = makeTableStyleResolver(pkg, presPath);
|
|
50
56
|
const presData = pkg.getPart(presPath);
|
|
51
57
|
const resources = new ResourceStore();
|
|
52
58
|
const charts = /* @__PURE__ */ new Map();
|
|
53
59
|
let cx = DEFAULT_CX;
|
|
54
60
|
let cy = DEFAULT_CY;
|
|
61
|
+
let defaultTextStyle;
|
|
62
|
+
let embeddedFonts = /* @__PURE__ */ new Map();
|
|
55
63
|
const slideParts = [];
|
|
56
64
|
if (presData) {
|
|
57
65
|
const pres = parser.parse(decoder.decode(presData)).find((n) => poIs(n, "p:presentation"));
|
|
66
|
+
embeddedFonts = loadPptxEmbeddedFonts(pkg, presPath, pres, (loss) => losses.push(loss));
|
|
58
67
|
const kids = pres ? poChildren(pres) : [];
|
|
68
|
+
defaultTextStyle = kids.find((c) => poIs(c, "p:defaultTextStyle"));
|
|
59
69
|
const sldSz = kids.find((c) => poIs(c, "p:sldSz"));
|
|
60
70
|
cx = (sldSz ? poIntAttr(sldSz, "cx") : void 0) || DEFAULT_CX;
|
|
61
71
|
cy = (sldSz ? poIntAttr(sldSz, "cy") : void 0) || DEFAULT_CY;
|
|
@@ -103,20 +113,38 @@ function readPptx(bytes) {
|
|
|
103
113
|
});
|
|
104
114
|
const part = slideParts[i];
|
|
105
115
|
if (part) {
|
|
106
|
-
const
|
|
116
|
+
const slideTree = parseXml(part.data);
|
|
117
|
+
const styles = slideStylesFor(pkg, part.path, stylesByLayout, resources, charts, (loss) => losses.push(loss.where ? loss : {
|
|
118
|
+
...loss,
|
|
119
|
+
where: `slide ${i + 1}`
|
|
120
|
+
}), defaultTextStyle, {
|
|
121
|
+
widthPt: pageW,
|
|
122
|
+
heightPt: pageH
|
|
123
|
+
}, overrideAlias(slideTree, "p:sld"));
|
|
107
124
|
const ctx = {
|
|
108
125
|
...styles.cascade ? { cascade: styles.cascade } : {},
|
|
109
126
|
colors: styles.colors,
|
|
127
|
+
...styles.background ? { backgroundFill: styles.background } : {},
|
|
128
|
+
slideSize: {
|
|
129
|
+
widthPt: pageW,
|
|
130
|
+
heightPt: pageH
|
|
131
|
+
},
|
|
132
|
+
...styles.themeFonts ? { themeFonts: styles.themeFonts } : {},
|
|
133
|
+
...styles.themeFills ? { themeFills: styles.themeFills } : {},
|
|
134
|
+
...styles.themeLineWidths ? { themeLineWidths: styles.themeLineWidths } : {},
|
|
110
135
|
resolveImage: makeSlideImageResolver(pkg, part.path, resources),
|
|
111
|
-
resolveChart: makeSlideChartResolver(pkg, part.path, charts, styles.colors),
|
|
136
|
+
resolveChart: makeSlideChartResolver(pkg, part.path, charts, styles.colors, resources),
|
|
112
137
|
resolveHyperlink: makeHyperlinkResolver(pkg, part.path),
|
|
113
138
|
resolveDiagram: makeSlideDiagramResolver(pkg, part.path),
|
|
139
|
+
resolveOlePreview: makeOlePreviewResolver(pkg, part.path, resources),
|
|
140
|
+
resolveTableStyle: tableStyles,
|
|
114
141
|
onLoss: (loss) => losses.push(loss.where ? loss : {
|
|
115
142
|
...loss,
|
|
116
143
|
where: `slide ${i + 1}`
|
|
117
144
|
})
|
|
118
145
|
};
|
|
119
|
-
|
|
146
|
+
const inherited = showMasterShapes(slideTree, "p:sld") ? styles.inheritedShapes ?? [] : [];
|
|
147
|
+
body.push(...parseSlide(slideTree, ctx, styles.background, pageW, pageH, inherited));
|
|
120
148
|
}
|
|
121
149
|
}
|
|
122
150
|
const section = {
|
|
@@ -141,7 +169,8 @@ function readPptx(bytes) {
|
|
|
141
169
|
section,
|
|
142
170
|
styles: EMPTY_STYLE_SHEET,
|
|
143
171
|
resources,
|
|
144
|
-
...charts.size > 0 ? { charts } : {}
|
|
172
|
+
...charts.size > 0 ? { charts } : {},
|
|
173
|
+
...embeddedFonts.size > 0 ? { embeddedFonts } : {}
|
|
145
174
|
},
|
|
146
175
|
losses
|
|
147
176
|
};
|
|
@@ -150,27 +179,41 @@ function readPptx(bytes) {
|
|
|
150
179
|
* Parse an OOXML part's bytes into preserve-order {@link PoNode} roots with the
|
|
151
180
|
* module's shared, presentation-tuned {@link XMLParser} (attributes kept, values
|
|
152
181
|
* not coerced, whitespace preserved). Shared with the slide-style resolvers.
|
|
182
|
+
*
|
|
183
|
+
* ISO/IEC 29500-3 §10.2 — `mc:AlternateContent` is resolved first, to the
|
|
184
|
+
* `mc:Fallback` a reader takes when it implements none of the namespaces the
|
|
185
|
+
* choices require. A deck writes the same shape twice this way, and reading the
|
|
186
|
+
* CHOICE means reading markup written for someone else: tdf143222's whole slide
|
|
187
|
+
* is an embedded worksheet whose preview picture lives in the fallback alone,
|
|
188
|
+
* and the choice — written for VML — carries no picture at all, so the slide
|
|
189
|
+
* came out blank. 82 of the corpus's decks carry such a block.
|
|
153
190
|
*/
|
|
154
191
|
function parseXml(data) {
|
|
155
|
-
return parser.parse(decoder.decode(data));
|
|
192
|
+
return parser.parse(resolveAlternateContent(decoder.decode(data)));
|
|
156
193
|
}
|
|
157
|
-
function parseSlide(
|
|
158
|
-
const sld =
|
|
194
|
+
function parseSlide(tree, ctx, inheritedBg, pageW, pageH, inheritedShapes = []) {
|
|
195
|
+
const sld = tree.find((n) => poIs(n, "p:sld"));
|
|
159
196
|
const cSld = sld ? poChildren(sld).find((c) => poIs(c, "p:cSld")) : void 0;
|
|
160
197
|
const colors = ctx.colors ?? defaultColorResolver;
|
|
161
198
|
const bgNode = cSld ? poChildren(cSld).find((c) => poIs(c, "p:bg")) : void 0;
|
|
162
|
-
const
|
|
199
|
+
const own = bgNode ? parseBackgroundFill(bgNode, colors, ctx.resolveImage, ctx.themeFills) : void 0;
|
|
200
|
+
const bg = own ?? inheritedBg;
|
|
163
201
|
const spTree = cSld ? poChildren(cSld).find((c) => poIs(c, "p:spTree")) : void 0;
|
|
202
|
+
const shapeCtx = own ? {
|
|
203
|
+
...ctx,
|
|
204
|
+
backgroundFill: own
|
|
205
|
+
} : ctx;
|
|
164
206
|
const out = [];
|
|
165
207
|
if (bg) out.push(backdropElement(bg, pageW, pageH));
|
|
166
|
-
|
|
208
|
+
out.push(...inheritedShapes.map(asBackdrop));
|
|
209
|
+
if (spTree) out.push(...parseSlideShapes(spTree, shapeCtx));
|
|
167
210
|
return out;
|
|
168
211
|
}
|
|
169
|
-
function partBackground(tree, root, colors) {
|
|
212
|
+
function partBackground(tree, root, colors, resolveImage, themeFills) {
|
|
170
213
|
const sld = tree.find((n) => poIs(n, root));
|
|
171
214
|
const cSld = sld ? poChildren(sld).find((c) => poIs(c, "p:cSld")) : void 0;
|
|
172
215
|
const bg = cSld ? poChildren(cSld).find((c) => poIs(c, "p:bg")) : void 0;
|
|
173
|
-
return bg ? parseBackgroundFill(bg, colors) : void 0;
|
|
216
|
+
return bg ? parseBackgroundFill(bg, colors, resolveImage, themeFills) : void 0;
|
|
174
217
|
}
|
|
175
218
|
function makeSlideImageResolver(pkg, slidePath, resources) {
|
|
176
219
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -183,19 +226,81 @@ function makeSlideImageResolver(pkg, slidePath, resources) {
|
|
|
183
226
|
return id;
|
|
184
227
|
};
|
|
185
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* The preview picture resolver for one slide's embedded objects: a `p:oleObj`
|
|
231
|
+
* `@spid` → the media the slide's legacy VML drawing hangs off that shape.
|
|
232
|
+
*
|
|
233
|
+
* Two relationship hops, and neither is the slide's own: the slide names the
|
|
234
|
+
* VML part, and the VML part names the picture. The whole part is read once,
|
|
235
|
+
* lazily — most slides have no embedded object at all.
|
|
236
|
+
*/
|
|
237
|
+
function makeOlePreviewResolver(pkg, slidePath, resources) {
|
|
238
|
+
let byShape;
|
|
239
|
+
let vmlPath;
|
|
240
|
+
const cache = /* @__PURE__ */ new Map();
|
|
241
|
+
return (spid) => {
|
|
242
|
+
const key = normalizeSpid(spid);
|
|
243
|
+
if (cache.has(key)) return cache.get(key);
|
|
244
|
+
if (byShape === void 0) {
|
|
245
|
+
const rel = pkg.getPartRelationships(slidePath).find((r) => r.type.endsWith("/vmlDrawing") || r.type.endsWith("/legacyDrawing"));
|
|
246
|
+
const part = rel ? pkg.resolveRelatedPart(slidePath, rel) : void 0;
|
|
247
|
+
byShape = part ? parseVmlImageRels(part.data) : /* @__PURE__ */ new Map();
|
|
248
|
+
vmlPath = part?.path;
|
|
249
|
+
}
|
|
250
|
+
const relId = byShape.get(key);
|
|
251
|
+
const imgRel = relId !== void 0 && vmlPath !== void 0 ? pkg.getPartRelationships(vmlPath).find((r) => r.id === relId) : void 0;
|
|
252
|
+
const media = imgRel && vmlPath !== void 0 ? pkg.resolveRelatedPart(vmlPath, imgRel) : void 0;
|
|
253
|
+
const id = media ? resources.put(media.data) : void 0;
|
|
254
|
+
cache.set(key, id);
|
|
255
|
+
return id;
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* §20.1.4.2.24 — the deck's table styles, by the GUID a table names.
|
|
260
|
+
*
|
|
261
|
+
* The list's own `@def` is NOT a fallback: it is the style PowerPoint applies
|
|
262
|
+
* when a table is INSERTED, and the table then records that GUID itself. A
|
|
263
|
+
* table that names none wears none — table-with-no-theme's two rows are bare
|
|
264
|
+
* text in a plain frame, not the blue banding `@def` points at.
|
|
265
|
+
*
|
|
266
|
+
* A GUID the part does not hold may still be one of the GALLERY's own, which
|
|
267
|
+
* every deck names and none ships (see `preset-table-styles`).
|
|
268
|
+
*
|
|
269
|
+
* The part is read once, on the first table in the deck.
|
|
270
|
+
*/
|
|
271
|
+
function makeTableStyleResolver(pkg, presPath) {
|
|
272
|
+
let byId;
|
|
273
|
+
return (styleId) => {
|
|
274
|
+
if (byId === void 0) {
|
|
275
|
+
byId = /* @__PURE__ */ new Map();
|
|
276
|
+
const rel = pkg.getPartRelationships(presPath).find((r) => r.type.endsWith("/tableStyles"));
|
|
277
|
+
const part = rel ? pkg.resolveRelatedPart(presPath, rel) : void 0;
|
|
278
|
+
for (const root of part ? parseXml(part.data) : []) {
|
|
279
|
+
const list = poIs(root, "a:tblStyleLst") ? root : poFindDescendant(root, "a:tblStyleLst");
|
|
280
|
+
if (!list) continue;
|
|
281
|
+
for (const style of poChildren(list)) {
|
|
282
|
+
const id = poIs(style, "a:tblStyle") ? poAttr(style, "styleId") : void 0;
|
|
283
|
+
if (id !== void 0) byId.set(id, style);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
if (styleId === void 0) return void 0;
|
|
288
|
+
return byId.get(styleId) ?? presetTableStyle(styleId, (xml) => parseXml(encoder.encode(xml)));
|
|
289
|
+
};
|
|
290
|
+
}
|
|
186
291
|
function makeHyperlinkResolver(pkg, slidePath) {
|
|
187
292
|
return (relId) => {
|
|
188
293
|
const rel = pkg.getPartRelationships(slidePath).find((r) => r.id === relId);
|
|
189
294
|
return rel && rel.targetMode === "External" ? rel.target : void 0;
|
|
190
295
|
};
|
|
191
296
|
}
|
|
192
|
-
function makeSlideChartResolver(pkg, slidePath, charts, colors) {
|
|
297
|
+
function makeSlideChartResolver(pkg, slidePath, charts, colors, resources) {
|
|
193
298
|
const cache = /* @__PURE__ */ new Map();
|
|
194
299
|
return (relId) => {
|
|
195
300
|
if (cache.has(relId)) return cache.get(relId);
|
|
196
301
|
const rel = pkg.getPartRelationships(slidePath).find((r) => r.id === relId);
|
|
197
302
|
const resolved = rel ? pkg.resolveRelatedPart(slidePath, rel) : void 0;
|
|
198
|
-
const chart = resolved ? parseChart(resolved.data, colors) : null;
|
|
303
|
+
const chart = resolved ? parseChart(resolved.data, colors, makeSlideImageResolver(pkg, resolved.path, resources)) : null;
|
|
199
304
|
let key;
|
|
200
305
|
if (chart && resolved) {
|
|
201
306
|
key = `${slidePath}!${relId}`;
|
|
@@ -212,49 +317,174 @@ function makeSlideDiagramResolver(pkg, slidePath) {
|
|
|
212
317
|
let spTree;
|
|
213
318
|
const dataRel = pkg.getPartRelationships(slidePath).find((r) => r.id === relId);
|
|
214
319
|
const data = dataRel ? pkg.resolveRelatedPart(slidePath, dataRel) : void 0;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const
|
|
218
|
-
if (
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
spTree = found;
|
|
222
|
-
break;
|
|
223
|
-
}
|
|
320
|
+
const draw = data ? drawingPart(pkg, slidePath, data) : void 0;
|
|
321
|
+
if (draw) for (const root of parseXml(draw.data)) {
|
|
322
|
+
const found = poFindDescendant(root, "dsp:spTree");
|
|
323
|
+
if (found) {
|
|
324
|
+
spTree = found;
|
|
325
|
+
break;
|
|
224
326
|
}
|
|
225
327
|
}
|
|
226
328
|
cache.set(relId, spTree);
|
|
227
329
|
return spTree;
|
|
228
330
|
};
|
|
229
331
|
}
|
|
230
|
-
|
|
332
|
+
/**
|
|
333
|
+
* The pre-rendered drawing a diagram's data part points at.
|
|
334
|
+
*
|
|
335
|
+
* PowerPoint names it from INSIDE the data: `<dsp:dataModelExt relId>` in the
|
|
336
|
+
* data's extension list, and that id is a relationship of the SLIDE, not of the
|
|
337
|
+
* data part. Looked for on the data part alone — where some producers do put it
|
|
338
|
+
* — two corpus decks with a `drawing1.xml` sitting right there reported having
|
|
339
|
+
* no drawing at all and rendered nothing (smartart-missing-bullet,
|
|
340
|
+
* tdf145528_SmartArt_Matrix).
|
|
341
|
+
*
|
|
342
|
+
* @param pkg The package.
|
|
343
|
+
* @param slidePath The slide the diagram is on.
|
|
344
|
+
* @param data The resolved `dgm:relIds@r:dm` data part.
|
|
345
|
+
* @returns The drawing part, or undefined when the deck ships none.
|
|
346
|
+
*/
|
|
347
|
+
function drawingPart(pkg, slidePath, data) {
|
|
348
|
+
const extRelId = parseXml(data.data).map((root) => poFindDescendant(root, "dsp:dataModelExt")).map((ext) => ext ? poAttr(ext, "relId") : void 0).find((id) => id !== void 0);
|
|
349
|
+
const bySlide = extRelId !== void 0 ? pkg.getPartRelationships(slidePath).find((r) => r.id === extRelId) : void 0;
|
|
350
|
+
if (bySlide) {
|
|
351
|
+
const part = pkg.resolveRelatedPart(slidePath, bySlide);
|
|
352
|
+
if (part) return part;
|
|
353
|
+
}
|
|
354
|
+
const own = pkg.getPartRelationships(data.path).find((r) => r.type.endsWith("/diagramDrawing"));
|
|
355
|
+
if (own) return pkg.resolveRelatedPart(data.path, own);
|
|
356
|
+
const onSlide = pkg.getPartRelationships(slidePath).filter((r) => r.type.endsWith("/diagramDrawing"));
|
|
357
|
+
return onSlide.length === 1 && onSlide[0] ? pkg.resolveRelatedPart(slidePath, onSlide[0]) : void 0;
|
|
358
|
+
}
|
|
359
|
+
function slideStylesFor(pkg, slidePath, cache, resources, charts, onLoss, deckDefaultTextStyle, slideSize, slideAlias) {
|
|
231
360
|
const layoutRel = pkg.getPartRelationships(slidePath).find((r) => r.type.endsWith("/slideLayout"));
|
|
232
361
|
const layout = layoutRel ? pkg.resolveRelatedPart(slidePath, layoutRel) : void 0;
|
|
233
362
|
if (!layout) return { colors: defaultColorResolver };
|
|
234
|
-
const
|
|
363
|
+
const key = slideAlias ? `${layout.path}|${aliasKey(slideAlias)}` : layout.path;
|
|
364
|
+
const cached = cache.get(key);
|
|
235
365
|
if (cached) return cached;
|
|
236
366
|
const masterRel = pkg.getPartRelationships(layout.path).find((r) => r.type.endsWith("/slideMaster"));
|
|
237
367
|
const master = masterRel ? pkg.resolveRelatedPart(layout.path, masterRel) : void 0;
|
|
238
|
-
const colors = master ? deckColorResolver(pkg, master.path) : defaultColorResolver;
|
|
239
368
|
const layoutTree = parseXml(layout.data);
|
|
240
369
|
const masterTree = master ? parseXml(master.data) : void 0;
|
|
241
|
-
const
|
|
242
|
-
const
|
|
370
|
+
const inheritedAlias = overrideAlias(layoutTree, "p:sldLayout") ?? (masterTree ? masterAlias(masterTree) : void 0);
|
|
371
|
+
const alias = slideAlias ?? inheritedAlias;
|
|
372
|
+
const theme = master ? themePart(pkg, master.path) : void 0;
|
|
373
|
+
const colors = master ? deckColorResolver(theme?.data, alias) : defaultColorResolver;
|
|
374
|
+
const inheritedColors = slideAlias === void 0 || !master ? colors : deckColorResolver(theme?.data, inheritedAlias);
|
|
375
|
+
const themeFills = theme ? {
|
|
376
|
+
fills: parseThemeFillStyles(theme.data),
|
|
377
|
+
backgrounds: parseThemeBgFillStyles(theme.data),
|
|
378
|
+
resolveImage: makeSlideImageResolver(pkg, theme.path, resources)
|
|
379
|
+
} : void 0;
|
|
380
|
+
const themeLineWidths = theme ? parseThemeLineWidths(theme.data) : void 0;
|
|
381
|
+
const themeFonts = theme ? parseThemeFonts(theme.data) : void 0;
|
|
382
|
+
const cascade = buildPlaceholderCascade(layoutTree, masterTree, colors, parseLevelStyles(deckDefaultTextStyle, colors, themeFonts), themeFonts);
|
|
383
|
+
const background = partBackground(layoutTree, "p:sldLayout", inheritedColors, makeSlideImageResolver(pkg, layout.path, resources), themeFills) ?? (masterTree && master ? partBackground(masterTree, "p:sldMaster", inheritedColors, makeSlideImageResolver(pkg, master.path, resources), themeFills) : void 0);
|
|
384
|
+
const deps = {
|
|
385
|
+
colors: inheritedColors,
|
|
386
|
+
resources,
|
|
387
|
+
charts,
|
|
388
|
+
onLoss,
|
|
389
|
+
slideSize,
|
|
390
|
+
...themeFills ? { themeFills } : {},
|
|
391
|
+
...themeLineWidths && themeLineWidths.length > 0 ? { themeLineWidths } : {},
|
|
392
|
+
...background ? { background } : {}
|
|
393
|
+
};
|
|
394
|
+
const inheritedShapes = [];
|
|
395
|
+
if (masterTree && master && showMasterShapes(layoutTree, "p:sldLayout")) inheritedShapes.push(...partShapes(pkg, master.path, masterTree, "p:sldMaster", deps));
|
|
396
|
+
inheritedShapes.push(...partShapes(pkg, layout.path, layoutTree, "p:sldLayout", deps));
|
|
243
397
|
const styles = {
|
|
244
398
|
cascade,
|
|
245
399
|
colors,
|
|
246
|
-
...
|
|
400
|
+
...themeFonts ? { themeFonts } : {},
|
|
401
|
+
...themeFills ? { themeFills } : {},
|
|
402
|
+
...themeLineWidths && themeLineWidths.length > 0 ? { themeLineWidths } : {},
|
|
403
|
+
...background ? { background } : {},
|
|
404
|
+
...inheritedShapes.length > 0 ? { inheritedShapes } : {}
|
|
247
405
|
};
|
|
248
|
-
cache.set(
|
|
406
|
+
cache.set(key, styles);
|
|
249
407
|
return styles;
|
|
250
408
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
409
|
+
/**
|
|
410
|
+
* A master's or layout's own drawn shapes — everything in its `p:spTree` that
|
|
411
|
+
* is not a placeholder, read with resolvers bound to THAT part: a logo's image
|
|
412
|
+
* relationship, a chart's, a hyperlink's are all scoped to the part that names
|
|
413
|
+
* them.
|
|
414
|
+
*/
|
|
415
|
+
function partShapes(pkg, path, tree, root, deps) {
|
|
416
|
+
const part = tree.find((n) => poIs(n, root));
|
|
417
|
+
const cSld = part ? poChildren(part).find((c) => poIs(c, "p:cSld")) : void 0;
|
|
418
|
+
const spTree = cSld ? poChildren(cSld).find((c) => poIs(c, "p:spTree")) : void 0;
|
|
419
|
+
if (!spTree) return [];
|
|
420
|
+
return parseSlideShapes(spTree, {
|
|
421
|
+
colors: deps.colors,
|
|
422
|
+
...deps.themeFills ? { themeFills: deps.themeFills } : {},
|
|
423
|
+
...deps.themeLineWidths ? { themeLineWidths: deps.themeLineWidths } : {},
|
|
424
|
+
...deps.background ? { backgroundFill: deps.background } : {},
|
|
425
|
+
slideSize: deps.slideSize,
|
|
426
|
+
resolveImage: makeSlideImageResolver(pkg, path, deps.resources),
|
|
427
|
+
resolveChart: makeSlideChartResolver(pkg, path, deps.charts, deps.colors, deps.resources),
|
|
428
|
+
resolveHyperlink: makeHyperlinkResolver(pkg, path),
|
|
429
|
+
resolveDiagram: makeSlideDiagramResolver(pkg, path),
|
|
430
|
+
onLoss: deps.onLoss
|
|
431
|
+
}, void 0, true);
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* §19.3.1.38/§19.3.1.39 `@showMasterSp` — whether this part draws the shapes it
|
|
435
|
+
* inherits. Absent, it does.
|
|
436
|
+
*/
|
|
437
|
+
function showMasterShapes(tree, root) {
|
|
438
|
+
const part = tree.find((n) => poIs(n, root));
|
|
439
|
+
return part === void 0 || poAttr(part, "showMasterSp") !== "0";
|
|
440
|
+
}
|
|
441
|
+
/** The master's `p:clrMap` (§19.3.1.6) as a scheme-alias table. */
|
|
442
|
+
function masterAlias(masterTree) {
|
|
443
|
+
const master = masterTree.find((n) => poIs(n, "p:sldMaster"));
|
|
444
|
+
const map = master ? poChildren(master).find((c) => poIs(c, "p:clrMap")) : void 0;
|
|
445
|
+
return map ? aliasFromAttrs(map) : void 0;
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* A layout's or slide's `p:clrMapOvr` (§19.3.1.7) as a scheme-alias table, or
|
|
449
|
+
* `undefined` when it holds `a:masterClrMapping` — which says "the master's",
|
|
450
|
+
* i.e. nothing of its own.
|
|
451
|
+
*/
|
|
452
|
+
function overrideAlias(tree, root) {
|
|
453
|
+
const part = tree.find((n) => poIs(n, root));
|
|
454
|
+
const ovr = part ? poChildren(part).find((c) => poIs(c, "p:clrMapOvr")) : void 0;
|
|
455
|
+
const own = ovr ? poChildren(ovr).find((c) => poIs(c, "a:overrideClrMapping")) : void 0;
|
|
456
|
+
return own ? aliasFromAttrs(own) : void 0;
|
|
457
|
+
}
|
|
458
|
+
function aliasFromAttrs(node) {
|
|
459
|
+
const alias = {};
|
|
460
|
+
for (const name of [
|
|
461
|
+
"bg1",
|
|
462
|
+
"tx1",
|
|
463
|
+
"bg2",
|
|
464
|
+
"tx2"
|
|
465
|
+
]) {
|
|
466
|
+
const slot = poAttr(node, name);
|
|
467
|
+
if (slot !== void 0) alias[name] = slot;
|
|
468
|
+
}
|
|
469
|
+
return alias;
|
|
470
|
+
}
|
|
471
|
+
/** A stable key for an alias table, so the per-layout cache can include it. */
|
|
472
|
+
function aliasKey(alias) {
|
|
473
|
+
return Object.entries(alias).sort(([a], [b]) => a < b ? -1 : 1).map(([k, v]) => `${k}=${v}`).join(",");
|
|
474
|
+
}
|
|
475
|
+
function deckColorResolver(theme, alias) {
|
|
255
476
|
const palette = new Map(DEFAULT_THEME_PALETTE);
|
|
256
|
-
for (const [slot, hex] of parseTheme(theme
|
|
257
|
-
|
|
477
|
+
if (theme) for (const [slot, hex] of parseTheme(theme)) palette.set(slot, hex);
|
|
478
|
+
if (!theme && !alias) return defaultColorResolver;
|
|
479
|
+
return makeColorResolver(palette, {
|
|
480
|
+
...DEFAULT_SCHEME_ALIAS,
|
|
481
|
+
...alias
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
/** The master's theme part, if it has one — its path names its own pictures. */
|
|
485
|
+
function themePart(pkg, masterPath) {
|
|
486
|
+
const rel = pkg.getPartRelationships(masterPath).find((r) => r.type.endsWith("/theme"));
|
|
487
|
+
return rel ? pkg.resolveRelatedPart(masterPath, rel) : void 0;
|
|
258
488
|
}
|
|
259
489
|
/**
|
|
260
490
|
* The {@link DocumentReader} for PresentationML (`.pptx`): sniffs the OPC ZIP for
|
|
@@ -271,7 +501,7 @@ var pptxReader = {
|
|
|
271
501
|
FEATURES.charts,
|
|
272
502
|
FEATURES.tables
|
|
273
503
|
]),
|
|
274
|
-
sniff: (bytes) => bytes[0] === 80 && bytes[1] === 75 &&
|
|
504
|
+
sniff: (bytes) => bytes[0] === 80 && bytes[1] === 75 && packageHasPart(bytes, "ppt/presentation.xml"),
|
|
275
505
|
read: (bytes) => readPptx(bytes)
|
|
276
506
|
};
|
|
277
507
|
//#endregion
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PoNode } from '../core/po-helpers.js';
|
|
2
|
+
/**
|
|
3
|
+
* The built-in table style a GUID names, or `undefined` when it is not one this
|
|
4
|
+
* reader holds.
|
|
5
|
+
*
|
|
6
|
+
* @param styleId The `a:tableStyleId` a table states.
|
|
7
|
+
* @param parse The module's XML reader, injected so this file needs none.
|
|
8
|
+
*/
|
|
9
|
+
export declare function presetTableStyle(styleId: string, parse: (xml: string) => ReadonlyArray<PoNode>): PoNode | undefined;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { poAttr, poIs } from "../core/po-helpers.js";
|
|
2
|
+
//#region src/pptx/preset-table-styles.ts
|
|
3
|
+
/** The gallery styles this reader knows, by the GUID a table names. */
|
|
4
|
+
var PRESETS = new Map([
|
|
5
|
+
["{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}", "<a:tblStyle styleId=\"{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}\" styleName=\"Medium Style 2 - Accent 1\"><a:wholeTbl><a:tcTxStyle><a:fontRef idx=\"minor\"><a:prstClr val=\"black\"/></a:fontRef><a:schemeClr val=\"dk1\"/></a:tcTxStyle><a:tcStyle><a:tcBdr><a:left><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:left><a:right><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:right><a:top><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:top><a:bottom><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:bottom><a:insideH><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:insideH><a:insideV><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:insideV></a:tcBdr><a:fill><a:solidFill><a:schemeClr val=\"accent1\"><a:tint val=\"20000\"/></a:schemeClr></a:solidFill></a:fill></a:tcStyle></a:wholeTbl><a:band1H><a:tcStyle><a:tcBdr/><a:fill><a:solidFill><a:schemeClr val=\"accent1\"><a:tint val=\"40000\"/></a:schemeClr></a:solidFill></a:fill></a:tcStyle></a:band1H><a:band2H><a:tcStyle><a:tcBdr/></a:tcStyle></a:band2H><a:band1V><a:tcStyle><a:tcBdr/><a:fill><a:solidFill><a:schemeClr val=\"accent1\"><a:tint val=\"40000\"/></a:schemeClr></a:solidFill></a:fill></a:tcStyle></a:band1V><a:band2V><a:tcStyle><a:tcBdr/></a:tcStyle></a:band2V><a:lastCol><a:tcTxStyle b=\"on\"><a:fontRef idx=\"minor\"><a:prstClr val=\"black\"/></a:fontRef><a:schemeClr val=\"lt1\"/></a:tcTxStyle><a:tcStyle><a:tcBdr/><a:fill><a:solidFill><a:schemeClr val=\"accent1\"/></a:solidFill></a:fill></a:tcStyle></a:lastCol><a:firstCol><a:tcTxStyle b=\"on\"><a:fontRef idx=\"minor\"><a:prstClr val=\"black\"/></a:fontRef><a:schemeClr val=\"lt1\"/></a:tcTxStyle><a:tcStyle><a:tcBdr/><a:fill><a:solidFill><a:schemeClr val=\"accent1\"/></a:solidFill></a:fill></a:tcStyle></a:firstCol><a:lastRow><a:tcTxStyle b=\"on\"><a:fontRef idx=\"minor\"><a:prstClr val=\"black\"/></a:fontRef><a:schemeClr val=\"lt1\"/></a:tcTxStyle><a:tcStyle><a:tcBdr><a:top><a:ln w=\"38100\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:top></a:tcBdr><a:fill><a:solidFill><a:schemeClr val=\"accent1\"/></a:solidFill></a:fill></a:tcStyle></a:lastRow><a:firstRow><a:tcTxStyle b=\"on\"><a:fontRef idx=\"minor\"><a:prstClr val=\"black\"/></a:fontRef><a:schemeClr val=\"lt1\"/></a:tcTxStyle><a:tcStyle><a:tcBdr><a:bottom><a:ln w=\"38100\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:bottom></a:tcBdr><a:fill><a:solidFill><a:schemeClr val=\"accent1\"/></a:solidFill></a:fill></a:tcStyle></a:firstRow></a:tblStyle>"],
|
|
6
|
+
["{073A0DAA-6AF3-43AB-8588-CEC1D06C72B9}", "<a:tblStyle styleId=\"{073A0DAA-6AF3-43AB-8588-CEC1D06C72B9}\" styleName=\"Medium Style 2\"><a:wholeTbl><a:tcTxStyle><a:fontRef idx=\"minor\"><a:prstClr val=\"black\"/></a:fontRef><a:schemeClr val=\"dk1\"/></a:tcTxStyle><a:tcStyle><a:tcBdr><a:left><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:left><a:right><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:right><a:top><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:top><a:bottom><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:bottom><a:insideH><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:insideH><a:insideV><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:insideV></a:tcBdr><a:fill><a:solidFill><a:schemeClr val=\"dk1\"><a:tint val=\"20000\"/></a:schemeClr></a:solidFill></a:fill></a:tcStyle></a:wholeTbl><a:band1H><a:tcStyle><a:tcBdr/><a:fill><a:solidFill><a:schemeClr val=\"dk1\"><a:tint val=\"40000\"/></a:schemeClr></a:solidFill></a:fill></a:tcStyle></a:band1H><a:band2H><a:tcStyle><a:tcBdr/></a:tcStyle></a:band2H><a:band1V><a:tcStyle><a:tcBdr/><a:fill><a:solidFill><a:schemeClr val=\"dk1\"><a:tint val=\"40000\"/></a:schemeClr></a:solidFill></a:fill></a:tcStyle></a:band1V><a:band2V><a:tcStyle><a:tcBdr/></a:tcStyle></a:band2V><a:lastCol><a:tcTxStyle b=\"on\"><a:fontRef idx=\"minor\"><a:prstClr val=\"black\"/></a:fontRef><a:schemeClr val=\"lt1\"/></a:tcTxStyle><a:tcStyle><a:tcBdr/><a:fill><a:solidFill><a:schemeClr val=\"dk1\"/></a:solidFill></a:fill></a:tcStyle></a:lastCol><a:firstCol><a:tcTxStyle b=\"on\"><a:fontRef idx=\"minor\"><a:prstClr val=\"black\"/></a:fontRef><a:schemeClr val=\"lt1\"/></a:tcTxStyle><a:tcStyle><a:tcBdr/><a:fill><a:solidFill><a:schemeClr val=\"dk1\"/></a:solidFill></a:fill></a:tcStyle></a:firstCol><a:lastRow><a:tcTxStyle b=\"on\"><a:fontRef idx=\"minor\"><a:prstClr val=\"black\"/></a:fontRef><a:schemeClr val=\"lt1\"/></a:tcTxStyle><a:tcStyle><a:tcBdr><a:top><a:ln w=\"38100\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:top></a:tcBdr><a:fill><a:solidFill><a:schemeClr val=\"dk1\"/></a:solidFill></a:fill></a:tcStyle></a:lastRow><a:firstRow><a:tcTxStyle b=\"on\"><a:fontRef idx=\"minor\"><a:prstClr val=\"black\"/></a:fontRef><a:schemeClr val=\"lt1\"/></a:tcTxStyle><a:tcStyle><a:tcBdr><a:bottom><a:ln w=\"38100\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill></a:ln></a:bottom></a:tcBdr><a:fill><a:solidFill><a:schemeClr val=\"dk1\"/></a:solidFill></a:fill></a:tcStyle></a:firstRow></a:tblStyle>"],
|
|
7
|
+
["{5940675A-B579-460E-94D1-54222C63F5DA}", "<a:tblStyle styleId=\"{5940675A-B579-460E-94D1-54222C63F5DA}\" styleName=\"No Style, Table Grid\"><a:wholeTbl><a:tcTxStyle><a:fontRef idx=\"minor\"><a:scrgbClr r=\"0\" g=\"0\" b=\"0\"/></a:fontRef><a:schemeClr val=\"tx1\"/></a:tcTxStyle><a:tcStyle><a:tcBdr><a:left><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"tx1\"/></a:solidFill></a:ln></a:left><a:right><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"tx1\"/></a:solidFill></a:ln></a:right><a:top><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"tx1\"/></a:solidFill></a:ln></a:top><a:bottom><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"tx1\"/></a:solidFill></a:ln></a:bottom><a:insideH><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"tx1\"/></a:solidFill></a:ln></a:insideH><a:insideV><a:ln w=\"12700\" cmpd=\"sng\"><a:solidFill><a:schemeClr val=\"tx1\"/></a:solidFill></a:ln></a:insideV></a:tcBdr><a:fill><a:noFill/></a:fill></a:tcStyle></a:wholeTbl></a:tblStyle>"],
|
|
8
|
+
["{2D5ABB26-0587-4C30-8999-92F81FD0307C}", "<a:tblStyle styleId=\"{2D5ABB26-0587-4C30-8999-92F81FD0307C}\" styleName=\"No Style, No Grid\"><a:wholeTbl><a:tcTxStyle><a:fontRef idx=\"minor\"><a:scrgbClr r=\"0\" g=\"0\" b=\"0\"/></a:fontRef><a:schemeClr val=\"tx1\"/></a:tcTxStyle><a:tcStyle><a:tcBdr><a:left><a:ln><a:noFill/></a:ln></a:left><a:right><a:ln><a:noFill/></a:ln></a:right><a:top><a:ln><a:noFill/></a:ln></a:top><a:bottom><a:ln><a:noFill/></a:ln></a:bottom><a:insideH><a:ln><a:noFill/></a:ln></a:insideH><a:insideV><a:ln><a:noFill/></a:ln></a:insideV></a:tcBdr><a:fill><a:noFill/></a:fill></a:tcStyle></a:wholeTbl></a:tblStyle>"]
|
|
9
|
+
]);
|
|
10
|
+
var parsed = /* @__PURE__ */ new Map();
|
|
11
|
+
/**
|
|
12
|
+
* The built-in table style a GUID names, or `undefined` when it is not one this
|
|
13
|
+
* reader holds.
|
|
14
|
+
*
|
|
15
|
+
* @param styleId The `a:tableStyleId` a table states.
|
|
16
|
+
* @param parse The module's XML reader, injected so this file needs none.
|
|
17
|
+
*/
|
|
18
|
+
function presetTableStyle(styleId, parse) {
|
|
19
|
+
const seen = parsed.get(styleId);
|
|
20
|
+
if (seen !== void 0 || parsed.has(styleId)) return seen;
|
|
21
|
+
const xml = PRESETS.get(styleId);
|
|
22
|
+
const style = xml ? parse(xml).find((n) => poIs(n, "a:tblStyle") && poAttr(n, "styleId") === styleId) : void 0;
|
|
23
|
+
parsed.set(styleId, style);
|
|
24
|
+
return style;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { presetTableStyle };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BodyElement, FloatAnchor, ShapeBlock, ShapeFill, ShapeGeometry, ShapeTextBody } from '../core/document-model/index.js';
|
|
2
2
|
import { ColorResolver } from '../core/drawingml/colors.js';
|
|
3
|
+
import { ThemeFonts } from '../core/drawingml/theme-parser.js';
|
|
3
4
|
import { Loss, Pt, ResourceId } from '../core/ir/index.js';
|
|
4
5
|
import { PoNode } from '../core/po-helpers.js';
|
|
5
6
|
import { PlaceholderCascade } from './placeholder-cascade.js';
|
|
@@ -15,6 +16,35 @@ export interface SlideContext {
|
|
|
15
16
|
readonly cascade?: PlaceholderCascade;
|
|
16
17
|
/** A slide-scoped blip relationship id (`a:blip @r:embed`) → a stored resource (PX3a). */
|
|
17
18
|
readonly resolveImage?: (relId: string) => ResourceId | undefined;
|
|
19
|
+
/** The deck theme's fill style lists, for a `p:bgRef` on this slide. */
|
|
20
|
+
readonly themeFills?: ThemeFillStyles;
|
|
21
|
+
/**
|
|
22
|
+
* §20.1.4.1.16 — the two typefaces the deck's theme names. A run states its
|
|
23
|
+
* own by TOKEN (`+mn-lt`) more often than by name.
|
|
24
|
+
*/
|
|
25
|
+
readonly themeFonts?: ThemeFonts;
|
|
26
|
+
/** §20.1.4.1.21 `a:lnStyleLst` — the widths an `a:lnRef` indexes, in points. */
|
|
27
|
+
readonly themeLineWidths?: ReadonlyArray<number>;
|
|
28
|
+
/**
|
|
29
|
+
* §19.3.1.43 — the slide's own background fill, which a shape marked
|
|
30
|
+
* `useBgFill` is painted with.
|
|
31
|
+
*/
|
|
32
|
+
readonly backgroundFill?: ShapeFill;
|
|
33
|
+
/** The slide's size, which says WHERE that background lies under a shape. */
|
|
34
|
+
readonly slideSize?: {
|
|
35
|
+
readonly widthPt: Pt;
|
|
36
|
+
readonly heightPt: Pt;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* §19.3.2.4 — the picture an embedded object shows, by the `@spid` of its
|
|
40
|
+
* shape in the slide's legacy VML drawing.
|
|
41
|
+
*/
|
|
42
|
+
readonly resolveOlePreview?: (spid: string) => ResourceId | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* §20.1.4.2.24 — the `a:tblStyle` a table names by GUID, from the deck's
|
|
45
|
+
* `tableStyles.xml`. A table that names none wears none.
|
|
46
|
+
*/
|
|
47
|
+
readonly resolveTableStyle?: (styleId: string | undefined) => PoNode | undefined;
|
|
18
48
|
/** A chart relationship id (`c:chart @r:id`) → its document-unique key (PX4a). */
|
|
19
49
|
readonly resolveChart?: (relId: string) => string | undefined;
|
|
20
50
|
/**
|
|
@@ -50,7 +80,7 @@ type GroupTransform = (box: ShapeBoxEmu) => ShapeBoxEmu;
|
|
|
50
80
|
* @param transform Maps child-space boxes to the slide (identity at the top level).
|
|
51
81
|
* @returns The container's shapes as positioned {@link BodyElement}s.
|
|
52
82
|
*/
|
|
53
|
-
export declare function parseSlideShapes(container: PoNode, ctx?: SlideContext, transform?: GroupTransform): Array<BodyElement>;
|
|
83
|
+
export declare function parseSlideShapes(container: PoNode, ctx?: SlideContext, transform?: GroupTransform, skipPlaceholders?: boolean): Array<BodyElement>;
|
|
54
84
|
/**
|
|
55
85
|
* The diagram's child shapes live in the spTree's own coordinate space
|
|
56
86
|
* (`dsp:grpSpPr/a:xfrm` `chOff`/`chExt`); map that onto a target box (the frame on
|
|
@@ -106,13 +136,43 @@ export declare function parseDiagramNodes(spTree: PoNode, transform: GroupTransf
|
|
|
106
136
|
*/
|
|
107
137
|
export declare function parseDiagramDrawing(spTree: PoNode, transform: GroupTransform, makeFloat: (box: ShapeBoxEmu) => FloatAnchor, colors: ColorResolver, resolveLink: LinkResolver): Array<ShapeBlock>;
|
|
108
138
|
/**
|
|
109
|
-
* `p:
|
|
110
|
-
*
|
|
111
|
-
|
|
112
|
-
|
|
139
|
+
* The theme fill styles a `p:bgRef` indexes into (§19.3.1.2), as the raw nodes
|
|
140
|
+
* the fill readers take.
|
|
141
|
+
*/
|
|
142
|
+
export interface ThemeFillStyles {
|
|
143
|
+
/** `a:fillStyleLst` — what an index of 1…999 names. */
|
|
144
|
+
readonly fills: ReadonlyArray<PoNode>;
|
|
145
|
+
/** `a:bgFillStyleLst` — what an index past 1000 names, 1001 being the first. */
|
|
146
|
+
readonly backgrounds: ReadonlyArray<PoNode>;
|
|
147
|
+
/**
|
|
148
|
+
* A picture named inside a style belongs to the THEME part: the Office
|
|
149
|
+
* "Berlin" background is a photograph the theme carries and its `r:embed`
|
|
150
|
+
* means nothing in the master's relationships (corpus: tdf123684, where it
|
|
151
|
+
* resolved to a different image entirely).
|
|
152
|
+
*/
|
|
153
|
+
readonly resolveImage?: (relId: string) => ResourceId | undefined;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* `p:bg` → the background fill, or `undefined` when it declares none.
|
|
157
|
+
*
|
|
158
|
+
* Two spellings. `p:bgPr` carries the fill itself — solid, gradient, or a
|
|
159
|
+
* PICTURE, which needs the owning part's image resolver since the blip's
|
|
160
|
+
* relationship is scoped to the part the background is written in. `p:bgRef`
|
|
161
|
+
* (§19.3.1.2) carries no fill at all: an index into the theme's style lists and
|
|
162
|
+
* the colour to put wherever that style says `phClr`. Read as its colour alone
|
|
163
|
+
* — which is all this did — a deck whose theme opens with a black-to-grey
|
|
164
|
+
* gradient came out flat, and one whose first background slot is a picture came
|
|
165
|
+
* out a single colour.
|
|
166
|
+
*
|
|
113
167
|
* Used for the slide's own background and the inherited layout/master one (PX5b).
|
|
168
|
+
*
|
|
169
|
+
* @param bg The `p:bg` node.
|
|
170
|
+
* @param colors The deck's colour resolver.
|
|
171
|
+
* @param resolveImage Resolver for a picture background's relationship, scoped
|
|
172
|
+
* to the part this `p:bg` is written in.
|
|
173
|
+
* @param theme The theme's fill style lists, for a `p:bgRef`.
|
|
114
174
|
*/
|
|
115
|
-
export declare function parseBackgroundFill(bg: PoNode, colors: ColorResolver): ShapeFill | undefined;
|
|
175
|
+
export declare function parseBackgroundFill(bg: PoNode, colors: ColorResolver, resolveImage?: (relId: string) => ResourceId | undefined, theme?: ThemeFillStyles): ShapeFill | undefined;
|
|
116
176
|
/**
|
|
117
177
|
* A full-slide backdrop element for a background fill: a rectangle covering the
|
|
118
178
|
* page, anchored behind the content (PX5b).
|
|
@@ -123,10 +183,18 @@ export declare function parseBackgroundFill(bg: PoNode, colors: ColorResolver):
|
|
|
123
183
|
*/
|
|
124
184
|
export declare function backdropElement(fill: ShapeFill, widthPt: Pt, heightPt: Pt): BodyElement;
|
|
125
185
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
186
|
+
* The same element, painted BEHIND the slide's own content.
|
|
187
|
+
*
|
|
188
|
+
* §19.3.1 — a slide's shape tree is drawn over its layout's, and that over the
|
|
189
|
+
* master's; nothing a deck states once can bury what a slide puts on it. Our
|
|
190
|
+
* page paints by KIND (every image, then every shape), so without this a
|
|
191
|
+
* layout's white card landed on top of the photograph the slide is made of —
|
|
192
|
+
* themes.pptx's fifth slide is one picture and it vanished under the card.
|
|
193
|
+
*
|
|
194
|
+
* @param el The inherited element.
|
|
195
|
+
* @returns The element with its float sunk to the backdrop layer.
|
|
129
196
|
*/
|
|
197
|
+
export declare function asBackdrop(el: BodyElement): BodyElement;
|
|
130
198
|
export declare function parseGeometry(spPr: PoNode | undefined): ShapeGeometry;
|
|
131
199
|
/**
|
|
132
200
|
* `p:txBody` → {@link ShapeTextBody}. `a:bodyPr` carries the insets and the
|
|
@@ -141,5 +209,5 @@ export declare function parseGeometry(spPr: PoNode | undefined): ShapeGeometry;
|
|
|
141
209
|
* @param resolveLink A run hyperlink resolver, or `undefined`.
|
|
142
210
|
* @returns The text body, or `undefined` when it holds no paragraphs.
|
|
143
211
|
*/
|
|
144
|
-
export declare function parseTxBody(txBody: PoNode, ph: PlaceholderRef | undefined, cascade: PlaceholderCascade | undefined, colors: ColorResolver, resolveLink: LinkResolver): ShapeTextBody | undefined;
|
|
212
|
+
export declare function parseTxBody(txBody: PoNode, ph: PlaceholderRef | undefined, cascade: PlaceholderCascade | undefined, colors: ColorResolver, resolveLink: LinkResolver, styleColor?: string, themeFonts?: ThemeFonts): ShapeTextBody | undefined;
|
|
145
213
|
export {};
|