@bendyline/squisq-formats 1.4.1 → 2.0.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/README.md +48 -2
- package/dist/{chunk-WWBIKRNP.js → chunk-2CSZJEAL.js} +13 -11
- package/dist/chunk-2CSZJEAL.js.map +1 -0
- package/dist/{chunk-RTS5XBZ7.js → chunk-2EFDWKC6.js} +262 -84
- package/dist/chunk-2EFDWKC6.js.map +1 -0
- package/dist/chunk-2PRVLAU3.js +740 -0
- package/dist/chunk-2PRVLAU3.js.map +1 -0
- package/dist/{chunk-SHLPSADL.js → chunk-4HJ6AK2Q.js} +54 -193
- package/dist/chunk-4HJ6AK2Q.js.map +1 -0
- package/dist/{chunk-5LSSWZPU.js → chunk-4VUWTSGM.js} +72 -25
- package/dist/chunk-4VUWTSGM.js.map +1 -0
- package/dist/{chunk-YESS7VY3.js → chunk-CVNVD7VH.js} +154 -39
- package/dist/chunk-CVNVD7VH.js.map +1 -0
- package/dist/chunk-CX3LH47J.js +99 -0
- package/dist/chunk-CX3LH47J.js.map +1 -0
- package/dist/{chunk-D7IFPWNZ.js → chunk-GVS2XXV6.js} +27 -26
- package/dist/chunk-GVS2XXV6.js.map +1 -0
- package/dist/chunk-H7T5DXUU.js +479 -0
- package/dist/chunk-H7T5DXUU.js.map +1 -0
- package/dist/{chunk-EHLGMSTE.js → chunk-HBSCRS5P.js} +10 -8
- package/dist/chunk-HBSCRS5P.js.map +1 -0
- package/dist/{chunk-46FMDOWZ.js → chunk-LXYLOOST.js} +49 -17
- package/dist/chunk-LXYLOOST.js.map +1 -0
- package/dist/{chunk-MJGRI6XR.js → chunk-MLX2BOJC.js} +12 -7
- package/dist/chunk-MLX2BOJC.js.map +1 -0
- package/dist/chunk-NKAJPJ4G.js +106 -0
- package/dist/chunk-NKAJPJ4G.js.map +1 -0
- package/dist/{chunk-DQAZR57U.js → chunk-O3GVVND4.js} +1 -1
- package/dist/chunk-ODL3SSPT.js +18 -0
- package/dist/chunk-ODL3SSPT.js.map +1 -0
- package/dist/chunk-X4USWOQ2.js +131 -0
- package/dist/chunk-X4USWOQ2.js.map +1 -0
- package/dist/chunk-XTLQXR4U.js +195 -0
- package/dist/chunk-XTLQXR4U.js.map +1 -0
- package/dist/chunk-YRT7GQ5Y.js +28 -0
- package/dist/chunk-YRT7GQ5Y.js.map +1 -0
- package/dist/chunk-ZZ7D4DN6.js +97 -0
- package/dist/chunk-ZZ7D4DN6.js.map +1 -0
- package/dist/container/index.d.ts +6 -2
- package/dist/container/index.js +15 -17
- package/dist/container/index.js.map +1 -1
- package/dist/docx/index.d.ts +6 -2
- package/dist/docx/index.js +5 -3
- package/dist/epub/index.d.ts +3 -1
- package/dist/epub/index.js +3 -3
- package/dist/export-Djev9BLU.d.ts +69 -0
- package/dist/extract-LNOA7DBK.js +15 -0
- package/dist/extract-LNOA7DBK.js.map +1 -0
- package/dist/html/index.d.ts +15 -85
- package/dist/html/index.js +3 -3
- package/dist/images-7FBWPKE3.js +7 -0
- package/dist/images-7FBWPKE3.js.map +1 -0
- package/dist/import-DTkDxHmZ.d.ts +84 -0
- package/dist/import-Yivc3kZM.d.ts +136 -0
- package/dist/index.d.ts +13 -4
- package/dist/index.js +30 -11
- package/dist/infer/index.d.ts +138 -0
- package/dist/infer/index.js +28 -0
- package/dist/infer/index.js.map +1 -0
- package/dist/layouts-7OUUVAGU.js +12 -0
- package/dist/layouts-7OUUVAGU.js.map +1 -0
- package/dist/layouts-CZ0bdsNL.d.ts +150 -0
- package/dist/mapTheme-IR27S6IV.js +11 -0
- package/dist/mapTheme-IR27S6IV.js.map +1 -0
- package/dist/ooxml/index.d.ts +21 -127
- package/dist/ooxml/index.js +31 -9
- package/dist/pdf/index.d.ts +3 -1
- package/dist/pdf/index.js +1 -1
- package/dist/pptx/index.d.ts +8 -108
- package/dist/pptx/index.js +13 -4
- package/dist/reader-Gof6OrJX.d.ts +140 -0
- package/dist/registry/index.d.ts +46 -8
- package/dist/registry/index.js +5 -2
- package/dist/themeReader-DPw4J5Ss.d.ts +56 -0
- package/dist/xlsx/index.d.ts +6 -66
- package/dist/xlsx/index.js +4 -2
- package/dist/zipLimits-bGYMS9cI.d.ts +29 -0
- package/package.json +8 -2
- package/src/__tests__/container.test.ts +41 -0
- package/src/__tests__/convert.test.ts +167 -0
- package/src/__tests__/epub.test.ts +102 -1
- package/src/__tests__/html.test.ts +62 -0
- package/src/__tests__/inferTheme.test.ts +135 -0
- package/src/__tests__/lossyWarnings.test.ts +41 -0
- package/src/__tests__/ooxml.test.ts +59 -2
- package/src/__tests__/ooxmlThemeReader.test.ts +92 -0
- package/src/__tests__/plainHtml.test.ts +15 -1
- package/src/__tests__/plainHtmlBundle.test.ts +18 -0
- package/src/__tests__/pptxImport.test.ts +30 -0
- package/src/__tests__/pptxInferFixtures.ts +314 -0
- package/src/__tests__/pptxLayoutInfer.test.ts +395 -0
- package/src/__tests__/zipSafety.test.ts +317 -0
- package/src/container/index.ts +20 -29
- package/src/docx/export.ts +4 -2
- package/src/docx/import.ts +4 -3
- package/src/epub/export.ts +94 -25
- package/src/html/docsHtmlBundle.ts +6 -2
- package/src/html/htmlTemplate.ts +31 -6
- package/src/html/imageUtils.ts +14 -5
- package/src/html/index.ts +12 -1
- package/src/html/plainHtml.ts +7 -3
- package/src/html/plainHtmlBundle.ts +11 -9
- package/src/index.ts +20 -0
- package/src/infer/extract.ts +127 -0
- package/src/infer/index.ts +168 -0
- package/src/infer/mapTheme.ts +176 -0
- package/src/infer/types.ts +27 -0
- package/src/ooxml/index.ts +14 -0
- package/src/ooxml/readUtils.ts +44 -0
- package/src/ooxml/reader.ts +87 -28
- package/src/ooxml/themeReader.ts +197 -0
- package/src/ooxml/types.ts +8 -9
- package/src/ooxml/writer.ts +28 -10
- package/src/pdf/export.ts +4 -2
- package/src/pdf/import.ts +40 -34
- package/src/pptx/export.ts +4 -2
- package/src/pptx/import.ts +214 -32
- package/src/pptx/index.ts +14 -0
- package/src/pptx/layouts.ts +1168 -0
- package/src/registry/convert.ts +54 -23
- package/src/registry/defaultFormats.ts +131 -44
- package/src/registry/index.ts +3 -0
- package/src/registry/types.ts +52 -6
- package/src/shared/boundedZipArchive.ts +342 -0
- package/src/shared/fidelity.ts +130 -0
- package/src/shared/zipEntryCount.ts +97 -0
- package/src/shared/zipLimits.ts +286 -0
- package/src/shared/zipSafety.ts +19 -0
- package/src/xlsx/import.ts +3 -2
- package/dist/chunk-46FMDOWZ.js.map +0 -1
- package/dist/chunk-5LSSWZPU.js.map +0 -1
- package/dist/chunk-D7IFPWNZ.js.map +0 -1
- package/dist/chunk-EHLGMSTE.js.map +0 -1
- package/dist/chunk-MJGRI6XR.js.map +0 -1
- package/dist/chunk-RTS5XBZ7.js.map +0 -1
- package/dist/chunk-SHLPSADL.js.map +0 -1
- package/dist/chunk-WWBIKRNP.js.map +0 -1
- package/dist/chunk-YESS7VY3.js.map +0 -1
- /package/dist/{chunk-DQAZR57U.js.map → chunk-O3GVVND4.js.map} +0 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmatic OOXML fixtures for theme/layout inference tests: themed PPTX
|
|
3
|
+
* decks (theme + master + layouts + slides, fully wired relationships) plus
|
|
4
|
+
* minimal themed DOCX/XLSX packages. Built with the package's own writer —
|
|
5
|
+
* no binary fixtures checked in.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
CONTENT_TYPE_DOCX_DOCUMENT,
|
|
10
|
+
CONTENT_TYPE_PPTX_PRESENTATION,
|
|
11
|
+
CONTENT_TYPE_PPTX_SLIDE,
|
|
12
|
+
CONTENT_TYPE_PPTX_SLIDE_LAYOUT,
|
|
13
|
+
CONTENT_TYPE_PPTX_SLIDE_MASTER,
|
|
14
|
+
CONTENT_TYPE_PPTX_THEME,
|
|
15
|
+
CONTENT_TYPE_XLSX_WORKBOOK,
|
|
16
|
+
NS_DRAWINGML,
|
|
17
|
+
NS_PML,
|
|
18
|
+
NS_R,
|
|
19
|
+
NS_WML,
|
|
20
|
+
REL_OFFICE_DOCUMENT,
|
|
21
|
+
REL_SLIDE,
|
|
22
|
+
REL_SLIDE_LAYOUT,
|
|
23
|
+
REL_SLIDE_MASTER,
|
|
24
|
+
REL_THEME,
|
|
25
|
+
} from '../ooxml/namespaces';
|
|
26
|
+
import { createPackage } from '../ooxml/writer';
|
|
27
|
+
import { xmlDeclaration } from '../ooxml/xmlUtils';
|
|
28
|
+
|
|
29
|
+
export const SLDSZ = { cx: 12192000, cy: 6858000 };
|
|
30
|
+
|
|
31
|
+
// ── Theme XML ────────────────────────────────────────────────────────
|
|
32
|
+
|
|
33
|
+
export interface ThemeXmlOptions {
|
|
34
|
+
name?: string;
|
|
35
|
+
dk1?: string; // inner color XML, e.g. '<a:srgbClr val="111111"/>'
|
|
36
|
+
lt1?: string;
|
|
37
|
+
dk2?: string;
|
|
38
|
+
lt2?: string;
|
|
39
|
+
accents?: string[]; // hex values without '#', accent1..N (missing slots omitted)
|
|
40
|
+
hlink?: string;
|
|
41
|
+
majorFont?: string;
|
|
42
|
+
minorFont?: string;
|
|
43
|
+
omitFontScheme?: boolean;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function buildThemeXml(opts: ThemeXmlOptions = {}): string {
|
|
47
|
+
const accents = opts.accents ?? ['4472c4', 'ed7d31', 'a5a5a5', 'ffc000', '5b9bd5', '70ad47'];
|
|
48
|
+
const accentXml = accents
|
|
49
|
+
.map((hex, i) => `<a:accent${i + 1}><a:srgbClr val="${hex}"/></a:accent${i + 1}>`)
|
|
50
|
+
.join('');
|
|
51
|
+
const fontScheme = opts.omitFontScheme
|
|
52
|
+
? ''
|
|
53
|
+
: `<a:fontScheme name="Test">` +
|
|
54
|
+
`<a:majorFont><a:latin typeface="${opts.majorFont ?? 'Playfair Display'}"/></a:majorFont>` +
|
|
55
|
+
`<a:minorFont><a:latin typeface="${opts.minorFont ?? 'Aptos'}"/></a:minorFont>` +
|
|
56
|
+
`</a:fontScheme>`;
|
|
57
|
+
return (
|
|
58
|
+
xmlDeclaration() +
|
|
59
|
+
`<a:theme xmlns:a="${NS_DRAWINGML}" name="${opts.name ?? 'Fixture Theme'}">` +
|
|
60
|
+
`<a:themeElements>` +
|
|
61
|
+
`<a:clrScheme name="Test">` +
|
|
62
|
+
`<a:dk1>${opts.dk1 ?? '<a:srgbClr val="1a1a2e"/>'}</a:dk1>` +
|
|
63
|
+
`<a:lt1>${opts.lt1 ?? '<a:srgbClr val="fdfdf8"/>'}</a:lt1>` +
|
|
64
|
+
`<a:dk2>${opts.dk2 ?? '<a:srgbClr val="30304a"/>'}</a:dk2>` +
|
|
65
|
+
`<a:lt2>${opts.lt2 ?? '<a:srgbClr val="efefe4"/>'}</a:lt2>` +
|
|
66
|
+
accentXml +
|
|
67
|
+
`<a:hlink>${opts.hlink ?? '<a:srgbClr val="0563c1"/>'}</a:hlink>` +
|
|
68
|
+
`<a:folHlink><a:srgbClr val="954f72"/></a:folHlink>` +
|
|
69
|
+
`</a:clrScheme>` +
|
|
70
|
+
fontScheme +
|
|
71
|
+
`</a:themeElements>` +
|
|
72
|
+
`</a:theme>`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ── PresentationML fragments ─────────────────────────────────────────
|
|
77
|
+
|
|
78
|
+
export interface PhSpOptions {
|
|
79
|
+
/** ph@type; omit for a plain body placeholder. */
|
|
80
|
+
type?: string;
|
|
81
|
+
idx?: number;
|
|
82
|
+
/** EMU geometry; omit xfrm entirely when absent. */
|
|
83
|
+
rect?: { x: number; y: number; cx: number; cy: number };
|
|
84
|
+
/** a:lvl1pPr defRPr attributes, e.g. 'sz="4400" b="1"'. */
|
|
85
|
+
lvl1DefRPr?: string;
|
|
86
|
+
/** ph@orient value (e.g. 'vert'). */
|
|
87
|
+
orient?: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** A placeholder `p:sp` for a layout/master/slide part. */
|
|
91
|
+
export function phSp(opts: PhSpOptions, id = 2): string {
|
|
92
|
+
const typeAttr = opts.type ? ` type="${opts.type}"` : '';
|
|
93
|
+
const idxAttr = opts.idx !== undefined ? ` idx="${opts.idx}"` : '';
|
|
94
|
+
const orientAttr = opts.orient ? ` orient="${opts.orient}"` : '';
|
|
95
|
+
const xfrm = opts.rect
|
|
96
|
+
? `<a:xfrm><a:off x="${opts.rect.x}" y="${opts.rect.y}"/>` +
|
|
97
|
+
`<a:ext cx="${opts.rect.cx}" cy="${opts.rect.cy}"/></a:xfrm>`
|
|
98
|
+
: '';
|
|
99
|
+
const lstStyle = opts.lvl1DefRPr
|
|
100
|
+
? `<a:lstStyle><a:lvl1pPr><a:defRPr ${opts.lvl1DefRPr}/></a:lvl1pPr></a:lstStyle>`
|
|
101
|
+
: `<a:lstStyle/>`;
|
|
102
|
+
return (
|
|
103
|
+
`<p:sp><p:nvSpPr><p:cNvPr id="${id}" name="ph${id}"/><p:cNvSpPr/>` +
|
|
104
|
+
`<p:nvPr><p:ph${typeAttr}${idxAttr}${orientAttr}/></p:nvPr></p:nvSpPr>` +
|
|
105
|
+
`<p:spPr>${xfrm}</p:spPr>` +
|
|
106
|
+
`<p:txBody><a:bodyPr/>${lstStyle}<a:p><a:endParaRPr/></a:p></p:txBody></p:sp>`
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface LayoutXmlOptions {
|
|
111
|
+
name?: string;
|
|
112
|
+
type?: string;
|
|
113
|
+
/** Raw p:sp strings (use phSp / decorSp). */
|
|
114
|
+
shapes?: string[];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function layoutXml(opts: LayoutXmlOptions = {}): string {
|
|
118
|
+
const typeAttr = opts.type ? ` type="${opts.type}"` : '';
|
|
119
|
+
return (
|
|
120
|
+
xmlDeclaration() +
|
|
121
|
+
`<p:sldLayout xmlns:a="${NS_DRAWINGML}" xmlns:r="${NS_R}" xmlns:p="${NS_PML}"${typeAttr}>` +
|
|
122
|
+
`<p:cSld${opts.name !== undefined ? ` name="${opts.name}"` : ''}><p:spTree>` +
|
|
123
|
+
`<p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/>` +
|
|
124
|
+
(opts.shapes ?? []).join('') +
|
|
125
|
+
`</p:spTree></p:cSld></p:sldLayout>`
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface SlideTextShape {
|
|
130
|
+
phType?: string;
|
|
131
|
+
phIdx?: number;
|
|
132
|
+
texts: string[];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** A slide with a title shape plus arbitrary placeholder text shapes. */
|
|
136
|
+
export function slideXml(title: string | null, shapes: SlideTextShape[] = []): string {
|
|
137
|
+
const titleSp = title
|
|
138
|
+
? `<p:sp><p:nvSpPr><p:nvPr><p:ph type="title"/></p:nvPr></p:nvSpPr>` +
|
|
139
|
+
`<p:txBody><a:p><a:r><a:t>${title}</a:t></a:r></a:p></p:txBody></p:sp>`
|
|
140
|
+
: '';
|
|
141
|
+
const bodySps = shapes
|
|
142
|
+
.map((s) => {
|
|
143
|
+
const typeAttr = s.phType ? ` type="${s.phType}"` : '';
|
|
144
|
+
const idxAttr = s.phIdx !== undefined ? ` idx="${s.phIdx}"` : '';
|
|
145
|
+
const paras = s.texts.map((t) => `<a:p><a:r><a:t>${t}</a:t></a:r></a:p>`).join('');
|
|
146
|
+
return (
|
|
147
|
+
`<p:sp><p:nvSpPr><p:nvPr><p:ph${typeAttr}${idxAttr}/></p:nvPr></p:nvSpPr>` +
|
|
148
|
+
`<p:txBody>${paras}</p:txBody></p:sp>`
|
|
149
|
+
);
|
|
150
|
+
})
|
|
151
|
+
.join('');
|
|
152
|
+
return (
|
|
153
|
+
xmlDeclaration() +
|
|
154
|
+
`<p:sld xmlns:p="${NS_PML}" xmlns:a="${NS_DRAWINGML}" xmlns:r="${NS_R}"><p:cSld><p:spTree>` +
|
|
155
|
+
titleSp +
|
|
156
|
+
bodySps +
|
|
157
|
+
`</p:spTree></p:cSld></p:sld>`
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// ── Whole-deck builder ───────────────────────────────────────────────
|
|
162
|
+
|
|
163
|
+
export interface FixtureSlide {
|
|
164
|
+
xml: string;
|
|
165
|
+
/** Index into `layouts`; omit for a slide with no layout relationship. */
|
|
166
|
+
layoutIndex?: number;
|
|
167
|
+
/** Extra relationships for this slide (e.g. image embeds). */
|
|
168
|
+
rels?: Array<{ id: string; type: string; target: string }>;
|
|
169
|
+
/** Binary media parts referenced by `rels`, keyed by package path. */
|
|
170
|
+
media?: Array<{ path: string; data: Uint8Array; contentType: string }>;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export interface ThemedPptxOptions {
|
|
174
|
+
themeXml?: string | null; // null = omit the theme part entirely
|
|
175
|
+
/** Attribute string for <p:clrMap …/>; default light mapping. */
|
|
176
|
+
clrMapAttrs?: string;
|
|
177
|
+
/** Raw p:sp strings placed in the master's spTree (for inheritance tests). */
|
|
178
|
+
masterShapes?: string[];
|
|
179
|
+
layouts?: string[]; // layout part XMLs (layoutXml())
|
|
180
|
+
slides?: FixtureSlide[];
|
|
181
|
+
sldSz?: { cx: number; cy: number };
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export async function buildThemedPptx(opts: ThemedPptxOptions = {}): Promise<ArrayBuffer> {
|
|
185
|
+
const pkg = createPackage();
|
|
186
|
+
const slides = opts.slides ?? [{ xml: slideXml('My Title', [{ texts: ['First bullet'] }]) }];
|
|
187
|
+
const layouts = opts.layouts ?? [];
|
|
188
|
+
const sldSz = opts.sldSz ?? SLDSZ;
|
|
189
|
+
|
|
190
|
+
const sldIds = slides.map((_, i) => `<p:sldId id="${256 + i}" r:id="rIdS${i + 1}"/>`).join('');
|
|
191
|
+
pkg.addPart(
|
|
192
|
+
'ppt/presentation.xml',
|
|
193
|
+
`${xmlDeclaration()}<p:presentation xmlns:p="${NS_PML}" xmlns:r="${NS_R}">` +
|
|
194
|
+
`<p:sldMasterIdLst><p:sldMasterId id="2147483648" r:id="rIdM1"/></p:sldMasterIdLst>` +
|
|
195
|
+
`<p:sldIdLst>${sldIds}</p:sldIdLst>` +
|
|
196
|
+
`<p:sldSz cx="${sldSz.cx}" cy="${sldSz.cy}"/>` +
|
|
197
|
+
`</p:presentation>`,
|
|
198
|
+
CONTENT_TYPE_PPTX_PRESENTATION,
|
|
199
|
+
);
|
|
200
|
+
pkg.addRelationship('', {
|
|
201
|
+
id: 'rId1',
|
|
202
|
+
type: REL_OFFICE_DOCUMENT,
|
|
203
|
+
target: 'ppt/presentation.xml',
|
|
204
|
+
});
|
|
205
|
+
pkg.addRelationship('ppt/presentation.xml', {
|
|
206
|
+
id: 'rIdM1',
|
|
207
|
+
type: REL_SLIDE_MASTER,
|
|
208
|
+
target: 'slideMasters/slideMaster1.xml',
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Master (carries the clrMap + optional inheritable placeholder geometry).
|
|
212
|
+
const layoutIds = layouts
|
|
213
|
+
.map((_, i) => `<p:sldLayoutId id="${2147483649 + i}" r:id="rIdL${i + 1}"/>`)
|
|
214
|
+
.join('');
|
|
215
|
+
pkg.addPart(
|
|
216
|
+
'ppt/slideMasters/slideMaster1.xml',
|
|
217
|
+
`${xmlDeclaration()}<p:sldMaster xmlns:a="${NS_DRAWINGML}" xmlns:r="${NS_R}" xmlns:p="${NS_PML}">` +
|
|
218
|
+
`<p:cSld name="Fixture Master"><p:spTree>` +
|
|
219
|
+
`<p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/>` +
|
|
220
|
+
(opts.masterShapes ?? []).join('') +
|
|
221
|
+
`</p:spTree></p:cSld>` +
|
|
222
|
+
`<p:clrMap ${opts.clrMapAttrs ?? 'bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2"'}` +
|
|
223
|
+
` accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4"` +
|
|
224
|
+
` accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/>` +
|
|
225
|
+
`<p:sldLayoutIdLst>${layoutIds}</p:sldLayoutIdLst>` +
|
|
226
|
+
`</p:sldMaster>`,
|
|
227
|
+
CONTENT_TYPE_PPTX_SLIDE_MASTER,
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
if (opts.themeXml !== null) {
|
|
231
|
+
pkg.addPart('ppt/theme/theme1.xml', opts.themeXml ?? buildThemeXml(), CONTENT_TYPE_PPTX_THEME);
|
|
232
|
+
pkg.addRelationship('ppt/slideMasters/slideMaster1.xml', {
|
|
233
|
+
id: 'rIdT1',
|
|
234
|
+
type: REL_THEME,
|
|
235
|
+
target: '../theme/theme1.xml',
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
layouts.forEach((xml, i) => {
|
|
240
|
+
const path = `ppt/slideLayouts/slideLayout${i + 1}.xml`;
|
|
241
|
+
pkg.addPart(path, xml, CONTENT_TYPE_PPTX_SLIDE_LAYOUT);
|
|
242
|
+
pkg.addRelationship('ppt/slideMasters/slideMaster1.xml', {
|
|
243
|
+
id: `rIdL${i + 1}`,
|
|
244
|
+
type: REL_SLIDE_LAYOUT,
|
|
245
|
+
target: `../slideLayouts/slideLayout${i + 1}.xml`,
|
|
246
|
+
});
|
|
247
|
+
pkg.addRelationship(path, {
|
|
248
|
+
id: 'rIdM1',
|
|
249
|
+
type: REL_SLIDE_MASTER,
|
|
250
|
+
target: '../slideMasters/slideMaster1.xml',
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
slides.forEach((slide, i) => {
|
|
255
|
+
const path = `ppt/slides/slide${i + 1}.xml`;
|
|
256
|
+
pkg.addPart(path, slide.xml, CONTENT_TYPE_PPTX_SLIDE);
|
|
257
|
+
pkg.addRelationship('ppt/presentation.xml', {
|
|
258
|
+
id: `rIdS${i + 1}`,
|
|
259
|
+
type: REL_SLIDE,
|
|
260
|
+
target: `slides/slide${i + 1}.xml`,
|
|
261
|
+
});
|
|
262
|
+
if (slide.layoutIndex !== undefined) {
|
|
263
|
+
pkg.addRelationship(path, {
|
|
264
|
+
id: 'rIdLo1',
|
|
265
|
+
type: REL_SLIDE_LAYOUT,
|
|
266
|
+
target: `../slideLayouts/slideLayout${slide.layoutIndex + 1}.xml`,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
for (const rel of slide.rels ?? []) pkg.addRelationship(path, rel);
|
|
270
|
+
for (const media of slide.media ?? []) {
|
|
271
|
+
pkg.addBinaryPart(media.path, media.data, media.contentType);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
return pkg.toArrayBuffer();
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ── DOCX / XLSX minimal themed packages ──────────────────────────────
|
|
279
|
+
|
|
280
|
+
export async function buildThemedDocx(themeXml?: string): Promise<ArrayBuffer> {
|
|
281
|
+
const pkg = createPackage();
|
|
282
|
+
pkg.addPart(
|
|
283
|
+
'word/document.xml',
|
|
284
|
+
`${xmlDeclaration()}<w:document xmlns:w="${NS_WML}"><w:body>` +
|
|
285
|
+
`<w:p><w:r><w:t>Hello</w:t></w:r></w:p></w:body></w:document>`,
|
|
286
|
+
CONTENT_TYPE_DOCX_DOCUMENT,
|
|
287
|
+
);
|
|
288
|
+
pkg.addPart('word/theme/theme1.xml', themeXml ?? buildThemeXml(), CONTENT_TYPE_PPTX_THEME);
|
|
289
|
+
pkg.addRelationship('', { id: 'rId1', type: REL_OFFICE_DOCUMENT, target: 'word/document.xml' });
|
|
290
|
+
pkg.addRelationship('word/document.xml', {
|
|
291
|
+
id: 'rId2',
|
|
292
|
+
type: REL_THEME,
|
|
293
|
+
target: 'theme/theme1.xml',
|
|
294
|
+
});
|
|
295
|
+
return pkg.toArrayBuffer();
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export async function buildThemedXlsx(themeXml?: string): Promise<ArrayBuffer> {
|
|
299
|
+
const pkg = createPackage();
|
|
300
|
+
pkg.addPart(
|
|
301
|
+
'xl/workbook.xml',
|
|
302
|
+
`${xmlDeclaration()}<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">` +
|
|
303
|
+
`<sheets/></workbook>`,
|
|
304
|
+
CONTENT_TYPE_XLSX_WORKBOOK,
|
|
305
|
+
);
|
|
306
|
+
pkg.addPart('xl/theme/theme1.xml', themeXml ?? buildThemeXml(), CONTENT_TYPE_PPTX_THEME);
|
|
307
|
+
pkg.addRelationship('', { id: 'rId1', type: REL_OFFICE_DOCUMENT, target: 'xl/workbook.xml' });
|
|
308
|
+
pkg.addRelationship('xl/workbook.xml', {
|
|
309
|
+
id: 'rId2',
|
|
310
|
+
type: REL_THEME,
|
|
311
|
+
target: 'theme/theme1.xml',
|
|
312
|
+
});
|
|
313
|
+
return pkg.toArrayBuffer();
|
|
314
|
+
}
|