@json-to-office/core-docx 7.1.2 → 7.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/dist/index.js +1647 -427
- package/dist/index.js.map +1 -1
- package/dist/ir/chartValues.d.ts +16 -0
- package/dist/ir/chartValues.d.ts.map +1 -0
- package/dist/ir/compiler.d.ts.map +1 -1
- package/dist/ir/features.d.ts.map +1 -1
- package/dist/ir/theme.d.ts +43 -0
- package/dist/ir/theme.d.ts.map +1 -0
- package/dist/ir/types.d.ts +45 -3
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/ir/units.d.ts +12 -0
- package/dist/ir/units.d.ts.map +1 -1
- package/dist/ir/validation.d.ts +2 -1
- package/dist/ir/validation.d.ts.map +1 -1
- package/dist/plugin/example/index.js +1644 -424
- package/dist/plugin/example/index.js.map +1 -1
- package/dist/quality/text-inventory.d.ts +13 -3
- package/dist/quality/text-inventory.d.ts.map +1 -1
- package/dist/renderers/chartText.d.ts +43 -0
- package/dist/renderers/chartText.d.ts.map +1 -0
- package/dist/renderers/docxjs/charts.d.ts +45 -0
- package/dist/renderers/docxjs/charts.d.ts.map +1 -0
- package/dist/renderers/docxjs/docxSubpath.d.ts +34 -0
- package/dist/renderers/docxjs/docxSubpath.d.ts.map +1 -0
- package/dist/renderers/docxjs/drawingGroup.d.ts +79 -0
- package/dist/renderers/docxjs/drawingGroup.d.ts.map +1 -0
- package/dist/renderers/docxjs/drawingGroupRepair.d.ts +36 -0
- package/dist/renderers/docxjs/drawingGroupRepair.d.ts.map +1 -0
- package/dist/renderers/docxjs/emit.d.ts +10 -2
- package/dist/renderers/docxjs/emit.d.ts.map +1 -1
- package/dist/renderers/docxjs/index.d.ts +2 -1
- package/dist/renderers/docxjs/index.d.ts.map +1 -1
- package/dist/renderers/docxjs/presetShapes.d.ts +233 -0
- package/dist/renderers/docxjs/presetShapes.d.ts.map +1 -0
- package/dist/renderers/office-open/chartLook.d.ts +45 -0
- package/dist/renderers/office-open/chartLook.d.ts.map +1 -0
- package/dist/renderers/office-open/chartParts.d.ts +29 -15
- package/dist/renderers/office-open/chartParts.d.ts.map +1 -1
- package/dist/renderers/office-open/emit.d.ts +25 -17
- package/dist/renderers/office-open/emit.d.ts.map +1 -1
- package/dist/renderers/office-open/index.d.ts +16 -3
- package/dist/renderers/office-open/index.d.ts.map +1 -1
- package/dist/renderers/office-open/themePart.d.ts +28 -0
- package/dist/renderers/office-open/themePart.d.ts.map +1 -0
- package/dist/styles/themeToStyles.d.ts.map +1 -1
- package/dist/styles/utils/styleHelpers.d.ts +3 -1
- package/dist/styles/utils/styleHelpers.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/chartWorkbook.d.ts +2 -1
- package/dist/utils/chartWorkbook.d.ts.map +1 -1
- package/dist/utils/fixFloatingImageIds.d.ts +17 -9
- package/dist/utils/fixFloatingImageIds.d.ts.map +1 -1
- package/dist/utils/packageDocument.d.ts.map +1 -1
- package/package.json +7 -7
|
@@ -1804,15 +1804,15 @@ function convertLineSpacing(lineSpacing) {
|
|
|
1804
1804
|
lineRule2 = "auto";
|
|
1805
1805
|
break;
|
|
1806
1806
|
case "atLeast":
|
|
1807
|
-
line = value !== void 0 ? value
|
|
1807
|
+
line = value !== void 0 ? pointsToTwips(value) : void 0;
|
|
1808
1808
|
lineRule2 = "atLeast";
|
|
1809
1809
|
break;
|
|
1810
1810
|
case "exactly":
|
|
1811
|
-
line = value !== void 0 ? value
|
|
1811
|
+
line = value !== void 0 ? pointsToTwips(value) : void 0;
|
|
1812
1812
|
lineRule2 = "exact";
|
|
1813
1813
|
break;
|
|
1814
1814
|
case "multiple":
|
|
1815
|
-
line = value !== void 0 ? value * SINGLE_LINE_SPACING_TWIPS : void 0;
|
|
1815
|
+
line = value !== void 0 ? Math.round(value * SINGLE_LINE_SPACING_TWIPS) : void 0;
|
|
1816
1816
|
lineRule2 = "auto";
|
|
1817
1817
|
break;
|
|
1818
1818
|
default:
|
|
@@ -2751,7 +2751,7 @@ var init_imageUtils = __esm({
|
|
|
2751
2751
|
});
|
|
2752
2752
|
|
|
2753
2753
|
// src/ir/types.ts
|
|
2754
|
-
var TWIPS_PER_INCH, TWIPS_PER_POINT2, EMU_PER_INCH, EMU_PER_TWIP, DOCX_IR_SCHEMA_VERSION, DOCX_IR_BORDER_STYLES;
|
|
2754
|
+
var TWIPS_PER_INCH, TWIPS_PER_POINT2, EMU_PER_INCH, EMU_PER_TWIP, DOCX_IR_SCHEMA_VERSION, NOT_XML_CHAR, DOCX_IR_BORDER_STYLES;
|
|
2755
2755
|
var init_types = __esm({
|
|
2756
2756
|
"src/ir/types.ts"() {
|
|
2757
2757
|
"use strict";
|
|
@@ -2760,6 +2760,7 @@ var init_types = __esm({
|
|
|
2760
2760
|
EMU_PER_INCH = 914400;
|
|
2761
2761
|
EMU_PER_TWIP = EMU_PER_INCH / TWIPS_PER_INCH;
|
|
2762
2762
|
DOCX_IR_SCHEMA_VERSION = 1;
|
|
2763
|
+
NOT_XML_CHAR = /[^\t\n\r\u0020-\uD7FF\uE000-\uFFFD\u{10000}-\u{10FFFF}]/u;
|
|
2763
2764
|
DOCX_IR_BORDER_STYLES = [
|
|
2764
2765
|
"single",
|
|
2765
2766
|
"dashDotStroked",
|
|
@@ -2797,6 +2798,9 @@ import { createHash as createHash2 } from "crypto";
|
|
|
2797
2798
|
function pointsToTwips2(points) {
|
|
2798
2799
|
return Math.round(points * TWIPS_PER_POINT2);
|
|
2799
2800
|
}
|
|
2801
|
+
function wholeTwips(twips2) {
|
|
2802
|
+
return Math.round(twips2);
|
|
2803
|
+
}
|
|
2800
2804
|
function pointsToHalfPoints(points) {
|
|
2801
2805
|
return Math.round(points * 2);
|
|
2802
2806
|
}
|
|
@@ -2812,8 +2816,8 @@ function inchesToEmu(inches) {
|
|
|
2812
2816
|
function pointsToEmu(points) {
|
|
2813
2817
|
return Math.round(points * EMU_PER_INCH / 72);
|
|
2814
2818
|
}
|
|
2815
|
-
function twipsToEmu(
|
|
2816
|
-
return Math.round(
|
|
2819
|
+
function twipsToEmu(twips2) {
|
|
2820
|
+
return Math.round(twips2 * EMU_PER_TWIP);
|
|
2817
2821
|
}
|
|
2818
2822
|
function pixelsToEmu(pixels) {
|
|
2819
2823
|
return Math.round(pixels * 9525);
|
|
@@ -2821,8 +2825,8 @@ function pixelsToEmu(pixels) {
|
|
|
2821
2825
|
function emuToPixels(emu) {
|
|
2822
2826
|
return emu / 9525;
|
|
2823
2827
|
}
|
|
2824
|
-
function twipsToPixels(
|
|
2825
|
-
return
|
|
2828
|
+
function twipsToPixels(twips2) {
|
|
2829
|
+
return twips2 / TWIPS_PER_INCH * 96;
|
|
2826
2830
|
}
|
|
2827
2831
|
function irColor(hex) {
|
|
2828
2832
|
return { hex: hex.startsWith("#") ? hex.slice(1) : hex };
|
|
@@ -2843,6 +2847,226 @@ var init_units = __esm({
|
|
|
2843
2847
|
}
|
|
2844
2848
|
});
|
|
2845
2849
|
|
|
2850
|
+
// src/ir/chartValues.ts
|
|
2851
|
+
function isNumericLabel(label) {
|
|
2852
|
+
return NUMERIC_LABEL.test(label.trim());
|
|
2853
|
+
}
|
|
2854
|
+
function scatterX(labels, index) {
|
|
2855
|
+
const label = labels[index];
|
|
2856
|
+
return label !== void 0 && isNumericLabel(label) ? Number(label) : index + 1;
|
|
2857
|
+
}
|
|
2858
|
+
var NUMERIC_LABEL;
|
|
2859
|
+
var init_chartValues = __esm({
|
|
2860
|
+
"src/ir/chartValues.ts"() {
|
|
2861
|
+
"use strict";
|
|
2862
|
+
NUMERIC_LABEL = /^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;
|
|
2863
|
+
}
|
|
2864
|
+
});
|
|
2865
|
+
|
|
2866
|
+
// src/renderers/chartText.ts
|
|
2867
|
+
function chartTextRoles(font) {
|
|
2868
|
+
const { bold, ...rest } = font;
|
|
2869
|
+
const text = rest;
|
|
2870
|
+
return {
|
|
2871
|
+
text,
|
|
2872
|
+
axisTitle: { ...text, bold },
|
|
2873
|
+
title: {
|
|
2874
|
+
...text,
|
|
2875
|
+
fontSize: Math.round(text.fontSize * CHART_TITLE_SCALE),
|
|
2876
|
+
bold: true
|
|
2877
|
+
}
|
|
2878
|
+
};
|
|
2879
|
+
}
|
|
2880
|
+
var CHART_TITLE_SCALE;
|
|
2881
|
+
var init_chartText = __esm({
|
|
2882
|
+
"src/renderers/chartText.ts"() {
|
|
2883
|
+
"use strict";
|
|
2884
|
+
CHART_TITLE_SCALE = 1.4;
|
|
2885
|
+
}
|
|
2886
|
+
});
|
|
2887
|
+
|
|
2888
|
+
// src/renderers/docxjs/docxSubpath.ts
|
|
2889
|
+
function docxSubpath(specifier, component, importer) {
|
|
2890
|
+
let module;
|
|
2891
|
+
let failure;
|
|
2892
|
+
let loading;
|
|
2893
|
+
return {
|
|
2894
|
+
specifier,
|
|
2895
|
+
load() {
|
|
2896
|
+
loading ??= importer().then(
|
|
2897
|
+
(loadedModule) => {
|
|
2898
|
+
module = loadedModule;
|
|
2899
|
+
},
|
|
2900
|
+
(reason) => {
|
|
2901
|
+
failure = { reason };
|
|
2902
|
+
}
|
|
2903
|
+
);
|
|
2904
|
+
return loading;
|
|
2905
|
+
},
|
|
2906
|
+
loaded: () => module !== void 0,
|
|
2907
|
+
get() {
|
|
2908
|
+
if (module !== void 0) return module;
|
|
2909
|
+
if (failure !== void 0) {
|
|
2910
|
+
const { reason } = failure;
|
|
2911
|
+
const detail = reason instanceof Error ? reason.message : String(reason);
|
|
2912
|
+
throw new Error(
|
|
2913
|
+
`The docx \`${component}\` component needs docx 9.8.0 or later: the \`${specifier}\` entry could not be loaded (${detail})`
|
|
2914
|
+
);
|
|
2915
|
+
}
|
|
2916
|
+
throw new Error(
|
|
2917
|
+
`${specifier} is not loaded: await its load() before buildDocument() (render() does)`
|
|
2918
|
+
);
|
|
2919
|
+
}
|
|
2920
|
+
};
|
|
2921
|
+
}
|
|
2922
|
+
var init_docxSubpath = __esm({
|
|
2923
|
+
"src/renderers/docxjs/docxSubpath.ts"() {
|
|
2924
|
+
"use strict";
|
|
2925
|
+
}
|
|
2926
|
+
});
|
|
2927
|
+
|
|
2928
|
+
// src/renderers/docxjs/charts.ts
|
|
2929
|
+
import { assertNever } from "@json-to-office/shared/rendering";
|
|
2930
|
+
function loadDocxCharts() {
|
|
2931
|
+
return charts.load();
|
|
2932
|
+
}
|
|
2933
|
+
function chartFont(role) {
|
|
2934
|
+
return {
|
|
2935
|
+
name: role.fontFamily,
|
|
2936
|
+
size: role.fontSize,
|
|
2937
|
+
color: role.color,
|
|
2938
|
+
bold: role.bold ?? false
|
|
2939
|
+
};
|
|
2940
|
+
}
|
|
2941
|
+
function chartRunOptions(chart, floating) {
|
|
2942
|
+
const roles = chartTextRoles(chart.textFont);
|
|
2943
|
+
const text = chartFont(roles.text);
|
|
2944
|
+
const axisTitle = chartFont(roles.axisTitle);
|
|
2945
|
+
const palette = chart.colors;
|
|
2946
|
+
const colorAt = (index) => palette.length > 0 ? palette[index % palette.length] : void 0;
|
|
2947
|
+
const withColor = (index) => {
|
|
2948
|
+
const color = colorAt(index);
|
|
2949
|
+
return color ? { color } : {};
|
|
2950
|
+
};
|
|
2951
|
+
const seriesName = (index) => chart.series[index].name ?? `Series ${index + 1}`;
|
|
2952
|
+
const categories = chart.series[0]?.labels ?? [];
|
|
2953
|
+
const axis = (title) => ({
|
|
2954
|
+
...title ? { title: { text: title, font: axisTitle } } : {},
|
|
2955
|
+
font: text
|
|
2956
|
+
});
|
|
2957
|
+
const common = {
|
|
2958
|
+
...chart.title && chart.showTitle !== false ? { title: { text: chart.title, font: chartFont(roles.title) } } : {},
|
|
2959
|
+
legend: chart.showLegend === false ? false : {
|
|
2960
|
+
position: LEGEND_POSITION[chart.legendPosition ?? "b"],
|
|
2961
|
+
font: text
|
|
2962
|
+
},
|
|
2963
|
+
font: { name: roles.text.fontFamily, color: roles.text.color },
|
|
2964
|
+
// Office-open's chart space is unfilled and unbordered; `ChartRun`'s
|
|
2965
|
+
// default is Word's white fill and grey border.
|
|
2966
|
+
chartArea: { fill: "none", border: "none" },
|
|
2967
|
+
transformation: {
|
|
2968
|
+
width: emuToPixels(chart.widthEmu),
|
|
2969
|
+
height: emuToPixels(chart.heightEmu)
|
|
2970
|
+
},
|
|
2971
|
+
// Without an authored description `ChartRun` describes the chart from
|
|
2972
|
+
// its data, which is deterministic; the name stays empty, as it is on
|
|
2973
|
+
// every other drawing this renderer writes.
|
|
2974
|
+
...chart.altText ? { altText: { name: "", description: chart.altText } } : {},
|
|
2975
|
+
...floating ? { floating } : {}
|
|
2976
|
+
};
|
|
2977
|
+
switch (chart.chartType) {
|
|
2978
|
+
case "column":
|
|
2979
|
+
case "bar":
|
|
2980
|
+
case "area":
|
|
2981
|
+
case "line":
|
|
2982
|
+
return {
|
|
2983
|
+
...common,
|
|
2984
|
+
type: chart.chartType,
|
|
2985
|
+
categories,
|
|
2986
|
+
...chart.chartType === "line" ? { markers: true } : {},
|
|
2987
|
+
series: chart.series.map((entry, index) => ({
|
|
2988
|
+
name: seriesName(index),
|
|
2989
|
+
values: entry.values,
|
|
2990
|
+
...withColor(index)
|
|
2991
|
+
})),
|
|
2992
|
+
categoryAxis: axis(chart.categoryAxisTitle),
|
|
2993
|
+
valueAxis: axis(chart.valueAxisTitle)
|
|
2994
|
+
};
|
|
2995
|
+
case "pie":
|
|
2996
|
+
case "doughnut":
|
|
2997
|
+
return {
|
|
2998
|
+
...common,
|
|
2999
|
+
type: chart.chartType,
|
|
3000
|
+
categories,
|
|
3001
|
+
series: chart.series.map((entry, index) => ({
|
|
3002
|
+
name: seriesName(index),
|
|
3003
|
+
values: entry.values,
|
|
3004
|
+
...palette.length > 0 ? { colors: entry.values.map((_, point) => colorAt(point)) } : {}
|
|
3005
|
+
}))
|
|
3006
|
+
};
|
|
3007
|
+
case "radar":
|
|
3008
|
+
return {
|
|
3009
|
+
...common,
|
|
3010
|
+
type: "radar",
|
|
3011
|
+
categories,
|
|
3012
|
+
markers: true,
|
|
3013
|
+
series: chart.series.map((entry, index) => ({
|
|
3014
|
+
name: seriesName(index),
|
|
3015
|
+
values: entry.values,
|
|
3016
|
+
...withColor(index)
|
|
3017
|
+
})),
|
|
3018
|
+
categoryAxis: axis(chart.categoryAxisTitle),
|
|
3019
|
+
valueAxis: axis(chart.valueAxisTitle)
|
|
3020
|
+
};
|
|
3021
|
+
case "scatter":
|
|
3022
|
+
return {
|
|
3023
|
+
...common,
|
|
3024
|
+
type: "scatter",
|
|
3025
|
+
markers: true,
|
|
3026
|
+
lines: "straight",
|
|
3027
|
+
series: chart.series.map((entry, index) => ({
|
|
3028
|
+
name: seriesName(index),
|
|
3029
|
+
points: entry.values.map((y, point) => ({
|
|
3030
|
+
x: scatterX(entry.labels, point),
|
|
3031
|
+
y
|
|
3032
|
+
})),
|
|
3033
|
+
...withColor(index)
|
|
3034
|
+
})),
|
|
3035
|
+
xAxis: { ...axis(chart.categoryAxisTitle), gridlines: false },
|
|
3036
|
+
yAxis: axis(chart.valueAxisTitle)
|
|
3037
|
+
};
|
|
3038
|
+
case "bubble":
|
|
3039
|
+
throw new Error(
|
|
3040
|
+
"the docxjs renderer has no emitter for a bubble chart; the compiler should have refused it"
|
|
3041
|
+
);
|
|
3042
|
+
default:
|
|
3043
|
+
return assertNever(chart.chartType, "DocxIrChartType");
|
|
3044
|
+
}
|
|
3045
|
+
}
|
|
3046
|
+
function emitChart(chart, floating) {
|
|
3047
|
+
return new (charts.get()).ChartRun(
|
|
3048
|
+
chartRunOptions(chart, floating)
|
|
3049
|
+
);
|
|
3050
|
+
}
|
|
3051
|
+
var charts, LEGEND_POSITION;
|
|
3052
|
+
var init_charts = __esm({
|
|
3053
|
+
"src/renderers/docxjs/charts.ts"() {
|
|
3054
|
+
"use strict";
|
|
3055
|
+
init_chartValues();
|
|
3056
|
+
init_units();
|
|
3057
|
+
init_chartText();
|
|
3058
|
+
init_docxSubpath();
|
|
3059
|
+
charts = docxSubpath("docx/charts", "chart", () => import("docx/charts"));
|
|
3060
|
+
LEGEND_POSITION = {
|
|
3061
|
+
b: "bottom",
|
|
3062
|
+
l: "left",
|
|
3063
|
+
r: "right",
|
|
3064
|
+
t: "top",
|
|
3065
|
+
tr: "topRight"
|
|
3066
|
+
};
|
|
3067
|
+
}
|
|
3068
|
+
});
|
|
3069
|
+
|
|
2846
3070
|
// src/renderers/docxjs/emit.ts
|
|
2847
3071
|
import {
|
|
2848
3072
|
AlignmentType,
|
|
@@ -2878,7 +3102,7 @@ import {
|
|
|
2878
3102
|
WidthType,
|
|
2879
3103
|
WpsShapeRun
|
|
2880
3104
|
} from "docx";
|
|
2881
|
-
import { assertNever } from "@json-to-office/shared/rendering";
|
|
3105
|
+
import { assertNever as assertNever2 } from "@json-to-office/shared/rendering";
|
|
2882
3106
|
function complexField(instruction, formatting, leading, cachedText) {
|
|
2883
3107
|
const options = runOptions(formatting);
|
|
2884
3108
|
const fieldChar = (type, extra = {}) => new TextRun({
|
|
@@ -2915,7 +3139,12 @@ function runOptions(formatting) {
|
|
|
2915
3139
|
if (formatting.bold !== void 0) options.bold = formatting.bold;
|
|
2916
3140
|
if (formatting.italic !== void 0) options.italics = formatting.italic;
|
|
2917
3141
|
if (formatting.underline !== void 0) {
|
|
2918
|
-
options.underline = formatting.underline ? {
|
|
3142
|
+
options.underline = formatting.underline ? {
|
|
3143
|
+
type: formatting.underline.type,
|
|
3144
|
+
// A native visual's text is the one place a run states its own
|
|
3145
|
+
// underline colour.
|
|
3146
|
+
...formatting.underline.color ? { color: formatting.underline.color.hex } : {}
|
|
3147
|
+
} : void 0;
|
|
2919
3148
|
}
|
|
2920
3149
|
if (formatting.strike !== void 0) options.strike = formatting.strike;
|
|
2921
3150
|
if (formatting.allCaps !== void 0) options.allCaps = formatting.allCaps;
|
|
@@ -3041,21 +3270,36 @@ function inlineChildren(children, resources = /* @__PURE__ */ new Map()) {
|
|
|
3041
3270
|
case "shape":
|
|
3042
3271
|
out.push(emitShape(child, resources));
|
|
3043
3272
|
break;
|
|
3044
|
-
case "drawingGroup":
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3273
|
+
case "drawingGroup": {
|
|
3274
|
+
const build = resources.drawingGroup;
|
|
3275
|
+
if (!build) {
|
|
3276
|
+
throw new Error(
|
|
3277
|
+
"the docxjs renderer was handed a drawing group without loading docx/shapes; render() loads it whenever the IR holds one"
|
|
3278
|
+
);
|
|
3279
|
+
}
|
|
3280
|
+
const pending = breakOption();
|
|
3281
|
+
if (pending.break) out.push(new TextRun(pending));
|
|
3282
|
+
out.push(build(child, resources));
|
|
3283
|
+
break;
|
|
3284
|
+
}
|
|
3285
|
+
case "chart": {
|
|
3286
|
+
const pending = breakOption();
|
|
3287
|
+
if (pending.break) out.push(new TextRun(pending));
|
|
3288
|
+
out.push(
|
|
3289
|
+
emitChart(
|
|
3290
|
+
child,
|
|
3291
|
+
child.floating ? floatingOptions(child.floating) : void 0
|
|
3292
|
+
)
|
|
3051
3293
|
);
|
|
3294
|
+
break;
|
|
3295
|
+
}
|
|
3052
3296
|
case "noteReference":
|
|
3053
3297
|
out.push(
|
|
3054
3298
|
child.noteKind === "endnote" ? new EndnoteReferenceRun(child.id) : new FootnoteReferenceRun(child.id)
|
|
3055
3299
|
);
|
|
3056
3300
|
break;
|
|
3057
3301
|
default:
|
|
3058
|
-
|
|
3302
|
+
assertNever2(child, "DocxIrInline");
|
|
3059
3303
|
}
|
|
3060
3304
|
}
|
|
3061
3305
|
return out;
|
|
@@ -3260,7 +3504,7 @@ function emitBlock(block2, resources = /* @__PURE__ */ new Map()) {
|
|
|
3260
3504
|
case "toc":
|
|
3261
3505
|
return emitToc(block2);
|
|
3262
3506
|
default:
|
|
3263
|
-
return
|
|
3507
|
+
return assertNever2(block2, "DocxIrBlock");
|
|
3264
3508
|
}
|
|
3265
3509
|
}
|
|
3266
3510
|
function emitToc(block2) {
|
|
@@ -3404,6 +3648,7 @@ var ALIGNMENT2, PAGE_FIELDS, isSequenceField, WRAP_TYPE, ThemedTableOfContents,
|
|
|
3404
3648
|
var init_emit = __esm({
|
|
3405
3649
|
"src/renderers/docxjs/emit.ts"() {
|
|
3406
3650
|
"use strict";
|
|
3651
|
+
init_charts();
|
|
3407
3652
|
ALIGNMENT2 = {
|
|
3408
3653
|
left: AlignmentType.LEFT,
|
|
3409
3654
|
center: AlignmentType.CENTER,
|
|
@@ -3702,10 +3947,13 @@ function canonicalizeRelationshipIds(zip) {
|
|
|
3702
3947
|
const rename = new Map(
|
|
3703
3948
|
ordered.map((id, index) => [id, `rId${highest + 1 + index}`])
|
|
3704
3949
|
);
|
|
3705
|
-
const rewrite = (xml) => xml.replace(
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3950
|
+
const rewrite = (xml) => xml.replace(
|
|
3951
|
+
/(\s[\w:.-]+=)"([^"]*)"/g,
|
|
3952
|
+
(whole, prefix, value) => {
|
|
3953
|
+
const replacement = rename.get(value);
|
|
3954
|
+
return replacement === void 0 ? whole : `${prefix}"${replacement}"`;
|
|
3955
|
+
}
|
|
3956
|
+
);
|
|
3709
3957
|
updates.push({ name: relsName, xml: rewrite(relsXml) });
|
|
3710
3958
|
if (partEntry) {
|
|
3711
3959
|
updates.push({ name: partName, xml: rewrite(partXml) });
|
|
@@ -3716,17 +3964,62 @@ function canonicalizeRelationshipIds(zip) {
|
|
|
3716
3964
|
if (entry) zip.updateFile(entry, Buffer.from(update.xml, "utf8"));
|
|
3717
3965
|
}
|
|
3718
3966
|
}
|
|
3967
|
+
function canonicalizeEmbeddedPackages(zip, generatedAt, depth = 1) {
|
|
3968
|
+
const names = zip.getEntries().map((entry) => entry.entryName).filter((name) => EMBEDDED_OFFICE_PACKAGE.test(name));
|
|
3969
|
+
let changed = false;
|
|
3970
|
+
for (const name of names) {
|
|
3971
|
+
const entry = zip.getEntry(name);
|
|
3972
|
+
if (!entry) continue;
|
|
3973
|
+
let nested;
|
|
3974
|
+
try {
|
|
3975
|
+
nested = new AdmZip(entry.getData());
|
|
3976
|
+
nested.getEntries();
|
|
3977
|
+
} catch {
|
|
3978
|
+
continue;
|
|
3979
|
+
}
|
|
3980
|
+
if (canonicalizeNestedPackage(nested, generatedAt, depth)) {
|
|
3981
|
+
zip.updateFile(entry, nested.toBuffer());
|
|
3982
|
+
changed = true;
|
|
3983
|
+
}
|
|
3984
|
+
}
|
|
3985
|
+
return changed;
|
|
3986
|
+
}
|
|
3987
|
+
function canonicalizeNestedPackage(zip, generatedAt, depth) {
|
|
3988
|
+
let changed = false;
|
|
3989
|
+
const coreProperties3 = zip.getEntry("docProps/core.xml");
|
|
3990
|
+
if (coreProperties3) {
|
|
3991
|
+
const xml = coreProperties3.getData().toString("utf8");
|
|
3992
|
+
const normalized = xml.replace(
|
|
3993
|
+
CORE_TIMESTAMP,
|
|
3994
|
+
`$1${generatedAt.toISOString()}$2`
|
|
3995
|
+
);
|
|
3996
|
+
if (normalized !== xml) {
|
|
3997
|
+
zip.updateFile(coreProperties3, Buffer.from(normalized, "utf8"));
|
|
3998
|
+
changed = true;
|
|
3999
|
+
}
|
|
4000
|
+
}
|
|
4001
|
+
if (depth < MAX_EMBEDDED_DEPTH && canonicalizeEmbeddedPackages(zip, generatedAt, depth + 1)) {
|
|
4002
|
+
changed = true;
|
|
4003
|
+
}
|
|
4004
|
+
const zipTimestamp = toDosTime(generatedAt);
|
|
4005
|
+
for (const entry of zip.getEntries()) {
|
|
4006
|
+
const header = entry.header;
|
|
4007
|
+
if (header.timeval !== zipTimestamp) {
|
|
4008
|
+
header.timeval = zipTimestamp;
|
|
4009
|
+
changed = true;
|
|
4010
|
+
}
|
|
4011
|
+
}
|
|
4012
|
+
return changed;
|
|
4013
|
+
}
|
|
3719
4014
|
function canonicalizeDocxBuffer(buffer, generatedAt = DEFAULT_GENERATION_DATE) {
|
|
3720
4015
|
const zip = new AdmZip(buffer);
|
|
3721
4016
|
normalizeTextCase(zip);
|
|
3722
4017
|
canonicalizeRelationshipIds(zip);
|
|
4018
|
+
canonicalizeEmbeddedPackages(zip, generatedAt);
|
|
3723
4019
|
const isoTimestamp = generatedAt.toISOString();
|
|
3724
4020
|
const coreProperties3 = zip.getEntry("docProps/core.xml");
|
|
3725
4021
|
if (coreProperties3) {
|
|
3726
|
-
const normalized = coreProperties3.getData().toString("utf8").replace(
|
|
3727
|
-
/(<dcterms:(?:created|modified)\b[^>]*>)[^<]*(<\/dcterms:(?:created|modified)>)/g,
|
|
3728
|
-
`$1${isoTimestamp}$2`
|
|
3729
|
-
);
|
|
4022
|
+
const normalized = coreProperties3.getData().toString("utf8").replace(CORE_TIMESTAMP, `$1${isoTimestamp}$2`);
|
|
3730
4023
|
zip.updateFile(coreProperties3, Buffer.from(normalized, "utf8"));
|
|
3731
4024
|
}
|
|
3732
4025
|
const zipTimestamp = toDosTime(generatedAt);
|
|
@@ -3739,35 +4032,567 @@ function normalizeDocxCaseBuffer(buffer) {
|
|
|
3739
4032
|
const zip = new AdmZip(buffer);
|
|
3740
4033
|
return normalizeTextCase(zip) ? zip.toBuffer() : buffer;
|
|
3741
4034
|
}
|
|
3742
|
-
var DEFAULT_GENERATION_DATE, STABLE_RELATIONSHIP_ID;
|
|
4035
|
+
var DEFAULT_GENERATION_DATE, STABLE_RELATIONSHIP_ID, CORE_TIMESTAMP, EMBEDDED_OFFICE_PACKAGE, MAX_EMBEDDED_DEPTH;
|
|
3743
4036
|
var init_packageDocument = __esm({
|
|
3744
4037
|
"src/utils/packageDocument.ts"() {
|
|
3745
4038
|
"use strict";
|
|
3746
4039
|
init_normalizeTextCase();
|
|
3747
4040
|
DEFAULT_GENERATION_DATE = /* @__PURE__ */ new Date("2000-01-01T00:00:00.000Z");
|
|
3748
4041
|
STABLE_RELATIONSHIP_ID = /^rId\d+$/;
|
|
4042
|
+
CORE_TIMESTAMP = /(<dcterms:(?:created|modified)\b[^>]*>)[^<]*(<\/dcterms:(?:created|modified)>)/g;
|
|
4043
|
+
EMBEDDED_OFFICE_PACKAGE = /\.(?:docx|pptx|xlsx|xlsm)$/i;
|
|
4044
|
+
MAX_EMBEDDED_DEPTH = 3;
|
|
3749
4045
|
}
|
|
3750
4046
|
});
|
|
3751
4047
|
|
|
3752
4048
|
// src/utils/fixFloatingImageIds.ts
|
|
3753
4049
|
import AdmZip2 from "adm-zip";
|
|
4050
|
+
function compareDrawingParts(a, b) {
|
|
4051
|
+
const ma = DRAWING_PART.exec(a);
|
|
4052
|
+
const mb = DRAWING_PART.exec(b);
|
|
4053
|
+
const rank = RANK.indexOf(ma[1]) - RANK.indexOf(mb[1]);
|
|
4054
|
+
return rank !== 0 ? rank : Number(ma[2] || 0) - Number(mb[2] || 0);
|
|
4055
|
+
}
|
|
3754
4056
|
function fixFloatingImageIdsInBuffer(buffer) {
|
|
3755
4057
|
const zip = new AdmZip2(buffer);
|
|
3756
|
-
|
|
3757
|
-
if (!documentEntry) {
|
|
4058
|
+
if (!zip.getEntry("word/document.xml")) {
|
|
3758
4059
|
throw new Error("document.xml not found in DOCX");
|
|
3759
4060
|
}
|
|
4061
|
+
const parts = zip.getEntries().filter((entry) => DRAWING_PART.test(entry.entryName)).sort((a, b) => compareDrawingParts(a.entryName, b.entryName));
|
|
3760
4062
|
let idCounter = 1;
|
|
3761
|
-
const
|
|
3762
|
-
const
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
4063
|
+
for (const entry of parts) {
|
|
4064
|
+
const xml = entry.getData().toString("utf8");
|
|
4065
|
+
const renumbered = xml.replace(
|
|
4066
|
+
/(<wp:docPr\b[^>]*?\s)id="\d+"/g,
|
|
4067
|
+
(_match, prefix) => `${prefix}id="${idCounter++}"`
|
|
4068
|
+
);
|
|
4069
|
+
zip.updateFile(entry, Buffer.from(renumbered, "utf8"));
|
|
4070
|
+
}
|
|
3766
4071
|
return zip.toBuffer();
|
|
3767
4072
|
}
|
|
4073
|
+
var DRAWING_PART, RANK;
|
|
3768
4074
|
var init_fixFloatingImageIds = __esm({
|
|
3769
4075
|
"src/utils/fixFloatingImageIds.ts"() {
|
|
3770
4076
|
"use strict";
|
|
4077
|
+
DRAWING_PART = /^word\/(document|header|footer|footnotes|endnotes|comments)(\d*)\.xml$/;
|
|
4078
|
+
RANK = [
|
|
4079
|
+
"document",
|
|
4080
|
+
"header",
|
|
4081
|
+
"footer",
|
|
4082
|
+
"footnotes",
|
|
4083
|
+
"endnotes",
|
|
4084
|
+
"comments"
|
|
4085
|
+
];
|
|
4086
|
+
}
|
|
4087
|
+
});
|
|
4088
|
+
|
|
4089
|
+
// src/renderers/docxjs/presetShapes.ts
|
|
4090
|
+
function docxPresetShape(geometry) {
|
|
4091
|
+
const name = Object.hasOwn(OOXML_PRESET_TO_DOCX, geometry) ? OOXML_PRESET_TO_DOCX[geometry] : void 0;
|
|
4092
|
+
if (!name) {
|
|
4093
|
+
throw new Error(
|
|
4094
|
+
`the docxjs renderer has no preset for the OOXML geometry "${geometry}"`
|
|
4095
|
+
);
|
|
4096
|
+
}
|
|
4097
|
+
return name;
|
|
4098
|
+
}
|
|
4099
|
+
function docxLineDash(dash) {
|
|
4100
|
+
const name = Object.hasOwn(OOXML_DASH_TO_DOCX, dash) ? OOXML_DASH_TO_DOCX[dash] : void 0;
|
|
4101
|
+
if (!name) {
|
|
4102
|
+
throw new Error(
|
|
4103
|
+
`the docxjs renderer has no line dash for the OOXML value "${dash}"`
|
|
4104
|
+
);
|
|
4105
|
+
}
|
|
4106
|
+
return name;
|
|
4107
|
+
}
|
|
4108
|
+
var OOXML_PRESET_TO_DOCX, OOXML_DASH_TO_DOCX;
|
|
4109
|
+
var init_presetShapes = __esm({
|
|
4110
|
+
"src/renderers/docxjs/presetShapes.ts"() {
|
|
4111
|
+
"use strict";
|
|
4112
|
+
OOXML_PRESET_TO_DOCX = {
|
|
4113
|
+
line: "line",
|
|
4114
|
+
lineInv: "inverseLine",
|
|
4115
|
+
straightConnector1: "straightConnector",
|
|
4116
|
+
bentConnector2: "elbowConnectorOneBend",
|
|
4117
|
+
bentConnector3: "elbowConnector",
|
|
4118
|
+
bentConnector4: "elbowConnectorThreeBends",
|
|
4119
|
+
bentConnector5: "elbowConnectorFourBends",
|
|
4120
|
+
curvedConnector2: "curvedConnectorOneBend",
|
|
4121
|
+
curvedConnector3: "curvedConnector",
|
|
4122
|
+
curvedConnector4: "curvedConnectorThreeBends",
|
|
4123
|
+
curvedConnector5: "curvedConnectorFourBends",
|
|
4124
|
+
triangle: "triangle",
|
|
4125
|
+
rtTriangle: "rightTriangle",
|
|
4126
|
+
diamond: "diamond",
|
|
4127
|
+
parallelogram: "parallelogram",
|
|
4128
|
+
trapezoid: "trapezoid",
|
|
4129
|
+
nonIsoscelesTrapezoid: "nonIsoscelesTrapezoid",
|
|
4130
|
+
pentagon: "pentagon",
|
|
4131
|
+
hexagon: "hexagon",
|
|
4132
|
+
heptagon: "heptagon",
|
|
4133
|
+
octagon: "octagon",
|
|
4134
|
+
decagon: "decagon",
|
|
4135
|
+
dodecagon: "dodecagon",
|
|
4136
|
+
ellipse: "ellipse",
|
|
4137
|
+
teardrop: "teardrop",
|
|
4138
|
+
pieWedge: "pieWedge",
|
|
4139
|
+
pie: "pie",
|
|
4140
|
+
blockArc: "blockArc",
|
|
4141
|
+
donut: "donut",
|
|
4142
|
+
noSmoking: "noSymbol",
|
|
4143
|
+
chord: "chord",
|
|
4144
|
+
arc: "arc",
|
|
4145
|
+
frame: "frame",
|
|
4146
|
+
halfFrame: "halfFrame",
|
|
4147
|
+
corner: "lShape",
|
|
4148
|
+
diagStripe: "diagonalStripe",
|
|
4149
|
+
plus: "cross",
|
|
4150
|
+
plaque: "plaque",
|
|
4151
|
+
can: "cylinder",
|
|
4152
|
+
cube: "cube",
|
|
4153
|
+
bevel: "beveledRectangle",
|
|
4154
|
+
foldedCorner: "foldedCorner",
|
|
4155
|
+
smileyFace: "smileyFace",
|
|
4156
|
+
heart: "heart",
|
|
4157
|
+
lightningBolt: "lightningBolt",
|
|
4158
|
+
sun: "sun",
|
|
4159
|
+
moon: "moon",
|
|
4160
|
+
cloud: "cloud",
|
|
4161
|
+
leftBracket: "leftBracket",
|
|
4162
|
+
rightBracket: "rightBracket",
|
|
4163
|
+
leftBrace: "leftBrace",
|
|
4164
|
+
rightBrace: "rightBrace",
|
|
4165
|
+
bracketPair: "bracketPair",
|
|
4166
|
+
bracePair: "bracePair",
|
|
4167
|
+
rect: "rectangle",
|
|
4168
|
+
roundRect: "roundedRectangle",
|
|
4169
|
+
round1Rect: "roundedCornerRectangle",
|
|
4170
|
+
round2SameRect: "topRoundedCornersRectangle",
|
|
4171
|
+
round2DiagRect: "diagonalRoundedCornersRectangle",
|
|
4172
|
+
snip1Rect: "snippedCornerRectangle",
|
|
4173
|
+
snip2SameRect: "topSnippedCornersRectangle",
|
|
4174
|
+
snip2DiagRect: "diagonalSnippedCornersRectangle",
|
|
4175
|
+
snipRoundRect: "roundedAndSnippedCornersRectangle",
|
|
4176
|
+
rightArrow: "rightArrow",
|
|
4177
|
+
leftArrow: "leftArrow",
|
|
4178
|
+
upArrow: "upArrow",
|
|
4179
|
+
downArrow: "downArrow",
|
|
4180
|
+
leftRightArrow: "leftRightArrow",
|
|
4181
|
+
upDownArrow: "upDownArrow",
|
|
4182
|
+
quadArrow: "quadArrow",
|
|
4183
|
+
leftRightUpArrow: "leftRightUpArrow",
|
|
4184
|
+
bentArrow: "bentArrow",
|
|
4185
|
+
uturnArrow: "uTurnArrow",
|
|
4186
|
+
leftUpArrow: "leftUpArrow",
|
|
4187
|
+
bentUpArrow: "bentUpArrow",
|
|
4188
|
+
curvedRightArrow: "curvedRightArrow",
|
|
4189
|
+
curvedLeftArrow: "curvedLeftArrow",
|
|
4190
|
+
curvedUpArrow: "curvedUpArrow",
|
|
4191
|
+
curvedDownArrow: "curvedDownArrow",
|
|
4192
|
+
stripedRightArrow: "stripedRightArrow",
|
|
4193
|
+
notchedRightArrow: "notchedRightArrow",
|
|
4194
|
+
homePlate: "pentagonArrow",
|
|
4195
|
+
chevron: "chevron",
|
|
4196
|
+
rightArrowCallout: "rightArrowCallout",
|
|
4197
|
+
downArrowCallout: "downArrowCallout",
|
|
4198
|
+
leftArrowCallout: "leftArrowCallout",
|
|
4199
|
+
upArrowCallout: "upArrowCallout",
|
|
4200
|
+
leftRightArrowCallout: "leftRightArrowCallout",
|
|
4201
|
+
upDownArrowCallout: "upDownArrowCallout",
|
|
4202
|
+
quadArrowCallout: "quadArrowCallout",
|
|
4203
|
+
circularArrow: "circularArrow",
|
|
4204
|
+
leftCircularArrow: "leftCircularArrow",
|
|
4205
|
+
leftRightCircularArrow: "leftRightCircularArrow",
|
|
4206
|
+
swooshArrow: "swooshArrow",
|
|
4207
|
+
mathPlus: "mathPlus",
|
|
4208
|
+
mathMinus: "mathMinus",
|
|
4209
|
+
mathMultiply: "mathMultiply",
|
|
4210
|
+
mathDivide: "mathDivide",
|
|
4211
|
+
mathEqual: "mathEqual",
|
|
4212
|
+
mathNotEqual: "mathNotEqual",
|
|
4213
|
+
flowChartProcess: "flowChartProcess",
|
|
4214
|
+
flowChartAlternateProcess: "flowChartAlternateProcess",
|
|
4215
|
+
flowChartDecision: "flowChartDecision",
|
|
4216
|
+
flowChartInputOutput: "flowChartInputOutput",
|
|
4217
|
+
flowChartPredefinedProcess: "flowChartPredefinedProcess",
|
|
4218
|
+
flowChartInternalStorage: "flowChartInternalStorage",
|
|
4219
|
+
flowChartDocument: "flowChartDocument",
|
|
4220
|
+
flowChartMultidocument: "flowChartMultidocument",
|
|
4221
|
+
flowChartTerminator: "flowChartTerminator",
|
|
4222
|
+
flowChartPreparation: "flowChartPreparation",
|
|
4223
|
+
flowChartManualInput: "flowChartManualInput",
|
|
4224
|
+
flowChartManualOperation: "flowChartManualOperation",
|
|
4225
|
+
flowChartConnector: "flowChartConnector",
|
|
4226
|
+
flowChartOffpageConnector: "flowChartOffpageConnector",
|
|
4227
|
+
flowChartPunchedCard: "flowChartPunchedCard",
|
|
4228
|
+
flowChartPunchedTape: "flowChartPunchedTape",
|
|
4229
|
+
flowChartSummingJunction: "flowChartSummingJunction",
|
|
4230
|
+
flowChartOr: "flowChartOr",
|
|
4231
|
+
flowChartCollate: "flowChartCollate",
|
|
4232
|
+
flowChartSort: "flowChartSort",
|
|
4233
|
+
flowChartExtract: "flowChartExtract",
|
|
4234
|
+
flowChartMerge: "flowChartMerge",
|
|
4235
|
+
flowChartOfflineStorage: "flowChartOfflineStorage",
|
|
4236
|
+
flowChartOnlineStorage: "flowChartOnlineStorage",
|
|
4237
|
+
flowChartDelay: "flowChartDelay",
|
|
4238
|
+
flowChartMagneticTape: "flowChartMagneticTape",
|
|
4239
|
+
flowChartMagneticDisk: "flowChartMagneticDisk",
|
|
4240
|
+
flowChartMagneticDrum: "flowChartMagneticDrum",
|
|
4241
|
+
flowChartDisplay: "flowChartDisplay",
|
|
4242
|
+
irregularSeal1: "explosion12",
|
|
4243
|
+
irregularSeal2: "explosion14",
|
|
4244
|
+
star4: "star4",
|
|
4245
|
+
star5: "star5",
|
|
4246
|
+
star6: "star6",
|
|
4247
|
+
star7: "star7",
|
|
4248
|
+
star8: "star8",
|
|
4249
|
+
star10: "star10",
|
|
4250
|
+
star12: "star12",
|
|
4251
|
+
star16: "star16",
|
|
4252
|
+
star24: "star24",
|
|
4253
|
+
star32: "star32",
|
|
4254
|
+
ribbon2: "ribbonUp",
|
|
4255
|
+
ribbon: "ribbonDown",
|
|
4256
|
+
ellipseRibbon2: "curvedRibbonUp",
|
|
4257
|
+
ellipseRibbon: "curvedRibbonDown",
|
|
4258
|
+
leftRightRibbon: "leftRightRibbon",
|
|
4259
|
+
verticalScroll: "verticalScroll",
|
|
4260
|
+
horizontalScroll: "horizontalScroll",
|
|
4261
|
+
wave: "wave",
|
|
4262
|
+
doubleWave: "doubleWave",
|
|
4263
|
+
wedgeRectCallout: "rectangularCallout",
|
|
4264
|
+
wedgeRoundRectCallout: "roundedRectangularCallout",
|
|
4265
|
+
wedgeEllipseCallout: "ellipticalCallout",
|
|
4266
|
+
cloudCallout: "cloudCallout",
|
|
4267
|
+
borderCallout1: "lineCallout",
|
|
4268
|
+
borderCallout2: "bentLineCallout",
|
|
4269
|
+
borderCallout3: "doubleBentLineCallout",
|
|
4270
|
+
accentCallout1: "lineCalloutWithAccentBar",
|
|
4271
|
+
accentCallout2: "bentLineCalloutWithAccentBar",
|
|
4272
|
+
accentCallout3: "doubleBentLineCalloutWithAccentBar",
|
|
4273
|
+
callout1: "lineCalloutWithNoBorder",
|
|
4274
|
+
callout2: "bentLineCalloutWithNoBorder",
|
|
4275
|
+
callout3: "doubleBentLineCalloutWithNoBorder",
|
|
4276
|
+
accentBorderCallout1: "lineCalloutWithBorderAndAccentBar",
|
|
4277
|
+
accentBorderCallout2: "bentLineCalloutWithBorderAndAccentBar",
|
|
4278
|
+
accentBorderCallout3: "doubleBentLineCalloutWithBorderAndAccentBar",
|
|
4279
|
+
actionButtonBlank: "actionButtonBlank",
|
|
4280
|
+
actionButtonHome: "actionButtonHome",
|
|
4281
|
+
actionButtonHelp: "actionButtonHelp",
|
|
4282
|
+
actionButtonInformation: "actionButtonInformation",
|
|
4283
|
+
actionButtonForwardNext: "actionButtonForwardNext",
|
|
4284
|
+
actionButtonBackPrevious: "actionButtonBackPrevious",
|
|
4285
|
+
actionButtonEnd: "actionButtonEnd",
|
|
4286
|
+
actionButtonBeginning: "actionButtonBeginning",
|
|
4287
|
+
actionButtonReturn: "actionButtonReturn",
|
|
4288
|
+
actionButtonDocument: "actionButtonDocument",
|
|
4289
|
+
actionButtonSound: "actionButtonSound",
|
|
4290
|
+
actionButtonMovie: "actionButtonMovie",
|
|
4291
|
+
gear6: "gear6",
|
|
4292
|
+
gear9: "gear9",
|
|
4293
|
+
funnel: "funnel",
|
|
4294
|
+
cornerTabs: "cornerTabs",
|
|
4295
|
+
squareTabs: "squareTabs",
|
|
4296
|
+
plaqueTabs: "plaqueTabs",
|
|
4297
|
+
chartX: "chartX",
|
|
4298
|
+
chartStar: "chartStar",
|
|
4299
|
+
chartPlus: "chartPlus"
|
|
4300
|
+
};
|
|
4301
|
+
OOXML_DASH_TO_DOCX = {
|
|
4302
|
+
solid: "solid",
|
|
4303
|
+
dot: "dot",
|
|
4304
|
+
dash: "dash",
|
|
4305
|
+
lgDash: "longDash",
|
|
4306
|
+
dashDot: "dashDot",
|
|
4307
|
+
lgDashDot: "longDashDot",
|
|
4308
|
+
lgDashDotDot: "longDashDotDot",
|
|
4309
|
+
sysDash: "shortDash",
|
|
4310
|
+
sysDot: "shortDot",
|
|
4311
|
+
sysDashDot: "shortDashDot",
|
|
4312
|
+
sysDashDotDot: "shortDashDotDot"
|
|
4313
|
+
};
|
|
4314
|
+
}
|
|
4315
|
+
});
|
|
4316
|
+
|
|
4317
|
+
// src/renderers/docxjs/drawingGroup.ts
|
|
4318
|
+
function chooseMarkers(ir) {
|
|
4319
|
+
const strings = [];
|
|
4320
|
+
collectStrings(ir, strings, /* @__PURE__ */ new WeakSet());
|
|
4321
|
+
const unused = (base) => {
|
|
4322
|
+
for (let n = 0; ; n += 1) {
|
|
4323
|
+
const candidate = n === 0 ? base : `${base}-${n}`;
|
|
4324
|
+
if (!strings.some((value) => value.includes(candidate))) return candidate;
|
|
4325
|
+
}
|
|
4326
|
+
};
|
|
4327
|
+
return {
|
|
4328
|
+
noAltText: unused(DEFAULT_MARKERS.noAltText),
|
|
4329
|
+
textBox: unused(DEFAULT_MARKERS.textBox)
|
|
4330
|
+
};
|
|
4331
|
+
}
|
|
4332
|
+
function collectStrings(node, out, seen) {
|
|
4333
|
+
if (typeof node === "string") {
|
|
4334
|
+
out.push(node);
|
|
4335
|
+
return;
|
|
4336
|
+
}
|
|
4337
|
+
if (!node || typeof node !== "object") return;
|
|
4338
|
+
if (node instanceof ArrayBuffer || ArrayBuffer.isView(node)) return;
|
|
4339
|
+
if (seen.has(node)) return;
|
|
4340
|
+
seen.add(node);
|
|
4341
|
+
if (node instanceof Map) {
|
|
4342
|
+
for (const [key, value] of node) {
|
|
4343
|
+
collectStrings(key, out, seen);
|
|
4344
|
+
collectStrings(value, out, seen);
|
|
4345
|
+
}
|
|
4346
|
+
return;
|
|
4347
|
+
}
|
|
4348
|
+
if (node instanceof Set) {
|
|
4349
|
+
for (const value of node) collectStrings(value, out, seen);
|
|
4350
|
+
return;
|
|
4351
|
+
}
|
|
4352
|
+
for (const value of Object.values(node)) collectStrings(value, out, seen);
|
|
4353
|
+
}
|
|
4354
|
+
function createDrawingGroupFactory(shapes2, pictures, markers) {
|
|
4355
|
+
return (group, resources) => new shapes2.ShapeGroupRun(
|
|
4356
|
+
drawingGroupOptions(group, resources, pictures, markers)
|
|
4357
|
+
);
|
|
4358
|
+
}
|
|
4359
|
+
function drawingGroupOptions(group, resources, pictures, markers = DEFAULT_MARKERS) {
|
|
4360
|
+
const canvasWidth = group.canvasWidthEmu;
|
|
4361
|
+
const canvasHeight = group.canvasHeightEmu;
|
|
4362
|
+
const near = (value, edge) => Math.abs(value - edge) <= OVERFLOW_TOLERANCE_EMU;
|
|
4363
|
+
const bounds = unrotatedBounds(group.children);
|
|
4364
|
+
const fillsCanvas = bounds !== void 0 && near(bounds.left, 0) && near(bounds.top, 0) && near(bounds.right, canvasWidth) && near(bounds.bottom, canvasHeight);
|
|
4365
|
+
const union = {
|
|
4366
|
+
left: Math.min(0, bounds?.left ?? 0),
|
|
4367
|
+
top: Math.min(0, bounds?.top ?? 0),
|
|
4368
|
+
right: Math.max(canvasWidth, bounds?.right ?? 0),
|
|
4369
|
+
bottom: Math.max(canvasHeight, bounds?.bottom ?? 0)
|
|
4370
|
+
};
|
|
4371
|
+
const overflows = union.left < -OVERFLOW_TOLERANCE_EMU || union.top < -OVERFLOW_TOLERANCE_EMU || union.right > canvasWidth + OVERFLOW_TOLERANCE_EMU || union.bottom > canvasHeight + OVERFLOW_TOLERANCE_EMU;
|
|
4372
|
+
const widthEmu = overflows ? (union.right - union.left) * group.widthEmu / canvasWidth : group.widthEmu;
|
|
4373
|
+
const heightEmu = overflows ? (union.bottom - union.top) * group.heightEmu / canvasHeight : group.heightEmu;
|
|
4374
|
+
return {
|
|
4375
|
+
children: [
|
|
4376
|
+
...fillsCanvas ? [] : [canvasPad(canvasWidth, canvasHeight)],
|
|
4377
|
+
...group.children.map(
|
|
4378
|
+
(child, index) => groupChild(child, index, resources, pictures, markers)
|
|
4379
|
+
)
|
|
4380
|
+
],
|
|
4381
|
+
transformation: {
|
|
4382
|
+
width: emuToPixels(widthEmu),
|
|
4383
|
+
height: emuToPixels(heightEmu)
|
|
4384
|
+
},
|
|
4385
|
+
// `||`, not `??`: docx treats '' as no description too, and would then
|
|
4386
|
+
// describe the diagram from the child names.
|
|
4387
|
+
altText: { name: "", description: group.altText || markers.noAltText },
|
|
4388
|
+
...group.floating ? { floating: floatingOptions(group.floating) } : {}
|
|
4389
|
+
};
|
|
4390
|
+
}
|
|
4391
|
+
function groupChild(child, index, resources, pictures, markers) {
|
|
4392
|
+
return child.kind === "picture" ? pictureChild(child, index, pictures) : shapeChild(child, index, resources, markers);
|
|
4393
|
+
}
|
|
4394
|
+
function canvasPad(canvasWidthEmu, canvasHeightEmu) {
|
|
4395
|
+
return {
|
|
4396
|
+
type: "rectangle",
|
|
4397
|
+
transformation: {
|
|
4398
|
+
offset: { left: 0, top: 0 },
|
|
4399
|
+
width: emuToPixels(canvasWidthEmu),
|
|
4400
|
+
height: emuToPixels(canvasHeightEmu)
|
|
4401
|
+
},
|
|
4402
|
+
fill: "none",
|
|
4403
|
+
line: "none",
|
|
4404
|
+
decorative: true,
|
|
4405
|
+
altText: { name: "Canvas" }
|
|
4406
|
+
};
|
|
4407
|
+
}
|
|
4408
|
+
function childTransformation(frame) {
|
|
4409
|
+
const rotation2 = frame.rotationDegrees;
|
|
4410
|
+
return {
|
|
4411
|
+
offset: { left: emuToPixels(frame.xEmu), top: emuToPixels(frame.yEmu) },
|
|
4412
|
+
width: emuToPixels(frame.widthEmu),
|
|
4413
|
+
height: emuToPixels(frame.heightEmu),
|
|
4414
|
+
...rotation2 !== void 0 && rotation2 % 360 !== 0 ? { rotation: rotation2 } : {},
|
|
4415
|
+
...frame.flipHorizontal || frame.flipVertical ? {
|
|
4416
|
+
flip: {
|
|
4417
|
+
...frame.flipHorizontal ? { horizontal: true } : {},
|
|
4418
|
+
...frame.flipVertical ? { vertical: true } : {}
|
|
4419
|
+
}
|
|
4420
|
+
} : {}
|
|
4421
|
+
};
|
|
4422
|
+
}
|
|
4423
|
+
function shapeChild(shape, index, resources, markers) {
|
|
4424
|
+
const paragraphs = shape.text?.paragraphs ?? [];
|
|
4425
|
+
return {
|
|
4426
|
+
type: docxPresetShape(shape.geometry),
|
|
4427
|
+
transformation: childTransformation(shape.frame),
|
|
4428
|
+
fill: shapeFill(shape.fill),
|
|
4429
|
+
line: shapeLine(shape.outline),
|
|
4430
|
+
altText: {
|
|
4431
|
+
name: shape.name ?? `Shape ${index + 1}`,
|
|
4432
|
+
...shape.isTextBox ? { title: markers.textBox } : {}
|
|
4433
|
+
},
|
|
4434
|
+
// Never `children: []`: docx would write an empty `w:txbxContent`, which
|
|
4435
|
+
// the schema does not allow.
|
|
4436
|
+
...paragraphs.length > 0 ? {
|
|
4437
|
+
children: paragraphs.map(
|
|
4438
|
+
(paragraph2) => emitParagraph(paragraph2, resources)
|
|
4439
|
+
)
|
|
4440
|
+
} : {},
|
|
4441
|
+
...shape.text ? { textOptions: textOptions(shape.text) } : {}
|
|
4442
|
+
};
|
|
4443
|
+
}
|
|
4444
|
+
function pictureChild(picture2, index, pictures) {
|
|
4445
|
+
const crop = picture2.crop;
|
|
4446
|
+
return {
|
|
4447
|
+
type: "picture",
|
|
4448
|
+
image: pictures(picture2.resourceId, {
|
|
4449
|
+
widthEmu: picture2.frame.widthEmu,
|
|
4450
|
+
heightEmu: picture2.frame.heightEmu
|
|
4451
|
+
}),
|
|
4452
|
+
transformation: childTransformation(picture2.frame),
|
|
4453
|
+
...crop ? {
|
|
4454
|
+
crop: {
|
|
4455
|
+
...crop.left !== void 0 ? { left: crop.left * 100 } : {},
|
|
4456
|
+
...crop.top !== void 0 ? { top: crop.top * 100 } : {},
|
|
4457
|
+
...crop.right !== void 0 ? { right: crop.right * 100 } : {},
|
|
4458
|
+
...crop.bottom !== void 0 ? { bottom: crop.bottom * 100 } : {}
|
|
4459
|
+
}
|
|
4460
|
+
} : {},
|
|
4461
|
+
altText: {
|
|
4462
|
+
name: picture2.name ?? `Picture ${index + 1}`,
|
|
4463
|
+
...picture2.altText ? { description: picture2.altText } : {}
|
|
4464
|
+
}
|
|
4465
|
+
};
|
|
4466
|
+
}
|
|
4467
|
+
function shapeFill(fill) {
|
|
4468
|
+
if (!fill || fill.kind === "none") return "none";
|
|
4469
|
+
return {
|
|
4470
|
+
type: "solid",
|
|
4471
|
+
color: fill.color.hex,
|
|
4472
|
+
...fill.transparencyPercent !== void 0 ? { transparency: clamp(fill.transparencyPercent, 0, 100) } : {}
|
|
4473
|
+
};
|
|
4474
|
+
}
|
|
4475
|
+
function shapeLine(outline) {
|
|
4476
|
+
if (!outline || !outline.color) return "none";
|
|
4477
|
+
return {
|
|
4478
|
+
color: outline.color.hex,
|
|
4479
|
+
// An omitted width is office-open's omitted `w`, a hairline, where docx's
|
|
4480
|
+
// own default would be 1pt.
|
|
4481
|
+
width: outline.widthEmu !== void 0 ? clamp(outline.widthEmu / EMU_PER_POINT, 0, MAX_POINTS) : 0,
|
|
4482
|
+
...outline.dash ? { dash: docxLineDash(outline.dash) } : {}
|
|
4483
|
+
};
|
|
4484
|
+
}
|
|
4485
|
+
function textOptions(text) {
|
|
4486
|
+
const insets = text.insetsEmu;
|
|
4487
|
+
const points = (emu) => clamp(emu / EMU_PER_POINT, 0, MAX_POINTS);
|
|
4488
|
+
const margins = insets ? {
|
|
4489
|
+
...insets.top !== void 0 ? { top: points(insets.top) } : {},
|
|
4490
|
+
...insets.right !== void 0 ? { right: points(insets.right) } : {},
|
|
4491
|
+
...insets.bottom !== void 0 ? { bottom: points(insets.bottom) } : {},
|
|
4492
|
+
...insets.left !== void 0 ? { left: points(insets.left) } : {}
|
|
4493
|
+
} : void 0;
|
|
4494
|
+
return {
|
|
4495
|
+
verticalAlignment: VERTICAL_ALIGNMENT[text.anchor ?? "top"],
|
|
4496
|
+
...margins && Object.keys(margins).length > 0 ? { margins } : {}
|
|
4497
|
+
};
|
|
4498
|
+
}
|
|
4499
|
+
function unrotatedBounds(children) {
|
|
4500
|
+
if (children.length === 0) return void 0;
|
|
4501
|
+
let left = Infinity;
|
|
4502
|
+
let top = Infinity;
|
|
4503
|
+
let right = -Infinity;
|
|
4504
|
+
let bottom = -Infinity;
|
|
4505
|
+
for (const { frame } of children) {
|
|
4506
|
+
left = Math.min(left, frame.xEmu);
|
|
4507
|
+
top = Math.min(top, frame.yEmu);
|
|
4508
|
+
right = Math.max(right, frame.xEmu + frame.widthEmu);
|
|
4509
|
+
bottom = Math.max(bottom, frame.yEmu + frame.heightEmu);
|
|
4510
|
+
}
|
|
4511
|
+
return { left, top, right, bottom };
|
|
4512
|
+
}
|
|
4513
|
+
function clamp(value, low, high) {
|
|
4514
|
+
return Math.min(high, Math.max(low, value));
|
|
4515
|
+
}
|
|
4516
|
+
var DEFAULT_MARKERS, EMU_PER_POINT, MAX_POINTS, OVERFLOW_TOLERANCE_EMU, VERTICAL_ALIGNMENT;
|
|
4517
|
+
var init_drawingGroup = __esm({
|
|
4518
|
+
"src/renderers/docxjs/drawingGroup.ts"() {
|
|
4519
|
+
"use strict";
|
|
4520
|
+
init_units();
|
|
4521
|
+
init_emit();
|
|
4522
|
+
init_presetShapes();
|
|
4523
|
+
DEFAULT_MARKERS = {
|
|
4524
|
+
noAltText: "jto:no-alt-text",
|
|
4525
|
+
textBox: "jto:text-box"
|
|
4526
|
+
};
|
|
4527
|
+
EMU_PER_POINT = 12700;
|
|
4528
|
+
MAX_POINTS = 1584;
|
|
4529
|
+
OVERFLOW_TOLERANCE_EMU = 2;
|
|
4530
|
+
VERTICAL_ALIGNMENT = {
|
|
4531
|
+
top: "top",
|
|
4532
|
+
middle: "center",
|
|
4533
|
+
bottom: "bottom"
|
|
4534
|
+
};
|
|
4535
|
+
}
|
|
4536
|
+
});
|
|
4537
|
+
|
|
4538
|
+
// src/renderers/docxjs/drawingGroupRepair.ts
|
|
4539
|
+
import AdmZip3 from "adm-zip";
|
|
4540
|
+
function repairDrawingGroupsInBuffer(buffer, markers) {
|
|
4541
|
+
const textBox = new RegExp(
|
|
4542
|
+
`(<wps:cNvPr\\b[^>]*?) title="${escapeRegExp2(markers.textBox)}"(\\s*/>)<wps:cNvSpPr/>`,
|
|
4543
|
+
"g"
|
|
4544
|
+
);
|
|
4545
|
+
const noAltText = new RegExp(
|
|
4546
|
+
`(<wp:docPr\\b[^>]*?) descr="${escapeRegExp2(markers.noAltText)}"`,
|
|
4547
|
+
"g"
|
|
4548
|
+
);
|
|
4549
|
+
const zip = new AdmZip3(buffer);
|
|
4550
|
+
const parts = zip.getEntries().filter((entry) => DRAWING_PART.test(entry.entryName)).sort((a, b) => compareDrawingParts(a.entryName, b.entryName));
|
|
4551
|
+
const texts = new Map(
|
|
4552
|
+
parts.map((entry) => [entry, entry.getData().toString("utf8")])
|
|
4553
|
+
);
|
|
4554
|
+
let highest = 0;
|
|
4555
|
+
for (const xml of texts.values()) {
|
|
4556
|
+
for (const match of xml.matchAll(DOC_PR_ID)) {
|
|
4557
|
+
highest = Math.max(highest, Number(match[1]));
|
|
4558
|
+
}
|
|
4559
|
+
for (const match of xml.replace(GROUP, "").matchAll(CNVPR_ID)) {
|
|
4560
|
+
highest = Math.max(highest, Number(match[1]));
|
|
4561
|
+
}
|
|
4562
|
+
}
|
|
4563
|
+
let next = highest + 1;
|
|
4564
|
+
for (const [entry, xml] of texts) {
|
|
4565
|
+
if (!xml.includes("<wpg:wgp")) continue;
|
|
4566
|
+
const repaired = xml.replace(
|
|
4567
|
+
GROUP,
|
|
4568
|
+
(span) => span.replace(CHILD_ID, (_match, head) => `${head}id="${next++}"`).replace(
|
|
4569
|
+
ROTATION,
|
|
4570
|
+
(_match, head, value) => `${head}rot="${Math.round(Number(value))}"`
|
|
4571
|
+
).replace(textBox, '$1$2<wps:cNvSpPr txBox="1"/>')
|
|
4572
|
+
).replace(noAltText, "$1");
|
|
4573
|
+
texts.set(entry, repaired);
|
|
4574
|
+
zip.updateFile(entry, Buffer.from(repaired, "utf8"));
|
|
4575
|
+
}
|
|
4576
|
+
for (const [entry, xml] of texts) {
|
|
4577
|
+
if (xml.includes(markers.noAltText) || xml.includes(markers.textBox)) {
|
|
4578
|
+
throw new Error(
|
|
4579
|
+
`the drawing-group repair left a marker in ${entry.entryName}`
|
|
4580
|
+
);
|
|
4581
|
+
}
|
|
4582
|
+
}
|
|
4583
|
+
return zip.toBuffer();
|
|
4584
|
+
}
|
|
4585
|
+
var GROUP, DOC_PR_ID, CNVPR_ID, CHILD_ID, ROTATION, escapeRegExp2;
|
|
4586
|
+
var init_drawingGroupRepair = __esm({
|
|
4587
|
+
"src/renderers/docxjs/drawingGroupRepair.ts"() {
|
|
4588
|
+
"use strict";
|
|
4589
|
+
init_fixFloatingImageIds();
|
|
4590
|
+
GROUP = /<wpg:wgp\b[^>]*>[\s\S]*?<\/wpg:wgp>/g;
|
|
4591
|
+
DOC_PR_ID = /<wp:docPr\b[^>]*?\sid="(\d+)"/g;
|
|
4592
|
+
CNVPR_ID = /<(?:wps|pic|wpg):cNvPr\b[^>]*?\sid="(\d+)"/g;
|
|
4593
|
+
CHILD_ID = /(<(?:wps|pic|wpg):cNvPr\b[^>]*?\s)id="\d+"/g;
|
|
4594
|
+
ROTATION = /(<a:xfrm\b[^>]*?\s)rot="([^"]*)"/g;
|
|
4595
|
+
escapeRegExp2 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3771
4596
|
}
|
|
3772
4597
|
});
|
|
3773
4598
|
|
|
@@ -3796,18 +4621,32 @@ function createDocxJsRenderer() {
|
|
|
3796
4621
|
format: "docx",
|
|
3797
4622
|
capabilities: DOCXJS_CAPABILITIES,
|
|
3798
4623
|
async render(ir, renderOptions) {
|
|
3799
|
-
|
|
4624
|
+
await loadDocxCharts();
|
|
4625
|
+
const prepared = await prepareImages(
|
|
3800
4626
|
ir,
|
|
3801
4627
|
renderOptions?.svgRasterFallback
|
|
3802
4628
|
);
|
|
4629
|
+
const markers = prepared.drawingGroups > 0 ? chooseMarkers(ir) : void 0;
|
|
4630
|
+
let resources = prepared.images;
|
|
4631
|
+
if (markers) {
|
|
4632
|
+
await shapes.load();
|
|
4633
|
+
resources = Object.assign(prepared.images, {
|
|
4634
|
+
drawingGroup: createDrawingGroupFactory(
|
|
4635
|
+
shapes.get(),
|
|
4636
|
+
prepared.pictureSource,
|
|
4637
|
+
markers
|
|
4638
|
+
)
|
|
4639
|
+
});
|
|
4640
|
+
}
|
|
3803
4641
|
const document = buildDocument(ir, resources);
|
|
3804
4642
|
const packed = await Packer.toBuffer(document);
|
|
3805
4643
|
const fixed = fixFloatingImageIdsInBuffer(packed);
|
|
4644
|
+
const repaired = markers ? repairDrawingGroupsInBuffer(fixed, markers) : fixed;
|
|
3806
4645
|
if (renderOptions?.deterministic === false)
|
|
3807
|
-
return new Uint8Array(normalizeDocxCaseBuffer(
|
|
4646
|
+
return new Uint8Array(normalizeDocxCaseBuffer(repaired));
|
|
3808
4647
|
return new Uint8Array(
|
|
3809
4648
|
canonicalizeDocxBuffer(
|
|
3810
|
-
|
|
4649
|
+
repaired,
|
|
3811
4650
|
resolveGenerationDate({
|
|
3812
4651
|
deterministic: renderOptions?.deterministic,
|
|
3813
4652
|
generatedAt: renderOptions?.generatedAt
|
|
@@ -3820,6 +4659,7 @@ function createDocxJsRenderer() {
|
|
|
3820
4659
|
function buildDocument(ir, resources = /* @__PURE__ */ new Map()) {
|
|
3821
4660
|
return new Document({
|
|
3822
4661
|
styles: emitStyles(ir.styles),
|
|
4662
|
+
...ir.theme ? { theme: themeOptions(ir.theme) } : {},
|
|
3823
4663
|
sections: ir.sections.map(
|
|
3824
4664
|
(section2, index) => sectionOptions(section2, resources, index === ir.sections.length - 1)
|
|
3825
4665
|
),
|
|
@@ -3851,6 +4691,21 @@ function buildDocument(ir, resources = /* @__PURE__ */ new Map()) {
|
|
|
3851
4691
|
} : {}
|
|
3852
4692
|
});
|
|
3853
4693
|
}
|
|
4694
|
+
function themeOptions(theme) {
|
|
4695
|
+
const colors = {};
|
|
4696
|
+
for (const [slot, color] of Object.entries(theme.colors)) {
|
|
4697
|
+
if (color) colors[slot] = color.hex;
|
|
4698
|
+
}
|
|
4699
|
+
const fonts = {
|
|
4700
|
+
...theme.headingFont ? { headings: theme.headingFont } : {},
|
|
4701
|
+
...theme.bodyFont ? { body: theme.bodyFont } : {}
|
|
4702
|
+
};
|
|
4703
|
+
return {
|
|
4704
|
+
name: theme.name,
|
|
4705
|
+
...Object.keys(colors).length > 0 ? { colors } : {},
|
|
4706
|
+
...Object.keys(fonts).length > 0 ? { fonts } : {}
|
|
4707
|
+
};
|
|
4708
|
+
}
|
|
3854
4709
|
function noteBodies(notes, resources) {
|
|
3855
4710
|
const bodies = {};
|
|
3856
4711
|
for (const note of notes) {
|
|
@@ -3888,7 +4743,7 @@ function numberingConfig(numbering) {
|
|
|
3888
4743
|
};
|
|
3889
4744
|
}
|
|
3890
4745
|
async function prepareImages(ir, svgRasterFallback) {
|
|
3891
|
-
const placements = collectImagePlacements(ir);
|
|
4746
|
+
const { placements, drawingGroups } = collectImagePlacements(ir);
|
|
3892
4747
|
const jobs = [];
|
|
3893
4748
|
for (const resource of ir.resources) {
|
|
3894
4749
|
if (resource.kind !== "image" || resource.mediaType !== "svg") continue;
|
|
@@ -3936,16 +4791,55 @@ async function prepareImages(ir, svgRasterFallback) {
|
|
|
3936
4791
|
});
|
|
3937
4792
|
});
|
|
3938
4793
|
}
|
|
3939
|
-
|
|
4794
|
+
const pictureSource = (resourceId, placement) => {
|
|
4795
|
+
const resource = ir.resources.find(
|
|
4796
|
+
(candidate) => candidate.kind === "image" && candidate.id === resourceId
|
|
4797
|
+
);
|
|
4798
|
+
if (!resource) {
|
|
4799
|
+
throw new Error(`no image was prepared for resource "${resourceId}"`);
|
|
4800
|
+
}
|
|
4801
|
+
const data = Buffer.from(resource.bytes);
|
|
4802
|
+
if (resource.mediaType !== "svg") {
|
|
4803
|
+
return {
|
|
4804
|
+
type: resource.mediaType,
|
|
4805
|
+
data
|
|
4806
|
+
};
|
|
4807
|
+
}
|
|
4808
|
+
const size = `${emuToPixels(placement.widthEmu)}x${emuToPixels(placement.heightEmu)}`;
|
|
4809
|
+
return {
|
|
4810
|
+
type: "svg",
|
|
4811
|
+
data,
|
|
4812
|
+
fallback: {
|
|
4813
|
+
type: "png",
|
|
4814
|
+
data: rasters.get(`${resourceId}:${size}`) ?? data
|
|
4815
|
+
}
|
|
4816
|
+
};
|
|
4817
|
+
};
|
|
4818
|
+
return { images: resources, pictureSource, drawingGroups };
|
|
3940
4819
|
}
|
|
3941
4820
|
function collectImagePlacements(ir) {
|
|
3942
4821
|
const placements = /* @__PURE__ */ new Map();
|
|
4822
|
+
let drawingGroups = 0;
|
|
4823
|
+
const record = (resourceId, widthEmu, heightEmu) => {
|
|
4824
|
+
const key = `${emuToPixels(widthEmu)}x${emuToPixels(heightEmu)}`;
|
|
4825
|
+
const sizes = placements.get(resourceId) ?? /* @__PURE__ */ new Set();
|
|
4826
|
+
sizes.add(key);
|
|
4827
|
+
placements.set(resourceId, sizes);
|
|
4828
|
+
};
|
|
3943
4829
|
const visitInline = (inline) => {
|
|
3944
4830
|
if (inline.kind === "image") {
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
4831
|
+
record(inline.resourceId, inline.widthEmu, inline.heightEmu);
|
|
4832
|
+
return;
|
|
4833
|
+
}
|
|
4834
|
+
if (inline.kind === "drawingGroup") {
|
|
4835
|
+
drawingGroups += 1;
|
|
4836
|
+
for (const child of inline.children) {
|
|
4837
|
+
if (child.kind === "picture") {
|
|
4838
|
+
record(child.resourceId, child.frame.widthEmu, child.frame.heightEmu);
|
|
4839
|
+
} else {
|
|
4840
|
+
child.text?.paragraphs.forEach(visitBlock);
|
|
4841
|
+
}
|
|
4842
|
+
}
|
|
3949
4843
|
return;
|
|
3950
4844
|
}
|
|
3951
4845
|
if (inline.kind === "hyperlink" || inline.kind === "revision") {
|
|
@@ -3976,7 +4870,7 @@ function collectImagePlacements(ir) {
|
|
|
3976
4870
|
for (const note of [...ir.footnotes, ...ir.endnotes]) {
|
|
3977
4871
|
note.children.forEach(visitBlock);
|
|
3978
4872
|
}
|
|
3979
|
-
return placements;
|
|
4873
|
+
return { placements, drawingGroups };
|
|
3980
4874
|
}
|
|
3981
4875
|
function sectionOptions(section2, resources, closesDocument = false) {
|
|
3982
4876
|
const { page, columns } = section2.properties;
|
|
@@ -4089,17 +4983,26 @@ function coreProperties(ir) {
|
|
|
4089
4983
|
...metadata.custom?.length ? { customProperties: metadata.custom } : {}
|
|
4090
4984
|
};
|
|
4091
4985
|
}
|
|
4092
|
-
var DOCXJS_RENDERER_ID, DOCXJS_CAPABILITIES;
|
|
4986
|
+
var DOCXJS_RENDERER_ID, shapes, DOCXJS_CAPABILITIES;
|
|
4093
4987
|
var init_docxjs = __esm({
|
|
4094
4988
|
"src/renderers/docxjs/index.ts"() {
|
|
4095
4989
|
"use strict";
|
|
4096
4990
|
init_styles2();
|
|
4991
|
+
init_charts();
|
|
4097
4992
|
init_imageUtils();
|
|
4098
4993
|
init_packageDocument();
|
|
4099
4994
|
init_fixFloatingImageIds();
|
|
4100
4995
|
init_emit();
|
|
4996
|
+
init_docxSubpath();
|
|
4997
|
+
init_drawingGroup();
|
|
4998
|
+
init_drawingGroupRepair();
|
|
4101
4999
|
init_units();
|
|
4102
5000
|
DOCXJS_RENDERER_ID = "docxjs";
|
|
5001
|
+
shapes = docxSubpath(
|
|
5002
|
+
"docx/shapes",
|
|
5003
|
+
"visual",
|
|
5004
|
+
() => import("docx/shapes")
|
|
5005
|
+
);
|
|
4103
5006
|
DOCXJS_CAPABILITIES = /* @__PURE__ */ new Set([
|
|
4104
5007
|
"paragraphs",
|
|
4105
5008
|
"styles",
|
|
@@ -4112,8 +5015,10 @@ var init_docxjs = __esm({
|
|
|
4112
5015
|
"images",
|
|
4113
5016
|
"floating-images",
|
|
4114
5017
|
"svg-images",
|
|
5018
|
+
"charts",
|
|
4115
5019
|
"text-frames",
|
|
4116
5020
|
"text-boxes",
|
|
5021
|
+
"drawing-groups",
|
|
4117
5022
|
"toc",
|
|
4118
5023
|
"cached-toc",
|
|
4119
5024
|
"fields",
|
|
@@ -4134,124 +5039,332 @@ var init_docxjs = __esm({
|
|
|
4134
5039
|
}
|
|
4135
5040
|
});
|
|
4136
5041
|
|
|
4137
|
-
// src/
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
zip.addFile(name, Buffer.from(content, "utf8"));
|
|
5042
|
+
// src/renderers/office-open/chartLook.ts
|
|
5043
|
+
function seriesLook(chartType) {
|
|
5044
|
+
switch (chartType) {
|
|
5045
|
+
case "line":
|
|
5046
|
+
case "scatter":
|
|
5047
|
+
return { marker: MARKER, smooth: false };
|
|
5048
|
+
case "radar":
|
|
5049
|
+
return { marker: MARKER };
|
|
5050
|
+
case "column":
|
|
5051
|
+
case "bar":
|
|
5052
|
+
return { invertIfNegative: false };
|
|
5053
|
+
default:
|
|
5054
|
+
return {};
|
|
4151
5055
|
}
|
|
4152
|
-
|
|
4153
|
-
|
|
5056
|
+
}
|
|
5057
|
+
function axesLook(chartType) {
|
|
5058
|
+
switch (chartType) {
|
|
5059
|
+
case "column":
|
|
5060
|
+
case "bar":
|
|
5061
|
+
case "line":
|
|
5062
|
+
case "area": {
|
|
5063
|
+
const horizontal = chartType === "bar";
|
|
5064
|
+
return {
|
|
5065
|
+
categoryAxis: {
|
|
5066
|
+
position: horizontal ? "l" : "b",
|
|
5067
|
+
...NO_TICKS,
|
|
5068
|
+
line: AXIS_LINE
|
|
5069
|
+
},
|
|
5070
|
+
valueAxis: {
|
|
5071
|
+
position: horizontal ? "b" : "l",
|
|
5072
|
+
gridLine: GRIDLINES,
|
|
5073
|
+
...NO_TICKS,
|
|
5074
|
+
lineVisible: false,
|
|
5075
|
+
crossBetween: chartType === "area" ? "midCat" : "between"
|
|
5076
|
+
}
|
|
5077
|
+
};
|
|
5078
|
+
}
|
|
5079
|
+
case "radar":
|
|
5080
|
+
return {
|
|
5081
|
+
categoryAxis: {
|
|
5082
|
+
position: "b",
|
|
5083
|
+
gridLine: GRIDLINES,
|
|
5084
|
+
...NO_TICKS,
|
|
5085
|
+
majorTickMark: "cross",
|
|
5086
|
+
line: AXIS_LINE
|
|
5087
|
+
},
|
|
5088
|
+
valueAxis: {
|
|
5089
|
+
position: "l",
|
|
5090
|
+
gridLine: GRIDLINES,
|
|
5091
|
+
...NO_TICKS,
|
|
5092
|
+
majorTickMark: "cross",
|
|
5093
|
+
line: AXIS_LINE,
|
|
5094
|
+
crossBetween: "between"
|
|
5095
|
+
}
|
|
5096
|
+
};
|
|
5097
|
+
case "scatter": {
|
|
5098
|
+
const line = { ...AXIS_LINE, color: SCATTER_AXIS_TINT };
|
|
5099
|
+
return {
|
|
5100
|
+
categoryAxis: {
|
|
5101
|
+
position: "b",
|
|
5102
|
+
...NO_TICKS,
|
|
5103
|
+
line,
|
|
5104
|
+
crossBetween: "midCat"
|
|
5105
|
+
},
|
|
5106
|
+
valueAxis: {
|
|
5107
|
+
position: "l",
|
|
5108
|
+
gridLine: GRIDLINES,
|
|
5109
|
+
...NO_TICKS,
|
|
5110
|
+
line,
|
|
5111
|
+
crossBetween: "midCat"
|
|
5112
|
+
}
|
|
5113
|
+
};
|
|
5114
|
+
}
|
|
5115
|
+
default:
|
|
5116
|
+
return {};
|
|
4154
5117
|
}
|
|
4155
|
-
return new Uint8Array(zip.toBuffer());
|
|
4156
5118
|
}
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
5119
|
+
function plotLook(chart) {
|
|
5120
|
+
const common = {
|
|
5121
|
+
...axesLook(chart.chartType),
|
|
5122
|
+
autoTitleDeleted: !(chart.title && chart.showTitle !== false),
|
|
5123
|
+
plotAreaUnfilled: true
|
|
5124
|
+
};
|
|
5125
|
+
switch (chart.chartType) {
|
|
5126
|
+
case "column":
|
|
5127
|
+
return { ...common, dataBorder: "none", gapWidth: 219, overlap: -27 };
|
|
5128
|
+
case "bar":
|
|
5129
|
+
return { ...common, dataBorder: "none", gapWidth: 182, overlap: 0 };
|
|
5130
|
+
case "area":
|
|
5131
|
+
return { ...common, dataBorder: "none" };
|
|
5132
|
+
case "line":
|
|
5133
|
+
return { ...common, ...LINE_SERIES, lineMarkers: true };
|
|
5134
|
+
case "radar":
|
|
5135
|
+
return { ...common, ...LINE_SERIES, radarStyle: "marker" };
|
|
5136
|
+
case "scatter": {
|
|
5137
|
+
const labels = chart.series[0]?.labels ?? [];
|
|
5138
|
+
return {
|
|
5139
|
+
...common,
|
|
5140
|
+
...LINE_SERIES,
|
|
5141
|
+
lineWidthPoints: 1.5,
|
|
5142
|
+
scatterStyle: "lineMarker",
|
|
5143
|
+
scatterXValues: labels.map((_, index) => scatterX(labels, index))
|
|
5144
|
+
};
|
|
5145
|
+
}
|
|
5146
|
+
case "pie":
|
|
5147
|
+
case "doughnut":
|
|
5148
|
+
return {
|
|
5149
|
+
...common,
|
|
5150
|
+
dataBorder: { widthPoints: 1.5, color: { scheme: "lt1" } },
|
|
5151
|
+
firstSliceAngle: 0,
|
|
5152
|
+
...chart.chartType === "doughnut" ? { holeSize: 50 } : {}
|
|
5153
|
+
};
|
|
5154
|
+
default:
|
|
5155
|
+
return common;
|
|
5156
|
+
}
|
|
5157
|
+
}
|
|
5158
|
+
var TEXT_1_TINT, SCATTER_AXIS_TINT, HAIRLINE_POINTS, GRIDLINES, AXIS_LINE, NO_TICKS, LINE_SERIES, MARKER;
|
|
5159
|
+
var init_chartLook = __esm({
|
|
5160
|
+
"src/renderers/office-open/chartLook.ts"() {
|
|
4160
5161
|
"use strict";
|
|
4161
|
-
|
|
4162
|
-
|
|
5162
|
+
init_chartValues();
|
|
5163
|
+
TEXT_1_TINT = { scheme: "tx1", lumMod: 15e3, lumOff: 85e3 };
|
|
5164
|
+
SCATTER_AXIS_TINT = {
|
|
5165
|
+
scheme: "tx1",
|
|
5166
|
+
lumMod: 25e3,
|
|
5167
|
+
lumOff: 75e3
|
|
5168
|
+
};
|
|
5169
|
+
HAIRLINE_POINTS = 0.75;
|
|
5170
|
+
GRIDLINES = {
|
|
5171
|
+
size: HAIRLINE_POINTS,
|
|
5172
|
+
color: TEXT_1_TINT
|
|
5173
|
+
};
|
|
5174
|
+
AXIS_LINE = {
|
|
5175
|
+
widthPoints: HAIRLINE_POINTS,
|
|
5176
|
+
color: TEXT_1_TINT
|
|
5177
|
+
};
|
|
5178
|
+
NO_TICKS = {
|
|
5179
|
+
majorTickMark: "none",
|
|
5180
|
+
minorTickMark: "none",
|
|
5181
|
+
tickLabelPosition: "nextTo"
|
|
5182
|
+
};
|
|
5183
|
+
LINE_SERIES = {
|
|
5184
|
+
lineWidthPoints: 2.25,
|
|
5185
|
+
lineCap: "rnd",
|
|
5186
|
+
lineJoin: "round",
|
|
5187
|
+
markerLineWidthPoints: HAIRLINE_POINTS
|
|
5188
|
+
};
|
|
5189
|
+
MARKER = { symbol: "circle", size: 5 };
|
|
4163
5190
|
}
|
|
4164
5191
|
});
|
|
4165
5192
|
|
|
4166
5193
|
// src/renderers/office-open/chartParts.ts
|
|
4167
5194
|
import {
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
matchChartParts,
|
|
4171
|
-
spliceChartXml
|
|
5195
|
+
finishChartXml,
|
|
5196
|
+
matchChartParts
|
|
4172
5197
|
} from "@json-to-office/shared/rendering";
|
|
4173
|
-
function
|
|
4174
|
-
const
|
|
4175
|
-
const textFont =
|
|
4176
|
-
const axisTitleFont =
|
|
4177
|
-
const chartTitleFont =
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
5198
|
+
function chartInput(chart) {
|
|
5199
|
+
const roles = chartTextRoles(chart.textFont);
|
|
5200
|
+
const textFont = roles.text;
|
|
5201
|
+
const axisTitleFont = roles.axisTitle;
|
|
5202
|
+
const chartTitleFont = roles.title;
|
|
5203
|
+
const look = plotLook(chart);
|
|
5204
|
+
const categoryAxis = {
|
|
5205
|
+
...look.categoryAxis,
|
|
5206
|
+
...chart.categoryAxisTitle ? { title: chart.categoryAxisTitle, titleFont: axisTitleFont } : {}
|
|
5207
|
+
};
|
|
5208
|
+
const valueAxis = {
|
|
5209
|
+
...look.valueAxis,
|
|
5210
|
+
...chart.valueAxisTitle ? { title: chart.valueAxisTitle, titleFont: axisTitleFont } : {}
|
|
4181
5211
|
};
|
|
4182
5212
|
return {
|
|
5213
|
+
...look,
|
|
4183
5214
|
chartType: chart.chartType,
|
|
4184
5215
|
series: chart.series,
|
|
4185
5216
|
colors: chart.colors,
|
|
5217
|
+
...chart.title && chart.showTitle !== false ? { title: chart.title } : {},
|
|
4186
5218
|
textFont,
|
|
4187
5219
|
titleFont: chartTitleFont,
|
|
4188
5220
|
...chart.legendPosition ? { legendPosition: chart.legendPosition } : {},
|
|
4189
|
-
...
|
|
4190
|
-
|
|
4191
|
-
title: chart.categoryAxisTitle,
|
|
4192
|
-
titleFont: axisTitleFont
|
|
4193
|
-
}
|
|
4194
|
-
} : {},
|
|
4195
|
-
...chart.valueAxisTitle ? {
|
|
4196
|
-
valueAxis: { title: chart.valueAxisTitle, titleFont: axisTitleFont }
|
|
4197
|
-
} : {}
|
|
5221
|
+
...Object.keys(categoryAxis).length > 0 ? { categoryAxis } : {},
|
|
5222
|
+
...Object.keys(valueAxis).length > 0 ? { valueAxis } : {}
|
|
4198
5223
|
};
|
|
4199
5224
|
}
|
|
4200
|
-
function
|
|
4201
|
-
|
|
4202
|
-
if (!entry) return;
|
|
4203
|
-
const xml = entry.getData().toString("utf8");
|
|
4204
|
-
if (xml.includes(`Extension="xlsx"`)) return;
|
|
4205
|
-
zip.updateFile(
|
|
4206
|
-
entry,
|
|
4207
|
-
Buffer.from(
|
|
4208
|
-
xml.replace(
|
|
4209
|
-
'<Default Extension="xml"',
|
|
4210
|
-
`<Default Extension="xlsx" ContentType="${CHART_WORKBOOK_CONTENT_TYPE}"/><Default Extension="xml"`
|
|
4211
|
-
),
|
|
4212
|
-
"utf8"
|
|
4213
|
-
)
|
|
4214
|
-
);
|
|
4215
|
-
}
|
|
4216
|
-
function spliceChartParts(zip, charts) {
|
|
4217
|
-
if (charts.length === 0) return;
|
|
5225
|
+
function finishChartParts(zip, charts2) {
|
|
5226
|
+
if (charts2.length === 0) return;
|
|
4218
5227
|
const parts = zip.getEntries().map((entry) => entry.entryName).map((name) => name.match(/^word\/charts\/chart(\d+)\.xml$/)).filter((match) => match !== null).map(
|
|
4219
5228
|
(match) => [
|
|
4220
5229
|
Number(match[1]),
|
|
4221
5230
|
zip.getEntry(match[0]).getData().toString("utf8")
|
|
4222
5231
|
]
|
|
4223
5232
|
);
|
|
4224
|
-
|
|
4225
|
-
|
|
5233
|
+
const inputs = charts2.map(chartInput);
|
|
5234
|
+
for (const { ordinal, xml, chart } of matchChartParts(parts, inputs)) {
|
|
5235
|
+
const finished = finishChartXml(xml, chart);
|
|
5236
|
+
if (finished === xml) continue;
|
|
4226
5237
|
zip.updateFile(
|
|
4227
5238
|
zip.getEntry(`word/charts/chart${ordinal}.xml`),
|
|
4228
|
-
Buffer.from(
|
|
5239
|
+
Buffer.from(finished, "utf8")
|
|
4229
5240
|
);
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
5241
|
+
}
|
|
5242
|
+
}
|
|
5243
|
+
var init_chartParts = __esm({
|
|
5244
|
+
"src/renderers/office-open/chartParts.ts"() {
|
|
5245
|
+
"use strict";
|
|
5246
|
+
init_chartText();
|
|
5247
|
+
init_chartLook();
|
|
5248
|
+
}
|
|
5249
|
+
});
|
|
5250
|
+
|
|
5251
|
+
// src/renderers/office-open/themePart.ts
|
|
5252
|
+
function replaceOnce(xml, pattern, replacer, what) {
|
|
5253
|
+
const count = [...xml.matchAll(pattern)].length;
|
|
5254
|
+
if (count !== 1) {
|
|
5255
|
+
throw new Error(
|
|
5256
|
+
`office-open's theme part has ${count} ${what}, expected one`
|
|
4233
5257
|
);
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
5258
|
+
}
|
|
5259
|
+
return xml.replace(pattern, replacer);
|
|
5260
|
+
}
|
|
5261
|
+
function spliceTheme(zip, theme) {
|
|
5262
|
+
const entry = zip.getEntry(THEME_PART);
|
|
5263
|
+
if (!entry) throw new Error(`office-open wrote no ${THEME_PART}`);
|
|
5264
|
+
let xml = entry.getData().toString("utf8");
|
|
5265
|
+
const name = esc(theme.name);
|
|
5266
|
+
xml = renamed(xml, "theme", name);
|
|
5267
|
+
const colors = Object.entries(theme.colors);
|
|
5268
|
+
if (colors.some(([, color]) => color)) {
|
|
5269
|
+
xml = renamed(xml, "clrScheme", name);
|
|
5270
|
+
for (const [slot, color] of colors) {
|
|
5271
|
+
if (!color) continue;
|
|
5272
|
+
const element = SCHEME_ELEMENT[slot];
|
|
5273
|
+
xml = replaceOnce(
|
|
5274
|
+
xml,
|
|
5275
|
+
new RegExp(`<a:${element}>[\\s\\S]*?</a:${element}>`, "g"),
|
|
5276
|
+
() => `<a:${element}><a:srgbClr val="${color.hex}"/></a:${element}>`,
|
|
5277
|
+
`a:${element}`
|
|
5278
|
+
);
|
|
5279
|
+
}
|
|
5280
|
+
}
|
|
5281
|
+
if (theme.headingFont || theme.bodyFont) {
|
|
5282
|
+
xml = renamed(xml, "fontScheme", name);
|
|
5283
|
+
for (const [collection, key, officeFace] of OFFICE_FACES) {
|
|
5284
|
+
const family = theme[key];
|
|
5285
|
+
if (family === void 0 || family === officeFace) continue;
|
|
5286
|
+
xml = replaceOnce(
|
|
5287
|
+
xml,
|
|
5288
|
+
new RegExp(`(<a:${collection}>)<a:latin\\b[^>]*/>`, "g"),
|
|
5289
|
+
(_match, open) => `${open}<a:latin typeface="${esc(family)}"/>`,
|
|
5290
|
+
`a:${collection} a:latin`
|
|
5291
|
+
);
|
|
5292
|
+
}
|
|
5293
|
+
}
|
|
5294
|
+
zip.updateFile(THEME_PART, Buffer.from(xml, "utf8"));
|
|
5295
|
+
}
|
|
5296
|
+
var THEME_PART, SCHEME_ELEMENT, OFFICE_FACES, esc, renamed;
|
|
5297
|
+
var init_themePart = __esm({
|
|
5298
|
+
"src/renderers/office-open/themePart.ts"() {
|
|
5299
|
+
"use strict";
|
|
5300
|
+
THEME_PART = "word/theme/theme1.xml";
|
|
5301
|
+
SCHEME_ELEMENT = {
|
|
5302
|
+
dark1: "dk1",
|
|
5303
|
+
light1: "lt1",
|
|
5304
|
+
dark2: "dk2",
|
|
5305
|
+
light2: "lt2",
|
|
5306
|
+
accent1: "accent1",
|
|
5307
|
+
accent2: "accent2",
|
|
5308
|
+
accent3: "accent3",
|
|
5309
|
+
accent4: "accent4",
|
|
5310
|
+
accent5: "accent5",
|
|
5311
|
+
accent6: "accent6",
|
|
5312
|
+
hyperlink: "hlink",
|
|
5313
|
+
followedHyperlink: "folHlink"
|
|
5314
|
+
};
|
|
5315
|
+
OFFICE_FACES = [
|
|
5316
|
+
["majorFont", "headingFont", "Calibri Light"],
|
|
5317
|
+
["minorFont", "bodyFont", "Calibri"]
|
|
5318
|
+
];
|
|
5319
|
+
esc = (value) => value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
5320
|
+
renamed = (xml, element, name) => replaceOnce(
|
|
5321
|
+
xml,
|
|
5322
|
+
new RegExp(`(<a:${element}\\b[^>]*?\\bname=")[^"]*(")`, "g"),
|
|
5323
|
+
(_match, open, close) => `${open}${name}${close}`,
|
|
5324
|
+
`a:${element} name`
|
|
4237
5325
|
);
|
|
4238
5326
|
}
|
|
4239
|
-
|
|
5327
|
+
});
|
|
5328
|
+
|
|
5329
|
+
// src/utils/chartWorkbook.ts
|
|
5330
|
+
import AdmZip4 from "adm-zip";
|
|
5331
|
+
import { chartWorkbookParts } from "@json-to-office/shared/rendering";
|
|
5332
|
+
import {
|
|
5333
|
+
CHART_WORKBOOK_SHEET_NAME,
|
|
5334
|
+
categoryReference,
|
|
5335
|
+
columnLetter,
|
|
5336
|
+
seriesNameReference,
|
|
5337
|
+
seriesValueReference
|
|
5338
|
+
} from "@json-to-office/shared/rendering";
|
|
5339
|
+
function buildChartWorkbook(series, options = {}) {
|
|
5340
|
+
const zip = new AdmZip4();
|
|
5341
|
+
for (const [name, content] of chartWorkbookParts(series, options)) {
|
|
5342
|
+
zip.addFile(name, Buffer.from(content, "utf8"));
|
|
5343
|
+
}
|
|
5344
|
+
for (const entry of zip.getEntries()) {
|
|
5345
|
+
entry.header.timeval = WORKBOOK_TIMESTAMP;
|
|
5346
|
+
}
|
|
5347
|
+
return new Uint8Array(zip.toBuffer());
|
|
4240
5348
|
}
|
|
4241
|
-
var
|
|
4242
|
-
var
|
|
4243
|
-
"src/
|
|
5349
|
+
var WORKBOOK_TIMESTAMP;
|
|
5350
|
+
var init_chartWorkbook = __esm({
|
|
5351
|
+
"src/utils/chartWorkbook.ts"() {
|
|
4244
5352
|
"use strict";
|
|
4245
|
-
|
|
4246
|
-
|
|
5353
|
+
init_packageDocument();
|
|
5354
|
+
WORKBOOK_TIMESTAMP = toDosTime(DEFAULT_GENERATION_DATE);
|
|
4247
5355
|
}
|
|
4248
5356
|
});
|
|
4249
5357
|
|
|
4250
5358
|
// src/renderers/office-open/emit.ts
|
|
4251
|
-
import { assertNever as
|
|
5359
|
+
import { assertNever as assertNever3 } from "@json-to-office/shared/rendering";
|
|
5360
|
+
import { chartLook, withSeriesLook } from "@json-to-office/shared/rendering";
|
|
4252
5361
|
function emptyContext() {
|
|
4253
5362
|
let next = 1;
|
|
4254
|
-
return {
|
|
5363
|
+
return {
|
|
5364
|
+
pictures: /* @__PURE__ */ new Map(),
|
|
5365
|
+
nextDrawingId: () => next++,
|
|
5366
|
+
charts: []
|
|
5367
|
+
};
|
|
4255
5368
|
}
|
|
4256
5369
|
function simpleField(instruction, cachedText) {
|
|
4257
5370
|
return {
|
|
@@ -4261,6 +5374,9 @@ function simpleField(instruction, cachedText) {
|
|
|
4261
5374
|
}
|
|
4262
5375
|
};
|
|
4263
5376
|
}
|
|
5377
|
+
function twips(value) {
|
|
5378
|
+
return Math.floor(value);
|
|
5379
|
+
}
|
|
4264
5380
|
function runProperties2(formatting) {
|
|
4265
5381
|
if (!formatting) return {};
|
|
4266
5382
|
const out = {};
|
|
@@ -4288,16 +5404,19 @@ function runProperties2(formatting) {
|
|
|
4288
5404
|
if (formatting.doubleStrike !== void 0) {
|
|
4289
5405
|
out.doubleStrike = formatting.doubleStrike;
|
|
4290
5406
|
}
|
|
4291
|
-
if (formatting.superScript) out.
|
|
4292
|
-
if (formatting.subScript) out.
|
|
5407
|
+
if (formatting.superScript) out.verticalAlign = "superscript";
|
|
5408
|
+
if (formatting.subScript) out.verticalAlign = "subscript";
|
|
4293
5409
|
if (formatting.smallCaps !== void 0) out.smallCaps = formatting.smallCaps;
|
|
4294
5410
|
if (formatting.allCaps !== void 0) out.allCaps = formatting.allCaps;
|
|
4295
|
-
if (formatting.highlight !== void 0)
|
|
5411
|
+
if (formatting.highlight !== void 0) {
|
|
5412
|
+
out.highlight = formatting.highlight;
|
|
5413
|
+
}
|
|
4296
5414
|
if (formatting.shading) out.shading = shading(formatting.shading);
|
|
4297
5415
|
if (formatting.scalePercent !== void 0)
|
|
4298
5416
|
out.scale = formatting.scalePercent;
|
|
4299
|
-
|
|
4300
|
-
|
|
5417
|
+
const stated = formatting.characterSpacingTwentieths;
|
|
5418
|
+
if (stated !== void 0 && stated !== 0) {
|
|
5419
|
+
out.characterSpacing = twips(stated);
|
|
4301
5420
|
}
|
|
4302
5421
|
if (formatting.language) out.language = { value: formatting.language };
|
|
4303
5422
|
if (formatting.noProof !== void 0) out.noProof = formatting.noProof;
|
|
@@ -4327,7 +5446,9 @@ function inlineChildren2(children, ctx = emptyContext()) {
|
|
|
4327
5446
|
switch (child.kind) {
|
|
4328
5447
|
case "lineBreak":
|
|
4329
5448
|
pendingBreaks += 1;
|
|
4330
|
-
if (child.clear && child.clear !== "none")
|
|
5449
|
+
if (child.clear && child.clear !== "none") {
|
|
5450
|
+
pendingClear = child.clear;
|
|
5451
|
+
}
|
|
4331
5452
|
break;
|
|
4332
5453
|
case "text":
|
|
4333
5454
|
out.push({
|
|
@@ -4365,7 +5486,7 @@ function inlineChildren2(children, ctx = emptyContext()) {
|
|
|
4365
5486
|
case "drawingGroup": {
|
|
4366
5487
|
const pending = breakOption();
|
|
4367
5488
|
if (pending.break) out.push(pending);
|
|
4368
|
-
out.push({ wpgGroup:
|
|
5489
|
+
out.push({ wpgGroup: drawingGroupOptions2(child, ctx) });
|
|
4369
5490
|
break;
|
|
4370
5491
|
}
|
|
4371
5492
|
case "hyperlink":
|
|
@@ -4395,8 +5516,9 @@ function inlineChildren2(children, ctx = emptyContext()) {
|
|
|
4395
5516
|
out.push({ wpsShape: shapeOptions(child, ctx) });
|
|
4396
5517
|
break;
|
|
4397
5518
|
case "chart":
|
|
4398
|
-
|
|
4399
|
-
|
|
5519
|
+
out.push({
|
|
5520
|
+
chart: chartOptions(child, ctx, ctx.charts?.push(child) ?? 1)
|
|
5521
|
+
});
|
|
4400
5522
|
break;
|
|
4401
5523
|
case "noteReference":
|
|
4402
5524
|
out.push(
|
|
@@ -4404,7 +5526,7 @@ function inlineChildren2(children, ctx = emptyContext()) {
|
|
|
4404
5526
|
);
|
|
4405
5527
|
break;
|
|
4406
5528
|
default:
|
|
4407
|
-
|
|
5529
|
+
assertNever3(child, "DocxIrInline");
|
|
4408
5530
|
}
|
|
4409
5531
|
}
|
|
4410
5532
|
return out;
|
|
@@ -4445,8 +5567,11 @@ function floatingOptions2(floating) {
|
|
|
4445
5567
|
...floating.vertical ? { verticalPosition: position(floating.vertical) } : {},
|
|
4446
5568
|
...floating.wrap ? {
|
|
4447
5569
|
wrap: {
|
|
4448
|
-
|
|
4449
|
-
|
|
5570
|
+
// Named, as OOXML names them; 0.11 took docx.js's numbers.
|
|
5571
|
+
type: floating.wrap.type,
|
|
5572
|
+
...floating.wrap.side ? {
|
|
5573
|
+
side: floating.wrap.side
|
|
5574
|
+
} : {}
|
|
4450
5575
|
}
|
|
4451
5576
|
} : {},
|
|
4452
5577
|
...floating.margins ? {
|
|
@@ -4473,66 +5598,92 @@ function imageMedia(ctx, resourceId, placement) {
|
|
|
4473
5598
|
}
|
|
4474
5599
|
function pictureOptions(image, ctx) {
|
|
4475
5600
|
const media = imageMedia(ctx, image.resourceId, image);
|
|
4476
|
-
|
|
4477
|
-
type:
|
|
5601
|
+
const source = media.type === "svg" ? {
|
|
5602
|
+
type: "svg",
|
|
4478
5603
|
data: media.data,
|
|
4479
|
-
//
|
|
4480
|
-
//
|
|
4481
|
-
|
|
5604
|
+
// The SVG slot always carries a raster: `prepareImages` falls back
|
|
5605
|
+
// to the vector bytes when none could be made.
|
|
5606
|
+
fallback: media.fallback ?? {
|
|
5607
|
+
type: "png",
|
|
5608
|
+
data: media.data
|
|
5609
|
+
}
|
|
5610
|
+
} : { type: media.type, data: media.data };
|
|
5611
|
+
return {
|
|
5612
|
+
...source,
|
|
4482
5613
|
// Raw numbers are EMUs in @office-open/docx. Passing pixels here makes a
|
|
4483
5614
|
// normal image only a few hundred EMUs wide, effectively a dot.
|
|
4484
5615
|
transformation: { width: image.widthEmu, height: image.heightEmu },
|
|
4485
5616
|
// The id is stated rather than left to the backend's process-global
|
|
4486
|
-
// counter. `name` stays empty, which is what
|
|
4487
|
-
|
|
4488
|
-
altText: { id: String(ctx.nextDrawingId()) },
|
|
5617
|
+
// counter. `name` stays empty, which is what the backend falls back to.
|
|
5618
|
+
altText: { id: String(ctx.nextDrawingId()), name: "" },
|
|
4489
5619
|
...image.floating ? { floating: floatingOptions2(image.floating) } : {}
|
|
4490
5620
|
// No `description` or `title`: no DOCX this pipeline has produced carries
|
|
4491
5621
|
// `wp:docPr` alt text, and the compiler warns so the gap is visible rather
|
|
4492
5622
|
// than silent.
|
|
4493
5623
|
};
|
|
4494
5624
|
}
|
|
4495
|
-
function
|
|
5625
|
+
function drawingGroupOptions2(group, ctx) {
|
|
4496
5626
|
const id = ctx.nextDrawingId();
|
|
4497
5627
|
return {
|
|
4498
5628
|
altText: {
|
|
4499
5629
|
id: String(id),
|
|
5630
|
+
name: "",
|
|
4500
5631
|
...group.altText ? { description: group.altText } : {}
|
|
4501
5632
|
},
|
|
4502
5633
|
transformation: { width: group.widthEmu, height: group.heightEmu },
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
5634
|
+
childOffsetX: 0,
|
|
5635
|
+
childOffsetY: 0,
|
|
5636
|
+
childExtentWidth: group.canvasWidthEmu,
|
|
5637
|
+
childExtentHeight: group.canvasHeightEmu,
|
|
5638
|
+
children: group.children.map((child) => groupChild2(child, ctx)),
|
|
4506
5639
|
...group.floating ? { floating: floatingOptions2(group.floating) } : {}
|
|
4507
5640
|
};
|
|
4508
5641
|
}
|
|
4509
|
-
function chartOptions(chart, ctx) {
|
|
5642
|
+
function chartOptions(chart, ctx, ordinal) {
|
|
4510
5643
|
const id = ctx.nextDrawingId();
|
|
5644
|
+
const input = chartInput(chart);
|
|
5645
|
+
const look = chartLook(input);
|
|
4511
5646
|
return {
|
|
4512
5647
|
type: chart.chartType,
|
|
4513
5648
|
categories: chart.series[0]?.labels ?? [],
|
|
4514
|
-
series: chart.series.map(
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
5649
|
+
series: chart.series.map(
|
|
5650
|
+
(entry, index) => withSeriesLook(
|
|
5651
|
+
{
|
|
5652
|
+
name: entry.name ?? `Series ${index + 1}`,
|
|
5653
|
+
values: entry.values,
|
|
5654
|
+
...seriesLook(chart.chartType)
|
|
5655
|
+
},
|
|
5656
|
+
look.series[index]
|
|
5657
|
+
)
|
|
5658
|
+
),
|
|
5659
|
+
...look.chart,
|
|
4519
5660
|
...chart.showLegend !== void 0 ? { showLegend: chart.showLegend } : {},
|
|
5661
|
+
externalData: {
|
|
5662
|
+
...look.chart.externalData,
|
|
5663
|
+
fileName: `chart${ordinal}.xlsx`,
|
|
5664
|
+
// A scatter chart's column A holds the x values its `c:xVal` caches.
|
|
5665
|
+
data: buildChartWorkbook(
|
|
5666
|
+
chart.series,
|
|
5667
|
+
input.scatterXValues ? { categoryValues: input.scatterXValues } : {}
|
|
5668
|
+
)
|
|
5669
|
+
},
|
|
4520
5670
|
transformation: { width: chart.widthEmu, height: chart.heightEmu },
|
|
4521
5671
|
altText: {
|
|
4522
5672
|
id: String(id),
|
|
5673
|
+
name: "",
|
|
4523
5674
|
...chart.altText ? { description: chart.altText } : {}
|
|
4524
5675
|
},
|
|
4525
5676
|
...chart.floating ? { floating: floatingOptions2(chart.floating) } : {}
|
|
4526
5677
|
};
|
|
4527
5678
|
}
|
|
4528
|
-
function
|
|
5679
|
+
function groupChild2(child, ctx) {
|
|
4529
5680
|
return child.kind === "shape" ? groupShape(child, ctx) : groupPicture(child, ctx);
|
|
4530
5681
|
}
|
|
4531
5682
|
function groupShape(shape, ctx) {
|
|
4532
5683
|
const id = ctx.nextDrawingId();
|
|
4533
5684
|
return {
|
|
4534
5685
|
type: "wps",
|
|
4535
|
-
transformation:
|
|
5686
|
+
transformation: childTransformation2(shape.frame),
|
|
4536
5687
|
data: {
|
|
4537
5688
|
nonVisualProperties: {
|
|
4538
5689
|
id,
|
|
@@ -4541,7 +5692,7 @@ function groupShape(shape, ctx) {
|
|
|
4541
5692
|
// to hold text, and it changes how the object behaves on selection.
|
|
4542
5693
|
...shape.isTextBox ? { textBox: "1" } : {}
|
|
4543
5694
|
},
|
|
4544
|
-
|
|
5695
|
+
geometry: shape.geometry,
|
|
4545
5696
|
...shape.fill ? { fill: drawingFill(shape.fill) } : {},
|
|
4546
5697
|
...shape.outline ? { outline: drawingOutline(shape.outline) } : {},
|
|
4547
5698
|
children: (shape.text?.paragraphs ?? []).map(
|
|
@@ -4567,7 +5718,7 @@ function groupPicture(picture2, ctx) {
|
|
|
4567
5718
|
fileName: media.fallbackFileName
|
|
4568
5719
|
}
|
|
4569
5720
|
} : {},
|
|
4570
|
-
transformation:
|
|
5721
|
+
transformation: childTransformation2(picture2.frame),
|
|
4571
5722
|
nonVisualProperties: {
|
|
4572
5723
|
id,
|
|
4573
5724
|
...picture2.name ? { name: picture2.name } : {},
|
|
@@ -4576,11 +5727,7 @@ function groupPicture(picture2, ctx) {
|
|
|
4576
5727
|
...picture2.crop ? { sourceRectangle: sourceRectangle(picture2.crop) } : {}
|
|
4577
5728
|
};
|
|
4578
5729
|
}
|
|
4579
|
-
function
|
|
4580
|
-
const flip = {
|
|
4581
|
-
...frame.flipHorizontal ? { horizontal: true } : {},
|
|
4582
|
-
...frame.flipVertical ? { vertical: true } : {}
|
|
4583
|
-
};
|
|
5730
|
+
function childTransformation2(frame) {
|
|
4584
5731
|
return {
|
|
4585
5732
|
offset: {
|
|
4586
5733
|
emus: { x: frame.xEmu, y: frame.yEmu },
|
|
@@ -4596,7 +5743,8 @@ function childTransformation(frame) {
|
|
|
4596
5743
|
},
|
|
4597
5744
|
// Degrees: the backend multiplies by 60000 on the way into `@rot`.
|
|
4598
5745
|
...frame.rotationDegrees !== void 0 ? { rotation: frame.rotationDegrees } : {},
|
|
4599
|
-
...
|
|
5746
|
+
...frame.flipHorizontal ? { flipHorizontal: true } : {},
|
|
5747
|
+
...frame.flipVertical ? { flipVertical: true } : {}
|
|
4600
5748
|
};
|
|
4601
5749
|
}
|
|
4602
5750
|
function drawingFill(fill) {
|
|
@@ -4604,7 +5752,6 @@ function drawingFill(fill) {
|
|
|
4604
5752
|
return {
|
|
4605
5753
|
type: "solid",
|
|
4606
5754
|
color: {
|
|
4607
|
-
type: "rgb",
|
|
4608
5755
|
value: fill.color.hex,
|
|
4609
5756
|
// Transparency becomes an alpha transform on the colour. DrawingML
|
|
4610
5757
|
// states *opacity*, so the value is the complement of what the author
|
|
@@ -4646,7 +5793,7 @@ function sourceRectangle(crop) {
|
|
|
4646
5793
|
function shapeOptions(shape, ctx) {
|
|
4647
5794
|
const id = String(ctx.nextDrawingId());
|
|
4648
5795
|
return {
|
|
4649
|
-
altText: { id },
|
|
5796
|
+
altText: { id, name: "" },
|
|
4650
5797
|
children: shape.children.map((child) => paragraph(child, ctx)),
|
|
4651
5798
|
// Raw transformation numbers are EMUs in @office-open/docx, while the IR
|
|
4652
5799
|
// deliberately stores native shape dimensions in pixels.
|
|
@@ -4657,7 +5804,7 @@ function shapeOptions(shape, ctx) {
|
|
|
4657
5804
|
...shape.fill ? {
|
|
4658
5805
|
fill: {
|
|
4659
5806
|
type: "solid",
|
|
4660
|
-
color: {
|
|
5807
|
+
color: { value: shape.fill.hex }
|
|
4661
5808
|
}
|
|
4662
5809
|
} : {},
|
|
4663
5810
|
...shape.outline ? { outline: drawingOutline(shape.outline) } : {},
|
|
@@ -4688,16 +5835,16 @@ function paragraphProperties2(formatting) {
|
|
|
4688
5835
|
if (formatting.indent) {
|
|
4689
5836
|
const indent = {};
|
|
4690
5837
|
if (formatting.indent.leftTwips !== void 0) {
|
|
4691
|
-
indent.left = formatting.indent.leftTwips;
|
|
5838
|
+
indent.left = twips(formatting.indent.leftTwips);
|
|
4692
5839
|
}
|
|
4693
5840
|
if (formatting.indent.rightTwips !== void 0) {
|
|
4694
|
-
indent.right = formatting.indent.rightTwips;
|
|
5841
|
+
indent.right = twips(formatting.indent.rightTwips);
|
|
4695
5842
|
}
|
|
4696
5843
|
if (formatting.indent.firstLineTwips !== void 0) {
|
|
4697
|
-
indent.firstLine = formatting.indent.firstLineTwips;
|
|
5844
|
+
indent.firstLine = twips(formatting.indent.firstLineTwips);
|
|
4698
5845
|
}
|
|
4699
5846
|
if (formatting.indent.hangingTwips !== void 0) {
|
|
4700
|
-
indent.hanging = formatting.indent.hangingTwips;
|
|
5847
|
+
indent.hanging = twips(formatting.indent.hangingTwips);
|
|
4701
5848
|
}
|
|
4702
5849
|
out.indent = indent;
|
|
4703
5850
|
}
|
|
@@ -4762,13 +5909,19 @@ function frameOptions2(frame) {
|
|
|
4762
5909
|
...frame.anchorLock !== void 0 ? { anchorLock: frame.anchorLock } : {},
|
|
4763
5910
|
...frame.rule ? { rule: frame.rule } : {}
|
|
4764
5911
|
};
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
5912
|
+
if (frame.xTwips !== void 0 || frame.yTwips !== void 0) {
|
|
5913
|
+
return {
|
|
5914
|
+
type: "absolute",
|
|
5915
|
+
position: { x: frame.xTwips ?? 0, y: frame.yTwips ?? 0 },
|
|
5916
|
+
...base
|
|
5917
|
+
};
|
|
5918
|
+
}
|
|
5919
|
+
return {
|
|
4770
5920
|
type: "alignment",
|
|
4771
|
-
alignment: {
|
|
5921
|
+
alignment: {
|
|
5922
|
+
x: frame.xAlign,
|
|
5923
|
+
y: frame.yAlign
|
|
5924
|
+
},
|
|
4772
5925
|
...base
|
|
4773
5926
|
};
|
|
4774
5927
|
}
|
|
@@ -4789,7 +5942,7 @@ function block(value, ctx = emptyContext()) {
|
|
|
4789
5942
|
case "toc":
|
|
4790
5943
|
return { toc: tableOfContents(value) };
|
|
4791
5944
|
default:
|
|
4792
|
-
return
|
|
5945
|
+
return assertNever3(value, "DocxIrBlock");
|
|
4793
5946
|
}
|
|
4794
5947
|
}
|
|
4795
5948
|
function tocEntry(entry) {
|
|
@@ -4808,6 +5961,7 @@ function tableOfContents(value) {
|
|
|
4808
5961
|
headingStyleRange: `${value.headingRange.from}-${value.headingRange.to}`
|
|
4809
5962
|
} : {},
|
|
4810
5963
|
...value.styleLevels?.length ? {
|
|
5964
|
+
// `StyleLevel` is a class the backend only reads the two fields of.
|
|
4811
5965
|
stylesWithLevels: value.styleLevels.map((style) => ({
|
|
4812
5966
|
styleName: style.styleName,
|
|
4813
5967
|
level: style.level
|
|
@@ -4828,15 +5982,17 @@ function table(value, ctx) {
|
|
|
4828
5982
|
// `w:w` is an integer in OOXML. A grid that splits a remainder between
|
|
4829
5983
|
// unstated columns comes out fractional, and the XML would carry it
|
|
4830
5984
|
// verbatim; floored here, as the docxjs backend floors it.
|
|
4831
|
-
size: value.width.kind === "auto" ? 0 : value.width.kind === "twips" ?
|
|
4832
|
-
type: value.width.kind === "twips" ? "
|
|
5985
|
+
size: value.width.kind === "auto" ? 0 : value.width.kind === "twips" ? twips(value.width.value) : value.width.value,
|
|
5986
|
+
type: value.width.kind === "twips" ? "twips" : value.width.kind === "percent" ? "percent" : "auto"
|
|
4833
5987
|
},
|
|
4834
5988
|
layout: value.layout,
|
|
4835
5989
|
// An empty grid is a table with nothing to say about its columns, which is
|
|
4836
5990
|
// not the same as one whose columns are all zero wide. The compiler hands
|
|
4837
5991
|
// over every grid in twips; floored for the same reason as the width.
|
|
4838
|
-
...value.columnGrid.values.length > 0 ? { columnWidths: value.columnGrid.values.map(
|
|
4839
|
-
...value.alignment ? {
|
|
5992
|
+
...value.columnGrid.values.length > 0 ? { columnWidths: value.columnGrid.values.map(twips) } : {},
|
|
5993
|
+
...value.alignment ? {
|
|
5994
|
+
alignment: alignment(value.alignment)
|
|
5995
|
+
} : {},
|
|
4840
5996
|
...value.borders ? { borders: borders2(value.borders) } : {},
|
|
4841
5997
|
...value.cellMargins ? { margins: cellMargins(value.cellMargins) } : {},
|
|
4842
5998
|
...value.floating ? { float: tableFloat2(value.floating) } : {}
|
|
@@ -4846,14 +6002,22 @@ function tableFloat2(floating) {
|
|
|
4846
6002
|
return {
|
|
4847
6003
|
...floating.horizontalAnchor ? { horizontalAnchor: floating.horizontalAnchor } : {},
|
|
4848
6004
|
...floating.verticalAnchor ? { verticalAnchor: floating.verticalAnchor } : {},
|
|
4849
|
-
...floating.absoluteHorizontalPositionTwips !== void 0 ? {
|
|
6005
|
+
...floating.absoluteHorizontalPositionTwips !== void 0 ? {
|
|
6006
|
+
absoluteHorizontalPosition: twips(
|
|
6007
|
+
floating.absoluteHorizontalPositionTwips
|
|
6008
|
+
)
|
|
6009
|
+
} : {},
|
|
4850
6010
|
...floating.relativeHorizontalPosition ? { relativeHorizontalPosition: floating.relativeHorizontalPosition } : {},
|
|
4851
|
-
...floating.absoluteVerticalPositionTwips !== void 0 ? {
|
|
6011
|
+
...floating.absoluteVerticalPositionTwips !== void 0 ? {
|
|
6012
|
+
absoluteVerticalPosition: twips(
|
|
6013
|
+
floating.absoluteVerticalPositionTwips
|
|
6014
|
+
)
|
|
6015
|
+
} : {},
|
|
4852
6016
|
...floating.relativeVerticalPosition ? { relativeVerticalPosition: floating.relativeVerticalPosition } : {},
|
|
4853
|
-
...floating.topFromTextTwips !== void 0 ? { topFromText: floating.topFromTextTwips } : {},
|
|
4854
|
-
...floating.rightFromTextTwips !== void 0 ? { rightFromText: floating.rightFromTextTwips } : {},
|
|
4855
|
-
...floating.bottomFromTextTwips !== void 0 ? { bottomFromText: floating.bottomFromTextTwips } : {},
|
|
4856
|
-
...floating.leftFromTextTwips !== void 0 ? { leftFromText: floating.leftFromTextTwips } : {},
|
|
6017
|
+
...floating.topFromTextTwips !== void 0 ? { topFromText: twips(floating.topFromTextTwips) } : {},
|
|
6018
|
+
...floating.rightFromTextTwips !== void 0 ? { rightFromText: twips(floating.rightFromTextTwips) } : {},
|
|
6019
|
+
...floating.bottomFromTextTwips !== void 0 ? { bottomFromText: twips(floating.bottomFromTextTwips) } : {},
|
|
6020
|
+
...floating.leftFromTextTwips !== void 0 ? { leftFromText: twips(floating.leftFromTextTwips) } : {},
|
|
4857
6021
|
...floating.overlap ? { overlap: floating.overlap } : {}
|
|
4858
6022
|
};
|
|
4859
6023
|
}
|
|
@@ -4861,7 +6025,10 @@ function tableRow(row, ctx) {
|
|
|
4861
6025
|
return {
|
|
4862
6026
|
cells: row.cells.map((cell) => tableCell(cell, ctx)),
|
|
4863
6027
|
...row.heightTwips !== void 0 ? {
|
|
4864
|
-
height: {
|
|
6028
|
+
height: {
|
|
6029
|
+
value: twips(row.heightTwips),
|
|
6030
|
+
rule: row.heightRule ?? "atLeast"
|
|
6031
|
+
}
|
|
4865
6032
|
} : {},
|
|
4866
6033
|
...row.isHeader !== void 0 ? { tableHeader: row.isHeader } : {},
|
|
4867
6034
|
...row.cantSplit !== void 0 ? { cantSplit: row.cantSplit } : {},
|
|
@@ -4869,20 +6036,30 @@ function tableRow(row, ctx) {
|
|
|
4869
6036
|
};
|
|
4870
6037
|
}
|
|
4871
6038
|
function tableCell(cell, ctx) {
|
|
6039
|
+
const children = cellChildren2(cell, ctx);
|
|
6040
|
+
if (cell.children[cell.children.length - 1]?.kind === "toc")
|
|
6041
|
+
children.push({ paragraph: { children: [] } });
|
|
4872
6042
|
return {
|
|
4873
|
-
children
|
|
4874
|
-
...cell.widthTwips !== void 0 ? { width: { size: cell.widthTwips, type: "
|
|
4875
|
-
...cell.verticalAlign ? {
|
|
6043
|
+
children,
|
|
6044
|
+
...cell.widthTwips !== void 0 ? { width: { size: twips(cell.widthTwips), type: "twips" } } : {},
|
|
6045
|
+
...cell.verticalAlign ? {
|
|
6046
|
+
verticalAlign: cell.verticalAlign
|
|
6047
|
+
} : {},
|
|
4876
6048
|
...cell.shading ? { shading: shading(cell.shading) } : {},
|
|
4877
6049
|
...cell.margins ? { margins: cellMargins(cell.margins) } : {},
|
|
4878
6050
|
...cell.borders ? { borders: borders2(cell.borders) } : {},
|
|
4879
6051
|
...cell.columnSpan !== void 0 ? { columnSpan: cell.columnSpan } : {},
|
|
4880
6052
|
...cell.rowSpan !== void 0 ? { verticalMerge: cell.rowSpan } : {},
|
|
4881
|
-
...cell.textDirection ? {
|
|
6053
|
+
...cell.textDirection ? {
|
|
6054
|
+
textDirection: cell.textDirection
|
|
6055
|
+
} : {}
|
|
4882
6056
|
};
|
|
4883
6057
|
}
|
|
6058
|
+
function cellChildren2(cell, ctx) {
|
|
6059
|
+
return cell.children.map((child) => block(child, ctx));
|
|
6060
|
+
}
|
|
4884
6061
|
function cellMargins(margins) {
|
|
4885
|
-
const side = (value) => value === void 0 ? void 0 : { size: value, type: "
|
|
6062
|
+
const side = (value) => value === void 0 ? void 0 : { size: twips(value), type: "twips" };
|
|
4886
6063
|
const out = {};
|
|
4887
6064
|
for (const [name, value] of [
|
|
4888
6065
|
["top", margins.topTwips],
|
|
@@ -4925,47 +6102,51 @@ function section(value, ctx, closesDocument = false) {
|
|
|
4925
6102
|
properties: {
|
|
4926
6103
|
...value.properties.type ? { type: value.properties.type } : {},
|
|
4927
6104
|
...value.properties.titlePage !== void 0 ? { titlePage: value.properties.titlePage } : {},
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
...page.code !== void 0 ? { code: page.code } : {}
|
|
4935
|
-
},
|
|
4936
|
-
margin: {
|
|
4937
|
-
top: page.margins.topTwips,
|
|
4938
|
-
right: page.margins.rightTwips,
|
|
4939
|
-
bottom: page.margins.bottomTwips,
|
|
4940
|
-
left: page.margins.leftTwips,
|
|
4941
|
-
...page.margins.headerTwips !== void 0 ? { header: page.margins.headerTwips } : {},
|
|
4942
|
-
...page.margins.footerTwips !== void 0 ? { footer: page.margins.footerTwips } : {},
|
|
4943
|
-
...page.margins.gutterTwips !== void 0 ? { gutter: page.margins.gutterTwips } : {}
|
|
4944
|
-
},
|
|
4945
|
-
...value.properties.pageNumbers ? {
|
|
4946
|
-
pageNumbers: {
|
|
4947
|
-
...value.properties.pageNumbers.start !== void 0 ? { start: value.properties.pageNumbers.start } : {},
|
|
4948
|
-
...value.properties.pageNumbers.formatType ? { formatType: value.properties.pageNumbers.formatType } : {}
|
|
4949
|
-
}
|
|
4950
|
-
} : {},
|
|
4951
|
-
...value.properties.borders ? {
|
|
4952
|
-
borders: {
|
|
4953
|
-
...value.properties.borders.display ? { display: value.properties.borders.display } : {},
|
|
4954
|
-
...value.properties.borders.offsetFrom ? { offsetFrom: value.properties.borders.offsetFrom } : {},
|
|
4955
|
-
...value.properties.borders.borders ? borders2(value.properties.borders.borders) : {}
|
|
4956
|
-
}
|
|
4957
|
-
} : {}
|
|
6105
|
+
// Orientation is implied by the width/height pair, which is how this
|
|
6106
|
+
// pipeline has always expressed it; stating it as well changes `w:pgSz`.
|
|
6107
|
+
pageSize: {
|
|
6108
|
+
width: twips(page.widthTwips),
|
|
6109
|
+
height: twips(page.heightTwips),
|
|
6110
|
+
...page.code !== void 0 ? { code: page.code } : {}
|
|
4958
6111
|
},
|
|
6112
|
+
pageMargin: {
|
|
6113
|
+
top: twips(page.margins.topTwips),
|
|
6114
|
+
right: twips(page.margins.rightTwips),
|
|
6115
|
+
bottom: twips(page.margins.bottomTwips),
|
|
6116
|
+
left: twips(page.margins.leftTwips),
|
|
6117
|
+
...page.margins.headerTwips !== void 0 ? { header: twips(page.margins.headerTwips) } : {},
|
|
6118
|
+
...page.margins.footerTwips !== void 0 ? { footer: twips(page.margins.footerTwips) } : {},
|
|
6119
|
+
...page.margins.gutterTwips !== void 0 ? { gutter: twips(page.margins.gutterTwips) } : {}
|
|
6120
|
+
},
|
|
6121
|
+
...value.properties.pageNumbers ? {
|
|
6122
|
+
pageNumberType: {
|
|
6123
|
+
...value.properties.pageNumbers.start !== void 0 ? { start: value.properties.pageNumbers.start } : {},
|
|
6124
|
+
...value.properties.pageNumbers.formatType ? {
|
|
6125
|
+
format: value.properties.pageNumbers.formatType
|
|
6126
|
+
} : {}
|
|
6127
|
+
}
|
|
6128
|
+
} : {},
|
|
6129
|
+
...value.properties.borders ? {
|
|
6130
|
+
pageBorders: {
|
|
6131
|
+
...value.properties.borders.display ? {
|
|
6132
|
+
display: value.properties.borders.display
|
|
6133
|
+
} : {},
|
|
6134
|
+
...value.properties.borders.offsetFrom ? {
|
|
6135
|
+
offsetFrom: value.properties.borders.offsetFrom
|
|
6136
|
+
} : {},
|
|
6137
|
+
...value.properties.borders.borders ? borders2(value.properties.borders.borders) : {}
|
|
6138
|
+
}
|
|
6139
|
+
} : {},
|
|
4959
6140
|
...columns ? {
|
|
4960
|
-
|
|
6141
|
+
columns: {
|
|
4961
6142
|
count: columns.count,
|
|
4962
|
-
...columns.spaceTwips !== void 0 ? { space: columns.spaceTwips } : {},
|
|
6143
|
+
...columns.spaceTwips !== void 0 ? { space: twips(columns.spaceTwips) } : {},
|
|
4963
6144
|
...columns.separator !== void 0 ? { separate: columns.separator } : {},
|
|
4964
6145
|
...columns.equalWidth !== void 0 ? { equalWidth: columns.equalWidth } : {},
|
|
4965
6146
|
...columns.widths ? {
|
|
4966
6147
|
children: columns.widths.map((column) => ({
|
|
4967
|
-
width: column.widthTwips,
|
|
4968
|
-
...column.spaceTwips !== void 0 ? { space: column.spaceTwips } : {}
|
|
6148
|
+
width: twips(column.widthTwips),
|
|
6149
|
+
...column.spaceTwips !== void 0 ? { space: twips(column.spaceTwips) } : {}
|
|
4969
6150
|
}))
|
|
4970
6151
|
} : {}
|
|
4971
6152
|
}
|
|
@@ -4993,14 +6174,16 @@ function headerFooterSet(set, ctx) {
|
|
|
4993
6174
|
function sectionChildren2(value, ctx, closesDocument = false) {
|
|
4994
6175
|
const blocks = value.children.map((child) => block(child, ctx));
|
|
4995
6176
|
const last = value.children[value.children.length - 1];
|
|
4996
|
-
|
|
6177
|
+
const bookmark = value.bookmark;
|
|
6178
|
+
if (bookmark?.closes && last?.kind !== "paragraph" || closesDocument && last?.kind === "paragraph" && last.frame !== void 0)
|
|
4997
6179
|
blocks.push({
|
|
4998
6180
|
paragraph: {
|
|
4999
6181
|
children: [],
|
|
5000
6182
|
spacing: { before: 0, after: 0, line: 20, lineRule: "exact" }
|
|
5001
6183
|
}
|
|
5002
6184
|
});
|
|
5003
|
-
|
|
6185
|
+
if (!closesDocument && !bookmark?.closes && last?.kind === "toc")
|
|
6186
|
+
blocks.push({ paragraph: { children: [] } });
|
|
5004
6187
|
if (!bookmark) return blocks;
|
|
5005
6188
|
return [
|
|
5006
6189
|
...bookmark.opens ? [{ bookmarkStart: { id: bookmark.id, name: bookmark.name } }] : [],
|
|
@@ -5011,43 +6194,44 @@ function sectionChildren2(value, ctx, closesDocument = false) {
|
|
|
5011
6194
|
function numberingConfig2(numbering) {
|
|
5012
6195
|
return {
|
|
5013
6196
|
reference: numbering.reference,
|
|
5014
|
-
levels: numbering.levels.map(
|
|
5015
|
-
level
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
6197
|
+
levels: numbering.levels.map(
|
|
6198
|
+
(level) => ({
|
|
6199
|
+
level: level.level,
|
|
6200
|
+
format: level.format,
|
|
6201
|
+
text: level.text,
|
|
6202
|
+
...level.alignment ? { alignment: alignment(level.alignment) } : {},
|
|
6203
|
+
...level.suffix ? { suffix: level.suffix } : {},
|
|
6204
|
+
// Always stated. docx.js writes `w:start w:val="1"` for a level that
|
|
6205
|
+
// names none, and so did this backend until 0.14, which writes no
|
|
6206
|
+
// `w:start` at all when it is not given one; Word and LibreOffice then
|
|
6207
|
+
// count every such list from 0.
|
|
6208
|
+
start: level.start ?? 1,
|
|
6209
|
+
...level.paragraphStyleId ? { paragraphStyle: level.paragraphStyleId } : {},
|
|
5023
6210
|
...level.indent ? {
|
|
5024
6211
|
paragraph: {
|
|
5025
6212
|
indent: {
|
|
5026
|
-
...level.indent.leftTwips !== void 0 ? { left: level.indent.leftTwips } : {},
|
|
5027
|
-
...level.indent.hangingTwips !== void 0 ? { hanging: level.indent.hangingTwips } : {}
|
|
6213
|
+
...level.indent.leftTwips !== void 0 ? { left: twips(level.indent.leftTwips) } : {},
|
|
6214
|
+
...level.indent.hangingTwips !== void 0 ? { hanging: twips(level.indent.hangingTwips) } : {}
|
|
5028
6215
|
}
|
|
5029
6216
|
}
|
|
5030
6217
|
} : {},
|
|
5031
6218
|
...level.run ? { run: runProperties2(level.run) } : {}
|
|
5032
|
-
}
|
|
5033
|
-
|
|
6219
|
+
})
|
|
6220
|
+
)
|
|
5034
6221
|
};
|
|
5035
6222
|
}
|
|
5036
|
-
var
|
|
6223
|
+
var BODY_ANCHOR;
|
|
5037
6224
|
var init_emit2 = __esm({
|
|
5038
6225
|
"src/renderers/office-open/emit.ts"() {
|
|
5039
6226
|
"use strict";
|
|
5040
6227
|
init_units();
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
tight: 2,
|
|
5045
|
-
topAndBottom: 3
|
|
5046
|
-
};
|
|
6228
|
+
init_chartWorkbook();
|
|
6229
|
+
init_chartLook();
|
|
6230
|
+
init_chartParts();
|
|
5047
6231
|
BODY_ANCHOR = {
|
|
5048
|
-
top: "
|
|
5049
|
-
middle: "
|
|
5050
|
-
bottom: "
|
|
6232
|
+
top: "top",
|
|
6233
|
+
middle: "center",
|
|
6234
|
+
bottom: "bottom"
|
|
5051
6235
|
};
|
|
5052
6236
|
}
|
|
5053
6237
|
});
|
|
@@ -5107,15 +6291,34 @@ var init_styles3 = __esm({
|
|
|
5107
6291
|
var office_open_exports = {};
|
|
5108
6292
|
__export(office_open_exports, {
|
|
5109
6293
|
OFFICE_OPEN_DOCX_RENDERER_ID: () => OFFICE_OPEN_DOCX_RENDERER_ID,
|
|
6294
|
+
OFFICE_OPEN_VERSION: () => OFFICE_OPEN_VERSION,
|
|
5110
6295
|
buildDocumentOptions: () => buildDocumentOptions,
|
|
5111
6296
|
createOfficeOpenDocxRenderer: () => createOfficeOpenDocxRenderer
|
|
5112
6297
|
});
|
|
5113
|
-
import
|
|
6298
|
+
import AdmZip5 from "adm-zip";
|
|
6299
|
+
import {
|
|
6300
|
+
assertBackendVersion,
|
|
6301
|
+
installedPackageVersion
|
|
6302
|
+
} from "@json-to-office/shared/rendering/node";
|
|
6303
|
+
function installedBackendVersion() {
|
|
6304
|
+
let resolved;
|
|
6305
|
+
try {
|
|
6306
|
+
resolved = import.meta.resolve?.(OFFICE_OPEN_DOCX);
|
|
6307
|
+
} catch {
|
|
6308
|
+
resolved = void 0;
|
|
6309
|
+
}
|
|
6310
|
+
return installedPackageVersion(OFFICE_OPEN_DOCX, import.meta.url, resolved);
|
|
6311
|
+
}
|
|
5114
6312
|
async function createOfficeOpenDocxRenderer() {
|
|
5115
6313
|
const backend = await import(
|
|
5116
6314
|
/* @vite-ignore */
|
|
5117
6315
|
OFFICE_OPEN_DOCX
|
|
5118
6316
|
);
|
|
6317
|
+
assertBackendVersion(
|
|
6318
|
+
OFFICE_OPEN_DOCX,
|
|
6319
|
+
OFFICE_OPEN_VERSION,
|
|
6320
|
+
installedBackendVersion()
|
|
6321
|
+
);
|
|
5119
6322
|
if (typeof backend.generateDocument !== "function") {
|
|
5120
6323
|
throw new Error(
|
|
5121
6324
|
`${OFFICE_OPEN_DOCX} does not export generateDocument(); the installed version is not compatible with this adapter.`
|
|
@@ -5126,10 +6329,10 @@ async function createOfficeOpenDocxRenderer() {
|
|
|
5126
6329
|
format: "docx",
|
|
5127
6330
|
capabilities: OFFICE_OPEN_CAPABILITIES,
|
|
5128
6331
|
async render(ir, options) {
|
|
5129
|
-
const
|
|
6332
|
+
const charts2 = [];
|
|
5130
6333
|
const document = await buildDocumentOptions(
|
|
5131
6334
|
ir,
|
|
5132
|
-
|
|
6335
|
+
charts2,
|
|
5133
6336
|
options?.svgRasterFallback
|
|
5134
6337
|
);
|
|
5135
6338
|
const bytes = await backend.generateDocument(document, {
|
|
@@ -5138,9 +6341,10 @@ async function createOfficeOpenDocxRenderer() {
|
|
|
5138
6341
|
let raw = Buffer.from(
|
|
5139
6342
|
bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)
|
|
5140
6343
|
);
|
|
5141
|
-
if (
|
|
5142
|
-
const zip = new
|
|
5143
|
-
|
|
6344
|
+
if (ir.theme || charts2.length > 0) {
|
|
6345
|
+
const zip = new AdmZip5(raw);
|
|
6346
|
+
if (ir.theme) spliceTheme(zip, ir.theme);
|
|
6347
|
+
finishChartParts(zip, charts2);
|
|
5144
6348
|
raw = zip.toBuffer();
|
|
5145
6349
|
}
|
|
5146
6350
|
if (options?.deterministic === false)
|
|
@@ -5157,12 +6361,12 @@ async function createOfficeOpenDocxRenderer() {
|
|
|
5157
6361
|
}
|
|
5158
6362
|
};
|
|
5159
6363
|
}
|
|
5160
|
-
async function buildDocumentOptions(ir,
|
|
6364
|
+
async function buildDocumentOptions(ir, charts2 = [], svgRasterFallback) {
|
|
5161
6365
|
let nextDrawingId = 1;
|
|
5162
6366
|
const ctx = {
|
|
5163
6367
|
pictures: await prepareImages2(ir, svgRasterFallback),
|
|
5164
6368
|
nextDrawingId: () => nextDrawingId++,
|
|
5165
|
-
charts
|
|
6369
|
+
charts: charts2
|
|
5166
6370
|
};
|
|
5167
6371
|
return {
|
|
5168
6372
|
styles: emitStyles2(ir.styles),
|
|
@@ -5170,16 +6374,20 @@ async function buildDocumentOptions(ir, charts = [], svgRasterFallback) {
|
|
|
5170
6374
|
(value, index) => section(value, ctx, index === ir.sections.length - 1)
|
|
5171
6375
|
),
|
|
5172
6376
|
...coreProperties2(ir),
|
|
5173
|
-
|
|
6377
|
+
settings: {
|
|
5174
6378
|
updateFields: ir.settings.updateFields,
|
|
5175
6379
|
...ir.settings.trackRevisions ? { trackRevisions: true } : {}
|
|
5176
6380
|
},
|
|
5177
|
-
...ir.numbering.length > 0 ? {
|
|
6381
|
+
...ir.numbering.length > 0 ? {
|
|
6382
|
+
numbering: {
|
|
6383
|
+
abstractNumberings: ir.numbering.map(numberingConfig2)
|
|
6384
|
+
}
|
|
6385
|
+
} : {},
|
|
5178
6386
|
...ir.footnotes.length > 0 ? { footnotes: noteBodies2(ir.footnotes, ctx) } : {},
|
|
5179
6387
|
...ir.endnotes.length > 0 ? { endnotes: noteBodies2(ir.endnotes, ctx) } : {},
|
|
5180
6388
|
...ir.comments.length > 0 ? {
|
|
5181
|
-
comments:
|
|
5182
|
-
|
|
6389
|
+
comments: ir.comments.map(
|
|
6390
|
+
(comment) => ({
|
|
5183
6391
|
id: comment.id,
|
|
5184
6392
|
author: comment.author,
|
|
5185
6393
|
...comment.initials ? { initials: comment.initials } : {},
|
|
@@ -5187,29 +6395,25 @@ async function buildDocumentOptions(ir, charts = [], svgRasterFallback) {
|
|
|
5187
6395
|
children: comment.children.map(
|
|
5188
6396
|
(child) => paragraphOf(child, ctx)
|
|
5189
6397
|
)
|
|
5190
|
-
})
|
|
5191
|
-
|
|
6398
|
+
})
|
|
6399
|
+
)
|
|
5192
6400
|
} : {}
|
|
5193
6401
|
};
|
|
5194
6402
|
}
|
|
5195
6403
|
function paragraphOf(value, ctx) {
|
|
5196
6404
|
const emitted = block(value, ctx);
|
|
5197
|
-
|
|
5198
|
-
if (!asParagraph) {
|
|
6405
|
+
if (!("paragraph" in emitted) || typeof emitted.paragraph === "string") {
|
|
5199
6406
|
throw new Error(
|
|
5200
6407
|
`the office-open renderer expected a paragraph, not a "${value.kind}"`
|
|
5201
6408
|
);
|
|
5202
6409
|
}
|
|
5203
|
-
return
|
|
6410
|
+
return emitted.paragraph;
|
|
5204
6411
|
}
|
|
5205
6412
|
function noteBodies2(notes, ctx) {
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
};
|
|
5211
|
-
}
|
|
5212
|
-
return bodies;
|
|
6413
|
+
return notes.map((note) => ({
|
|
6414
|
+
id: note.id,
|
|
6415
|
+
children: note.children.map((child) => paragraphOf(child, ctx))
|
|
6416
|
+
}));
|
|
5213
6417
|
}
|
|
5214
6418
|
async function prepareImages2(ir, svgRasterFallback) {
|
|
5215
6419
|
const placements = collectImagePlacements2(ir);
|
|
@@ -5232,23 +6436,16 @@ async function prepareImages2(ir, svgRasterFallback) {
|
|
|
5232
6436
|
if (resource.kind !== "image") continue;
|
|
5233
6437
|
const type = resource.mediaType;
|
|
5234
6438
|
const data = Buffer.from(resource.bytes);
|
|
5235
|
-
const placementData = /* @__PURE__ */ new Map();
|
|
5236
|
-
[...placements.get(resource.id) ?? []].forEach((size, index) => {
|
|
5237
|
-
placementData.set(
|
|
5238
|
-
size,
|
|
5239
|
-
index === 0 ? data : distinguishImageBytes(data, type, size)
|
|
5240
|
-
);
|
|
5241
|
-
});
|
|
5242
6439
|
resources.set(resource.id, (placement) => {
|
|
5243
6440
|
const sizeKey = placementKey(placement);
|
|
5244
6441
|
const stem = `${resource.id}-${sizeKey}`;
|
|
5245
6442
|
return {
|
|
5246
6443
|
type,
|
|
5247
|
-
//
|
|
5248
|
-
//
|
|
5249
|
-
//
|
|
5250
|
-
//
|
|
5251
|
-
data
|
|
6444
|
+
// The same bytes at every size: the backend keeps each drawing's
|
|
6445
|
+
// extent on the drawing. 0.11 kept it on its deduplicated media
|
|
6446
|
+
// entry, and an image drawn at a second size took the first one's,
|
|
6447
|
+
// unless its bytes were told apart.
|
|
6448
|
+
data,
|
|
5252
6449
|
// Named after the resource and the size it is drawn at, so two
|
|
5253
6450
|
// placements of one image at one size share a single part and a third
|
|
5254
6451
|
// at another size gets its own.
|
|
@@ -5271,104 +6468,6 @@ async function prepareImages2(ir, svgRasterFallback) {
|
|
|
5271
6468
|
function placementKey(placement) {
|
|
5272
6469
|
return `${emuToPixels(placement.widthEmu)}x${emuToPixels(placement.heightEmu)}`;
|
|
5273
6470
|
}
|
|
5274
|
-
function distinguishImageBytes(data, mediaType, placement) {
|
|
5275
|
-
const marker = Buffer.from(`json-to-office:${placement}`, "utf8");
|
|
5276
|
-
switch (mediaType) {
|
|
5277
|
-
case "png":
|
|
5278
|
-
return addPngTextChunk(data, marker);
|
|
5279
|
-
case "jpg":
|
|
5280
|
-
return addJpegComment(data, marker);
|
|
5281
|
-
case "gif":
|
|
5282
|
-
return addGifComment(data, marker);
|
|
5283
|
-
case "svg":
|
|
5284
|
-
return Buffer.concat([
|
|
5285
|
-
data,
|
|
5286
|
-
Buffer.from(`
|
|
5287
|
-
<!-- ${marker.toString("utf8")} -->`, "utf8")
|
|
5288
|
-
]);
|
|
5289
|
-
case "bmp": {
|
|
5290
|
-
const marked = Buffer.concat([data, marker]);
|
|
5291
|
-
if (marked.length >= 14 && marked.subarray(0, 2).toString("ascii") === "BM") {
|
|
5292
|
-
marked.writeUInt32LE(marked.length, 2);
|
|
5293
|
-
}
|
|
5294
|
-
return marked;
|
|
5295
|
-
}
|
|
5296
|
-
default:
|
|
5297
|
-
return Buffer.concat([data, marker]);
|
|
5298
|
-
}
|
|
5299
|
-
}
|
|
5300
|
-
function addPngTextChunk(data, marker) {
|
|
5301
|
-
const signature = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
|
|
5302
|
-
if (data.length < 8 || !data.subarray(0, 8).equals(signature)) {
|
|
5303
|
-
return Buffer.concat([data, marker]);
|
|
5304
|
-
}
|
|
5305
|
-
let offset = 8;
|
|
5306
|
-
while (offset + 12 <= data.length) {
|
|
5307
|
-
const payloadLength = data.readUInt32BE(offset);
|
|
5308
|
-
const chunkEnd = offset + 12 + payloadLength;
|
|
5309
|
-
if (chunkEnd > data.length) break;
|
|
5310
|
-
if (data.subarray(offset + 4, offset + 8).toString("ascii") === "IEND") {
|
|
5311
|
-
const payload = Buffer.concat([
|
|
5312
|
-
Buffer.from("json-to-office\0", "latin1"),
|
|
5313
|
-
marker
|
|
5314
|
-
]);
|
|
5315
|
-
const chunk = Buffer.alloc(12 + payload.length);
|
|
5316
|
-
chunk.writeUInt32BE(payload.length, 0);
|
|
5317
|
-
chunk.write("tEXt", 4, 4, "ascii");
|
|
5318
|
-
payload.copy(chunk, 8);
|
|
5319
|
-
chunk.writeUInt32BE(
|
|
5320
|
-
crc32(chunk.subarray(4, 8 + payload.length)),
|
|
5321
|
-
8 + payload.length
|
|
5322
|
-
);
|
|
5323
|
-
return Buffer.concat([
|
|
5324
|
-
data.subarray(0, offset),
|
|
5325
|
-
chunk,
|
|
5326
|
-
data.subarray(offset)
|
|
5327
|
-
]);
|
|
5328
|
-
}
|
|
5329
|
-
offset = chunkEnd;
|
|
5330
|
-
}
|
|
5331
|
-
throw new Error(
|
|
5332
|
-
"Cannot mark a PNG that has no intact IEND chunk; its bytes were not checked to decode before rendering"
|
|
5333
|
-
);
|
|
5334
|
-
}
|
|
5335
|
-
function addJpegComment(data, marker) {
|
|
5336
|
-
if (data.length < 2 || data[0] !== 255 || data[1] !== 216) {
|
|
5337
|
-
return Buffer.concat([data, marker]);
|
|
5338
|
-
}
|
|
5339
|
-
const comment = Buffer.alloc(4 + marker.length);
|
|
5340
|
-
comment[0] = 255;
|
|
5341
|
-
comment[1] = 254;
|
|
5342
|
-
comment.writeUInt16BE(marker.length + 2, 2);
|
|
5343
|
-
marker.copy(comment, 4);
|
|
5344
|
-
return Buffer.concat([data.subarray(0, 2), comment, data.subarray(2)]);
|
|
5345
|
-
}
|
|
5346
|
-
function addGifComment(data, marker) {
|
|
5347
|
-
const trailer = data.lastIndexOf(59);
|
|
5348
|
-
if (trailer < 0 || marker.length > 255) {
|
|
5349
|
-
return Buffer.concat([data, marker]);
|
|
5350
|
-
}
|
|
5351
|
-
const comment = Buffer.concat([
|
|
5352
|
-
Buffer.from([33, 254, marker.length]),
|
|
5353
|
-
marker,
|
|
5354
|
-
Buffer.from([0])
|
|
5355
|
-
]);
|
|
5356
|
-
return Buffer.concat([
|
|
5357
|
-
data.subarray(0, trailer),
|
|
5358
|
-
comment,
|
|
5359
|
-
data.subarray(trailer)
|
|
5360
|
-
]);
|
|
5361
|
-
}
|
|
5362
|
-
function crc32(data) {
|
|
5363
|
-
let crc = 4294967295;
|
|
5364
|
-
for (const byte of data) {
|
|
5365
|
-
crc ^= byte;
|
|
5366
|
-
for (let bit = 0; bit < 8; bit += 1) {
|
|
5367
|
-
crc = crc >>> 1 ^ (crc & 1 ? 3988292384 : 0);
|
|
5368
|
-
}
|
|
5369
|
-
}
|
|
5370
|
-
return (crc ^ 4294967295) >>> 0;
|
|
5371
|
-
}
|
|
5372
6471
|
function collectImagePlacements2(ir) {
|
|
5373
6472
|
const placements = /* @__PURE__ */ new Map();
|
|
5374
6473
|
const record = (resourceId, placement) => {
|
|
@@ -5436,17 +6535,19 @@ function coreProperties2(ir) {
|
|
|
5436
6535
|
...metadata.custom?.length ? { customProperties: metadata.custom } : {}
|
|
5437
6536
|
};
|
|
5438
6537
|
}
|
|
5439
|
-
var OFFICE_OPEN_DOCX_RENDERER_ID, OFFICE_OPEN_DOCX, OFFICE_OPEN_CAPABILITIES;
|
|
6538
|
+
var OFFICE_OPEN_DOCX_RENDERER_ID, OFFICE_OPEN_DOCX, OFFICE_OPEN_VERSION, OFFICE_OPEN_CAPABILITIES;
|
|
5440
6539
|
var init_office_open = __esm({
|
|
5441
6540
|
"src/renderers/office-open/index.ts"() {
|
|
5442
6541
|
"use strict";
|
|
5443
6542
|
init_chartParts();
|
|
6543
|
+
init_themePart();
|
|
5444
6544
|
init_imageUtils();
|
|
5445
6545
|
init_packageDocument();
|
|
5446
6546
|
init_emit2();
|
|
5447
6547
|
init_styles3();
|
|
5448
6548
|
OFFICE_OPEN_DOCX_RENDERER_ID = "office-open";
|
|
5449
6549
|
OFFICE_OPEN_DOCX = "@office-open/docx";
|
|
6550
|
+
OFFICE_OPEN_VERSION = "0.14.6";
|
|
5450
6551
|
OFFICE_OPEN_CAPABILITIES = /* @__PURE__ */ new Set([
|
|
5451
6552
|
"paragraphs",
|
|
5452
6553
|
"styles",
|
|
@@ -6688,6 +7789,7 @@ import {
|
|
|
6688
7789
|
assetUnreadableError
|
|
6689
7790
|
} from "@json-to-office/shared/rendering";
|
|
6690
7791
|
import { capsFormatting as capsFormatting2, synthesizeFamilyName as synthesizeFamilyName2 } from "@json-to-office/shared";
|
|
7792
|
+
import { unrenderedComponentText } from "@json-to-office/quality";
|
|
6691
7793
|
import {
|
|
6692
7794
|
isNativeVisualProps as isNativeVisualProps4
|
|
6693
7795
|
} from "@json-to-office/shared-docx";
|
|
@@ -7813,7 +8915,8 @@ function createDocumentStyles(themeNameOrObject = "consulting", language) {
|
|
|
7813
8915
|
tabStops: effectiveTabStops.map(
|
|
7814
8916
|
(ts) => ({
|
|
7815
8917
|
type: ts.type,
|
|
7816
|
-
|
|
8918
|
+
// Whole twips: `w:pos` is an integer no backend rounds.
|
|
8919
|
+
positionTwips: ts.position === "max" ? RIGHT_MARGIN_TAB_TWIPS : Math.round(ts.position),
|
|
7817
8920
|
...ts.leader && { leader: ts.leader }
|
|
7818
8921
|
})
|
|
7819
8922
|
)
|
|
@@ -9360,6 +10463,7 @@ function emptyToUndefined(formatting) {
|
|
|
9360
10463
|
}
|
|
9361
10464
|
|
|
9362
10465
|
// src/ir/compiler.ts
|
|
10466
|
+
init_chartValues();
|
|
9363
10467
|
init_types();
|
|
9364
10468
|
|
|
9365
10469
|
// src/ir/measure.ts
|
|
@@ -9392,6 +10496,49 @@ function tableWidthTwips(width, measureTwips) {
|
|
|
9392
10496
|
|
|
9393
10497
|
// src/ir/compiler.ts
|
|
9394
10498
|
init_units();
|
|
10499
|
+
|
|
10500
|
+
// src/ir/theme.ts
|
|
10501
|
+
init_colorUtils();
|
|
10502
|
+
init_styleHelpers();
|
|
10503
|
+
init_types();
|
|
10504
|
+
var THEME_COLOR_TOKENS = [
|
|
10505
|
+
["dark1", "text"],
|
|
10506
|
+
["light1", "background"],
|
|
10507
|
+
["dark2", "textSecondary"],
|
|
10508
|
+
["light2", "backgroundSecondary"],
|
|
10509
|
+
["accent1", "primary"],
|
|
10510
|
+
["accent2", "secondary"],
|
|
10511
|
+
["accent3", "accent"],
|
|
10512
|
+
["accent4", "accent4"],
|
|
10513
|
+
["accent5", "accent5"],
|
|
10514
|
+
["accent6", "accent6"]
|
|
10515
|
+
];
|
|
10516
|
+
var NOT_XML_CHARS = new RegExp(NOT_XML_CHAR.source, "gu");
|
|
10517
|
+
var xmlText = (value) => (value ?? "").replace(NOT_XML_CHARS, "").trim();
|
|
10518
|
+
function compileTheme(theme, themeName) {
|
|
10519
|
+
const colors = {};
|
|
10520
|
+
for (const [slot, token] of THEME_COLOR_TOKENS) {
|
|
10521
|
+
const hex = schemeHex(token, theme);
|
|
10522
|
+
if (hex) colors[slot] = { hex };
|
|
10523
|
+
}
|
|
10524
|
+
const headingFont = xmlText(resolveFontFamily(theme, "heading"));
|
|
10525
|
+
const bodyFont = xmlText(resolveFontFamily(theme, "body"));
|
|
10526
|
+
return {
|
|
10527
|
+
name: xmlText(theme.name) || xmlText(themeName) || "Office Theme",
|
|
10528
|
+
colors,
|
|
10529
|
+
...headingFont ? { headingFont } : {},
|
|
10530
|
+
...bodyFont ? { bodyFont } : {}
|
|
10531
|
+
};
|
|
10532
|
+
}
|
|
10533
|
+
function schemeHex(token, theme) {
|
|
10534
|
+
try {
|
|
10535
|
+
return resolveColor(token, theme);
|
|
10536
|
+
} catch {
|
|
10537
|
+
return void 0;
|
|
10538
|
+
}
|
|
10539
|
+
}
|
|
10540
|
+
|
|
10541
|
+
// src/ir/compiler.ts
|
|
9395
10542
|
var CONTENT_BOOKMARK_ID_BASE = 2e6;
|
|
9396
10543
|
var SINGLE_LINE_TWIPS = 240;
|
|
9397
10544
|
function compileDocument(structure, layout, warnings = [], images = /* @__PURE__ */ new Map(), options = {}) {
|
|
@@ -9457,6 +10604,7 @@ function compileDocument(structure, layout, warnings = [], images = /* @__PURE__
|
|
|
9457
10604
|
trackRevisions: structure.trackRevisions === true,
|
|
9458
10605
|
...noProofWords(structure.theme) ? { noProofWords: noProofWords(structure.theme) } : {}
|
|
9459
10606
|
},
|
|
10607
|
+
theme: compileTheme(structure.theme, structure.themeName),
|
|
9460
10608
|
// The statistic styles are appended rather than built with the rest: a
|
|
9461
10609
|
// document that uses no statistic must keep the exact style set it had
|
|
9462
10610
|
// before the component had styles, or every recorded golden moves for a
|
|
@@ -10225,14 +11373,6 @@ function compileShape2(props, children, scope) {
|
|
|
10225
11373
|
);
|
|
10226
11374
|
}
|
|
10227
11375
|
const fill = style?.shading?.fill;
|
|
10228
|
-
const dropOutline = Boolean(fill) && Boolean(outline.outline);
|
|
10229
|
-
if (dropOutline) {
|
|
10230
|
-
warnOnce(
|
|
10231
|
-
ctx,
|
|
10232
|
-
"text-box",
|
|
10233
|
-
'[core-docx] text-box renderAs "shape" cannot carry a fill and a border at once (docx emits invalid shape properties); keeping the fill and dropping the border.'
|
|
10234
|
-
);
|
|
10235
|
-
}
|
|
10236
11376
|
ctx.features.require("text-boxes", path3);
|
|
10237
11377
|
if (props.floating) ctx.features.require("floating-images", path3);
|
|
10238
11378
|
const insets = shapeInsets(
|
|
@@ -10251,7 +11391,7 @@ function compileShape2(props, children, scope) {
|
|
|
10251
11391
|
heightPx: height.pixels,
|
|
10252
11392
|
children,
|
|
10253
11393
|
...fill ? { fill: irColor(resolveColor(fill, ctx.theme)) } : {},
|
|
10254
|
-
...outline.outline
|
|
11394
|
+
...outline.outline ? { outline: outline.outline } : {},
|
|
10255
11395
|
...insets ? { insetsEmu: insets } : {},
|
|
10256
11396
|
...props.floating ? { floating: compileFloating(props.floating, ctx, path3) } : {}
|
|
10257
11397
|
}
|
|
@@ -10433,7 +11573,9 @@ function compileToc(component, scope) {
|
|
|
10433
11573
|
formatting: {
|
|
10434
11574
|
alignment: "left",
|
|
10435
11575
|
spacing: {
|
|
10436
|
-
beforeTwips:
|
|
11576
|
+
beforeTwips: wholeTwips(
|
|
11577
|
+
ctx.theme.componentDefaults?.heading?.spacing?.before ?? 240
|
|
11578
|
+
),
|
|
10437
11579
|
// ~9pt, which separates the title from the list clearly enough to
|
|
10438
11580
|
// read as a heading rather than a first entry.
|
|
10439
11581
|
afterTwips: 180
|
|
@@ -10553,8 +11695,8 @@ function compileStatistic(component, scope) {
|
|
|
10553
11695
|
const alignment2 = compileAlignment(props.alignment) ?? "center";
|
|
10554
11696
|
ctx.usesStatistic = true;
|
|
10555
11697
|
const spacing = props.spacing ? {
|
|
10556
|
-
...props.spacing.before !== void 0 ? { beforeTwips: props.spacing.before } : {},
|
|
10557
|
-
...props.spacing.after !== void 0 ? { afterTwips: props.spacing.after } : {}
|
|
11698
|
+
...props.spacing.before !== void 0 ? { beforeTwips: wholeTwips(props.spacing.before) } : {},
|
|
11699
|
+
...props.spacing.after !== void 0 ? { afterTwips: wholeTwips(props.spacing.after) } : {}
|
|
10558
11700
|
} : void 0;
|
|
10559
11701
|
if (props.format !== void 0) {
|
|
10560
11702
|
warnOnce(
|
|
@@ -11179,7 +12321,7 @@ function paragraphFormatting(props, ctx, extra = {}) {
|
|
|
11179
12321
|
if (Array.isArray(props.tabStops) && props.tabStops.length > 0) {
|
|
11180
12322
|
formatting.tabStops = props.tabStops.map(
|
|
11181
12323
|
(stop) => ({
|
|
11182
|
-
positionTwips: stop.position,
|
|
12324
|
+
positionTwips: wholeTwips(stop.position),
|
|
11183
12325
|
type: stop.type ?? "left",
|
|
11184
12326
|
...stop.leader ? { leader: stop.leader } : {}
|
|
11185
12327
|
})
|
|
@@ -11228,7 +12370,10 @@ function compileSpacing(props, ctx) {
|
|
|
11228
12370
|
}
|
|
11229
12371
|
function compileLineSpacing(value) {
|
|
11230
12372
|
if (typeof value === "number") {
|
|
11231
|
-
return {
|
|
12373
|
+
return {
|
|
12374
|
+
lineTwips: wholeTwips(value * SINGLE_LINE_TWIPS),
|
|
12375
|
+
lineRule: "auto"
|
|
12376
|
+
};
|
|
11232
12377
|
}
|
|
11233
12378
|
if (typeof value !== "object" || value === null) return void 0;
|
|
11234
12379
|
const { type, value: amount } = value;
|
|
@@ -11249,7 +12394,7 @@ function compileLineSpacing(value) {
|
|
|
11249
12394
|
};
|
|
11250
12395
|
case "multiple":
|
|
11251
12396
|
return {
|
|
11252
|
-
...amount !== void 0 ? { lineTwips: amount * SINGLE_LINE_TWIPS } : {},
|
|
12397
|
+
...amount !== void 0 ? { lineTwips: wholeTwips(amount * SINGLE_LINE_TWIPS) } : {},
|
|
11253
12398
|
lineRule: "auto"
|
|
11254
12399
|
};
|
|
11255
12400
|
default:
|
|
@@ -11469,6 +12614,7 @@ function compileImage2(component, scope) {
|
|
|
11469
12614
|
}
|
|
11470
12615
|
var DEFAULT_CHART_HEIGHT_INCHES = 3;
|
|
11471
12616
|
var MAX_CHART_TEXT_POINTS = 10;
|
|
12617
|
+
var MIN_CHART_TEXT_POINTS = 1;
|
|
11472
12618
|
function chartTextFont(theme) {
|
|
11473
12619
|
const bodySize = getThemeFonts(theme).body?.size;
|
|
11474
12620
|
let color = "000000";
|
|
@@ -11478,9 +12624,12 @@ function chartTextFont(theme) {
|
|
|
11478
12624
|
}
|
|
11479
12625
|
return {
|
|
11480
12626
|
fontFamily: resolveFontFamily(theme, "body"),
|
|
11481
|
-
fontSize: Math.
|
|
11482
|
-
|
|
11483
|
-
|
|
12627
|
+
fontSize: Math.max(
|
|
12628
|
+
MIN_CHART_TEXT_POINTS,
|
|
12629
|
+
Math.min(
|
|
12630
|
+
typeof bodySize === "number" && bodySize > 0 ? bodySize : 11,
|
|
12631
|
+
MAX_CHART_TEXT_POINTS
|
|
12632
|
+
)
|
|
11484
12633
|
),
|
|
11485
12634
|
bold: false,
|
|
11486
12635
|
color
|
|
@@ -11491,7 +12640,7 @@ function compileChart(component, scope) {
|
|
|
11491
12640
|
const props = component.props ?? {};
|
|
11492
12641
|
if (props.type === "bubble") {
|
|
11493
12642
|
throw new Error(
|
|
11494
|
-
`Chart at ${path3} is a bubble chart,
|
|
12643
|
+
`Chart at ${path3} is a bubble chart, but the docx \`chart\` component has no bubble sizes; use the pptx \`chart\` component on the pptxgenjs renderer.`
|
|
11495
12644
|
);
|
|
11496
12645
|
}
|
|
11497
12646
|
const rawSeries = Array.isArray(props.data) ? props.data : [];
|
|
@@ -11513,10 +12662,22 @@ function compileChart(component, scope) {
|
|
|
11513
12662
|
`Chart series "${label}" at ${path3} has ${labels.length} labels and ${values.length} values; they must be the same length.`
|
|
11514
12663
|
);
|
|
11515
12664
|
}
|
|
12665
|
+
if (labels.length === 0) {
|
|
12666
|
+
throw new Error(
|
|
12667
|
+
`Chart series "${label}" at ${path3} has no data points; give it at least one label and value.`
|
|
12668
|
+
);
|
|
12669
|
+
}
|
|
12670
|
+
const numbers = values.map((value) => Number(value));
|
|
12671
|
+
const bad = numbers.findIndex((value) => !Number.isFinite(value));
|
|
12672
|
+
if (bad !== -1) {
|
|
12673
|
+
throw new Error(
|
|
12674
|
+
`Chart series "${label}" at ${path3} has a value that is not a finite number (${JSON.stringify(values[bad])} at "${String(labels[bad])}").`
|
|
12675
|
+
);
|
|
12676
|
+
}
|
|
11516
12677
|
return {
|
|
11517
12678
|
...typeof raw.name === "string" ? { name: raw.name } : {},
|
|
11518
12679
|
labels: labels.map((value) => String(value)),
|
|
11519
|
-
values:
|
|
12680
|
+
values: numbers
|
|
11520
12681
|
};
|
|
11521
12682
|
});
|
|
11522
12683
|
const categories = series[0].labels;
|
|
@@ -11528,6 +12689,34 @@ function compileChart(component, scope) {
|
|
|
11528
12689
|
);
|
|
11529
12690
|
}
|
|
11530
12691
|
}
|
|
12692
|
+
if (props.type === "pie" && series.length > 1) {
|
|
12693
|
+
throw new Error(
|
|
12694
|
+
`Chart at ${path3} is a pie with ${series.length} series; a pie draws one series. Use a doughnut for one ring per series, or a column chart to compare them.`
|
|
12695
|
+
);
|
|
12696
|
+
}
|
|
12697
|
+
if (props.type === "pie" || props.type === "doughnut") {
|
|
12698
|
+
for (const [index, entry] of series.entries()) {
|
|
12699
|
+
const at = entry.values.findIndex((value) => value < 0);
|
|
12700
|
+
if (at === -1) continue;
|
|
12701
|
+
throw new Error(
|
|
12702
|
+
`Chart series "${entry.name ?? `series ${index}`}" at ${path3} has a negative value (${entry.values[at]} at "${entry.labels[at]}"); a ${props.type} chart draws each value as a share of the whole.`
|
|
12703
|
+
);
|
|
12704
|
+
}
|
|
12705
|
+
}
|
|
12706
|
+
if (props.type === "scatter" && series.some((entry) => entry.labels.some((label) => !isNumericLabel(label)))) {
|
|
12707
|
+
warnOnce(
|
|
12708
|
+
ctx,
|
|
12709
|
+
"chart",
|
|
12710
|
+
`Chart at ${path3} is a scatter chart whose labels are not all numbers; each label is its point's x, so these points are placed at 1, 2, 3\u2026 in order.`
|
|
12711
|
+
);
|
|
12712
|
+
}
|
|
12713
|
+
if ((props.type === "pie" || props.type === "doughnut") && (typeof props.catAxisTitle === "string" || typeof props.valAxisTitle === "string")) {
|
|
12714
|
+
warnOnce(
|
|
12715
|
+
ctx,
|
|
12716
|
+
"chart",
|
|
12717
|
+
`Chart at ${path3} is a ${props.type} chart, which has no axes; its axis titles are not drawn.`
|
|
12718
|
+
);
|
|
12719
|
+
}
|
|
11531
12720
|
const colors = Array.isArray(props.chartColors) ? props.chartColors.map(
|
|
11532
12721
|
(color) => resolveColor(String(color), ctx.theme)
|
|
11533
12722
|
) : chartPaletteValues(ctx.theme).flatMap((value) => {
|
|
@@ -11540,13 +12729,21 @@ function compileChart(component, scope) {
|
|
|
11540
12729
|
const contentWidthInches = scope.measureTwips / 1440;
|
|
11541
12730
|
const widthInches = typeof props.width === "number" ? props.width : contentWidthInches;
|
|
11542
12731
|
const heightInches = typeof props.height === "number" ? props.height : DEFAULT_CHART_HEIGHT_INCHES;
|
|
12732
|
+
const widthEmu = inchesToEmu(widthInches);
|
|
12733
|
+
const heightEmu = inchesToEmu(heightInches);
|
|
12734
|
+
if (!(widthEmu > 0 && heightEmu > 0)) {
|
|
12735
|
+
const inches = (value) => String(Number.isFinite(value) ? Math.round(value * 100) / 100 : value);
|
|
12736
|
+
throw new Error(
|
|
12737
|
+
`Chart at ${path3} has no room: it would be ${inches(widthInches)}\xD7${inches(heightInches)} in. Set \`width\`/\`height\`, or give it a container with space.`
|
|
12738
|
+
);
|
|
12739
|
+
}
|
|
11543
12740
|
const chart = {
|
|
11544
12741
|
kind: "chart",
|
|
11545
12742
|
chartType: props.type,
|
|
11546
12743
|
series,
|
|
11547
12744
|
colors,
|
|
11548
|
-
widthEmu
|
|
11549
|
-
heightEmu
|
|
12745
|
+
widthEmu,
|
|
12746
|
+
heightEmu,
|
|
11550
12747
|
...typeof props.title === "string" ? { title: props.title } : {},
|
|
11551
12748
|
...props.showTitle !== void 0 ? { showTitle: props.showTitle } : {},
|
|
11552
12749
|
...props.showLegend !== void 0 ? { showLegend: props.showLegend } : {},
|
|
@@ -11710,8 +12907,8 @@ function compileFrame(floating, ctx, path3) {
|
|
|
11710
12907
|
const useAbsolute = hasHorizontalOffset || hasVerticalOffset;
|
|
11711
12908
|
const frame = {
|
|
11712
12909
|
// 2in by 1in when the author gave no size.
|
|
11713
|
-
widthTwips: floating.width || 2880,
|
|
11714
|
-
heightTwips: floating.height || 1440,
|
|
12910
|
+
widthTwips: wholeTwips(floating.width || 2880),
|
|
12911
|
+
heightTwips: wholeTwips(floating.height || 1440),
|
|
11715
12912
|
anchorHorizontal: floating.horizontalPosition?.relative || "page",
|
|
11716
12913
|
anchorVertical: floating.verticalPosition?.relative || "page",
|
|
11717
12914
|
...floating.wrap?.type ? { wrap: floating.wrap.type } : {}
|
|
@@ -11724,17 +12921,21 @@ function compileFrame(floating, ctx, path3) {
|
|
|
11724
12921
|
if (typeof rawX === "string" || typeof rawY === "string") {
|
|
11725
12922
|
const hRelative = floating.horizontalPosition?.relative;
|
|
11726
12923
|
const vRelative = floating.verticalPosition?.relative;
|
|
11727
|
-
frame.xTwips =
|
|
11728
|
-
|
|
11729
|
-
|
|
12924
|
+
frame.xTwips = wholeTwips(
|
|
12925
|
+
resolveOffsetTwips(
|
|
12926
|
+
rawX,
|
|
12927
|
+
hRelative && hRelative !== "page" ? getAvailableWidthTwips(ctx.theme, ctx.themeName) : getPageWidthTwips(ctx.theme, ctx.themeName)
|
|
12928
|
+
)
|
|
11730
12929
|
);
|
|
11731
|
-
frame.yTwips =
|
|
11732
|
-
|
|
11733
|
-
|
|
12930
|
+
frame.yTwips = wholeTwips(
|
|
12931
|
+
resolveOffsetTwips(
|
|
12932
|
+
rawY,
|
|
12933
|
+
vRelative && vRelative !== "page" ? getAvailableHeightTwips(ctx.theme, ctx.themeName) : getPageHeightTwips(ctx.theme, ctx.themeName)
|
|
12934
|
+
)
|
|
11734
12935
|
);
|
|
11735
12936
|
} else {
|
|
11736
|
-
frame.xTwips = rawX;
|
|
11737
|
-
frame.yTwips = rawY;
|
|
12937
|
+
frame.xTwips = wholeTwips(rawX);
|
|
12938
|
+
frame.yTwips = wholeTwips(rawY);
|
|
11738
12939
|
}
|
|
11739
12940
|
return frame;
|
|
11740
12941
|
}
|
|
@@ -11745,7 +12946,7 @@ function compileFrame(floating, ctx, path3) {
|
|
|
11745
12946
|
function compileFloating(floating, ctx, path3) {
|
|
11746
12947
|
if (floating.wrap?.type === "tight") {
|
|
11747
12948
|
throw new Error(
|
|
11748
|
-
"Image floating wrap.type 'tight' is not supported
|
|
12949
|
+
"Image floating wrap.type 'tight' is not supported. Use 'square', 'topAndBottom', or 'none'."
|
|
11749
12950
|
);
|
|
11750
12951
|
}
|
|
11751
12952
|
const hRelative = floating.horizontalPosition?.relative;
|
|
@@ -12068,10 +13269,17 @@ function cellChildren(cell, baseStyle, scope, rowRevision) {
|
|
|
12068
13269
|
return wrap(cellVisual(content, scope));
|
|
12069
13270
|
}
|
|
12070
13271
|
if (content.name !== "paragraph") {
|
|
13272
|
+
const text2 = unrenderedComponentText(content.name);
|
|
13273
|
+
warnOnce(
|
|
13274
|
+
ctx,
|
|
13275
|
+
"table",
|
|
13276
|
+
`${scope.path} holds a "${content.name}", which a table cell cannot render, so it shows "${text2}" instead. A cell takes a string, a paragraph, an image, a visual or a highcharts chart; set statistics side by side with a columns component.`,
|
|
13277
|
+
"W_UNSUPPORTED_CELL_CONTENT"
|
|
13278
|
+
);
|
|
12071
13279
|
return wrap([
|
|
12072
13280
|
{
|
|
12073
13281
|
kind: "text",
|
|
12074
|
-
text:
|
|
13282
|
+
text: text2,
|
|
12075
13283
|
formatting: placeholderFormatting(base)
|
|
12076
13284
|
}
|
|
12077
13285
|
]);
|
|
@@ -13269,6 +14477,11 @@ init_widthUtils();
|
|
|
13269
14477
|
import probe2 from "probe-image-size";
|
|
13270
14478
|
|
|
13271
14479
|
// src/quality/text-inventory.ts
|
|
14480
|
+
import {
|
|
14481
|
+
unrenderedComponentText as unrenderedComponentText2
|
|
14482
|
+
} from "@json-to-office/quality";
|
|
14483
|
+
import { TABLE_CELL_COMPONENTS } from "@json-to-office/shared-docx";
|
|
14484
|
+
var CELL_COMPONENTS = new Set(TABLE_CELL_COMPONENTS);
|
|
13272
14485
|
function tocDepth(depth) {
|
|
13273
14486
|
const range = asRecord(depth) ?? {};
|
|
13274
14487
|
const from = typeof range.from === "number" ? range.from : 1;
|
|
@@ -13317,7 +14530,14 @@ function collectDocxTextInventory(children, basePath = "/children") {
|
|
|
13317
14530
|
add(`${path3}/content`, rec.content, cellRole, extra);
|
|
13318
14531
|
else {
|
|
13319
14532
|
const inner = asRecord(rec.content);
|
|
13320
|
-
if (inner)
|
|
14533
|
+
if (inner && typeof inner.name === "string" && !CELL_COMPONENTS.has(inner.name)) {
|
|
14534
|
+
add(
|
|
14535
|
+
`${path3}/content`,
|
|
14536
|
+
unrenderedComponentText2(inner.name),
|
|
14537
|
+
cellRole,
|
|
14538
|
+
{ ...extra, optional: true, unrendered: inner.name }
|
|
14539
|
+
);
|
|
14540
|
+
} else if (inner)
|
|
13321
14541
|
visitNode(inner, `${path3}/content`, { ...inherited, inCell: true });
|
|
13322
14542
|
}
|
|
13323
14543
|
return;
|