@json-to-office/core-docx 7.3.0 → 7.4.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.
@@ -4,13 +4,15 @@
4
4
  * The docx `chart` component spells every series as labels and values, the
5
5
  * vocabulary it shares with the pptx component. A scatter chart has no
6
6
  * categories, though: each point needs an x. The label is that x when it reads
7
- * as a number; one that does not is placed at its position, 1, 2, 3… in order,
8
- * which is what Word and LibreOffice do with an x value written as text. Both
9
- * renderers write the x values as numbers. The compiler warns about such a
10
- * chart once, so both renderers say the same thing about it.
7
+ * as a finite number; text is placed at its position, 1, 2, 3… in order.
8
+ * A numeric label outside the finite range is refused rather than moved to a
9
+ * different x. Both renderers write the x values as numbers. The compiler
10
+ * warns about text labels once, so both renderers say the same thing about it.
11
11
  */
12
- /** Whether a label reads as a number, ignoring surrounding whitespace. */
12
+ /** Whether a label reads as a finite number. */
13
13
  export declare function isNumericLabel(label: string): boolean;
14
+ /** Whether a numeric label exceeds the range a chart can plot. */
15
+ export declare function isOutOfRangeNumericLabel(label: string): boolean;
14
16
  /** The x of a scatter chart's point `index`: its label, or its position. */
15
17
  export declare function scatterX(labels: readonly string[], index: number): number;
16
18
  //# sourceMappingURL=chartValues.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chartValues.d.ts","sourceRoot":"","sources":["../../src/ir/chartValues.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAKzE"}
