@json-to-office/core-docx 6.8.0 → 7.0.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/blocks/document.d.ts.map +1 -1
- package/dist/core/generationContext.d.ts +2 -2
- package/dist/core/generationContext.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +238 -93
- package/dist/index.js.map +1 -1
- package/dist/plugin/createDocumentGenerator.d.ts.map +1 -1
- package/dist/plugin/example/index.js +161 -54
- package/dist/plugin/example/index.js.map +1 -1
- package/dist/plugin/index.d.ts +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/types.d.ts +27 -0
- package/dist/plugin/types.d.ts.map +1 -1
- package/dist/quality/facts.d.ts +14 -1
- package/dist/quality/facts.d.ts.map +1 -1
- package/dist/quality/rules.d.ts +2 -2
- package/dist/quality/rules.d.ts.map +1 -1
- package/dist/renderers/docxjs/index.d.ts.map +1 -1
- package/dist/renderers/office-open/emit.d.ts +1 -1
- package/dist/renderers/office-open/emit.d.ts.map +1 -1
- package/dist/renderers/office-open/index.d.ts.map +1 -1
- package/dist/styles/themeToStyles.d.ts +23 -0
- package/dist/styles/themeToStyles.d.ts.map +1 -1
- package/dist/templates/themes/consulting.docx.theme.json +2 -1
- package/dist/templates/themes/index.d.ts +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1389,7 +1389,8 @@ var init_consulting_docx_theme = __esm({
|
|
|
1389
1389
|
},
|
|
1390
1390
|
stat: {
|
|
1391
1391
|
face: "heading",
|
|
1392
|
-
|
|
1392
|
+
size: 22,
|
|
1393
|
+
weight: 400,
|
|
1393
1394
|
color: "accent",
|
|
1394
1395
|
lineHeight: 1
|
|
1395
1396
|
},
|
|
@@ -1696,7 +1697,7 @@ var init_themes = __esm({
|
|
|
1696
1697
|
getTheme = (themeName) => {
|
|
1697
1698
|
return themes[themeName];
|
|
1698
1699
|
};
|
|
1699
|
-
getThemeWithFallback = (themeName, fallbackTheme = "
|
|
1700
|
+
getThemeWithFallback = (themeName, fallbackTheme = "consulting") => {
|
|
1700
1701
|
const theme = getTheme(themeName) || getTheme(fallbackTheme);
|
|
1701
1702
|
if (!theme) {
|
|
1702
1703
|
throw new Error(
|
|
@@ -1729,7 +1730,7 @@ function resolveTheme(theme, themeName) {
|
|
|
1729
1730
|
if (themeName) {
|
|
1730
1731
|
return getTheme(themeName);
|
|
1731
1732
|
}
|
|
1732
|
-
return getTheme("
|
|
1733
|
+
return getTheme("consulting");
|
|
1733
1734
|
}
|
|
1734
1735
|
function resolveFontFamily(theme, fontRef) {
|
|
1735
1736
|
if (!theme?.fonts?.body?.family) {
|
|
@@ -3792,7 +3793,9 @@ function createDocxJsRenderer() {
|
|
|
3792
3793
|
function buildDocument(ir, resources = /* @__PURE__ */ new Map()) {
|
|
3793
3794
|
return new Document({
|
|
3794
3795
|
styles: emitStyles(ir.styles),
|
|
3795
|
-
sections: ir.sections.map(
|
|
3796
|
+
sections: ir.sections.map(
|
|
3797
|
+
(section2, index) => sectionOptions(section2, resources, index === ir.sections.length - 1)
|
|
3798
|
+
),
|
|
3796
3799
|
...coreProperties(ir),
|
|
3797
3800
|
features: {
|
|
3798
3801
|
updateFields: ir.settings.updateFields,
|
|
@@ -3948,7 +3951,7 @@ function collectImagePlacements(ir) {
|
|
|
3948
3951
|
}
|
|
3949
3952
|
return placements;
|
|
3950
3953
|
}
|
|
3951
|
-
function sectionOptions(section2, resources) {
|
|
3954
|
+
function sectionOptions(section2, resources, closesDocument = false) {
|
|
3952
3955
|
const { page, columns } = section2.properties;
|
|
3953
3956
|
const options = {
|
|
3954
3957
|
properties: {
|
|
@@ -3987,7 +3990,7 @@ function sectionOptions(section2, resources) {
|
|
|
3987
3990
|
}
|
|
3988
3991
|
} : {}
|
|
3989
3992
|
},
|
|
3990
|
-
children: sectionChildren(section2, resources)
|
|
3993
|
+
children: sectionChildren(section2, resources, closesDocument)
|
|
3991
3994
|
};
|
|
3992
3995
|
const headers = chromeSlots(section2.headers, Header, resources);
|
|
3993
3996
|
if (headers) options.headers = headers;
|
|
@@ -4009,12 +4012,13 @@ function chromeSlots(set, Part, resources) {
|
|
|
4009
4012
|
function partChildren(part, resources) {
|
|
4010
4013
|
return part.children.map((block2) => emitBlock(block2, resources));
|
|
4011
4014
|
}
|
|
4012
|
-
function sectionChildren(section2, resources) {
|
|
4015
|
+
function sectionChildren(section2, resources, closesDocument = false) {
|
|
4013
4016
|
const blocks = section2.children.map((block2) => emitBlock(block2, resources));
|
|
4014
4017
|
const bookmark = section2.bookmark;
|
|
4015
|
-
|
|
4018
|
+
const endsInFrame = closesDocument && lastBlockIsFrame(section2);
|
|
4019
|
+
if (!bookmark && !endsInFrame) return blocks;
|
|
4016
4020
|
const out = [...blocks];
|
|
4017
|
-
if (bookmark
|
|
4021
|
+
if (bookmark?.opens) {
|
|
4018
4022
|
const start = new BookmarkStart2(bookmark.name, bookmark.id);
|
|
4019
4023
|
const first = out[0];
|
|
4020
4024
|
if (first instanceof Paragraph2) {
|
|
@@ -4023,20 +4027,26 @@ function sectionChildren(section2, resources) {
|
|
|
4023
4027
|
out.unshift(anchorParagraph(start));
|
|
4024
4028
|
}
|
|
4025
4029
|
}
|
|
4026
|
-
if (bookmark
|
|
4030
|
+
if (bookmark?.closes) {
|
|
4027
4031
|
const end = new BookmarkEnd2(bookmark.id);
|
|
4028
4032
|
const last = out[out.length - 1];
|
|
4029
|
-
if (last instanceof Paragraph2) {
|
|
4033
|
+
if (last instanceof Paragraph2 && !endsInFrame) {
|
|
4030
4034
|
last.addChildElement(end);
|
|
4031
4035
|
} else {
|
|
4032
4036
|
out.push(anchorParagraph(end));
|
|
4033
4037
|
}
|
|
4038
|
+
} else if (endsInFrame) {
|
|
4039
|
+
out.push(anchorParagraph());
|
|
4034
4040
|
}
|
|
4035
4041
|
return out;
|
|
4036
4042
|
}
|
|
4043
|
+
function lastBlockIsFrame(section2) {
|
|
4044
|
+
const last = section2.children[section2.children.length - 1];
|
|
4045
|
+
return last?.kind === "paragraph" && last.frame !== void 0;
|
|
4046
|
+
}
|
|
4037
4047
|
function anchorParagraph(anchor) {
|
|
4038
4048
|
return new Paragraph2({
|
|
4039
|
-
children: [anchor],
|
|
4049
|
+
children: anchor ? [anchor] : [],
|
|
4040
4050
|
spacing: { before: 0, after: 0, line: 20, lineRule: LineRuleType2.EXACT }
|
|
4041
4051
|
});
|
|
4042
4052
|
}
|
|
@@ -4855,7 +4865,7 @@ function borders2(value) {
|
|
|
4855
4865
|
}
|
|
4856
4866
|
return out;
|
|
4857
4867
|
}
|
|
4858
|
-
function section(value, ctx) {
|
|
4868
|
+
function section(value, ctx, closesDocument = false) {
|
|
4859
4869
|
const { page, columns } = value.properties;
|
|
4860
4870
|
return {
|
|
4861
4871
|
properties: {
|
|
@@ -4907,7 +4917,7 @@ function section(value, ctx) {
|
|
|
4907
4917
|
}
|
|
4908
4918
|
} : {}
|
|
4909
4919
|
},
|
|
4910
|
-
children: sectionChildren2(value, ctx),
|
|
4920
|
+
children: sectionChildren2(value, ctx, closesDocument),
|
|
4911
4921
|
...value.headers ? { headers: headerFooterSet(value.headers, ctx) } : {},
|
|
4912
4922
|
...value.footers ? { footers: headerFooterSet(value.footers, ctx) } : {}
|
|
4913
4923
|
};
|
|
@@ -4920,8 +4930,16 @@ function headerFooterSet(set, ctx) {
|
|
|
4920
4930
|
}
|
|
4921
4931
|
return out;
|
|
4922
4932
|
}
|
|
4923
|
-
function sectionChildren2(value, ctx) {
|
|
4933
|
+
function sectionChildren2(value, ctx, closesDocument = false) {
|
|
4924
4934
|
const blocks = value.children.map((child) => block(child, ctx));
|
|
4935
|
+
const last = value.children[value.children.length - 1];
|
|
4936
|
+
if (closesDocument && last?.kind === "paragraph" && last.frame !== void 0)
|
|
4937
|
+
blocks.push({
|
|
4938
|
+
paragraph: {
|
|
4939
|
+
children: [],
|
|
4940
|
+
spacing: { before: 0, after: 0, line: 20, lineRule: "exact" }
|
|
4941
|
+
}
|
|
4942
|
+
});
|
|
4925
4943
|
const bookmark = value.bookmark;
|
|
4926
4944
|
if (!bookmark) return blocks;
|
|
4927
4945
|
return [
|
|
@@ -5090,7 +5108,9 @@ async function buildDocumentOptions(ir, charts = [], svgRasterFallback) {
|
|
|
5090
5108
|
};
|
|
5091
5109
|
return {
|
|
5092
5110
|
styles: emitStyles2(ir.styles),
|
|
5093
|
-
sections: ir.sections.map(
|
|
5111
|
+
sections: ir.sections.map(
|
|
5112
|
+
(value, index) => section(value, ctx, index === ir.sections.length - 1)
|
|
5113
|
+
),
|
|
5094
5114
|
...coreProperties2(ir),
|
|
5095
5115
|
features: {
|
|
5096
5116
|
updateFields: ir.settings.updateFields,
|
|
@@ -6824,7 +6844,12 @@ function resolveColors(entries, at, deps) {
|
|
|
6824
6844
|
init_themes();
|
|
6825
6845
|
init_colorUtils();
|
|
6826
6846
|
init_styleHelpers();
|
|
6827
|
-
import {
|
|
6847
|
+
import {
|
|
6848
|
+
capsFormatting,
|
|
6849
|
+
designCanvas,
|
|
6850
|
+
synthesizeFamilyName,
|
|
6851
|
+
typeScaleSizes
|
|
6852
|
+
} from "@json-to-office/shared";
|
|
6828
6853
|
var RIGHT_MARGIN_TAB_TWIPS = 9026 * 2;
|
|
6829
6854
|
var STATISTIC_NUMBER_STYLE_ID = "StatisticNumber";
|
|
6830
6855
|
var STATISTIC_DESCRIPTION_STYLE_ID = "StatisticDescription";
|
|
@@ -6833,6 +6858,27 @@ var STATISTIC_SIZE_POINTS = {
|
|
|
6833
6858
|
medium: 28,
|
|
6834
6859
|
large: 40
|
|
6835
6860
|
};
|
|
6861
|
+
function statisticSizes(theme, size) {
|
|
6862
|
+
const sizeOf = (style) => {
|
|
6863
|
+
const value = theme.styles?.[style]?.size;
|
|
6864
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
6865
|
+
};
|
|
6866
|
+
const role = sizeOf("stat");
|
|
6867
|
+
const medium = sizeOf(STATISTIC_NUMBER_STYLE_ID) ?? role ?? STATISTIC_SIZE_POINTS.medium;
|
|
6868
|
+
const scale = role === void 0 ? void 0 : theme.typography?.scale?.[designCanvas("docx", theme.page?.size)];
|
|
6869
|
+
const steps = scale ? typeScaleSizes(scale) : [];
|
|
6870
|
+
const below = [...steps].reverse().find((step) => step < medium - 0.01);
|
|
6871
|
+
const above = steps.find((step) => step > medium + 0.01);
|
|
6872
|
+
const number = size === "small" ? role !== void 0 && below !== void 0 ? below : STATISTIC_SIZE_POINTS.small : size === "large" ? role !== void 0 && above !== void 0 ? above : STATISTIC_SIZE_POINTS.large : medium;
|
|
6873
|
+
const label = sizeOf("label");
|
|
6874
|
+
return {
|
|
6875
|
+
number,
|
|
6876
|
+
medium,
|
|
6877
|
+
// Half-points in the document, floored at 6pt.
|
|
6878
|
+
suffix: label ?? Math.max(12, Math.round(number)) / 2,
|
|
6879
|
+
description: sizeOf(STATISTIC_DESCRIPTION_STYLE_ID) ?? label ?? 10
|
|
6880
|
+
};
|
|
6881
|
+
}
|
|
6836
6882
|
function getStyleSafe(theme, styleName) {
|
|
6837
6883
|
return theme.styles && Object.hasOwn(theme.styles, styleName) ? theme.styles[styleName] : void 0;
|
|
6838
6884
|
}
|
|
@@ -7008,8 +7054,8 @@ function chromeRun(fontProps, theme, sizeHalfPoints) {
|
|
|
7008
7054
|
...fontProps.italic !== void 0 && { italic: fontProps.italic }
|
|
7009
7055
|
};
|
|
7010
7056
|
}
|
|
7011
|
-
function createDocumentStyles(themeNameOrObject = "
|
|
7012
|
-
const theme = typeof themeNameOrObject === "string" ? getTheme(themeNameOrObject) || getTheme("
|
|
7057
|
+
function createDocumentStyles(themeNameOrObject = "consulting", language) {
|
|
7058
|
+
const theme = typeof themeNameOrObject === "string" ? getTheme(themeNameOrObject) || getTheme("consulting") : themeNameOrObject;
|
|
7013
7059
|
const paragraphStyles = [
|
|
7014
7060
|
// Normal body text style
|
|
7015
7061
|
{
|
|
@@ -7480,14 +7526,19 @@ function createDocumentStyles(themeNameOrObject = "minimal", language) {
|
|
|
7480
7526
|
};
|
|
7481
7527
|
}
|
|
7482
7528
|
function createStatisticStyles(theme) {
|
|
7529
|
+
const sizes = statisticSizes(theme, "medium");
|
|
7530
|
+
const stat = theme.styles?.stat;
|
|
7531
|
+
const faces = ["heading", "body", "mono", "light"];
|
|
7532
|
+
const face = faces.find((candidate) => candidate === stat?.font) ?? "heading";
|
|
7533
|
+
const weight = typeof stat?.fontWeight === "number" ? stat.fontWeight : void 0;
|
|
7483
7534
|
const definitions = [
|
|
7484
7535
|
{
|
|
7485
7536
|
id: STATISTIC_NUMBER_STYLE_ID,
|
|
7486
7537
|
name: "Statistic Number",
|
|
7487
|
-
font:
|
|
7488
|
-
sizePoints:
|
|
7489
|
-
color: theme.colors.primary,
|
|
7490
|
-
bold: true,
|
|
7538
|
+
font: face,
|
|
7539
|
+
sizePoints: sizes.medium,
|
|
7540
|
+
color: typeof stat?.color === "string" ? stat.color : theme.colors.primary,
|
|
7541
|
+
bold: weight === void 0 ? true : weight >= 600,
|
|
7491
7542
|
// Space above separates the figure from whatever preceded it; none below,
|
|
7492
7543
|
// because the description is the other half of the same block.
|
|
7493
7544
|
spacing: { before: 12, after: 0 },
|
|
@@ -7500,7 +7551,7 @@ function createStatisticStyles(theme) {
|
|
|
7500
7551
|
id: STATISTIC_DESCRIPTION_STYLE_ID,
|
|
7501
7552
|
name: "Statistic Description",
|
|
7502
7553
|
font: "body",
|
|
7503
|
-
sizePoints:
|
|
7554
|
+
sizePoints: sizes.description,
|
|
7504
7555
|
color: theme.colors.textMuted,
|
|
7505
7556
|
bold: false,
|
|
7506
7557
|
spacing: { before: 0, after: 12 },
|
|
@@ -10072,9 +10123,10 @@ function compileStatistic(component, scope) {
|
|
|
10072
10123
|
);
|
|
10073
10124
|
}
|
|
10074
10125
|
const text = (value) => normalizeUnicodeText(String(value ?? ""));
|
|
10075
|
-
const
|
|
10076
|
-
const
|
|
10077
|
-
const
|
|
10126
|
+
const sizes = statisticSizes(ctx.theme, props.size);
|
|
10127
|
+
const numberPoints = sizes.number;
|
|
10128
|
+
const resized = numberPoints !== sizes.medium;
|
|
10129
|
+
const suffixHalfPoints = Math.round(sizes.suffix * 2);
|
|
10078
10130
|
const numberRuns = [];
|
|
10079
10131
|
const numberText = text(props.number);
|
|
10080
10132
|
if (numberText) {
|
|
@@ -12365,10 +12417,10 @@ import {
|
|
|
12365
12417
|
} from "@json-to-office/quality";
|
|
12366
12418
|
import { DEFAULT_DOCX_RENDERER_ID as DEFAULT_DOCX_RENDERER_ID2 } from "@json-to-office/shared-docx";
|
|
12367
12419
|
import {
|
|
12368
|
-
designCanvas as
|
|
12420
|
+
designCanvas as designCanvas3,
|
|
12369
12421
|
designColors as designColors2,
|
|
12370
12422
|
resolveDesignColor as resolveDesignColor2,
|
|
12371
|
-
typeScaleSizes
|
|
12423
|
+
typeScaleSizes as typeScaleSizes2
|
|
12372
12424
|
} from "@json-to-office/shared";
|
|
12373
12425
|
|
|
12374
12426
|
// src/core/generationContext.ts
|
|
@@ -12424,7 +12476,7 @@ function applyThemeOverrides(theme, overrides) {
|
|
|
12424
12476
|
// src/themes/design-system.ts
|
|
12425
12477
|
init_defaults();
|
|
12426
12478
|
import {
|
|
12427
|
-
designCanvas,
|
|
12479
|
+
designCanvas as designCanvas2,
|
|
12428
12480
|
resolveMotif,
|
|
12429
12481
|
resolveTypeRoles,
|
|
12430
12482
|
validateDesignColors
|
|
@@ -12434,7 +12486,7 @@ function resolveDocxDesignSystem(theme) {
|
|
|
12434
12486
|
const motif = resolveMotif(theme.motif);
|
|
12435
12487
|
if (!theme.typography && !theme.spacing)
|
|
12436
12488
|
return motif === theme.motif ? theme : withMotif(theme, motif);
|
|
12437
|
-
const canvas =
|
|
12489
|
+
const canvas = designCanvas2("docx", theme.page.size);
|
|
12438
12490
|
const roles = resolveTypeRoles(theme, canvas, theme.fonts.body.size ?? 11);
|
|
12439
12491
|
const styles = { ...theme.styles };
|
|
12440
12492
|
for (const [name, role] of Object.entries(roles)) {
|
|
@@ -12519,7 +12571,7 @@ function resolveThemeContext(documentIn, options = {}) {
|
|
|
12519
12571
|
}
|
|
12520
12572
|
const document = documentIn.props === void 0 ? { ...documentIn, props: {} } : documentIn;
|
|
12521
12573
|
const authoredThemeName = document.props.theme || void 0;
|
|
12522
|
-
const baseThemeName = authoredThemeName ?? "
|
|
12574
|
+
const baseThemeName = authoredThemeName ?? "consulting";
|
|
12523
12575
|
let theme = resolveNamedTheme ? resolveNamedTheme(
|
|
12524
12576
|
baseThemeName,
|
|
12525
12577
|
warnings,
|
|
@@ -12883,7 +12935,8 @@ async function expandBlocksWithPlugins(document, theme, plugins, render, preserv
|
|
|
12883
12935
|
document: second.standard,
|
|
12884
12936
|
preserved: first.preserved,
|
|
12885
12937
|
sourceMap: evaluator.sourceMap,
|
|
12886
|
-
blocks: evaluator.blocks
|
|
12938
|
+
blocks: evaluator.blocks,
|
|
12939
|
+
pluginOutputs: evaluator.pluginOutputs
|
|
12887
12940
|
};
|
|
12888
12941
|
}
|
|
12889
12942
|
|
|
@@ -13694,10 +13747,7 @@ function textSizeFact(node, props, path4, typography, role) {
|
|
|
13694
13747
|
};
|
|
13695
13748
|
}
|
|
13696
13749
|
function statisticSizeFacts(props, path4, typography) {
|
|
13697
|
-
const
|
|
13698
|
-
const styled = (id) => finiteNumber(asRecord2(typography.styles[id])?.size);
|
|
13699
|
-
const numberPoints = named ?? STATISTIC_SIZE_POINTS.medium;
|
|
13700
|
-
const painted = props.size === "small" || props.size === "large" ? numberPoints : styled("StatisticNumber") ?? numberPoints;
|
|
13750
|
+
const sizes = statisticSizes(typography.theme, props.size);
|
|
13701
13751
|
const present = (value) => value !== void 0 && value !== null && String(value).trim() !== "";
|
|
13702
13752
|
const facts = [];
|
|
13703
13753
|
const add = (suffix, role, fontSizePt) => facts.push({
|
|
@@ -13708,19 +13758,11 @@ function statisticSizeFacts(props, path4, typography) {
|
|
|
13708
13758
|
fontSizePt,
|
|
13709
13759
|
authored: false
|
|
13710
13760
|
});
|
|
13711
|
-
if (present(props.number)) add("number", "statistic",
|
|
13761
|
+
if (present(props.number)) add("number", "statistic", sizes.number);
|
|
13712
13762
|
if (present(props.unit) || present(props.trend) || present(props.trendValue))
|
|
13713
|
-
add(
|
|
13714
|
-
"suffix",
|
|
13715
|
-
"statistic-suffix",
|
|
13716
|
-
Math.max(12, Math.round(numberPoints)) / 2
|
|
13717
|
-
);
|
|
13763
|
+
add("suffix", "statistic-suffix", sizes.suffix);
|
|
13718
13764
|
if (present(props.description))
|
|
13719
|
-
add(
|
|
13720
|
-
"description",
|
|
13721
|
-
"statistic-description",
|
|
13722
|
-
styled("StatisticDescription") ?? 10
|
|
13723
|
-
);
|
|
13765
|
+
add("description", "statistic-description", sizes.description);
|
|
13724
13766
|
return facts;
|
|
13725
13767
|
}
|
|
13726
13768
|
function tocSizeFacts(props, path4, typography) {
|
|
@@ -13822,8 +13864,8 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13822
13864
|
fonts: options.fonts,
|
|
13823
13865
|
warnings: options.warnings
|
|
13824
13866
|
});
|
|
13825
|
-
const expanded = expandBlocks(themed.document, themed.theme);
|
|
13826
|
-
const context = expanded.blocks.length > 0 ? { ...themed, document: expanded.document } : themed;
|
|
13867
|
+
const expanded = options.expanded ?? expandBlocks(themed.document, themed.theme);
|
|
13868
|
+
const context = options.expanded !== void 0 || expanded.blocks.length > 0 ? { ...themed, document: expanded.document } : themed;
|
|
13827
13869
|
const resolved = resolveDocumentTree(context.document, context.theme);
|
|
13828
13870
|
const basePage = pageBox(resolved.theme, context.themeName);
|
|
13829
13871
|
const typography = {
|
|
@@ -13835,7 +13877,7 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13835
13877
|
let previousHeadingLevel;
|
|
13836
13878
|
const authoredPath = (path4) => toAuthoredPointer(
|
|
13837
13879
|
themed.sourceMap ?? {},
|
|
13838
|
-
toAuthoredPointer(expanded.sourceMap, path4)
|
|
13880
|
+
toAuthoredPointer(expanded.sourceMap, path4, expanded.pluginOutputs)
|
|
13839
13881
|
);
|
|
13840
13882
|
const addFact = (raw) => {
|
|
13841
13883
|
const fact = {
|
|
@@ -13974,7 +14016,7 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13974
14016
|
);
|
|
13975
14017
|
if (size) roleSizesPt[key] = size.fontSizePt;
|
|
13976
14018
|
}
|
|
13977
|
-
const scale = resolved.theme.typography?.scale?.[
|
|
14019
|
+
const scale = resolved.theme.typography?.scale?.[designCanvas3("docx", resolved.theme.page?.size)];
|
|
13978
14020
|
const typeScalePt = [
|
|
13979
14021
|
.../* @__PURE__ */ new Set([
|
|
13980
14022
|
...Object.values(roleSizesPt),
|
|
@@ -13982,7 +14024,7 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13982
14024
|
const size = resolveFontSize(resolved.theme, role);
|
|
13983
14025
|
return size === void 0 ? [] : [size];
|
|
13984
14026
|
}),
|
|
13985
|
-
...scale ?
|
|
14027
|
+
...scale ? typeScaleSizes2(scale) : []
|
|
13986
14028
|
])
|
|
13987
14029
|
].sort((a, b) => a - b);
|
|
13988
14030
|
addFact({
|
|
@@ -14138,6 +14180,7 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
14138
14180
|
for (const fact of svgTextFacts(props, path4)) addFact(fact);
|
|
14139
14181
|
const drawn = drawnRatio(props);
|
|
14140
14182
|
const natural = readableRatio(props);
|
|
14183
|
+
const authored = authoredPropsAt(path4);
|
|
14141
14184
|
addFact({
|
|
14142
14185
|
id: `docx:image:${path4}`,
|
|
14143
14186
|
kind: "docx/image",
|
|
@@ -14145,7 +14188,13 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
14145
14188
|
...typeof props.alt === "string" && props.alt.trim() !== "" && { alt: props.alt },
|
|
14146
14189
|
captioned: isCaptioned(facts, authoredPath(path4)),
|
|
14147
14190
|
...drawn !== void 0 && { drawnRatio: drawn },
|
|
14148
|
-
...natural !== void 0 && { naturalRatio: natural }
|
|
14191
|
+
...natural !== void 0 && { naturalRatio: natural },
|
|
14192
|
+
...authoredPath(path4) === path4 && finiteNumber(authored?.width) !== void 0 && finiteNumber(authored?.height) !== void 0 && {
|
|
14193
|
+
authoredSizePx: {
|
|
14194
|
+
width: authored.width,
|
|
14195
|
+
height: authored.height
|
|
14196
|
+
}
|
|
14197
|
+
}
|
|
14149
14198
|
});
|
|
14150
14199
|
}
|
|
14151
14200
|
if (node.name === "heading") {
|
|
@@ -14711,6 +14760,8 @@ import {
|
|
|
14711
14760
|
// src/quality/rules.ts
|
|
14712
14761
|
import {
|
|
14713
14762
|
chartInfoDesignFindings,
|
|
14763
|
+
configurationLabel,
|
|
14764
|
+
configurationSource,
|
|
14714
14765
|
DEFAULT_MAXIMUM_CHART_SERIES,
|
|
14715
14766
|
DEFAULT_MAXIMUM_PIE_SLICES,
|
|
14716
14767
|
fontCountFinding,
|
|
@@ -15310,18 +15361,21 @@ var docxRequiredChromeRule = {
|
|
|
15310
15361
|
if (required.length === 0) return [];
|
|
15311
15362
|
return facts.filter(
|
|
15312
15363
|
(fact) => fact.kind === "docx/chrome-slot"
|
|
15313
|
-
).filter((fact) => required.includes(fact.role) && !fact.present).map((fact) =>
|
|
15314
|
-
|
|
15315
|
-
|
|
15316
|
-
|
|
15317
|
-
|
|
15318
|
-
|
|
15319
|
-
|
|
15320
|
-
|
|
15321
|
-
|
|
15322
|
-
|
|
15323
|
-
|
|
15324
|
-
|
|
15364
|
+
).filter((fact) => required.includes(fact.role) && !fact.present).map((fact) => {
|
|
15365
|
+
const source = configurationSource(configuration, "required");
|
|
15366
|
+
return {
|
|
15367
|
+
path: fact.path,
|
|
15368
|
+
relatedPaths: [fact.invocation],
|
|
15369
|
+
message: `${fact.block} states no ${fact.role} in its "${fact.slot}" slot; ${configurationLabel(source, profile)} expects one on every ${fact.block}.`,
|
|
15370
|
+
suggestion: `Fill the "${fact.slot}" slot. The theme already styles it.`,
|
|
15371
|
+
context: { block: fact.block, slot: fact.slot, role: fact.role },
|
|
15372
|
+
evidence: {
|
|
15373
|
+
actual: "empty",
|
|
15374
|
+
expected: fact.role,
|
|
15375
|
+
values: { source, required }
|
|
15376
|
+
}
|
|
15377
|
+
};
|
|
15378
|
+
});
|
|
15325
15379
|
}
|
|
15326
15380
|
};
|
|
15327
15381
|
var docxExhibitRequiredRule = {
|
|
@@ -15382,16 +15436,21 @@ var docxRunningHeadRule = {
|
|
|
15382
15436
|
const missing = required.filter((part) => !fact[part]);
|
|
15383
15437
|
if (missing.length === 0) return [];
|
|
15384
15438
|
const parts = missing.map((part) => part === "pageNumber" ? "page-number field" : part).join(", ");
|
|
15439
|
+
const source = configurationSource(
|
|
15440
|
+
configuration,
|
|
15441
|
+
"required",
|
|
15442
|
+
"fromSection"
|
|
15443
|
+
);
|
|
15385
15444
|
return [
|
|
15386
15445
|
{
|
|
15387
15446
|
path: fact.path,
|
|
15388
|
-
message: `Section ${fact.index + 1} carries no ${parts};
|
|
15447
|
+
message: `Section ${fact.index + 1} carries no ${parts}; ${configurationLabel(source, profile)} expects a running head ` + (from === 0 ? "on every section." : `on every section from section ${from + 1} on.`),
|
|
15389
15448
|
suggestion: "Invoke a running-head block at the top of the first body section: its section effect fills every later section with the title and n / N.",
|
|
15390
15449
|
context: { section: fact.index, missing },
|
|
15391
15450
|
evidence: {
|
|
15392
15451
|
actual: required.filter((part) => fact[part]),
|
|
15393
15452
|
expected: required,
|
|
15394
|
-
values: { source
|
|
15453
|
+
values: { source, fromSection: from }
|
|
15395
15454
|
}
|
|
15396
15455
|
}
|
|
15397
15456
|
];
|
|
@@ -15448,13 +15507,16 @@ var docxSizeCountRule = {
|
|
|
15448
15507
|
formats: ["docx"],
|
|
15449
15508
|
defaultEnabled: false,
|
|
15450
15509
|
defaultParameters: { maximumSizes: 8 },
|
|
15451
|
-
evaluate: ({ facts, configuration, profile }) =>
|
|
15452
|
-
|
|
15453
|
-
|
|
15454
|
-
|
|
15455
|
-
|
|
15456
|
-
|
|
15457
|
-
|
|
15510
|
+
evaluate: ({ facts, configuration, profile }) => {
|
|
15511
|
+
const source = configurationSource(configuration, "maximumSizes");
|
|
15512
|
+
return sizeCountFinding(
|
|
15513
|
+
paintedSizes(facts),
|
|
15514
|
+
numberParameter(configuration.parameters, "maximumSizes", 8),
|
|
15515
|
+
themeFact(facts)?.path ?? "/props",
|
|
15516
|
+
{ source, label: configurationLabel(source, profile) },
|
|
15517
|
+
DOCX_TYPE_VOCABULARY
|
|
15518
|
+
);
|
|
15519
|
+
}
|
|
15458
15520
|
};
|
|
15459
15521
|
var docxRoleDriftRule = {
|
|
15460
15522
|
id: "docx/role-drift",
|
|
@@ -15511,7 +15573,12 @@ var docxBodyMeasureRule = {
|
|
|
15511
15573
|
actual: fact.charactersPerLine,
|
|
15512
15574
|
expected: wide ? maximum : minimum,
|
|
15513
15575
|
unit: "characters",
|
|
15514
|
-
values: {
|
|
15576
|
+
values: {
|
|
15577
|
+
source: configurationSource(
|
|
15578
|
+
configuration,
|
|
15579
|
+
wide ? "maximumCharacters" : "minimumCharacters"
|
|
15580
|
+
)
|
|
15581
|
+
}
|
|
15515
15582
|
}
|
|
15516
15583
|
};
|
|
15517
15584
|
});
|
|
@@ -15559,7 +15626,12 @@ var docxSectionContentRule = {
|
|
|
15559
15626
|
actual: 0,
|
|
15560
15627
|
expected: 1,
|
|
15561
15628
|
unit: "headings",
|
|
15562
|
-
values: {
|
|
15629
|
+
values: {
|
|
15630
|
+
source: configurationSource(
|
|
15631
|
+
configuration,
|
|
15632
|
+
"minimumWordsForHeading"
|
|
15633
|
+
)
|
|
15634
|
+
}
|
|
15563
15635
|
}
|
|
15564
15636
|
}
|
|
15565
15637
|
];
|
|
@@ -15576,7 +15648,7 @@ var docxHeadingKeepNextRule = {
|
|
|
15576
15648
|
defaultCertainty: "deterministic",
|
|
15577
15649
|
formats: ["docx"],
|
|
15578
15650
|
defaultEnabled: false,
|
|
15579
|
-
evaluate: ({ facts }) => facts.filter(
|
|
15651
|
+
evaluate: ({ facts, configuration }) => facts.filter(
|
|
15580
15652
|
(fact) => fact.kind === "docx/heading" && !fact.keepNext
|
|
15581
15653
|
).map((fact) => {
|
|
15582
15654
|
const heading = /\/props\/level$/.test(fact.path) ? fact.path.replace(/\/props\/level$/, "") : void 0;
|
|
@@ -15585,7 +15657,7 @@ var docxHeadingKeepNextRule = {
|
|
|
15585
15657
|
message: "This heading is not bound to the content under it: a page break can leave it alone at the foot of a page.",
|
|
15586
15658
|
suggestion: heading ? "Set keepNext on the heading, or give the theme\u2019s heading style keepNext so every level is bound." : "Give the theme\u2019s heading style keepNext, or set it in the block definition that draws this heading.",
|
|
15587
15659
|
context: { level: fact.level },
|
|
15588
|
-
evidence: { values: { source:
|
|
15660
|
+
evidence: { values: { source: configurationSource(configuration) } },
|
|
15589
15661
|
...heading && {
|
|
15590
15662
|
fixes: [
|
|
15591
15663
|
{
|
|
@@ -15638,7 +15710,20 @@ var docxImageAspectRule = {
|
|
|
15638
15710
|
{
|
|
15639
15711
|
path: fact.path,
|
|
15640
15712
|
drawn: fact.drawnRatio,
|
|
15641
|
-
natural: fact.naturalRatio
|
|
15713
|
+
natural: fact.naturalRatio,
|
|
15714
|
+
...fact.authoredSizePx && {
|
|
15715
|
+
sides: {
|
|
15716
|
+
width: {
|
|
15717
|
+
path: `${fact.path}/props/width`,
|
|
15718
|
+
value: fact.authoredSizePx.width
|
|
15719
|
+
},
|
|
15720
|
+
height: {
|
|
15721
|
+
path: `${fact.path}/props/height`,
|
|
15722
|
+
value: fact.authoredSizePx.height
|
|
15723
|
+
},
|
|
15724
|
+
decimals: 0
|
|
15725
|
+
}
|
|
15726
|
+
}
|
|
15642
15727
|
},
|
|
15643
15728
|
"page",
|
|
15644
15729
|
tolerance
|
|
@@ -15667,17 +15752,18 @@ var docxContentsRule = {
|
|
|
15667
15752
|
(fact) => fact.kind === "docx/outline"
|
|
15668
15753
|
);
|
|
15669
15754
|
if (!outline || outline.contents || outline.headings < minimum) return [];
|
|
15755
|
+
const source = configurationSource(configuration, "minimumHeadings");
|
|
15670
15756
|
return [
|
|
15671
15757
|
{
|
|
15672
15758
|
path: outline.path,
|
|
15673
|
-
message: `The document carries ${outline.headings} headings and no table of contents;
|
|
15759
|
+
message: `The document carries ${outline.headings} headings and no table of contents; ${configurationLabel(source, profile)} expects one from ${minimum}.`,
|
|
15674
15760
|
suggestion: "Add a `toc` component after the cover. Word fills it from the headings already there.",
|
|
15675
15761
|
context: { headings: outline.headings, minimum },
|
|
15676
15762
|
evidence: {
|
|
15677
15763
|
actual: outline.headings,
|
|
15678
15764
|
expected: minimum,
|
|
15679
15765
|
unit: "headings",
|
|
15680
|
-
values: { source
|
|
15766
|
+
values: { source }
|
|
15681
15767
|
}
|
|
15682
15768
|
}
|
|
15683
15769
|
];
|
|
@@ -15722,7 +15808,7 @@ var DOCX_QUALITY_PROFILES = {
|
|
|
15722
15808
|
"client-report": {
|
|
15723
15809
|
id: "client-report",
|
|
15724
15810
|
formats: ["docx"],
|
|
15725
|
-
description: "Client or public-administration report: a running head with page numbers on every section after the cover, a takeaway and a source wherever a block declares them, no heading skipped, every size on the theme scale with at most
|
|
15811
|
+
description: "Client or public-administration report: a running head with page numbers on every section after the cover, a takeaway and a source wherever a block declares them, no heading skipped, every size on the theme scale with at most nine in play, a readable measure, no empty or untitled section, every heading bound to what follows and every figure named, no page rendered empty or left half blank under the running head, and at least one chart or table.",
|
|
15726
15812
|
rules: {
|
|
15727
15813
|
"docx/required-chrome": {
|
|
15728
15814
|
parameters: { required: ["takeaway", "source"] }
|
|
@@ -15735,14 +15821,15 @@ var DOCX_QUALITY_PROFILES = {
|
|
|
15735
15821
|
},
|
|
15736
15822
|
"docx/heading-hierarchy": { severity: "warning" },
|
|
15737
15823
|
"docx/type-scale": { enabled: true },
|
|
15738
|
-
// Measured 2026-09-
|
|
15739
|
-
//
|
|
15740
|
-
//
|
|
15741
|
-
//
|
|
15742
|
-
// (
|
|
15743
|
-
//
|
|
15744
|
-
//
|
|
15745
|
-
|
|
15824
|
+
// Measured 2026-09-16 with statistics, lists and contents counted, once
|
|
15825
|
+
// a statistic paints in the theme's roles (#454): a client report built
|
|
15826
|
+
// from the house blocks paints up to nine sizes — 8 (source, chrome),
|
|
15827
|
+
// 9 (labels, the kpi-row's unit and caption), 9.5 (table cells), 10.5
|
|
15828
|
+
// (body), 12.5 and 16 (headings), 13 (subtitle), 18 (a four-up kpi
|
|
15829
|
+
// figure) and 22 (display, the kpi figure). The 155 client reports of
|
|
15830
|
+
// the checkpoint, host-study and verification runs came in at nine or
|
|
15831
|
+
// fewer; a size past the house set is an ad-hoc one.
|
|
15832
|
+
"docx/size-count": { enabled: true, parameters: { maximumSizes: 9 } },
|
|
15746
15833
|
"docx/role-drift": { enabled: true },
|
|
15747
15834
|
// The report blocks place every figure in a captioned block, so a page
|
|
15748
15835
|
// with no text under the running head is a stray break or an empty
|
|
@@ -17792,7 +17879,7 @@ function createBuilderImpl(state) {
|
|
|
17792
17879
|
}
|
|
17793
17880
|
return new Set(list);
|
|
17794
17881
|
}
|
|
17795
|
-
async function expandDocument(document, options) {
|
|
17882
|
+
async function expandDocument(document, options, provenance = false) {
|
|
17796
17883
|
const preserveSet = resolvePreserveSet(options);
|
|
17797
17884
|
const rootIn = document;
|
|
17798
17885
|
const internalDocument = rootIn.props === void 0 ? { ...rootIn, props: {} } : rootIn;
|
|
@@ -17852,7 +17939,7 @@ function createBuilderImpl(state) {
|
|
|
17852
17939
|
warnings,
|
|
17853
17940
|
resolveNamedTheme: resolveDocumentTheme
|
|
17854
17941
|
});
|
|
17855
|
-
if (modedRoot.props.blocks !== void 0) {
|
|
17942
|
+
if (modedRoot.props.blocks !== void 0 || provenance) {
|
|
17856
17943
|
const expanded = await expandBlocksWithPlugins(
|
|
17857
17944
|
modedRoot,
|
|
17858
17945
|
modedTheme,
|
|
@@ -17900,6 +17987,7 @@ function createBuilderImpl(state) {
|
|
|
17900
17987
|
modedDoc: modedDoc2,
|
|
17901
17988
|
sourceMap: expanded.sourceMap,
|
|
17902
17989
|
blockPaths: expanded.blocks,
|
|
17990
|
+
pluginOutputs: expanded.pluginOutputs,
|
|
17903
17991
|
warnings,
|
|
17904
17992
|
preserveSet,
|
|
17905
17993
|
processed: {
|
|
@@ -17948,8 +18036,64 @@ function createBuilderImpl(state) {
|
|
|
17948
18036
|
throw error;
|
|
17949
18037
|
}
|
|
17950
18038
|
}
|
|
18039
|
+
async function prepareQuality(document, options) {
|
|
18040
|
+
const {
|
|
18041
|
+
modedRoot,
|
|
18042
|
+
modedTheme,
|
|
18043
|
+
themeName,
|
|
18044
|
+
modedDoc,
|
|
18045
|
+
sourceMap,
|
|
18046
|
+
blockPaths,
|
|
18047
|
+
pluginOutputs,
|
|
18048
|
+
warnings
|
|
18049
|
+
} = await expandDocument(document, options, true);
|
|
18050
|
+
const prepared = prepareDocxQualityDocument(
|
|
18051
|
+
document,
|
|
18052
|
+
{
|
|
18053
|
+
context: { document: modedRoot, theme: modedTheme, themeName },
|
|
18054
|
+
expanded: {
|
|
18055
|
+
document: modedDoc,
|
|
18056
|
+
sourceMap: sourceMap ?? {},
|
|
18057
|
+
blocks: blockPaths ?? [],
|
|
18058
|
+
...pluginOutputs && { pluginOutputs }
|
|
18059
|
+
},
|
|
18060
|
+
customThemes: state.customThemes,
|
|
18061
|
+
fonts: state.fonts,
|
|
18062
|
+
renderer: options?.renderer ?? state.renderer ?? modedRoot.renderer,
|
|
18063
|
+
warnings
|
|
18064
|
+
}
|
|
18065
|
+
);
|
|
18066
|
+
return { prepared, warnings: warnings.length > 0 ? warnings : null };
|
|
18067
|
+
}
|
|
18068
|
+
async function generateBufferFromPrepared(prepared, options) {
|
|
18069
|
+
const { context } = prepared.model;
|
|
18070
|
+
const warnings = [];
|
|
18071
|
+
const baseDir = options?.baseDir ?? state.baseDir;
|
|
18072
|
+
const deterministic = options?.deterministic ?? state.deterministic;
|
|
18073
|
+
const generatedAt = options?.generatedAt ?? state.generatedAt;
|
|
18074
|
+
const renderer = options?.renderer ?? state.renderer ?? prepared.renderer;
|
|
18075
|
+
const { buffer } = await generateBufferViaIr(context.document, {
|
|
18076
|
+
context,
|
|
18077
|
+
prepared,
|
|
18078
|
+
...state.services ? { services: state.services } : {},
|
|
18079
|
+
...state.fonts ? { fonts: state.fonts } : {},
|
|
18080
|
+
...baseDir !== void 0 ? { baseDir } : {},
|
|
18081
|
+
...deterministic !== void 0 ? { deterministic } : {},
|
|
18082
|
+
...generatedAt !== void 0 ? { generatedAt } : {},
|
|
18083
|
+
...renderer !== void 0 ? { renderer } : {},
|
|
18084
|
+
warnings
|
|
18085
|
+
});
|
|
18086
|
+
return {
|
|
18087
|
+
buffer,
|
|
18088
|
+
warnings: warnings.length > 0 ? warnings : null,
|
|
18089
|
+
standardDefinition: context.document,
|
|
18090
|
+
preservedDefinition: void 0
|
|
18091
|
+
};
|
|
18092
|
+
}
|
|
17951
18093
|
async function generateBuffer(document, options) {
|
|
17952
18094
|
try {
|
|
18095
|
+
const reused = options?.prepared && resolvePreserveSet(options) === void 0 ? options.prepared : void 0;
|
|
18096
|
+
if (reused) return await generateBufferFromPrepared(reused, options);
|
|
17953
18097
|
const {
|
|
17954
18098
|
modedRoot,
|
|
17955
18099
|
modedTheme,
|
|
@@ -18079,6 +18223,7 @@ function createBuilderImpl(state) {
|
|
|
18079
18223
|
generateBuffer,
|
|
18080
18224
|
generateFile,
|
|
18081
18225
|
expandStandardDefinition,
|
|
18226
|
+
prepareQuality,
|
|
18082
18227
|
getComponentNames,
|
|
18083
18228
|
validate,
|
|
18084
18229
|
generateSchema,
|