@shbernal/ts-pptx 4.1.0 → 4.2.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 +11 -11
- package/dist/anim-presets-Qbgh8uut.js +55 -0
- package/dist/anim-presets-Qbgh8uut.js.map +1 -0
- package/dist/{autopage-D4kyVp11.js → autopage-DqZ37VpL.js} +11 -12
- package/dist/autopage-DqZ37VpL.js.map +1 -0
- package/dist/{binary-string-CKVAYI3M.js → binary-string-Ba8VM3b9.js} +3 -4
- package/dist/binary-string-Ba8VM3b9.js.map +1 -0
- package/dist/{body-insets-kVHmjGc6.js → body-insets-BDHymJvz.js} +7 -9
- package/dist/body-insets-BDHymJvz.js.map +1 -0
- package/dist/browser.d.ts +24 -16
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +19 -19
- package/dist/browser.js.map +1 -1
- package/dist/{image-size-DwDbakcl.js → chart-metadata-CwiTTcJq.js} +576 -538
- package/dist/chart-metadata-CwiTTcJq.js.map +1 -0
- package/dist/{clip-DHDlnHUq.d.ts → clip-ISfCMtWA.d.ts} +6 -10
- package/dist/clip-ISfCMtWA.d.ts.map +1 -0
- package/dist/{notes-BcT571R4.js → comments-CKIZYRbZ.js} +517 -389
- package/dist/comments-CKIZYRbZ.js.map +1 -0
- package/dist/{diagnostics-DiMmBU8P.d.ts → diagnostics-MoA4MBq5.d.ts} +52 -50
- package/dist/diagnostics-MoA4MBq5.d.ts.map +1 -0
- package/dist/{embedded-fonts-CI_YGW2d.d.ts → embedded-fonts-U7HIIhPO.d.ts} +4 -6
- package/dist/embedded-fonts-U7HIIhPO.d.ts.map +1 -0
- package/dist/{entry-compose-6hF9aTmT.d.ts → entry-compose-CiakSt-f.d.ts} +53 -74
- package/dist/entry-compose-CiakSt-f.d.ts.map +1 -0
- package/dist/{errors-Da2nXCJm.js → entry-errors-JMthgJ2g.js} +41 -25
- package/dist/entry-errors-JMthgJ2g.js.map +1 -0
- package/dist/{table-cell-margins-PDshga8T.js → enums-BP9wsb9Q.js} +42 -45
- package/dist/enums-BP9wsb9Q.js.map +1 -0
- package/dist/{enums-DQRpVOLh.d.ts → enums-PcXr3o3J.d.ts} +11 -12
- package/dist/{enums-DQRpVOLh.d.ts.map → enums-PcXr3o3J.d.ts.map} +1 -1
- package/dist/families.d.ts +24 -26
- package/dist/families.d.ts.map +1 -1
- package/dist/families.js +3 -4
- package/dist/{fit-CcXbg__l.js → fit-Bpmzep6O.js} +60 -52
- package/dist/fit-Bpmzep6O.js.map +1 -0
- package/dist/{font-metrics-CBGmhLo0.d.ts → font-metrics-DTppw4t3.d.ts} +61 -37
- package/dist/font-metrics-DTppw4t3.d.ts.map +1 -0
- package/dist/{grid-9B2w5EaY.js → grid-DUIMxjfl.js} +23 -26
- package/dist/grid-DUIMxjfl.js.map +1 -0
- package/dist/{html-dom-DvJmuHt2.js → html-dom-LZCgntnJ.js} +42 -43
- package/dist/html-dom-LZCgntnJ.js.map +1 -0
- package/dist/html.d.ts +53 -9
- package/dist/html.d.ts.map +1 -1
- package/dist/html.js +12 -13
- package/dist/html.js.map +1 -1
- package/dist/index.d.ts +21 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -15
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts +14 -16
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +18 -19
- package/dist/inspect.js.map +1 -1
- package/dist/{text-anchor-BgLPbwbL.js → lock-attrs-CSQnFDHP.js} +62 -12
- package/dist/lock-attrs-CSQnFDHP.js.map +1 -0
- package/dist/math.d.ts +2 -4
- package/dist/math.d.ts.map +1 -1
- package/dist/math.js +12 -13
- package/dist/math.js.map +1 -1
- package/dist/measure.d.ts +23 -12
- package/dist/measure.d.ts.map +1 -1
- package/dist/measure.js +3 -3
- package/dist/node.d.ts +21 -13
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +12 -12
- package/dist/node.js.map +1 -1
- package/dist/{options-internal-WqgMf720.js → options-internal-BWgmLPdx.js} +4 -5
- package/dist/options-internal-BWgmLPdx.js.map +1 -0
- package/dist/{package-KoEgVwII.d.ts → package-CANBWuSm.d.ts} +4 -12
- package/dist/package-CANBWuSm.d.ts.map +1 -0
- package/dist/{playbtn-CUqQdoDf.js → playbtn-BQZFJir9.js} +4 -5
- package/dist/playbtn-BQZFJir9.js.map +1 -0
- package/dist/{pres-BA9_lJbY.d.ts → pres-BkEkUAEM.d.ts} +383 -230
- package/dist/pres-BkEkUAEM.d.ts.map +1 -0
- package/dist/{presentation-Cyl74rq2.js → presentation-4Ggq0_Xa.js} +408 -288
- package/dist/presentation-4Ggq0_Xa.js.map +1 -0
- package/dist/{presentation-types-B3VQH4Bz.d.ts → presentation-types-BgnZR-0a.d.ts} +1104 -457
- package/dist/presentation-types-BgnZR-0a.d.ts.map +1 -0
- package/dist/read.d.ts +18 -13
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +4 -4
- package/dist/script.d.ts +116 -65
- package/dist/script.d.ts.map +1 -1
- package/dist/script.js +2697 -777
- package/dist/script.js.map +1 -1
- package/dist/{shapes-BcyFdZpp.js → shapes-CAPOjU0Q.js} +1556 -487
- package/dist/shapes-CAPOjU0Q.js.map +1 -0
- package/dist/{slide-BqPtyKmb.d.ts → slide-BmT4kMoO.d.ts} +94 -86
- package/dist/slide-BmT4kMoO.d.ts.map +1 -0
- package/dist/{slide-size-BalTjFuv.js → slide-size-SkScz1ig.js} +2 -3
- package/dist/{slide-size-BalTjFuv.js.map → slide-size-SkScz1ig.js.map} +1 -1
- package/dist/{table-dom-CVbvUfgh.js → table-dom-BYga4FYY.js} +3 -4
- package/dist/{table-dom-CVbvUfgh.js.map → table-dom-BYga4FYY.js.map} +1 -1
- package/dist/{text-BvFFMMFQ.js → text-CU08xJGs.js} +365 -318
- package/dist/text-CU08xJGs.js.map +1 -0
- package/dist/{transition-speed-kUEWDWTx.js → transition-speed-CNJ0fSpQ.js} +2 -3
- package/dist/{transition-speed-kUEWDWTx.js.map → transition-speed-CNJ0fSpQ.js.map} +1 -1
- package/dist/{units-internal-DFcUYjh3.js → units-internal-BR3a4cIi.js} +26 -29
- package/dist/units-internal-BR3a4cIi.js.map +1 -0
- package/dist/{zip-CYZ0F6BV.js → zip-7JTh61LX.js} +8 -10
- package/dist/zip-7JTh61LX.js.map +1 -0
- package/dist/{zip-CTll_dr0.d.ts → zip-uUjs9Cqx.d.ts} +4 -6
- package/dist/zip-uUjs9Cqx.d.ts.map +1 -0
- package/dist/zip.d.ts +3 -3
- package/dist/zip.js +3 -3
- package/dist/{zoom-BoNyOlPm.js → zoom-CSSeOwM8.js} +1153 -583
- package/dist/zoom-CSSeOwM8.js.map +1 -0
- package/package.json +20 -21
- package/skills/{ts-pptx-upstream → pptx-ts-upstream}/SKILL.md +27 -74
- package/dist/autopage-D4kyVp11.js.map +0 -1
- package/dist/binary-string-CKVAYI3M.js.map +0 -1
- package/dist/body-insets-kVHmjGc6.js.map +0 -1
- package/dist/clip-DHDlnHUq.d.ts.map +0 -1
- package/dist/diagnostics-DiMmBU8P.d.ts.map +0 -1
- package/dist/embedded-fonts-CI_YGW2d.d.ts.map +0 -1
- package/dist/entry-compose-6hF9aTmT.d.ts.map +0 -1
- package/dist/errors-Da2nXCJm.js.map +0 -1
- package/dist/fit-CcXbg__l.js.map +0 -1
- package/dist/font-metrics-CBGmhLo0.d.ts.map +0 -1
- package/dist/grid-9B2w5EaY.js.map +0 -1
- package/dist/html-dom-DvJmuHt2.js.map +0 -1
- package/dist/image-size-DwDbakcl.js.map +0 -1
- package/dist/notes-BcT571R4.js.map +0 -1
- package/dist/options-internal-WqgMf720.js.map +0 -1
- package/dist/package-KoEgVwII.d.ts.map +0 -1
- package/dist/playbtn-CUqQdoDf.js.map +0 -1
- package/dist/pres-BA9_lJbY.d.ts.map +0 -1
- package/dist/presentation-Cyl74rq2.js.map +0 -1
- package/dist/presentation-types-B3VQH4Bz.d.ts.map +0 -1
- package/dist/shapes-BcyFdZpp.js.map +0 -1
- package/dist/slide-BqPtyKmb.d.ts.map +0 -1
- package/dist/table-cell-margins-PDshga8T.js.map +0 -1
- package/dist/text-BvFFMMFQ.js.map +0 -1
- package/dist/text-anchor-BgLPbwbL.js.map +0 -1
- package/dist/units-internal-DFcUYjh3.js.map +0 -1
- package/dist/zip-CTll_dr0.d.ts.map +0 -1
- package/dist/zip-CYZ0F6BV.js.map +0 -1
- package/dist/zoom-BoNyOlPm.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { w as PERCENT_SCALE } from "./
|
|
3
|
-
import { t as bytesToBinaryString } from "./binary-string-
|
|
4
|
-
|
|
1
|
+
import { d as warnOnce, r as InvalidOptionError } from "./entry-errors-JMthgJ2g.js";
|
|
2
|
+
import { w as PERCENT_SCALE } from "./enums-BP9wsb9Q.js";
|
|
3
|
+
import { t as bytesToBinaryString } from "./binary-string-Ba8VM3b9.js";
|
|
4
|
+
// src/media/image-formats.ts
|
|
5
5
|
/**
|
|
6
6
|
* Every recognised format, keyed by its canonical extension. Iteration order is sniffing order;
|
|
7
7
|
* no two signatures overlap, so it only has to be stable, not carefully chosen.
|
|
@@ -87,10 +87,9 @@ function imageFormatForBytes(bytes) {
|
|
|
87
87
|
for (const format of Object.values(IMAGE_FORMATS)) if (format.magic?.(bytes)) return format;
|
|
88
88
|
return null;
|
|
89
89
|
}
|
|
90
|
-
|
|
91
|
-
//#region src/media/base64.ts
|
|
90
|
+
// src/media/base64.ts
|
|
92
91
|
/**
|
|
93
|
-
* Base64 payload handling for media parts
|
|
92
|
+
* Base64 payload handling for media parts, isomorphic across Node and browsers
|
|
94
93
|
* (`TextEncoder`/`atob`/`btoa` only, no `Buffer`).
|
|
95
94
|
*/
|
|
96
95
|
/**
|
|
@@ -116,7 +115,7 @@ function bytesToBase64(bytes) {
|
|
|
116
115
|
* Present a freshly loaded media payload as a `data:` URI.
|
|
117
116
|
*
|
|
118
117
|
* A {@link RuntimeAdapter.loadMedia} implementation returns whichever encoding its host
|
|
119
|
-
* makes cheap
|
|
118
|
+
* makes cheap: the browser adapter a full URI, because `FileReader.readAsDataURL` is what
|
|
120
119
|
* decodes a blob without blocking; Node and the neutral adapter raw base64, because neither
|
|
121
120
|
* has a `FileReader`. This is where the two become one, so nothing downstream of the load
|
|
122
121
|
* has to ask which it got.
|
|
@@ -178,341 +177,178 @@ function decodeBase64ToBytes(b64) {
|
|
|
178
177
|
function hasBase64Header(data) {
|
|
179
178
|
return typeof data === "string" && base64PayloadStart(data) >= 0;
|
|
180
179
|
}
|
|
181
|
-
|
|
182
|
-
//#region src/ooxml/namespaces.ts
|
|
180
|
+
// src/hex-color.ts
|
|
183
181
|
/**
|
|
184
|
-
*
|
|
182
|
+
* pptx-ts: hex colour text, in the one spelling both halves use.
|
|
185
183
|
*
|
|
186
|
-
* A
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
184
|
+
* A caller may write a colour with or without a leading `#`, and the library accepts both
|
|
185
|
+
* everywhere, which means every site that validates or parses one strips it first. Those
|
|
186
|
+
* strips had drifted into three spellings across six sites, and one of them was not
|
|
187
|
+
* anchored: `.replace('#', '')` takes the `#` out of `'FF00#0'` and hands `'FF000'` on, which
|
|
188
|
+
* then fails the six-digit test and takes a different branch than the anchored forms would.
|
|
189
|
+
* No caller is known to reach that, which is exactly why it wants one spelling rather than a
|
|
190
|
+
* test at each site.
|
|
191
191
|
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
* constants
|
|
196
|
-
*
|
|
197
|
-
* reach it and neither pays for the other's dependencies. The two that fail loudly reach outside
|
|
198
|
-
* `ooxml/` for that alone: `sequence.ts` for `errors.ts`, and `check-enum.ts` for `errors.ts` and
|
|
199
|
-
* `diagnostics.ts`. `read/oxml/dom.ts` re-exports it, so no read-side import path changed.
|
|
192
|
+
* This lives at the root rather than under `gen/` or `read/` because both halves need it:
|
|
193
|
+
* the emitters strip on the way in, the readers strip on the way back out. For the same
|
|
194
|
+
* reason, the *validation* belongs here too. `REGEX_HEX_COLOR` used to live in
|
|
195
|
+
* `constants-internal.ts`, which is a write-side module the read path cannot import, so the read
|
|
196
|
+
* path re-spelled the regex; so did one write-side site. Six sites, three spellings of one fact.
|
|
200
197
|
*/
|
|
201
|
-
/** Canonical OOXML prefix → namespace URI registry. */
|
|
202
|
-
const OOXML_NS = Object.freeze({
|
|
203
|
-
a: "http://schemas.openxmlformats.org/drawingml/2006/main",
|
|
204
|
-
a14: "http://schemas.microsoft.com/office/drawing/2010/main",
|
|
205
|
-
asvg: "http://schemas.microsoft.com/office/drawing/2016/SVG/main",
|
|
206
|
-
c: "http://schemas.openxmlformats.org/drawingml/2006/chart",
|
|
207
|
-
c15: "http://schemas.microsoft.com/office/drawing/2012/chart",
|
|
208
|
-
cp: "http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
|
|
209
|
-
ct: "http://schemas.openxmlformats.org/package/2006/content-types",
|
|
210
|
-
cx: "http://schemas.microsoft.com/office/drawing/2014/chartex",
|
|
211
|
-
dc: "http://purl.org/dc/elements/1.1/",
|
|
212
|
-
dcterms: "http://purl.org/dc/terms/",
|
|
213
|
-
dgm: "http://schemas.openxmlformats.org/drawingml/2006/diagram",
|
|
214
|
-
dsp: "http://schemas.microsoft.com/office/drawing/2008/diagram",
|
|
215
|
-
ep: "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties",
|
|
216
|
-
m: "http://schemas.openxmlformats.org/officeDocument/2006/math",
|
|
217
|
-
mc: "http://schemas.openxmlformats.org/markup-compatibility/2006",
|
|
218
|
-
p: "http://schemas.openxmlformats.org/presentationml/2006/main",
|
|
219
|
-
p14: "http://schemas.microsoft.com/office/powerpoint/2010/main",
|
|
220
|
-
p15: "http://schemas.microsoft.com/office/powerpoint/2012/main",
|
|
221
|
-
p159: "http://schemas.microsoft.com/office/powerpoint/2015/9/main",
|
|
222
|
-
p188: "http://schemas.microsoft.com/office/powerpoint/2018/8/main",
|
|
223
|
-
pr: "http://schemas.openxmlformats.org/package/2006/relationships",
|
|
224
|
-
r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
|
|
225
|
-
vt: "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
|
226
|
-
});
|
|
227
198
|
/**
|
|
228
|
-
*
|
|
199
|
+
* A colour written as six hex digits, `#` already stripped.
|
|
229
200
|
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
* prefix to it, and the table elements themselves are in the `a` namespace. So it lives beside
|
|
233
|
-
* the registry rather than in it, which keeps every entry there a prefix a document can declare.
|
|
201
|
+
* Not exported: {@link isHexColor} is the whole of what the call sites want, and a shared mutable
|
|
202
|
+
* `RegExp` object is a worse export than a predicate.
|
|
234
203
|
*/
|
|
235
|
-
const
|
|
204
|
+
const REGEX_HEX_COLOR = /^[0-9a-fA-F]{6}$/;
|
|
205
|
+
/** An 8-hex RGBA colour, `#` already stripped: {@link splitRgbaHex}'s test. */
|
|
206
|
+
const REGEX_ARGB_HEX = /^[0-9a-fA-F]{8}$/;
|
|
207
|
+
/** Strip a single leading `#` from a colour, leaving any other character alone. */
|
|
208
|
+
function stripHash(value) {
|
|
209
|
+
return value.startsWith("#") ? value.slice(1) : value;
|
|
210
|
+
}
|
|
236
211
|
/**
|
|
237
|
-
*
|
|
238
|
-
* have always written them.
|
|
212
|
+
* Is `value` a 6-hex RGB colour? A leading `#` is stripped first, so both spellings agree.
|
|
239
213
|
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
214
|
+
* This is the *shape* test only. Whether the caller may also name a scheme colour there is the
|
|
215
|
+
* call site's question, and each still asks it: `createColorElement` falls back to the default
|
|
216
|
+
* font colour, `makeXmlTheme` keeps the Office default and warns, `normalizeHex` throws.
|
|
217
|
+
* @param value - the caller's colour, with or without a leading `#`
|
|
244
218
|
*/
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
"xmlns:p": OOXML_NS.p
|
|
249
|
-
});
|
|
250
|
-
//#endregion
|
|
251
|
-
//#region src/ooxml/rel-types.ts
|
|
219
|
+
function isHexColor(value) {
|
|
220
|
+
return REGEX_HEX_COLOR.test(stripHash(value));
|
|
221
|
+
}
|
|
252
222
|
/**
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
* These are long, near-identical strings that differ in one path segment, which makes a typo
|
|
256
|
-
* both easy to write and invisible on review — a wrong URI does not throw, it silently matches
|
|
257
|
-
* nothing on the read side and produces a part PowerPoint ignores or rejects on the write side.
|
|
258
|
-
*
|
|
259
|
-
* **Why this module is neither `gen/` nor `read/`.** Both halves need the same URIs, and for a
|
|
260
|
-
* while each kept its own copy (`gen/oxml/schema-uris.ts`, `read/api/rel-types.ts`), with a note
|
|
261
|
-
* in both saying a shared home was "a separate decision". It is this module: a rel type is a fact
|
|
262
|
-
* about the OOXML package format, not about writing or reading one, so neither side should own it.
|
|
263
|
-
* A divergence between the two copies would mean the writer emitting a rel the reader cannot find
|
|
264
|
-
* — a round-trip bug with no compile-time signal.
|
|
265
|
-
*
|
|
266
|
-
* Only types used by more than one module live here. A rel type exactly one module cares about
|
|
267
|
-
* (`tags`, `oleObject`, the modern comments part, …) stays declared next to the code that reads or
|
|
268
|
-
* emits it — hoisting those would trade a definition you can see for one you have to go and find,
|
|
269
|
-
* and buy nothing. A writer and a reader of the same part count as two modules even when each
|
|
270
|
-
* names the string once: that pair is exactly the divergence this module exists to prevent.
|
|
223
|
+
* Is `value` an 8-hex RGBA colour? A leading `#` is stripped first.
|
|
271
224
|
*
|
|
272
|
-
* The
|
|
273
|
-
*
|
|
274
|
-
*/
|
|
275
|
-
/**
|
|
276
|
-
* Prefix for `.rels` `Type` URIs — append the type name (`slide`, `image`, `theme`, …).
|
|
277
|
-
* Exported for the write side, which builds one-off rel types at their call sites.
|
|
278
|
-
*/
|
|
279
|
-
const OFFICE_REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/";
|
|
280
|
-
/** `xmlns` of every `<Relationships>` part. Also the prefix of the package-scoped rel types. */
|
|
281
|
-
const PACKAGE_REL_NS = OOXML_NS.pr;
|
|
282
|
-
/**
|
|
283
|
-
* Prefix for the Microsoft rel types this library emits and reads. Exported for the same reason
|
|
284
|
-
* as {@link OFFICE_REL}: a rel type only one module names is built from it at that module's call site.
|
|
285
|
-
*/
|
|
286
|
-
const MS_REL = "http://schemas.microsoft.com/office/";
|
|
287
|
-
/** `p:sldIdLst` → a slide part. */
|
|
288
|
-
const SLIDE_REL = OFFICE_REL + "slide";
|
|
289
|
-
/** A slide → its layout; a master → each of its layouts. */
|
|
290
|
-
const SLIDE_LAYOUT_REL = OFFICE_REL + "slideLayout";
|
|
291
|
-
/** A layout → its master; the presentation → each master. */
|
|
292
|
-
const SLIDE_MASTER_REL = OFFICE_REL + "slideMaster";
|
|
293
|
-
/** A slide → its notes slide. */
|
|
294
|
-
const NOTES_SLIDE_REL = OFFICE_REL + "notesSlide";
|
|
295
|
-
/** A notes slide → the notes master; the presentation → the notes master. */
|
|
296
|
-
const NOTES_MASTER_REL = OFFICE_REL + "notesMaster";
|
|
297
|
-
/** A master or notes master → its theme. Layouts and slides inherit it rather than holding one. */
|
|
298
|
-
const THEME_REL = OFFICE_REL + "theme";
|
|
299
|
-
/** The package root → `ppt/presentation.xml`. The entry point to everything above. */
|
|
300
|
-
const OFFICE_DOCUMENT_REL = OFFICE_REL + "officeDocument";
|
|
301
|
-
/** Any part → an image in `ppt/media/`. */
|
|
302
|
-
const IMAGE_REL = OFFICE_REL + "image";
|
|
303
|
-
/** Any part → an external or internal jump target. External ones carry `TargetMode="External"`. */
|
|
304
|
-
const HYPERLINK_REL = OFFICE_REL + "hyperlink";
|
|
305
|
-
/** The presentation → `ppt/tableStyles.xml`. */
|
|
306
|
-
const TABLE_STYLES_REL = OFFICE_REL + "tableStyles";
|
|
307
|
-
/** The package root → `docProps/core.xml`. Package-scoped, so not under {@link OFFICE_REL}. */
|
|
308
|
-
const CORE_PROPS_REL = PACKAGE_REL_NS + "/metadata/core-properties";
|
|
309
|
-
/** The package root → `docProps/app.xml`. */
|
|
310
|
-
const EXTENDED_PROPS_REL = OFFICE_REL + "extended-properties";
|
|
311
|
-
/** The package root → `docProps/custom.xml`. */
|
|
312
|
-
const CUSTOM_PROPS_REL = OFFICE_REL + "custom-properties";
|
|
313
|
-
/** A slide → its legacy comments part (`ppt/comments/commentN.xml`). */
|
|
314
|
-
const COMMENTS_REL = OFFICE_REL + "comments";
|
|
315
|
-
/** The presentation → the deck-wide legacy comment-author registry (`ppt/commentAuthors.xml`). */
|
|
316
|
-
const COMMENT_AUTHORS_REL = OFFICE_REL + "commentAuthors";
|
|
317
|
-
/** The presentation → the 2018 comment-author registry (`ppt/authors.xml`), a Microsoft rel type. */
|
|
318
|
-
const MODERN_COMMENT_AUTHORS_REL = MS_REL + "2018/10/relationships/authors";
|
|
319
|
-
/** The presentation → `ppt/presProps.xml`. */
|
|
320
|
-
const PRES_PROPS_REL = OFFICE_REL + "presProps";
|
|
321
|
-
/** The presentation → `ppt/viewProps.xml`. */
|
|
322
|
-
const VIEW_PROPS_REL = OFFICE_REL + "viewProps";
|
|
323
|
-
/** The presentation → the handout master. */
|
|
324
|
-
const HANDOUT_MASTER_REL = OFFICE_REL + "handoutMaster";
|
|
325
|
-
/** A part → a theme override, which replaces the deck theme for that part alone. */
|
|
326
|
-
const THEME_OVERRIDE_REL = OFFICE_REL + "themeOverride";
|
|
327
|
-
/** The presentation → an embedded font part, one per face. */
|
|
328
|
-
const FONT_REL = OFFICE_REL + "font";
|
|
329
|
-
/** A slide → an audio blob in `ppt/media/`. Paired with {@link MS_MEDIA_REL} on the same target. */
|
|
330
|
-
const AUDIO_REL = OFFICE_REL + "audio";
|
|
331
|
-
/** A slide → a video blob in `ppt/media/`, or an online-video placeholder. Paired with {@link MS_MEDIA_REL}. */
|
|
332
|
-
const VIDEO_REL = OFFICE_REL + "video";
|
|
333
|
-
/**
|
|
334
|
-
* The MS-2007 `media` rel every audio/video shape carries alongside the ECMA one, pointing at the
|
|
335
|
-
* same target. It is what `<p14:media r:embed>` resolves, so a media shape needs both.
|
|
225
|
+
* The 8-digit form is RGB followed by one alpha byte; {@link splitRgbaHex} is what takes it apart.
|
|
226
|
+
* @param value - the caller's colour, with or without a leading `#`
|
|
336
227
|
*/
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
/** A slide → a classic (`c:`) chart part. */
|
|
341
|
-
const CHART_REL = OFFICE_REL + "chart";
|
|
342
|
-
/** A slide → a chartEx (`cx:`, Office 2016) chart part — an MS rel, not the ECMA `chart` one. */
|
|
343
|
-
const CHARTEX_REL = MS_REL + "2014/relationships/chartEx";
|
|
344
|
-
/** A chart part → its mandatory style sidecar. */
|
|
345
|
-
const CHART_STYLE_REL = MS_REL + "2011/relationships/chartStyle";
|
|
346
|
-
/** A chart part → its mandatory colour-style sidecar. */
|
|
347
|
-
const CHART_COLOR_STYLE_REL = MS_REL + "2011/relationships/chartColorStyle";
|
|
348
|
-
/** Any part → an embedded OPC package (an Office file, itself a zip): a chart's workbook, an OLE payload. */
|
|
349
|
-
const PACKAGE_REL = OFFICE_REL + "package";
|
|
228
|
+
function isArgbHex(value) {
|
|
229
|
+
return REGEX_ARGB_HEX.test(stripHash(value));
|
|
230
|
+
}
|
|
350
231
|
/**
|
|
351
|
-
*
|
|
352
|
-
*
|
|
232
|
+
* Split an 8-hex RGBA colour into its 6-hex RGB and a 0–1 alpha; anything else passes through
|
|
233
|
+
* unchanged with no alpha.
|
|
234
|
+
*
|
|
235
|
+
* `#` is stripped first, so both spellings reach the same answer. Two sites parsed this by
|
|
236
|
+
* hand (`createColorElement`, which turns the alpha into an `<a:alpha>` sibling, and
|
|
237
|
+
* `normalizeShadowOptions`, which turns it into a shadow's `_alpha`), and they divided by 255 at
|
|
238
|
+
* different points in their arithmetic.
|
|
239
|
+
* @param value - the caller's colour, with or without a leading `#`
|
|
353
240
|
*/
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
/** `ppt/slideMasters/slideMasterN.xml`. */
|
|
364
|
-
const SLIDE_MASTER_CONTENT_TYPE = OD_CONTENT + "presentationml.slideMaster+xml";
|
|
365
|
-
/** `ppt/slideLayouts/slideLayoutN.xml`. */
|
|
366
|
-
const SLIDE_LAYOUT_CONTENT_TYPE = OD_CONTENT + "presentationml.slideLayout+xml";
|
|
367
|
-
/** `ppt/notesSlides/notesSlideN.xml`. */
|
|
368
|
-
const NOTES_SLIDE_CONTENT_TYPE = OD_CONTENT + "presentationml.notesSlide+xml";
|
|
369
|
-
/** `ppt/notesMasters/notesMasterN.xml`. */
|
|
370
|
-
const NOTES_MASTER_CONTENT_TYPE = OD_CONTENT + "presentationml.notesMaster+xml";
|
|
371
|
-
/** `ppt/theme/themeN.xml`. Not `presentationml.`: a theme is a DrawingML part. */
|
|
372
|
-
const THEME_CONTENT_TYPE = OD_CONTENT + "theme+xml";
|
|
373
|
-
/** `ppt/tableStyles.xml`. */
|
|
374
|
-
const TABLE_STYLES_CONTENT_TYPE = OD_CONTENT + "presentationml.tableStyles+xml";
|
|
375
|
-
/** `ppt/presentation.xml` in an editable `.pptx`. A `.potx` template's main part is a different one. */
|
|
376
|
-
const PRESENTATION_MAIN_CONTENT_TYPE = OD_CONTENT + "presentationml.presentation.main+xml";
|
|
377
|
-
/** Every `.rels` part. Declared once as a `Default` for the `rels` extension, never as an Override. */
|
|
378
|
-
const RELATIONSHIPS_CONTENT_TYPE = PACKAGE_CONTENT + "relationships+xml";
|
|
379
|
-
/** `ppt/presProps.xml`. */
|
|
380
|
-
const PRES_PROPS_CONTENT_TYPE = OD_CONTENT + "presentationml.presProps+xml";
|
|
381
|
-
/** `ppt/viewProps.xml`. */
|
|
382
|
-
const VIEW_PROPS_CONTENT_TYPE = OD_CONTENT + "presentationml.viewProps+xml";
|
|
383
|
-
/** `ppt/comments/commentN.xml`, a legacy comments part. */
|
|
384
|
-
const COMMENTS_CONTENT_TYPE = OD_CONTENT + "presentationml.comments+xml";
|
|
385
|
-
/** `ppt/commentAuthors.xml`. */
|
|
386
|
-
const COMMENT_AUTHORS_CONTENT_TYPE = OD_CONTENT + "presentationml.commentAuthors+xml";
|
|
387
|
-
/** `docProps/core.xml`. Package-scoped, so not under the officedocument prefix. */
|
|
388
|
-
const CORE_PROPS_CONTENT_TYPE = PACKAGE_CONTENT + "core-properties+xml";
|
|
389
|
-
/** `docProps/app.xml`. */
|
|
390
|
-
const EXTENDED_PROPS_CONTENT_TYPE = OD_CONTENT + "extended-properties+xml";
|
|
391
|
-
/** `docProps/custom.xml`. */
|
|
392
|
-
const CUSTOM_PROPS_CONTENT_TYPE = OD_CONTENT + "custom-properties+xml";
|
|
393
|
-
/** `ppt/charts/chartN.xml`, a classic (`c:`) chart. */
|
|
394
|
-
const CHART_CONTENT_TYPE = OD_CONTENT + "drawingml.chart+xml";
|
|
395
|
-
/** `ppt/charts/chartExN.xml`. A chartEx part carries a Microsoft content type, not an `openxmlformats` one. */
|
|
396
|
-
const CHARTEX_CONTENT_TYPE = MS_OFFICE_CONTENT + "chartex+xml";
|
|
397
|
-
/** A chart's mandatory `style{N}.xml` sidecar. */
|
|
398
|
-
const CHART_STYLE_CONTENT_TYPE = MS_OFFICE_CONTENT + "chartstyle+xml";
|
|
399
|
-
/** A chart's mandatory `colors{N}.xml` sidecar. */
|
|
400
|
-
const CHART_COLOR_STYLE_CONTENT_TYPE = MS_OFFICE_CONTENT + "chartcolorstyle+xml";
|
|
401
|
-
/** An embedded `.xlsx` workbook: a chart's data, or an OLE payload. */
|
|
402
|
-
const XLSX_CONTENT_TYPE = OD_CONTENT + "spreadsheetml.sheet";
|
|
241
|
+
function splitRgbaHex(value) {
|
|
242
|
+
const hex = stripHash(value);
|
|
243
|
+
if (!isArgbHex(hex)) return { rgb: hex };
|
|
244
|
+
return {
|
|
245
|
+
rgb: hex.slice(0, 6),
|
|
246
|
+
alpha: parseInt(hex.slice(6, 8), 16) / 255
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
// src/ooxml/xsd-boolean.ts
|
|
403
250
|
/**
|
|
404
|
-
*
|
|
251
|
+
* Parsing an `xsd:boolean` attribute value.
|
|
405
252
|
*
|
|
406
|
-
*
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
},
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
contentType: null,
|
|
506
|
-
scope: "page"
|
|
507
|
-
},
|
|
508
|
-
{
|
|
509
|
-
relType: HYPERLINK_REL,
|
|
510
|
-
contentType: null,
|
|
511
|
-
scope: "page"
|
|
512
|
-
}
|
|
513
|
-
];
|
|
514
|
-
//#endregion
|
|
515
|
-
//#region src/ooxml/st-enums.ts
|
|
253
|
+
* **Why a function at all.** `xsd:boolean` has four lexical forms (`1`, `0`, `true`, `false`),
|
|
254
|
+
* and OOXML attributes typed with it accept every one of them. PowerPoint writes only `1` and
|
|
255
|
+
* `0`, so a hand-rolled `=== '1'` test passes against every deck this library produces and
|
|
256
|
+
* against every deck PowerPoint produces, and silently misreads the other producers. That is the
|
|
257
|
+
* worst shape a bug can have: invisible to the fixtures, visible only on a customer's file.
|
|
258
|
+
*
|
|
259
|
+
* **Why this module is neither `gen/` nor `read/`.** The lexical space of a schema type is a fact
|
|
260
|
+
* about the schema, like `sequence.ts`'s document order and `body-insets.ts`'s defaults. The
|
|
261
|
+
* parser lived in `read/oxml/dom.ts` because reading is where most of the demand is, and three
|
|
262
|
+
* private copies had collapsed into it, but `read/oxml/dom.ts` imports `@xmldom/xmldom`, so
|
|
263
|
+
* anything outside `read/` that wants this five-line function has to take a DOM dependency to get
|
|
264
|
+
* it, or write a fourth copy. `script/from-read/detect.ts` hit exactly that and wrote the copy.
|
|
265
|
+
*
|
|
266
|
+
* The DOM-typed convenience wrapper stays behind in `read/oxml/dom.ts` as `boolAttr`, because
|
|
267
|
+
* *that* one really is about reading an element.
|
|
268
|
+
*
|
|
269
|
+
* **The write direction is here too**, and it is where the interesting distinction lives: an
|
|
270
|
+
* emitter writing a boolean has THREE useful shapes, not one; see {@link xsdBool} and
|
|
271
|
+
* {@link xsdBoolIfTrue}. Sixty-odd inline ternaries spelled them in three ways with nothing
|
|
272
|
+
* naming which was which.
|
|
273
|
+
*/
|
|
274
|
+
/**
|
|
275
|
+
* Parse an `xsd:boolean` OOXML attribute (`1`/`0`/`true`/`false`); else `null`.
|
|
276
|
+
*
|
|
277
|
+
* `null` for an absent *or* unparseable value is deliberate and load-bearing at the call sites:
|
|
278
|
+
* several attributes have a schema default of `true`, so they test `!== false` rather than
|
|
279
|
+
* `=== true` and an unset attribute has to be distinguishable from an explicit `0`.
|
|
280
|
+
*/
|
|
281
|
+
function boolValue(value) {
|
|
282
|
+
if (value === "1" || value === "true") return true;
|
|
283
|
+
if (value === "0" || value === "false") return false;
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* A boolean as the `1`/`0` an `xsd:boolean` attribute takes.
|
|
288
|
+
*
|
|
289
|
+
* Writes the attribute either way, so `false` is *stated*. Use this wherever the schema
|
|
290
|
+
* default is `true`, or wherever the absence of the attribute would mean something other
|
|
291
|
+
* than `false`: a value inherited from a list style, a layout or the theme.
|
|
292
|
+
* @param value - the resolved boolean
|
|
293
|
+
*/
|
|
294
|
+
function xsdBool(value) {
|
|
295
|
+
return value ? "1" : "0";
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* A boolean as `1`, or `null` so the attribute is left out entirely.
|
|
299
|
+
*
|
|
300
|
+
* **Correct only where the schema default is `false`.** It collapses "false" and "unset" into
|
|
301
|
+
* one output, which is the two-spellings-for-three-states shape the API policy warns about: the
|
|
302
|
+
* next attribute with a `true` default written this way reads as correct and is wrong. Every
|
|
303
|
+
* current caller is on a `false`-defaulting attribute, so the collapse costs nothing today;
|
|
304
|
+
* naming it is what makes the next one visible.
|
|
305
|
+
* @param value - the resolved boolean
|
|
306
|
+
*/
|
|
307
|
+
function xsdBoolIfTrue(value) {
|
|
308
|
+
return value ? "1" : null;
|
|
309
|
+
}
|
|
310
|
+
// src/ooxml/check-enum.ts
|
|
311
|
+
/**
|
|
312
|
+
* Check a value against its `ST_` union, reporting and dropping it when outside (the write-path
|
|
313
|
+
* policy, described in the module note).
|
|
314
|
+
*
|
|
315
|
+
* `undefined`/`null` returns `null` without reporting: an unset option is not an invalid one, and
|
|
316
|
+
* it is by far the common case.
|
|
317
|
+
*
|
|
318
|
+
* The offending value is interpolated into the message deliberately. {@link warnOnce} dedups on
|
|
319
|
+
* code **and** message, so keeping the value in the text is what lets a second, *different* bad
|
|
320
|
+
* value under the same code still get reported.
|
|
321
|
+
* @param value - the value the caller supplied, if any
|
|
322
|
+
* @param valid - the enum's members
|
|
323
|
+
* @param code - the condition to report
|
|
324
|
+
* @param label - how to name the offending option in the message, e.g. ``'table cell: cell3D `preset`'``
|
|
325
|
+
* @param detail - extra structured context to merge into the diagnostic's `detail`
|
|
326
|
+
* @returns the value when legal, else `null`
|
|
327
|
+
*/
|
|
328
|
+
function checkEnumOrWarn(value, valid, code, label, detail) {
|
|
329
|
+
if (value === void 0 || value === null) return null;
|
|
330
|
+
if (valid.includes(value)) return value;
|
|
331
|
+
warnOnce(code, `${label} value \`${String(value)}\` is not valid and is ignored. Use one of ${valid.join(", ")}.`, {
|
|
332
|
+
received: value,
|
|
333
|
+
valid,
|
|
334
|
+
...detail
|
|
335
|
+
});
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Check a value against its `ST_` union, throwing when outside (the read/edit-path policy, described
|
|
340
|
+
* in the module note).
|
|
341
|
+
* @param value - the value the caller asked for
|
|
342
|
+
* @param valid - the enum's members
|
|
343
|
+
* @param attribute - the attribute's name, for the message
|
|
344
|
+
* @param code - the condition to report
|
|
345
|
+
* @returns `value`, when it is legal
|
|
346
|
+
*/
|
|
347
|
+
function checkEnumOrThrow(value, valid, attribute, code) {
|
|
348
|
+
if (valid.includes(value)) return value;
|
|
349
|
+
throw new InvalidOptionError(code, `Invalid ${attribute}: ${JSON.stringify(value)}. Expected one of: ${valid.join(", ")}.`);
|
|
350
|
+
}
|
|
351
|
+
// src/ooxml/st-enums.ts
|
|
516
352
|
/**
|
|
517
353
|
* `ST_` simple-type enumerations from ECMA-376, declared once as the single source of both the
|
|
518
354
|
* TypeScript union a caller is checked against and the runtime list a value is validated against.
|
|
@@ -525,7 +361,7 @@ const SHARED_PARTS = [
|
|
|
525
361
|
* which is harmless, but nothing would have caught a divergence in *content*.
|
|
526
362
|
*
|
|
527
363
|
* **The shape.** Every entry is a `readonly` tuple declared `as const`, with its union derived via
|
|
528
|
-
* `(typeof X)[number]`. Widening the tuple widens the union in the same edit
|
|
364
|
+
* `(typeof X)[number]`. Widening the tuple widens the union in the same edit, so they cannot drift.
|
|
529
365
|
* This is the idiom `EXTRA_SHAPE_PRESETS` already used; this module brings the stragglers onto it,
|
|
530
366
|
* and holds a few closed schema lists that are not `ST_` types, such as `EMBEDDED_FONT_SLOTS`.
|
|
531
367
|
*
|
|
@@ -543,11 +379,11 @@ const SHARED_PARTS = [
|
|
|
543
379
|
* unfinished for a while. `src/types/chart.ts`
|
|
544
380
|
* hand-wrote four of those unions beside the option that takes them and typed the other three as
|
|
545
381
|
* bare `string`, so `barDir` carried no compile-time check at all, and `dataLabelPosition`'s
|
|
546
|
-
* hand-written union was missing `inBase
|
|
382
|
+
* hand-written union was missing `inBase`, a value the validator accepts on a stacked bar, so
|
|
547
383
|
* the two spellings had already diverged in content. Both are gone: for every option here, the
|
|
548
384
|
* type a caller is checked against and the tuple the validator checks are one declaration.
|
|
549
385
|
*/
|
|
550
|
-
/** `ST_TextAutonumberScheme
|
|
386
|
+
/** `ST_TextAutonumberScheme`: the numbering an auto-numbered bullet counts in (`a:buAutoNum/@type`). */
|
|
551
387
|
const TEXT_AUTONUM_SCHEMES = [
|
|
552
388
|
"alphaLcParenBoth",
|
|
553
389
|
"alphaUcParenBoth",
|
|
@@ -591,19 +427,19 @@ const TEXT_AUTONUM_SCHEMES = [
|
|
|
591
427
|
"hindiNumParenR",
|
|
592
428
|
"hindiAlpha1Period"
|
|
593
429
|
];
|
|
594
|
-
/** `ST_TextStrikeType
|
|
430
|
+
/** `ST_TextStrikeType`: a run's strikethrough (`a:rPr/@strike`). */
|
|
595
431
|
const TEXT_STRIKE_TYPES = [
|
|
596
432
|
"noStrike",
|
|
597
433
|
"sngStrike",
|
|
598
434
|
"dblStrike"
|
|
599
435
|
];
|
|
600
|
-
/** `ST_TextCapsType
|
|
436
|
+
/** `ST_TextCapsType`: a run's capitalization (`a:rPr/@cap`). */
|
|
601
437
|
const TEXT_CAPS_TYPES = [
|
|
602
438
|
"none",
|
|
603
439
|
"small",
|
|
604
440
|
"all"
|
|
605
441
|
];
|
|
606
|
-
/** `ST_TextUnderlineType
|
|
442
|
+
/** `ST_TextUnderlineType`: a run's underline (`a:rPr/@u`). */
|
|
607
443
|
const TEXT_UNDERLINE_TYPES = [
|
|
608
444
|
"none",
|
|
609
445
|
"words",
|
|
@@ -624,7 +460,7 @@ const TEXT_UNDERLINE_TYPES = [
|
|
|
624
460
|
"wavyHeavy",
|
|
625
461
|
"wavyDbl"
|
|
626
462
|
];
|
|
627
|
-
/** `ST_TextTabAlignType
|
|
463
|
+
/** `ST_TextTabAlignType`: a tab stop's alignment (`a:tab/@algn`). */
|
|
628
464
|
const TEXT_TAB_ALIGN_TYPES = [
|
|
629
465
|
"l",
|
|
630
466
|
"ctr",
|
|
@@ -632,7 +468,7 @@ const TEXT_TAB_ALIGN_TYPES = [
|
|
|
632
468
|
"dec"
|
|
633
469
|
];
|
|
634
470
|
/**
|
|
635
|
-
* `ST_SchemeColorVal
|
|
471
|
+
* `ST_SchemeColorVal`: a theme colour reference (`a:schemeClr/@val`). Wider than
|
|
636
472
|
* {@link THEME_COLOR_SLOTS}: it adds the `bg1`/`tx1`/`bg2`/`tx2` aliases the colour map resolves,
|
|
637
473
|
* and `phClr`, the colour a theme style-matrix entry is applied in.
|
|
638
474
|
*/
|
|
@@ -713,7 +549,7 @@ const TRANSITION_VARIANT_ATTRIBUTES = {
|
|
|
713
549
|
zoom: ["dir"]
|
|
714
550
|
};
|
|
715
551
|
/**
|
|
716
|
-
* `ST_BevelPresetType
|
|
552
|
+
* `ST_BevelPresetType`: the bevel profile applied to a 3-D edge.
|
|
717
553
|
* @see ECMA-376 Part 1 §20.1.10.9
|
|
718
554
|
*/
|
|
719
555
|
const BEVEL_PRESETS = [
|
|
@@ -731,7 +567,7 @@ const BEVEL_PRESETS = [
|
|
|
731
567
|
"artDeco"
|
|
732
568
|
];
|
|
733
569
|
/**
|
|
734
|
-
* `ST_PresetMaterialType
|
|
570
|
+
* `ST_PresetMaterialType`: how a 3-D surface responds to light.
|
|
735
571
|
* @see ECMA-376 Part 1 §20.1.10.50
|
|
736
572
|
*/
|
|
737
573
|
const PRESET_MATERIALS = [
|
|
@@ -752,7 +588,7 @@ const PRESET_MATERIALS = [
|
|
|
752
588
|
"softmetal"
|
|
753
589
|
];
|
|
754
590
|
/**
|
|
755
|
-
* `ST_LightRigType
|
|
591
|
+
* `ST_LightRigType`: the preset lighting scene.
|
|
756
592
|
* @see ECMA-376 Part 1 §20.1.10.35
|
|
757
593
|
*/
|
|
758
594
|
const LIGHT_RIGS = [
|
|
@@ -785,7 +621,7 @@ const LIGHT_RIGS = [
|
|
|
785
621
|
"brightRoom"
|
|
786
622
|
];
|
|
787
623
|
/**
|
|
788
|
-
* `ST_LightRigDirection
|
|
624
|
+
* `ST_LightRigDirection`: where the light rig sits relative to the scene.
|
|
789
625
|
* @see ECMA-376 Part 1 §20.1.10.33
|
|
790
626
|
*/
|
|
791
627
|
const LIGHT_RIG_DIRECTIONS = [
|
|
@@ -799,12 +635,12 @@ const LIGHT_RIG_DIRECTIONS = [
|
|
|
799
635
|
"br"
|
|
800
636
|
];
|
|
801
637
|
/**
|
|
802
|
-
* `ST_TextHorzOverflowType
|
|
638
|
+
* `ST_TextHorzOverflowType`: `a:bodyPr/@horzOverflow` and `a:tcPr/@horzOverflow`.
|
|
803
639
|
* @see ECMA-376 Part 1 §20.1.10.68
|
|
804
640
|
*/
|
|
805
641
|
const TEXT_HORZ_OVERFLOW = ["clip", "overflow"];
|
|
806
642
|
/**
|
|
807
|
-
* `ST_TextAnchoringType
|
|
643
|
+
* `ST_TextAnchoringType`: `a:bodyPr/@anchor` and `a:tcPr/@anchor`.
|
|
808
644
|
* @see ECMA-376 Part 1 §20.1.10.60
|
|
809
645
|
*/
|
|
810
646
|
const TEXT_ANCHORS = [
|
|
@@ -815,7 +651,7 @@ const TEXT_ANCHORS = [
|
|
|
815
651
|
"dist"
|
|
816
652
|
];
|
|
817
653
|
/**
|
|
818
|
-
* `ST_PresetPatternVal
|
|
654
|
+
* `ST_PresetPatternVal`: `a:pattFill/@prst`, the hatch a pattern fill draws.
|
|
819
655
|
*/
|
|
820
656
|
const PATTERN_PRESETS = [
|
|
821
657
|
"pct5",
|
|
@@ -874,7 +710,7 @@ const PATTERN_PRESETS = [
|
|
|
874
710
|
"zigZag"
|
|
875
711
|
];
|
|
876
712
|
/**
|
|
877
|
-
* `ST_TextVerticalType
|
|
713
|
+
* `ST_TextVerticalType`: `a:bodyPr/@vert` and `a:tcPr/@vert`.
|
|
878
714
|
* @see ECMA-376 Part 1 §20.1.10.83
|
|
879
715
|
*/
|
|
880
716
|
const TEXT_VERTICAL = [
|
|
@@ -887,7 +723,7 @@ const TEXT_VERTICAL = [
|
|
|
887
723
|
"wordArtVertRtl"
|
|
888
724
|
];
|
|
889
725
|
/**
|
|
890
|
-
* `ST_LineEndType
|
|
726
|
+
* `ST_LineEndType`: the arrowhead at either end of a stroke (`a:headEnd/@type`,
|
|
891
727
|
* `a:tailEnd/@type`).
|
|
892
728
|
* @see ECMA-376 Part 1 §20.1.10.33
|
|
893
729
|
*/
|
|
@@ -914,11 +750,34 @@ const EMBEDDED_FONT_SLOTS = [
|
|
|
914
750
|
"boldItalic"
|
|
915
751
|
];
|
|
916
752
|
/**
|
|
917
|
-
* `
|
|
753
|
+
* `ST_PlaceholderType`: the kind of placeholder a `p:ph` fills (`p:ph/@type`). Absent, it means
|
|
754
|
+
* `obj`.
|
|
755
|
+
* @see ECMA-376 Part 1 §19.7.10
|
|
756
|
+
*/
|
|
757
|
+
const PLACEHOLDER_TYPES = [
|
|
758
|
+
"title",
|
|
759
|
+
"body",
|
|
760
|
+
"ctrTitle",
|
|
761
|
+
"subTitle",
|
|
762
|
+
"dt",
|
|
763
|
+
"sldNum",
|
|
764
|
+
"ftr",
|
|
765
|
+
"hdr",
|
|
766
|
+
"obj",
|
|
767
|
+
"chart",
|
|
768
|
+
"tbl",
|
|
769
|
+
"clipArt",
|
|
770
|
+
"dgm",
|
|
771
|
+
"media",
|
|
772
|
+
"sldImg",
|
|
773
|
+
"pic"
|
|
774
|
+
];
|
|
775
|
+
/**
|
|
776
|
+
* `ST_TextShapeType`: the preset path text is bent along (`a:prstTxWarp/@prst`), which
|
|
918
777
|
* PowerPoint calls WordArt.
|
|
919
778
|
*
|
|
920
779
|
* `textNoShape` is the identity member: it is legal, and it warps nothing. The library does not
|
|
921
|
-
* narrow this set
|
|
780
|
+
* narrow this set: every member is a shape PowerPoint draws.
|
|
922
781
|
* @see ECMA-376 Part 1 §20.1.10.76
|
|
923
782
|
*/
|
|
924
783
|
const TEXT_SHAPE_TYPES = [
|
|
@@ -965,7 +824,7 @@ const TEXT_SHAPE_TYPES = [
|
|
|
965
824
|
"textCascadeDown"
|
|
966
825
|
];
|
|
967
826
|
/**
|
|
968
|
-
* `ST_PresetLineDashVal
|
|
827
|
+
* `ST_PresetLineDashVal`: the dash pattern of a line or border (`a:prstDash/@val`).
|
|
969
828
|
*
|
|
970
829
|
* The `sys*` members are the "system" dashes whose exact dot/gap ratio the renderer picks; the
|
|
971
830
|
* rest are defined by the spec. Both `BorderProps.dashType` and `ShapeLineProps.dashType` accept
|
|
@@ -986,12 +845,12 @@ const PRESET_LINE_DASHES = [
|
|
|
986
845
|
"sysDashDotDot"
|
|
987
846
|
];
|
|
988
847
|
/**
|
|
989
|
-
* `ST_BarDir
|
|
848
|
+
* `ST_BarDir`: whether a bar/column plot runs horizontally or vertically (`c:barDir/@val`).
|
|
990
849
|
* @see ECMA-376 Part 1 §21.2.3.3
|
|
991
850
|
*/
|
|
992
851
|
const BAR_DIRECTIONS = ["bar", "col"];
|
|
993
852
|
/**
|
|
994
|
-
* `ST_BarGrouping
|
|
853
|
+
* `ST_BarGrouping`: how a bar/column plot stacks its series (`c:grouping/@val` inside
|
|
995
854
|
* `c:barChart`/`c:bar3DChart`).
|
|
996
855
|
* @see ECMA-376 Part 1 §21.2.3.4
|
|
997
856
|
*/
|
|
@@ -1002,7 +861,7 @@ const BAR_GROUPINGS = [
|
|
|
1002
861
|
"stacked"
|
|
1003
862
|
];
|
|
1004
863
|
/**
|
|
1005
|
-
* `ST_Grouping
|
|
864
|
+
* `ST_Grouping`: the same decision for the plots that have no clustered form
|
|
1006
865
|
* (`c:areaChart`, `c:lineChart`).
|
|
1007
866
|
* @see ECMA-376 Part 1 §21.2.3.17
|
|
1008
867
|
*/
|
|
@@ -1012,7 +871,7 @@ const GROUPINGS = [
|
|
|
1012
871
|
"stacked"
|
|
1013
872
|
];
|
|
1014
873
|
/**
|
|
1015
|
-
* `ST_Shape
|
|
874
|
+
* `ST_Shape`: the solid a 3-D bar is drawn as (`c:shape/@val`).
|
|
1016
875
|
* @see ECMA-376 Part 1 §21.2.3.35
|
|
1017
876
|
*/
|
|
1018
877
|
const BAR_3D_SHAPES = [
|
|
@@ -1024,7 +883,7 @@ const BAR_3D_SHAPES = [
|
|
|
1024
883
|
"pyramidToMax"
|
|
1025
884
|
];
|
|
1026
885
|
/**
|
|
1027
|
-
* `ST_RadarStyle
|
|
886
|
+
* `ST_RadarStyle`: how a radar plot is drawn (`c:radarStyle/@val`).
|
|
1028
887
|
* @see ECMA-376 Part 1 §21.2.3.33
|
|
1029
888
|
*/
|
|
1030
889
|
const RADAR_STYLES = [
|
|
@@ -1039,8 +898,8 @@ const RADAR_STYLES = [
|
|
|
1039
898
|
* what made the other two read as typos rather than as a second vocabulary.
|
|
1040
899
|
*
|
|
1041
900
|
* Both spellings are accepted on the public option and normalized to the wire one at definition
|
|
1042
|
-
* time. Before that, `radarStyle: 'marker'`
|
|
1043
|
-
* reading a chart part
|
|
901
|
+
* time. Before that, `radarStyle: 'marker'` (the schema's word, and the obvious guess for anyone
|
|
902
|
+
* reading a chart part) failed the enum check and silently fell back to `standard`, so a caller
|
|
1044
903
|
* asking for markers got a plain radar.
|
|
1045
904
|
*/
|
|
1046
905
|
const RADAR_STYLE_ALIASES = {
|
|
@@ -1049,12 +908,12 @@ const RADAR_STYLE_ALIASES = {
|
|
|
1049
908
|
};
|
|
1050
909
|
/**
|
|
1051
910
|
* The alias spellings alone, for the definer's enum check. Derived from the map rather than
|
|
1052
|
-
* written out again
|
|
911
|
+
* written out again: the whole point of this module is that the list a value is validated
|
|
1053
912
|
* against and the union it is typed against cannot drift apart.
|
|
1054
913
|
*/
|
|
1055
914
|
const RADAR_STYLE_ALIAS_NAMES = Object.keys(RADAR_STYLE_ALIASES);
|
|
1056
915
|
/**
|
|
1057
|
-
* `ST_LegendPos
|
|
916
|
+
* `ST_LegendPos`: where the legend sits relative to the plot area (`c:legendPos/@val`).
|
|
1058
917
|
* @see ECMA-376 Part 1 §21.2.3.24
|
|
1059
918
|
*/
|
|
1060
919
|
const LEGEND_POSITIONS = [
|
|
@@ -1065,7 +924,7 @@ const LEGEND_POSITIONS = [
|
|
|
1065
924
|
"t"
|
|
1066
925
|
];
|
|
1067
926
|
/**
|
|
1068
|
-
* `ST_DispBlanksAs
|
|
927
|
+
* `ST_DispBlanksAs`: what a plot draws where a value is missing (`c:dispBlanksAs/@val`).
|
|
1069
928
|
* @see ECMA-376 Part 1 §21.2.3.10
|
|
1070
929
|
*/
|
|
1071
930
|
const DISPLAY_BLANKS_AS = [
|
|
@@ -1078,7 +937,7 @@ const DISPLAY_BLANKS_AS = [
|
|
|
1078
937
|
*
|
|
1079
938
|
* The schema also has `plus`, `star`, `x`, `picture` and `auto`. Neither PowerPoint 2013 nor
|
|
1080
939
|
* PowerPoint Online draws the first three, `picture` needs a `c:spPr` blip this API has no
|
|
1081
|
-
* spelling for, and `auto` is what leaving the option off already means
|
|
940
|
+
* spelling for, and `auto` is what leaving the option off already means, so the accepted set is
|
|
1082
941
|
* deliberately smaller than the type. Widen it only with evidence that the member renders.
|
|
1083
942
|
* @see ECMA-376 Part 1 §21.2.3.27
|
|
1084
943
|
*/
|
|
@@ -1091,25 +950,25 @@ const LINE_DATA_SYMBOLS = [
|
|
|
1091
950
|
"square",
|
|
1092
951
|
"triangle"
|
|
1093
952
|
];
|
|
1094
|
-
/** `ST_TickLblPos
|
|
953
|
+
/** `ST_TickLblPos`: where an axis draws its tick labels (`c:tickLblPos/@val`). */
|
|
1095
954
|
const TICK_LABEL_POSITIONS = [
|
|
1096
955
|
"high",
|
|
1097
956
|
"low",
|
|
1098
957
|
"nextTo",
|
|
1099
958
|
"none"
|
|
1100
959
|
];
|
|
1101
|
-
/** `ST_Orientation
|
|
960
|
+
/** `ST_Orientation`: which way an axis runs (`c:orientation/@val`). */
|
|
1102
961
|
const AXIS_ORIENTATIONS = ["maxMin", "minMax"];
|
|
1103
|
-
/** `ST_TickMark
|
|
962
|
+
/** `ST_TickMark`: an axis' major or minor tick marks (`c:majorTickMark/@val`, `c:minorTickMark/@val`). */
|
|
1104
963
|
const TICK_MARKS = [
|
|
1105
964
|
"cross",
|
|
1106
965
|
"in",
|
|
1107
966
|
"none",
|
|
1108
967
|
"out"
|
|
1109
968
|
];
|
|
1110
|
-
/** `ST_CrossBetween
|
|
969
|
+
/** `ST_CrossBetween`: whether a value axis crosses its category axis between or on categories (`c:crossBetween/@val`). */
|
|
1111
970
|
const CROSS_BETWEEN = ["between", "midCat"];
|
|
1112
|
-
/** `ST_BuiltInUnit
|
|
971
|
+
/** `ST_BuiltInUnit`: the unit a value axis displays its labels in (`c:builtInUnit/@val`). */
|
|
1113
972
|
const BUILT_IN_UNITS = [
|
|
1114
973
|
"hundreds",
|
|
1115
974
|
"thousands",
|
|
@@ -1121,21 +980,21 @@ const BUILT_IN_UNITS = [
|
|
|
1121
980
|
"billions",
|
|
1122
981
|
"trillions"
|
|
1123
982
|
];
|
|
1124
|
-
/** `ST_TimeUnit
|
|
983
|
+
/** `ST_TimeUnit`: a date axis' base, major or minor time unit (`c:baseTimeUnit/@val` and its two siblings). */
|
|
1125
984
|
const TIME_UNITS = [
|
|
1126
985
|
"days",
|
|
1127
986
|
"months",
|
|
1128
987
|
"years"
|
|
1129
988
|
];
|
|
1130
|
-
/** `ST_ErrDir
|
|
989
|
+
/** `ST_ErrDir`: the axis an error bar measures along (`c:errDir/@val`). */
|
|
1131
990
|
const ERROR_BAR_DIRECTIONS = ["x", "y"];
|
|
1132
|
-
/** `ST_ErrBarType
|
|
991
|
+
/** `ST_ErrBarType`: which sides of a point draw an error bar (`c:errBarType/@val`). */
|
|
1133
992
|
const ERROR_BAR_TYPES = [
|
|
1134
993
|
"both",
|
|
1135
994
|
"minus",
|
|
1136
995
|
"plus"
|
|
1137
996
|
];
|
|
1138
|
-
/** `ST_ErrValType
|
|
997
|
+
/** `ST_ErrValType`: how an error bar's amount is read (`c:errValType/@val`). */
|
|
1139
998
|
const ERROR_BAR_VALUE_TYPES = [
|
|
1140
999
|
"cust",
|
|
1141
1000
|
"fixedVal",
|
|
@@ -1146,7 +1005,7 @@ const ERROR_BAR_VALUE_TYPES = [
|
|
|
1146
1005
|
/**
|
|
1147
1006
|
* The twelve theme colour slots (`a:clrScheme` children) a `p:clrMap` token can point at.
|
|
1148
1007
|
*
|
|
1149
|
-
* Not an `ST_` type
|
|
1008
|
+
* Not an `ST_` type: these are element names inside `a:CT_ColorScheme`, which the schema
|
|
1150
1009
|
* declares as a fixed sequence rather than an enumeration. The effect is the same: a closed,
|
|
1151
1010
|
* ordered set of twelve names, in the order the scheme declares them.
|
|
1152
1011
|
* @see ECMA-376 Part 1 §20.1.6.2
|
|
@@ -1170,7 +1029,7 @@ const THEME_COLOR_SLOTS = [
|
|
|
1170
1029
|
*
|
|
1171
1030
|
* A slide's `schemeClr val="tx1"` names a *token*, not a slot: the master's `p:clrMap` is the
|
|
1172
1031
|
* indirection that sends it to a {@link ThemeColorSlot}. Which is why the two lists look alike
|
|
1173
|
-
* and are not the same list
|
|
1032
|
+
* and are not the same list: `bg1`/`tx1` are tokens, `lt1`/`dk1` are slots.
|
|
1174
1033
|
* @see ECMA-376 Part 1 §19.3.1.6
|
|
1175
1034
|
*/
|
|
1176
1035
|
const COLOR_MAP_TOKENS = [
|
|
@@ -1192,8 +1051,8 @@ const COLOR_MAP_TOKENS = [
|
|
|
1192
1051
|
* and the one the script printer recognises so it can skip printing a map that is the default.
|
|
1193
1052
|
*
|
|
1194
1053
|
* "Identity" up to the light/dark naming: each token points at the slot of the same name, with
|
|
1195
|
-
* `bg`/`tx` reading as light/dark. A deck that maps them anywhere else
|
|
1196
|
-
* dark slots is the usual case
|
|
1054
|
+
* `bg`/`tx` reading as light/dark. A deck that maps them anywhere else (swapping the light and
|
|
1055
|
+
* dark slots is the usual case) resolves every `schemeClr` in the deck differently.
|
|
1197
1056
|
*
|
|
1198
1057
|
* Typed `Record<ColorMapToken, ThemeColorSlot>` so a token added to {@link COLOR_MAP_TOKENS}
|
|
1199
1058
|
* without a mapping, or a slot misspelled, is a compile error rather than a theme that opens
|
|
@@ -1214,182 +1073,339 @@ const DEFAULT_COLOR_MAP = {
|
|
|
1214
1073
|
hlink: "hlink",
|
|
1215
1074
|
folHlink: "folHlink"
|
|
1216
1075
|
};
|
|
1217
|
-
|
|
1218
|
-
//#region src/hex-color.ts
|
|
1219
|
-
/**
|
|
1220
|
-
* pptx-ts: hex colour text, in the one spelling both halves use.
|
|
1221
|
-
*
|
|
1222
|
-
* A caller may write a colour with or without a leading `#`, and the library accepts both
|
|
1223
|
-
* everywhere — which means every site that validates or parses one strips it first. Those
|
|
1224
|
-
* strips had drifted into three spellings across six sites, and one of them was not
|
|
1225
|
-
* anchored: `.replace('#', '')` takes the `#` out of `'FF00#0'` and hands `'FF000'` on, which
|
|
1226
|
-
* then fails the six-digit test and takes a different branch than the anchored forms would.
|
|
1227
|
-
* No caller is known to reach that, which is exactly why it wants one spelling rather than a
|
|
1228
|
-
* test at each site.
|
|
1229
|
-
*
|
|
1230
|
-
* This lives at the root rather than under `gen/` or `read/` because both halves need it:
|
|
1231
|
-
* the emitters strip on the way in, the readers strip on the way back out — and for the same
|
|
1232
|
-
* reason the *validation* belongs here too. `REGEX_HEX_COLOR` used to live in
|
|
1233
|
-
* `constants-internal.ts`, which is a write-side module the read path cannot import, so the read
|
|
1234
|
-
* path re-spelled the regex; so did one write-side site. Six sites, three spellings of one fact.
|
|
1235
|
-
*/
|
|
1076
|
+
// src/ooxml/namespaces.ts
|
|
1236
1077
|
/**
|
|
1237
|
-
*
|
|
1078
|
+
* OOXML namespace URIs, by their canonical prefix.
|
|
1238
1079
|
*
|
|
1239
|
-
*
|
|
1240
|
-
*
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
const REGEX_ARGB_HEX = /^[0-9a-fA-F]{8}$/;
|
|
1245
|
-
/** Strip a single leading `#` from a colour, leaving any other character alone. */
|
|
1246
|
-
function stripHash(value) {
|
|
1247
|
-
return value.startsWith("#") ? value.slice(1) : value;
|
|
1248
|
-
}
|
|
1249
|
-
/**
|
|
1250
|
-
* Is `value` a 6-hex RGB colour? A leading `#` is stripped first, so both spellings agree.
|
|
1080
|
+
* A namespace URI is a fact about the format, not about reading or writing one, so it belongs
|
|
1081
|
+
* here rather than on either side, by the same reasoning `rel-types.ts` states at length, and for
|
|
1082
|
+
* the same failure mode: these are long, near-identical strings, and a typo does not throw. It
|
|
1083
|
+
* silently matches nothing on the read side and produces a part PowerPoint ignores on the write
|
|
1084
|
+
* side.
|
|
1251
1085
|
*
|
|
1252
|
-
*
|
|
1253
|
-
*
|
|
1254
|
-
*
|
|
1255
|
-
*
|
|
1086
|
+
* The table lived in `read/oxml/dom.ts` and could not be reached from `gen/`, because that
|
|
1087
|
+
* module imports `@xmldom/xmldom` at module scope and pulling an XML DOM into the write-only
|
|
1088
|
+
* bundle is a real cost. So the write side hand-wrote the URIs instead: three separate `A_NS`
|
|
1089
|
+
* constants and seven copies of the same `xmlns:a`/`xmlns:r`/`xmlns:p` triple. This module has
|
|
1090
|
+
* **no runtime imports**, and no module beside it imports from `gen/` or `read/`, so both sides can
|
|
1091
|
+
* reach it and neither pays for the other's dependencies. The two that fail loudly reach outside
|
|
1092
|
+
* `ooxml/` for that alone: `sequence.ts` for `errors.ts`, and `check-enum.ts` for `errors.ts` and
|
|
1093
|
+
* `diagnostics.ts`. `read/oxml/dom.ts` re-exports it, so no read-side import path changed.
|
|
1256
1094
|
*/
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1095
|
+
/** Canonical OOXML prefix → namespace URI registry. */
|
|
1096
|
+
const OOXML_NS = Object.freeze({
|
|
1097
|
+
a: "http://schemas.openxmlformats.org/drawingml/2006/main",
|
|
1098
|
+
a14: "http://schemas.microsoft.com/office/drawing/2010/main",
|
|
1099
|
+
ahyp: "http://schemas.microsoft.com/office/drawing/2018/hyperlinkcolor",
|
|
1100
|
+
asvg: "http://schemas.microsoft.com/office/drawing/2016/SVG/main",
|
|
1101
|
+
c: "http://schemas.openxmlformats.org/drawingml/2006/chart",
|
|
1102
|
+
c15: "http://schemas.microsoft.com/office/drawing/2012/chart",
|
|
1103
|
+
cp: "http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
|
|
1104
|
+
ct: "http://schemas.openxmlformats.org/package/2006/content-types",
|
|
1105
|
+
cx: "http://schemas.microsoft.com/office/drawing/2014/chartex",
|
|
1106
|
+
dc: "http://purl.org/dc/elements/1.1/",
|
|
1107
|
+
dcterms: "http://purl.org/dc/terms/",
|
|
1108
|
+
dgm: "http://schemas.openxmlformats.org/drawingml/2006/diagram",
|
|
1109
|
+
dsp: "http://schemas.microsoft.com/office/drawing/2008/diagram",
|
|
1110
|
+
ep: "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties",
|
|
1111
|
+
m: "http://schemas.openxmlformats.org/officeDocument/2006/math",
|
|
1112
|
+
mc: "http://schemas.openxmlformats.org/markup-compatibility/2006",
|
|
1113
|
+
p: "http://schemas.openxmlformats.org/presentationml/2006/main",
|
|
1114
|
+
p14: "http://schemas.microsoft.com/office/powerpoint/2010/main",
|
|
1115
|
+
p15: "http://schemas.microsoft.com/office/powerpoint/2012/main",
|
|
1116
|
+
p159: "http://schemas.microsoft.com/office/powerpoint/2015/9/main",
|
|
1117
|
+
p188: "http://schemas.microsoft.com/office/powerpoint/2018/8/main",
|
|
1118
|
+
pr: "http://schemas.openxmlformats.org/package/2006/relationships",
|
|
1119
|
+
r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
|
|
1120
|
+
vt: "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
|
1121
|
+
});
|
|
1260
1122
|
/**
|
|
1261
|
-
*
|
|
1123
|
+
* `a:graphicData/@uri` for a DrawingML table.
|
|
1262
1124
|
*
|
|
1263
|
-
* The
|
|
1264
|
-
* @
|
|
1125
|
+
* The other three payloads a `p:graphicFrame` can hold name a URI that is also a namespace, so
|
|
1126
|
+
* they read it off {@link OOXML_NS} (`c`, `cx`, `dgm`). A table's does not: nothing binds a
|
|
1127
|
+
* prefix to it, and the table elements themselves are in the `a` namespace. So it lives beside
|
|
1128
|
+
* the registry rather than in it, which keeps every entry there a prefix a document can declare.
|
|
1265
1129
|
*/
|
|
1266
|
-
|
|
1267
|
-
return REGEX_ARGB_HEX.test(stripHash(value));
|
|
1268
|
-
}
|
|
1130
|
+
const TABLE_GRAPHIC_DATA_URI = "http://schemas.openxmlformats.org/drawingml/2006/table";
|
|
1269
1131
|
/**
|
|
1270
|
-
*
|
|
1271
|
-
*
|
|
1132
|
+
* The `xmlns` declarations every PresentationML part root carries, in the order the emitters
|
|
1133
|
+
* have always written them.
|
|
1272
1134
|
*
|
|
1273
|
-
*
|
|
1274
|
-
*
|
|
1275
|
-
*
|
|
1276
|
-
*
|
|
1277
|
-
* @param value - the caller's colour, with or without a leading `#`
|
|
1135
|
+
* Spread this **first** in a root element's attribute map: `el()` serializes attributes in
|
|
1136
|
+
* object-key order, so the three keys have to keep the positions the literals occupied or the
|
|
1137
|
+
* emitted bytes move. A root with extra attributes (`show` on `p:sld`, `def` on `a:tblStyleLst`)
|
|
1138
|
+
* lists them after the spread, which is where they already were.
|
|
1278
1139
|
*/
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
};
|
|
1286
|
-
}
|
|
1287
|
-
//#endregion
|
|
1288
|
-
//#region src/ooxml/xsd-boolean.ts
|
|
1140
|
+
const PML_ROOT_NS = Object.freeze({
|
|
1141
|
+
"xmlns:a": OOXML_NS.a,
|
|
1142
|
+
"xmlns:r": OOXML_NS.r,
|
|
1143
|
+
"xmlns:p": OOXML_NS.p
|
|
1144
|
+
});
|
|
1145
|
+
// src/ooxml/rel-types.ts
|
|
1289
1146
|
/**
|
|
1290
|
-
*
|
|
1147
|
+
* OPC relationship type URIs and part content types, and the schema-URI bases they are built from.
|
|
1291
1148
|
*
|
|
1292
|
-
*
|
|
1293
|
-
*
|
|
1294
|
-
*
|
|
1295
|
-
* against every deck PowerPoint produces, and silently misreads the other producers. That is the
|
|
1296
|
-
* worst shape a bug can have: invisible to the fixtures, visible only on a customer's file.
|
|
1149
|
+
* These are long, near-identical strings that differ in one path segment, which makes a typo
|
|
1150
|
+
* both easy to write and invisible on review: a wrong URI does not throw, it silently matches
|
|
1151
|
+
* nothing on the read side and produces a part PowerPoint ignores or rejects on the write side.
|
|
1297
1152
|
*
|
|
1298
|
-
* **Why this module is neither `gen/` nor `read/`.**
|
|
1299
|
-
*
|
|
1300
|
-
*
|
|
1301
|
-
*
|
|
1302
|
-
*
|
|
1303
|
-
*
|
|
1153
|
+
* **Why this module is neither `gen/` nor `read/`.** Both halves need the same URIs, and for a
|
|
1154
|
+
* while each kept its own copy (`gen/oxml/schema-uris.ts`, `read/api/rel-types.ts`), with a note
|
|
1155
|
+
* in both saying a shared home was "a separate decision". It is this module: a rel type is a fact
|
|
1156
|
+
* about the OOXML package format, not about writing or reading one, so neither side should own it.
|
|
1157
|
+
* A divergence between the two copies would mean the writer emitting a rel the reader cannot find,
|
|
1158
|
+
* a round-trip bug with no compile-time signal.
|
|
1304
1159
|
*
|
|
1305
|
-
*
|
|
1306
|
-
*
|
|
1160
|
+
* Only types used by more than one module live here. A rel type exactly one module cares about
|
|
1161
|
+
* (`tags`, `oleObject`, the modern comments part, …) stays declared next to the code that reads or
|
|
1162
|
+
* emits it. Hoisting those would trade a definition you can see for one you have to go and find,
|
|
1163
|
+
* and buy nothing. A writer and a reader of the same part count as two modules even when each
|
|
1164
|
+
* names the string once: that pair is exactly the divergence this module exists to prevent.
|
|
1307
1165
|
*
|
|
1308
|
-
*
|
|
1309
|
-
*
|
|
1310
|
-
* {@link xsdBoolIfTrue}. Sixty-odd inline ternaries spelled them in three ways with nothing
|
|
1311
|
-
* naming which was which.
|
|
1166
|
+
* The same reasoning covers **part content types**, which are the same kind of fact and fail the
|
|
1167
|
+
* same silent way, including every entry the writer's `[Content_Types].xml` declares.
|
|
1312
1168
|
*/
|
|
1313
1169
|
/**
|
|
1314
|
-
*
|
|
1315
|
-
*
|
|
1316
|
-
* `null` for an absent *or* unparseable value is deliberate and load-bearing at the call sites:
|
|
1317
|
-
* several attributes have a schema default of `true`, so they test `!== false` rather than
|
|
1318
|
-
* `=== true` and an unset attribute has to be distinguishable from an explicit `0`.
|
|
1170
|
+
* Prefix for `.rels` `Type` URIs; append the type name (`slide`, `image`, `theme`, …).
|
|
1171
|
+
* Exported for the write side, which builds one-off rel types at their call sites.
|
|
1319
1172
|
*/
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1173
|
+
const OFFICE_REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/";
|
|
1174
|
+
/** `xmlns` of every `<Relationships>` part. Also the prefix of the package-scoped rel types. */
|
|
1175
|
+
const PACKAGE_REL_NS = OOXML_NS.pr;
|
|
1176
|
+
/**
|
|
1177
|
+
* Prefix for the Microsoft rel types this library emits and reads. Exported for the same reason
|
|
1178
|
+
* as {@link OFFICE_REL}: a rel type only one module names is built from it at that module's call site.
|
|
1179
|
+
*/
|
|
1180
|
+
const MS_REL = "http://schemas.microsoft.com/office/";
|
|
1181
|
+
/** `p:sldIdLst` → a slide part. */
|
|
1182
|
+
const SLIDE_REL = OFFICE_REL + "slide";
|
|
1183
|
+
/** A slide → its layout; a master → each of its layouts. */
|
|
1184
|
+
const SLIDE_LAYOUT_REL = OFFICE_REL + "slideLayout";
|
|
1185
|
+
/** A layout → its master; the presentation → each master. */
|
|
1186
|
+
const SLIDE_MASTER_REL = OFFICE_REL + "slideMaster";
|
|
1187
|
+
/** A slide → its notes slide. */
|
|
1188
|
+
const NOTES_SLIDE_REL = OFFICE_REL + "notesSlide";
|
|
1189
|
+
/** A notes slide → the notes master; the presentation → the notes master. */
|
|
1190
|
+
const NOTES_MASTER_REL = OFFICE_REL + "notesMaster";
|
|
1191
|
+
/** A master or notes master → its theme. Layouts and slides inherit it rather than holding one. */
|
|
1192
|
+
const THEME_REL = OFFICE_REL + "theme";
|
|
1193
|
+
/** The package root → `ppt/presentation.xml`. The entry point to everything above. */
|
|
1194
|
+
const OFFICE_DOCUMENT_REL = OFFICE_REL + "officeDocument";
|
|
1195
|
+
/** Any part → an image in `ppt/media/`. */
|
|
1196
|
+
const IMAGE_REL = OFFICE_REL + "image";
|
|
1197
|
+
/** Any part → an external or internal jump target. External ones carry `TargetMode="External"`. */
|
|
1198
|
+
const HYPERLINK_REL = OFFICE_REL + "hyperlink";
|
|
1199
|
+
/** The presentation → `ppt/tableStyles.xml`. */
|
|
1200
|
+
const TABLE_STYLES_REL = OFFICE_REL + "tableStyles";
|
|
1201
|
+
/** The package root → `docProps/core.xml`. Package-scoped, so not under {@link OFFICE_REL}. */
|
|
1202
|
+
const CORE_PROPS_REL = PACKAGE_REL_NS + "/metadata/core-properties";
|
|
1203
|
+
/** The package root → `docProps/app.xml`. */
|
|
1204
|
+
const EXTENDED_PROPS_REL = OFFICE_REL + "extended-properties";
|
|
1205
|
+
/** The package root → `docProps/custom.xml`. */
|
|
1206
|
+
const CUSTOM_PROPS_REL = OFFICE_REL + "custom-properties";
|
|
1207
|
+
/** A slide → its legacy comments part (`ppt/comments/commentN.xml`). */
|
|
1208
|
+
const COMMENTS_REL = OFFICE_REL + "comments";
|
|
1209
|
+
/** The presentation → the deck-wide legacy comment-author registry (`ppt/commentAuthors.xml`). */
|
|
1210
|
+
const COMMENT_AUTHORS_REL = OFFICE_REL + "commentAuthors";
|
|
1211
|
+
/** The presentation → the 2018 comment-author registry (`ppt/authors.xml`), a Microsoft rel type. */
|
|
1212
|
+
const MODERN_COMMENT_AUTHORS_REL = MS_REL + "2018/10/relationships/authors";
|
|
1213
|
+
/** The presentation → `ppt/presProps.xml`. */
|
|
1214
|
+
const PRES_PROPS_REL = OFFICE_REL + "presProps";
|
|
1215
|
+
/** The presentation → `ppt/viewProps.xml`. */
|
|
1216
|
+
const VIEW_PROPS_REL = OFFICE_REL + "viewProps";
|
|
1217
|
+
/** The presentation → the handout master. */
|
|
1218
|
+
const HANDOUT_MASTER_REL = OFFICE_REL + "handoutMaster";
|
|
1219
|
+
/** A part → a theme override, which replaces the deck theme for that part alone. */
|
|
1220
|
+
const THEME_OVERRIDE_REL = OFFICE_REL + "themeOverride";
|
|
1221
|
+
/** The presentation → an embedded font part, one per face. */
|
|
1222
|
+
const FONT_REL = OFFICE_REL + "font";
|
|
1223
|
+
/** A slide → an audio blob in `ppt/media/`. Paired with {@link MS_MEDIA_REL} on the same target. */
|
|
1224
|
+
const AUDIO_REL = OFFICE_REL + "audio";
|
|
1225
|
+
/** A slide → a video blob in `ppt/media/`, or an online-video placeholder. Paired with {@link MS_MEDIA_REL}. */
|
|
1226
|
+
const VIDEO_REL = OFFICE_REL + "video";
|
|
1325
1227
|
/**
|
|
1326
|
-
*
|
|
1327
|
-
*
|
|
1328
|
-
* Writes the attribute either way, so `false` is *stated*. Use this wherever the schema
|
|
1329
|
-
* default is `true`, or wherever the absence of the attribute would mean something other
|
|
1330
|
-
* than `false` — a value inherited from a list style, a layout or the theme.
|
|
1331
|
-
* @param value - the resolved boolean
|
|
1228
|
+
* The MS-2007 `media` rel every audio/video shape carries alongside the ECMA one, pointing at the
|
|
1229
|
+
* same target. It is what `<p14:media r:embed>` resolves, so a media shape needs both.
|
|
1332
1230
|
*/
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1231
|
+
const MS_MEDIA_REL = MS_REL + "2007/relationships/media";
|
|
1232
|
+
/** A slide → an embedded 3D model (`.glb`). Note `2017/06`, not the `2017` of the model3d namespace. */
|
|
1233
|
+
const MODEL3D_REL = MS_REL + "2017/06/relationships/model3d";
|
|
1234
|
+
/** A slide → a classic (`c:`) chart part. */
|
|
1235
|
+
const CHART_REL = OFFICE_REL + "chart";
|
|
1236
|
+
/** A slide → a chartEx (`cx:`, Office 2016) chart part: an MS rel, not the ECMA `chart` one. */
|
|
1237
|
+
const CHARTEX_REL = MS_REL + "2014/relationships/chartEx";
|
|
1238
|
+
/** A chart part → its mandatory style sidecar. */
|
|
1239
|
+
const CHART_STYLE_REL = MS_REL + "2011/relationships/chartStyle";
|
|
1240
|
+
/** A chart part → its mandatory colour-style sidecar. */
|
|
1241
|
+
const CHART_COLOR_STYLE_REL = MS_REL + "2011/relationships/chartColorStyle";
|
|
1242
|
+
/** Any part → an embedded OPC package (an Office file, itself a zip): a chart's workbook, an OLE payload. */
|
|
1243
|
+
const PACKAGE_REL = OFFICE_REL + "package";
|
|
1336
1244
|
/**
|
|
1337
|
-
*
|
|
1338
|
-
*
|
|
1339
|
-
* **Correct only where the schema default is `false`.** It collapses "false" and "unset" into
|
|
1340
|
-
* one output, which is the two-spellings-for-three-states shape the API policy warns about: the
|
|
1341
|
-
* next attribute with a `true` default written this way reads as correct and is wrong. Every
|
|
1342
|
-
* current caller is on a `false`-defaulting attribute, so the collapse costs nothing today —
|
|
1343
|
-
* naming it is what makes the next one visible.
|
|
1344
|
-
* @param value - the resolved boolean
|
|
1245
|
+
* Root of the ECMA-376 content types. Exported for a content type only one module names, which is
|
|
1246
|
+
* built from it at that module's call site; a shared one is a constant below.
|
|
1345
1247
|
*/
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1248
|
+
const OD_CONTENT = "application/vnd.openxmlformats-officedocument.";
|
|
1249
|
+
/** Root of the OPC package-level content types. Private: callers want one of the constants below. */
|
|
1250
|
+
const PACKAGE_CONTENT = "application/vnd.openxmlformats-package.";
|
|
1251
|
+
/** Root of the Microsoft Office content types the chartEx family uses. Private. */
|
|
1252
|
+
const MS_OFFICE_CONTENT = "application/vnd.ms-office.";
|
|
1253
|
+
/** Root of the PowerPoint-specific Microsoft content types. Exported for the same reason as {@link OD_CONTENT}. */
|
|
1254
|
+
const MS_POWERPOINT_CONTENT = "application/vnd.ms-powerpoint.";
|
|
1255
|
+
/** `ppt/slides/slideN.xml`. */
|
|
1256
|
+
const SLIDE_CONTENT_TYPE = OD_CONTENT + "presentationml.slide+xml";
|
|
1257
|
+
/** `ppt/slideMasters/slideMasterN.xml`. */
|
|
1258
|
+
const SLIDE_MASTER_CONTENT_TYPE = OD_CONTENT + "presentationml.slideMaster+xml";
|
|
1259
|
+
/** `ppt/slideLayouts/slideLayoutN.xml`. */
|
|
1260
|
+
const SLIDE_LAYOUT_CONTENT_TYPE = OD_CONTENT + "presentationml.slideLayout+xml";
|
|
1261
|
+
/** `ppt/notesSlides/notesSlideN.xml`. */
|
|
1262
|
+
const NOTES_SLIDE_CONTENT_TYPE = OD_CONTENT + "presentationml.notesSlide+xml";
|
|
1263
|
+
/** `ppt/notesMasters/notesMasterN.xml`. */
|
|
1264
|
+
const NOTES_MASTER_CONTENT_TYPE = OD_CONTENT + "presentationml.notesMaster+xml";
|
|
1265
|
+
/** `ppt/theme/themeN.xml`. Not `presentationml.`: a theme is a DrawingML part. */
|
|
1266
|
+
const THEME_CONTENT_TYPE = OD_CONTENT + "theme+xml";
|
|
1267
|
+
/** `ppt/tableStyles.xml`. */
|
|
1268
|
+
const TABLE_STYLES_CONTENT_TYPE = OD_CONTENT + "presentationml.tableStyles+xml";
|
|
1269
|
+
/** `ppt/presentation.xml` in an editable `.pptx`. A `.potx` template's main part is a different one. */
|
|
1270
|
+
const PRESENTATION_MAIN_CONTENT_TYPE = OD_CONTENT + "presentationml.presentation.main+xml";
|
|
1271
|
+
/** Every `.rels` part. Declared once as a `Default` for the `rels` extension, never as an Override. */
|
|
1272
|
+
const RELATIONSHIPS_CONTENT_TYPE = PACKAGE_CONTENT + "relationships+xml";
|
|
1273
|
+
/** `ppt/presProps.xml`. */
|
|
1274
|
+
const PRES_PROPS_CONTENT_TYPE = OD_CONTENT + "presentationml.presProps+xml";
|
|
1275
|
+
/** `ppt/viewProps.xml`. */
|
|
1276
|
+
const VIEW_PROPS_CONTENT_TYPE = OD_CONTENT + "presentationml.viewProps+xml";
|
|
1277
|
+
/** `ppt/comments/commentN.xml`, a legacy comments part. */
|
|
1278
|
+
const COMMENTS_CONTENT_TYPE = OD_CONTENT + "presentationml.comments+xml";
|
|
1279
|
+
/** `ppt/commentAuthors.xml`. */
|
|
1280
|
+
const COMMENT_AUTHORS_CONTENT_TYPE = OD_CONTENT + "presentationml.commentAuthors+xml";
|
|
1281
|
+
/** `docProps/core.xml`. Package-scoped, so not under the officedocument prefix. */
|
|
1282
|
+
const CORE_PROPS_CONTENT_TYPE = PACKAGE_CONTENT + "core-properties+xml";
|
|
1283
|
+
/** `docProps/app.xml`. */
|
|
1284
|
+
const EXTENDED_PROPS_CONTENT_TYPE = OD_CONTENT + "extended-properties+xml";
|
|
1285
|
+
/** `docProps/custom.xml`. */
|
|
1286
|
+
const CUSTOM_PROPS_CONTENT_TYPE = OD_CONTENT + "custom-properties+xml";
|
|
1287
|
+
/** `ppt/charts/chartN.xml`, a classic (`c:`) chart. */
|
|
1288
|
+
const CHART_CONTENT_TYPE = OD_CONTENT + "drawingml.chart+xml";
|
|
1289
|
+
/** `ppt/charts/chartExN.xml`. A chartEx part carries a Microsoft content type, not an `openxmlformats` one. */
|
|
1290
|
+
const CHARTEX_CONTENT_TYPE = MS_OFFICE_CONTENT + "chartex+xml";
|
|
1291
|
+
/** A chart's mandatory `style{N}.xml` sidecar. */
|
|
1292
|
+
const CHART_STYLE_CONTENT_TYPE = MS_OFFICE_CONTENT + "chartstyle+xml";
|
|
1293
|
+
/** A chart's mandatory `colors{N}.xml` sidecar. */
|
|
1294
|
+
const CHART_COLOR_STYLE_CONTENT_TYPE = MS_OFFICE_CONTENT + "chartcolorstyle+xml";
|
|
1295
|
+
/** An embedded `.xlsx` workbook: a chart's data, or an OLE payload. */
|
|
1296
|
+
const XLSX_CONTENT_TYPE = OD_CONTENT + "spreadsheetml.sheet";
|
|
1351
1297
|
/**
|
|
1352
|
-
*
|
|
1353
|
-
* policy — see the module note).
|
|
1354
|
-
*
|
|
1355
|
-
* `undefined`/`null` returns `null` without reporting: an unset option is not an invalid one, and
|
|
1356
|
-
* it is by far the common case.
|
|
1298
|
+
* Every kind of part a page points at without owning it.
|
|
1357
1299
|
*
|
|
1358
|
-
*
|
|
1359
|
-
*
|
|
1360
|
-
*
|
|
1361
|
-
*
|
|
1362
|
-
*
|
|
1363
|
-
* @param code - the condition to report
|
|
1364
|
-
* @param label - how to name the offending option in the message, e.g. ``'table cell: cell3D `preset`'``
|
|
1365
|
-
* @param detail - extra structured context to merge into the diagnostic's `detail`
|
|
1366
|
-
* @returns the value when legal, else `null`
|
|
1367
|
-
*/
|
|
1368
|
-
function checkEnumOrWarn(value, valid, code, label, detail) {
|
|
1369
|
-
if (value === void 0 || value === null) return null;
|
|
1370
|
-
if (valid.includes(value)) return value;
|
|
1371
|
-
warnOnce(code, `${label} value \`${String(value)}\` is not valid and is ignored — use one of ${valid.join(", ")}.`, {
|
|
1372
|
-
received: value,
|
|
1373
|
-
valid,
|
|
1374
|
-
...detail
|
|
1375
|
-
});
|
|
1376
|
-
return null;
|
|
1377
|
-
}
|
|
1378
|
-
/**
|
|
1379
|
-
* Check a value against its `ST_` union, throwing when outside (the read/edit-path policy — see
|
|
1380
|
-
* the module note).
|
|
1381
|
-
* @param value - the value the caller asked for
|
|
1382
|
-
* @param valid - the enum's members
|
|
1383
|
-
* @param attribute - the attribute's name, for the message
|
|
1384
|
-
* @param code - the condition to report
|
|
1385
|
-
* @returns `value`, when it is legal
|
|
1300
|
+
* Two questions read this table, under different keys. Copying a page asks whether a relationship's
|
|
1301
|
+
* target may be shared by the copies rather than copied (every row, by `relType`). Pruning after a
|
|
1302
|
+
* slide is removed asks whether a part is deck chrome that stays even while nothing reaches it (the
|
|
1303
|
+
* `deck` rows, by `contentType`). They were two hand-kept lists, and the two author registries were
|
|
1304
|
+
* on the first and missing from the second.
|
|
1386
1305
|
*/
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1306
|
+
const SHARED_PARTS = [
|
|
1307
|
+
{
|
|
1308
|
+
relType: SLIDE_LAYOUT_REL,
|
|
1309
|
+
contentType: SLIDE_LAYOUT_CONTENT_TYPE,
|
|
1310
|
+
scope: "deck"
|
|
1311
|
+
},
|
|
1312
|
+
{
|
|
1313
|
+
relType: SLIDE_MASTER_REL,
|
|
1314
|
+
contentType: SLIDE_MASTER_CONTENT_TYPE,
|
|
1315
|
+
scope: "deck"
|
|
1316
|
+
},
|
|
1317
|
+
{
|
|
1318
|
+
relType: NOTES_MASTER_REL,
|
|
1319
|
+
contentType: NOTES_MASTER_CONTENT_TYPE,
|
|
1320
|
+
scope: "deck"
|
|
1321
|
+
},
|
|
1322
|
+
{
|
|
1323
|
+
relType: THEME_REL,
|
|
1324
|
+
contentType: THEME_CONTENT_TYPE,
|
|
1325
|
+
scope: "deck"
|
|
1326
|
+
},
|
|
1327
|
+
{
|
|
1328
|
+
relType: THEME_OVERRIDE_REL,
|
|
1329
|
+
contentType: OD_CONTENT + "themeOverride+xml",
|
|
1330
|
+
scope: "deck"
|
|
1331
|
+
},
|
|
1332
|
+
{
|
|
1333
|
+
relType: HANDOUT_MASTER_REL,
|
|
1334
|
+
contentType: OD_CONTENT + "presentationml.handoutMaster+xml",
|
|
1335
|
+
scope: "deck"
|
|
1336
|
+
},
|
|
1337
|
+
{
|
|
1338
|
+
relType: PRES_PROPS_REL,
|
|
1339
|
+
contentType: PRES_PROPS_CONTENT_TYPE,
|
|
1340
|
+
scope: "deck"
|
|
1341
|
+
},
|
|
1342
|
+
{
|
|
1343
|
+
relType: VIEW_PROPS_REL,
|
|
1344
|
+
contentType: VIEW_PROPS_CONTENT_TYPE,
|
|
1345
|
+
scope: "deck"
|
|
1346
|
+
},
|
|
1347
|
+
{
|
|
1348
|
+
relType: TABLE_STYLES_REL,
|
|
1349
|
+
contentType: TABLE_STYLES_CONTENT_TYPE,
|
|
1350
|
+
scope: "deck"
|
|
1351
|
+
},
|
|
1352
|
+
{
|
|
1353
|
+
relType: OFFICE_DOCUMENT_REL,
|
|
1354
|
+
contentType: PRESENTATION_MAIN_CONTENT_TYPE,
|
|
1355
|
+
scope: "deck"
|
|
1356
|
+
},
|
|
1357
|
+
{
|
|
1358
|
+
relType: COMMENT_AUTHORS_REL,
|
|
1359
|
+
contentType: COMMENT_AUTHORS_CONTENT_TYPE,
|
|
1360
|
+
scope: "deck"
|
|
1361
|
+
},
|
|
1362
|
+
{
|
|
1363
|
+
relType: MODERN_COMMENT_AUTHORS_REL,
|
|
1364
|
+
contentType: "application/vnd.ms-powerpoint.authors+xml",
|
|
1365
|
+
scope: "deck"
|
|
1366
|
+
},
|
|
1367
|
+
{
|
|
1368
|
+
relType: IMAGE_REL,
|
|
1369
|
+
contentType: null,
|
|
1370
|
+
scope: "media"
|
|
1371
|
+
},
|
|
1372
|
+
{
|
|
1373
|
+
relType: AUDIO_REL,
|
|
1374
|
+
contentType: null,
|
|
1375
|
+
scope: "media"
|
|
1376
|
+
},
|
|
1377
|
+
{
|
|
1378
|
+
relType: VIDEO_REL,
|
|
1379
|
+
contentType: null,
|
|
1380
|
+
scope: "media"
|
|
1381
|
+
},
|
|
1382
|
+
{
|
|
1383
|
+
relType: MS_MEDIA_REL,
|
|
1384
|
+
contentType: null,
|
|
1385
|
+
scope: "media"
|
|
1386
|
+
},
|
|
1387
|
+
{
|
|
1388
|
+
relType: MODEL3D_REL,
|
|
1389
|
+
contentType: null,
|
|
1390
|
+
scope: "media"
|
|
1391
|
+
},
|
|
1392
|
+
{
|
|
1393
|
+
relType: FONT_REL,
|
|
1394
|
+
contentType: null,
|
|
1395
|
+
scope: "media"
|
|
1396
|
+
},
|
|
1397
|
+
{
|
|
1398
|
+
relType: SLIDE_REL,
|
|
1399
|
+
contentType: null,
|
|
1400
|
+
scope: "page"
|
|
1401
|
+
},
|
|
1402
|
+
{
|
|
1403
|
+
relType: HYPERLINK_REL,
|
|
1404
|
+
contentType: null,
|
|
1405
|
+
scope: "page"
|
|
1406
|
+
}
|
|
1407
|
+
];
|
|
1408
|
+
// src/ooxml/line-cap.ts
|
|
1393
1409
|
/**
|
|
1394
1410
|
* Every `cap` the write API names and the token it writes. `satisfies` over `Record<LineCap, …>`
|
|
1395
1411
|
* makes a member added to `LineCap` without a token a compile error, and `ST_LineCap` has exactly
|
|
@@ -1406,8 +1422,16 @@ function lineCapToken(cap) {
|
|
|
1406
1422
|
}
|
|
1407
1423
|
/** A `cap` token back to the `LineCap` that authors it. */
|
|
1408
1424
|
const LINE_CAP_BY_TOKEN = Object.fromEntries(Object.entries(TOKEN_BY_LINE_CAP).map(([cap, token]) => [token, cap]));
|
|
1409
|
-
|
|
1410
|
-
|
|
1425
|
+
// src/ooxml/show-jumps.ts
|
|
1426
|
+
const SHOW_JUMPS = [
|
|
1427
|
+
"firstslide",
|
|
1428
|
+
"previousslide",
|
|
1429
|
+
"nextslide",
|
|
1430
|
+
"lastslide",
|
|
1431
|
+
"lastslideviewed",
|
|
1432
|
+
"endshow"
|
|
1433
|
+
];
|
|
1434
|
+
// src/ooxml/text-align.ts
|
|
1411
1435
|
/**
|
|
1412
1436
|
* Every `align` the write API names and the token it writes. `satisfies` over `Record<HAlign, …>`
|
|
1413
1437
|
* makes a member added to `HAlign` without a token a compile error. `justLow`, `dist` and
|
|
@@ -1425,21 +1449,20 @@ function textAlignToken(align) {
|
|
|
1425
1449
|
}
|
|
1426
1450
|
/** An `algn` token back to the `align` a generated script writes. */
|
|
1427
1451
|
const HALIGN_BY_TEXT_ALIGN = Object.fromEntries(Object.entries(ALGN_BY_ALIGN).map(([align, token]) => [token, align]));
|
|
1428
|
-
|
|
1429
|
-
//#region src/media/image-size.ts
|
|
1452
|
+
// src/media/image-size.ts
|
|
1430
1453
|
/**
|
|
1431
1454
|
* Intrinsic image geometry: reading a natural pixel size out of header bytes, and the
|
|
1432
1455
|
* `<a:srcRect>` crop math that fits that natural size into a display box.
|
|
1433
1456
|
*
|
|
1434
|
-
* Shared by both sides of the library
|
|
1435
|
-
* API's `Picture.setImage({ fit })
|
|
1457
|
+
* Shared by both sides of the library, the write path (`addImage({ sizing })`) and the read
|
|
1458
|
+
* API's `Picture.setImage({ fit })`, which is why it lives outside `gen/` and `read/`.
|
|
1436
1459
|
* Everything here is synchronous and pure: headers only, never pixel decoding.
|
|
1437
1460
|
*/
|
|
1438
1461
|
/**
|
|
1439
1462
|
* Read the intrinsic dimensions of an image from its header bytes.
|
|
1440
1463
|
* - synchronous: parses only file-format headers, never decodes pixels
|
|
1441
|
-
* - raster: PNG, JPEG, GIF, BMP, TIFF, and WebP (VP8 / VP8L / VP8X)
|
|
1442
|
-
* - vector: SVG
|
|
1464
|
+
* - raster: PNG, JPEG, GIF, BMP, TIFF, and WebP (VP8 / VP8L / VP8X): natural pixels
|
|
1465
|
+
* - vector: SVG, with the intrinsic size from the root `<svg>` width/height or viewBox
|
|
1443
1466
|
* - unrecognized formats return `null` (no measurable intrinsic size)
|
|
1444
1467
|
*
|
|
1445
1468
|
* Used by image `sizing: 'cover' | 'contain'` to compute an aspect-correct
|
|
@@ -1452,7 +1475,7 @@ function getImageSizeFromBase64(dataB64) {
|
|
|
1452
1475
|
return b ? getImageSizeFromBytes(b) : null;
|
|
1453
1476
|
}
|
|
1454
1477
|
/**
|
|
1455
|
-
* Read the intrinsic dimensions of an image from raw header bytes
|
|
1478
|
+
* Read the intrinsic dimensions of an image from raw header bytes: the
|
|
1456
1479
|
* byte-level core shared by {@link getImageSizeFromBase64} and the read API's
|
|
1457
1480
|
* `Picture.setImage({ fit })`, which already holds the media bytes.
|
|
1458
1481
|
* @param {Uint8Array} b - image bytes
|
|
@@ -1461,7 +1484,7 @@ function getImageSizeFromBase64(dataB64) {
|
|
|
1461
1484
|
function getImageSizeFromBytes(b) {
|
|
1462
1485
|
if (!b || b.length < 24) return null;
|
|
1463
1486
|
const u = (n) => b[n] ?? 0;
|
|
1464
|
-
if (IMAGE_FORMATS.png.magic
|
|
1487
|
+
if (IMAGE_FORMATS.png.magic(b)) {
|
|
1465
1488
|
const w = u(16) << 24 | u(17) << 16 | u(18) << 8 | u(19);
|
|
1466
1489
|
const h = u(20) << 24 | u(21) << 16 | u(22) << 8 | u(23);
|
|
1467
1490
|
return w > 0 && h > 0 ? {
|
|
@@ -1469,7 +1492,7 @@ function getImageSizeFromBytes(b) {
|
|
|
1469
1492
|
h
|
|
1470
1493
|
} : null;
|
|
1471
1494
|
}
|
|
1472
|
-
if (IMAGE_FORMATS.gif.magic
|
|
1495
|
+
if (IMAGE_FORMATS.gif.magic(b)) {
|
|
1473
1496
|
const w = u(6) | u(7) << 8;
|
|
1474
1497
|
const h = u(8) | u(9) << 8;
|
|
1475
1498
|
return w > 0 && h > 0 ? {
|
|
@@ -1477,7 +1500,7 @@ function getImageSizeFromBytes(b) {
|
|
|
1477
1500
|
h
|
|
1478
1501
|
} : null;
|
|
1479
1502
|
}
|
|
1480
|
-
if (IMAGE_FORMATS.bmp.magic
|
|
1503
|
+
if (IMAGE_FORMATS.bmp.magic(b)) {
|
|
1481
1504
|
if ((u(14) | u(15) << 8 | u(16) << 16 | u(17) << 24) === 12) {
|
|
1482
1505
|
const w = u(18) | u(19) << 8;
|
|
1483
1506
|
const h = u(20) | u(21) << 8;
|
|
@@ -1496,7 +1519,7 @@ function getImageSizeFromBytes(b) {
|
|
|
1496
1519
|
h: ah
|
|
1497
1520
|
} : null;
|
|
1498
1521
|
}
|
|
1499
|
-
if (IMAGE_FORMATS.webp.magic
|
|
1522
|
+
if (IMAGE_FORMATS.webp.magic(b)) {
|
|
1500
1523
|
const fourCC = String.fromCharCode(u(12), u(13), u(14), u(15));
|
|
1501
1524
|
if (fourCC === "VP8 " && b.length >= 30) {
|
|
1502
1525
|
const w = (u(26) | u(27) << 8) & 16383;
|
|
@@ -1525,7 +1548,7 @@ function getImageSizeFromBytes(b) {
|
|
|
1525
1548
|
}
|
|
1526
1549
|
return null;
|
|
1527
1550
|
}
|
|
1528
|
-
if (IMAGE_FORMATS.jpeg.magic
|
|
1551
|
+
if (IMAGE_FORMATS.jpeg.magic(b)) {
|
|
1529
1552
|
let i = 2;
|
|
1530
1553
|
while (i + 9 < b.length) {
|
|
1531
1554
|
if (b[i] !== 255) {
|
|
@@ -1664,7 +1687,22 @@ function getSvgSizeFromMarkup(svg) {
|
|
|
1664
1687
|
function utf8Decode(bytes) {
|
|
1665
1688
|
return new TextDecoder().decode(bytes);
|
|
1666
1689
|
}
|
|
1667
|
-
|
|
1668
|
-
|
|
1690
|
+
// src/ooxml/chart-metadata.ts
|
|
1691
|
+
/**
|
|
1692
|
+
* The pptx-ts chart-metadata extension on `c:chartSpace/c:extLst`: the `c:ext/@uri` it is filed
|
|
1693
|
+
* under and the namespace of its payload.
|
|
1694
|
+
*
|
|
1695
|
+
* Here because both sides spell them: the writer stamps them from `addChart`'s `metadata`, and
|
|
1696
|
+
* `Chart.metadata` finds the extension by them. No runtime imports.
|
|
1697
|
+
*/
|
|
1698
|
+
/**
|
|
1699
|
+
* Stable pptx-ts vendor GUID identifying the chart-metadata extension. Custom data rides under
|
|
1700
|
+
* this URI in a foreign namespace so PowerPoint preserves it (the extLst mechanism) instead of
|
|
1701
|
+
* stripping or repairing it as it would an unrecognised sibling element.
|
|
1702
|
+
*/
|
|
1703
|
+
const CHART_METADATA_EXT_URI = "{094A432E-1F6C-499B-95B8-B57DC9536949}";
|
|
1704
|
+
/** Foreign namespace for the chart-metadata extension payload. */
|
|
1705
|
+
const CHART_METADATA_NS = "http://ts-pptx.com/schema/chart/metadata";
|
|
1706
|
+
export { SLIDE_LAYOUT_CONTENT_TYPE as $, TICK_LABEL_POSITIONS as $t, FONT_REL as A, LEGEND_POSITIONS as At, NOTES_SLIDE_CONTENT_TYPE as B, RADAR_STYLE_ALIASES as Bt, COMMENT_AUTHORS_REL as C, DEFAULT_COLOR_MAP as Ct, CUSTOM_PROPS_REL as D, ERROR_BAR_TYPES as Dt, CUSTOM_PROPS_CONTENT_TYPE as E, ERROR_BAR_DIRECTIONS as Et, MS_MEDIA_REL as F, PATTERN_PRESETS as Ft, PACKAGE_REL as G, TEXT_CAPS_TYPES as Gt, OD_CONTENT as H, SCHEME_COLOR_VALUES as Ht, MS_POWERPOINT_CONTENT as I, PLACEHOLDER_TYPES as It, PRES_PROPS_CONTENT_TYPE as J, TEXT_STRIKE_TYPES as Jt, PACKAGE_REL_NS as K, TEXT_HORZ_OVERFLOW as Kt, MS_REL as L, PRESET_LINE_DASHES as Lt, IMAGE_REL as M, LIGHT_RIG_DIRECTIONS as Mt, MODEL3D_REL as N, LINE_DATA_SYMBOLS as Nt, EXTENDED_PROPS_CONTENT_TYPE as O, ERROR_BAR_VALUE_TYPES as Ot, MODERN_COMMENT_AUTHORS_REL as P, LINE_END_TYPES as Pt, SLIDE_CONTENT_TYPE as Q, THEME_COLOR_SLOTS as Qt, NOTES_MASTER_CONTENT_TYPE as R, PRESET_MATERIALS as Rt, COMMENT_AUTHORS_CONTENT_TYPE as S, CROSS_BETWEEN as St, CORE_PROPS_REL as T, EMBEDDED_FONT_SLOTS as Tt, OFFICE_DOCUMENT_REL as U, TEXT_ANCHORS as Ut, NOTES_SLIDE_REL as V, RADAR_STYLE_ALIAS_NAMES as Vt, OFFICE_REL as W, TEXT_AUTONUM_SCHEMES as Wt, RELATIONSHIPS_CONTENT_TYPE as X, TEXT_UNDERLINE_TYPES as Xt, PRES_PROPS_REL as Y, TEXT_TAB_ALIGN_TYPES as Yt, SHARED_PARTS as Z, TEXT_VERTICAL as Zt, CHART_REL as _, imageFormatForBytes as _n, BAR_DIRECTIONS as _t, getImageSizeFromBytes as a, checkEnumOrWarn as an, TABLE_STYLES_REL as at, COMMENTS_CONTENT_TYPE as b, BUILT_IN_UNITS as bt, SHOW_JUMPS as c, xsdBoolIfTrue as cn, VIDEO_REL as ct, AUDIO_REL as d, stripHash as dn, XLSX_CONTENT_TYPE as dt, TICK_MARKS as en, SLIDE_LAYOUT_REL as et, CHARTEX_CONTENT_TYPE as f, bytesToBase64 as fn, OOXML_NS as ft, CHART_CONTENT_TYPE as g, toMediaDataUri as gn, BAR_3D_SHAPES as gt, CHART_COLOR_STYLE_REL as h, svgMarkupToDataUri as hn, AXIS_ORIENTATIONS as ht, getImageSizeFromBase64 as i, checkEnumOrThrow as in, TABLE_STYLES_CONTENT_TYPE as it, HYPERLINK_REL as j, LIGHT_RIGS as jt, EXTENDED_PROPS_REL as k, GROUPINGS as kt, LINE_CAP_BY_TOKEN as l, isHexColor as ln, VIEW_PROPS_CONTENT_TYPE as lt, CHART_COLOR_STYLE_CONTENT_TYPE as m, hasBase64Header as mn, TABLE_GRAPHIC_DATA_URI as mt, CHART_METADATA_NS as n, TRANSITION_TYPES as nn, SLIDE_MASTER_REL as nt, HALIGN_BY_TEXT_ALIGN as o, boolValue as on, THEME_CONTENT_TYPE as ot, CHARTEX_REL as p, decodeBase64ToBytes as pn, PML_ROOT_NS as pt, PRESENTATION_MAIN_CONTENT_TYPE as q, TEXT_SHAPE_TYPES as qt, fitSrcRectPercents as r, TRANSITION_VARIANT_ATTRIBUTES as rn, SLIDE_REL as rt, textAlignToken as s, xsdBool as sn, THEME_REL as st, CHART_METADATA_EXT_URI as t, TIME_UNITS as tn, SLIDE_MASTER_CONTENT_TYPE as tt, lineCapToken as u, splitRgbaHex as un, VIEW_PROPS_REL as ut, CHART_STYLE_CONTENT_TYPE as v, imageFormatForContentType as vn, BAR_GROUPINGS as vt, CORE_PROPS_CONTENT_TYPE as w, DISPLAY_BLANKS_AS as wt, COMMENTS_REL as x, COLOR_MAP_TOKENS as xt, CHART_STYLE_REL as y, imageFormatForExtension as yn, BEVEL_PRESETS as yt, NOTES_MASTER_REL as z, RADAR_STYLES as zt };
|
|
1669
1707
|
|
|
1670
|
-
//# sourceMappingURL=
|
|
1708
|
+
//# sourceMappingURL=chart-metadata-CwiTTcJq.js.map
|