@json-to-office/core-docx 2.7.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blocks/document.d.ts +16 -0
- package/dist/blocks/document.d.ts.map +1 -0
- package/dist/blocks/index.d.ts +1 -71
- package/dist/blocks/index.d.ts.map +1 -1
- package/dist/core/generationContext.d.ts +3 -0
- package/dist/core/generationContext.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +311 -660
- package/dist/index.js.map +1 -1
- package/dist/ir/compiler.d.ts.map +1 -1
- package/dist/plugin/createDocumentGenerator.d.ts.map +1 -1
- package/dist/plugin/example/index.js +305 -647
- package/dist/plugin/example/index.js.map +1 -1
- package/dist/plugin/types.d.ts +2 -0
- package/dist/plugin/types.d.ts.map +1 -1
- package/dist/quality/facts.d.ts +8 -2
- package/dist/quality/facts.d.ts.map +1 -1
- package/dist/quality/rules.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/dist/blocks/cover.d.ts +0 -22
- package/dist/blocks/cover.d.ts.map +0 -1
- package/dist/blocks/keyTakeaways.d.ts +0 -20
- package/dist/blocks/keyTakeaways.d.ts.map +0 -1
- package/dist/blocks/recipe.d.ts +0 -31
- package/dist/blocks/recipe.d.ts.map +0 -1
- package/dist/blocks/runningHead.d.ts +0 -69
- package/dist/blocks/runningHead.d.ts.map +0 -1
- package/dist/blocks/sectionOpener.d.ts +0 -26
- package/dist/blocks/sectionOpener.d.ts.map +0 -1
- package/dist/blocks/types.d.ts +0 -15
- package/dist/blocks/types.d.ts.map +0 -1
|
@@ -8702,641 +8702,6 @@ function emptyToUndefined(formatting) {
|
|
|
8702
8702
|
return entries.length === 0 ? void 0 : Object.fromEntries(entries);
|
|
8703
8703
|
}
|
|
8704
8704
|
|
|
8705
|
-
// src/blocks/index.ts
|
|
8706
|
-
import {
|
|
8707
|
-
COVER_BUDGET,
|
|
8708
|
-
KEY_TAKEAWAYS_BUDGET,
|
|
8709
|
-
RUNNING_HEAD_BUDGET,
|
|
8710
|
-
SECTION_OPENER_BUDGET
|
|
8711
|
-
} from "@json-to-office/shared-docx";
|
|
8712
|
-
|
|
8713
|
-
// src/blocks/cover.ts
|
|
8714
|
-
init_widthUtils();
|
|
8715
|
-
|
|
8716
|
-
// src/blocks/recipe.ts
|
|
8717
|
-
var MIN_RULE_PT = 0.25;
|
|
8718
|
-
var MAX_RULE_PT = 12;
|
|
8719
|
-
function clampRule(weightPt) {
|
|
8720
|
-
return Math.min(MAX_RULE_PT, Math.max(MIN_RULE_PT, weightPt));
|
|
8721
|
-
}
|
|
8722
|
-
var FALLBACK_EYEBROW_FONT = {
|
|
8723
|
-
size: 9,
|
|
8724
|
-
bold: true,
|
|
8725
|
-
color: "accent",
|
|
8726
|
-
case: "upper"
|
|
8727
|
-
};
|
|
8728
|
-
function hasStyle(theme, role) {
|
|
8729
|
-
const styles = theme.styles;
|
|
8730
|
-
return styles?.[role] !== void 0;
|
|
8731
|
-
}
|
|
8732
|
-
function roleProps(theme, role, fallbackFont, color) {
|
|
8733
|
-
if (hasStyle(theme, role)) {
|
|
8734
|
-
return {
|
|
8735
|
-
themeStyle: role,
|
|
8736
|
-
...color !== void 0 && { font: { color } }
|
|
8737
|
-
};
|
|
8738
|
-
}
|
|
8739
|
-
return { font: { ...fallbackFont, ...color !== void 0 && { color } } };
|
|
8740
|
-
}
|
|
8741
|
-
|
|
8742
|
-
// src/blocks/cover.ts
|
|
8743
|
-
var DROP_SHARE = 0.3;
|
|
8744
|
-
var DROP_SHARE_WITH_LOGO = 0.22;
|
|
8745
|
-
var DEFAULT_LOGO_WIDTH = "25%";
|
|
8746
|
-
var FALLBACK = {
|
|
8747
|
-
ruleWeightPt: 3,
|
|
8748
|
-
ruleColor: "accent",
|
|
8749
|
-
padPt: 12,
|
|
8750
|
-
metaFont: { size: 9, color: "textSecondary" }
|
|
8751
|
-
};
|
|
8752
|
-
function compileCover(props, theme) {
|
|
8753
|
-
const recipe = theme.chrome?.cover;
|
|
8754
|
-
const ruleWeightPt = recipe?.rule?.weightPt ?? FALLBACK.ruleWeightPt;
|
|
8755
|
-
const padPt = recipe?.padPt ?? FALLBACK.padPt;
|
|
8756
|
-
const heightPt = getAvailableHeightTwips(theme) / 20;
|
|
8757
|
-
const dropPt = Math.round(
|
|
8758
|
-
heightPt * (props.logo ? DROP_SHARE_WITH_LOGO : DROP_SHARE)
|
|
8759
|
-
);
|
|
8760
|
-
const children = [];
|
|
8761
|
-
const sourceMap = {};
|
|
8762
|
-
const emit = (child, slots) => {
|
|
8763
|
-
const index = children.push(child) - 1;
|
|
8764
|
-
sourceMap[`/children/${index}`] = "";
|
|
8765
|
-
for (const [emitted, authored] of Object.entries(slots)) {
|
|
8766
|
-
sourceMap[`/children/${index}${emitted}`] = authored;
|
|
8767
|
-
}
|
|
8768
|
-
};
|
|
8769
|
-
if (props.logo) {
|
|
8770
|
-
const { width, height, ...source } = props.logo;
|
|
8771
|
-
emit(
|
|
8772
|
-
{
|
|
8773
|
-
name: "image",
|
|
8774
|
-
props: {
|
|
8775
|
-
...source,
|
|
8776
|
-
width: width ?? DEFAULT_LOGO_WIDTH,
|
|
8777
|
-
...height !== void 0 && { height },
|
|
8778
|
-
alignment: theme.chrome?.logoSlot?.alignment ?? "left",
|
|
8779
|
-
spacing: { before: 0, after: 0 }
|
|
8780
|
-
}
|
|
8781
|
-
},
|
|
8782
|
-
{ "/props": "/props/logo" }
|
|
8783
|
-
);
|
|
8784
|
-
}
|
|
8785
|
-
const drawsRule = ruleWeightPt > 0;
|
|
8786
|
-
if (drawsRule) {
|
|
8787
|
-
emit(
|
|
8788
|
-
{
|
|
8789
|
-
name: "divider",
|
|
8790
|
-
props: {
|
|
8791
|
-
thickness: clampRule(ruleWeightPt),
|
|
8792
|
-
color: recipe?.rule?.color ?? FALLBACK.ruleColor,
|
|
8793
|
-
spacing: { before: dropPt, after: padPt }
|
|
8794
|
-
}
|
|
8795
|
-
},
|
|
8796
|
-
{}
|
|
8797
|
-
);
|
|
8798
|
-
}
|
|
8799
|
-
let dropPending = !drawsRule;
|
|
8800
|
-
const before = () => {
|
|
8801
|
-
if (!dropPending) return {};
|
|
8802
|
-
dropPending = false;
|
|
8803
|
-
return { before: dropPt };
|
|
8804
|
-
};
|
|
8805
|
-
if (props.client) {
|
|
8806
|
-
emit(
|
|
8807
|
-
{
|
|
8808
|
-
name: "paragraph",
|
|
8809
|
-
props: {
|
|
8810
|
-
text: props.client,
|
|
8811
|
-
keepNext: true,
|
|
8812
|
-
spacing: { ...before(), after: 4 },
|
|
8813
|
-
...roleProps(theme, "eyebrow", FALLBACK_EYEBROW_FONT)
|
|
8814
|
-
}
|
|
8815
|
-
},
|
|
8816
|
-
{ "/props/text": "/props/client" }
|
|
8817
|
-
);
|
|
8818
|
-
}
|
|
8819
|
-
const titleRole = recipe?.type && hasStyle(theme, recipe.type) ? recipe.type : "title";
|
|
8820
|
-
emit(
|
|
8821
|
-
{
|
|
8822
|
-
name: "paragraph",
|
|
8823
|
-
props: {
|
|
8824
|
-
text: props.title,
|
|
8825
|
-
keepNext: true,
|
|
8826
|
-
...dropPending && { spacing: before() },
|
|
8827
|
-
...roleProps(theme, titleRole, { size: 26, bold: true }, recipe?.color)
|
|
8828
|
-
}
|
|
8829
|
-
},
|
|
8830
|
-
{ "/props/text": "/props/title" }
|
|
8831
|
-
);
|
|
8832
|
-
if (props.subtitle) {
|
|
8833
|
-
emit(
|
|
8834
|
-
{
|
|
8835
|
-
name: "paragraph",
|
|
8836
|
-
props: {
|
|
8837
|
-
text: props.subtitle,
|
|
8838
|
-
keepNext: true,
|
|
8839
|
-
...roleProps(theme, "subtitle", { size: 13, color: "textSecondary" })
|
|
8840
|
-
}
|
|
8841
|
-
},
|
|
8842
|
-
{ "/props/text": "/props/subtitle" }
|
|
8843
|
-
);
|
|
8844
|
-
}
|
|
8845
|
-
const meta = [props.date, props.confidentiality].filter(
|
|
8846
|
-
(part) => typeof part === "string" && part !== ""
|
|
8847
|
-
);
|
|
8848
|
-
if (meta.length > 0) {
|
|
8849
|
-
emit(
|
|
8850
|
-
{
|
|
8851
|
-
name: "paragraph",
|
|
8852
|
-
props: {
|
|
8853
|
-
text: meta.join(" \xB7 "),
|
|
8854
|
-
spacing: { before: padPt, after: 0 },
|
|
8855
|
-
...roleProps(theme, "label", FALLBACK.metaFont)
|
|
8856
|
-
}
|
|
8857
|
-
},
|
|
8858
|
-
{
|
|
8859
|
-
"/props/text": props.date ? "/props/date" : "/props/confidentiality"
|
|
8860
|
-
}
|
|
8861
|
-
);
|
|
8862
|
-
}
|
|
8863
|
-
return { children, sourceMap };
|
|
8864
|
-
}
|
|
8865
|
-
|
|
8866
|
-
// src/blocks/keyTakeaways.ts
|
|
8867
|
-
var KEY_TAKEAWAYS_DEFAULT_LABEL = "Key takeaways";
|
|
8868
|
-
var FALLBACK_RECIPE = {
|
|
8869
|
-
ruleWeightPt: 1.5,
|
|
8870
|
-
ruleColor: "accent",
|
|
8871
|
-
padPt: 6,
|
|
8872
|
-
type: "label"
|
|
8873
|
-
};
|
|
8874
|
-
function compileKeyTakeaways(props, theme) {
|
|
8875
|
-
const recipe = theme.chrome?.keyTakeaways;
|
|
8876
|
-
const labelRole = recipe?.type ?? FALLBACK_RECIPE.type;
|
|
8877
|
-
const labelStyle = hasStyle(theme, labelRole);
|
|
8878
|
-
const ruleWeightPt = clampRule(
|
|
8879
|
-
recipe?.rule?.weightPt ?? FALLBACK_RECIPE.ruleWeightPt
|
|
8880
|
-
);
|
|
8881
|
-
const ruleColor = recipe?.rule?.color ?? recipe?.color ?? FALLBACK_RECIPE.ruleColor;
|
|
8882
|
-
const padPt = recipe?.padPt ?? FALLBACK_RECIPE.padPt;
|
|
8883
|
-
const children = [
|
|
8884
|
-
{
|
|
8885
|
-
name: "divider",
|
|
8886
|
-
props: {
|
|
8887
|
-
thickness: ruleWeightPt,
|
|
8888
|
-
color: ruleColor,
|
|
8889
|
-
spacing: { before: 12, after: padPt }
|
|
8890
|
-
}
|
|
8891
|
-
},
|
|
8892
|
-
{
|
|
8893
|
-
name: "paragraph",
|
|
8894
|
-
props: {
|
|
8895
|
-
text: props.label ?? KEY_TAKEAWAYS_DEFAULT_LABEL,
|
|
8896
|
-
keepNext: true,
|
|
8897
|
-
spacing: { after: 4 },
|
|
8898
|
-
// The label role when the theme resolves one; a bold run in the
|
|
8899
|
-
// recipe's colour otherwise, so the label still reads as a label.
|
|
8900
|
-
...labelStyle ? { themeStyle: labelRole } : {
|
|
8901
|
-
font: {
|
|
8902
|
-
bold: true,
|
|
8903
|
-
...recipe?.color !== void 0 && { color: recipe.color }
|
|
8904
|
-
}
|
|
8905
|
-
}
|
|
8906
|
-
}
|
|
8907
|
-
},
|
|
8908
|
-
{
|
|
8909
|
-
name: "list",
|
|
8910
|
-
props: { items: [...props.items] }
|
|
8911
|
-
},
|
|
8912
|
-
{
|
|
8913
|
-
name: "divider",
|
|
8914
|
-
props: {
|
|
8915
|
-
thickness: 0.5,
|
|
8916
|
-
color: "borderPrimary",
|
|
8917
|
-
spacing: { before: padPt, after: 12 }
|
|
8918
|
-
}
|
|
8919
|
-
}
|
|
8920
|
-
];
|
|
8921
|
-
return {
|
|
8922
|
-
children,
|
|
8923
|
-
sourceMap: {
|
|
8924
|
-
"/children/0": "",
|
|
8925
|
-
"/children/1": "",
|
|
8926
|
-
"/children/1/props/text": "/props/label",
|
|
8927
|
-
"/children/2": "",
|
|
8928
|
-
"/children/2/props/items": "/props/items",
|
|
8929
|
-
"/children/3": ""
|
|
8930
|
-
}
|
|
8931
|
-
};
|
|
8932
|
-
}
|
|
8933
|
-
|
|
8934
|
-
// src/blocks/runningHead.ts
|
|
8935
|
-
init_styles();
|
|
8936
|
-
init_widthUtils();
|
|
8937
|
-
var FALLBACK2 = {
|
|
8938
|
-
headFont: { size: 8, color: "textMuted", case: "upper" },
|
|
8939
|
-
footFont: { size: 8, color: "textMuted" },
|
|
8940
|
-
ruleWeightPt: 0.5,
|
|
8941
|
-
ruleColor: "border"
|
|
8942
|
-
};
|
|
8943
|
-
var PAGE_OF_TOTAL = "{PAGE} / {TOTAL_PAGES}";
|
|
8944
|
-
function sectionMeasureTwips(theme, page) {
|
|
8945
|
-
if (!page || page.size === void 0 && page.margins === void 0) {
|
|
8946
|
-
return getAvailableWidthTwips(theme);
|
|
8947
|
-
}
|
|
8948
|
-
const width = page.size ? getPageDimensions(page.size).width : getPageDimensions(theme.page.size).width;
|
|
8949
|
-
const margins = getDocumentMargins(theme);
|
|
8950
|
-
const left = page.margins?.left ?? margins.left ?? 1440;
|
|
8951
|
-
const right = page.margins?.right ?? margins.right ?? 1440;
|
|
8952
|
-
return Math.max(0, width - left - right);
|
|
8953
|
-
}
|
|
8954
|
-
function compileRunningHead(props, theme, scope) {
|
|
8955
|
-
const measure = sectionMeasureTwips(theme, scope.page);
|
|
8956
|
-
const head = theme.chrome?.runningHead;
|
|
8957
|
-
const foot = theme.chrome?.confidentialFooter;
|
|
8958
|
-
const slot = (name) => props[name] !== void 0 ? `${scope.block}/props/${name}` : void 0;
|
|
8959
|
-
const header = [];
|
|
8960
|
-
const headerMap = {};
|
|
8961
|
-
const title = props.title ?? scope.documentTitle ?? "";
|
|
8962
|
-
const tracker = scope.opener?.text ?? props.tracker ?? "";
|
|
8963
|
-
if (title !== "" || tracker !== "") {
|
|
8964
|
-
const both = title !== "" && tracker !== "";
|
|
8965
|
-
header.push({
|
|
8966
|
-
name: "paragraph",
|
|
8967
|
-
props: {
|
|
8968
|
-
text: both ? `${title} ${tracker}` : title || tracker,
|
|
8969
|
-
...both ? { tabStops: [{ type: "right", position: measure }] } : { alignment: title !== "" ? "left" : head?.alignment ?? "right" },
|
|
8970
|
-
spacing: { before: 0, after: 0 },
|
|
8971
|
-
...roleProps(
|
|
8972
|
-
theme,
|
|
8973
|
-
head?.type ?? "tracker",
|
|
8974
|
-
FALLBACK2.headFont,
|
|
8975
|
-
head?.color
|
|
8976
|
-
)
|
|
8977
|
-
}
|
|
8978
|
-
});
|
|
8979
|
-
headerMap["/0"] = scope.block;
|
|
8980
|
-
headerMap["/0/props/text"] = (tracker !== "" ? scope.opener?.slot ?? slot("tracker") : slot("title")) ?? scope.block;
|
|
8981
|
-
}
|
|
8982
|
-
const headRule = head?.rule?.weightPt ?? FALLBACK2.ruleWeightPt;
|
|
8983
|
-
if (headRule > 0) {
|
|
8984
|
-
header.push({
|
|
8985
|
-
name: "divider",
|
|
8986
|
-
props: {
|
|
8987
|
-
thickness: clampRule(headRule),
|
|
8988
|
-
color: head?.rule?.color ?? FALLBACK2.ruleColor,
|
|
8989
|
-
spacing: { before: 2, after: 0 }
|
|
8990
|
-
}
|
|
8991
|
-
});
|
|
8992
|
-
headerMap[`/${header.length - 1}`] = scope.block;
|
|
8993
|
-
}
|
|
8994
|
-
const footer = [];
|
|
8995
|
-
const footerMap = {};
|
|
8996
|
-
const footRule = foot?.rule?.weightPt ?? FALLBACK2.ruleWeightPt;
|
|
8997
|
-
if (footRule > 0) {
|
|
8998
|
-
footer.push({
|
|
8999
|
-
name: "divider",
|
|
9000
|
-
props: {
|
|
9001
|
-
thickness: clampRule(footRule),
|
|
9002
|
-
color: foot?.rule?.color ?? FALLBACK2.ruleColor,
|
|
9003
|
-
spacing: { before: 0, after: 4 }
|
|
9004
|
-
}
|
|
9005
|
-
});
|
|
9006
|
-
footerMap["/0"] = scope.block;
|
|
9007
|
-
}
|
|
9008
|
-
const parts = [
|
|
9009
|
-
props.confidentiality ?? "",
|
|
9010
|
-
props.pageNumbers === false ? "" : PAGE_OF_TOTAL,
|
|
9011
|
-
props.date ?? ""
|
|
9012
|
-
];
|
|
9013
|
-
const present = parts.filter((part) => part !== "");
|
|
9014
|
-
if (present.length > 0) {
|
|
9015
|
-
const single = present.length === 1;
|
|
9016
|
-
const alignment2 = present[0] === PAGE_OF_TOTAL ? "center" : foot?.alignment ?? "left";
|
|
9017
|
-
footer.push({
|
|
9018
|
-
name: "paragraph",
|
|
9019
|
-
props: {
|
|
9020
|
-
text: single ? present[0] : parts.join(" ").replace(/\t+$/, ""),
|
|
9021
|
-
...single ? { alignment: alignment2 } : {
|
|
9022
|
-
tabStops: [
|
|
9023
|
-
{ type: "center", position: Math.round(measure / 2) },
|
|
9024
|
-
{ type: "right", position: measure }
|
|
9025
|
-
]
|
|
9026
|
-
},
|
|
9027
|
-
spacing: { before: 0, after: 0 },
|
|
9028
|
-
...roleProps(
|
|
9029
|
-
theme,
|
|
9030
|
-
foot?.type ?? "footer",
|
|
9031
|
-
FALLBACK2.footFont,
|
|
9032
|
-
foot?.color
|
|
9033
|
-
)
|
|
9034
|
-
}
|
|
9035
|
-
});
|
|
9036
|
-
const index = footer.length - 1;
|
|
9037
|
-
footerMap[`/${index}`] = scope.block;
|
|
9038
|
-
footerMap[`/${index}/props/text`] = slot("confidentiality") ?? slot("date") ?? scope.block;
|
|
9039
|
-
}
|
|
9040
|
-
return {
|
|
9041
|
-
header: { children: header, sourceMap: headerMap },
|
|
9042
|
-
footer: { children: footer, sourceMap: footerMap }
|
|
9043
|
-
};
|
|
9044
|
-
}
|
|
9045
|
-
|
|
9046
|
-
// src/blocks/sectionOpener.ts
|
|
9047
|
-
function compileSectionOpener(props, theme) {
|
|
9048
|
-
const children = [];
|
|
9049
|
-
const sourceMap = {};
|
|
9050
|
-
const pageBreak = props.pageBreak === true;
|
|
9051
|
-
if (props.number !== void 0) {
|
|
9052
|
-
children.push({
|
|
9053
|
-
name: "paragraph",
|
|
9054
|
-
props: {
|
|
9055
|
-
text: String(props.number),
|
|
9056
|
-
keepNext: true,
|
|
9057
|
-
spacing: { after: 2 },
|
|
9058
|
-
...pageBreak && { pageBreak: true },
|
|
9059
|
-
...roleProps(theme, "eyebrow", FALLBACK_EYEBROW_FONT)
|
|
9060
|
-
}
|
|
9061
|
-
});
|
|
9062
|
-
sourceMap["/children/0"] = "";
|
|
9063
|
-
sourceMap["/children/0/props/text"] = "/props/number";
|
|
9064
|
-
}
|
|
9065
|
-
const index = children.length;
|
|
9066
|
-
children.push({
|
|
9067
|
-
name: "heading",
|
|
9068
|
-
props: {
|
|
9069
|
-
text: props.title,
|
|
9070
|
-
level: 1,
|
|
9071
|
-
...pageBreak && index === 0 && { pageBreak: true }
|
|
9072
|
-
}
|
|
9073
|
-
});
|
|
9074
|
-
sourceMap[`/children/${index}`] = "";
|
|
9075
|
-
sourceMap[`/children/${index}/props/text`] = "/props/title";
|
|
9076
|
-
return { children, sourceMap };
|
|
9077
|
-
}
|
|
9078
|
-
function sectionTracker(section2) {
|
|
9079
|
-
if (!Array.isArray(section2.children)) return void 0;
|
|
9080
|
-
for (const [index, child] of section2.children.entries()) {
|
|
9081
|
-
if (typeof child !== "object" || child === null || child.name !== "section-opener" || child.enabled === false) {
|
|
9082
|
-
continue;
|
|
9083
|
-
}
|
|
9084
|
-
const props = child.props;
|
|
9085
|
-
if (!props) continue;
|
|
9086
|
-
if (typeof props.tracker === "string" && props.tracker !== "") {
|
|
9087
|
-
return { text: props.tracker, slot: `/children/${index}/props/tracker` };
|
|
9088
|
-
}
|
|
9089
|
-
if (typeof props.title === "string" && props.title !== "") {
|
|
9090
|
-
return { text: props.title, slot: `/children/${index}/props/title` };
|
|
9091
|
-
}
|
|
9092
|
-
}
|
|
9093
|
-
return void 0;
|
|
9094
|
-
}
|
|
9095
|
-
|
|
9096
|
-
// src/blocks/index.ts
|
|
9097
|
-
var BLOCK_NAMES = [
|
|
9098
|
-
"key-takeaways",
|
|
9099
|
-
"cover",
|
|
9100
|
-
"section-opener",
|
|
9101
|
-
"running-head"
|
|
9102
|
-
];
|
|
9103
|
-
function slotBudget(block2, props, pointer, slot, maxWords) {
|
|
9104
|
-
const value = props[slot];
|
|
9105
|
-
return typeof value === "string" ? [
|
|
9106
|
-
{
|
|
9107
|
-
block: block2,
|
|
9108
|
-
slot,
|
|
9109
|
-
path: `${pointer}/props/${slot}`,
|
|
9110
|
-
words: wordCount(value),
|
|
9111
|
-
maxWords
|
|
9112
|
-
}
|
|
9113
|
-
] : [];
|
|
9114
|
-
}
|
|
9115
|
-
function budgetsOf(block2, budget) {
|
|
9116
|
-
return (props, pointer) => Object.entries(budget).flatMap(
|
|
9117
|
-
([slot, { maxWords }]) => slotBudget(block2, props, pointer, slot, maxWords)
|
|
9118
|
-
);
|
|
9119
|
-
}
|
|
9120
|
-
var BLOCKS = {
|
|
9121
|
-
"key-takeaways": {
|
|
9122
|
-
kind: "flow",
|
|
9123
|
-
compile: (props, theme) => compileKeyTakeaways(props, theme),
|
|
9124
|
-
budgets: (props, pointer) => (Array.isArray(props.items) ? props.items : []).flatMap(
|
|
9125
|
-
(item, index) => typeof item === "string" ? [
|
|
9126
|
-
{
|
|
9127
|
-
block: "key-takeaways",
|
|
9128
|
-
slot: "items",
|
|
9129
|
-
path: `${pointer}/props/items/${index}`,
|
|
9130
|
-
words: wordCount(item),
|
|
9131
|
-
maxWords: KEY_TAKEAWAYS_BUDGET.items.maxWords
|
|
9132
|
-
}
|
|
9133
|
-
] : []
|
|
9134
|
-
)
|
|
9135
|
-
},
|
|
9136
|
-
cover: {
|
|
9137
|
-
kind: "flow",
|
|
9138
|
-
compile: (props, theme) => compileCover(props, theme),
|
|
9139
|
-
budgets: budgetsOf("cover", COVER_BUDGET)
|
|
9140
|
-
},
|
|
9141
|
-
"section-opener": {
|
|
9142
|
-
kind: "flow",
|
|
9143
|
-
compile: (props, theme) => compileSectionOpener(props, theme),
|
|
9144
|
-
budgets: budgetsOf("section-opener", SECTION_OPENER_BUDGET)
|
|
9145
|
-
},
|
|
9146
|
-
"running-head": {
|
|
9147
|
-
kind: "chrome",
|
|
9148
|
-
budgets: budgetsOf("running-head", RUNNING_HEAD_BUDGET)
|
|
9149
|
-
}
|
|
9150
|
-
};
|
|
9151
|
-
function isBlockName(name) {
|
|
9152
|
-
return BLOCK_NAMES.includes(name);
|
|
9153
|
-
}
|
|
9154
|
-
function isChromeBlockName(name) {
|
|
9155
|
-
return isBlockName(name) && BLOCKS[name].kind === "chrome";
|
|
9156
|
-
}
|
|
9157
|
-
function isRecord(value) {
|
|
9158
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9159
|
-
}
|
|
9160
|
-
var SECTION_CHILD = /^\/children\/\d+\/children\/\d+$/;
|
|
9161
|
-
var SECTION = /^\/children\/(\d+)$/;
|
|
9162
|
-
function planChrome(document, theme) {
|
|
9163
|
-
const plans = /* @__PURE__ */ new Map();
|
|
9164
|
-
if (!isRecord(document) || document.name !== "docx" || !Array.isArray(document.children)) {
|
|
9165
|
-
return plans;
|
|
9166
|
-
}
|
|
9167
|
-
const metadata = isRecord(document.props) ? document.props.metadata : void 0;
|
|
9168
|
-
const documentTitle = isRecord(metadata) && typeof metadata.title === "string" ? metadata.title : void 0;
|
|
9169
|
-
let inForce;
|
|
9170
|
-
document.children.forEach((section2, index) => {
|
|
9171
|
-
if (!isRecord(section2) || section2.name !== "section" || section2.enabled === false) {
|
|
9172
|
-
return;
|
|
9173
|
-
}
|
|
9174
|
-
const sectionPointer = `/children/${index}`;
|
|
9175
|
-
const children = Array.isArray(section2.children) ? section2.children : [];
|
|
9176
|
-
children.forEach((child, childIndex) => {
|
|
9177
|
-
if (isRecord(child) && isChromeBlockName(child.name) && child.enabled !== false) {
|
|
9178
|
-
inForce = {
|
|
9179
|
-
block: `${sectionPointer}/children/${childIndex}`,
|
|
9180
|
-
props: isRecord(child.props) ? child.props : {}
|
|
9181
|
-
};
|
|
9182
|
-
}
|
|
9183
|
-
});
|
|
9184
|
-
if (!inForce) return;
|
|
9185
|
-
const opener = sectionTracker(section2);
|
|
9186
|
-
const sectionProps = isRecord(section2.props) ? section2.props : {};
|
|
9187
|
-
plans.set(
|
|
9188
|
-
index,
|
|
9189
|
-
compileRunningHead(inForce.props, theme, {
|
|
9190
|
-
block: inForce.block,
|
|
9191
|
-
documentTitle,
|
|
9192
|
-
...opener && {
|
|
9193
|
-
opener: {
|
|
9194
|
-
text: opener.text,
|
|
9195
|
-
slot: `${sectionPointer}${opener.slot}`
|
|
9196
|
-
}
|
|
9197
|
-
},
|
|
9198
|
-
...isRecord(sectionProps.page) && {
|
|
9199
|
-
page: sectionProps.page
|
|
9200
|
-
}
|
|
9201
|
-
})
|
|
9202
|
-
);
|
|
9203
|
-
});
|
|
9204
|
-
return plans;
|
|
9205
|
-
}
|
|
9206
|
-
function expandBlocks(document, theme) {
|
|
9207
|
-
const sourceMap = {};
|
|
9208
|
-
const blocks = [];
|
|
9209
|
-
const chrome = planChrome(document, theme);
|
|
9210
|
-
const walk2 = (node, pointer) => {
|
|
9211
|
-
if (Array.isArray(node)) {
|
|
9212
|
-
return node.map((child, index) => walk2(child, `${pointer}/${index}`));
|
|
9213
|
-
}
|
|
9214
|
-
if (!isRecord(node)) return node;
|
|
9215
|
-
if (typeof node.name === "string" && node.enabled !== false && isBlockName(node.name)) {
|
|
9216
|
-
const definition = BLOCKS[node.name];
|
|
9217
|
-
if (definition.kind === "chrome") {
|
|
9218
|
-
if (!SECTION_CHILD.test(pointer)) return node;
|
|
9219
|
-
blocks.push(pointer);
|
|
9220
|
-
return { ...node, children: [] };
|
|
9221
|
-
}
|
|
9222
|
-
if (isRecord(node.props)) {
|
|
9223
|
-
const compiled = definition.compile(node.props, theme);
|
|
9224
|
-
blocks.push(pointer);
|
|
9225
|
-
for (const [emitted, authored] of Object.entries(compiled.sourceMap)) {
|
|
9226
|
-
sourceMap[`${pointer}${emitted}`] = `${pointer}${authored}`;
|
|
9227
|
-
}
|
|
9228
|
-
return { ...node, children: compiled.children };
|
|
9229
|
-
}
|
|
9230
|
-
}
|
|
9231
|
-
const next = { ...node };
|
|
9232
|
-
if (isRecord(node.props)) {
|
|
9233
|
-
const props = { ...node.props };
|
|
9234
|
-
let changed = false;
|
|
9235
|
-
for (const key of ["header", "footer"]) {
|
|
9236
|
-
if (Array.isArray(props[key])) {
|
|
9237
|
-
props[key] = walk2(props[key], `${pointer}/props/${key}`);
|
|
9238
|
-
changed = true;
|
|
9239
|
-
}
|
|
9240
|
-
}
|
|
9241
|
-
if (Array.isArray(props.columns)) {
|
|
9242
|
-
props.columns = props.columns.map((column, index) => {
|
|
9243
|
-
if (!isRecord(column)) return column;
|
|
9244
|
-
const base = `${pointer}/props/columns/${index}`;
|
|
9245
|
-
const out = { ...column };
|
|
9246
|
-
if (isRecord(column.header) && "content" in column.header) {
|
|
9247
|
-
out.header = {
|
|
9248
|
-
...column.header,
|
|
9249
|
-
content: walk2(column.header.content, `${base}/header/content`)
|
|
9250
|
-
};
|
|
9251
|
-
}
|
|
9252
|
-
if (Array.isArray(column.cells)) {
|
|
9253
|
-
out.cells = column.cells.map(
|
|
9254
|
-
(cell, cellIndex) => isRecord(cell) && "content" in cell ? {
|
|
9255
|
-
...cell,
|
|
9256
|
-
content: walk2(
|
|
9257
|
-
cell.content,
|
|
9258
|
-
`${base}/cells/${cellIndex}/content`
|
|
9259
|
-
)
|
|
9260
|
-
} : cell
|
|
9261
|
-
);
|
|
9262
|
-
}
|
|
9263
|
-
return out;
|
|
9264
|
-
});
|
|
9265
|
-
changed = true;
|
|
9266
|
-
}
|
|
9267
|
-
if (changed) next.props = props;
|
|
9268
|
-
}
|
|
9269
|
-
if (Array.isArray(node.children)) {
|
|
9270
|
-
next.children = walk2(node.children, `${pointer}/children`);
|
|
9271
|
-
}
|
|
9272
|
-
const section2 = SECTION.exec(pointer);
|
|
9273
|
-
if (section2 && node.name === "section" && node.enabled !== false) {
|
|
9274
|
-
const plan = chrome.get(Number(section2[1]));
|
|
9275
|
-
if (plan) {
|
|
9276
|
-
const props = isRecord(next.props) ? { ...next.props } : {};
|
|
9277
|
-
let changed = false;
|
|
9278
|
-
for (const part of ["header", "footer"]) {
|
|
9279
|
-
const { children, sourceMap: partMap } = plan[part];
|
|
9280
|
-
if (props[part] !== void 0 || children.length === 0) continue;
|
|
9281
|
-
props[part] = children;
|
|
9282
|
-
changed = true;
|
|
9283
|
-
const base = `${pointer}/props/${part}`;
|
|
9284
|
-
sourceMap[base] = partMap["/0"] ?? pointer;
|
|
9285
|
-
for (const [emitted, authored] of Object.entries(partMap)) {
|
|
9286
|
-
sourceMap[`${base}${emitted}`] = authored;
|
|
9287
|
-
}
|
|
9288
|
-
}
|
|
9289
|
-
if (props.pageBreak === void 0) {
|
|
9290
|
-
props.pageBreak = true;
|
|
9291
|
-
changed = true;
|
|
9292
|
-
}
|
|
9293
|
-
if (changed) next.props = props;
|
|
9294
|
-
}
|
|
9295
|
-
}
|
|
9296
|
-
return next;
|
|
9297
|
-
};
|
|
9298
|
-
const expanded = walk2(document, "");
|
|
9299
|
-
return {
|
|
9300
|
-
document: blocks.length > 0 ? expanded : document,
|
|
9301
|
-
sourceMap,
|
|
9302
|
-
blocks
|
|
9303
|
-
};
|
|
9304
|
-
}
|
|
9305
|
-
function toAuthoredPointer(sourceMap, pointer) {
|
|
9306
|
-
let best;
|
|
9307
|
-
for (const emitted of Object.keys(sourceMap)) {
|
|
9308
|
-
if ((pointer === emitted || pointer.startsWith(`${emitted}/`)) && (best === void 0 || emitted.length > best.length)) {
|
|
9309
|
-
best = emitted;
|
|
9310
|
-
}
|
|
9311
|
-
}
|
|
9312
|
-
if (best === void 0) return pointer;
|
|
9313
|
-
return `${sourceMap[best]}${pointer.slice(best.length)}`;
|
|
9314
|
-
}
|
|
9315
|
-
function blockSlotBudgets(document, blocks) {
|
|
9316
|
-
return blocks.flatMap((pointer) => {
|
|
9317
|
-
const node = nodeAt(document, pointer);
|
|
9318
|
-
if (!isRecord(node) || !isRecord(node.props) || !isBlockName(node.name)) {
|
|
9319
|
-
return [];
|
|
9320
|
-
}
|
|
9321
|
-
return BLOCKS[node.name].budgets(node.props, pointer);
|
|
9322
|
-
});
|
|
9323
|
-
}
|
|
9324
|
-
function wordCount(text) {
|
|
9325
|
-
const trimmed = text.trim();
|
|
9326
|
-
return trimmed === "" ? 0 : trimmed.split(/\s+/).length;
|
|
9327
|
-
}
|
|
9328
|
-
function nodeAt(root, pointer) {
|
|
9329
|
-
if (pointer === "") return root;
|
|
9330
|
-
let current = root;
|
|
9331
|
-
for (const segment of pointer.slice(1).split("/")) {
|
|
9332
|
-
const key = segment.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
9333
|
-
if (Array.isArray(current)) current = current[Number(key)];
|
|
9334
|
-
else if (isRecord(current)) current = current[key];
|
|
9335
|
-
else return void 0;
|
|
9336
|
-
}
|
|
9337
|
-
return current;
|
|
9338
|
-
}
|
|
9339
|
-
|
|
9340
8705
|
// src/ir/compiler.ts
|
|
9341
8706
|
init_types();
|
|
9342
8707
|
init_units();
|
|
@@ -9762,7 +9127,7 @@ function compileComponent(component, scope) {
|
|
|
9762
9127
|
case "table":
|
|
9763
9128
|
return compileTable(component, scope);
|
|
9764
9129
|
default:
|
|
9765
|
-
if (
|
|
9130
|
+
if (component.name === "group") {
|
|
9766
9131
|
if (component.enabled === false) return [];
|
|
9767
9132
|
return compileBlock(component, scope);
|
|
9768
9133
|
}
|
|
@@ -12805,6 +12170,204 @@ function normalizeDocument(document) {
|
|
|
12805
12170
|
return [normalized];
|
|
12806
12171
|
}
|
|
12807
12172
|
|
|
12173
|
+
// src/blocks/document.ts
|
|
12174
|
+
init_styles();
|
|
12175
|
+
init_widthUtils();
|
|
12176
|
+
import {
|
|
12177
|
+
JsonBlockEvaluator,
|
|
12178
|
+
BlockEvaluationError,
|
|
12179
|
+
composeBlocksWithPlugins,
|
|
12180
|
+
readBlockDefinitions,
|
|
12181
|
+
blockValueAt,
|
|
12182
|
+
isBlockRecord,
|
|
12183
|
+
toAuthoredBlockPointer
|
|
12184
|
+
} from "@json-to-office/shared";
|
|
12185
|
+
import { blockSlotBudgets } from "@json-to-office/shared";
|
|
12186
|
+
import { validateDocument as validateDocument2 } from "@json-to-office/shared-docx";
|
|
12187
|
+
var toAuthoredPointer = toAuthoredBlockPointer;
|
|
12188
|
+
function docxBlockContext(document, theme, path3 = "") {
|
|
12189
|
+
const index = /^\/children\/(\d+)/.exec(path3)?.[1];
|
|
12190
|
+
const section2 = index === void 0 ? void 0 : blockValueAt(document, `/children/${index}`);
|
|
12191
|
+
const page = isBlockRecord(section2) && isBlockRecord(section2.props) && isBlockRecord(section2.props.page) ? section2.props.page : {};
|
|
12192
|
+
const margins = getDocumentMargins(theme);
|
|
12193
|
+
const dimensions = getPageDimensions(
|
|
12194
|
+
page.size ?? theme.page.size
|
|
12195
|
+
);
|
|
12196
|
+
const overrides = isBlockRecord(page.margins) ? page.margins : {};
|
|
12197
|
+
const width = Object.keys(page).length ? Math.max(
|
|
12198
|
+
0,
|
|
12199
|
+
dimensions.width - Number(overrides.left ?? margins.left ?? 1440) - Number(overrides.right ?? margins.right ?? 1440)
|
|
12200
|
+
) : getAvailableWidthTwips(theme);
|
|
12201
|
+
const height = Object.keys(page).length ? Math.max(
|
|
12202
|
+
0,
|
|
12203
|
+
dimensions.height - Number(overrides.top ?? margins.top ?? 1440) - Number(overrides.bottom ?? margins.bottom ?? 1440)
|
|
12204
|
+
) : getAvailableHeightTwips(theme);
|
|
12205
|
+
return {
|
|
12206
|
+
document: blockValueAt(document, "/props/metadata") ?? {},
|
|
12207
|
+
page: { width, height },
|
|
12208
|
+
section: {}
|
|
12209
|
+
};
|
|
12210
|
+
}
|
|
12211
|
+
function createDocxBlockEvaluator(document, theme, extra = {}) {
|
|
12212
|
+
return new JsonBlockEvaluator(readBlockDefinitions(document), {
|
|
12213
|
+
format: "docx",
|
|
12214
|
+
theme,
|
|
12215
|
+
contextAt: (path3) => docxBlockContext(document, theme, path3),
|
|
12216
|
+
contextSources: { "/document": "/props/metadata" },
|
|
12217
|
+
measure: (axis, unit, context) => Number(blockValueAt(context, `/page/${axis}`)) / (unit === "twip" ? 1 : unit === "in" ? 1440 : 20),
|
|
12218
|
+
...extra
|
|
12219
|
+
});
|
|
12220
|
+
}
|
|
12221
|
+
function expandBlocks(document, theme) {
|
|
12222
|
+
const effects = [];
|
|
12223
|
+
const evaluator = createDocxBlockEvaluator(document, theme, {
|
|
12224
|
+
onSection: (effect) => effects.push(effect)
|
|
12225
|
+
});
|
|
12226
|
+
const expanded = evaluator.expand(document);
|
|
12227
|
+
return finishDocxBlocks(expanded, document, theme, evaluator, effects);
|
|
12228
|
+
}
|
|
12229
|
+
function validateEffects(document, effects) {
|
|
12230
|
+
for (const effect of effects) {
|
|
12231
|
+
const parts = effect.path.split("/").slice(1);
|
|
12232
|
+
const section2 = blockValueAt(document, "/" + parts.slice(0, 2).join("/"));
|
|
12233
|
+
let valid = parts.length >= 4 && parts[0] === "children" && parts[2] === "children" && isBlockRecord(section2) && section2.name === "section";
|
|
12234
|
+
for (let i = 4; i < parts.length; i += 2) {
|
|
12235
|
+
const parent = blockValueAt(document, "/" + parts.slice(0, i).join("/"));
|
|
12236
|
+
valid &&= parts[i] === "children" && isBlockRecord(parent) && parent.name === "group";
|
|
12237
|
+
}
|
|
12238
|
+
if (!valid)
|
|
12239
|
+
throw new BlockEvaluationError([
|
|
12240
|
+
{
|
|
12241
|
+
path: effect.environment.source,
|
|
12242
|
+
code: "invalid_placement",
|
|
12243
|
+
message: "Section effects require a block in a top-level section body, optionally nested in transparent groups."
|
|
12244
|
+
}
|
|
12245
|
+
]);
|
|
12246
|
+
}
|
|
12247
|
+
}
|
|
12248
|
+
function finishDocxBlocks(expanded, document, theme, evaluator, effects, validate = true) {
|
|
12249
|
+
if (isBlockRecord(expanded) && Array.isArray(expanded.children)) {
|
|
12250
|
+
let inherited;
|
|
12251
|
+
expanded.children.forEach((section2, index) => {
|
|
12252
|
+
if (!isBlockRecord(section2) || section2.name !== "section" || section2.enabled === false)
|
|
12253
|
+
return;
|
|
12254
|
+
const path3 = `/children/${index}`;
|
|
12255
|
+
const local = effects.filter(
|
|
12256
|
+
(e) => e.path.startsWith(`${path3}/children/`)
|
|
12257
|
+
);
|
|
12258
|
+
let tracker;
|
|
12259
|
+
let trackerSource = path3;
|
|
12260
|
+
for (const effect of local) {
|
|
12261
|
+
if (effect.settings.tracker !== void 0) {
|
|
12262
|
+
tracker = evaluator.evaluate(
|
|
12263
|
+
effect.settings.tracker,
|
|
12264
|
+
effect.environment,
|
|
12265
|
+
`${path3}/props/tracker`,
|
|
12266
|
+
`${effect.environment.definition}/section/tracker`
|
|
12267
|
+
);
|
|
12268
|
+
trackerSource = toAuthoredPointer(
|
|
12269
|
+
evaluator.sourceMap,
|
|
12270
|
+
`${path3}/props/tracker`
|
|
12271
|
+
);
|
|
12272
|
+
}
|
|
12273
|
+
}
|
|
12274
|
+
let chrome = inherited;
|
|
12275
|
+
for (const effect of local) {
|
|
12276
|
+
if (effect.settings.header !== void 0 || effect.settings.footer !== void 0) {
|
|
12277
|
+
chrome = effect;
|
|
12278
|
+
if (effect.settings.scope === "following") inherited = effect;
|
|
12279
|
+
}
|
|
12280
|
+
}
|
|
12281
|
+
const props = isBlockRecord(section2.props) ? { ...section2.props } : {};
|
|
12282
|
+
if (chrome) {
|
|
12283
|
+
const environment = {
|
|
12284
|
+
...chrome.environment,
|
|
12285
|
+
context: {
|
|
12286
|
+
...docxBlockContext(document, theme, path3),
|
|
12287
|
+
section: { tracker }
|
|
12288
|
+
},
|
|
12289
|
+
contextSources: {
|
|
12290
|
+
"/document": "/props/metadata",
|
|
12291
|
+
"/section/tracker": trackerSource
|
|
12292
|
+
}
|
|
12293
|
+
};
|
|
12294
|
+
for (const part of ["header", "footer"]) {
|
|
12295
|
+
if (props[part] !== void 0 || chrome.settings[part] === void 0)
|
|
12296
|
+
continue;
|
|
12297
|
+
const compiled = evaluator.evaluate(
|
|
12298
|
+
chrome.settings[part],
|
|
12299
|
+
environment,
|
|
12300
|
+
`${path3}/props/${part}`,
|
|
12301
|
+
`${environment.definition}/section/${part}`
|
|
12302
|
+
);
|
|
12303
|
+
props[part] = evaluator.expand(compiled, `${path3}/props/${part}`);
|
|
12304
|
+
}
|
|
12305
|
+
if (props.pageBreak === void 0)
|
|
12306
|
+
props.pageBreak = chrome.settings.pageBreak ?? true;
|
|
12307
|
+
}
|
|
12308
|
+
for (const effect of local)
|
|
12309
|
+
if (effect.settings.pageBreak !== void 0 && props.pageBreak === void 0)
|
|
12310
|
+
props.pageBreak = effect.settings.pageBreak;
|
|
12311
|
+
section2.props = props;
|
|
12312
|
+
});
|
|
12313
|
+
}
|
|
12314
|
+
validateEffects(expanded, effects);
|
|
12315
|
+
if (evaluator.blocks.length && validate) {
|
|
12316
|
+
const result = validateDocument2(expanded);
|
|
12317
|
+
if (!result.valid)
|
|
12318
|
+
throw new BlockEvaluationError(
|
|
12319
|
+
result.errors.map((issue) => ({
|
|
12320
|
+
path: toAuthoredPointer(evaluator.sourceMap, issue.path),
|
|
12321
|
+
code: issue.code ?? "block_invalid_output",
|
|
12322
|
+
message: issue.message
|
|
12323
|
+
}))
|
|
12324
|
+
);
|
|
12325
|
+
}
|
|
12326
|
+
return {
|
|
12327
|
+
document: expanded,
|
|
12328
|
+
sourceMap: evaluator.sourceMap,
|
|
12329
|
+
blocks: evaluator.blocks
|
|
12330
|
+
};
|
|
12331
|
+
}
|
|
12332
|
+
async function expandBlocksWithPlugins(document, theme, plugins, render, preserve = /* @__PURE__ */ new Set()) {
|
|
12333
|
+
const effects = [];
|
|
12334
|
+
const evaluator = createDocxBlockEvaluator(document, theme, {
|
|
12335
|
+
reservedNames: [...plugins],
|
|
12336
|
+
onSection: (effect) => effects.push(effect)
|
|
12337
|
+
});
|
|
12338
|
+
const walk2 = (value) => composeBlocksWithPlugins(evaluator, value, {
|
|
12339
|
+
plugins,
|
|
12340
|
+
render,
|
|
12341
|
+
preserve
|
|
12342
|
+
});
|
|
12343
|
+
const first = await walk2(document);
|
|
12344
|
+
const finished = finishDocxBlocks(
|
|
12345
|
+
first.standard,
|
|
12346
|
+
document,
|
|
12347
|
+
theme,
|
|
12348
|
+
evaluator,
|
|
12349
|
+
effects,
|
|
12350
|
+
false
|
|
12351
|
+
);
|
|
12352
|
+
const second = await walk2(finished.document);
|
|
12353
|
+
validateEffects(second.standard, effects);
|
|
12354
|
+
const result = validateDocument2(second.standard);
|
|
12355
|
+
if (!result.valid)
|
|
12356
|
+
throw new BlockEvaluationError(
|
|
12357
|
+
result.errors.map((issue) => ({
|
|
12358
|
+
path: toAuthoredPointer(evaluator.sourceMap, issue.path),
|
|
12359
|
+
code: issue.code ?? "block_invalid_output",
|
|
12360
|
+
message: issue.message
|
|
12361
|
+
}))
|
|
12362
|
+
);
|
|
12363
|
+
return {
|
|
12364
|
+
document: second.standard,
|
|
12365
|
+
preserved: first.preserved,
|
|
12366
|
+
sourceMap: evaluator.sourceMap,
|
|
12367
|
+
blocks: evaluator.blocks
|
|
12368
|
+
};
|
|
12369
|
+
}
|
|
12370
|
+
|
|
12808
12371
|
// src/quality/facts.ts
|
|
12809
12372
|
init_styleHelpers();
|
|
12810
12373
|
init_defaults();
|
|
@@ -13011,6 +12574,7 @@ function tableDesignFact(props, path3, theme, themeName, authored) {
|
|
|
13011
12574
|
alignment: alignments.size === 1 ? [...alignments][0] : alignments.size === 0 ? "left" : "mixed",
|
|
13012
12575
|
hasCellDefaults: asRecord(authoredColumn.cellDefaults) !== void 0,
|
|
13013
12576
|
hasHeader: asRecord(authoredColumn.header) !== void 0,
|
|
12577
|
+
generated: false,
|
|
13014
12578
|
cellsWithOwnAlignment: cells.flatMap((cell, cellIndex) => {
|
|
13015
12579
|
const alignment2 = asRecord(cell)?.horizontalAlignment;
|
|
13016
12580
|
return typeof alignment2 === "string" && DOCX_ALIGNMENTS.has(alignment2) && alignment2 !== "right" ? [cellIndex] : [];
|
|
@@ -13247,7 +12811,10 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13247
12811
|
const facts = [];
|
|
13248
12812
|
const provenance = {};
|
|
13249
12813
|
let previousHeadingLevel;
|
|
13250
|
-
const authoredPath = (path3) => toAuthoredPointer(
|
|
12814
|
+
const authoredPath = (path3) => toAuthoredPointer(
|
|
12815
|
+
themed.sourceMap ?? {},
|
|
12816
|
+
toAuthoredPointer(expanded.sourceMap, path3)
|
|
12817
|
+
);
|
|
13251
12818
|
const addFact = (raw) => {
|
|
13252
12819
|
const fact = {
|
|
13253
12820
|
...raw,
|
|
@@ -13262,7 +12829,7 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13262
12829
|
...fact.relatedPaths && { relatedPaths: fact.relatedPaths }
|
|
13263
12830
|
};
|
|
13264
12831
|
};
|
|
13265
|
-
for (const budget of blockSlotBudgets(
|
|
12832
|
+
for (const budget of blockSlotBudgets(themed.document, expanded.blocks)) {
|
|
13266
12833
|
addFact({
|
|
13267
12834
|
id: `docx:block-slot:${budget.path}`,
|
|
13268
12835
|
kind: "docx/block-slot",
|
|
@@ -13357,7 +12924,19 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13357
12924
|
context.themeName,
|
|
13358
12925
|
authoredPropsAt(path3)
|
|
13359
12926
|
);
|
|
13360
|
-
if (design)
|
|
12927
|
+
if (design)
|
|
12928
|
+
addFact({
|
|
12929
|
+
...design,
|
|
12930
|
+
columns: design.columns.map((column) => {
|
|
12931
|
+
const authored = authoredPath(column.path);
|
|
12932
|
+
const table2 = /^(.*)\/props\/columns\/\d+$/.exec(authored)?.[1];
|
|
12933
|
+
return {
|
|
12934
|
+
...column,
|
|
12935
|
+
path: authored,
|
|
12936
|
+
generated: table2 === void 0 || asRecord(nodeAtPointer(themed.document, table2))?.name !== "table"
|
|
12937
|
+
};
|
|
12938
|
+
})
|
|
12939
|
+
});
|
|
13361
12940
|
}
|
|
13362
12941
|
if (node.name === "chart" || node.name === "highcharts") {
|
|
13363
12942
|
const fact = chartFact(node, props, path3, paletteTokens);
|
|
@@ -13412,11 +12991,19 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13412
12991
|
facts,
|
|
13413
12992
|
provenance,
|
|
13414
12993
|
renderer: options.renderer ?? DEFAULT_DOCX_RENDERER_ID2,
|
|
13415
|
-
...expanded.blocks.length > 0 && {
|
|
12994
|
+
...(expanded.blocks.length > 0 || (themed.blockPaths?.length ?? 0) > 0) && {
|
|
13416
12995
|
metadata: {
|
|
13417
12996
|
blocks: {
|
|
13418
|
-
sourceMap:
|
|
13419
|
-
|
|
12997
|
+
sourceMap: {
|
|
12998
|
+
...themed.sourceMap,
|
|
12999
|
+
...Object.fromEntries(
|
|
13000
|
+
Object.entries(expanded.sourceMap).map(([key, value]) => [
|
|
13001
|
+
key,
|
|
13002
|
+
toAuthoredPointer(themed.sourceMap ?? {}, value)
|
|
13003
|
+
])
|
|
13004
|
+
)
|
|
13005
|
+
},
|
|
13006
|
+
blocks: [...themed.blockPaths ?? [], ...expanded.blocks],
|
|
13420
13007
|
document: context.document
|
|
13421
13008
|
}
|
|
13422
13009
|
}
|
|
@@ -13754,12 +13341,12 @@ function createBuilderImpl(state) {
|
|
|
13754
13341
|
);
|
|
13755
13342
|
}
|
|
13756
13343
|
}
|
|
13757
|
-
const validateEmitted = vOpts.enabled === false ? void 0 : (emitted, componentLabel) => {
|
|
13344
|
+
const validateEmitted = vOpts.enabled === false ? void 0 : (emitted, componentLabel, sourcePath) => {
|
|
13758
13345
|
const result = validateDocument(
|
|
13759
13346
|
{
|
|
13760
13347
|
...internalDocument,
|
|
13761
13348
|
...renderer !== void 0 ? { renderer } : {},
|
|
13762
|
-
children: emitted
|
|
13349
|
+
children: sourcePath === void 0 ? emitted : [{ name: "section", props: {}, children: emitted }]
|
|
13763
13350
|
},
|
|
13764
13351
|
state.components,
|
|
13765
13352
|
{ allowUnknownFields: vOpts.allowUnknownFields }
|
|
@@ -13767,7 +13354,10 @@ function createBuilderImpl(state) {
|
|
|
13767
13354
|
if (!result.valid) {
|
|
13768
13355
|
throw new ComponentValidationError2(
|
|
13769
13356
|
(result.errors ?? []).map((e) => ({
|
|
13770
|
-
path: e.path ?? ""
|
|
13357
|
+
path: sourcePath === void 0 ? e.path ?? "" : (e.path ?? "").replace(
|
|
13358
|
+
/^\/children\/0\/children\/\d+/,
|
|
13359
|
+
sourcePath
|
|
13360
|
+
),
|
|
13771
13361
|
message: `custom component '${componentLabel}' emitted invalid output \u2014 ${e.message}`
|
|
13772
13362
|
})),
|
|
13773
13363
|
emitted
|
|
@@ -13785,6 +13375,62 @@ function createBuilderImpl(state) {
|
|
|
13785
13375
|
warnings,
|
|
13786
13376
|
resolveNamedTheme: resolveDocumentTheme
|
|
13787
13377
|
});
|
|
13378
|
+
if (modedRoot.props.blocks !== void 0) {
|
|
13379
|
+
const expanded = await expandBlocksWithPlugins(
|
|
13380
|
+
modedRoot,
|
|
13381
|
+
modedTheme,
|
|
13382
|
+
new Set(componentMap.keys()),
|
|
13383
|
+
async (component, path3) => {
|
|
13384
|
+
const custom = componentMap.get(String(component.name));
|
|
13385
|
+
const version = resolveComponentVersion(
|
|
13386
|
+
custom.name,
|
|
13387
|
+
custom.versions,
|
|
13388
|
+
component.version
|
|
13389
|
+
);
|
|
13390
|
+
const checked = validateComponentProps(
|
|
13391
|
+
version,
|
|
13392
|
+
component.props ?? {},
|
|
13393
|
+
custom.name,
|
|
13394
|
+
{ clean: vOpts.allowUnknownFields === true }
|
|
13395
|
+
);
|
|
13396
|
+
if (!checked.valid)
|
|
13397
|
+
throw new ComponentValidationError2(
|
|
13398
|
+
(checked.errors ?? []).map((e) => ({ path: path3, message: e.message })),
|
|
13399
|
+
component
|
|
13400
|
+
);
|
|
13401
|
+
const output = await version.render({
|
|
13402
|
+
props: cleanComponentProps(version, component.props ?? {}),
|
|
13403
|
+
theme: modedTheme,
|
|
13404
|
+
children: component.children,
|
|
13405
|
+
addWarning: (message, context) => warnings.push({
|
|
13406
|
+
component: custom.name,
|
|
13407
|
+
message,
|
|
13408
|
+
severity: "warning",
|
|
13409
|
+
context
|
|
13410
|
+
})
|
|
13411
|
+
});
|
|
13412
|
+
const emitted = Array.isArray(output) ? output : [output];
|
|
13413
|
+
validateEmitted?.(emitted, custom.name, path3);
|
|
13414
|
+
return emitted;
|
|
13415
|
+
},
|
|
13416
|
+
preserveSet
|
|
13417
|
+
);
|
|
13418
|
+
const [modedDoc2] = normalizeDocument(expanded.document);
|
|
13419
|
+
return {
|
|
13420
|
+
modedRoot,
|
|
13421
|
+
modedTheme,
|
|
13422
|
+
themeName,
|
|
13423
|
+
modedDoc: modedDoc2,
|
|
13424
|
+
sourceMap: expanded.sourceMap,
|
|
13425
|
+
blockPaths: expanded.blocks,
|
|
13426
|
+
warnings,
|
|
13427
|
+
preserveSet,
|
|
13428
|
+
processed: {
|
|
13429
|
+
standard: modedDoc2.children ?? [],
|
|
13430
|
+
preserved: expanded.preserved.children ?? []
|
|
13431
|
+
}
|
|
13432
|
+
};
|
|
13433
|
+
}
|
|
13788
13434
|
const processed = await processDocumentComponents(
|
|
13789
13435
|
modedRoot.children || [],
|
|
13790
13436
|
preserveSet,
|
|
@@ -13809,9 +13455,13 @@ function createBuilderImpl(state) {
|
|
|
13809
13455
|
}
|
|
13810
13456
|
async function expandStandardDefinition(document, options) {
|
|
13811
13457
|
try {
|
|
13812
|
-
const { modedDoc, warnings } = await expandDocument(
|
|
13458
|
+
const { modedDoc, warnings, sourceMap } = await expandDocument(
|
|
13459
|
+
document,
|
|
13460
|
+
options
|
|
13461
|
+
);
|
|
13813
13462
|
return {
|
|
13814
13463
|
standardDefinition: modedDoc,
|
|
13464
|
+
...sourceMap && { sourceMap },
|
|
13815
13465
|
warnings: warnings.length > 0 ? warnings : null
|
|
13816
13466
|
};
|
|
13817
13467
|
} catch (error) {
|
|
@@ -13829,6 +13479,8 @@ function createBuilderImpl(state) {
|
|
|
13829
13479
|
themeName,
|
|
13830
13480
|
processed,
|
|
13831
13481
|
modedDoc,
|
|
13482
|
+
sourceMap,
|
|
13483
|
+
blockPaths,
|
|
13832
13484
|
warnings,
|
|
13833
13485
|
preserveSet
|
|
13834
13486
|
} = await expandDocument(document, options);
|
|
@@ -13839,7 +13491,13 @@ function createBuilderImpl(state) {
|
|
|
13839
13491
|
const { buffer } = await generateBufferViaIr(modedDoc, {
|
|
13840
13492
|
// The prologue already ran: the theme had to be resolved before custom
|
|
13841
13493
|
// components expanded, because each one's `render` is handed it.
|
|
13842
|
-
context: {
|
|
13494
|
+
context: {
|
|
13495
|
+
document: modedDoc,
|
|
13496
|
+
theme: modedTheme,
|
|
13497
|
+
themeName,
|
|
13498
|
+
...sourceMap !== void 0 && { sourceMap },
|
|
13499
|
+
...blockPaths !== void 0 && { blockPaths }
|
|
13500
|
+
},
|
|
13843
13501
|
...state.services ? { services: state.services } : {},
|
|
13844
13502
|
...state.fonts ? { fonts: state.fonts } : {},
|
|
13845
13503
|
...baseDir !== void 0 ? { baseDir } : {},
|