reamkit 1.22.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/converter/ream.d.ts +16 -0
- package/dist/esm/core/converter/ream.js +59 -9
- package/dist/esm/core/document-model/types.d.ts +18 -0
- package/dist/esm/core/drawingml/chart-geometry.js +11 -5
- package/dist/esm/core/drawingml/colors.d.ts +4 -2
- package/dist/esm/core/drawingml/colors.js +15 -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 +137 -23
- package/dist/esm/core/metafile/picture.d.ts +12 -1
- package/dist/esm/core/metafile/wmf.js +149 -9
- 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/excel/print-model.js +3 -1
- 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/layout/page-doc.d.ts +39 -0
- package/dist/esm/layout/styled-layout.d.ts +2 -2
- package/dist/esm/layout/styled-layout.js +301 -35
- package/dist/esm/pdf/styled-page-emitter.js +35 -2
- 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/placeholder-cascade.d.ts +73 -6
- package/dist/esm/pptx/placeholder-cascade.js +114 -18
- 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 +27 -5
- 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 +7 -1
- package/dist/esm/pptx/slide-parser.js +106 -33
- package/dist/esm/pptx/sp-helpers.d.ts +2 -1
- package/dist/esm/pptx/sp-helpers.js +3 -2
- package/dist/esm/pptx/table-style.d.ts +9 -1
- package/dist/esm/pptx/table-style.js +49 -7
- 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 +6 -3
- 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.js +31 -19
- 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
|
/**
|
|
@@ -7,9 +7,12 @@ import { poAttr, poChildren, poFindDescendant, poIntAttr, poIs } from "../core/p
|
|
|
7
7
|
import { packageHasPart } from "../core/bytes.js";
|
|
8
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, parseThemeBgFillStyles, parseThemeFillStyles, parseThemeLineWidths } 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 { loadPptxEmbeddedFonts } from "./embedded-fonts.js";
|
|
14
|
+
import { presetTableStyle } from "./preset-table-styles.js";
|
|
15
|
+
import { resolveAlternateContent } from "../core/opc/alternate-content.js";
|
|
13
16
|
import { buildPlaceholderCascade, parseLevelStyles } from "./placeholder-cascade.js";
|
|
14
17
|
import { normalizeSpid, parseVmlImageRels } from "./ole-preview.js";
|
|
15
18
|
import { asBackdrop, backdropElement, parseBackgroundFill, parseSlideShapes } from "./slide-parser.js";
|
|
@@ -19,6 +22,7 @@ var EMU_PER_PT = 12700;
|
|
|
19
22
|
var DEFAULT_CX = 9144e3;
|
|
20
23
|
var DEFAULT_CY = 6858e3;
|
|
21
24
|
var decoder = new TextDecoder();
|
|
25
|
+
var encoder = new TextEncoder();
|
|
22
26
|
var parser = new XMLParser({
|
|
23
27
|
htmlEntities: true,
|
|
24
28
|
ignoreAttributes: false,
|
|
@@ -55,9 +59,11 @@ function readPptx(bytes) {
|
|
|
55
59
|
let cx = DEFAULT_CX;
|
|
56
60
|
let cy = DEFAULT_CY;
|
|
57
61
|
let defaultTextStyle;
|
|
62
|
+
let embeddedFonts = /* @__PURE__ */ new Map();
|
|
58
63
|
const slideParts = [];
|
|
59
64
|
if (presData) {
|
|
60
65
|
const pres = parser.parse(decoder.decode(presData)).find((n) => poIs(n, "p:presentation"));
|
|
66
|
+
embeddedFonts = loadPptxEmbeddedFonts(pkg, presPath, pres, (loss) => losses.push(loss));
|
|
61
67
|
const kids = pres ? poChildren(pres) : [];
|
|
62
68
|
defaultTextStyle = kids.find((c) => poIs(c, "p:defaultTextStyle"));
|
|
63
69
|
const sldSz = kids.find((c) => poIs(c, "p:sldSz"));
|
|
@@ -123,6 +129,7 @@ function readPptx(bytes) {
|
|
|
123
129
|
widthPt: pageW,
|
|
124
130
|
heightPt: pageH
|
|
125
131
|
},
|
|
132
|
+
...styles.themeFonts ? { themeFonts: styles.themeFonts } : {},
|
|
126
133
|
...styles.themeFills ? { themeFills: styles.themeFills } : {},
|
|
127
134
|
...styles.themeLineWidths ? { themeLineWidths: styles.themeLineWidths } : {},
|
|
128
135
|
resolveImage: makeSlideImageResolver(pkg, part.path, resources),
|
|
@@ -162,7 +169,8 @@ function readPptx(bytes) {
|
|
|
162
169
|
section,
|
|
163
170
|
styles: EMPTY_STYLE_SHEET,
|
|
164
171
|
resources,
|
|
165
|
-
...charts.size > 0 ? { charts } : {}
|
|
172
|
+
...charts.size > 0 ? { charts } : {},
|
|
173
|
+
...embeddedFonts.size > 0 ? { embeddedFonts } : {}
|
|
166
174
|
},
|
|
167
175
|
losses
|
|
168
176
|
};
|
|
@@ -171,9 +179,17 @@ function readPptx(bytes) {
|
|
|
171
179
|
* Parse an OOXML part's bytes into preserve-order {@link PoNode} roots with the
|
|
172
180
|
* module's shared, presentation-tuned {@link XMLParser} (attributes kept, values
|
|
173
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.
|
|
174
190
|
*/
|
|
175
191
|
function parseXml(data) {
|
|
176
|
-
return parser.parse(decoder.decode(data));
|
|
192
|
+
return parser.parse(resolveAlternateContent(decoder.decode(data)));
|
|
177
193
|
}
|
|
178
194
|
function parseSlide(tree, ctx, inheritedBg, pageW, pageH, inheritedShapes = []) {
|
|
179
195
|
const sld = tree.find((n) => poIs(n, "p:sld"));
|
|
@@ -247,6 +263,9 @@ function makeOlePreviewResolver(pkg, slidePath, resources) {
|
|
|
247
263
|
* table that names none wears none — table-with-no-theme's two rows are bare
|
|
248
264
|
* text in a plain frame, not the blue banding `@def` points at.
|
|
249
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
|
+
*
|
|
250
269
|
* The part is read once, on the first table in the deck.
|
|
251
270
|
*/
|
|
252
271
|
function makeTableStyleResolver(pkg, presPath) {
|
|
@@ -265,7 +284,8 @@ function makeTableStyleResolver(pkg, presPath) {
|
|
|
265
284
|
}
|
|
266
285
|
}
|
|
267
286
|
}
|
|
268
|
-
|
|
287
|
+
if (styleId === void 0) return void 0;
|
|
288
|
+
return byId.get(styleId) ?? presetTableStyle(styleId, (xml) => parseXml(encoder.encode(xml)));
|
|
269
289
|
};
|
|
270
290
|
}
|
|
271
291
|
function makeHyperlinkResolver(pkg, slidePath) {
|
|
@@ -358,7 +378,8 @@ function slideStylesFor(pkg, slidePath, cache, resources, charts, onLoss, deckDe
|
|
|
358
378
|
resolveImage: makeSlideImageResolver(pkg, theme.path, resources)
|
|
359
379
|
} : void 0;
|
|
360
380
|
const themeLineWidths = theme ? parseThemeLineWidths(theme.data) : void 0;
|
|
361
|
-
const
|
|
381
|
+
const themeFonts = theme ? parseThemeFonts(theme.data) : void 0;
|
|
382
|
+
const cascade = buildPlaceholderCascade(layoutTree, masterTree, colors, parseLevelStyles(deckDefaultTextStyle, colors, themeFonts), themeFonts);
|
|
362
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);
|
|
363
384
|
const deps = {
|
|
364
385
|
colors: inheritedColors,
|
|
@@ -376,6 +397,7 @@ function slideStylesFor(pkg, slidePath, cache, resources, charts, onLoss, deckDe
|
|
|
376
397
|
const styles = {
|
|
377
398
|
cascade,
|
|
378
399
|
colors,
|
|
400
|
+
...themeFonts ? { themeFonts } : {},
|
|
379
401
|
...themeFills ? { themeFills } : {},
|
|
380
402
|
...themeLineWidths && themeLineWidths.length > 0 ? { themeLineWidths } : {},
|
|
381
403
|
...background ? { background } : {},
|
|
@@ -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';
|
|
@@ -17,6 +18,11 @@ export interface SlideContext {
|
|
|
17
18
|
readonly resolveImage?: (relId: string) => ResourceId | undefined;
|
|
18
19
|
/** The deck theme's fill style lists, for a `p:bgRef` on this slide. */
|
|
19
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;
|
|
20
26
|
/** §20.1.4.1.21 `a:lnStyleLst` — the widths an `a:lnRef` indexes, in points. */
|
|
21
27
|
readonly themeLineWidths?: ReadonlyArray<number>;
|
|
22
28
|
/**
|
|
@@ -203,5 +209,5 @@ export declare function parseGeometry(spPr: PoNode | undefined): ShapeGeometry;
|
|
|
203
209
|
* @param resolveLink A run hyperlink resolver, or `undefined`.
|
|
204
210
|
* @returns The text body, or `undefined` when it holds no paragraphs.
|
|
205
211
|
*/
|
|
206
|
-
export declare function parseTxBody(txBody: PoNode, ph: PlaceholderRef | undefined, cascade: PlaceholderCascade | undefined, colors: ColorResolver, resolveLink: LinkResolver, styleColor?: string): 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;
|
|
207
213
|
export {};
|
|
@@ -3,7 +3,7 @@ import { FEATURES } from "../core/ir/features.js";
|
|
|
3
3
|
import { poAttr, poChildren, poFindDescendant, poIntAttr, poIs, poTag, poText } from "../core/po-helpers.js";
|
|
4
4
|
import { defaultColorResolver, placeholderColors, resolveColorNode } from "../core/drawingml/colors.js";
|
|
5
5
|
import { boxFromXfrm, parsePh, parseXfrmBox, rPrToRunProps } from "./sp-helpers.js";
|
|
6
|
-
import { parseBullet } from "./placeholder-cascade.js";
|
|
6
|
+
import { lineSpacing, parseBullet, spacingFractions, spacingFromLineFraction } from "./placeholder-cascade.js";
|
|
7
7
|
import { colorChangeOf, parseCustGeom, parseFill, parseLine, parsePrstGeom, parseShadow, parseXfrm, statesFill, styleRefFill, styleRefFontColor, styleRefLine } from "../word/drawing-parser.js";
|
|
8
8
|
import { cellStyle, lineBorder, tableStyleFlags, tableStyleId, withCellStyle, withoutFill } from "./table-style.js";
|
|
9
9
|
//#region src/pptx/slide-parser.ts
|
|
@@ -116,19 +116,25 @@ function parseSp(sp, ctx, transform) {
|
|
|
116
116
|
const style = poChildren(sp).find((c) => poIs(c, "p:style"));
|
|
117
117
|
const txBody = poChildren(sp).find((c) => poIs(c, "p:txBody"));
|
|
118
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
|
|
121
|
-
const
|
|
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));
|
|
122
127
|
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
128
|
const themeStyles = ctx.themeFills ? {
|
|
128
129
|
fills: ctx.themeFills.fills,
|
|
129
130
|
bgFills: ctx.themeFills.backgrounds
|
|
130
131
|
} : void 0;
|
|
131
|
-
const
|
|
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;
|
|
132
138
|
if (style) {
|
|
133
139
|
const fromStyle = styleRefLine(style, colors, ctx.themeLineWidths);
|
|
134
140
|
if (fromStyle) line = line ? {
|
|
@@ -136,6 +142,8 @@ function parseSp(sp, ctx, transform) {
|
|
|
136
142
|
...Object.fromEntries(Object.entries(line).filter(([, v]) => v !== void 0))
|
|
137
143
|
} : fromStyle;
|
|
138
144
|
}
|
|
145
|
+
const shadowFrom = from((n) => poChildren(n).some((c) => poIs(c, "a:effectLst")));
|
|
146
|
+
const shadow = shadowFrom ? parseShadow(shadowFrom, colors) : void 0;
|
|
139
147
|
const visibleLine = line !== void 0 && line.fill !== "none";
|
|
140
148
|
if (!text && styled.kind === "none" && !visibleLine) return void 0;
|
|
141
149
|
const xfrm = spPr ? poChildren(spPr).find((c) => poIs(c, "a:xfrm")) : void 0;
|
|
@@ -147,6 +155,7 @@ function parseSp(sp, ctx, transform) {
|
|
|
147
155
|
geometry,
|
|
148
156
|
fill: styled,
|
|
149
157
|
...line ? { line } : {},
|
|
158
|
+
...shadow ? { shadow } : {},
|
|
150
159
|
...spin && Object.keys(spin).length > 0 ? { transform: spin } : {},
|
|
151
160
|
...text ? { text } : {},
|
|
152
161
|
paragraphProperties: {}
|
|
@@ -177,7 +186,10 @@ function parseGraphicFrame(gf, ctx, transform) {
|
|
|
177
186
|
if (uri === TABLE_URI) {
|
|
178
187
|
const tbl = poFindDescendant(gf, "a:tbl");
|
|
179
188
|
if (!tbl) return [];
|
|
180
|
-
const table = parseTable(tbl, ctx.colors ?? defaultColorResolver, ctx.resolveTableStyle
|
|
189
|
+
const table = parseTable(tbl, ctx.colors ?? defaultColorResolver, ctx.resolveTableStyle, {
|
|
190
|
+
...ctx.themeFills ? { fills: ctx.themeFills.fills } : {},
|
|
191
|
+
...ctx.themeLineWidths ? { lineWidths: ctx.themeLineWidths } : {}
|
|
192
|
+
});
|
|
181
193
|
return [{
|
|
182
194
|
kind: "table",
|
|
183
195
|
table: {
|
|
@@ -569,14 +581,14 @@ function picAltText(pic) {
|
|
|
569
581
|
const title = cNvPr ? poAttr(cNvPr, "title") : void 0;
|
|
570
582
|
return (descr ?? title)?.trim() || void 0;
|
|
571
583
|
}
|
|
572
|
-
function txBodyParagraphs(txBody, ph, cascade, colors, resolveLink, styleColor) {
|
|
584
|
+
function txBodyParagraphs(txBody, ph, cascade, colors, resolveLink, styleColor, themeFonts) {
|
|
573
585
|
const content = [];
|
|
574
586
|
const counters = [];
|
|
575
587
|
for (const child of poChildren(txBody)) {
|
|
576
588
|
if (!poIs(child, "a:p")) continue;
|
|
577
589
|
content.push({
|
|
578
590
|
kind: "paragraph",
|
|
579
|
-
paragraph: parseSlideParagraph(child, ph, cascade, colors, resolveLink, counters, styleColor)
|
|
591
|
+
paragraph: parseSlideParagraph(child, ph, cascade, colors, resolveLink, counters, styleColor, themeFonts)
|
|
580
592
|
});
|
|
581
593
|
}
|
|
582
594
|
return content;
|
|
@@ -594,10 +606,11 @@ function txBodyParagraphs(txBody, ph, cascade, colors, resolveLink, styleColor)
|
|
|
594
606
|
* @param resolveLink A run hyperlink resolver, or `undefined`.
|
|
595
607
|
* @returns The text body, or `undefined` when it holds no paragraphs.
|
|
596
608
|
*/
|
|
597
|
-
function parseTxBody(txBody, ph, cascade, colors, resolveLink, styleColor) {
|
|
598
|
-
const content = txBodyParagraphs(txBody, ph, cascade, colors, resolveLink, styleColor);
|
|
609
|
+
function parseTxBody(txBody, ph, cascade, colors, resolveLink, styleColor, themeFonts) {
|
|
610
|
+
const content = txBodyParagraphs(txBody, ph, cascade, colors, resolveLink, styleColor, themeFonts);
|
|
599
611
|
if (content.length === 0) return void 0;
|
|
600
612
|
const bodyPr = poChildren(txBody).find((c) => poIs(c, "a:bodyPr"));
|
|
613
|
+
const fitted = fitToBody(content, bodyPr);
|
|
601
614
|
const lIns = bodyPr ? poIntAttr(bodyPr, "lIns") : void 0;
|
|
602
615
|
const tIns = bodyPr ? poIntAttr(bodyPr, "tIns") : void 0;
|
|
603
616
|
const rIns = bodyPr ? poIntAttr(bodyPr, "rIns") : void 0;
|
|
@@ -605,7 +618,7 @@ function parseTxBody(txBody, ph, cascade, colors, resolveLink, styleColor) {
|
|
|
605
618
|
const a = bodyPr ? poAttr(bodyPr, "anchor") : void 0;
|
|
606
619
|
const anchor = a === "ctr" || a === "b" || a === "t" ? a : ph && cascade ? cascade.anchorFor(ph) : void 0;
|
|
607
620
|
return {
|
|
608
|
-
content,
|
|
621
|
+
content: fitted,
|
|
609
622
|
...lIns !== void 0 ? { insetLeft: emuToPt(lIns) } : {},
|
|
610
623
|
...tIns !== void 0 ? { insetTop: emuToPt(tIns) } : {},
|
|
611
624
|
...rIns !== void 0 ? { insetRight: emuToPt(rIns) } : {},
|
|
@@ -613,7 +626,53 @@ function parseTxBody(txBody, ph, cascade, colors, resolveLink, styleColor) {
|
|
|
613
626
|
...anchor ? { anchor } : {}
|
|
614
627
|
};
|
|
615
628
|
}
|
|
616
|
-
|
|
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) {
|
|
617
676
|
const pPr = poChildren(aP).find((c) => poIs(c, "a:pPr"));
|
|
618
677
|
const level = (pPr ? poIntAttr(pPr, "lvl") : void 0) ?? 0;
|
|
619
678
|
const defaults = {
|
|
@@ -625,7 +684,7 @@ function parseSlideParagraph(aP, ph, cascade, colors, resolveLink, counters, sty
|
|
|
625
684
|
const alignment = algn !== void 0 ? ALGN_TO_ALIGNMENT[algn] : void 0;
|
|
626
685
|
const runs = [];
|
|
627
686
|
for (const child of poChildren(aP)) if (poIs(child, "a:r") || poIs(child, "a:fld")) {
|
|
628
|
-
const run = parseSlideRun(child, defaults, colors, resolveLink);
|
|
687
|
+
const run = parseSlideRun(child, defaults, colors, resolveLink, themeFonts);
|
|
629
688
|
if (run) runs.push(run);
|
|
630
689
|
}
|
|
631
690
|
const marL = pPr ? poIntAttr(pPr, "marL") : void 0;
|
|
@@ -645,27 +704,41 @@ function parseSlideParagraph(aP, ph, cascade, colors, resolveLink, counters, sty
|
|
|
645
704
|
listMarker: true
|
|
646
705
|
});
|
|
647
706
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
...defaults,
|
|
655
|
-
fontSizePt: pt(sz / 100)
|
|
656
|
-
}
|
|
657
|
-
});
|
|
658
|
-
}
|
|
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
|
+
};
|
|
659
713
|
return {
|
|
660
714
|
properties: {
|
|
661
715
|
...inherited,
|
|
662
716
|
...alignment ? { alignment } : {},
|
|
663
717
|
...indentLeft !== void 0 ? { indentLeft } : {},
|
|
664
|
-
...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 } : {}
|
|
665
722
|
},
|
|
666
723
|
runs
|
|
667
724
|
};
|
|
668
725
|
}
|
|
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
|
+
}
|
|
669
742
|
function bulletProps(base, bullet) {
|
|
670
743
|
const sizePt = bullet.sizePts ?? (bullet.sizePct !== void 0 && base.fontSizePt !== void 0 ? base.fontSizePt * bullet.sizePct : void 0);
|
|
671
744
|
return {
|
|
@@ -688,7 +761,7 @@ function autoNumSuffix(type) {
|
|
|
688
761
|
if (type.endsWith("Period")) return ".";
|
|
689
762
|
return "";
|
|
690
763
|
}
|
|
691
|
-
function parseSlideRun(node, defaults, colors, resolveLink) {
|
|
764
|
+
function parseSlideRun(node, defaults, colors, resolveLink, themeFonts) {
|
|
692
765
|
const t = poChildren(node).find((c) => poIs(c, "a:t"));
|
|
693
766
|
const text = t ? poText(t) : "";
|
|
694
767
|
if (text.length === 0) return void 0;
|
|
@@ -700,12 +773,12 @@ function parseSlideRun(node, defaults, colors, resolveLink) {
|
|
|
700
773
|
text,
|
|
701
774
|
properties: {
|
|
702
775
|
...defaults,
|
|
703
|
-
...rPrToRunProps(rPr, colors)
|
|
776
|
+
...rPrToRunProps(rPr, colors, themeFonts)
|
|
704
777
|
},
|
|
705
778
|
...href ? { href } : {}
|
|
706
779
|
};
|
|
707
780
|
}
|
|
708
|
-
function parseTable(tbl, colors, resolveTableStyle) {
|
|
781
|
+
function parseTable(tbl, colors, resolveTableStyle, theme) {
|
|
709
782
|
const grid = [];
|
|
710
783
|
const tblGrid = poChildren(tbl).find((c) => poIs(c, "a:tblGrid"));
|
|
711
784
|
if (tblGrid) {
|
|
@@ -738,7 +811,7 @@ function parseTable(tbl, colors, resolveTableStyle) {
|
|
|
738
811
|
rowCount: rows.length,
|
|
739
812
|
col: c,
|
|
740
813
|
colCount: grid.length
|
|
741
|
-
}, colors);
|
|
814
|
+
}, colors, theme);
|
|
742
815
|
const tc = sources[r]?.[c];
|
|
743
816
|
return withCellStyle(cell, tc && cellSaysNoFill(tc) ? withoutFill(part) : part);
|
|
744
817
|
})
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RunProperties } 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 { PoNode } from '../core/po-helpers.js';
|
|
4
5
|
/**
|
|
5
6
|
* §19.3.1.36 `p:ph` — a shape's placeholder reference. `type`/`idx` tie a slide
|
|
@@ -42,4 +43,4 @@ export declare function parseXfrmBox(spPr: PoNode | undefined): ShapeBoxEmu | un
|
|
|
42
43
|
* (`sz`, hundredths of a point), bold/italic/underline, solid colour and the
|
|
43
44
|
* latin typeface. Scheme colours and the theme font cascade come in PX5.
|
|
44
45
|
*/
|
|
45
|
-
export declare function rPrToRunProps(rPr: PoNode | undefined, colors: ColorResolver): RunProperties;
|
|
46
|
+
export declare function rPrToRunProps(rPr: PoNode | undefined, colors: ColorResolver, themeFonts?: ThemeFonts): RunProperties;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { pt } from "../core/ir/units.js";
|
|
2
2
|
import { poAttr, poChildren, poIntAttr, poIs } from "../core/po-helpers.js";
|
|
3
3
|
import { resolveColorNode } from "../core/drawingml/colors.js";
|
|
4
|
+
import { resolveThemeFont } from "../core/drawingml/theme-parser.js";
|
|
4
5
|
//#region src/pptx/sp-helpers.ts
|
|
5
6
|
var isTrue = (v) => v === "1" || v === "true" || v === "on";
|
|
6
7
|
/**
|
|
@@ -54,13 +55,13 @@ function parseXfrmBox(spPr) {
|
|
|
54
55
|
* (`sz`, hundredths of a point), bold/italic/underline, solid colour and the
|
|
55
56
|
* latin typeface. Scheme colours and the theme font cascade come in PX5.
|
|
56
57
|
*/
|
|
57
|
-
function rPrToRunProps(rPr, colors) {
|
|
58
|
+
function rPrToRunProps(rPr, colors, themeFonts) {
|
|
58
59
|
if (!rPr) return {};
|
|
59
60
|
const sz = poIntAttr(rPr, "sz");
|
|
60
61
|
const u = poAttr(rPr, "u");
|
|
61
62
|
const colorHex = solidFillColor(rPr, colors);
|
|
62
63
|
const latin = poChildren(rPr).find((c) => poIs(c, "a:latin"));
|
|
63
|
-
const typeface = latin ? poAttr(latin, "typeface")?.trim() : void 0;
|
|
64
|
+
const typeface = resolveThemeFont(latin ? poAttr(latin, "typeface")?.trim() : void 0, themeFonts);
|
|
64
65
|
const flag = (name) => {
|
|
65
66
|
const v = poAttr(rPr, name);
|
|
66
67
|
return v === void 0 ? void 0 : isTrue(v);
|
|
@@ -29,6 +29,13 @@ export interface CellPosition {
|
|
|
29
29
|
export declare function tableStyleFlags(tblPr: PoNode | undefined): TableStyleFlags;
|
|
30
30
|
/** The GUID a table names, if it names one (`a:tblPr/a:tableStyleId`). */
|
|
31
31
|
export declare function tableStyleId(tblPr: PoNode | undefined): string | undefined;
|
|
32
|
+
/** What the deck's theme lends a style that points at it instead of spelling it out. */
|
|
33
|
+
export interface TableStyleTheme {
|
|
34
|
+
/** §20.1.4.1.14 `a:fillStyleLst` — the fills an `a:fillRef` indexes. */
|
|
35
|
+
readonly fills?: ReadonlyArray<PoNode>;
|
|
36
|
+
/** §20.1.4.2.19 `a:lnStyleLst` — the widths an `a:lnRef` indexes, in points. */
|
|
37
|
+
readonly lineWidths?: ReadonlyArray<number>;
|
|
38
|
+
}
|
|
32
39
|
/**
|
|
33
40
|
* The style a cell wears, composed from every part that reaches it.
|
|
34
41
|
*
|
|
@@ -36,9 +43,10 @@ export declare function tableStyleId(tblPr: PoNode | undefined): string | undefi
|
|
|
36
43
|
* @param flags Which conditional parts the table asks for.
|
|
37
44
|
* @param at Where the cell sits.
|
|
38
45
|
* @param colors The deck's colour resolver.
|
|
46
|
+
* @param theme The theme's style lists, for the parts that point at them.
|
|
39
47
|
* @returns The composed part, empty when the style says nothing.
|
|
40
48
|
*/
|
|
41
|
-
export declare function cellStyle(style: PoNode, flags: TableStyleFlags, at: CellPosition, colors: ColorResolver): TableStylePart;
|
|
49
|
+
export declare function cellStyle(style: PoNode, flags: TableStyleFlags, at: CellPosition, colors: ColorResolver, theme?: TableStyleTheme): TableStylePart;
|
|
42
50
|
/**
|
|
43
51
|
* §20.1.2.1 `a:ln` → the rule it draws on one side of a cell.
|
|
44
52
|
*
|
|
@@ -26,9 +26,10 @@ function tableStyleId(tblPr) {
|
|
|
26
26
|
* @param flags Which conditional parts the table asks for.
|
|
27
27
|
* @param at Where the cell sits.
|
|
28
28
|
* @param colors The deck's colour resolver.
|
|
29
|
+
* @param theme The theme's style lists, for the parts that point at them.
|
|
29
30
|
* @returns The composed part, empty when the style says nothing.
|
|
30
31
|
*/
|
|
31
|
-
function cellStyle(style, flags, at, colors) {
|
|
32
|
+
function cellStyle(style, flags, at, colors, theme) {
|
|
32
33
|
const names = ["a:wholeTbl"];
|
|
33
34
|
if (flags.bandCol) names.push(bandName(at.col, flags.firstCol, "V"));
|
|
34
35
|
if (flags.bandRow) names.push(bandName(at.row, flags.firstRow, "H"));
|
|
@@ -36,27 +37,52 @@ function cellStyle(style, flags, at, colors) {
|
|
|
36
37
|
if (flags.lastCol && at.col === at.colCount - 1) names.push("a:lastCol");
|
|
37
38
|
if (flags.firstRow && at.row === 0) names.push("a:firstRow");
|
|
38
39
|
if (flags.lastRow && at.row === at.rowCount - 1) names.push("a:lastRow");
|
|
39
|
-
let out =
|
|
40
|
+
let out = tableBackground(style, colors, theme);
|
|
40
41
|
for (const name of names) {
|
|
41
42
|
const part = poChildren(style).find((c) => poIs(c, name));
|
|
42
43
|
if (part) out = {
|
|
43
44
|
...out,
|
|
44
|
-
...partStyle(part, colors)
|
|
45
|
+
...partStyle(part, colors, theme)
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
48
|
return out;
|
|
48
49
|
}
|
|
50
|
+
function tableBackground(style, colors, theme) {
|
|
51
|
+
const bg = poChildren(style).find((c) => poIs(c, "a:tblBg"));
|
|
52
|
+
if (!bg) return {};
|
|
53
|
+
const solid = poChildren(bg).find((c) => poIs(c, "a:solidFill"));
|
|
54
|
+
const hex = (solid ? colorOf(solid, colors) : void 0) ?? refFillColor(poChildren(bg).find((c) => poIs(c, "a:fillRef")), colors, theme);
|
|
55
|
+
return hex ? { shadingHex: hex } : {};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* §20.1.4.1.16 `a:fillRef` — a fill named by its place in the theme's list,
|
|
59
|
+
* with the colour to put wherever that fill says `phClr`.
|
|
60
|
+
*
|
|
61
|
+
* Only its COLOUR is taken: a slot may be a gradient or a picture, and a cell's
|
|
62
|
+
* shading is one colour. The first solid colour the slot names, or the
|
|
63
|
+
* reference's own, is the nearest true answer.
|
|
64
|
+
*/
|
|
65
|
+
function refFillColor(ref, colors, theme) {
|
|
66
|
+
if (!ref) return void 0;
|
|
67
|
+
const own = colorOf(ref, colors);
|
|
68
|
+
const idx = poIntAttr(ref, "idx");
|
|
69
|
+
const slot = idx !== void 0 && idx > 0 ? theme?.fills?.[idx - 1] : void 0;
|
|
70
|
+
if (!slot) return own;
|
|
71
|
+
const solid = poChildren(slot).find((c) => poIs(c, "a:solidFill"));
|
|
72
|
+
const slotHex = solid ? colorOf(solid, colors) : void 0;
|
|
73
|
+
return slotHex && slotHex !== "PHCLR" ? own ?? slotHex : own;
|
|
74
|
+
}
|
|
49
75
|
function bandName(index, edge, axis) {
|
|
50
76
|
return (edge ? index - 1 : index) % 2 === 0 ? `a:band1${axis}` : `a:band2${axis}`;
|
|
51
77
|
}
|
|
52
|
-
function partStyle(part, colors) {
|
|
78
|
+
function partStyle(part, colors, theme) {
|
|
53
79
|
const tcStyle = poChildren(part).find((c) => poIs(c, "a:tcStyle"));
|
|
54
80
|
const txStyle = poChildren(part).find((c) => poIs(c, "a:tcTxStyle"));
|
|
55
81
|
const fill = tcStyle ? poChildren(tcStyle).find((c) => poIs(c, "a:fill")) : void 0;
|
|
56
82
|
const solid = fill ? poChildren(fill).find((c) => poIs(c, "a:solidFill")) : void 0;
|
|
57
83
|
const shadingHex = solid ? colorOf(solid, colors) : void 0;
|
|
58
84
|
const bdr = tcStyle ? poChildren(tcStyle).find((c) => poIs(c, "a:tcBdr")) : void 0;
|
|
59
|
-
const borders = bdr ? partBorders(bdr, colors) : void 0;
|
|
85
|
+
const borders = bdr ? partBorders(bdr, colors, theme) : void 0;
|
|
60
86
|
const on = (name) => poAttr(txStyle, name) === "on";
|
|
61
87
|
const colorHex = txStyle ? colorOf(txStyle, colors) : void 0;
|
|
62
88
|
return {
|
|
@@ -75,15 +101,31 @@ var SIDES = [
|
|
|
75
101
|
["a:insideH", "insideH"],
|
|
76
102
|
["a:insideV", "insideV"]
|
|
77
103
|
];
|
|
78
|
-
function partBorders(bdr, colors) {
|
|
104
|
+
function partBorders(bdr, colors, theme) {
|
|
79
105
|
const out = {};
|
|
80
106
|
for (const [tag, side] of SIDES) {
|
|
81
107
|
const holder = poChildren(bdr).find((c) => poIs(c, tag));
|
|
82
108
|
const ln = holder ? poChildren(holder).find((c) => poIs(c, "a:ln")) : void 0;
|
|
83
|
-
if (ln)
|
|
109
|
+
if (ln) {
|
|
110
|
+
out[side] = lineBorder(ln, colors);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const border = refBorder(holder ? poChildren(holder).find((c) => poIs(c, "a:lnRef")) : void 0, colors, theme);
|
|
114
|
+
if (border) out[side] = border;
|
|
84
115
|
}
|
|
85
116
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
86
117
|
}
|
|
118
|
+
function refBorder(ref, colors, theme) {
|
|
119
|
+
if (!ref || poAttr(ref, "idx") === "0") return void 0;
|
|
120
|
+
const colorHex = colorOf(ref, colors);
|
|
121
|
+
if (colorHex === void 0) return void 0;
|
|
122
|
+
const idx = poIntAttr(ref, "idx");
|
|
123
|
+
return {
|
|
124
|
+
style: "single",
|
|
125
|
+
colorHex,
|
|
126
|
+
width: pt((idx !== void 0 && idx > 0 ? theme?.lineWidths?.[idx - 1] : void 0) ?? .75)
|
|
127
|
+
};
|
|
128
|
+
}
|
|
87
129
|
/**
|
|
88
130
|
* §20.1.2.1 `a:ln` → the rule it draws on one side of a cell.
|
|
89
131
|
*
|