@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
package/dist/index.js
CHANGED
|
@@ -8454,641 +8454,6 @@ function emptyToUndefined(formatting) {
|
|
|
8454
8454
|
return entries.length === 0 ? void 0 : Object.fromEntries(entries);
|
|
8455
8455
|
}
|
|
8456
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
|
-
|
|
9092
8457
|
// src/ir/compiler.ts
|
|
9093
8458
|
init_types();
|
|
9094
8459
|
init_units();
|
|
@@ -9514,7 +8879,7 @@ function compileComponent(component, scope) {
|
|
|
9514
8879
|
case "table":
|
|
9515
8880
|
return compileTable(component, scope);
|
|
9516
8881
|
default:
|
|
9517
|
-
if (
|
|
8882
|
+
if (component.name === "group") {
|
|
9518
8883
|
if (component.enabled === false) return [];
|
|
9519
8884
|
return compileBlock(component, scope);
|
|
9520
8885
|
}
|
|
@@ -12719,6 +12084,204 @@ function normalizeDocument(document) {
|
|
|
12719
12084
|
return [normalized];
|
|
12720
12085
|
}
|
|
12721
12086
|
|
|
12087
|
+
// src/blocks/document.ts
|
|
12088
|
+
init_styles();
|
|
12089
|
+
init_widthUtils();
|
|
12090
|
+
import {
|
|
12091
|
+
JsonBlockEvaluator,
|
|
12092
|
+
BlockEvaluationError,
|
|
12093
|
+
composeBlocksWithPlugins,
|
|
12094
|
+
readBlockDefinitions,
|
|
12095
|
+
blockValueAt,
|
|
12096
|
+
isBlockRecord,
|
|
12097
|
+
toAuthoredBlockPointer
|
|
12098
|
+
} from "@json-to-office/shared";
|
|
12099
|
+
import { blockSlotBudgets } from "@json-to-office/shared";
|
|
12100
|
+
import { validateDocument } from "@json-to-office/shared-docx";
|
|
12101
|
+
var toAuthoredPointer = toAuthoredBlockPointer;
|
|
12102
|
+
function docxBlockContext(document, theme, path4 = "") {
|
|
12103
|
+
const index = /^\/children\/(\d+)/.exec(path4)?.[1];
|
|
12104
|
+
const section2 = index === void 0 ? void 0 : blockValueAt(document, `/children/${index}`);
|
|
12105
|
+
const page = isBlockRecord(section2) && isBlockRecord(section2.props) && isBlockRecord(section2.props.page) ? section2.props.page : {};
|
|
12106
|
+
const margins = getDocumentMargins(theme);
|
|
12107
|
+
const dimensions = getPageDimensions(
|
|
12108
|
+
page.size ?? theme.page.size
|
|
12109
|
+
);
|
|
12110
|
+
const overrides = isBlockRecord(page.margins) ? page.margins : {};
|
|
12111
|
+
const width = Object.keys(page).length ? Math.max(
|
|
12112
|
+
0,
|
|
12113
|
+
dimensions.width - Number(overrides.left ?? margins.left ?? 1440) - Number(overrides.right ?? margins.right ?? 1440)
|
|
12114
|
+
) : getAvailableWidthTwips(theme);
|
|
12115
|
+
const height = Object.keys(page).length ? Math.max(
|
|
12116
|
+
0,
|
|
12117
|
+
dimensions.height - Number(overrides.top ?? margins.top ?? 1440) - Number(overrides.bottom ?? margins.bottom ?? 1440)
|
|
12118
|
+
) : getAvailableHeightTwips(theme);
|
|
12119
|
+
return {
|
|
12120
|
+
document: blockValueAt(document, "/props/metadata") ?? {},
|
|
12121
|
+
page: { width, height },
|
|
12122
|
+
section: {}
|
|
12123
|
+
};
|
|
12124
|
+
}
|
|
12125
|
+
function createDocxBlockEvaluator(document, theme, extra = {}) {
|
|
12126
|
+
return new JsonBlockEvaluator(readBlockDefinitions(document), {
|
|
12127
|
+
format: "docx",
|
|
12128
|
+
theme,
|
|
12129
|
+
contextAt: (path4) => docxBlockContext(document, theme, path4),
|
|
12130
|
+
contextSources: { "/document": "/props/metadata" },
|
|
12131
|
+
measure: (axis, unit, context) => Number(blockValueAt(context, `/page/${axis}`)) / (unit === "twip" ? 1 : unit === "in" ? 1440 : 20),
|
|
12132
|
+
...extra
|
|
12133
|
+
});
|
|
12134
|
+
}
|
|
12135
|
+
function expandBlocks(document, theme) {
|
|
12136
|
+
const effects = [];
|
|
12137
|
+
const evaluator = createDocxBlockEvaluator(document, theme, {
|
|
12138
|
+
onSection: (effect) => effects.push(effect)
|
|
12139
|
+
});
|
|
12140
|
+
const expanded = evaluator.expand(document);
|
|
12141
|
+
return finishDocxBlocks(expanded, document, theme, evaluator, effects);
|
|
12142
|
+
}
|
|
12143
|
+
function validateEffects(document, effects) {
|
|
12144
|
+
for (const effect of effects) {
|
|
12145
|
+
const parts = effect.path.split("/").slice(1);
|
|
12146
|
+
const section2 = blockValueAt(document, "/" + parts.slice(0, 2).join("/"));
|
|
12147
|
+
let valid = parts.length >= 4 && parts[0] === "children" && parts[2] === "children" && isBlockRecord(section2) && section2.name === "section";
|
|
12148
|
+
for (let i = 4; i < parts.length; i += 2) {
|
|
12149
|
+
const parent = blockValueAt(document, "/" + parts.slice(0, i).join("/"));
|
|
12150
|
+
valid &&= parts[i] === "children" && isBlockRecord(parent) && parent.name === "group";
|
|
12151
|
+
}
|
|
12152
|
+
if (!valid)
|
|
12153
|
+
throw new BlockEvaluationError([
|
|
12154
|
+
{
|
|
12155
|
+
path: effect.environment.source,
|
|
12156
|
+
code: "invalid_placement",
|
|
12157
|
+
message: "Section effects require a block in a top-level section body, optionally nested in transparent groups."
|
|
12158
|
+
}
|
|
12159
|
+
]);
|
|
12160
|
+
}
|
|
12161
|
+
}
|
|
12162
|
+
function finishDocxBlocks(expanded, document, theme, evaluator, effects, validate = true) {
|
|
12163
|
+
if (isBlockRecord(expanded) && Array.isArray(expanded.children)) {
|
|
12164
|
+
let inherited;
|
|
12165
|
+
expanded.children.forEach((section2, index) => {
|
|
12166
|
+
if (!isBlockRecord(section2) || section2.name !== "section" || section2.enabled === false)
|
|
12167
|
+
return;
|
|
12168
|
+
const path4 = `/children/${index}`;
|
|
12169
|
+
const local = effects.filter(
|
|
12170
|
+
(e) => e.path.startsWith(`${path4}/children/`)
|
|
12171
|
+
);
|
|
12172
|
+
let tracker;
|
|
12173
|
+
let trackerSource = path4;
|
|
12174
|
+
for (const effect of local) {
|
|
12175
|
+
if (effect.settings.tracker !== void 0) {
|
|
12176
|
+
tracker = evaluator.evaluate(
|
|
12177
|
+
effect.settings.tracker,
|
|
12178
|
+
effect.environment,
|
|
12179
|
+
`${path4}/props/tracker`,
|
|
12180
|
+
`${effect.environment.definition}/section/tracker`
|
|
12181
|
+
);
|
|
12182
|
+
trackerSource = toAuthoredPointer(
|
|
12183
|
+
evaluator.sourceMap,
|
|
12184
|
+
`${path4}/props/tracker`
|
|
12185
|
+
);
|
|
12186
|
+
}
|
|
12187
|
+
}
|
|
12188
|
+
let chrome = inherited;
|
|
12189
|
+
for (const effect of local) {
|
|
12190
|
+
if (effect.settings.header !== void 0 || effect.settings.footer !== void 0) {
|
|
12191
|
+
chrome = effect;
|
|
12192
|
+
if (effect.settings.scope === "following") inherited = effect;
|
|
12193
|
+
}
|
|
12194
|
+
}
|
|
12195
|
+
const props = isBlockRecord(section2.props) ? { ...section2.props } : {};
|
|
12196
|
+
if (chrome) {
|
|
12197
|
+
const environment = {
|
|
12198
|
+
...chrome.environment,
|
|
12199
|
+
context: {
|
|
12200
|
+
...docxBlockContext(document, theme, path4),
|
|
12201
|
+
section: { tracker }
|
|
12202
|
+
},
|
|
12203
|
+
contextSources: {
|
|
12204
|
+
"/document": "/props/metadata",
|
|
12205
|
+
"/section/tracker": trackerSource
|
|
12206
|
+
}
|
|
12207
|
+
};
|
|
12208
|
+
for (const part of ["header", "footer"]) {
|
|
12209
|
+
if (props[part] !== void 0 || chrome.settings[part] === void 0)
|
|
12210
|
+
continue;
|
|
12211
|
+
const compiled = evaluator.evaluate(
|
|
12212
|
+
chrome.settings[part],
|
|
12213
|
+
environment,
|
|
12214
|
+
`${path4}/props/${part}`,
|
|
12215
|
+
`${environment.definition}/section/${part}`
|
|
12216
|
+
);
|
|
12217
|
+
props[part] = evaluator.expand(compiled, `${path4}/props/${part}`);
|
|
12218
|
+
}
|
|
12219
|
+
if (props.pageBreak === void 0)
|
|
12220
|
+
props.pageBreak = chrome.settings.pageBreak ?? true;
|
|
12221
|
+
}
|
|
12222
|
+
for (const effect of local)
|
|
12223
|
+
if (effect.settings.pageBreak !== void 0 && props.pageBreak === void 0)
|
|
12224
|
+
props.pageBreak = effect.settings.pageBreak;
|
|
12225
|
+
section2.props = props;
|
|
12226
|
+
});
|
|
12227
|
+
}
|
|
12228
|
+
validateEffects(expanded, effects);
|
|
12229
|
+
if (evaluator.blocks.length && validate) {
|
|
12230
|
+
const result = validateDocument(expanded);
|
|
12231
|
+
if (!result.valid)
|
|
12232
|
+
throw new BlockEvaluationError(
|
|
12233
|
+
result.errors.map((issue) => ({
|
|
12234
|
+
path: toAuthoredPointer(evaluator.sourceMap, issue.path),
|
|
12235
|
+
code: issue.code ?? "block_invalid_output",
|
|
12236
|
+
message: issue.message
|
|
12237
|
+
}))
|
|
12238
|
+
);
|
|
12239
|
+
}
|
|
12240
|
+
return {
|
|
12241
|
+
document: expanded,
|
|
12242
|
+
sourceMap: evaluator.sourceMap,
|
|
12243
|
+
blocks: evaluator.blocks
|
|
12244
|
+
};
|
|
12245
|
+
}
|
|
12246
|
+
async function expandBlocksWithPlugins(document, theme, plugins, render, preserve = /* @__PURE__ */ new Set()) {
|
|
12247
|
+
const effects = [];
|
|
12248
|
+
const evaluator = createDocxBlockEvaluator(document, theme, {
|
|
12249
|
+
reservedNames: [...plugins],
|
|
12250
|
+
onSection: (effect) => effects.push(effect)
|
|
12251
|
+
});
|
|
12252
|
+
const walk2 = (value) => composeBlocksWithPlugins(evaluator, value, {
|
|
12253
|
+
plugins,
|
|
12254
|
+
render,
|
|
12255
|
+
preserve
|
|
12256
|
+
});
|
|
12257
|
+
const first = await walk2(document);
|
|
12258
|
+
const finished = finishDocxBlocks(
|
|
12259
|
+
first.standard,
|
|
12260
|
+
document,
|
|
12261
|
+
theme,
|
|
12262
|
+
evaluator,
|
|
12263
|
+
effects,
|
|
12264
|
+
false
|
|
12265
|
+
);
|
|
12266
|
+
const second = await walk2(finished.document);
|
|
12267
|
+
validateEffects(second.standard, effects);
|
|
12268
|
+
const result = validateDocument(second.standard);
|
|
12269
|
+
if (!result.valid)
|
|
12270
|
+
throw new BlockEvaluationError(
|
|
12271
|
+
result.errors.map((issue) => ({
|
|
12272
|
+
path: toAuthoredPointer(evaluator.sourceMap, issue.path),
|
|
12273
|
+
code: issue.code ?? "block_invalid_output",
|
|
12274
|
+
message: issue.message
|
|
12275
|
+
}))
|
|
12276
|
+
);
|
|
12277
|
+
return {
|
|
12278
|
+
document: second.standard,
|
|
12279
|
+
preserved: first.preserved,
|
|
12280
|
+
sourceMap: evaluator.sourceMap,
|
|
12281
|
+
blocks: evaluator.blocks
|
|
12282
|
+
};
|
|
12283
|
+
}
|
|
12284
|
+
|
|
12722
12285
|
// src/quality/facts.ts
|
|
12723
12286
|
init_styleHelpers();
|
|
12724
12287
|
init_defaults();
|
|
@@ -12925,6 +12488,7 @@ function tableDesignFact(props, path4, theme, themeName, authored) {
|
|
|
12925
12488
|
alignment: alignments.size === 1 ? [...alignments][0] : alignments.size === 0 ? "left" : "mixed",
|
|
12926
12489
|
hasCellDefaults: asRecord(authoredColumn.cellDefaults) !== void 0,
|
|
12927
12490
|
hasHeader: asRecord(authoredColumn.header) !== void 0,
|
|
12491
|
+
generated: false,
|
|
12928
12492
|
cellsWithOwnAlignment: cells.flatMap((cell, cellIndex) => {
|
|
12929
12493
|
const alignment2 = asRecord(cell)?.horizontalAlignment;
|
|
12930
12494
|
return typeof alignment2 === "string" && DOCX_ALIGNMENTS.has(alignment2) && alignment2 !== "right" ? [cellIndex] : [];
|
|
@@ -13161,7 +12725,10 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13161
12725
|
const facts = [];
|
|
13162
12726
|
const provenance = {};
|
|
13163
12727
|
let previousHeadingLevel;
|
|
13164
|
-
const authoredPath = (path4) => toAuthoredPointer(
|
|
12728
|
+
const authoredPath = (path4) => toAuthoredPointer(
|
|
12729
|
+
themed.sourceMap ?? {},
|
|
12730
|
+
toAuthoredPointer(expanded.sourceMap, path4)
|
|
12731
|
+
);
|
|
13165
12732
|
const addFact = (raw) => {
|
|
13166
12733
|
const fact = {
|
|
13167
12734
|
...raw,
|
|
@@ -13176,7 +12743,7 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13176
12743
|
...fact.relatedPaths && { relatedPaths: fact.relatedPaths }
|
|
13177
12744
|
};
|
|
13178
12745
|
};
|
|
13179
|
-
for (const budget of blockSlotBudgets(
|
|
12746
|
+
for (const budget of blockSlotBudgets(themed.document, expanded.blocks)) {
|
|
13180
12747
|
addFact({
|
|
13181
12748
|
id: `docx:block-slot:${budget.path}`,
|
|
13182
12749
|
kind: "docx/block-slot",
|
|
@@ -13271,7 +12838,19 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13271
12838
|
context.themeName,
|
|
13272
12839
|
authoredPropsAt(path4)
|
|
13273
12840
|
);
|
|
13274
|
-
if (design)
|
|
12841
|
+
if (design)
|
|
12842
|
+
addFact({
|
|
12843
|
+
...design,
|
|
12844
|
+
columns: design.columns.map((column) => {
|
|
12845
|
+
const authored = authoredPath(column.path);
|
|
12846
|
+
const table2 = /^(.*)\/props\/columns\/\d+$/.exec(authored)?.[1];
|
|
12847
|
+
return {
|
|
12848
|
+
...column,
|
|
12849
|
+
path: authored,
|
|
12850
|
+
generated: table2 === void 0 || asRecord(nodeAtPointer(themed.document, table2))?.name !== "table"
|
|
12851
|
+
};
|
|
12852
|
+
})
|
|
12853
|
+
});
|
|
13275
12854
|
}
|
|
13276
12855
|
if (node.name === "chart" || node.name === "highcharts") {
|
|
13277
12856
|
const fact = chartFact(node, props, path4, paletteTokens);
|
|
@@ -13326,11 +12905,19 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13326
12905
|
facts,
|
|
13327
12906
|
provenance,
|
|
13328
12907
|
renderer: options.renderer ?? DEFAULT_DOCX_RENDERER_ID2,
|
|
13329
|
-
...expanded.blocks.length > 0 && {
|
|
12908
|
+
...(expanded.blocks.length > 0 || (themed.blockPaths?.length ?? 0) > 0) && {
|
|
13330
12909
|
metadata: {
|
|
13331
12910
|
blocks: {
|
|
13332
|
-
sourceMap:
|
|
13333
|
-
|
|
12911
|
+
sourceMap: {
|
|
12912
|
+
...themed.sourceMap,
|
|
12913
|
+
...Object.fromEntries(
|
|
12914
|
+
Object.entries(expanded.sourceMap).map(([key, value]) => [
|
|
12915
|
+
key,
|
|
12916
|
+
toAuthoredPointer(themed.sourceMap ?? {}, value)
|
|
12917
|
+
])
|
|
12918
|
+
)
|
|
12919
|
+
},
|
|
12920
|
+
blocks: [...themed.blockPaths ?? [], ...expanded.blocks],
|
|
13334
12921
|
document: context.document
|
|
13335
12922
|
}
|
|
13336
12923
|
}
|
|
@@ -14355,6 +13942,7 @@ var docxTableDesignRule = {
|
|
|
14355
13942
|
}
|
|
14356
13943
|
};
|
|
14357
13944
|
function alignColumnRight(column) {
|
|
13945
|
+
if (column.generated) return [];
|
|
14358
13946
|
const operations = [
|
|
14359
13947
|
column.hasCellDefaults ? {
|
|
14360
13948
|
op: "add",
|
|
@@ -14760,7 +14348,7 @@ function validateComponentProps(schema, props, componentName, opts) {
|
|
|
14760
14348
|
componentName
|
|
14761
14349
|
});
|
|
14762
14350
|
}
|
|
14763
|
-
function
|
|
14351
|
+
function validateDocument2(document, customComponents, options) {
|
|
14764
14352
|
const knownCustomNames = new Set(customComponents.map((c) => c.name));
|
|
14765
14353
|
const documentResult = validateDocumentUnified(document, {
|
|
14766
14354
|
knownCustomNames,
|
|
@@ -15164,7 +14752,7 @@ function createBuilderImpl(state) {
|
|
|
15164
14752
|
...options?.validation
|
|
15165
14753
|
};
|
|
15166
14754
|
if (vOpts.enabled !== false) {
|
|
15167
|
-
const result =
|
|
14755
|
+
const result = validateDocument2(
|
|
15168
14756
|
validationDocument,
|
|
15169
14757
|
state.components,
|
|
15170
14758
|
{ allowUnknownFields: vOpts.allowUnknownFields }
|
|
@@ -15179,12 +14767,12 @@ function createBuilderImpl(state) {
|
|
|
15179
14767
|
);
|
|
15180
14768
|
}
|
|
15181
14769
|
}
|
|
15182
|
-
const validateEmitted = vOpts.enabled === false ? void 0 : (emitted, componentLabel) => {
|
|
15183
|
-
const result =
|
|
14770
|
+
const validateEmitted = vOpts.enabled === false ? void 0 : (emitted, componentLabel, sourcePath) => {
|
|
14771
|
+
const result = validateDocument2(
|
|
15184
14772
|
{
|
|
15185
14773
|
...internalDocument,
|
|
15186
14774
|
...renderer !== void 0 ? { renderer } : {},
|
|
15187
|
-
children: emitted
|
|
14775
|
+
children: sourcePath === void 0 ? emitted : [{ name: "section", props: {}, children: emitted }]
|
|
15188
14776
|
},
|
|
15189
14777
|
state.components,
|
|
15190
14778
|
{ allowUnknownFields: vOpts.allowUnknownFields }
|
|
@@ -15192,7 +14780,10 @@ function createBuilderImpl(state) {
|
|
|
15192
14780
|
if (!result.valid) {
|
|
15193
14781
|
throw new ComponentValidationError2(
|
|
15194
14782
|
(result.errors ?? []).map((e) => ({
|
|
15195
|
-
path: e.path ?? ""
|
|
14783
|
+
path: sourcePath === void 0 ? e.path ?? "" : (e.path ?? "").replace(
|
|
14784
|
+
/^\/children\/0\/children\/\d+/,
|
|
14785
|
+
sourcePath
|
|
14786
|
+
),
|
|
15196
14787
|
message: `custom component '${componentLabel}' emitted invalid output \u2014 ${e.message}`
|
|
15197
14788
|
})),
|
|
15198
14789
|
emitted
|
|
@@ -15210,6 +14801,62 @@ function createBuilderImpl(state) {
|
|
|
15210
14801
|
warnings,
|
|
15211
14802
|
resolveNamedTheme: resolveDocumentTheme
|
|
15212
14803
|
});
|
|
14804
|
+
if (modedRoot.props.blocks !== void 0) {
|
|
14805
|
+
const expanded = await expandBlocksWithPlugins(
|
|
14806
|
+
modedRoot,
|
|
14807
|
+
modedTheme,
|
|
14808
|
+
new Set(componentMap.keys()),
|
|
14809
|
+
async (component, path4) => {
|
|
14810
|
+
const custom = componentMap.get(String(component.name));
|
|
14811
|
+
const version = resolveComponentVersion(
|
|
14812
|
+
custom.name,
|
|
14813
|
+
custom.versions,
|
|
14814
|
+
component.version
|
|
14815
|
+
);
|
|
14816
|
+
const checked = validateComponentProps(
|
|
14817
|
+
version,
|
|
14818
|
+
component.props ?? {},
|
|
14819
|
+
custom.name,
|
|
14820
|
+
{ clean: vOpts.allowUnknownFields === true }
|
|
14821
|
+
);
|
|
14822
|
+
if (!checked.valid)
|
|
14823
|
+
throw new ComponentValidationError2(
|
|
14824
|
+
(checked.errors ?? []).map((e) => ({ path: path4, message: e.message })),
|
|
14825
|
+
component
|
|
14826
|
+
);
|
|
14827
|
+
const output = await version.render({
|
|
14828
|
+
props: cleanComponentProps(version, component.props ?? {}),
|
|
14829
|
+
theme: modedTheme,
|
|
14830
|
+
children: component.children,
|
|
14831
|
+
addWarning: (message, context) => warnings.push({
|
|
14832
|
+
component: custom.name,
|
|
14833
|
+
message,
|
|
14834
|
+
severity: "warning",
|
|
14835
|
+
context
|
|
14836
|
+
})
|
|
14837
|
+
});
|
|
14838
|
+
const emitted = Array.isArray(output) ? output : [output];
|
|
14839
|
+
validateEmitted?.(emitted, custom.name, path4);
|
|
14840
|
+
return emitted;
|
|
14841
|
+
},
|
|
14842
|
+
preserveSet
|
|
14843
|
+
);
|
|
14844
|
+
const [modedDoc2] = normalizeDocument(expanded.document);
|
|
14845
|
+
return {
|
|
14846
|
+
modedRoot,
|
|
14847
|
+
modedTheme,
|
|
14848
|
+
themeName,
|
|
14849
|
+
modedDoc: modedDoc2,
|
|
14850
|
+
sourceMap: expanded.sourceMap,
|
|
14851
|
+
blockPaths: expanded.blocks,
|
|
14852
|
+
warnings,
|
|
14853
|
+
preserveSet,
|
|
14854
|
+
processed: {
|
|
14855
|
+
standard: modedDoc2.children ?? [],
|
|
14856
|
+
preserved: expanded.preserved.children ?? []
|
|
14857
|
+
}
|
|
14858
|
+
};
|
|
14859
|
+
}
|
|
15213
14860
|
const processed = await processDocumentComponents(
|
|
15214
14861
|
modedRoot.children || [],
|
|
15215
14862
|
preserveSet,
|
|
@@ -15234,9 +14881,13 @@ function createBuilderImpl(state) {
|
|
|
15234
14881
|
}
|
|
15235
14882
|
async function expandStandardDefinition(document, options) {
|
|
15236
14883
|
try {
|
|
15237
|
-
const { modedDoc, warnings } = await expandDocument(
|
|
14884
|
+
const { modedDoc, warnings, sourceMap } = await expandDocument(
|
|
14885
|
+
document,
|
|
14886
|
+
options
|
|
14887
|
+
);
|
|
15238
14888
|
return {
|
|
15239
14889
|
standardDefinition: modedDoc,
|
|
14890
|
+
...sourceMap && { sourceMap },
|
|
15240
14891
|
warnings: warnings.length > 0 ? warnings : null
|
|
15241
14892
|
};
|
|
15242
14893
|
} catch (error) {
|
|
@@ -15254,6 +14905,8 @@ function createBuilderImpl(state) {
|
|
|
15254
14905
|
themeName,
|
|
15255
14906
|
processed,
|
|
15256
14907
|
modedDoc,
|
|
14908
|
+
sourceMap,
|
|
14909
|
+
blockPaths,
|
|
15257
14910
|
warnings,
|
|
15258
14911
|
preserveSet
|
|
15259
14912
|
} = await expandDocument(document, options);
|
|
@@ -15264,7 +14917,13 @@ function createBuilderImpl(state) {
|
|
|
15264
14917
|
const { buffer } = await generateBufferViaIr(modedDoc, {
|
|
15265
14918
|
// The prologue already ran: the theme had to be resolved before custom
|
|
15266
14919
|
// components expanded, because each one's `render` is handed it.
|
|
15267
|
-
context: {
|
|
14920
|
+
context: {
|
|
14921
|
+
document: modedDoc,
|
|
14922
|
+
theme: modedTheme,
|
|
14923
|
+
themeName,
|
|
14924
|
+
...sourceMap !== void 0 && { sourceMap },
|
|
14925
|
+
...blockPaths !== void 0 && { blockPaths }
|
|
14926
|
+
},
|
|
15268
14927
|
...state.services ? { services: state.services } : {},
|
|
15269
14928
|
...state.fonts ? { fonts: state.fonts } : {},
|
|
15270
14929
|
...baseDir !== void 0 ? { baseDir } : {},
|
|
@@ -15321,7 +14980,7 @@ function createBuilderImpl(state) {
|
|
|
15321
14980
|
function validate(document) {
|
|
15322
14981
|
try {
|
|
15323
14982
|
const internalDocument = document;
|
|
15324
|
-
const result =
|
|
14983
|
+
const result = validateDocument2(
|
|
15325
14984
|
internalDocument,
|
|
15326
14985
|
state.components
|
|
15327
14986
|
);
|
|
@@ -15400,7 +15059,6 @@ function getCoreVersion() {
|
|
|
15400
15059
|
return "Core v1.0.0";
|
|
15401
15060
|
}
|
|
15402
15061
|
export {
|
|
15403
|
-
BLOCK_NAMES,
|
|
15404
15062
|
ComponentValidationError2 as ComponentValidationError,
|
|
15405
15063
|
DocumentGenerator as CoreDocumentGenerator,
|
|
15406
15064
|
DEFAULT_DOCX_RENDERER_ID,
|
|
@@ -15415,10 +15073,6 @@ export {
|
|
|
15415
15073
|
analyzeDocxQuality,
|
|
15416
15074
|
blockSlotBudgets,
|
|
15417
15075
|
cleanComponentProps,
|
|
15418
|
-
compileCover,
|
|
15419
|
-
compileKeyTakeaways,
|
|
15420
|
-
compileRunningHead,
|
|
15421
|
-
compileSectionOpener,
|
|
15422
15076
|
consultingTheme,
|
|
15423
15077
|
createComponent,
|
|
15424
15078
|
createDocumentGenerator,
|
|
@@ -15449,7 +15103,6 @@ export {
|
|
|
15449
15103
|
getExampleNames,
|
|
15450
15104
|
getVisualPrepassStats,
|
|
15451
15105
|
hasNodeBuiltins,
|
|
15452
|
-
isChromeBlockName,
|
|
15453
15106
|
isColumnsComponent,
|
|
15454
15107
|
isDocxRendererId,
|
|
15455
15108
|
isHeadingComponent,
|
|
@@ -15473,12 +15126,10 @@ export {
|
|
|
15473
15126
|
resetVisualPrepassStats,
|
|
15474
15127
|
resolveDocxQualityProfile,
|
|
15475
15128
|
runExample,
|
|
15476
|
-
sectionMeasureTwips,
|
|
15477
|
-
sectionTracker,
|
|
15478
15129
|
themes,
|
|
15479
15130
|
toAuthoredPointer,
|
|
15480
15131
|
validateComponentProps,
|
|
15481
|
-
validateDocument,
|
|
15132
|
+
validateDocument2 as validateDocument,
|
|
15482
15133
|
validateJsonSchema,
|
|
15483
15134
|
validateThemeJsonString,
|
|
15484
15135
|
vermilionTheme
|