@office-kit/pptx-preview 0.8.1 → 0.9.1
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/index.js +1 -1
- package/dist/node.js +1 -1
- package/dist/{src-BMb2-vud.js → src-C_bsFwWV.js} +138 -44
- package/dist/src-C_bsFwWV.js.map +1 -0
- package/package.json +2 -2
- package/dist/src-BMb2-vud.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as MONO, c as TIMES, d as substituteFamily, l as defaultMeasurer, n as renderSlideSvg, o as SANS, r as ARIAL, s as SERIF, t as auditTextLayout } from "./src-
|
|
1
|
+
import { a as MONO, c as TIMES, d as substituteFamily, l as defaultMeasurer, n as renderSlideSvg, o as SANS, r as ARIAL, s as SERIF, t as auditTextLayout } from "./src-C_bsFwWV.js";
|
|
2
2
|
export { ARIAL, MONO, SANS, SERIF, TIMES, auditTextLayout, defaultMeasurer, renderSlideSvg as renderSlideToSvg, substituteFamily };
|
package/dist/node.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as MONO, c as TIMES, d as substituteFamily, i as AVG_GLYPH_W_RATIO, l as defaultMeasurer, n as renderSlideSvg, o as SANS, r as ARIAL, s as SERIF, t as auditTextLayout, u as isCjk } from "./src-
|
|
1
|
+
import { a as MONO, c as TIMES, d as substituteFamily, i as AVG_GLYPH_W_RATIO, l as defaultMeasurer, n as renderSlideSvg, o as SANS, r as ARIAL, s as SERIF, t as auditTextLayout, u as isCjk } from "./src-C_bsFwWV.js";
|
|
2
2
|
import { getSlideSize } from "@office-kit/pptx";
|
|
3
3
|
import { Resvg } from "@resvg/resvg-js";
|
|
4
4
|
import * as fontkit from "fontkit";
|
|
@@ -32,6 +32,29 @@ const FALLBACK_DESCENT = .22;
|
|
|
32
32
|
const FALLBACK_LINEGAP = .08;
|
|
33
33
|
const BASELINE_LEADING_DROP = .036;
|
|
34
34
|
const GRID_NUDGE_X = -.75;
|
|
35
|
+
const EAST_ASIAN_CHAR = /[ᄀ-ᅟ⺀-〾ぁ-㏿㐀-䶿一-鿿ꀀ-가-힣豈-︰-﹏-⦆¢-₩]/;
|
|
36
|
+
const CLOSING_PUNCT = /^[、。,.・)」』】〉》”’!?:;ー〜…,.!?:;)\]}]+$/;
|
|
37
|
+
const OPENING_PUNCT = /^[(「『【〈《“‘([{]+$/;
|
|
38
|
+
const splitEastAsianBreakables = (word) => {
|
|
39
|
+
if (!EAST_ASIAN_CHAR.test(word)) return [word];
|
|
40
|
+
const parts = [];
|
|
41
|
+
let latin = "";
|
|
42
|
+
for (const ch of word) if (EAST_ASIAN_CHAR.test(ch)) {
|
|
43
|
+
if (latin !== "") {
|
|
44
|
+
parts.push(latin);
|
|
45
|
+
latin = "";
|
|
46
|
+
}
|
|
47
|
+
parts.push(ch);
|
|
48
|
+
} else latin += ch;
|
|
49
|
+
if (latin !== "") parts.push(latin);
|
|
50
|
+
const glued = [];
|
|
51
|
+
for (const part of parts) {
|
|
52
|
+
const prev = glued.at(-1);
|
|
53
|
+
if (prev !== void 0 && (CLOSING_PUNCT.test(part) || OPENING_PUNCT.test(prev))) glued[glued.length - 1] = prev + part;
|
|
54
|
+
else glued.push(part);
|
|
55
|
+
}
|
|
56
|
+
return glued;
|
|
57
|
+
};
|
|
35
58
|
const specOf = (piece) => ({
|
|
36
59
|
family: piece.family,
|
|
37
60
|
sizePx: piece.sizePx,
|
|
@@ -113,23 +136,25 @@ const layoutCore = (input, measure) => {
|
|
|
113
136
|
});
|
|
114
137
|
continue;
|
|
115
138
|
}
|
|
116
|
-
for (const
|
|
117
|
-
const isSpace = /^\s+$/.test(
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
139
|
+
for (const word of piece.text.match(/\s+|\S+/g) ?? []) {
|
|
140
|
+
const isSpace = /^\s+$/.test(word);
|
|
141
|
+
for (const seg of isSpace ? [word] : splitEastAsianBreakables(word)) {
|
|
142
|
+
const w = mWidth(seg, specOf(piece));
|
|
143
|
+
if (input.wrap && !isSpace && w > avail - bulletLead && [...seg].length > 1) for (const ch of seg) tokens.push({
|
|
144
|
+
text: ch,
|
|
145
|
+
piece,
|
|
146
|
+
isSpace: false,
|
|
147
|
+
isBreak: false,
|
|
148
|
+
width: mWidth(ch, specOf(piece))
|
|
149
|
+
});
|
|
150
|
+
else tokens.push({
|
|
151
|
+
text: seg,
|
|
152
|
+
piece,
|
|
153
|
+
isSpace,
|
|
154
|
+
isBreak: false,
|
|
155
|
+
width: w
|
|
156
|
+
});
|
|
157
|
+
}
|
|
133
158
|
}
|
|
134
159
|
}
|
|
135
160
|
const wrapped = wrapTokens(tokens, input.wrap, wrapRight - firstLeft - bulletLead, avail);
|
|
@@ -2628,16 +2653,20 @@ const renderValueAxis = (f, axis) => {
|
|
|
2628
2653
|
const tickLen = AXIS_TICK_LEN;
|
|
2629
2654
|
for (const t of ticks) if (axis.orientation === "vertical") {
|
|
2630
2655
|
const yp = f.plotY + f.plotH - (t - axis.min) / range * f.plotH;
|
|
2656
|
+
const onRight = axis.side === "right";
|
|
2657
|
+
const edgeX = onRight ? f.plotX + f.plotW : f.plotX;
|
|
2631
2658
|
if (showGrid) out.push(`<line x1="${px(f.plotX)}" y1="${px(yp)}" x2="${px(f.plotX + f.plotW)}" y2="${px(yp)}" stroke="${gridStroke}" stroke-width="0.5"/>`);
|
|
2632
2659
|
if (tickMark !== "none") {
|
|
2633
|
-
const
|
|
2634
|
-
const
|
|
2660
|
+
const outward = onRight ? tickLen : -5;
|
|
2661
|
+
const inward = onRight ? -5 : tickLen;
|
|
2662
|
+
const tx1 = tickMark === "in" ? edgeX : edgeX + outward;
|
|
2663
|
+
const tx2 = tickMark === "out" ? edgeX : edgeX + inward;
|
|
2635
2664
|
out.push(`<line x1="${px(tx1)}" y1="${px(yp)}" x2="${px(tx2)}" y2="${px(yp)}" stroke="${axisColor}" stroke-width="1"/>`);
|
|
2636
2665
|
}
|
|
2637
|
-
const labelX =
|
|
2666
|
+
const labelX = onRight ? edgeX + 4 : edgeX - 4;
|
|
2638
2667
|
const rot = axis.labelRotationDeg ?? 0;
|
|
2639
2668
|
const transform = rot ? ` transform="rotate(${rot} ${px(labelX)} ${px(yp)})"` : "";
|
|
2640
|
-
out.push(`<text x="${px(labelX)}" y="${px(yp)}" text-anchor="end" dominant-baseline="middle" ${axisTickAttrs(axis.labelStyle)}${transform}>${escapeXml(fmtTick(t))}</text>`);
|
|
2669
|
+
out.push(`<text x="${px(labelX)}" y="${px(yp)}" text-anchor="${onRight ? "start" : "end"}" dominant-baseline="middle" ${axisTickAttrs(axis.labelStyle)}${transform}>${escapeXml(fmtTick(t))}</text>`);
|
|
2641
2670
|
} else {
|
|
2642
2671
|
const xp = f.plotX + (t - axis.min) / range * f.plotW;
|
|
2643
2672
|
if (showGrid) out.push(`<line x1="${px(xp)}" y1="${px(f.plotY)}" x2="${px(xp)}" y2="${px(f.plotY + f.plotH)}" stroke="${gridStroke}" stroke-width="0.5"/>`);
|
|
@@ -2768,6 +2797,12 @@ const renderChartTitle = (f, title, style) => {
|
|
|
2768
2797
|
const fontStyleAttr = style?.italic ? " font-style=\"italic\"" : "";
|
|
2769
2798
|
return `<text x="${px(f.x + f.w / 2)}" y="${px(f.titleY)}" text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="${chartFontPx(sz)}" fill="${fill}" font-weight="${weight}"${fontStyleAttr}>${escapeXml(title)}</text>`;
|
|
2770
2799
|
};
|
|
2800
|
+
const FULLWIDTH_CHAR_PATTERN = /[\u1100-\u115F\u2E80-\u303E\u3041-\u33FF\u3400-\u4DBF\u4E00-\u9FFF\uA000-\uA4CF\uAC00-\uD7A3\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFF60\uFFE0-\uFFE6]/u;
|
|
2801
|
+
const approxLegendTextPx = (text, fontPx) => {
|
|
2802
|
+
let units = 0;
|
|
2803
|
+
for (const ch of text) units += FULLWIDTH_CHAR_PATTERN.test(ch) ? 1 : .55;
|
|
2804
|
+
return units * fontPx;
|
|
2805
|
+
};
|
|
2771
2806
|
const renderChartLegend = (f, names, colors, position = "b", textStyle, markerSymbols) => {
|
|
2772
2807
|
if (names.length === 0) return "";
|
|
2773
2808
|
const sz = textStyle?.sizePt ?? 11;
|
|
@@ -2785,33 +2820,27 @@ const renderChartLegend = (f, names, colors, position = "b", textStyle, markerSy
|
|
|
2785
2820
|
return `<rect x="${px(swatchX)}" y="${px(swatchY)}" width="9" height="9" fill="${color}"/>`;
|
|
2786
2821
|
};
|
|
2787
2822
|
const out = [];
|
|
2788
|
-
if (position === "b") {
|
|
2789
|
-
const
|
|
2790
|
-
const
|
|
2791
|
-
const
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
}
|
|
2798
|
-
return out.join("");
|
|
2799
|
-
}
|
|
2800
|
-
if (position === "t") {
|
|
2801
|
-
const itemPx = Math.min(140, f.w / names.length);
|
|
2802
|
-
const totalW = itemPx * names.length;
|
|
2803
|
-
const startX = f.x + (f.w - totalW) / 2;
|
|
2804
|
-
const yTop = f.y + 4;
|
|
2823
|
+
if (position === "b" || position === "t") {
|
|
2824
|
+
const swatchGapPx = 14;
|
|
2825
|
+
const itemGapPx = 12;
|
|
2826
|
+
const labelWidths = names.map((name, i) => approxLegendTextPx(name ?? `Series ${i + 1}`, sz * PX_PER_PT));
|
|
2827
|
+
const naturalTotal = labelWidths.reduce((sum, w) => sum + swatchGapPx + w, 0) + itemGapPx * (names.length - 1);
|
|
2828
|
+
const scale = Math.min(1, f.w / Math.max(1, naturalTotal));
|
|
2829
|
+
const effAttrs = scale < 1 ? `font-family="sans-serif" font-size="${chartFontPx(sz * scale)}" fill="${fill}"${weight}${italic}` : textAttrs;
|
|
2830
|
+
const rowY = position === "b" ? f.legendY : f.y + 12;
|
|
2831
|
+
let cursor = f.x + Math.max(0, (f.w - naturalTotal * scale) / 2);
|
|
2805
2832
|
for (let i = 0; i < names.length; i++) {
|
|
2806
|
-
|
|
2807
|
-
|
|
2833
|
+
out.push(swatch(i, cursor, rowY - 4), `<text x="${px(cursor + swatchGapPx * scale)}" y="${px(rowY)}" dominant-baseline="middle" ${effAttrs}>${escapeXml(names[i] ?? `Series ${i + 1}`)}</text>`);
|
|
2834
|
+
cursor += (swatchGapPx + (labelWidths[i] ?? 0) + itemGapPx) * scale;
|
|
2808
2835
|
}
|
|
2809
2836
|
return out.join("");
|
|
2810
2837
|
}
|
|
2811
2838
|
const lineH = 14;
|
|
2812
2839
|
const totalH = names.length * lineH;
|
|
2813
2840
|
const yStart = position === "tr" ? f.y + 12 : Math.max(f.y + 12, f.y + (f.h - totalH) / 2);
|
|
2814
|
-
const
|
|
2841
|
+
const maxLabelPx = Math.max(0, ...names.map((name, i) => approxLegendTextPx(name ?? `Series ${i + 1}`, sz * PX_PER_PT)));
|
|
2842
|
+
const rightColW = Math.min(f.w * .45, 14 + maxLabelPx + 4);
|
|
2843
|
+
const xCol = position === "l" ? f.x + 6 : f.x + f.w - rightColW;
|
|
2815
2844
|
for (let i = 0; i < names.length; i++) {
|
|
2816
2845
|
const yp = yStart + i * lineH;
|
|
2817
2846
|
out.push(swatch(i, xCol, yp - 4), `<text x="${px(xCol + 14)}" y="${px(yp + 4)}" dominant-baseline="middle" ${textAttrs}>${escapeXml(names[i] ?? `Series ${i + 1}`)}</text>`);
|
|
@@ -3614,7 +3643,72 @@ const renderChart = (shape, x, y, w, h, transform, theme) => {
|
|
|
3614
3643
|
for (const s of spec.series) for (const v of s.values) if (v !== null && Number.isFinite(v)) finiteCount++;
|
|
3615
3644
|
let plot = "";
|
|
3616
3645
|
let axes = "";
|
|
3617
|
-
|
|
3646
|
+
const isCombo = isCartesian && spec.kind !== "bar" && spec.series.some((s) => s.chartKind !== void 0 && s.chartKind !== spec.kind || s.secondaryAxis === true);
|
|
3647
|
+
if (isCombo) {
|
|
3648
|
+
const baked = spec.series.map((s, i) => ({
|
|
3649
|
+
...s,
|
|
3650
|
+
color: s.color ?? colors[i % colors.length] ?? "#888"
|
|
3651
|
+
}));
|
|
3652
|
+
const primarySeries = baked.filter((s) => s.secondaryAxis !== true);
|
|
3653
|
+
const secondarySeries = baked.filter((s) => s.secondaryAxis === true);
|
|
3654
|
+
const primaryScale = seriesMinMax({
|
|
3655
|
+
...spec,
|
|
3656
|
+
series: primarySeries
|
|
3657
|
+
});
|
|
3658
|
+
const { valueAxis: _primaryOnlyAxis, ...specWithoutAxis } = spec;
|
|
3659
|
+
const secondaryScale = secondarySeries.length > 0 ? seriesMinMax({
|
|
3660
|
+
...specWithoutAxis,
|
|
3661
|
+
series: secondarySeries
|
|
3662
|
+
}) : null;
|
|
3663
|
+
const N = pointCount(spec);
|
|
3664
|
+
if (!spec.valueAxisHidden) axes = renderValueAxis(f, {
|
|
3665
|
+
orientation: "vertical",
|
|
3666
|
+
min: primaryScale.min,
|
|
3667
|
+
max: primaryScale.max,
|
|
3668
|
+
majorUnit: spec.valueAxis?.majorUnit ?? primaryScale.step,
|
|
3669
|
+
...spec.valueAxis?.numberFormat !== void 0 ? { numberFormat: spec.valueAxis.numberFormat } : {},
|
|
3670
|
+
...spec.valueAxisMajorGridlines !== void 0 ? { majorGridlines: spec.valueAxisMajorGridlines } : {},
|
|
3671
|
+
...spec.valueAxisLabelStyle !== void 0 ? { labelStyle: spec.valueAxisLabelStyle } : {}
|
|
3672
|
+
});
|
|
3673
|
+
if (secondaryScale) axes += renderValueAxis(f, {
|
|
3674
|
+
orientation: "vertical",
|
|
3675
|
+
side: "right",
|
|
3676
|
+
min: secondaryScale.min,
|
|
3677
|
+
max: secondaryScale.max,
|
|
3678
|
+
majorUnit: secondaryScale.step,
|
|
3679
|
+
majorGridlines: false,
|
|
3680
|
+
...spec.valueAxisLabelStyle !== void 0 ? { labelStyle: spec.valueAxisLabelStyle } : {}
|
|
3681
|
+
});
|
|
3682
|
+
if (N > 0 && !(spec.categoryAxisHidden || spec.categoryAxisTickLabelPos === "none")) axes += renderCategoryAxis(f, "horizontal", spec.categories, N, spec.categoryAxisTickLabelSkip ?? 1, spec.categoryAxisLabelStyle, spec.categoryAxisLabelRotationDeg, spec.categoryAxisLabelAlign, spec.categoryAxisLineColor);
|
|
3683
|
+
const groups = /* @__PURE__ */ new Map();
|
|
3684
|
+
for (const s of baked) {
|
|
3685
|
+
const kind = s.chartKind ?? spec.kind;
|
|
3686
|
+
const secondary = s.secondaryAxis === true;
|
|
3687
|
+
const key = `${kind}|${secondary ? "1" : "0"}`;
|
|
3688
|
+
const group = groups.get(key);
|
|
3689
|
+
if (group) group.series.push(s);
|
|
3690
|
+
else groups.set(key, {
|
|
3691
|
+
kind,
|
|
3692
|
+
secondary,
|
|
3693
|
+
series: [s]
|
|
3694
|
+
});
|
|
3695
|
+
}
|
|
3696
|
+
const paintOrder = (g) => (g.secondary ? 2 : 0) + (g.kind === "line" || g.kind === "area" ? 1 : 0);
|
|
3697
|
+
for (const group of [...groups.values()].sort((a, b) => paintOrder(a) - paintOrder(b))) {
|
|
3698
|
+
const scale = group.secondary && secondaryScale ? secondaryScale : primaryScale;
|
|
3699
|
+
const groupSpec = {
|
|
3700
|
+
...spec,
|
|
3701
|
+
series: group.series,
|
|
3702
|
+
valueAxis: {
|
|
3703
|
+
min: scale.min,
|
|
3704
|
+
max: scale.max
|
|
3705
|
+
}
|
|
3706
|
+
};
|
|
3707
|
+
if (group.kind === "line" || group.kind === "area") plot += renderLineChart(f, groupSpec, colors, group.kind === "area");
|
|
3708
|
+
else plot += renderColumnChart(f, groupSpec, colors);
|
|
3709
|
+
}
|
|
3710
|
+
}
|
|
3711
|
+
if (!isCombo && isCartesian) {
|
|
3618
3712
|
const { min, max, step } = seriesMinMax(spec);
|
|
3619
3713
|
const N = pointCount(spec);
|
|
3620
3714
|
const majorUnit = spec.valueAxis?.majorUnit ?? step;
|
|
@@ -3648,7 +3742,7 @@ const renderChart = (shape, x, y, w, h, transform, theme) => {
|
|
|
3648
3742
|
const labelsHidden = spec.categoryAxisHidden || spec.categoryAxisTickLabelPos === "none";
|
|
3649
3743
|
if (N > 0 && !labelsHidden) axes += renderCategoryAxis(f, spec.kind === "bar" ? "vertical" : "horizontal", spec.categories, N, spec.categoryAxisTickLabelSkip ?? 1, spec.categoryAxisLabelStyle, spec.categoryAxisLabelRotationDeg, spec.categoryAxisLabelAlign, spec.categoryAxisLineColor);
|
|
3650
3744
|
}
|
|
3651
|
-
switch (spec.kind) {
|
|
3745
|
+
if (!isCombo) switch (spec.kind) {
|
|
3652
3746
|
case "column":
|
|
3653
3747
|
case "bar":
|
|
3654
3748
|
plot = spec.kind === "column" ? renderColumnChart(f, spec, colors) : renderBarChart(f, spec, colors);
|
|
@@ -4591,4 +4685,4 @@ const auditTextLayout = (pres, options = {}) => {
|
|
|
4591
4685
|
//#endregion
|
|
4592
4686
|
export { MONO as a, TIMES as c, substituteFamily as d, AVG_GLYPH_W_RATIO as i, defaultMeasurer as l, renderSlideSvg as n, SANS as o, ARIAL as r, SERIF as s, auditTextLayout as t, isCjk as u };
|
|
4593
4687
|
|
|
4594
|
-
//# sourceMappingURL=src-
|
|
4688
|
+
//# sourceMappingURL=src-C_bsFwWV.js.map
|