docgen-utils 1.0.14 → 1.0.15
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/bundle.js +948 -37
- package/dist/bundle.min.js +96 -91
- package/dist/cli.js +912 -66
- package/dist/packages/cli/commands/common.d.ts +2 -0
- package/dist/packages/cli/commands/common.d.ts.map +1 -0
- package/dist/packages/cli/commands/common.js +22 -0
- package/dist/packages/cli/commands/common.js.map +1 -0
- package/dist/packages/cli/commands/export-docs.d.ts.map +1 -1
- package/dist/packages/cli/commands/export-docs.js +2 -6
- package/dist/packages/cli/commands/export-docs.js.map +1 -1
- package/dist/packages/cli/commands/export-slides.d.ts.map +1 -1
- package/dist/packages/cli/commands/export-slides.js +1 -25
- package/dist/packages/cli/commands/export-slides.js.map +1 -1
- package/dist/packages/slides/import-pptx.d.ts.map +1 -1
- package/dist/packages/slides/import-pptx.js +1180 -47
- package/dist/packages/slides/import-pptx.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -69594,28 +69594,62 @@ function hexToRgba(hex, alpha100k) {
|
|
|
69594
69594
|
const a = Math.round(alpha100k / 1e5 * 100) / 100;
|
|
69595
69595
|
return `rgba(${r},${g},${b},${a})`;
|
|
69596
69596
|
}
|
|
69597
|
+
function applyTint(hex, tintVal) {
|
|
69598
|
+
const factor = tintVal / 1e5;
|
|
69599
|
+
const r = parseInt(hex.slice(1, 3), 16);
|
|
69600
|
+
const g = parseInt(hex.slice(3, 5), 16);
|
|
69601
|
+
const b = parseInt(hex.slice(5, 7), 16);
|
|
69602
|
+
const nr = Math.round(r + (255 - r) * (1 - factor));
|
|
69603
|
+
const ng = Math.round(g + (255 - g) * (1 - factor));
|
|
69604
|
+
const nb = Math.round(b + (255 - b) * (1 - factor));
|
|
69605
|
+
return `#${nr.toString(16).padStart(2, "0")}${ng.toString(16).padStart(2, "0")}${nb.toString(16).padStart(2, "0")}`;
|
|
69606
|
+
}
|
|
69607
|
+
function applyShade(hex, shadeVal) {
|
|
69608
|
+
const factor = shadeVal / 1e5;
|
|
69609
|
+
const r = Math.round(parseInt(hex.slice(1, 3), 16) * factor);
|
|
69610
|
+
const g = Math.round(parseInt(hex.slice(3, 5), 16) * factor);
|
|
69611
|
+
const b = Math.round(parseInt(hex.slice(5, 7), 16) * factor);
|
|
69612
|
+
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
69613
|
+
}
|
|
69614
|
+
function applyColorModifiers(colorEl, hex) {
|
|
69615
|
+
let color = hex;
|
|
69616
|
+
let alphaVal;
|
|
69617
|
+
const tintEl = findChild2(colorEl, "tint");
|
|
69618
|
+
if (tintEl) {
|
|
69619
|
+
const val = parseInt(tintEl.getAttribute("val") ?? "100000", 10);
|
|
69620
|
+
color = applyTint(color, val);
|
|
69621
|
+
}
|
|
69622
|
+
const shadeEl = findChild2(colorEl, "shade");
|
|
69623
|
+
if (shadeEl) {
|
|
69624
|
+
const val = parseInt(shadeEl.getAttribute("val") ?? "100000", 10);
|
|
69625
|
+
color = applyShade(color, val);
|
|
69626
|
+
}
|
|
69627
|
+
const alphaEl = findChild2(colorEl, "alpha");
|
|
69628
|
+
if (alphaEl) {
|
|
69629
|
+
alphaVal = parseInt(alphaEl.getAttribute("val") ?? "100000", 10);
|
|
69630
|
+
}
|
|
69631
|
+
return { color, alpha: alphaVal };
|
|
69632
|
+
}
|
|
69597
69633
|
function resolveColor2(parent, themeColors) {
|
|
69598
69634
|
const srgbClr = findChild2(parent, "srgbClr");
|
|
69599
69635
|
if (srgbClr) {
|
|
69600
69636
|
const hex = "#" + (srgbClr.getAttribute("val") ?? "000000");
|
|
69601
|
-
const
|
|
69602
|
-
if (
|
|
69603
|
-
|
|
69604
|
-
return hexToRgba(hex, alphaVal);
|
|
69637
|
+
const { color, alpha } = applyColorModifiers(srgbClr, hex);
|
|
69638
|
+
if (alpha !== void 0 && alpha < 1e5) {
|
|
69639
|
+
return hexToRgba(color, alpha);
|
|
69605
69640
|
}
|
|
69606
|
-
return
|
|
69641
|
+
return color;
|
|
69607
69642
|
}
|
|
69608
69643
|
const schemeClr = findChild2(parent, "schemeClr");
|
|
69609
69644
|
if (schemeClr) {
|
|
69610
69645
|
const val = schemeClr.getAttribute("val");
|
|
69611
69646
|
if (val && themeColors.has(val)) {
|
|
69612
69647
|
const hex = themeColors.get(val);
|
|
69613
|
-
const
|
|
69614
|
-
if (
|
|
69615
|
-
|
|
69616
|
-
return hexToRgba(hex, alphaVal);
|
|
69648
|
+
const { color, alpha } = applyColorModifiers(schemeClr, hex);
|
|
69649
|
+
if (alpha !== void 0 && alpha < 1e5) {
|
|
69650
|
+
return hexToRgba(color, alpha);
|
|
69617
69651
|
}
|
|
69618
|
-
return
|
|
69652
|
+
return color;
|
|
69619
69653
|
}
|
|
69620
69654
|
}
|
|
69621
69655
|
return void 0;
|
|
@@ -69661,6 +69695,144 @@ function extractFill(spPr, themeColors) {
|
|
|
69661
69695
|
if (solidFill) return resolveColor2(solidFill, themeColors);
|
|
69662
69696
|
return extractGradientFill(spPr, themeColors);
|
|
69663
69697
|
}
|
|
69698
|
+
function resolveBgRef(bgRef, bgFillStyles, themeColors) {
|
|
69699
|
+
const idx = parseInt(bgRef.getAttribute("idx") ?? "0", 10);
|
|
69700
|
+
if (idx < 1001 || bgFillStyles.length === 0) return void 0;
|
|
69701
|
+
const styleIdx = idx - 1001;
|
|
69702
|
+
if (styleIdx >= bgFillStyles.length) return void 0;
|
|
69703
|
+
const fillStyle = bgFillStyles[styleIdx];
|
|
69704
|
+
const phColor = resolveColor2(bgRef, themeColors);
|
|
69705
|
+
if (fillStyle.localName === "solidFill") {
|
|
69706
|
+
const phClr = findChild2(fillStyle, "schemeClr");
|
|
69707
|
+
if (phClr?.getAttribute("val") === "phClr" && phColor) {
|
|
69708
|
+
return phColor;
|
|
69709
|
+
}
|
|
69710
|
+
return resolveColor2(fillStyle, themeColors) ?? phColor;
|
|
69711
|
+
}
|
|
69712
|
+
if (fillStyle.localName === "gradFill") {
|
|
69713
|
+
return extractGradientFill(
|
|
69714
|
+
// Wrap in a parent element for extractGradientFill
|
|
69715
|
+
{ children: [fillStyle] },
|
|
69716
|
+
themeColors
|
|
69717
|
+
);
|
|
69718
|
+
}
|
|
69719
|
+
return phColor;
|
|
69720
|
+
}
|
|
69721
|
+
function extractBgFill(bgEl, bgFillStyles, themeColors) {
|
|
69722
|
+
const bgPr = findChild2(bgEl, "bgPr");
|
|
69723
|
+
if (bgPr) {
|
|
69724
|
+
return extractFill(bgPr, themeColors);
|
|
69725
|
+
}
|
|
69726
|
+
const bgRef = findChild2(bgEl, "bgRef");
|
|
69727
|
+
if (bgRef) {
|
|
69728
|
+
return resolveBgRef(bgRef, bgFillStyles, themeColors);
|
|
69729
|
+
}
|
|
69730
|
+
return void 0;
|
|
69731
|
+
}
|
|
69732
|
+
function extractCustGeomClipPath(custGeom) {
|
|
69733
|
+
const pathLst = findChild2(custGeom, "pathLst");
|
|
69734
|
+
if (!pathLst) return void 0;
|
|
69735
|
+
const pathEl = findChild2(pathLst, "path");
|
|
69736
|
+
if (!pathEl) return void 0;
|
|
69737
|
+
const pathW = parseInt(pathEl.getAttribute("w") ?? "0", 10);
|
|
69738
|
+
const pathH = parseInt(pathEl.getAttribute("h") ?? "0", 10);
|
|
69739
|
+
if (pathW <= 0 || pathH <= 0) return void 0;
|
|
69740
|
+
const points = [];
|
|
69741
|
+
for (let i = 0; i < pathEl.children.length; i++) {
|
|
69742
|
+
const cmd = pathEl.children[i];
|
|
69743
|
+
const localName = cmd.localName;
|
|
69744
|
+
if (localName === "moveTo" || localName === "lnTo") {
|
|
69745
|
+
const pt = findChild2(cmd, "pt");
|
|
69746
|
+
if (pt) {
|
|
69747
|
+
const x = parseInt(pt.getAttribute("x") ?? "0", 10);
|
|
69748
|
+
const y = parseInt(pt.getAttribute("y") ?? "0", 10);
|
|
69749
|
+
points.push({ x, y });
|
|
69750
|
+
}
|
|
69751
|
+
} else if (localName === "close") {
|
|
69752
|
+
} else {
|
|
69753
|
+
return void 0;
|
|
69754
|
+
}
|
|
69755
|
+
}
|
|
69756
|
+
if (points.length < 3) return void 0;
|
|
69757
|
+
const polygonPoints = points.map((p) => {
|
|
69758
|
+
const xPct = Math.round(p.x / pathW * 1e4) / 100;
|
|
69759
|
+
const yPct = Math.round(p.y / pathH * 1e4) / 100;
|
|
69760
|
+
return `${xPct}% ${yPct}%`;
|
|
69761
|
+
}).join(", ");
|
|
69762
|
+
return `polygon(${polygonPoints})`;
|
|
69763
|
+
}
|
|
69764
|
+
function parseDecorativeShapes(spTree, scale, themeColors, imageMap, themeFonts) {
|
|
69765
|
+
const elements = [];
|
|
69766
|
+
for (let i = 0; i < spTree.children.length; i++) {
|
|
69767
|
+
const child = spTree.children[i];
|
|
69768
|
+
if (child.localName === "sp") {
|
|
69769
|
+
const nvSpPr = findChild2(child, "nvSpPr");
|
|
69770
|
+
if (nvSpPr) {
|
|
69771
|
+
const phEl = findChild2(findChild2(nvSpPr, "nvPr") ?? nvSpPr, "ph");
|
|
69772
|
+
if (phEl) continue;
|
|
69773
|
+
}
|
|
69774
|
+
const spPr = findChild2(child, "spPr");
|
|
69775
|
+
if (spPr) {
|
|
69776
|
+
const custGeom = findChild2(spPr, "custGeom");
|
|
69777
|
+
if (custGeom) {
|
|
69778
|
+
const clipPath = extractCustGeomClipPath(custGeom);
|
|
69779
|
+
if (!clipPath) continue;
|
|
69780
|
+
const shape2 = parseShape(child, scale, themeColors, themeFonts);
|
|
69781
|
+
if (shape2) {
|
|
69782
|
+
shape2.clipPath = clipPath;
|
|
69783
|
+
elements.push({ kind: "shape", data: shape2 });
|
|
69784
|
+
}
|
|
69785
|
+
continue;
|
|
69786
|
+
}
|
|
69787
|
+
}
|
|
69788
|
+
const shape = parseShape(child, scale, themeColors, themeFonts);
|
|
69789
|
+
if (shape) elements.push({ kind: "shape", data: shape });
|
|
69790
|
+
} else if (child.localName === "pic") {
|
|
69791
|
+
const img = parsePicture(child, scale, imageMap);
|
|
69792
|
+
if (img) elements.push({ kind: "image", data: img });
|
|
69793
|
+
} else if (child.localName === "grpSp") {
|
|
69794
|
+
const grpElements = parseGroupShape(child, scale, themeColors, imageMap, themeFonts);
|
|
69795
|
+
elements.push(...grpElements);
|
|
69796
|
+
}
|
|
69797
|
+
}
|
|
69798
|
+
return elements;
|
|
69799
|
+
}
|
|
69800
|
+
function parseGroupShape(grpSp, scale, themeColors, imageMap, themeFonts) {
|
|
69801
|
+
const elements = [];
|
|
69802
|
+
for (let i = 0; i < grpSp.children.length; i++) {
|
|
69803
|
+
const child = grpSp.children[i];
|
|
69804
|
+
if (child.localName === "sp") {
|
|
69805
|
+
const nvSpPr = findChild2(child, "nvSpPr");
|
|
69806
|
+
if (nvSpPr) {
|
|
69807
|
+
const phEl = findChild2(findChild2(nvSpPr, "nvPr") ?? nvSpPr, "ph");
|
|
69808
|
+
if (phEl) continue;
|
|
69809
|
+
}
|
|
69810
|
+
const spPr = findChild2(child, "spPr");
|
|
69811
|
+
if (spPr) {
|
|
69812
|
+
const custGeom = findChild2(spPr, "custGeom");
|
|
69813
|
+
if (custGeom) {
|
|
69814
|
+
const clipPath = extractCustGeomClipPath(custGeom);
|
|
69815
|
+
if (!clipPath) continue;
|
|
69816
|
+
const shape2 = parseShape(child, scale, themeColors, themeFonts);
|
|
69817
|
+
if (shape2) {
|
|
69818
|
+
shape2.clipPath = clipPath;
|
|
69819
|
+
elements.push({ kind: "shape", data: shape2 });
|
|
69820
|
+
}
|
|
69821
|
+
continue;
|
|
69822
|
+
}
|
|
69823
|
+
}
|
|
69824
|
+
const shape = parseShape(child, scale, themeColors, themeFonts);
|
|
69825
|
+
if (shape) elements.push({ kind: "shape", data: shape });
|
|
69826
|
+
} else if (child.localName === "pic") {
|
|
69827
|
+
const img = parsePicture(child, scale, imageMap);
|
|
69828
|
+
if (img) elements.push({ kind: "image", data: img });
|
|
69829
|
+
} else if (child.localName === "grpSp") {
|
|
69830
|
+
const nested = parseGroupShape(child, scale, themeColors, imageMap, themeFonts);
|
|
69831
|
+
elements.push(...nested);
|
|
69832
|
+
}
|
|
69833
|
+
}
|
|
69834
|
+
return elements;
|
|
69835
|
+
}
|
|
69664
69836
|
function extractRunProps(rPr, scale, themeColors, themeFonts) {
|
|
69665
69837
|
if (!rPr) return {};
|
|
69666
69838
|
const result = {};
|
|
@@ -69670,6 +69842,8 @@ function extractRunProps(rPr, scale, themeColors, themeFonts) {
|
|
|
69670
69842
|
if (b === "1" || b === "true") result.bold = true;
|
|
69671
69843
|
const i = rPr.getAttribute("i");
|
|
69672
69844
|
if (i === "1" || i === "true") result.italic = true;
|
|
69845
|
+
const u = rPr.getAttribute("u");
|
|
69846
|
+
if (u && u !== "none") result.underline = true;
|
|
69673
69847
|
const solidFill = findChild2(rPr, "solidFill");
|
|
69674
69848
|
if (solidFill) {
|
|
69675
69849
|
const color = resolveColor2(solidFill, themeColors);
|
|
@@ -69764,14 +69938,32 @@ function parseShape(sp, scale, themeColors, themeFonts) {
|
|
|
69764
69938
|
if (!off || !ext) return null;
|
|
69765
69939
|
const wEmu = parseInt(ext.getAttribute("cx") ?? "0", 10);
|
|
69766
69940
|
const hEmu = parseInt(ext.getAttribute("cy") ?? "0", 10);
|
|
69941
|
+
let fill = extractFill(spPr, themeColors);
|
|
69942
|
+
if (!fill && !findChild2(spPr, "noFill")) {
|
|
69943
|
+
const styleEl = findChild2(sp, "style");
|
|
69944
|
+
if (styleEl) {
|
|
69945
|
+
const fillRef = findChild2(styleEl, "fillRef");
|
|
69946
|
+
if (fillRef) {
|
|
69947
|
+
const fillIdx = parseInt(fillRef.getAttribute("idx") ?? "0", 10);
|
|
69948
|
+
if (fillIdx > 0) {
|
|
69949
|
+
fill = resolveColor2(fillRef, themeColors) ?? void 0;
|
|
69950
|
+
}
|
|
69951
|
+
}
|
|
69952
|
+
}
|
|
69953
|
+
}
|
|
69767
69954
|
const shape = {
|
|
69768
69955
|
x: Math.round(emuToPx2(parseInt(off.getAttribute("x") ?? "0", 10)) * scale),
|
|
69769
69956
|
y: Math.round(emuToPx2(parseInt(off.getAttribute("y") ?? "0", 10)) * scale),
|
|
69770
69957
|
w: Math.round(emuToPx2(wEmu) * scale),
|
|
69771
69958
|
h: Math.round(emuToPx2(hEmu) * scale),
|
|
69772
|
-
fill
|
|
69959
|
+
fill,
|
|
69773
69960
|
paragraphs: []
|
|
69774
69961
|
};
|
|
69962
|
+
const rotAttr = xfrm.getAttribute("rot");
|
|
69963
|
+
if (rotAttr) {
|
|
69964
|
+
const rotDeg = parseInt(rotAttr, 10) / 6e4;
|
|
69965
|
+
if (rotDeg !== 0) shape.rotation = rotDeg;
|
|
69966
|
+
}
|
|
69775
69967
|
const prstGeom = findChild2(spPr, "prstGeom");
|
|
69776
69968
|
const prstType = prstGeom?.getAttribute("prst");
|
|
69777
69969
|
if (prstType === "roundRect" && prstGeom) {
|
|
@@ -69783,6 +69975,10 @@ function parseShape(sp, scale, themeColors, themeFonts) {
|
|
|
69783
69975
|
shape.borderRadius = Math.round(emuToPx2(radiusEmu) * scale);
|
|
69784
69976
|
} else if (prstType === "ellipse") {
|
|
69785
69977
|
shape.isEllipse = true;
|
|
69978
|
+
} else if (prstType === "rtTriangle") {
|
|
69979
|
+
shape.clipPath = "polygon(0 0, 0 100%, 100% 100%)";
|
|
69980
|
+
} else if (prstType === "triangle" || prstType === "isoTriangle") {
|
|
69981
|
+
shape.clipPath = "polygon(50% 0, 0 100%, 100% 100%)";
|
|
69786
69982
|
}
|
|
69787
69983
|
const ln = findChild2(spPr, "ln");
|
|
69788
69984
|
if (ln) {
|
|
@@ -69878,6 +70074,10 @@ function parseShape(sp, scale, themeColors, themeFonts) {
|
|
|
69878
70074
|
if (buChar) {
|
|
69879
70075
|
para.bulletChar = buChar.getAttribute("char") ?? void 0;
|
|
69880
70076
|
}
|
|
70077
|
+
const buFont = findChild2(pPr, "buFont");
|
|
70078
|
+
if (buFont) {
|
|
70079
|
+
para.bulletFont = buFont.getAttribute("typeface") ?? void 0;
|
|
70080
|
+
}
|
|
69881
70081
|
const buClr = findChild2(pPr, "buClr");
|
|
69882
70082
|
if (buClr) {
|
|
69883
70083
|
para.bulletColor = resolveColor2(buClr, themeColors);
|
|
@@ -69897,6 +70097,7 @@ function parseShape(sp, scale, themeColors, themeFonts) {
|
|
|
69897
70097
|
text,
|
|
69898
70098
|
bold: props.bold ?? defaults?.bold,
|
|
69899
70099
|
italic: props.italic ?? defaults?.italic,
|
|
70100
|
+
underline: props.underline ?? defaults?.underline,
|
|
69900
70101
|
fontSize: props.fontSize ?? defaults?.fontSize,
|
|
69901
70102
|
color: props.color ?? defaults?.color,
|
|
69902
70103
|
fontFamily: props.fontFamily ?? defaults?.fontFamily,
|
|
@@ -69965,12 +70166,16 @@ function parsePicture(pic, scale, imageMap) {
|
|
|
69965
70166
|
const alt = cNvPr?.getAttribute("descr") ?? void 0;
|
|
69966
70167
|
const srcRect = findChild2(blipFill, "srcRect");
|
|
69967
70168
|
let hasCrop = false;
|
|
70169
|
+
let cropLeft = 0;
|
|
70170
|
+
let cropTop = 0;
|
|
70171
|
+
let cropRight = 0;
|
|
70172
|
+
let cropBottom = 0;
|
|
69968
70173
|
if (srcRect) {
|
|
69969
|
-
|
|
69970
|
-
|
|
69971
|
-
|
|
69972
|
-
|
|
69973
|
-
hasCrop =
|
|
70174
|
+
cropLeft = parseInt(srcRect.getAttribute("l") ?? "0", 10) / 1e3;
|
|
70175
|
+
cropRight = parseInt(srcRect.getAttribute("r") ?? "0", 10) / 1e3;
|
|
70176
|
+
cropTop = parseInt(srcRect.getAttribute("t") ?? "0", 10) / 1e3;
|
|
70177
|
+
cropBottom = parseInt(srcRect.getAttribute("b") ?? "0", 10) / 1e3;
|
|
70178
|
+
hasCrop = cropLeft > 0 || cropRight > 0 || cropTop > 0 || cropBottom > 0;
|
|
69974
70179
|
}
|
|
69975
70180
|
let borderRadius;
|
|
69976
70181
|
const prstGeom = findChild2(spPr, "prstGeom");
|
|
@@ -69984,6 +70189,12 @@ function parsePicture(pic, scale, imageMap) {
|
|
|
69984
70189
|
const radiusEmu = minDim * Math.min(adjVal, 5e4) / 1e5;
|
|
69985
70190
|
borderRadius = Math.round(emuToPx2(radiusEmu) * scale);
|
|
69986
70191
|
}
|
|
70192
|
+
let rotation;
|
|
70193
|
+
const rotAttr = xfrm.getAttribute("rot");
|
|
70194
|
+
if (rotAttr) {
|
|
70195
|
+
const rotDeg = parseInt(rotAttr, 10) / 6e4;
|
|
70196
|
+
if (rotDeg !== 0) rotation = rotDeg;
|
|
70197
|
+
}
|
|
69987
70198
|
return {
|
|
69988
70199
|
x: Math.round(emuToPx2(parseInt(off.getAttribute("x") ?? "0", 10)) * scale),
|
|
69989
70200
|
y: Math.round(emuToPx2(parseInt(off.getAttribute("y") ?? "0", 10)) * scale),
|
|
@@ -69992,7 +70203,12 @@ function parsePicture(pic, scale, imageMap) {
|
|
|
69992
70203
|
dataUri,
|
|
69993
70204
|
alt,
|
|
69994
70205
|
borderRadius,
|
|
69995
|
-
hasCrop
|
|
70206
|
+
hasCrop,
|
|
70207
|
+
cropLeft: hasCrop ? cropLeft : void 0,
|
|
70208
|
+
cropTop: hasCrop ? cropTop : void 0,
|
|
70209
|
+
cropRight: hasCrop ? cropRight : void 0,
|
|
70210
|
+
cropBottom: hasCrop ? cropBottom : void 0,
|
|
70211
|
+
rotation
|
|
69996
70212
|
};
|
|
69997
70213
|
}
|
|
69998
70214
|
async function parseTableStyles(zip, parser, themeColors) {
|
|
@@ -70112,6 +70328,10 @@ function parseParagraphsFromTxBody(txBody, scale, themeColors, themeFonts) {
|
|
|
70112
70328
|
if (buChar) {
|
|
70113
70329
|
para.bulletChar = buChar.getAttribute("char") ?? void 0;
|
|
70114
70330
|
}
|
|
70331
|
+
const buFont = findChild2(pPr, "buFont");
|
|
70332
|
+
if (buFont) {
|
|
70333
|
+
para.bulletFont = buFont.getAttribute("typeface") ?? void 0;
|
|
70334
|
+
}
|
|
70115
70335
|
const buClr = findChild2(pPr, "buClr");
|
|
70116
70336
|
if (buClr) {
|
|
70117
70337
|
para.bulletColor = resolveColor2(buClr, themeColors);
|
|
@@ -70131,6 +70351,7 @@ function parseParagraphsFromTxBody(txBody, scale, themeColors, themeFonts) {
|
|
|
70131
70351
|
text,
|
|
70132
70352
|
bold: props.bold ?? defaults?.bold,
|
|
70133
70353
|
italic: props.italic ?? defaults?.italic,
|
|
70354
|
+
underline: props.underline ?? defaults?.underline,
|
|
70134
70355
|
fontSize: props.fontSize ?? defaults?.fontSize,
|
|
70135
70356
|
color: props.color ?? defaults?.color,
|
|
70136
70357
|
fontFamily: props.fontFamily ?? defaults?.fontFamily,
|
|
@@ -70276,15 +70497,492 @@ function parseTable2(graphicFrame, scale, themeColors, themeFonts, tableStyleMap
|
|
|
70276
70497
|
}
|
|
70277
70498
|
return table;
|
|
70278
70499
|
}
|
|
70279
|
-
function
|
|
70500
|
+
function resolveChartColor(parent, themeColors) {
|
|
70501
|
+
const solidFill = findChild2(parent, "solidFill");
|
|
70502
|
+
if (!solidFill) return void 0;
|
|
70503
|
+
return resolveColor2(solidFill, themeColors);
|
|
70504
|
+
}
|
|
70505
|
+
function parseChartRichText(richEl) {
|
|
70506
|
+
const paragraphs = findChildren2(richEl, "p");
|
|
70507
|
+
let text = "";
|
|
70508
|
+
let font;
|
|
70509
|
+
let color;
|
|
70510
|
+
let size;
|
|
70511
|
+
for (const p of paragraphs) {
|
|
70512
|
+
const runs = findChildren2(p, "r");
|
|
70513
|
+
for (const r of runs) {
|
|
70514
|
+
const tEl = findChild2(r, "t");
|
|
70515
|
+
if (tEl?.textContent) text += tEl.textContent;
|
|
70516
|
+
if (font === void 0) {
|
|
70517
|
+
const rPr = findChild2(r, "rPr");
|
|
70518
|
+
if (rPr) {
|
|
70519
|
+
const szAttr = rPr.getAttribute("sz");
|
|
70520
|
+
if (szAttr) size = hptToPx(parseInt(szAttr, 10));
|
|
70521
|
+
const latin = findChild2(rPr, "latin");
|
|
70522
|
+
if (latin) font = latin.getAttribute("typeface") ?? void 0;
|
|
70523
|
+
const fill = findChild2(rPr, "solidFill");
|
|
70524
|
+
if (fill) {
|
|
70525
|
+
const srgb = findChild2(fill, "srgbClr");
|
|
70526
|
+
if (srgb) color = "#" + (srgb.getAttribute("val") ?? "000000");
|
|
70527
|
+
}
|
|
70528
|
+
}
|
|
70529
|
+
}
|
|
70530
|
+
}
|
|
70531
|
+
}
|
|
70532
|
+
return { text, font, color, size };
|
|
70533
|
+
}
|
|
70534
|
+
function parseChartAxis(axEl, themeColors) {
|
|
70535
|
+
const axis = {
|
|
70536
|
+
position: "b"
|
|
70537
|
+
};
|
|
70538
|
+
const axPos = findChild2(axEl, "axPos");
|
|
70539
|
+
if (axPos) {
|
|
70540
|
+
const val = axPos.getAttribute("val");
|
|
70541
|
+
if (val === "b" || val === "l" || val === "r" || val === "t") {
|
|
70542
|
+
axis.position = val;
|
|
70543
|
+
}
|
|
70544
|
+
}
|
|
70545
|
+
const titleEl = findChild2(axEl, "title");
|
|
70546
|
+
if (titleEl) {
|
|
70547
|
+
const tx = findChild2(titleEl, "tx");
|
|
70548
|
+
if (tx) {
|
|
70549
|
+
const rich = findChild2(tx, "rich");
|
|
70550
|
+
if (rich) {
|
|
70551
|
+
const parsed = parseChartRichText(rich);
|
|
70552
|
+
axis.title = parsed.text;
|
|
70553
|
+
}
|
|
70554
|
+
}
|
|
70555
|
+
}
|
|
70556
|
+
const numFmt = findChild2(axEl, "numFmt");
|
|
70557
|
+
if (numFmt) {
|
|
70558
|
+
const fmt = numFmt.getAttribute("formatCode");
|
|
70559
|
+
if (fmt) axis.numFormat = fmt;
|
|
70560
|
+
}
|
|
70561
|
+
const txPr = findChild2(axEl, "txPr");
|
|
70562
|
+
if (txPr) {
|
|
70563
|
+
const pEls = findChildren2(txPr, "p");
|
|
70564
|
+
for (const p of pEls) {
|
|
70565
|
+
const pPr = findChild2(p, "pPr");
|
|
70566
|
+
if (pPr) {
|
|
70567
|
+
const defRPr = findChild2(pPr, "defRPr");
|
|
70568
|
+
if (defRPr) {
|
|
70569
|
+
const szAttr = defRPr.getAttribute("sz");
|
|
70570
|
+
if (szAttr) axis.labelSize = hptToPx(parseInt(szAttr, 10));
|
|
70571
|
+
const latin = findChild2(defRPr, "latin");
|
|
70572
|
+
if (latin) axis.labelFont = latin.getAttribute("typeface") ?? void 0;
|
|
70573
|
+
const fill = findChild2(defRPr, "solidFill");
|
|
70574
|
+
if (fill) {
|
|
70575
|
+
const srgb = findChild2(fill, "srgbClr");
|
|
70576
|
+
if (srgb) axis.labelColor = "#" + (srgb.getAttribute("val") ?? "000000");
|
|
70577
|
+
}
|
|
70578
|
+
}
|
|
70579
|
+
}
|
|
70580
|
+
}
|
|
70581
|
+
}
|
|
70582
|
+
const gridlines = findChild2(axEl, "majorGridlines");
|
|
70583
|
+
if (gridlines) {
|
|
70584
|
+
const spPr = findChild2(gridlines, "spPr");
|
|
70585
|
+
if (spPr) {
|
|
70586
|
+
const ln = findChild2(spPr, "ln");
|
|
70587
|
+
if (ln) {
|
|
70588
|
+
const fill = findChild2(ln, "solidFill");
|
|
70589
|
+
if (fill) {
|
|
70590
|
+
const srgb = findChild2(fill, "srgbClr");
|
|
70591
|
+
if (srgb) {
|
|
70592
|
+
axis.gridlineColor = "#" + (srgb.getAttribute("val") ?? "CCCCCC");
|
|
70593
|
+
const alphaEl = findChild2(srgb, "alpha");
|
|
70594
|
+
if (alphaEl) {
|
|
70595
|
+
axis.gridlineAlpha = parseInt(alphaEl.getAttribute("val") ?? "100000", 10) / 1e3;
|
|
70596
|
+
}
|
|
70597
|
+
}
|
|
70598
|
+
}
|
|
70599
|
+
}
|
|
70600
|
+
}
|
|
70601
|
+
}
|
|
70602
|
+
const scaling = findChild2(axEl, "scaling");
|
|
70603
|
+
if (scaling) {
|
|
70604
|
+
const minEl = findChild2(scaling, "min");
|
|
70605
|
+
if (minEl) {
|
|
70606
|
+
const val = minEl.getAttribute("val");
|
|
70607
|
+
if (val) axis.min = parseFloat(val);
|
|
70608
|
+
}
|
|
70609
|
+
}
|
|
70610
|
+
return axis;
|
|
70611
|
+
}
|
|
70612
|
+
async function parseChart(graphicFrame, scale, themeColors, zip, slideRelsDoc, parser) {
|
|
70613
|
+
const xfrm = findChild2(graphicFrame, "xfrm");
|
|
70614
|
+
if (!xfrm) return null;
|
|
70615
|
+
const off = findChild2(xfrm, "off");
|
|
70616
|
+
const ext = findChild2(xfrm, "ext");
|
|
70617
|
+
if (!off || !ext) return null;
|
|
70618
|
+
const graphic = findChild2(graphicFrame, "graphic");
|
|
70619
|
+
if (!graphic) return null;
|
|
70620
|
+
const graphicData = findChild2(graphic, "graphicData");
|
|
70621
|
+
if (!graphicData) return null;
|
|
70622
|
+
const uri2 = graphicData.getAttribute("uri") ?? "";
|
|
70623
|
+
if (!uri2.includes("chart")) return null;
|
|
70624
|
+
let chartRId;
|
|
70625
|
+
for (let i = 0; i < graphicData.children.length; i++) {
|
|
70626
|
+
const child = graphicData.children[i];
|
|
70627
|
+
if (child.localName === "chart") {
|
|
70628
|
+
chartRId = child.getAttribute("r:id") ?? child.getAttributeNS("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id") ?? void 0;
|
|
70629
|
+
break;
|
|
70630
|
+
}
|
|
70631
|
+
}
|
|
70632
|
+
if (!chartRId) return null;
|
|
70633
|
+
let chartTarget;
|
|
70634
|
+
const rels = slideRelsDoc.getElementsByTagName("Relationship");
|
|
70635
|
+
for (let ri = 0; ri < rels.length; ri++) {
|
|
70636
|
+
const rel = rels[ri];
|
|
70637
|
+
if (rel.getAttribute("Id") === chartRId) {
|
|
70638
|
+
chartTarget = rel.getAttribute("Target") ?? void 0;
|
|
70639
|
+
break;
|
|
70640
|
+
}
|
|
70641
|
+
}
|
|
70642
|
+
if (!chartTarget) return null;
|
|
70643
|
+
const chartPath = chartTarget.startsWith("../") ? "ppt/" + chartTarget.slice(3) : chartTarget;
|
|
70644
|
+
const chartXml = await zip.file(chartPath)?.async("text");
|
|
70645
|
+
if (!chartXml) return null;
|
|
70646
|
+
const chartDoc = parser.parseFromString(chartXml, "application/xml");
|
|
70647
|
+
const chartSpace = chartDoc.documentElement;
|
|
70648
|
+
const x = Math.round(emuToPx2(parseInt(off.getAttribute("x") ?? "0", 10)) * scale);
|
|
70649
|
+
const y = Math.round(emuToPx2(parseInt(off.getAttribute("y") ?? "0", 10)) * scale);
|
|
70650
|
+
const w = Math.round(emuToPx2(parseInt(ext.getAttribute("cx") ?? "0", 10)) * scale);
|
|
70651
|
+
const h = Math.round(emuToPx2(parseInt(ext.getAttribute("cy") ?? "0", 10)) * scale);
|
|
70652
|
+
const chartEl = findChild2(chartSpace, "chart");
|
|
70653
|
+
if (!chartEl) return null;
|
|
70654
|
+
let title;
|
|
70655
|
+
let titleFont;
|
|
70656
|
+
let titleColor;
|
|
70657
|
+
let titleSize;
|
|
70658
|
+
const titleEl = findChild2(chartEl, "title");
|
|
70659
|
+
if (titleEl) {
|
|
70660
|
+
const tx = findChild2(titleEl, "tx");
|
|
70661
|
+
if (tx) {
|
|
70662
|
+
const rich = findChild2(tx, "rich");
|
|
70663
|
+
if (rich) {
|
|
70664
|
+
const parsed = parseChartRichText(rich);
|
|
70665
|
+
title = parsed.text;
|
|
70666
|
+
titleFont = parsed.font;
|
|
70667
|
+
titleColor = parsed.color;
|
|
70668
|
+
titleSize = parsed.size;
|
|
70669
|
+
}
|
|
70670
|
+
}
|
|
70671
|
+
}
|
|
70672
|
+
const plotArea = findChild2(chartEl, "plotArea");
|
|
70673
|
+
if (!plotArea) return null;
|
|
70674
|
+
const barChart = findChild2(plotArea, "barChart");
|
|
70675
|
+
if (!barChart) return null;
|
|
70676
|
+
const barDirEl = findChild2(barChart, "barDir");
|
|
70677
|
+
const barDir = barDirEl?.getAttribute("val") ?? "col";
|
|
70678
|
+
const chartType = barDir === "bar" ? "bar" : "column";
|
|
70679
|
+
const gapWidthEl = findChild2(barChart, "gapWidth");
|
|
70680
|
+
const gapWidth = gapWidthEl ? parseInt(gapWidthEl.getAttribute("val") ?? "150", 10) : 150;
|
|
70681
|
+
const roundedCornersEl = findChild2(chartSpace, "roundedCorners");
|
|
70682
|
+
const roundedCorners = roundedCornersEl?.getAttribute("val") === "1";
|
|
70683
|
+
const series = [];
|
|
70684
|
+
const serEls = findChildren2(barChart, "ser");
|
|
70685
|
+
for (const ser of serEls) {
|
|
70686
|
+
const seriesData = {
|
|
70687
|
+
categories: [],
|
|
70688
|
+
values: [],
|
|
70689
|
+
fillColors: []
|
|
70690
|
+
};
|
|
70691
|
+
const txEl = findChild2(ser, "tx");
|
|
70692
|
+
if (txEl) {
|
|
70693
|
+
const strRef = findChild2(txEl, "strRef");
|
|
70694
|
+
if (strRef) {
|
|
70695
|
+
const strCache = findChild2(strRef, "strCache");
|
|
70696
|
+
if (strCache) {
|
|
70697
|
+
const pt = findChild2(strCache, "pt");
|
|
70698
|
+
if (pt) {
|
|
70699
|
+
const v = findChild2(pt, "v");
|
|
70700
|
+
if (v?.textContent) seriesData.name = v.textContent;
|
|
70701
|
+
}
|
|
70702
|
+
}
|
|
70703
|
+
}
|
|
70704
|
+
}
|
|
70705
|
+
const serSpPr = findChild2(ser, "spPr");
|
|
70706
|
+
if (serSpPr) {
|
|
70707
|
+
const color = resolveChartColor(serSpPr, themeColors);
|
|
70708
|
+
if (color) seriesData.seriesColor = color;
|
|
70709
|
+
}
|
|
70710
|
+
const dPtMap = /* @__PURE__ */ new Map();
|
|
70711
|
+
const dPtEls = findChildren2(ser, "dPt");
|
|
70712
|
+
for (const dPt of dPtEls) {
|
|
70713
|
+
const idxEl = findChild2(dPt, "idx");
|
|
70714
|
+
const idx = idxEl ? parseInt(idxEl.getAttribute("val") ?? "0", 10) : 0;
|
|
70715
|
+
const spPr = findChild2(dPt, "spPr");
|
|
70716
|
+
if (spPr) {
|
|
70717
|
+
const color = resolveChartColor(spPr, themeColors);
|
|
70718
|
+
if (color) dPtMap.set(idx, color);
|
|
70719
|
+
}
|
|
70720
|
+
}
|
|
70721
|
+
const catEl = findChild2(ser, "cat");
|
|
70722
|
+
if (catEl) {
|
|
70723
|
+
const strRef = findChild2(catEl, "strRef");
|
|
70724
|
+
if (strRef) {
|
|
70725
|
+
const strCache = findChild2(strRef, "strCache");
|
|
70726
|
+
if (strCache) {
|
|
70727
|
+
const pts = findChildren2(strCache, "pt");
|
|
70728
|
+
for (const pt of pts) {
|
|
70729
|
+
const v = findChild2(pt, "v");
|
|
70730
|
+
seriesData.categories.push(v?.textContent ?? "");
|
|
70731
|
+
}
|
|
70732
|
+
}
|
|
70733
|
+
}
|
|
70734
|
+
}
|
|
70735
|
+
const valEl = findChild2(ser, "val");
|
|
70736
|
+
if (valEl) {
|
|
70737
|
+
const numRef = findChild2(valEl, "numRef");
|
|
70738
|
+
if (numRef) {
|
|
70739
|
+
const numCache = findChild2(numRef, "numCache");
|
|
70740
|
+
if (numCache) {
|
|
70741
|
+
const pts = findChildren2(numCache, "pt");
|
|
70742
|
+
for (const pt of pts) {
|
|
70743
|
+
const v = findChild2(pt, "v");
|
|
70744
|
+
seriesData.values.push(parseFloat(v?.textContent ?? "0"));
|
|
70745
|
+
}
|
|
70746
|
+
}
|
|
70747
|
+
}
|
|
70748
|
+
}
|
|
70749
|
+
for (let i = 0; i < seriesData.values.length; i++) {
|
|
70750
|
+
seriesData.fillColors.push(dPtMap.get(i) ?? void 0);
|
|
70751
|
+
}
|
|
70752
|
+
series.push(seriesData);
|
|
70753
|
+
}
|
|
70754
|
+
if (series.length === 0) return null;
|
|
70755
|
+
let categoryAxis;
|
|
70756
|
+
let valueAxis;
|
|
70757
|
+
const catAx = findChild2(plotArea, "catAx");
|
|
70758
|
+
if (catAx) {
|
|
70759
|
+
categoryAxis = parseChartAxis(catAx, themeColors);
|
|
70760
|
+
}
|
|
70761
|
+
const valAx = findChild2(plotArea, "valAx");
|
|
70762
|
+
if (valAx) {
|
|
70763
|
+
valueAxis = parseChartAxis(valAx, themeColors);
|
|
70764
|
+
}
|
|
70765
|
+
return {
|
|
70766
|
+
x,
|
|
70767
|
+
y,
|
|
70768
|
+
w,
|
|
70769
|
+
h,
|
|
70770
|
+
chartType,
|
|
70771
|
+
title,
|
|
70772
|
+
titleFont,
|
|
70773
|
+
titleColor,
|
|
70774
|
+
titleSize,
|
|
70775
|
+
series,
|
|
70776
|
+
categoryAxis,
|
|
70777
|
+
valueAxis,
|
|
70778
|
+
gapWidth,
|
|
70779
|
+
roundedCorners
|
|
70780
|
+
};
|
|
70781
|
+
}
|
|
70782
|
+
function formatChartValue(value, numFormat) {
|
|
70783
|
+
if (!numFormat || numFormat === "General") {
|
|
70784
|
+
return Number.isInteger(value) ? value.toString() : value.toFixed(1);
|
|
70785
|
+
}
|
|
70786
|
+
let prefix = "";
|
|
70787
|
+
let suffix = "";
|
|
70788
|
+
let fmt = numFormat;
|
|
70789
|
+
const prefixMatch = fmt.match(/^"([^"]*)"(.*)$/);
|
|
70790
|
+
if (prefixMatch) {
|
|
70791
|
+
prefix = prefixMatch[1];
|
|
70792
|
+
fmt = prefixMatch[2];
|
|
70793
|
+
}
|
|
70794
|
+
const suffixMatch = fmt.match(/^(.*)"([^"]*)"$/);
|
|
70795
|
+
if (suffixMatch) {
|
|
70796
|
+
fmt = suffixMatch[1];
|
|
70797
|
+
suffix = suffixMatch[2];
|
|
70798
|
+
}
|
|
70799
|
+
const decimalMatch = fmt.match(/\.(0+)/);
|
|
70800
|
+
const decimals = decimalMatch ? decimalMatch[1].length : 0;
|
|
70801
|
+
const absVal = Math.abs(value);
|
|
70802
|
+
let formatted;
|
|
70803
|
+
if (fmt.includes(",")) {
|
|
70804
|
+
const parts = absVal.toFixed(decimals).split(".");
|
|
70805
|
+
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
70806
|
+
formatted = parts.join(".");
|
|
70807
|
+
} else {
|
|
70808
|
+
formatted = absVal.toFixed(decimals);
|
|
70809
|
+
}
|
|
70810
|
+
const sign2 = value < 0 ? "-" : "";
|
|
70811
|
+
return sign2 + prefix + formatted + suffix;
|
|
70812
|
+
}
|
|
70813
|
+
function escSvg(text) {
|
|
70814
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
70815
|
+
}
|
|
70816
|
+
function renderChartSvg(chart, elId) {
|
|
70817
|
+
const { x, y, w, h } = chart;
|
|
70818
|
+
const titleHeight = chart.title ? Math.max(24, (chart.titleSize ?? 16) + 12) : 0;
|
|
70819
|
+
const axisLabelHeight = 16;
|
|
70820
|
+
const axisTitleHeight = chart.categoryAxis?.title ? 18 : 0;
|
|
70821
|
+
const valAxisTitleWidth = chart.valueAxis?.title ? 20 : 0;
|
|
70822
|
+
const allValues = chart.series.flatMap((s) => s.values);
|
|
70823
|
+
const maxValue = Math.max(...allValues, 0);
|
|
70824
|
+
const valNumFormat = chart.valueAxis?.numFormat;
|
|
70825
|
+
const maxFormattedLabel = formatChartValue(maxValue, valNumFormat);
|
|
70826
|
+
const valLabelCharWidth = (chart.valueAxis?.labelSize ?? 11) * 0.6;
|
|
70827
|
+
const valLabelWidth = Math.max(30, maxFormattedLabel.length * valLabelCharWidth + 8);
|
|
70828
|
+
const marginTop = 8 + titleHeight;
|
|
70829
|
+
const marginBottom = 8 + axisLabelHeight + axisTitleHeight + 4;
|
|
70830
|
+
const marginLeft = 4 + valAxisTitleWidth + valLabelWidth;
|
|
70831
|
+
const marginRight = 12;
|
|
70832
|
+
const plotX = marginLeft;
|
|
70833
|
+
const plotY = marginTop;
|
|
70834
|
+
const plotW = w - marginLeft - marginRight;
|
|
70835
|
+
const plotH = h - marginTop - marginBottom;
|
|
70836
|
+
if (plotW <= 0 || plotH <= 0) return "";
|
|
70837
|
+
const minValue = chart.valueAxis?.min ?? 0;
|
|
70838
|
+
const valueRange = maxValue - minValue;
|
|
70839
|
+
if (valueRange <= 0) return "";
|
|
70840
|
+
const rawInterval = valueRange / 5;
|
|
70841
|
+
const magnitude = Math.pow(10, Math.floor(Math.log10(rawInterval)));
|
|
70842
|
+
const normalized = rawInterval / magnitude;
|
|
70843
|
+
let niceInterval;
|
|
70844
|
+
if (normalized <= 1) niceInterval = 1 * magnitude;
|
|
70845
|
+
else if (normalized <= 2) niceInterval = 2 * magnitude;
|
|
70846
|
+
else if (normalized <= 5) niceInterval = 5 * magnitude;
|
|
70847
|
+
else niceInterval = 10 * magnitude;
|
|
70848
|
+
const ticks = [];
|
|
70849
|
+
let tickVal = Math.ceil(minValue / niceInterval) * niceInterval;
|
|
70850
|
+
while (tickVal <= maxValue) {
|
|
70851
|
+
ticks.push(tickVal);
|
|
70852
|
+
tickVal += niceInterval;
|
|
70853
|
+
}
|
|
70854
|
+
if (minValue <= 0 && !ticks.includes(0)) {
|
|
70855
|
+
ticks.unshift(0);
|
|
70856
|
+
ticks.sort((a, b) => a - b);
|
|
70857
|
+
}
|
|
70858
|
+
const labelFont = chart.categoryAxis?.labelFont ?? chart.titleFont ?? "sans-serif";
|
|
70859
|
+
const labelColor = chart.categoryAxis?.labelColor ?? "#333";
|
|
70860
|
+
const labelSize = chart.categoryAxis?.labelSize ?? 11;
|
|
70861
|
+
const valLabelColor = chart.valueAxis?.labelColor ?? labelColor;
|
|
70862
|
+
const valLabelSize = chart.valueAxis?.labelSize ?? 11;
|
|
70863
|
+
let svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${h}" viewBox="0 0 ${w} ${h}" style="overflow:visible">`;
|
|
70864
|
+
if (chart.title) {
|
|
70865
|
+
const tFont = chart.titleFont ? `font-family:${cssFontFamily(chart.titleFont)};` : `font-family:${cssFontFamily(labelFont)};`;
|
|
70866
|
+
const tColor = chart.titleColor ?? "#000";
|
|
70867
|
+
const tSize = chart.titleSize ?? 16;
|
|
70868
|
+
svg += `<text x="${w / 2}" y="${8 + tSize}" text-anchor="middle" style="${tFont}font-size:${tSize}px;font-weight:bold;fill:${tColor}">${escSvg(chart.title)}</text>`;
|
|
70869
|
+
}
|
|
70870
|
+
if (chart.valueAxis) {
|
|
70871
|
+
const gColor = chart.valueAxis.gridlineColor ?? "#e0e0e0";
|
|
70872
|
+
const gAlpha = chart.valueAxis.gridlineAlpha !== void 0 ? chart.valueAxis.gridlineAlpha / 100 : 0.3;
|
|
70873
|
+
for (const tick of ticks) {
|
|
70874
|
+
const tickY = plotY + plotH - (tick - minValue) / valueRange * plotH;
|
|
70875
|
+
svg += `<line x1="${plotX}" y1="${tickY}" x2="${plotX + plotW}" y2="${tickY}" stroke="${gColor}" stroke-opacity="${gAlpha}" stroke-width="1"/>`;
|
|
70876
|
+
}
|
|
70877
|
+
}
|
|
70878
|
+
const numCategories = chart.series[0]?.categories.length ?? 0;
|
|
70879
|
+
const numSeries = chart.series.length;
|
|
70880
|
+
if (numCategories > 0) {
|
|
70881
|
+
const gapFraction = (chart.gapWidth ?? 150) / 100;
|
|
70882
|
+
const categoryWidth = plotW / numCategories;
|
|
70883
|
+
const barGroupWidth = categoryWidth / (1 + gapFraction);
|
|
70884
|
+
const gapSpace = categoryWidth - barGroupWidth;
|
|
70885
|
+
const barWidth = barGroupWidth / numSeries;
|
|
70886
|
+
const cornerRadius = chart.roundedCorners ? Math.min(barWidth * 0.15, 4) : 0;
|
|
70887
|
+
for (let si = 0; si < numSeries; si++) {
|
|
70888
|
+
const s = chart.series[si];
|
|
70889
|
+
for (let ci = 0; ci < s.values.length; ci++) {
|
|
70890
|
+
const val = s.values[ci];
|
|
70891
|
+
const barH = (val - minValue) / valueRange * plotH;
|
|
70892
|
+
const barX = plotX + ci * categoryWidth + gapSpace / 2 + si * barWidth;
|
|
70893
|
+
const barY = plotY + plotH - barH;
|
|
70894
|
+
const fillColor = s.fillColors[ci] ?? s.seriesColor ?? "#4472C4";
|
|
70895
|
+
if (cornerRadius > 0) {
|
|
70896
|
+
const r = Math.min(cornerRadius, barH / 2, barWidth / 2);
|
|
70897
|
+
svg += `<path d="M${barX},${barY + barH} L${barX},${barY + r} Q${barX},${barY} ${barX + r},${barY} L${barX + barWidth - r},${barY} Q${barX + barWidth},${barY} ${barX + barWidth},${barY + r} L${barX + barWidth},${barY + barH} Z" fill="${fillColor}"/>`;
|
|
70898
|
+
} else {
|
|
70899
|
+
svg += `<rect x="${barX}" y="${barY}" width="${barWidth}" height="${barH}" fill="${fillColor}"/>`;
|
|
70900
|
+
}
|
|
70901
|
+
}
|
|
70902
|
+
}
|
|
70903
|
+
}
|
|
70904
|
+
svg += `<line x1="${plotX}" y1="${plotY + plotH}" x2="${plotX + plotW}" y2="${plotY + plotH}" stroke="${labelColor}" stroke-width="1"/>`;
|
|
70905
|
+
svg += `<line x1="${plotX}" y1="${plotY}" x2="${plotX}" y2="${plotY + plotH}" stroke="${valLabelColor}" stroke-width="1"/>`;
|
|
70906
|
+
if (numCategories > 0) {
|
|
70907
|
+
const categoryWidth = plotW / numCategories;
|
|
70908
|
+
const cats = chart.series[0]?.categories ?? [];
|
|
70909
|
+
for (let ci = 0; ci < cats.length; ci++) {
|
|
70910
|
+
const labelX = plotX + ci * categoryWidth + categoryWidth / 2;
|
|
70911
|
+
const labelY = plotY + plotH + 4;
|
|
70912
|
+
const catText = cats[ci];
|
|
70913
|
+
const lines = catText.split("\n");
|
|
70914
|
+
const lineH = labelSize + 2;
|
|
70915
|
+
for (let li = 0; li < lines.length; li++) {
|
|
70916
|
+
svg += `<text x="${labelX}" y="${labelY + labelSize + li * lineH}" text-anchor="middle" style="font-family:${cssFontFamily(labelFont)};font-size:${labelSize}px;fill:${labelColor}">${escSvg(lines[li])}</text>`;
|
|
70917
|
+
}
|
|
70918
|
+
}
|
|
70919
|
+
}
|
|
70920
|
+
for (const tick of ticks) {
|
|
70921
|
+
const tickY = plotY + plotH - (tick - minValue) / valueRange * plotH;
|
|
70922
|
+
const label = formatChartValue(tick, valNumFormat);
|
|
70923
|
+
svg += `<text x="${plotX - 6}" y="${tickY + valLabelSize * 0.35}" text-anchor="end" style="font-family:${cssFontFamily(labelFont)};font-size:${valLabelSize}px;fill:${valLabelColor}">${escSvg(label)}</text>`;
|
|
70924
|
+
}
|
|
70925
|
+
if (chart.categoryAxis?.title) {
|
|
70926
|
+
const axTitleY = plotY + plotH + axisLabelHeight + axisTitleHeight + 2;
|
|
70927
|
+
svg += `<text x="${plotX + plotW / 2}" y="${axTitleY}" text-anchor="middle" style="font-family:${cssFontFamily(labelFont)};font-size:${labelSize}px;fill:${labelColor}">${escSvg(chart.categoryAxis.title)}</text>`;
|
|
70928
|
+
}
|
|
70929
|
+
if (chart.valueAxis?.title) {
|
|
70930
|
+
const axTitleX = 4 + (chart.titleSize ?? 12) * 0.5;
|
|
70931
|
+
const axTitleY = plotY + plotH / 2;
|
|
70932
|
+
svg += `<text x="${axTitleX}" y="${axTitleY}" text-anchor="middle" transform="rotate(-90, ${axTitleX}, ${axTitleY})" style="font-family:${cssFontFamily(labelFont)};font-size:${labelSize}px;fill:${valLabelColor}">${escSvg(chart.valueAxis.title)}</text>`;
|
|
70933
|
+
}
|
|
70934
|
+
svg += `</svg>`;
|
|
70935
|
+
const wrapperStyles = [
|
|
70936
|
+
"position:absolute",
|
|
70937
|
+
`left:${x}px`,
|
|
70938
|
+
`top:${y}px`,
|
|
70939
|
+
`width:${w}px`,
|
|
70940
|
+
`height:${h}px`
|
|
70941
|
+
];
|
|
70942
|
+
return `<div id="${elId}" data-elementType="chart" style="${wrapperStyles.join(";")}">${svg}</div>
|
|
70943
|
+
`;
|
|
70944
|
+
}
|
|
70945
|
+
function renderSlideHtml(elements, bgColor, contentOffsetX = 0) {
|
|
70280
70946
|
let inner = "";
|
|
70281
70947
|
let elementIndex = 0;
|
|
70282
70948
|
for (const el of elements) {
|
|
70283
70949
|
const elId = `el-${elementIndex++}`;
|
|
70284
70950
|
if (el.kind === "image") {
|
|
70285
70951
|
const img = el.data;
|
|
70952
|
+
const altAttr = img.alt ? ` alt="${img.alt.replace(/"/g, """)}"` : "";
|
|
70286
70953
|
const isFullbleed = img.x <= 10 && img.y <= 10 && img.w >= TARGET_WIDTH - 20 && img.h >= TARGET_HEIGHT - 20;
|
|
70287
|
-
|
|
70954
|
+
if (img.hasCrop && img.cropLeft !== void 0 && img.cropTop !== void 0 && img.cropRight !== void 0 && img.cropBottom !== void 0) {
|
|
70955
|
+
const visW = (100 - img.cropLeft - img.cropRight) / 100;
|
|
70956
|
+
const visH = (100 - img.cropTop - img.cropBottom) / 100;
|
|
70957
|
+
if (visW > 0 && visH > 0) {
|
|
70958
|
+
const displayW = img.w / visW;
|
|
70959
|
+
const displayH = img.h / visH;
|
|
70960
|
+
const offsetX = -(img.cropLeft / 100) * displayW;
|
|
70961
|
+
const offsetY = -(img.cropTop / 100) * displayH;
|
|
70962
|
+
const wrapperStyles = [
|
|
70963
|
+
"position:absolute",
|
|
70964
|
+
`left:${img.x}px`,
|
|
70965
|
+
`top:${img.y}px`,
|
|
70966
|
+
`width:${img.w}px`,
|
|
70967
|
+
`height:${img.h}px`,
|
|
70968
|
+
"overflow:hidden"
|
|
70969
|
+
];
|
|
70970
|
+
if (img.rotation) {
|
|
70971
|
+
wrapperStyles.push(`transform:rotate(${img.rotation}deg)`);
|
|
70972
|
+
wrapperStyles.push("transform-origin:center center");
|
|
70973
|
+
}
|
|
70974
|
+
if (img.borderRadius && img.borderRadius > 0) {
|
|
70975
|
+
wrapperStyles.push(`border-radius:${img.borderRadius}px`);
|
|
70976
|
+
}
|
|
70977
|
+
const imgStyle = `position:absolute;width:${Math.round(displayW)}px;height:${Math.round(displayH)}px;left:${Math.round(offsetX)}px;top:${Math.round(offsetY)}px`;
|
|
70978
|
+
inner += `<div id="${elId}" data-elementType="image" style="${wrapperStyles.join(";")}">`;
|
|
70979
|
+
inner += `<img src="${img.dataUri}"${altAttr} style="${imgStyle}" />`;
|
|
70980
|
+
inner += `</div>
|
|
70981
|
+
`;
|
|
70982
|
+
continue;
|
|
70983
|
+
}
|
|
70984
|
+
}
|
|
70985
|
+
const objectFit = isFullbleed ? "cover" : "contain";
|
|
70288
70986
|
const stylesList = [
|
|
70289
70987
|
"position:absolute",
|
|
70290
70988
|
`left:${img.x}px`,
|
|
@@ -70293,11 +70991,14 @@ function renderSlideHtml(elements, bgColor) {
|
|
|
70293
70991
|
`height:${img.h}px`,
|
|
70294
70992
|
`object-fit:${objectFit}`
|
|
70295
70993
|
];
|
|
70994
|
+
if (img.rotation) {
|
|
70995
|
+
stylesList.push(`transform:rotate(${img.rotation}deg)`);
|
|
70996
|
+
stylesList.push("transform-origin:center center");
|
|
70997
|
+
}
|
|
70296
70998
|
if (img.borderRadius && img.borderRadius > 0) {
|
|
70297
70999
|
stylesList.push(`border-radius:${img.borderRadius}px`);
|
|
70298
71000
|
}
|
|
70299
71001
|
const styles2 = stylesList.join(";");
|
|
70300
|
-
const altAttr = img.alt ? ` alt="${img.alt.replace(/"/g, """)}"` : "";
|
|
70301
71002
|
inner += `<img id="${elId}" data-elementType="image" src="${img.dataUri}"${altAttr} style="${styles2}" />
|
|
70302
71003
|
`;
|
|
70303
71004
|
continue;
|
|
@@ -70380,6 +71081,7 @@ function renderSlideHtml(elements, bgColor) {
|
|
|
70380
71081
|
}
|
|
70381
71082
|
if (run.bold) rStyles.push("font-weight:bold");
|
|
70382
71083
|
if (run.italic) rStyles.push("font-style:italic");
|
|
71084
|
+
if (run.underline) rStyles.push("text-decoration:underline");
|
|
70383
71085
|
if (run.fontFamily)
|
|
70384
71086
|
rStyles.push(`font-family:${cssFontFamily(run.fontFamily)}`);
|
|
70385
71087
|
if (run.textShadow) rStyles.push(`text-shadow:${run.textShadow}`);
|
|
@@ -70401,6 +71103,11 @@ function renderSlideHtml(elements, bgColor) {
|
|
|
70401
71103
|
`;
|
|
70402
71104
|
continue;
|
|
70403
71105
|
}
|
|
71106
|
+
if (el.kind === "chart") {
|
|
71107
|
+
const chart = el.data;
|
|
71108
|
+
inner += renderChartSvg(chart, elId);
|
|
71109
|
+
continue;
|
|
71110
|
+
}
|
|
70404
71111
|
const shape = el.data;
|
|
70405
71112
|
const styles = [
|
|
70406
71113
|
"position:absolute",
|
|
@@ -70413,6 +71120,12 @@ function renderSlideHtml(elements, bgColor) {
|
|
|
70413
71120
|
if (shape.fill) {
|
|
70414
71121
|
styles.push(`background:${shape.fill}`);
|
|
70415
71122
|
}
|
|
71123
|
+
if (shape.clipPath) {
|
|
71124
|
+
styles.push(`clip-path:${shape.clipPath}`);
|
|
71125
|
+
}
|
|
71126
|
+
if (shape.rotation) {
|
|
71127
|
+
styles.push(`transform:rotate(${shape.rotation}deg)`);
|
|
71128
|
+
}
|
|
70416
71129
|
if (shape.borderRadius) {
|
|
70417
71130
|
styles.push(`border-radius:${shape.borderRadius}px`);
|
|
70418
71131
|
} else if (shape.isEllipse) {
|
|
@@ -70448,7 +71161,10 @@ function renderSlideHtml(elements, bgColor) {
|
|
|
70448
71161
|
else if (shape.verticalAlign === "bottom")
|
|
70449
71162
|
styles.push("justify-content:flex-end");
|
|
70450
71163
|
}
|
|
70451
|
-
if (shape.
|
|
71164
|
+
if (shape.w <= 0 || shape.h <= 0) {
|
|
71165
|
+
continue;
|
|
71166
|
+
}
|
|
71167
|
+
if (shape.paragraphs.length === 0 && !shape.fill && !shape.borderWidth && !shape.isEllipse) {
|
|
70452
71168
|
continue;
|
|
70453
71169
|
}
|
|
70454
71170
|
const hasText = shape.paragraphs.length > 0;
|
|
@@ -70468,8 +71184,12 @@ function renderSlideHtml(elements, bgColor) {
|
|
|
70468
71184
|
if (para.indentPx) pStyles.push(`text-indent:${para.indentPx}px`);
|
|
70469
71185
|
let runHtml = "";
|
|
70470
71186
|
if (para.bulletChar) {
|
|
70471
|
-
const
|
|
70472
|
-
|
|
71187
|
+
const bulletStyleParts = ["margin-right:4px"];
|
|
71188
|
+
if (para.bulletColor) bulletStyleParts.push(`color:${para.bulletColor}`);
|
|
71189
|
+
if (para.bulletFont) bulletStyleParts.push(`font-family:${cssFontFamily(para.bulletFont)}`);
|
|
71190
|
+
const firstRunFontSize = para.runs[0]?.fontSize;
|
|
71191
|
+
if (firstRunFontSize) bulletStyleParts.push(`font-size:${firstRunFontSize}px`);
|
|
71192
|
+
runHtml += `<span style="${bulletStyleParts.join(";")}">${para.bulletChar}</span>`;
|
|
70473
71193
|
}
|
|
70474
71194
|
for (const run of para.runs) {
|
|
70475
71195
|
const rStyles = [];
|
|
@@ -70484,6 +71204,7 @@ function renderSlideHtml(elements, bgColor) {
|
|
|
70484
71204
|
}
|
|
70485
71205
|
if (run.bold) rStyles.push("font-weight:bold");
|
|
70486
71206
|
if (run.italic) rStyles.push("font-style:italic");
|
|
71207
|
+
if (run.underline) rStyles.push("text-decoration:underline");
|
|
70487
71208
|
if (run.fontFamily)
|
|
70488
71209
|
rStyles.push(`font-family:${cssFontFamily(run.fontFamily)}`);
|
|
70489
71210
|
if (run.textShadow) rStyles.push(`text-shadow:${run.textShadow}`);
|
|
@@ -70500,8 +71221,12 @@ function renderSlideHtml(elements, bgColor) {
|
|
|
70500
71221
|
`;
|
|
70501
71222
|
}
|
|
70502
71223
|
const bg = bgColor ?? "#fff";
|
|
71224
|
+
const offsetPx = Math.round(contentOffsetX);
|
|
71225
|
+
const innerWrapStyle = offsetPx > 0 ? ` style="position:absolute;left:${offsetPx}px;top:0"` : "";
|
|
70503
71226
|
return `<div style="position:relative;width:${TARGET_WIDTH}px;height:${TARGET_HEIGHT}px;overflow:hidden;font-family:'Segoe UI',Arial,sans-serif;background:${bg}">
|
|
70504
|
-
${
|
|
71227
|
+
<div${innerWrapStyle}>
|
|
71228
|
+
${inner}</div>
|
|
71229
|
+
</div>`;
|
|
70505
71230
|
}
|
|
70506
71231
|
async function importPptx(arrayBuffer) {
|
|
70507
71232
|
const zip = await import_jszip2.default.loadAsync(arrayBuffer);
|
|
@@ -70515,6 +71240,8 @@ async function importPptx(arrayBuffer) {
|
|
|
70515
71240
|
const slideWPx = emuToPx2(slideWEmu);
|
|
70516
71241
|
const slideHPx = emuToPx2(slideHEmu);
|
|
70517
71242
|
const scale = Math.min(TARGET_WIDTH / slideWPx, TARGET_HEIGHT / slideHPx);
|
|
71243
|
+
const scaledContentW = slideWPx * scale;
|
|
71244
|
+
const contentOffsetX = (TARGET_WIDTH - scaledContentW) / 2;
|
|
70518
71245
|
const sldIdLst = presDoc.getElementsByTagName("p:sldIdLst")[0];
|
|
70519
71246
|
const visibleSlideRIds = [];
|
|
70520
71247
|
if (sldIdLst) {
|
|
@@ -70563,6 +71290,7 @@ async function importPptx(arrayBuffer) {
|
|
|
70563
71290
|
}
|
|
70564
71291
|
const themeColors = /* @__PURE__ */ new Map();
|
|
70565
71292
|
const themeXml = await zip.file("ppt/theme/theme1.xml")?.async("text");
|
|
71293
|
+
const bgFillStyles = [];
|
|
70566
71294
|
if (themeXml) {
|
|
70567
71295
|
const themeDoc = parser.parseFromString(themeXml, "application/xml");
|
|
70568
71296
|
const clrScheme = themeDoc.getElementsByTagName("a:clrScheme")[0];
|
|
@@ -70609,6 +71337,12 @@ async function importPptx(arrayBuffer) {
|
|
|
70609
71337
|
if (lt1Color) themeColors.set("bg1", lt1Color);
|
|
70610
71338
|
const lt2Color = themeColors.get("lt2");
|
|
70611
71339
|
if (lt2Color) themeColors.set("bg2", lt2Color);
|
|
71340
|
+
const bgFillStyleLst = themeDoc.getElementsByTagName("a:bgFillStyleLst")[0];
|
|
71341
|
+
if (bgFillStyleLst) {
|
|
71342
|
+
for (let i = 0; i < bgFillStyleLst.children.length; i++) {
|
|
71343
|
+
bgFillStyles.push(bgFillStyleLst.children[i]);
|
|
71344
|
+
}
|
|
71345
|
+
}
|
|
70612
71346
|
}
|
|
70613
71347
|
let themeFonts;
|
|
70614
71348
|
if (themeXml) {
|
|
@@ -70644,6 +71378,89 @@ async function importPptx(arrayBuffer) {
|
|
|
70644
71378
|
fontStyleBlock = `<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=${fontFamilies}&display=swap">`;
|
|
70645
71379
|
}
|
|
70646
71380
|
const slides = [];
|
|
71381
|
+
let masterBg;
|
|
71382
|
+
let masterDecorativeElements = [];
|
|
71383
|
+
const masterXml = await zip.file("ppt/slideMasters/slideMaster1.xml")?.async("text");
|
|
71384
|
+
if (masterXml) {
|
|
71385
|
+
const masterDoc = parser.parseFromString(masterXml, "application/xml");
|
|
71386
|
+
const masterBgEl = masterDoc.getElementsByTagName("p:bg")[0];
|
|
71387
|
+
if (masterBgEl) {
|
|
71388
|
+
masterBg = extractBgFill(masterBgEl, bgFillStyles, themeColors);
|
|
71389
|
+
}
|
|
71390
|
+
const masterImageMap = /* @__PURE__ */ new Map();
|
|
71391
|
+
const masterRelsXml = await zip.file("ppt/slideMasters/_rels/slideMaster1.xml.rels")?.async("text");
|
|
71392
|
+
if (masterRelsXml) {
|
|
71393
|
+
const relsDoc = parser.parseFromString(masterRelsXml, "application/xml");
|
|
71394
|
+
const rels = relsDoc.getElementsByTagName("Relationship");
|
|
71395
|
+
for (let ri = 0; ri < rels.length; ri++) {
|
|
71396
|
+
const rel = rels[ri];
|
|
71397
|
+
const type2 = rel.getAttribute("Type") ?? "";
|
|
71398
|
+
if (!type2.includes("/image")) continue;
|
|
71399
|
+
const rId = rel.getAttribute("Id");
|
|
71400
|
+
const target = rel.getAttribute("Target");
|
|
71401
|
+
if (!rId || !target) continue;
|
|
71402
|
+
const mediaPath = target.startsWith("../") ? "ppt/" + target.slice(3) : target;
|
|
71403
|
+
const imgFile = zip.file(mediaPath);
|
|
71404
|
+
if (!imgFile) continue;
|
|
71405
|
+
const imgData = await imgFile.async("base64");
|
|
71406
|
+
const ext = mediaPath.split(".").pop()?.toLowerCase() ?? "png";
|
|
71407
|
+
const mime = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "svg" ? "image/svg+xml" : `image/${ext}`;
|
|
71408
|
+
masterImageMap.set(rId, `data:${mime};base64,${imgData}`);
|
|
71409
|
+
}
|
|
71410
|
+
}
|
|
71411
|
+
const masterSpTree = masterDoc.getElementsByTagName("p:spTree")[0];
|
|
71412
|
+
if (masterSpTree) {
|
|
71413
|
+
masterDecorativeElements = parseDecorativeShapes(masterSpTree, scale, themeColors, masterImageMap, themeFonts);
|
|
71414
|
+
}
|
|
71415
|
+
}
|
|
71416
|
+
const layoutCache = /* @__PURE__ */ new Map();
|
|
71417
|
+
async function getLayoutInfo(layoutPath) {
|
|
71418
|
+
if (layoutCache.has(layoutPath)) return layoutCache.get(layoutPath);
|
|
71419
|
+
const result = { bg: void 0, showMasterSp: true, decorativeElements: [] };
|
|
71420
|
+
const layoutXml = await zip.file(layoutPath)?.async("text");
|
|
71421
|
+
if (layoutXml) {
|
|
71422
|
+
const layoutDoc = parser.parseFromString(layoutXml, "application/xml");
|
|
71423
|
+
const cSld = layoutDoc.getElementsByTagName("p:cSld")[0];
|
|
71424
|
+
const rootEl = layoutDoc.documentElement;
|
|
71425
|
+
const showMasterSpAttr = rootEl.getAttribute("showMasterSp");
|
|
71426
|
+
if (showMasterSpAttr === "0") {
|
|
71427
|
+
result.showMasterSp = false;
|
|
71428
|
+
}
|
|
71429
|
+
const layoutBgEl = layoutDoc.getElementsByTagName("p:bg")[0];
|
|
71430
|
+
if (layoutBgEl) {
|
|
71431
|
+
result.bg = extractBgFill(layoutBgEl, bgFillStyles, themeColors);
|
|
71432
|
+
}
|
|
71433
|
+
const layoutImageMap = /* @__PURE__ */ new Map();
|
|
71434
|
+
const layoutBaseName = layoutPath.split("/").pop();
|
|
71435
|
+
const layoutRelsPath = layoutPath.replace(layoutBaseName, `_rels/${layoutBaseName}.rels`);
|
|
71436
|
+
const layoutRelsXml = await zip.file(layoutRelsPath)?.async("text");
|
|
71437
|
+
if (layoutRelsXml) {
|
|
71438
|
+
const relsDoc = parser.parseFromString(layoutRelsXml, "application/xml");
|
|
71439
|
+
const rels = relsDoc.getElementsByTagName("Relationship");
|
|
71440
|
+
for (let ri = 0; ri < rels.length; ri++) {
|
|
71441
|
+
const rel = rels[ri];
|
|
71442
|
+
const type2 = rel.getAttribute("Type") ?? "";
|
|
71443
|
+
if (!type2.includes("/image")) continue;
|
|
71444
|
+
const rId = rel.getAttribute("Id");
|
|
71445
|
+
const target = rel.getAttribute("Target");
|
|
71446
|
+
if (!rId || !target) continue;
|
|
71447
|
+
const mediaPath = target.startsWith("../") ? "ppt/" + target.slice(3) : target;
|
|
71448
|
+
const imgFile = zip.file(mediaPath);
|
|
71449
|
+
if (!imgFile) continue;
|
|
71450
|
+
const imgData = await imgFile.async("base64");
|
|
71451
|
+
const ext = mediaPath.split(".").pop()?.toLowerCase() ?? "png";
|
|
71452
|
+
const mime = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "svg" ? "image/svg+xml" : `image/${ext}`;
|
|
71453
|
+
layoutImageMap.set(rId, `data:${mime};base64,${imgData}`);
|
|
71454
|
+
}
|
|
71455
|
+
}
|
|
71456
|
+
const layoutSpTree = layoutDoc.getElementsByTagName("p:spTree")[0];
|
|
71457
|
+
if (layoutSpTree) {
|
|
71458
|
+
result.decorativeElements = parseDecorativeShapes(layoutSpTree, scale, themeColors, layoutImageMap, themeFonts);
|
|
71459
|
+
}
|
|
71460
|
+
}
|
|
71461
|
+
layoutCache.set(layoutPath, result);
|
|
71462
|
+
return result;
|
|
71463
|
+
}
|
|
70647
71464
|
for (const slideFile of slideFiles) {
|
|
70648
71465
|
const slideXml = await zip.file(slideFile)?.async("text");
|
|
70649
71466
|
if (!slideXml) continue;
|
|
@@ -70652,27 +71469,47 @@ async function importPptx(arrayBuffer) {
|
|
|
70652
71469
|
let slideBg = void 0;
|
|
70653
71470
|
const bgEl = slideDoc.getElementsByTagName("p:bg")[0];
|
|
70654
71471
|
if (bgEl) {
|
|
70655
|
-
|
|
70656
|
-
if (bgPr) {
|
|
70657
|
-
slideBg = extractFill(bgPr, themeColors);
|
|
70658
|
-
}
|
|
71472
|
+
slideBg = extractBgFill(bgEl, bgFillStyles, themeColors);
|
|
70659
71473
|
}
|
|
70660
|
-
if (!spTree) {
|
|
70661
|
-
slides.push(renderSlideHtml([], slideBg));
|
|
70662
|
-
continue;
|
|
70663
|
-
}
|
|
70664
|
-
const imageMap = /* @__PURE__ */ new Map();
|
|
70665
71474
|
const slideBaseName = slideFile.split("/").pop();
|
|
70666
|
-
const relsPath = slideFile.replace(
|
|
70667
|
-
slideBaseName,
|
|
70668
|
-
`_rels/${slideBaseName}.rels`
|
|
70669
|
-
);
|
|
71475
|
+
const relsPath = slideFile.replace(slideBaseName, `_rels/${slideBaseName}.rels`);
|
|
70670
71476
|
const relsXml = await zip.file(relsPath)?.async("text");
|
|
71477
|
+
let layoutPath;
|
|
70671
71478
|
if (relsXml) {
|
|
70672
71479
|
const relsDoc = parser.parseFromString(relsXml, "application/xml");
|
|
70673
71480
|
const rels = relsDoc.getElementsByTagName("Relationship");
|
|
70674
|
-
for (let
|
|
70675
|
-
const rel = rels[
|
|
71481
|
+
for (let ri = 0; ri < rels.length; ri++) {
|
|
71482
|
+
const rel = rels[ri];
|
|
71483
|
+
const type2 = rel.getAttribute("Type") ?? "";
|
|
71484
|
+
if (type2.includes("/slideLayout")) {
|
|
71485
|
+
const target = rel.getAttribute("Target");
|
|
71486
|
+
if (target) {
|
|
71487
|
+
layoutPath = target.startsWith("../") ? "ppt/" + target.slice(3) : "ppt/slides/" + target;
|
|
71488
|
+
}
|
|
71489
|
+
break;
|
|
71490
|
+
}
|
|
71491
|
+
}
|
|
71492
|
+
}
|
|
71493
|
+
let layoutInfo;
|
|
71494
|
+
if (layoutPath) {
|
|
71495
|
+
layoutInfo = await getLayoutInfo(layoutPath);
|
|
71496
|
+
}
|
|
71497
|
+
if (!slideBg && layoutInfo?.bg) {
|
|
71498
|
+
slideBg = layoutInfo.bg;
|
|
71499
|
+
}
|
|
71500
|
+
if (!slideBg && masterBg) {
|
|
71501
|
+
slideBg = masterBg;
|
|
71502
|
+
}
|
|
71503
|
+
if (!spTree) {
|
|
71504
|
+
slides.push(renderSlideHtml([], slideBg, contentOffsetX));
|
|
71505
|
+
continue;
|
|
71506
|
+
}
|
|
71507
|
+
const imageMap = /* @__PURE__ */ new Map();
|
|
71508
|
+
const slideRelsDoc = relsXml ? parser.parseFromString(relsXml, "application/xml") : null;
|
|
71509
|
+
if (slideRelsDoc) {
|
|
71510
|
+
const rels = slideRelsDoc.getElementsByTagName("Relationship");
|
|
71511
|
+
for (let ri = 0; ri < rels.length; ri++) {
|
|
71512
|
+
const rel = rels[ri];
|
|
70676
71513
|
const type2 = rel.getAttribute("Type") ?? "";
|
|
70677
71514
|
if (!type2.includes("/image")) continue;
|
|
70678
71515
|
const rId = rel.getAttribute("Id");
|
|
@@ -70688,6 +71525,12 @@ async function importPptx(arrayBuffer) {
|
|
|
70688
71525
|
}
|
|
70689
71526
|
}
|
|
70690
71527
|
const elements = [];
|
|
71528
|
+
if (layoutInfo?.showMasterSp !== false) {
|
|
71529
|
+
elements.push(...masterDecorativeElements);
|
|
71530
|
+
}
|
|
71531
|
+
if (layoutInfo?.decorativeElements) {
|
|
71532
|
+
elements.push(...layoutInfo.decorativeElements);
|
|
71533
|
+
}
|
|
70691
71534
|
for (let i = 0; i < spTree.children.length; i++) {
|
|
70692
71535
|
const child = spTree.children[i];
|
|
70693
71536
|
if (child.localName === "sp") {
|
|
@@ -70698,10 +71541,15 @@ async function importPptx(arrayBuffer) {
|
|
|
70698
71541
|
if (img) elements.push({ kind: "image", data: img });
|
|
70699
71542
|
} else if (child.localName === "graphicFrame") {
|
|
70700
71543
|
const table = parseTable2(child, scale, themeColors, themeFonts, tableStyleMap);
|
|
70701
|
-
if (table)
|
|
71544
|
+
if (table) {
|
|
71545
|
+
elements.push({ kind: "table", data: table });
|
|
71546
|
+
} else if (slideRelsDoc) {
|
|
71547
|
+
const chart = await parseChart(child, scale, themeColors, zip, slideRelsDoc, parser);
|
|
71548
|
+
if (chart) elements.push({ kind: "chart", data: chart });
|
|
71549
|
+
}
|
|
70702
71550
|
}
|
|
70703
71551
|
}
|
|
70704
|
-
slides.push(renderSlideHtml(elements, slideBg));
|
|
71552
|
+
slides.push(renderSlideHtml(elements, slideBg, contentOffsetX));
|
|
70705
71553
|
}
|
|
70706
71554
|
if (fontStyleBlock && slides.length > 0) {
|
|
70707
71555
|
slides[0] = fontStyleBlock + slides[0];
|
|
@@ -96278,6 +97126,28 @@ async function createDocxBuffer(html, options = {}) {
|
|
|
96278
97126
|
return Packer.toBuffer(doc);
|
|
96279
97127
|
}
|
|
96280
97128
|
|
|
97129
|
+
// packages/cli/commands/common.ts
|
|
97130
|
+
var userAgent = "Mozilla/5.0 (compatible; Copilot/1.0)";
|
|
97131
|
+
async function fetchWithProxy(url) {
|
|
97132
|
+
const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.https_proxy || process.env.http_proxy;
|
|
97133
|
+
if (proxyUrl) {
|
|
97134
|
+
const undici = await Promise.resolve().then(() => __toESM(require_undici(), 1));
|
|
97135
|
+
const agent = new undici.ProxyAgent(proxyUrl);
|
|
97136
|
+
const response = await undici.fetch(url, {
|
|
97137
|
+
dispatcher: agent,
|
|
97138
|
+
headers: {
|
|
97139
|
+
"User-Agent": userAgent
|
|
97140
|
+
}
|
|
97141
|
+
});
|
|
97142
|
+
return response;
|
|
97143
|
+
}
|
|
97144
|
+
return fetch(url, {
|
|
97145
|
+
headers: {
|
|
97146
|
+
"User-Agent": userAgent
|
|
97147
|
+
}
|
|
97148
|
+
});
|
|
97149
|
+
}
|
|
97150
|
+
|
|
96281
97151
|
// packages/cli/commands/export-docs.ts
|
|
96282
97152
|
function findAllImageElements(elements) {
|
|
96283
97153
|
const images = [];
|
|
@@ -96309,12 +97179,7 @@ async function fetchExternalImages(elements) {
|
|
|
96309
97179
|
for (const imgEl of externalImages) {
|
|
96310
97180
|
try {
|
|
96311
97181
|
const src = imgEl.src;
|
|
96312
|
-
const response = await
|
|
96313
|
-
headers: {
|
|
96314
|
-
// Some servers require a User-Agent
|
|
96315
|
-
"User-Agent": "Mozilla/5.0 (compatible; DocxExporter/1.0)"
|
|
96316
|
-
}
|
|
96317
|
-
});
|
|
97182
|
+
const response = await fetchWithProxy(src);
|
|
96318
97183
|
if (!response.ok) {
|
|
96319
97184
|
console.warn(`Failed to fetch image: ${src} (${response.status})`);
|
|
96320
97185
|
continue;
|
|
@@ -96598,25 +97463,6 @@ import { fileURLToPath } from "node:url";
|
|
|
96598
97463
|
import { chromium as chromium2 } from "playwright";
|
|
96599
97464
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
96600
97465
|
var __dirname = path4.dirname(__filename2);
|
|
96601
|
-
async function fetchWithProxy(url) {
|
|
96602
|
-
const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.https_proxy || process.env.http_proxy;
|
|
96603
|
-
if (proxyUrl) {
|
|
96604
|
-
const undici = await Promise.resolve().then(() => __toESM(require_undici(), 1));
|
|
96605
|
-
const agent = new undici.ProxyAgent(proxyUrl);
|
|
96606
|
-
const response = await undici.fetch(url, {
|
|
96607
|
-
dispatcher: agent,
|
|
96608
|
-
headers: {
|
|
96609
|
-
"User-Agent": "Mozilla/5.0 (compatible; DocGen/1.0)"
|
|
96610
|
-
}
|
|
96611
|
-
});
|
|
96612
|
-
return response;
|
|
96613
|
-
}
|
|
96614
|
-
return fetch(url, {
|
|
96615
|
-
headers: {
|
|
96616
|
-
"User-Agent": "Mozilla/5.0 (compatible; DocGen/1.0)"
|
|
96617
|
-
}
|
|
96618
|
-
});
|
|
96619
|
-
}
|
|
96620
97466
|
async function embedExternalImages(html) {
|
|
96621
97467
|
const imgRegex = /<img\s+([^>]*?)src="(https?:\/\/[^"]+)"([^>]*)>/gi;
|
|
96622
97468
|
const matches2 = [...html.matchAll(imgRegex)];
|