@json-to-office/core-docx 2.5.0 → 2.7.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/cover.d.ts +22 -0
- package/dist/blocks/cover.d.ts.map +1 -0
- package/dist/blocks/index.d.ts +72 -0
- package/dist/blocks/index.d.ts.map +1 -0
- package/dist/blocks/keyTakeaways.d.ts +20 -0
- package/dist/blocks/keyTakeaways.d.ts.map +1 -0
- package/dist/blocks/recipe.d.ts +31 -0
- package/dist/blocks/recipe.d.ts.map +1 -0
- package/dist/blocks/runningHead.d.ts +69 -0
- package/dist/blocks/runningHead.d.ts.map +1 -0
- package/dist/blocks/sectionOpener.d.ts +26 -0
- package/dist/blocks/sectionOpener.d.ts.map +1 -0
- package/dist/blocks/types.d.ts +15 -0
- package/dist/blocks/types.d.ts.map +1 -0
- package/dist/components/highcharts.d.ts +2 -2
- package/dist/components/highcharts.d.ts.map +1 -1
- package/dist/core/componentTransform.d.ts +8 -0
- package/dist/core/componentTransform.d.ts.map +1 -1
- package/dist/core/desugarExternals.d.ts +2 -0
- package/dist/core/desugarExternals.d.ts.map +1 -1
- package/dist/core/generateFromIr.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1267 -129
- package/dist/index.js.map +1 -1
- package/dist/ir/compiler.d.ts.map +1 -1
- package/dist/plugin/example/index.js +1233 -130
- package/dist/plugin/example/index.js.map +1 -1
- package/dist/quality/facts.d.ts +23 -1
- package/dist/quality/facts.d.ts.map +1 -1
- package/dist/quality/rules.d.ts +6 -0
- package/dist/quality/rules.d.ts.map +1 -1
- package/dist/styles/index.d.ts +1 -1
- package/dist/styles/index.d.ts.map +1 -1
- package/dist/templates/themes/consulting.docx.theme.json +307 -0
- package/dist/templates/themes/index.d.ts +1755 -0
- package/dist/templates/themes/index.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -238,43 +238,6 @@ var init_colorUtils = __esm({
|
|
|
238
238
|
}
|
|
239
239
|
});
|
|
240
240
|
|
|
241
|
-
// src/utils/generationContext.ts
|
|
242
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
243
|
-
import { isAbsolute, resolve } from "path";
|
|
244
|
-
function runWithBaseDir(baseDir, callback) {
|
|
245
|
-
return baseDir === void 0 ? callback() : baseDirStorage.run(resolve(baseDir), callback);
|
|
246
|
-
}
|
|
247
|
-
function resolveFromBaseDir(filePath) {
|
|
248
|
-
const base = baseDirStorage.getStore();
|
|
249
|
-
if (!base || isAbsolute(filePath)) return filePath;
|
|
250
|
-
return resolve(base, filePath);
|
|
251
|
-
}
|
|
252
|
-
function runWithWarnings(warnings, callback) {
|
|
253
|
-
return warnings === void 0 ? callback() : warningsStorage.run(warnings, callback);
|
|
254
|
-
}
|
|
255
|
-
function reportWarning(component, code, message, context) {
|
|
256
|
-
const warnings = warningsStorage.getStore();
|
|
257
|
-
if (warnings) {
|
|
258
|
-
warnings.push({
|
|
259
|
-
component,
|
|
260
|
-
message,
|
|
261
|
-
severity: "warning",
|
|
262
|
-
context: { code, ...context }
|
|
263
|
-
});
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
console.warn(`[json-to-docx] [${code}] ${message}`);
|
|
267
|
-
}
|
|
268
|
-
var generationDateStorage, baseDirStorage, warningsStorage;
|
|
269
|
-
var init_generationContext = __esm({
|
|
270
|
-
"src/utils/generationContext.ts"() {
|
|
271
|
-
"use strict";
|
|
272
|
-
generationDateStorage = new AsyncLocalStorage();
|
|
273
|
-
baseDirStorage = new AsyncLocalStorage();
|
|
274
|
-
warningsStorage = new AsyncLocalStorage();
|
|
275
|
-
}
|
|
276
|
-
});
|
|
277
|
-
|
|
278
241
|
// src/templates/themes/minimal.docx.theme.json
|
|
279
242
|
var minimal_docx_theme_default;
|
|
280
243
|
var init_minimal_docx_theme = __esm({
|
|
@@ -880,6 +843,320 @@ var init_vermilion_docx_theme = __esm({
|
|
|
880
843
|
}
|
|
881
844
|
});
|
|
882
845
|
|
|
846
|
+
// src/templates/themes/consulting.docx.theme.json
|
|
847
|
+
var consulting_docx_theme_default;
|
|
848
|
+
var init_consulting_docx_theme = __esm({
|
|
849
|
+
"src/templates/themes/consulting.docx.theme.json"() {
|
|
850
|
+
consulting_docx_theme_default = {
|
|
851
|
+
name: "consulting",
|
|
852
|
+
displayName: "Consulting House",
|
|
853
|
+
description: "The house style for client and technical reports \u2014 near-black ink, three greys and one deep-blue accent, Calibri body under Arial headings, hairline rules, no fills behind body text, safe fonts only",
|
|
854
|
+
version: "1.0.0",
|
|
855
|
+
colors: {
|
|
856
|
+
primary: "#1A1F26",
|
|
857
|
+
secondary: "#4B5563",
|
|
858
|
+
accent: "#1B4F8A",
|
|
859
|
+
text: "#1A1F26",
|
|
860
|
+
background: "#FFFFFF",
|
|
861
|
+
border: "#C9CED6",
|
|
862
|
+
textPrimary: "#1A1F26",
|
|
863
|
+
textSecondary: "#4B5563",
|
|
864
|
+
textMuted: "#7B8794",
|
|
865
|
+
borderPrimary: "#C9CED6",
|
|
866
|
+
borderSecondary: "#E4E7EB",
|
|
867
|
+
backgroundPrimary: "#FFFFFF",
|
|
868
|
+
backgroundSecondary: "#F2F4F7",
|
|
869
|
+
accent4: "#5B8DC9",
|
|
870
|
+
accent5: "#A9C4E4",
|
|
871
|
+
accent6: "#7B8794"
|
|
872
|
+
},
|
|
873
|
+
palette: {
|
|
874
|
+
rule: "#C9CED6",
|
|
875
|
+
textMuted: "#7B8794",
|
|
876
|
+
onPrimary: "#FFFFFF",
|
|
877
|
+
surfaceInverse: "#1A1F26",
|
|
878
|
+
positive: "#1E7F4F",
|
|
879
|
+
negative: "#B42318",
|
|
880
|
+
chart: ["accent", "secondary", "accent4", "textMuted", "accent5", "rule"]
|
|
881
|
+
},
|
|
882
|
+
fonts: {
|
|
883
|
+
heading: { family: "Arial", size: 16 },
|
|
884
|
+
body: { family: "Calibri", size: 10.5 },
|
|
885
|
+
mono: { family: "Consolas", size: 9.5 },
|
|
886
|
+
light: { family: "Arial", size: 16 }
|
|
887
|
+
},
|
|
888
|
+
page: {
|
|
889
|
+
size: "A4",
|
|
890
|
+
margins: {
|
|
891
|
+
top: 1440,
|
|
892
|
+
bottom: 1440,
|
|
893
|
+
left: 1440,
|
|
894
|
+
right: 1440,
|
|
895
|
+
header: 680,
|
|
896
|
+
footer: 680,
|
|
897
|
+
gutter: 0
|
|
898
|
+
}
|
|
899
|
+
},
|
|
900
|
+
typography: {
|
|
901
|
+
roles: {
|
|
902
|
+
eyebrow: {
|
|
903
|
+
face: "heading",
|
|
904
|
+
size: 8,
|
|
905
|
+
weight: 700,
|
|
906
|
+
case: "upper",
|
|
907
|
+
tracking: 8,
|
|
908
|
+
color: "accent",
|
|
909
|
+
spaceAfter: 4
|
|
910
|
+
},
|
|
911
|
+
display: {
|
|
912
|
+
face: "heading",
|
|
913
|
+
weight: 700,
|
|
914
|
+
color: "primary",
|
|
915
|
+
lineHeight: 1.05,
|
|
916
|
+
spaceAfter: 8
|
|
917
|
+
},
|
|
918
|
+
stat: {
|
|
919
|
+
face: "heading",
|
|
920
|
+
weight: 700,
|
|
921
|
+
color: "accent",
|
|
922
|
+
lineHeight: 1
|
|
923
|
+
},
|
|
924
|
+
quote: {
|
|
925
|
+
face: "body",
|
|
926
|
+
color: "textSecondary",
|
|
927
|
+
lineHeight: 1.3
|
|
928
|
+
},
|
|
929
|
+
label: {
|
|
930
|
+
face: "body",
|
|
931
|
+
size: 9,
|
|
932
|
+
weight: 700,
|
|
933
|
+
color: "textSecondary"
|
|
934
|
+
},
|
|
935
|
+
footer: { face: "body", size: 8, color: "textMuted" },
|
|
936
|
+
tableHeader: {
|
|
937
|
+
face: "body",
|
|
938
|
+
size: 9,
|
|
939
|
+
weight: 700,
|
|
940
|
+
color: "primary"
|
|
941
|
+
},
|
|
942
|
+
tableCell: { face: "body", size: 9.5, color: "textPrimary" },
|
|
943
|
+
chartLabel: {
|
|
944
|
+
face: "body",
|
|
945
|
+
size: 9,
|
|
946
|
+
weight: 400,
|
|
947
|
+
color: "textSecondary"
|
|
948
|
+
},
|
|
949
|
+
tracker: {
|
|
950
|
+
face: "body",
|
|
951
|
+
size: 8,
|
|
952
|
+
case: "upper",
|
|
953
|
+
tracking: 6,
|
|
954
|
+
color: "textMuted"
|
|
955
|
+
},
|
|
956
|
+
source: { face: "body", size: 8, color: "textMuted" }
|
|
957
|
+
},
|
|
958
|
+
scale: {
|
|
959
|
+
a4: { base: 10.5, ratio: 1.2, baselinePt: 2 },
|
|
960
|
+
letter: { base: 10.5, ratio: 1.2, baselinePt: 2 }
|
|
961
|
+
}
|
|
962
|
+
},
|
|
963
|
+
spacing: {
|
|
964
|
+
basePt: 8,
|
|
965
|
+
blockGap: { tight: 4, normal: 8, loose: 16 },
|
|
966
|
+
canvas: {
|
|
967
|
+
a4: { safeAreaIn: 1, gutterIn: 0, columns: 12 },
|
|
968
|
+
letter: { safeAreaIn: 1, gutterIn: 0, columns: 12 }
|
|
969
|
+
}
|
|
970
|
+
},
|
|
971
|
+
chrome: {
|
|
972
|
+
runningHead: {
|
|
973
|
+
type: "tracker",
|
|
974
|
+
color: "textMuted",
|
|
975
|
+
rule: { weightPt: 0.5, color: "rule" },
|
|
976
|
+
alignment: "right"
|
|
977
|
+
},
|
|
978
|
+
tracker: {
|
|
979
|
+
type: "tracker",
|
|
980
|
+
color: "textMuted",
|
|
981
|
+
alignment: "right"
|
|
982
|
+
},
|
|
983
|
+
actionTitle: { type: "display", color: "primary" },
|
|
984
|
+
keyTakeaways: {
|
|
985
|
+
type: "label",
|
|
986
|
+
color: "primary",
|
|
987
|
+
rule: { weightPt: 2, color: "accent" },
|
|
988
|
+
padPt: 8
|
|
989
|
+
},
|
|
990
|
+
sourceLine: { type: "source", color: "textMuted" },
|
|
991
|
+
confidentialFooter: {
|
|
992
|
+
type: "footer",
|
|
993
|
+
color: "textMuted",
|
|
994
|
+
rule: { weightPt: 0.5, color: "rule" },
|
|
995
|
+
alignment: "left"
|
|
996
|
+
},
|
|
997
|
+
logoSlot: { alignment: "right" },
|
|
998
|
+
cover: {
|
|
999
|
+
type: "display",
|
|
1000
|
+
color: "primary",
|
|
1001
|
+
rule: { weightPt: 3, color: "accent" }
|
|
1002
|
+
}
|
|
1003
|
+
},
|
|
1004
|
+
motif: {
|
|
1005
|
+
kind: "rule",
|
|
1006
|
+
color: "accent",
|
|
1007
|
+
weightPt: 3,
|
|
1008
|
+
placement: "top"
|
|
1009
|
+
},
|
|
1010
|
+
styles: {
|
|
1011
|
+
normal: {
|
|
1012
|
+
font: "body",
|
|
1013
|
+
color: "textPrimary",
|
|
1014
|
+
lineSpacing: { type: "multiple", value: 1.2 },
|
|
1015
|
+
alignment: "left",
|
|
1016
|
+
spacing: { after: 8 }
|
|
1017
|
+
},
|
|
1018
|
+
title: {
|
|
1019
|
+
font: "heading",
|
|
1020
|
+
size: 26,
|
|
1021
|
+
bold: true,
|
|
1022
|
+
color: "primary",
|
|
1023
|
+
alignment: "left",
|
|
1024
|
+
lineSpacing: { type: "multiple", value: 1.05 },
|
|
1025
|
+
spacing: { before: 0, after: 6 }
|
|
1026
|
+
},
|
|
1027
|
+
subtitle: {
|
|
1028
|
+
font: "body",
|
|
1029
|
+
size: 13,
|
|
1030
|
+
color: "textSecondary",
|
|
1031
|
+
alignment: "left",
|
|
1032
|
+
lineSpacing: { type: "multiple", value: 1.2 },
|
|
1033
|
+
spacing: { before: 0, after: 18 }
|
|
1034
|
+
},
|
|
1035
|
+
heading1: {
|
|
1036
|
+
font: "heading",
|
|
1037
|
+
size: 16,
|
|
1038
|
+
bold: true,
|
|
1039
|
+
color: "primary",
|
|
1040
|
+
lineSpacing: { type: "multiple", value: 1.1 },
|
|
1041
|
+
spacing: { before: 24, after: 8 },
|
|
1042
|
+
keepNext: true,
|
|
1043
|
+
alignment: "left",
|
|
1044
|
+
borders: {
|
|
1045
|
+
bottom: { style: "single", size: 4, color: "rule", space: 4 }
|
|
1046
|
+
}
|
|
1047
|
+
},
|
|
1048
|
+
heading2: {
|
|
1049
|
+
font: "heading",
|
|
1050
|
+
size: 12.5,
|
|
1051
|
+
bold: true,
|
|
1052
|
+
color: "primary",
|
|
1053
|
+
spacing: { before: 16, after: 6 },
|
|
1054
|
+
keepNext: true,
|
|
1055
|
+
alignment: "left"
|
|
1056
|
+
},
|
|
1057
|
+
heading3: {
|
|
1058
|
+
font: "body",
|
|
1059
|
+
size: 11,
|
|
1060
|
+
bold: true,
|
|
1061
|
+
color: "primary",
|
|
1062
|
+
spacing: { before: 12, after: 4 },
|
|
1063
|
+
keepNext: true,
|
|
1064
|
+
alignment: "left"
|
|
1065
|
+
},
|
|
1066
|
+
heading4: {
|
|
1067
|
+
font: "body",
|
|
1068
|
+
size: 10.5,
|
|
1069
|
+
bold: true,
|
|
1070
|
+
color: "textSecondary",
|
|
1071
|
+
spacing: { before: 10, after: 4 },
|
|
1072
|
+
keepNext: true,
|
|
1073
|
+
alignment: "left"
|
|
1074
|
+
},
|
|
1075
|
+
heading5: {
|
|
1076
|
+
font: "body",
|
|
1077
|
+
size: 10.5,
|
|
1078
|
+
bold: false,
|
|
1079
|
+
italic: true,
|
|
1080
|
+
color: "textSecondary",
|
|
1081
|
+
spacing: { before: 8, after: 4 },
|
|
1082
|
+
keepNext: true,
|
|
1083
|
+
alignment: "left"
|
|
1084
|
+
},
|
|
1085
|
+
heading6: {
|
|
1086
|
+
font: "body",
|
|
1087
|
+
size: 9,
|
|
1088
|
+
bold: true,
|
|
1089
|
+
case: "upper",
|
|
1090
|
+
color: "textMuted",
|
|
1091
|
+
characterSpacing: { type: "expanded", value: 20 },
|
|
1092
|
+
spacing: { before: 8, after: 4 },
|
|
1093
|
+
keepNext: true,
|
|
1094
|
+
alignment: "left"
|
|
1095
|
+
},
|
|
1096
|
+
TOC1: {
|
|
1097
|
+
font: "body",
|
|
1098
|
+
size: 10.5,
|
|
1099
|
+
bold: true,
|
|
1100
|
+
color: "textPrimary",
|
|
1101
|
+
spacing: { before: 4, after: 3 },
|
|
1102
|
+
tabStops: [{ type: "right", position: 9026, leader: "none" }]
|
|
1103
|
+
},
|
|
1104
|
+
TOC2: {
|
|
1105
|
+
font: "body",
|
|
1106
|
+
size: 10.5,
|
|
1107
|
+
color: "textSecondary",
|
|
1108
|
+
indent: { left: 240 },
|
|
1109
|
+
spacing: { after: 2 },
|
|
1110
|
+
tabStops: [{ type: "right", position: 9026, leader: "none" }]
|
|
1111
|
+
},
|
|
1112
|
+
TOC3: {
|
|
1113
|
+
font: "body",
|
|
1114
|
+
size: 10,
|
|
1115
|
+
color: "textMuted",
|
|
1116
|
+
indent: { left: 480 },
|
|
1117
|
+
spacing: { after: 2 },
|
|
1118
|
+
tabStops: [{ type: "right", position: 9026, leader: "none" }]
|
|
1119
|
+
}
|
|
1120
|
+
},
|
|
1121
|
+
componentDefaults: {
|
|
1122
|
+
table: {
|
|
1123
|
+
width: 100,
|
|
1124
|
+
borderColor: "#C9CED6",
|
|
1125
|
+
borderSize: 0.5,
|
|
1126
|
+
hideBorders: { left: true, right: true, insideVertical: true },
|
|
1127
|
+
cellDefaults: {
|
|
1128
|
+
font: { size: 9.5 },
|
|
1129
|
+
padding: { top: 4, bottom: 4 },
|
|
1130
|
+
verticalAlignment: "middle"
|
|
1131
|
+
},
|
|
1132
|
+
headerCellDefaults: {
|
|
1133
|
+
color: "#1A1F26",
|
|
1134
|
+
font: { size: 9, bold: true },
|
|
1135
|
+
padding: { top: 0, bottom: 5 },
|
|
1136
|
+
verticalAlignment: "bottom",
|
|
1137
|
+
borderColor: { bottom: "#1A1F26" },
|
|
1138
|
+
borderSize: { bottom: 0.75 }
|
|
1139
|
+
}
|
|
1140
|
+
},
|
|
1141
|
+
list: {
|
|
1142
|
+
format: "bullet",
|
|
1143
|
+
bullet: "\u2022",
|
|
1144
|
+
spacing: { item: 2 }
|
|
1145
|
+
},
|
|
1146
|
+
image: {
|
|
1147
|
+
alignment: "center"
|
|
1148
|
+
},
|
|
1149
|
+
statistic: {
|
|
1150
|
+
alignment: "left"
|
|
1151
|
+
},
|
|
1152
|
+
section: {
|
|
1153
|
+
pageBreak: false
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
});
|
|
1159
|
+
|
|
883
1160
|
// src/templates/themes/index.ts
|
|
884
1161
|
import fs from "fs";
|
|
885
1162
|
import path from "path";
|
|
@@ -894,7 +1171,8 @@ function loadThemesFromJson() {
|
|
|
894
1171
|
const themes2 = {
|
|
895
1172
|
minimal: ensureThemeDefaults(minimal_docx_theme_default),
|
|
896
1173
|
devportal: ensureThemeDefaults(devportal_docx_theme_default),
|
|
897
|
-
vermilion: ensureThemeDefaults(vermilion_docx_theme_default)
|
|
1174
|
+
vermilion: ensureThemeDefaults(vermilion_docx_theme_default),
|
|
1175
|
+
consulting: ensureThemeDefaults(consulting_docx_theme_default)
|
|
898
1176
|
};
|
|
899
1177
|
try {
|
|
900
1178
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -932,7 +1210,7 @@ function loadThemesFromJson() {
|
|
|
932
1210
|
_themesCache = themes2;
|
|
933
1211
|
return themes2;
|
|
934
1212
|
}
|
|
935
|
-
var _themesCache, themes, getTheme, getThemeWithFallback, hasTheme, getThemeNames, minimalTheme, devportalTheme, vermilionTheme;
|
|
1213
|
+
var _themesCache, themes, getTheme, getThemeWithFallback, hasTheme, getThemeNames, minimalTheme, devportalTheme, vermilionTheme, consultingTheme;
|
|
936
1214
|
var init_themes = __esm({
|
|
937
1215
|
"src/templates/themes/index.ts"() {
|
|
938
1216
|
"use strict";
|
|
@@ -940,6 +1218,7 @@ var init_themes = __esm({
|
|
|
940
1218
|
init_minimal_docx_theme();
|
|
941
1219
|
init_devportal_docx_theme();
|
|
942
1220
|
init_vermilion_docx_theme();
|
|
1221
|
+
init_consulting_docx_theme();
|
|
943
1222
|
_themesCache = null;
|
|
944
1223
|
themes = loadThemesFromJson();
|
|
945
1224
|
getTheme = (themeName) => {
|
|
@@ -963,6 +1242,7 @@ var init_themes = __esm({
|
|
|
963
1242
|
minimalTheme = themes["minimal"];
|
|
964
1243
|
devportalTheme = themes["devportal"];
|
|
965
1244
|
vermilionTheme = themes["vermilion"];
|
|
1245
|
+
consultingTheme = themes["consulting"];
|
|
966
1246
|
}
|
|
967
1247
|
});
|
|
968
1248
|
|
|
@@ -1279,6 +1559,43 @@ var init_layoutUtils = __esm({
|
|
|
1279
1559
|
}
|
|
1280
1560
|
});
|
|
1281
1561
|
|
|
1562
|
+
// src/utils/generationContext.ts
|
|
1563
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
1564
|
+
import { isAbsolute, resolve } from "path";
|
|
1565
|
+
function runWithBaseDir(baseDir, callback) {
|
|
1566
|
+
return baseDir === void 0 ? callback() : baseDirStorage.run(resolve(baseDir), callback);
|
|
1567
|
+
}
|
|
1568
|
+
function resolveFromBaseDir(filePath) {
|
|
1569
|
+
const base = baseDirStorage.getStore();
|
|
1570
|
+
if (!base || isAbsolute(filePath)) return filePath;
|
|
1571
|
+
return resolve(base, filePath);
|
|
1572
|
+
}
|
|
1573
|
+
function runWithWarnings(warnings, callback) {
|
|
1574
|
+
return warnings === void 0 ? callback() : warningsStorage.run(warnings, callback);
|
|
1575
|
+
}
|
|
1576
|
+
function reportWarning(component, code, message, context) {
|
|
1577
|
+
const warnings = warningsStorage.getStore();
|
|
1578
|
+
if (warnings) {
|
|
1579
|
+
warnings.push({
|
|
1580
|
+
component,
|
|
1581
|
+
message,
|
|
1582
|
+
severity: "warning",
|
|
1583
|
+
context: { code, ...context }
|
|
1584
|
+
});
|
|
1585
|
+
return;
|
|
1586
|
+
}
|
|
1587
|
+
console.warn(`[json-to-docx] [${code}] ${message}`);
|
|
1588
|
+
}
|
|
1589
|
+
var generationDateStorage, baseDirStorage, warningsStorage;
|
|
1590
|
+
var init_generationContext = __esm({
|
|
1591
|
+
"src/utils/generationContext.ts"() {
|
|
1592
|
+
"use strict";
|
|
1593
|
+
generationDateStorage = new AsyncLocalStorage();
|
|
1594
|
+
baseDirStorage = new AsyncLocalStorage();
|
|
1595
|
+
warningsStorage = new AsyncLocalStorage();
|
|
1596
|
+
}
|
|
1597
|
+
});
|
|
1598
|
+
|
|
1282
1599
|
// src/themes/json/parser.ts
|
|
1283
1600
|
import { validateThemeJson } from "@json-to-office/shared-docx/validation/unified";
|
|
1284
1601
|
var ThemeValidationError, ThemeParseError, ThemeParser;
|
|
@@ -4688,7 +5005,10 @@ async function resolveDocumentFonts(document, theme, fonts, warnings, forceMater
|
|
|
4688
5005
|
}
|
|
4689
5006
|
|
|
4690
5007
|
// src/core/generateFromIr.ts
|
|
4691
|
-
import {
|
|
5008
|
+
import {
|
|
5009
|
+
toChartFontFaces,
|
|
5010
|
+
toRasterizeFontFaces
|
|
5011
|
+
} from "@json-to-office/shared/fonts/node";
|
|
4692
5012
|
|
|
4693
5013
|
// src/core/prerasterizeVisuals.ts
|
|
4694
5014
|
import {
|
|
@@ -5106,6 +5426,87 @@ async function prerasterizeVisuals(root, serviceConfig, options = {}) {
|
|
|
5106
5426
|
return map;
|
|
5107
5427
|
}
|
|
5108
5428
|
|
|
5429
|
+
// src/core/componentTransform.ts
|
|
5430
|
+
async function transformComponents(doc, replace) {
|
|
5431
|
+
return await walk(doc, replace);
|
|
5432
|
+
}
|
|
5433
|
+
async function walk(node, replace) {
|
|
5434
|
+
if (Array.isArray(node)) {
|
|
5435
|
+
return Promise.all(node.map((child) => walk(child, replace)));
|
|
5436
|
+
}
|
|
5437
|
+
if (!node || typeof node !== "object") return node;
|
|
5438
|
+
const obj = node;
|
|
5439
|
+
if (typeof obj.name === "string" && obj.props) {
|
|
5440
|
+
const replacement = await replace(obj);
|
|
5441
|
+
if (replacement) return replacement;
|
|
5442
|
+
}
|
|
5443
|
+
const next = { ...obj };
|
|
5444
|
+
if (Array.isArray(obj.children)) {
|
|
5445
|
+
next.children = await walk(obj.children, replace);
|
|
5446
|
+
}
|
|
5447
|
+
if (obj.props && typeof obj.props === "object") {
|
|
5448
|
+
const props = obj.props;
|
|
5449
|
+
let changed = false;
|
|
5450
|
+
const nextProps = { ...props };
|
|
5451
|
+
for (const key of ["header", "footer"]) {
|
|
5452
|
+
if (Array.isArray(props[key])) {
|
|
5453
|
+
nextProps[key] = await walk(props[key], replace);
|
|
5454
|
+
changed = true;
|
|
5455
|
+
}
|
|
5456
|
+
}
|
|
5457
|
+
if (Array.isArray(props.columns)) {
|
|
5458
|
+
nextProps.columns = await Promise.all(
|
|
5459
|
+
props.columns.map(
|
|
5460
|
+
(column) => walkColumn(column, replace)
|
|
5461
|
+
)
|
|
5462
|
+
);
|
|
5463
|
+
changed = true;
|
|
5464
|
+
}
|
|
5465
|
+
if (changed) next.props = nextProps;
|
|
5466
|
+
}
|
|
5467
|
+
return next;
|
|
5468
|
+
}
|
|
5469
|
+
async function walkColumn(column, replace) {
|
|
5470
|
+
if (!column || typeof column !== "object") return column;
|
|
5471
|
+
const source = column;
|
|
5472
|
+
const next = { ...source };
|
|
5473
|
+
const header = source.header;
|
|
5474
|
+
if (header && typeof header === "object" && "content" in header) {
|
|
5475
|
+
next.header = { ...header, content: await walk(header.content, replace) };
|
|
5476
|
+
}
|
|
5477
|
+
if (Array.isArray(source.cells)) {
|
|
5478
|
+
next.cells = await Promise.all(
|
|
5479
|
+
source.cells.map(async (cell) => {
|
|
5480
|
+
if (cell && typeof cell === "object" && "content" in cell) {
|
|
5481
|
+
const source2 = cell;
|
|
5482
|
+
return { ...source2, content: await walk(source2.content, replace) };
|
|
5483
|
+
}
|
|
5484
|
+
return cell;
|
|
5485
|
+
})
|
|
5486
|
+
);
|
|
5487
|
+
}
|
|
5488
|
+
return next;
|
|
5489
|
+
}
|
|
5490
|
+
function withNodeIdentity(original, replacement) {
|
|
5491
|
+
const out = { ...replacement };
|
|
5492
|
+
if (original.id !== void 0) out.id = original.id;
|
|
5493
|
+
if (original.enabled !== void 0) out.enabled = original.enabled;
|
|
5494
|
+
return out;
|
|
5495
|
+
}
|
|
5496
|
+
function containsComponent(root, name) {
|
|
5497
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
5498
|
+
const visit = (node) => {
|
|
5499
|
+
if (!node || typeof node !== "object" || seen.has(node)) return false;
|
|
5500
|
+
seen.add(node);
|
|
5501
|
+
if (Array.isArray(node)) return node.some(visit);
|
|
5502
|
+
const obj = node;
|
|
5503
|
+
if (typeof obj.name === "string" && obj.enabled === false) return false;
|
|
5504
|
+
if (obj.name === name && obj.props !== void 0) return true;
|
|
5505
|
+
return Object.values(obj).some(visit);
|
|
5506
|
+
};
|
|
5507
|
+
return visit(root);
|
|
5508
|
+
}
|
|
5509
|
+
|
|
5109
5510
|
// src/core/desugarExternals.ts
|
|
5110
5511
|
import {
|
|
5111
5512
|
clampVisualDpi as clampVisualDpi2,
|
|
@@ -5117,6 +5518,14 @@ import {
|
|
|
5117
5518
|
|
|
5118
5519
|
// src/components/highcharts.ts
|
|
5119
5520
|
init_colorUtils();
|
|
5521
|
+
init_layoutUtils();
|
|
5522
|
+
import {
|
|
5523
|
+
chartFamilyResolver,
|
|
5524
|
+
chartPointsPerPixel,
|
|
5525
|
+
POINTS_PER_PIXEL_96DPI,
|
|
5526
|
+
withChartFontFaceCss,
|
|
5527
|
+
withChartTypography
|
|
5528
|
+
} from "@json-to-office/shared";
|
|
5120
5529
|
var DEFAULT_EXPORT_SERVER_URL = "http://localhost:7801";
|
|
5121
5530
|
async function generateChart(config, servicesConfig) {
|
|
5122
5531
|
if (!isNodeEnvironment()) {
|
|
@@ -5180,84 +5589,81 @@ function withThemeColors(config, theme) {
|
|
|
5180
5589
|
options: { ...config.options, colors: palette }
|
|
5181
5590
|
};
|
|
5182
5591
|
}
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
const
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
}
|
|
5194
|
-
|
|
5195
|
-
// src/core/componentTransform.ts
|
|
5196
|
-
async function transformComponents(doc, replace) {
|
|
5197
|
-
return await walk(doc, replace);
|
|
5198
|
-
}
|
|
5199
|
-
async function walk(node, replace) {
|
|
5200
|
-
if (Array.isArray(node)) {
|
|
5201
|
-
return Promise.all(node.map((child) => walk(child, replace)));
|
|
5202
|
-
}
|
|
5203
|
-
if (!node || typeof node !== "object") return node;
|
|
5204
|
-
const obj = node;
|
|
5205
|
-
if (typeof obj.name === "string" && obj.props) {
|
|
5206
|
-
const replacement = await replace(obj);
|
|
5207
|
-
if (replacement) return replacement;
|
|
5592
|
+
var POINTS_PER_TWIP = 1 / 20;
|
|
5593
|
+
var POINTS_PER_PIXEL = POINTS_PER_PIXEL_96DPI;
|
|
5594
|
+
function placedWidthPt(config, theme) {
|
|
5595
|
+
const { width, height } = config;
|
|
5596
|
+
const chart = config.options.chart;
|
|
5597
|
+
if (typeof width === "number") return width * POINTS_PER_PIXEL;
|
|
5598
|
+
if (typeof width === "string") {
|
|
5599
|
+
const page = getPageSetup(theme);
|
|
5600
|
+
const contentWidthPt = (page.size.width - page.margin.left - page.margin.right) * POINTS_PER_TWIP;
|
|
5601
|
+
return parseFloat(width) / 100 * contentWidthPt;
|
|
5208
5602
|
}
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
next.children = await walk(obj.children, replace);
|
|
5603
|
+
if (typeof height === "number" && chart.height > 0) {
|
|
5604
|
+
return height / chart.height * chart.width * POINTS_PER_PIXEL;
|
|
5212
5605
|
}
|
|
5213
|
-
|
|
5214
|
-
const props = obj.props;
|
|
5215
|
-
let changed = false;
|
|
5216
|
-
const nextProps = { ...props };
|
|
5217
|
-
for (const key of ["header", "footer"]) {
|
|
5218
|
-
if (Array.isArray(props[key])) {
|
|
5219
|
-
nextProps[key] = await walk(props[key], replace);
|
|
5220
|
-
changed = true;
|
|
5221
|
-
}
|
|
5222
|
-
}
|
|
5223
|
-
if (Array.isArray(props.columns)) {
|
|
5224
|
-
nextProps.columns = await Promise.all(
|
|
5225
|
-
props.columns.map(
|
|
5226
|
-
(column) => walkColumn(column, replace)
|
|
5227
|
-
)
|
|
5228
|
-
);
|
|
5229
|
-
changed = true;
|
|
5230
|
-
}
|
|
5231
|
-
if (changed) next.props = nextProps;
|
|
5232
|
-
}
|
|
5233
|
-
return next;
|
|
5606
|
+
return void 0;
|
|
5234
5607
|
}
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
const
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5608
|
+
function toHex(token, theme) {
|
|
5609
|
+
return `#${resolveColor(token, theme)}`;
|
|
5610
|
+
}
|
|
5611
|
+
function themeChartTypography(theme) {
|
|
5612
|
+
const styles = theme.styles ?? {};
|
|
5613
|
+
const family = chartFamilyResolver(theme);
|
|
5614
|
+
const bodyPt = styles.normal?.size ?? theme.fonts.body.size ?? 11;
|
|
5615
|
+
const label = styles.chartLabel;
|
|
5616
|
+
const heading = styles.heading3;
|
|
5617
|
+
const labelPt = label?.size ?? Math.max(bodyPt - 1, 6);
|
|
5618
|
+
return {
|
|
5619
|
+
bodyFamily: family(theme.fonts.body.family),
|
|
5620
|
+
headingFamily: family(theme.fonts.heading.family),
|
|
5621
|
+
textColor: toHex("textPrimary", theme),
|
|
5622
|
+
mutedColor: toHex("textSecondary", theme),
|
|
5623
|
+
labelPt,
|
|
5624
|
+
labelWeight: label?.fontWeight ?? (label?.bold ? 700 : void 0),
|
|
5625
|
+
titlePt: heading?.size ?? bodyPt + 2,
|
|
5626
|
+
titleWeight: heading?.fontWeight ?? (heading?.bold === false ? void 0 : 700),
|
|
5627
|
+
sourcePt: styles.source?.size ?? Math.max(labelPt - 1, 6)
|
|
5628
|
+
};
|
|
5629
|
+
}
|
|
5630
|
+
function withThemeTypography(config, theme) {
|
|
5631
|
+
if (!theme?.fonts?.body?.family || !theme.fonts.heading?.family) {
|
|
5632
|
+
return config;
|
|
5253
5633
|
}
|
|
5254
|
-
return
|
|
5634
|
+
return {
|
|
5635
|
+
...config,
|
|
5636
|
+
options: withChartTypography(
|
|
5637
|
+
config.options,
|
|
5638
|
+
themeChartTypography(theme),
|
|
5639
|
+
chartPointsPerPixel(
|
|
5640
|
+
config.options.chart.width,
|
|
5641
|
+
placedWidthPt(config, theme)
|
|
5642
|
+
)
|
|
5643
|
+
)
|
|
5644
|
+
};
|
|
5255
5645
|
}
|
|
5256
|
-
function
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5646
|
+
function withChartFontFaces(config, theme, faces) {
|
|
5647
|
+
if (!faces?.length || !theme?.fonts) return config;
|
|
5648
|
+
return withChartFontFaceCss(config, faces, [
|
|
5649
|
+
theme.fonts.body.family,
|
|
5650
|
+
theme.fonts.heading.family
|
|
5651
|
+
]);
|
|
5652
|
+
}
|
|
5653
|
+
async function renderChartToImageProps(props, theme, servicesConfig, chartFonts) {
|
|
5654
|
+
const config = withChartFontFaces(
|
|
5655
|
+
withThemeTypography(withThemeColors(props, theme), theme),
|
|
5656
|
+
theme,
|
|
5657
|
+
chartFonts
|
|
5658
|
+
);
|
|
5659
|
+
const chart = await generateChart(config, servicesConfig);
|
|
5660
|
+
const hasConfigDimensions = config.width !== void 0 || config.height !== void 0;
|
|
5661
|
+
return {
|
|
5662
|
+
base64: chart.base64DataUri,
|
|
5663
|
+
width: hasConfigDimensions ? config.width : chart.width,
|
|
5664
|
+
height: hasConfigDimensions ? config.height : chart.height,
|
|
5665
|
+
alignment: "center"
|
|
5666
|
+
};
|
|
5261
5667
|
}
|
|
5262
5668
|
|
|
5263
5669
|
// src/core/desugarExternals.ts
|
|
@@ -5289,7 +5695,8 @@ async function desugarExternals(document, options) {
|
|
|
5289
5695
|
props: await renderChartToImageProps(
|
|
5290
5696
|
node.props,
|
|
5291
5697
|
options.theme,
|
|
5292
|
-
options.services?.highcharts
|
|
5698
|
+
options.services?.highcharts,
|
|
5699
|
+
options.chartFonts
|
|
5293
5700
|
)
|
|
5294
5701
|
});
|
|
5295
5702
|
}
|
|
@@ -8047,6 +8454,641 @@ function emptyToUndefined(formatting) {
|
|
|
8047
8454
|
return entries.length === 0 ? void 0 : Object.fromEntries(entries);
|
|
8048
8455
|
}
|
|
8049
8456
|
|
|
8457
|
+
// src/blocks/index.ts
|
|
8458
|
+
import {
|
|
8459
|
+
COVER_BUDGET,
|
|
8460
|
+
KEY_TAKEAWAYS_BUDGET,
|
|
8461
|
+
RUNNING_HEAD_BUDGET,
|
|
8462
|
+
SECTION_OPENER_BUDGET
|
|
8463
|
+
} from "@json-to-office/shared-docx";
|
|
8464
|
+
|
|
8465
|
+
// src/blocks/cover.ts
|
|
8466
|
+
init_widthUtils();
|
|
8467
|
+
|
|
8468
|
+
// src/blocks/recipe.ts
|
|
8469
|
+
var MIN_RULE_PT = 0.25;
|
|
8470
|
+
var MAX_RULE_PT = 12;
|
|
8471
|
+
function clampRule(weightPt) {
|
|
8472
|
+
return Math.min(MAX_RULE_PT, Math.max(MIN_RULE_PT, weightPt));
|
|
8473
|
+
}
|
|
8474
|
+
var FALLBACK_EYEBROW_FONT = {
|
|
8475
|
+
size: 9,
|
|
8476
|
+
bold: true,
|
|
8477
|
+
color: "accent",
|
|
8478
|
+
case: "upper"
|
|
8479
|
+
};
|
|
8480
|
+
function hasStyle(theme, role) {
|
|
8481
|
+
const styles = theme.styles;
|
|
8482
|
+
return styles?.[role] !== void 0;
|
|
8483
|
+
}
|
|
8484
|
+
function roleProps(theme, role, fallbackFont, color) {
|
|
8485
|
+
if (hasStyle(theme, role)) {
|
|
8486
|
+
return {
|
|
8487
|
+
themeStyle: role,
|
|
8488
|
+
...color !== void 0 && { font: { color } }
|
|
8489
|
+
};
|
|
8490
|
+
}
|
|
8491
|
+
return { font: { ...fallbackFont, ...color !== void 0 && { color } } };
|
|
8492
|
+
}
|
|
8493
|
+
|
|
8494
|
+
// src/blocks/cover.ts
|
|
8495
|
+
var DROP_SHARE = 0.3;
|
|
8496
|
+
var DROP_SHARE_WITH_LOGO = 0.22;
|
|
8497
|
+
var DEFAULT_LOGO_WIDTH = "25%";
|
|
8498
|
+
var FALLBACK = {
|
|
8499
|
+
ruleWeightPt: 3,
|
|
8500
|
+
ruleColor: "accent",
|
|
8501
|
+
padPt: 12,
|
|
8502
|
+
metaFont: { size: 9, color: "textSecondary" }
|
|
8503
|
+
};
|
|
8504
|
+
function compileCover(props, theme) {
|
|
8505
|
+
const recipe = theme.chrome?.cover;
|
|
8506
|
+
const ruleWeightPt = recipe?.rule?.weightPt ?? FALLBACK.ruleWeightPt;
|
|
8507
|
+
const padPt = recipe?.padPt ?? FALLBACK.padPt;
|
|
8508
|
+
const heightPt = getAvailableHeightTwips(theme) / 20;
|
|
8509
|
+
const dropPt = Math.round(
|
|
8510
|
+
heightPt * (props.logo ? DROP_SHARE_WITH_LOGO : DROP_SHARE)
|
|
8511
|
+
);
|
|
8512
|
+
const children = [];
|
|
8513
|
+
const sourceMap = {};
|
|
8514
|
+
const emit = (child, slots) => {
|
|
8515
|
+
const index = children.push(child) - 1;
|
|
8516
|
+
sourceMap[`/children/${index}`] = "";
|
|
8517
|
+
for (const [emitted, authored] of Object.entries(slots)) {
|
|
8518
|
+
sourceMap[`/children/${index}${emitted}`] = authored;
|
|
8519
|
+
}
|
|
8520
|
+
};
|
|
8521
|
+
if (props.logo) {
|
|
8522
|
+
const { width, height, ...source } = props.logo;
|
|
8523
|
+
emit(
|
|
8524
|
+
{
|
|
8525
|
+
name: "image",
|
|
8526
|
+
props: {
|
|
8527
|
+
...source,
|
|
8528
|
+
width: width ?? DEFAULT_LOGO_WIDTH,
|
|
8529
|
+
...height !== void 0 && { height },
|
|
8530
|
+
alignment: theme.chrome?.logoSlot?.alignment ?? "left",
|
|
8531
|
+
spacing: { before: 0, after: 0 }
|
|
8532
|
+
}
|
|
8533
|
+
},
|
|
8534
|
+
{ "/props": "/props/logo" }
|
|
8535
|
+
);
|
|
8536
|
+
}
|
|
8537
|
+
const drawsRule = ruleWeightPt > 0;
|
|
8538
|
+
if (drawsRule) {
|
|
8539
|
+
emit(
|
|
8540
|
+
{
|
|
8541
|
+
name: "divider",
|
|
8542
|
+
props: {
|
|
8543
|
+
thickness: clampRule(ruleWeightPt),
|
|
8544
|
+
color: recipe?.rule?.color ?? FALLBACK.ruleColor,
|
|
8545
|
+
spacing: { before: dropPt, after: padPt }
|
|
8546
|
+
}
|
|
8547
|
+
},
|
|
8548
|
+
{}
|
|
8549
|
+
);
|
|
8550
|
+
}
|
|
8551
|
+
let dropPending = !drawsRule;
|
|
8552
|
+
const before = () => {
|
|
8553
|
+
if (!dropPending) return {};
|
|
8554
|
+
dropPending = false;
|
|
8555
|
+
return { before: dropPt };
|
|
8556
|
+
};
|
|
8557
|
+
if (props.client) {
|
|
8558
|
+
emit(
|
|
8559
|
+
{
|
|
8560
|
+
name: "paragraph",
|
|
8561
|
+
props: {
|
|
8562
|
+
text: props.client,
|
|
8563
|
+
keepNext: true,
|
|
8564
|
+
spacing: { ...before(), after: 4 },
|
|
8565
|
+
...roleProps(theme, "eyebrow", FALLBACK_EYEBROW_FONT)
|
|
8566
|
+
}
|
|
8567
|
+
},
|
|
8568
|
+
{ "/props/text": "/props/client" }
|
|
8569
|
+
);
|
|
8570
|
+
}
|
|
8571
|
+
const titleRole = recipe?.type && hasStyle(theme, recipe.type) ? recipe.type : "title";
|
|
8572
|
+
emit(
|
|
8573
|
+
{
|
|
8574
|
+
name: "paragraph",
|
|
8575
|
+
props: {
|
|
8576
|
+
text: props.title,
|
|
8577
|
+
keepNext: true,
|
|
8578
|
+
...dropPending && { spacing: before() },
|
|
8579
|
+
...roleProps(theme, titleRole, { size: 26, bold: true }, recipe?.color)
|
|
8580
|
+
}
|
|
8581
|
+
},
|
|
8582
|
+
{ "/props/text": "/props/title" }
|
|
8583
|
+
);
|
|
8584
|
+
if (props.subtitle) {
|
|
8585
|
+
emit(
|
|
8586
|
+
{
|
|
8587
|
+
name: "paragraph",
|
|
8588
|
+
props: {
|
|
8589
|
+
text: props.subtitle,
|
|
8590
|
+
keepNext: true,
|
|
8591
|
+
...roleProps(theme, "subtitle", { size: 13, color: "textSecondary" })
|
|
8592
|
+
}
|
|
8593
|
+
},
|
|
8594
|
+
{ "/props/text": "/props/subtitle" }
|
|
8595
|
+
);
|
|
8596
|
+
}
|
|
8597
|
+
const meta = [props.date, props.confidentiality].filter(
|
|
8598
|
+
(part) => typeof part === "string" && part !== ""
|
|
8599
|
+
);
|
|
8600
|
+
if (meta.length > 0) {
|
|
8601
|
+
emit(
|
|
8602
|
+
{
|
|
8603
|
+
name: "paragraph",
|
|
8604
|
+
props: {
|
|
8605
|
+
text: meta.join(" \xB7 "),
|
|
8606
|
+
spacing: { before: padPt, after: 0 },
|
|
8607
|
+
...roleProps(theme, "label", FALLBACK.metaFont)
|
|
8608
|
+
}
|
|
8609
|
+
},
|
|
8610
|
+
{
|
|
8611
|
+
"/props/text": props.date ? "/props/date" : "/props/confidentiality"
|
|
8612
|
+
}
|
|
8613
|
+
);
|
|
8614
|
+
}
|
|
8615
|
+
return { children, sourceMap };
|
|
8616
|
+
}
|
|
8617
|
+
|
|
8618
|
+
// src/blocks/keyTakeaways.ts
|
|
8619
|
+
var KEY_TAKEAWAYS_DEFAULT_LABEL = "Key takeaways";
|
|
8620
|
+
var FALLBACK_RECIPE = {
|
|
8621
|
+
ruleWeightPt: 1.5,
|
|
8622
|
+
ruleColor: "accent",
|
|
8623
|
+
padPt: 6,
|
|
8624
|
+
type: "label"
|
|
8625
|
+
};
|
|
8626
|
+
function compileKeyTakeaways(props, theme) {
|
|
8627
|
+
const recipe = theme.chrome?.keyTakeaways;
|
|
8628
|
+
const labelRole = recipe?.type ?? FALLBACK_RECIPE.type;
|
|
8629
|
+
const labelStyle = hasStyle(theme, labelRole);
|
|
8630
|
+
const ruleWeightPt = clampRule(
|
|
8631
|
+
recipe?.rule?.weightPt ?? FALLBACK_RECIPE.ruleWeightPt
|
|
8632
|
+
);
|
|
8633
|
+
const ruleColor = recipe?.rule?.color ?? recipe?.color ?? FALLBACK_RECIPE.ruleColor;
|
|
8634
|
+
const padPt = recipe?.padPt ?? FALLBACK_RECIPE.padPt;
|
|
8635
|
+
const children = [
|
|
8636
|
+
{
|
|
8637
|
+
name: "divider",
|
|
8638
|
+
props: {
|
|
8639
|
+
thickness: ruleWeightPt,
|
|
8640
|
+
color: ruleColor,
|
|
8641
|
+
spacing: { before: 12, after: padPt }
|
|
8642
|
+
}
|
|
8643
|
+
},
|
|
8644
|
+
{
|
|
8645
|
+
name: "paragraph",
|
|
8646
|
+
props: {
|
|
8647
|
+
text: props.label ?? KEY_TAKEAWAYS_DEFAULT_LABEL,
|
|
8648
|
+
keepNext: true,
|
|
8649
|
+
spacing: { after: 4 },
|
|
8650
|
+
// The label role when the theme resolves one; a bold run in the
|
|
8651
|
+
// recipe's colour otherwise, so the label still reads as a label.
|
|
8652
|
+
...labelStyle ? { themeStyle: labelRole } : {
|
|
8653
|
+
font: {
|
|
8654
|
+
bold: true,
|
|
8655
|
+
...recipe?.color !== void 0 && { color: recipe.color }
|
|
8656
|
+
}
|
|
8657
|
+
}
|
|
8658
|
+
}
|
|
8659
|
+
},
|
|
8660
|
+
{
|
|
8661
|
+
name: "list",
|
|
8662
|
+
props: { items: [...props.items] }
|
|
8663
|
+
},
|
|
8664
|
+
{
|
|
8665
|
+
name: "divider",
|
|
8666
|
+
props: {
|
|
8667
|
+
thickness: 0.5,
|
|
8668
|
+
color: "borderPrimary",
|
|
8669
|
+
spacing: { before: padPt, after: 12 }
|
|
8670
|
+
}
|
|
8671
|
+
}
|
|
8672
|
+
];
|
|
8673
|
+
return {
|
|
8674
|
+
children,
|
|
8675
|
+
sourceMap: {
|
|
8676
|
+
"/children/0": "",
|
|
8677
|
+
"/children/1": "",
|
|
8678
|
+
"/children/1/props/text": "/props/label",
|
|
8679
|
+
"/children/2": "",
|
|
8680
|
+
"/children/2/props/items": "/props/items",
|
|
8681
|
+
"/children/3": ""
|
|
8682
|
+
}
|
|
8683
|
+
};
|
|
8684
|
+
}
|
|
8685
|
+
|
|
8686
|
+
// src/blocks/runningHead.ts
|
|
8687
|
+
init_styles();
|
|
8688
|
+
init_widthUtils();
|
|
8689
|
+
var FALLBACK2 = {
|
|
8690
|
+
headFont: { size: 8, color: "textMuted", case: "upper" },
|
|
8691
|
+
footFont: { size: 8, color: "textMuted" },
|
|
8692
|
+
ruleWeightPt: 0.5,
|
|
8693
|
+
ruleColor: "border"
|
|
8694
|
+
};
|
|
8695
|
+
var PAGE_OF_TOTAL = "{PAGE} / {TOTAL_PAGES}";
|
|
8696
|
+
function sectionMeasureTwips(theme, page) {
|
|
8697
|
+
if (!page || page.size === void 0 && page.margins === void 0) {
|
|
8698
|
+
return getAvailableWidthTwips(theme);
|
|
8699
|
+
}
|
|
8700
|
+
const width = page.size ? getPageDimensions(page.size).width : getPageDimensions(theme.page.size).width;
|
|
8701
|
+
const margins = getDocumentMargins(theme);
|
|
8702
|
+
const left = page.margins?.left ?? margins.left ?? 1440;
|
|
8703
|
+
const right = page.margins?.right ?? margins.right ?? 1440;
|
|
8704
|
+
return Math.max(0, width - left - right);
|
|
8705
|
+
}
|
|
8706
|
+
function compileRunningHead(props, theme, scope) {
|
|
8707
|
+
const measure = sectionMeasureTwips(theme, scope.page);
|
|
8708
|
+
const head = theme.chrome?.runningHead;
|
|
8709
|
+
const foot = theme.chrome?.confidentialFooter;
|
|
8710
|
+
const slot = (name) => props[name] !== void 0 ? `${scope.block}/props/${name}` : void 0;
|
|
8711
|
+
const header = [];
|
|
8712
|
+
const headerMap = {};
|
|
8713
|
+
const title = props.title ?? scope.documentTitle ?? "";
|
|
8714
|
+
const tracker = scope.opener?.text ?? props.tracker ?? "";
|
|
8715
|
+
if (title !== "" || tracker !== "") {
|
|
8716
|
+
const both = title !== "" && tracker !== "";
|
|
8717
|
+
header.push({
|
|
8718
|
+
name: "paragraph",
|
|
8719
|
+
props: {
|
|
8720
|
+
text: both ? `${title} ${tracker}` : title || tracker,
|
|
8721
|
+
...both ? { tabStops: [{ type: "right", position: measure }] } : { alignment: title !== "" ? "left" : head?.alignment ?? "right" },
|
|
8722
|
+
spacing: { before: 0, after: 0 },
|
|
8723
|
+
...roleProps(
|
|
8724
|
+
theme,
|
|
8725
|
+
head?.type ?? "tracker",
|
|
8726
|
+
FALLBACK2.headFont,
|
|
8727
|
+
head?.color
|
|
8728
|
+
)
|
|
8729
|
+
}
|
|
8730
|
+
});
|
|
8731
|
+
headerMap["/0"] = scope.block;
|
|
8732
|
+
headerMap["/0/props/text"] = (tracker !== "" ? scope.opener?.slot ?? slot("tracker") : slot("title")) ?? scope.block;
|
|
8733
|
+
}
|
|
8734
|
+
const headRule = head?.rule?.weightPt ?? FALLBACK2.ruleWeightPt;
|
|
8735
|
+
if (headRule > 0) {
|
|
8736
|
+
header.push({
|
|
8737
|
+
name: "divider",
|
|
8738
|
+
props: {
|
|
8739
|
+
thickness: clampRule(headRule),
|
|
8740
|
+
color: head?.rule?.color ?? FALLBACK2.ruleColor,
|
|
8741
|
+
spacing: { before: 2, after: 0 }
|
|
8742
|
+
}
|
|
8743
|
+
});
|
|
8744
|
+
headerMap[`/${header.length - 1}`] = scope.block;
|
|
8745
|
+
}
|
|
8746
|
+
const footer = [];
|
|
8747
|
+
const footerMap = {};
|
|
8748
|
+
const footRule = foot?.rule?.weightPt ?? FALLBACK2.ruleWeightPt;
|
|
8749
|
+
if (footRule > 0) {
|
|
8750
|
+
footer.push({
|
|
8751
|
+
name: "divider",
|
|
8752
|
+
props: {
|
|
8753
|
+
thickness: clampRule(footRule),
|
|
8754
|
+
color: foot?.rule?.color ?? FALLBACK2.ruleColor,
|
|
8755
|
+
spacing: { before: 0, after: 4 }
|
|
8756
|
+
}
|
|
8757
|
+
});
|
|
8758
|
+
footerMap["/0"] = scope.block;
|
|
8759
|
+
}
|
|
8760
|
+
const parts = [
|
|
8761
|
+
props.confidentiality ?? "",
|
|
8762
|
+
props.pageNumbers === false ? "" : PAGE_OF_TOTAL,
|
|
8763
|
+
props.date ?? ""
|
|
8764
|
+
];
|
|
8765
|
+
const present = parts.filter((part) => part !== "");
|
|
8766
|
+
if (present.length > 0) {
|
|
8767
|
+
const single = present.length === 1;
|
|
8768
|
+
const alignment2 = present[0] === PAGE_OF_TOTAL ? "center" : foot?.alignment ?? "left";
|
|
8769
|
+
footer.push({
|
|
8770
|
+
name: "paragraph",
|
|
8771
|
+
props: {
|
|
8772
|
+
text: single ? present[0] : parts.join(" ").replace(/\t+$/, ""),
|
|
8773
|
+
...single ? { alignment: alignment2 } : {
|
|
8774
|
+
tabStops: [
|
|
8775
|
+
{ type: "center", position: Math.round(measure / 2) },
|
|
8776
|
+
{ type: "right", position: measure }
|
|
8777
|
+
]
|
|
8778
|
+
},
|
|
8779
|
+
spacing: { before: 0, after: 0 },
|
|
8780
|
+
...roleProps(
|
|
8781
|
+
theme,
|
|
8782
|
+
foot?.type ?? "footer",
|
|
8783
|
+
FALLBACK2.footFont,
|
|
8784
|
+
foot?.color
|
|
8785
|
+
)
|
|
8786
|
+
}
|
|
8787
|
+
});
|
|
8788
|
+
const index = footer.length - 1;
|
|
8789
|
+
footerMap[`/${index}`] = scope.block;
|
|
8790
|
+
footerMap[`/${index}/props/text`] = slot("confidentiality") ?? slot("date") ?? scope.block;
|
|
8791
|
+
}
|
|
8792
|
+
return {
|
|
8793
|
+
header: { children: header, sourceMap: headerMap },
|
|
8794
|
+
footer: { children: footer, sourceMap: footerMap }
|
|
8795
|
+
};
|
|
8796
|
+
}
|
|
8797
|
+
|
|
8798
|
+
// src/blocks/sectionOpener.ts
|
|
8799
|
+
function compileSectionOpener(props, theme) {
|
|
8800
|
+
const children = [];
|
|
8801
|
+
const sourceMap = {};
|
|
8802
|
+
const pageBreak = props.pageBreak === true;
|
|
8803
|
+
if (props.number !== void 0) {
|
|
8804
|
+
children.push({
|
|
8805
|
+
name: "paragraph",
|
|
8806
|
+
props: {
|
|
8807
|
+
text: String(props.number),
|
|
8808
|
+
keepNext: true,
|
|
8809
|
+
spacing: { after: 2 },
|
|
8810
|
+
...pageBreak && { pageBreak: true },
|
|
8811
|
+
...roleProps(theme, "eyebrow", FALLBACK_EYEBROW_FONT)
|
|
8812
|
+
}
|
|
8813
|
+
});
|
|
8814
|
+
sourceMap["/children/0"] = "";
|
|
8815
|
+
sourceMap["/children/0/props/text"] = "/props/number";
|
|
8816
|
+
}
|
|
8817
|
+
const index = children.length;
|
|
8818
|
+
children.push({
|
|
8819
|
+
name: "heading",
|
|
8820
|
+
props: {
|
|
8821
|
+
text: props.title,
|
|
8822
|
+
level: 1,
|
|
8823
|
+
...pageBreak && index === 0 && { pageBreak: true }
|
|
8824
|
+
}
|
|
8825
|
+
});
|
|
8826
|
+
sourceMap[`/children/${index}`] = "";
|
|
8827
|
+
sourceMap[`/children/${index}/props/text`] = "/props/title";
|
|
8828
|
+
return { children, sourceMap };
|
|
8829
|
+
}
|
|
8830
|
+
function sectionTracker(section2) {
|
|
8831
|
+
if (!Array.isArray(section2.children)) return void 0;
|
|
8832
|
+
for (const [index, child] of section2.children.entries()) {
|
|
8833
|
+
if (typeof child !== "object" || child === null || child.name !== "section-opener" || child.enabled === false) {
|
|
8834
|
+
continue;
|
|
8835
|
+
}
|
|
8836
|
+
const props = child.props;
|
|
8837
|
+
if (!props) continue;
|
|
8838
|
+
if (typeof props.tracker === "string" && props.tracker !== "") {
|
|
8839
|
+
return { text: props.tracker, slot: `/children/${index}/props/tracker` };
|
|
8840
|
+
}
|
|
8841
|
+
if (typeof props.title === "string" && props.title !== "") {
|
|
8842
|
+
return { text: props.title, slot: `/children/${index}/props/title` };
|
|
8843
|
+
}
|
|
8844
|
+
}
|
|
8845
|
+
return void 0;
|
|
8846
|
+
}
|
|
8847
|
+
|
|
8848
|
+
// src/blocks/index.ts
|
|
8849
|
+
var BLOCK_NAMES = [
|
|
8850
|
+
"key-takeaways",
|
|
8851
|
+
"cover",
|
|
8852
|
+
"section-opener",
|
|
8853
|
+
"running-head"
|
|
8854
|
+
];
|
|
8855
|
+
function slotBudget(block2, props, pointer, slot, maxWords) {
|
|
8856
|
+
const value = props[slot];
|
|
8857
|
+
return typeof value === "string" ? [
|
|
8858
|
+
{
|
|
8859
|
+
block: block2,
|
|
8860
|
+
slot,
|
|
8861
|
+
path: `${pointer}/props/${slot}`,
|
|
8862
|
+
words: wordCount(value),
|
|
8863
|
+
maxWords
|
|
8864
|
+
}
|
|
8865
|
+
] : [];
|
|
8866
|
+
}
|
|
8867
|
+
function budgetsOf(block2, budget) {
|
|
8868
|
+
return (props, pointer) => Object.entries(budget).flatMap(
|
|
8869
|
+
([slot, { maxWords }]) => slotBudget(block2, props, pointer, slot, maxWords)
|
|
8870
|
+
);
|
|
8871
|
+
}
|
|
8872
|
+
var BLOCKS = {
|
|
8873
|
+
"key-takeaways": {
|
|
8874
|
+
kind: "flow",
|
|
8875
|
+
compile: (props, theme) => compileKeyTakeaways(props, theme),
|
|
8876
|
+
budgets: (props, pointer) => (Array.isArray(props.items) ? props.items : []).flatMap(
|
|
8877
|
+
(item, index) => typeof item === "string" ? [
|
|
8878
|
+
{
|
|
8879
|
+
block: "key-takeaways",
|
|
8880
|
+
slot: "items",
|
|
8881
|
+
path: `${pointer}/props/items/${index}`,
|
|
8882
|
+
words: wordCount(item),
|
|
8883
|
+
maxWords: KEY_TAKEAWAYS_BUDGET.items.maxWords
|
|
8884
|
+
}
|
|
8885
|
+
] : []
|
|
8886
|
+
)
|
|
8887
|
+
},
|
|
8888
|
+
cover: {
|
|
8889
|
+
kind: "flow",
|
|
8890
|
+
compile: (props, theme) => compileCover(props, theme),
|
|
8891
|
+
budgets: budgetsOf("cover", COVER_BUDGET)
|
|
8892
|
+
},
|
|
8893
|
+
"section-opener": {
|
|
8894
|
+
kind: "flow",
|
|
8895
|
+
compile: (props, theme) => compileSectionOpener(props, theme),
|
|
8896
|
+
budgets: budgetsOf("section-opener", SECTION_OPENER_BUDGET)
|
|
8897
|
+
},
|
|
8898
|
+
"running-head": {
|
|
8899
|
+
kind: "chrome",
|
|
8900
|
+
budgets: budgetsOf("running-head", RUNNING_HEAD_BUDGET)
|
|
8901
|
+
}
|
|
8902
|
+
};
|
|
8903
|
+
function isBlockName(name) {
|
|
8904
|
+
return BLOCK_NAMES.includes(name);
|
|
8905
|
+
}
|
|
8906
|
+
function isChromeBlockName(name) {
|
|
8907
|
+
return isBlockName(name) && BLOCKS[name].kind === "chrome";
|
|
8908
|
+
}
|
|
8909
|
+
function isRecord(value) {
|
|
8910
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8911
|
+
}
|
|
8912
|
+
var SECTION_CHILD = /^\/children\/\d+\/children\/\d+$/;
|
|
8913
|
+
var SECTION = /^\/children\/(\d+)$/;
|
|
8914
|
+
function planChrome(document, theme) {
|
|
8915
|
+
const plans = /* @__PURE__ */ new Map();
|
|
8916
|
+
if (!isRecord(document) || document.name !== "docx" || !Array.isArray(document.children)) {
|
|
8917
|
+
return plans;
|
|
8918
|
+
}
|
|
8919
|
+
const metadata = isRecord(document.props) ? document.props.metadata : void 0;
|
|
8920
|
+
const documentTitle = isRecord(metadata) && typeof metadata.title === "string" ? metadata.title : void 0;
|
|
8921
|
+
let inForce;
|
|
8922
|
+
document.children.forEach((section2, index) => {
|
|
8923
|
+
if (!isRecord(section2) || section2.name !== "section" || section2.enabled === false) {
|
|
8924
|
+
return;
|
|
8925
|
+
}
|
|
8926
|
+
const sectionPointer = `/children/${index}`;
|
|
8927
|
+
const children = Array.isArray(section2.children) ? section2.children : [];
|
|
8928
|
+
children.forEach((child, childIndex) => {
|
|
8929
|
+
if (isRecord(child) && isChromeBlockName(child.name) && child.enabled !== false) {
|
|
8930
|
+
inForce = {
|
|
8931
|
+
block: `${sectionPointer}/children/${childIndex}`,
|
|
8932
|
+
props: isRecord(child.props) ? child.props : {}
|
|
8933
|
+
};
|
|
8934
|
+
}
|
|
8935
|
+
});
|
|
8936
|
+
if (!inForce) return;
|
|
8937
|
+
const opener = sectionTracker(section2);
|
|
8938
|
+
const sectionProps = isRecord(section2.props) ? section2.props : {};
|
|
8939
|
+
plans.set(
|
|
8940
|
+
index,
|
|
8941
|
+
compileRunningHead(inForce.props, theme, {
|
|
8942
|
+
block: inForce.block,
|
|
8943
|
+
documentTitle,
|
|
8944
|
+
...opener && {
|
|
8945
|
+
opener: {
|
|
8946
|
+
text: opener.text,
|
|
8947
|
+
slot: `${sectionPointer}${opener.slot}`
|
|
8948
|
+
}
|
|
8949
|
+
},
|
|
8950
|
+
...isRecord(sectionProps.page) && {
|
|
8951
|
+
page: sectionProps.page
|
|
8952
|
+
}
|
|
8953
|
+
})
|
|
8954
|
+
);
|
|
8955
|
+
});
|
|
8956
|
+
return plans;
|
|
8957
|
+
}
|
|
8958
|
+
function expandBlocks(document, theme) {
|
|
8959
|
+
const sourceMap = {};
|
|
8960
|
+
const blocks = [];
|
|
8961
|
+
const chrome = planChrome(document, theme);
|
|
8962
|
+
const walk2 = (node, pointer) => {
|
|
8963
|
+
if (Array.isArray(node)) {
|
|
8964
|
+
return node.map((child, index) => walk2(child, `${pointer}/${index}`));
|
|
8965
|
+
}
|
|
8966
|
+
if (!isRecord(node)) return node;
|
|
8967
|
+
if (typeof node.name === "string" && node.enabled !== false && isBlockName(node.name)) {
|
|
8968
|
+
const definition = BLOCKS[node.name];
|
|
8969
|
+
if (definition.kind === "chrome") {
|
|
8970
|
+
if (!SECTION_CHILD.test(pointer)) return node;
|
|
8971
|
+
blocks.push(pointer);
|
|
8972
|
+
return { ...node, children: [] };
|
|
8973
|
+
}
|
|
8974
|
+
if (isRecord(node.props)) {
|
|
8975
|
+
const compiled = definition.compile(node.props, theme);
|
|
8976
|
+
blocks.push(pointer);
|
|
8977
|
+
for (const [emitted, authored] of Object.entries(compiled.sourceMap)) {
|
|
8978
|
+
sourceMap[`${pointer}${emitted}`] = `${pointer}${authored}`;
|
|
8979
|
+
}
|
|
8980
|
+
return { ...node, children: compiled.children };
|
|
8981
|
+
}
|
|
8982
|
+
}
|
|
8983
|
+
const next = { ...node };
|
|
8984
|
+
if (isRecord(node.props)) {
|
|
8985
|
+
const props = { ...node.props };
|
|
8986
|
+
let changed = false;
|
|
8987
|
+
for (const key of ["header", "footer"]) {
|
|
8988
|
+
if (Array.isArray(props[key])) {
|
|
8989
|
+
props[key] = walk2(props[key], `${pointer}/props/${key}`);
|
|
8990
|
+
changed = true;
|
|
8991
|
+
}
|
|
8992
|
+
}
|
|
8993
|
+
if (Array.isArray(props.columns)) {
|
|
8994
|
+
props.columns = props.columns.map((column, index) => {
|
|
8995
|
+
if (!isRecord(column)) return column;
|
|
8996
|
+
const base = `${pointer}/props/columns/${index}`;
|
|
8997
|
+
const out = { ...column };
|
|
8998
|
+
if (isRecord(column.header) && "content" in column.header) {
|
|
8999
|
+
out.header = {
|
|
9000
|
+
...column.header,
|
|
9001
|
+
content: walk2(column.header.content, `${base}/header/content`)
|
|
9002
|
+
};
|
|
9003
|
+
}
|
|
9004
|
+
if (Array.isArray(column.cells)) {
|
|
9005
|
+
out.cells = column.cells.map(
|
|
9006
|
+
(cell, cellIndex) => isRecord(cell) && "content" in cell ? {
|
|
9007
|
+
...cell,
|
|
9008
|
+
content: walk2(
|
|
9009
|
+
cell.content,
|
|
9010
|
+
`${base}/cells/${cellIndex}/content`
|
|
9011
|
+
)
|
|
9012
|
+
} : cell
|
|
9013
|
+
);
|
|
9014
|
+
}
|
|
9015
|
+
return out;
|
|
9016
|
+
});
|
|
9017
|
+
changed = true;
|
|
9018
|
+
}
|
|
9019
|
+
if (changed) next.props = props;
|
|
9020
|
+
}
|
|
9021
|
+
if (Array.isArray(node.children)) {
|
|
9022
|
+
next.children = walk2(node.children, `${pointer}/children`);
|
|
9023
|
+
}
|
|
9024
|
+
const section2 = SECTION.exec(pointer);
|
|
9025
|
+
if (section2 && node.name === "section" && node.enabled !== false) {
|
|
9026
|
+
const plan = chrome.get(Number(section2[1]));
|
|
9027
|
+
if (plan) {
|
|
9028
|
+
const props = isRecord(next.props) ? { ...next.props } : {};
|
|
9029
|
+
let changed = false;
|
|
9030
|
+
for (const part of ["header", "footer"]) {
|
|
9031
|
+
const { children, sourceMap: partMap } = plan[part];
|
|
9032
|
+
if (props[part] !== void 0 || children.length === 0) continue;
|
|
9033
|
+
props[part] = children;
|
|
9034
|
+
changed = true;
|
|
9035
|
+
const base = `${pointer}/props/${part}`;
|
|
9036
|
+
sourceMap[base] = partMap["/0"] ?? pointer;
|
|
9037
|
+
for (const [emitted, authored] of Object.entries(partMap)) {
|
|
9038
|
+
sourceMap[`${base}${emitted}`] = authored;
|
|
9039
|
+
}
|
|
9040
|
+
}
|
|
9041
|
+
if (props.pageBreak === void 0) {
|
|
9042
|
+
props.pageBreak = true;
|
|
9043
|
+
changed = true;
|
|
9044
|
+
}
|
|
9045
|
+
if (changed) next.props = props;
|
|
9046
|
+
}
|
|
9047
|
+
}
|
|
9048
|
+
return next;
|
|
9049
|
+
};
|
|
9050
|
+
const expanded = walk2(document, "");
|
|
9051
|
+
return {
|
|
9052
|
+
document: blocks.length > 0 ? expanded : document,
|
|
9053
|
+
sourceMap,
|
|
9054
|
+
blocks
|
|
9055
|
+
};
|
|
9056
|
+
}
|
|
9057
|
+
function toAuthoredPointer(sourceMap, pointer) {
|
|
9058
|
+
let best;
|
|
9059
|
+
for (const emitted of Object.keys(sourceMap)) {
|
|
9060
|
+
if ((pointer === emitted || pointer.startsWith(`${emitted}/`)) && (best === void 0 || emitted.length > best.length)) {
|
|
9061
|
+
best = emitted;
|
|
9062
|
+
}
|
|
9063
|
+
}
|
|
9064
|
+
if (best === void 0) return pointer;
|
|
9065
|
+
return `${sourceMap[best]}${pointer.slice(best.length)}`;
|
|
9066
|
+
}
|
|
9067
|
+
function blockSlotBudgets(document, blocks) {
|
|
9068
|
+
return blocks.flatMap((pointer) => {
|
|
9069
|
+
const node = nodeAt(document, pointer);
|
|
9070
|
+
if (!isRecord(node) || !isRecord(node.props) || !isBlockName(node.name)) {
|
|
9071
|
+
return [];
|
|
9072
|
+
}
|
|
9073
|
+
return BLOCKS[node.name].budgets(node.props, pointer);
|
|
9074
|
+
});
|
|
9075
|
+
}
|
|
9076
|
+
function wordCount(text) {
|
|
9077
|
+
const trimmed = text.trim();
|
|
9078
|
+
return trimmed === "" ? 0 : trimmed.split(/\s+/).length;
|
|
9079
|
+
}
|
|
9080
|
+
function nodeAt(root, pointer) {
|
|
9081
|
+
if (pointer === "") return root;
|
|
9082
|
+
let current = root;
|
|
9083
|
+
for (const segment of pointer.slice(1).split("/")) {
|
|
9084
|
+
const key = segment.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
9085
|
+
if (Array.isArray(current)) current = current[Number(key)];
|
|
9086
|
+
else if (isRecord(current)) current = current[key];
|
|
9087
|
+
else return void 0;
|
|
9088
|
+
}
|
|
9089
|
+
return current;
|
|
9090
|
+
}
|
|
9091
|
+
|
|
8050
9092
|
// src/ir/compiler.ts
|
|
8051
9093
|
init_types();
|
|
8052
9094
|
init_units();
|
|
@@ -8344,33 +9386,47 @@ function compileChromeParagraph(component, scope) {
|
|
|
8344
9386
|
const text = String(props.text ?? "");
|
|
8345
9387
|
if (reportUnlowered(component, props, text, scope)) return [];
|
|
8346
9388
|
const font = props.font ?? {};
|
|
8347
|
-
const
|
|
9389
|
+
const named = chromeStyle(ctx.theme, props.themeStyle);
|
|
9390
|
+
const base = { ...getNormalStyle(ctx.theme), ...named };
|
|
9391
|
+
const styleId = named ? paragraphStyleId(props.themeStyle) ?? "Normal" : "Normal";
|
|
9392
|
+
if (styleId !== "Normal" && !ctx.styleIds.has(styleId)) {
|
|
9393
|
+
ctx.styleIds.add(styleId);
|
|
9394
|
+
}
|
|
8348
9395
|
const chromeProps = {
|
|
8349
9396
|
text,
|
|
8350
|
-
...
|
|
9397
|
+
...named ? { themeStyle: props.themeStyle } : {},
|
|
9398
|
+
...props.alignment ? { alignment: props.alignment } : named?.alignment ? { alignment: named.alignment } : {},
|
|
8351
9399
|
...props.spacing ? { spacing: props.spacing } : {},
|
|
9400
|
+
...props.indent ? { indent: props.indent } : {},
|
|
9401
|
+
...props.tabStops ? { tabStops: props.tabStops } : {},
|
|
8352
9402
|
...props.boldColor ? { boldColor: props.boldColor } : {},
|
|
8353
9403
|
font: {
|
|
8354
|
-
family: font.family || resolveFontFamily(ctx.theme,
|
|
8355
|
-
size: font.size ??
|
|
8356
|
-
color: font.color ||
|
|
8357
|
-
bold: font.bold ?? false,
|
|
8358
|
-
italic: font.italic ?? false,
|
|
9404
|
+
family: font.family || resolveFontFamily(ctx.theme, base.font) || getThemeFonts(ctx.theme).body.family,
|
|
9405
|
+
size: font.size ?? base.size ?? 11,
|
|
9406
|
+
color: font.color || base.color || "textPrimary",
|
|
9407
|
+
bold: font.bold ?? base.bold ?? false,
|
|
9408
|
+
italic: font.italic ?? base.italic ?? false,
|
|
8359
9409
|
...font.underline !== void 0 ? { underline: font.underline } : {},
|
|
8360
|
-
...font.fontWeight !== void 0 ? { fontWeight: font.fontWeight } : {},
|
|
8361
|
-
...font.case !== void 0 ? { case: font.case } : {},
|
|
9410
|
+
...(font.fontWeight ?? base.fontWeight) !== void 0 ? { fontWeight: font.fontWeight ?? base.fontWeight } : {},
|
|
9411
|
+
...(font.case ?? base.case) !== void 0 ? { case: font.case ?? base.case } : {},
|
|
9412
|
+
...(font.characterSpacing ?? base.characterSpacing) !== void 0 ? { characterSpacing: font.characterSpacing ?? base.characterSpacing } : {},
|
|
8362
9413
|
...font.lineSpacing !== void 0 ? { lineSpacing: font.lineSpacing } : {}
|
|
8363
9414
|
}
|
|
8364
9415
|
};
|
|
8365
9416
|
return [
|
|
8366
9417
|
paragraphNode(scope, compileRuns(chromeProps, text, ctx, scope.path), {
|
|
8367
|
-
styleId
|
|
9418
|
+
styleId,
|
|
8368
9419
|
formatting: paragraphFormatting(chromeProps, ctx, {
|
|
8369
9420
|
alwaysSpacing: true
|
|
8370
9421
|
})
|
|
8371
9422
|
})
|
|
8372
9423
|
];
|
|
8373
9424
|
}
|
|
9425
|
+
function chromeStyle(theme, themeStyle) {
|
|
9426
|
+
if (typeof themeStyle !== "string" || !themeStyle) return void 0;
|
|
9427
|
+
const styles = getThemeStyles(theme);
|
|
9428
|
+
return styles[themeStyle] ?? styles[themeStyle.toLowerCase()];
|
|
9429
|
+
}
|
|
8374
9430
|
function compileChromeImage(component, scope) {
|
|
8375
9431
|
const { ctx, path: path4 } = scope;
|
|
8376
9432
|
const props = component.props ?? {};
|
|
@@ -8458,6 +9514,10 @@ function compileComponent(component, scope) {
|
|
|
8458
9514
|
case "table":
|
|
8459
9515
|
return compileTable(component, scope);
|
|
8460
9516
|
default:
|
|
9517
|
+
if (isBlockName(component.name)) {
|
|
9518
|
+
if (component.enabled === false) return [];
|
|
9519
|
+
return compileBlock(component, scope);
|
|
9520
|
+
}
|
|
8461
9521
|
scope.ctx.unsupported.push({
|
|
8462
9522
|
name: component.name,
|
|
8463
9523
|
path: scope.path
|
|
@@ -8465,6 +9525,20 @@ function compileComponent(component, scope) {
|
|
|
8465
9525
|
return [];
|
|
8466
9526
|
}
|
|
8467
9527
|
}
|
|
9528
|
+
function compileBlock(component, scope) {
|
|
9529
|
+
const children = component.children;
|
|
9530
|
+
if (!Array.isArray(children)) {
|
|
9531
|
+
scope.ctx.unsupported.push({ name: component.name, path: scope.path });
|
|
9532
|
+
return [];
|
|
9533
|
+
}
|
|
9534
|
+
return children.flatMap(
|
|
9535
|
+
(child, index) => compileComponent(child, {
|
|
9536
|
+
...scope,
|
|
9537
|
+
path: `${scope.path}.children[${index}]`,
|
|
9538
|
+
id: `${scope.id}:b${index}`
|
|
9539
|
+
})
|
|
9540
|
+
);
|
|
9541
|
+
}
|
|
8468
9542
|
var MARKDOWN_LIST_LEVELS = {
|
|
8469
9543
|
unordered: [
|
|
8470
9544
|
{ level: 0, format: "bullet", text: "\u2022", alignment: "left" },
|
|
@@ -12071,11 +13145,13 @@ function walkActive(node, path4, page, visit) {
|
|
|
12071
13145
|
);
|
|
12072
13146
|
}
|
|
12073
13147
|
function prepareDocxQualityDocument(document, options = {}) {
|
|
12074
|
-
const
|
|
13148
|
+
const themed = options.context ?? resolveThemeContext(normalizeDocument(document)[0], {
|
|
12075
13149
|
customThemes: options.customThemes,
|
|
12076
13150
|
fonts: options.fonts,
|
|
12077
13151
|
warnings: options.warnings
|
|
12078
13152
|
});
|
|
13153
|
+
const expanded = expandBlocks(themed.document, themed.theme);
|
|
13154
|
+
const context = expanded.blocks.length > 0 ? { ...themed, document: expanded.document } : themed;
|
|
12079
13155
|
const resolved = resolveDocumentTree(context.document, context.theme);
|
|
12080
13156
|
const basePage = pageBox(resolved.theme, context.themeName);
|
|
12081
13157
|
const typography = {
|
|
@@ -12085,13 +13161,28 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
12085
13161
|
const facts = [];
|
|
12086
13162
|
const provenance = {};
|
|
12087
13163
|
let previousHeadingLevel;
|
|
12088
|
-
const
|
|
13164
|
+
const authoredPath = (path4) => toAuthoredPointer(expanded.sourceMap, path4);
|
|
13165
|
+
const addFact = (raw) => {
|
|
13166
|
+
const fact = {
|
|
13167
|
+
...raw,
|
|
13168
|
+
path: authoredPath(raw.path),
|
|
13169
|
+
...raw.relatedPaths && {
|
|
13170
|
+
relatedPaths: raw.relatedPaths.map(authoredPath)
|
|
13171
|
+
}
|
|
13172
|
+
};
|
|
12089
13173
|
facts.push(fact);
|
|
12090
13174
|
provenance[fact.id] = {
|
|
12091
13175
|
path: fact.path,
|
|
12092
13176
|
...fact.relatedPaths && { relatedPaths: fact.relatedPaths }
|
|
12093
13177
|
};
|
|
12094
13178
|
};
|
|
13179
|
+
for (const budget of blockSlotBudgets(context.document, expanded.blocks)) {
|
|
13180
|
+
addFact({
|
|
13181
|
+
id: `docx:block-slot:${budget.path}`,
|
|
13182
|
+
kind: "docx/block-slot",
|
|
13183
|
+
...budget
|
|
13184
|
+
});
|
|
13185
|
+
}
|
|
12095
13186
|
const paletteHexes = {};
|
|
12096
13187
|
const visualColors = designColors2(
|
|
12097
13188
|
resolved.theme.colors,
|
|
@@ -12234,7 +13325,16 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
12234
13325
|
},
|
|
12235
13326
|
facts,
|
|
12236
13327
|
provenance,
|
|
12237
|
-
renderer: options.renderer ?? DEFAULT_DOCX_RENDERER_ID2
|
|
13328
|
+
renderer: options.renderer ?? DEFAULT_DOCX_RENDERER_ID2,
|
|
13329
|
+
...expanded.blocks.length > 0 && {
|
|
13330
|
+
metadata: {
|
|
13331
|
+
blocks: {
|
|
13332
|
+
sourceMap: expanded.sourceMap,
|
|
13333
|
+
blocks: expanded.blocks,
|
|
13334
|
+
document: context.document
|
|
13335
|
+
}
|
|
13336
|
+
}
|
|
13337
|
+
}
|
|
12238
13338
|
};
|
|
12239
13339
|
}
|
|
12240
13340
|
|
|
@@ -12274,19 +13374,22 @@ async function compileDocumentScoped(document, options, warnings) {
|
|
|
12274
13374
|
});
|
|
12275
13375
|
const { context } = prepared.model;
|
|
12276
13376
|
const hasVisual = collectVisualProps(context.document).length > 0;
|
|
13377
|
+
const hasHighcharts = containsComponent(context.document, "highcharts");
|
|
12277
13378
|
const resolvedFonts = await resolveDocumentFonts(
|
|
12278
13379
|
context.document,
|
|
12279
13380
|
context.theme,
|
|
12280
13381
|
options.fonts,
|
|
12281
13382
|
warnings,
|
|
12282
|
-
hasVisual
|
|
13383
|
+
hasVisual || hasHighcharts
|
|
12283
13384
|
);
|
|
12284
13385
|
const visualFonts = hasVisual ? toRasterizeFontFaces(resolvedFonts, warnings) : [];
|
|
13386
|
+
const chartFonts = hasHighcharts ? toChartFontFaces(resolvedFonts) : [];
|
|
12285
13387
|
const desugared = await desugarExternals(context.document, {
|
|
12286
13388
|
theme: context.theme,
|
|
12287
13389
|
...options.services ? { services: options.services } : {},
|
|
12288
13390
|
...options.baseDir !== void 0 ? { baseDir: options.baseDir } : {},
|
|
12289
|
-
...visualFonts.length > 0 ? { visualFonts } : {}
|
|
13391
|
+
...visualFonts.length > 0 ? { visualFonts } : {},
|
|
13392
|
+
...chartFonts.length > 0 ? { chartFonts } : {}
|
|
12290
13393
|
});
|
|
12291
13394
|
const resolved = desugared === context.document ? prepared.model.document : resolveDocumentTree(desugared, context.theme);
|
|
12292
13395
|
const structure = await processResolvedDocument(
|
|
@@ -13102,6 +14205,28 @@ var docxPlaceholderRule = {
|
|
|
13102
14205
|
})
|
|
13103
14206
|
)
|
|
13104
14207
|
};
|
|
14208
|
+
var docxSlotBudgetRule = {
|
|
14209
|
+
id: "docx/slot-budget",
|
|
14210
|
+
code: QUALITY_CODES.SLOT_BUDGET,
|
|
14211
|
+
category: "composition",
|
|
14212
|
+
defaultSeverity: "warning",
|
|
14213
|
+
defaultCertainty: "deterministic",
|
|
14214
|
+
formats: ["docx"],
|
|
14215
|
+
evaluate: ({ facts }) => facts.filter(
|
|
14216
|
+
(fact) => fact.kind === "docx/block-slot"
|
|
14217
|
+
).filter((fact) => fact.words > fact.maxWords).map((fact) => ({
|
|
14218
|
+
path: fact.path,
|
|
14219
|
+
message: `${fact.block} ${fact.slot} entry runs to ${fact.words} words; the slot holds ${fact.maxWords} \u2014 one claim, one sentence.`,
|
|
14220
|
+
suggestion: "Cut it to the conclusion. Move the evidence into the body it summarises.",
|
|
14221
|
+
evidence: {
|
|
14222
|
+
summary: "words in the slot against its budget",
|
|
14223
|
+
actual: fact.words,
|
|
14224
|
+
expected: fact.maxWords,
|
|
14225
|
+
unit: "words"
|
|
14226
|
+
},
|
|
14227
|
+
context: { block: fact.block, slot: fact.slot }
|
|
14228
|
+
}))
|
|
14229
|
+
};
|
|
13105
14230
|
var DEFAULT_MAX_FONT_FAMILIES = 3;
|
|
13106
14231
|
var docxFontCountRule = {
|
|
13107
14232
|
id: "docx/font-count",
|
|
@@ -13267,6 +14392,7 @@ var DOCX_QUALITY_RULES = {
|
|
|
13267
14392
|
docxSvgTextBoundsRule,
|
|
13268
14393
|
docxLineBoxRule,
|
|
13269
14394
|
docxPlaceholderRule,
|
|
14395
|
+
docxSlotBudgetRule,
|
|
13270
14396
|
docxChartRule,
|
|
13271
14397
|
docxTableDesignRule,
|
|
13272
14398
|
docxFontCountRule,
|
|
@@ -14274,6 +15400,7 @@ function getCoreVersion() {
|
|
|
14274
15400
|
return "Core v1.0.0";
|
|
14275
15401
|
}
|
|
14276
15402
|
export {
|
|
15403
|
+
BLOCK_NAMES,
|
|
14277
15404
|
ComponentValidationError2 as ComponentValidationError,
|
|
14278
15405
|
DocumentGenerator as CoreDocumentGenerator,
|
|
14279
15406
|
DEFAULT_DOCX_RENDERER_ID,
|
|
@@ -14286,7 +15413,13 @@ export {
|
|
|
14286
15413
|
UncompiledComponentError,
|
|
14287
15414
|
UnknownPreservedComponentError,
|
|
14288
15415
|
analyzeDocxQuality,
|
|
15416
|
+
blockSlotBudgets,
|
|
14289
15417
|
cleanComponentProps,
|
|
15418
|
+
compileCover,
|
|
15419
|
+
compileKeyTakeaways,
|
|
15420
|
+
compileRunningHead,
|
|
15421
|
+
compileSectionOpener,
|
|
15422
|
+
consultingTheme,
|
|
14290
15423
|
createComponent,
|
|
14291
15424
|
createDocumentGenerator,
|
|
14292
15425
|
createMinimalTheme,
|
|
@@ -14296,6 +15429,7 @@ export {
|
|
|
14296
15429
|
docxRendererIds,
|
|
14297
15430
|
docxRendererStatuses,
|
|
14298
15431
|
examples,
|
|
15432
|
+
expandBlocks,
|
|
14299
15433
|
exportPluginSchema,
|
|
14300
15434
|
exportThemeToJson,
|
|
14301
15435
|
flattenVisuals,
|
|
@@ -14315,6 +15449,7 @@ export {
|
|
|
14315
15449
|
getExampleNames,
|
|
14316
15450
|
getVisualPrepassStats,
|
|
14317
15451
|
hasNodeBuiltins,
|
|
15452
|
+
isChromeBlockName,
|
|
14318
15453
|
isColumnsComponent,
|
|
14319
15454
|
isDocxRendererId,
|
|
14320
15455
|
isHeadingComponent,
|
|
@@ -14338,7 +15473,10 @@ export {
|
|
|
14338
15473
|
resetVisualPrepassStats,
|
|
14339
15474
|
resolveDocxQualityProfile,
|
|
14340
15475
|
runExample,
|
|
15476
|
+
sectionMeasureTwips,
|
|
15477
|
+
sectionTracker,
|
|
14341
15478
|
themes,
|
|
15479
|
+
toAuthoredPointer,
|
|
14342
15480
|
validateComponentProps,
|
|
14343
15481
|
validateDocument,
|
|
14344
15482
|
validateJsonSchema,
|