1
+ {"version":3,"file":"chartValues.d.ts","sourceRoot":"","sources":["../../src/ir/chartValues.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,gDAAgD;AAChD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED,kEAAkE;AAClE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG/D;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAUzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/ir/compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,gBAAgB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAqD3D,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,wBAAwB,CAAC;AAuC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAEL,KAAK,MAAM,EAuCZ,MAAM,SAAS,CAAC;AAyBjB,2DAA2D;AAC3D,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,2EAA2E;IAC3E,QAAQ,EAAE,SAAS,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;IACrD,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B;;;;OAIG;IACH,WAAW,EAAE,oBAAoB,EAAE,CAAC;CACrC;AAoGD,wBAAgB,eAAe,CAC7B,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,UAAU,EAClB,QAAQ,GAAE,iBAAiB,EAAO,EAClC,MAAM,GAAE,cAA0B,EAClC,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,GACvC,iBAAiB,CAkHnB"}
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/ir/compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,gBAAgB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAqD3D,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,wBAAwB,CAAC;AAuC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAEL,KAAK,MAAM,EAwCZ,MAAM,SAAS,CAAC;AAyBjB,2DAA2D;AAC3D,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,2EAA2E;IAC3E,QAAQ,EAAE,SAAS,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;IACrD,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B;;;;OAIG;IACH,WAAW,EAAE,oBAAoB,EAAE,CAAC;CACrC;AAoGD,wBAAgB,eAAe,CAC7B,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,UAAU,EAClB,QAAQ,GAAE,iBAAiB,EAAO,EAClC,MAAM,GAAE,cAA0B,EAClC,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,GACvC,iBAAiB,CAkHnB"}
@@ -2848,12 +2848,28 @@ var init_units = __esm({
2848
2848
  });
2849
2849
 
2850
2850
  // src/ir/chartValues.ts
2851
+ function numericLabelValue(label) {
2852
+ const value = label.trim();
2853
+ return NUMERIC_LABEL.test(value) ? Number(value) : void 0;
2854
+ }
2851
2855
  function isNumericLabel(label) {
2852
- return NUMERIC_LABEL.test(label.trim());
2856
+ const value = numericLabelValue(label);
2857
+ return value !== void 0 && Number.isFinite(value);
2858
+ }
2859
+ function isOutOfRangeNumericLabel(label) {
2860
+ const value = numericLabelValue(label);
2861
+ return value !== void 0 && !Number.isFinite(value);
2853
2862
  }
2854
2863
  function scatterX(labels, index) {
2855
2864
  const label = labels[index];
2856
- return label !== void 0 && isNumericLabel(label) ? Number(label) : index + 1;
2865
+ const value = label === void 0 ? void 0 : numericLabelValue(label);
2866
+ if (value === void 0) return index + 1;
2867
+ if (!Number.isFinite(value)) {
2868
+ throw new RangeError(
2869
+ `Scatter x label ${JSON.stringify(label)} is not finite.`
2870
+ );
2871
+ }
2872
+ return value;
2857
2873
  }
2858
2874
  var NUMERIC_LABEL;
2859
2875
  var init_chartValues = __esm({
@@ -2886,7 +2902,7 @@ var init_chartText = __esm({
2886
2902
  });
2887
2903
 
2888
2904
  // src/renderers/docxjs/docxSubpath.ts
2889
- function docxSubpath(specifier, component, importer) {
2905
+ function docxSubpath(specifier, component, importer, since = "9.8.0") {
2890
2906
  let module;
2891
2907
  let failure;
2892
2908
  let loading;
@@ -2910,7 +2926,7 @@ function docxSubpath(specifier, component, importer) {
2910
2926
  const { reason } = failure;
2911
2927
  const detail = reason instanceof Error ? reason.message : String(reason);
2912
2928
  throw new Error(
2913
- `The docx \`${component}\` component needs docx 9.8.0 or later: the \`${specifier}\` entry could not be loaded (${detail})`
2929
+ `The docx \`${component}\` component needs docx ${since} or later: the \`${specifier}\` entry could not be loaded (${detail})`
2914
2930
  );
2915
2931
  }
2916
2932
  throw new Error(
@@ -3507,8 +3523,19 @@ function emitBlock(block2, resources = /* @__PURE__ */ new Map()) {
3507
3523
  return assertNever2(block2, "DocxIrBlock");
3508
3524
  }
3509
3525
  }
3526
+ function emitOutsideBody(emit) {
3527
+ const was = outsideBody;
3528
+ outsideBody = true;
3529
+ try {
3530
+ return emit();
3531
+ } finally {
3532
+ outsideBody = was;
3533
+ }
3534
+ }
3510
3535
  function emitToc(block2) {
3511
- return new ThemedTableOfContents(block2.alias ?? "Table of Contents", {
3536
+ const cached = outsideBody && block2.cachedEntries?.length;
3537
+ const Field = cached ? ThemedTableOfContents : TableOfContents;
3538
+ return new Field(block2.alias ?? "Table of Contents", {
3512
3539
  ...block2.hyperlink !== void 0 ? { hyperlink: block2.hyperlink } : {},
3513
3540
  ...block2.headingRange ? {
3514
3541
  headingStyleRange: `${block2.headingRange.from}-${block2.headingRange.to}`
@@ -3521,7 +3548,7 @@ function emitToc(block2) {
3521
3548
  pageNumbersEntryLevelsRange: block2.omitPageNumbersForLevels.map((range) => `${range.from}-${range.to}`).join(",")
3522
3549
  } : {},
3523
3550
  ...block2.entrySeparator !== void 0 ? { entryAndPageNumberSeparator: block2.entrySeparator } : {},
3524
- ...block2.cachedEntries?.length ? {
3551
+ ...cached ? {
3525
3552
  cachedEntries: block2.cachedEntries.map((entry) => ({
3526
3553
  title: entry.text,
3527
3554
  level: entry.level
@@ -3644,7 +3671,7 @@ function emitBorder(border3) {
3644
3671
  ...border3.spacePoints !== void 0 ? { space: border3.spacePoints } : {}
3645
3672
  };
3646
3673
  }
3647
- var ALIGNMENT2, PAGE_FIELDS, isSequenceField, WRAP_TYPE, ThemedTableOfContents, VERTICAL_ALIGN, TABLE_ANCHOR, HORIZONTAL_POSITION, VERTICAL_POSITION;
3674
+ var ALIGNMENT2, PAGE_FIELDS, isSequenceField, WRAP_TYPE, ThemedTableOfContents, outsideBody, VERTICAL_ALIGN, TABLE_ANCHOR, HORIZONTAL_POSITION, VERTICAL_POSITION;
3648
3675
  var init_emit = __esm({
3649
3676
  "src/renderers/docxjs/emit.ts"() {
3650
3677
  "use strict";
@@ -3670,6 +3697,7 @@ var init_emit = __esm({
3670
3697
  Object.defineProperty(ThemedTableOfContents.prototype, "getTabStopsForLevel", {
3671
3698
  value: () => []
3672
3699
  });
3700
+ outsideBody = false;
3673
3701
  VERTICAL_ALIGN = {
3674
3702
  top: VerticalAlign.TOP,
3675
3703
  center: VerticalAlign.CENTER,
@@ -3857,6 +3885,318 @@ var init_styles2 = __esm({
3857
3885
  }
3858
3886
  });
3859
3887
 
3888
+ // src/renderers/docxjs/pageNumbers.ts
3889
+ import {
3890
+ Tab as Tab2
3891
+ } from "docx";
3892
+ function needsPageNumbers(ir) {
3893
+ const seen = /* @__PURE__ */ new Set();
3894
+ const visit = (value) => {
3895
+ if (typeof value !== "object" || value === null) return false;
3896
+ if (ArrayBuffer.isView(value) || seen.has(value)) return false;
3897
+ seen.add(value);
3898
+ if (Array.isArray(value)) return value.some(visit);
3899
+ if (value.kind === "toc") return true;
3900
+ return Object.values(value).some(visit);
3901
+ };
3902
+ return ir.sections.some((section2) => visit(section2.children));
3903
+ }
3904
+ async function createPageNumberEstimator(ir) {
3905
+ await layout.load();
3906
+ const cached = cachedContentsEntries(ir);
3907
+ const separators = contentsSeparators(ir);
3908
+ const estimate = layout.loaded() ? layout.get().estimatePageNumbersWith({ guess: true }) : void 0;
3909
+ return (body, context) => {
3910
+ renumberContentsBookmarks(body);
3911
+ restoreEntryNumbers(body, cached, separators);
3912
+ dropContentsEntryTabs(body);
3913
+ writeSeparatorTabs(body, context);
3914
+ endContentsInLastEntry(body);
3915
+ if (!estimate) {
3916
+ unavailable(
3917
+ `the \`docx/layout\` entry could not be loaded (${failureOf(() => layout.get())})`
3918
+ );
3919
+ return { bookmarks: /* @__PURE__ */ new Map() };
3920
+ }
3921
+ try {
3922
+ const estimated = estimate(body, context);
3923
+ if (complete(estimated)) clearUpdateFields(context.file);
3924
+ return estimated;
3925
+ } catch (error) {
3926
+ unavailable(error instanceof Error ? error.message : String(error));
3927
+ return { bookmarks: /* @__PURE__ */ new Map() };
3928
+ }
3929
+ };
3930
+ }
3931
+ function unavailable(reason) {
3932
+ reportWarning(
3933
+ "toc",
3934
+ PAGE_NUMBERS_UNAVAILABLE,
3935
+ `The table of contents is written without page numbers: laying the pages out failed (${reason}). Word fills them in when it updates the fields on open.`
3936
+ );
3937
+ }
3938
+ function failureOf(get) {
3939
+ try {
3940
+ get();
3941
+ return "unknown";
3942
+ } catch (error) {
3943
+ return error instanceof Error ? error.message : String(error);
3944
+ }
3945
+ }
3946
+ function complete(estimated) {
3947
+ return estimated.pageCount !== void 0 && (estimated.guesses ?? []).length === 0;
3948
+ }
3949
+ function clearUpdateFields(file) {
3950
+ const root = file?.Settings?.root;
3951
+ if (!root) return;
3952
+ const at = root.findIndex(
3953
+ (element) => element?.rootKey === "w:updateFields"
3954
+ );
3955
+ if (at >= 0) root.splice(at, 1);
3956
+ }
3957
+ function isContentsField(sdt) {
3958
+ let found = false;
3959
+ const visit = (element) => {
3960
+ if (found) return;
3961
+ if (nameOf(element) === "w:instrText") {
3962
+ found = childrenOf(element).some(
3963
+ (child) => typeof child === "string" && /^\s*TOC\b/.test(child)
3964
+ );
3965
+ return;
3966
+ }
3967
+ childrenOf(element).forEach(visit);
3968
+ };
3969
+ visit(sdt);
3970
+ return found;
3971
+ }
3972
+ function contentsFields(body) {
3973
+ const found = [];
3974
+ const visit = (element) => {
3975
+ const name = nameOf(element);
3976
+ if (name === void 0 || name === "_attr") return;
3977
+ if (name === "w:sdt" && isContentsField(element)) {
3978
+ found.push(element);
3979
+ return;
3980
+ }
3981
+ childrenOf(element).forEach(visit);
3982
+ };
3983
+ visit(body);
3984
+ return found;
3985
+ }
3986
+ function entryParagraphs(field) {
3987
+ return childrenOf(field).filter((content) => nameOf(content) === "w:sdtContent").flatMap(
3988
+ (content) => childrenOf(content).filter((paragraph2) => nameOf(paragraph2) === "w:p")
3989
+ );
3990
+ }
3991
+ function dropContentsEntryTabs(body) {
3992
+ for (const field of contentsFields(body)) {
3993
+ for (const paragraph2 of entryParagraphs(field)) {
3994
+ for (const properties of childrenOf(paragraph2)) {
3995
+ if (nameOf(properties) !== "w:pPr") continue;
3996
+ properties["w:pPr"] = childrenOf(properties).filter(
3997
+ (child) => nameOf(child) !== "w:tabs"
3998
+ );
3999
+ }
4000
+ }
4001
+ }
4002
+ }
4003
+ function endContentsInLastEntry(body) {
4004
+ for (const field of contentsFields(body)) {
4005
+ for (const content of childrenOf(field)) {
4006
+ if (nameOf(content) !== "w:sdtContent") continue;
4007
+ const paragraphs = childrenOf(content);
4008
+ const last = paragraphs[paragraphs.length - 1];
4009
+ const entry = paragraphs[paragraphs.length - 2];
4010
+ if (nameOf(last) !== "w:p" || nameOf(entry) !== "w:p") continue;
4011
+ const runs = childrenOf(last);
4012
+ const onlyTheEnd = runs.length === 1 && nameOf(runs[0]) === "w:r" && childrenOf(runs[0]).every(
4013
+ (child) => nameOf(child) === "w:fldChar" && attributesOf(child)?.["w:fldCharType"] === "end"
4014
+ );
4015
+ const entries = paragraphs.filter(
4016
+ (paragraph2) => textNodes(paragraph2).length > 0
4017
+ );
4018
+ if (!onlyTheEnd || entries.length < 2 || textNodes(entry).length === 0)
4019
+ continue;
4020
+ childrenOf(entry).push(runs[0]);
4021
+ paragraphs.pop();
4022
+ }
4023
+ }
4024
+ }
4025
+ function writeSeparatorTabs(body, context) {
4026
+ const tab = () => new Tab2().prepForXml(context);
4027
+ const visit = (element) => {
4028
+ const name = nameOf(element);
4029
+ if (name === void 0 || name === "_attr") return;
4030
+ if (name === "w:r") {
4031
+ const children = childrenOf(element);
4032
+ children.forEach((child, index) => {
4033
+ if (nameOf(child) !== "w:t") return;
4034
+ const text = childrenOf(child).filter(
4035
+ (part) => typeof part === "string"
4036
+ );
4037
+ if (text.length === 1 && text[0] === " ") children[index] = tab();
4038
+ });
4039
+ return;
4040
+ }
4041
+ childrenOf(element).forEach(visit);
4042
+ };
4043
+ for (const field of contentsFields(body))
4044
+ entryParagraphs(field).forEach(visit);
4045
+ }
4046
+ function textNodes(element) {
4047
+ const name = nameOf(element);
4048
+ if (name === void 0 || name === "_attr" || name === "w:instrText")
4049
+ return [];
4050
+ const children = childrenOf(element);
4051
+ if (name === "w:t")
4052
+ return children.flatMap(
4053
+ (child, index) => typeof child === "string" ? [{ parent: children, index }] : []
4054
+ );
4055
+ return children.flatMap(textNodes);
4056
+ }
4057
+ function contentsSeparators(ir) {
4058
+ const separators = [];
4059
+ const visit = (value) => {
4060
+ if (typeof value !== "object" || value === null) return;
4061
+ if (ArrayBuffer.isView(value)) return;
4062
+ if (Array.isArray(value)) {
4063
+ value.forEach(visit);
4064
+ return;
4065
+ }
4066
+ if (value.kind === "toc") {
4067
+ separators.push(value.entrySeparator);
4068
+ return;
4069
+ }
4070
+ Object.values(value).forEach(visit);
4071
+ };
4072
+ for (const section2 of ir.sections) visit(section2.children);
4073
+ return separators;
4074
+ }
4075
+ function cachedContentsEntries(ir) {
4076
+ const fields = [];
4077
+ const visit = (value) => {
4078
+ if (typeof value !== "object" || value === null) return;
4079
+ if (ArrayBuffer.isView(value)) return;
4080
+ if (Array.isArray(value)) {
4081
+ value.forEach(visit);
4082
+ return;
4083
+ }
4084
+ if (value.kind === "toc") {
4085
+ const toc = value;
4086
+ fields.push(toc.cachedEntries?.map((entry) => entry.text));
4087
+ return;
4088
+ }
4089
+ Object.values(value).forEach(visit);
4090
+ };
4091
+ for (const section2 of ir.sections) visit(section2.children);
4092
+ return fields;
4093
+ }
4094
+ function restoreEntryNumbers(body, cached, separators = []) {
4095
+ contentsFields(body).forEach((field, index) => {
4096
+ const texts = cached[index];
4097
+ const paragraphs = entryParagraphs(field).filter(
4098
+ (paragraph2) => textNodes(paragraph2).length > 0
4099
+ );
4100
+ if (!texts || texts.length !== paragraphs.length) return;
4101
+ paragraphs.forEach((paragraph2, entry) => {
4102
+ const nodes = textNodes(paragraph2);
4103
+ let title = nodes.map(({ parent, index: at }) => parent[at]).join("");
4104
+ const separator = separators[index];
4105
+ if (separator && title.endsWith(separator))
4106
+ title = title.slice(0, -separator.length);
4107
+ const text = texts[entry];
4108
+ if (title === "" || text === title || !text.endsWith(title)) return;
4109
+ const [first] = nodes;
4110
+ first.parent[first.index] = text.slice(0, text.length - title.length) + first.parent[first.index];
4111
+ });
4112
+ });
4113
+ }
4114
+ function renumberContentsBookmarks(body) {
4115
+ const names = /* @__PURE__ */ new Map();
4116
+ const paragraphs = (element) => {
4117
+ const name = nameOf(element);
4118
+ if (name === void 0 || name === "_attr") return;
4119
+ if (name !== "w:p") {
4120
+ childrenOf(element).forEach(paragraphs);
4121
+ return;
4122
+ }
4123
+ const children = childrenOf(element);
4124
+ for (const start of children) {
4125
+ if (nameOf(start) !== "w:bookmarkStart") continue;
4126
+ const attributes = attributesOf(start);
4127
+ const old = attributes?.["w:name"];
4128
+ if (typeof old !== "string" || !CONTENTS_BOOKMARK.test(old)) continue;
4129
+ const ordinal = names.size + 1;
4130
+ const renamed2 = `_Toc${ordinal}`;
4131
+ const id = CONTENTS_BOOKMARK_ID_BASE + ordinal;
4132
+ names.set(old, renamed2);
4133
+ const oldId = attributes["w:id"];
4134
+ attributes["w:name"] = renamed2;
4135
+ attributes["w:id"] = id;
4136
+ const end = [...children].reverse().find(
4137
+ (child) => nameOf(child) === "w:bookmarkEnd" && String(attributesOf(child)?.["w:id"]) === String(oldId)
4138
+ );
4139
+ if (end) attributesOf(end)["w:id"] = id;
4140
+ }
4141
+ };
4142
+ paragraphs(body);
4143
+ if (names.size === 0) return;
4144
+ const references = (element) => {
4145
+ const name = nameOf(element);
4146
+ if (name === void 0) return;
4147
+ if (name === "w:hyperlink") {
4148
+ const attributes = attributesOf(element);
4149
+ const anchor = attributes?.["w:anchor"];
4150
+ if (typeof anchor === "string" && names.has(anchor))
4151
+ attributes["w:anchor"] = names.get(anchor);
4152
+ }
4153
+ if (name === "w:instrText") {
4154
+ const children = childrenOf(element);
4155
+ children.forEach((child, index) => {
4156
+ if (typeof child !== "string") return;
4157
+ children[index] = child.replace(
4158
+ /\b(PAGEREF\s+)(_Toc\d+)\b/g,
4159
+ (match, field, bookmark) => names.has(bookmark) ? `${field}${names.get(bookmark)}` : match
4160
+ );
4161
+ });
4162
+ element[name] = children;
4163
+ return;
4164
+ }
4165
+ if (name === "_attr") return;
4166
+ childrenOf(element).forEach(references);
4167
+ };
4168
+ references(body);
4169
+ }
4170
+ function attributesOf(element) {
4171
+ const attributes = childrenOf(element).find(
4172
+ (child) => nameOf(child) === "_attr"
4173
+ );
4174
+ return attributes?._attr;
4175
+ }
4176
+ var PAGE_NUMBERS_UNAVAILABLE, layout, nameOf, childrenOf, CONTENTS_BOOKMARK_ID_BASE, CONTENTS_BOOKMARK;
4177
+ var init_pageNumbers = __esm({
4178
+ "src/renderers/docxjs/pageNumbers.ts"() {
4179
+ "use strict";
4180
+ init_generationContext();
4181
+ init_docxSubpath();
4182
+ PAGE_NUMBERS_UNAVAILABLE = "W_DOCX_PAGE_NUMBERS_UNAVAILABLE";
4183
+ layout = docxSubpath(
4184
+ "docx/layout",
4185
+ "toc",
4186
+ () => import("docx/layout"),
4187
+ "9.9.0"
4188
+ );
4189
+ nameOf = (element) => typeof element === "object" && element !== null && !Array.isArray(element) ? Object.keys(element)[0] : void 0;
4190
+ childrenOf = (element) => {
4191
+ const name = nameOf(element);
4192
+ const content = name === void 0 ? void 0 : element[name];
4193
+ return Array.isArray(content) ? content : content === void 0 ? [] : [content];
4194
+ };
4195
+ CONTENTS_BOOKMARK_ID_BASE = 3e6;
4196
+ CONTENTS_BOOKMARK = /^_Toc\d+$/;
4197
+ }
4198
+ });
4199
+
3860
4200
  // src/utils/normalizeTextCase.ts
3861
4201
  function normalizeTextCase(zip) {
3862
4202
  let changed = false;
@@ -4638,7 +4978,8 @@ function createDocxJsRenderer() {
4638
4978
  )
4639
4979
  });
4640
4980
  }
4641
- const document = buildDocument(ir, resources);
4981
+ const pageNumbers = needsPageNumbers(ir) ? await createPageNumberEstimator(ir) : void 0;
4982
+ const document = buildDocument(ir, resources, pageNumbers);
4642
4983
  const packed = await Packer.toBuffer(document);
4643
4984
  const fixed = fixFloatingImageIdsInBuffer(packed);
4644
4985
  const repaired = markers ? repairDrawingGroupsInBuffer(fixed, markers) : fixed;
@@ -4656,13 +4997,12 @@ function createDocxJsRenderer() {
4656
4997
  }
4657
4998
  };
4658
4999
  }
4659
- function buildDocument(ir, resources = /* @__PURE__ */ new Map()) {
5000
+ function buildDocument(ir, resources = /* @__PURE__ */ new Map(), pageNumbers) {
4660
5001
  return new Document({
5002
+ ...pageNumbers ? { pageNumbers } : {},
4661
5003
  styles: emitStyles(ir.styles),
4662
5004
  ...ir.theme ? { theme: themeOptions(ir.theme) } : {},
4663
- sections: ir.sections.map(
4664
- (section2, index) => sectionOptions(section2, resources, index === ir.sections.length - 1)
4665
- ),
5005
+ sections: ir.sections.map((section2) => sectionOptions(section2, resources)),
4666
5006
  ...coreProperties(ir),
4667
5007
  features: {
4668
5008
  updateFields: ir.settings.updateFields,
@@ -4681,8 +5021,8 @@ function buildDocument(ir, resources = /* @__PURE__ */ new Map()) {
4681
5021
  author: comment.author,
4682
5022
  ...comment.initials ? { initials: comment.initials } : {},
4683
5023
  date: new Date(comment.date),
4684
- children: comment.children.map(
4685
- (block2) => emitBlock(block2, resources)
5024
+ children: emitOutsideBody(
5025
+ () => comment.children.map((block2) => emitBlock(block2, resources))
4686
5026
  ),
4687
5027
  ...comment.parentId !== void 0 ? { parentId: comment.parentId } : {},
4688
5028
  ...comment.resolved !== void 0 ? { resolved: comment.resolved } : {}
@@ -4710,8 +5050,8 @@ function noteBodies(notes, resources) {
4710
5050
  const bodies = {};
4711
5051
  for (const note of notes) {
4712
5052
  bodies[String(note.id)] = {
4713
- children: note.children.map(
4714
- (block2) => emitBlock(block2, resources)
5053
+ children: emitOutsideBody(
5054
+ () => note.children.map((block2) => emitBlock(block2, resources))
4715
5055
  )
4716
5056
  };
4717
5057
  }
@@ -4872,7 +5212,7 @@ function collectImagePlacements(ir) {
4872
5212
  }
4873
5213
  return { placements, drawingGroups };
4874
5214
  }
4875
- function sectionOptions(section2, resources, closesDocument = false) {
5215
+ function sectionOptions(section2, resources) {
4876
5216
  const { page, columns } = section2.properties;
4877
5217
  const options = {
4878
5218
  properties: {
@@ -4911,7 +5251,7 @@ function sectionOptions(section2, resources, closesDocument = false) {
4911
5251
  }
4912
5252
  } : {}
4913
5253
  },
4914
- children: sectionChildren(section2, resources, closesDocument)
5254
+ children: sectionChildren(section2, resources)
4915
5255
  };
4916
5256
  const headers = chromeSlots(section2.headers, Header, resources);
4917
5257
  if (headers) options.headers = headers;
@@ -4925,7 +5265,9 @@ function chromeSlots(set, Part, resources) {
4925
5265
  for (const slot of ["default", "first", "even"]) {
4926
5266
  const part = set[slot];
4927
5267
  if (part) {
4928
- out[slot] = new Part({ children: partChildren(part, resources) });
5268
+ out[slot] = new Part({
5269
+ children: emitOutsideBody(() => partChildren(part, resources))
5270
+ });
4929
5271
  }
4930
5272
  }
4931
5273
  return Object.keys(out).length > 0 ? out : void 0;
@@ -4933,10 +5275,10 @@ function chromeSlots(set, Part, resources) {
4933
5275
  function partChildren(part, resources) {
4934
5276
  return part.children.map((block2) => emitBlock(block2, resources));
4935
5277
  }
4936
- function sectionChildren(section2, resources, closesDocument = false) {
5278
+ function sectionChildren(section2, resources) {
4937
5279
  const blocks = section2.children.map((block2) => emitBlock(block2, resources));
4938
5280
  const bookmark = section2.bookmark;
4939
- const endsInFrame = closesDocument && lastBlockIsFrame(section2);
5281
+ const endsInFrame = lastBlockIsFrame(section2);
4940
5282
  if (!bookmark && !endsInFrame) return blocks;
4941
5283
  const out = [...blocks];
4942
5284
  if (bookmark?.opens) {
@@ -4989,6 +5331,7 @@ var init_docxjs = __esm({
4989
5331
  "use strict";
4990
5332
  init_styles2();
4991
5333
  init_charts();
5334
+ init_pageNumbers();
4992
5335
  init_imageUtils();
4993
5336
  init_packageDocument();
4994
5337
  init_fixFloatingImageIds();
@@ -6175,7 +6518,7 @@ function sectionChildren2(value, ctx, closesDocument = false) {
6175
6518
  const blocks = value.children.map((child) => block(child, ctx));
6176
6519
  const last = value.children[value.children.length - 1];
6177
6520
  const bookmark = value.bookmark;
6178
- if (bookmark?.closes && last?.kind !== "paragraph" || closesDocument && last?.kind === "paragraph" && last.frame !== void 0)
6521
+ if (bookmark?.closes && last?.kind !== "paragraph" || last?.kind === "paragraph" && last.frame !== void 0 && (closesDocument || !bookmark?.closes))
6179
6522
  blocks.push({
6180
6523
  paragraph: {
6181
6524
  children: [],
@@ -10541,9 +10884,9 @@ function schemeHex(token, theme) {
10541
10884
  // src/ir/compiler.ts
10542
10885
  var CONTENT_BOOKMARK_ID_BASE = 2e6;
10543
10886
  var SINGLE_LINE_TWIPS = 240;
10544
- function compileDocument(structure, layout, warnings = [], images = /* @__PURE__ */ new Map(), options = {}) {
10887
+ function compileDocument(structure, layout2, warnings = [], images = /* @__PURE__ */ new Map(), options = {}) {
10545
10888
  const styles = createDocumentStyles(structure.theme, structure.language);
10546
- const outline = collectOutline(layout, warnings);
10889
+ const outline = collectOutline(layout2, warnings);
10547
10890
  const ctx = {
10548
10891
  theme: structure.theme,
10549
10892
  themeName: structure.themeName,
@@ -10578,10 +10921,10 @@ function compileDocument(structure, layout, warnings = [], images = /* @__PURE__
10578
10921
  };
10579
10922
  ctx.features.require("paragraphs", "sections");
10580
10923
  ctx.features.require("styles", "styles");
10581
- if (layout.sections.length > 1) ctx.features.require("sections", "sections");
10582
- const ordinals = computeSectionOrdinals(layout.sections);
10583
- const chrome = resolveSectionChrome(layout.sections);
10584
- const sections = layout.sections.map(
10924
+ if (layout2.sections.length > 1) ctx.features.require("sections", "sections");
10925
+ const ordinals = computeSectionOrdinals(layout2.sections);
10926
+ const chrome = resolveSectionChrome(layout2.sections);
10927
+ const sections = layout2.sections.map(
10585
10928
  (section2, index) => compileSection(section2, index, ordinals[index], chrome[index], ctx)
10586
10929
  );
10587
10930
  if (ctx.hasResolvedComment && !ctx.comments.some((comment) => comment.parentId !== void 0)) {
@@ -10659,9 +11002,9 @@ function separateFromTables(blocks, bodyAfterTwips) {
10659
11002
  }
10660
11003
  }
10661
11004
  }
10662
- function collectOutline(layout, warnings) {
11005
+ function collectOutline(layout2, warnings) {
10663
11006
  try {
10664
- return collectDocumentOutline(layout.sections);
11007
+ return collectDocumentOutline(layout2.sections);
10665
11008
  } catch (error) {
10666
11009
  warnings.push({
10667
11010
  component: "document",
@@ -12703,11 +13046,21 @@ function compileChart(component, scope) {
12703
13046
  );
12704
13047
  }
12705
13048
  }
13049
+ if (props.type === "scatter") {
13050
+ for (const [index, entry] of series.entries()) {
13051
+ const at = entry.labels.findIndex(isOutOfRangeNumericLabel);
13052
+ if (at !== -1) {
13053
+ throw new Error(
13054
+ `Chart series "${entry.name ?? `series ${index}`}" at ${path3} has an x label ${JSON.stringify(entry.labels[at])} outside the finite number range.`
13055
+ );
13056
+ }
13057
+ }
13058
+ }
12706
13059
  if (props.type === "scatter" && series.some((entry) => entry.labels.some((label) => !isNumericLabel(label)))) {
12707
13060
  warnOnce(
12708
13061
  ctx,
12709
13062
  "chart",
12710
- `Chart at ${path3} is a scatter chart whose labels are not all numbers; each label is its point's x, so these points are placed at 1, 2, 3\u2026 in order.`
13063
+ `Chart at ${path3} is a scatter chart whose labels are not all finite numbers; labels that do not read as finite numbers use their 1-based positions for x.`
12711
13064
  );
12712
13065
  }
12713
13066
  if ((props.type === "pie" || props.type === "doughnut") && (typeof props.catAxisTitle === "string" || typeof props.valAxisTitle === "string")) {
@@ -13197,13 +13550,19 @@ function compileTableRow(row, columnTwips, spacing, baseStyle, scope) {
13197
13550
  ...scope.cantSplit !== void 0 ? { cantSplit: scope.cantSplit } : {}
13198
13551
  };
13199
13552
  }
13553
+ var NORMAL_TABLE_CELL_MARGINS = {
13554
+ topTwips: 0,
13555
+ bottomTwips: 0,
13556
+ leftTwips: 108,
13557
+ rightTwips: 108
13558
+ };
13200
13559
  function compileTableCell(cell, columnTwips, spacing, baseStyle, keepNext, partScope, rowRevision, markRevision) {
13201
- const margins = !cell.missing && cell.padding ? {
13560
+ const margins = cell.missing ? void 0 : cell.padding ? {
13202
13561
  topTwips: pointsToTwips2(cell.padding.top),
13203
13562
  bottomTwips: pointsToTwips2(cell.padding.bottom),
13204
13563
  leftTwips: pointsToTwips2(cell.padding.left),
13205
13564
  rightTwips: pointsToTwips2(cell.padding.right)
13206
- } : void 0;
13565
+ } : NORMAL_TABLE_CELL_MARGINS;
13207
13566
  const scope = {
13208
13567
  ...partScope,
13209
13568
  measureTwips: cellMeasureTwips(columnTwips, margins)
@@ -13716,8 +14075,8 @@ function hasPageBreak(component) {
13716
14075
  }
13717
14076
  return false;
13718
14077
  }
13719
- function getColumnSettings(layout) {
13720
- switch (layout) {
14078
+ function getColumnSettings(layout2) {
14079
+ switch (layout2) {
13721
14080
  case "multi-column":
13722
14081
  return {
13723
14082
  count: 2,
@@ -15957,19 +16316,19 @@ async function compileDocumentScoped(document, options, warnings) {
15957
16316
  context.themeName,
15958
16317
  resolveGenerationDate(options)
15959
16318
  );
15960
- const layout = applyLayout(
16319
+ const layout2 = applyLayout(
15961
16320
  structure.sections,
15962
16321
  context.theme,
15963
16322
  context.themeName
15964
16323
  );
15965
16324
  const images = await loadImageResources(
15966
- layout.sections.flatMap((section2) => [
16325
+ layout2.sections.flatMap((section2) => [
15967
16326
  ...section2.components,
15968
16327
  ...Array.isArray(section2.header) ? section2.header : [],
15969
16328
  ...Array.isArray(section2.footer) ? section2.footer : []
15970
16329
  ])
15971
16330
  );
15972
- const compiled = compileDocument(structure, layout, warnings, images, {
16331
+ const compiled = compileDocument(structure, layout2, warnings, images, {
15973
16332
  // A caller that collects nothing still needs to hear about a dropped
15974
16333
  // value, so warnings go to the console when there is no collector.
15975
16334
  echoWarnings: options.warnings === void 0