@json-to-office/core-docx 0.7.0 → 0.9.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/columns.d.ts.map +1 -1
- package/dist/components/heading.d.ts.map +1 -1
- package/dist/components/image.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/statistic.d.ts +1 -1
- package/dist/components/statistic.d.ts.map +1 -1
- package/dist/core/content.d.ts +7 -0
- package/dist/core/content.d.ts.map +1 -1
- package/dist/core/fontResolution.d.ts +15 -0
- package/dist/core/fontResolution.d.ts.map +1 -0
- package/dist/core/generator.d.ts +11 -3
- package/dist/core/generator.d.ts.map +1 -1
- package/dist/core/structure.d.ts.map +1 -1
- package/dist/index.js +411 -192
- package/dist/index.js.map +1 -1
- package/dist/plugin/createDocumentGenerator.d.ts +3 -1
- package/dist/plugin/createDocumentGenerator.d.ts.map +1 -1
- package/dist/plugin/example/index.js +374 -176
- package/dist/plugin/example/index.js.map +1 -1
- package/dist/styles/utils/componentDefaults.d.ts +1 -6
- package/dist/styles/utils/componentDefaults.d.ts.map +1 -1
- package/dist/styles/utils/resolveComponentTree.d.ts +19 -0
- package/dist/styles/utils/resolveComponentTree.d.ts.map +1 -0
- package/dist/templates/themes/index.d.ts +84 -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/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -5
|
@@ -1813,6 +1813,67 @@ import { Packer as Packer2 } from "docx";
|
|
|
1813
1813
|
// src/plugin/createDocumentGenerator.ts
|
|
1814
1814
|
init_styles();
|
|
1815
1815
|
import { Packer } from "docx";
|
|
1816
|
+
import { applyExportMode, scopedThemeName } from "@json-to-office/shared";
|
|
1817
|
+
|
|
1818
|
+
// src/core/fontResolution.ts
|
|
1819
|
+
import {
|
|
1820
|
+
collectFontNamesFromDocx,
|
|
1821
|
+
validateFontReferences,
|
|
1822
|
+
FontRegistry
|
|
1823
|
+
} from "@json-to-office/shared";
|
|
1824
|
+
import {
|
|
1825
|
+
loadFileFontSource,
|
|
1826
|
+
FontDiskCache,
|
|
1827
|
+
fetchVariableFontSource
|
|
1828
|
+
} from "@json-to-office/shared/fonts/node";
|
|
1829
|
+
async function resolveDocumentFonts(document, theme, fonts, warnings) {
|
|
1830
|
+
const emit = (code, message) => {
|
|
1831
|
+
if (warnings) {
|
|
1832
|
+
warnings.push({
|
|
1833
|
+
component: "fontRegistry",
|
|
1834
|
+
message,
|
|
1835
|
+
severity: "warning",
|
|
1836
|
+
context: { code }
|
|
1837
|
+
});
|
|
1838
|
+
} else {
|
|
1839
|
+
console.warn(`[json-to-docx] ${code}: ${message}`);
|
|
1840
|
+
}
|
|
1841
|
+
};
|
|
1842
|
+
const names = /* @__PURE__ */ new Set();
|
|
1843
|
+
for (const n of collectFontNamesFromDocx(document)) names.add(n);
|
|
1844
|
+
for (const n of collectFontNamesFromDocx(theme)) names.add(n);
|
|
1845
|
+
if (names.size === 0) return [];
|
|
1846
|
+
const validation = validateFontReferences({
|
|
1847
|
+
referencedNames: names,
|
|
1848
|
+
registeredEntries: fonts?.extraEntries
|
|
1849
|
+
});
|
|
1850
|
+
if (validation.warnings.length > 0) {
|
|
1851
|
+
if (fonts?.strict) {
|
|
1852
|
+
throw new Error(
|
|
1853
|
+
`Unresolved font references (strict mode):
|
|
1854
|
+
` + validation.warnings.map((w) => ` - ${w.message}`).join("\n")
|
|
1855
|
+
);
|
|
1856
|
+
}
|
|
1857
|
+
for (const w of validation.warnings) {
|
|
1858
|
+
emit(w.code, w.message);
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
if (!fonts?.onResolved) return [];
|
|
1862
|
+
const registry = new FontRegistry({
|
|
1863
|
+
opts: fonts,
|
|
1864
|
+
fileLoader: loadFileFontSource,
|
|
1865
|
+
variableLoader: fetchVariableFontSource,
|
|
1866
|
+
diskCache: fonts?.googleFonts?.cacheDir ? new FontDiskCache(fonts.googleFonts.cacheDir) : void 0
|
|
1867
|
+
});
|
|
1868
|
+
const resolved = await registry.resolveMany(names);
|
|
1869
|
+
for (const r of resolved) {
|
|
1870
|
+
for (const msg of r.warnings) {
|
|
1871
|
+
emit("FONT_UNRESOLVED", msg);
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
fonts.onResolved(resolved);
|
|
1875
|
+
return resolved;
|
|
1876
|
+
}
|
|
1816
1877
|
|
|
1817
1878
|
// src/plugin/version-resolver.ts
|
|
1818
1879
|
import { resolveComponentVersion } from "@json-to-office/shared/plugin";
|
|
@@ -1969,24 +2030,175 @@ var formatDate = (date, formatString = "MMMM d, yyyy") => {
|
|
|
1969
2030
|
return format(date, formatString);
|
|
1970
2031
|
};
|
|
1971
2032
|
|
|
2033
|
+
// src/styles/utils/componentDefaults.ts
|
|
2034
|
+
import { mergeWithDefaults } from "@json-to-office/shared";
|
|
2035
|
+
import { mergeWithDefaults as mergeWithDefaults2 } from "@json-to-office/shared";
|
|
2036
|
+
function getComponentDefaults(theme) {
|
|
2037
|
+
return theme.componentDefaults || {};
|
|
2038
|
+
}
|
|
2039
|
+
function getHeadingDefaults(theme) {
|
|
2040
|
+
const defaults = getComponentDefaults(theme);
|
|
2041
|
+
return defaults?.heading || {};
|
|
2042
|
+
}
|
|
2043
|
+
function getHeadingDefaultsForLevel(theme, level) {
|
|
2044
|
+
const defaults = {};
|
|
2045
|
+
if (theme.styles) {
|
|
2046
|
+
const styleKey = `heading${level}`;
|
|
2047
|
+
const headingStyle = theme.styles[styleKey];
|
|
2048
|
+
if (headingStyle?.alignment) {
|
|
2049
|
+
defaults.alignment = headingStyle.alignment;
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
return defaults;
|
|
2053
|
+
}
|
|
2054
|
+
function getTextDefaults(theme) {
|
|
2055
|
+
const defaults = getComponentDefaults(theme);
|
|
2056
|
+
return defaults?.paragraph || {};
|
|
2057
|
+
}
|
|
2058
|
+
function getImageDefaults(theme) {
|
|
2059
|
+
const defaults = getComponentDefaults(theme);
|
|
2060
|
+
return defaults?.image || {};
|
|
2061
|
+
}
|
|
2062
|
+
function getStatisticDefaults(theme) {
|
|
2063
|
+
const defaults = getComponentDefaults(theme);
|
|
2064
|
+
return defaults?.statistic || {};
|
|
2065
|
+
}
|
|
2066
|
+
function getTableDefaults(theme) {
|
|
2067
|
+
const defaults = getComponentDefaults(theme);
|
|
2068
|
+
return defaults?.table || {};
|
|
2069
|
+
}
|
|
2070
|
+
function getSectionDefaults(theme) {
|
|
2071
|
+
const defaults = getComponentDefaults(theme);
|
|
2072
|
+
return defaults?.section || {};
|
|
2073
|
+
}
|
|
2074
|
+
function getColumnsDefaults(theme) {
|
|
2075
|
+
const defaults = getComponentDefaults(theme);
|
|
2076
|
+
return defaults?.columns || {};
|
|
2077
|
+
}
|
|
2078
|
+
function getListDefaults(theme) {
|
|
2079
|
+
const defaults = getComponentDefaults(theme);
|
|
2080
|
+
return defaults?.list || {};
|
|
2081
|
+
}
|
|
2082
|
+
function resolveHeadingProps(props, theme) {
|
|
2083
|
+
const defaults = getHeadingDefaults(theme);
|
|
2084
|
+
return mergeWithDefaults(props, defaults);
|
|
2085
|
+
}
|
|
2086
|
+
function resolveParagraphProps(props, theme) {
|
|
2087
|
+
const defaults = getTextDefaults(theme);
|
|
2088
|
+
return mergeWithDefaults(props, defaults);
|
|
2089
|
+
}
|
|
2090
|
+
function resolveImageProps(props, theme) {
|
|
2091
|
+
const defaults = getImageDefaults(theme);
|
|
2092
|
+
return mergeWithDefaults(props, defaults);
|
|
2093
|
+
}
|
|
2094
|
+
function resolveStatisticProps(props, theme) {
|
|
2095
|
+
const defaults = getStatisticDefaults(theme);
|
|
2096
|
+
return mergeWithDefaults(props, defaults);
|
|
2097
|
+
}
|
|
2098
|
+
function resolveTableProps(props, theme) {
|
|
2099
|
+
const defaults = getTableDefaults(theme);
|
|
2100
|
+
return mergeWithDefaults(props, defaults);
|
|
2101
|
+
}
|
|
2102
|
+
function resolveSectionProps(props, theme) {
|
|
2103
|
+
const defaults = getSectionDefaults(theme);
|
|
2104
|
+
return mergeWithDefaults(props, defaults);
|
|
2105
|
+
}
|
|
2106
|
+
function resolveColumnsProps(props, theme) {
|
|
2107
|
+
const defaults = getColumnsDefaults(theme);
|
|
2108
|
+
return mergeWithDefaults(props, defaults);
|
|
2109
|
+
}
|
|
2110
|
+
function resolveListProps(props, theme) {
|
|
2111
|
+
const defaults = getListDefaults(theme);
|
|
2112
|
+
return mergeWithDefaults(props, defaults);
|
|
2113
|
+
}
|
|
2114
|
+
function resolveHighchartsProps(props, _theme) {
|
|
2115
|
+
return props;
|
|
2116
|
+
}
|
|
2117
|
+
function getCustomComponentDefaults(theme, componentName) {
|
|
2118
|
+
const defaults = getComponentDefaults(theme);
|
|
2119
|
+
return defaults?.[componentName] || {};
|
|
2120
|
+
}
|
|
2121
|
+
function resolveCustomComponentProps(props, theme, componentName) {
|
|
2122
|
+
const defaults = getCustomComponentDefaults(theme, componentName);
|
|
2123
|
+
return mergeWithDefaults(props, defaults);
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
// src/styles/utils/resolveComponentTree.ts
|
|
2127
|
+
function resolveHeadingWithLevelDefaults(props, theme) {
|
|
2128
|
+
const resolved = resolveHeadingProps(props, theme);
|
|
2129
|
+
const level = resolved.level || 1;
|
|
2130
|
+
const levelDefaults = getHeadingDefaultsForLevel(theme, level);
|
|
2131
|
+
return {
|
|
2132
|
+
...resolved,
|
|
2133
|
+
// Only apply level-specific defaults if no explicit alignment in original props
|
|
2134
|
+
...props.alignment ? {} : levelDefaults
|
|
2135
|
+
};
|
|
2136
|
+
}
|
|
2137
|
+
var RESOLVER_MAP = {
|
|
2138
|
+
heading: resolveHeadingWithLevelDefaults,
|
|
2139
|
+
paragraph: resolveParagraphProps,
|
|
2140
|
+
image: resolveImageProps,
|
|
2141
|
+
statistic: resolveStatisticProps,
|
|
2142
|
+
table: resolveTableProps,
|
|
2143
|
+
section: resolveSectionProps,
|
|
2144
|
+
columns: resolveColumnsProps,
|
|
2145
|
+
list: resolveListProps,
|
|
2146
|
+
highcharts: resolveHighchartsProps
|
|
2147
|
+
};
|
|
2148
|
+
function resolveComponentDefaults(component, theme) {
|
|
2149
|
+
if (!component.props) return component;
|
|
2150
|
+
const resolver = RESOLVER_MAP[component.name];
|
|
2151
|
+
const resolvedProps = resolver ? resolver(component.props, theme) : resolveCustomComponentProps(
|
|
2152
|
+
component.props,
|
|
2153
|
+
theme,
|
|
2154
|
+
component.name
|
|
2155
|
+
);
|
|
2156
|
+
return { ...component, props: resolvedProps };
|
|
2157
|
+
}
|
|
2158
|
+
function resolveComponentTree(components, theme) {
|
|
2159
|
+
return components.map((component) => {
|
|
2160
|
+
const resolved = resolveComponentDefaults(component, theme);
|
|
2161
|
+
const children = resolved.children;
|
|
2162
|
+
if (children && children.length > 0) {
|
|
2163
|
+
return {
|
|
2164
|
+
...resolved,
|
|
2165
|
+
children: resolveComponentTree(children, theme)
|
|
2166
|
+
};
|
|
2167
|
+
}
|
|
2168
|
+
return resolved;
|
|
2169
|
+
});
|
|
2170
|
+
}
|
|
2171
|
+
|
|
1972
2172
|
// src/core/structure.ts
|
|
1973
2173
|
async function processDocument(document, theme, themeName) {
|
|
1974
2174
|
const metadata = createDocumentMetadata(document.props);
|
|
2175
|
+
const docDefaults = document.props.componentDefaults;
|
|
2176
|
+
const effectiveTheme = docDefaults ? {
|
|
2177
|
+
...theme,
|
|
2178
|
+
componentDefaults: mergeWithDefaults2(
|
|
2179
|
+
docDefaults,
|
|
2180
|
+
theme.componentDefaults || {}
|
|
2181
|
+
)
|
|
2182
|
+
} : theme;
|
|
1975
2183
|
const context = createRenderContext(
|
|
1976
2184
|
{
|
|
1977
2185
|
metadata,
|
|
1978
2186
|
sections: [],
|
|
1979
|
-
theme,
|
|
2187
|
+
theme: effectiveTheme,
|
|
1980
2188
|
themeName
|
|
1981
2189
|
},
|
|
1982
|
-
|
|
2190
|
+
effectiveTheme,
|
|
1983
2191
|
themeName
|
|
1984
2192
|
);
|
|
1985
|
-
const
|
|
2193
|
+
const resolvedChildren = resolveComponentTree(
|
|
2194
|
+
document.children || [],
|
|
2195
|
+
effectiveTheme
|
|
2196
|
+
);
|
|
2197
|
+
const sections = await extractSections(resolvedChildren, context);
|
|
1986
2198
|
return {
|
|
1987
2199
|
metadata,
|
|
1988
2200
|
sections,
|
|
1989
|
-
theme,
|
|
2201
|
+
theme: effectiveTheme,
|
|
1990
2202
|
themeName
|
|
1991
2203
|
};
|
|
1992
2204
|
}
|
|
@@ -2016,19 +2228,24 @@ async function extractSections(components, context) {
|
|
|
2016
2228
|
Math.max(component.props.level || 1, 1),
|
|
2017
2229
|
6
|
|
2018
2230
|
);
|
|
2019
|
-
sectionComponents.unshift(
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2231
|
+
sectionComponents.unshift(
|
|
2232
|
+
resolveComponentDefaults(
|
|
2233
|
+
{
|
|
2234
|
+
name: "heading",
|
|
2235
|
+
props: {
|
|
2236
|
+
text: component.props.title,
|
|
2237
|
+
level: headingLevel,
|
|
2238
|
+
pageBreak: shouldPageBreak,
|
|
2239
|
+
// Apply zero-spacing to prevent unwanted initial line
|
|
2240
|
+
spacing: {
|
|
2241
|
+
before: 0,
|
|
2242
|
+
after: 0
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
},
|
|
2246
|
+
context.fullTheme
|
|
2247
|
+
)
|
|
2248
|
+
);
|
|
2032
2249
|
}
|
|
2033
2250
|
sections.push({
|
|
2034
2251
|
title: component.props?.title,
|
|
@@ -2068,18 +2285,23 @@ async function flattenComponents(components, context) {
|
|
|
2068
2285
|
Math.max(component.props.level || 1, 1),
|
|
2069
2286
|
6
|
|
2070
2287
|
);
|
|
2071
|
-
flattened.push(
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2288
|
+
flattened.push(
|
|
2289
|
+
resolveComponentDefaults(
|
|
2290
|
+
{
|
|
2291
|
+
name: "heading",
|
|
2292
|
+
props: {
|
|
2293
|
+
text: component.props.title,
|
|
2294
|
+
level: headingLevel,
|
|
2295
|
+
// Apply zero-spacing to prevent unwanted initial line
|
|
2296
|
+
spacing: {
|
|
2297
|
+
before: 0,
|
|
2298
|
+
after: 0
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
},
|
|
2302
|
+
context.fullTheme
|
|
2303
|
+
)
|
|
2304
|
+
);
|
|
2083
2305
|
}
|
|
2084
2306
|
flattened.push(...await flattenComponents(component.children, context));
|
|
2085
2307
|
} else {
|
|
@@ -3844,93 +4066,6 @@ async function renderComponentWithCache(component, theme, themeName, context, by
|
|
|
3844
4066
|
return rendered;
|
|
3845
4067
|
}
|
|
3846
4068
|
|
|
3847
|
-
// src/styles/utils/componentDefaults.ts
|
|
3848
|
-
function getComponentDefaults(theme) {
|
|
3849
|
-
return theme.componentDefaults || {};
|
|
3850
|
-
}
|
|
3851
|
-
function getHeadingDefaults(theme) {
|
|
3852
|
-
const defaults = getComponentDefaults(theme);
|
|
3853
|
-
return defaults?.heading || {};
|
|
3854
|
-
}
|
|
3855
|
-
function getHeadingDefaultsForLevel(theme, level) {
|
|
3856
|
-
const defaults = {};
|
|
3857
|
-
if (theme.styles) {
|
|
3858
|
-
const styleKey = `heading${level}`;
|
|
3859
|
-
const headingStyle = theme.styles[styleKey];
|
|
3860
|
-
if (headingStyle?.alignment) {
|
|
3861
|
-
defaults.alignment = headingStyle.alignment;
|
|
3862
|
-
}
|
|
3863
|
-
}
|
|
3864
|
-
return defaults;
|
|
3865
|
-
}
|
|
3866
|
-
function getTextDefaults(theme) {
|
|
3867
|
-
const defaults = getComponentDefaults(theme);
|
|
3868
|
-
return defaults?.paragraph || {};
|
|
3869
|
-
}
|
|
3870
|
-
function getImageDefaults(theme) {
|
|
3871
|
-
const defaults = getComponentDefaults(theme);
|
|
3872
|
-
return defaults?.image || {};
|
|
3873
|
-
}
|
|
3874
|
-
function getStatisticDefaults(theme) {
|
|
3875
|
-
const defaults = getComponentDefaults(theme);
|
|
3876
|
-
return defaults?.statistic || {};
|
|
3877
|
-
}
|
|
3878
|
-
function getColumnsDefaults(theme) {
|
|
3879
|
-
const defaults = getComponentDefaults(theme);
|
|
3880
|
-
return defaults?.columns || {};
|
|
3881
|
-
}
|
|
3882
|
-
function getListDefaults(theme) {
|
|
3883
|
-
const defaults = getComponentDefaults(theme);
|
|
3884
|
-
return defaults?.list || {};
|
|
3885
|
-
}
|
|
3886
|
-
function deepMerge(target, source) {
|
|
3887
|
-
const output = { ...target };
|
|
3888
|
-
if (isObject(target) && isObject(source)) {
|
|
3889
|
-
Object.keys(source).forEach((key) => {
|
|
3890
|
-
if (isObject(source[key])) {
|
|
3891
|
-
if (!(key in target)) {
|
|
3892
|
-
output[key] = source[key];
|
|
3893
|
-
} else {
|
|
3894
|
-
output[key] = deepMerge(target[key], source[key]);
|
|
3895
|
-
}
|
|
3896
|
-
} else {
|
|
3897
|
-
output[key] = source[key];
|
|
3898
|
-
}
|
|
3899
|
-
});
|
|
3900
|
-
}
|
|
3901
|
-
return output;
|
|
3902
|
-
}
|
|
3903
|
-
function isObject(item) {
|
|
3904
|
-
return item !== null && typeof item === "object" && !Array.isArray(item);
|
|
3905
|
-
}
|
|
3906
|
-
function mergeWithDefaults(userConfig, themeDefaults) {
|
|
3907
|
-
return deepMerge(themeDefaults, userConfig);
|
|
3908
|
-
}
|
|
3909
|
-
function resolveHeadingProps(props, theme) {
|
|
3910
|
-
const defaults = getHeadingDefaults(theme);
|
|
3911
|
-
return mergeWithDefaults(props, defaults);
|
|
3912
|
-
}
|
|
3913
|
-
function resolveParagraphProps(props, theme) {
|
|
3914
|
-
const defaults = getTextDefaults(theme);
|
|
3915
|
-
return mergeWithDefaults(props, defaults);
|
|
3916
|
-
}
|
|
3917
|
-
function resolveImageProps(props, theme) {
|
|
3918
|
-
const defaults = getImageDefaults(theme);
|
|
3919
|
-
return mergeWithDefaults(props, defaults);
|
|
3920
|
-
}
|
|
3921
|
-
function resolveStatisticProps(props, theme) {
|
|
3922
|
-
const defaults = getStatisticDefaults(theme);
|
|
3923
|
-
return mergeWithDefaults(props, defaults);
|
|
3924
|
-
}
|
|
3925
|
-
function resolveColumnsProps(props, theme) {
|
|
3926
|
-
const defaults = getColumnsDefaults(theme);
|
|
3927
|
-
return mergeWithDefaults(props, defaults);
|
|
3928
|
-
}
|
|
3929
|
-
function resolveListProps(props, theme) {
|
|
3930
|
-
const defaults = getListDefaults(theme);
|
|
3931
|
-
return mergeWithDefaults(props, defaults);
|
|
3932
|
-
}
|
|
3933
|
-
|
|
3934
4069
|
// src/core/content.ts
|
|
3935
4070
|
import {
|
|
3936
4071
|
Paragraph,
|
|
@@ -4024,9 +4159,22 @@ var globalBookmarkRegistry = new BookmarkRegistry();
|
|
|
4024
4159
|
|
|
4025
4160
|
// src/core/content.ts
|
|
4026
4161
|
init_styleHelpers();
|
|
4162
|
+
import { synthesizeFamilyName } from "@json-to-office/shared";
|
|
4027
4163
|
init_colorUtils();
|
|
4028
4164
|
init_styleHelpers();
|
|
4029
4165
|
init_widthUtils();
|
|
4166
|
+
function applyFontWeightAlias(opts) {
|
|
4167
|
+
if (!opts.fontFamily) {
|
|
4168
|
+
return { font: void 0, bold: opts.bold, italics: opts.italic };
|
|
4169
|
+
}
|
|
4170
|
+
const weight = opts.fontWeight ?? (opts.bold === true ? 700 : void 0);
|
|
4171
|
+
const synth = synthesizeFamilyName(
|
|
4172
|
+
opts.fontFamily,
|
|
4173
|
+
weight,
|
|
4174
|
+
opts.italic === true
|
|
4175
|
+
);
|
|
4176
|
+
return { font: synth.family, bold: synth.bold, italics: synth.italic };
|
|
4177
|
+
}
|
|
4030
4178
|
function createText(content, theme, themeName, options = {}) {
|
|
4031
4179
|
const normalizedContent = normalizeUnicodeText(content);
|
|
4032
4180
|
const style = options.style || "Normal";
|
|
@@ -4046,15 +4194,27 @@ function createText(content, theme, themeName, options = {}) {
|
|
|
4046
4194
|
if (options.columnBreak) {
|
|
4047
4195
|
children.push(new ColumnBreak());
|
|
4048
4196
|
}
|
|
4197
|
+
const hasWeightRequest = options.fontWeight != null || options.bold === true;
|
|
4198
|
+
const effectiveFamily = options.fontFamily ?? (hasWeightRequest ? resolveFontFamily(theme, "body") : void 0);
|
|
4199
|
+
const weighted = applyFontWeightAlias({
|
|
4200
|
+
fontFamily: effectiveFamily,
|
|
4201
|
+
bold: options.bold,
|
|
4202
|
+
italic: options.italic,
|
|
4203
|
+
fontWeight: options.fontWeight
|
|
4204
|
+
});
|
|
4049
4205
|
const baseTextStyle = {
|
|
4050
|
-
|
|
4206
|
+
// Only emit `font` when it came from the caller or from an alias —
|
|
4207
|
+
// emitting the theme body family on every run would be a behavior change.
|
|
4208
|
+
...(options.fontFamily || weighted.font && weighted.font !== effectiveFamily) && {
|
|
4209
|
+
font: weighted.font
|
|
4210
|
+
},
|
|
4051
4211
|
...options.fontSize && { size: options.fontSize * 2 },
|
|
4052
4212
|
// Convert points to half-points
|
|
4053
4213
|
...options.fontColor && {
|
|
4054
4214
|
color: resolveColor(options.fontColor, theme)
|
|
4055
4215
|
},
|
|
4056
|
-
...
|
|
4057
|
-
...
|
|
4216
|
+
...weighted.bold !== void 0 && { bold: weighted.bold },
|
|
4217
|
+
...weighted.italics !== void 0 && { italics: weighted.italics },
|
|
4058
4218
|
...options.underline !== void 0 && {
|
|
4059
4219
|
underline: options.underline ? { type: "single" } : void 0
|
|
4060
4220
|
}
|
|
@@ -4174,13 +4334,25 @@ function createHeading(text, level, theme, _themeName, options = {}) {
|
|
|
4174
4334
|
children.push(new ColumnBreak());
|
|
4175
4335
|
}
|
|
4176
4336
|
const hasDecorators = /(\*\*\*|___|(\*\*|__)|(\*|_))/.test(normalizedText);
|
|
4337
|
+
const headingHasWeightRequest = options.fontWeight != null || options.bold === true;
|
|
4338
|
+
const headingEffectiveFamily = options.fontFamily ?? (headingHasWeightRequest ? resolveFontFamily(theme, "heading") : void 0);
|
|
4339
|
+
const headingWeighted = applyFontWeightAlias({
|
|
4340
|
+
fontFamily: headingEffectiveFamily,
|
|
4341
|
+
bold: options.bold,
|
|
4342
|
+
italic: options.italic,
|
|
4343
|
+
fontWeight: options.fontWeight
|
|
4344
|
+
});
|
|
4177
4345
|
const baseTextStyle = {
|
|
4178
|
-
...options.fontFamily
|
|
4346
|
+
...(options.fontFamily || headingWeighted.font && headingWeighted.font !== headingEffectiveFamily) && {
|
|
4347
|
+
font: headingWeighted.font
|
|
4348
|
+
},
|
|
4179
4349
|
...options.fontSize && { size: options.fontSize * 2 },
|
|
4180
4350
|
// points to half-points
|
|
4181
4351
|
...options.fontColor && { color: resolveColor(options.fontColor, theme) },
|
|
4182
|
-
...
|
|
4183
|
-
...
|
|
4352
|
+
...headingWeighted.bold !== void 0 && { bold: headingWeighted.bold },
|
|
4353
|
+
...headingWeighted.italics !== void 0 && {
|
|
4354
|
+
italics: headingWeighted.italics
|
|
4355
|
+
},
|
|
4184
4356
|
...options.underline !== void 0 && {
|
|
4185
4357
|
underline: options.underline ? { type: "single" } : void 0
|
|
4186
4358
|
}
|
|
@@ -4692,12 +4864,18 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
4692
4864
|
if (!cell) {
|
|
4693
4865
|
return cellChildren;
|
|
4694
4866
|
}
|
|
4867
|
+
const cellWeighted = applyFontWeightAlias({
|
|
4868
|
+
fontFamily: cellDefaults.font?.family || baseCellStyle.font,
|
|
4869
|
+
bold: cellDefaults.font?.bold ?? false,
|
|
4870
|
+
italic: cellDefaults.font?.italic ?? false,
|
|
4871
|
+
fontWeight: cellDefaults.font?.fontWeight
|
|
4872
|
+
});
|
|
4695
4873
|
const mergedStyle = {
|
|
4696
|
-
font:
|
|
4874
|
+
font: cellWeighted.font,
|
|
4697
4875
|
size: cellDefaults.font?.size ? cellDefaults.font.size * 2 : baseCellStyle.size,
|
|
4698
4876
|
// Convert to half-points
|
|
4699
|
-
bold:
|
|
4700
|
-
italics:
|
|
4877
|
+
bold: cellWeighted.bold ?? false,
|
|
4878
|
+
italics: cellWeighted.italics ?? false,
|
|
4701
4879
|
underline: cellDefaults.font?.underline ? { type: "single" } : void 0,
|
|
4702
4880
|
color: cellDefaults.color || baseCellStyle.color
|
|
4703
4881
|
};
|
|
@@ -4705,15 +4883,21 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
|
|
|
4705
4883
|
if (isParagraphComponent(cell)) {
|
|
4706
4884
|
const textComp = cell;
|
|
4707
4885
|
const paragraphFont = textComp.props.font;
|
|
4886
|
+
const paraWeighted = applyFontWeightAlias({
|
|
4887
|
+
fontFamily: paragraphFont?.family ?? mergedStyle.font,
|
|
4888
|
+
bold: paragraphFont?.bold,
|
|
4889
|
+
italic: paragraphFont?.italic,
|
|
4890
|
+
fontWeight: paragraphFont?.fontWeight
|
|
4891
|
+
});
|
|
4708
4892
|
const paragraphStyle = {
|
|
4709
4893
|
...mergedStyle,
|
|
4710
|
-
...
|
|
4894
|
+
...paraWeighted.font && { font: paraWeighted.font },
|
|
4711
4895
|
...paragraphFont?.size && { size: paragraphFont.size * 2 },
|
|
4712
|
-
...
|
|
4713
|
-
bold:
|
|
4896
|
+
...paraWeighted.bold !== void 0 && {
|
|
4897
|
+
bold: paraWeighted.bold
|
|
4714
4898
|
},
|
|
4715
|
-
...
|
|
4716
|
-
italics:
|
|
4899
|
+
...paraWeighted.italics !== void 0 && {
|
|
4900
|
+
italics: paraWeighted.italics
|
|
4717
4901
|
},
|
|
4718
4902
|
...paragraphFont?.underline !== void 0 && {
|
|
4719
4903
|
underline: paragraphFont.underline ? { type: "single" } : void 0
|
|
@@ -5144,35 +5328,29 @@ function createFooterElement(children, _options) {
|
|
|
5144
5328
|
// src/components/heading.ts
|
|
5145
5329
|
function renderHeadingComponent(component, theme, themeName) {
|
|
5146
5330
|
if (!isHeadingComponent(component)) return [];
|
|
5147
|
-
const
|
|
5148
|
-
const
|
|
5149
|
-
const levelDefaults = getHeadingDefaultsForLevel(theme, level);
|
|
5150
|
-
const finalConfig = {
|
|
5151
|
-
...resolvedConfig,
|
|
5152
|
-
// Only apply level defaults if no explicit alignment was provided in the original props
|
|
5153
|
-
...component.props.alignment ? {} : levelDefaults
|
|
5154
|
-
};
|
|
5155
|
-
const bookmarkId = component.id || globalBookmarkRegistry.generateId(finalConfig.text, "heading");
|
|
5331
|
+
const config = component.props;
|
|
5332
|
+
const bookmarkId = component.id || globalBookmarkRegistry.generateId(config.text, "heading");
|
|
5156
5333
|
const header = createHeading(
|
|
5157
|
-
|
|
5158
|
-
|
|
5334
|
+
config.text,
|
|
5335
|
+
config.level || 1,
|
|
5159
5336
|
theme,
|
|
5160
5337
|
themeName,
|
|
5161
5338
|
{
|
|
5162
|
-
alignment:
|
|
5163
|
-
spacing:
|
|
5164
|
-
lineSpacing:
|
|
5165
|
-
columnBreak:
|
|
5339
|
+
alignment: config.alignment,
|
|
5340
|
+
spacing: config.spacing,
|
|
5341
|
+
lineSpacing: config.lineSpacing,
|
|
5342
|
+
columnBreak: config.columnBreak,
|
|
5166
5343
|
// Local font overrides
|
|
5167
|
-
fontFamily:
|
|
5168
|
-
fontSize:
|
|
5169
|
-
fontColor:
|
|
5170
|
-
bold:
|
|
5171
|
-
|
|
5172
|
-
|
|
5344
|
+
fontFamily: config.font?.family,
|
|
5345
|
+
fontSize: config.font?.size,
|
|
5346
|
+
fontColor: config.font?.color,
|
|
5347
|
+
bold: config.font?.bold,
|
|
5348
|
+
fontWeight: config.font?.fontWeight,
|
|
5349
|
+
italic: config.font?.italic,
|
|
5350
|
+
underline: config.font?.underline,
|
|
5173
5351
|
// Pagination control
|
|
5174
|
-
keepNext:
|
|
5175
|
-
keepLines:
|
|
5352
|
+
keepNext: config.keepNext,
|
|
5353
|
+
keepLines: config.keepLines,
|
|
5176
5354
|
// Bookmark ID for internal linking
|
|
5177
5355
|
bookmarkId
|
|
5178
5356
|
}
|
|
@@ -5217,7 +5395,7 @@ function parseMarkdownList(text) {
|
|
|
5217
5395
|
}
|
|
5218
5396
|
function renderParagraphComponent(component, theme, themeName) {
|
|
5219
5397
|
if (!isParagraphComponent(component)) return [];
|
|
5220
|
-
const resolvedConfig =
|
|
5398
|
+
const resolvedConfig = component.props;
|
|
5221
5399
|
const listData = parseMarkdownList(resolvedConfig.text);
|
|
5222
5400
|
if (listData) {
|
|
5223
5401
|
const reference = globalNumberingRegistry.generateReference("markdown-list");
|
|
@@ -5283,6 +5461,7 @@ function renderParagraphComponent(component, theme, themeName) {
|
|
|
5283
5461
|
fontSize: resolvedConfig.font?.size,
|
|
5284
5462
|
fontColor: resolvedConfig.font?.color,
|
|
5285
5463
|
bold: resolvedConfig.font?.bold,
|
|
5464
|
+
fontWeight: resolvedConfig.font?.fontWeight,
|
|
5286
5465
|
italic: resolvedConfig.font?.italic,
|
|
5287
5466
|
underline: resolvedConfig.font?.underline,
|
|
5288
5467
|
// Pass outline level for TOC support
|
|
@@ -5402,7 +5581,7 @@ function fillMissingLevels(levels, maxLevel) {
|
|
|
5402
5581
|
}
|
|
5403
5582
|
function renderListComponent(component, theme, themeName) {
|
|
5404
5583
|
if (!isListComponent(component)) return [];
|
|
5405
|
-
const resolvedConfig =
|
|
5584
|
+
const resolvedConfig = component.props;
|
|
5406
5585
|
const maxLevel = getMaxLevelFromItems(resolvedConfig.items);
|
|
5407
5586
|
const reference = resolvedConfig.reference || globalNumberingRegistry.generateReference("list");
|
|
5408
5587
|
if (!globalNumberingRegistry.has(reference)) {
|
|
@@ -5433,7 +5612,7 @@ function renderListComponent(component, theme, themeName) {
|
|
|
5433
5612
|
// src/components/image.ts
|
|
5434
5613
|
async function renderImageComponent(component, theme, themeName) {
|
|
5435
5614
|
if (!isImageComponent(component)) return [];
|
|
5436
|
-
const resolvedConfig =
|
|
5615
|
+
const resolvedConfig = component.props;
|
|
5437
5616
|
const imageSource = resolvedConfig.base64 || resolvedConfig.path;
|
|
5438
5617
|
if (!imageSource) {
|
|
5439
5618
|
throw new Error(
|
|
@@ -5793,7 +5972,6 @@ async function renderColumnsComponent(component, theme, themeName, context) {
|
|
|
5793
5972
|
if (context.parent && isTextBoxComponent(context.parent)) {
|
|
5794
5973
|
return await renderColumnsAsTable(component, theme, themeName, context);
|
|
5795
5974
|
}
|
|
5796
|
-
resolveColumnsProps(component.props, theme);
|
|
5797
5975
|
const elements = [];
|
|
5798
5976
|
if (component.children) {
|
|
5799
5977
|
for (const child of component.children) {
|
|
@@ -5905,9 +6083,9 @@ async function renderColumnsAsTable(component, theme, themeName, context) {
|
|
|
5905
6083
|
}
|
|
5906
6084
|
|
|
5907
6085
|
// src/components/statistic.ts
|
|
5908
|
-
function renderStatisticComponent(component,
|
|
6086
|
+
function renderStatisticComponent(component, _theme) {
|
|
5909
6087
|
if (!isStatisticComponent(component)) return [];
|
|
5910
|
-
const resolvedConfig =
|
|
6088
|
+
const resolvedConfig = component.props;
|
|
5911
6089
|
return createStatistic(
|
|
5912
6090
|
{
|
|
5913
6091
|
number: resolvedConfig.number,
|
|
@@ -6762,7 +6940,8 @@ function createBuilderImpl(state) {
|
|
|
6762
6940
|
customThemes: state.customThemes,
|
|
6763
6941
|
debug: state.debug,
|
|
6764
6942
|
enableCache: state.enableCache,
|
|
6765
|
-
services: state.services
|
|
6943
|
+
services: state.services,
|
|
6944
|
+
fonts: state.fonts
|
|
6766
6945
|
};
|
|
6767
6946
|
return createBuilderImpl(
|
|
6768
6947
|
newState
|
|
@@ -6775,25 +6954,37 @@ function createBuilderImpl(state) {
|
|
|
6775
6954
|
internalDocument,
|
|
6776
6955
|
state.components
|
|
6777
6956
|
);
|
|
6778
|
-
const
|
|
6779
|
-
const docTheme = resolveDocumentTheme(
|
|
6957
|
+
const baseThemeName = internalDocument.props.theme || "minimal";
|
|
6958
|
+
const docTheme = resolveDocumentTheme(baseThemeName);
|
|
6780
6959
|
const warnings = [];
|
|
6960
|
+
const mode = applyExportMode({
|
|
6961
|
+
doc: internalDocument,
|
|
6962
|
+
theme: docTheme,
|
|
6963
|
+
fonts: state.fonts
|
|
6964
|
+
});
|
|
6965
|
+
const modedTheme = mode.theme;
|
|
6966
|
+
const themeName = scopedThemeName(baseThemeName, state.fonts?.mode);
|
|
6967
|
+
for (const w of mode.warnings) {
|
|
6968
|
+
warnings.push({
|
|
6969
|
+
component: "fontRegistry",
|
|
6970
|
+
message: w.message,
|
|
6971
|
+
severity: "warning",
|
|
6972
|
+
context: { code: w.code }
|
|
6973
|
+
});
|
|
6974
|
+
}
|
|
6781
6975
|
const processedComponents = await processDocumentComponents(
|
|
6782
|
-
|
|
6976
|
+
mode.doc.children || [],
|
|
6783
6977
|
warnings,
|
|
6784
|
-
|
|
6978
|
+
modedTheme
|
|
6785
6979
|
);
|
|
6786
6980
|
const processedDocument = {
|
|
6787
|
-
...
|
|
6981
|
+
...mode.doc,
|
|
6788
6982
|
children: processedComponents
|
|
6789
6983
|
};
|
|
6790
|
-
const [
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
themeName
|
|
6795
|
-
);
|
|
6796
|
-
const layout = applyLayout(structure.sections, docTheme, themeName);
|
|
6984
|
+
const [modedDoc] = normalizeDocument(processedDocument);
|
|
6985
|
+
await resolveDocumentFonts(modedDoc, modedTheme, state.fonts, warnings);
|
|
6986
|
+
const structure = await processDocument(modedDoc, modedTheme, themeName);
|
|
6987
|
+
const layout = applyLayout(structure.sections, modedTheme, themeName);
|
|
6797
6988
|
const generatedDocument = await renderDocument(structure, layout, {
|
|
6798
6989
|
services: state.services
|
|
6799
6990
|
});
|
|
@@ -6874,13 +7065,19 @@ function createBuilderImpl(state) {
|
|
|
6874
7065
|
const themeName = internalDocument.props.theme || "minimal";
|
|
6875
7066
|
const docTheme = resolveDocumentTheme(themeName);
|
|
6876
7067
|
const warnings = [];
|
|
7068
|
+
const mode = applyExportMode({
|
|
7069
|
+
doc: internalDocument,
|
|
7070
|
+
theme: docTheme,
|
|
7071
|
+
fonts: state.fonts
|
|
7072
|
+
});
|
|
7073
|
+
const modedTheme = mode.theme;
|
|
6877
7074
|
const processedComponents = await processDocumentComponents(
|
|
6878
|
-
|
|
7075
|
+
mode.doc.children || [],
|
|
6879
7076
|
warnings,
|
|
6880
|
-
|
|
7077
|
+
modedTheme
|
|
6881
7078
|
);
|
|
6882
7079
|
const processedDocument = {
|
|
6883
|
-
...
|
|
7080
|
+
...mode.doc,
|
|
6884
7081
|
children: processedComponents
|
|
6885
7082
|
};
|
|
6886
7083
|
const [finalReportComponent] = normalizeDocument(processedDocument);
|
|
@@ -6912,7 +7109,8 @@ function createDocumentGenerator(options) {
|
|
|
6912
7109
|
customThemes: options.customThemes,
|
|
6913
7110
|
debug: options.debug ?? false,
|
|
6914
7111
|
enableCache: options.enableCache ?? false,
|
|
6915
|
-
services: options.services
|
|
7112
|
+
services: options.services,
|
|
7113
|
+
fonts: options.fonts
|
|
6916
7114
|
};
|
|
6917
7115
|
return createBuilderImpl(initialState);
|
|
6918
7116
|
}
|