@json-to-office/core-docx 2.7.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blocks/document.d.ts +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 +296 -659
- 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 +291 -646
- 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 +2 -2
- package/dist/quality/facts.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();
|
|
@@ -13161,7 +12724,10 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13161
12724
|
const facts = [];
|
|
13162
12725
|
const provenance = {};
|
|
13163
12726
|
let previousHeadingLevel;
|
|
13164
|
-
const authoredPath = (path4) => toAuthoredPointer(
|
|
12727
|
+
const authoredPath = (path4) => toAuthoredPointer(
|
|
12728
|
+
themed.sourceMap ?? {},
|
|
12729
|
+
toAuthoredPointer(expanded.sourceMap, path4)
|
|
12730
|
+
);
|
|
13165
12731
|
const addFact = (raw) => {
|
|
13166
12732
|
const fact = {
|
|
13167
12733
|
...raw,
|
|
@@ -13176,7 +12742,7 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13176
12742
|
...fact.relatedPaths && { relatedPaths: fact.relatedPaths }
|
|
13177
12743
|
};
|
|
13178
12744
|
};
|
|
13179
|
-
for (const budget of blockSlotBudgets(
|
|
12745
|
+
for (const budget of blockSlotBudgets(themed.document, expanded.blocks)) {
|
|
13180
12746
|
addFact({
|
|
13181
12747
|
id: `docx:block-slot:${budget.path}`,
|
|
13182
12748
|
kind: "docx/block-slot",
|
|
@@ -13326,11 +12892,19 @@ function prepareDocxQualityDocument(document, options = {}) {
|
|
|
13326
12892
|
facts,
|
|
13327
12893
|
provenance,
|
|
13328
12894
|
renderer: options.renderer ?? DEFAULT_DOCX_RENDERER_ID2,
|
|
13329
|
-
...expanded.blocks.length > 0 && {
|
|
12895
|
+
...(expanded.blocks.length > 0 || (themed.blockPaths?.length ?? 0) > 0) && {
|
|
13330
12896
|
metadata: {
|
|
13331
12897
|
blocks: {
|
|
13332
|
-
sourceMap:
|
|
13333
|
-
|
|
12898
|
+
sourceMap: {
|
|
12899
|
+
...themed.sourceMap,
|
|
12900
|
+
...Object.fromEntries(
|
|
12901
|
+
Object.entries(expanded.sourceMap).map(([key, value]) => [
|
|
12902
|
+
key,
|
|
12903
|
+
toAuthoredPointer(themed.sourceMap ?? {}, value)
|
|
12904
|
+
])
|
|
12905
|
+
)
|
|
12906
|
+
},
|
|
12907
|
+
blocks: [...themed.blockPaths ?? [], ...expanded.blocks],
|
|
13334
12908
|
document: context.document
|
|
13335
12909
|
}
|
|
13336
12910
|
}
|
|
@@ -14760,7 +14334,7 @@ function validateComponentProps(schema, props, componentName, opts) {
|
|
|
14760
14334
|
componentName
|
|
14761
14335
|
});
|
|
14762
14336
|
}
|
|
14763
|
-
function
|
|
14337
|
+
function validateDocument2(document, customComponents, options) {
|
|
14764
14338
|
const knownCustomNames = new Set(customComponents.map((c) => c.name));
|
|
14765
14339
|
const documentResult = validateDocumentUnified(document, {
|
|
14766
14340
|
knownCustomNames,
|
|
@@ -15164,7 +14738,7 @@ function createBuilderImpl(state) {
|
|
|
15164
14738
|
...options?.validation
|
|
15165
14739
|
};
|
|
15166
14740
|
if (vOpts.enabled !== false) {
|
|
15167
|
-
const result =
|
|
14741
|
+
const result = validateDocument2(
|
|
15168
14742
|
validationDocument,
|
|
15169
14743
|
state.components,
|
|
15170
14744
|
{ allowUnknownFields: vOpts.allowUnknownFields }
|
|
@@ -15179,12 +14753,12 @@ function createBuilderImpl(state) {
|
|
|
15179
14753
|
);
|
|
15180
14754
|
}
|
|
15181
14755
|
}
|
|
15182
|
-
const validateEmitted = vOpts.enabled === false ? void 0 : (emitted, componentLabel) => {
|
|
15183
|
-
const result =
|
|
14756
|
+
const validateEmitted = vOpts.enabled === false ? void 0 : (emitted, componentLabel, sourcePath) => {
|
|
14757
|
+
const result = validateDocument2(
|
|
15184
14758
|
{
|
|
15185
14759
|
...internalDocument,
|
|
15186
14760
|
...renderer !== void 0 ? { renderer } : {},
|
|
15187
|
-
children: emitted
|
|
14761
|
+
children: sourcePath === void 0 ? emitted : [{ name: "section", props: {}, children: emitted }]
|
|
15188
14762
|
},
|
|
15189
14763
|
state.components,
|
|
15190
14764
|
{ allowUnknownFields: vOpts.allowUnknownFields }
|
|
@@ -15192,7 +14766,10 @@ function createBuilderImpl(state) {
|
|
|
15192
14766
|
if (!result.valid) {
|
|
15193
14767
|
throw new ComponentValidationError2(
|
|
15194
14768
|
(result.errors ?? []).map((e) => ({
|
|
15195
|
-
path: e.path ?? ""
|
|
14769
|
+
path: sourcePath === void 0 ? e.path ?? "" : (e.path ?? "").replace(
|
|
14770
|
+
/^\/children\/0\/children\/\d+/,
|
|
14771
|
+
sourcePath
|
|
14772
|
+
),
|
|
15196
14773
|
message: `custom component '${componentLabel}' emitted invalid output \u2014 ${e.message}`
|
|
15197
14774
|
})),
|
|
15198
14775
|
emitted
|
|
@@ -15210,6 +14787,62 @@ function createBuilderImpl(state) {
|
|
|
15210
14787
|
warnings,
|
|
15211
14788
|
resolveNamedTheme: resolveDocumentTheme
|
|
15212
14789
|
});
|
|
14790
|
+
if (modedRoot.props.blocks !== void 0) {
|
|
14791
|
+
const expanded = await expandBlocksWithPlugins(
|
|
14792
|
+
modedRoot,
|
|
14793
|
+
modedTheme,
|
|
14794
|
+
new Set(componentMap.keys()),
|
|
14795
|
+
async (component, path4) => {
|
|
14796
|
+
const custom = componentMap.get(String(component.name));
|
|
14797
|
+
const version = resolveComponentVersion(
|
|
14798
|
+
custom.name,
|
|
14799
|
+
custom.versions,
|
|
14800
|
+
component.version
|
|
14801
|
+
);
|
|
14802
|
+
const checked = validateComponentProps(
|
|
14803
|
+
version,
|
|
14804
|
+
component.props ?? {},
|
|
14805
|
+
custom.name,
|
|
14806
|
+
{ clean: vOpts.allowUnknownFields === true }
|
|
14807
|
+
);
|
|
14808
|
+
if (!checked.valid)
|
|
14809
|
+
throw new ComponentValidationError2(
|
|
14810
|
+
(checked.errors ?? []).map((e) => ({ path: path4, message: e.message })),
|
|
14811
|
+
component
|
|
14812
|
+
);
|
|
14813
|
+
const output = await version.render({
|
|
14814
|
+
props: cleanComponentProps(version, component.props ?? {}),
|
|
14815
|
+
theme: modedTheme,
|
|
14816
|
+
children: component.children,
|
|
14817
|
+
addWarning: (message, context) => warnings.push({
|
|
14818
|
+
component: custom.name,
|
|
14819
|
+
message,
|
|
14820
|
+
severity: "warning",
|
|
14821
|
+
context
|
|
14822
|
+
})
|
|
14823
|
+
});
|
|
14824
|
+
const emitted = Array.isArray(output) ? output : [output];
|
|
14825
|
+
validateEmitted?.(emitted, custom.name, path4);
|
|
14826
|
+
return emitted;
|
|
14827
|
+
},
|
|
14828
|
+
preserveSet
|
|
14829
|
+
);
|
|
14830
|
+
const [modedDoc2] = normalizeDocument(expanded.document);
|
|
14831
|
+
return {
|
|
14832
|
+
modedRoot,
|
|
14833
|
+
modedTheme,
|
|
14834
|
+
themeName,
|
|
14835
|
+
modedDoc: modedDoc2,
|
|
14836
|
+
sourceMap: expanded.sourceMap,
|
|
14837
|
+
blockPaths: expanded.blocks,
|
|
14838
|
+
warnings,
|
|
14839
|
+
preserveSet,
|
|
14840
|
+
processed: {
|
|
14841
|
+
standard: modedDoc2.children ?? [],
|
|
14842
|
+
preserved: expanded.preserved.children ?? []
|
|
14843
|
+
}
|
|
14844
|
+
};
|
|
14845
|
+
}
|
|
15213
14846
|
const processed = await processDocumentComponents(
|
|
15214
14847
|
modedRoot.children || [],
|
|
15215
14848
|
preserveSet,
|
|
@@ -15234,9 +14867,13 @@ function createBuilderImpl(state) {
|
|
|
15234
14867
|
}
|
|
15235
14868
|
async function expandStandardDefinition(document, options) {
|
|
15236
14869
|
try {
|
|
15237
|
-
const { modedDoc, warnings } = await expandDocument(
|
|
14870
|
+
const { modedDoc, warnings, sourceMap } = await expandDocument(
|
|
14871
|
+
document,
|
|
14872
|
+
options
|
|
14873
|
+
);
|
|
15238
14874
|
return {
|
|
15239
14875
|
standardDefinition: modedDoc,
|
|
14876
|
+
...sourceMap && { sourceMap },
|
|
15240
14877
|
warnings: warnings.length > 0 ? warnings : null
|
|
15241
14878
|
};
|
|
15242
14879
|
} catch (error) {
|
|
@@ -15254,6 +14891,8 @@ function createBuilderImpl(state) {
|
|
|
15254
14891
|
themeName,
|
|
15255
14892
|
processed,
|
|
15256
14893
|
modedDoc,
|
|
14894
|
+
sourceMap,
|
|
14895
|
+
blockPaths,
|
|
15257
14896
|
warnings,
|
|
15258
14897
|
preserveSet
|
|
15259
14898
|
} = await expandDocument(document, options);
|
|
@@ -15264,7 +14903,13 @@ function createBuilderImpl(state) {
|
|
|
15264
14903
|
const { buffer } = await generateBufferViaIr(modedDoc, {
|
|
15265
14904
|
// The prologue already ran: the theme had to be resolved before custom
|
|
15266
14905
|
// components expanded, because each one's `render` is handed it.
|
|
15267
|
-
context: {
|
|
14906
|
+
context: {
|
|
14907
|
+
document: modedDoc,
|
|
14908
|
+
theme: modedTheme,
|
|
14909
|
+
themeName,
|
|
14910
|
+
...sourceMap !== void 0 && { sourceMap },
|
|
14911
|
+
...blockPaths !== void 0 && { blockPaths }
|
|
14912
|
+
},
|
|
15268
14913
|
...state.services ? { services: state.services } : {},
|
|
15269
14914
|
...state.fonts ? { fonts: state.fonts } : {},
|
|
15270
14915
|
...baseDir !== void 0 ? { baseDir } : {},
|
|
@@ -15321,7 +14966,7 @@ function createBuilderImpl(state) {
|
|
|
15321
14966
|
function validate(document) {
|
|
15322
14967
|
try {
|
|
15323
14968
|
const internalDocument = document;
|
|
15324
|
-
const result =
|
|
14969
|
+
const result = validateDocument2(
|
|
15325
14970
|
internalDocument,
|
|
15326
14971
|
state.components
|
|
15327
14972
|
);
|
|
@@ -15400,7 +15045,6 @@ function getCoreVersion() {
|
|
|
15400
15045
|
return "Core v1.0.0";
|
|
15401
15046
|
}
|
|
15402
15047
|
export {
|
|
15403
|
-
BLOCK_NAMES,
|
|
15404
15048
|
ComponentValidationError2 as ComponentValidationError,
|
|
15405
15049
|
DocumentGenerator as CoreDocumentGenerator,
|
|
15406
15050
|
DEFAULT_DOCX_RENDERER_ID,
|
|
@@ -15415,10 +15059,6 @@ export {
|
|
|
15415
15059
|
analyzeDocxQuality,
|
|
15416
15060
|
blockSlotBudgets,
|
|
15417
15061
|
cleanComponentProps,
|
|
15418
|
-
compileCover,
|
|
15419
|
-
compileKeyTakeaways,
|
|
15420
|
-
compileRunningHead,
|
|
15421
|
-
compileSectionOpener,
|
|
15422
15062
|
consultingTheme,
|
|
15423
15063
|
createComponent,
|
|
15424
15064
|
createDocumentGenerator,
|
|
@@ -15449,7 +15089,6 @@ export {
|
|
|
15449
15089
|
getExampleNames,
|
|
15450
15090
|
getVisualPrepassStats,
|
|
15451
15091
|
hasNodeBuiltins,
|
|
15452
|
-
isChromeBlockName,
|
|
15453
15092
|
isColumnsComponent,
|
|
15454
15093
|
isDocxRendererId,
|
|
15455
15094
|
isHeadingComponent,
|
|
@@ -15473,12 +15112,10 @@ export {
|
|
|
15473
15112
|
resetVisualPrepassStats,
|
|
15474
15113
|
resolveDocxQualityProfile,
|
|
15475
15114
|
runExample,
|
|
15476
|
-
sectionMeasureTwips,
|
|
15477
|
-
sectionTracker,
|
|
15478
15115
|
themes,
|
|
15479
15116
|
toAuthoredPointer,
|
|
15480
15117
|
validateComponentProps,
|
|
15481
|
-
validateDocument,
|
|
15118
|
+
validateDocument2 as validateDocument,
|
|
15482
15119
|
validateJsonSchema,
|
|
15483
15120
|
validateThemeJsonString,
|
|
15484
15121
|
vermilionTheme
|