@json-to-office/core-pptx 0.35.0 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/generator.d.ts.map +1 -1
- package/dist/core/packagePresentation.d.ts +6 -1
- package/dist/core/packagePresentation.d.ts.map +1 -1
- package/dist/core/svgRasterFallback.d.ts +12 -0
- package/dist/core/svgRasterFallback.d.ts.map +1 -0
- package/dist/index.js +156 -16
- package/dist/index.js.map +1 -1
- package/dist/plugin/createPresentationGenerator.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/warn.d.ts +1 -0
- package/dist/utils/warn.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/core/generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAEH,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,OAAO,KAAK,EACV,+BAA+B,EAC/B,eAAe,EACf,eAAe,EACf,cAAc,EACf,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAK9E,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,2BAA2B;IAC1C,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,4BAA4B;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC/C;;;;OAIG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,UAAU,CAAC,EAAE,2BAA2B,CAAC;IACzC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,6EAA6E;AAC7E,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,SAAgB,MAAM,EAAE,eAAe,EAAE,CAAC;gBAE9B,MAAM,EAAE,eAAe,EAAE;CAStC;AAqBD;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAYhE;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,OAAO,GAClB,UAAU,IAAI,+BAA+B,CAI/C;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,+BAA+B,EACzC,OAAO,CAAC,EAAE,iBAAiB,EAC3B,QAAQ,CAAC,EAAE,eAAe,EAAE,EAC5B,YAAY,CAAC,EAAE,cAAc,EAAE,GAC9B,OAAO,CAAC,SAAS,CAAC,CAgBpB;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,GAAG,+BAA+B,EACpD,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,GAAG,+BAA+B,EACpD,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/core/generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAEH,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,OAAO,KAAK,EACV,+BAA+B,EAC/B,eAAe,EACf,eAAe,EACf,cAAc,EACf,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAK9E,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,2BAA2B;IAC1C,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,4BAA4B;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC/C;;;;OAIG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,UAAU,CAAC,EAAE,2BAA2B,CAAC;IACzC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,6EAA6E;AAC7E,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,SAAgB,MAAM,EAAE,eAAe,EAAE,CAAC;gBAE9B,MAAM,EAAE,eAAe,EAAE;CAStC;AAqBD;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAYhE;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,OAAO,GAClB,UAAU,IAAI,+BAA+B,CAI/C;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,+BAA+B,EACzC,OAAO,CAAC,EAAE,iBAAiB,EAC3B,QAAQ,CAAC,EAAE,eAAe,EAAE,EAC5B,YAAY,CAAC,EAAE,cAAc,EAAE,GAC9B,OAAO,CAAC,SAAS,CAAC,CAgBpB;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,GAAG,+BAA+B,EACpD,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,GAAG,+BAA+B,EACpD,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,CAyD3B;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,GAAG,+BAA+B,EACpD,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,4BAA4B,GACrC,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;CAQjC,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import type { PendingXmlFill } from '../types';
|
|
2
|
+
import type { PendingXmlFill, PipelineWarning } from '../types';
|
|
3
3
|
/** Stable default shared by package entries and OOXML core metadata. */
|
|
4
4
|
export declare const DEFAULT_GENERATED_AT = "2000-01-01T00:00:00.000Z";
|
|
5
5
|
export interface PresentationPackagingOptions {
|
|
@@ -13,6 +13,11 @@ export interface PresentationPackagingOptions {
|
|
|
13
13
|
* the registered fill XML.
|
|
14
14
|
*/
|
|
15
15
|
pendingFills?: PendingXmlFill[];
|
|
16
|
+
/**
|
|
17
|
+
* Warning sink for post-generation repairs. Only the SVG raster fallback
|
|
18
|
+
* pass reports here; when omitted its failures go to `console.warn`.
|
|
19
|
+
*/
|
|
20
|
+
warnings?: PipelineWarning[];
|
|
16
21
|
}
|
|
17
22
|
/**
|
|
18
23
|
* Apply post-generation OOXML fixes and deterministic package metadata.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packagePresentation.d.ts","sourceRoot":"","sources":["../../src/core/packagePresentation.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"packagePresentation.d.ts","sourceRoot":"","sources":["../../src/core/packagePresentation.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAMhE,wEAAwE;AACxE,eAAO,MAAM,oBAAoB,6BAA6B,CAAC;AAE/D,MAAM,WAAW,4BAA4B;IAC3C,+DAA+D;IAC/D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC5B;;;;OAIG;IACH,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;CAC9B;AAqLD;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,MAAM,CAAC,CAqCjB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type JSZip from 'jszip';
|
|
2
|
+
import type { PipelineWarning } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Replace the broken-image placeholders PptxGenJS writes for inline SVG
|
|
5
|
+
* pictures with real rasterizations of those SVGs. Never throws: a missing
|
|
6
|
+
* native binding or an SVG resvg rejects degrades to a warning and leaves the
|
|
7
|
+
* package as generated.
|
|
8
|
+
*
|
|
9
|
+
* @returns whether any part of the zip was rewritten.
|
|
10
|
+
*/
|
|
11
|
+
export declare function repairSvgRasterFallbacks(zip: JSZip, warnings?: PipelineWarning[]): Promise<boolean>;
|
|
12
|
+
//# sourceMappingURL=svgRasterFallback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svgRasterFallback.d.ts","sourceRoot":"","sources":["../../src/core/svgRasterFallback.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAyIhD;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,KAAK,EACV,QAAQ,CAAC,EAAE,eAAe,EAAE,GAC3B,OAAO,CAAC,OAAO,CAAC,CAkElB"}
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ var W = {
|
|
|
21
21
|
IMAGE_NO_SOURCE: "IMAGE_NO_SOURCE",
|
|
22
22
|
IMAGE_PROBE_FAILED: "IMAGE_PROBE_FAILED",
|
|
23
23
|
IMAGE_PATH_OUTSIDE_ROOTS: "IMAGE_PATH_OUTSIDE_ROOTS",
|
|
24
|
+
IMAGE_SVG_RASTER_FAILED: "IMAGE_SVG_RASTER_FAILED",
|
|
24
25
|
MISSING_TEMPLATE: "MISSING_TEMPLATE",
|
|
25
26
|
UNKNOWN_PLACEHOLDER: "UNKNOWN_PLACEHOLDER",
|
|
26
27
|
PLACEHOLDER_NO_POSITION: "PLACEHOLDER_NO_POSITION",
|
|
@@ -2074,6 +2075,142 @@ import {
|
|
|
2074
2075
|
|
|
2075
2076
|
// src/core/packagePresentation.ts
|
|
2076
2077
|
import JSZip from "jszip";
|
|
2078
|
+
|
|
2079
|
+
// src/core/svgRasterFallback.ts
|
|
2080
|
+
import path3 from "path";
|
|
2081
|
+
var EMU_PER_INCH = 914400;
|
|
2082
|
+
var RASTER_SCALE = 3;
|
|
2083
|
+
var MAX_EDGE_PX = 4096;
|
|
2084
|
+
var MIN_EDGE_PX = 16;
|
|
2085
|
+
var DEFAULT_EDGE_PX = 1024;
|
|
2086
|
+
var PART_PATTERNS = [
|
|
2087
|
+
/^ppt\/slides\/slide\d+\.xml$/,
|
|
2088
|
+
/^ppt\/slideLayouts\/[^/]+\.xml$/,
|
|
2089
|
+
/^ppt\/slideMasters\/[^/]+\.xml$/
|
|
2090
|
+
];
|
|
2091
|
+
var SVG_BLIP = /<asvg:svgBlip\b[^>]*r:embed="([^"]+)"/g;
|
|
2092
|
+
var BLIP = /<a:blip\b[^>]*r:embed="([^"]+)"/g;
|
|
2093
|
+
var EXTENT = /<a:ext\s+cx="(\d+)"\s+cy="(\d+)"/;
|
|
2094
|
+
var RELATIONSHIP = /<Relationship\b([^>]*)>/g;
|
|
2095
|
+
var resvgModule;
|
|
2096
|
+
function loadResvg() {
|
|
2097
|
+
resvgModule ??= import("@resvg/resvg-js");
|
|
2098
|
+
return resvgModule;
|
|
2099
|
+
}
|
|
2100
|
+
async function readRelationships(zip, partPath) {
|
|
2101
|
+
const dir = path3.posix.dirname(partPath);
|
|
2102
|
+
const relsPath = `${dir}/_rels/${path3.posix.basename(partPath)}.rels`;
|
|
2103
|
+
const targets = /* @__PURE__ */ new Map();
|
|
2104
|
+
const entry = zip.file(relsPath);
|
|
2105
|
+
if (!entry) return targets;
|
|
2106
|
+
const xml = await entry.async("string");
|
|
2107
|
+
for (const match of xml.matchAll(RELATIONSHIP)) {
|
|
2108
|
+
const attrs = match[1];
|
|
2109
|
+
if (/\bTargetMode="External"/.test(attrs)) continue;
|
|
2110
|
+
const id = /\bId="([^"]+)"/.exec(attrs)?.[1];
|
|
2111
|
+
const target = /\bTarget="([^"]+)"/.exec(attrs)?.[1];
|
|
2112
|
+
if (!id || !target) continue;
|
|
2113
|
+
targets.set(
|
|
2114
|
+
id,
|
|
2115
|
+
target.startsWith("/") ? target.slice(1) : path3.posix.normalize(path3.posix.join(dir, target))
|
|
2116
|
+
);
|
|
2117
|
+
}
|
|
2118
|
+
return targets;
|
|
2119
|
+
}
|
|
2120
|
+
function collectWorkItems(xml, rels, items) {
|
|
2121
|
+
const blips = [...xml.matchAll(BLIP)];
|
|
2122
|
+
for (const svgBlip of xml.matchAll(SVG_BLIP)) {
|
|
2123
|
+
const at = svgBlip.index ?? 0;
|
|
2124
|
+
const preview = blips.filter((blip) => (blip.index ?? 0) < at).pop();
|
|
2125
|
+
if (!preview) continue;
|
|
2126
|
+
const pngPart = rels.get(preview[1]);
|
|
2127
|
+
const svgPart = rels.get(svgBlip[1]);
|
|
2128
|
+
if (!pngPart || !svgPart) continue;
|
|
2129
|
+
const picEnd = xml.indexOf("</p:pic>", at);
|
|
2130
|
+
const extent = EXTENT.exec(picEnd === -1 ? "" : xml.slice(at, picEnd));
|
|
2131
|
+
const cx = extent ? Number(extent[1]) : void 0;
|
|
2132
|
+
const cy = extent ? Number(extent[2]) : void 0;
|
|
2133
|
+
const existing = items.get(pngPart);
|
|
2134
|
+
items.set(pngPart, {
|
|
2135
|
+
svgPart,
|
|
2136
|
+
cx: Math.max(cx ?? 0, existing?.cx ?? 0) || void 0,
|
|
2137
|
+
cy: Math.max(cy ?? 0, existing?.cy ?? 0) || void 0
|
|
2138
|
+
});
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
function toPixels(emu) {
|
|
2142
|
+
const px = Math.round(emu / EMU_PER_INCH * 96 * RASTER_SCALE);
|
|
2143
|
+
return Math.min(MAX_EDGE_PX, Math.max(MIN_EDGE_PX, px));
|
|
2144
|
+
}
|
|
2145
|
+
function resolveFitTo(intrinsicAspect, cx, cy) {
|
|
2146
|
+
if (!cx || !cy) return { mode: "width", value: DEFAULT_EDGE_PX };
|
|
2147
|
+
const wide = intrinsicAspect > cx / cy;
|
|
2148
|
+
const mode = wide ? "height" : "width";
|
|
2149
|
+
let value = wide ? toPixels(cy) : toPixels(cx);
|
|
2150
|
+
const other = wide ? Math.round(value * intrinsicAspect) : Math.round(value / intrinsicAspect);
|
|
2151
|
+
const longest = Math.max(value, other);
|
|
2152
|
+
if (longest > MAX_EDGE_PX) {
|
|
2153
|
+
value = Math.max(MIN_EDGE_PX, Math.floor(value * MAX_EDGE_PX / longest));
|
|
2154
|
+
}
|
|
2155
|
+
return { mode, value };
|
|
2156
|
+
}
|
|
2157
|
+
async function repairSvgRasterFallbacks(zip, warnings) {
|
|
2158
|
+
const pending = /* @__PURE__ */ new Map();
|
|
2159
|
+
for (const [partPath, entry] of Object.entries(zip.files)) {
|
|
2160
|
+
if (entry.dir || !PART_PATTERNS.some((rule) => rule.test(partPath))) {
|
|
2161
|
+
continue;
|
|
2162
|
+
}
|
|
2163
|
+
const xml = await entry.async("string");
|
|
2164
|
+
if (!xml.includes("asvg:svgBlip")) continue;
|
|
2165
|
+
collectWorkItems(xml, await readRelationships(zip, partPath), pending);
|
|
2166
|
+
}
|
|
2167
|
+
if (pending.size === 0) return false;
|
|
2168
|
+
let Resvg;
|
|
2169
|
+
try {
|
|
2170
|
+
({ Resvg } = await loadResvg());
|
|
2171
|
+
} catch (error) {
|
|
2172
|
+
warn(
|
|
2173
|
+
warnings,
|
|
2174
|
+
W.IMAGE_SVG_RASTER_FAILED,
|
|
2175
|
+
`Could not load the SVG rasterizer, so inline SVG images keep PowerPoint's broken-image fallback: ${String(error)}`,
|
|
2176
|
+
{ component: "image" }
|
|
2177
|
+
);
|
|
2178
|
+
return false;
|
|
2179
|
+
}
|
|
2180
|
+
const rendered = /* @__PURE__ */ new Map();
|
|
2181
|
+
let changed = false;
|
|
2182
|
+
for (const [pngPart, item] of pending) {
|
|
2183
|
+
try {
|
|
2184
|
+
if (!zip.file(pngPart)) {
|
|
2185
|
+
throw new Error(`missing preview part ${pngPart}`);
|
|
2186
|
+
}
|
|
2187
|
+
const source = zip.file(item.svgPart);
|
|
2188
|
+
if (!source) throw new Error(`missing part ${item.svgPart}`);
|
|
2189
|
+
const svg = await source.async("string");
|
|
2190
|
+
const probe2 = new Resvg(svg);
|
|
2191
|
+
const fitTo = resolveFitTo(probe2.width / probe2.height, item.cx, item.cy);
|
|
2192
|
+
const key = `${fitTo.mode}:${fitTo.value}
|
|
2193
|
+
${svg}`;
|
|
2194
|
+
let png = rendered.get(key);
|
|
2195
|
+
if (!png) {
|
|
2196
|
+
png = Buffer.from(new Resvg(svg, { fitTo }).render().asPng());
|
|
2197
|
+
rendered.set(key, png);
|
|
2198
|
+
}
|
|
2199
|
+
zip.file(pngPart, png);
|
|
2200
|
+
changed = true;
|
|
2201
|
+
} catch (error) {
|
|
2202
|
+
warn(
|
|
2203
|
+
warnings,
|
|
2204
|
+
W.IMAGE_SVG_RASTER_FAILED,
|
|
2205
|
+
`Could not rasterize ${item.svgPart}, so it keeps PowerPoint's broken-image fallback: ${String(error)}`,
|
|
2206
|
+
{ component: "image" }
|
|
2207
|
+
);
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
return changed;
|
|
2211
|
+
}
|
|
2212
|
+
|
|
2213
|
+
// src/core/packagePresentation.ts
|
|
2077
2214
|
var MEDIUM_STYLE_2_ACCENT_1 = "{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}";
|
|
2078
2215
|
var NO_STYLE_NO_GRID = "{2D5ABB26-0587-4C30-8999-92F81FD0307C}";
|
|
2079
2216
|
var DEFAULT_GENERATED_AT = "2000-01-01T00:00:00.000Z";
|
|
@@ -2127,24 +2264,24 @@ function remapChartReferences(value, chartIds) {
|
|
|
2127
2264
|
);
|
|
2128
2265
|
}
|
|
2129
2266
|
async function canonicalizeChartIds(zip) {
|
|
2130
|
-
const sourceIds = Object.keys(zip.files).map((
|
|
2267
|
+
const sourceIds = Object.keys(zip.files).map((path4) => path4.match(/^ppt\/charts\/chart(\d+)\.xml$/)?.[1]).filter((value) => value !== void 0).map(Number).sort((a, b) => a - b);
|
|
2131
2268
|
const chartIds = new Map(sourceIds.map((id, index) => [id, index + 1]));
|
|
2132
2269
|
if (chartIds.size === 0) return;
|
|
2133
|
-
for (const [
|
|
2134
|
-
if (entry.dir || !
|
|
2270
|
+
for (const [path4, entry] of Object.entries(zip.files)) {
|
|
2271
|
+
if (entry.dir || !path4.endsWith(".xml") && !path4.endsWith(".rels")) {
|
|
2135
2272
|
continue;
|
|
2136
2273
|
}
|
|
2137
2274
|
const xml = await entry.async("string");
|
|
2138
2275
|
const remapped = remapChartReferences(xml, chartIds);
|
|
2139
|
-
if (remapped !== xml) zip.file(
|
|
2276
|
+
if (remapped !== xml) zip.file(path4, remapped);
|
|
2140
2277
|
}
|
|
2141
2278
|
const renames = [];
|
|
2142
|
-
for (const [
|
|
2279
|
+
for (const [path4, entry] of Object.entries(zip.files)) {
|
|
2143
2280
|
if (entry.dir) continue;
|
|
2144
|
-
const remappedPath = remapChartReferences(
|
|
2145
|
-
if (remappedPath ===
|
|
2281
|
+
const remappedPath = remapChartReferences(path4, chartIds);
|
|
2282
|
+
if (remappedPath === path4) continue;
|
|
2146
2283
|
renames.push({
|
|
2147
|
-
from:
|
|
2284
|
+
from: path4,
|
|
2148
2285
|
to: remappedPath,
|
|
2149
2286
|
data: await entry.async("nodebuffer"),
|
|
2150
2287
|
date: entry.date
|
|
@@ -2174,12 +2311,12 @@ async function canonicalizePackage(zip, generatedAt, depth = 0) {
|
|
|
2174
2311
|
zip.file("docProps/core.xml", coreXml);
|
|
2175
2312
|
}
|
|
2176
2313
|
if (depth < 3) {
|
|
2177
|
-
for (const [
|
|
2178
|
-
if (entry.dir || !EMBEDDED_OFFICE_PACKAGE.test(
|
|
2314
|
+
for (const [path4, entry] of Object.entries(zip.files)) {
|
|
2315
|
+
if (entry.dir || !EMBEDDED_OFFICE_PACKAGE.test(path4)) continue;
|
|
2179
2316
|
try {
|
|
2180
2317
|
const nested = await JSZip.loadAsync(await entry.async("nodebuffer"));
|
|
2181
2318
|
await canonicalizePackage(nested, generatedAt, depth + 1);
|
|
2182
|
-
zip.file(
|
|
2319
|
+
zip.file(path4, await generateZip(nested));
|
|
2183
2320
|
} catch {
|
|
2184
2321
|
}
|
|
2185
2322
|
}
|
|
@@ -2191,8 +2328,8 @@ async function canonicalizePackage(zip, generatedAt, depth = 0) {
|
|
|
2191
2328
|
async function packagePresentationBuffer(buffer, options = {}) {
|
|
2192
2329
|
const zip = await JSZip.loadAsync(buffer);
|
|
2193
2330
|
let changed = false;
|
|
2194
|
-
for (const [
|
|
2195
|
-
if (!
|
|
2331
|
+
for (const [path4, entry] of Object.entries(zip.files)) {
|
|
2332
|
+
if (!path4.match(/^ppt\/slides\/slide\d+\.xml$/)) continue;
|
|
2196
2333
|
let xml = await entry.async("string");
|
|
2197
2334
|
let fileChanged = false;
|
|
2198
2335
|
if (xml.includes(MEDIUM_STYLE_2_ACCENT_1)) {
|
|
@@ -2207,10 +2344,11 @@ async function packagePresentationBuffer(buffer, options = {}) {
|
|
|
2207
2344
|
}
|
|
2208
2345
|
}
|
|
2209
2346
|
if (fileChanged) {
|
|
2210
|
-
zip.file(
|
|
2347
|
+
zip.file(path4, xml);
|
|
2211
2348
|
changed = true;
|
|
2212
2349
|
}
|
|
2213
2350
|
}
|
|
2351
|
+
changed = await repairSvgRasterFallbacks(zip, options.warnings) || changed;
|
|
2214
2352
|
if (options.deterministic !== false) {
|
|
2215
2353
|
const generatedAt = resolveGeneratedAt(options.generatedAt);
|
|
2216
2354
|
await canonicalizeChartIds(zip);
|
|
@@ -2314,7 +2452,8 @@ async function generateBufferWithWarnings(jsonConfig, options) {
|
|
|
2314
2452
|
const data = await pptx.write({ outputType: "nodebuffer" });
|
|
2315
2453
|
const buffer = await packagePresentationBuffer(data, {
|
|
2316
2454
|
...options,
|
|
2317
|
-
pendingFills
|
|
2455
|
+
pendingFills,
|
|
2456
|
+
warnings
|
|
2318
2457
|
});
|
|
2319
2458
|
return { buffer, warnings };
|
|
2320
2459
|
}
|
|
@@ -2702,7 +2841,8 @@ function createBuilderImpl(state) {
|
|
|
2702
2841
|
const buffer = await packagePresentationBuffer(data, {
|
|
2703
2842
|
deterministic: options?.deterministic ?? state.packaging.deterministic,
|
|
2704
2843
|
generatedAt: options?.generatedAt ?? state.packaging.generatedAt,
|
|
2705
|
-
pendingFills
|
|
2844
|
+
pendingFills,
|
|
2845
|
+
warnings
|
|
2706
2846
|
});
|
|
2707
2847
|
return { buffer, warnings };
|
|
2708
2848
|
} catch (error) {
|