@json-to-office/core-docx 0.33.0 → 0.35.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/components/heading.d.ts.map +1 -1
- package/dist/components/list.d.ts.map +1 -1
- package/dist/components/paragraph.d.ts.map +1 -1
- package/dist/components/section.d.ts.map +1 -1
- package/dist/components/table.d.ts.map +1 -1
- package/dist/components/toc/index.d.ts.map +1 -1
- package/dist/components/visual.d.ts +15 -2
- package/dist/components/visual.d.ts.map +1 -1
- package/dist/core/cached-render.d.ts +9 -1
- package/dist/core/cached-render.d.ts.map +1 -1
- package/dist/core/collectTocHeadings.d.ts +60 -0
- package/dist/core/collectTocHeadings.d.ts.map +1 -0
- package/dist/core/content.d.ts +17 -1
- package/dist/core/content.d.ts.map +1 -1
- package/dist/core/flattenVisuals.d.ts +8 -1
- package/dist/core/flattenVisuals.d.ts.map +1 -1
- package/dist/core/fontResolution.d.ts +15 -1
- package/dist/core/fontResolution.d.ts.map +1 -1
- package/dist/core/generator.d.ts.map +1 -1
- package/dist/core/layout.d.ts +5 -0
- package/dist/core/layout.d.ts.map +1 -1
- package/dist/core/prerasterizeVisuals.d.ts +8 -1
- package/dist/core/prerasterizeVisuals.d.ts.map +1 -1
- package/dist/core/render.d.ts +8 -1
- package/dist/core/render.d.ts.map +1 -1
- package/dist/core/sectionBookmarks.d.ts +53 -0
- package/dist/core/sectionBookmarks.d.ts.map +1 -0
- package/dist/core/sectionOrdinals.d.ts +32 -0
- package/dist/core/sectionOrdinals.d.ts.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +943 -206
- package/dist/index.js.map +1 -1
- package/dist/plugin/createDocumentGenerator.d.ts.map +1 -1
- package/dist/plugin/example/index.js +3286 -2568
- package/dist/plugin/example/index.js.map +1 -1
- package/dist/styles/index.d.ts +2 -2
- package/dist/styles/index.d.ts.map +1 -1
- package/dist/styles/themeToDocxAdapter.d.ts.map +1 -1
- package/dist/styles/utils/layoutUtils.d.ts +48 -0
- package/dist/styles/utils/layoutUtils.d.ts.map +1 -1
- package/dist/templates/themes/index.d.ts +552 -12
- package/dist/templates/themes/index.d.ts.map +1 -1
- package/dist/themes/defaults.d.ts +96 -0
- package/dist/themes/defaults.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/index.d.ts +16 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/commentAnchors.d.ts +39 -0
- package/dist/utils/commentAnchors.d.ts.map +1 -0
- package/dist/utils/commentRegistry.d.ts +49 -0
- package/dist/utils/commentRegistry.d.ts.map +1 -0
- package/dist/utils/componentAnnotations.d.ts +23 -0
- package/dist/utils/componentAnnotations.d.ts.map +1 -0
- package/dist/utils/fixFloatingImageIds.d.ts +1 -1
- package/dist/utils/fixFloatingImageIds.d.ts.map +1 -1
- package/dist/utils/noteRegistry.d.ts +43 -0
- package/dist/utils/noteRegistry.d.ts.map +1 -0
- package/dist/utils/noteResolver.d.ts +31 -0
- package/dist/utils/noteResolver.d.ts.map +1 -0
- package/dist/utils/numberingConfig.d.ts +15 -0
- package/dist/utils/numberingConfig.d.ts.map +1 -1
- package/dist/utils/placeholderProcessor.d.ts +2 -2
- package/dist/utils/placeholderProcessor.d.ts.map +1 -1
- package/dist/utils/revisionUtils.d.ts +32 -9
- package/dist/utils/revisionUtils.d.ts.map +1 -1
- package/dist/utils/textParser.d.ts +12 -0
- package/dist/utils/textParser.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1134,7 +1134,7 @@ function getPageDimensions(size) {
|
|
|
1134
1134
|
if (typeof size === "string") {
|
|
1135
1135
|
return PAGE_SIZES[size];
|
|
1136
1136
|
}
|
|
1137
|
-
return size;
|
|
1137
|
+
return { width: size.width, height: size.height };
|
|
1138
1138
|
}
|
|
1139
1139
|
var resolveTableParagraphSpacing, PAGE_SIZES, getTableStyle, getDocumentMargins, getPageSetup;
|
|
1140
1140
|
var init_layoutUtils = __esm({
|
|
@@ -1151,10 +1151,10 @@ var init_layoutUtils = __esm({
|
|
|
1151
1151
|
};
|
|
1152
1152
|
};
|
|
1153
1153
|
PAGE_SIZES = {
|
|
1154
|
-
A4: { width: 11906, height: 16838 },
|
|
1155
|
-
A3: { width: 16838, height: 23811 },
|
|
1156
|
-
LETTER: { width: 12240, height: 15840 },
|
|
1157
|
-
LEGAL: { width: 12240, height: 20160 }
|
|
1154
|
+
A4: { width: 11906, height: 16838, code: 9 },
|
|
1155
|
+
A3: { width: 16838, height: 23811, code: 8 },
|
|
1156
|
+
LETTER: { width: 12240, height: 15840, code: 1 },
|
|
1157
|
+
LEGAL: { width: 12240, height: 20160, code: 5 }
|
|
1158
1158
|
};
|
|
1159
1159
|
getTableStyle = (theme, themeName) => {
|
|
1160
1160
|
const themeConfig = resolveTheme(theme, themeName);
|
|
@@ -1291,7 +1291,8 @@ var init_layoutUtils = __esm({
|
|
|
1291
1291
|
return {
|
|
1292
1292
|
size: {
|
|
1293
1293
|
width: dimensions.width,
|
|
1294
|
-
height: dimensions.height
|
|
1294
|
+
height: dimensions.height,
|
|
1295
|
+
...dimensions.code !== void 0 && { code: dimensions.code }
|
|
1295
1296
|
},
|
|
1296
1297
|
margin: {
|
|
1297
1298
|
top: margins.top ?? defaultMargins.top ?? 1440,
|
|
@@ -1303,10 +1304,11 @@ var init_layoutUtils = __esm({
|
|
|
1303
1304
|
}
|
|
1304
1305
|
return {
|
|
1305
1306
|
size: {
|
|
1306
|
-
width:
|
|
1307
|
-
//
|
|
1308
|
-
height:
|
|
1309
|
-
//
|
|
1307
|
+
width: PAGE_SIZES.A4.width,
|
|
1308
|
+
// 210mm in twips (A4)
|
|
1309
|
+
height: PAGE_SIZES.A4.height,
|
|
1310
|
+
// 297mm in twips (A4)
|
|
1311
|
+
code: PAGE_SIZES.A4.code
|
|
1310
1312
|
},
|
|
1311
1313
|
margin: {
|
|
1312
1314
|
top: defaultMargins.top ?? 1440,
|
|
@@ -2528,18 +2530,7 @@ function getColumnSettings(layout) {
|
|
|
2528
2530
|
function createSectionProperties(columnSettings, theme, themeName, sectionType, pageOverride) {
|
|
2529
2531
|
const basePageSetup = getPageSetup(theme, themeName);
|
|
2530
2532
|
const pageSetup = pageOverride ? {
|
|
2531
|
-
size:
|
|
2532
|
-
...basePageSetup.size,
|
|
2533
|
-
...pageOverride.size && typeof pageOverride.size === "object" ? pageOverride.size : pageOverride.size ? (() => {
|
|
2534
|
-
const sizes = {
|
|
2535
|
-
A4: { width: 11906, height: 16838 },
|
|
2536
|
-
A3: { width: 16838, height: 23811 },
|
|
2537
|
-
LETTER: { width: 12240, height: 15840 },
|
|
2538
|
-
LEGAL: { width: 12240, height: 20160 }
|
|
2539
|
-
};
|
|
2540
|
-
return sizes[pageOverride.size];
|
|
2541
|
-
})() : {}
|
|
2542
|
-
},
|
|
2533
|
+
size: pageOverride.size ? getPageDimensions(pageOverride.size) : basePageSetup.size,
|
|
2543
2534
|
margin: {
|
|
2544
2535
|
...basePageSetup.margin,
|
|
2545
2536
|
...pageOverride.margins || {}
|
|
@@ -2641,8 +2632,8 @@ Suggestion: ${suggestion}`
|
|
|
2641
2632
|
// src/core/render.ts
|
|
2642
2633
|
import {
|
|
2643
2634
|
Document,
|
|
2644
|
-
Paragraph as
|
|
2645
|
-
TextRun as
|
|
2635
|
+
Paragraph as Paragraph9,
|
|
2636
|
+
TextRun as TextRun9,
|
|
2646
2637
|
AlignmentType as AlignmentType5,
|
|
2647
2638
|
BookmarkStart as BookmarkStart2,
|
|
2648
2639
|
BookmarkEnd as BookmarkEnd2
|
|
@@ -3061,17 +3052,19 @@ function convertBorders(borders, theme) {
|
|
|
3061
3052
|
color: resolveColor(side.color, theme),
|
|
3062
3053
|
...side.space !== void 0 ? { space: side.space } : {}
|
|
3063
3054
|
} : void 0;
|
|
3064
|
-
const
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3055
|
+
const sides = [
|
|
3056
|
+
"top",
|
|
3057
|
+
"bottom",
|
|
3058
|
+
"left",
|
|
3059
|
+
"right",
|
|
3060
|
+
"between"
|
|
3061
|
+
];
|
|
3062
|
+
const converted = {};
|
|
3063
|
+
for (const side of sides) {
|
|
3064
|
+
const value = mapSide(borders[side]);
|
|
3065
|
+
if (value) converted[side] = value;
|
|
3066
|
+
}
|
|
3067
|
+
return Object.keys(converted).length > 0 ? converted : void 0;
|
|
3075
3068
|
}
|
|
3076
3069
|
function createWordStyles(themeNameOrObject = "minimal", language) {
|
|
3077
3070
|
const theme = typeof themeNameOrObject === "string" ? getTheme(themeNameOrObject) || getTheme("minimal") : themeNameOrObject;
|
|
@@ -3440,7 +3433,7 @@ function createWordStyles(themeNameOrObject = "minimal", language) {
|
|
|
3440
3433
|
}
|
|
3441
3434
|
const tocMatch = /^TOC([1-9])$/.exec(styleKey);
|
|
3442
3435
|
const customStyle = tocMatch ? styleValue : resolveStyleWithBaseStyle(theme, styleKey) || styleValue;
|
|
3443
|
-
const styleId = tocMatch ? `
|
|
3436
|
+
const styleId = tocMatch ? `TOC${tocMatch[1]}` : styleKey;
|
|
3444
3437
|
const styleName = tocMatch ? `TOC ${tocMatch[1]}` : styleKey.replace(/([A-Z])/g, " $1").trim();
|
|
3445
3438
|
const mapBaseStyleId = (base) => {
|
|
3446
3439
|
if (!base) return "Normal";
|
|
@@ -3512,8 +3505,8 @@ function createWordStyles(themeNameOrObject = "minimal", language) {
|
|
|
3512
3505
|
continue;
|
|
3513
3506
|
}
|
|
3514
3507
|
paragraphStyles.push({
|
|
3515
|
-
//
|
|
3516
|
-
id: `
|
|
3508
|
+
// Canonical id and display name — see the styleId note above.
|
|
3509
|
+
id: `TOC${i}`,
|
|
3517
3510
|
name: `TOC ${i}`,
|
|
3518
3511
|
basedOn: "Normal",
|
|
3519
3512
|
next: "Normal",
|
|
@@ -3536,20 +3529,43 @@ function createWordStyles(themeNameOrObject = "minimal", language) {
|
|
|
3536
3529
|
}
|
|
3537
3530
|
});
|
|
3538
3531
|
}
|
|
3532
|
+
const noteStyle = resolveStyleWithBaseStyle(theme, "normal") || theme.styles?.normal;
|
|
3533
|
+
const bodyRun = convertRunProperties(
|
|
3534
|
+
mergeFontAndStyleProperties(resolveFontProperties(theme, noteStyle?.font), {
|
|
3535
|
+
size: noteStyle?.size,
|
|
3536
|
+
color: noteStyle?.color
|
|
3537
|
+
}),
|
|
3538
|
+
theme,
|
|
3539
|
+
theme.colors.text
|
|
3540
|
+
);
|
|
3541
|
+
const noteRun = {
|
|
3542
|
+
...bodyRun,
|
|
3543
|
+
...typeof bodyRun.size === "number" && {
|
|
3544
|
+
size: Math.max(12, bodyRun.size - 4)
|
|
3545
|
+
}
|
|
3546
|
+
};
|
|
3539
3547
|
return {
|
|
3540
3548
|
paragraphStyles,
|
|
3541
3549
|
// Cast needed due to docx typing
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3550
|
+
default: {
|
|
3551
|
+
// Document-default proofing language (w:docDefaults/w:rPrDefault). Runs
|
|
3552
|
+
// that don't set their own w:lang inherit this, so Word spell-checks the
|
|
3553
|
+
// whole document in the requested language unless a component overrides
|
|
3554
|
+
// it.
|
|
3555
|
+
...language && {
|
|
3547
3556
|
document: {
|
|
3548
3557
|
run: {
|
|
3549
3558
|
language: { value: language }
|
|
3550
3559
|
}
|
|
3551
3560
|
}
|
|
3552
|
-
}
|
|
3561
|
+
},
|
|
3562
|
+
// Run properties only: docx's own note paragraph defaults (single line
|
|
3563
|
+
// spacing, no space after) are already what a note wants, and an empty
|
|
3564
|
+
// spacing override would drop its line rule.
|
|
3565
|
+
footnoteText: { run: noteRun },
|
|
3566
|
+
footnoteReference: { run: { ...noteRun, superScript: true } },
|
|
3567
|
+
endnoteText: { run: noteRun },
|
|
3568
|
+
endnoteReference: { run: { ...noteRun, superScript: true } }
|
|
3553
3569
|
}
|
|
3554
3570
|
};
|
|
3555
3571
|
}
|
|
@@ -3671,7 +3687,15 @@ import {
|
|
|
3671
3687
|
} from "docx";
|
|
3672
3688
|
|
|
3673
3689
|
// src/utils/textParser.ts
|
|
3674
|
-
import {
|
|
3690
|
+
import {
|
|
3691
|
+
TextRun,
|
|
3692
|
+
ExternalHyperlink,
|
|
3693
|
+
InternalHyperlink,
|
|
3694
|
+
FootnoteReferenceRun,
|
|
3695
|
+
EndnoteReferenceRun,
|
|
3696
|
+
Tab
|
|
3697
|
+
} from "docx";
|
|
3698
|
+
var FOOTNOTE_MARKER_REGEX = /\[\^([^\]\s]+)\]/;
|
|
3675
3699
|
function escapeRegExp(s) {
|
|
3676
3700
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3677
3701
|
}
|
|
@@ -3848,8 +3872,8 @@ function buildTextRuns(text, commonProps, opts = {}) {
|
|
|
3848
3872
|
return runs;
|
|
3849
3873
|
}
|
|
3850
3874
|
function createTextRunsWithNewlines(text, baseStyle, options, overrideStyle) {
|
|
3851
|
-
|
|
3852
|
-
|
|
3875
|
+
const runs = (segment) => buildTextRuns(
|
|
3876
|
+
segment,
|
|
3853
3877
|
buildRunCommonProps(baseStyle, {
|
|
3854
3878
|
bold: overrideStyle?.bold,
|
|
3855
3879
|
italics: overrideStyle?.italics,
|
|
@@ -3857,6 +3881,34 @@ function createTextRunsWithNewlines(text, baseStyle, options, overrideStyle) {
|
|
|
3857
3881
|
}),
|
|
3858
3882
|
{ noProof: baseStyle.noProof, noProofWords: options.noProofWords }
|
|
3859
3883
|
);
|
|
3884
|
+
if (!options.noteRef) return runs(text);
|
|
3885
|
+
return splitNoteMarkers(text, options.noteRef, runs);
|
|
3886
|
+
}
|
|
3887
|
+
function splitNoteMarkers(text, noteRef, runs) {
|
|
3888
|
+
const regex = new RegExp(FOOTNOTE_MARKER_REGEX.source, "g");
|
|
3889
|
+
const out = [];
|
|
3890
|
+
let lastIndex = 0;
|
|
3891
|
+
let pending = "";
|
|
3892
|
+
let match;
|
|
3893
|
+
while ((match = regex.exec(text)) !== null) {
|
|
3894
|
+
const note = noteRef(match[1]);
|
|
3895
|
+
if (note === void 0) {
|
|
3896
|
+
pending += text.slice(lastIndex, regex.lastIndex);
|
|
3897
|
+
lastIndex = regex.lastIndex;
|
|
3898
|
+
continue;
|
|
3899
|
+
}
|
|
3900
|
+
const before = pending + text.slice(lastIndex, match.index);
|
|
3901
|
+
pending = "";
|
|
3902
|
+
if (before) out.push(...runs(before));
|
|
3903
|
+
out.push(
|
|
3904
|
+
note.endnote ? new EndnoteReferenceRun(note.id) : new FootnoteReferenceRun(note.id)
|
|
3905
|
+
);
|
|
3906
|
+
lastIndex = regex.lastIndex;
|
|
3907
|
+
}
|
|
3908
|
+
if (out.length === 0) return runs(text);
|
|
3909
|
+
const trailing = pending + text.slice(lastIndex);
|
|
3910
|
+
if (trailing) out.push(...runs(trailing));
|
|
3911
|
+
return out;
|
|
3860
3912
|
}
|
|
3861
3913
|
function parseTextWithHyperlinks(text, baseStyle = {}, options = {}) {
|
|
3862
3914
|
const normalizedText = normalizeUnicodeText(text);
|
|
@@ -4112,6 +4164,52 @@ initializeBuiltinPlaceholders();
|
|
|
4112
4164
|
|
|
4113
4165
|
// src/utils/revisionUtils.ts
|
|
4114
4166
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
4167
|
+
|
|
4168
|
+
// src/utils/componentAnnotations.ts
|
|
4169
|
+
function isRecord(value) {
|
|
4170
|
+
return typeof value === "object" && value !== null;
|
|
4171
|
+
}
|
|
4172
|
+
function hasKey(value, key) {
|
|
4173
|
+
return isRecord(value) && Boolean(value[key]);
|
|
4174
|
+
}
|
|
4175
|
+
function cellHasAnnotation(cell, key) {
|
|
4176
|
+
if (!isRecord(cell)) return false;
|
|
4177
|
+
if (hasKey(cell, key)) return true;
|
|
4178
|
+
const content = cell.content;
|
|
4179
|
+
return isRecord(content) && componentHasAnnotation(content, key);
|
|
4180
|
+
}
|
|
4181
|
+
function componentHasAnnotation(component, key) {
|
|
4182
|
+
const props = component.props;
|
|
4183
|
+
if (props) {
|
|
4184
|
+
if (props[key]) return true;
|
|
4185
|
+
const items = props.items;
|
|
4186
|
+
if (Array.isArray(items) && items.some((item) => hasKey(item, key))) {
|
|
4187
|
+
return true;
|
|
4188
|
+
}
|
|
4189
|
+
const rows = props.rows;
|
|
4190
|
+
if (Array.isArray(rows) && rows.some((row) => hasKey(row, key))) {
|
|
4191
|
+
return true;
|
|
4192
|
+
}
|
|
4193
|
+
const columns = props.columns;
|
|
4194
|
+
if (Array.isArray(columns) && columns.some((column) => {
|
|
4195
|
+
if (!isRecord(column)) return false;
|
|
4196
|
+
if (cellHasAnnotation(column.header, key)) return true;
|
|
4197
|
+
const cells = column.cells;
|
|
4198
|
+
return Array.isArray(cells) && cells.some((cell) => cellHasAnnotation(cell, key));
|
|
4199
|
+
})) {
|
|
4200
|
+
return true;
|
|
4201
|
+
}
|
|
4202
|
+
}
|
|
4203
|
+
const children = component.children;
|
|
4204
|
+
if (Array.isArray(children)) {
|
|
4205
|
+
return children.some(
|
|
4206
|
+
(child) => isRecord(child) && componentHasAnnotation(child, key)
|
|
4207
|
+
);
|
|
4208
|
+
}
|
|
4209
|
+
return false;
|
|
4210
|
+
}
|
|
4211
|
+
|
|
4212
|
+
// src/utils/revisionUtils.ts
|
|
4115
4213
|
var DEFAULT_REVISION_AUTHOR = "json-to-office";
|
|
4116
4214
|
var DEFAULT_REVISION_DATE = "1970-01-01T00:00:00Z";
|
|
4117
4215
|
var RevisionIdRegistry = class {
|
|
@@ -4196,25 +4294,25 @@ function createRevisionRuns(revision, baseStyle) {
|
|
|
4196
4294
|
return runs;
|
|
4197
4295
|
}
|
|
4198
4296
|
function componentHasRevision(component) {
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4297
|
+
return componentHasAnnotation(component, "revision");
|
|
4298
|
+
}
|
|
4299
|
+
function createRevisionMark(mark) {
|
|
4300
|
+
const attributes = {
|
|
4301
|
+
id: globalRevisionIdRegistry.next(),
|
|
4302
|
+
author: mark.author || DEFAULT_REVISION_AUTHOR,
|
|
4303
|
+
date: mark.date || DEFAULT_REVISION_DATE
|
|
4304
|
+
};
|
|
4305
|
+
return mark.type === "insert" ? { insertion: attributes } : { deletion: attributes };
|
|
4306
|
+
}
|
|
4307
|
+
function createMarkedTextRuns(text, mark, baseStyle) {
|
|
4308
|
+
return createRevisionRuns(
|
|
4309
|
+
{
|
|
4310
|
+
author: mark.author,
|
|
4311
|
+
date: mark.date,
|
|
4312
|
+
segments: [{ type: mark.type, text }]
|
|
4313
|
+
},
|
|
4314
|
+
baseStyle
|
|
4315
|
+
);
|
|
4218
4316
|
}
|
|
4219
4317
|
|
|
4220
4318
|
// src/core/cached-render.ts
|
|
@@ -4291,14 +4389,23 @@ async function clearComponentCache() {
|
|
|
4291
4389
|
}
|
|
4292
4390
|
bypassStats.clear();
|
|
4293
4391
|
}
|
|
4392
|
+
var DYNAMIC_CONTEXT_COMPONENTS = /* @__PURE__ */ new Set([
|
|
4393
|
+
"toc",
|
|
4394
|
+
"section",
|
|
4395
|
+
"visual",
|
|
4396
|
+
"heading",
|
|
4397
|
+
"list",
|
|
4398
|
+
"paragraph"
|
|
4399
|
+
]);
|
|
4400
|
+
function componentBypassReason(component) {
|
|
4401
|
+
if (componentHasRevision(component)) return "revision-ids";
|
|
4402
|
+
if (componentHasAnnotation(component, "comment")) return "comment-ids";
|
|
4403
|
+
if ("id" in component) return "bookmark-id";
|
|
4404
|
+
if (DYNAMIC_CONTEXT_COMPONENTS.has(component.name)) return "dynamic-context";
|
|
4405
|
+
return null;
|
|
4406
|
+
}
|
|
4294
4407
|
async function renderComponentWithCache(component, theme, themeName, context, bypassCache = false) {
|
|
4295
|
-
const bypassReason =
|
|
4296
|
-
component
|
|
4297
|
-
) ? "revision-ids" : "id" in component ? "bookmark-id" : component.name === "toc" || component.name === "section" || component.name === "visual" || component.name === "heading" || // Both explicit lists and markdown-list paragraphs register
|
|
4298
|
-
// numbering in the current document scope. Cached paragraphs can
|
|
4299
|
-
// otherwise reference definitions that only existed in a previous
|
|
4300
|
-
// render.
|
|
4301
|
-
component.name === "list" || component.name === "paragraph" ? "dynamic-context" : null;
|
|
4408
|
+
const bypassReason = componentBypassReason(component);
|
|
4302
4409
|
if (!componentCache) {
|
|
4303
4410
|
initializeComponentCache();
|
|
4304
4411
|
}
|
|
@@ -4368,8 +4475,8 @@ function getComponentCacheStats() {
|
|
|
4368
4475
|
|
|
4369
4476
|
// src/core/content.ts
|
|
4370
4477
|
import {
|
|
4371
|
-
Paragraph,
|
|
4372
|
-
TextRun as
|
|
4478
|
+
Paragraph as Paragraph3,
|
|
4479
|
+
TextRun as TextRun7,
|
|
4373
4480
|
Table,
|
|
4374
4481
|
TableRow,
|
|
4375
4482
|
TableCell,
|
|
@@ -4464,6 +4571,252 @@ var BookmarkRegistry = class {
|
|
|
4464
4571
|
};
|
|
4465
4572
|
var globalBookmarkRegistry = new BookmarkRegistry();
|
|
4466
4573
|
|
|
4574
|
+
// src/utils/commentAnchors.ts
|
|
4575
|
+
import {
|
|
4576
|
+
CommentRangeEnd,
|
|
4577
|
+
CommentRangeStart,
|
|
4578
|
+
CommentReference,
|
|
4579
|
+
TextRun as TextRun5
|
|
4580
|
+
} from "docx";
|
|
4581
|
+
|
|
4582
|
+
// src/utils/commentRegistry.ts
|
|
4583
|
+
import { Paragraph, TextRun as TextRun4 } from "docx";
|
|
4584
|
+
import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
|
|
4585
|
+
var DEFAULT_COMMENT_AUTHOR = "json-to-office";
|
|
4586
|
+
var DEFAULT_COMMENT_DATE = "1970-01-01T00:00:00Z";
|
|
4587
|
+
function createState() {
|
|
4588
|
+
return { counter: 0, comments: [], hasResolved: false };
|
|
4589
|
+
}
|
|
4590
|
+
function deriveInitials(author) {
|
|
4591
|
+
const initials = author.split(/[\s._-]+/).filter(Boolean).map((word) => word[0]).join("").toUpperCase().slice(0, 3);
|
|
4592
|
+
return initials || author.slice(0, 2).toUpperCase();
|
|
4593
|
+
}
|
|
4594
|
+
function bodyParagraphs(text) {
|
|
4595
|
+
return normalizeUnicodeText(text).split("\n").map((line) => new Paragraph({ children: [new TextRun4({ text: line })] }));
|
|
4596
|
+
}
|
|
4597
|
+
var CommentRegistry = class {
|
|
4598
|
+
fallback = createState();
|
|
4599
|
+
scopes = new AsyncLocalStorage4();
|
|
4600
|
+
get state() {
|
|
4601
|
+
return this.scopes.getStore() ?? this.fallback;
|
|
4602
|
+
}
|
|
4603
|
+
/** Run work with an isolated registry that follows its async call chain. */
|
|
4604
|
+
runScoped(callback) {
|
|
4605
|
+
return this.scopes.run(createState(), callback);
|
|
4606
|
+
}
|
|
4607
|
+
/**
|
|
4608
|
+
* Register a comment thread and return every id its anchors must carry — the
|
|
4609
|
+
* root first, then each reply in order. Word anchors every comment in a
|
|
4610
|
+
* thread over the same range, so all of them need a range and a reference.
|
|
4611
|
+
*
|
|
4612
|
+
* Ids are unique and monotonic within a render. `parentId` is derived here
|
|
4613
|
+
* rather than authored; docx turns it into the `w15:paraIdParent` links in
|
|
4614
|
+
* `word/commentsExtended.xml`.
|
|
4615
|
+
*/
|
|
4616
|
+
register(comment) {
|
|
4617
|
+
const state = this.state;
|
|
4618
|
+
const resolved = comment.resolved;
|
|
4619
|
+
const rootId = ++state.counter;
|
|
4620
|
+
state.comments.push({
|
|
4621
|
+
...this.toOptions(comment, rootId),
|
|
4622
|
+
...resolved !== void 0 && { resolved }
|
|
4623
|
+
});
|
|
4624
|
+
const ids = [rootId];
|
|
4625
|
+
for (const reply of comment.replies ?? []) {
|
|
4626
|
+
const replyId = ++state.counter;
|
|
4627
|
+
state.comments.push({
|
|
4628
|
+
...this.toOptions(reply, replyId),
|
|
4629
|
+
parentId: rootId,
|
|
4630
|
+
// Word resolves a thread as a whole, so the flag rides every member.
|
|
4631
|
+
...resolved !== void 0 && { resolved }
|
|
4632
|
+
});
|
|
4633
|
+
ids.push(replyId);
|
|
4634
|
+
}
|
|
4635
|
+
if (resolved !== void 0) state.hasResolved = true;
|
|
4636
|
+
return ids;
|
|
4637
|
+
}
|
|
4638
|
+
toOptions(comment, id) {
|
|
4639
|
+
const author = comment.author || DEFAULT_COMMENT_AUTHOR;
|
|
4640
|
+
return {
|
|
4641
|
+
id,
|
|
4642
|
+
author,
|
|
4643
|
+
initials: comment.initials || deriveInitials(author),
|
|
4644
|
+
date: new Date(comment.date || DEFAULT_COMMENT_DATE),
|
|
4645
|
+
children: bodyParagraphs(comment.text)
|
|
4646
|
+
};
|
|
4647
|
+
}
|
|
4648
|
+
/**
|
|
4649
|
+
* Every comment registered in this scope, in id order.
|
|
4650
|
+
*
|
|
4651
|
+
* docx writes `word/commentsExtended.xml` — and therefore any `w15:done` —
|
|
4652
|
+
* only when at least one comment in the document carries a `parentId`. A
|
|
4653
|
+
* document whose only resolved comment has no replies would silently lose
|
|
4654
|
+
* that state, so say so rather than dropping it quietly.
|
|
4655
|
+
*/
|
|
4656
|
+
getAll() {
|
|
4657
|
+
const state = this.state;
|
|
4658
|
+
if (state.hasResolved && !state.comments.some((comment) => comment.parentId !== void 0)) {
|
|
4659
|
+
console.warn(
|
|
4660
|
+
"A comment sets `resolved` but the document has no replies. Word stores the resolved flag in commentsExtended.xml, which is written only for threaded comments, so the flag will not survive."
|
|
4661
|
+
);
|
|
4662
|
+
}
|
|
4663
|
+
return [...state.comments];
|
|
4664
|
+
}
|
|
4665
|
+
/** Test-only: reset the current scope's counter and bodies. */
|
|
4666
|
+
clear() {
|
|
4667
|
+
const state = this.scopes.getStore();
|
|
4668
|
+
if (state) {
|
|
4669
|
+
state.counter = 0;
|
|
4670
|
+
state.comments.length = 0;
|
|
4671
|
+
state.hasResolved = false;
|
|
4672
|
+
} else {
|
|
4673
|
+
this.fallback = createState();
|
|
4674
|
+
}
|
|
4675
|
+
}
|
|
4676
|
+
};
|
|
4677
|
+
var globalCommentRegistry = new CommentRegistry();
|
|
4678
|
+
|
|
4679
|
+
// src/utils/commentAnchors.ts
|
|
4680
|
+
function openCommentRange(comment) {
|
|
4681
|
+
if (!comment) return void 0;
|
|
4682
|
+
const ids = globalCommentRegistry.register(comment);
|
|
4683
|
+
return { ids, start: ids.map((id) => new CommentRangeStart(id)) };
|
|
4684
|
+
}
|
|
4685
|
+
function closeCommentRange(ids) {
|
|
4686
|
+
return ids.flatMap((id) => [
|
|
4687
|
+
new CommentRangeEnd(id),
|
|
4688
|
+
new TextRun5({ children: [new CommentReference(id)] })
|
|
4689
|
+
]);
|
|
4690
|
+
}
|
|
4691
|
+
|
|
4692
|
+
// src/utils/noteRegistry.ts
|
|
4693
|
+
import { Paragraph as Paragraph2, TextRun as TextRun6 } from "docx";
|
|
4694
|
+
import { AsyncLocalStorage as AsyncLocalStorage5 } from "async_hooks";
|
|
4695
|
+
function createState2() {
|
|
4696
|
+
return {
|
|
4697
|
+
footnoteCounter: 0,
|
|
4698
|
+
endnoteCounter: 0,
|
|
4699
|
+
footnotes: {},
|
|
4700
|
+
endnotes: {}
|
|
4701
|
+
};
|
|
4702
|
+
}
|
|
4703
|
+
function bodyParagraphs2(text, style) {
|
|
4704
|
+
return normalizeUnicodeText(text).split("\n").map(
|
|
4705
|
+
(line) => new Paragraph2({
|
|
4706
|
+
style,
|
|
4707
|
+
children: [new TextRun6({ text: line })]
|
|
4708
|
+
})
|
|
4709
|
+
);
|
|
4710
|
+
}
|
|
4711
|
+
var NoteRegistry = class {
|
|
4712
|
+
fallback = createState2();
|
|
4713
|
+
scopes = new AsyncLocalStorage5();
|
|
4714
|
+
get state() {
|
|
4715
|
+
return this.scopes.getStore() ?? this.fallback;
|
|
4716
|
+
}
|
|
4717
|
+
/** Run work with an isolated registry that follows its async call chain. */
|
|
4718
|
+
runScoped(callback) {
|
|
4719
|
+
return this.scopes.run(createState2(), callback);
|
|
4720
|
+
}
|
|
4721
|
+
/**
|
|
4722
|
+
* Register a footnote body and return the id its reference must use. Ids are
|
|
4723
|
+
* unique and monotonic within a render.
|
|
4724
|
+
*/
|
|
4725
|
+
registerFootnote(text) {
|
|
4726
|
+
const state = this.state;
|
|
4727
|
+
const id = ++state.footnoteCounter;
|
|
4728
|
+
state.footnotes[String(id)] = {
|
|
4729
|
+
children: bodyParagraphs2(text, "FootnoteText")
|
|
4730
|
+
};
|
|
4731
|
+
return id;
|
|
4732
|
+
}
|
|
4733
|
+
/** Register an endnote body and return the id its reference must use. */
|
|
4734
|
+
registerEndnote(text) {
|
|
4735
|
+
const state = this.state;
|
|
4736
|
+
const id = ++state.endnoteCounter;
|
|
4737
|
+
state.endnotes[String(id)] = {
|
|
4738
|
+
children: bodyParagraphs2(text, "EndnoteText")
|
|
4739
|
+
};
|
|
4740
|
+
return id;
|
|
4741
|
+
}
|
|
4742
|
+
/** Every footnote registered in this scope, keyed by id. */
|
|
4743
|
+
getFootnotes() {
|
|
4744
|
+
return { ...this.state.footnotes };
|
|
4745
|
+
}
|
|
4746
|
+
/** Every endnote registered in this scope, keyed by id. */
|
|
4747
|
+
getEndnotes() {
|
|
4748
|
+
return { ...this.state.endnotes };
|
|
4749
|
+
}
|
|
4750
|
+
/** Test-only: reset the current scope's counters and bodies. */
|
|
4751
|
+
clear() {
|
|
4752
|
+
const state = this.scopes.getStore();
|
|
4753
|
+
if (state) {
|
|
4754
|
+
state.footnoteCounter = 0;
|
|
4755
|
+
state.endnoteCounter = 0;
|
|
4756
|
+
for (const key of Object.keys(state.footnotes)) {
|
|
4757
|
+
delete state.footnotes[key];
|
|
4758
|
+
}
|
|
4759
|
+
for (const key of Object.keys(state.endnotes)) {
|
|
4760
|
+
delete state.endnotes[key];
|
|
4761
|
+
}
|
|
4762
|
+
} else {
|
|
4763
|
+
this.fallback = createState2();
|
|
4764
|
+
}
|
|
4765
|
+
}
|
|
4766
|
+
};
|
|
4767
|
+
var globalNoteRegistry = new NoteRegistry();
|
|
4768
|
+
|
|
4769
|
+
// src/utils/noteResolver.ts
|
|
4770
|
+
function collectDeclared(footnotes, endnotes) {
|
|
4771
|
+
const declared = /* @__PURE__ */ new Map();
|
|
4772
|
+
const declare = (note, endnote) => {
|
|
4773
|
+
const existing = declared.get(note.id);
|
|
4774
|
+
if (existing) {
|
|
4775
|
+
console.warn(
|
|
4776
|
+
existing.endnote === endnote ? `Note id "${note.id}" is declared twice in the same ${endnote ? "endnotes" : "footnotes"} array. Using the first declaration and ignoring the rest.` : `Note id "${note.id}" is declared as both a footnote and an endnote in the same paragraph. Using the footnote and ignoring the endnote.`
|
|
4777
|
+
);
|
|
4778
|
+
return;
|
|
4779
|
+
}
|
|
4780
|
+
declared.set(note.id, { text: note.text, endnote });
|
|
4781
|
+
};
|
|
4782
|
+
for (const note of footnotes ?? []) declare(note, false);
|
|
4783
|
+
for (const note of endnotes ?? []) declare(note, true);
|
|
4784
|
+
return declared;
|
|
4785
|
+
}
|
|
4786
|
+
function createNoteResolver(footnotes, endnotes) {
|
|
4787
|
+
const declared = collectDeclared(footnotes, endnotes);
|
|
4788
|
+
if (declared.size === 0) return void 0;
|
|
4789
|
+
const registered = /* @__PURE__ */ new Map();
|
|
4790
|
+
return {
|
|
4791
|
+
resolve(id) {
|
|
4792
|
+
const existing = registered.get(id);
|
|
4793
|
+
if (existing !== void 0) return existing;
|
|
4794
|
+
const note = declared.get(id);
|
|
4795
|
+
if (note === void 0) {
|
|
4796
|
+
console.warn(
|
|
4797
|
+
`Note marker "[^${id}]" has no matching entry in this paragraph's footnotes or endnotes (declared: ${[...declared.keys()].join(", ")}). Rendering the marker as literal text.`
|
|
4798
|
+
);
|
|
4799
|
+
return void 0;
|
|
4800
|
+
}
|
|
4801
|
+
const resolved = {
|
|
4802
|
+
id: note.endnote ? globalNoteRegistry.registerEndnote(note.text) : globalNoteRegistry.registerFootnote(note.text),
|
|
4803
|
+
endnote: note.endnote
|
|
4804
|
+
};
|
|
4805
|
+
registered.set(id, resolved);
|
|
4806
|
+
return resolved;
|
|
4807
|
+
},
|
|
4808
|
+
reportUnemitted(text) {
|
|
4809
|
+
for (const [id, note] of declared) {
|
|
4810
|
+
if (registered.has(id)) continue;
|
|
4811
|
+
const kind = note.endnote ? "Endnote" : "Footnote";
|
|
4812
|
+
console.warn(
|
|
4813
|
+
text.includes(`[^${id}]`) ? `${kind} "${id}" is declared and its marker appears in the text, but the marker was not resolved \u2014 markers are not recognised in text that also contains {PLACEHOLDER} substitutions. The note will not appear in the document.` : `${kind} "${id}" is declared but never referenced as [^${id}] in this paragraph. It will not appear in the document.`
|
|
4814
|
+
);
|
|
4815
|
+
}
|
|
4816
|
+
}
|
|
4817
|
+
};
|
|
4818
|
+
}
|
|
4819
|
+
|
|
4467
4820
|
// src/core/content.ts
|
|
4468
4821
|
init_styleHelpers();
|
|
4469
4822
|
import { synthesizeFamilyName } from "@json-to-office/shared";
|
|
@@ -4487,6 +4840,20 @@ function resolveNoProofWords(theme, optionWords) {
|
|
|
4487
4840
|
const merged = [...themeWords || [], ...optionWords || []];
|
|
4488
4841
|
return merged.length > 0 ? Array.from(new Set(merged)) : void 0;
|
|
4489
4842
|
}
|
|
4843
|
+
function reportNotesUnsupportedInRevision(footnotes, endnotes, revision) {
|
|
4844
|
+
const declared = [...footnotes ?? [], ...endnotes ?? []];
|
|
4845
|
+
if (declared.length === 0) return;
|
|
4846
|
+
const text = revision.segments.map((segment) => segment.text).join("");
|
|
4847
|
+
const referenced = declared.filter((note) => text.includes(`[^${note.id}]`));
|
|
4848
|
+
console.warn(
|
|
4849
|
+
`Paragraph declares ${declared.length} note(s) (${declared.map((note) => note.id).join(", ")}) alongside a \`revision\`. Tracked-change text renders literally, so note markers are not resolved there` + (referenced.length > 0 ? ` \u2014 the marker(s) ${referenced.map((note) => `[^${note.id}]`).join(", ")} will render as literal text` : "") + ". The notes will not appear in the document."
|
|
4850
|
+
);
|
|
4851
|
+
}
|
|
4852
|
+
function wrapInComment(children, comment) {
|
|
4853
|
+
const anchor = openCommentRange(comment);
|
|
4854
|
+
if (!anchor) return children;
|
|
4855
|
+
return [...anchor.start, ...children, ...closeCommentRange(anchor.ids)];
|
|
4856
|
+
}
|
|
4490
4857
|
function createText(content, theme, themeName, options = {}) {
|
|
4491
4858
|
const normalizedContent = normalizeUnicodeText(content);
|
|
4492
4859
|
const style = options.style || "Normal";
|
|
@@ -4506,6 +4873,10 @@ function createText(content, theme, themeName, options = {}) {
|
|
|
4506
4873
|
if (options.columnBreak) {
|
|
4507
4874
|
children.push(new ColumnBreak());
|
|
4508
4875
|
}
|
|
4876
|
+
const commentAnchor = openCommentRange(options.comment);
|
|
4877
|
+
if (commentAnchor) {
|
|
4878
|
+
children.push(...commentAnchor.start);
|
|
4879
|
+
}
|
|
4509
4880
|
const hasWeightRequest = options.fontWeight != null || options.bold === true;
|
|
4510
4881
|
const effectiveFamily = options.fontFamily ?? (hasWeightRequest ? resolveFontFamily(theme, "body") : void 0);
|
|
4511
4882
|
const weighted = applyFontWeightAlias({
|
|
@@ -4542,6 +4913,11 @@ function createText(content, theme, themeName, options = {}) {
|
|
|
4542
4913
|
...options.noProof !== void 0 && { noProof: options.noProof }
|
|
4543
4914
|
};
|
|
4544
4915
|
if (options.revision) {
|
|
4916
|
+
reportNotesUnsupportedInRevision(
|
|
4917
|
+
options.footnotes,
|
|
4918
|
+
options.endnotes,
|
|
4919
|
+
options.revision
|
|
4920
|
+
);
|
|
4545
4921
|
const revisionRuns = createRevisionRuns(options.revision, baseTextStyle);
|
|
4546
4922
|
if (options.bookmarkId) {
|
|
4547
4923
|
globalBookmarkRegistry.register(
|
|
@@ -4559,11 +4935,17 @@ function createText(content, theme, themeName, options = {}) {
|
|
|
4559
4935
|
children.push(...revisionRuns);
|
|
4560
4936
|
}
|
|
4561
4937
|
} else {
|
|
4938
|
+
const noteResolver = createNoteResolver(
|
|
4939
|
+
options.footnotes,
|
|
4940
|
+
options.endnotes
|
|
4941
|
+
);
|
|
4562
4942
|
const textRuns = parseTextWithDecorators(normalizedContent, baseTextStyle, {
|
|
4563
4943
|
boldColor: options.boldColor ? resolveColor(options.boldColor, theme) : void 0,
|
|
4564
4944
|
enableHyperlinks: true,
|
|
4565
|
-
noProofWords: resolveNoProofWords(theme, options.noProofWords)
|
|
4945
|
+
noProofWords: resolveNoProofWords(theme, options.noProofWords),
|
|
4946
|
+
noteRef: noteResolver?.resolve
|
|
4566
4947
|
});
|
|
4948
|
+
noteResolver?.reportUnemitted(normalizedContent);
|
|
4567
4949
|
if (options.bookmarkId) {
|
|
4568
4950
|
globalBookmarkRegistry.register(
|
|
4569
4951
|
options.bookmarkId,
|
|
@@ -4580,9 +4962,12 @@ function createText(content, theme, themeName, options = {}) {
|
|
|
4580
4962
|
children.push(...textRuns);
|
|
4581
4963
|
}
|
|
4582
4964
|
}
|
|
4965
|
+
if (commentAnchor) {
|
|
4966
|
+
children.push(...closeCommentRange(commentAnchor.ids));
|
|
4967
|
+
}
|
|
4583
4968
|
const isFloating = !!options.floating;
|
|
4584
4969
|
const frameOptions = isFloating && options.floating ? mapFrameOptions(options.floating, theme, themeName) : void 0;
|
|
4585
|
-
return new
|
|
4970
|
+
return new Paragraph3({
|
|
4586
4971
|
children,
|
|
4587
4972
|
style,
|
|
4588
4973
|
alignment: options.alignment ? getAlignment(options.alignment) : void 0,
|
|
@@ -4677,6 +5062,10 @@ function createHeading(text, level, theme, _themeName, options = {}) {
|
|
|
4677
5062
|
if (options.columnBreak) {
|
|
4678
5063
|
children.push(new ColumnBreak());
|
|
4679
5064
|
}
|
|
5065
|
+
const commentAnchor = openCommentRange(options.comment);
|
|
5066
|
+
if (commentAnchor) {
|
|
5067
|
+
children.push(...commentAnchor.start);
|
|
5068
|
+
}
|
|
4680
5069
|
const hasDecorators = /(\*\*\*|___|(\*\*|__)|(\*|_))/.test(normalizedText);
|
|
4681
5070
|
const headingHasWeightRequest = options.fontWeight != null || options.bold === true;
|
|
4682
5071
|
const headingEffectiveFamily = options.fontFamily ?? (headingHasWeightRequest ? resolveFontFamily(theme, "heading") : void 0);
|
|
@@ -4713,7 +5102,7 @@ function createHeading(text, level, theme, _themeName, options = {}) {
|
|
|
4713
5102
|
const headingNoProofWords = resolveNoProofWords(theme, options.noProofWords);
|
|
4714
5103
|
const makeHeadingRuns = (value) => splitByNoProofWords(
|
|
4715
5104
|
value,
|
|
4716
|
-
(segment, matched) => new
|
|
5105
|
+
(segment, matched) => new TextRun7({
|
|
4717
5106
|
text: segment,
|
|
4718
5107
|
...baseTextStyle,
|
|
4719
5108
|
...matched && { noProof: true }
|
|
@@ -4772,7 +5161,10 @@ function createHeading(text, level, theme, _themeName, options = {}) {
|
|
|
4772
5161
|
children.push(...makeHeadingRuns(normalizedText));
|
|
4773
5162
|
}
|
|
4774
5163
|
}
|
|
4775
|
-
|
|
5164
|
+
if (commentAnchor) {
|
|
5165
|
+
children.push(...closeCommentRange(commentAnchor.ids));
|
|
5166
|
+
}
|
|
5167
|
+
return new Paragraph3({
|
|
4776
5168
|
children,
|
|
4777
5169
|
style: styleId,
|
|
4778
5170
|
alignment: getAlignment(options.alignment || "left"),
|
|
@@ -4839,7 +5231,7 @@ async function createImage(path4, theme, themeName, options = {}) {
|
|
|
4839
5231
|
spacing.after = pointsToTwips(options.spacing.after);
|
|
4840
5232
|
}
|
|
4841
5233
|
elements.push(
|
|
4842
|
-
new
|
|
5234
|
+
new Paragraph3({
|
|
4843
5235
|
children: [imageRun],
|
|
4844
5236
|
alignment,
|
|
4845
5237
|
...Object.keys(spacing).length > 0 && { spacing },
|
|
@@ -4856,7 +5248,7 @@ async function createImage(path4, theme, themeName, options = {}) {
|
|
|
4856
5248
|
const hasDecorators = /(\*\*\*|___|(\*\*|__)|(\*|_))/.test(options.caption);
|
|
4857
5249
|
if (!hasDecorators) {
|
|
4858
5250
|
elements.push(
|
|
4859
|
-
new
|
|
5251
|
+
new Paragraph3({
|
|
4860
5252
|
text: normalizeUnicodeText(options.caption),
|
|
4861
5253
|
style: "Normal",
|
|
4862
5254
|
alignment: AlignmentType2.LEFT
|
|
@@ -4872,7 +5264,7 @@ async function createImage(path4, theme, themeName, options = {}) {
|
|
|
4872
5264
|
}
|
|
4873
5265
|
);
|
|
4874
5266
|
elements.push(
|
|
4875
|
-
new
|
|
5267
|
+
new Paragraph3({
|
|
4876
5268
|
children: textRuns,
|
|
4877
5269
|
style: "Normal",
|
|
4878
5270
|
// Use Normal style for consistent font inheritance
|
|
@@ -4889,13 +5281,13 @@ function createStatistic(data, options = {}) {
|
|
|
4889
5281
|
const normalizedNumber = normalizeUnicodeText(data.number);
|
|
4890
5282
|
const normalizedDescription = normalizeUnicodeText(data.description);
|
|
4891
5283
|
return [
|
|
4892
|
-
new
|
|
5284
|
+
new Paragraph3({
|
|
4893
5285
|
text: normalizedNumber,
|
|
4894
5286
|
style: "StatisticNumber",
|
|
4895
5287
|
alignment,
|
|
4896
5288
|
spacing: options.spacing
|
|
4897
5289
|
}),
|
|
4898
|
-
new
|
|
5290
|
+
new Paragraph3({
|
|
4899
5291
|
text: normalizedDescription,
|
|
4900
5292
|
style: "StatisticDescription",
|
|
4901
5293
|
alignment
|
|
@@ -4907,6 +5299,15 @@ function createList(items, _theme, _themeName, options = {}) {
|
|
|
4907
5299
|
return [];
|
|
4908
5300
|
}
|
|
4909
5301
|
const paragraphs = [];
|
|
5302
|
+
const noteResolver = createNoteResolver(options.footnotes, options.endnotes);
|
|
5303
|
+
const rendersAt = items.map((item) => {
|
|
5304
|
+
const text = typeof item === "string" ? item : item.text;
|
|
5305
|
+
const revision = typeof item === "object" ? item.revision : void 0;
|
|
5306
|
+
return Boolean(text.trim()) || Boolean(revision);
|
|
5307
|
+
});
|
|
5308
|
+
const firstRendered = rendersAt.indexOf(true);
|
|
5309
|
+
const lastRendered = rendersAt.lastIndexOf(true);
|
|
5310
|
+
const commentAnchor = firstRendered === -1 ? void 0 : openCommentRange(options.comment);
|
|
4910
5311
|
items.forEach((item, index) => {
|
|
4911
5312
|
const itemText = typeof item === "string" ? item : item.text;
|
|
4912
5313
|
const itemLevel = typeof item === "object" ? item.level || 0 : 0;
|
|
@@ -4918,7 +5319,8 @@ function createList(items, _theme, _themeName, options = {}) {
|
|
|
4918
5319
|
itemText,
|
|
4919
5320
|
{},
|
|
4920
5321
|
{
|
|
4921
|
-
enableHyperlinks: true
|
|
5322
|
+
enableHyperlinks: true,
|
|
5323
|
+
noteRef: noteResolver?.resolve
|
|
4922
5324
|
}
|
|
4923
5325
|
);
|
|
4924
5326
|
const spacing = {};
|
|
@@ -4930,10 +5332,15 @@ function createList(items, _theme, _themeName, options = {}) {
|
|
|
4930
5332
|
} else if (options.spacing?.item) {
|
|
4931
5333
|
spacing.after = pointsToTwips(options.spacing.item);
|
|
4932
5334
|
}
|
|
4933
|
-
const
|
|
5335
|
+
const paragraphChildren = [
|
|
5336
|
+
...commentAnchor && index === firstRendered ? commentAnchor.start : [],
|
|
5337
|
+
...textRuns,
|
|
5338
|
+
...commentAnchor && index === lastRendered ? closeCommentRange(commentAnchor.ids) : []
|
|
5339
|
+
];
|
|
5340
|
+
const paragraph = new Paragraph3({
|
|
4934
5341
|
style: "Normal",
|
|
4935
5342
|
// Apply Normal style for font inheritance
|
|
4936
|
-
children:
|
|
5343
|
+
children: paragraphChildren,
|
|
4937
5344
|
alignment: options.alignment ? getAlignment(options.alignment) : AlignmentType2.LEFT,
|
|
4938
5345
|
spacing,
|
|
4939
5346
|
// Use proper docx numbering instead of prepending text
|
|
@@ -4946,6 +5353,9 @@ function createList(items, _theme, _themeName, options = {}) {
|
|
|
4946
5353
|
});
|
|
4947
5354
|
paragraphs.push(paragraph);
|
|
4948
5355
|
});
|
|
5356
|
+
noteResolver?.reportUnemitted(
|
|
5357
|
+
items.map((item) => typeof item === "string" ? item : item.text).join("\n")
|
|
5358
|
+
);
|
|
4949
5359
|
return paragraphs;
|
|
4950
5360
|
}
|
|
4951
5361
|
async function createTable(columns, tableConfig, theme, themeName, _options = {}) {
|
|
@@ -5279,10 +5689,10 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
5279
5689
|
return false;
|
|
5280
5690
|
}
|
|
5281
5691
|
};
|
|
5282
|
-
const processCellContent = async (cell, cellDefaults, baseCellStyle) => {
|
|
5692
|
+
const processCellContent = async (cell, cellDefaults, baseCellStyle, comment, revision, rowMark) => {
|
|
5283
5693
|
let cellChildren = [];
|
|
5284
5694
|
if (!cell) {
|
|
5285
|
-
return cellChildren;
|
|
5695
|
+
return wrapInComment(cellChildren, comment);
|
|
5286
5696
|
}
|
|
5287
5697
|
const cellWeighted = applyFontWeightAlias({
|
|
5288
5698
|
fontFamily: cellDefaults.font?.family || baseCellStyle.font,
|
|
@@ -5326,11 +5736,10 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
5326
5736
|
color: resolveColor(paragraphFont.color, theme)
|
|
5327
5737
|
}
|
|
5328
5738
|
};
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
);
|
|
5739
|
+
const paragraphRevision = revision ?? textComp.props.revision;
|
|
5740
|
+
cellChildren = paragraphRevision ? createRevisionRuns(paragraphRevision, paragraphStyle) : rowMark ? createMarkedTextRuns(textComp.props.text, rowMark, paragraphStyle) : parseTextWithDecorators(textComp.props.text, paragraphStyle, {
|
|
5741
|
+
enableHyperlinks: true
|
|
5742
|
+
});
|
|
5334
5743
|
} else if (isImageComponent(cell)) {
|
|
5335
5744
|
const imageComp = cell;
|
|
5336
5745
|
try {
|
|
@@ -5365,7 +5774,7 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
5365
5774
|
} catch (error) {
|
|
5366
5775
|
const imageSource = imageComp.props.svg?.trim() ? "inline-svg" : imageComp.props.base64 || imageComp.props.path || "unknown";
|
|
5367
5776
|
cellChildren = [
|
|
5368
|
-
new
|
|
5777
|
+
new TextRun7({
|
|
5369
5778
|
text: `[IMAGE: ${imageSource.substring(0, 50)}${imageSource.length > 50 ? "..." : ""}]`,
|
|
5370
5779
|
font: mergedStyle.font,
|
|
5371
5780
|
size: mergedStyle.size,
|
|
@@ -5375,7 +5784,7 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
5375
5784
|
}
|
|
5376
5785
|
} else {
|
|
5377
5786
|
cellChildren = [
|
|
5378
|
-
new
|
|
5787
|
+
new TextRun7({
|
|
5379
5788
|
text: `[Unsupported component type: ${cell.name}]`,
|
|
5380
5789
|
font: mergedStyle.font,
|
|
5381
5790
|
size: mergedStyle.size,
|
|
@@ -5384,11 +5793,11 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
5384
5793
|
];
|
|
5385
5794
|
}
|
|
5386
5795
|
} else {
|
|
5387
|
-
cellChildren = parseTextWithDecorators(cell, mergedStyle, {
|
|
5796
|
+
cellChildren = revision ? createRevisionRuns(revision, mergedStyle) : rowMark ? createMarkedTextRuns(cell, rowMark, mergedStyle) : parseTextWithDecorators(cell, mergedStyle, {
|
|
5388
5797
|
enableHyperlinks: true
|
|
5389
5798
|
});
|
|
5390
5799
|
}
|
|
5391
|
-
return cellChildren;
|
|
5800
|
+
return wrapInComment(cellChildren, comment);
|
|
5392
5801
|
};
|
|
5393
5802
|
const numColumns = columns.length;
|
|
5394
5803
|
const headerHeight = columns.reduce(
|
|
@@ -5445,7 +5854,9 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
5445
5854
|
const cellChildren = await processCellContent(
|
|
5446
5855
|
headerCell?.content,
|
|
5447
5856
|
mergedDefaults,
|
|
5448
|
-
tableStyle.tableHeader
|
|
5857
|
+
tableStyle.tableHeader,
|
|
5858
|
+
headerCell?.comment,
|
|
5859
|
+
headerCell?.revision
|
|
5449
5860
|
);
|
|
5450
5861
|
const horizontalAlignment = mergedDefaults.horizontalAlignment;
|
|
5451
5862
|
const verticalAlignment = getVerticalAlignment(
|
|
@@ -5453,7 +5864,7 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
5453
5864
|
);
|
|
5454
5865
|
return new TableCell({
|
|
5455
5866
|
children: [
|
|
5456
|
-
new
|
|
5867
|
+
new Paragraph3({
|
|
5457
5868
|
...tableConfig.keepInOnePage && { keepNext: true },
|
|
5458
5869
|
spacing: tableStyle.headerParagraph,
|
|
5459
5870
|
alignment: getAlignment(horizontalAlignment),
|
|
@@ -5496,6 +5907,10 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
5496
5907
|
const dataRows = await Promise.all(
|
|
5497
5908
|
Array.from({ length: numRows }, async (_, rowIndex) => {
|
|
5498
5909
|
const isLastRow = rowIndex === numRows - 1;
|
|
5910
|
+
const rowProps = tableConfig.rows?.[rowIndex];
|
|
5911
|
+
const rowRevision = rowProps?.revision;
|
|
5912
|
+
const rowRevisionAttributes = rowRevision ? createRevisionMark(rowRevision) : void 0;
|
|
5913
|
+
const paragraphMarks = rowRevision ? columns.map(() => ({ run: createRevisionMark(rowRevision) })) : void 0;
|
|
5499
5914
|
const rowHeight = columns.reduce(
|
|
5500
5915
|
(maxHeight, column, colIndex) => {
|
|
5501
5916
|
const cell = column.cells?.[rowIndex];
|
|
@@ -5525,6 +5940,14 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
5525
5940
|
);
|
|
5526
5941
|
return new TableRow({
|
|
5527
5942
|
height: rowHeight !== void 0 ? { value: rowHeight * 20, rule: "atLeast" } : void 0,
|
|
5943
|
+
...rowProps?.cantSplit !== void 0 && {
|
|
5944
|
+
cantSplit: rowProps.cantSplit
|
|
5945
|
+
},
|
|
5946
|
+
...rowProps?.tableHeader !== void 0 && {
|
|
5947
|
+
tableHeader: rowProps.tableHeader
|
|
5948
|
+
},
|
|
5949
|
+
// w:trPr/w:ins | w:del — the row itself was inserted or deleted.
|
|
5950
|
+
...rowRevisionAttributes,
|
|
5528
5951
|
children: await Promise.all(
|
|
5529
5952
|
columns.map(async (column, colIndex) => {
|
|
5530
5953
|
const cell = column.cells?.[rowIndex];
|
|
@@ -5548,10 +5971,11 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
5548
5971
|
);
|
|
5549
5972
|
return new TableCell({
|
|
5550
5973
|
children: [
|
|
5551
|
-
new
|
|
5974
|
+
new Paragraph3({
|
|
5552
5975
|
...tableConfig.keepInOnePage && !isLastRow || isLastRow && tableConfig.keepNext ? { keepNext: true } : {},
|
|
5553
5976
|
spacing: tableStyle.cellParagraph,
|
|
5554
5977
|
alignment: AlignmentType2.LEFT,
|
|
5978
|
+
...paragraphMarks?.[colIndex],
|
|
5555
5979
|
children: []
|
|
5556
5980
|
})
|
|
5557
5981
|
],
|
|
@@ -5616,7 +6040,10 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
5616
6040
|
const cellChildren = await processCellContent(
|
|
5617
6041
|
cell.content,
|
|
5618
6042
|
mergedDefaults,
|
|
5619
|
-
tableStyle.tableCell
|
|
6043
|
+
tableStyle.tableCell,
|
|
6044
|
+
cell.comment,
|
|
6045
|
+
cell.revision,
|
|
6046
|
+
rowRevision
|
|
5620
6047
|
);
|
|
5621
6048
|
const horizontalAlignment = mergedDefaults.horizontalAlignment;
|
|
5622
6049
|
const verticalAlignment = getVerticalAlignment(
|
|
@@ -5624,10 +6051,11 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
5624
6051
|
);
|
|
5625
6052
|
return new TableCell({
|
|
5626
6053
|
children: [
|
|
5627
|
-
new
|
|
6054
|
+
new Paragraph3({
|
|
5628
6055
|
...tableConfig.keepInOnePage && !isLastRow || isLastRow && tableConfig.keepNext ? { keepNext: true } : {},
|
|
5629
6056
|
spacing: tableStyle.cellParagraph,
|
|
5630
6057
|
alignment: getAlignment(horizontalAlignment),
|
|
6058
|
+
...paragraphMarks?.[colIndex],
|
|
5631
6059
|
children: cellChildren
|
|
5632
6060
|
})
|
|
5633
6061
|
],
|
|
@@ -5786,7 +6214,9 @@ function renderHeadingComponent(component, theme, themeName) {
|
|
|
5786
6214
|
// Bookmark ID for internal linking
|
|
5787
6215
|
bookmarkId,
|
|
5788
6216
|
// Tracked-change segments (rendered as native Word revisions)
|
|
5789
|
-
revision: config.revision
|
|
6217
|
+
revision: config.revision,
|
|
6218
|
+
// Review comment anchored to this heading's text
|
|
6219
|
+
comment: config.comment
|
|
5790
6220
|
}
|
|
5791
6221
|
);
|
|
5792
6222
|
return [header];
|
|
@@ -5794,7 +6224,7 @@ function renderHeadingComponent(component, theme, themeName) {
|
|
|
5794
6224
|
|
|
5795
6225
|
// src/utils/numberingConfig.ts
|
|
5796
6226
|
import { AlignmentType as AlignmentType3, convertInchesToTwip, LevelFormat } from "docx";
|
|
5797
|
-
import { AsyncLocalStorage as
|
|
6227
|
+
import { AsyncLocalStorage as AsyncLocalStorage6 } from "async_hooks";
|
|
5798
6228
|
var LEVEL_FORMAT_MAP = {
|
|
5799
6229
|
decimal: LevelFormat.DECIMAL,
|
|
5800
6230
|
upperRoman: LevelFormat.UPPER_ROMAN,
|
|
@@ -5872,6 +6302,21 @@ function getAlignment2(alignment) {
|
|
|
5872
6302
|
if (!alignment) return AlignmentType3.LEFT;
|
|
5873
6303
|
return ALIGNMENT_MAP[alignment] || AlignmentType3.LEFT;
|
|
5874
6304
|
}
|
|
6305
|
+
function createMarkerRunStyle(font) {
|
|
6306
|
+
if (!font) return void 0;
|
|
6307
|
+
const run = {
|
|
6308
|
+
...font.family && { font: font.family },
|
|
6309
|
+
// docx run sizes are half-points.
|
|
6310
|
+
...font.size !== void 0 && { size: font.size * 2 },
|
|
6311
|
+
...font.color && { color: font.color },
|
|
6312
|
+
...font.bold !== void 0 && { bold: font.bold },
|
|
6313
|
+
...font.italic !== void 0 && { italics: font.italic },
|
|
6314
|
+
...font.underline !== void 0 && {
|
|
6315
|
+
underline: font.underline ? { type: "single" } : void 0
|
|
6316
|
+
}
|
|
6317
|
+
};
|
|
6318
|
+
return Object.keys(run).length > 0 ? run : void 0;
|
|
6319
|
+
}
|
|
5875
6320
|
function createNumberingConfig(config) {
|
|
5876
6321
|
const levels = [];
|
|
5877
6322
|
for (const levelConfig of config.levels) {
|
|
@@ -5880,6 +6325,7 @@ function createNumberingConfig(config) {
|
|
|
5880
6325
|
const text = levelConfig.text || (format2 === LevelFormat.BULLET ? "\u2022" : `%${levelConfig.level + 1}.`);
|
|
5881
6326
|
const baseIndent = levelConfig.indent?.left !== void 0 ? levelConfig.indent.left / 72 : 0.5 * (levelConfig.level + 1);
|
|
5882
6327
|
const hangingIndent = levelConfig.indent?.hanging !== void 0 ? levelConfig.indent.hanging / 72 : 0.25;
|
|
6328
|
+
const markerRun = createMarkerRunStyle(levelConfig.font);
|
|
5883
6329
|
const level = {
|
|
5884
6330
|
level: levelConfig.level,
|
|
5885
6331
|
format: format2,
|
|
@@ -5891,7 +6337,10 @@ function createNumberingConfig(config) {
|
|
|
5891
6337
|
left: convertInchesToTwip(baseIndent),
|
|
5892
6338
|
hanging: convertInchesToTwip(hangingIndent)
|
|
5893
6339
|
}
|
|
5894
|
-
}
|
|
6340
|
+
},
|
|
6341
|
+
// The marker glyph carries its own run properties; without this it
|
|
6342
|
+
// inherits whatever the list paragraph resolves to.
|
|
6343
|
+
...markerRun && { run: markerRun }
|
|
5895
6344
|
},
|
|
5896
6345
|
// Add start number if specified
|
|
5897
6346
|
...levelConfig.start !== void 0 && { start: levelConfig.start }
|
|
@@ -5908,7 +6357,7 @@ var NumberingRegistry = class {
|
|
|
5908
6357
|
configs: /* @__PURE__ */ new Map(),
|
|
5909
6358
|
counter: 0
|
|
5910
6359
|
};
|
|
5911
|
-
scopes = new
|
|
6360
|
+
scopes = new AsyncLocalStorage6();
|
|
5912
6361
|
get state() {
|
|
5913
6362
|
return this.scopes.getStore() ?? this.fallback;
|
|
5914
6363
|
}
|
|
@@ -6020,7 +6469,10 @@ function renderParagraphComponent(component, theme, themeName) {
|
|
|
6020
6469
|
return createList(listData.items, theme, themeName, {
|
|
6021
6470
|
numberingReference: reference,
|
|
6022
6471
|
spacing: resolvedConfig.spacing,
|
|
6023
|
-
alignment: resolvedConfig.alignment
|
|
6472
|
+
alignment: resolvedConfig.alignment,
|
|
6473
|
+
comment: resolvedConfig.comment,
|
|
6474
|
+
footnotes: resolvedConfig.footnotes,
|
|
6475
|
+
endnotes: resolvedConfig.endnotes
|
|
6024
6476
|
});
|
|
6025
6477
|
}
|
|
6026
6478
|
const styleFromTheme = (() => {
|
|
@@ -6084,12 +6536,18 @@ function renderParagraphComponent(component, theme, themeName) {
|
|
|
6084
6536
|
// Pass bookmark ID for internal linking
|
|
6085
6537
|
bookmarkId: resolvedConfig.id,
|
|
6086
6538
|
// Tracked-change segments (rendered as native Word revisions)
|
|
6087
|
-
revision: resolvedConfig.revision
|
|
6539
|
+
revision: resolvedConfig.revision,
|
|
6540
|
+
// Review comment anchored to this paragraph's text
|
|
6541
|
+
comment: resolvedConfig.comment,
|
|
6542
|
+
// Note bodies for the `[^id]` markers in this paragraph
|
|
6543
|
+
footnotes: resolvedConfig.footnotes,
|
|
6544
|
+
endnotes: resolvedConfig.endnotes
|
|
6088
6545
|
});
|
|
6089
6546
|
return [text];
|
|
6090
6547
|
}
|
|
6091
6548
|
|
|
6092
6549
|
// src/components/list.ts
|
|
6550
|
+
init_colorUtils();
|
|
6093
6551
|
function createLevelsFromSimplifiedProps(props) {
|
|
6094
6552
|
const levels = [];
|
|
6095
6553
|
let format2;
|
|
@@ -6136,6 +6594,22 @@ function createLevelsFromSimplifiedProps(props) {
|
|
|
6136
6594
|
}
|
|
6137
6595
|
return levels;
|
|
6138
6596
|
}
|
|
6597
|
+
function resolveMarkerFonts(levels, theme) {
|
|
6598
|
+
return levels.map((level) => {
|
|
6599
|
+
const font = level.font;
|
|
6600
|
+
if (!font?.color) return level;
|
|
6601
|
+
return {
|
|
6602
|
+
...level,
|
|
6603
|
+
font: { ...font, color: resolveColor(font.color, theme) }
|
|
6604
|
+
};
|
|
6605
|
+
});
|
|
6606
|
+
}
|
|
6607
|
+
function applyListStart(levels, start) {
|
|
6608
|
+
if (start === void 0) return levels;
|
|
6609
|
+
return levels.map(
|
|
6610
|
+
(level) => level.level === 0 && level.start === void 0 ? { ...level, start } : level
|
|
6611
|
+
);
|
|
6612
|
+
}
|
|
6139
6613
|
function getMaxLevelFromItems(items) {
|
|
6140
6614
|
if (!items || !Array.isArray(items)) {
|
|
6141
6615
|
return 0;
|
|
@@ -6198,7 +6672,10 @@ function renderListComponent(component, theme, themeName) {
|
|
|
6198
6672
|
let levels;
|
|
6199
6673
|
if (resolvedConfig.levels && resolvedConfig.levels.length > 0) {
|
|
6200
6674
|
levels = fillMissingLevels(
|
|
6201
|
-
|
|
6675
|
+
applyListStart(
|
|
6676
|
+
resolvedConfig.levels,
|
|
6677
|
+
resolvedConfig.start
|
|
6678
|
+
),
|
|
6202
6679
|
maxLevel
|
|
6203
6680
|
);
|
|
6204
6681
|
} else {
|
|
@@ -6207,7 +6684,7 @@ function renderListComponent(component, theme, themeName) {
|
|
|
6207
6684
|
}
|
|
6208
6685
|
const config = {
|
|
6209
6686
|
reference,
|
|
6210
|
-
levels
|
|
6687
|
+
levels: resolveMarkerFonts(levels, theme)
|
|
6211
6688
|
};
|
|
6212
6689
|
const numberingConfig = createNumberingConfig(config);
|
|
6213
6690
|
globalNumberingRegistry.register(numberingConfig);
|
|
@@ -6215,7 +6692,9 @@ function renderListComponent(component, theme, themeName) {
|
|
|
6215
6692
|
return createList(resolvedConfig.items, theme, themeName, {
|
|
6216
6693
|
numberingReference: reference,
|
|
6217
6694
|
spacing: resolvedConfig.spacing,
|
|
6218
|
-
alignment: resolvedConfig.alignment
|
|
6695
|
+
alignment: resolvedConfig.alignment,
|
|
6696
|
+
// Review comment spanning the whole list
|
|
6697
|
+
comment: resolvedConfig.comment
|
|
6219
6698
|
});
|
|
6220
6699
|
}
|
|
6221
6700
|
|
|
@@ -6306,10 +6785,10 @@ function convertBorders2(bordersConfig, theme) {
|
|
|
6306
6785
|
// src/styles/utils/cellUtils.ts
|
|
6307
6786
|
init_styleHelpers();
|
|
6308
6787
|
init_colorUtils();
|
|
6309
|
-
import { Paragraph as
|
|
6788
|
+
import { Paragraph as Paragraph4 } from "docx";
|
|
6310
6789
|
function buildCellOptions(children, styleCfg, theme) {
|
|
6311
6790
|
const cellOpts = {
|
|
6312
|
-
children: children.length ? children : [new
|
|
6791
|
+
children: children.length ? children : [new Paragraph4({})],
|
|
6313
6792
|
margins: {
|
|
6314
6793
|
top: styleCfg?.padding?.top ? pointsToTwips(styleCfg.padding.top) : 0,
|
|
6315
6794
|
right: styleCfg?.padding?.right ? pointsToTwips(styleCfg.padding.right) : 0,
|
|
@@ -6512,25 +6991,66 @@ async function renderTableComponent(component, theme, themeName) {
|
|
|
6512
6991
|
}
|
|
6513
6992
|
|
|
6514
6993
|
// src/components/section.ts
|
|
6515
|
-
import { Paragraph as
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6994
|
+
import { Paragraph as Paragraph6, BookmarkStart, BookmarkEnd } from "docx";
|
|
6995
|
+
|
|
6996
|
+
// src/core/sectionBookmarks.ts
|
|
6997
|
+
import { AsyncLocalStorage as AsyncLocalStorage7 } from "async_hooks";
|
|
6998
|
+
var NESTED_LINK_ID_BASE = 1e6;
|
|
6999
|
+
function createState3() {
|
|
7000
|
+
return { nextNested: 1, resolved: /* @__PURE__ */ new WeakMap() };
|
|
7001
|
+
}
|
|
7002
|
+
var SectionBookmarkRegistry = class {
|
|
7003
|
+
fallback = createState3();
|
|
7004
|
+
scopes = new AsyncLocalStorage7();
|
|
7005
|
+
get state() {
|
|
7006
|
+
return this.scopes.getStore() ?? this.fallback;
|
|
7007
|
+
}
|
|
7008
|
+
/** Run work with an isolated registry that follows its async call chain. */
|
|
7009
|
+
runScoped(callback) {
|
|
7010
|
+
return this.scopes.run(createState3(), callback);
|
|
7011
|
+
}
|
|
7012
|
+
/**
|
|
7013
|
+
* The bookmark for a layout section, derived from its ordinal.
|
|
7014
|
+
*
|
|
7015
|
+
* Every layout chunk of one user-defined section shares an ordinal (see
|
|
7016
|
+
* `computeSectionOrdinals`), so they all resolve to the same bookmark — which
|
|
7017
|
+
* is the point: the start lands in the first chunk and the end in the last.
|
|
7018
|
+
*/
|
|
7019
|
+
forLayoutSection(ordinal) {
|
|
7020
|
+
return { id: `_Section_${ordinal}`, linkId: ordinal };
|
|
7021
|
+
}
|
|
7022
|
+
/**
|
|
7023
|
+
* The bookmark for a `section` component, allocated on first sight and
|
|
7024
|
+
* remembered so re-resolving the same component never allocates twice.
|
|
7025
|
+
*/
|
|
7026
|
+
forSectionComponent(component) {
|
|
7027
|
+
const state = this.state;
|
|
7028
|
+
const existing = state.resolved.get(component);
|
|
7029
|
+
if (existing) return existing;
|
|
7030
|
+
const ordinal = state.nextNested++;
|
|
7031
|
+
const bookmark = {
|
|
7032
|
+
id: `_NestedSection_${ordinal}`,
|
|
7033
|
+
linkId: NESTED_LINK_ID_BASE + ordinal
|
|
7034
|
+
};
|
|
7035
|
+
state.resolved.set(component, bookmark);
|
|
7036
|
+
return bookmark;
|
|
7037
|
+
}
|
|
7038
|
+
/** Test-only: reset the unscoped fallback counters. */
|
|
7039
|
+
clear() {
|
|
7040
|
+
if (!this.scopes.getStore()) {
|
|
7041
|
+
this.fallback = createState3();
|
|
7042
|
+
}
|
|
7043
|
+
}
|
|
7044
|
+
};
|
|
7045
|
+
var globalSectionBookmarkRegistry = new SectionBookmarkRegistry();
|
|
7046
|
+
|
|
7047
|
+
// src/components/section.ts
|
|
6528
7048
|
async function renderSectionComponent(component, theme, themeName, context) {
|
|
6529
7049
|
if (!isSectionComponent(component)) return [];
|
|
6530
7050
|
const elements = [];
|
|
6531
|
-
const { id: sectionBookmarkId, linkId: bookmarkLinkId } =
|
|
7051
|
+
const { id: sectionBookmarkId, linkId: bookmarkLinkId } = globalSectionBookmarkRegistry.forSectionComponent(component);
|
|
6532
7052
|
elements.push(
|
|
6533
|
-
new
|
|
7053
|
+
new Paragraph6({
|
|
6534
7054
|
children: [new BookmarkStart(sectionBookmarkId, bookmarkLinkId)],
|
|
6535
7055
|
spacing: {
|
|
6536
7056
|
before: 0,
|
|
@@ -6558,7 +7078,7 @@ async function renderSectionComponent(component, theme, themeName, context) {
|
|
|
6558
7078
|
}
|
|
6559
7079
|
}
|
|
6560
7080
|
elements.push(
|
|
6561
|
-
new
|
|
7081
|
+
new Paragraph6({
|
|
6562
7082
|
children: [new BookmarkEnd(bookmarkLinkId)],
|
|
6563
7083
|
spacing: {
|
|
6564
7084
|
before: 0,
|
|
@@ -6572,7 +7092,7 @@ async function renderSectionComponent(component, theme, themeName, context) {
|
|
|
6572
7092
|
|
|
6573
7093
|
// src/components/columns.ts
|
|
6574
7094
|
import {
|
|
6575
|
-
Paragraph as
|
|
7095
|
+
Paragraph as Paragraph7,
|
|
6576
7096
|
Table as Table5,
|
|
6577
7097
|
TableRow as TableRow3,
|
|
6578
7098
|
TableCell as TableCell3,
|
|
@@ -6664,7 +7184,7 @@ async function renderColumnsAsTable(component, theme, themeName, context) {
|
|
|
6664
7184
|
columnElements.push(...rendered);
|
|
6665
7185
|
}
|
|
6666
7186
|
if (columnElements.length === 0) {
|
|
6667
|
-
columnElements.push(new
|
|
7187
|
+
columnElements.push(new Paragraph7({}));
|
|
6668
7188
|
}
|
|
6669
7189
|
cells.push(
|
|
6670
7190
|
new TableCell3({
|
|
@@ -6715,12 +7235,34 @@ function renderStatisticComponent(component, _theme) {
|
|
|
6715
7235
|
|
|
6716
7236
|
// src/components/toc/index.ts
|
|
6717
7237
|
import {
|
|
6718
|
-
Paragraph as
|
|
7238
|
+
Paragraph as Paragraph8,
|
|
6719
7239
|
TableOfContents,
|
|
6720
7240
|
AlignmentType as AlignmentType4,
|
|
6721
|
-
TextRun as
|
|
7241
|
+
TextRun as TextRun8,
|
|
6722
7242
|
StyleLevel
|
|
6723
7243
|
} from "docx";
|
|
7244
|
+
function toStyleDisplayName(styleId) {
|
|
7245
|
+
return styleId.replace(/([A-Z])/g, " $1").replace(/[-_]+/g, " ").replace(/\s+/g, " ").trim();
|
|
7246
|
+
}
|
|
7247
|
+
function selectCachedEntries(collected, options) {
|
|
7248
|
+
if (!collected || collected.length === 0) return [];
|
|
7249
|
+
const { depthStart, depthEnd, sectionBookmarkId, styleLevels } = options;
|
|
7250
|
+
const entries = [];
|
|
7251
|
+
for (const entry of collected) {
|
|
7252
|
+
if (sectionBookmarkId && entry.sectionBookmarkId !== sectionBookmarkId) {
|
|
7253
|
+
continue;
|
|
7254
|
+
}
|
|
7255
|
+
if (entry.styleId !== void 0) {
|
|
7256
|
+
const level = styleLevels.get(entry.styleId) ?? styleLevels.get(toStyleDisplayName(entry.styleId));
|
|
7257
|
+
if (level === void 0) continue;
|
|
7258
|
+
entries.push({ title: entry.title, level });
|
|
7259
|
+
continue;
|
|
7260
|
+
}
|
|
7261
|
+
if (entry.level < depthStart || entry.level > depthEnd) continue;
|
|
7262
|
+
entries.push({ title: entry.title, level: entry.level });
|
|
7263
|
+
}
|
|
7264
|
+
return entries;
|
|
7265
|
+
}
|
|
6724
7266
|
function parseDepthRange(rawDepth, fieldName, defaultFrom = 1, defaultTo = 3) {
|
|
6725
7267
|
if (typeof rawDepth !== "object" || rawDepth === null) {
|
|
6726
7268
|
throw new Error(
|
|
@@ -6776,9 +7318,9 @@ function renderTocComponent(component, theme, context) {
|
|
|
6776
7318
|
const paragraphs = [];
|
|
6777
7319
|
if (componentProps.title) {
|
|
6778
7320
|
paragraphs.push(
|
|
6779
|
-
new
|
|
7321
|
+
new Paragraph8({
|
|
6780
7322
|
children: [
|
|
6781
|
-
new
|
|
7323
|
+
new TextRun8({
|
|
6782
7324
|
text: componentProps.title,
|
|
6783
7325
|
bold: true,
|
|
6784
7326
|
size: 28
|
|
@@ -6796,11 +7338,14 @@ function renderTocComponent(component, theme, context) {
|
|
|
6796
7338
|
);
|
|
6797
7339
|
}
|
|
6798
7340
|
const stylesWithLevels = [];
|
|
7341
|
+
const styleLevels = /* @__PURE__ */ new Map();
|
|
6799
7342
|
if (componentProps.styles && componentProps.styles.length > 0) {
|
|
6800
7343
|
for (const styleMapping of componentProps.styles) {
|
|
6801
7344
|
const styleId = styleMapping.styleId;
|
|
6802
7345
|
const isCustomStyle = !!theme.styles && Object.prototype.hasOwnProperty.call(theme.styles, styleId);
|
|
6803
|
-
const styleDisplayName = isCustomStyle ? styleId
|
|
7346
|
+
const styleDisplayName = isCustomStyle ? toStyleDisplayName(styleId) : styleId;
|
|
7347
|
+
styleLevels.set(styleId, styleMapping.level);
|
|
7348
|
+
styleLevels.set(styleDisplayName, styleMapping.level);
|
|
6804
7349
|
stylesWithLevels.push(
|
|
6805
7350
|
new StyleLevel(styleDisplayName, styleMapping.level)
|
|
6806
7351
|
);
|
|
@@ -6808,6 +7353,12 @@ function renderTocComponent(component, theme, context) {
|
|
|
6808
7353
|
}
|
|
6809
7354
|
const effectiveDepthStart = depthStart;
|
|
6810
7355
|
const effectiveDepthEnd = depthEnd;
|
|
7356
|
+
const cachedEntries = selectCachedEntries(context?.tocHeadings, {
|
|
7357
|
+
depthStart,
|
|
7358
|
+
depthEnd,
|
|
7359
|
+
sectionBookmarkId,
|
|
7360
|
+
styleLevels
|
|
7361
|
+
});
|
|
6811
7362
|
const tocOptions = {
|
|
6812
7363
|
hyperlink: true,
|
|
6813
7364
|
// Enable clickable hyperlinks (\h switch)
|
|
@@ -6846,7 +7397,10 @@ function renderTocComponent(component, theme, context) {
|
|
|
6846
7397
|
// default to tab
|
|
6847
7398
|
};
|
|
6848
7399
|
paragraphs.push(
|
|
6849
|
-
new TableOfContents(componentProps.title ?? "Table of Contents",
|
|
7400
|
+
new TableOfContents(componentProps.title ?? "Table of Contents", {
|
|
7401
|
+
...tocOptions,
|
|
7402
|
+
...cachedEntries.length > 0 && { cachedEntries }
|
|
7403
|
+
})
|
|
6850
7404
|
);
|
|
6851
7405
|
return paragraphs;
|
|
6852
7406
|
}
|
|
@@ -7056,14 +7610,19 @@ function effectiveVisualServerUrl(props, serviceConfig) {
|
|
|
7056
7610
|
if (serviceConfig?.render) return void 0;
|
|
7057
7611
|
return props.serverUrl;
|
|
7058
7612
|
}
|
|
7059
|
-
async function rasterizeVisualSlide(presentation, dpi, propsServerUrl, serviceConfig, baseDir) {
|
|
7613
|
+
async function rasterizeVisualSlide(presentation, dpi, propsServerUrl, serviceConfig, baseDir, fonts) {
|
|
7060
7614
|
if (!isNodeEnvironment()) {
|
|
7061
7615
|
throw new Error(
|
|
7062
7616
|
"Visual rasterization requires a Node.js environment. It is not available in browser environments."
|
|
7063
7617
|
);
|
|
7064
7618
|
}
|
|
7065
7619
|
if (serviceConfig?.render) {
|
|
7066
|
-
return serviceConfig.render({
|
|
7620
|
+
return serviceConfig.render({
|
|
7621
|
+
presentation,
|
|
7622
|
+
dpi,
|
|
7623
|
+
baseDir,
|
|
7624
|
+
...fonts?.length ? { fonts: [...fonts] } : {}
|
|
7625
|
+
});
|
|
7067
7626
|
}
|
|
7068
7627
|
const serverUrl = resolveServiceUrl(
|
|
7069
7628
|
propsServerUrl,
|
|
@@ -7073,7 +7632,12 @@ async function rasterizeVisualSlide(presentation, dpi, propsServerUrl, serviceCo
|
|
|
7073
7632
|
const response = await postJsonToService({
|
|
7074
7633
|
url: serverUrl,
|
|
7075
7634
|
path: "/rasterize",
|
|
7076
|
-
body: {
|
|
7635
|
+
body: {
|
|
7636
|
+
presentation,
|
|
7637
|
+
dpi,
|
|
7638
|
+
...baseDir !== void 0 && { baseDir },
|
|
7639
|
+
...fonts?.length ? { fonts } : {}
|
|
7640
|
+
},
|
|
7077
7641
|
headers: serviceConfig?.headers,
|
|
7078
7642
|
serviceLabel: "PPTX rasterization service",
|
|
7079
7643
|
onUnreachable: (url, cause) => `PPTX rasterization service is not reachable at ${url}. Configure services.pptx with a \`render\` callback or a running \`serverUrl\`.
|
|
@@ -7119,7 +7683,8 @@ async function renderVisualComponent(component, theme, themeName, context) {
|
|
|
7119
7683
|
dpi,
|
|
7120
7684
|
props.serverUrl,
|
|
7121
7685
|
serviceConfig,
|
|
7122
|
-
getBaseDir()
|
|
7686
|
+
getBaseDir(),
|
|
7687
|
+
context?.visualFonts
|
|
7123
7688
|
);
|
|
7124
7689
|
}
|
|
7125
7690
|
return await createImage(
|
|
@@ -7253,6 +7818,11 @@ function collectVisualProps(root) {
|
|
|
7253
7818
|
function toErrorMessage(error) {
|
|
7254
7819
|
return error instanceof Error ? error.message : String(error);
|
|
7255
7820
|
}
|
|
7821
|
+
var HTTP_STATUS_IN_MESSAGE = /\breturned (\d{3})\b/;
|
|
7822
|
+
function isSchemaRejection(error) {
|
|
7823
|
+
const match = HTTP_STATUS_IN_MESSAGE.exec(toErrorMessage(error));
|
|
7824
|
+
return match !== null && match[1] === "400";
|
|
7825
|
+
}
|
|
7256
7826
|
function* chunksOf(items, size) {
|
|
7257
7827
|
for (let i = 0; i < items.length; i += size) yield items.slice(i, i + size);
|
|
7258
7828
|
}
|
|
@@ -7311,22 +7881,38 @@ async function prerasterizeVisuals(root, serviceConfig, options = {}) {
|
|
|
7311
7881
|
const limit = createLimiter(
|
|
7312
7882
|
Math.max(1, options.concurrency ?? DEFAULT_FALLBACK_CONCURRENCY)
|
|
7313
7883
|
);
|
|
7884
|
+
let fontsRejected = false;
|
|
7885
|
+
const requestFonts = () => fontsRejected || !options.fonts?.length ? void 0 : options.fonts;
|
|
7886
|
+
const rasterizeOne = async (target) => {
|
|
7887
|
+
const fonts = requestFonts();
|
|
7888
|
+
const call = (withFonts) => rasterizeVisualSlide(
|
|
7889
|
+
target.presentation,
|
|
7890
|
+
target.dpi,
|
|
7891
|
+
void 0,
|
|
7892
|
+
serviceConfig,
|
|
7893
|
+
options.baseDir,
|
|
7894
|
+
withFonts
|
|
7895
|
+
);
|
|
7896
|
+
try {
|
|
7897
|
+
return { ok: true, ...await call(fonts) };
|
|
7898
|
+
} catch (error) {
|
|
7899
|
+
if (!fonts || !isSchemaRejection(error)) {
|
|
7900
|
+
return { ok: false, error: toErrorMessage(error) };
|
|
7901
|
+
}
|
|
7902
|
+
try {
|
|
7903
|
+
const result = await call(void 0);
|
|
7904
|
+
fontsRejected = true;
|
|
7905
|
+
return { ok: true, ...result };
|
|
7906
|
+
} catch {
|
|
7907
|
+
return { ok: false, error: toErrorMessage(error) };
|
|
7908
|
+
}
|
|
7909
|
+
}
|
|
7910
|
+
};
|
|
7314
7911
|
const rasterizeIndividually = async (chunk) => {
|
|
7315
7912
|
await Promise.all(
|
|
7316
7913
|
chunk.map(
|
|
7317
7914
|
(target) => limit(async () => {
|
|
7318
|
-
|
|
7319
|
-
const result = await rasterizeVisualSlide(
|
|
7320
|
-
target.presentation,
|
|
7321
|
-
target.dpi,
|
|
7322
|
-
void 0,
|
|
7323
|
-
serviceConfig,
|
|
7324
|
-
options.baseDir
|
|
7325
|
-
);
|
|
7326
|
-
map.set(target.key, { ok: true, ...result });
|
|
7327
|
-
} catch (error) {
|
|
7328
|
-
map.set(target.key, { ok: false, error: toErrorMessage(error) });
|
|
7329
|
-
}
|
|
7915
|
+
map.set(target.key, await rasterizeOne(target));
|
|
7330
7916
|
})
|
|
7331
7917
|
)
|
|
7332
7918
|
);
|
|
@@ -7339,7 +7925,8 @@ async function prerasterizeVisuals(root, serviceConfig, options = {}) {
|
|
|
7339
7925
|
presentation: target.presentation,
|
|
7340
7926
|
dpi: target.dpi
|
|
7341
7927
|
})),
|
|
7342
|
-
...options.baseDir !== void 0 && { baseDir: options.baseDir }
|
|
7928
|
+
...options.baseDir !== void 0 && { baseDir: options.baseDir },
|
|
7929
|
+
...options.fonts?.length ? { fonts: [...options.fonts] } : {}
|
|
7343
7930
|
});
|
|
7344
7931
|
if (!applyBatchResponse(chunk, response, map)) {
|
|
7345
7932
|
throw new Error(
|
|
@@ -7368,10 +7955,10 @@ async function prerasterizeVisuals(root, serviceConfig, options = {}) {
|
|
|
7368
7955
|
serviceConfig?.serverUrl,
|
|
7369
7956
|
DEFAULT_RASTERIZE_SERVER_URL
|
|
7370
7957
|
);
|
|
7371
|
-
|
|
7372
|
-
let
|
|
7958
|
+
const postBatch = async (chunk, fonts) => {
|
|
7959
|
+
let response;
|
|
7373
7960
|
try {
|
|
7374
|
-
|
|
7961
|
+
response = await postJsonToService({
|
|
7375
7962
|
url: serverUrl,
|
|
7376
7963
|
path: "/rasterize/batch",
|
|
7377
7964
|
body: {
|
|
@@ -7379,22 +7966,112 @@ async function prerasterizeVisuals(root, serviceConfig, options = {}) {
|
|
|
7379
7966
|
presentation: target.presentation,
|
|
7380
7967
|
dpi: target.dpi
|
|
7381
7968
|
})),
|
|
7382
|
-
...options.baseDir !== void 0 && { baseDir: options.baseDir }
|
|
7969
|
+
...options.baseDir !== void 0 && { baseDir: options.baseDir },
|
|
7970
|
+
...fonts?.length ? { fonts } : {}
|
|
7383
7971
|
},
|
|
7384
7972
|
headers: serviceConfig?.headers,
|
|
7385
7973
|
timeoutMs: BATCH_TIMEOUT_BASE_MS + BATCH_TIMEOUT_PER_SLIDE_MS * chunk.length,
|
|
7386
7974
|
serviceLabel: "PPTX batch rasterization service",
|
|
7387
7975
|
onUnreachable: (url, cause) => `PPTX rasterization service is not reachable at ${url}. Cause: ${cause}`
|
|
7388
7976
|
});
|
|
7389
|
-
|
|
7977
|
+
} catch (error) {
|
|
7978
|
+
return { applied: false, schemaRejected: isSchemaRejection(error) };
|
|
7979
|
+
}
|
|
7980
|
+
try {
|
|
7981
|
+
if (applyBatchResponse(chunk, await response.json(), map)) {
|
|
7982
|
+
return { applied: true };
|
|
7983
|
+
}
|
|
7390
7984
|
} catch {
|
|
7391
|
-
applied = false;
|
|
7392
7985
|
}
|
|
7393
|
-
|
|
7986
|
+
return { applied: false, schemaRejected: false };
|
|
7987
|
+
};
|
|
7988
|
+
for (const chunk of chunksOf(unique, MAX_RASTERIZE_BATCH_SLIDES)) {
|
|
7989
|
+
const fonts = requestFonts();
|
|
7990
|
+
let outcome = await postBatch(chunk, fonts);
|
|
7991
|
+
if (!outcome.applied && fonts && outcome.schemaRejected) {
|
|
7992
|
+
const retry = await postBatch(chunk, void 0);
|
|
7993
|
+
if (retry.applied) {
|
|
7994
|
+
fontsRejected = true;
|
|
7995
|
+
outcome = retry;
|
|
7996
|
+
}
|
|
7997
|
+
}
|
|
7998
|
+
if (!outcome.applied) await rasterizeIndividually(chunk);
|
|
7394
7999
|
}
|
|
7395
8000
|
return map;
|
|
7396
8001
|
}
|
|
7397
8002
|
|
|
8003
|
+
// src/core/sectionOrdinals.ts
|
|
8004
|
+
function computeSectionOrdinals(sections) {
|
|
8005
|
+
let counter = 0;
|
|
8006
|
+
return sections.map((section, index) => {
|
|
8007
|
+
if (!section.belongsToUserSection) {
|
|
8008
|
+
if (section.isUserSection) counter++;
|
|
8009
|
+
return { closeBookmark: false };
|
|
8010
|
+
}
|
|
8011
|
+
const ordinal = section.isUserSection ? counter + 1 : counter;
|
|
8012
|
+
if (section.isUserSection) counter++;
|
|
8013
|
+
const next = sections[index + 1];
|
|
8014
|
+
const closeBookmark = !next || !next.belongsToUserSection || next.isUserSection;
|
|
8015
|
+
return { ordinal, closeBookmark };
|
|
8016
|
+
});
|
|
8017
|
+
}
|
|
8018
|
+
|
|
8019
|
+
// src/core/collectTocHeadings.ts
|
|
8020
|
+
import { getStandardComponent } from "@json-to-office/shared-docx";
|
|
8021
|
+
function normalizeEntryTitle(text) {
|
|
8022
|
+
return normalizeUnicodeText(text).replace(/(\*\*\*|___)([\s\S]*?)\1/g, "$2").replace(/(\*\*|__)([\s\S]*?)\1/g, "$2").replace(/(\*|_)([\s\S]*?)\1/g, "$2").trim();
|
|
8023
|
+
}
|
|
8024
|
+
function isContainer(name) {
|
|
8025
|
+
return getStandardComponent(name)?.hasChildren === true;
|
|
8026
|
+
}
|
|
8027
|
+
function isEnabled(component) {
|
|
8028
|
+
return !("enabled" in component && component.enabled === false);
|
|
8029
|
+
}
|
|
8030
|
+
function styleEntryKey(props) {
|
|
8031
|
+
const themeStyle = props.themeStyle;
|
|
8032
|
+
if (typeof themeStyle !== "string" || !themeStyle) return void 0;
|
|
8033
|
+
if (/^heading[1-6]$/i.test(themeStyle)) return void 0;
|
|
8034
|
+
if (["normal", "title", "subtitle"].includes(themeStyle.toLowerCase())) {
|
|
8035
|
+
return void 0;
|
|
8036
|
+
}
|
|
8037
|
+
return themeStyle;
|
|
8038
|
+
}
|
|
8039
|
+
function collectTocHeadings(sections) {
|
|
8040
|
+
const entries = [];
|
|
8041
|
+
const ordinals = computeSectionOrdinals(sections);
|
|
8042
|
+
sections.forEach((section, index) => {
|
|
8043
|
+
const ordinal = ordinals[index]?.ordinal;
|
|
8044
|
+
const sectionBookmarkId = ordinal ? globalSectionBookmarkRegistry.forLayoutSection(ordinal).id : void 0;
|
|
8045
|
+
const visit = (component) => {
|
|
8046
|
+
if (!isEnabled(component)) return;
|
|
8047
|
+
const props = component.props ?? {};
|
|
8048
|
+
if (component.name === "heading") {
|
|
8049
|
+
const text = typeof props.text === "string" ? props.text : "";
|
|
8050
|
+
const title = normalizeEntryTitle(text);
|
|
8051
|
+
if (title) {
|
|
8052
|
+
const level = typeof props.level === "number" ? props.level : 1;
|
|
8053
|
+
entries.push({ title, level, sectionBookmarkId });
|
|
8054
|
+
}
|
|
8055
|
+
return;
|
|
8056
|
+
}
|
|
8057
|
+
if (component.name === "paragraph") {
|
|
8058
|
+
const styleId = styleEntryKey(props);
|
|
8059
|
+
const text = typeof props.text === "string" ? props.text : "";
|
|
8060
|
+
const title = normalizeEntryTitle(text);
|
|
8061
|
+
if (styleId && title) {
|
|
8062
|
+
entries.push({ title, level: 1, styleId, sectionBookmarkId });
|
|
8063
|
+
}
|
|
8064
|
+
return;
|
|
8065
|
+
}
|
|
8066
|
+
if (!isContainer(component.name)) return;
|
|
8067
|
+
const children = component.children;
|
|
8068
|
+
if (Array.isArray(children)) children.forEach(visit);
|
|
8069
|
+
};
|
|
8070
|
+
section.components.forEach(visit);
|
|
8071
|
+
});
|
|
8072
|
+
return entries;
|
|
8073
|
+
}
|
|
8074
|
+
|
|
7398
8075
|
// src/core/render.ts
|
|
7399
8076
|
function getAlignment3(alignment) {
|
|
7400
8077
|
switch (alignment) {
|
|
@@ -7432,7 +8109,23 @@ async function renderDocument(structure, layout, options) {
|
|
|
7432
8109
|
() => globalBookmarkRegistry.runScoped(
|
|
7433
8110
|
() => globalRevisionIdRegistry.runScoped(
|
|
7434
8111
|
() => globalNumberingRegistry.runScoped(
|
|
7435
|
-
() =>
|
|
8112
|
+
() => globalSectionBookmarkRegistry.runScoped(
|
|
8113
|
+
() => (
|
|
8114
|
+
// Comment ids are a separate OOXML namespace from w:ins/w:del,
|
|
8115
|
+
// but they need the same per-render isolation: outside this nest
|
|
8116
|
+
// concurrent generations would interleave counters and an anchor
|
|
8117
|
+
// would point at another document's comment body.
|
|
8118
|
+
globalCommentRegistry.runScoped(
|
|
8119
|
+
() => (
|
|
8120
|
+
// Footnote ids are document-scoped too: a reference resolved
|
|
8121
|
+
// against another render's counter points at the wrong body.
|
|
8122
|
+
globalNoteRegistry.runScoped(
|
|
8123
|
+
() => renderDocumentScoped(structure, layout, options)
|
|
8124
|
+
)
|
|
8125
|
+
)
|
|
8126
|
+
)
|
|
8127
|
+
)
|
|
8128
|
+
)
|
|
7436
8129
|
)
|
|
7437
8130
|
)
|
|
7438
8131
|
)
|
|
@@ -7452,11 +8145,12 @@ async function renderDocumentScoped(structure, layout, options) {
|
|
|
7452
8145
|
structure.themeName
|
|
7453
8146
|
);
|
|
7454
8147
|
context.services = options?.services;
|
|
8148
|
+
context.visualFonts = options?.visualFonts;
|
|
7455
8149
|
try {
|
|
7456
8150
|
const visualRasterResults = await prerasterizeVisuals(
|
|
7457
8151
|
layout.sections,
|
|
7458
8152
|
options?.services?.pptx,
|
|
7459
|
-
{ baseDir: getBaseDir() }
|
|
8153
|
+
{ baseDir: getBaseDir(), fonts: options?.visualFonts }
|
|
7460
8154
|
);
|
|
7461
8155
|
if (visualRasterResults.size > 0) {
|
|
7462
8156
|
context.visualRasterResults = visualRasterResults;
|
|
@@ -7467,19 +8161,23 @@ async function renderDocumentScoped(structure, layout, options) {
|
|
|
7467
8161
|
error instanceof Error ? error.message : error
|
|
7468
8162
|
);
|
|
7469
8163
|
}
|
|
7470
|
-
|
|
8164
|
+
try {
|
|
8165
|
+
const tocHeadings = collectTocHeadings(layout.sections);
|
|
8166
|
+
if (tocHeadings.length > 0) {
|
|
8167
|
+
context.tocHeadings = tocHeadings;
|
|
8168
|
+
}
|
|
8169
|
+
} catch (error) {
|
|
8170
|
+
console.warn(
|
|
8171
|
+
"[core-docx] TOC entry collection failed; the TOC field will rely on the reader refreshing it:",
|
|
8172
|
+
error instanceof Error ? error.message : error
|
|
8173
|
+
);
|
|
8174
|
+
}
|
|
8175
|
+
const sectionOrdinals = computeSectionOrdinals(layout.sections);
|
|
7471
8176
|
let previousHeader = void 0;
|
|
7472
8177
|
let previousFooter = void 0;
|
|
7473
8178
|
for (let idx = 0; idx < layout.sections.length; idx++) {
|
|
7474
8179
|
const layoutSection = layout.sections[idx];
|
|
7475
|
-
|
|
7476
|
-
if (layoutSection.belongsToUserSection) {
|
|
7477
|
-
if (layoutSection.isUserSection) {
|
|
7478
|
-
sectionOrdinal = sectionBookmarkCounter + 1;
|
|
7479
|
-
} else {
|
|
7480
|
-
sectionOrdinal = sectionBookmarkCounter;
|
|
7481
|
-
}
|
|
7482
|
-
}
|
|
8180
|
+
const { ordinal: sectionOrdinal, closeBookmark } = sectionOrdinals[idx];
|
|
7483
8181
|
let headerToUse;
|
|
7484
8182
|
if (layoutSection.header === "linkToPrevious") {
|
|
7485
8183
|
headerToUse = previousHeader;
|
|
@@ -7503,13 +8201,6 @@ async function renderDocumentScoped(structure, layout, options) {
|
|
|
7503
8201
|
header: headerToUse,
|
|
7504
8202
|
footer: footerToUse
|
|
7505
8203
|
};
|
|
7506
|
-
let closeBookmark = false;
|
|
7507
|
-
if (layoutSection.belongsToUserSection && sectionOrdinal !== void 0) {
|
|
7508
|
-
const next = layout.sections[idx + 1];
|
|
7509
|
-
if (!next || !next.belongsToUserSection || next.isUserSection) {
|
|
7510
|
-
closeBookmark = true;
|
|
7511
|
-
}
|
|
7512
|
-
}
|
|
7513
8204
|
const rendered = await renderSection(
|
|
7514
8205
|
sectionToRender,
|
|
7515
8206
|
structure.theme,
|
|
@@ -7519,14 +8210,14 @@ async function renderDocumentScoped(structure, layout, options) {
|
|
|
7519
8210
|
closeBookmark,
|
|
7520
8211
|
options?.bypassCache === true
|
|
7521
8212
|
);
|
|
7522
|
-
if (layoutSection.isUserSection) {
|
|
7523
|
-
sectionBookmarkCounter++;
|
|
7524
|
-
}
|
|
7525
8213
|
if (rendered.children.length > 0) {
|
|
7526
8214
|
sections.push(rendered);
|
|
7527
8215
|
}
|
|
7528
8216
|
}
|
|
7529
8217
|
const numberingConfigs = globalNumberingRegistry.getAll();
|
|
8218
|
+
const comments = globalCommentRegistry.getAll();
|
|
8219
|
+
const footnotes = globalNoteRegistry.getFootnotes();
|
|
8220
|
+
const endnotes = globalNoteRegistry.getEndnotes();
|
|
7530
8221
|
return new Document({
|
|
7531
8222
|
styles: createWordStyles(structure.theme, structure.language),
|
|
7532
8223
|
sections,
|
|
@@ -7537,6 +8228,12 @@ async function renderDocumentScoped(structure, layout, options) {
|
|
|
7537
8228
|
// Word opens the document in review mode (further edits are tracked)
|
|
7538
8229
|
...structure.trackRevisions && { trackRevisions: true }
|
|
7539
8230
|
},
|
|
8231
|
+
// word/comments.xml, emitted only when something was actually commented
|
|
8232
|
+
...comments.length > 0 && { comments: { children: comments } },
|
|
8233
|
+
// word/footnotes.xml and word/endnotes.xml bodies, keyed by the id their
|
|
8234
|
+
// references carry
|
|
8235
|
+
...Object.keys(footnotes).length > 0 && { footnotes },
|
|
8236
|
+
...Object.keys(endnotes).length > 0 && { endnotes },
|
|
7540
8237
|
// Add numbering configurations if any lists were rendered
|
|
7541
8238
|
...numberingConfigs.length > 0 && {
|
|
7542
8239
|
numbering: {
|
|
@@ -7583,9 +8280,9 @@ async function renderHeaderFooterComponents(components, theme, themeName, contex
|
|
|
7583
8280
|
let imageSource = resolveImageSource(imageComp.props);
|
|
7584
8281
|
if (!imageSource) {
|
|
7585
8282
|
elements.push(
|
|
7586
|
-
new
|
|
8283
|
+
new Paragraph9({
|
|
7587
8284
|
children: [
|
|
7588
|
-
new
|
|
8285
|
+
new TextRun9({
|
|
7589
8286
|
text: "[IMAGE: Missing path, base64, or svg property]",
|
|
7590
8287
|
font: getThemeFonts(theme).body.family,
|
|
7591
8288
|
size: 20,
|
|
@@ -7653,7 +8350,7 @@ async function renderHeaderFooterComponents(components, theme, themeName, contex
|
|
|
7653
8350
|
...floatingOptions && { floating: floatingOptions }
|
|
7654
8351
|
});
|
|
7655
8352
|
elements.push(
|
|
7656
|
-
new
|
|
8353
|
+
new Paragraph9({
|
|
7657
8354
|
children: [imageRun],
|
|
7658
8355
|
alignment: imageComp.props.alignment ? getAlignment3(imageComp.props.alignment) : void 0,
|
|
7659
8356
|
style: "Normal"
|
|
@@ -7666,9 +8363,9 @@ async function renderHeaderFooterComponents(components, theme, themeName, contex
|
|
|
7666
8363
|
error instanceof Error ? error.message : error
|
|
7667
8364
|
);
|
|
7668
8365
|
elements.push(
|
|
7669
|
-
new
|
|
8366
|
+
new Paragraph9({
|
|
7670
8367
|
children: [
|
|
7671
|
-
new
|
|
8368
|
+
new TextRun9({
|
|
7672
8369
|
text: `[IMAGE: ${sourcePreview}]`,
|
|
7673
8370
|
font: getThemeFonts(theme).body.family,
|
|
7674
8371
|
size: 20,
|
|
@@ -7698,8 +8395,9 @@ async function renderHeaderFooterComponents(components, theme, themeName, contex
|
|
|
7698
8395
|
async function renderSection(section, theme, themeName, context, sectionOrdinal, closeBookmark, bypassCache = false) {
|
|
7699
8396
|
const elements = [];
|
|
7700
8397
|
const isFirstLayoutOfUserSection = section.isUserSection;
|
|
7701
|
-
const
|
|
7702
|
-
const
|
|
8398
|
+
const bookmark = section.belongsToUserSection && sectionOrdinal ? globalSectionBookmarkRegistry.forLayoutSection(sectionOrdinal) : void 0;
|
|
8399
|
+
const sharedLinkId = bookmark?.linkId;
|
|
8400
|
+
const sectionBookmarkId = bookmark?.id;
|
|
7703
8401
|
const sectionContext = {
|
|
7704
8402
|
...context,
|
|
7705
8403
|
section: {
|
|
@@ -7712,7 +8410,7 @@ async function renderSection(section, theme, themeName, context, sectionOrdinal,
|
|
|
7712
8410
|
};
|
|
7713
8411
|
if (sectionBookmarkId && isFirstLayoutOfUserSection && sharedLinkId !== void 0) {
|
|
7714
8412
|
elements.push(
|
|
7715
|
-
new
|
|
8413
|
+
new Paragraph9({
|
|
7716
8414
|
children: [new BookmarkStart2(sectionBookmarkId, sharedLinkId)],
|
|
7717
8415
|
spacing: {
|
|
7718
8416
|
before: 0,
|
|
@@ -7737,7 +8435,7 @@ async function renderSection(section, theme, themeName, context, sectionOrdinal,
|
|
|
7737
8435
|
}
|
|
7738
8436
|
if (closeBookmark && sharedLinkId !== void 0) {
|
|
7739
8437
|
elements.push(
|
|
7740
|
-
new
|
|
8438
|
+
new Paragraph9({
|
|
7741
8439
|
children: [new BookmarkEnd2(sharedLinkId)]
|
|
7742
8440
|
})
|
|
7743
8441
|
);
|
|
@@ -7822,14 +8520,17 @@ async function renderComponent(component, theme, themeName, context) {
|
|
|
7822
8520
|
import {
|
|
7823
8521
|
collectFontNamesFromDocx,
|
|
7824
8522
|
validateFontReferences,
|
|
7825
|
-
FontRegistry
|
|
8523
|
+
FontRegistry,
|
|
8524
|
+
documentFontRegistry,
|
|
8525
|
+
themeFontRegistry,
|
|
8526
|
+
mergeFontRegistries
|
|
7826
8527
|
} from "@json-to-office/shared";
|
|
7827
8528
|
import {
|
|
7828
8529
|
loadFileFontSource,
|
|
7829
8530
|
FontDiskCache,
|
|
7830
8531
|
fetchVariableFontSource
|
|
7831
8532
|
} from "@json-to-office/shared/fonts/node";
|
|
7832
|
-
async function resolveDocumentFonts(document, theme, fonts, warnings) {
|
|
8533
|
+
async function resolveDocumentFonts(document, theme, fonts, warnings, forceMaterialize = false) {
|
|
7833
8534
|
const emit = (code, message) => {
|
|
7834
8535
|
if (warnings) {
|
|
7835
8536
|
warnings.push({
|
|
@@ -7846,9 +8547,14 @@ async function resolveDocumentFonts(document, theme, fonts, warnings) {
|
|
|
7846
8547
|
for (const n of collectFontNamesFromDocx(document)) names.add(n);
|
|
7847
8548
|
for (const n of collectFontNamesFromDocx(theme)) names.add(n);
|
|
7848
8549
|
if (names.size === 0) return [];
|
|
8550
|
+
const registryEntries = mergeFontRegistries(
|
|
8551
|
+
themeFontRegistry(theme),
|
|
8552
|
+
documentFontRegistry(document),
|
|
8553
|
+
fonts?.extraEntries
|
|
8554
|
+
);
|
|
7849
8555
|
const validation = validateFontReferences({
|
|
7850
8556
|
referencedNames: names,
|
|
7851
|
-
registeredEntries:
|
|
8557
|
+
registeredEntries: registryEntries
|
|
7852
8558
|
});
|
|
7853
8559
|
if (validation.warnings.length > 0) {
|
|
7854
8560
|
if (fonts?.strict) {
|
|
@@ -7861,9 +8567,11 @@ async function resolveDocumentFonts(document, theme, fonts, warnings) {
|
|
|
7861
8567
|
emit(w.code, w.message);
|
|
7862
8568
|
}
|
|
7863
8569
|
}
|
|
7864
|
-
if (!fonts?.onResolved) return [];
|
|
8570
|
+
if (!fonts?.onResolved && !forceMaterialize) return [];
|
|
7865
8571
|
const registry = new FontRegistry({
|
|
7866
|
-
|
|
8572
|
+
// Spread keeps baseDir/googleFonts/mode/substitution intact for
|
|
8573
|
+
// materializeSource; extraEntries carries the merged registry.
|
|
8574
|
+
opts: { ...fonts, extraEntries: registryEntries },
|
|
7867
8575
|
fileLoader: loadFileFontSource,
|
|
7868
8576
|
variableLoader: fetchVariableFontSource,
|
|
7869
8577
|
diskCache: fonts?.googleFonts?.cacheDir ? new FontDiskCache(fonts.googleFonts.cacheDir) : void 0
|
|
@@ -7874,10 +8582,13 @@ async function resolveDocumentFonts(document, theme, fonts, warnings) {
|
|
|
7874
8582
|
emit("FONT_UNRESOLVED", msg);
|
|
7875
8583
|
}
|
|
7876
8584
|
}
|
|
7877
|
-
fonts
|
|
8585
|
+
fonts?.onResolved?.(resolved);
|
|
7878
8586
|
return resolved;
|
|
7879
8587
|
}
|
|
7880
8588
|
|
|
8589
|
+
// src/core/generator.ts
|
|
8590
|
+
import { toRasterizeFontFaces } from "@json-to-office/shared/fonts/node";
|
|
8591
|
+
|
|
7881
8592
|
// src/utils/packageDocument.ts
|
|
7882
8593
|
import AdmZip2 from "adm-zip";
|
|
7883
8594
|
import { Packer } from "docx";
|
|
@@ -7891,9 +8602,9 @@ function fixFloatingImageIdsInBuffer(buffer) {
|
|
|
7891
8602
|
throw new Error("document.xml not found in DOCX");
|
|
7892
8603
|
}
|
|
7893
8604
|
let idCounter = 1;
|
|
7894
|
-
const documentXml = documentEntry.getData().toString("utf8").replace(
|
|
8605
|
+
const documentXml = documentEntry.getData().toString("utf8").replace(/(<wp:docPr\b[^>]*?\s)id="\d+"/g, (_match, prefix) => {
|
|
7895
8606
|
const newId = idCounter++;
|
|
7896
|
-
return
|
|
8607
|
+
return `${prefix}id="${newId}"`;
|
|
7897
8608
|
});
|
|
7898
8609
|
zip.updateFile(documentEntry, Buffer.from(documentXml, "utf8"));
|
|
7899
8610
|
return zip.toBuffer();
|
|
@@ -8137,7 +8848,15 @@ async function generateDocumentWithCustomThemes(documentIn, customThemes, servic
|
|
|
8137
8848
|
fonts,
|
|
8138
8849
|
warnings
|
|
8139
8850
|
});
|
|
8140
|
-
|
|
8851
|
+
const hasVisual = collectVisualProps(document).length > 0;
|
|
8852
|
+
const resolvedFonts = await resolveDocumentFonts(
|
|
8853
|
+
document,
|
|
8854
|
+
theme,
|
|
8855
|
+
fonts,
|
|
8856
|
+
warnings,
|
|
8857
|
+
hasVisual
|
|
8858
|
+
);
|
|
8859
|
+
const visualFonts = hasVisual ? toRasterizeFontFaces(resolvedFonts, warnings) : [];
|
|
8141
8860
|
const structure = await processDocument(
|
|
8142
8861
|
document,
|
|
8143
8862
|
theme,
|
|
@@ -8148,7 +8867,8 @@ async function generateDocumentWithCustomThemes(documentIn, customThemes, servic
|
|
|
8148
8867
|
const renderedDocument = await renderDocument(structure, layout, {
|
|
8149
8868
|
bypassCache: false,
|
|
8150
8869
|
services,
|
|
8151
|
-
baseDir
|
|
8870
|
+
baseDir,
|
|
8871
|
+
...visualFonts.length > 0 && { visualFonts }
|
|
8152
8872
|
});
|
|
8153
8873
|
return renderedDocument;
|
|
8154
8874
|
}
|
|
@@ -8262,7 +8982,11 @@ async function flattenVisuals(doc, options) {
|
|
|
8262
8982
|
renderBatch: options.rasterizeBatch,
|
|
8263
8983
|
dpi: options.dpi
|
|
8264
8984
|
},
|
|
8265
|
-
{
|
|
8985
|
+
{
|
|
8986
|
+
baseDir: options.baseDir,
|
|
8987
|
+
concurrency: options.concurrency,
|
|
8988
|
+
fonts: options.fonts
|
|
8989
|
+
}
|
|
8266
8990
|
).catch(() => /* @__PURE__ */ new Map());
|
|
8267
8991
|
rasterize = async (request) => {
|
|
8268
8992
|
const hit = preRasterized.get(
|
|
@@ -8283,6 +9007,7 @@ async function flattenVisuals(doc, options) {
|
|
|
8283
9007
|
rasterize,
|
|
8284
9008
|
dpi: options.dpi,
|
|
8285
9009
|
baseDir: options.baseDir,
|
|
9010
|
+
fonts: options.fonts,
|
|
8286
9011
|
limit: createLimiter(
|
|
8287
9012
|
Math.max(1, options.concurrency ?? DEFAULT_CONCURRENCY)
|
|
8288
9013
|
)
|
|
@@ -8296,7 +9021,8 @@ async function rasterizeVisual(obj, ctx) {
|
|
|
8296
9021
|
() => ctx.rasterize({
|
|
8297
9022
|
presentation: buildVisualPresentation(props),
|
|
8298
9023
|
dpi,
|
|
8299
|
-
baseDir: ctx.baseDir
|
|
9024
|
+
baseDir: ctx.baseDir,
|
|
9025
|
+
...ctx.fonts?.length ? { fonts: [...ctx.fonts] } : {}
|
|
8300
9026
|
})
|
|
8301
9027
|
);
|
|
8302
9028
|
const image = {
|
|
@@ -8572,6 +9298,7 @@ async function runExample(example, options = {}) {
|
|
|
8572
9298
|
|
|
8573
9299
|
// src/plugin/createDocumentGenerator.ts
|
|
8574
9300
|
init_themes();
|
|
9301
|
+
import { toRasterizeFontFaces as toRasterizeFontFaces2 } from "@json-to-office/shared/fonts/node";
|
|
8575
9302
|
|
|
8576
9303
|
// src/plugin/version-resolver.ts
|
|
8577
9304
|
import { resolveComponentVersion } from "@json-to-office/shared/plugin";
|
|
@@ -9099,7 +9826,15 @@ function createBuilderImpl(state) {
|
|
|
9099
9826
|
warnings,
|
|
9100
9827
|
preserveSet
|
|
9101
9828
|
} = await expandDocument(document, options);
|
|
9102
|
-
|
|
9829
|
+
const hasVisual = collectVisualProps(modedDoc).length > 0;
|
|
9830
|
+
const resolvedFonts = await resolveDocumentFonts(
|
|
9831
|
+
modedDoc,
|
|
9832
|
+
modedTheme,
|
|
9833
|
+
state.fonts,
|
|
9834
|
+
warnings,
|
|
9835
|
+
hasVisual
|
|
9836
|
+
);
|
|
9837
|
+
const visualFonts = hasVisual ? toRasterizeFontFaces2(resolvedFonts, warnings) : [];
|
|
9103
9838
|
const packageOptions = {
|
|
9104
9839
|
deterministic: options?.deterministic ?? state.deterministic,
|
|
9105
9840
|
generatedAt: options?.generatedAt ?? state.generatedAt
|
|
@@ -9114,7 +9849,8 @@ function createBuilderImpl(state) {
|
|
|
9114
9849
|
const generatedDocument = await renderDocument(structure, layout, {
|
|
9115
9850
|
services: state.services,
|
|
9116
9851
|
bypassCache: !state.enableCache,
|
|
9117
|
-
baseDir: options?.baseDir ?? state.baseDir
|
|
9852
|
+
baseDir: options?.baseDir ?? state.baseDir,
|
|
9853
|
+
...visualFonts.length > 0 && { visualFonts }
|
|
9118
9854
|
});
|
|
9119
9855
|
const preservedDefinition = preserveSet ? {
|
|
9120
9856
|
...modedRoot,
|
|
@@ -9273,6 +10009,7 @@ export {
|
|
|
9273
10009
|
UnknownPreservedComponentError,
|
|
9274
10010
|
cleanComponentProps,
|
|
9275
10011
|
clearComponentCache,
|
|
10012
|
+
componentBypassReason,
|
|
9276
10013
|
corporateTheme,
|
|
9277
10014
|
createComponent,
|
|
9278
10015
|
createDocumentGenerator,
|