@json-to-office/core-docx 0.24.0 → 0.25.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/paragraph.d.ts.map +1 -1
- package/dist/core/content.d.ts +16 -0
- package/dist/core/content.d.ts.map +1 -1
- package/dist/core/generationContext.d.ts +39 -0
- package/dist/core/generationContext.d.ts.map +1 -0
- package/dist/core/generator.d.ts.map +1 -1
- package/dist/index.js +221 -111
- package/dist/index.js.map +1 -1
- package/dist/plugin/createDocumentGenerator.d.ts.map +1 -1
- package/dist/plugin/example/index.js +214 -70
- package/dist/plugin/example/index.js.map +1 -1
- package/dist/styles/themeToDocxAdapter.d.ts.map +1 -1
- package/dist/styles/utils/styleHelpers.d.ts +1 -0
- package/dist/styles/utils/styleHelpers.d.ts.map +1 -1
- package/dist/templates/themes/index.d.ts +152 -0
- package/dist/templates/themes/index.d.ts.map +1 -1
- package/dist/themes/defaults.d.ts +20 -0
- package/dist/themes/defaults.d.ts.map +1 -1
- package/dist/themes/overrides.d.ts +23 -0
- package/dist/themes/overrides.d.ts.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/placeholderProcessor.d.ts.map +1 -1
- package/dist/utils/textParser.d.ts +2 -0
- package/dist/utils/textParser.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1059,7 +1059,8 @@ function resolveFontProperties(theme, fontRef) {
|
|
|
1059
1059
|
alignment: fontDef.alignment,
|
|
1060
1060
|
lineSpacing: fontDef.lineSpacing,
|
|
1061
1061
|
spacing: fontDef.spacing,
|
|
1062
|
-
characterSpacing: fontDef.characterSpacing
|
|
1062
|
+
characterSpacing: fontDef.characterSpacing,
|
|
1063
|
+
scale: fontDef.scale
|
|
1063
1064
|
};
|
|
1064
1065
|
}
|
|
1065
1066
|
function mergeFontAndStyleProperties(fontProps, styleOverrides) {
|
|
@@ -1941,6 +1942,9 @@ import {
|
|
|
1941
1942
|
isVisualComponent
|
|
1942
1943
|
} from "@json-to-office/shared-docx";
|
|
1943
1944
|
|
|
1945
|
+
// src/core/generationContext.ts
|
|
1946
|
+
import { applyExportMode, scopedThemeName } from "@json-to-office/shared";
|
|
1947
|
+
|
|
1944
1948
|
// src/styles/theme-resolver.ts
|
|
1945
1949
|
init_themes();
|
|
1946
1950
|
function resolveBuiltInTheme(themeName, options = {}) {
|
|
@@ -1959,6 +1963,81 @@ function resolveBuiltInTheme(themeName, options = {}) {
|
|
|
1959
1963
|
return getThemeWithFallback(themeName);
|
|
1960
1964
|
}
|
|
1961
1965
|
|
|
1966
|
+
// src/themes/overrides.ts
|
|
1967
|
+
import { createHash } from "crypto";
|
|
1968
|
+
function applyThemeOverrides(theme, overrides) {
|
|
1969
|
+
if (!overrides) return theme;
|
|
1970
|
+
const fonts = { ...theme.fonts };
|
|
1971
|
+
for (const [role, def] of Object.entries(overrides.fonts ?? {})) {
|
|
1972
|
+
const key = role;
|
|
1973
|
+
fonts[key] = { ...theme.fonts[key], ...def };
|
|
1974
|
+
}
|
|
1975
|
+
const styles = { ...theme.styles ?? {} };
|
|
1976
|
+
for (const [name, def] of Object.entries(overrides.styles ?? {})) {
|
|
1977
|
+
styles[name] = { ...styles[name], ...def };
|
|
1978
|
+
}
|
|
1979
|
+
return {
|
|
1980
|
+
...theme,
|
|
1981
|
+
colors: { ...theme.colors, ...overrides.colors ?? {} },
|
|
1982
|
+
fonts,
|
|
1983
|
+
...Object.keys(styles).length > 0 && { styles }
|
|
1984
|
+
};
|
|
1985
|
+
}
|
|
1986
|
+
function themeOverridesDigest(overrides) {
|
|
1987
|
+
return createHash("sha256").update(JSON.stringify(overrides)).digest("hex").slice(0, 8);
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
// src/core/generationContext.ts
|
|
1991
|
+
function defaultNamedThemeLookup(themeName, customThemes, warnings) {
|
|
1992
|
+
if (customThemes) {
|
|
1993
|
+
if (customThemes[themeName]) return customThemes[themeName];
|
|
1994
|
+
const themeNameLower = themeName.toLowerCase();
|
|
1995
|
+
const matchingThemeKey = Object.keys(customThemes).find(
|
|
1996
|
+
(key) => key.toLowerCase() === themeNameLower
|
|
1997
|
+
);
|
|
1998
|
+
if (matchingThemeKey) return customThemes[matchingThemeKey];
|
|
1999
|
+
return resolveBuiltInTheme(themeName, { customThemes, warnings });
|
|
2000
|
+
}
|
|
2001
|
+
return resolveBuiltInTheme(themeName, { warnings });
|
|
2002
|
+
}
|
|
2003
|
+
function resolveThemeContext(documentIn, options = {}) {
|
|
2004
|
+
const { customThemes, fonts, warnings, resolveNamedTheme } = options;
|
|
2005
|
+
if (documentIn.props === null) {
|
|
2006
|
+
throw new Error(
|
|
2007
|
+
"Document `props` is null. Omit it, or provide an object \u2014 a null props cannot carry a theme."
|
|
2008
|
+
);
|
|
2009
|
+
}
|
|
2010
|
+
const document = documentIn.props === void 0 ? { ...documentIn, props: {} } : documentIn;
|
|
2011
|
+
const baseThemeName = document.props.theme || "minimal";
|
|
2012
|
+
let theme = resolveNamedTheme ? resolveNamedTheme(baseThemeName, warnings) : defaultNamedThemeLookup(baseThemeName, customThemes, warnings);
|
|
2013
|
+
const themeOverrides = document.props.themeOverrides;
|
|
2014
|
+
let themeName = baseThemeName;
|
|
2015
|
+
if (themeOverrides) {
|
|
2016
|
+
theme = applyThemeOverrides(theme, themeOverrides);
|
|
2017
|
+
themeName = `${themeName}+ov:${themeOverridesDigest(themeOverrides)}`;
|
|
2018
|
+
}
|
|
2019
|
+
const mode = applyExportMode({ doc: document, theme, fonts });
|
|
2020
|
+
for (const w of mode.warnings) {
|
|
2021
|
+
if (warnings) {
|
|
2022
|
+
warnings.push({
|
|
2023
|
+
component: "fontRegistry",
|
|
2024
|
+
message: w.message,
|
|
2025
|
+
severity: "warning",
|
|
2026
|
+
context: { code: w.code }
|
|
2027
|
+
});
|
|
2028
|
+
} else {
|
|
2029
|
+
console.warn(`[json-to-docx] [${w.code}] ${w.message}`);
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
return {
|
|
2033
|
+
document: mode.doc,
|
|
2034
|
+
theme: mode.theme,
|
|
2035
|
+
// Scope by mode too: substitute rewrites the theme in place, so caches
|
|
2036
|
+
// must not share slots with custom-mode runs keyed on the same name.
|
|
2037
|
+
themeName: scopedThemeName(themeName, fonts?.mode)
|
|
2038
|
+
};
|
|
2039
|
+
}
|
|
2040
|
+
|
|
1962
2041
|
// src/utils/formatters.ts
|
|
1963
2042
|
import { format } from "date-fns";
|
|
1964
2043
|
var formatDate = (date, formatString = "MMMM d, yyyy") => {
|
|
@@ -2955,7 +3034,8 @@ function convertRunProperties(merged, theme, defaultColor, defaultSize) {
|
|
|
2955
3034
|
...merged.underline !== void 0 && merged.underline && { underline: { type: "single" } },
|
|
2956
3035
|
...merged.characterSpacing && {
|
|
2957
3036
|
characterSpacing: merged.characterSpacing.type === "condensed" ? -merged.characterSpacing.value : merged.characterSpacing.value
|
|
2958
|
-
}
|
|
3037
|
+
},
|
|
3038
|
+
...merged.scale && { scale: merged.scale }
|
|
2959
3039
|
};
|
|
2960
3040
|
}
|
|
2961
3041
|
function convertParagraphProperties(merged, styleProps, theme) {
|
|
@@ -3029,7 +3109,8 @@ function createWordStyles(themeNameOrObject = "minimal", language) {
|
|
|
3029
3109
|
bold: normalStyle?.bold,
|
|
3030
3110
|
italic: normalStyle?.italic,
|
|
3031
3111
|
underline: normalStyle?.underline,
|
|
3032
|
-
characterSpacing: normalStyle?.characterSpacing
|
|
3112
|
+
characterSpacing: normalStyle?.characterSpacing,
|
|
3113
|
+
scale: normalStyle?.scale
|
|
3033
3114
|
});
|
|
3034
3115
|
return convertRunProperties(merged, theme, theme.colors.text);
|
|
3035
3116
|
})(),
|
|
@@ -3067,7 +3148,8 @@ function createWordStyles(themeNameOrObject = "minimal", language) {
|
|
|
3067
3148
|
bold: headingStyle.bold,
|
|
3068
3149
|
italic: headingStyle.italic,
|
|
3069
3150
|
underline: headingStyle.underline,
|
|
3070
|
-
characterSpacing: headingStyle.characterSpacing
|
|
3151
|
+
characterSpacing: headingStyle.characterSpacing,
|
|
3152
|
+
scale: headingStyle.scale
|
|
3071
3153
|
});
|
|
3072
3154
|
return convertRunProperties(merged, theme, theme.colors.primary, 20);
|
|
3073
3155
|
})(),
|
|
@@ -3133,7 +3215,8 @@ function createWordStyles(themeNameOrObject = "minimal", language) {
|
|
|
3133
3215
|
bold: headingStyle.bold,
|
|
3134
3216
|
italic: headingStyle.italic,
|
|
3135
3217
|
underline: headingStyle.underline,
|
|
3136
|
-
characterSpacing: headingStyle.characterSpacing
|
|
3218
|
+
characterSpacing: headingStyle.characterSpacing,
|
|
3219
|
+
scale: headingStyle.scale
|
|
3137
3220
|
});
|
|
3138
3221
|
return convertRunProperties(merged, theme, theme.colors.primary, 20);
|
|
3139
3222
|
})(),
|
|
@@ -3200,7 +3283,8 @@ function createWordStyles(themeNameOrObject = "minimal", language) {
|
|
|
3200
3283
|
bold: titleStyle.bold,
|
|
3201
3284
|
italic: titleStyle.italic,
|
|
3202
3285
|
underline: titleStyle.underline,
|
|
3203
|
-
characterSpacing: titleStyle.characterSpacing
|
|
3286
|
+
characterSpacing: titleStyle.characterSpacing,
|
|
3287
|
+
scale: titleStyle.scale
|
|
3204
3288
|
});
|
|
3205
3289
|
return convertRunProperties(merged, theme, theme.colors.primary, 20);
|
|
3206
3290
|
})(),
|
|
@@ -3261,7 +3345,8 @@ function createWordStyles(themeNameOrObject = "minimal", language) {
|
|
|
3261
3345
|
bold: subtitleStyle.bold,
|
|
3262
3346
|
italic: subtitleStyle.italic,
|
|
3263
3347
|
underline: subtitleStyle.underline,
|
|
3264
|
-
characterSpacing: subtitleStyle.characterSpacing
|
|
3348
|
+
characterSpacing: subtitleStyle.characterSpacing,
|
|
3349
|
+
scale: subtitleStyle.scale
|
|
3265
3350
|
});
|
|
3266
3351
|
return convertRunProperties(merged, theme, theme.colors.secondary);
|
|
3267
3352
|
})(),
|
|
@@ -3403,7 +3488,8 @@ function createWordStyles(themeNameOrObject = "minimal", language) {
|
|
|
3403
3488
|
bold: customStyle.bold,
|
|
3404
3489
|
italic: customStyle.italic,
|
|
3405
3490
|
underline: customStyle.underline,
|
|
3406
|
-
characterSpacing: customStyle.characterSpacing
|
|
3491
|
+
characterSpacing: customStyle.characterSpacing,
|
|
3492
|
+
scale: customStyle.scale
|
|
3407
3493
|
});
|
|
3408
3494
|
return convertRunProperties(merged, theme, theme.colors.text);
|
|
3409
3495
|
})(),
|
|
@@ -3511,7 +3597,7 @@ __reExport(cache_exports, cache_star);
|
|
|
3511
3597
|
import * as cache_star from "@json-to-office/shared/cache";
|
|
3512
3598
|
|
|
3513
3599
|
// src/cache/key-generator.ts
|
|
3514
|
-
import { createHash } from "crypto";
|
|
3600
|
+
import { createHash as createHash2 } from "crypto";
|
|
3515
3601
|
var CacheKeyGenerator = class {
|
|
3516
3602
|
version;
|
|
3517
3603
|
constructor(version = "1.0") {
|
|
@@ -3585,7 +3671,7 @@ var CacheKeyGenerator = class {
|
|
|
3585
3671
|
* Create hash
|
|
3586
3672
|
*/
|
|
3587
3673
|
hash(input) {
|
|
3588
|
-
return
|
|
3674
|
+
return createHash2("sha256").update(input).digest("hex").substring(0, 16);
|
|
3589
3675
|
}
|
|
3590
3676
|
};
|
|
3591
3677
|
|
|
@@ -3600,11 +3686,12 @@ function normalizeUnicodeText(text) {
|
|
|
3600
3686
|
// src/utils/placeholderProcessor.ts
|
|
3601
3687
|
import {
|
|
3602
3688
|
TextRun as TextRun2,
|
|
3603
|
-
PageNumber
|
|
3689
|
+
PageNumber,
|
|
3690
|
+
Tab as Tab2
|
|
3604
3691
|
} from "docx";
|
|
3605
3692
|
|
|
3606
3693
|
// src/utils/textParser.ts
|
|
3607
|
-
import { TextRun, ExternalHyperlink, InternalHyperlink } from "docx";
|
|
3694
|
+
import { TextRun, ExternalHyperlink, InternalHyperlink, Tab } from "docx";
|
|
3608
3695
|
function escapeRegExp(s) {
|
|
3609
3696
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3610
3697
|
}
|
|
@@ -3727,28 +3814,49 @@ function createTextRunsWithNewlines(text, baseStyle, options, overrideStyle) {
|
|
|
3727
3814
|
...runStyle.bold !== void 0 && { bold: runStyle.bold },
|
|
3728
3815
|
...runStyle.italics !== void 0 && { italics: runStyle.italics },
|
|
3729
3816
|
...baseStyle.underline && { underline: baseStyle.underline },
|
|
3817
|
+
...baseStyle.scale && { scale: baseStyle.scale },
|
|
3818
|
+
...baseStyle.characterSpacing && {
|
|
3819
|
+
characterSpacing: baseStyle.characterSpacing
|
|
3820
|
+
},
|
|
3730
3821
|
...baseStyle.language && { language: baseStyle.language }
|
|
3731
3822
|
};
|
|
3732
3823
|
const wholeRunNoProof = baseStyle.noProof === true;
|
|
3733
3824
|
const wordsForLine = wholeRunNoProof ? void 0 : options.noProofWords;
|
|
3734
3825
|
let firstSegment = true;
|
|
3735
|
-
const lineRuns =
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
}
|
|
3745
|
-
|
|
3746
|
-
});
|
|
3826
|
+
const lineRuns = [];
|
|
3827
|
+
const tabSegments = line.split(" ");
|
|
3828
|
+
tabSegments.forEach((tabSegment, tabIndex) => {
|
|
3829
|
+
if (tabIndex > 0) {
|
|
3830
|
+
lineRuns.push(
|
|
3831
|
+
new TextRun({
|
|
3832
|
+
children: [new Tab()],
|
|
3833
|
+
...commonProps,
|
|
3834
|
+
...needsLineBreak && firstSegment && { break: 1 }
|
|
3835
|
+
})
|
|
3836
|
+
);
|
|
3747
3837
|
firstSegment = false;
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3838
|
+
}
|
|
3839
|
+
if (!tabSegment && tabSegments.length > 1) return;
|
|
3840
|
+
lineRuns.push(
|
|
3841
|
+
...splitByNoProofWords(
|
|
3842
|
+
tabSegment,
|
|
3843
|
+
(segment, matched) => {
|
|
3844
|
+
const segNoProof = matched || wholeRunNoProof;
|
|
3845
|
+
const run = new TextRun({
|
|
3846
|
+
text: segment,
|
|
3847
|
+
...commonProps,
|
|
3848
|
+
...(matched || baseStyle.noProof !== void 0) && {
|
|
3849
|
+
noProof: segNoProof
|
|
3850
|
+
},
|
|
3851
|
+
...needsLineBreak && firstSegment && { break: 1 }
|
|
3852
|
+
});
|
|
3853
|
+
firstSegment = false;
|
|
3854
|
+
return run;
|
|
3855
|
+
},
|
|
3856
|
+
wordsForLine
|
|
3857
|
+
)
|
|
3858
|
+
);
|
|
3859
|
+
});
|
|
3752
3860
|
runs.push(...lineRuns);
|
|
3753
3861
|
}
|
|
3754
3862
|
}
|
|
@@ -3983,27 +4091,48 @@ function createTextRunsWithNewlines2(text, baseStyle, noProofWords) {
|
|
|
3983
4091
|
bold: baseStyle.bold,
|
|
3984
4092
|
italics: baseStyle.italics,
|
|
3985
4093
|
underline: baseStyle.underline,
|
|
4094
|
+
...baseStyle.scale && { scale: baseStyle.scale },
|
|
4095
|
+
...baseStyle.characterSpacing && {
|
|
4096
|
+
characterSpacing: baseStyle.characterSpacing
|
|
4097
|
+
},
|
|
3986
4098
|
...baseStyle.language && { language: baseStyle.language }
|
|
3987
4099
|
};
|
|
3988
4100
|
const wholeRunNoProof = baseStyle.noProof === true;
|
|
3989
4101
|
const wordsForLine = wholeRunNoProof ? void 0 : noProofWords;
|
|
3990
4102
|
let firstSegment = true;
|
|
3991
|
-
const lineRuns =
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4103
|
+
const lineRuns = [];
|
|
4104
|
+
const tabSegments = line.split(" ");
|
|
4105
|
+
tabSegments.forEach((tabSegment, tabIndex) => {
|
|
4106
|
+
if (tabIndex > 0) {
|
|
4107
|
+
lineRuns.push(
|
|
4108
|
+
new TextRun2({
|
|
4109
|
+
children: [new Tab2()],
|
|
4110
|
+
...commonProps,
|
|
4111
|
+
break: needsLineBreak && firstSegment ? 1 : void 0
|
|
4112
|
+
})
|
|
4113
|
+
);
|
|
4002
4114
|
firstSegment = false;
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4115
|
+
}
|
|
4116
|
+
if (!tabSegment && tabSegments.length > 1) return;
|
|
4117
|
+
lineRuns.push(
|
|
4118
|
+
...splitByNoProofWords(
|
|
4119
|
+
tabSegment,
|
|
4120
|
+
(segment, matched) => {
|
|
4121
|
+
const run = new TextRun2({
|
|
4122
|
+
text: segment,
|
|
4123
|
+
...commonProps,
|
|
4124
|
+
...(matched || baseStyle.noProof !== void 0) && {
|
|
4125
|
+
noProof: matched || wholeRunNoProof
|
|
4126
|
+
},
|
|
4127
|
+
break: needsLineBreak && firstSegment ? 1 : void 0
|
|
4128
|
+
});
|
|
4129
|
+
firstSegment = false;
|
|
4130
|
+
return run;
|
|
4131
|
+
},
|
|
4132
|
+
wordsForLine
|
|
4133
|
+
)
|
|
4134
|
+
);
|
|
4135
|
+
});
|
|
4007
4136
|
runs.push(...lineRuns);
|
|
4008
4137
|
}
|
|
4009
4138
|
}
|
|
@@ -4158,12 +4287,12 @@ function componentHasRevision(component) {
|
|
|
4158
4287
|
}
|
|
4159
4288
|
|
|
4160
4289
|
// src/core/cached-render.ts
|
|
4161
|
-
import { createHash as
|
|
4290
|
+
import { createHash as createHash3 } from "crypto";
|
|
4162
4291
|
var componentCache = null;
|
|
4163
4292
|
var cacheKeyGen = null;
|
|
4164
4293
|
function createThemeHash(theme) {
|
|
4165
4294
|
const themeString = JSON.stringify(theme);
|
|
4166
|
-
return
|
|
4295
|
+
return createHash3("sha256").update(themeString).digest("hex").substring(0, 8);
|
|
4167
4296
|
}
|
|
4168
4297
|
function initializeComponentCache(cache) {
|
|
4169
4298
|
if (cache) {
|
|
@@ -4431,6 +4560,12 @@ function createText(content, theme, themeName, options = {}) {
|
|
|
4431
4560
|
...options.underline !== void 0 && {
|
|
4432
4561
|
underline: options.underline ? { type: "single" } : void 0
|
|
4433
4562
|
},
|
|
4563
|
+
// Character width scaling in percent (w:w)
|
|
4564
|
+
...options.scale && { scale: options.scale },
|
|
4565
|
+
// Letter tracking (w:spacing, twentieths of a point; negative = condensed)
|
|
4566
|
+
...options.characterSpacing && {
|
|
4567
|
+
characterSpacing: options.characterSpacing.type === "condensed" ? -options.characterSpacing.value : options.characterSpacing.value
|
|
4568
|
+
},
|
|
4434
4569
|
// Proofing: per-run language and/or no-proof. Omitting language lets the
|
|
4435
4570
|
// run inherit the document default set on docDefaults.
|
|
4436
4571
|
...options.language && { language: { value: options.language } },
|
|
@@ -4455,7 +4590,7 @@ function createText(content, theme, themeName, options = {}) {
|
|
|
4455
4590
|
}
|
|
4456
4591
|
} else {
|
|
4457
4592
|
const textRuns = parseTextWithDecorators(normalizedContent, baseTextStyle, {
|
|
4458
|
-
boldColor: options.boldColor,
|
|
4593
|
+
boldColor: options.boldColor ? resolveColor(options.boldColor, theme) : void 0,
|
|
4459
4594
|
enableHyperlinks: true,
|
|
4460
4595
|
noProofWords: resolveNoProofWords(theme, options.noProofWords)
|
|
4461
4596
|
});
|
|
@@ -4487,7 +4622,9 @@ function createText(content, theme, themeName, options = {}) {
|
|
|
4487
4622
|
},
|
|
4488
4623
|
...frameOptions && { frame: frameOptions },
|
|
4489
4624
|
...options.keepNext !== void 0 && { keepNext: options.keepNext },
|
|
4490
|
-
...options.keepLines !== void 0 && { keepLines: options.keepLines }
|
|
4625
|
+
...options.keepLines !== void 0 && { keepLines: options.keepLines },
|
|
4626
|
+
...options.indent && { indent: options.indent },
|
|
4627
|
+
...options.tabStops && options.tabStops.length > 0 && { tabStops: options.tabStops }
|
|
4491
4628
|
});
|
|
4492
4629
|
}
|
|
4493
4630
|
function mapFrameOptions(floating, theme, themeName) {
|
|
@@ -4593,6 +4730,12 @@ function createHeading(text, level, theme, _themeName, options = {}) {
|
|
|
4593
4730
|
...options.underline !== void 0 && {
|
|
4594
4731
|
underline: options.underline ? { type: "single" } : void 0
|
|
4595
4732
|
},
|
|
4733
|
+
// Character width scaling in percent (w:w)
|
|
4734
|
+
...options.scale && { scale: options.scale },
|
|
4735
|
+
// Letter tracking (w:spacing, twentieths of a point; negative = condensed)
|
|
4736
|
+
...options.characterSpacing && {
|
|
4737
|
+
characterSpacing: options.characterSpacing.type === "condensed" ? -options.characterSpacing.value : options.characterSpacing.value
|
|
4738
|
+
},
|
|
4596
4739
|
// Proofing: per-run language and/or no-proof (see createText).
|
|
4597
4740
|
...options.language && { language: { value: options.language } },
|
|
4598
4741
|
...options.noProof !== void 0 && { noProof: options.noProof }
|
|
@@ -4633,7 +4776,7 @@ function createHeading(text, level, theme, _themeName, options = {}) {
|
|
|
4633
4776
|
const headingTextChildren = [];
|
|
4634
4777
|
if (hasDecorators) {
|
|
4635
4778
|
const textRuns = parseTextWithDecorators(normalizedText, baseTextStyle, {
|
|
4636
|
-
boldColor: options.boldColor,
|
|
4779
|
+
boldColor: options.boldColor ? resolveColor(options.boldColor, theme) : void 0,
|
|
4637
4780
|
enableHyperlinks: true,
|
|
4638
4781
|
noProofWords: headingNoProofWords
|
|
4639
4782
|
});
|
|
@@ -4650,7 +4793,7 @@ function createHeading(text, level, theme, _themeName, options = {}) {
|
|
|
4650
4793
|
} else {
|
|
4651
4794
|
if (hasDecorators) {
|
|
4652
4795
|
const textRuns = parseTextWithDecorators(normalizedText, baseTextStyle, {
|
|
4653
|
-
boldColor: options.boldColor,
|
|
4796
|
+
boldColor: options.boldColor ? resolveColor(options.boldColor, theme) : void 0,
|
|
4654
4797
|
enableHyperlinks: true,
|
|
4655
4798
|
noProofWords: headingNoProofWords
|
|
4656
4799
|
});
|
|
@@ -4666,7 +4809,8 @@ function createHeading(text, level, theme, _themeName, options = {}) {
|
|
|
4666
4809
|
// Only override spacing if explicitly provided
|
|
4667
4810
|
spacing: hasExplicitSpacing ? spacing : void 0,
|
|
4668
4811
|
...options.keepNext !== void 0 && { keepNext: options.keepNext },
|
|
4669
|
-
...options.keepLines !== void 0 && { keepLines: options.keepLines }
|
|
4812
|
+
...options.keepLines !== void 0 && { keepLines: options.keepLines },
|
|
4813
|
+
...options.indent && { indent: options.indent }
|
|
4670
4814
|
});
|
|
4671
4815
|
}
|
|
4672
4816
|
async function createImage(path4, theme, themeName, options = {}) {
|
|
@@ -5658,6 +5802,8 @@ function renderHeadingComponent(component, theme, themeName) {
|
|
|
5658
5802
|
fontWeight: config.font?.fontWeight,
|
|
5659
5803
|
italic: config.font?.italic,
|
|
5660
5804
|
underline: config.font?.underline,
|
|
5805
|
+
scale: config.font?.scale,
|
|
5806
|
+
characterSpacing: config.font?.characterSpacing,
|
|
5661
5807
|
// Proofing: local language override + no-proof toggle + known-words list
|
|
5662
5808
|
language: config.language,
|
|
5663
5809
|
noProof: config.noProof,
|
|
@@ -5665,6 +5811,8 @@ function renderHeadingComponent(component, theme, themeName) {
|
|
|
5665
5811
|
// Pagination control
|
|
5666
5812
|
keepNext: config.keepNext,
|
|
5667
5813
|
keepLines: config.keepLines,
|
|
5814
|
+
// Paragraph indentation (w:ind) in twips
|
|
5815
|
+
indent: config.indent,
|
|
5668
5816
|
// Bookmark ID for internal linking
|
|
5669
5817
|
bookmarkId,
|
|
5670
5818
|
// Tracked-change segments (rendered as native Word revisions)
|
|
@@ -5945,6 +6093,8 @@ function renderParagraphComponent(component, theme, themeName) {
|
|
|
5945
6093
|
fontWeight: resolvedConfig.font?.fontWeight,
|
|
5946
6094
|
italic: resolvedConfig.font?.italic,
|
|
5947
6095
|
underline: resolvedConfig.font?.underline,
|
|
6096
|
+
scale: resolvedConfig.font?.scale,
|
|
6097
|
+
characterSpacing: resolvedConfig.font?.characterSpacing,
|
|
5948
6098
|
// Proofing: local language override + no-proof toggle + known-words list
|
|
5949
6099
|
language: resolvedConfig.language,
|
|
5950
6100
|
noProof: resolvedConfig.noProof,
|
|
@@ -5957,6 +6107,10 @@ function renderParagraphComponent(component, theme, themeName) {
|
|
|
5957
6107
|
keepNext: resolvedConfig.keepNext,
|
|
5958
6108
|
// Pass keepLines property
|
|
5959
6109
|
keepLines: resolvedConfig.keepLines,
|
|
6110
|
+
// Paragraph indentation (w:ind) in twips
|
|
6111
|
+
indent: resolvedConfig.indent,
|
|
6112
|
+
// Tab stops (w:tabs); \t characters in text jump to these positions
|
|
6113
|
+
tabStops: resolvedConfig.tabStops,
|
|
5960
6114
|
// Pass bookmark ID for internal linking
|
|
5961
6115
|
bookmarkId: resolvedConfig.id,
|
|
5962
6116
|
// Tracked-change segments (rendered as native Word revisions)
|
|
@@ -7505,9 +7659,6 @@ async function resolveDocumentFonts(document, theme, fonts, warnings) {
|
|
|
7505
7659
|
return resolved;
|
|
7506
7660
|
}
|
|
7507
7661
|
|
|
7508
|
-
// src/core/generator.ts
|
|
7509
|
-
import { applyExportMode, scopedThemeName } from "@json-to-office/shared";
|
|
7510
|
-
|
|
7511
7662
|
// src/utils/packageDocument.ts
|
|
7512
7663
|
import AdmZip2 from "adm-zip";
|
|
7513
7664
|
import { Packer } from "docx";
|
|
@@ -7761,42 +7912,11 @@ async function generateFromConfig(props, components, options) {
|
|
|
7761
7912
|
return await generateDocument(reportComponent, options);
|
|
7762
7913
|
}
|
|
7763
7914
|
async function generateDocumentWithCustomThemes(documentIn, customThemes, services, fonts, warnings, generationDate) {
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
theme = customThemes[themeName];
|
|
7770
|
-
} else {
|
|
7771
|
-
const themeNameLower = themeName.toLowerCase();
|
|
7772
|
-
const matchingThemeKey = Object.keys(customThemes).find(
|
|
7773
|
-
(key) => key.toLowerCase() === themeNameLower
|
|
7774
|
-
);
|
|
7775
|
-
if (matchingThemeKey) {
|
|
7776
|
-
theme = customThemes[matchingThemeKey];
|
|
7777
|
-
} else {
|
|
7778
|
-
theme = resolveBuiltInTheme(themeName, { customThemes, warnings });
|
|
7779
|
-
}
|
|
7780
|
-
}
|
|
7781
|
-
} else {
|
|
7782
|
-
theme = resolveBuiltInTheme(themeName, { warnings });
|
|
7783
|
-
}
|
|
7784
|
-
const mode = applyExportMode({ doc: document, theme, fonts });
|
|
7785
|
-
document = mode.doc;
|
|
7786
|
-
theme = mode.theme;
|
|
7787
|
-
themeName = scopedThemeName(themeName, fonts?.mode);
|
|
7788
|
-
for (const w of mode.warnings) {
|
|
7789
|
-
if (warnings) {
|
|
7790
|
-
warnings.push({
|
|
7791
|
-
component: "fontRegistry",
|
|
7792
|
-
message: w.message,
|
|
7793
|
-
severity: "warning",
|
|
7794
|
-
context: { code: w.code }
|
|
7795
|
-
});
|
|
7796
|
-
} else {
|
|
7797
|
-
console.warn(`[json-to-docx] [${w.code}] ${w.message}`);
|
|
7798
|
-
}
|
|
7799
|
-
}
|
|
7915
|
+
const { document, theme, themeName } = resolveThemeContext(documentIn, {
|
|
7916
|
+
customThemes,
|
|
7917
|
+
fonts,
|
|
7918
|
+
warnings
|
|
7919
|
+
});
|
|
7800
7920
|
await resolveDocumentFonts(document, theme, fonts, warnings);
|
|
7801
7921
|
const structure = await processDocument(
|
|
7802
7922
|
document,
|
|
@@ -8212,9 +8332,6 @@ async function runExample(example, options = {}) {
|
|
|
8212
8332
|
}
|
|
8213
8333
|
}
|
|
8214
8334
|
|
|
8215
|
-
// src/plugin/createDocumentGenerator.ts
|
|
8216
|
-
import { applyExportMode as applyExportMode2, scopedThemeName as scopedThemeName2 } from "@json-to-office/shared";
|
|
8217
|
-
|
|
8218
8335
|
// src/plugin/version-resolver.ts
|
|
8219
8336
|
import { resolveComponentVersion } from "@json-to-office/shared/plugin";
|
|
8220
8337
|
|
|
@@ -8678,32 +8795,25 @@ function createBuilderImpl(state) {
|
|
|
8678
8795
|
}
|
|
8679
8796
|
};
|
|
8680
8797
|
const warnings = [];
|
|
8681
|
-
const
|
|
8682
|
-
|
|
8683
|
-
|
|
8684
|
-
|
|
8685
|
-
|
|
8686
|
-
|
|
8798
|
+
const {
|
|
8799
|
+
document: modedRoot,
|
|
8800
|
+
theme: modedTheme,
|
|
8801
|
+
themeName
|
|
8802
|
+
} = resolveThemeContext(internalDocument, {
|
|
8803
|
+
customThemes: state.customThemes,
|
|
8804
|
+
fonts: state.fonts,
|
|
8805
|
+
warnings,
|
|
8806
|
+
resolveNamedTheme: resolveDocumentTheme
|
|
8687
8807
|
});
|
|
8688
|
-
const modedTheme = mode.theme;
|
|
8689
|
-
const themeName = scopedThemeName2(baseThemeName, state.fonts?.mode);
|
|
8690
|
-
for (const w of mode.warnings) {
|
|
8691
|
-
warnings.push({
|
|
8692
|
-
component: "fontRegistry",
|
|
8693
|
-
message: w.message,
|
|
8694
|
-
severity: "warning",
|
|
8695
|
-
context: { code: w.code }
|
|
8696
|
-
});
|
|
8697
|
-
}
|
|
8698
8808
|
const processed = await processDocumentComponents(
|
|
8699
|
-
|
|
8809
|
+
modedRoot.children || [],
|
|
8700
8810
|
preserveSet,
|
|
8701
8811
|
warnings,
|
|
8702
8812
|
modedTheme,
|
|
8703
8813
|
validateEmitted
|
|
8704
8814
|
);
|
|
8705
8815
|
const processedDocument = {
|
|
8706
|
-
...
|
|
8816
|
+
...modedRoot,
|
|
8707
8817
|
children: processed.standard
|
|
8708
8818
|
};
|
|
8709
8819
|
const [modedDoc] = normalizeDocument(processedDocument);
|
|
@@ -8724,7 +8834,7 @@ function createBuilderImpl(state) {
|
|
|
8724
8834
|
bypassCache: !state.enableCache
|
|
8725
8835
|
});
|
|
8726
8836
|
const preservedDefinition = preserveSet ? {
|
|
8727
|
-
...
|
|
8837
|
+
...modedRoot,
|
|
8728
8838
|
children: processed.preserved
|
|
8729
8839
|
} : void 0;
|
|
8730
8840
|
return {
|