ppt2json 0.2.0 → 0.3.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 +10 -2
- package/dist/index.d.mts +44 -26
- package/dist/index.d.ts +44 -26
- package/dist/index.js +202 -244
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +202 -248
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -33,8 +33,7 @@ __export(index_exports, {
|
|
|
33
33
|
parsePptxToJson: () => parsePptxToJson
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
|
-
var
|
|
37
|
-
var import_json2pptx = require("json2pptx");
|
|
36
|
+
var import_json2pptx_schema = require("json2pptx-schema");
|
|
38
37
|
|
|
39
38
|
// parser/parse.ts
|
|
40
39
|
var import_jszip = __toESM(require("jszip"));
|
|
@@ -3159,176 +3158,8 @@ function shapeArc(cX, cY, rX, rY, stAng, endAng, isClose) {
|
|
|
3159
3158
|
}
|
|
3160
3159
|
function getCustomShapePath(custShapType, w, h) {
|
|
3161
3160
|
const pathLstNode = getTextByPathList(custShapType, ["a:pathLst"]);
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
const maxX = parseInt(pathNodes["attrs"]["w"]);
|
|
3165
|
-
const maxY = parseInt(pathNodes["attrs"]["h"]);
|
|
3166
|
-
const cX = maxX === 0 ? 0 : 1 / maxX * w;
|
|
3167
|
-
const cY = maxY === 0 ? 0 : 1 / maxY * h;
|
|
3168
|
-
let d = "";
|
|
3169
|
-
let moveToNode = getTextByPathList(pathNodes, ["a:moveTo"]);
|
|
3170
|
-
let lnToNodes = pathNodes["a:lnTo"];
|
|
3171
|
-
let cubicBezToNodes = pathNodes["a:cubicBezTo"];
|
|
3172
|
-
let quadBezToNodes = pathNodes["a:quadBezTo"];
|
|
3173
|
-
const arcToNodes = pathNodes["a:arcTo"];
|
|
3174
|
-
let closeNode = getTextByPathList(pathNodes, ["a:close"]);
|
|
3175
|
-
if (!Array.isArray(moveToNode)) moveToNode = [moveToNode];
|
|
3176
|
-
const multiSapeAry = [];
|
|
3177
|
-
if (moveToNode.length > 0) {
|
|
3178
|
-
Object.keys(moveToNode).forEach((key) => {
|
|
3179
|
-
const moveToPtNode = moveToNode[key]["a:pt"];
|
|
3180
|
-
if (moveToPtNode) {
|
|
3181
|
-
Object.keys(moveToPtNode).forEach((key2) => {
|
|
3182
|
-
const moveToNoPt = moveToPtNode[key2];
|
|
3183
|
-
const spX = moveToNoPt["attrs"]?.["x"];
|
|
3184
|
-
const spY = moveToNoPt["attrs"]?.["y"];
|
|
3185
|
-
const order = moveToNoPt["attrs"]?.["order"];
|
|
3186
|
-
multiSapeAry.push({
|
|
3187
|
-
type: "movto",
|
|
3188
|
-
x: spX,
|
|
3189
|
-
y: spY,
|
|
3190
|
-
order
|
|
3191
|
-
});
|
|
3192
|
-
});
|
|
3193
|
-
}
|
|
3194
|
-
});
|
|
3195
|
-
if (lnToNodes) {
|
|
3196
|
-
if (!Array.isArray(lnToNodes)) lnToNodes = [lnToNodes];
|
|
3197
|
-
Object.keys(lnToNodes).forEach((key) => {
|
|
3198
|
-
const lnToPtNode = lnToNodes[key]["a:pt"];
|
|
3199
|
-
if (lnToPtNode) {
|
|
3200
|
-
Object.keys(lnToPtNode).forEach((key2) => {
|
|
3201
|
-
const lnToNoPt = lnToPtNode[key2];
|
|
3202
|
-
const ptX = lnToNoPt["attrs"]?.["x"];
|
|
3203
|
-
const ptY = lnToNoPt["attrs"]?.["y"];
|
|
3204
|
-
const order = lnToNoPt["attrs"]?.["order"];
|
|
3205
|
-
multiSapeAry.push({
|
|
3206
|
-
type: "lnto",
|
|
3207
|
-
x: ptX,
|
|
3208
|
-
y: ptY,
|
|
3209
|
-
order
|
|
3210
|
-
});
|
|
3211
|
-
});
|
|
3212
|
-
}
|
|
3213
|
-
});
|
|
3214
|
-
}
|
|
3215
|
-
if (cubicBezToNodes) {
|
|
3216
|
-
const cubicBezToPtNodesAry = [];
|
|
3217
|
-
if (!Array.isArray(cubicBezToNodes)) cubicBezToNodes = [cubicBezToNodes];
|
|
3218
|
-
Object.keys(cubicBezToNodes).forEach((key) => {
|
|
3219
|
-
cubicBezToPtNodesAry.push(cubicBezToNodes[key]["a:pt"]);
|
|
3220
|
-
});
|
|
3221
|
-
cubicBezToPtNodesAry.forEach((key) => {
|
|
3222
|
-
const pts_ary = [];
|
|
3223
|
-
key.forEach((pt) => {
|
|
3224
|
-
const pt_obj = {
|
|
3225
|
-
x: pt["attrs"]["x"],
|
|
3226
|
-
y: pt["attrs"]["y"]
|
|
3227
|
-
};
|
|
3228
|
-
pts_ary.push(pt_obj);
|
|
3229
|
-
});
|
|
3230
|
-
const order = key[0]["attrs"]["order"];
|
|
3231
|
-
multiSapeAry.push({
|
|
3232
|
-
type: "cubicBezTo",
|
|
3233
|
-
cubBzPt: pts_ary,
|
|
3234
|
-
order
|
|
3235
|
-
});
|
|
3236
|
-
});
|
|
3237
|
-
}
|
|
3238
|
-
if (quadBezToNodes) {
|
|
3239
|
-
const quadBezToPtNodesAry = [];
|
|
3240
|
-
if (!Array.isArray(quadBezToNodes)) quadBezToNodes = [quadBezToNodes];
|
|
3241
|
-
Object.keys(quadBezToNodes).forEach((key) => {
|
|
3242
|
-
quadBezToPtNodesAry.push(quadBezToNodes[key]["a:pt"]);
|
|
3243
|
-
});
|
|
3244
|
-
quadBezToPtNodesAry.forEach((key) => {
|
|
3245
|
-
const pts_ary = [];
|
|
3246
|
-
key.forEach((pt) => {
|
|
3247
|
-
const pt_obj = {
|
|
3248
|
-
x: pt["attrs"]["x"],
|
|
3249
|
-
y: pt["attrs"]["y"]
|
|
3250
|
-
};
|
|
3251
|
-
pts_ary.push(pt_obj);
|
|
3252
|
-
});
|
|
3253
|
-
const order = key[0]["attrs"]["order"];
|
|
3254
|
-
multiSapeAry.push({
|
|
3255
|
-
type: "quadBezTo",
|
|
3256
|
-
quadBzPt: pts_ary,
|
|
3257
|
-
order
|
|
3258
|
-
});
|
|
3259
|
-
});
|
|
3260
|
-
}
|
|
3261
|
-
if (arcToNodes) {
|
|
3262
|
-
const arcToNodesAttrs = arcToNodes["attrs"];
|
|
3263
|
-
const order = arcToNodesAttrs["order"];
|
|
3264
|
-
const hR = arcToNodesAttrs["hR"];
|
|
3265
|
-
const wR = arcToNodesAttrs["wR"];
|
|
3266
|
-
const stAng = arcToNodesAttrs["stAng"];
|
|
3267
|
-
const swAng = arcToNodesAttrs["swAng"];
|
|
3268
|
-
let shftX = 0;
|
|
3269
|
-
let shftY = 0;
|
|
3270
|
-
const arcToPtNode = getTextByPathList(arcToNodes, ["a:pt", "attrs"]);
|
|
3271
|
-
if (arcToPtNode) {
|
|
3272
|
-
shftX = arcToPtNode["x"];
|
|
3273
|
-
shftY = arcToPtNode["y"];
|
|
3274
|
-
}
|
|
3275
|
-
multiSapeAry.push({
|
|
3276
|
-
type: "arcTo",
|
|
3277
|
-
hR,
|
|
3278
|
-
wR,
|
|
3279
|
-
stAng,
|
|
3280
|
-
swAng,
|
|
3281
|
-
shftX,
|
|
3282
|
-
shftY,
|
|
3283
|
-
order
|
|
3284
|
-
});
|
|
3285
|
-
}
|
|
3286
|
-
if (closeNode) {
|
|
3287
|
-
if (!Array.isArray(closeNode)) closeNode = [closeNode];
|
|
3288
|
-
Object.keys(closeNode).forEach(() => {
|
|
3289
|
-
multiSapeAry.push({
|
|
3290
|
-
type: "close",
|
|
3291
|
-
order: Infinity
|
|
3292
|
-
});
|
|
3293
|
-
});
|
|
3294
|
-
}
|
|
3295
|
-
multiSapeAry.sort((a, b) => a.order - b.order);
|
|
3296
|
-
let k = 0;
|
|
3297
|
-
while (k < multiSapeAry.length) {
|
|
3298
|
-
if (multiSapeAry[k].type === "movto") {
|
|
3299
|
-
const spX = parseInt(multiSapeAry[k].x) * cX;
|
|
3300
|
-
const spY = parseInt(multiSapeAry[k].y) * cY;
|
|
3301
|
-
d += " M" + spX + "," + spY;
|
|
3302
|
-
} else if (multiSapeAry[k].type === "lnto") {
|
|
3303
|
-
const Lx = parseInt(multiSapeAry[k].x) * cX;
|
|
3304
|
-
const Ly = parseInt(multiSapeAry[k].y) * cY;
|
|
3305
|
-
d += " L" + Lx + "," + Ly;
|
|
3306
|
-
} else if (multiSapeAry[k].type === "cubicBezTo") {
|
|
3307
|
-
const Cx1 = parseInt(multiSapeAry[k].cubBzPt[0].x) * cX;
|
|
3308
|
-
const Cy1 = parseInt(multiSapeAry[k].cubBzPt[0].y) * cY;
|
|
3309
|
-
const Cx2 = parseInt(multiSapeAry[k].cubBzPt[1].x) * cX;
|
|
3310
|
-
const Cy2 = parseInt(multiSapeAry[k].cubBzPt[1].y) * cY;
|
|
3311
|
-
const Cx3 = parseInt(multiSapeAry[k].cubBzPt[2].x) * cX;
|
|
3312
|
-
const Cy3 = parseInt(multiSapeAry[k].cubBzPt[2].y) * cY;
|
|
3313
|
-
d += " C" + Cx1 + "," + Cy1 + " " + Cx2 + "," + Cy2 + " " + Cx3 + "," + Cy3;
|
|
3314
|
-
} else if (multiSapeAry[k].type === "quadBezTo") {
|
|
3315
|
-
const Qx1 = parseInt(multiSapeAry[k].quadBzPt[0].x) * cX;
|
|
3316
|
-
const Qy1 = parseInt(multiSapeAry[k].quadBzPt[0].y) * cY;
|
|
3317
|
-
const Qx2 = parseInt(multiSapeAry[k].quadBzPt[1].x) * cX;
|
|
3318
|
-
const Qy2 = parseInt(multiSapeAry[k].quadBzPt[1].y) * cY;
|
|
3319
|
-
d += " Q" + Qx1 + "," + Qy1 + " " + Qx2 + "," + Qy2;
|
|
3320
|
-
} else if (multiSapeAry[k].type === "arcTo") {
|
|
3321
|
-
const hR = parseInt(multiSapeAry[k].hR) * cX;
|
|
3322
|
-
const wR = parseInt(multiSapeAry[k].wR) * cY;
|
|
3323
|
-
const stAng = parseInt(multiSapeAry[k].stAng) / 6e4;
|
|
3324
|
-
const swAng = parseInt(multiSapeAry[k].swAng) / 6e4;
|
|
3325
|
-
const endAng = stAng + swAng;
|
|
3326
|
-
d += shapeArc(wR, hR, wR, hR, stAng, endAng, false);
|
|
3327
|
-
} else if (multiSapeAry[k].type === "close") d += "z";
|
|
3328
|
-
k++;
|
|
3329
|
-
}
|
|
3330
|
-
}
|
|
3331
|
-
return d;
|
|
3161
|
+
const pathNodes = normalizeToArray(getTextByPathList(pathLstNode, ["a:path"]));
|
|
3162
|
+
return pathNodes.map((pathNode) => buildCustomShapeSegment(pathNode, w, h)).filter(Boolean).join(" ");
|
|
3332
3163
|
}
|
|
3333
3164
|
function identifyShape(shapeData) {
|
|
3334
3165
|
const pathLst = shapeData["a:pathLst"];
|
|
@@ -3343,16 +3174,16 @@ function identifyShape(shapeData) {
|
|
|
3343
3174
|
}
|
|
3344
3175
|
function extractPathCommands(path) {
|
|
3345
3176
|
const commands = [];
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
const pt = moveTo["a:pt"];
|
|
3177
|
+
const moveToList = normalizeToArray(path["a:moveTo"]);
|
|
3178
|
+
moveToList.forEach((moveTo) => {
|
|
3179
|
+
const pt = Array.isArray(moveTo?.["a:pt"]) ? moveTo["a:pt"][0] : moveTo?.["a:pt"];
|
|
3349
3180
|
if (pt) {
|
|
3350
3181
|
commands.push({
|
|
3351
3182
|
type: "moveTo",
|
|
3352
3183
|
points: [{ x: parseInt(pt.attrs?.x) || 0, y: parseInt(pt.attrs?.y) || 0 }]
|
|
3353
3184
|
});
|
|
3354
3185
|
}
|
|
3355
|
-
}
|
|
3186
|
+
});
|
|
3356
3187
|
const lineToList = normalizeToArray(path["a:lnTo"]);
|
|
3357
3188
|
lineToList.forEach((lnTo) => {
|
|
3358
3189
|
const pt = lnTo["a:pt"];
|
|
@@ -3402,6 +3233,55 @@ function normalizeToArray(value) {
|
|
|
3402
3233
|
if (!value) return [];
|
|
3403
3234
|
return Array.isArray(value) ? value : [value];
|
|
3404
3235
|
}
|
|
3236
|
+
function buildCustomShapeSegment(pathNode, w, h) {
|
|
3237
|
+
if (!pathNode || typeof pathNode !== "object") return "";
|
|
3238
|
+
const maxX = parseInt(pathNode.attrs?.w) || 0;
|
|
3239
|
+
const maxY = parseInt(pathNode.attrs?.h) || 0;
|
|
3240
|
+
const scaleX = maxX === 0 ? 0 : w / maxX;
|
|
3241
|
+
const scaleY = maxY === 0 ? 0 : h / maxY;
|
|
3242
|
+
const commands = extractPathCommands(pathNode);
|
|
3243
|
+
if (!commands.length) return "";
|
|
3244
|
+
return commands.map((command) => mapCommandToPath(command, scaleX, scaleY)).filter(Boolean).join(" ");
|
|
3245
|
+
}
|
|
3246
|
+
function mapCommandToPath(command, scaleX, scaleY) {
|
|
3247
|
+
switch (command.type) {
|
|
3248
|
+
case "moveTo": {
|
|
3249
|
+
const point = command.points?.[0];
|
|
3250
|
+
return `M${scaleValue(point?.x, scaleX)},${scaleValue(point?.y, scaleY)}`;
|
|
3251
|
+
}
|
|
3252
|
+
case "lineTo": {
|
|
3253
|
+
const point = command.points?.[0];
|
|
3254
|
+
return `L${scaleValue(point?.x, scaleX)},${scaleValue(point?.y, scaleY)}`;
|
|
3255
|
+
}
|
|
3256
|
+
case "cubicBezTo": {
|
|
3257
|
+
if (!Array.isArray(command.points) || command.points.length < 3) return "";
|
|
3258
|
+
const [p1, p2, p3] = command.points;
|
|
3259
|
+
return `C${scaleValue(p1?.x, scaleX)},${scaleValue(p1?.y, scaleY)} ${scaleValue(p2?.x, scaleX)},${scaleValue(p2?.y, scaleY)} ${scaleValue(p3?.x, scaleX)},${scaleValue(p3?.y, scaleY)}`;
|
|
3260
|
+
}
|
|
3261
|
+
case "quadBezTo": {
|
|
3262
|
+
if (!Array.isArray(command.points) || command.points.length < 2) return "";
|
|
3263
|
+
const [p1, p2] = command.points;
|
|
3264
|
+
return `Q${scaleValue(p1?.x, scaleX)},${scaleValue(p1?.y, scaleY)} ${scaleValue(p2?.x, scaleX)},${scaleValue(p2?.y, scaleY)}`;
|
|
3265
|
+
}
|
|
3266
|
+
case "arcTo": {
|
|
3267
|
+
const startAngle = (parseInt(command.stAng) || 0) / 6e4;
|
|
3268
|
+
const sweepAngle = (parseInt(command.swAng) || 0) / 6e4;
|
|
3269
|
+
const endAngle = startAngle + sweepAngle;
|
|
3270
|
+
const radiusX = scaleValue(command.wR, scaleX);
|
|
3271
|
+
const radiusY = scaleValue(command.hR, scaleY);
|
|
3272
|
+
return shapeArc(radiusX, radiusY, radiusX, radiusY, startAngle, endAngle, false).trim();
|
|
3273
|
+
}
|
|
3274
|
+
case "close":
|
|
3275
|
+
return "z";
|
|
3276
|
+
default:
|
|
3277
|
+
return "";
|
|
3278
|
+
}
|
|
3279
|
+
}
|
|
3280
|
+
function scaleValue(value, scale) {
|
|
3281
|
+
const numeric = typeof value === "number" ? value : parseFloat(String(value ?? 0));
|
|
3282
|
+
if (!Number.isFinite(numeric) || !Number.isFinite(scale)) return 0;
|
|
3283
|
+
return numeric * scale;
|
|
3284
|
+
}
|
|
3405
3285
|
function analyzePathCommands(commands, pathWidth, pathHeight) {
|
|
3406
3286
|
const analysis = {
|
|
3407
3287
|
lineCount: 0,
|
|
@@ -9340,6 +9220,7 @@ async function genDiagram(node, warpObj) {
|
|
|
9340
9220
|
|
|
9341
9221
|
// utils.ts
|
|
9342
9222
|
var PT_TO_PX = 96 / 72;
|
|
9223
|
+
var EXPORTED_OBJECT_NAME_RE = /^(shape-text|shape|text)-(\d+)-(.+)$/;
|
|
9343
9224
|
function toPx(value) {
|
|
9344
9225
|
if (value === void 0 || value === null) return void 0;
|
|
9345
9226
|
return value * PT_TO_PX;
|
|
@@ -9357,18 +9238,80 @@ function mapFillColor(value) {
|
|
|
9357
9238
|
if (!value) return void 0;
|
|
9358
9239
|
return value.startsWith("#") ? value : `#${value}`;
|
|
9359
9240
|
}
|
|
9241
|
+
function parseExportedObjectName(name) {
|
|
9242
|
+
if (!name) return void 0;
|
|
9243
|
+
const match = name.match(EXPORTED_OBJECT_NAME_RE);
|
|
9244
|
+
if (!match) return void 0;
|
|
9245
|
+
const slideIndex = Number.parseInt(match[2], 10);
|
|
9246
|
+
if (!Number.isFinite(slideIndex)) return void 0;
|
|
9247
|
+
return {
|
|
9248
|
+
kind: match[1],
|
|
9249
|
+
slideIndex,
|
|
9250
|
+
refId: match[3]
|
|
9251
|
+
};
|
|
9252
|
+
}
|
|
9253
|
+
function parseGradientPosition(value) {
|
|
9254
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
9255
|
+
return value > 100 ? value / 1e3 : value;
|
|
9256
|
+
}
|
|
9257
|
+
if (typeof value !== "string") return 0;
|
|
9258
|
+
const numeric = Number.parseFloat(value);
|
|
9259
|
+
if (!Number.isFinite(numeric)) return 0;
|
|
9260
|
+
if (value.trim().endsWith("%")) return numeric;
|
|
9261
|
+
return numeric > 100 ? numeric / 1e3 : numeric;
|
|
9262
|
+
}
|
|
9263
|
+
function mapGradient(value) {
|
|
9264
|
+
if (!value || typeof value !== "object") return void 0;
|
|
9265
|
+
const colors = Array.isArray(value.colors) ? value.colors.filter((stop) => stop && typeof stop === "object").map((stop) => ({
|
|
9266
|
+
pos: parseGradientPosition(stop.pos),
|
|
9267
|
+
color: mapFillColor(stop.color) ?? "#FFFFFF"
|
|
9268
|
+
})) : [];
|
|
9269
|
+
return {
|
|
9270
|
+
type: typeof value.type === "string" ? value.type === "line" ? "linear" : value.type : typeof value.path === "string" ? value.path === "line" ? "linear" : value.path : "linear",
|
|
9271
|
+
rotate: typeof value.rotate === "number" ? value.rotate : typeof value.rot === "number" ? value.rot : 0,
|
|
9272
|
+
colors
|
|
9273
|
+
};
|
|
9274
|
+
}
|
|
9360
9275
|
function mapFill(fill) {
|
|
9361
|
-
if (!fill) return
|
|
9362
|
-
if (typeof fill === "string")
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
|
|
9366
|
-
|
|
9367
|
-
|
|
9368
|
-
|
|
9369
|
-
|
|
9276
|
+
if (!fill) return void 0;
|
|
9277
|
+
if (typeof fill === "string") {
|
|
9278
|
+
const color = mapFillColor(fill);
|
|
9279
|
+
return color ? { type: "solid", color } : void 0;
|
|
9280
|
+
}
|
|
9281
|
+
if (typeof fill !== "object") {
|
|
9282
|
+
return void 0;
|
|
9283
|
+
}
|
|
9284
|
+
if (fill.type === "color" && typeof fill.value === "string") {
|
|
9285
|
+
const color = mapFillColor(fill.value);
|
|
9286
|
+
return color ? { type: "solid", color } : void 0;
|
|
9287
|
+
}
|
|
9288
|
+
if (fill.type === "solid" || fill.type === void 0 && typeof fill.color === "string") {
|
|
9289
|
+
const color = mapFillColor(fill.color);
|
|
9290
|
+
return color ? { type: "solid", color } : void 0;
|
|
9370
9291
|
}
|
|
9371
|
-
|
|
9292
|
+
if (fill.type === "gradient") {
|
|
9293
|
+
const gradient = mapGradient(fill.value ?? fill.gradient ?? fill);
|
|
9294
|
+
return gradient ? { type: "gradient", gradient } : void 0;
|
|
9295
|
+
}
|
|
9296
|
+
if ((fill.type === "image" || fill.type === "pattern") && fill.value?.picBase64) {
|
|
9297
|
+
return {
|
|
9298
|
+
type: "image",
|
|
9299
|
+
src: fill.value.picBase64,
|
|
9300
|
+
...typeof fill.value.opacity === "number" ? { opacity: fill.value.opacity } : {}
|
|
9301
|
+
};
|
|
9302
|
+
}
|
|
9303
|
+
if (fill.type === "image" && typeof fill.src === "string") {
|
|
9304
|
+
return {
|
|
9305
|
+
type: "image",
|
|
9306
|
+
src: fill.src,
|
|
9307
|
+
...typeof fill.opacity === "number" ? { opacity: fill.opacity } : {}
|
|
9308
|
+
};
|
|
9309
|
+
}
|
|
9310
|
+
if (fill.gradient || fill.colors) {
|
|
9311
|
+
const gradient = mapGradient(fill.gradient ?? fill);
|
|
9312
|
+
return gradient ? { type: "gradient", gradient } : void 0;
|
|
9313
|
+
}
|
|
9314
|
+
return void 0;
|
|
9372
9315
|
}
|
|
9373
9316
|
function convertFontSizeToPx(content) {
|
|
9374
9317
|
return content.replace(/font-size:\s*([0-9.]+)pt/gi, (_, size) => {
|
|
@@ -9493,14 +9436,16 @@ function mapKeypoints(pathFormula, raw) {
|
|
|
9493
9436
|
// element-mapper.ts
|
|
9494
9437
|
function mapElement(raw) {
|
|
9495
9438
|
if (!raw || !raw.type) return null;
|
|
9496
|
-
const
|
|
9497
|
-
|
|
9439
|
+
const exportedMeta = parseExportedObjectName(raw.name);
|
|
9440
|
+
const base = mapBaseElement(raw, exportedMeta);
|
|
9441
|
+
if (raw.type === "text" || isExportedTextShape(raw, exportedMeta)) {
|
|
9498
9442
|
const content = raw.content !== void 0 ? normalizeTextContent(raw.content) : raw.content;
|
|
9499
9443
|
const fallbackLineHeight = hasMultiLineText(content) ? 1.5 : 1;
|
|
9500
9444
|
const lineHeight = raw.lineHeight ?? fallbackLineHeight;
|
|
9501
9445
|
const normalizedHeight = normalizeTextHeight(base.height, content, lineHeight);
|
|
9502
9446
|
return {
|
|
9503
9447
|
...base,
|
|
9448
|
+
type: "text",
|
|
9504
9449
|
height: normalizedHeight,
|
|
9505
9450
|
rotate: base.rotate ?? 0,
|
|
9506
9451
|
flipH: void 0,
|
|
@@ -9512,7 +9457,7 @@ function mapElement(raw) {
|
|
|
9512
9457
|
lineHeight,
|
|
9513
9458
|
paragraphSpace: raw.paragraphSpace,
|
|
9514
9459
|
vertical: raw.isVertical,
|
|
9515
|
-
fill: mapFill(raw.fill)
|
|
9460
|
+
fill: mapFill(raw.fill)
|
|
9516
9461
|
};
|
|
9517
9462
|
}
|
|
9518
9463
|
if (raw.type === "image") {
|
|
@@ -9537,10 +9482,11 @@ function mapElement(raw) {
|
|
|
9537
9482
|
};
|
|
9538
9483
|
}
|
|
9539
9484
|
if (raw.type === "shape") {
|
|
9540
|
-
const
|
|
9485
|
+
const fill = mapFill(raw.fill) ?? { type: "solid", color: "rgba(255,255,255,0)" };
|
|
9541
9486
|
const pathFormula = mapPathFormula(raw.shapType);
|
|
9542
9487
|
const keypoints = pathFormula ? mapKeypoints(pathFormula, raw.keypoints) : void 0;
|
|
9543
|
-
const
|
|
9488
|
+
const normalizedShapeText = raw.content !== void 0 ? normalizeTextContent(raw.content) : void 0;
|
|
9489
|
+
const hasText = hasRenderableText(normalizedShapeText);
|
|
9544
9490
|
let path = raw.path;
|
|
9545
9491
|
let viewBox = raw.viewBox ?? [raw.width ?? 0, raw.height ?? 0];
|
|
9546
9492
|
let special = false;
|
|
@@ -9579,17 +9525,17 @@ function mapElement(raw) {
|
|
|
9579
9525
|
}
|
|
9580
9526
|
return {
|
|
9581
9527
|
...base,
|
|
9528
|
+
type: "shape",
|
|
9582
9529
|
rotate: base.rotate ?? 0,
|
|
9583
9530
|
fixedRatio: false,
|
|
9584
9531
|
path,
|
|
9585
9532
|
viewBox,
|
|
9586
9533
|
pathFormula: pathFormula ?? void 0,
|
|
9587
9534
|
keypoints: keypoints ?? void 0,
|
|
9588
|
-
|
|
9589
|
-
fill: fill ?? "",
|
|
9535
|
+
fill,
|
|
9590
9536
|
...special ? { special: true } : {},
|
|
9591
9537
|
text: hasText ? {
|
|
9592
|
-
content:
|
|
9538
|
+
content: normalizedShapeText,
|
|
9593
9539
|
align: normalizeVAlign(raw.vAlign) ?? "middle",
|
|
9594
9540
|
defaultColor: normalizeColor(raw.defaultColor) ?? normalizeColor(raw.color) ?? "#333",
|
|
9595
9541
|
defaultFontName: raw.fontName ?? "",
|
|
@@ -9600,6 +9546,7 @@ function mapElement(raw) {
|
|
|
9600
9546
|
if (raw.type === "line") {
|
|
9601
9547
|
return {
|
|
9602
9548
|
...base,
|
|
9549
|
+
type: "line",
|
|
9603
9550
|
start: toPxPair(raw.start),
|
|
9604
9551
|
end: toPxPair(raw.end),
|
|
9605
9552
|
broken: toPxPair(raw.broken),
|
|
@@ -9636,9 +9583,6 @@ function normalizeElement(element) {
|
|
|
9636
9583
|
points: ["", ""]
|
|
9637
9584
|
};
|
|
9638
9585
|
}
|
|
9639
|
-
if (element.type === "shape" && element.fill) {
|
|
9640
|
-
element.fill = mapFillColor(element.fill) ?? element.fill;
|
|
9641
|
-
}
|
|
9642
9586
|
if (element.type === "text" && element.content) {
|
|
9643
9587
|
element.content = normalizeTextContent(element.content);
|
|
9644
9588
|
}
|
|
@@ -9689,20 +9633,21 @@ function mapOutline(raw) {
|
|
|
9689
9633
|
style: raw.borderType
|
|
9690
9634
|
};
|
|
9691
9635
|
}
|
|
9692
|
-
function mapBaseElement(raw) {
|
|
9636
|
+
function mapBaseElement(raw, exportedMeta) {
|
|
9693
9637
|
const outline = mapOutline(raw);
|
|
9694
9638
|
const shadow = mapShadow(raw.shadow);
|
|
9695
|
-
const
|
|
9639
|
+
const fill = mapFill(raw.fill);
|
|
9640
|
+
const exportedId = exportedMeta?.kind === "shape-text" ? `${exportedMeta.refId}__text` : exportedMeta?.refId;
|
|
9696
9641
|
return {
|
|
9697
9642
|
type: raw.type,
|
|
9698
|
-
id: raw.id,
|
|
9643
|
+
id: exportedId ?? raw.id,
|
|
9699
9644
|
groupId: raw.groupId,
|
|
9700
9645
|
left: toPx(raw.left),
|
|
9701
9646
|
top: toPx(raw.top),
|
|
9702
9647
|
width: toPx(raw.width),
|
|
9703
9648
|
height: toPx(raw.height),
|
|
9704
9649
|
rotate: raw.rotate,
|
|
9705
|
-
fill
|
|
9650
|
+
fill,
|
|
9706
9651
|
opacity: raw.opacity,
|
|
9707
9652
|
outline: outline ?? void 0,
|
|
9708
9653
|
shadow: shadow ?? void 0,
|
|
@@ -9710,6 +9655,15 @@ function mapBaseElement(raw) {
|
|
|
9710
9655
|
flipV: raw.isFlipV
|
|
9711
9656
|
};
|
|
9712
9657
|
}
|
|
9658
|
+
function isExportedTextShape(raw, exportedMeta) {
|
|
9659
|
+
if (raw?.type !== "shape" || !raw?.content) return false;
|
|
9660
|
+
return exportedMeta?.kind === "text" || exportedMeta?.kind === "shape-text";
|
|
9661
|
+
}
|
|
9662
|
+
function hasRenderableText(content) {
|
|
9663
|
+
if (!content) return false;
|
|
9664
|
+
const plainText = content.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim();
|
|
9665
|
+
return plainText.length > 0;
|
|
9666
|
+
}
|
|
9713
9667
|
|
|
9714
9668
|
// slide-normalizer.ts
|
|
9715
9669
|
var ID_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
|
|
@@ -9724,7 +9678,8 @@ function normalizeSlide(slide, index) {
|
|
|
9724
9678
|
const orderB = typeof b?.order === "number" ? b.order : 0;
|
|
9725
9679
|
return orderA - orderB;
|
|
9726
9680
|
});
|
|
9727
|
-
const
|
|
9681
|
+
const restoredElements = restoreExportedRoundTripElements(orderedElements);
|
|
9682
|
+
const elements = flattenElements(restoredElements).map((element, elementIndex) => {
|
|
9728
9683
|
if (!element.id) {
|
|
9729
9684
|
element.id = makeId(`slide-${index}-element-${elementIndex}-${element.type}`);
|
|
9730
9685
|
}
|
|
@@ -9732,7 +9687,7 @@ function normalizeSlide(slide, index) {
|
|
|
9732
9687
|
});
|
|
9733
9688
|
return {
|
|
9734
9689
|
id: slide?.id ?? slide?.slideId ?? makeId(`slide-${index}`),
|
|
9735
|
-
background: backgroundFill
|
|
9690
|
+
background: backgroundFill,
|
|
9736
9691
|
elements,
|
|
9737
9692
|
remark: slide?.remark ?? ""
|
|
9738
9693
|
};
|
|
@@ -9749,6 +9704,44 @@ function makeId(seed) {
|
|
|
9749
9704
|
}
|
|
9750
9705
|
return id;
|
|
9751
9706
|
}
|
|
9707
|
+
function restoreExportedRoundTripElements(elements) {
|
|
9708
|
+
const restored = elements.map((element) => {
|
|
9709
|
+
if (element?.type === "group" && Array.isArray(element.elements)) {
|
|
9710
|
+
return {
|
|
9711
|
+
...element,
|
|
9712
|
+
elements: restoreExportedRoundTripElements(element.elements)
|
|
9713
|
+
};
|
|
9714
|
+
}
|
|
9715
|
+
return element;
|
|
9716
|
+
});
|
|
9717
|
+
const shapesByRefId = /* @__PURE__ */ new Map();
|
|
9718
|
+
for (const element of restored) {
|
|
9719
|
+
const meta = parseExportedObjectName(element?.name);
|
|
9720
|
+
if (meta?.kind === "shape") {
|
|
9721
|
+
shapesByRefId.set(meta.refId, element);
|
|
9722
|
+
}
|
|
9723
|
+
}
|
|
9724
|
+
return restored.filter((element) => {
|
|
9725
|
+
const meta = parseExportedObjectName(element?.name);
|
|
9726
|
+
if (meta?.kind !== "shape-text") {
|
|
9727
|
+
return true;
|
|
9728
|
+
}
|
|
9729
|
+
const targetShape = shapesByRefId.get(meta.refId);
|
|
9730
|
+
if (!targetShape || targetShape.type !== "shape") {
|
|
9731
|
+
return true;
|
|
9732
|
+
}
|
|
9733
|
+
mergeShapeText(targetShape, element);
|
|
9734
|
+
return false;
|
|
9735
|
+
});
|
|
9736
|
+
}
|
|
9737
|
+
function mergeShapeText(targetShape, textShape) {
|
|
9738
|
+
if (!targetShape.content && textShape?.content) {
|
|
9739
|
+
targetShape.content = textShape.content;
|
|
9740
|
+
}
|
|
9741
|
+
if (textShape?.vAlign) {
|
|
9742
|
+
targetShape.vAlign = textShape.vAlign;
|
|
9743
|
+
}
|
|
9744
|
+
}
|
|
9752
9745
|
function hashSeed(value) {
|
|
9753
9746
|
let hash = 1779033703 ^ value.length;
|
|
9754
9747
|
for (let index = 0; index < value.length; index += 1) {
|
|
@@ -9782,49 +9775,14 @@ var DEFAULT_THEME = {
|
|
|
9782
9775
|
};
|
|
9783
9776
|
async function parsePptxToJson(file) {
|
|
9784
9777
|
const fileBuffer = await file.arrayBuffer();
|
|
9785
|
-
const zip = await import_jszip2.default.loadAsync(fileBuffer);
|
|
9786
|
-
const embedded = import_json2pptx.ENABLE_DECK_JSON ? await resolveEmbeddedDeck(zip) : null;
|
|
9787
|
-
if (embedded?.deck) {
|
|
9788
|
-
return {
|
|
9789
|
-
deck: embedded.deck,
|
|
9790
|
-
warnings: embedded.warnings
|
|
9791
|
-
};
|
|
9792
|
-
}
|
|
9793
9778
|
return {
|
|
9794
9779
|
deck: await buildDeckFromPptx(fileBuffer),
|
|
9795
|
-
warnings:
|
|
9780
|
+
warnings: []
|
|
9796
9781
|
};
|
|
9797
9782
|
}
|
|
9798
|
-
|
|
9799
|
-
const
|
|
9800
|
-
|
|
9801
|
-
) ?? null;
|
|
9802
|
-
if (!embeddedFile) {
|
|
9803
|
-
return null;
|
|
9804
|
-
}
|
|
9805
|
-
const payloadText = await embeddedFile.async("string");
|
|
9806
|
-
try {
|
|
9807
|
-
const parsed = JSON.parse(payloadText);
|
|
9808
|
-
if (isDeckEnvelope(parsed) && parsed.deck) {
|
|
9809
|
-
return {
|
|
9810
|
-
deck: parsed.deck,
|
|
9811
|
-
warnings: parsed.version && parsed.version !== import_json2pptx.PPTX_JSON_PAYLOAD_VERSION ? [
|
|
9812
|
-
`Embedded JSON payload version ${parsed.version} differs from ${import_json2pptx.PPTX_JSON_PAYLOAD_VERSION}.`
|
|
9813
|
-
] : []
|
|
9814
|
-
};
|
|
9815
|
-
}
|
|
9816
|
-
return {
|
|
9817
|
-
deck: parsed,
|
|
9818
|
-
warnings: []
|
|
9819
|
-
};
|
|
9820
|
-
} catch {
|
|
9821
|
-
return {
|
|
9822
|
-
warnings: ["Embedded JSON payload could not be parsed. Falling back to PPTX parsing."]
|
|
9823
|
-
};
|
|
9824
|
-
}
|
|
9825
|
-
}
|
|
9826
|
-
function isDeckEnvelope(payload) {
|
|
9827
|
-
return typeof payload === "object" && payload !== null && "deck" in payload;
|
|
9783
|
+
function normalizeDeck(value) {
|
|
9784
|
+
const document = (0, import_json2pptx_schema.parseDocument)(value);
|
|
9785
|
+
return document;
|
|
9828
9786
|
}
|
|
9829
9787
|
async function buildDeckFromPptx(buffer) {
|
|
9830
9788
|
const pptxJson = await parse2(buffer);
|
|
@@ -9834,7 +9792,7 @@ async function buildDeckFromPptx(buffer) {
|
|
|
9834
9792
|
const slides = (Array.isArray(pptxJson.slides) ? pptxJson.slides : []).map(
|
|
9835
9793
|
(slide, index) => normalizeSlide(slide, index)
|
|
9836
9794
|
);
|
|
9837
|
-
return {
|
|
9795
|
+
return normalizeDeck({
|
|
9838
9796
|
title: DEFAULT_DECK_TITLE,
|
|
9839
9797
|
width,
|
|
9840
9798
|
height,
|
|
@@ -9843,7 +9801,7 @@ async function buildDeckFromPptx(buffer) {
|
|
|
9843
9801
|
themeColors
|
|
9844
9802
|
},
|
|
9845
9803
|
slides
|
|
9846
|
-
};
|
|
9804
|
+
});
|
|
9847
9805
|
}
|
|
9848
9806
|
function mapThemeColors(pptxJson) {
|
|
9849
9807
|
if (!Array.isArray(pptxJson.themeColors)) {
|