@json-to-office/core-docx 6.8.1 → 7.0.1
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/desugarExternals.d.ts.map +1 -1
- package/dist/core/generationContext.d.ts +2 -2
- package/dist/core/generationContext.d.ts.map +1 -1
- package/dist/core/imageResources.d.ts.map +1 -1
- package/dist/core/layout.d.ts +7 -0
- package/dist/core/layout.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +334 -98
- package/dist/index.js.map +1 -1
- package/dist/ir/compiler.d.ts.map +1 -1
- package/dist/ir/types.d.ts +14 -0
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/plugin/createDocumentGenerator.d.ts.map +1 -1
- package/dist/plugin/example/index.js +257 -59
- 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/emit.d.ts.map +1 -1
- package/dist/renderers/office-open/chartParts.d.ts.map +1 -1
- package/dist/renderers/office-open/emit.d.ts.map +1 -1
- package/dist/styles/index.d.ts +2 -1
- package/dist/styles/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/styles/utils/layoutUtils.d.ts +41 -0
- package/dist/styles/utils/layoutUtils.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) {
|
|
@@ -1846,6 +1847,21 @@ function getPageDimensions(size) {
|
|
|
1846
1847
|
}
|
|
1847
1848
|
return { width: size.width, height: size.height };
|
|
1848
1849
|
}
|
|
1850
|
+
function themeForSectionPage(theme, page) {
|
|
1851
|
+
if (!page || !page.size && !page.margins) return theme;
|
|
1852
|
+
const base = getPageSetup(theme);
|
|
1853
|
+
return {
|
|
1854
|
+
...theme,
|
|
1855
|
+
page: {
|
|
1856
|
+
...theme.page,
|
|
1857
|
+
size: page.size ?? theme.page?.size ?? "A4",
|
|
1858
|
+
margins: { ...theme.page?.margins, ...base.margin, ...page.margins }
|
|
1859
|
+
}
|
|
1860
|
+
};
|
|
1861
|
+
}
|
|
1862
|
+
function pageSizeDiffers(a, b) {
|
|
1863
|
+
return a.width !== b.width || a.height !== b.height;
|
|
1864
|
+
}
|
|
1849
1865
|
var resolveTableParagraphSpacing, PAGE_SIZES, getTableStyle, getDocumentMargins, getPageSetup;
|
|
1850
1866
|
var init_layoutUtils = __esm({
|
|
1851
1867
|
"src/styles/utils/layoutUtils.ts"() {
|
|
@@ -3231,7 +3247,7 @@ function emitBlock(block2, resources = /* @__PURE__ */ new Map()) {
|
|
|
3231
3247
|
}
|
|
3232
3248
|
}
|
|
3233
3249
|
function emitToc(block2) {
|
|
3234
|
-
return new
|
|
3250
|
+
return new ThemedTableOfContents(block2.alias ?? "Table of Contents", {
|
|
3235
3251
|
...block2.hyperlink !== void 0 ? { hyperlink: block2.hyperlink } : {},
|
|
3236
3252
|
...block2.headingRange ? {
|
|
3237
3253
|
headingStyleRange: `${block2.headingRange.from}-${block2.headingRange.to}`
|
|
@@ -3363,7 +3379,7 @@ function emitBorder(border3) {
|
|
|
3363
3379
|
...border3.spacePoints !== void 0 ? { space: border3.spacePoints } : {}
|
|
3364
3380
|
};
|
|
3365
3381
|
}
|
|
3366
|
-
var ALIGNMENT2, PAGE_FIELDS, isSequenceField, WRAP_TYPE, VERTICAL_ALIGN, TABLE_ANCHOR, HORIZONTAL_POSITION, VERTICAL_POSITION, BORDER_STYLE;
|
|
3382
|
+
var ALIGNMENT2, PAGE_FIELDS, isSequenceField, WRAP_TYPE, ThemedTableOfContents, VERTICAL_ALIGN, TABLE_ANCHOR, HORIZONTAL_POSITION, VERTICAL_POSITION, BORDER_STYLE;
|
|
3367
3383
|
var init_emit = __esm({
|
|
3368
3384
|
"src/renderers/docxjs/emit.ts"() {
|
|
3369
3385
|
"use strict";
|
|
@@ -3383,6 +3399,11 @@ var init_emit = __esm({
|
|
|
3383
3399
|
tight: TextWrappingType.TIGHT,
|
|
3384
3400
|
topAndBottom: TextWrappingType.TOP_AND_BOTTOM
|
|
3385
3401
|
};
|
|
3402
|
+
ThemedTableOfContents = class extends TableOfContents {
|
|
3403
|
+
};
|
|
3404
|
+
Object.defineProperty(ThemedTableOfContents.prototype, "getTabStopsForLevel", {
|
|
3405
|
+
value: () => []
|
|
3406
|
+
});
|
|
3386
3407
|
VERTICAL_ALIGN = {
|
|
3387
3408
|
top: VerticalAlign.TOP,
|
|
3388
3409
|
center: VerticalAlign.CENTER,
|
|
@@ -4143,13 +4164,30 @@ import {
|
|
|
4143
4164
|
spliceChartXml
|
|
4144
4165
|
} from "@json-to-office/shared/rendering";
|
|
4145
4166
|
function spliceInput(chart) {
|
|
4167
|
+
const { bold, ...rest } = chart.textFont;
|
|
4168
|
+
const textFont = rest;
|
|
4169
|
+
const axisTitleFont = { ...rest, bold };
|
|
4170
|
+
const chartTitleFont = {
|
|
4171
|
+
...rest,
|
|
4172
|
+
fontSize: Math.round(rest.fontSize * CHART_TITLE_SCALE),
|
|
4173
|
+
bold: true
|
|
4174
|
+
};
|
|
4146
4175
|
return {
|
|
4147
4176
|
chartType: chart.chartType,
|
|
4148
4177
|
series: chart.series,
|
|
4149
4178
|
colors: chart.colors,
|
|
4179
|
+
textFont,
|
|
4180
|
+
titleFont: chartTitleFont,
|
|
4150
4181
|
...chart.legendPosition ? { legendPosition: chart.legendPosition } : {},
|
|
4151
|
-
...chart.categoryAxisTitle ? {
|
|
4152
|
-
|
|
4182
|
+
...chart.categoryAxisTitle ? {
|
|
4183
|
+
categoryAxis: {
|
|
4184
|
+
title: chart.categoryAxisTitle,
|
|
4185
|
+
titleFont: axisTitleFont
|
|
4186
|
+
}
|
|
4187
|
+
} : {},
|
|
4188
|
+
...chart.valueAxisTitle ? {
|
|
4189
|
+
valueAxis: { title: chart.valueAxisTitle, titleFont: axisTitleFont }
|
|
4190
|
+
} : {}
|
|
4153
4191
|
};
|
|
4154
4192
|
}
|
|
4155
4193
|
function declareWorkbookContentType(zip) {
|
|
@@ -4193,10 +4231,12 @@ function spliceChartParts(zip, charts) {
|
|
|
4193
4231
|
}
|
|
4194
4232
|
declareWorkbookContentType(zip);
|
|
4195
4233
|
}
|
|
4234
|
+
var CHART_TITLE_SCALE;
|
|
4196
4235
|
var init_chartParts = __esm({
|
|
4197
4236
|
"src/renderers/office-open/chartParts.ts"() {
|
|
4198
4237
|
"use strict";
|
|
4199
4238
|
init_chartWorkbook();
|
|
4239
|
+
CHART_TITLE_SCALE = 1.4;
|
|
4200
4240
|
}
|
|
4201
4241
|
});
|
|
4202
4242
|
|
|
@@ -4742,9 +4782,6 @@ function tocEntry(entry) {
|
|
|
4742
4782
|
return {
|
|
4743
4783
|
paragraph: {
|
|
4744
4784
|
style: `TOC${entry.level}`,
|
|
4745
|
-
tabStops: [
|
|
4746
|
-
{ type: "right", position: TOC_PAGE_TAB_TWIPS, leader: "dot" }
|
|
4747
|
-
],
|
|
4748
4785
|
children: [{ text: entry.text }, { children: [{ tab: true }] }]
|
|
4749
4786
|
}
|
|
4750
4787
|
};
|
|
@@ -4774,13 +4811,18 @@ function table(value, ctx) {
|
|
|
4774
4811
|
return {
|
|
4775
4812
|
rows: value.rows.map((row) => tableRow(row, ctx)),
|
|
4776
4813
|
width: {
|
|
4777
|
-
|
|
4814
|
+
// `w:w` is an integer in OOXML. A grid that splits a remainder between
|
|
4815
|
+
// unstated columns comes out fractional, and the XML would carry it
|
|
4816
|
+
// verbatim; floored here, as the docxjs backend floors it.
|
|
4817
|
+
size: value.width.kind === "auto" ? 0 : value.width.kind === "twips" ? Math.floor(value.width.value) : value.width.value,
|
|
4778
4818
|
type: value.width.kind === "twips" ? "dxa" : value.width.kind === "percent" ? "pct" : "auto"
|
|
4779
4819
|
},
|
|
4780
4820
|
layout: value.layout,
|
|
4781
4821
|
// An empty grid is a table with nothing to say about its columns, which is
|
|
4782
4822
|
// not the same as one whose columns are all zero wide.
|
|
4783
|
-
...value.columnGrid.values.length > 0 ? {
|
|
4823
|
+
...value.columnGrid.values.length > 0 ? {
|
|
4824
|
+
columnWidths: value.columnGrid.unit === "twips" ? value.columnGrid.values.map(Math.floor) : value.columnGrid.values
|
|
4825
|
+
} : {},
|
|
4784
4826
|
...value.alignment ? { alignment: alignment(value.alignment) } : {},
|
|
4785
4827
|
...value.borders ? { borders: borders2(value.borders) } : {},
|
|
4786
4828
|
...value.cellMargins ? { margins: cellMargins(value.cellMargins) } : {},
|
|
@@ -4972,7 +5014,7 @@ function numberingConfig2(numbering) {
|
|
|
4972
5014
|
}))
|
|
4973
5015
|
};
|
|
4974
5016
|
}
|
|
4975
|
-
var WRAP_TYPE2, BODY_ANCHOR
|
|
5017
|
+
var WRAP_TYPE2, BODY_ANCHOR;
|
|
4976
5018
|
var init_emit2 = __esm({
|
|
4977
5019
|
"src/renderers/office-open/emit.ts"() {
|
|
4978
5020
|
"use strict";
|
|
@@ -4988,7 +5030,6 @@ var init_emit2 = __esm({
|
|
|
4988
5030
|
middle: "ctr",
|
|
4989
5031
|
bottom: "b"
|
|
4990
5032
|
};
|
|
4991
|
-
TOC_PAGE_TAB_TWIPS = 9025;
|
|
4992
5033
|
}
|
|
4993
5034
|
});
|
|
4994
5035
|
|
|
@@ -5269,7 +5310,9 @@ function addPngTextChunk(data, marker) {
|
|
|
5269
5310
|
}
|
|
5270
5311
|
offset = chunkEnd;
|
|
5271
5312
|
}
|
|
5272
|
-
|
|
5313
|
+
throw new Error(
|
|
5314
|
+
"Cannot mark a PNG that has no intact IEND chunk; its bytes were not checked to decode before rendering"
|
|
5315
|
+
);
|
|
5273
5316
|
}
|
|
5274
5317
|
function addJpegComment(data, marker) {
|
|
5275
5318
|
if (data.length < 2 || data[0] !== 255 || data[1] !== 216) {
|
|
@@ -5968,6 +6011,7 @@ function containsComponent(root, name) {
|
|
|
5968
6011
|
}
|
|
5969
6012
|
|
|
5970
6013
|
// src/core/desugarExternals.ts
|
|
6014
|
+
init_layoutUtils();
|
|
5971
6015
|
import {
|
|
5972
6016
|
clampVisualDpi as clampVisualDpi2,
|
|
5973
6017
|
DEFAULT_VISUAL_DPI as DEFAULT_VISUAL_DPI2,
|
|
@@ -6171,8 +6215,18 @@ async function desugarExternals(document, options) {
|
|
|
6171
6215
|
}
|
|
6172
6216
|
).catch(() => /* @__PURE__ */ new Map());
|
|
6173
6217
|
const chartCache = /* @__PURE__ */ new Map();
|
|
6174
|
-
|
|
6218
|
+
const replace = (theme, inSection) => async function replaceNode(node) {
|
|
6175
6219
|
if (node.enabled === false) return void 0;
|
|
6220
|
+
if (node.name === "section" && !inSection) {
|
|
6221
|
+
const page = node.props.page;
|
|
6222
|
+
return transformComponents(
|
|
6223
|
+
node,
|
|
6224
|
+
replace(themeForSectionPage(theme, page), true)
|
|
6225
|
+
);
|
|
6226
|
+
}
|
|
6227
|
+
return replaceExternal(node, theme);
|
|
6228
|
+
};
|
|
6229
|
+
const replaceExternal = async (node, theme) => {
|
|
6176
6230
|
if (node.name === "visual") {
|
|
6177
6231
|
if (isNativeVisualProps2(node.props)) return void 0;
|
|
6178
6232
|
return withNodeIdentity(node, {
|
|
@@ -6190,7 +6244,7 @@ async function desugarExternals(document, options) {
|
|
|
6190
6244
|
name: "image",
|
|
6191
6245
|
props: await renderChartToImageProps(
|
|
6192
6246
|
node.props,
|
|
6193
|
-
|
|
6247
|
+
theme,
|
|
6194
6248
|
options.services?.highcharts,
|
|
6195
6249
|
options.chartFonts,
|
|
6196
6250
|
options.warnings,
|
|
@@ -6199,7 +6253,8 @@ async function desugarExternals(document, options) {
|
|
|
6199
6253
|
});
|
|
6200
6254
|
}
|
|
6201
6255
|
return void 0;
|
|
6202
|
-
}
|
|
6256
|
+
};
|
|
6257
|
+
return transformComponents(document, replace(options.theme, false));
|
|
6203
6258
|
}
|
|
6204
6259
|
async function visualImageProps(props, prerastered, options) {
|
|
6205
6260
|
const serviceConfig = options.services?.pptx;
|
|
@@ -6234,6 +6289,7 @@ init_imageUtils();
|
|
|
6234
6289
|
import {
|
|
6235
6290
|
isNativeVisualProps as isNativeVisualProps3
|
|
6236
6291
|
} from "@json-to-office/shared-docx";
|
|
6292
|
+
import { imageIntegrityDefect } from "@json-to-office/shared/images/node";
|
|
6237
6293
|
async function loadImageResources(components) {
|
|
6238
6294
|
const sources = /* @__PURE__ */ new Set();
|
|
6239
6295
|
for (const component of components) collectSources(component, sources);
|
|
@@ -6243,6 +6299,8 @@ async function loadImageResources(components) {
|
|
|
6243
6299
|
[...sources].map(async (source) => {
|
|
6244
6300
|
try {
|
|
6245
6301
|
const result = await getImageBuffer(source);
|
|
6302
|
+
const defect = imageIntegrityDefect(result.buffer);
|
|
6303
|
+
if (defect) throw new Error(defect);
|
|
6246
6304
|
const intrinsic = readIntrinsic(result.buffer, source);
|
|
6247
6305
|
loaded.set(source, {
|
|
6248
6306
|
bytes: result.buffer,
|
|
@@ -6843,7 +6901,12 @@ function resolveColors(entries, at, deps) {
|
|
|
6843
6901
|
init_themes();
|
|
6844
6902
|
init_colorUtils();
|
|
6845
6903
|
init_styleHelpers();
|
|
6846
|
-
import {
|
|
6904
|
+
import {
|
|
6905
|
+
capsFormatting,
|
|
6906
|
+
designCanvas,
|
|
6907
|
+
synthesizeFamilyName,
|
|
6908
|
+
typeScaleSizes
|
|
6909
|
+
} from "@json-to-office/shared";
|
|
6847
6910
|
var RIGHT_MARGIN_TAB_TWIPS = 9026 * 2;
|
|
6848
6911
|
var STATISTIC_NUMBER_STYLE_ID = "StatisticNumber";
|
|
6849
6912
|
var STATISTIC_DESCRIPTION_STYLE_ID = "StatisticDescription";
|
|
@@ -6852,6 +6915,27 @@ var STATISTIC_SIZE_POINTS = {
|
|
|
6852
6915
|
medium: 28,
|
|
6853
6916
|
large: 40
|
|
6854
6917
|
};
|
|
6918
|
+
function statisticSizes(theme, size) {
|
|
6919
|
+
const sizeOf = (style) => {
|
|
6920
|
+
const value = theme.styles?.[style]?.size;
|
|
6921
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
6922
|
+
};
|
|
6923
|
+
const role = sizeOf("stat");
|
|
6924
|
+
const medium = sizeOf(STATISTIC_NUMBER_STYLE_ID) ?? role ?? STATISTIC_SIZE_POINTS.medium;
|
|
6925
|
+
const scale = role === void 0 ? void 0 : theme.typography?.scale?.[designCanvas("docx", theme.page?.size)];
|
|
6926
|
+
const steps = scale ? typeScaleSizes(scale) : [];
|
|
6927
|
+
const below = [...steps].reverse().find((step) => step < medium - 0.01);
|
|
6928
|
+
const above = steps.find((step) => step > medium + 0.01);
|
|
6929
|
+
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;
|
|
6930
|
+
const label = sizeOf("label");
|
|
6931
|
+
return {
|
|
6932
|
+
number,
|
|
6933
|
+
medium,
|
|
6934
|
+
// Half-points in the document, floored at 6pt.
|
|
6935
|
+
suffix: label ?? Math.max(12, Math.round(number)) / 2,
|
|
6936
|
+
description: sizeOf(STATISTIC_DESCRIPTION_STYLE_ID) ?? label ?? 10
|
|
6937
|
+
};
|
|
6938
|
+
}
|
|
6855
6939
|
function getStyleSafe(theme, styleName) {
|
|
6856
6940
|
return theme.styles && Object.hasOwn(theme.styles, styleName) ? theme.styles[styleName] : void 0;
|
|
6857
6941
|
}
|
|
@@ -7027,8 +7111,8 @@ function chromeRun(fontProps, theme, sizeHalfPoints) {
|
|
|
7027
7111
|
...fontProps.italic !== void 0 && { italic: fontProps.italic }
|
|
7028
7112
|
};
|
|
7029
7113
|
}
|
|
7030
|
-
function createDocumentStyles(themeNameOrObject = "
|
|
7031
|
-
const theme = typeof themeNameOrObject === "string" ? getTheme(themeNameOrObject) || getTheme("
|
|
7114
|
+
function createDocumentStyles(themeNameOrObject = "consulting", language) {
|
|
7115
|
+
const theme = typeof themeNameOrObject === "string" ? getTheme(themeNameOrObject) || getTheme("consulting") : themeNameOrObject;
|
|
7032
7116
|
const paragraphStyles = [
|
|
7033
7117
|
// Normal body text style
|
|
7034
7118
|
{
|
|
@@ -7499,14 +7583,19 @@ function createDocumentStyles(themeNameOrObject = "minimal", language) {
|
|
|
7499
7583
|
};
|
|
7500
7584
|
}
|
|
7501
7585
|
function createStatisticStyles(theme) {
|
|
7586
|
+
const sizes = statisticSizes(theme, "medium");
|
|
7587
|
+
const stat = theme.styles?.stat;
|
|
7588
|
+
const faces = ["heading", "body", "mono", "light"];
|
|
7589
|
+
const face = faces.find((candidate) => candidate === stat?.font) ?? "heading";
|
|
7590
|
+
const weight = typeof stat?.fontWeight === "number" ? stat.fontWeight : void 0;
|
|
7502
7591
|
const definitions = [
|
|
7503
7592
|
{
|
|
7504
7593
|
id: STATISTIC_NUMBER_STYLE_ID,
|
|
7505
7594
|
name: "Statistic Number",
|
|
7506
|
-
font:
|
|
7507
|
-
sizePoints:
|
|
7508
|
-
color: theme.colors.primary,
|
|
7509
|
-
bold: true,
|
|
7595
|
+
font: face,
|
|
7596
|
+
sizePoints: sizes.medium,
|
|
7597
|
+
color: typeof stat?.color === "string" ? stat.color : theme.colors.primary,
|
|
7598
|
+
bold: weight === void 0 ? true : weight >= 600,
|
|
7510
7599
|
// Space above separates the figure from whatever preceded it; none below,
|
|
7511
7600
|
// because the description is the other half of the same block.
|
|
7512
7601
|
spacing: { before: 12, after: 0 },
|
|
@@ -7519,7 +7608,7 @@ function createStatisticStyles(theme) {
|
|
|
7519
7608
|
id: STATISTIC_DESCRIPTION_STYLE_ID,
|
|
7520
7609
|
name: "Statistic Description",
|
|
7521
7610
|
font: "body",
|
|
7522
|
-
sizePoints:
|
|
7611
|
+
sizePoints: sizes.description,
|
|
7523
7612
|
color: theme.colors.textMuted,
|
|
7524
7613
|
bold: false,
|
|
7525
7614
|
spacing: { before: 0, after: 12 },
|
|
@@ -9138,8 +9227,25 @@ function resolveSectionChrome(sections) {
|
|
|
9138
9227
|
});
|
|
9139
9228
|
}
|
|
9140
9229
|
function compileSection(section2, index, ordinal, chrome, ctx) {
|
|
9230
|
+
const documentTheme = ctx.theme;
|
|
9231
|
+
ctx.theme = themeForSectionPage(documentTheme, section2.pageOverride);
|
|
9232
|
+
try {
|
|
9233
|
+
return compileSectionBody(section2, index, ordinal, chrome, ctx);
|
|
9234
|
+
} finally {
|
|
9235
|
+
ctx.theme = documentTheme;
|
|
9236
|
+
}
|
|
9237
|
+
}
|
|
9238
|
+
function compileSectionBody(section2, index, ordinal, chrome, ctx) {
|
|
9141
9239
|
const path4 = `sections[${index}]`;
|
|
9142
9240
|
const { page, column } = section2.properties;
|
|
9241
|
+
if (section2.forcedPageBreak) {
|
|
9242
|
+
warnOnce(
|
|
9243
|
+
ctx,
|
|
9244
|
+
"section",
|
|
9245
|
+
`${path4} is set to continue on the page but changes the paper size or orientation, which a continuous section break cannot do, so it starts on a new page instead. Set pageBreak: true on the section to say so, or keep the page size of the section before it.`,
|
|
9246
|
+
"W_SECTION_PAGE_BREAK_FORCED"
|
|
9247
|
+
);
|
|
9248
|
+
}
|
|
9143
9249
|
if (column && column.count > 1) {
|
|
9144
9250
|
ctx.features.require("columns", `${path4}.properties.columns`);
|
|
9145
9251
|
}
|
|
@@ -10091,9 +10197,10 @@ function compileStatistic(component, scope) {
|
|
|
10091
10197
|
);
|
|
10092
10198
|
}
|
|
10093
10199
|
const text = (value) => normalizeUnicodeText(String(value ?? ""));
|
|
10094
|
-
const
|
|
10095
|
-
const
|
|
10096
|
-
const
|
|
10200
|
+
const sizes = statisticSizes(ctx.theme, props.size);
|
|
10201
|
+
const numberPoints = sizes.number;
|
|
10202
|
+
const resized = numberPoints !== sizes.medium;
|
|
10203
|
+
const suffixHalfPoints = Math.round(sizes.suffix * 2);
|
|
10097
10204
|
const numberRuns = [];
|
|
10098
10205
|
const numberText = text(props.number);
|
|
10099
10206
|
if (numberText) {
|
|
@@ -10993,6 +11100,24 @@ function compileImage2(component, scope) {
|
|
|
10993
11100
|
return blocks;
|
|
10994
11101
|
}
|
|
10995
11102
|
var DEFAULT_CHART_HEIGHT_INCHES = 3;
|
|
11103
|
+
var MAX_CHART_TEXT_POINTS = 10;
|
|
11104
|
+
function chartTextFont(theme) {
|
|
11105
|
+
const bodySize = getThemeFonts(theme).body?.size;
|
|
11106
|
+
let color = "000000";
|
|
11107
|
+
try {
|
|
11108
|
+
color = resolveColor("textPrimary", theme);
|
|
11109
|
+
} catch {
|
|
11110
|
+
}
|
|
11111
|
+
return {
|
|
11112
|
+
fontFamily: resolveFontFamily(theme, "body"),
|
|
11113
|
+
fontSize: Math.min(
|
|
11114
|
+
typeof bodySize === "number" && bodySize > 0 ? bodySize : 11,
|
|
11115
|
+
MAX_CHART_TEXT_POINTS
|
|
11116
|
+
),
|
|
11117
|
+
bold: false,
|
|
11118
|
+
color
|
|
11119
|
+
};
|
|
11120
|
+
}
|
|
10996
11121
|
function compileChart(component, scope) {
|
|
10997
11122
|
const { ctx, path: path4 } = scope;
|
|
10998
11123
|
const props = component.props ?? {};
|
|
@@ -11061,6 +11186,7 @@ function compileChart(component, scope) {
|
|
|
11061
11186
|
...props.legendPos ? { legendPosition: props.legendPos } : {},
|
|
11062
11187
|
...typeof props.catAxisTitle === "string" ? { categoryAxisTitle: props.catAxisTitle } : {},
|
|
11063
11188
|
...typeof props.valAxisTitle === "string" ? { valueAxisTitle: props.valAxisTitle } : {},
|
|
11189
|
+
textFont: chartTextFont(ctx.theme),
|
|
11064
11190
|
...typeof props.alt === "string" && props.alt ? { altText: props.alt } : {},
|
|
11065
11191
|
...props.floating ? { floating: compileFloating(props.floating, ctx, path4) } : {}
|
|
11066
11192
|
};
|
|
@@ -11799,6 +11925,18 @@ init_styles();
|
|
|
11799
11925
|
init_widthUtils();
|
|
11800
11926
|
function applyLayout(sections, theme, themeName) {
|
|
11801
11927
|
const layoutSections = [];
|
|
11928
|
+
const push = (layoutSection) => {
|
|
11929
|
+
const previous = layoutSections[layoutSections.length - 1];
|
|
11930
|
+
if (previous && layoutSection.properties.type === "continuous" && pageSizeDiffers(
|
|
11931
|
+
previous.properties.page.size,
|
|
11932
|
+
layoutSection.properties.page.size
|
|
11933
|
+
)) {
|
|
11934
|
+
layoutSection.properties.type = "nextPage";
|
|
11935
|
+
layoutSection.breakBefore = true;
|
|
11936
|
+
layoutSection.forcedPageBreak = true;
|
|
11937
|
+
}
|
|
11938
|
+
layoutSections.push(layoutSection);
|
|
11939
|
+
};
|
|
11802
11940
|
for (let i = 0; i < sections.length; i++) {
|
|
11803
11941
|
const section2 = sections[i];
|
|
11804
11942
|
const layoutGroups = analyzeLayoutGroups(section2.components);
|
|
@@ -11807,7 +11945,7 @@ function applyLayout(sections, theme, themeName) {
|
|
|
11807
11945
|
const isFirstSection = i === 0;
|
|
11808
11946
|
const breakBefore = isFirstSection || Boolean(section2.pageBreak);
|
|
11809
11947
|
const sectionType2 = breakBefore ? "nextPage" : "continuous";
|
|
11810
|
-
|
|
11948
|
+
push({
|
|
11811
11949
|
properties: createSectionProperties(
|
|
11812
11950
|
getColumnSettings("single"),
|
|
11813
11951
|
theme,
|
|
@@ -11829,7 +11967,12 @@ function applyLayout(sections, theme, themeName) {
|
|
|
11829
11967
|
for (let j = 0; j < layoutGroups.length; j++) {
|
|
11830
11968
|
const group = layoutGroups[j];
|
|
11831
11969
|
const isSingleColumnsGroup = group.components.length === 1 && isColumnsComponent(group.components[0]);
|
|
11832
|
-
const columnSettings = isSingleColumnsGroup ? createColumnSettingsFromConfig(
|
|
11970
|
+
const columnSettings = isSingleColumnsGroup ? createColumnSettingsFromConfig(
|
|
11971
|
+
group.components[0],
|
|
11972
|
+
// Percentages are of this section's text measure, not the theme's.
|
|
11973
|
+
theme ? themeForSectionPage(theme, section2.page) : theme,
|
|
11974
|
+
themeName
|
|
11975
|
+
) : getColumnSettings(group.layout);
|
|
11833
11976
|
const isFirstSection = i === 0 && j === 0;
|
|
11834
11977
|
const titlelessSectionBreak = Boolean(section2.pageBreak && j === 0);
|
|
11835
11978
|
const breakBefore = group.breakBefore || isFirstSection || titlelessSectionBreak;
|
|
@@ -11837,7 +11980,7 @@ function applyLayout(sections, theme, themeName) {
|
|
|
11837
11980
|
const contentComponents = isSingleColumnsGroup ? processLayoutComponents(
|
|
11838
11981
|
group.components[0].children || []
|
|
11839
11982
|
) : processLayoutComponents(group.components);
|
|
11840
|
-
|
|
11983
|
+
push({
|
|
11841
11984
|
properties: createSectionProperties(
|
|
11842
11985
|
columnSettings,
|
|
11843
11986
|
theme,
|
|
@@ -12384,10 +12527,10 @@ import {
|
|
|
12384
12527
|
} from "@json-to-office/quality";
|
|
12385
12528
|
import { DEFAULT_DOCX_RENDERER_ID as DEFAULT_DOCX_RENDERER_ID2 } from "@json-to-office/shared-docx";
|
|
12386
12529
|
import {
|
|
12387
|
-
designCanvas as
|
|
12530
|
+
designCanvas as designCanvas3,
|
|
12388
12531
|
designColors as designColors2,
|
|
12389
12532
|
resolveDesignColor as resolveDesignColor2,
|
|
12390
|
-
typeScaleSizes
|
|
12533
|
+
typeScaleSizes as typeScaleSizes2
|
|
12391
12534
|
} from "@json-to-office/shared";
|
|
12392
12535
|
|
|
12393
12536
|
// src/core/generationContext.ts
|
|
@@ -12443,7 +12586,7 @@ function applyThemeOverrides(theme, overrides) {
|
|
|
12443
12586
|
// src/themes/design-system.ts
|
|
12444
12587
|
init_defaults();
|
|
12445
12588
|
import {
|
|
12446
|
-
designCanvas,
|
|
12589
|
+
designCanvas as designCanvas2,
|
|
12447
12590
|
resolveMotif,
|
|
12448
12591
|
resolveTypeRoles,
|
|
12449
12592
|
validateDesignColors
|
|
@@ -12453,7 +12596,7 @@ function resolveDocxDesignSystem(theme) {
|
|
|
12453
12596
|
const motif = resolveMotif(theme.motif);
|
|
12454
12597
|
if (!theme.typography && !theme.spacing)
|
|
12455
12598
|
return motif === theme.motif ? theme : withMotif(theme, motif);
|
|
12456
|
-
const canvas =
|
|
12599
|
+
const canvas = designCanvas2("docx", theme.page.size);
|
|
12457
12600
|
const roles = resolveTypeRoles(theme, canvas, theme.fonts.body.size ?? 11);
|
|
12458
12601
|
const styles = { ...theme.styles };
|
|
12459
12602
|
for (const [name, role] of Object.entries(roles)) {
|
|
@@ -12538,7 +12681,7 @@ function resolveThemeContext(documentIn, options = {}) {
|
|
|
12538
12681
|
}
|
|
12539
12682
|
const document = documentIn.props === void 0 ? { ...documentIn, props: {} } : documentIn;
|
|
12540
12683
|
const authoredThemeName = document.props.theme || void 0;
|
|
12541
|
-
const baseThemeName = authoredThemeName ?? "
|
|
12684
|
+
const baseThemeName = authoredThemeName ?? "consulting";
|
|
12542
12685
|
let theme = resolveNamedTheme ? resolveNamedTheme(
|
|
12543
12686
|
baseThemeName,
|
|
12544
12687
|
warnings,
|
|
@@ -12902,7 +13045,8 @@ async function expandBlocksWithPlugins(document, theme, plugins, render, preserv
|
|
|
12902
13045
|
document: second.standard,
|
|
12903
13046
|
preserved: first.preserved,
|
|
12904
13047
|
sourceMap: evaluator.sourceMap,
|
|
12905
|
-
blocks: evaluator.blocks
|
|
13048
|
+
blocks: evaluator.blocks,
|
|
13049
|
+
pluginOutputs: evaluator.pluginOutputs
|
|
12906
13050
|
};
|
|
12907
13051
|
}
|
|
12908
13052
|
|
|
@@ -13713,10 +13857,7 @@ function textSizeFact(node, props, path4, typography, role) {
|
|
|
13713
13857
|
};
|
|
13714
13858
|
}
|
|
13715
13859
|
function statisticSizeFacts(props, path4, typography) {
|
|
13716
|
-
const
|
|
13717
|
-
const styled = (id) => finiteNumber(asRecord2(typography.styles[id])?.size);
|
|
13718
|
-
const numberPoints = named ?? STATISTIC_SIZE_POINTS.medium;
|
|
13719
|
-
const painted = props.size === "small" || props.size === "large" ? numberPoints : styled("StatisticNumber") ?? numberPoints;
|
|
13860
|
+
const sizes = statisticSizes(typography.theme, props.size);
|
|
13720
13861
|
const present = (value) => value !== void 0 && value !== null && String(value).trim() !== "";
|
|
13721
13862
|
const facts = [];
|
|
13722
13863
|
const add = (suffix, role, fontSizePt) => facts.push({
|
|
@@ -13727,19 +13868,11 @@ function statisticSizeFacts(props, path4, typography) {
|
|
|
13727
13868
|
fontSizePt,
|
|
13728
13869
|
authored: false
|
|
13729
13870
|
});
|
|
13730
|
-
if (present(props.number)) add("number", "statistic",
|
|
13871
|
+
if (present(props.number)) add("number", "statistic", sizes.number);
|
|
13731
13872
|
if (present(props.unit) || present(props.trend) || present(props.trendValue))
|
|
13732
|
-
add(
|
|
13733
|
-
"suffix",
|
|
13734
|
-
"statistic-suffix",
|
|
13735
|
-
Math.max(12, Math.round(numberPoints)) / 2
|
|
13736
|
-
);
|
|
13873
|
+
add("suffix", "statistic-suffix", sizes.suffix);
|
|
13737
13874
|
if (present(props.description))
|
|
13738
|
-
add(
|
|
13739
|
-
"description",
|
|
13740
|
-
"statistic-description",
|
|
13741
|
-
styled("StatisticDescription") ?? 10
|
|
13742
|
-
);
|
|
13875
|
+
add("description", "statistic-description", sizes.description);
|
|
13743
13876
|
return facts;
|
|
13744
13877
|
}
|
|
13745
13878
|
function tocSizeFacts(props, path4, typography) {
|
|
@@ -13841,8 +13974,8 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13841
13974
|
fonts: options.fonts,
|
|
13842
13975
|
warnings: options.warnings
|
|
13843
13976
|
});
|
|
13844
|
-
const expanded = expandBlocks(themed.document, themed.theme);
|
|
13845
|
-
const context = expanded.blocks.length > 0 ? { ...themed, document: expanded.document } : themed;
|
|
13977
|
+
const expanded = options.expanded ?? expandBlocks(themed.document, themed.theme);
|
|
13978
|
+
const context = options.expanded !== void 0 || expanded.blocks.length > 0 ? { ...themed, document: expanded.document } : themed;
|
|
13846
13979
|
const resolved = resolveDocumentTree(context.document, context.theme);
|
|
13847
13980
|
const basePage = pageBox(resolved.theme, context.themeName);
|
|
13848
13981
|
const typography = {
|
|
@@ -13854,7 +13987,7 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13854
13987
|
let previousHeadingLevel;
|
|
13855
13988
|
const authoredPath = (path4) => toAuthoredPointer(
|
|
13856
13989
|
themed.sourceMap ?? {},
|
|
13857
|
-
toAuthoredPointer(expanded.sourceMap, path4)
|
|
13990
|
+
toAuthoredPointer(expanded.sourceMap, path4, expanded.pluginOutputs)
|
|
13858
13991
|
);
|
|
13859
13992
|
const addFact = (raw) => {
|
|
13860
13993
|
const fact = {
|
|
@@ -13993,7 +14126,7 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13993
14126
|
);
|
|
13994
14127
|
if (size) roleSizesPt[key] = size.fontSizePt;
|
|
13995
14128
|
}
|
|
13996
|
-
const scale = resolved.theme.typography?.scale?.[
|
|
14129
|
+
const scale = resolved.theme.typography?.scale?.[designCanvas3("docx", resolved.theme.page?.size)];
|
|
13997
14130
|
const typeScalePt = [
|
|
13998
14131
|
.../* @__PURE__ */ new Set([
|
|
13999
14132
|
...Object.values(roleSizesPt),
|
|
@@ -14001,7 +14134,7 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
14001
14134
|
const size = resolveFontSize(resolved.theme, role);
|
|
14002
14135
|
return size === void 0 ? [] : [size];
|
|
14003
14136
|
}),
|
|
14004
|
-
...scale ?
|
|
14137
|
+
...scale ? typeScaleSizes2(scale) : []
|
|
14005
14138
|
])
|
|
14006
14139
|
].sort((a, b) => a - b);
|
|
14007
14140
|
addFact({
|
|
@@ -14157,6 +14290,7 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
14157
14290
|
for (const fact of svgTextFacts(props, path4)) addFact(fact);
|
|
14158
14291
|
const drawn = drawnRatio(props);
|
|
14159
14292
|
const natural = readableRatio(props);
|
|
14293
|
+
const authored = authoredPropsAt(path4);
|
|
14160
14294
|
addFact({
|
|
14161
14295
|
id: `docx:image:${path4}`,
|
|
14162
14296
|
kind: "docx/image",
|
|
@@ -14164,7 +14298,13 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
14164
14298
|
...typeof props.alt === "string" && props.alt.trim() !== "" && { alt: props.alt },
|
|
14165
14299
|
captioned: isCaptioned(facts, authoredPath(path4)),
|
|
14166
14300
|
...drawn !== void 0 && { drawnRatio: drawn },
|
|
14167
|
-
...natural !== void 0 && { naturalRatio: natural }
|
|
14301
|
+
...natural !== void 0 && { naturalRatio: natural },
|
|
14302
|
+
...authoredPath(path4) === path4 && finiteNumber(authored?.width) !== void 0 && finiteNumber(authored?.height) !== void 0 && {
|
|
14303
|
+
authoredSizePx: {
|
|
14304
|
+
width: authored.width,
|
|
14305
|
+
height: authored.height
|
|
14306
|
+
}
|
|
14307
|
+
}
|
|
14168
14308
|
});
|
|
14169
14309
|
}
|
|
14170
14310
|
if (node.name === "heading") {
|
|
@@ -14730,6 +14870,8 @@ import {
|
|
|
14730
14870
|
// src/quality/rules.ts
|
|
14731
14871
|
import {
|
|
14732
14872
|
chartInfoDesignFindings,
|
|
14873
|
+
configurationLabel,
|
|
14874
|
+
configurationSource,
|
|
14733
14875
|
DEFAULT_MAXIMUM_CHART_SERIES,
|
|
14734
14876
|
DEFAULT_MAXIMUM_PIE_SLICES,
|
|
14735
14877
|
fontCountFinding,
|
|
@@ -15329,18 +15471,21 @@ var docxRequiredChromeRule = {
|
|
|
15329
15471
|
if (required.length === 0) return [];
|
|
15330
15472
|
return facts.filter(
|
|
15331
15473
|
(fact) => fact.kind === "docx/chrome-slot"
|
|
15332
|
-
).filter((fact) => required.includes(fact.role) && !fact.present).map((fact) =>
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
|
|
15336
|
-
|
|
15337
|
-
|
|
15338
|
-
|
|
15339
|
-
|
|
15340
|
-
|
|
15341
|
-
|
|
15342
|
-
|
|
15343
|
-
|
|
15474
|
+
).filter((fact) => required.includes(fact.role) && !fact.present).map((fact) => {
|
|
15475
|
+
const source = configurationSource(configuration, "required");
|
|
15476
|
+
return {
|
|
15477
|
+
path: fact.path,
|
|
15478
|
+
relatedPaths: [fact.invocation],
|
|
15479
|
+
message: `${fact.block} states no ${fact.role} in its "${fact.slot}" slot; ${configurationLabel(source, profile)} expects one on every ${fact.block}.`,
|
|
15480
|
+
suggestion: `Fill the "${fact.slot}" slot. The theme already styles it.`,
|
|
15481
|
+
context: { block: fact.block, slot: fact.slot, role: fact.role },
|
|
15482
|
+
evidence: {
|
|
15483
|
+
actual: "empty",
|
|
15484
|
+
expected: fact.role,
|
|
15485
|
+
values: { source, required }
|
|
15486
|
+
}
|
|
15487
|
+
};
|
|
15488
|
+
});
|
|
15344
15489
|
}
|
|
15345
15490
|
};
|
|
15346
15491
|
var docxExhibitRequiredRule = {
|
|
@@ -15401,16 +15546,21 @@ var docxRunningHeadRule = {
|
|
|
15401
15546
|
const missing = required.filter((part) => !fact[part]);
|
|
15402
15547
|
if (missing.length === 0) return [];
|
|
15403
15548
|
const parts = missing.map((part) => part === "pageNumber" ? "page-number field" : part).join(", ");
|
|
15549
|
+
const source = configurationSource(
|
|
15550
|
+
configuration,
|
|
15551
|
+
"required",
|
|
15552
|
+
"fromSection"
|
|
15553
|
+
);
|
|
15404
15554
|
return [
|
|
15405
15555
|
{
|
|
15406
15556
|
path: fact.path,
|
|
15407
|
-
message: `Section ${fact.index + 1} carries no ${parts};
|
|
15557
|
+
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.`),
|
|
15408
15558
|
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.",
|
|
15409
15559
|
context: { section: fact.index, missing },
|
|
15410
15560
|
evidence: {
|
|
15411
15561
|
actual: required.filter((part) => fact[part]),
|
|
15412
15562
|
expected: required,
|
|
15413
|
-
values: { source
|
|
15563
|
+
values: { source, fromSection: from }
|
|
15414
15564
|
}
|
|
15415
15565
|
}
|
|
15416
15566
|
];
|
|
@@ -15467,13 +15617,16 @@ var docxSizeCountRule = {
|
|
|
15467
15617
|
formats: ["docx"],
|
|
15468
15618
|
defaultEnabled: false,
|
|
15469
15619
|
defaultParameters: { maximumSizes: 8 },
|
|
15470
|
-
evaluate: ({ facts, configuration, profile }) =>
|
|
15471
|
-
|
|
15472
|
-
|
|
15473
|
-
|
|
15474
|
-
|
|
15475
|
-
|
|
15476
|
-
|
|
15620
|
+
evaluate: ({ facts, configuration, profile }) => {
|
|
15621
|
+
const source = configurationSource(configuration, "maximumSizes");
|
|
15622
|
+
return sizeCountFinding(
|
|
15623
|
+
paintedSizes(facts),
|
|
15624
|
+
numberParameter(configuration.parameters, "maximumSizes", 8),
|
|
15625
|
+
themeFact(facts)?.path ?? "/props",
|
|
15626
|
+
{ source, label: configurationLabel(source, profile) },
|
|
15627
|
+
DOCX_TYPE_VOCABULARY
|
|
15628
|
+
);
|
|
15629
|
+
}
|
|
15477
15630
|
};
|
|
15478
15631
|
var docxRoleDriftRule = {
|
|
15479
15632
|
id: "docx/role-drift",
|
|
@@ -15530,7 +15683,12 @@ var docxBodyMeasureRule = {
|
|
|
15530
15683
|
actual: fact.charactersPerLine,
|
|
15531
15684
|
expected: wide ? maximum : minimum,
|
|
15532
15685
|
unit: "characters",
|
|
15533
|
-
values: {
|
|
15686
|
+
values: {
|
|
15687
|
+
source: configurationSource(
|
|
15688
|
+
configuration,
|
|
15689
|
+
wide ? "maximumCharacters" : "minimumCharacters"
|
|
15690
|
+
)
|
|
15691
|
+
}
|
|
15534
15692
|
}
|
|
15535
15693
|
};
|
|
15536
15694
|
});
|
|
@@ -15578,7 +15736,12 @@ var docxSectionContentRule = {
|
|
|
15578
15736
|
actual: 0,
|
|
15579
15737
|
expected: 1,
|
|
15580
15738
|
unit: "headings",
|
|
15581
|
-
values: {
|
|
15739
|
+
values: {
|
|
15740
|
+
source: configurationSource(
|
|
15741
|
+
configuration,
|
|
15742
|
+
"minimumWordsForHeading"
|
|
15743
|
+
)
|
|
15744
|
+
}
|
|
15582
15745
|
}
|
|
15583
15746
|
}
|
|
15584
15747
|
];
|
|
@@ -15595,7 +15758,7 @@ var docxHeadingKeepNextRule = {
|
|
|
15595
15758
|
defaultCertainty: "deterministic",
|
|
15596
15759
|
formats: ["docx"],
|
|
15597
15760
|
defaultEnabled: false,
|
|
15598
|
-
evaluate: ({ facts }) => facts.filter(
|
|
15761
|
+
evaluate: ({ facts, configuration }) => facts.filter(
|
|
15599
15762
|
(fact) => fact.kind === "docx/heading" && !fact.keepNext
|
|
15600
15763
|
).map((fact) => {
|
|
15601
15764
|
const heading = /\/props\/level$/.test(fact.path) ? fact.path.replace(/\/props\/level$/, "") : void 0;
|
|
@@ -15604,7 +15767,7 @@ var docxHeadingKeepNextRule = {
|
|
|
15604
15767
|
message: "This heading is not bound to the content under it: a page break can leave it alone at the foot of a page.",
|
|
15605
15768
|
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.",
|
|
15606
15769
|
context: { level: fact.level },
|
|
15607
|
-
evidence: { values: { source:
|
|
15770
|
+
evidence: { values: { source: configurationSource(configuration) } },
|
|
15608
15771
|
...heading && {
|
|
15609
15772
|
fixes: [
|
|
15610
15773
|
{
|
|
@@ -15657,7 +15820,20 @@ var docxImageAspectRule = {
|
|
|
15657
15820
|
{
|
|
15658
15821
|
path: fact.path,
|
|
15659
15822
|
drawn: fact.drawnRatio,
|
|
15660
|
-
natural: fact.naturalRatio
|
|
15823
|
+
natural: fact.naturalRatio,
|
|
15824
|
+
...fact.authoredSizePx && {
|
|
15825
|
+
sides: {
|
|
15826
|
+
width: {
|
|
15827
|
+
path: `${fact.path}/props/width`,
|
|
15828
|
+
value: fact.authoredSizePx.width
|
|
15829
|
+
},
|
|
15830
|
+
height: {
|
|
15831
|
+
path: `${fact.path}/props/height`,
|
|
15832
|
+
value: fact.authoredSizePx.height
|
|
15833
|
+
},
|
|
15834
|
+
decimals: 0
|
|
15835
|
+
}
|
|
15836
|
+
}
|
|
15661
15837
|
},
|
|
15662
15838
|
"page",
|
|
15663
15839
|
tolerance
|
|
@@ -15686,17 +15862,18 @@ var docxContentsRule = {
|
|
|
15686
15862
|
(fact) => fact.kind === "docx/outline"
|
|
15687
15863
|
);
|
|
15688
15864
|
if (!outline || outline.contents || outline.headings < minimum) return [];
|
|
15865
|
+
const source = configurationSource(configuration, "minimumHeadings");
|
|
15689
15866
|
return [
|
|
15690
15867
|
{
|
|
15691
15868
|
path: outline.path,
|
|
15692
|
-
message: `The document carries ${outline.headings} headings and no table of contents;
|
|
15869
|
+
message: `The document carries ${outline.headings} headings and no table of contents; ${configurationLabel(source, profile)} expects one from ${minimum}.`,
|
|
15693
15870
|
suggestion: "Add a `toc` component after the cover. Word fills it from the headings already there.",
|
|
15694
15871
|
context: { headings: outline.headings, minimum },
|
|
15695
15872
|
evidence: {
|
|
15696
15873
|
actual: outline.headings,
|
|
15697
15874
|
expected: minimum,
|
|
15698
15875
|
unit: "headings",
|
|
15699
|
-
values: { source
|
|
15876
|
+
values: { source }
|
|
15700
15877
|
}
|
|
15701
15878
|
}
|
|
15702
15879
|
];
|
|
@@ -15741,7 +15918,7 @@ var DOCX_QUALITY_PROFILES = {
|
|
|
15741
15918
|
"client-report": {
|
|
15742
15919
|
id: "client-report",
|
|
15743
15920
|
formats: ["docx"],
|
|
15744
|
-
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
|
|
15921
|
+
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.",
|
|
15745
15922
|
rules: {
|
|
15746
15923
|
"docx/required-chrome": {
|
|
15747
15924
|
parameters: { required: ["takeaway", "source"] }
|
|
@@ -15754,14 +15931,15 @@ var DOCX_QUALITY_PROFILES = {
|
|
|
15754
15931
|
},
|
|
15755
15932
|
"docx/heading-hierarchy": { severity: "warning" },
|
|
15756
15933
|
"docx/type-scale": { enabled: true },
|
|
15757
|
-
// Measured 2026-09-
|
|
15758
|
-
//
|
|
15759
|
-
//
|
|
15760
|
-
//
|
|
15761
|
-
// (
|
|
15762
|
-
//
|
|
15763
|
-
//
|
|
15764
|
-
|
|
15934
|
+
// Measured 2026-09-16 with statistics, lists and contents counted, once
|
|
15935
|
+
// a statistic paints in the theme's roles (#454): a client report built
|
|
15936
|
+
// from the house blocks paints up to nine sizes — 8 (source, chrome),
|
|
15937
|
+
// 9 (labels, the kpi-row's unit and caption), 9.5 (table cells), 10.5
|
|
15938
|
+
// (body), 12.5 and 16 (headings), 13 (subtitle), 18 (a four-up kpi
|
|
15939
|
+
// figure) and 22 (display, the kpi figure). The 155 client reports of
|
|
15940
|
+
// the checkpoint, host-study and verification runs came in at nine or
|
|
15941
|
+
// fewer; a size past the house set is an ad-hoc one.
|
|
15942
|
+
"docx/size-count": { enabled: true, parameters: { maximumSizes: 9 } },
|
|
15765
15943
|
"docx/role-drift": { enabled: true },
|
|
15766
15944
|
// The report blocks place every figure in a captioned block, so a page
|
|
15767
15945
|
// with no text under the running head is a stray break or an empty
|
|
@@ -17811,7 +17989,7 @@ function createBuilderImpl(state) {
|
|
|
17811
17989
|
}
|
|
17812
17990
|
return new Set(list);
|
|
17813
17991
|
}
|
|
17814
|
-
async function expandDocument(document, options) {
|
|
17992
|
+
async function expandDocument(document, options, provenance = false) {
|
|
17815
17993
|
const preserveSet = resolvePreserveSet(options);
|
|
17816
17994
|
const rootIn = document;
|
|
17817
17995
|
const internalDocument = rootIn.props === void 0 ? { ...rootIn, props: {} } : rootIn;
|
|
@@ -17871,7 +18049,7 @@ function createBuilderImpl(state) {
|
|
|
17871
18049
|
warnings,
|
|
17872
18050
|
resolveNamedTheme: resolveDocumentTheme
|
|
17873
18051
|
});
|
|
17874
|
-
if (modedRoot.props.blocks !== void 0) {
|
|
18052
|
+
if (modedRoot.props.blocks !== void 0 || provenance) {
|
|
17875
18053
|
const expanded = await expandBlocksWithPlugins(
|
|
17876
18054
|
modedRoot,
|
|
17877
18055
|
modedTheme,
|
|
@@ -17919,6 +18097,7 @@ function createBuilderImpl(state) {
|
|
|
17919
18097
|
modedDoc: modedDoc2,
|
|
17920
18098
|
sourceMap: expanded.sourceMap,
|
|
17921
18099
|
blockPaths: expanded.blocks,
|
|
18100
|
+
pluginOutputs: expanded.pluginOutputs,
|
|
17922
18101
|
warnings,
|
|
17923
18102
|
preserveSet,
|
|
17924
18103
|
processed: {
|
|
@@ -17967,8 +18146,64 @@ function createBuilderImpl(state) {
|
|
|
17967
18146
|
throw error;
|
|
17968
18147
|
}
|
|
17969
18148
|
}
|
|
18149
|
+
async function prepareQuality(document, options) {
|
|
18150
|
+
const {
|
|
18151
|
+
modedRoot,
|
|
18152
|
+
modedTheme,
|
|
18153
|
+
themeName,
|
|
18154
|
+
modedDoc,
|
|
18155
|
+
sourceMap,
|
|
18156
|
+
blockPaths,
|
|
18157
|
+
pluginOutputs,
|
|
18158
|
+
warnings
|
|
18159
|
+
} = await expandDocument(document, options, true);
|
|
18160
|
+
const prepared = prepareDocxQualityDocument(
|
|
18161
|
+
document,
|
|
18162
|
+
{
|
|
18163
|
+
context: { document: modedRoot, theme: modedTheme, themeName },
|
|
18164
|
+
expanded: {
|
|
18165
|
+
document: modedDoc,
|
|
18166
|
+
sourceMap: sourceMap ?? {},
|
|
18167
|
+
blocks: blockPaths ?? [],
|
|
18168
|
+
...pluginOutputs && { pluginOutputs }
|
|
18169
|
+
},
|
|
18170
|
+
customThemes: state.customThemes,
|
|
18171
|
+
fonts: state.fonts,
|
|
18172
|
+
renderer: options?.renderer ?? state.renderer ?? modedRoot.renderer,
|
|
18173
|
+
warnings
|
|
18174
|
+
}
|
|
18175
|
+
);
|
|
18176
|
+
return { prepared, warnings: warnings.length > 0 ? warnings : null };
|
|
18177
|
+
}
|
|
18178
|
+
async function generateBufferFromPrepared(prepared, options) {
|
|
18179
|
+
const { context } = prepared.model;
|
|
18180
|
+
const warnings = [];
|
|
18181
|
+
const baseDir = options?.baseDir ?? state.baseDir;
|
|
18182
|
+
const deterministic = options?.deterministic ?? state.deterministic;
|
|
18183
|
+
const generatedAt = options?.generatedAt ?? state.generatedAt;
|
|
18184
|
+
const renderer = options?.renderer ?? state.renderer ?? prepared.renderer;
|
|
18185
|
+
const { buffer } = await generateBufferViaIr(context.document, {
|
|
18186
|
+
context,
|
|
18187
|
+
prepared,
|
|
18188
|
+
...state.services ? { services: state.services } : {},
|
|
18189
|
+
...state.fonts ? { fonts: state.fonts } : {},
|
|
18190
|
+
...baseDir !== void 0 ? { baseDir } : {},
|
|
18191
|
+
...deterministic !== void 0 ? { deterministic } : {},
|
|
18192
|
+
...generatedAt !== void 0 ? { generatedAt } : {},
|
|
18193
|
+
...renderer !== void 0 ? { renderer } : {},
|
|
18194
|
+
warnings
|
|
18195
|
+
});
|
|
18196
|
+
return {
|
|
18197
|
+
buffer,
|
|
18198
|
+
warnings: warnings.length > 0 ? warnings : null,
|
|
18199
|
+
standardDefinition: context.document,
|
|
18200
|
+
preservedDefinition: void 0
|
|
18201
|
+
};
|
|
18202
|
+
}
|
|
17970
18203
|
async function generateBuffer(document, options) {
|
|
17971
18204
|
try {
|
|
18205
|
+
const reused = options?.prepared && resolvePreserveSet(options) === void 0 ? options.prepared : void 0;
|
|
18206
|
+
if (reused) return await generateBufferFromPrepared(reused, options);
|
|
17972
18207
|
const {
|
|
17973
18208
|
modedRoot,
|
|
17974
18209
|
modedTheme,
|
|
@@ -18098,6 +18333,7 @@ function createBuilderImpl(state) {
|
|
|
18098
18333
|
generateBuffer,
|
|
18099
18334
|
generateFile,
|
|
18100
18335
|
expandStandardDefinition,
|
|
18336
|
+
prepareQuality,
|
|
18101
18337
|
getComponentNames,
|
|
18102
18338
|
validate,
|
|
18103
18339
|
generateSchema,
|