docx 9.8.1 → 9.9.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/charts.cjs +18 -10
- package/dist/charts.iife.js +18 -10
- package/dist/charts.mjs +18 -10
- package/dist/charts.umd.cjs +18 -10
- package/dist/index.cjs +2300 -283
- package/dist/index.d.cts +605 -32
- package/dist/index.d.ts +605 -32
- package/dist/index.iife.js +2300 -283
- package/dist/index.mjs +2293 -284
- package/dist/index.umd.cjs +2300 -283
- package/dist/layout.cjs +50860 -0
- package/dist/layout.d.cts +385 -0
- package/dist/layout.d.ts +385 -0
- package/dist/layout.iife.js +50863 -0
- package/dist/layout.mjs +50856 -0
- package/dist/layout.umd.cjs +50864 -0
- package/dist/math.cjs +7 -7
- package/dist/math.iife.js +7 -7
- package/dist/math.mjs +7 -7
- package/dist/math.umd.cjs +7 -7
- package/dist/shapes.cjs +2051 -2470
- package/dist/shapes.iife.js +2051 -2470
- package/dist/shapes.mjs +2051 -2470
- package/dist/shapes.umd.cjs +2051 -2470
- package/dist/watermarks.cjs +4 -4
- package/dist/watermarks.iife.js +4 -4
- package/dist/watermarks.mjs +4 -4
- package/dist/watermarks.umd.cjs +4 -4
- package/package.json +18 -5
package/dist/index.mjs
CHANGED
|
@@ -33,7 +33,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
33
33
|
throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
|
|
34
34
|
});
|
|
35
35
|
//#endregion
|
|
36
|
-
//#region \0@oxc-project+runtime@0.
|
|
36
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/typeof.js
|
|
37
37
|
function _typeof(o) {
|
|
38
38
|
"@babel/helpers - typeof";
|
|
39
39
|
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
@@ -43,7 +43,7 @@ function _typeof(o) {
|
|
|
43
43
|
}, _typeof(o);
|
|
44
44
|
}
|
|
45
45
|
//#endregion
|
|
46
|
-
//#region \0@oxc-project+runtime@0.
|
|
46
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/toPrimitive.js
|
|
47
47
|
function toPrimitive(t, r) {
|
|
48
48
|
if ("object" != _typeof(t) || !t) return t;
|
|
49
49
|
var e = t[Symbol.toPrimitive];
|
|
@@ -55,13 +55,13 @@ function toPrimitive(t, r) {
|
|
|
55
55
|
return ("string" === r ? String : Number)(t);
|
|
56
56
|
}
|
|
57
57
|
//#endregion
|
|
58
|
-
//#region \0@oxc-project+runtime@0.
|
|
58
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/toPropertyKey.js
|
|
59
59
|
function toPropertyKey(t) {
|
|
60
60
|
var i = toPrimitive(t, "string");
|
|
61
61
|
return "symbol" == _typeof(i) ? i : i + "";
|
|
62
62
|
}
|
|
63
63
|
//#endregion
|
|
64
|
-
//#region \0@oxc-project+runtime@0.
|
|
64
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/defineProperty.js
|
|
65
65
|
function _defineProperty(e, r, t) {
|
|
66
66
|
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
67
67
|
value: t,
|
|
@@ -271,7 +271,7 @@ var IgnoreIfEmptyXmlComponent = class extends XmlComponent {
|
|
|
271
271
|
}
|
|
272
272
|
};
|
|
273
273
|
//#endregion
|
|
274
|
-
//#region \0@oxc-project+runtime@0.
|
|
274
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/objectSpread2.js
|
|
275
275
|
function ownKeys(e, r) {
|
|
276
276
|
var t = Object.keys(e);
|
|
277
277
|
if (Object.getOwnPropertySymbols) {
|
|
@@ -8953,11 +8953,11 @@ var BuilderElement = class extends XmlComponent {
|
|
|
8953
8953
|
* @publicApi
|
|
8954
8954
|
*/
|
|
8955
8955
|
var AlignmentType = {
|
|
8956
|
-
/** Align Start */
|
|
8956
|
+
/** Align Start: the left in a left-to-right paragraph, and the right in a `bidirectional` (right-to-left) paragraph */
|
|
8957
8957
|
START: "start",
|
|
8958
8958
|
/** Align Center */
|
|
8959
8959
|
CENTER: "center",
|
|
8960
|
-
/** End */
|
|
8960
|
+
/** Align End: the right in a left-to-right paragraph, and the left in a `bidirectional` (right-to-left) paragraph */
|
|
8961
8961
|
END: "end",
|
|
8962
8962
|
/** Justified */
|
|
8963
8963
|
BOTH: "both",
|
|
@@ -8973,9 +8973,9 @@ var AlignmentType = {
|
|
|
8973
8973
|
LOW_KASHIDA: "lowKashida",
|
|
8974
8974
|
/** Thai Language Justification */
|
|
8975
8975
|
THAI_DISTRIBUTE: "thaiDistribute",
|
|
8976
|
-
/** Align Left */
|
|
8976
|
+
/** Align Left: a paragraph stays on the left of the page even when it is `bidirectional` (right-to-left) */
|
|
8977
8977
|
LEFT: "left",
|
|
8978
|
-
/** Align Right */
|
|
8978
|
+
/** Align Right: a paragraph stays on the right of the page even when it is `bidirectional` (right-to-left) */
|
|
8979
8979
|
RIGHT: "right",
|
|
8980
8980
|
/** Justified */
|
|
8981
8981
|
JUSTIFIED: "both"
|
|
@@ -9789,6 +9789,40 @@ var createFieldChar = (type, dirty) => new BuilderElement({
|
|
|
9789
9789
|
* field instructions, an optional separate character, field result, and an end character.
|
|
9790
9790
|
*/
|
|
9791
9791
|
var createBegin = (dirty) => createFieldChar(FieldCharacterType.BEGIN, dirty);
|
|
9792
|
+
/** The formatted begin characters of the fields that are dirty only when the document isn't given page numbers */
|
|
9793
|
+
var dirtyWithoutPageNumbers = /* @__PURE__ */ new WeakSet();
|
|
9794
|
+
/** The beginning of a field that is dirty, so Word updates it, unless the document is given page numbers */
|
|
9795
|
+
var BeginDirtyWithoutPageNumbers = class extends BuilderElement {
|
|
9796
|
+
constructor() {
|
|
9797
|
+
super({
|
|
9798
|
+
name: "w:fldChar",
|
|
9799
|
+
attributes: {
|
|
9800
|
+
type: {
|
|
9801
|
+
key: "w:fldCharType",
|
|
9802
|
+
value: FieldCharacterType.BEGIN
|
|
9803
|
+
},
|
|
9804
|
+
dirty: {
|
|
9805
|
+
key: "w:dirty",
|
|
9806
|
+
value: true
|
|
9807
|
+
}
|
|
9808
|
+
}
|
|
9809
|
+
});
|
|
9810
|
+
}
|
|
9811
|
+
prepForXml(context) {
|
|
9812
|
+
const xml = super.prepForXml(context);
|
|
9813
|
+
dirtyWithoutPageNumbers.add(xml);
|
|
9814
|
+
return xml;
|
|
9815
|
+
}
|
|
9816
|
+
};
|
|
9817
|
+
/**
|
|
9818
|
+
* Creates the beginning of a field whose result is written when the document is given page numbers, such as a page
|
|
9819
|
+
* reference or a SEQ field. It is written dirty, so Word updates the field when it opens the document, and asks to. When
|
|
9820
|
+
* the document is given page numbers, it is written clean (see {@link isDirtyWithoutPageNumbers}), so Word shows the
|
|
9821
|
+
* number written, or nothing when none could be worked out, and doesn't ask.
|
|
9822
|
+
*/
|
|
9823
|
+
var createBeginDirtyWithoutPageNumbers = () => new BeginDirtyWithoutPageNumbers();
|
|
9824
|
+
/** Whether a formatted field character is the beginning of a field that is dirty only without page numbers */
|
|
9825
|
+
var isDirtyWithoutPageNumbers = (element) => typeof element === "object" && element !== null && dirtyWithoutPageNumbers.has(element);
|
|
9792
9826
|
/**
|
|
9793
9827
|
* Creates the separator between field code and field result in a complex field.
|
|
9794
9828
|
*
|
|
@@ -9959,7 +9993,8 @@ var NumberFormat = {
|
|
|
9959
9993
|
THAI_NUMBERS: "thaiNumbers",
|
|
9960
9994
|
THAI_COUNTING: "thaiCounting",
|
|
9961
9995
|
BAHT_TEXT: "bahtText",
|
|
9962
|
-
DOLLAR_TEXT: "dollarText"
|
|
9996
|
+
DOLLAR_TEXT: "dollarText",
|
|
9997
|
+
CUSTOM: "custom"
|
|
9963
9998
|
};
|
|
9964
9999
|
//#endregion
|
|
9965
10000
|
//#region src/file/shared/space-type.ts
|
|
@@ -11301,13 +11336,8 @@ var Symbol$1 = class extends XmlComponent {
|
|
|
11301
11336
|
*/
|
|
11302
11337
|
var SymbolRun = class extends Run {
|
|
11303
11338
|
constructor(options) {
|
|
11304
|
-
|
|
11305
|
-
|
|
11306
|
-
this.root.push(new Symbol$1(options));
|
|
11307
|
-
return this;
|
|
11308
|
-
}
|
|
11309
|
-
super(options);
|
|
11310
|
-
this.root.push(new Symbol$1(options.char, options.symbolfont));
|
|
11339
|
+
super(typeof options === "string" ? {} : options);
|
|
11340
|
+
this.root.push(typeof options === "string" ? new Symbol$1(options) : new Symbol$1(options.char, options.symbolfont));
|
|
11311
11341
|
}
|
|
11312
11342
|
};
|
|
11313
11343
|
//#endregion
|
|
@@ -14288,6 +14318,16 @@ var SourceRectangleAttributes = class extends XmlAttributeComponent {
|
|
|
14288
14318
|
}
|
|
14289
14319
|
};
|
|
14290
14320
|
/**
|
|
14321
|
+
* Converts a crop percentage to thousandths of a percent.
|
|
14322
|
+
*
|
|
14323
|
+
* @throws If the percentage isn't a number from 0 to 100
|
|
14324
|
+
*/
|
|
14325
|
+
var cropValue = (value, edge) => {
|
|
14326
|
+
if (value === void 0) return;
|
|
14327
|
+
if (!(value >= 0 && value <= 100)) throw new Error(`Invalid crop ${edge} ${value}. Expected a number from 0 to 100`);
|
|
14328
|
+
return Math.round(value * 1e3);
|
|
14329
|
+
};
|
|
14330
|
+
/**
|
|
14291
14331
|
* Represents a source rectangle for blip fills.
|
|
14292
14332
|
*
|
|
14293
14333
|
* This element specifies a portion of the blip (image) to use as the fill.
|
|
@@ -14314,10 +14354,10 @@ var SourceRectangle = class extends XmlComponent {
|
|
|
14314
14354
|
constructor(crop) {
|
|
14315
14355
|
super("a:srcRect");
|
|
14316
14356
|
if (crop) this.root.push(new SourceRectangleAttributes({
|
|
14317
|
-
left: crop.left
|
|
14318
|
-
top: crop.top
|
|
14319
|
-
right: crop.right
|
|
14320
|
-
bottom: crop.bottom
|
|
14357
|
+
left: cropValue(crop.left, "left"),
|
|
14358
|
+
top: cropValue(crop.top, "top"),
|
|
14359
|
+
right: cropValue(crop.right, "right"),
|
|
14360
|
+
bottom: cropValue(crop.bottom, "bottom")
|
|
14321
14361
|
}));
|
|
14322
14362
|
}
|
|
14323
14363
|
};
|
|
@@ -14671,7 +14711,9 @@ var NonVisualProperties = class extends XmlComponent {
|
|
|
14671
14711
|
this.root.push(createHyperlinkClick(element.linkId, false));
|
|
14672
14712
|
break;
|
|
14673
14713
|
}
|
|
14674
|
-
|
|
14714
|
+
const result = super.prepForXml(context);
|
|
14715
|
+
this.root.splice(1);
|
|
14716
|
+
return result;
|
|
14675
14717
|
}
|
|
14676
14718
|
};
|
|
14677
14719
|
//#endregion
|
|
@@ -15618,6 +15660,18 @@ var createEffectExtent = ({ top, right, bottom, left }) => new BuilderElement({
|
|
|
15618
15660
|
* @module
|
|
15619
15661
|
*/
|
|
15620
15662
|
/**
|
|
15663
|
+
* The largest width or height, in EMUs, Word opens a drawing at. The standard allows `ST_PositiveCoordinate` up to
|
|
15664
|
+
* 27273042316900, but Word and PowerPoint restrict it to 2147483647 and won't open a document with a larger drawing.
|
|
15665
|
+
*
|
|
15666
|
+
* Reference: [MS-OI29500] Part 1 Section 20.1.10.42, ST_PositiveCoordinate
|
|
15667
|
+
*/
|
|
15668
|
+
var MAX_EXTENT = 2147483647;
|
|
15669
|
+
var EMUS_PER_PIXEL = 9525;
|
|
15670
|
+
var checkExtent = (dimension, value) => {
|
|
15671
|
+
if (value !== void 0 && value > MAX_EXTENT) throw new Error(`Invalid drawing ${dimension} ${value} EMUs (${Math.round(value / EMUS_PER_PIXEL)} pixels). Word won't open a drawing with a ${dimension} over ${MAX_EXTENT} EMUs (${Math.floor(MAX_EXTENT / EMUS_PER_PIXEL)} pixels). Sizes such as an ImageRun's transformation are in pixels, not EMUs`);
|
|
15672
|
+
return value;
|
|
15673
|
+
};
|
|
15674
|
+
/**
|
|
15621
15675
|
* Creates an extent element for inline drawings.
|
|
15622
15676
|
*
|
|
15623
15677
|
* This element specifies the extents of the parent DrawingML object within
|
|
@@ -15641,17 +15695,19 @@ var createEffectExtent = ({ top, right, bottom, left }) => new BuilderElement({
|
|
|
15641
15695
|
* y: 914400
|
|
15642
15696
|
* });
|
|
15643
15697
|
* ```
|
|
15698
|
+
*
|
|
15699
|
+
* @throws Error if the width or height is over 2147483647 EMUs, which Word won't open
|
|
15644
15700
|
*/
|
|
15645
15701
|
var createExtent = ({ x, y }) => new BuilderElement({
|
|
15646
15702
|
name: "wp:extent",
|
|
15647
15703
|
attributes: {
|
|
15648
15704
|
x: {
|
|
15649
15705
|
key: "cx",
|
|
15650
|
-
value: x
|
|
15706
|
+
value: checkExtent("width", x)
|
|
15651
15707
|
},
|
|
15652
15708
|
y: {
|
|
15653
15709
|
key: "cy",
|
|
15654
|
-
value: y
|
|
15710
|
+
value: checkExtent("height", y)
|
|
15655
15711
|
}
|
|
15656
15712
|
}
|
|
15657
15713
|
});
|
|
@@ -16043,7 +16099,6 @@ var createDeletion = ({ id, author, date }, run) => new BuilderElement({
|
|
|
16043
16099
|
var ImageRun = class extends XmlComponent {
|
|
16044
16100
|
constructor(options) {
|
|
16045
16101
|
var _options$insertion;
|
|
16046
|
-
var _super = (..._args) => (super(..._args), _defineProperty(this, "imageData", void 0), this);
|
|
16047
16102
|
const key = `${hashedId(options.data)}.${options.type}`;
|
|
16048
16103
|
const imageData = options.type === "svg" ? _objectSpread2(_objectSpread2({ type: options.type }, createImageData(options, key)), {}, { fallback: _objectSpread2({ type: options.fallback.type }, createImageData(_objectSpread2(_objectSpread2({}, options.fallback), {}, { transformation: options.transformation }), `${hashedId(options.fallback.data)}.${options.fallback.type}`)) }) : _objectSpread2({ type: options.type }, createImageData(options, key));
|
|
16049
16104
|
const drawing = new Drawing(imageData, {
|
|
@@ -16057,8 +16112,10 @@ var ImageRun = class extends XmlComponent {
|
|
|
16057
16112
|
});
|
|
16058
16113
|
const properties = new RunProperties(options.run);
|
|
16059
16114
|
const revision = (_options$insertion = options.insertion) !== null && _options$insertion !== void 0 ? _options$insertion : options.deletion;
|
|
16115
|
+
const rootName = options.insertion ? "w:ins" : options.deletion ? "w:del" : "w:r";
|
|
16116
|
+
super(rootName);
|
|
16117
|
+
_defineProperty(this, "imageData", void 0);
|
|
16060
16118
|
if (revision) {
|
|
16061
|
-
_super(options.insertion ? "w:ins" : "w:del");
|
|
16062
16119
|
this.root.push(new ChangeAttributes({
|
|
16063
16120
|
id: revision.id,
|
|
16064
16121
|
author: revision.author,
|
|
@@ -16070,7 +16127,6 @@ var ImageRun = class extends XmlComponent {
|
|
|
16070
16127
|
});
|
|
16071
16128
|
this.addChildElement(options.insertion && options.deletion ? createDeletion(options.deletion, run) : run);
|
|
16072
16129
|
} else {
|
|
16073
|
-
_super("w:r");
|
|
16074
16130
|
this.root.push(properties);
|
|
16075
16131
|
this.root.push(drawing);
|
|
16076
16132
|
}
|
|
@@ -16223,6 +16279,10 @@ var SequentialIdentifierInstruction = class extends XmlComponent {
|
|
|
16223
16279
|
* Each identifier maintains its own sequence, allowing you to have separate numbering
|
|
16224
16280
|
* for figures, tables, equations, etc.
|
|
16225
16281
|
*
|
|
16282
|
+
* It is written dirty, so Word numbers it when it opens the document, after asking to update the fields. When the
|
|
16283
|
+
* document is given `pageNumbers`, it is written clean, with its number counted as Word counts it, or blank where
|
|
16284
|
+
* Word's count isn't known, and Word doesn't ask.
|
|
16285
|
+
*
|
|
16226
16286
|
* Reference: http://officeopenxml.com/WPrun.php
|
|
16227
16287
|
*
|
|
16228
16288
|
* @publicApi
|
|
@@ -16251,7 +16311,7 @@ var SequentialIdentifierInstruction = class extends XmlComponent {
|
|
|
16251
16311
|
var SequentialIdentifier = class extends Run {
|
|
16252
16312
|
constructor(identifier) {
|
|
16253
16313
|
super({});
|
|
16254
|
-
this.root.push(
|
|
16314
|
+
this.root.push(createBeginDirtyWithoutPageNumbers());
|
|
16255
16315
|
this.root.push(new SequentialIdentifierInstruction(identifier));
|
|
16256
16316
|
this.root.push(createSeparate());
|
|
16257
16317
|
this.root.push(createEnd());
|
|
@@ -16276,7 +16336,10 @@ var SequentialIdentifier = class extends Run {
|
|
|
16276
16336
|
var FldSimpleAttrs = class extends XmlAttributeComponent {
|
|
16277
16337
|
constructor(..._args) {
|
|
16278
16338
|
super(..._args);
|
|
16279
|
-
_defineProperty(this, "xmlKeys", {
|
|
16339
|
+
_defineProperty(this, "xmlKeys", {
|
|
16340
|
+
instr: "w:instr",
|
|
16341
|
+
fldLock: "w:fldLock"
|
|
16342
|
+
});
|
|
16280
16343
|
}
|
|
16281
16344
|
};
|
|
16282
16345
|
/**
|
|
@@ -16309,12 +16372,18 @@ var FldSimpleAttrs = class extends XmlAttributeComponent {
|
|
|
16309
16372
|
*
|
|
16310
16373
|
* // Simple field with cached value
|
|
16311
16374
|
* new SimpleField("DATE", "2024-01-01");
|
|
16375
|
+
*
|
|
16376
|
+
* // Locked field, Word keeps the cached value when fields are updated
|
|
16377
|
+
* new SimpleField("DATE", "2024-01-01", { locked: true });
|
|
16312
16378
|
* ```
|
|
16313
16379
|
*/
|
|
16314
16380
|
var SimpleField = class extends XmlComponent {
|
|
16315
|
-
constructor(instruction, cachedValue) {
|
|
16381
|
+
constructor(instruction, cachedValue, options = {}) {
|
|
16316
16382
|
super("w:fldSimple");
|
|
16317
|
-
this.root.push(new FldSimpleAttrs({
|
|
16383
|
+
this.root.push(new FldSimpleAttrs({
|
|
16384
|
+
instr: instruction,
|
|
16385
|
+
fldLock: options.locked ? true : void 0
|
|
16386
|
+
}));
|
|
16318
16387
|
if (cachedValue !== void 0) this.root.push(new TextRun(cachedValue));
|
|
16319
16388
|
}
|
|
16320
16389
|
};
|
|
@@ -16339,6 +16408,1035 @@ var SimpleMailMergeField = class extends SimpleField {
|
|
|
16339
16408
|
}
|
|
16340
16409
|
};
|
|
16341
16410
|
//#endregion
|
|
16411
|
+
//#region src/file/document/body/field-number-formats.ts
|
|
16412
|
+
var LARGEST_ROMAN = 32767;
|
|
16413
|
+
var LARGEST_LETTERS = 780;
|
|
16414
|
+
var ROMAN = [
|
|
16415
|
+
[1e3, "M"],
|
|
16416
|
+
[900, "CM"],
|
|
16417
|
+
[500, "D"],
|
|
16418
|
+
[400, "CD"],
|
|
16419
|
+
[100, "C"],
|
|
16420
|
+
[90, "XC"],
|
|
16421
|
+
[50, "L"],
|
|
16422
|
+
[40, "XL"],
|
|
16423
|
+
[10, "X"],
|
|
16424
|
+
[9, "IX"],
|
|
16425
|
+
[5, "V"],
|
|
16426
|
+
[4, "IV"],
|
|
16427
|
+
[1, "I"]
|
|
16428
|
+
];
|
|
16429
|
+
var roman = (value) => value <= LARGEST_ROMAN ? ROMAN.reduce(({ rest, text }, [amount, numeral]) => ({
|
|
16430
|
+
rest: rest % amount,
|
|
16431
|
+
text: text + numeral.repeat(Math.floor(rest / amount))
|
|
16432
|
+
}), {
|
|
16433
|
+
rest: value,
|
|
16434
|
+
text: ""
|
|
16435
|
+
}).text : void 0;
|
|
16436
|
+
var letters = (value) => value === 0 ? "" : value <= LARGEST_LETTERS ? String.fromCharCode(65 + (value - 1) % 26).repeat(Math.ceil(value / 26)) : void 0;
|
|
16437
|
+
var ordinal = (value) => {
|
|
16438
|
+
var _ref;
|
|
16439
|
+
return `${value}${value % 100 >= 11 && value % 100 <= 13 ? "th" : (_ref = [
|
|
16440
|
+
"th",
|
|
16441
|
+
"st",
|
|
16442
|
+
"nd",
|
|
16443
|
+
"rd"
|
|
16444
|
+
][value % 10]) !== null && _ref !== void 0 ? _ref : "th"}`;
|
|
16445
|
+
};
|
|
16446
|
+
/**
|
|
16447
|
+
* The number formats of a field's `\*` switch that are written as Word writes them, by their names in any capitals.
|
|
16448
|
+
* Word writes roman numerals and letters in small letters when the name starts with a small letter, as `roman`, and in
|
|
16449
|
+
* capitals otherwise, as `Roman` and `ROMAN`
|
|
16450
|
+
*/
|
|
16451
|
+
var numberWriterOf = (format) => {
|
|
16452
|
+
const small = format.charAt(0) !== format.charAt(0).toUpperCase();
|
|
16453
|
+
const inCase = (write) => (value) => {
|
|
16454
|
+
var _write;
|
|
16455
|
+
return small ? (_write = write(value)) === null || _write === void 0 ? void 0 : _write.toLowerCase() : write(value);
|
|
16456
|
+
};
|
|
16457
|
+
switch (format.toLowerCase()) {
|
|
16458
|
+
case "arabic": return String;
|
|
16459
|
+
case "roman": return inCase(roman);
|
|
16460
|
+
case "alphabetic": return inCase(letters);
|
|
16461
|
+
case "ordinal": return (value) => value > 0 ? ordinal(value) : void 0;
|
|
16462
|
+
case "arabicdash": return (value) => `- ${value} -`;
|
|
16463
|
+
default: return;
|
|
16464
|
+
}
|
|
16465
|
+
};
|
|
16466
|
+
var PLAIN_FORMATS = /* @__PURE__ */ new Set([
|
|
16467
|
+
"mergeformat",
|
|
16468
|
+
"charformat",
|
|
16469
|
+
"mergeformatinet"
|
|
16470
|
+
]);
|
|
16471
|
+
var CASE_FORMATS = /* @__PURE__ */ new Set([
|
|
16472
|
+
"upper",
|
|
16473
|
+
"lower",
|
|
16474
|
+
"firstcap",
|
|
16475
|
+
"caps"
|
|
16476
|
+
]);
|
|
16477
|
+
/**
|
|
16478
|
+
* Whether Word's text for a picture of a field's `\#` switch is known: one of digits (`0`), digits only where the number
|
|
16479
|
+
* has them (`#`) and commas between thousands, as Word wrote `00`, `000`, `0`, `#` and `#,##0` for page numbers
|
|
16480
|
+
* (`scripts/layout-probes/word-page-fields.ts` PF5 to PF7)
|
|
16481
|
+
*/
|
|
16482
|
+
var isNumberPicture = (picture) => /^[#0,]*[#0][#0,]*$/.test(picture);
|
|
16483
|
+
/**
|
|
16484
|
+
* A number with a picture: with as many digits as it has `0`s at least, which Word fills with 0s (5 is 05 with `00`), and
|
|
16485
|
+
* its thousands between commas when it has one (1234 is 1,234 with `#,##0`). Undefined where a `#` has no digit of the
|
|
16486
|
+
* number, which Word writes as a space, not yet seen
|
|
16487
|
+
*/
|
|
16488
|
+
var inNumberPicture = (value, picture) => {
|
|
16489
|
+
const zeros = [...picture].filter((character) => character === "0").length;
|
|
16490
|
+
const places = zeros + [...picture].filter((character) => character === "#").length;
|
|
16491
|
+
const digits = String(value).padStart(zeros, "0");
|
|
16492
|
+
if (digits.length < places || zeros === 0 && value === 0) return;
|
|
16493
|
+
return picture.includes(",") ? digits.replace(/\B(?=(\d{3})+$)/g, ",") : digits;
|
|
16494
|
+
};
|
|
16495
|
+
/**
|
|
16496
|
+
* Text in the capitals of a field's switch, applied after its number's format, as Word wrote `\* roman \* Upper` as V,
|
|
16497
|
+
* `\* Ordinal \* Upper` as 5TH, and "above" with `\* Upper` as ABOVE (`word-page-fields.ts` PF3 and PF5)
|
|
16498
|
+
*/
|
|
16499
|
+
var inCapitals = (text, capitals) => {
|
|
16500
|
+
switch (capitals) {
|
|
16501
|
+
case "upper": return text.toUpperCase();
|
|
16502
|
+
case "lower": return text.toLowerCase();
|
|
16503
|
+
case "firstcap": return text.charAt(0).toUpperCase() + text.slice(1);
|
|
16504
|
+
default: return text;
|
|
16505
|
+
}
|
|
16506
|
+
};
|
|
16507
|
+
//#endregion
|
|
16508
|
+
//#region src/file/document/body/page-number-fields.ts
|
|
16509
|
+
/**
|
|
16510
|
+
* Writes estimated page numbers into the fields of a tree of elements that show them: those docx formats to write a
|
|
16511
|
+
* document, and those `patchDocument` parses from a template. Not part of the public API.
|
|
16512
|
+
*
|
|
16513
|
+
* A page reference is a PAGEREF field, and the numbers of pages of the document and of a section are NUMPAGES and
|
|
16514
|
+
* SECTIONPAGES fields. Each field's result is written just after its `separate` field character, and any result it had
|
|
16515
|
+
* is taken out.
|
|
16516
|
+
*
|
|
16517
|
+
* @module
|
|
16518
|
+
*/
|
|
16519
|
+
/** Reads a field that shows a page's number or a number of pages, or undefined for another field */
|
|
16520
|
+
var numberFieldOf = (instruction) => {
|
|
16521
|
+
var _match;
|
|
16522
|
+
const field = new RegExp("^\\s*(PAGEREF|NUMPAGES|SECTIONPAGES)\\b(.*)$", "is").exec(instruction);
|
|
16523
|
+
const reference = (field === null || field === void 0 ? void 0 : field[1].toUpperCase()) === "PAGEREF" ? new RegExp("^\\s*(\"?)([^\\s\"\\\\]+)\\1(.*)$", "s").exec(field[2]) : void 0;
|
|
16524
|
+
if (!field || field[1].toUpperCase() === "PAGEREF" && !reference) return;
|
|
16525
|
+
const parts = (_match = (reference ? reference[3] : field[2]).match(/"[^"]*"|\S+/g)) !== null && _match !== void 0 ? _match : [];
|
|
16526
|
+
let numberFormat;
|
|
16527
|
+
let picture;
|
|
16528
|
+
const capitals = [];
|
|
16529
|
+
let relative = false;
|
|
16530
|
+
let written = true;
|
|
16531
|
+
for (let index = 0; index < parts.length; index++) {
|
|
16532
|
+
const part = parts[index];
|
|
16533
|
+
const argument = () => {
|
|
16534
|
+
var _parts$index;
|
|
16535
|
+
return (part.length > 2 ? part.slice(2) : (_parts$index = parts[++index]) !== null && _parts$index !== void 0 ? _parts$index : "").replace(/^"(.*)"$/, "$1");
|
|
16536
|
+
};
|
|
16537
|
+
if (/^\\p$/i.test(part)) relative = true;
|
|
16538
|
+
else if (part.startsWith("\\#")) {
|
|
16539
|
+
var _picture;
|
|
16540
|
+
const value = argument();
|
|
16541
|
+
written && (written = picture === void 0 && isNumberPicture(value));
|
|
16542
|
+
(_picture = picture) !== null && _picture !== void 0 || (picture = value);
|
|
16543
|
+
} else if (part.startsWith("\\*")) {
|
|
16544
|
+
const name = argument();
|
|
16545
|
+
const lower = name.toLowerCase();
|
|
16546
|
+
if (CASE_FORMATS.has(lower)) capitals.push(lower);
|
|
16547
|
+
else if (name !== "" && !PLAIN_FORMATS.has(lower)) {
|
|
16548
|
+
var _numberFormat;
|
|
16549
|
+
written && (written = numberFormat === void 0 && numberWriterOf(name) !== void 0);
|
|
16550
|
+
(_numberFormat = numberFormat) !== null && _numberFormat !== void 0 || (numberFormat = name);
|
|
16551
|
+
}
|
|
16552
|
+
}
|
|
16553
|
+
}
|
|
16554
|
+
const own = _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, numberFormat === void 0 ? {} : { numberFormat }), picture === void 0 ? {} : { picture }), capitals.length === 0 ? {} : { capitals: capitals[0] }), {}, { written: written && capitals.length <= 1 && capitals[0] !== "caps" && (numberFormat === void 0 || picture === void 0) });
|
|
16555
|
+
return reference ? _objectSpread2({
|
|
16556
|
+
type: "pageReference",
|
|
16557
|
+
bookmark: reference[2],
|
|
16558
|
+
relative
|
|
16559
|
+
}, own) : _objectSpread2({
|
|
16560
|
+
type: "pageCount",
|
|
16561
|
+
scope: field[1].toUpperCase() === "NUMPAGES" ? "document" : "section"
|
|
16562
|
+
}, own);
|
|
16563
|
+
};
|
|
16564
|
+
/**
|
|
16565
|
+
* Whether a field is a table of contents that writes the number of a SEQ field before each page number (`\s`), such as
|
|
16566
|
+
* 2-5 for page 5 of chapter 2, which isn't written
|
|
16567
|
+
*/
|
|
16568
|
+
var prefixesPageNumbers = (instruction) => new RegExp("^\\s*TOC\\b.*\\\\s\\b", "is").test(instruction);
|
|
16569
|
+
/**
|
|
16570
|
+
* The result of a field that shows a page's number or a number of pages, or undefined to leave it as it is. A field
|
|
16571
|
+
* the estimate has no number for is left as it is, or made blank, and so is a page number in a table of contents that
|
|
16572
|
+
* writes a SEQ field's number before it.
|
|
16573
|
+
*/
|
|
16574
|
+
var resultFrom = (instruction, { enclosing, within, inTextBox }, { estimate, sectionPageCount, blank, relativeTo }) => {
|
|
16575
|
+
const field = numberFieldOf(instruction);
|
|
16576
|
+
if (field === void 0) return;
|
|
16577
|
+
const { bookmarks, pageCount, bookmarkPageNumbers } = estimate;
|
|
16578
|
+
const { numberFormat, picture, capitals, written } = field;
|
|
16579
|
+
const writesNumber = numberFormat !== void 0 || picture !== void 0;
|
|
16580
|
+
/** A number in the field's format of its own, or as it is */
|
|
16581
|
+
const inFormat = (value) => value === void 0 ? void 0 : picture === void 0 ? numberWriterOf(numberFormat !== null && numberFormat !== void 0 ? numberFormat : "arabic")(value) : inNumberPicture(value, picture);
|
|
16582
|
+
const position = field.type === "pageReference" && field.relative && within === "counted" && !inTextBox ? relativeTo === null || relativeTo === void 0 ? void 0 : relativeTo(field.bookmark) : void 0;
|
|
16583
|
+
let result;
|
|
16584
|
+
if (!written) result = void 0;
|
|
16585
|
+
else if (field.type === "pageCount") result = inFormat(field.scope === "document" ? pageCount : sectionPageCount);
|
|
16586
|
+
else if (enclosing.some(prefixesPageNumbers)) result = void 0;
|
|
16587
|
+
else if (writesNumber) result = inFormat(bookmarkPageNumbers === null || bookmarkPageNumbers === void 0 ? void 0 : bookmarkPageNumbers.get(field.bookmark));
|
|
16588
|
+
else result = field.relative ? position : bookmarks.get(field.bookmark);
|
|
16589
|
+
return result === void 0 ? blank ? "" : void 0 : inCapitals(result, capitals);
|
|
16590
|
+
};
|
|
16591
|
+
/** Where the content of an element is: in what an application that doesn't read Word's own shows, or in deleted text */
|
|
16592
|
+
var placeIn = (name, within) => name === "mc:Fallback" || within === "fallback" ? "fallback" : name === "w:del" || name === "w:moveFrom" ? "deleted" : within;
|
|
16593
|
+
/**
|
|
16594
|
+
* Writes the results the filling works out into the fields in the elements, in order.
|
|
16595
|
+
*/
|
|
16596
|
+
var fillFields = (tree, elements, open, filling, within = "counted", inTextBox = false) => {
|
|
16597
|
+
for (let index = 0; index < elements.length; index++) {
|
|
16598
|
+
const element = elements[index];
|
|
16599
|
+
const name = tree.nameOf(element);
|
|
16600
|
+
if (name === void 0) continue;
|
|
16601
|
+
const current = open[open.length - 1];
|
|
16602
|
+
if (name === "w:fldChar") {
|
|
16603
|
+
const type = tree.attributeOf(element, "w:fldCharType");
|
|
16604
|
+
if (type === "begin") open.push({
|
|
16605
|
+
begin: element,
|
|
16606
|
+
instruction: "",
|
|
16607
|
+
inResult: false
|
|
16608
|
+
});
|
|
16609
|
+
else if (type === "separate" && current) {
|
|
16610
|
+
tree.writeClean(current.begin, current.instruction);
|
|
16611
|
+
current.inResult = true;
|
|
16612
|
+
current.result = filling.resultOf(current.instruction, {
|
|
16613
|
+
within,
|
|
16614
|
+
enclosing: open.slice(0, -1).map((field) => field.instruction),
|
|
16615
|
+
inTextBox
|
|
16616
|
+
});
|
|
16617
|
+
if (current.result !== void 0) {
|
|
16618
|
+
elements.splice(index + 1, 0, tree.textElement(current.result));
|
|
16619
|
+
index++;
|
|
16620
|
+
}
|
|
16621
|
+
} else if (type === "end") open.pop();
|
|
16622
|
+
} else if (name === "w:instrText" && current && !current.inResult) current.instruction += tree.textOf(element);
|
|
16623
|
+
else if ((name === "w:t" || name === "w:tab" || name === "w:br" || name === "w:cr") && (current === null || current === void 0 ? void 0 : current.result) !== void 0) {
|
|
16624
|
+
elements.splice(index, 1);
|
|
16625
|
+
index--;
|
|
16626
|
+
} else if (name === "w:fldSimple") {
|
|
16627
|
+
const result = filling.resultOf(String(tree.attributeOf(element, "w:instr")), {
|
|
16628
|
+
within,
|
|
16629
|
+
enclosing: open.map((field) => field.instruction),
|
|
16630
|
+
inTextBox
|
|
16631
|
+
});
|
|
16632
|
+
if (result === void 0) {
|
|
16633
|
+
var _tree$contentOf;
|
|
16634
|
+
fillFields(tree, (_tree$contentOf = tree.contentOf(element)) !== null && _tree$contentOf !== void 0 ? _tree$contentOf : [], [], filling, within, inTextBox);
|
|
16635
|
+
} else tree.setSimpleFieldResult(element, result);
|
|
16636
|
+
} else {
|
|
16637
|
+
var _tree$contentOf2;
|
|
16638
|
+
if (name === "w:p") {
|
|
16639
|
+
var _filling$beforeParagr;
|
|
16640
|
+
(_filling$beforeParagr = filling.beforeParagraph) === null || _filling$beforeParagr === void 0 || _filling$beforeParagr.call(filling, element);
|
|
16641
|
+
}
|
|
16642
|
+
fillFields(tree, (_tree$contentOf2 = tree.contentOf(element)) !== null && _tree$contentOf2 !== void 0 ? _tree$contentOf2 : [], open, filling, placeIn(name, within), inTextBox || name === "w:txbxContent");
|
|
16643
|
+
if (name === "w:p") filling.afterParagraph(element);
|
|
16644
|
+
}
|
|
16645
|
+
}
|
|
16646
|
+
};
|
|
16647
|
+
/** The section properties (`w:sectPr`) in the elements, in order: those of the paragraphs that end sections, and the last */
|
|
16648
|
+
var sectionPropertiesIn = (tree, elements) => elements.flatMap((element) => {
|
|
16649
|
+
var _tree$contentOf3;
|
|
16650
|
+
const name = tree.nameOf(element);
|
|
16651
|
+
if (name === void 0) return [];
|
|
16652
|
+
return name === "w:sectPr" ? [element] : sectionPropertiesIn(tree, (_tree$contentOf3 = tree.contentOf(element)) !== null && _tree$contentOf3 !== void 0 ? _tree$contentOf3 : []);
|
|
16653
|
+
});
|
|
16654
|
+
/** Whether a paragraph ends a section: whether its properties have the section's */
|
|
16655
|
+
var endsSection = (tree, paragraph) => {
|
|
16656
|
+
var _tree$contentOf4;
|
|
16657
|
+
return ((_tree$contentOf4 = tree.contentOf(paragraph)) !== null && _tree$contentOf4 !== void 0 ? _tree$contentOf4 : []).some((child) => {
|
|
16658
|
+
var _tree$contentOf5;
|
|
16659
|
+
return tree.nameOf(child) === "w:pPr" && ((_tree$contentOf5 = tree.contentOf(child)) !== null && _tree$contentOf5 !== void 0 ? _tree$contentOf5 : []).some((part) => tree.nameOf(part) === "w:sectPr");
|
|
16660
|
+
});
|
|
16661
|
+
};
|
|
16662
|
+
/**
|
|
16663
|
+
* The number of pages each header and footer shows in its SECTIONPAGES fields, by the id of the relationship to it:
|
|
16664
|
+
* that of the sections whose pages it is on, when they all have the same. A section without a header or footer of a kind
|
|
16665
|
+
* has the one of the section before, as Word lays them out.
|
|
16666
|
+
*/
|
|
16667
|
+
var partPageCountsOf = (tree, body, sectionPageCounts) => {
|
|
16668
|
+
const countsOfParts = sectionPropertiesIn(tree, [body]).reduce((all, properties) => {
|
|
16669
|
+
var _tree$contentOf6, _all;
|
|
16670
|
+
const references = ((_tree$contentOf6 = tree.contentOf(properties)) !== null && _tree$contentOf6 !== void 0 ? _tree$contentOf6 : []).flatMap((child) => {
|
|
16671
|
+
const name = tree.nameOf(child);
|
|
16672
|
+
return name === "w:headerReference" || name === "w:footerReference" ? [[`${name} ${String(tree.attributeOf(child, "w:type"))}`, String(tree.attributeOf(child, "r:id"))]] : [];
|
|
16673
|
+
});
|
|
16674
|
+
return [...all, new Map([...(_all = all[all.length - 1]) !== null && _all !== void 0 ? _all : [], ...references])];
|
|
16675
|
+
}, []).reduce((counts, parts, section) => {
|
|
16676
|
+
for (const id of parts.values()) {
|
|
16677
|
+
var _counts$get;
|
|
16678
|
+
counts.set(id, [...(_counts$get = counts.get(id)) !== null && _counts$get !== void 0 ? _counts$get : [], sectionPageCounts[section]]);
|
|
16679
|
+
}
|
|
16680
|
+
return counts;
|
|
16681
|
+
}, /* @__PURE__ */ new Map());
|
|
16682
|
+
return new Map([...countsOfParts].flatMap(([id, [first, ...rest]]) => first !== void 0 && rest.every((count) => count === first) ? [[id, first]] : []));
|
|
16683
|
+
};
|
|
16684
|
+
/**
|
|
16685
|
+
* Writes the estimated page numbers into the fields of a document's body that show them: its PAGEREF fields, in its
|
|
16686
|
+
* tables of contents and elsewhere, and its NUMPAGES and SECTIONPAGES fields.
|
|
16687
|
+
*
|
|
16688
|
+
* @returns The number of pages each header and footer shows in its SECTIONPAGES fields, by the id of the relationship to it
|
|
16689
|
+
*/
|
|
16690
|
+
var fillBodyFields = (tree, body, estimate, { blank }) => {
|
|
16691
|
+
const { sectionPageCounts = [], relativePositions } = estimate;
|
|
16692
|
+
let section = 0;
|
|
16693
|
+
const relativeCounts = /* @__PURE__ */ new Map();
|
|
16694
|
+
const relativeTo = (bookmark) => {
|
|
16695
|
+
var _relativeCounts$get, _relativePositions$ge;
|
|
16696
|
+
const count = (_relativeCounts$get = relativeCounts.get(bookmark)) !== null && _relativeCounts$get !== void 0 ? _relativeCounts$get : 0;
|
|
16697
|
+
relativeCounts.set(bookmark, count + 1);
|
|
16698
|
+
return relativePositions === null || relativePositions === void 0 || (_relativePositions$ge = relativePositions.get(bookmark)) === null || _relativePositions$ge === void 0 ? void 0 : _relativePositions$ge[count];
|
|
16699
|
+
};
|
|
16700
|
+
fillFields(tree, [body], [], {
|
|
16701
|
+
resultOf: (instruction, place) => resultFrom(instruction, place, {
|
|
16702
|
+
estimate,
|
|
16703
|
+
sectionPageCount: sectionPageCounts[section],
|
|
16704
|
+
blank,
|
|
16705
|
+
relativeTo
|
|
16706
|
+
}),
|
|
16707
|
+
afterParagraph: (paragraph) => {
|
|
16708
|
+
section += endsSection(tree, paragraph) ? 1 : 0;
|
|
16709
|
+
}
|
|
16710
|
+
});
|
|
16711
|
+
return partPageCountsOf(tree, body, sectionPageCounts);
|
|
16712
|
+
};
|
|
16713
|
+
/**
|
|
16714
|
+
* Writes the estimated page numbers into the fields of a header, footer, footnote or endnote that show them, with the
|
|
16715
|
+
* number of pages its SECTIONPAGES fields show, if it is known. A page reference with `\p` in a footnote or endnote
|
|
16716
|
+
* (`notes`) writes "on page" and its bookmark's page, whatever page it is on, as Word writes it
|
|
16717
|
+
* (`word-page-fields.docx` PF8f, PF8g)
|
|
16718
|
+
*/
|
|
16719
|
+
var fillPartFields = (tree, part, estimate, { blank, sectionPageCount, notes = false }) => {
|
|
16720
|
+
const onPage = (bookmark) => {
|
|
16721
|
+
const page = estimate.bookmarks.get(bookmark);
|
|
16722
|
+
return page === void 0 ? void 0 : `on page ${page}`;
|
|
16723
|
+
};
|
|
16724
|
+
fillFields(tree, [part], [], {
|
|
16725
|
+
resultOf: (instruction, place) => resultFrom(instruction, place, _objectSpread2({
|
|
16726
|
+
estimate,
|
|
16727
|
+
sectionPageCount,
|
|
16728
|
+
blank
|
|
16729
|
+
}, notes ? { relativeTo: onPage } : {})),
|
|
16730
|
+
afterParagraph: () => void 0
|
|
16731
|
+
});
|
|
16732
|
+
};
|
|
16733
|
+
/** Writes the numbers of the SEQ fields of a document's body into them */
|
|
16734
|
+
var fillSequenceFields = (tree, body, { beforeParagraph, resultOf }) => fillFields(tree, [body], [], {
|
|
16735
|
+
resultOf: (instruction, { within }) => resultOf(instruction, within),
|
|
16736
|
+
beforeParagraph,
|
|
16737
|
+
afterParagraph: () => void 0
|
|
16738
|
+
});
|
|
16739
|
+
//#endregion
|
|
16740
|
+
//#region src/file/table-of-contents/field-instruction.ts
|
|
16741
|
+
/**
|
|
16742
|
+
* Field Instruction module for Table of Contents.
|
|
16743
|
+
*
|
|
16744
|
+
* This module handles the generation of TOC field instruction text
|
|
16745
|
+
* that controls how the table of contents is built.
|
|
16746
|
+
*
|
|
16747
|
+
* Reference: http://officeopenxml.com/WPfieldInstructions.php
|
|
16748
|
+
*
|
|
16749
|
+
* @module
|
|
16750
|
+
*/
|
|
16751
|
+
/**
|
|
16752
|
+
* Represents a field instruction for a Table of Contents.
|
|
16753
|
+
*
|
|
16754
|
+
* The FieldInstruction class generates the TOC field code string that Word uses
|
|
16755
|
+
* to determine how to build the table of contents, including which headings to include,
|
|
16756
|
+
* formatting options, and other TOC-specific settings.
|
|
16757
|
+
*
|
|
16758
|
+
* Reference: http://officeopenxml.com/WPfieldInstructions.php
|
|
16759
|
+
*
|
|
16760
|
+
* ## XSD Schema
|
|
16761
|
+
* ```xml
|
|
16762
|
+
* <xsd:element name="instrText" type="CT_Text"/>
|
|
16763
|
+
* ```
|
|
16764
|
+
*
|
|
16765
|
+
* @example
|
|
16766
|
+
* ```typescript
|
|
16767
|
+
* // Basic TOC field instruction
|
|
16768
|
+
* new FieldInstruction({ headingStyleRange: "1-3" });
|
|
16769
|
+
*
|
|
16770
|
+
* // TOC with hyperlinks and custom styles
|
|
16771
|
+
* new FieldInstruction({
|
|
16772
|
+
* hyperlink: true,
|
|
16773
|
+
* headingStyleRange: "1-3",
|
|
16774
|
+
* stylesWithLevels: [new StyleLevel("CustomStyle", 2)],
|
|
16775
|
+
* });
|
|
16776
|
+
* ```
|
|
16777
|
+
*/
|
|
16778
|
+
var FieldInstruction = class extends XmlComponent {
|
|
16779
|
+
constructor(properties = {}) {
|
|
16780
|
+
super("w:instrText");
|
|
16781
|
+
_defineProperty(this, "properties", void 0);
|
|
16782
|
+
this.properties = properties;
|
|
16783
|
+
this.root.push(new TextAttributes({ space: SpaceType.PRESERVE }));
|
|
16784
|
+
let instruction = "TOC";
|
|
16785
|
+
if (this.properties.captionLabel) instruction = `${instruction} \\a "${this.properties.captionLabel}"`;
|
|
16786
|
+
if (this.properties.entriesFromBookmark) instruction = `${instruction} \\b "${this.properties.entriesFromBookmark}"`;
|
|
16787
|
+
if (this.properties.captionLabelIncludingNumbers) instruction = `${instruction} \\c "${this.properties.captionLabelIncludingNumbers}"`;
|
|
16788
|
+
if (this.properties.sequenceAndPageNumbersSeparator) instruction = `${instruction} \\d "${this.properties.sequenceAndPageNumbersSeparator}"`;
|
|
16789
|
+
if (this.properties.tcFieldIdentifier) instruction = `${instruction} \\f "${this.properties.tcFieldIdentifier}"`;
|
|
16790
|
+
if (this.properties.hyperlink) instruction = `${instruction} \\h`;
|
|
16791
|
+
if (this.properties.tcFieldLevelRange) instruction = `${instruction} \\l "${this.properties.tcFieldLevelRange}"`;
|
|
16792
|
+
if (this.properties.pageNumbersEntryLevelsRange) instruction = `${instruction} \\n "${this.properties.pageNumbersEntryLevelsRange}"`;
|
|
16793
|
+
if (this.properties.headingStyleRange) instruction = `${instruction} \\o "${this.properties.headingStyleRange}"`;
|
|
16794
|
+
if (this.properties.entryAndPageNumberSeparator) instruction = `${instruction} \\p "${this.properties.entryAndPageNumberSeparator}"`;
|
|
16795
|
+
if (this.properties.seqFieldIdentifierForPrefix) instruction = `${instruction} \\s "${this.properties.seqFieldIdentifierForPrefix}"`;
|
|
16796
|
+
if (this.properties.stylesWithLevels && this.properties.stylesWithLevels.length) {
|
|
16797
|
+
const styles = this.properties.stylesWithLevels.map((sl) => `${sl.styleName},${sl.level}`).join(",");
|
|
16798
|
+
instruction = `${instruction} \\t "${styles}"`;
|
|
16799
|
+
}
|
|
16800
|
+
if (this.properties.useAppliedParagraphOutlineLevel) instruction = `${instruction} \\u`;
|
|
16801
|
+
if (this.properties.preserveTabInEntries) instruction = `${instruction} \\w`;
|
|
16802
|
+
if (this.properties.preserveNewLineInEntries) instruction = `${instruction} \\x`;
|
|
16803
|
+
if (this.properties.hideTabAndPageNumbersInWebView) instruction = `${instruction} \\z`;
|
|
16804
|
+
this.root.push(instruction);
|
|
16805
|
+
}
|
|
16806
|
+
};
|
|
16807
|
+
//#endregion
|
|
16808
|
+
//#region src/file/table-of-contents/sdt-content.ts
|
|
16809
|
+
/**
|
|
16810
|
+
* Structured Document Tag Content module.
|
|
16811
|
+
*
|
|
16812
|
+
* This module represents the content container for structured document tags,
|
|
16813
|
+
* including table of contents elements.
|
|
16814
|
+
*
|
|
16815
|
+
* Reference: http://officeopenxml.com/WPtableOfContents.php
|
|
16816
|
+
*
|
|
16817
|
+
* @module
|
|
16818
|
+
*/
|
|
16819
|
+
/**
|
|
16820
|
+
* Represents the content portion of a Structured Document Tag.
|
|
16821
|
+
*
|
|
16822
|
+
* The StructuredDocumentTagContent contains the actual content elements
|
|
16823
|
+
* (paragraphs, tables, etc.) within a structured document tag, such as
|
|
16824
|
+
* the paragraphs that make up a table of contents.
|
|
16825
|
+
*
|
|
16826
|
+
* Reference: http://officeopenxml.com/WPtableOfContents.php
|
|
16827
|
+
*
|
|
16828
|
+
* ## XSD Schema
|
|
16829
|
+
* ```xml
|
|
16830
|
+
* <xsd:complexType name="CT_SdtContentBlock">
|
|
16831
|
+
* <xsd:group ref="EG_ContentBlockContent" minOccurs="0" maxOccurs="unbounded"/>
|
|
16832
|
+
* </xsd:complexType>
|
|
16833
|
+
* ```
|
|
16834
|
+
*
|
|
16835
|
+
* @example
|
|
16836
|
+
* ```typescript
|
|
16837
|
+
* const content = new StructuredDocumentTagContent();
|
|
16838
|
+
* content.addChildElement(new Paragraph("Content"));
|
|
16839
|
+
* ```
|
|
16840
|
+
*/
|
|
16841
|
+
var StructuredDocumentTagContent = class extends XmlComponent {
|
|
16842
|
+
constructor() {
|
|
16843
|
+
super("w:sdtContent");
|
|
16844
|
+
}
|
|
16845
|
+
};
|
|
16846
|
+
//#endregion
|
|
16847
|
+
//#region src/file/table-of-contents/heading-entries.ts
|
|
16848
|
+
/**
|
|
16849
|
+
* Entries written into a table of contents from the headings of the document.
|
|
16850
|
+
*
|
|
16851
|
+
* A table of contents is a TOC field. Word fills in its entries when it updates the field. Until then, and in
|
|
16852
|
+
* applications that don't update it, such as LibreOffice, it shows the entries it was last filled in with, and without
|
|
16853
|
+
* any it is empty. So once the body is written, each table of contents that wasn't given `cachedEntries` or
|
|
16854
|
+
* `contentChildren` is filled in from the headings its switches include, the way Word fills it in: each heading is
|
|
16855
|
+
* bookmarked, and its entry links to the bookmark and gives its page with a PAGEREF field. The page numbers are left
|
|
16856
|
+
* empty, because they depend on how the document is laid out. Word fills them in when it updates the field, unless the
|
|
16857
|
+
* document's `pageNumbers` writes them.
|
|
16858
|
+
*
|
|
16859
|
+
* @module
|
|
16860
|
+
*/
|
|
16861
|
+
/**
|
|
16862
|
+
* The beginning of a table of contents' field: dirty or clean, as the caller set it, or else dirty unless the document
|
|
16863
|
+
* is given page numbers
|
|
16864
|
+
*/
|
|
16865
|
+
var beginOf = (beginDirty) => beginDirty === void 0 ? createBeginDirtyWithoutPageNumbers() : createBegin(beginDirty);
|
|
16866
|
+
/** The formatted tables of contents, with what each is filled in with, or undefined when it was given its content */
|
|
16867
|
+
var writtenTables = /* @__PURE__ */ new WeakMap();
|
|
16868
|
+
/**
|
|
16869
|
+
* Records a formatted table of contents, so the paragraphs in it aren't taken for headings, with what to fill it in
|
|
16870
|
+
* with from the headings once the body it is in is written. That is undefined when it was given its content.
|
|
16871
|
+
*/
|
|
16872
|
+
var recordTableOfContents = (table, fillWith) => {
|
|
16873
|
+
writtenTables.set(table, fillWith);
|
|
16874
|
+
};
|
|
16875
|
+
/**
|
|
16876
|
+
* The ids of the bookmarks on a body's headings: the first for its first bookmarked heading, and so on. Each is taken
|
|
16877
|
+
* from the counter every bookmark shares, the first time it is needed, so a document packed again is written the same.
|
|
16878
|
+
*/
|
|
16879
|
+
var HeadingBookmarkIds = class {
|
|
16880
|
+
constructor() {
|
|
16881
|
+
_defineProperty(this, "ids", []);
|
|
16882
|
+
}
|
|
16883
|
+
get(index) {
|
|
16884
|
+
var _this$ids, _this$ids$index;
|
|
16885
|
+
(_this$ids$index = (_this$ids = this.ids)[index]) !== null && _this$ids$index !== void 0 || (_this$ids[index] = bookmarkUniqueNumericId());
|
|
16886
|
+
return this.ids[index];
|
|
16887
|
+
}
|
|
16888
|
+
};
|
|
16889
|
+
/** The name of a formatted element, or `_attr` for its parent's attributes */
|
|
16890
|
+
var nameOf$2 = (element) => typeof element === "object" && element !== null ? Object.keys(element)[0] : void 0;
|
|
16891
|
+
/** The children of a formatted element. An element with only attributes has them as its one child */
|
|
16892
|
+
var childrenOf = (element) => {
|
|
16893
|
+
const name = nameOf$2(element);
|
|
16894
|
+
const content = name === void 0 ? void 0 : element[name];
|
|
16895
|
+
return Array.isArray(content) ? content : content === void 0 ? [] : [content];
|
|
16896
|
+
};
|
|
16897
|
+
var childOf = (element, name) => childrenOf(element).find((child) => nameOf$2(child) === name);
|
|
16898
|
+
var attributeOf = (element, attribute) => {
|
|
16899
|
+
var _childOf;
|
|
16900
|
+
return (_childOf = childOf(element, "_attr")) === null || _childOf === void 0 || (_childOf = _childOf._attr) === null || _childOf === void 0 ? void 0 : _childOf[attribute];
|
|
16901
|
+
};
|
|
16902
|
+
/** An attribute such as `w:val="2"` as a number. Imported XML gives it as a string */
|
|
16903
|
+
var numberAttributeOf = (element, attribute) => {
|
|
16904
|
+
const value = attributeOf(element, attribute);
|
|
16905
|
+
return value === void 0 ? void 0 : Number(value);
|
|
16906
|
+
};
|
|
16907
|
+
/** The block-level containers of paragraphs: tables, their rows and cells, and content controls */
|
|
16908
|
+
var BLOCK_CONTAINERS = /* @__PURE__ */ new Set([
|
|
16909
|
+
"w:tbl",
|
|
16910
|
+
"w:tr",
|
|
16911
|
+
"w:tc",
|
|
16912
|
+
"w:sdt",
|
|
16913
|
+
"w:sdtContent",
|
|
16914
|
+
"w:customXml"
|
|
16915
|
+
]);
|
|
16916
|
+
/**
|
|
16917
|
+
* The paragraphs and the tables of contents, in the order they are in the body. A table of contents isn't looked into,
|
|
16918
|
+
* so the paragraphs in it aren't taken for headings. Nor are paragraphs in text boxes, as in Word.
|
|
16919
|
+
*/
|
|
16920
|
+
var blocksOf = (elements) => elements.flatMap((element) => {
|
|
16921
|
+
const name = nameOf$2(element);
|
|
16922
|
+
if (name === "w:p" || writtenTables.has(element)) return [element];
|
|
16923
|
+
return name !== void 0 && BLOCK_CONTAINERS.has(name) ? blocksOf(childrenOf(element)) : [];
|
|
16924
|
+
});
|
|
16925
|
+
/** The elements in a paragraph that its text is in. Deleted text, field instructions and drawings aren't */
|
|
16926
|
+
var TEXT_CONTAINERS = /* @__PURE__ */ new Set([
|
|
16927
|
+
"w:r",
|
|
16928
|
+
"w:hyperlink",
|
|
16929
|
+
"w:ins",
|
|
16930
|
+
"w:moveTo",
|
|
16931
|
+
"w:smartTag",
|
|
16932
|
+
"w:customXml",
|
|
16933
|
+
"w:sdt",
|
|
16934
|
+
"w:sdtContent",
|
|
16935
|
+
"w:fldSimple",
|
|
16936
|
+
"w:dir",
|
|
16937
|
+
"w:bdo"
|
|
16938
|
+
]);
|
|
16939
|
+
/** The text an element in a run stands for, such as `\t` for a tab. A page or column break isn't text */
|
|
16940
|
+
var textOfRunContent = (element) => {
|
|
16941
|
+
switch (nameOf$2(element)) {
|
|
16942
|
+
case "w:t": return childrenOf(element).filter((child) => typeof child === "string").join("");
|
|
16943
|
+
case "w:tab": return " ";
|
|
16944
|
+
case "w:br": return [void 0, "textWrapping"].includes(attributeOf(element, "w:type")) ? "\n" : "";
|
|
16945
|
+
case "w:cr": return "\n";
|
|
16946
|
+
case "w:noBreakHyphen": return "-";
|
|
16947
|
+
default: return "";
|
|
16948
|
+
}
|
|
16949
|
+
};
|
|
16950
|
+
/** The text of a paragraph. Of a field, only its result is text, not its instruction */
|
|
16951
|
+
var textOf = (paragraph) => {
|
|
16952
|
+
const fields = [];
|
|
16953
|
+
const read = (element) => {
|
|
16954
|
+
const name = nameOf$2(element);
|
|
16955
|
+
if (name !== void 0 && TEXT_CONTAINERS.has(name)) return childrenOf(element).map(read).join("");
|
|
16956
|
+
if (name === "w:fldChar") {
|
|
16957
|
+
const type = attributeOf(element, "w:fldCharType");
|
|
16958
|
+
if (type === "begin") fields.push(false);
|
|
16959
|
+
else if (type === "separate") fields[fields.length - 1] = true;
|
|
16960
|
+
else fields.pop();
|
|
16961
|
+
return "";
|
|
16962
|
+
}
|
|
16963
|
+
return fields.every(Boolean) ? textOfRunContent(element) : "";
|
|
16964
|
+
};
|
|
16965
|
+
return childrenOf(paragraph).map(read).join("");
|
|
16966
|
+
};
|
|
16967
|
+
/** The bookmarks started and ended in an element, in order */
|
|
16968
|
+
var bookmarkMarksOf = (element) => {
|
|
16969
|
+
const name = nameOf$2(element);
|
|
16970
|
+
if (name === "w:bookmarkStart") return [{
|
|
16971
|
+
start: true,
|
|
16972
|
+
id: attributeOf(element, "w:id"),
|
|
16973
|
+
name: attributeOf(element, "w:name")
|
|
16974
|
+
}];
|
|
16975
|
+
if (name === "w:bookmarkEnd") return [{
|
|
16976
|
+
start: false,
|
|
16977
|
+
id: attributeOf(element, "w:id")
|
|
16978
|
+
}];
|
|
16979
|
+
return name === void 0 || name === "_attr" ? [] : childrenOf(element).flatMap(bookmarkMarksOf);
|
|
16980
|
+
};
|
|
16981
|
+
/**
|
|
16982
|
+
* The names of the bookmarks each paragraph is in, for the `\b` switch: those open where it starts, followed through the
|
|
16983
|
+
* body, and those that start in it.
|
|
16984
|
+
*/
|
|
16985
|
+
var bookmarksOf = (paragraphs) => {
|
|
16986
|
+
const open = /* @__PURE__ */ new Map();
|
|
16987
|
+
return paragraphs.map((paragraph) => {
|
|
16988
|
+
const marks = bookmarkMarksOf(paragraph);
|
|
16989
|
+
const names = /* @__PURE__ */ new Set([...open.values(), ...marks.flatMap((mark) => mark.start ? [mark.name] : [])]);
|
|
16990
|
+
for (const mark of marks) if (mark.start) open.set(mark.id, mark.name);
|
|
16991
|
+
else open.delete(mark.id);
|
|
16992
|
+
return names;
|
|
16993
|
+
});
|
|
16994
|
+
};
|
|
16995
|
+
/** The details of each paragraph that could be a heading. The bookmarks it is in are only followed when needed */
|
|
16996
|
+
var paragraphDetailsOf = (paragraphs, followBookmarks) => {
|
|
16997
|
+
const bookmarks = followBookmarks ? bookmarksOf(paragraphs) : [];
|
|
16998
|
+
return paragraphs.map((element, index) => {
|
|
16999
|
+
var _bookmarks$index;
|
|
17000
|
+
const properties = childOf(element, "w:pPr");
|
|
17001
|
+
return {
|
|
17002
|
+
element,
|
|
17003
|
+
styleId: attributeOf(childOf(properties, "w:pStyle"), "w:val"),
|
|
17004
|
+
outlineLevel: numberAttributeOf(childOf(properties, "w:outlineLvl"), "w:val"),
|
|
17005
|
+
text: textOf(element),
|
|
17006
|
+
bookmarks: (_bookmarks$index = bookmarks[index]) !== null && _bookmarks$index !== void 0 ? _bookmarks$index : /* @__PURE__ */ new Set()
|
|
17007
|
+
};
|
|
17008
|
+
});
|
|
17009
|
+
};
|
|
17010
|
+
/** The document's paragraph styles, by id, read from the styles as they are written */
|
|
17011
|
+
var stylesOf = (context) => {
|
|
17012
|
+
var _context$file;
|
|
17013
|
+
const styles = (_context$file = context.file) === null || _context$file === void 0 || (_context$file = _context$file.Styles) === null || _context$file === void 0 ? void 0 : _context$file.prepForXml(context);
|
|
17014
|
+
return new Map(childrenOf(styles).filter((style) => nameOf$2(style) === "w:style" && ["paragraph", void 0].includes(attributeOf(style, "w:type"))).map((style) => [attributeOf(style, "w:styleId"), {
|
|
17015
|
+
name: attributeOf(childOf(style, "w:name"), "w:val"),
|
|
17016
|
+
basedOn: attributeOf(childOf(style, "w:basedOn"), "w:val"),
|
|
17017
|
+
outlineLevel: numberAttributeOf(childOf(childOf(style, "w:pPr"), "w:outlineLvl"), "w:val")
|
|
17018
|
+
}]));
|
|
17019
|
+
};
|
|
17020
|
+
/** A range such as `1-3` */
|
|
17021
|
+
var parseRange = (range) => {
|
|
17022
|
+
const match = /^\s*(\d+)\s*-\s*(\d+)\s*$/.exec(range);
|
|
17023
|
+
return match ? [Number(match[1]), Number(match[2])] : void 0;
|
|
17024
|
+
};
|
|
17025
|
+
var isWithin = (level, [from, to]) => level >= from && level <= to;
|
|
17026
|
+
/** The level of a built-in heading style, Heading 1 to Heading 9, by its name, or by its id when it has no name */
|
|
17027
|
+
var headingLevelOf = (styleId, styles) => {
|
|
17028
|
+
var _styles$get$name, _styles$get;
|
|
17029
|
+
if (styleId === void 0) return;
|
|
17030
|
+
const match = /^heading ?([1-9])$/i.exec((_styles$get$name = (_styles$get = styles.get(styleId)) === null || _styles$get === void 0 ? void 0 : _styles$get.name) !== null && _styles$get$name !== void 0 ? _styles$get$name : styleId);
|
|
17031
|
+
return match ? Number(match[1]) : void 0;
|
|
17032
|
+
};
|
|
17033
|
+
/**
|
|
17034
|
+
* A style's outline level, from 0: its own, or else the one of the style it is based on. A built-in heading style has
|
|
17035
|
+
* its heading's. Following the styles it is based on stops after as many as there are, in case they loop.
|
|
17036
|
+
*/
|
|
17037
|
+
var styleOutlineLevelOf = (styleId, styles, depth = 0) => {
|
|
17038
|
+
var _style$outlineLevel;
|
|
17039
|
+
if (styleId === void 0 || depth > styles.size) return;
|
|
17040
|
+
const style = styles.get(styleId);
|
|
17041
|
+
const heading = headingLevelOf(styleId, styles);
|
|
17042
|
+
return (_style$outlineLevel = style === null || style === void 0 ? void 0 : style.outlineLevel) !== null && _style$outlineLevel !== void 0 ? _style$outlineLevel : heading === void 0 ? styleOutlineLevelOf(style === null || style === void 0 ? void 0 : style.basedOn, styles, depth + 1) : heading - 1;
|
|
17043
|
+
};
|
|
17044
|
+
/**
|
|
17045
|
+
* Reads the heading level of the document's paragraphs, as the `\s` switch of a SEQ field follows it: the level of a
|
|
17046
|
+
* paragraph in a built-in heading style, Heading 1 to Heading 9. A paragraph whose outline level is another, or that has
|
|
17047
|
+
* one without a heading style, is `"unclear"`, as which of the two Word follows hasn't been checked. Other paragraphs
|
|
17048
|
+
* are undefined.
|
|
17049
|
+
*/
|
|
17050
|
+
var headingLevels = (context) => {
|
|
17051
|
+
const styles = stylesOf(context);
|
|
17052
|
+
return (paragraph) => {
|
|
17053
|
+
const properties = childOf(paragraph, "w:pPr");
|
|
17054
|
+
const styleId = attributeOf(childOf(properties, "w:pStyle"), "w:val");
|
|
17055
|
+
const heading = headingLevelOf(styleId, styles);
|
|
17056
|
+
const outlineLevel = outlineLevelOf({
|
|
17057
|
+
styleId,
|
|
17058
|
+
outlineLevel: numberAttributeOf(childOf(properties, "w:outlineLvl"), "w:val")
|
|
17059
|
+
}, styles);
|
|
17060
|
+
const outline = outlineLevel === void 0 || outlineLevel >= 9 ? void 0 : outlineLevel + 1;
|
|
17061
|
+
if (heading !== void 0 && (outline === void 0 || outline === heading)) return heading;
|
|
17062
|
+
return outline === void 0 ? void 0 : "unclear";
|
|
17063
|
+
};
|
|
17064
|
+
};
|
|
17065
|
+
/** A paragraph's outline level, from 0: its own, or else its style's */
|
|
17066
|
+
var outlineLevelOf = (paragraph, styles) => {
|
|
17067
|
+
var _paragraph$outlineLev;
|
|
17068
|
+
return (_paragraph$outlineLev = paragraph.outlineLevel) !== null && _paragraph$outlineLev !== void 0 ? _paragraph$outlineLev : styleOutlineLevelOf(paragraph.styleId, styles);
|
|
17069
|
+
};
|
|
17070
|
+
/** The level a table of contents gives a paragraph, or undefined when it doesn't include it */
|
|
17071
|
+
var levelIn = (properties, paragraph, styles) => {
|
|
17072
|
+
var _styles$get2;
|
|
17073
|
+
const { entriesFromBookmark, headingStyleRange, stylesWithLevels = [], useAppliedParagraphOutlineLevel } = properties;
|
|
17074
|
+
if (paragraph.text.trim() === "" || entriesFromBookmark && !paragraph.bookmarks.has(entriesFromBookmark)) return;
|
|
17075
|
+
const names = [paragraph.styleId, paragraph.styleId === void 0 ? void 0 : (_styles$get2 = styles.get(paragraph.styleId)) === null || _styles$get2 === void 0 ? void 0 : _styles$get2.name].filter((name) => name !== void 0).map((name) => name.toLowerCase());
|
|
17076
|
+
const listed = stylesWithLevels.find((style) => names.includes(style.styleName.toLowerCase()));
|
|
17077
|
+
if (listed) return listed.level;
|
|
17078
|
+
const namesItsEntries = Boolean(headingStyleRange) || stylesWithLevels.length > 0 || Boolean(useAppliedParagraphOutlineLevel) || Boolean(properties.tcFieldIdentifier) || Boolean(properties.tcFieldLevelRange) || Boolean(properties.captionLabel) || Boolean(properties.captionLabelIncludingNumbers);
|
|
17079
|
+
const headingRange = headingStyleRange ? parseRange(headingStyleRange) : namesItsEntries ? void 0 : [1, 9];
|
|
17080
|
+
const heading = headingLevelOf(paragraph.styleId, styles);
|
|
17081
|
+
if (headingRange && heading !== void 0 && isWithin(heading, headingRange)) return heading;
|
|
17082
|
+
const outlineLevel = useAppliedParagraphOutlineLevel ? outlineLevelOf(paragraph, styles) : void 0;
|
|
17083
|
+
return outlineLevel !== void 0 && isWithin(outlineLevel + 1, headingRange !== null && headingRange !== void 0 ? headingRange : [1, 9]) ? outlineLevel + 1 : void 0;
|
|
17084
|
+
};
|
|
17085
|
+
/** The runs of an entry's title. Tabs and line breaks are kept only when the table of contents keeps them (\w and \x) */
|
|
17086
|
+
var titleRunsOf = (title, properties) => {
|
|
17087
|
+
const text = properties.preserveTabInEntries ? title : title.replace(/\t/g, " ");
|
|
17088
|
+
return (properties.preserveNewLineInEntries ? text.split("\n") : [text.replace(/\n/g, " ")]).map((line, index) => new TextRun({
|
|
17089
|
+
break: index > 0 ? 1 : void 0,
|
|
17090
|
+
children: line.split(" ").flatMap((part, partIndex) => [...partIndex > 0 ? [new Tab()] : [], ...part === "" ? [] : [part]])
|
|
17091
|
+
}));
|
|
17092
|
+
};
|
|
17093
|
+
/**
|
|
17094
|
+
* The paragraph style of the entries at a level: the built-in TOC style, found by its name, "toc 1" to "toc 9". When
|
|
17095
|
+
* the document doesn't have it, the entries are indented as Word's are, 220 twips a level.
|
|
17096
|
+
*/
|
|
17097
|
+
var entryStyleOf = (level, styles) => {
|
|
17098
|
+
var _find;
|
|
17099
|
+
const named = (_find = [...styles].find(([, style]) => {
|
|
17100
|
+
var _style$name;
|
|
17101
|
+
return ((_style$name = style.name) === null || _style$name === void 0 ? void 0 : _style$name.toLowerCase()) === `toc ${level}`;
|
|
17102
|
+
})) === null || _find === void 0 ? void 0 : _find[0];
|
|
17103
|
+
const id = named !== null && named !== void 0 ? named : `TOC${level}`;
|
|
17104
|
+
return named !== void 0 || styles.has(id) || level === 1 ? { id } : {
|
|
17105
|
+
id,
|
|
17106
|
+
indent: (level - 1) * 220
|
|
17107
|
+
};
|
|
17108
|
+
};
|
|
17109
|
+
/** The formatted content of a table of contents with its entries */
|
|
17110
|
+
var contentOf = ({ properties, beginDirty, textWidth }, entries, styles, context) => {
|
|
17111
|
+
var _parseRange;
|
|
17112
|
+
const withoutPageNumbers = properties.pageNumbersEntryLevelsRange ? (_parseRange = parseRange(properties.pageNumbersEntryLevelsRange)) !== null && _parseRange !== void 0 ? _parseRange : [1, 9] : void 0;
|
|
17113
|
+
const content = new StructuredDocumentTagContent();
|
|
17114
|
+
entries.forEach((entry, index) => {
|
|
17115
|
+
const hasPageNumber = withoutPageNumbers === void 0 || !isWithin(entry.level, withoutPageNumbers);
|
|
17116
|
+
const children = [...titleRunsOf(entry.title, properties), ...hasPageNumber ? [new TextRun({ children: [properties.entryAndPageNumberSeparator || new Tab()] }), new PageReference(entry.bookmark, { hyperlink: properties.hyperlink })] : []];
|
|
17117
|
+
const style = entryStyleOf(entry.level, styles);
|
|
17118
|
+
content.addChildElement(new Paragraph({
|
|
17119
|
+
style: style.id,
|
|
17120
|
+
indent: style.indent === void 0 ? void 0 : { left: style.indent },
|
|
17121
|
+
tabStops: [{
|
|
17122
|
+
type: "right",
|
|
17123
|
+
position: textWidth,
|
|
17124
|
+
leader: "dot"
|
|
17125
|
+
}],
|
|
17126
|
+
children: [...index === 0 ? [new Run({ children: [
|
|
17127
|
+
beginOf(beginDirty),
|
|
17128
|
+
new FieldInstruction(properties),
|
|
17129
|
+
createSeparate()
|
|
17130
|
+
] })] : [], ...properties.hyperlink ? [new InternalHyperlink({
|
|
17131
|
+
anchor: entry.bookmark,
|
|
17132
|
+
children
|
|
17133
|
+
})] : children]
|
|
17134
|
+
}));
|
|
17135
|
+
});
|
|
17136
|
+
content.addChildElement(new Paragraph({ children: [new Run({ children: [createEnd()] })] }));
|
|
17137
|
+
return content.prepForXml(context);
|
|
17138
|
+
};
|
|
17139
|
+
/** Puts a bookmark around the content of a formatted paragraph */
|
|
17140
|
+
var bookmark = (paragraph, name, id, context) => {
|
|
17141
|
+
const children = childrenOf(paragraph);
|
|
17142
|
+
const start = children.findIndex((child) => nameOf$2(child) === "w:pPr") + 1;
|
|
17143
|
+
paragraph["w:p"] = [
|
|
17144
|
+
...children.slice(0, start),
|
|
17145
|
+
new BookmarkStart(name, id).prepForXml(context),
|
|
17146
|
+
...children.slice(start),
|
|
17147
|
+
new BookmarkEnd(id).prepForXml(context)
|
|
17148
|
+
];
|
|
17149
|
+
};
|
|
17150
|
+
/**
|
|
17151
|
+
* Fills in the tables of contents in a formatted body from its headings, and bookmarks the headings they list. A
|
|
17152
|
+
* table of contents that doesn't list any heading is left empty, for Word to fill in.
|
|
17153
|
+
*/
|
|
17154
|
+
var fillTablesOfContents = (body, context, bookmarkIds) => {
|
|
17155
|
+
const blocks = blocksOf(childrenOf(body));
|
|
17156
|
+
const tables = blocks.flatMap((block) => {
|
|
17157
|
+
const options = writtenTables.get(block);
|
|
17158
|
+
return options ? [[block, options]] : [];
|
|
17159
|
+
});
|
|
17160
|
+
if (tables.length === 0) return;
|
|
17161
|
+
const styles = stylesOf(context);
|
|
17162
|
+
const followBookmarks = tables.some(([, { properties }]) => Boolean(properties.entriesFromBookmark));
|
|
17163
|
+
const headings = paragraphDetailsOf(blocks.filter((block) => nameOf$2(block) === "w:p"), followBookmarks).map((paragraph) => ({
|
|
17164
|
+
paragraph,
|
|
17165
|
+
levels: tables.map(([, { properties }]) => levelIn(properties, paragraph, styles))
|
|
17166
|
+
})).filter(({ levels }) => levels.some((level) => level !== void 0)).map((heading, index) => _objectSpread2(_objectSpread2({}, heading), {}, { id: bookmarkIds.get(index) }));
|
|
17167
|
+
for (const { paragraph, id } of headings) bookmark(paragraph.element, `_Toc${id}`, id, context);
|
|
17168
|
+
tables.forEach(([table, options], index) => {
|
|
17169
|
+
const entries = headings.flatMap(({ paragraph, levels, id }) => {
|
|
17170
|
+
const level = levels[index];
|
|
17171
|
+
return level === void 0 ? [] : [{
|
|
17172
|
+
title: paragraph.text,
|
|
17173
|
+
level,
|
|
17174
|
+
bookmark: `_Toc${id}`
|
|
17175
|
+
}];
|
|
17176
|
+
});
|
|
17177
|
+
if (entries.length === 0) return;
|
|
17178
|
+
table["w:sdt"] = childrenOf(table).map((child) => nameOf$2(child) === "w:sdtContent" ? contentOf(options, entries, styles, context) : child);
|
|
17179
|
+
});
|
|
17180
|
+
};
|
|
17181
|
+
//#endregion
|
|
17182
|
+
//#region src/file/document/body/sequence-numbers.ts
|
|
17183
|
+
/**
|
|
17184
|
+
* Caption numbers written into the SEQ fields of a document, such as the 2 of "Figure 2", when the document is given page
|
|
17185
|
+
* numbers.
|
|
17186
|
+
*
|
|
17187
|
+
* A SEQ field (`SequentialIdentifier`) shows how many SEQ fields of its identifier, such as "Figure", there are up to and
|
|
17188
|
+
* including it, so the number doesn't depend on how the pages are laid out. Its switches change the count: `\r 5` starts
|
|
17189
|
+
* it again from 5, `\c` repeats the number of the one before, `\s 1` starts it again after each Heading 1, `\h` hides the
|
|
17190
|
+
* number, and `\* ROMAN` writes it in roman numerals. `docx` writes SEQ fields dirty, for Word to number when it opens the
|
|
17191
|
+
* document, which makes Word ask to update the fields. When the document is given page numbers, each is written clean
|
|
17192
|
+
* with its number, counted as Word counts it. What Word does was read from its PDF of `scripts/layout-probes/word-seq.ts`.
|
|
17193
|
+
*
|
|
17194
|
+
* Word counts the SEQ fields of the body, those in text boxes and hidden text too, in order, and counts an identifier in
|
|
17195
|
+
* any capitals, or in quotes, as the same one. It writes the SEQ fields of headers, footers, footnotes and endnotes as an
|
|
17196
|
+
* error, "Error! Main Document Only.", and doesn't count them with the body's.
|
|
17197
|
+
*
|
|
17198
|
+
* Where Word's count isn't known, the field is left blank rather than given a number that could be wrong: a switch it
|
|
17199
|
+
* doesn't follow, a SEQ field in deleted text, and every SEQ field of an identifier that also has SEQ fields in a comment.
|
|
17200
|
+
* The fields of its identifier after one whose number isn't known are left blank too, until one starts the count again
|
|
17201
|
+
* with `\r`. A number in a format not followed is left blank, but the count goes on.
|
|
17202
|
+
*
|
|
17203
|
+
* @module
|
|
17204
|
+
*/
|
|
17205
|
+
var IDENTIFIER = new RegExp("^\\p{L}[\\p{L}\\p{N}_]*$", "u");
|
|
17206
|
+
/** Reads the switches of a SEQ field, and a bookmark before them, or undefined when one of them isn't followed */
|
|
17207
|
+
var sequenceOf = (switches) => {
|
|
17208
|
+
var _step, _format;
|
|
17209
|
+
let step;
|
|
17210
|
+
let hidden = false;
|
|
17211
|
+
let format;
|
|
17212
|
+
let caseFormat = false;
|
|
17213
|
+
let picture = false;
|
|
17214
|
+
for (let index = 0; index < switches.length; index++) {
|
|
17215
|
+
var _switches, _next;
|
|
17216
|
+
const name = switches[index];
|
|
17217
|
+
const argument = (_switches = switches[index + 1]) !== null && _switches !== void 0 ? _switches : "";
|
|
17218
|
+
let next;
|
|
17219
|
+
if (index === 0 && !name.startsWith("\\")) next = { type: "bookmark" };
|
|
17220
|
+
else if (name === "\\c" || name === "\\n") next = { type: name === "\\c" ? "repeat" : "next" };
|
|
17221
|
+
else if ((name === "\\r" || name === "\\s") && /^\d+$/.test(argument)) {
|
|
17222
|
+
index++;
|
|
17223
|
+
next = name === "\\r" ? {
|
|
17224
|
+
type: "reset",
|
|
17225
|
+
to: Number(argument)
|
|
17226
|
+
} : {
|
|
17227
|
+
type: "heading",
|
|
17228
|
+
level: Number(argument)
|
|
17229
|
+
};
|
|
17230
|
+
} else if (name === "\\h") hidden = true;
|
|
17231
|
+
else if (name === "\\#" && index + 1 < switches.length) {
|
|
17232
|
+
index++;
|
|
17233
|
+
picture = true;
|
|
17234
|
+
} else if (name === "\\*" && index + 1 < switches.length) {
|
|
17235
|
+
const value = switches[++index];
|
|
17236
|
+
if (CASE_FORMATS.has(value.toLowerCase())) caseFormat = true;
|
|
17237
|
+
else if (!PLAIN_FORMATS.has(value.toLowerCase())) {
|
|
17238
|
+
if (format !== void 0) return;
|
|
17239
|
+
format = value;
|
|
17240
|
+
}
|
|
17241
|
+
} else return;
|
|
17242
|
+
if (next && step) return;
|
|
17243
|
+
step = (_next = next) !== null && _next !== void 0 ? _next : step;
|
|
17244
|
+
}
|
|
17245
|
+
if ((step === null || step === void 0 ? void 0 : step.type) === "bookmark" && switches.length > 1) return;
|
|
17246
|
+
const written = !picture && !(caseFormat && format !== void 0 && format.toLowerCase() !== "arabic");
|
|
17247
|
+
return {
|
|
17248
|
+
step: (_step = step) !== null && _step !== void 0 ? _step : { type: "next" },
|
|
17249
|
+
hidden: hidden && format === void 0,
|
|
17250
|
+
format: written ? (_format = format) !== null && _format !== void 0 ? _format : "ARABIC" : ""
|
|
17251
|
+
};
|
|
17252
|
+
};
|
|
17253
|
+
/** Reads a SEQ field's instruction, or undefined when the field isn't a SEQ field */
|
|
17254
|
+
var sequenceFieldOf = (instruction) => {
|
|
17255
|
+
var _match$1$match;
|
|
17256
|
+
const match = new RegExp("^\\s*SEQ\\b(.*)$", "is").exec(instruction);
|
|
17257
|
+
if (!match) return;
|
|
17258
|
+
const [written, ...switches] = (_match$1$match = match[1].match(/"[^"]*"|\S+/g)) !== null && _match$1$match !== void 0 ? _match$1$match : [];
|
|
17259
|
+
if (written === void 0) return {};
|
|
17260
|
+
const identifier = written.replace(/^"(.*)"$/, "$1");
|
|
17261
|
+
return IDENTIFIER.test(identifier) ? {
|
|
17262
|
+
identifier,
|
|
17263
|
+
sequence: sequenceOf(switches)
|
|
17264
|
+
} : { identifier };
|
|
17265
|
+
};
|
|
17266
|
+
/** Whether a field's instruction is that of a SEQ field */
|
|
17267
|
+
var isSequenceField = (instruction) => sequenceFieldOf(instruction) !== void 0;
|
|
17268
|
+
/** The identifier, in small letters, of each SEQ field in the formatted elements */
|
|
17269
|
+
var identifiersIn = (element) => {
|
|
17270
|
+
if (typeof element !== "object" || element === null) return [];
|
|
17271
|
+
if (Array.isArray(element)) return element.flatMap(identifiersIn);
|
|
17272
|
+
return Object.entries(element).flatMap(([name, content]) => {
|
|
17273
|
+
return [...(name === "w:instrText" && Array.isArray(content) ? content : name === "_attr" ? [content["w:instr"]] : []).flatMap((instruction) => {
|
|
17274
|
+
const field = typeof instruction === "string" ? sequenceFieldOf(instruction) : void 0;
|
|
17275
|
+
return (field === null || field === void 0 ? void 0 : field.identifier) === void 0 ? [] : [field.identifier.toLowerCase()];
|
|
17276
|
+
}), ...identifiersIn(content)];
|
|
17277
|
+
});
|
|
17278
|
+
};
|
|
17279
|
+
/** The identifiers, in small letters, of the SEQ fields in the document's comments, whose count in Word isn't known */
|
|
17280
|
+
var identifiersInCommentsOf = (context) => {
|
|
17281
|
+
var _context$file;
|
|
17282
|
+
const comments = (_context$file = context.file) === null || _context$file === void 0 ? void 0 : _context$file.Comments;
|
|
17283
|
+
if (!comments) return /* @__PURE__ */ new Set();
|
|
17284
|
+
const wrapper = {
|
|
17285
|
+
View: comments,
|
|
17286
|
+
Relationships: comments.Relationships
|
|
17287
|
+
};
|
|
17288
|
+
return new Set(identifiersIn(comments.prepForXml(_objectSpread2(_objectSpread2({}, context), {}, {
|
|
17289
|
+
viewWrapper: wrapper,
|
|
17290
|
+
stack: []
|
|
17291
|
+
}))));
|
|
17292
|
+
};
|
|
17293
|
+
/** Counts the SEQ fields of a document's body, in order, as Word counts them */
|
|
17294
|
+
var sequenceNumbering = (context) => {
|
|
17295
|
+
const levelOf = headingLevels(context);
|
|
17296
|
+
const numbers = /* @__PURE__ */ new Map();
|
|
17297
|
+
const counted = /* @__PURE__ */ new Map();
|
|
17298
|
+
const headingsAt = [];
|
|
17299
|
+
let unclearAt = -1;
|
|
17300
|
+
let paragraph = -1;
|
|
17301
|
+
let unknown;
|
|
17302
|
+
/**
|
|
17303
|
+
* The number of a field that starts the count again after headings of a level or a higher one (`\s`): the number of
|
|
17304
|
+
* fields of its identifier since the last of them, with it, as Word counts them. It isn't known when a paragraph
|
|
17305
|
+
* whose level isn't clear came after that heading, or a field since it whose number didn't follow as the next one's
|
|
17306
|
+
*/
|
|
17307
|
+
const afterHeading = (key, level) => {
|
|
17308
|
+
var _counted$get;
|
|
17309
|
+
const headingAt = Math.max(-1, ...headingsAt.slice(1, level + 1).filter((at) => at !== void 0));
|
|
17310
|
+
const since = ((_counted$get = counted.get(key)) !== null && _counted$get !== void 0 ? _counted$get : []).filter((field) => field.paragraph >= headingAt);
|
|
17311
|
+
const followed = since.every(({ step }) => (step === null || step === void 0 ? void 0 : step.type) === "next" || (step === null || step === void 0 ? void 0 : step.type) === "heading" && step.level === level);
|
|
17312
|
+
if (unclearAt > headingAt || !followed) return;
|
|
17313
|
+
return since.length + 1;
|
|
17314
|
+
};
|
|
17315
|
+
return {
|
|
17316
|
+
startParagraph: (element) => {
|
|
17317
|
+
paragraph++;
|
|
17318
|
+
const level = levelOf(element);
|
|
17319
|
+
if (level === "unclear") unclearAt = paragraph;
|
|
17320
|
+
else if (level !== void 0) headingsAt[level] = paragraph;
|
|
17321
|
+
},
|
|
17322
|
+
numberOf: (instruction, place) => {
|
|
17323
|
+
var _unknown, _counted$get2, _numberWriterOf;
|
|
17324
|
+
const { identifier, sequence } = sequenceFieldOf(instruction);
|
|
17325
|
+
if (identifier === void 0 || place === "fallback") return;
|
|
17326
|
+
(_unknown = unknown) !== null && _unknown !== void 0 || (unknown = identifiersInCommentsOf(context));
|
|
17327
|
+
const key = identifier.toLowerCase();
|
|
17328
|
+
if ((sequence === null || sequence === void 0 ? void 0 : sequence.step.type) === "bookmark" && place === "counted" && !unknown.has(key)) return;
|
|
17329
|
+
const before = numbers.has(key) ? numbers.get(key) : 0;
|
|
17330
|
+
const step = unknown.has(key) || place === "deleted" ? void 0 : sequence === null || sequence === void 0 ? void 0 : sequence.step;
|
|
17331
|
+
const value = (step === null || step === void 0 ? void 0 : step.type) === "reset" ? step.to : (step === null || step === void 0 ? void 0 : step.type) === "repeat" ? before : (step === null || step === void 0 ? void 0 : step.type) === "heading" ? afterHeading(key, step.level) : (step === null || step === void 0 ? void 0 : step.type) === "next" && before !== void 0 ? before + 1 : void 0;
|
|
17332
|
+
numbers.set(key, value);
|
|
17333
|
+
counted.set(key, [...(_counted$get2 = counted.get(key)) !== null && _counted$get2 !== void 0 ? _counted$get2 : [], _objectSpread2({ paragraph }, value === void 0 ? {} : { step })]);
|
|
17334
|
+
return value === void 0 || sequence === void 0 ? void 0 : sequence.hidden ? "" : (_numberWriterOf = numberWriterOf(sequence.format)) === null || _numberWriterOf === void 0 ? void 0 : _numberWriterOf(value);
|
|
17335
|
+
}
|
|
17336
|
+
};
|
|
17337
|
+
};
|
|
17338
|
+
//#endregion
|
|
17339
|
+
//#region src/file/document/body/page-numbers.ts
|
|
17340
|
+
/**
|
|
17341
|
+
* Page numbers written into the fields of a document that show them, when it is written, from an estimate of its pages.
|
|
17342
|
+
*
|
|
17343
|
+
* A page reference is a PAGEREF field, such as the page number of an entry in a table of contents, and the numbers of
|
|
17344
|
+
* pages of the document and of a section are NUMPAGES and SECTIONPAGES fields. Word works their results out when it
|
|
17345
|
+
* updates the fields, or lays the pages out, and until then, and in applications that don't, the fields show the results
|
|
17346
|
+
* they were written with. `docx` doesn't lay out pages, so it writes the results empty, unless the document is given a
|
|
17347
|
+
* {@link PageNumberEstimator}, such as `estimatePageNumbers` from `docx/layout`. Then, once the body is written, each of
|
|
17348
|
+
* those fields in the body, and then in the headers and footers, is given the number the estimator worked out.
|
|
17349
|
+
*
|
|
17350
|
+
* Page references and tables of contents are written dirty, so Word updates them when it opens the document, and asks
|
|
17351
|
+
* "This document contains fields that may refer to other files. Do you want to update the fields in this document?".
|
|
17352
|
+
* When the document is given page numbers, they are written clean, so Word shows them as they are and doesn't ask. A
|
|
17353
|
+
* page number the estimator didn't work out is left blank, until the fields are updated. So are SEQ fields, the numbers
|
|
17354
|
+
* of captions, which are given their numbers then too.
|
|
17355
|
+
*
|
|
17356
|
+
* @module
|
|
17357
|
+
*/
|
|
17358
|
+
var nameOf$1 = (element) => {
|
|
17359
|
+
const name = typeof element === "object" && element !== null && !Array.isArray(element) ? Object.keys(element)[0] : void 0;
|
|
17360
|
+
return name === "_attr" ? void 0 : name;
|
|
17361
|
+
};
|
|
17362
|
+
var textElement = (text) => ({ "w:t": [{ _attr: { "xml:space": "preserve" } }, text] });
|
|
17363
|
+
/** The elements docx formats to write a document */
|
|
17364
|
+
var FORMATTED = {
|
|
17365
|
+
nameOf: nameOf$1,
|
|
17366
|
+
contentOf: (element) => {
|
|
17367
|
+
const content = element[nameOf$1(element)];
|
|
17368
|
+
return Array.isArray(content) ? content : void 0;
|
|
17369
|
+
},
|
|
17370
|
+
attributeOf: (element, attribute) => {
|
|
17371
|
+
var _holder$_attr;
|
|
17372
|
+
const content = element[nameOf$1(element)];
|
|
17373
|
+
const holder = Array.isArray(content) ? content.find((child) => typeof child === "object" && child !== null && "_attr" in child) : content;
|
|
17374
|
+
return holder === null || holder === void 0 || (_holder$_attr = holder._attr) === null || _holder$_attr === void 0 ? void 0 : _holder$_attr[attribute];
|
|
17375
|
+
},
|
|
17376
|
+
textOf: (element) => FORMATTED.contentOf(element).filter((part) => typeof part === "string").join(""),
|
|
17377
|
+
textElement,
|
|
17378
|
+
writeClean: (begin) => {
|
|
17379
|
+
if (isDirtyWithoutPageNumbers(begin)) {
|
|
17380
|
+
const attributes = begin["w:fldChar"]._attr;
|
|
17381
|
+
begin["w:fldChar"] = { _attr: Object.fromEntries(Object.entries(attributes).filter(([key]) => key !== "w:dirty")) };
|
|
17382
|
+
}
|
|
17383
|
+
},
|
|
17384
|
+
setSimpleFieldResult: (element, text) => {
|
|
17385
|
+
const content = element["w:fldSimple"];
|
|
17386
|
+
element["w:fldSimple"] = [...(Array.isArray(content) ? content : [content]).filter((child) => typeof child === "object" && child !== null && "_attr" in child), { "w:r": [textElement(text)] }];
|
|
17387
|
+
}
|
|
17388
|
+
};
|
|
17389
|
+
/** The estimate of each document's pages, and the numbers of pages its headers and footers show, once its body is written */
|
|
17390
|
+
var estimates = /* @__PURE__ */ new WeakMap();
|
|
17391
|
+
/**
|
|
17392
|
+
* Writes the numbers of the SEQ fields of a formatted body into them, counted as Word counts them (see
|
|
17393
|
+
* {@link sequenceNumbering}), and writes them clean, whether or not their numbers were worked out. It is done after its
|
|
17394
|
+
* tables of contents are filled in from its headings, as Word leaves a heading's SEQ number out of its entry.
|
|
17395
|
+
*/
|
|
17396
|
+
var fillSequenceNumbers = (body, context) => {
|
|
17397
|
+
const { startParagraph, numberOf } = sequenceNumbering(context);
|
|
17398
|
+
fillSequenceFields(FORMATTED, body, {
|
|
17399
|
+
beforeParagraph: (paragraph) => startParagraph(paragraph),
|
|
17400
|
+
resultOf: (instruction, within) => isSequenceField(instruction) ? numberOf(instruction, within) : void 0
|
|
17401
|
+
});
|
|
17402
|
+
};
|
|
17403
|
+
/**
|
|
17404
|
+
* Writes the page numbers the estimator works out into the fields of a formatted body that show them: the PAGEREF fields
|
|
17405
|
+
* in its tables of contents and elsewhere, those with `\p` and in number formats of their own, and its NUMPAGES and
|
|
17406
|
+
* SECTIONPAGES fields. A field whose number the estimator didn't work out is left as it is. Page references and tables
|
|
17407
|
+
* of contents are written clean, whether or not their numbers were worked out. The estimate is kept for the document's
|
|
17408
|
+
* headers and footers.
|
|
17409
|
+
*/
|
|
17410
|
+
var fillPageNumbers = (body, context, estimator) => {
|
|
17411
|
+
const estimate = estimator(body, context);
|
|
17412
|
+
const partPageCounts = fillBodyFields(FORMATTED, body, estimate, { blank: false });
|
|
17413
|
+
if (context.file) estimates.set(context.file, {
|
|
17414
|
+
estimate,
|
|
17415
|
+
partPageCounts
|
|
17416
|
+
});
|
|
17417
|
+
};
|
|
17418
|
+
/**
|
|
17419
|
+
* Writes the page numbers worked out for the document a header, footer, footnote, endnote or comment is in into the
|
|
17420
|
+
* fields of the formatted part that show them, once the document's body is written. Its page references and SEQ fields
|
|
17421
|
+
* are written clean, and its SEQ fields are left blank: Word writes them as an error, "Error! Main Document Only.".
|
|
17422
|
+
*
|
|
17423
|
+
* @param part - The formatted part, if it has anything to write
|
|
17424
|
+
* @param context - The context it was formatted in, with the document it is in
|
|
17425
|
+
* @param referenceId - The number of the relationship to a header or footer. The SECTIONPAGES fields of the other parts
|
|
17426
|
+
* are left as they are
|
|
17427
|
+
*/
|
|
17428
|
+
var fillPartPageNumbers = (part, context, referenceId) => {
|
|
17429
|
+
const written = context.file && estimates.get(context.file);
|
|
17430
|
+
if (!part || !written) return;
|
|
17431
|
+
const sectionPageCount = referenceId === void 0 ? void 0 : written.partPageCounts.get(`rId${referenceId}`);
|
|
17432
|
+
const notes = "w:footnotes" in part || "w:endnotes" in part;
|
|
17433
|
+
fillPartFields(FORMATTED, part, written.estimate, {
|
|
17434
|
+
blank: false,
|
|
17435
|
+
sectionPageCount,
|
|
17436
|
+
notes
|
|
17437
|
+
});
|
|
17438
|
+
};
|
|
17439
|
+
//#endregion
|
|
16342
17440
|
//#region src/file/relationships/attributes.ts
|
|
16343
17441
|
/**
|
|
16344
17442
|
* Attributes for the Relationships element.
|
|
@@ -16388,7 +17486,7 @@ var RelationshipsAttributes = class extends XmlAttributeComponent {
|
|
|
16388
17486
|
* );
|
|
16389
17487
|
* ```
|
|
16390
17488
|
*/
|
|
16391
|
-
var Relationships = class extends XmlComponent {
|
|
17489
|
+
var Relationships = class Relationships extends XmlComponent {
|
|
16392
17490
|
constructor() {
|
|
16393
17491
|
super("Relationships");
|
|
16394
17492
|
this.root.push(new RelationshipsAttributes({ xmlns: "http://schemas.openxmlformats.org/package/2006/relationships" }));
|
|
@@ -16405,6 +17503,20 @@ var Relationships = class extends XmlComponent {
|
|
|
16405
17503
|
this.root.push(createRelationship(`rId${id}`, type, target, targetMode));
|
|
16406
17504
|
}
|
|
16407
17505
|
/**
|
|
17506
|
+
* Creates a copy of the relationships given. Relationships added to the copy aren't added to them, so the compiler
|
|
17507
|
+
* adds the ones it writes for a part, such as to its images, to a copy, and packing a document again doesn't add
|
|
17508
|
+
* them a second time.
|
|
17509
|
+
*
|
|
17510
|
+
* Static, as `IContext` is public and has `Relationships`, so a new instance member would change the public API.
|
|
17511
|
+
*
|
|
17512
|
+
* @param relationships - The relationships to copy
|
|
17513
|
+
*/
|
|
17514
|
+
static copy(relationships) {
|
|
17515
|
+
const copy = new Relationships();
|
|
17516
|
+
copy.root.push(...relationships.root.slice(1));
|
|
17517
|
+
return copy;
|
|
17518
|
+
}
|
|
17519
|
+
/**
|
|
16408
17520
|
* Gets the count of relationships in this collection.
|
|
16409
17521
|
* Excludes the attributes element from the count.
|
|
16410
17522
|
*/
|
|
@@ -16415,6 +17527,17 @@ var Relationships = class extends XmlComponent {
|
|
|
16415
17527
|
//#endregion
|
|
16416
17528
|
//#region src/file/paragraph/run/comment-run.ts
|
|
16417
17529
|
/**
|
|
17530
|
+
* Comment module for WordprocessingML documents.
|
|
17531
|
+
*
|
|
17532
|
+
* This module provides support for comments (annotations) in documents. Comments
|
|
17533
|
+
* consist of comment ranges (start/end markers), comment references, and the
|
|
17534
|
+
* actual comment content.
|
|
17535
|
+
*
|
|
17536
|
+
* Reference: http://officeopenxml.com/WPrun.php
|
|
17537
|
+
*
|
|
17538
|
+
* @module
|
|
17539
|
+
*/
|
|
17540
|
+
/**
|
|
16418
17541
|
* @internal
|
|
16419
17542
|
*/
|
|
16420
17543
|
var CommentAttributes = class extends XmlAttributeComponent {
|
|
@@ -16444,6 +17567,7 @@ var RootCommentsAttributes = class extends XmlAttributeComponent {
|
|
|
16444
17567
|
constructor(..._args3) {
|
|
16445
17568
|
super(..._args3);
|
|
16446
17569
|
_defineProperty(this, "xmlKeys", {
|
|
17570
|
+
"xmlns:wpc": "xmlns:wpc",
|
|
16447
17571
|
"xmlns:cx": "xmlns:cx",
|
|
16448
17572
|
"xmlns:cx1": "xmlns:cx1",
|
|
16449
17573
|
"xmlns:cx2": "xmlns:cx2",
|
|
@@ -16684,6 +17808,7 @@ var Comments = class extends XmlComponent {
|
|
|
16684
17808
|
_defineProperty(this, "isEmpty", void 0);
|
|
16685
17809
|
this.isEmpty = children.length === 0;
|
|
16686
17810
|
this.root.push(new RootCommentsAttributes({
|
|
17811
|
+
"xmlns:wpc": "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
|
|
16687
17812
|
"xmlns:cx": "http://schemas.microsoft.com/office/drawing/2014/chartex",
|
|
16688
17813
|
"xmlns:cx1": "http://schemas.microsoft.com/office/drawing/2015/9/8/chartex",
|
|
16689
17814
|
"xmlns:cx2": "http://schemas.microsoft.com/office/drawing/2015/10/21/chartex",
|
|
@@ -16752,6 +17877,15 @@ var Comments = class extends XmlComponent {
|
|
|
16752
17877
|
get IsEmpty() {
|
|
16753
17878
|
return this.isEmpty;
|
|
16754
17879
|
}
|
|
17880
|
+
/**
|
|
17881
|
+
* Formats the comments, with the page numbers worked out for their document written into their fields, when the
|
|
17882
|
+
* document's body is written with an estimate of its pages.
|
|
17883
|
+
*/
|
|
17884
|
+
prepForXml(context) {
|
|
17885
|
+
const xml = super.prepForXml(context);
|
|
17886
|
+
fillPartPageNumbers(xml, context);
|
|
17887
|
+
return xml;
|
|
17888
|
+
}
|
|
16755
17889
|
};
|
|
16756
17890
|
//#endregion
|
|
16757
17891
|
//#region src/file/paragraph/run/comments-extended.ts
|
|
@@ -18050,7 +19184,7 @@ var BookmarkEndAttributes = class extends XmlAttributeComponent {
|
|
|
18050
19184
|
* });
|
|
18051
19185
|
* ```
|
|
18052
19186
|
*/
|
|
18053
|
-
var Bookmark = class {
|
|
19187
|
+
var Bookmark = class Bookmark {
|
|
18054
19188
|
constructor(options) {
|
|
18055
19189
|
_defineProperty(this, "start", void 0);
|
|
18056
19190
|
_defineProperty(this, "children", void 0);
|
|
@@ -18060,6 +19194,19 @@ var Bookmark = class {
|
|
|
18060
19194
|
this.children = options.children;
|
|
18061
19195
|
this.end = new BookmarkEnd(linkId);
|
|
18062
19196
|
}
|
|
19197
|
+
/**
|
|
19198
|
+
* The components written in this bookmark's place: its start, its children and its end. A bookmark in its
|
|
19199
|
+
* children is written the same way, so one bookmark can hold another.
|
|
19200
|
+
*
|
|
19201
|
+
* @internal
|
|
19202
|
+
*/
|
|
19203
|
+
get writtenAs() {
|
|
19204
|
+
return [
|
|
19205
|
+
this.start,
|
|
19206
|
+
...this.children.flatMap((child) => child instanceof Bookmark ? child.writtenAs : [child]),
|
|
19207
|
+
this.end
|
|
19208
|
+
];
|
|
19209
|
+
}
|
|
18063
19210
|
};
|
|
18064
19211
|
/**
|
|
18065
19212
|
* Represents the start marker of a bookmark range.
|
|
@@ -18067,6 +19214,10 @@ var Bookmark = class {
|
|
|
18067
19214
|
* This element marks the beginning of a bookmarked region in the document.
|
|
18068
19215
|
* It must be paired with a corresponding BookmarkEnd element with the same id.
|
|
18069
19216
|
*
|
|
19217
|
+
* The id must be unique in the document. `Bookmark` takes its ids from
|
|
19218
|
+
* `bookmarkUniqueNumericId`, so take this one from it too, or it can be the
|
|
19219
|
+
* same as a `Bookmark`'s.
|
|
19220
|
+
*
|
|
18070
19221
|
* Reference: http://officeopenxml.com/WPbookmark.php
|
|
18071
19222
|
*
|
|
18072
19223
|
* ## XSD Schema
|
|
@@ -18084,7 +19235,10 @@ var Bookmark = class {
|
|
|
18084
19235
|
*
|
|
18085
19236
|
* @example
|
|
18086
19237
|
* ```typescript
|
|
18087
|
-
*
|
|
19238
|
+
* // A bookmark across two paragraphs
|
|
19239
|
+
* const id = bookmarkUniqueNumericId();
|
|
19240
|
+
* new Paragraph({ children: [new BookmarkStart("myBookmark", id), new TextRun("First")] });
|
|
19241
|
+
* new Paragraph({ children: [new TextRun("Last"), new BookmarkEnd(id)] });
|
|
18088
19242
|
* ```
|
|
18089
19243
|
*/
|
|
18090
19244
|
var BookmarkStart = class extends XmlComponent {
|
|
@@ -18101,7 +19255,8 @@ var BookmarkStart = class extends XmlComponent {
|
|
|
18101
19255
|
* Represents the end marker of a bookmark range.
|
|
18102
19256
|
*
|
|
18103
19257
|
* This element marks the end of a bookmarked region in the document.
|
|
18104
|
-
* It must be paired with a corresponding BookmarkStart element with the same id
|
|
19258
|
+
* It must be paired with a corresponding BookmarkStart element with the same id,
|
|
19259
|
+
* taken from `bookmarkUniqueNumericId` (see `BookmarkStart`).
|
|
18105
19260
|
*
|
|
18106
19261
|
* Reference: http://officeopenxml.com/WPbookmark.php
|
|
18107
19262
|
*
|
|
@@ -18120,7 +19275,9 @@ var BookmarkStart = class extends XmlComponent {
|
|
|
18120
19275
|
*
|
|
18121
19276
|
* @example
|
|
18122
19277
|
* ```typescript
|
|
18123
|
-
*
|
|
19278
|
+
* const id = bookmarkUniqueNumericId();
|
|
19279
|
+
* new BookmarkStart("myBookmark", id);
|
|
19280
|
+
* new BookmarkEnd(id);
|
|
18124
19281
|
* ```
|
|
18125
19282
|
*/
|
|
18126
19283
|
var BookmarkEnd = class extends XmlComponent {
|
|
@@ -18294,6 +19451,10 @@ var PageReferenceFieldInstruction = class extends XmlComponent {
|
|
|
18294
19451
|
* The PAGEREF field displays the page number of the page containing
|
|
18295
19452
|
* the specified bookmark, useful for cross-references like "see page 5".
|
|
18296
19453
|
*
|
|
19454
|
+
* It is written dirty, so Word fills in the page number when it opens the document, after asking to. When the
|
|
19455
|
+
* document is given `pageNumbers`, it is written clean, with the number they work out, or blank when they couldn't,
|
|
19456
|
+
* and Word doesn't ask.
|
|
19457
|
+
*
|
|
18297
19458
|
* @publicApi
|
|
18298
19459
|
*
|
|
18299
19460
|
* @example
|
|
@@ -18314,8 +19475,9 @@ var PageReferenceFieldInstruction = class extends XmlComponent {
|
|
|
18314
19475
|
var PageReference = class extends Run {
|
|
18315
19476
|
constructor(bookmarkId, options = {}) {
|
|
18316
19477
|
super({ children: [
|
|
18317
|
-
|
|
19478
|
+
createBeginDirtyWithoutPageNumbers(),
|
|
18318
19479
|
new PageReferenceFieldInstruction(bookmarkId, options),
|
|
19480
|
+
createSeparate(),
|
|
18319
19481
|
createEnd()
|
|
18320
19482
|
] });
|
|
18321
19483
|
}
|
|
@@ -18830,17 +19992,18 @@ var createFrameProperties = (options) => {
|
|
|
18830
19992
|
//#endregion
|
|
18831
19993
|
//#region src/file/paragraph/properties.ts
|
|
18832
19994
|
/**
|
|
18833
|
-
*
|
|
18834
|
-
*
|
|
18835
|
-
* This module provides the paragraph properties (pPr) element which specifies
|
|
18836
|
-
* the formatting applied to a paragraph.
|
|
18837
|
-
*
|
|
18838
|
-
* Reference: http://officeopenxml.com/WPparagraphProperties.php
|
|
18839
|
-
*
|
|
18840
|
-
* @see https://c-rex.net/projects/samples/ooxml/e1/Part4/OOXML_P4_DOCX_suppressLineNumbers_topic_ID0ECJAO.html
|
|
19995
|
+
* The alignment to write for each side of the page in a right-to-left paragraph.
|
|
18841
19996
|
*
|
|
18842
|
-
*
|
|
19997
|
+
* Word and LibreOffice read `w:jc` `left` and `right` as the start and end of the paragraph, the same as
|
|
19998
|
+
* `start` and `end` (ISO/IEC 29500-4 maps the transitional `left` and `right` onto the strict `start` and `end`,
|
|
19999
|
+
* and [MS-OE376] 2.3.1.13 notes the same for Word 2007). So in a `w:bidi` paragraph `left` lands on the right
|
|
20000
|
+
* side of the page. Swapping keeps `AlignmentType.LEFT` and `AlignmentType.RIGHT` on the side of the page they name.
|
|
20001
|
+
* `left` and `right` are written rather than `end` and `start` because Word 2007 does not know `start` and `end`.
|
|
18843
20002
|
*/
|
|
20003
|
+
var RIGHT_TO_LEFT_ALIGNMENTS = {
|
|
20004
|
+
left: "right",
|
|
20005
|
+
right: "left"
|
|
20006
|
+
};
|
|
18844
20007
|
/**
|
|
18845
20008
|
* Represents paragraph properties (pPr) in a WordprocessingML document.
|
|
18846
20009
|
*
|
|
@@ -19004,7 +20167,7 @@ var ParagraphProperties = class extends IgnoreIfEmptyXmlComponent {
|
|
|
19004
20167
|
if (options.spacing) this.push(createSpacing(options.spacing));
|
|
19005
20168
|
if (options.indent) this.push(createIndent(options.indent));
|
|
19006
20169
|
if (options.contextualSpacing !== void 0) this.push(new OnOffElement("w:contextualSpacing", options.contextualSpacing));
|
|
19007
|
-
if (options.alignment) this.push(createAlignment(options.alignment));
|
|
20170
|
+
if (options.alignment) this.push(createAlignment(options.bidirectional && RIGHT_TO_LEFT_ALIGNMENTS[options.alignment] || options.alignment));
|
|
19008
20171
|
if (options.outlineLevel !== void 0) this.push(createOutlineLevel(options.outlineLevel));
|
|
19009
20172
|
if (options.suppressLineNumbers !== void 0) this.push(new OnOffElement("w:suppressLineNumbers", options.suppressLineNumbers));
|
|
19010
20173
|
if (options.autoSpaceEastAsianText !== void 0) this.push(new OnOffElement("w:autoSpaceDN", options.autoSpaceEastAsianText));
|
|
@@ -19020,6 +20183,31 @@ var ParagraphProperties = class extends IgnoreIfEmptyXmlComponent {
|
|
|
19020
20183
|
this.root.push(item);
|
|
19021
20184
|
}
|
|
19022
20185
|
/**
|
|
20186
|
+
* Adds the section properties (`w:sectPr`) of the section this paragraph ends.
|
|
20187
|
+
*
|
|
20188
|
+
* They go after the paragraph's run properties and before its revision (`w:pPrChange`),
|
|
20189
|
+
* the order CT_PPr gives them.
|
|
20190
|
+
*
|
|
20191
|
+
* @param sectionProperties - The properties of the section the paragraph ends
|
|
20192
|
+
*/
|
|
20193
|
+
addSectionProperties(sectionProperties) {
|
|
20194
|
+
const revisionIndex = this.root.findIndex((item) => item instanceof ParagraphPropertiesChange);
|
|
20195
|
+
if (revisionIndex === -1) {
|
|
20196
|
+
this.root.push(sectionProperties);
|
|
20197
|
+
return;
|
|
20198
|
+
}
|
|
20199
|
+
this.root.splice(revisionIndex, 0, sectionProperties);
|
|
20200
|
+
}
|
|
20201
|
+
/**
|
|
20202
|
+
* Removes the section properties added with {@link addSectionProperties}.
|
|
20203
|
+
*
|
|
20204
|
+
* @param sectionProperties - The properties of the section to remove
|
|
20205
|
+
*/
|
|
20206
|
+
removeSectionProperties(sectionProperties) {
|
|
20207
|
+
const index = this.root.indexOf(sectionProperties);
|
|
20208
|
+
if (index !== -1) this.root.splice(index, 1);
|
|
20209
|
+
}
|
|
20210
|
+
/**
|
|
19023
20211
|
* Prepares the paragraph properties for XML serialization.
|
|
19024
20212
|
*
|
|
19025
20213
|
* This method creates concrete numbering instances for any numbering references
|
|
@@ -19047,13 +20235,6 @@ var ParagraphPropertiesChange = class extends XmlComponent {
|
|
|
19047
20235
|
//#endregion
|
|
19048
20236
|
//#region src/file/paragraph/paragraph.ts
|
|
19049
20237
|
/**
|
|
19050
|
-
* Paragraph module for WordprocessingML documents.
|
|
19051
|
-
*
|
|
19052
|
-
* Reference: http://officeopenxml.com/WPparagraph.php
|
|
19053
|
-
*
|
|
19054
|
-
* @module
|
|
19055
|
-
*/
|
|
19056
|
-
/**
|
|
19057
20238
|
* Represents a paragraph in a WordprocessingML document.
|
|
19058
20239
|
*
|
|
19059
20240
|
* A paragraph is the primary unit of block-level content in a document and can contain
|
|
@@ -19105,9 +20286,7 @@ var Paragraph = class extends FileChild {
|
|
|
19105
20286
|
if (options.text) this.root.push(new TextRun(options.text));
|
|
19106
20287
|
if (options.children) for (const child of options.children) {
|
|
19107
20288
|
if (child instanceof Bookmark) {
|
|
19108
|
-
this.root.push(child.
|
|
19109
|
-
for (const textRun of child.children) this.root.push(textRun);
|
|
19110
|
-
this.root.push(child.end);
|
|
20289
|
+
this.root.push(...child.writtenAs);
|
|
19111
20290
|
continue;
|
|
19112
20291
|
}
|
|
19113
20292
|
this.root.push(child);
|
|
@@ -19122,6 +20301,28 @@ var Paragraph = class extends FileChild {
|
|
|
19122
20301
|
}
|
|
19123
20302
|
return super.prepForXml(context);
|
|
19124
20303
|
}
|
|
20304
|
+
/**
|
|
20305
|
+
* Ends a section at this paragraph by adding the section's properties to the paragraph's properties,
|
|
20306
|
+
* as Word does with the last paragraph of each section but the last.
|
|
20307
|
+
*
|
|
20308
|
+
* The body adds them only while it is written and removes them afterwards with
|
|
20309
|
+
* {@link removeSectionProperties}, so the same paragraph can be used in other documents.
|
|
20310
|
+
*
|
|
20311
|
+
* @internal
|
|
20312
|
+
* @param sectionProperties - The properties of the section the paragraph ends
|
|
20313
|
+
*/
|
|
20314
|
+
addSectionProperties(sectionProperties) {
|
|
20315
|
+
this.properties.addSectionProperties(sectionProperties);
|
|
20316
|
+
}
|
|
20317
|
+
/**
|
|
20318
|
+
* Removes the section properties added with {@link addSectionProperties}.
|
|
20319
|
+
*
|
|
20320
|
+
* @internal
|
|
20321
|
+
* @param sectionProperties - The properties of the section to remove
|
|
20322
|
+
*/
|
|
20323
|
+
removeSectionProperties(sectionProperties) {
|
|
20324
|
+
this.properties.removeSectionProperties(sectionProperties);
|
|
20325
|
+
}
|
|
19125
20326
|
addRunToFront(run) {
|
|
19126
20327
|
this.root.splice(1, 0, run);
|
|
19127
20328
|
return this;
|
|
@@ -19214,7 +20415,7 @@ var MathText = class extends XmlComponent {
|
|
|
19214
20415
|
}
|
|
19215
20416
|
};
|
|
19216
20417
|
//#endregion
|
|
19217
|
-
//#region \0@oxc-project+runtime@0.
|
|
20418
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/objectWithoutPropertiesLoose.js
|
|
19218
20419
|
function _objectWithoutPropertiesLoose(r, e) {
|
|
19219
20420
|
if (null == r) return {};
|
|
19220
20421
|
var t = {};
|
|
@@ -19225,7 +20426,7 @@ function _objectWithoutPropertiesLoose(r, e) {
|
|
|
19225
20426
|
return t;
|
|
19226
20427
|
}
|
|
19227
20428
|
//#endregion
|
|
19228
|
-
//#region \0@oxc-project+runtime@0.
|
|
20429
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/objectWithoutProperties.js
|
|
19229
20430
|
function _objectWithoutProperties(e, t) {
|
|
19230
20431
|
if (null == e) return {};
|
|
19231
20432
|
var o, r, i = _objectWithoutPropertiesLoose(e, t);
|
|
@@ -21178,6 +22379,168 @@ var createLineNumberType = ({ countBy, start, restart, distance }) => new Builde
|
|
|
21178
22379
|
}
|
|
21179
22380
|
});
|
|
21180
22381
|
//#endregion
|
|
22382
|
+
//#region src/file/document/body/section-properties/properties/note-properties.ts
|
|
22383
|
+
/**
|
|
22384
|
+
* Where the footnotes of a section are placed.
|
|
22385
|
+
*
|
|
22386
|
+
* ## XSD Schema
|
|
22387
|
+
* ```xml
|
|
22388
|
+
* <xsd:simpleType name="ST_FtnPos">
|
|
22389
|
+
* <xsd:restriction base="xsd:string">
|
|
22390
|
+
* <xsd:enumeration value="pageBottom"/>
|
|
22391
|
+
* <xsd:enumeration value="beneathText"/>
|
|
22392
|
+
* <xsd:enumeration value="sectEnd"/>
|
|
22393
|
+
* <xsd:enumeration value="docEnd"/>
|
|
22394
|
+
* </xsd:restriction>
|
|
22395
|
+
* </xsd:simpleType>
|
|
22396
|
+
* ```
|
|
22397
|
+
*
|
|
22398
|
+
* @publicApi
|
|
22399
|
+
*/
|
|
22400
|
+
var FootnotePosition = {
|
|
22401
|
+
/** At the bottom of each page */
|
|
22402
|
+
PAGE_BOTTOM: "pageBottom",
|
|
22403
|
+
/** Directly below the text on each page */
|
|
22404
|
+
BENEATH_TEXT: "beneathText",
|
|
22405
|
+
/** At the end of the section */
|
|
22406
|
+
SECTION_END: "sectEnd",
|
|
22407
|
+
/** At the end of the document */
|
|
22408
|
+
DOCUMENT_END: "docEnd"
|
|
22409
|
+
};
|
|
22410
|
+
/**
|
|
22411
|
+
* Where the endnotes of a section are placed.
|
|
22412
|
+
*
|
|
22413
|
+
* ## XSD Schema
|
|
22414
|
+
* ```xml
|
|
22415
|
+
* <xsd:simpleType name="ST_EdnPos">
|
|
22416
|
+
* <xsd:restriction base="xsd:string">
|
|
22417
|
+
* <xsd:enumeration value="sectEnd"/>
|
|
22418
|
+
* <xsd:enumeration value="docEnd"/>
|
|
22419
|
+
* </xsd:restriction>
|
|
22420
|
+
* </xsd:simpleType>
|
|
22421
|
+
* ```
|
|
22422
|
+
*
|
|
22423
|
+
* @publicApi
|
|
22424
|
+
*/
|
|
22425
|
+
var EndnotePosition = {
|
|
22426
|
+
/** At the end of the section */
|
|
22427
|
+
SECTION_END: "sectEnd",
|
|
22428
|
+
/** At the end of the document */
|
|
22429
|
+
DOCUMENT_END: "docEnd"
|
|
22430
|
+
};
|
|
22431
|
+
/**
|
|
22432
|
+
* When the footnote or endnote numbering restarts.
|
|
22433
|
+
*
|
|
22434
|
+
* ## XSD Schema
|
|
22435
|
+
* ```xml
|
|
22436
|
+
* <xsd:simpleType name="ST_RestartNumber">
|
|
22437
|
+
* <xsd:restriction base="xsd:string">
|
|
22438
|
+
* <xsd:enumeration value="continuous"/>
|
|
22439
|
+
* <xsd:enumeration value="eachSect"/>
|
|
22440
|
+
* <xsd:enumeration value="eachPage"/>
|
|
22441
|
+
* </xsd:restriction>
|
|
22442
|
+
* </xsd:simpleType>
|
|
22443
|
+
* ```
|
|
22444
|
+
*
|
|
22445
|
+
* @publicApi
|
|
22446
|
+
*/
|
|
22447
|
+
var NoteNumberRestart = {
|
|
22448
|
+
/** Numbering never restarts */
|
|
22449
|
+
CONTINUOUS: "continuous",
|
|
22450
|
+
/** Numbering restarts in each section */
|
|
22451
|
+
EACH_SECTION: "eachSect",
|
|
22452
|
+
/** Numbering restarts on each page */
|
|
22453
|
+
EACH_PAGE: "eachPage"
|
|
22454
|
+
};
|
|
22455
|
+
var createNoteProperties = ({ name, position, numberFormat, start, restart }) => new BuilderElement({
|
|
22456
|
+
name,
|
|
22457
|
+
children: [
|
|
22458
|
+
...position === void 0 ? [] : [new BuilderElement({
|
|
22459
|
+
name: "w:pos",
|
|
22460
|
+
attributes: { val: {
|
|
22461
|
+
key: "w:val",
|
|
22462
|
+
value: position
|
|
22463
|
+
} }
|
|
22464
|
+
})],
|
|
22465
|
+
...numberFormat ? [new BuilderElement({
|
|
22466
|
+
name: "w:numFmt",
|
|
22467
|
+
attributes: {
|
|
22468
|
+
val: {
|
|
22469
|
+
key: "w:val",
|
|
22470
|
+
value: numberFormat.type
|
|
22471
|
+
},
|
|
22472
|
+
format: {
|
|
22473
|
+
key: "w:format",
|
|
22474
|
+
value: numberFormat.format
|
|
22475
|
+
}
|
|
22476
|
+
}
|
|
22477
|
+
})] : [],
|
|
22478
|
+
...start === void 0 ? [] : [new BuilderElement({
|
|
22479
|
+
name: "w:numStart",
|
|
22480
|
+
attributes: { val: {
|
|
22481
|
+
key: "w:val",
|
|
22482
|
+
value: decimalNumber(start)
|
|
22483
|
+
} }
|
|
22484
|
+
})],
|
|
22485
|
+
...restart === void 0 ? [] : [new BuilderElement({
|
|
22486
|
+
name: "w:numRestart",
|
|
22487
|
+
attributes: { val: {
|
|
22488
|
+
key: "w:val",
|
|
22489
|
+
value: restart
|
|
22490
|
+
} }
|
|
22491
|
+
})]
|
|
22492
|
+
]
|
|
22493
|
+
});
|
|
22494
|
+
/**
|
|
22495
|
+
* Creates the footnote properties (footnotePr) of a section.
|
|
22496
|
+
*
|
|
22497
|
+
* ## XSD Schema
|
|
22498
|
+
* ```xml
|
|
22499
|
+
* <xsd:complexType name="CT_FtnProps">
|
|
22500
|
+
* <xsd:sequence>
|
|
22501
|
+
* <xsd:element name="pos" type="CT_FtnPos" minOccurs="0"/>
|
|
22502
|
+
* <xsd:element name="numFmt" type="CT_NumFmt" minOccurs="0"/>
|
|
22503
|
+
* <xsd:group ref="EG_FtnEdnNumProps" minOccurs="0"/>
|
|
22504
|
+
* </xsd:sequence>
|
|
22505
|
+
* </xsd:complexType>
|
|
22506
|
+
* ```
|
|
22507
|
+
*
|
|
22508
|
+
* @example
|
|
22509
|
+
* ```typescript
|
|
22510
|
+
* // Footnotes at the end of the section, numbered a, b, c and restarting in each section
|
|
22511
|
+
* createFootnoteProperties({
|
|
22512
|
+
* position: FootnotePosition.SECTION_END,
|
|
22513
|
+
* numberFormat: { type: NumberFormat.LOWER_LETTER },
|
|
22514
|
+
* restart: NoteNumberRestart.EACH_SECTION,
|
|
22515
|
+
* });
|
|
22516
|
+
* ```
|
|
22517
|
+
*/
|
|
22518
|
+
var createFootnoteProperties = (options) => createNoteProperties(_objectSpread2({ name: "w:footnotePr" }, options));
|
|
22519
|
+
/**
|
|
22520
|
+
* Creates the endnote properties (endnotePr) of a section.
|
|
22521
|
+
*
|
|
22522
|
+
* ## XSD Schema
|
|
22523
|
+
* ```xml
|
|
22524
|
+
* <xsd:complexType name="CT_EdnProps">
|
|
22525
|
+
* <xsd:sequence>
|
|
22526
|
+
* <xsd:element name="pos" type="CT_EdnPos" minOccurs="0"/>
|
|
22527
|
+
* <xsd:element name="numFmt" type="CT_NumFmt" minOccurs="0"/>
|
|
22528
|
+
* <xsd:group ref="EG_FtnEdnNumProps" minOccurs="0"/>
|
|
22529
|
+
* </xsd:sequence>
|
|
22530
|
+
* </xsd:complexType>
|
|
22531
|
+
* ```
|
|
22532
|
+
*
|
|
22533
|
+
* @example
|
|
22534
|
+
* ```typescript
|
|
22535
|
+
* // Endnotes at the end of the document, numbered 001, 002, 003
|
|
22536
|
+
* createEndnoteProperties({
|
|
22537
|
+
* position: EndnotePosition.DOCUMENT_END,
|
|
22538
|
+
* numberFormat: { type: NumberFormat.CUSTOM, format: "001" },
|
|
22539
|
+
* });
|
|
22540
|
+
* ```
|
|
22541
|
+
*/
|
|
22542
|
+
var createEndnoteProperties = (options) => createNoteProperties(_objectSpread2({ name: "w:endnotePr" }, options));
|
|
22543
|
+
//#endregion
|
|
21181
22544
|
//#region src/file/document/body/section-properties/properties/page-borders.ts
|
|
21182
22545
|
/**
|
|
21183
22546
|
* Page borders module for WordprocessingML section properties.
|
|
@@ -21417,7 +22780,7 @@ var PageNumberSeparator = {
|
|
|
21417
22780
|
COLON: "colon",
|
|
21418
22781
|
/** Em dash separator (—) */
|
|
21419
22782
|
EM_DASH: "emDash",
|
|
21420
|
-
/** En dash separator (–) */
|
|
22783
|
+
/** En dash separator (–), written as `enDash` */
|
|
21421
22784
|
EN_DASH: "endash"
|
|
21422
22785
|
};
|
|
21423
22786
|
/**
|
|
@@ -21447,7 +22810,7 @@ var PageNumberSeparator = {
|
|
|
21447
22810
|
* });
|
|
21448
22811
|
* ```
|
|
21449
22812
|
*/
|
|
21450
|
-
var createPageNumberType = ({ start, formatType, separator }) => new BuilderElement({
|
|
22813
|
+
var createPageNumberType = ({ start, formatType, separator, chapterHeadingLevel }) => new BuilderElement({
|
|
21451
22814
|
name: "w:pgNumType",
|
|
21452
22815
|
attributes: {
|
|
21453
22816
|
start: {
|
|
@@ -21460,7 +22823,11 @@ var createPageNumberType = ({ start, formatType, separator }) => new BuilderElem
|
|
|
21460
22823
|
},
|
|
21461
22824
|
separator: {
|
|
21462
22825
|
key: "w:chapSep",
|
|
21463
|
-
value: separator
|
|
22826
|
+
value: separator === PageNumberSeparator.EN_DASH ? "enDash" : separator
|
|
22827
|
+
},
|
|
22828
|
+
chapterHeadingLevel: {
|
|
22829
|
+
key: "w:chapStyle",
|
|
22830
|
+
value: chapterHeadingLevel === void 0 ? void 0 : decimalNumber(chapterHeadingLevel)
|
|
21464
22831
|
}
|
|
21465
22832
|
}
|
|
21466
22833
|
});
|
|
@@ -21764,7 +23131,7 @@ var sectionPageSizeDefaults = {
|
|
|
21764
23131
|
* ```
|
|
21765
23132
|
*/
|
|
21766
23133
|
var SectionProperties = class SectionProperties extends XmlComponent {
|
|
21767
|
-
constructor({ page: { size: { width = sectionPageSizeDefaults.WIDTH, height = sectionPageSizeDefaults.HEIGHT, orientation = sectionPageSizeDefaults.ORIENTATION, code } = {}, margin: { top = sectionMarginDefaults.TOP, right = sectionMarginDefaults.RIGHT, bottom = sectionMarginDefaults.BOTTOM, left = sectionMarginDefaults.LEFT, header = sectionMarginDefaults.HEADER, footer = sectionMarginDefaults.FOOTER, gutter = sectionMarginDefaults.GUTTER } = {}, pageNumbers = {}, borders, textDirection } = {}, grid: { linePitch = 360, charSpace, type: gridType } = {}, headerWrapperGroup = {}, footerWrapperGroup = {}, lineNumbers, titlePage, verticalAlign, column, type, revision } = {}) {
|
|
23134
|
+
constructor({ page: { size: { width = sectionPageSizeDefaults.WIDTH, height = sectionPageSizeDefaults.HEIGHT, orientation = sectionPageSizeDefaults.ORIENTATION, code } = {}, margin: { top = sectionMarginDefaults.TOP, right = sectionMarginDefaults.RIGHT, bottom = sectionMarginDefaults.BOTTOM, left = sectionMarginDefaults.LEFT, header = sectionMarginDefaults.HEADER, footer = sectionMarginDefaults.FOOTER, gutter = sectionMarginDefaults.GUTTER } = {}, pageNumbers = {}, borders, textDirection } = {}, grid: { linePitch = 360, charSpace, type: gridType } = {}, headerWrapperGroup = {}, footerWrapperGroup = {}, lineNumbers, titlePage, verticalAlign, column, type, footnoteProperties, endnoteProperties, revision } = {}) {
|
|
21768
23135
|
super("w:sectPr");
|
|
21769
23136
|
_defineProperty(
|
|
21770
23137
|
this,
|
|
@@ -21787,6 +23154,8 @@ var SectionProperties = class SectionProperties extends XmlComponent {
|
|
|
21787
23154
|
});
|
|
21788
23155
|
this.addHeaderFooterGroup(HeaderFooterType.HEADER, headerWrapperGroup);
|
|
21789
23156
|
this.addHeaderFooterGroup(HeaderFooterType.FOOTER, footerWrapperGroup);
|
|
23157
|
+
if (footnoteProperties) this.root.push(createFootnoteProperties(footnoteProperties));
|
|
23158
|
+
if (endnoteProperties) this.root.push(createEndnoteProperties(endnoteProperties));
|
|
21790
23159
|
if (type) this.root.push(createSectionType(type));
|
|
21791
23160
|
this.root.push(createPageSize({
|
|
21792
23161
|
width,
|
|
@@ -21911,7 +23280,7 @@ var SectionPropertiesChange = class extends XmlComponent {
|
|
|
21911
23280
|
* ```
|
|
21912
23281
|
*/
|
|
21913
23282
|
var Body = class extends XmlComponent {
|
|
21914
|
-
constructor() {
|
|
23283
|
+
constructor({ pageNumbers } = {}) {
|
|
21915
23284
|
super("w:body");
|
|
21916
23285
|
_defineProperty(this, "sections", []);
|
|
21917
23286
|
_defineProperty(
|
|
@@ -21919,11 +23288,15 @@ var Body = class extends XmlComponent {
|
|
|
21919
23288
|
/**
|
|
21920
23289
|
* Section properties that were moved into a paragraph at the end of their section
|
|
21921
23290
|
* by {@link addSection}, keyed by that paragraph. Used to find the section that
|
|
21922
|
-
* governs a given child of the body
|
|
23291
|
+
* governs a given child of the body, and to write each section's properties into
|
|
23292
|
+
* its paragraph while the body is written.
|
|
21923
23293
|
*/
|
|
21924
23294
|
"sectionParagraphs",
|
|
21925
23295
|
/* @__PURE__ */ new Map()
|
|
21926
23296
|
);
|
|
23297
|
+
_defineProperty(this, "headingBookmarkIds", new HeadingBookmarkIds());
|
|
23298
|
+
_defineProperty(this, "pageNumbers", void 0);
|
|
23299
|
+
this.pageNumbers = pageNumbers;
|
|
21927
23300
|
}
|
|
21928
23301
|
/**
|
|
21929
23302
|
* Finds the section properties that govern a top-level child of the body.
|
|
@@ -21938,7 +23311,7 @@ var Body = class extends XmlComponent {
|
|
|
21938
23311
|
* @returns The governing section properties, or undefined if the body has no sections
|
|
21939
23312
|
*/
|
|
21940
23313
|
getSectionPropertiesFor(child) {
|
|
21941
|
-
const start = child ? this.root.indexOf(child)
|
|
23314
|
+
const start = child ? Math.max(this.root.indexOf(child), 0) : 0;
|
|
21942
23315
|
for (let i = start; i < this.root.length; i++) {
|
|
21943
23316
|
const component = this.root[i];
|
|
21944
23317
|
if (component instanceof SectionProperties) return component;
|
|
@@ -21950,8 +23323,10 @@ var Body = class extends XmlComponent {
|
|
|
21950
23323
|
/**
|
|
21951
23324
|
* Adds new section properties to the document body.
|
|
21952
23325
|
*
|
|
21953
|
-
* Creates a new section by moving the previous section's properties into
|
|
21954
|
-
*
|
|
23326
|
+
* Creates a new section by moving the previous section's properties into the last
|
|
23327
|
+
* paragraph of that section, and then adding the new section as the current section.
|
|
23328
|
+
* When that section doesn't end with a paragraph of its own (it ends with a table, or
|
|
23329
|
+
* it is empty), an empty paragraph is added to hold its properties.
|
|
21955
23330
|
*
|
|
21956
23331
|
* According to the OOXML specification:
|
|
21957
23332
|
* - Section properties for all sections except the last must be stored in a paragraph's
|
|
@@ -21962,16 +23337,24 @@ var Body = class extends XmlComponent {
|
|
|
21962
23337
|
*/
|
|
21963
23338
|
addSection(options) {
|
|
21964
23339
|
const currentSection = this.sections.pop();
|
|
21965
|
-
const
|
|
21966
|
-
this.
|
|
21967
|
-
|
|
23340
|
+
const lastParagraph = this.lastParagraphOfSection();
|
|
23341
|
+
if (currentSection && lastParagraph) this.sectionParagraphs.set(lastParagraph, currentSection);
|
|
23342
|
+
else {
|
|
23343
|
+
const sectionParagraph = this.createSectionParagraph();
|
|
23344
|
+
this.root.push(sectionParagraph);
|
|
23345
|
+
if (currentSection) this.sectionParagraphs.set(sectionParagraph, currentSection);
|
|
23346
|
+
}
|
|
21968
23347
|
this.sections.push(new SectionProperties(options));
|
|
21969
23348
|
}
|
|
21970
23349
|
/**
|
|
21971
23350
|
* Prepares the body element for XML serialization.
|
|
21972
23351
|
*
|
|
21973
23352
|
* Ensures that the last section's properties are placed as a direct child of the body
|
|
21974
|
-
* element, as required by the OOXML specification.
|
|
23353
|
+
* element, as required by the OOXML specification. Once the body is written, its tables
|
|
23354
|
+
* of contents are filled in from its headings, and, when the body has a page number
|
|
23355
|
+
* estimator, its page references are given their page numbers. Its SEQ fields are given
|
|
23356
|
+
* their numbers after the tables of contents are filled in, as Word leaves a heading's SEQ
|
|
23357
|
+
* number out of its entry.
|
|
21975
23358
|
*
|
|
21976
23359
|
* @param context - The XML serialization context
|
|
21977
23360
|
* @returns The prepared XML object or undefined
|
|
@@ -21981,7 +23364,19 @@ var Body = class extends XmlComponent {
|
|
|
21981
23364
|
this.root.splice(0, 1);
|
|
21982
23365
|
this.root.push(this.sections.pop());
|
|
21983
23366
|
}
|
|
21984
|
-
|
|
23367
|
+
for (const [paragraph, section] of this.sectionParagraphs) paragraph.addSectionProperties(section);
|
|
23368
|
+
let xml;
|
|
23369
|
+
try {
|
|
23370
|
+
xml = super.prepForXml(context);
|
|
23371
|
+
} finally {
|
|
23372
|
+
for (const [paragraph, section] of this.sectionParagraphs) paragraph.removeSectionProperties(section);
|
|
23373
|
+
}
|
|
23374
|
+
fillTablesOfContents(xml, context, this.headingBookmarkIds);
|
|
23375
|
+
if (this.pageNumbers) {
|
|
23376
|
+
fillSequenceNumbers(xml, context);
|
|
23377
|
+
fillPageNumbers(xml, context, this.pageNumbers);
|
|
23378
|
+
}
|
|
23379
|
+
return xml;
|
|
21985
23380
|
}
|
|
21986
23381
|
/**
|
|
21987
23382
|
* Adds a block-level component to the body.
|
|
@@ -21992,14 +23387,32 @@ var Body = class extends XmlComponent {
|
|
|
21992
23387
|
* @param component - The XML component to add (paragraph, table, etc.)
|
|
21993
23388
|
*/
|
|
21994
23389
|
push(component) {
|
|
23390
|
+
const section = component instanceof Paragraph ? this.sectionParagraphs.get(component) : void 0;
|
|
23391
|
+
if (section) {
|
|
23392
|
+
const sectionParagraph = this.createSectionParagraph();
|
|
23393
|
+
this.root.splice(this.root.indexOf(component) + 1, 0, sectionParagraph);
|
|
23394
|
+
this.sectionParagraphs.delete(component);
|
|
23395
|
+
this.sectionParagraphs.set(sectionParagraph, section);
|
|
23396
|
+
}
|
|
21995
23397
|
this.root.push(component);
|
|
21996
23398
|
}
|
|
21997
|
-
|
|
21998
|
-
|
|
21999
|
-
|
|
22000
|
-
|
|
22001
|
-
|
|
22002
|
-
|
|
23399
|
+
/**
|
|
23400
|
+
* The paragraph the current section ends with, which can hold its properties.
|
|
23401
|
+
*
|
|
23402
|
+
* There is none when the section ends with something other than a paragraph, or is empty:
|
|
23403
|
+
* its last child is then the placeholder at the start of the body (removed when the body is
|
|
23404
|
+
* written) or the paragraph that ends the section before, which has properties of its own.
|
|
23405
|
+
*/
|
|
23406
|
+
lastParagraphOfSection() {
|
|
23407
|
+
const last = this.root[this.root.length - 1];
|
|
23408
|
+
return last instanceof Paragraph && last !== this.root[0] && !this.sectionParagraphs.has(last) && this.root.indexOf(last) === this.root.length - 1 ? last : void 0;
|
|
23409
|
+
}
|
|
23410
|
+
/**
|
|
23411
|
+
* An empty paragraph to end a section that has no paragraph of its own to end it. The section's
|
|
23412
|
+
* properties are written into it with the others, when the body is written.
|
|
23413
|
+
*/
|
|
23414
|
+
createSectionParagraph() {
|
|
23415
|
+
return new Paragraph({});
|
|
22003
23416
|
}
|
|
22004
23417
|
};
|
|
22005
23418
|
//#endregion
|
|
@@ -23111,6 +24524,9 @@ var TDirection = class extends XmlComponent {
|
|
|
23111
24524
|
var TableCellProperties = class extends IgnoreIfEmptyXmlComponent {
|
|
23112
24525
|
constructor(options) {
|
|
23113
24526
|
super("w:tcPr", options.includeIfEmpty);
|
|
24527
|
+
_defineProperty(this, "hasWidth", void 0);
|
|
24528
|
+
_defineProperty(this, "hasColumnWidth", false);
|
|
24529
|
+
this.hasWidth = options.width !== void 0;
|
|
23114
24530
|
if (options.width) this.root.push(createTableWidthElement("w:tcW", options.width));
|
|
23115
24531
|
if (options.columnSpan) this.root.push(new GridSpan(options.columnSpan));
|
|
23116
24532
|
if (options.verticalMerge) this.root.push(new VerticalMerge(options.verticalMerge));
|
|
@@ -23128,6 +24544,19 @@ var TableCellProperties = class extends IgnoreIfEmptyXmlComponent {
|
|
|
23128
24544
|
if (options.cellMerge) this.root.push(new CellMerge(options.cellMerge));
|
|
23129
24545
|
if (options.revision) this.root.push(new TableCellPropertiesChange(options.revision));
|
|
23130
24546
|
}
|
|
24547
|
+
/**
|
|
24548
|
+
* Gives a cell without a width of its own the width of the table's columns it spans, in twips.
|
|
24549
|
+
*
|
|
24550
|
+
* @internal
|
|
24551
|
+
*/
|
|
24552
|
+
setColumnWidth(twips) {
|
|
24553
|
+
if (this.hasWidth) return;
|
|
24554
|
+
this.root.splice(0, this.hasColumnWidth ? 1 : 0, createTableWidthElement("w:tcW", {
|
|
24555
|
+
size: twips,
|
|
24556
|
+
type: WidthType.DXA
|
|
24557
|
+
}));
|
|
24558
|
+
this.hasColumnWidth = true;
|
|
24559
|
+
}
|
|
23131
24560
|
};
|
|
23132
24561
|
var TableCellPropertiesChange = class extends XmlComponent {
|
|
23133
24562
|
constructor(options) {
|
|
@@ -23186,10 +24615,20 @@ var TableCell = class extends XmlComponent {
|
|
|
23186
24615
|
"options",
|
|
23187
24616
|
void 0
|
|
23188
24617
|
);
|
|
24618
|
+
_defineProperty(this, "properties", void 0);
|
|
23189
24619
|
this.options = options;
|
|
23190
|
-
this.
|
|
24620
|
+
this.properties = new TableCellProperties(options);
|
|
24621
|
+
this.root.push(this.properties);
|
|
23191
24622
|
for (const child of options.children) this.root.push(child);
|
|
23192
24623
|
}
|
|
24624
|
+
/**
|
|
24625
|
+
* Gives the cell, unless it has a width of its own, the width of the table's columns it spans, in twips.
|
|
24626
|
+
*
|
|
24627
|
+
* @internal
|
|
24628
|
+
*/
|
|
24629
|
+
setColumnWidth(twips) {
|
|
24630
|
+
this.properties.setColumnWidth(twips);
|
|
24631
|
+
}
|
|
23193
24632
|
prepForXml(context) {
|
|
23194
24633
|
if (!(this.root[this.root.length - 1] instanceof Paragraph)) this.root.push(new Paragraph({}));
|
|
23195
24634
|
return super.prepForXml(context);
|
|
@@ -24053,6 +25492,7 @@ var Table = class Table extends FileChild {
|
|
|
24053
25492
|
columnIndex += cell.options.columnSpan || 1;
|
|
24054
25493
|
});
|
|
24055
25494
|
});
|
|
25495
|
+
this.setCellWidths(DEFAULT_AVAILABLE_WIDTH);
|
|
24056
25496
|
this.resolvedColumnWidths = columnWidths !== null && columnWidths !== void 0 ? columnWidths : resolveColumnWidths({
|
|
24057
25497
|
rows,
|
|
24058
25498
|
width: this.width,
|
|
@@ -24109,6 +25549,7 @@ var Table = class Table extends FileChild {
|
|
|
24109
25549
|
* serializing.
|
|
24110
25550
|
*/
|
|
24111
25551
|
prepForXml(context) {
|
|
25552
|
+
this.setCellWidths(this.resolveAvailableWidth(context));
|
|
24112
25553
|
if (this.columnWidths === void 0) {
|
|
24113
25554
|
this.resolvedColumnWidths = resolveColumnWidths({
|
|
24114
25555
|
rows: this.rows,
|
|
@@ -24121,6 +25562,29 @@ var Table = class Table extends FileChild {
|
|
|
24121
25562
|
return super.prepForXml(context);
|
|
24122
25563
|
}
|
|
24123
25564
|
/**
|
|
25565
|
+
* Gives each cell without a width of its own the width of the `columnWidths` it spans, as Word sizes the columns of
|
|
25566
|
+
* cells without a width to their content, whatever the grid says. When the table's width is wider than the columns
|
|
25567
|
+
* add up to, they are scaled up to fill it, as Word and LibreOffice lay them out, so columns given as proportions
|
|
25568
|
+
* keep them.
|
|
25569
|
+
*/
|
|
25570
|
+
setCellWidths(availableWidth) {
|
|
25571
|
+
var _resolvePreferredWidt;
|
|
25572
|
+
if (this.columnWidths === void 0) return;
|
|
25573
|
+
const total = this.columnWidths.reduce((sum, columnWidth) => sum + columnWidth, 0);
|
|
25574
|
+
const tableWidth = (_resolvePreferredWidt = resolvePreferredWidth(this.width, availableWidth)) !== null && _resolvePreferredWidt !== void 0 ? _resolvePreferredWidt : 0;
|
|
25575
|
+
const scale = total > 0 && tableWidth > total ? tableWidth / total : 1;
|
|
25576
|
+
for (const row of this.rows) {
|
|
25577
|
+
let column = 0;
|
|
25578
|
+
for (const cell of row.cells) {
|
|
25579
|
+
const span = cell.options.columnSpan || 1;
|
|
25580
|
+
const spanned = this.columnWidths.slice(column, column + span);
|
|
25581
|
+
const cellWidth = Math.round(spanned.reduce((sum, columnWidth) => sum + columnWidth, 0) * scale);
|
|
25582
|
+
if (spanned.length === span && cellWidth > 0) cell.setColumnWidth(cellWidth);
|
|
25583
|
+
column += span;
|
|
25584
|
+
}
|
|
25585
|
+
}
|
|
25586
|
+
}
|
|
25587
|
+
/**
|
|
24124
25588
|
* Finds the width in twips available to this table from the serialization context:
|
|
24125
25589
|
* the parent cell for a nested table, otherwise the text width of the section the
|
|
24126
25590
|
* table belongs to (the first section for headers, footers and other parts). Falls
|
|
@@ -24733,7 +26197,7 @@ var CustomProperties = class extends XmlComponent {
|
|
|
24733
26197
|
for (const property of properties) this.addCustomProperty(property);
|
|
24734
26198
|
}
|
|
24735
26199
|
prepForXml(context) {
|
|
24736
|
-
this.
|
|
26200
|
+
this.root.splice(1, this.root.length - 1, ...this.properties);
|
|
24737
26201
|
return super.prepForXml(context);
|
|
24738
26202
|
}
|
|
24739
26203
|
addCustomProperty(property) {
|
|
@@ -24995,7 +26459,7 @@ var Document = class extends XmlComponent {
|
|
|
24995
26459
|
"w16sdtdh",
|
|
24996
26460
|
"w16se"
|
|
24997
26461
|
], "w14 w15 wp14"));
|
|
24998
|
-
this.body = new Body();
|
|
26462
|
+
this.body = new Body({ pageNumbers: options.pageNumbers });
|
|
24999
26463
|
if (options.background) this.root.push(new DocumentBackground(options.background));
|
|
25000
26464
|
this.root.push(this.body);
|
|
25001
26465
|
}
|
|
@@ -25293,6 +26757,15 @@ var Endnotes = class extends XmlComponent {
|
|
|
25293
26757
|
});
|
|
25294
26758
|
this.root.push(endnote);
|
|
25295
26759
|
}
|
|
26760
|
+
/**
|
|
26761
|
+
* Formats the endnotes, with the page numbers worked out for their document written into their fields, when the
|
|
26762
|
+
* document's body is written with an estimate of its pages.
|
|
26763
|
+
*/
|
|
26764
|
+
prepForXml(context) {
|
|
26765
|
+
const xml = super.prepForXml(context);
|
|
26766
|
+
fillPartPageNumbers(xml, context);
|
|
26767
|
+
return xml;
|
|
26768
|
+
}
|
|
25296
26769
|
};
|
|
25297
26770
|
//#endregion
|
|
25298
26771
|
//#region src/file/endnotes-wrapper.ts
|
|
@@ -25434,6 +26907,15 @@ var Footer$1 = class extends InitializableXmlComponent {
|
|
|
25434
26907
|
add(item) {
|
|
25435
26908
|
this.root.push(item);
|
|
25436
26909
|
}
|
|
26910
|
+
/**
|
|
26911
|
+
* Formats the footer, with the page numbers worked out for its document written into its fields, when the document's
|
|
26912
|
+
* body is written with an estimate of its pages.
|
|
26913
|
+
*/
|
|
26914
|
+
prepForXml(context) {
|
|
26915
|
+
const xml = super.prepForXml(context);
|
|
26916
|
+
fillPartPageNumbers(xml, context, this.refId);
|
|
26917
|
+
return xml;
|
|
26918
|
+
}
|
|
25437
26919
|
};
|
|
25438
26920
|
//#endregion
|
|
25439
26921
|
//#region src/file/footer-wrapper.ts
|
|
@@ -25784,6 +27266,15 @@ var FootNotes = class extends XmlComponent {
|
|
|
25784
27266
|
});
|
|
25785
27267
|
this.root.push(footnote);
|
|
25786
27268
|
}
|
|
27269
|
+
/**
|
|
27270
|
+
* Formats the footnotes, with the page numbers worked out for their document written into their fields, when the
|
|
27271
|
+
* document's body is written with an estimate of its pages.
|
|
27272
|
+
*/
|
|
27273
|
+
prepForXml(context) {
|
|
27274
|
+
const xml = super.prepForXml(context);
|
|
27275
|
+
fillPartPageNumbers(xml, context);
|
|
27276
|
+
return xml;
|
|
27277
|
+
}
|
|
25787
27278
|
};
|
|
25788
27279
|
//#endregion
|
|
25789
27280
|
//#region src/file/footnotes-wrapper.ts
|
|
@@ -25957,6 +27448,15 @@ var Header$1 = class extends InitializableXmlComponent {
|
|
|
25957
27448
|
add(item) {
|
|
25958
27449
|
this.root.push(item);
|
|
25959
27450
|
}
|
|
27451
|
+
/**
|
|
27452
|
+
* Formats the header, with the page numbers worked out for its document written into its fields, when the document's
|
|
27453
|
+
* body is written with an estimate of its pages.
|
|
27454
|
+
*/
|
|
27455
|
+
prepForXml(context) {
|
|
27456
|
+
const xml = super.prepForXml(context);
|
|
27457
|
+
fillPartPageNumbers(xml, context, this.refId);
|
|
27458
|
+
return xml;
|
|
27459
|
+
}
|
|
25960
27460
|
};
|
|
25961
27461
|
//#endregion
|
|
25962
27462
|
//#region src/file/header-wrapper.ts
|
|
@@ -26961,8 +28461,7 @@ var Numbering = class extends XmlComponent {
|
|
|
26961
28461
|
* @returns The prepared XML object
|
|
26962
28462
|
*/
|
|
26963
28463
|
prepForXml(context) {
|
|
26964
|
-
|
|
26965
|
-
for (const numbering of this.concreteNumberingMap.values()) this.root.push(numbering);
|
|
28464
|
+
this.root.splice(1, this.root.length - 1, ...this.abstractNumberingMap.values(), ...this.concreteNumberingMap.values());
|
|
26966
28465
|
return super.prepForXml(context);
|
|
26967
28466
|
}
|
|
26968
28467
|
/**
|
|
@@ -27016,6 +28515,7 @@ var Numbering = class extends XmlComponent {
|
|
|
27016
28515
|
};
|
|
27017
28516
|
//#endregion
|
|
27018
28517
|
//#region src/file/package-part/package-part.ts
|
|
28518
|
+
var PATH_PART = /^[\w-]+$/;
|
|
27019
28519
|
var RESERVED_FOLDERS = /* @__PURE__ */ new Set([
|
|
27020
28520
|
"_rels",
|
|
27021
28521
|
"fonts",
|
|
@@ -27054,6 +28554,7 @@ var RESERVED_FOLDERS = /* @__PURE__ */ new Set([
|
|
|
27054
28554
|
var PackagePart = class {
|
|
27055
28555
|
/**
|
|
27056
28556
|
* @throws If the folder isn't a single folder name, or is one of the folders docx writes parts of its own in
|
|
28557
|
+
* @throws If the name or the extension isn't a single part of a file name, which could lead out of the folder
|
|
27057
28558
|
*/
|
|
27058
28559
|
constructor(options) {
|
|
27059
28560
|
_defineProperty(this, "options", void 0);
|
|
@@ -27066,7 +28567,9 @@ var PackagePart = class {
|
|
|
27066
28567
|
);
|
|
27067
28568
|
_defineProperty(this, "addedTo", /* @__PURE__ */ new WeakSet());
|
|
27068
28569
|
this.options = options;
|
|
27069
|
-
if (
|
|
28570
|
+
if (!PATH_PART.test(options.folder) || RESERVED_FOLDERS.has(options.folder)) throw new Error(`Invalid package part folder "${options.folder}". Expected a folder name docx doesn't use, such as "charts"`);
|
|
28571
|
+
if (!PATH_PART.test(options.name)) throw new Error(`Invalid package part name "${options.name}". Expected letters, digits, "_" and "-", such as "chart"`);
|
|
28572
|
+
if (!PATH_PART.test(options.extension)) throw new Error(`Invalid package part extension "${options.extension}". Expected letters, digits, "_" and "-", such as "xml"`);
|
|
27070
28573
|
}
|
|
27071
28574
|
/**
|
|
27072
28575
|
* Adds the part to the package being written, once, and a relationship to it from the part being written.
|
|
@@ -27088,7 +28591,7 @@ var PackageParts = class {
|
|
|
27088
28591
|
/**
|
|
27089
28592
|
* @param contentTypes - Where each part's content type is added
|
|
27090
28593
|
* @param existingPaths - The paths under word/ of the parts the package already has, such as a template's charts,
|
|
27091
|
-
* which new parts
|
|
28594
|
+
* which new parts don't take
|
|
27092
28595
|
*/
|
|
27093
28596
|
constructor(contentTypes, existingPaths = /* @__PURE__ */ new Set()) {
|
|
27094
28597
|
_defineProperty(this, "contentTypes", void 0);
|
|
@@ -27387,6 +28890,7 @@ var SettingsAttributes = class extends XmlAttributeComponent {
|
|
|
27387
28890
|
* ```xml
|
|
27388
28891
|
* <xsd:complexType name="CT_Settings">
|
|
27389
28892
|
* <xsd:sequence>
|
|
28893
|
+
* <xsd:element name="embedTrueTypeFonts" type="CT_OnOff" minOccurs="0"/>
|
|
27390
28894
|
* <xsd:element name="trackRevisions" type="CT_OnOff" minOccurs="0"/>
|
|
27391
28895
|
* <xsd:element name="defaultTabStop" type="CT_TwipsMeasure" minOccurs="0"/>
|
|
27392
28896
|
* <xsd:element name="autoHyphenation" type="CT_OnOff" minOccurs="0"/>
|
|
@@ -27445,6 +28949,7 @@ var Settings = class extends XmlComponent {
|
|
|
27445
28949
|
Ignorable: "w14 w15 wp14"
|
|
27446
28950
|
}));
|
|
27447
28951
|
this.root.push(new OnOffElement("w:displayBackgroundShape", true));
|
|
28952
|
+
if (options.embedFonts !== void 0) this.root.push(new OnOffElement("w:embedTrueTypeFonts", options.embedFonts));
|
|
27448
28953
|
if (options.trackRevisions !== void 0) this.root.push(new OnOffElement("w:trackRevisions", options.trackRevisions));
|
|
27449
28954
|
if (options.defaultTabStop !== void 0) this.root.push(new NumberValueElement("w:defaultTabStop", options.defaultTabStop));
|
|
27450
28955
|
if (((_options$hyphenation = options.hyphenation) === null || _options$hyphenation === void 0 ? void 0 : _options$hyphenation.autoHyphenation) !== void 0) this.root.push(new OnOffElement("w:autoHyphenation", options.hyphenation.autoHyphenation));
|
|
@@ -28033,6 +29538,39 @@ var HyperlinkStyle = class extends StyleForCharacter {
|
|
|
28033
29538
|
}, options));
|
|
28034
29539
|
}
|
|
28035
29540
|
};
|
|
29541
|
+
/**
|
|
29542
|
+
* Represents the Normal Table style, the default style of tables.
|
|
29543
|
+
*
|
|
29544
|
+
* It gives cells the margins Word gives the tables it makes: 108 twips (0.075 inches) on the left and right. Without a
|
|
29545
|
+
* default table style, Word gives cells no margins, so their text touches the borders, where LibreOffice and other
|
|
29546
|
+
* applications use these margins.
|
|
29547
|
+
*/
|
|
29548
|
+
var NormalTableStyle = class extends Style {
|
|
29549
|
+
constructor() {
|
|
29550
|
+
super({
|
|
29551
|
+
type: "table",
|
|
29552
|
+
styleId: "TableNormal",
|
|
29553
|
+
default: true
|
|
29554
|
+
}, {
|
|
29555
|
+
name: "Normal Table",
|
|
29556
|
+
uiPriority: 99,
|
|
29557
|
+
semiHidden: true,
|
|
29558
|
+
unhideWhenUsed: true
|
|
29559
|
+
});
|
|
29560
|
+
this.root.push(new TableProperties({
|
|
29561
|
+
indent: {
|
|
29562
|
+
size: 0,
|
|
29563
|
+
type: WidthType.DXA
|
|
29564
|
+
},
|
|
29565
|
+
cellMargin: {
|
|
29566
|
+
top: 0,
|
|
29567
|
+
left: 108,
|
|
29568
|
+
bottom: 0,
|
|
29569
|
+
right: 108
|
|
29570
|
+
}
|
|
29571
|
+
}));
|
|
29572
|
+
}
|
|
29573
|
+
};
|
|
28036
29574
|
//#endregion
|
|
28037
29575
|
//#region src/file/styles/styles.ts
|
|
28038
29576
|
/** The name of a formatted element, such as `w:style`, or `_attr` for its parent's attributes */
|
|
@@ -28325,6 +29863,7 @@ var createDefaultStyles = (options = {}) => {
|
|
|
28325
29863
|
name: "Normal",
|
|
28326
29864
|
quickFormat: true
|
|
28327
29865
|
}),
|
|
29866
|
+
normalTable: new NormalTableStyle(),
|
|
28328
29867
|
document: new DocumentDefaults((_options$document = options.document) !== null && _options$document !== void 0 ? _options$document : {}),
|
|
28329
29868
|
title: new TitleStyle(_objectSpread2({ run: { size: 56 } }, options.title)),
|
|
28330
29869
|
heading1: new Heading1Style(_objectSpread2({ run: {
|
|
@@ -28999,7 +30538,7 @@ var Theme = class extends XmlComponent {
|
|
|
28999
30538
|
*/
|
|
29000
30539
|
var File = class {
|
|
29001
30540
|
constructor(options) {
|
|
29002
|
-
var _options$creator, _options$revision, _options$lastModified, _options$comments, _options$customProper, _options$features, _options$features2, _options$hyphenation, _options$hyphenation2, _options$hyphenation3, _options$hyphenation4, _options$
|
|
30541
|
+
var _options$creator, _options$revision, _options$lastModified, _options$comments, _options$customProper, _options$features, _options$features2, _options$fonts, _options$hyphenation, _options$hyphenation2, _options$hyphenation3, _options$hyphenation4, _options$fonts2;
|
|
29003
30542
|
_defineProperty(this, "currentRelationshipId", 1);
|
|
29004
30543
|
_defineProperty(this, "documentWrapper", void 0);
|
|
29005
30544
|
_defineProperty(this, "headers", []);
|
|
@@ -29047,13 +30586,17 @@ var File = class {
|
|
|
29047
30586
|
this.endnotesWrapper = new EndnotesWrapper();
|
|
29048
30587
|
this.contentTypes = new ContentTypes();
|
|
29049
30588
|
this.packageParts = new PackageParts(this.contentTypes);
|
|
29050
|
-
this.documentWrapper = new DocumentWrapper({
|
|
30589
|
+
this.documentWrapper = new DocumentWrapper({
|
|
30590
|
+
background: options.background,
|
|
30591
|
+
pageNumbers: options.pageNumbers
|
|
30592
|
+
});
|
|
29051
30593
|
this.settings = new Settings({
|
|
29052
30594
|
compatibilityModeVersion: options.compatabilityModeVersion,
|
|
29053
30595
|
compatibility: options.compatibility,
|
|
29054
30596
|
evenAndOddHeaders: options.evenAndOddHeaderAndFooters ? true : false,
|
|
29055
30597
|
trackRevisions: (_options$features = options.features) === null || _options$features === void 0 ? void 0 : _options$features.trackRevisions,
|
|
29056
30598
|
updateFields: (_options$features2 = options.features) === null || _options$features2 === void 0 ? void 0 : _options$features2.updateFields,
|
|
30599
|
+
embedFonts: ((_options$fonts = options.fonts) === null || _options$fonts === void 0 ? void 0 : _options$fonts.length) ? true : void 0,
|
|
29057
30600
|
defaultTabStop: options.defaultTabStop,
|
|
29058
30601
|
hyphenation: {
|
|
29059
30602
|
autoHyphenation: (_options$hyphenation = options.hyphenation) === null || _options$hyphenation === void 0 ? void 0 : _options$hyphenation.autoHyphenation,
|
|
@@ -29064,16 +30607,20 @@ var File = class {
|
|
|
29064
30607
|
});
|
|
29065
30608
|
this.media = new Media();
|
|
29066
30609
|
if (options.externalStyles !== void 0) {
|
|
29067
|
-
var _options$styles$defau, _options$styles;
|
|
30610
|
+
var _options$styles$defau, _options$styles, _options$styles2, _options$styles3;
|
|
29068
30611
|
const given = (_options$styles$defau = (_options$styles = options.styles) === null || _options$styles === void 0 ? void 0 : _options$styles.default) !== null && _options$styles$defau !== void 0 ? _options$styles$defau : {};
|
|
29069
30612
|
const defaultStyles = Object.entries(createDefaultStyles(given));
|
|
29070
30613
|
const isGiven = ([key]) => given[key] !== void 0;
|
|
29071
30614
|
const externalStyles = new ExternalStylesFactory().newInstance(options.externalStyles);
|
|
29072
|
-
this.styles = new Styles(_objectSpread2(_objectSpread2({}, externalStyles), {}, {
|
|
29073
|
-
|
|
29074
|
-
|
|
29075
|
-
|
|
29076
|
-
|
|
30615
|
+
this.styles = new Styles(_objectSpread2(_objectSpread2({}, externalStyles), {}, {
|
|
30616
|
+
paragraphStyles: (_options$styles2 = options.styles) === null || _options$styles2 === void 0 ? void 0 : _options$styles2.paragraphStyles,
|
|
30617
|
+
characterStyles: (_options$styles3 = options.styles) === null || _options$styles3 === void 0 ? void 0 : _options$styles3.characterStyles,
|
|
30618
|
+
importedStyles: [
|
|
30619
|
+
...defaultStyles.filter((entry) => !isGiven(entry)).map(([, style]) => style),
|
|
30620
|
+
...externalStyles.importedStyles,
|
|
30621
|
+
...defaultStyles.filter(isGiven).map(([, style]) => style)
|
|
30622
|
+
]
|
|
30623
|
+
}));
|
|
29077
30624
|
} else if (options.styles) {
|
|
29078
30625
|
const defaultStyles = new DefaultStylesFactory().newInstance(options.styles.default);
|
|
29079
30626
|
this.styles = new Styles(_objectSpread2(_objectSpread2({}, defaultStyles), options.styles));
|
|
@@ -29085,7 +30632,7 @@ var File = class {
|
|
|
29085
30632
|
for (const section of options.sections) this.addSection(section);
|
|
29086
30633
|
if (options.footnotes) for (const key in options.footnotes) this.footnotesWrapper.View.createFootNote(parseFloat(key), options.footnotes[key].children);
|
|
29087
30634
|
if (options.endnotes) for (const key in options.endnotes) this.endnotesWrapper.View.createEndnote(parseFloat(key), options.endnotes[key].children);
|
|
29088
|
-
this.fontWrapper = new FontWrapper((_options$
|
|
30635
|
+
this.fontWrapper = new FontWrapper((_options$fonts2 = options.fonts) !== null && _options$fonts2 !== void 0 ? _options$fonts2 : []);
|
|
29089
30636
|
this.theme = new Theme(options.theme);
|
|
29090
30637
|
this.documentWrapper.Relationships.addRelationship(this.currentRelationshipId++, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", "theme/theme1.xml");
|
|
29091
30638
|
}
|
|
@@ -29221,113 +30768,6 @@ var File = class {
|
|
|
29221
30768
|
}
|
|
29222
30769
|
};
|
|
29223
30770
|
//#endregion
|
|
29224
|
-
//#region src/file/table-of-contents/field-instruction.ts
|
|
29225
|
-
/**
|
|
29226
|
-
* Field Instruction module for Table of Contents.
|
|
29227
|
-
*
|
|
29228
|
-
* This module handles the generation of TOC field instruction text
|
|
29229
|
-
* that controls how the table of contents is built.
|
|
29230
|
-
*
|
|
29231
|
-
* Reference: http://officeopenxml.com/WPfieldInstructions.php
|
|
29232
|
-
*
|
|
29233
|
-
* @module
|
|
29234
|
-
*/
|
|
29235
|
-
/**
|
|
29236
|
-
* Represents a field instruction for a Table of Contents.
|
|
29237
|
-
*
|
|
29238
|
-
* The FieldInstruction class generates the TOC field code string that Word uses
|
|
29239
|
-
* to determine how to build the table of contents, including which headings to include,
|
|
29240
|
-
* formatting options, and other TOC-specific settings.
|
|
29241
|
-
*
|
|
29242
|
-
* Reference: http://officeopenxml.com/WPfieldInstructions.php
|
|
29243
|
-
*
|
|
29244
|
-
* ## XSD Schema
|
|
29245
|
-
* ```xml
|
|
29246
|
-
* <xsd:element name="instrText" type="CT_Text"/>
|
|
29247
|
-
* ```
|
|
29248
|
-
*
|
|
29249
|
-
* @example
|
|
29250
|
-
* ```typescript
|
|
29251
|
-
* // Basic TOC field instruction
|
|
29252
|
-
* new FieldInstruction({ headingStyleRange: "1-3" });
|
|
29253
|
-
*
|
|
29254
|
-
* // TOC with hyperlinks and custom styles
|
|
29255
|
-
* new FieldInstruction({
|
|
29256
|
-
* hyperlink: true,
|
|
29257
|
-
* headingStyleRange: "1-3",
|
|
29258
|
-
* stylesWithLevels: [new StyleLevel("CustomStyle", 2)],
|
|
29259
|
-
* });
|
|
29260
|
-
* ```
|
|
29261
|
-
*/
|
|
29262
|
-
var FieldInstruction = class extends XmlComponent {
|
|
29263
|
-
constructor(properties = {}) {
|
|
29264
|
-
super("w:instrText");
|
|
29265
|
-
_defineProperty(this, "properties", void 0);
|
|
29266
|
-
this.properties = properties;
|
|
29267
|
-
this.root.push(new TextAttributes({ space: SpaceType.PRESERVE }));
|
|
29268
|
-
let instruction = "TOC";
|
|
29269
|
-
if (this.properties.captionLabel) instruction = `${instruction} \\a "${this.properties.captionLabel}"`;
|
|
29270
|
-
if (this.properties.entriesFromBookmark) instruction = `${instruction} \\b "${this.properties.entriesFromBookmark}"`;
|
|
29271
|
-
if (this.properties.captionLabelIncludingNumbers) instruction = `${instruction} \\c "${this.properties.captionLabelIncludingNumbers}"`;
|
|
29272
|
-
if (this.properties.sequenceAndPageNumbersSeparator) instruction = `${instruction} \\d "${this.properties.sequenceAndPageNumbersSeparator}"`;
|
|
29273
|
-
if (this.properties.tcFieldIdentifier) instruction = `${instruction} \\f "${this.properties.tcFieldIdentifier}"`;
|
|
29274
|
-
if (this.properties.hyperlink) instruction = `${instruction} \\h`;
|
|
29275
|
-
if (this.properties.tcFieldLevelRange) instruction = `${instruction} \\l "${this.properties.tcFieldLevelRange}"`;
|
|
29276
|
-
if (this.properties.pageNumbersEntryLevelsRange) instruction = `${instruction} \\n "${this.properties.pageNumbersEntryLevelsRange}"`;
|
|
29277
|
-
if (this.properties.headingStyleRange) instruction = `${instruction} \\o "${this.properties.headingStyleRange}"`;
|
|
29278
|
-
if (this.properties.entryAndPageNumberSeparator) instruction = `${instruction} \\p "${this.properties.entryAndPageNumberSeparator}"`;
|
|
29279
|
-
if (this.properties.seqFieldIdentifierForPrefix) instruction = `${instruction} \\s "${this.properties.seqFieldIdentifierForPrefix}"`;
|
|
29280
|
-
if (this.properties.stylesWithLevels && this.properties.stylesWithLevels.length) {
|
|
29281
|
-
const styles = this.properties.stylesWithLevels.map((sl) => `${sl.styleName},${sl.level}`).join(",");
|
|
29282
|
-
instruction = `${instruction} \\t "${styles}"`;
|
|
29283
|
-
}
|
|
29284
|
-
if (this.properties.useAppliedParagraphOutlineLevel) instruction = `${instruction} \\u`;
|
|
29285
|
-
if (this.properties.preserveTabInEntries) instruction = `${instruction} \\w`;
|
|
29286
|
-
if (this.properties.preserveNewLineInEntries) instruction = `${instruction} \\x`;
|
|
29287
|
-
if (this.properties.hideTabAndPageNumbersInWebView) instruction = `${instruction} \\z`;
|
|
29288
|
-
this.root.push(instruction);
|
|
29289
|
-
}
|
|
29290
|
-
};
|
|
29291
|
-
//#endregion
|
|
29292
|
-
//#region src/file/table-of-contents/sdt-content.ts
|
|
29293
|
-
/**
|
|
29294
|
-
* Structured Document Tag Content module.
|
|
29295
|
-
*
|
|
29296
|
-
* This module represents the content container for structured document tags,
|
|
29297
|
-
* including table of contents elements.
|
|
29298
|
-
*
|
|
29299
|
-
* Reference: http://officeopenxml.com/WPtableOfContents.php
|
|
29300
|
-
*
|
|
29301
|
-
* @module
|
|
29302
|
-
*/
|
|
29303
|
-
/**
|
|
29304
|
-
* Represents the content portion of a Structured Document Tag.
|
|
29305
|
-
*
|
|
29306
|
-
* The StructuredDocumentTagContent contains the actual content elements
|
|
29307
|
-
* (paragraphs, tables, etc.) within a structured document tag, such as
|
|
29308
|
-
* the paragraphs that make up a table of contents.
|
|
29309
|
-
*
|
|
29310
|
-
* Reference: http://officeopenxml.com/WPtableOfContents.php
|
|
29311
|
-
*
|
|
29312
|
-
* ## XSD Schema
|
|
29313
|
-
* ```xml
|
|
29314
|
-
* <xsd:complexType name="CT_SdtContentBlock">
|
|
29315
|
-
* <xsd:group ref="EG_ContentBlockContent" minOccurs="0" maxOccurs="unbounded"/>
|
|
29316
|
-
* </xsd:complexType>
|
|
29317
|
-
* ```
|
|
29318
|
-
*
|
|
29319
|
-
* @example
|
|
29320
|
-
* ```typescript
|
|
29321
|
-
* const content = new StructuredDocumentTagContent();
|
|
29322
|
-
* content.addChildElement(new Paragraph("Content"));
|
|
29323
|
-
* ```
|
|
29324
|
-
*/
|
|
29325
|
-
var StructuredDocumentTagContent = class extends XmlComponent {
|
|
29326
|
-
constructor() {
|
|
29327
|
-
super("w:sdtContent");
|
|
29328
|
-
}
|
|
29329
|
-
};
|
|
29330
|
-
//#endregion
|
|
29331
30771
|
//#region src/file/table-of-contents/sdt-properties.ts
|
|
29332
30772
|
/**
|
|
29333
30773
|
* Structured Document Tag Properties module.
|
|
@@ -29407,6 +30847,12 @@ var _excluded$2 = [
|
|
|
29407
30847
|
* TableOfContents creates an auto-generated list of document headings
|
|
29408
30848
|
* with page numbers. It uses a TOC field code to generate entries.
|
|
29409
30849
|
*
|
|
30850
|
+
* Unless it is given `cachedEntries` or `contentChildren`, it is written with an
|
|
30851
|
+
* entry for each heading its options include, linked to a bookmark on the heading,
|
|
30852
|
+
* so it isn't empty before Word updates it or in applications that don't update it.
|
|
30853
|
+
* The page numbers are left for Word to fill in when it updates the field, unless the document's `pageNumbers`
|
|
30854
|
+
* writes them.
|
|
30855
|
+
*
|
|
29410
30856
|
* Reference: http://officeopenxml.com/WPtableOfContents.php
|
|
29411
30857
|
*
|
|
29412
30858
|
* @publicApi
|
|
@@ -29432,12 +30878,18 @@ var _excluded$2 = [
|
|
|
29432
30878
|
*/
|
|
29433
30879
|
var TableOfContents = class extends FileChild {
|
|
29434
30880
|
constructor(alias = "Table of Contents", _ref = {}) {
|
|
29435
|
-
let { contentChildren = [], cachedEntries = [], beginDirty
|
|
30881
|
+
let { contentChildren = [], cachedEntries = [], beginDirty } = _ref, properties = _objectWithoutProperties(_ref, _excluded$2);
|
|
29436
30882
|
super("w:sdt");
|
|
30883
|
+
_defineProperty(
|
|
30884
|
+
this,
|
|
30885
|
+
/** What it is filled in with from the headings, when it isn't given its content */
|
|
30886
|
+
"fromHeadings",
|
|
30887
|
+
void 0
|
|
30888
|
+
);
|
|
29437
30889
|
this.root.push(new StructuredDocumentTagProperties(alias));
|
|
29438
30890
|
const content = new StructuredDocumentTagContent();
|
|
29439
30891
|
const beginParagraphMandatoryChildren = [new Run({ children: [
|
|
29440
|
-
|
|
30892
|
+
beginOf(beginDirty),
|
|
29441
30893
|
new FieldInstruction(properties),
|
|
29442
30894
|
createSeparate()
|
|
29443
30895
|
] })];
|
|
@@ -29464,9 +30916,27 @@ var TableOfContents = class extends FileChild {
|
|
|
29464
30916
|
for (const child of contentChildren) content.addChildElement(child);
|
|
29465
30917
|
const endParagraph = new Paragraph({ children: endParagraphMandatoryChildren });
|
|
29466
30918
|
content.addChildElement(endParagraph);
|
|
30919
|
+
if (contentChildren.length === 0) this.fromHeadings = {
|
|
30920
|
+
properties,
|
|
30921
|
+
beginDirty
|
|
30922
|
+
};
|
|
29467
30923
|
}
|
|
29468
30924
|
this.root.push(content);
|
|
29469
30925
|
}
|
|
30926
|
+
/**
|
|
30927
|
+
* Written empty, and filled in from the headings once the body it is in is written, unless it was given its content.
|
|
30928
|
+
* The page numbers are aligned to the right of the text in its section.
|
|
30929
|
+
*/
|
|
30930
|
+
prepForXml(context) {
|
|
30931
|
+
const xml = super.prepForXml(context);
|
|
30932
|
+
recordTableOfContents(xml, this.fromHeadings && _objectSpread2(_objectSpread2({}, this.fromHeadings), {}, { textWidth: this.textWidthIn(context) }));
|
|
30933
|
+
return xml;
|
|
30934
|
+
}
|
|
30935
|
+
/** The width of the text in the section it is in */
|
|
30936
|
+
textWidthIn(context) {
|
|
30937
|
+
var _context$file$Documen, _context$file;
|
|
30938
|
+
return (_context$file$Documen = (_context$file = context.file) === null || _context$file === void 0 || (_context$file = _context$file.Document) === null || _context$file === void 0 || (_context$file = _context$file.View.Body.getSectionPropertiesFor(this)) === null || _context$file === void 0 ? void 0 : _context$file.AvailableTextWidth) !== null && _context$file$Documen !== void 0 ? _context$file$Documen : DEFAULT_AVAILABLE_WIDTH;
|
|
30939
|
+
}
|
|
29470
30940
|
getTabStopsForLevel(level, pageWidth = 9025) {
|
|
29471
30941
|
return [{
|
|
29472
30942
|
type: "clear",
|
|
@@ -33880,11 +35350,11 @@ var NumberingReplacer = class {
|
|
|
33880
35350
|
*
|
|
33881
35351
|
* @module
|
|
33882
35352
|
*/
|
|
33883
|
-
var formatter$
|
|
35353
|
+
var formatter$3 = new Formatter();
|
|
33884
35354
|
/**
|
|
33885
35355
|
* Formats a part's XML, with the relationships that anything in it that refers to other parts adds to.
|
|
33886
35356
|
*/
|
|
33887
|
-
var xmlifyPart = (file, content, prettify, relationships, standalone = true) => (0, import_xml.default)(formatter$
|
|
35357
|
+
var xmlifyPart = (file, content, prettify, relationships, standalone = true) => (0, import_xml.default)(formatter$3.format(content, {
|
|
33888
35358
|
viewWrapper: {
|
|
33889
35359
|
View: content,
|
|
33890
35360
|
Relationships: relationships
|
|
@@ -34005,7 +35475,6 @@ var Compiler = class {
|
|
|
34005
35475
|
return zip;
|
|
34006
35476
|
}
|
|
34007
35477
|
xmlifyFile(file, prettify) {
|
|
34008
|
-
const documentRelationshipCount = file.Document.Relationships.RelationshipCount + 1;
|
|
34009
35478
|
const documentXmlData = (0, import_xml.default)(this.formatter.format(file.Document.View, {
|
|
34010
35479
|
viewWrapper: file.Document,
|
|
34011
35480
|
file,
|
|
@@ -34017,7 +35486,6 @@ var Compiler = class {
|
|
|
34017
35486
|
encoding: "UTF-8"
|
|
34018
35487
|
}
|
|
34019
35488
|
});
|
|
34020
|
-
const commentRelationshipCount = file.Comments.Relationships.RelationshipCount + 1;
|
|
34021
35489
|
const commentXmlData = (0, import_xml.default)(this.formatter.format(file.Comments, {
|
|
34022
35490
|
viewWrapper: {
|
|
34023
35491
|
View: file.Comments,
|
|
@@ -34032,7 +35500,6 @@ var Compiler = class {
|
|
|
34032
35500
|
encoding: "UTF-8"
|
|
34033
35501
|
}
|
|
34034
35502
|
});
|
|
34035
|
-
const footnoteRelationshipCount = file.FootNotes.Relationships.RelationshipCount + 1;
|
|
34036
35503
|
const footnoteXmlData = (0, import_xml.default)(this.formatter.format(file.FootNotes.View, {
|
|
34037
35504
|
viewWrapper: file.FootNotes,
|
|
34038
35505
|
file,
|
|
@@ -34044,17 +35511,31 @@ var Compiler = class {
|
|
|
34044
35511
|
encoding: "UTF-8"
|
|
34045
35512
|
}
|
|
34046
35513
|
});
|
|
35514
|
+
const endnoteXmlData = (0, import_xml.default)(this.formatter.format(file.Endnotes.View, {
|
|
35515
|
+
viewWrapper: file.Endnotes,
|
|
35516
|
+
file,
|
|
35517
|
+
stack: []
|
|
35518
|
+
}), {
|
|
35519
|
+
indent: prettify,
|
|
35520
|
+
declaration: { encoding: "UTF-8" }
|
|
35521
|
+
});
|
|
35522
|
+
const documentRelationshipCount = file.Document.Relationships.RelationshipCount + 1;
|
|
35523
|
+
const commentRelationshipCount = file.Comments.Relationships.RelationshipCount + 1;
|
|
35524
|
+
const footnoteRelationshipCount = file.FootNotes.Relationships.RelationshipCount + 1;
|
|
35525
|
+
const endnoteRelationshipCount = file.Endnotes.Relationships.RelationshipCount + 1;
|
|
34047
35526
|
const documentMediaDatas = this.imageReplacer.getMediaData(documentXmlData, file.Media);
|
|
34048
35527
|
const commentMediaDatas = this.imageReplacer.getMediaData(commentXmlData, file.Media);
|
|
34049
35528
|
const footnoteMediaDatas = this.imageReplacer.getMediaData(footnoteXmlData, file.Media);
|
|
35529
|
+
const endnoteMediaDatas = this.imageReplacer.getMediaData(endnoteXmlData, file.Media);
|
|
34050
35530
|
return _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({
|
|
34051
35531
|
Relationships: {
|
|
34052
35532
|
data: (() => {
|
|
35533
|
+
const relationships = Relationships.copy(file.Document.Relationships);
|
|
34053
35534
|
documentMediaDatas.forEach((mediaData, i) => {
|
|
34054
|
-
|
|
35535
|
+
relationships.addRelationship(documentRelationshipCount + i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`);
|
|
34055
35536
|
});
|
|
34056
|
-
|
|
34057
|
-
return (0, import_xml.default)(this.formatter.format(
|
|
35537
|
+
relationships.addRelationship(relationships.RelationshipCount + 1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable", "fontTable.xml");
|
|
35538
|
+
return (0, import_xml.default)(this.formatter.format(relationships, {
|
|
34058
35539
|
viewWrapper: file.Document,
|
|
34059
35540
|
file,
|
|
34060
35541
|
stack: []
|
|
@@ -34103,20 +35584,6 @@ var Compiler = class {
|
|
|
34103
35584
|
}),
|
|
34104
35585
|
path: "docProps/core.xml"
|
|
34105
35586
|
},
|
|
34106
|
-
Numbering: {
|
|
34107
|
-
data: (0, import_xml.default)(this.formatter.format(file.Numbering, {
|
|
34108
|
-
viewWrapper: file.Document,
|
|
34109
|
-
file,
|
|
34110
|
-
stack: []
|
|
34111
|
-
}), {
|
|
34112
|
-
indent: prettify,
|
|
34113
|
-
declaration: {
|
|
34114
|
-
standalone: "yes",
|
|
34115
|
-
encoding: "UTF-8"
|
|
34116
|
-
}
|
|
34117
|
-
}),
|
|
34118
|
-
path: "word/numbering.xml"
|
|
34119
|
-
},
|
|
34120
35587
|
FileRelationships: {
|
|
34121
35588
|
data: (0, import_xml.default)(this.formatter.format(file.FileRelationships, {
|
|
34122
35589
|
viewWrapper: file.Document,
|
|
@@ -34137,11 +35604,13 @@ var Compiler = class {
|
|
|
34137
35604
|
indent: prettify,
|
|
34138
35605
|
declaration: { encoding: "UTF-8" }
|
|
34139
35606
|
});
|
|
34140
|
-
this.imageReplacer.getMediaData(xmlData, file.Media)
|
|
34141
|
-
|
|
35607
|
+
const mediaDatas = this.imageReplacer.getMediaData(xmlData, file.Media);
|
|
35608
|
+
const relationships = Relationships.copy(headerWrapper.Relationships);
|
|
35609
|
+
mediaDatas.forEach((mediaData, i) => {
|
|
35610
|
+
relationships.addRelationship(i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`);
|
|
34142
35611
|
});
|
|
34143
35612
|
return {
|
|
34144
|
-
data: (0, import_xml.default)(this.formatter.format(
|
|
35613
|
+
data: (0, import_xml.default)(this.formatter.format(relationships, {
|
|
34145
35614
|
viewWrapper: headerWrapper,
|
|
34146
35615
|
file,
|
|
34147
35616
|
stack: []
|
|
@@ -34161,11 +35630,13 @@ var Compiler = class {
|
|
|
34161
35630
|
indent: prettify,
|
|
34162
35631
|
declaration: { encoding: "UTF-8" }
|
|
34163
35632
|
});
|
|
34164
|
-
this.imageReplacer.getMediaData(xmlData, file.Media)
|
|
34165
|
-
|
|
35633
|
+
const mediaDatas = this.imageReplacer.getMediaData(xmlData, file.Media);
|
|
35634
|
+
const relationships = Relationships.copy(footerWrapper.Relationships);
|
|
35635
|
+
mediaDatas.forEach((mediaData, i) => {
|
|
35636
|
+
relationships.addRelationship(i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`);
|
|
34166
35637
|
});
|
|
34167
35638
|
return {
|
|
34168
|
-
data: (0, import_xml.default)(this.formatter.format(
|
|
35639
|
+
data: (0, import_xml.default)(this.formatter.format(relationships, {
|
|
34169
35640
|
viewWrapper: footerWrapper,
|
|
34170
35641
|
file,
|
|
34171
35642
|
stack: []
|
|
@@ -34245,10 +35716,11 @@ var Compiler = class {
|
|
|
34245
35716
|
},
|
|
34246
35717
|
FootNotesRelationships: {
|
|
34247
35718
|
data: (() => {
|
|
35719
|
+
const relationships = Relationships.copy(file.FootNotes.Relationships);
|
|
34248
35720
|
footnoteMediaDatas.forEach((mediaData, i) => {
|
|
34249
|
-
|
|
35721
|
+
relationships.addRelationship(footnoteRelationshipCount + i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`);
|
|
34250
35722
|
});
|
|
34251
|
-
return (0, import_xml.default)(this.formatter.format(
|
|
35723
|
+
return (0, import_xml.default)(this.formatter.format(relationships, {
|
|
34252
35724
|
viewWrapper: file.FootNotes,
|
|
34253
35725
|
file,
|
|
34254
35726
|
stack: []
|
|
@@ -34260,25 +35732,27 @@ var Compiler = class {
|
|
|
34260
35732
|
path: "word/_rels/footnotes.xml.rels"
|
|
34261
35733
|
},
|
|
34262
35734
|
Endnotes: {
|
|
34263
|
-
data: (
|
|
34264
|
-
|
|
34265
|
-
file
|
|
34266
|
-
|
|
34267
|
-
}), {
|
|
34268
|
-
indent: prettify,
|
|
34269
|
-
declaration: { encoding: "UTF-8" }
|
|
34270
|
-
}),
|
|
35735
|
+
data: (() => {
|
|
35736
|
+
const xmlData = this.imageReplacer.replace(endnoteXmlData, endnoteMediaDatas, endnoteRelationshipCount);
|
|
35737
|
+
return this.numberingReplacer.replace(xmlData, file.Numbering.ConcreteNumbering);
|
|
35738
|
+
})(),
|
|
34271
35739
|
path: "word/endnotes.xml"
|
|
34272
35740
|
},
|
|
34273
35741
|
EndnotesRelationships: {
|
|
34274
|
-
data: (
|
|
34275
|
-
|
|
34276
|
-
|
|
34277
|
-
|
|
34278
|
-
|
|
34279
|
-
|
|
34280
|
-
|
|
34281
|
-
|
|
35742
|
+
data: (() => {
|
|
35743
|
+
const relationships = Relationships.copy(file.Endnotes.Relationships);
|
|
35744
|
+
endnoteMediaDatas.forEach((mediaData, i) => {
|
|
35745
|
+
relationships.addRelationship(endnoteRelationshipCount + i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`);
|
|
35746
|
+
});
|
|
35747
|
+
return (0, import_xml.default)(this.formatter.format(relationships, {
|
|
35748
|
+
viewWrapper: file.Endnotes,
|
|
35749
|
+
file,
|
|
35750
|
+
stack: []
|
|
35751
|
+
}), {
|
|
35752
|
+
indent: prettify,
|
|
35753
|
+
declaration: { encoding: "UTF-8" }
|
|
35754
|
+
});
|
|
35755
|
+
})(),
|
|
34282
35756
|
path: "word/_rels/endnotes.xml.rels"
|
|
34283
35757
|
},
|
|
34284
35758
|
Settings: {
|
|
@@ -34305,10 +35779,11 @@ var Compiler = class {
|
|
|
34305
35779
|
},
|
|
34306
35780
|
CommentsRelationships: {
|
|
34307
35781
|
data: (() => {
|
|
35782
|
+
const relationships = Relationships.copy(file.Comments.Relationships);
|
|
34308
35783
|
commentMediaDatas.forEach((mediaData, i) => {
|
|
34309
|
-
|
|
35784
|
+
relationships.addRelationship(commentRelationshipCount + i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`);
|
|
34310
35785
|
});
|
|
34311
|
-
return (0, import_xml.default)(this.formatter.format(
|
|
35786
|
+
return (0, import_xml.default)(this.formatter.format(relationships, {
|
|
34312
35787
|
viewWrapper: {
|
|
34313
35788
|
View: file.Comments,
|
|
34314
35789
|
Relationships: file.Comments.Relationships
|
|
@@ -34395,6 +35870,20 @@ var Compiler = class {
|
|
|
34395
35870
|
path: "word/theme/theme1.xml"
|
|
34396
35871
|
},
|
|
34397
35872
|
PackageParts: xmlifyPackageParts(file, prettify),
|
|
35873
|
+
Numbering: {
|
|
35874
|
+
data: (0, import_xml.default)(this.formatter.format(file.Numbering, {
|
|
35875
|
+
viewWrapper: file.Document,
|
|
35876
|
+
file,
|
|
35877
|
+
stack: []
|
|
35878
|
+
}), {
|
|
35879
|
+
indent: prettify,
|
|
35880
|
+
declaration: {
|
|
35881
|
+
standalone: "yes",
|
|
35882
|
+
encoding: "UTF-8"
|
|
35883
|
+
}
|
|
35884
|
+
}),
|
|
35885
|
+
path: "word/numbering.xml"
|
|
35886
|
+
},
|
|
34398
35887
|
ContentTypes: {
|
|
34399
35888
|
data: (0, import_xml.default)(this.formatter.format(file.ContentTypes, {
|
|
34400
35889
|
viewWrapper: file.Document,
|
|
@@ -34410,7 +35899,7 @@ var Compiler = class {
|
|
|
34410
35899
|
}
|
|
34411
35900
|
};
|
|
34412
35901
|
//#endregion
|
|
34413
|
-
//#region \0@oxc-project+runtime@0.
|
|
35902
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/asyncToGenerator.js
|
|
34414
35903
|
function asyncGeneratorStep(n, t, e, r, o, a, c) {
|
|
34415
35904
|
try {
|
|
34416
35905
|
var i = n[a](c), u = i.value;
|
|
@@ -34580,13 +36069,62 @@ var Packer = class Packer {
|
|
|
34580
36069
|
};
|
|
34581
36070
|
_defineProperty(Packer, "compiler", new Compiler());
|
|
34582
36071
|
//#endregion
|
|
36072
|
+
//#region src/patcher/bookmark-ids.ts
|
|
36073
|
+
var bookmarkIdOf = (element) => {
|
|
36074
|
+
var _element$attributes;
|
|
36075
|
+
if (element.name !== "w:bookmarkStart" && element.name !== "w:bookmarkEnd") return;
|
|
36076
|
+
const id = Number((_element$attributes = element.attributes) === null || _element$attributes === void 0 ? void 0 : _element$attributes["w:id"]);
|
|
36077
|
+
return Number.isInteger(id) ? id : void 0;
|
|
36078
|
+
};
|
|
36079
|
+
/**
|
|
36080
|
+
* Finds the id of every bookmark in an element, at any depth.
|
|
36081
|
+
*
|
|
36082
|
+
* @param element - The element to search, such as a part's root
|
|
36083
|
+
* @returns The ids, once for each bookmarkStart and bookmarkEnd
|
|
36084
|
+
*/
|
|
36085
|
+
var findBookmarkIds = (element) => {
|
|
36086
|
+
var _element$elements;
|
|
36087
|
+
const id = bookmarkIdOf(element);
|
|
36088
|
+
return [...id === void 0 ? [] : [id], ...((_element$elements = element.elements) !== null && _element$elements !== void 0 ? _element$elements : []).flatMap(findBookmarkIds)];
|
|
36089
|
+
};
|
|
36090
|
+
/**
|
|
36091
|
+
* Creates a function that renumbers the bookmarks in content being inserted, so none takes an id the document
|
|
36092
|
+
* already uses. Bookmark ids must be unique within a document, but a bookmark's id is chosen when it is created,
|
|
36093
|
+
* without knowing which ids the template has.
|
|
36094
|
+
*
|
|
36095
|
+
* A bookmark keeps its id if nothing in the document uses it yet, and otherwise gets the next unused one. An id is
|
|
36096
|
+
* renumbered the same way each time, so a bookmark's start and end still share one, even in separate patches.
|
|
36097
|
+
*
|
|
36098
|
+
* @param idsInDocument - The ids of the bookmarks already in the document
|
|
36099
|
+
* @returns A function that returns the elements with their bookmarks renumbered
|
|
36100
|
+
*/
|
|
36101
|
+
var renumberBookmarksAvoiding = (idsInDocument) => {
|
|
36102
|
+
const usedIds = new Set(idsInDocument);
|
|
36103
|
+
const newIds = /* @__PURE__ */ new Map();
|
|
36104
|
+
let highestId = idsInDocument.reduce((highest, id) => Math.max(highest, id), 0);
|
|
36105
|
+
const newIdFor = (id) => {
|
|
36106
|
+
const knownId = newIds.get(id);
|
|
36107
|
+
if (knownId !== void 0) return knownId;
|
|
36108
|
+
const newId = usedIds.has(id) ? highestId + 1 : id;
|
|
36109
|
+
highestId = Math.max(highestId, newId);
|
|
36110
|
+
usedIds.add(newId);
|
|
36111
|
+
newIds.set(id, newId);
|
|
36112
|
+
return newId;
|
|
36113
|
+
};
|
|
36114
|
+
const renumber = (element) => {
|
|
36115
|
+
const id = bookmarkIdOf(element);
|
|
36116
|
+
return _objectSpread2(_objectSpread2(_objectSpread2({}, element), id === void 0 ? {} : { attributes: _objectSpread2(_objectSpread2({}, element.attributes), {}, { "w:id": String(newIdFor(id)) }) }), element.elements === void 0 ? {} : { elements: element.elements.map(renumber) });
|
|
36117
|
+
};
|
|
36118
|
+
return (elements) => elements.map(renumber);
|
|
36119
|
+
};
|
|
36120
|
+
//#endregion
|
|
34583
36121
|
//#region src/patcher/util.ts
|
|
34584
36122
|
/**
|
|
34585
36123
|
* Utility functions for XML manipulation in document patching.
|
|
34586
36124
|
*
|
|
34587
36125
|
* @module
|
|
34588
36126
|
*/
|
|
34589
|
-
var formatter$
|
|
36127
|
+
var formatter$2 = new Formatter();
|
|
34590
36128
|
/**
|
|
34591
36129
|
* Converts XML string to JSON element structure.
|
|
34592
36130
|
*
|
|
@@ -34626,7 +36164,7 @@ var toJson = (xmlData) => {
|
|
|
34626
36164
|
*/
|
|
34627
36165
|
var createTextElementContents = (text) => {
|
|
34628
36166
|
var _textJson$elements$0$;
|
|
34629
|
-
return (_textJson$elements$0$ = toJson((0, import_xml.default)(formatter$
|
|
36167
|
+
return (_textJson$elements$0$ = toJson((0, import_xml.default)(formatter$2.format(new Text({ text })))).elements[0].elements) !== null && _textJson$elements$0$ !== void 0 ? _textJson$elements$0$ : [];
|
|
34630
36168
|
};
|
|
34631
36169
|
/**
|
|
34632
36170
|
* Adds xml:space="preserve" attribute to an element.
|
|
@@ -34761,6 +36299,11 @@ var PatchType = {
|
|
|
34761
36299
|
/** Replace content within paragraphs (inline replacement) */
|
|
34762
36300
|
PARAGRAPH: "paragraph",
|
|
34763
36301
|
/**
|
|
36302
|
+
* Repeat the rows of a table that hold the placeholder's fields, such as `{{items.name}}`, once for each row of
|
|
36303
|
+
* data. See {@link TableRowsPatch}
|
|
36304
|
+
*/
|
|
36305
|
+
TABLE_ROWS: "tableRows",
|
|
36306
|
+
/**
|
|
34764
36307
|
* Change a drawing whose alt text holds the placeholder, and the parts it refers to, such as the data of a chart made
|
|
34765
36308
|
* in Word. See {@link DrawingPatch}
|
|
34766
36309
|
*/
|
|
@@ -35074,6 +36617,291 @@ var patchDrawings = ({ parts, binaryParts, file, patches, delimiters }, createCo
|
|
|
35074
36617
|
for (const { drawing, patch } of found) patch.patch(drawing, createTemplatePackage(parts, binaryParts, file, createContext(drawing.part.path)));
|
|
35075
36618
|
};
|
|
35076
36619
|
//#endregion
|
|
36620
|
+
//#region src/patcher/notes.ts
|
|
36621
|
+
/**
|
|
36622
|
+
* Footnotes and endnotes for content inserted into an existing document.
|
|
36623
|
+
*
|
|
36624
|
+
* @module
|
|
36625
|
+
*/
|
|
36626
|
+
var formatter$1 = new Formatter();
|
|
36627
|
+
var DOCUMENT_PATH = "word/document.xml";
|
|
36628
|
+
var FOOTNOTES = {
|
|
36629
|
+
path: "word/footnotes.xml",
|
|
36630
|
+
rootName: "w:footnotes",
|
|
36631
|
+
noteName: "w:footnote",
|
|
36632
|
+
referenceName: "w:footnoteReference",
|
|
36633
|
+
contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml",
|
|
36634
|
+
relationshipType: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
|
|
36635
|
+
create: {
|
|
36636
|
+
part: () => new FootNotes(),
|
|
36637
|
+
mark: () => new FootnoteRefRun(),
|
|
36638
|
+
styles: () => [
|
|
36639
|
+
new FootnoteText({}),
|
|
36640
|
+
new FootnoteTextChar({}),
|
|
36641
|
+
new FootnoteReferenceStyle({})
|
|
36642
|
+
]
|
|
36643
|
+
}
|
|
36644
|
+
};
|
|
36645
|
+
var ENDNOTES = {
|
|
36646
|
+
path: "word/endnotes.xml",
|
|
36647
|
+
rootName: "w:endnotes",
|
|
36648
|
+
noteName: "w:endnote",
|
|
36649
|
+
referenceName: "w:endnoteReference",
|
|
36650
|
+
contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml",
|
|
36651
|
+
relationshipType: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes",
|
|
36652
|
+
create: {
|
|
36653
|
+
part: () => new Endnotes(),
|
|
36654
|
+
mark: () => new EndnoteRefRun(),
|
|
36655
|
+
styles: () => [
|
|
36656
|
+
new EndnoteText({}),
|
|
36657
|
+
new EndnoteTextChar({}),
|
|
36658
|
+
new EndnoteReferenceStyle({})
|
|
36659
|
+
]
|
|
36660
|
+
}
|
|
36661
|
+
};
|
|
36662
|
+
var formatElement = (component, context) => toJson((0, import_xml.default)(formatter$1.format(component, context))).elements[0];
|
|
36663
|
+
var findIds = (element, names) => {
|
|
36664
|
+
var _element$name, _element$attributes, _element$elements;
|
|
36665
|
+
const id = names.includes((_element$name = element.name) !== null && _element$name !== void 0 ? _element$name : "") ? Number((_element$attributes = element.attributes) === null || _element$attributes === void 0 ? void 0 : _element$attributes["w:id"]) : NaN;
|
|
36666
|
+
return [...Number.isInteger(id) ? [id] : [], ...((_element$elements = element.elements) !== null && _element$elements !== void 0 ? _element$elements : []).flatMap((child) => findIds(child, names))];
|
|
36667
|
+
};
|
|
36668
|
+
var withMark = (paragraph, mark) => {
|
|
36669
|
+
var _paragraph$elements, _elements$;
|
|
36670
|
+
const elements = (_paragraph$elements = paragraph.elements) !== null && _paragraph$elements !== void 0 ? _paragraph$elements : [];
|
|
36671
|
+
const index = ((_elements$ = elements[0]) === null || _elements$ === void 0 ? void 0 : _elements$.name) === "w:pPr" ? 1 : 0;
|
|
36672
|
+
return _objectSpread2(_objectSpread2({}, paragraph), {}, { elements: [
|
|
36673
|
+
...elements.slice(0, index),
|
|
36674
|
+
mark,
|
|
36675
|
+
...elements.slice(index)
|
|
36676
|
+
] });
|
|
36677
|
+
};
|
|
36678
|
+
var patchNotesOfKind = (kind, notes, parts, { createContext, addContentTypeOverride, renumberBookmarks }) => {
|
|
36679
|
+
const givenNotes = new Map(Object.entries(notes).map(([id, note]) => [Number(id), note]));
|
|
36680
|
+
const noteOfId = /* @__PURE__ */ new Map();
|
|
36681
|
+
let highestId;
|
|
36682
|
+
const renumber = (element) => {
|
|
36683
|
+
var _element$attributes2, _highestId;
|
|
36684
|
+
const note = element.name === kind.referenceName ? givenNotes.get(Number((_element$attributes2 = element.attributes) === null || _element$attributes2 === void 0 ? void 0 : _element$attributes2["w:id"])) : void 0;
|
|
36685
|
+
if (note === void 0) return element.elements === void 0 ? element : _objectSpread2(_objectSpread2({}, element), {}, { elements: element.elements.map(renumber) });
|
|
36686
|
+
highestId = ((_highestId = highestId) !== null && _highestId !== void 0 ? _highestId : [...parts.values()].flatMap((part) => findIds(part, [kind.noteName, kind.referenceName])).reduce((highest, id) => Math.max(highest, id), 0)) + 1;
|
|
36687
|
+
noteOfId.set(highestId, note);
|
|
36688
|
+
return _objectSpread2(_objectSpread2({}, element), {}, { attributes: _objectSpread2(_objectSpread2({}, element.attributes), {}, { "w:id": String(highestId) }) });
|
|
36689
|
+
};
|
|
36690
|
+
const findOrAddPart = () => {
|
|
36691
|
+
var _parts$get;
|
|
36692
|
+
const relationship = getFirstLevelElements((_parts$get = parts.get(relationshipsPathOf(DOCUMENT_PATH))) !== null && _parts$get !== void 0 ? _parts$get : {}, "Relationships").find((element) => {
|
|
36693
|
+
var _element$attributes3;
|
|
36694
|
+
return ((_element$attributes3 = element.attributes) === null || _element$attributes3 === void 0 ? void 0 : _element$attributes3.Type) === kind.relationshipType;
|
|
36695
|
+
});
|
|
36696
|
+
const path = relationship ? resolveTarget(DOCUMENT_PATH, String(relationship.attributes.Target)) : kind.path;
|
|
36697
|
+
if (!parts.has(path)) {
|
|
36698
|
+
parts.set(path, {
|
|
36699
|
+
declaration: { attributes: {
|
|
36700
|
+
version: "1.0",
|
|
36701
|
+
encoding: "UTF-8",
|
|
36702
|
+
standalone: "yes"
|
|
36703
|
+
} },
|
|
36704
|
+
elements: [formatElement(kind.create.part(), createContext(path))]
|
|
36705
|
+
});
|
|
36706
|
+
addContentTypeOverride(kind.contentType, `/${path}`);
|
|
36707
|
+
}
|
|
36708
|
+
if (!relationship) createContext(DOCUMENT_PATH).viewWrapper.Relationships.addRelationship(uniqueId(), kind.relationshipType, relativeTarget(DOCUMENT_PATH, path));
|
|
36709
|
+
return path;
|
|
36710
|
+
};
|
|
36711
|
+
const write = () => {
|
|
36712
|
+
if (noteOfId.size === 0) return;
|
|
36713
|
+
const path = findOrAddPart();
|
|
36714
|
+
const context = createContext(path);
|
|
36715
|
+
const contentOfNote = new Map([...new Set(noteOfId.values())].map((note) => {
|
|
36716
|
+
const mark = formatElement(kind.create.mark(), context);
|
|
36717
|
+
return [note, renumberBookmarks(note.children.map((paragraph) => formatElement(paragraph, context)).map((paragraph, index) => index === 0 ? withMark(paragraph, mark) : paragraph))];
|
|
36718
|
+
}));
|
|
36719
|
+
getFirstLevelElements(parts.get(path), kind.rootName).push(...[...noteOfId].map(([id, note]) => ({
|
|
36720
|
+
type: "element",
|
|
36721
|
+
name: kind.noteName,
|
|
36722
|
+
attributes: { "w:id": String(id) },
|
|
36723
|
+
elements: [...contentOfNote.get(note)]
|
|
36724
|
+
})));
|
|
36725
|
+
const stylesPart = parts.get("word/styles.xml");
|
|
36726
|
+
if (stylesPart) {
|
|
36727
|
+
const styles = getFirstLevelElements(stylesPart, "w:styles");
|
|
36728
|
+
const styleIds = new Set(styles.map((style) => {
|
|
36729
|
+
var _style$attributes;
|
|
36730
|
+
return (_style$attributes = style.attributes) === null || _style$attributes === void 0 ? void 0 : _style$attributes["w:styleId"];
|
|
36731
|
+
}));
|
|
36732
|
+
styles.push(...kind.create.styles().map((style) => formatElement(style, context)).filter((style) => {
|
|
36733
|
+
var _style$attributes2;
|
|
36734
|
+
return !styleIds.has((_style$attributes2 = style.attributes) === null || _style$attributes2 === void 0 ? void 0 : _style$attributes2["w:styleId"]);
|
|
36735
|
+
}));
|
|
36736
|
+
}
|
|
36737
|
+
};
|
|
36738
|
+
return {
|
|
36739
|
+
renumber: (elements) => elements.map(renumber),
|
|
36740
|
+
write
|
|
36741
|
+
};
|
|
36742
|
+
};
|
|
36743
|
+
/**
|
|
36744
|
+
* Creates the writer of the footnotes and endnotes that patches refer to.
|
|
36745
|
+
*
|
|
36746
|
+
* A patch refers to a note with a reference run, such as `new FootnoteReferenceRun(1)`, whose id is the note's in
|
|
36747
|
+
* `footnotes`. Only references to the given notes are renumbered, and only the notes that are referred to are written.
|
|
36748
|
+
*
|
|
36749
|
+
* @param notes - The footnotes and endnotes, by the id the patches' reference runs are given
|
|
36750
|
+
* @param parts - The document's XML parts, parsed, by their paths, which the notes are written to
|
|
36751
|
+
* @param helpers - The patcher's helpers for what the notes refer to
|
|
36752
|
+
*/
|
|
36753
|
+
var patchNotes = ({ footnotes = {}, endnotes = {} }, parts, helpers) => {
|
|
36754
|
+
const patchers = [patchNotesOfKind(FOOTNOTES, footnotes, parts, helpers), patchNotesOfKind(ENDNOTES, endnotes, parts, helpers)];
|
|
36755
|
+
return {
|
|
36756
|
+
renumber: (elements) => patchers.reduce((renumbered, patcher) => patcher.renumber(renumbered), elements),
|
|
36757
|
+
write: () => {
|
|
36758
|
+
for (const patcher of patchers) patcher.write();
|
|
36759
|
+
}
|
|
36760
|
+
};
|
|
36761
|
+
};
|
|
36762
|
+
//#endregion
|
|
36763
|
+
//#region src/patcher/page-numbers.ts
|
|
36764
|
+
/**
|
|
36765
|
+
* Page numbers written into a template's fields once `patchDocument` has patched it, from an estimate of its pages, as
|
|
36766
|
+
* a document's are when it is written with `pageNumbers`.
|
|
36767
|
+
*
|
|
36768
|
+
* @module
|
|
36769
|
+
*/
|
|
36770
|
+
/** The elements of a template, as xml-js parses them */
|
|
36771
|
+
var PARSED = {
|
|
36772
|
+
nameOf: (element) => element.type === "element" ? element.name : void 0,
|
|
36773
|
+
contentOf: (element) => element.elements,
|
|
36774
|
+
attributeOf: (element, attribute) => {
|
|
36775
|
+
var _element$attributes;
|
|
36776
|
+
return (_element$attributes = element.attributes) === null || _element$attributes === void 0 ? void 0 : _element$attributes[attribute];
|
|
36777
|
+
},
|
|
36778
|
+
textOf: (element) => {
|
|
36779
|
+
var _element$elements;
|
|
36780
|
+
return ((_element$elements = element.elements) !== null && _element$elements !== void 0 ? _element$elements : []).filter(({ type }) => type === "text").map(({ text }) => String(text)).join("");
|
|
36781
|
+
},
|
|
36782
|
+
textElement: (text) => ({
|
|
36783
|
+
type: "element",
|
|
36784
|
+
name: "w:t",
|
|
36785
|
+
attributes: { "xml:space": "preserve" },
|
|
36786
|
+
elements: [{
|
|
36787
|
+
type: "text",
|
|
36788
|
+
text
|
|
36789
|
+
}]
|
|
36790
|
+
}),
|
|
36791
|
+
writeClean: (begin, instruction) => {
|
|
36792
|
+
var _begin$attributes;
|
|
36793
|
+
if (/^\s*(PAGEREF|TOC)\b/i.test(instruction) && ((_begin$attributes = begin.attributes) === null || _begin$attributes === void 0 ? void 0 : _begin$attributes["w:dirty"]) !== void 0) begin.attributes = Object.fromEntries(Object.entries(begin.attributes).filter(([key]) => key !== "w:dirty"));
|
|
36794
|
+
},
|
|
36795
|
+
setSimpleFieldResult: (element, text) => {
|
|
36796
|
+
element.elements = [{
|
|
36797
|
+
type: "element",
|
|
36798
|
+
name: "w:r",
|
|
36799
|
+
elements: [PARSED.textElement(text)]
|
|
36800
|
+
}];
|
|
36801
|
+
}
|
|
36802
|
+
};
|
|
36803
|
+
var DOCUMENT = "word/document.xml";
|
|
36804
|
+
var IMPORT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk";
|
|
36805
|
+
var ZIP = [
|
|
36806
|
+
80,
|
|
36807
|
+
75,
|
|
36808
|
+
3,
|
|
36809
|
+
4
|
|
36810
|
+
];
|
|
36811
|
+
/** A package's parts, from a zip file: its XML parts parsed, as patchDocument parses a template's, and the rest as bytes */
|
|
36812
|
+
var readPackage = function() {
|
|
36813
|
+
var _ref = _asyncToGenerator(function* (data) {
|
|
36814
|
+
if (!ZIP.every((byte, index) => data[index] === byte)) return;
|
|
36815
|
+
try {
|
|
36816
|
+
const zip = yield import_jszip_min.default.loadAsync(data);
|
|
36817
|
+
const parts = /* @__PURE__ */ new Map();
|
|
36818
|
+
const binaryParts = /* @__PURE__ */ new Map();
|
|
36819
|
+
for (const [path, file] of Object.entries(zip.files)) {
|
|
36820
|
+
if (file.dir) continue;
|
|
36821
|
+
if (/\.(xml|rels)$/.test(path)) parts.set(path, toJson(yield file.async("text")));
|
|
36822
|
+
else binaryParts.set(path, yield file.async("uint8array"));
|
|
36823
|
+
}
|
|
36824
|
+
const importedDocuments = yield readImportedDocuments(parts, binaryParts);
|
|
36825
|
+
return _objectSpread2({
|
|
36826
|
+
parts,
|
|
36827
|
+
binaryParts
|
|
36828
|
+
}, importedDocuments.size > 0 ? { importedDocuments } : {});
|
|
36829
|
+
} catch (_unused) {
|
|
36830
|
+
return;
|
|
36831
|
+
}
|
|
36832
|
+
});
|
|
36833
|
+
return function readPackage(_x) {
|
|
36834
|
+
return _ref.apply(this, arguments);
|
|
36835
|
+
};
|
|
36836
|
+
}();
|
|
36837
|
+
/**
|
|
36838
|
+
* Each .docx the parts of a package import (`w:altChunk`), by its path: the parts the relationships of each part refer to
|
|
36839
|
+
* as imported, which are zip files that can be read. Those in other formats, such as HTML, are left to the layout.
|
|
36840
|
+
*/
|
|
36841
|
+
var readImportedDocuments = function() {
|
|
36842
|
+
var _ref2 = _asyncToGenerator(function* (parts, binaryParts) {
|
|
36843
|
+
const imported = /* @__PURE__ */ new Map();
|
|
36844
|
+
for (const [path, relationships] of parts) {
|
|
36845
|
+
var _rootOf$elements, _rootOf;
|
|
36846
|
+
if (!path.endsWith(".rels")) continue;
|
|
36847
|
+
for (const { attributes = {} } of (_rootOf$elements = (_rootOf = rootOf(relationships)) === null || _rootOf === void 0 ? void 0 : _rootOf.elements) !== null && _rootOf$elements !== void 0 ? _rootOf$elements : []) {
|
|
36848
|
+
const target = resolveTarget(sourceOfRelationships(path), String(attributes.Target));
|
|
36849
|
+
const data = binaryParts.get(target);
|
|
36850
|
+
const read = attributes.Type === IMPORT && attributes.TargetMode !== "External" && data ? yield readPackage(data) : void 0;
|
|
36851
|
+
if (read) imported.set(target, read);
|
|
36852
|
+
}
|
|
36853
|
+
}
|
|
36854
|
+
return imported;
|
|
36855
|
+
});
|
|
36856
|
+
return function readImportedDocuments(_x2, _x3) {
|
|
36857
|
+
return _ref2.apply(this, arguments);
|
|
36858
|
+
};
|
|
36859
|
+
}();
|
|
36860
|
+
/** The root element of a part, such as `w:document` */
|
|
36861
|
+
var rootOf = (part) => {
|
|
36862
|
+
var _part$elements;
|
|
36863
|
+
return part === null || part === void 0 || (_part$elements = part.elements) === null || _part$elements === void 0 ? void 0 : _part$elements.find(({ type }) => type === "element");
|
|
36864
|
+
};
|
|
36865
|
+
/**
|
|
36866
|
+
* Writes the page numbers the estimator works out for a patched template into the fields of its body, headers and
|
|
36867
|
+
* footers that show them: its PAGEREF fields, in its tables of contents and elsewhere, and its NUMPAGES and SECTIONPAGES
|
|
36868
|
+
* fields. The results a field was written with are those of the template before it was patched, so a field whose number
|
|
36869
|
+
* the estimator doesn't work out is left blank, as it is in a document written with `pageNumbers`. Page references and
|
|
36870
|
+
* tables of contents are written clean, as they are in a document written with `pageNumbers`, so Word shows their numbers
|
|
36871
|
+
* as they are and doesn't ask to update the fields.
|
|
36872
|
+
*
|
|
36873
|
+
* The documents it imports (`w:altChunk`) as .docx files are unzipped for the estimator to read, as Word turns them into
|
|
36874
|
+
* paragraphs and tables of the template's own when it opens it.
|
|
36875
|
+
*
|
|
36876
|
+
* @param parts - The template's XML parts, parsed, by their paths, which are changed in place
|
|
36877
|
+
* @param binaryParts - Its other parts, by their paths, for the estimator to read the fonts it embeds and the documents
|
|
36878
|
+
* it imports
|
|
36879
|
+
*/
|
|
36880
|
+
var fillTemplatePageNumbers = function() {
|
|
36881
|
+
var _ref3 = _asyncToGenerator(function* (parts, estimator, binaryParts = /* @__PURE__ */ new Map()) {
|
|
36882
|
+
var _rootOf$elements2, _rootOf2;
|
|
36883
|
+
const document = rootOf(parts.get(DOCUMENT));
|
|
36884
|
+
if (!document) return;
|
|
36885
|
+
const importedDocuments = yield readImportedDocuments(parts, binaryParts);
|
|
36886
|
+
const estimate = estimator(_objectSpread2({
|
|
36887
|
+
parts,
|
|
36888
|
+
binaryParts
|
|
36889
|
+
}, importedDocuments.size > 0 ? { importedDocuments } : {}));
|
|
36890
|
+
const partPageCounts = fillBodyFields(PARSED, document, estimate, { blank: true });
|
|
36891
|
+
const relationships = (_rootOf$elements2 = (_rootOf2 = rootOf(parts.get(relationshipsPathOf(DOCUMENT)))) === null || _rootOf2 === void 0 ? void 0 : _rootOf2.elements) !== null && _rootOf$elements2 !== void 0 ? _rootOf$elements2 : [];
|
|
36892
|
+
for (const { attributes = {} } of relationships) {
|
|
36893
|
+
const part = /\/(header|footer)$/.test(String(attributes.Type)) ? rootOf(parts.get(resolveTarget(DOCUMENT, String(attributes.Target)))) : void 0;
|
|
36894
|
+
if (part) fillPartFields(PARSED, part, estimate, {
|
|
36895
|
+
blank: true,
|
|
36896
|
+
sectionPageCount: partPageCounts.get(String(attributes.Id))
|
|
36897
|
+
});
|
|
36898
|
+
}
|
|
36899
|
+
});
|
|
36900
|
+
return function fillTemplatePageNumbers(_x4, _x5) {
|
|
36901
|
+
return _ref3.apply(this, arguments);
|
|
36902
|
+
};
|
|
36903
|
+
}();
|
|
36904
|
+
//#endregion
|
|
35077
36905
|
//#region src/patcher/paragraph-split-inject.ts
|
|
35078
36906
|
var TokenNotFoundError = class extends Error {
|
|
35079
36907
|
constructor(token) {
|
|
@@ -35375,9 +37203,11 @@ var SPLIT_TOKEN = "
|
|
|
35375
37203
|
* @param context - The document context for formatting
|
|
35376
37204
|
* @param keepOriginalStyles - Whether to preserve original text formatting
|
|
35377
37205
|
* @param recursive - Whether to replace every occurrence in a paragraph, rather than only the first
|
|
37206
|
+
* @param renumberIds - Renumbers the bookmarks and note references the patch inserts, so they don't take an id the
|
|
37207
|
+
* document uses
|
|
35378
37208
|
* @returns Result containing the modified element and whether a replacement occurred
|
|
35379
37209
|
*/
|
|
35380
|
-
var replacer = ({ json, patch, patchText, context, keepOriginalStyles = true, recursive = true }) => {
|
|
37210
|
+
var replacer = ({ json, patch, patchText, context, keepOriginalStyles = true, recursive = true, renumberIds = (elements) => elements }) => {
|
|
35381
37211
|
const renderedParagraphs = findLocationOfText(json, patchText);
|
|
35382
37212
|
if (renderedParagraphs.length === 0) return {
|
|
35383
37213
|
element: json,
|
|
@@ -35387,9 +37217,15 @@ var replacer = ({ json, patch, patchText, context, keepOriginalStyles = true, re
|
|
|
35387
37217
|
const paragraphsToPatch = patch.type === PatchType.DOCUMENT ? withoutNestedParagraphs(paragraphsInPatchOrder) : paragraphsInPatchOrder;
|
|
35388
37218
|
for (const renderedParagraph of paragraphsToPatch) switch (patch.type) {
|
|
35389
37219
|
case PatchType.DOCUMENT: {
|
|
37220
|
+
var _children;
|
|
35390
37221
|
const parentElement = goToParentElementFromPath(json, renderedParagraph.pathToParagraph);
|
|
35391
37222
|
const elementIndex = getLastElementIndexFromPath(renderedParagraph.pathToParagraph);
|
|
35392
|
-
|
|
37223
|
+
const children = formatChildren(patch, context, renumberIds);
|
|
37224
|
+
const endParagraph = parentElement.name === "w:tc" && elementIndex === parentElement.elements.length - 1 && ((_children = children[children.length - 1]) === null || _children === void 0 ? void 0 : _children.name) !== "w:p" ? [{
|
|
37225
|
+
type: "element",
|
|
37226
|
+
name: "w:p"
|
|
37227
|
+
}] : [];
|
|
37228
|
+
parentElement.elements.splice(elementIndex, 1, ...children, ...endParagraph);
|
|
35393
37229
|
break;
|
|
35394
37230
|
}
|
|
35395
37231
|
case PatchType.PARAGRAPH:
|
|
@@ -35403,7 +37239,7 @@ var replacer = ({ json, patch, patchText, context, keepOriginalStyles = true, re
|
|
|
35403
37239
|
renderedParagraph: paragraph,
|
|
35404
37240
|
patchText,
|
|
35405
37241
|
fromIndex,
|
|
35406
|
-
children: formatChildren(patch, context),
|
|
37242
|
+
children: formatChildren(patch, context, renumberIds),
|
|
35407
37243
|
keepOriginalStyles
|
|
35408
37244
|
});
|
|
35409
37245
|
paragraph = renderParagraphNode({
|
|
@@ -35421,10 +37257,10 @@ var replacer = ({ json, patch, patchText, context, keepOriginalStyles = true, re
|
|
|
35421
37257
|
didFindOccurrence: true
|
|
35422
37258
|
};
|
|
35423
37259
|
};
|
|
35424
|
-
var formatChildren = (patch, context) => patch.children.flatMap((c) => {
|
|
37260
|
+
var formatChildren = (patch, context, renumberIds) => renumberIds(patch.children.flatMap((c) => {
|
|
35425
37261
|
var _c$writtenAs;
|
|
35426
37262
|
return (_c$writtenAs = c.writtenAs) !== null && _c$writtenAs !== void 0 ? _c$writtenAs : c;
|
|
35427
|
-
}).map((c) => toJson((0, import_xml.default)(formatter.format(c, context)))).map((c) => c.elements[0]);
|
|
37263
|
+
}).map((c) => toJson((0, import_xml.default)(formatter.format(c, context)))).map((c) => c.elements[0]));
|
|
35428
37264
|
/**
|
|
35429
37265
|
* Replaces the first occurrence of the placeholder from `fromIndex` on, splitting the run it starts in.
|
|
35430
37266
|
*
|
|
@@ -35442,12 +37278,21 @@ var replaceOccurrenceInParagraph = ({ paragraphElement, renderedParagraph, patch
|
|
|
35442
37278
|
const runElementToBeReplaced = paragraphElement.elements[index];
|
|
35443
37279
|
const { left, right } = splitRunElement(runElementToBeReplaced, SPLIT_TOKEN);
|
|
35444
37280
|
const runProperties = runElementToBeReplaced.elements.find((e) => e.type === "element" && e.name === "w:rPr");
|
|
35445
|
-
const newRunElements = keepOriginalStyles && runProperties ? children.map((e) =>
|
|
37281
|
+
const newRunElements = keepOriginalStyles && runProperties ? children.map((e) => withRunPropertiesOnRuns(e, runProperties)) : children;
|
|
35446
37282
|
const patchedRightElement = runProperties ? _objectSpread2(_objectSpread2({}, right), {}, { elements: [runProperties, ...right.elements] }) : right;
|
|
35447
37283
|
paragraphElement.elements.splice(index, 1, left, ...newRunElements, patchedRightElement);
|
|
35448
37284
|
return index + 1 + newRunElements.length;
|
|
35449
37285
|
};
|
|
35450
37286
|
/**
|
|
37287
|
+
* Gives the runs of inserted content the placeholder's run properties. Content such as a hyperlink can't take run
|
|
37288
|
+
* properties itself, so its runs take them, and its text is formatted as the text around it is. Runs inside a run, such
|
|
37289
|
+
* as in its text box, are that content's own, and are left alone.
|
|
37290
|
+
*/
|
|
37291
|
+
var withRunPropertiesOnRuns = (element, originalRunProperties) => {
|
|
37292
|
+
if (element.name === "w:r") return withRunProperties(element, originalRunProperties);
|
|
37293
|
+
return element.elements ? _objectSpread2(_objectSpread2({}, element), {}, { elements: element.elements.map((e) => withRunPropertiesOnRuns(e, originalRunProperties)) }) : element;
|
|
37294
|
+
};
|
|
37295
|
+
/**
|
|
35451
37296
|
* Gives a run the placeholder's run properties. A run can only have one w:rPr, so properties the run
|
|
35452
37297
|
* sets itself are kept, and the placeholder's fill in the rest.
|
|
35453
37298
|
*/
|
|
@@ -35539,6 +37384,118 @@ var goToElementFromPath = (json, path) => {
|
|
|
35539
37384
|
var goToParentElementFromPath = (json, path) => goToElementFromPath(json, path.slice(0, path.length - 1));
|
|
35540
37385
|
var getLastElementIndexFromPath = (path) => path[path.length - 1];
|
|
35541
37386
|
//#endregion
|
|
37387
|
+
//#region src/patcher/table-rows.ts
|
|
37388
|
+
var EMPTY = {
|
|
37389
|
+
type: PatchType.PARAGRAPH,
|
|
37390
|
+
children: []
|
|
37391
|
+
};
|
|
37392
|
+
/**
|
|
37393
|
+
* Repeats the rows of the tables in an element that hold the patch's fields, such as `{{items.name}}` for the key
|
|
37394
|
+
* "items", once for each of the patch's rows, and patches the fields in each copy with the row's patches.
|
|
37395
|
+
*
|
|
37396
|
+
* @param json - The element to patch, such as a part's root
|
|
37397
|
+
* @param key - The patch's key, such as "items"
|
|
37398
|
+
* @param patch - The rows of data
|
|
37399
|
+
* @param delimiters - The placeholders' delimiters
|
|
37400
|
+
* @param patchPlaceholder - Patches a field in a copy of the rows, as `patchDocument` patches a placeholder
|
|
37401
|
+
*/
|
|
37402
|
+
var patchTableRows = ({ json, key, patch, delimiters: { start, end }, patchPlaceholder }) => {
|
|
37403
|
+
const fieldStart = `${start}${key}.`;
|
|
37404
|
+
for (const rows of findRowsToRepeat(json, fieldStart)) {
|
|
37405
|
+
const fields = fieldsIn(rows.elements, fieldStart, end);
|
|
37406
|
+
const copies = patch.rows.flatMap((row, index) => {
|
|
37407
|
+
const copy = {
|
|
37408
|
+
type: "element",
|
|
37409
|
+
name: "w:tbl",
|
|
37410
|
+
elements: [...index === 0 ? rows.elements.map(copyOf) : withoutIds(rows.elements)]
|
|
37411
|
+
};
|
|
37412
|
+
const fieldPatches = new Map(Object.entries(row).flatMap(([field, p]) => p === void 0 ? [] : [[field, p]]));
|
|
37413
|
+
for (const [field, fieldPatch] of fieldPatches) patchPlaceholder(copy, `${key}.${field}`, fieldPatch);
|
|
37414
|
+
for (const field of fields.filter((f) => !fieldPatches.has(f))) patchPlaceholder(copy, `${key}.${field}`, EMPTY);
|
|
37415
|
+
return copy.elements;
|
|
37416
|
+
});
|
|
37417
|
+
rows.parent.elements.splice(rows.parent.elements.indexOf(rows.elements[0]), rows.elements.length, ...copies);
|
|
37418
|
+
if (rows.table && !hasRows(rows.table.element)) rows.table.parent.elements.splice(rows.table.parent.elements.indexOf(rows.table.element), 1);
|
|
37419
|
+
}
|
|
37420
|
+
};
|
|
37421
|
+
/**
|
|
37422
|
+
* The rows that hold a field, grouped into the rows next to each other in a table, which are repeated together.
|
|
37423
|
+
*/
|
|
37424
|
+
var findRowsToRepeat = (json, fieldStart) => {
|
|
37425
|
+
const found = findLocationOfText(json, fieldStart).flatMap((paragraph) => {
|
|
37426
|
+
const row = rowHolding(json, paragraph.pathToParagraph);
|
|
37427
|
+
return row ? [row] : [];
|
|
37428
|
+
});
|
|
37429
|
+
const rows = found.filter((row) => !found.some((other) => isInside(row.path, other.path))).filter((row, index, all) => all.findIndex((other) => other.row === row.row) === index);
|
|
37430
|
+
return [...new Set(rows.map((row) => row.parent))].flatMap((parent) => {
|
|
37431
|
+
const siblingRows = parent.elements.filter((e) => e.name === "w:tr");
|
|
37432
|
+
const positions = rows.filter((row) => row.parent === parent).map((row) => siblingRows.indexOf(row.row)).sort((a, b) => a - b);
|
|
37433
|
+
const { table } = rows.find((row) => row.parent === parent);
|
|
37434
|
+
return positions.reduce((all, position) => {
|
|
37435
|
+
const previous = all[all.length - 1];
|
|
37436
|
+
return (previous === null || previous === void 0 ? void 0 : previous[previous.length - 1]) === position - 1 ? [...all.slice(0, -1), [...previous, position]] : [...all, [position]];
|
|
37437
|
+
}, []).map((group) => {
|
|
37438
|
+
const first = parent.elements.indexOf(siblingRows[group[0]]);
|
|
37439
|
+
const last = parent.elements.indexOf(siblingRows[group[group.length - 1]]);
|
|
37440
|
+
return {
|
|
37441
|
+
parent,
|
|
37442
|
+
table,
|
|
37443
|
+
elements: parent.elements.slice(first, last + 1)
|
|
37444
|
+
};
|
|
37445
|
+
});
|
|
37446
|
+
});
|
|
37447
|
+
};
|
|
37448
|
+
/**
|
|
37449
|
+
* The row nearest to the paragraph at the end of the path that holds it, if it is in a table.
|
|
37450
|
+
*/
|
|
37451
|
+
var rowHolding = (json, pathToParagraph) => {
|
|
37452
|
+
let element = json;
|
|
37453
|
+
let row;
|
|
37454
|
+
let table;
|
|
37455
|
+
for (let i = 1; i < pathToParagraph.length; i++) {
|
|
37456
|
+
const child = element.elements[pathToParagraph[i]];
|
|
37457
|
+
if (child.name === "w:tbl") table = {
|
|
37458
|
+
element: child,
|
|
37459
|
+
parent: element
|
|
37460
|
+
};
|
|
37461
|
+
if (child.name === "w:tr") row = {
|
|
37462
|
+
parent: element,
|
|
37463
|
+
table,
|
|
37464
|
+
row: child,
|
|
37465
|
+
path: pathToParagraph.slice(0, i + 1)
|
|
37466
|
+
};
|
|
37467
|
+
element = child;
|
|
37468
|
+
}
|
|
37469
|
+
return row;
|
|
37470
|
+
};
|
|
37471
|
+
var isInside = (path, ancestorPath) => path.length > ancestorPath.length && ancestorPath.every((index, i) => path[i] === index);
|
|
37472
|
+
var hasRows = (table) => {
|
|
37473
|
+
var _table$elements;
|
|
37474
|
+
return ((_table$elements = table.elements) !== null && _table$elements !== void 0 ? _table$elements : []).some((e) => e.name === "w:tr" || e.name !== "w:tblPr" && e.name !== "w:tblGrid" && hasRows(e));
|
|
37475
|
+
};
|
|
37476
|
+
/**
|
|
37477
|
+
* The names of the fields in the elements, such as "name" for `{{items.name}}`.
|
|
37478
|
+
*/
|
|
37479
|
+
var fieldsIn = (elements, fieldStart, end) => {
|
|
37480
|
+
const fields = findLocationOfText({ elements: [...elements] }, fieldStart).flatMap(({ text }) => text.split(fieldStart).slice(1).flatMap((after) => {
|
|
37481
|
+
const fieldEnd = after.indexOf(end);
|
|
37482
|
+
return fieldEnd > 0 ? [after.slice(0, fieldEnd)] : [];
|
|
37483
|
+
}));
|
|
37484
|
+
return [...new Set(fields)];
|
|
37485
|
+
};
|
|
37486
|
+
var copyOf = (element) => JSON.parse(JSON.stringify(element));
|
|
37487
|
+
var ATTRIBUTES_TO_REMOVE = ["w14:paraId", "w14:textId"];
|
|
37488
|
+
var ELEMENTS_TO_REMOVE = ["w:bookmarkStart", "w:bookmarkEnd"];
|
|
37489
|
+
/**
|
|
37490
|
+
* A copy of elements without what must be unique in a document, so they can be in the document more than once.
|
|
37491
|
+
*
|
|
37492
|
+
* @param parent - The elements' parent, as a content control's id is an element in its properties
|
|
37493
|
+
*/
|
|
37494
|
+
var withoutIds = (elements, parent) => elements.filter((e) => {
|
|
37495
|
+
var _e$name;
|
|
37496
|
+
return !ELEMENTS_TO_REMOVE.includes((_e$name = e.name) !== null && _e$name !== void 0 ? _e$name : "") && !((parent === null || parent === void 0 ? void 0 : parent.name) === "w:sdtPr" && e.name === "w:id");
|
|
37497
|
+
}).map((e) => _objectSpread2(_objectSpread2(_objectSpread2({}, e), e.attributes === void 0 ? {} : { attributes: Object.fromEntries(Object.entries(e.attributes).filter(([name]) => !ATTRIBUTES_TO_REMOVE.includes(name))) }), e.elements === void 0 ? {} : { elements: [...withoutIds(e.elements, e)] }));
|
|
37498
|
+
//#endregion
|
|
35542
37499
|
//#region src/patcher/theme-colors.ts
|
|
35543
37500
|
var THEME_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
|
|
35544
37501
|
var COLOR_NAMES = /* @__PURE__ */ new Map([
|
|
@@ -35597,7 +37554,7 @@ var readTheme = function() {
|
|
|
35597
37554
|
return ((_item$attributes3 = item.attributes) === null || _item$attributes3 === void 0 ? void 0 : _item$attributes3.Type) === THEME_RELATIONSHIP_TYPE;
|
|
35598
37555
|
});
|
|
35599
37556
|
const target = theme === null || theme === void 0 || (_theme$attributes = theme.attributes) === null || _theme$attributes === void 0 ? void 0 : _theme$attributes.Target;
|
|
35600
|
-
return typeof target === "string" ? readPart(zip,
|
|
37557
|
+
return typeof target === "string" ? readPart(zip, resolveTarget("word/document.xml", target)) : void 0;
|
|
35601
37558
|
});
|
|
35602
37559
|
return function readTheme(_x3) {
|
|
35603
37560
|
return _ref2.apply(this, arguments);
|
|
@@ -35636,6 +37593,23 @@ var readThemeColors = function() {
|
|
|
35636
37593
|
*
|
|
35637
37594
|
* @module
|
|
35638
37595
|
*/
|
|
37596
|
+
/**
|
|
37597
|
+
* Throws if a patch, or a patch for a field of one of its rows, isn't one `patchDocument` can apply, such as a patch
|
|
37598
|
+
* from JavaScript without its children.
|
|
37599
|
+
*
|
|
37600
|
+
* @param key - The patch's key, such as "items", or for a field of a row, such as "items.name"
|
|
37601
|
+
* @param inTableRow - Whether the patch is for a field of a row, where a drawing patch can't be
|
|
37602
|
+
*/
|
|
37603
|
+
var assertValidPatch = (key, patch, { inTableRow }) => {
|
|
37604
|
+
if ((patch === null || patch === void 0 ? void 0 : patch.type) === PatchType.TABLE_ROWS && Array.isArray(patch.rows)) {
|
|
37605
|
+
for (const row of patch.rows) {
|
|
37606
|
+
if (typeof row !== "object" || row === null) throw new Error(`Invalid patch "${key}". Expected each of its rows to be an object of patches, by the name of their field`);
|
|
37607
|
+
for (const [field, fieldPatch] of Object.entries(row)) if (fieldPatch !== void 0) assertValidPatch(`${key}.${field}`, fieldPatch, { inTableRow: true });
|
|
37608
|
+
}
|
|
37609
|
+
return;
|
|
37610
|
+
}
|
|
37611
|
+
if (!((patch === null || patch === void 0 ? void 0 : patch.type) === PatchType.DRAWING ? !inTableRow && typeof patch.patch === "function" : (patch === null || patch === void 0 ? void 0 : patch.type) !== PatchType.TABLE_ROWS && Array.isArray(patch === null || patch === void 0 ? void 0 : patch.children))) throw new Error(`Invalid patch "${key}". Expected { type: PatchType.PARAGRAPH or PatchType.DOCUMENT, children: [...] }, ${inTableRow ? "or { type: PatchType.TABLE_ROWS, rows: [...] }" : "{ type: PatchType.TABLE_ROWS, rows: [...] }, or a drawing patch such as ChartDataPatch from docx/charts"}`);
|
|
37612
|
+
};
|
|
35639
37613
|
var imageReplacer = new ImageReplacer();
|
|
35640
37614
|
var UTF16LE = new Uint8Array([255, 254]);
|
|
35641
37615
|
var UTF16BE = new Uint8Array([254, 255]);
|
|
@@ -35683,7 +37657,7 @@ var patchDocument = function() {
|
|
|
35683
37657
|
var _ref = _asyncToGenerator(function* ({ outputType, data, patches, keepOriginalStyles, placeholderDelimiters = {
|
|
35684
37658
|
start: "{{",
|
|
35685
37659
|
end: "}}"
|
|
35686
|
-
}, recursive = true }) {
|
|
37660
|
+
}, recursive = true, footnotes, endnotes, pageNumbers }) {
|
|
35687
37661
|
const zipContent = data instanceof import_jszip_min.default ? data : yield import_jszip_min.default.loadAsync(data);
|
|
35688
37662
|
const contexts = /* @__PURE__ */ new Map();
|
|
35689
37663
|
const themeColors = yield readThemeColors(zipContent);
|
|
@@ -35703,7 +37677,7 @@ var patchDocument = function() {
|
|
|
35703
37677
|
const binaryContentMap = /* @__PURE__ */ new Map();
|
|
35704
37678
|
if (!(placeholderDelimiters === null || placeholderDelimiters === void 0 ? void 0 : placeholderDelimiters.start.trim()) || !(placeholderDelimiters === null || placeholderDelimiters === void 0 ? void 0 : placeholderDelimiters.end.trim())) throw new Error("Both start and end delimiters must be non-empty strings.");
|
|
35705
37679
|
const { start, end } = placeholderDelimiters;
|
|
35706
|
-
for (const [key, patch] of Object.entries(patches))
|
|
37680
|
+
for (const [key, patch] of Object.entries(patches)) assertValidPatch(key, patch, { inTableRow: false });
|
|
35707
37681
|
for (const [key, value] of Object.entries(zipContent.files)) {
|
|
35708
37682
|
const binaryValue = yield value.async("uint8array");
|
|
35709
37683
|
const startBytes = binaryValue.slice(0, 2);
|
|
@@ -35732,6 +37706,7 @@ var patchDocument = function() {
|
|
|
35732
37706
|
}
|
|
35733
37707
|
map.set(key, json);
|
|
35734
37708
|
}
|
|
37709
|
+
const renumberBookmarks = renumberBookmarksAvoiding([...map.values()].flatMap(findBookmarkIds));
|
|
35735
37710
|
const createContext = (key) => ({
|
|
35736
37711
|
file,
|
|
35737
37712
|
viewWrapper: { Relationships: { addRelationship: (id, type, target, targetMode) => {
|
|
@@ -35745,6 +37720,17 @@ var patchDocument = function() {
|
|
|
35745
37720
|
} } },
|
|
35746
37721
|
stack: []
|
|
35747
37722
|
});
|
|
37723
|
+
const notes = patchNotes({
|
|
37724
|
+
footnotes,
|
|
37725
|
+
endnotes
|
|
37726
|
+
}, map, {
|
|
37727
|
+
createContext,
|
|
37728
|
+
addContentTypeOverride: (contentType, partName) => contentTypeOverrides.push({
|
|
37729
|
+
contentType,
|
|
37730
|
+
partName
|
|
37731
|
+
}),
|
|
37732
|
+
renumberBookmarks
|
|
37733
|
+
});
|
|
35748
37734
|
patchDrawings({
|
|
35749
37735
|
parts: map,
|
|
35750
37736
|
binaryParts: binaryContentMap,
|
|
@@ -35755,35 +37741,56 @@ var patchDocument = function() {
|
|
|
35755
37741
|
end
|
|
35756
37742
|
}
|
|
35757
37743
|
}, createContext);
|
|
37744
|
+
const textPatches = Object.entries(patches).flatMap(([key, patch]) => patch.type === PatchType.DRAWING ? [] : [[key, patch]]);
|
|
37745
|
+
const patchesInOrder = [...textPatches.filter(([, patch]) => patch.type === PatchType.TABLE_ROWS), ...textPatches.filter(([, patch]) => patch.type !== PatchType.TABLE_ROWS)];
|
|
35758
37746
|
for (const [key, json] of [...map]) {
|
|
35759
37747
|
if (!key.startsWith("word/") || key.endsWith(".xml.rels")) continue;
|
|
35760
37748
|
const context = createContext(key);
|
|
35761
37749
|
contexts.set(key, context);
|
|
35762
|
-
|
|
35763
|
-
if (patchValue.type === PatchType.
|
|
35764
|
-
|
|
35765
|
-
|
|
35766
|
-
|
|
35767
|
-
|
|
35768
|
-
|
|
35769
|
-
|
|
35770
|
-
|
|
37750
|
+
const patchPlaceholder = (element, patchKey, patchValue) => {
|
|
37751
|
+
if (patchValue.type === PatchType.TABLE_ROWS) {
|
|
37752
|
+
patchTableRows({
|
|
37753
|
+
json: element,
|
|
37754
|
+
key: patchKey,
|
|
37755
|
+
patch: patchValue,
|
|
37756
|
+
delimiters: {
|
|
37757
|
+
start,
|
|
37758
|
+
end
|
|
37759
|
+
},
|
|
37760
|
+
patchPlaceholder
|
|
37761
|
+
});
|
|
37762
|
+
return;
|
|
37763
|
+
}
|
|
37764
|
+
const hyperlinkRelationships = [];
|
|
37765
|
+
const { didFindOccurrence } = replacer({
|
|
37766
|
+
json: element,
|
|
37767
|
+
patch: _objectSpread2(_objectSpread2({}, patchValue), {}, { children: patchValue.children.flatMap((child) => child instanceof Bookmark ? child.writtenAs : [child]).map((child) => {
|
|
37768
|
+
if (child instanceof ExternalHyperlink) {
|
|
37769
|
+
const concreteHyperlink = new ConcreteHyperlink(child.options.children, uniqueId());
|
|
37770
|
+
hyperlinkRelationships.push({
|
|
35771
37771
|
key,
|
|
35772
37772
|
id: concreteHyperlink.linkId,
|
|
35773
37773
|
type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
|
|
35774
|
-
target:
|
|
37774
|
+
target: child.options.link,
|
|
35775
37775
|
targetMode: TargetModeType.EXTERNAL
|
|
35776
37776
|
});
|
|
35777
37777
|
return concreteHyperlink;
|
|
35778
|
-
} else return
|
|
37778
|
+
} else return child;
|
|
35779
37779
|
}) }),
|
|
35780
|
-
patchText
|
|
37780
|
+
patchText: `${start}${patchKey}${end}`,
|
|
35781
37781
|
context,
|
|
35782
37782
|
keepOriginalStyles,
|
|
35783
|
-
recursive
|
|
37783
|
+
recursive,
|
|
37784
|
+
renumberIds: (elements) => notes.renumber(renumberBookmarks(elements))
|
|
35784
37785
|
});
|
|
35785
|
-
|
|
35786
|
-
|
|
37786
|
+
if (didFindOccurrence) relationshipAdditions.push(...hyperlinkRelationships);
|
|
37787
|
+
};
|
|
37788
|
+
for (const [patchKey, patchValue] of patchesInOrder) patchPlaceholder(json, patchKey, patchValue);
|
|
37789
|
+
}
|
|
37790
|
+
notes.write();
|
|
37791
|
+
for (const [key, json] of map) {
|
|
37792
|
+
if (!key.startsWith("word/") || key.endsWith(".xml.rels")) continue;
|
|
37793
|
+
const mediaDatas = imageReplacer.getMediaData(JSON.stringify(json), file.Media);
|
|
35787
37794
|
if (mediaDatas.length > 0) {
|
|
35788
37795
|
hasMedia = true;
|
|
35789
37796
|
imageRelationshipAdditions.push({
|
|
@@ -35812,6 +37819,7 @@ var patchDocument = function() {
|
|
|
35812
37819
|
map.set(relationshipKey, relationshipsJson);
|
|
35813
37820
|
appendRelationship(relationshipsJson, id, type, target, targetMode);
|
|
35814
37821
|
}
|
|
37822
|
+
if (pageNumbers) yield fillTemplatePageNumbers(map, pageNumbers, binaryContentMap);
|
|
35815
37823
|
const packageParts = xmlifyPackageParts(file, void 0);
|
|
35816
37824
|
if (hasMedia || contentTypeOverrides.length > 0) {
|
|
35817
37825
|
const contentTypesJson = map.get("[Content_Types].xml");
|
|
@@ -35845,12 +37853,13 @@ var patchDocument = function() {
|
|
|
35845
37853
|
};
|
|
35846
37854
|
}();
|
|
35847
37855
|
/**
|
|
35848
|
-
* The element with an extra escape on each "&" in its text. xml-js reads "&" in text as an "&"
|
|
35849
|
-
* would write a text's literal "&", such as in a document about HTML, as "&".
|
|
37856
|
+
* The element with an extra escape on each "&" in its text and attributes. xml-js reads "&" in text as an "&"
|
|
37857
|
+
* already escaped, and would write a text's literal "&", such as in a document about HTML, as "&". It escapes the
|
|
37858
|
+
* quotes in an attribute before `attributeValueFn` is given it, so that can't tell its """ from a literal one.
|
|
35850
37859
|
*/
|
|
35851
|
-
var withAmpersandsEscaped = (element) => _objectSpread2(_objectSpread2({}, element), element.elements === void 0 ? {} : { elements: element.elements.map((child) => child.type === "text" ? _objectSpread2(_objectSpread2({}, child), {}, { text: String(child.text).replace(/&/g, "&") }) : withAmpersandsEscaped(child)) });
|
|
37860
|
+
var withAmpersandsEscaped = (element) => _objectSpread2(_objectSpread2(_objectSpread2({}, element), element.attributes === void 0 ? {} : { attributes: Object.fromEntries(Object.entries(element.attributes).map(([key, value]) => [key, value === void 0 ? value : String(value).replace(/&/g, "&")])) }), element.elements === void 0 ? {} : { elements: element.elements.map((child) => child.type === "text" ? _objectSpread2(_objectSpread2({}, child), {}, { text: String(child.text).replace(/&/g, "&") }) : withAmpersandsEscaped(child)) });
|
|
35852
37861
|
var toXml = (jsonObj) => {
|
|
35853
|
-
return (0, import_lib.js2xml)(withAmpersandsEscaped(jsonObj), { attributeValueFn: (str) => String(str).replace(
|
|
37862
|
+
return (0, import_lib.js2xml)(withAmpersandsEscaped(jsonObj), { attributeValueFn: (str) => String(str).replace(/</g, "<").replace(/>/g, ">").replace(/'/g, "'") });
|
|
35854
37863
|
};
|
|
35855
37864
|
//#endregion
|
|
35856
37865
|
//#region src/patcher/patch-detector.ts
|
|
@@ -35915,4 +37924,4 @@ var findPatchKeys = (text) => {
|
|
|
35915
37924
|
return (_text$match = text.match(pattern)) !== null && _text$match !== void 0 ? _text$match : [];
|
|
35916
37925
|
};
|
|
35917
37926
|
//#endregion
|
|
35918
|
-
export { AbstractNumbering, AlignmentType, AnnotationReference, Attributes, BaseXmlComponent, Body, Bookmark, BookmarkEnd, BookmarkStart, Border, BorderStyle, BuilderElement, CarriageReturn, CellMerge, CellMergeAttributes, CharacterSet, CheckBox, CheckBoxSymbolElement, CheckBoxUtil, Column, ColumnBreak, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, Comments, CommentsExtended, CommentsIds, ConcreteHyperlink, ConcreteNumbering, ContinuationSeparator, DayLong, DayShort, DeletedTableCell, DeletedTableRow, DeletedTextRun, File as Document, File, DocumentAttributeNamespaces, DocumentAttributes, DocumentBackground, DocumentBackgroundAttributes, DocumentDefaults, DocumentGridType, Drawing, DrawingPatch, DropCapType, EMPTY_OBJECT, EmphasisMarkType, EmptyElement, EndnoteIdReference, EndnoteReference, EndnoteReferenceRun, EndnoteReferenceRunAttributes, Endnotes, ExternalHyperlink, FileChild, FootNoteReferenceRunAttributes, FootNotes, Footer, FooterWrapper, FootnoteReference, FootnoteReferenceElement, FootnoteReferenceRun, FrameAnchorType, FrameWrap, GridSpan, Header, HeaderFooterReferenceType, HeaderFooterType, HeaderWrapper, HeadingLevel, HeightRule, HighlightColor, HorizontalPositionAlign, HorizontalPositionRelativeFrom, HpsMeasureElement, HyperlinkType, IgnoreIfEmptyXmlComponent, ImageRun, ImportedRootElementAttributes, ImportedXmlComponent, InitializableXmlComponent, InsertedTableCell, InsertedTableRow, InsertedTextRun, InternalHyperlink, LastRenderedPageBreak, LeaderType, Level, LevelBase, LevelForOverride, LevelFormat, LevelOverride, LevelSuffix, LineNumberRestartFormat, LineRuleType, Math$1 as Math, MathAngledBrackets, MathCurlyBrackets, MathDegree, MathDenominator, MathFraction, MathFunction, MathFunctionName, MathFunctionProperties, MathIntegral, MathLimit, MathLimitLower, MathLimitUpper, MathNumerator, MathPreSubSuperScript, MathRadical, MathRadicalProperties, MathRoundBrackets, MathRun, MathSquareBrackets, MathSubScript, MathSubSuperScript, MathSum, MathSuperScript, Media, MonthLong, MonthShort, NextAttributeComponent, NoBreakHyphen, NonVisualDrawingProperties, NumberFormat, NumberProperties, NumberValueElement, NumberedItemReference, NumberedItemReferenceFormat, Numbering, OnOffElement, OverlapType, PackagePart, Packer, PageBorderDisplay, PageBorderOffsetFrom, PageBorderZOrder, PageBorders, PageBreak, PageBreakBefore, PageNumber, PageNumberElement, PageNumberSeparator, PageOrientation, PageReference, PageTextDirection, PageTextDirectionType, Paragraph, ParagraphProperties, ParagraphPropertiesChange, ParagraphPropertiesDefaults, ParagraphRunProperties, PatchType, PositionalTab, PositionalTabAlignment, PositionalTabLeader, PositionalTabRelativeTo, PrettifyType, RelativeHorizontalPosition, RelativeVerticalPosition, Run, RunProperties, RunPropertiesChange, RunPropertiesDefaults, SchemeColor, SectionProperties, SectionPropertiesChange, SectionType, Separator, SequentialIdentifier, ShadingType, SimpleField, SimpleMailMergeField, SoftHyphen, SpaceType, StringContainer, StringEnumValueElement, StringValueElement, StyleForCharacter, StyleForParagraph, StyleLevel, Styles, SymbolRun, TDirection, Tab, TabStopPosition, TabStopType, Table, TableAnchorType, TableBorders, TableCell, TableCellBorders, TableLayoutType, TableOfContents, TableProperties, TableRow, TableRowProperties, TableRowPropertiesChange, TextDirection, TextEffect, TextRun, TextWrappingSide, TextWrappingType, Textbox, ThematicBreak, Theme, UnderlineType, VerticalAlign, VerticalAlignSection, VerticalAlignTable, VerticalAnchor, VerticalMerge, VerticalMergeRevisionType, VerticalMergeType, VerticalPositionAlign, VerticalPositionRelativeFrom, WidthType, WpgGroupRun, WpsShapeRun, XmlAttributeComponent, XmlComponent, YearLong, YearShort, abstractNumUniqueNumericIdGen, bookmarkUniqueNumericId, bookmarkUniqueNumericIdGen, commentIdToParaId, concreteNumUniqueNumericIdGen, convertInchesToTwip, convertMillimetersToTwip, convertToXmlComponent, createAlignment, createBodyProperties, createBorderElement, createColumns, createDocumentGrid, createDotEmphasisMark, createEmphasisMark, createFrameProperties, createHeaderFooterReference, createHorizontalPosition, createIndent, createLineNumberType, createMathAccentCharacter, createMathBase, createMathLimitLocation, createMathNAryProperties, createMathPreSubSuperScriptProperties, createMathSubScriptElement, createMathSubScriptProperties, createMathSubSuperScriptProperties, createMathSuperScriptElement, createMathSuperScriptProperties, createOutlineLevel, createPageMargin, createPageNumberType, createPageSize, createParagraphStyle, createRunFonts, createSectionType, createShading, createSimplePos, createSpacing, createStringElement, createTabStop, createTabStopItem, createTableFloatProperties, createTableLayout, createTableLook, createTableRowHeight, createTableWidthElement, createTransformation, createUnderline, createVerticalAlign, createVerticalPosition, createVmlShape, createWrapNone, createWrapSquare, createWrapThrough, createWrapTight, createWrapTopAndBottom, dateTimeValue, decimalNumber, docPropertiesUniqueNumericId, docPropertiesUniqueNumericIdGen, eighthPointMeasureValue, encodeUtf8, hashedId, hexColorValue, hpsMeasureValue, longHexNumber, measurementOrPercentValue, patchDetector, patchDocument, percentageValue, pointMeasureValue, positiveUniversalMeasureValue, sectionMarginDefaults, sectionPageSizeDefaults, shortHexNumber, signedHpsMeasureValue, signedTwipsMeasureValue, standardizeData, twipsMeasureValue, uCharHexNumber, uniqueId, uniqueNumericIdCreator, uniqueUuid, universalMeasureToTwips, universalMeasureValue, unsignedDecimalNumber };
|
|
37927
|
+
export { AbstractNumbering, AlignmentType, AnnotationReference, Attributes, BaseXmlComponent, Body, Bookmark, BookmarkEnd, BookmarkStart, Border, BorderStyle, BuilderElement, CarriageReturn, CellMerge, CellMergeAttributes, CharacterSet, CheckBox, CheckBoxSymbolElement, CheckBoxUtil, Column, ColumnBreak, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, Comments, CommentsExtended, CommentsIds, ConcreteHyperlink, ConcreteNumbering, ContinuationSeparator, DayLong, DayShort, DeletedTableCell, DeletedTableRow, DeletedTextRun, File as Document, File, DocumentAttributeNamespaces, DocumentAttributes, DocumentBackground, DocumentBackgroundAttributes, DocumentDefaults, DocumentGridType, Drawing, DrawingPatch, DropCapType, EMPTY_OBJECT, EmphasisMarkType, EmptyElement, EndnoteIdReference, EndnotePosition, EndnoteReference, EndnoteReferenceRun, EndnoteReferenceRunAttributes, Endnotes, ExternalHyperlink, FileChild, FootNoteReferenceRunAttributes, FootNotes, Footer, FooterWrapper, FootnotePosition, FootnoteReference, FootnoteReferenceElement, FootnoteReferenceRun, FrameAnchorType, FrameWrap, GridSpan, Header, HeaderFooterReferenceType, HeaderFooterType, HeaderWrapper, HeadingLevel, HeightRule, HighlightColor, HorizontalPositionAlign, HorizontalPositionRelativeFrom, HpsMeasureElement, HyperlinkType, IgnoreIfEmptyXmlComponent, ImageRun, ImportedRootElementAttributes, ImportedXmlComponent, InitializableXmlComponent, InsertedTableCell, InsertedTableRow, InsertedTextRun, InternalHyperlink, LastRenderedPageBreak, LeaderType, Level, LevelBase, LevelForOverride, LevelFormat, LevelOverride, LevelSuffix, LineNumberRestartFormat, LineRuleType, Math$1 as Math, MathAngledBrackets, MathCurlyBrackets, MathDegree, MathDenominator, MathFraction, MathFunction, MathFunctionName, MathFunctionProperties, MathIntegral, MathLimit, MathLimitLower, MathLimitUpper, MathNumerator, MathPreSubSuperScript, MathRadical, MathRadicalProperties, MathRoundBrackets, MathRun, MathSquareBrackets, MathSubScript, MathSubSuperScript, MathSum, MathSuperScript, Media, MonthLong, MonthShort, NextAttributeComponent, NoBreakHyphen, NonVisualDrawingProperties, NoteNumberRestart, NumberFormat, NumberProperties, NumberValueElement, NumberedItemReference, NumberedItemReferenceFormat, Numbering, OnOffElement, OverlapType, PackagePart, Packer, PageBorderDisplay, PageBorderOffsetFrom, PageBorderZOrder, PageBorders, PageBreak, PageBreakBefore, PageNumber, PageNumberElement, PageNumberSeparator, PageOrientation, PageReference, PageTextDirection, PageTextDirectionType, Paragraph, ParagraphProperties, ParagraphPropertiesChange, ParagraphPropertiesDefaults, ParagraphRunProperties, PatchType, PositionalTab, PositionalTabAlignment, PositionalTabLeader, PositionalTabRelativeTo, PrettifyType, RelativeHorizontalPosition, RelativeVerticalPosition, Run, RunProperties, RunPropertiesChange, RunPropertiesDefaults, SchemeColor, SectionProperties, SectionPropertiesChange, SectionType, Separator, SequentialIdentifier, ShadingType, SimpleField, SimpleMailMergeField, SoftHyphen, SpaceType, StringContainer, StringEnumValueElement, StringValueElement, StyleForCharacter, StyleForParagraph, StyleLevel, Styles, SymbolRun, TDirection, Tab, TabStopPosition, TabStopType, Table, TableAnchorType, TableBorders, TableCell, TableCellBorders, TableLayoutType, TableOfContents, TableProperties, TableRow, TableRowProperties, TableRowPropertiesChange, TextDirection, TextEffect, TextRun, TextWrappingSide, TextWrappingType, Textbox, ThematicBreak, Theme, UnderlineType, VerticalAlign, VerticalAlignSection, VerticalAlignTable, VerticalAnchor, VerticalMerge, VerticalMergeRevisionType, VerticalMergeType, VerticalPositionAlign, VerticalPositionRelativeFrom, WidthType, WpgGroupRun, WpsShapeRun, XmlAttributeComponent, XmlComponent, YearLong, YearShort, abstractNumUniqueNumericIdGen, bookmarkUniqueNumericId, bookmarkUniqueNumericIdGen, commentIdToParaId, concreteNumUniqueNumericIdGen, convertInchesToTwip, convertMillimetersToTwip, convertToXmlComponent, createAlignment, createBodyProperties, createBorderElement, createColumns, createDocumentGrid, createDotEmphasisMark, createEmphasisMark, createEndnoteProperties, createFootnoteProperties, createFrameProperties, createHeaderFooterReference, createHorizontalPosition, createIndent, createLineNumberType, createMathAccentCharacter, createMathBase, createMathLimitLocation, createMathNAryProperties, createMathPreSubSuperScriptProperties, createMathSubScriptElement, createMathSubScriptProperties, createMathSubSuperScriptProperties, createMathSuperScriptElement, createMathSuperScriptProperties, createOutlineLevel, createPageMargin, createPageNumberType, createPageSize, createParagraphStyle, createRunFonts, createSectionType, createShading, createSimplePos, createSpacing, createStringElement, createTabStop, createTabStopItem, createTableFloatProperties, createTableLayout, createTableLook, createTableRowHeight, createTableWidthElement, createTransformation, createUnderline, createVerticalAlign, createVerticalPosition, createVmlShape, createWrapNone, createWrapSquare, createWrapThrough, createWrapTight, createWrapTopAndBottom, dateTimeValue, decimalNumber, docPropertiesUniqueNumericId, docPropertiesUniqueNumericIdGen, eighthPointMeasureValue, encodeUtf8, fillPageNumbers, fillPartPageNumbers, fillSequenceNumbers, hashedId, hexColorValue, hpsMeasureValue, longHexNumber, measurementOrPercentValue, patchDetector, patchDocument, percentageValue, pointMeasureValue, positiveUniversalMeasureValue, sectionMarginDefaults, sectionPageSizeDefaults, shortHexNumber, signedHpsMeasureValue, signedTwipsMeasureValue, standardizeData, twipsMeasureValue, uCharHexNumber, uniqueId, uniqueNumericIdCreator, uniqueUuid, universalMeasureToTwips, universalMeasureValue, unsignedDecimalNumber };
|