docx 9.8.1 → 9.10.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 +2480 -361
- package/dist/index.d.cts +668 -38
- package/dist/index.d.ts +668 -38
- package/dist/index.iife.js +2480 -361
- package/dist/index.mjs +2473 -362
- package/dist/index.umd.cjs +2480 -361
- package/dist/layout.cjs +50855 -0
- package/dist/layout.d.cts +385 -0
- package/dist/layout.d.ts +385 -0
- package/dist/layout.iife.js +50858 -0
- package/dist/layout.mjs +50851 -0
- package/dist/layout.umd.cjs +50859 -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 +21 -7
package/dist/index.iife.js
CHANGED
|
@@ -31,7 +31,7 @@ var docx = (function(exports) {
|
|
|
31
31
|
enumerable: true
|
|
32
32
|
}) : target, mod));
|
|
33
33
|
//#endregion
|
|
34
|
-
//#region \0@oxc-project+runtime@0.
|
|
34
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/typeof.js
|
|
35
35
|
function _typeof(o) {
|
|
36
36
|
"@babel/helpers - typeof";
|
|
37
37
|
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
@@ -41,7 +41,7 @@ var docx = (function(exports) {
|
|
|
41
41
|
}, _typeof(o);
|
|
42
42
|
}
|
|
43
43
|
//#endregion
|
|
44
|
-
//#region \0@oxc-project+runtime@0.
|
|
44
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/toPrimitive.js
|
|
45
45
|
function toPrimitive(t, r) {
|
|
46
46
|
if ("object" != _typeof(t) || !t) return t;
|
|
47
47
|
var e = t[Symbol.toPrimitive];
|
|
@@ -53,13 +53,13 @@ var docx = (function(exports) {
|
|
|
53
53
|
return ("string" === r ? String : Number)(t);
|
|
54
54
|
}
|
|
55
55
|
//#endregion
|
|
56
|
-
//#region \0@oxc-project+runtime@0.
|
|
56
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/toPropertyKey.js
|
|
57
57
|
function toPropertyKey(t) {
|
|
58
58
|
var i = toPrimitive(t, "string");
|
|
59
59
|
return "symbol" == _typeof(i) ? i : i + "";
|
|
60
60
|
}
|
|
61
61
|
//#endregion
|
|
62
|
-
//#region \0@oxc-project+runtime@0.
|
|
62
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/defineProperty.js
|
|
63
63
|
function _defineProperty(e, r, t) {
|
|
64
64
|
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
65
65
|
value: t,
|
|
@@ -269,7 +269,7 @@ var docx = (function(exports) {
|
|
|
269
269
|
}
|
|
270
270
|
};
|
|
271
271
|
//#endregion
|
|
272
|
-
//#region \0@oxc-project+runtime@0.
|
|
272
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/objectSpread2.js
|
|
273
273
|
function ownKeys(e, r) {
|
|
274
274
|
var t = Object.keys(e);
|
|
275
275
|
if (Object.getOwnPropertySymbols) {
|
|
@@ -8951,11 +8951,11 @@ var docx = (function(exports) {
|
|
|
8951
8951
|
* @publicApi
|
|
8952
8952
|
*/
|
|
8953
8953
|
var AlignmentType = {
|
|
8954
|
-
/** Align Start */
|
|
8954
|
+
/** Align Start: the left in a left-to-right paragraph, and the right in a `bidirectional` (right-to-left) paragraph */
|
|
8955
8955
|
START: "start",
|
|
8956
8956
|
/** Align Center */
|
|
8957
8957
|
CENTER: "center",
|
|
8958
|
-
/** End */
|
|
8958
|
+
/** Align End: the right in a left-to-right paragraph, and the left in a `bidirectional` (right-to-left) paragraph */
|
|
8959
8959
|
END: "end",
|
|
8960
8960
|
/** Justified */
|
|
8961
8961
|
BOTH: "both",
|
|
@@ -8971,9 +8971,9 @@ var docx = (function(exports) {
|
|
|
8971
8971
|
LOW_KASHIDA: "lowKashida",
|
|
8972
8972
|
/** Thai Language Justification */
|
|
8973
8973
|
THAI_DISTRIBUTE: "thaiDistribute",
|
|
8974
|
-
/** Align Left */
|
|
8974
|
+
/** Align Left: a paragraph stays on the left of the page even when it is `bidirectional` (right-to-left) */
|
|
8975
8975
|
LEFT: "left",
|
|
8976
|
-
/** Align Right */
|
|
8976
|
+
/** Align Right: a paragraph stays on the right of the page even when it is `bidirectional` (right-to-left) */
|
|
8977
8977
|
RIGHT: "right",
|
|
8978
8978
|
/** Justified */
|
|
8979
8979
|
JUSTIFIED: "both"
|
|
@@ -9787,6 +9787,40 @@ var docx = (function(exports) {
|
|
|
9787
9787
|
* field instructions, an optional separate character, field result, and an end character.
|
|
9788
9788
|
*/
|
|
9789
9789
|
var createBegin = (dirty) => createFieldChar(FieldCharacterType.BEGIN, dirty);
|
|
9790
|
+
/** The formatted begin characters of the fields that are dirty only when the document isn't given page numbers */
|
|
9791
|
+
var dirtyWithoutPageNumbers = /* @__PURE__ */ new WeakSet();
|
|
9792
|
+
/** The beginning of a field that is dirty, so Word updates it, unless the document is given page numbers */
|
|
9793
|
+
var BeginDirtyWithoutPageNumbers = class extends BuilderElement {
|
|
9794
|
+
constructor() {
|
|
9795
|
+
super({
|
|
9796
|
+
name: "w:fldChar",
|
|
9797
|
+
attributes: {
|
|
9798
|
+
type: {
|
|
9799
|
+
key: "w:fldCharType",
|
|
9800
|
+
value: FieldCharacterType.BEGIN
|
|
9801
|
+
},
|
|
9802
|
+
dirty: {
|
|
9803
|
+
key: "w:dirty",
|
|
9804
|
+
value: true
|
|
9805
|
+
}
|
|
9806
|
+
}
|
|
9807
|
+
});
|
|
9808
|
+
}
|
|
9809
|
+
prepForXml(context) {
|
|
9810
|
+
const xml = super.prepForXml(context);
|
|
9811
|
+
dirtyWithoutPageNumbers.add(xml);
|
|
9812
|
+
return xml;
|
|
9813
|
+
}
|
|
9814
|
+
};
|
|
9815
|
+
/**
|
|
9816
|
+
* Creates the beginning of a field whose result is written when the document is given page numbers, such as a page
|
|
9817
|
+
* reference or a SEQ field. It is written dirty, so Word updates the field when it opens the document, and asks to. When
|
|
9818
|
+
* the document is given page numbers, it is written clean (see {@link isDirtyWithoutPageNumbers}), so Word shows the
|
|
9819
|
+
* number written, or nothing when none could be worked out, and doesn't ask.
|
|
9820
|
+
*/
|
|
9821
|
+
var createBeginDirtyWithoutPageNumbers = () => new BeginDirtyWithoutPageNumbers();
|
|
9822
|
+
/** Whether a formatted field character is the beginning of a field that is dirty only without page numbers */
|
|
9823
|
+
var isDirtyWithoutPageNumbers = (element) => typeof element === "object" && element !== null && dirtyWithoutPageNumbers.has(element);
|
|
9790
9824
|
/**
|
|
9791
9825
|
* Creates the separator between field code and field result in a complex field.
|
|
9792
9826
|
*
|
|
@@ -9957,7 +9991,8 @@ var docx = (function(exports) {
|
|
|
9957
9991
|
THAI_NUMBERS: "thaiNumbers",
|
|
9958
9992
|
THAI_COUNTING: "thaiCounting",
|
|
9959
9993
|
BAHT_TEXT: "bahtText",
|
|
9960
|
-
DOLLAR_TEXT: "dollarText"
|
|
9994
|
+
DOLLAR_TEXT: "dollarText",
|
|
9995
|
+
CUSTOM: "custom"
|
|
9961
9996
|
};
|
|
9962
9997
|
//#endregion
|
|
9963
9998
|
//#region src/file/shared/space-type.ts
|
|
@@ -11299,13 +11334,8 @@ DOT: "dot" };
|
|
|
11299
11334
|
*/
|
|
11300
11335
|
var SymbolRun = class extends Run {
|
|
11301
11336
|
constructor(options) {
|
|
11302
|
-
|
|
11303
|
-
|
|
11304
|
-
this.root.push(new Symbol$1(options));
|
|
11305
|
-
return this;
|
|
11306
|
-
}
|
|
11307
|
-
super(options);
|
|
11308
|
-
this.root.push(new Symbol$1(options.char, options.symbolfont));
|
|
11337
|
+
super(typeof options === "string" ? {} : options);
|
|
11338
|
+
this.root.push(typeof options === "string" ? new Symbol$1(options) : new Symbol$1(options.char, options.symbolfont));
|
|
11309
11339
|
}
|
|
11310
11340
|
};
|
|
11311
11341
|
//#endregion
|
|
@@ -12757,7 +12787,7 @@ DOT: "dot" };
|
|
|
12757
12787
|
hash.sha512 = hash.sha.sha512;
|
|
12758
12788
|
hash.ripemd160 = hash.ripemd.ripemd160;
|
|
12759
12789
|
})))(), 1);
|
|
12760
|
-
var urlAlphabet = "
|
|
12790
|
+
var urlAlphabet = "57X6y3wQZNzYjJB2L_10pxbackgroundhimselfUTF-8DEMOGRAPHICSVqvt4KW9";
|
|
12761
12791
|
//#endregion
|
|
12762
12792
|
//#region node_modules/nanoid/non-secure/index.js
|
|
12763
12793
|
var customAlphabet = (alphabet, defaultSize = 21) => {
|
|
@@ -14286,6 +14316,16 @@ DOT: "dot" };
|
|
|
14286
14316
|
}
|
|
14287
14317
|
};
|
|
14288
14318
|
/**
|
|
14319
|
+
* Converts a crop percentage to thousandths of a percent.
|
|
14320
|
+
*
|
|
14321
|
+
* @throws If the percentage isn't a number from 0 to 100
|
|
14322
|
+
*/
|
|
14323
|
+
var cropValue = (value, edge) => {
|
|
14324
|
+
if (value === void 0) return;
|
|
14325
|
+
if (!(value >= 0 && value <= 100)) throw new Error(`Invalid crop ${edge} ${value}. Expected a number from 0 to 100`);
|
|
14326
|
+
return Math.round(value * 1e3);
|
|
14327
|
+
};
|
|
14328
|
+
/**
|
|
14289
14329
|
* Represents a source rectangle for blip fills.
|
|
14290
14330
|
*
|
|
14291
14331
|
* This element specifies a portion of the blip (image) to use as the fill.
|
|
@@ -14312,10 +14352,10 @@ DOT: "dot" };
|
|
|
14312
14352
|
constructor(crop) {
|
|
14313
14353
|
super("a:srcRect");
|
|
14314
14354
|
if (crop) this.root.push(new SourceRectangleAttributes({
|
|
14315
|
-
left: crop.left
|
|
14316
|
-
top: crop.top
|
|
14317
|
-
right: crop.right
|
|
14318
|
-
bottom: crop.bottom
|
|
14355
|
+
left: cropValue(crop.left, "left"),
|
|
14356
|
+
top: cropValue(crop.top, "top"),
|
|
14357
|
+
right: cropValue(crop.right, "right"),
|
|
14358
|
+
bottom: cropValue(crop.bottom, "bottom")
|
|
14319
14359
|
}));
|
|
14320
14360
|
}
|
|
14321
14361
|
};
|
|
@@ -14544,48 +14584,6 @@ DOT: "dot" };
|
|
|
14544
14584
|
}
|
|
14545
14585
|
};
|
|
14546
14586
|
//#endregion
|
|
14547
|
-
//#region src/file/drawing/doc-properties/doc-properties-children.ts
|
|
14548
|
-
/**
|
|
14549
|
-
* Child elements for document properties.
|
|
14550
|
-
*
|
|
14551
|
-
* This module provides hyperlink elements that can be attached to
|
|
14552
|
-
* drawing elements for interactive behavior.
|
|
14553
|
-
*
|
|
14554
|
-
* @module
|
|
14555
|
-
*/
|
|
14556
|
-
/**
|
|
14557
|
-
* Creates a click hyperlink element for a drawing.
|
|
14558
|
-
*
|
|
14559
|
-
* This element defines what happens when a user clicks on a drawing element.
|
|
14560
|
-
*
|
|
14561
|
-
* ## XSD Schema
|
|
14562
|
-
* ```xml
|
|
14563
|
-
* <xsd:complexType name="CT_Hyperlink">
|
|
14564
|
-
* <xsd:group ref="EG_PContent" minOccurs="0" maxOccurs="unbounded"/>
|
|
14565
|
-
* <xsd:attribute name="tgtFrame" type="s:ST_String"/>
|
|
14566
|
-
* <xsd:attribute name="tooltip" type="s:ST_String"/>
|
|
14567
|
-
* <xsd:attribute name="docLocation" type="s:ST_String"/>
|
|
14568
|
-
* <xsd:attribute name="history" type="s:ST_OnOff"/>
|
|
14569
|
-
* <xsd:attribute name="anchor" type="s:ST_String"/>
|
|
14570
|
-
* <xsd:attribute ref="r:id"/>
|
|
14571
|
-
* </xsd:complexType>
|
|
14572
|
-
* ```
|
|
14573
|
-
*
|
|
14574
|
-
* @param linkId - The relationship ID for the hyperlink target
|
|
14575
|
-
* @param hasXmlNs - Whether to include the XML namespace declaration
|
|
14576
|
-
* @returns An XML component representing the click hyperlink
|
|
14577
|
-
*/
|
|
14578
|
-
var createHyperlinkClick = (linkId, hasXmlNs) => new BuilderElement({
|
|
14579
|
-
name: "a:hlinkClick",
|
|
14580
|
-
attributes: _objectSpread2(_objectSpread2({}, hasXmlNs ? { xmlns: {
|
|
14581
|
-
key: "xmlns:a",
|
|
14582
|
-
value: "http://schemas.openxmlformats.org/drawingml/2006/main"
|
|
14583
|
-
} } : {}), {}, { id: {
|
|
14584
|
-
key: "r:id",
|
|
14585
|
-
value: `rId${linkId}`
|
|
14586
|
-
} })
|
|
14587
|
-
});
|
|
14588
|
-
//#endregion
|
|
14589
14587
|
//#region src/file/drawing/inline/graphic/graphic-data/pic/non-visual-pic-properties/non-visual-properties/non-visual-properties-attributes.ts
|
|
14590
14588
|
/**
|
|
14591
14589
|
* Non-visual properties attributes module.
|
|
@@ -14666,10 +14664,12 @@ DOT: "dot" };
|
|
|
14666
14664
|
for (let i = context.stack.length - 1; i >= 0; i--) {
|
|
14667
14665
|
const element = context.stack[i];
|
|
14668
14666
|
if (!(element instanceof ConcreteHyperlink)) continue;
|
|
14669
|
-
this.root.push(
|
|
14667
|
+
this.root.push(element.createDrawingClick(context, false));
|
|
14670
14668
|
break;
|
|
14671
14669
|
}
|
|
14672
|
-
|
|
14670
|
+
const result = super.prepForXml(context);
|
|
14671
|
+
this.root.splice(1);
|
|
14672
|
+
return result;
|
|
14673
14673
|
}
|
|
14674
14674
|
};
|
|
14675
14675
|
//#endregion
|
|
@@ -15334,6 +15334,48 @@ EXTERNAL: "External" };
|
|
|
15334
15334
|
}
|
|
15335
15335
|
});
|
|
15336
15336
|
//#endregion
|
|
15337
|
+
//#region src/file/drawing/doc-properties/doc-properties-children.ts
|
|
15338
|
+
/**
|
|
15339
|
+
* Child elements for document properties.
|
|
15340
|
+
*
|
|
15341
|
+
* This module provides hyperlink elements that can be attached to
|
|
15342
|
+
* drawing elements for interactive behavior.
|
|
15343
|
+
*
|
|
15344
|
+
* @module
|
|
15345
|
+
*/
|
|
15346
|
+
/**
|
|
15347
|
+
* Creates a click hyperlink element for a drawing.
|
|
15348
|
+
*
|
|
15349
|
+
* This element defines what happens when a user clicks on a drawing element.
|
|
15350
|
+
*
|
|
15351
|
+
* ## XSD Schema
|
|
15352
|
+
* ```xml
|
|
15353
|
+
* <xsd:complexType name="CT_Hyperlink">
|
|
15354
|
+
* <xsd:group ref="EG_PContent" minOccurs="0" maxOccurs="unbounded"/>
|
|
15355
|
+
* <xsd:attribute name="tgtFrame" type="s:ST_String"/>
|
|
15356
|
+
* <xsd:attribute name="tooltip" type="s:ST_String"/>
|
|
15357
|
+
* <xsd:attribute name="docLocation" type="s:ST_String"/>
|
|
15358
|
+
* <xsd:attribute name="history" type="s:ST_OnOff"/>
|
|
15359
|
+
* <xsd:attribute name="anchor" type="s:ST_String"/>
|
|
15360
|
+
* <xsd:attribute ref="r:id"/>
|
|
15361
|
+
* </xsd:complexType>
|
|
15362
|
+
* ```
|
|
15363
|
+
*
|
|
15364
|
+
* @param linkId - The relationship ID for the hyperlink target
|
|
15365
|
+
* @param hasXmlNs - Whether to include the XML namespace declaration
|
|
15366
|
+
* @returns An XML component representing the click hyperlink
|
|
15367
|
+
*/
|
|
15368
|
+
var createHyperlinkClick = (linkId, hasXmlNs) => new BuilderElement({
|
|
15369
|
+
name: "a:hlinkClick",
|
|
15370
|
+
attributes: _objectSpread2(_objectSpread2({}, hasXmlNs ? { xmlns: {
|
|
15371
|
+
key: "xmlns:a",
|
|
15372
|
+
value: "http://schemas.openxmlformats.org/drawingml/2006/main"
|
|
15373
|
+
} } : {}), {}, { id: {
|
|
15374
|
+
key: "r:id",
|
|
15375
|
+
value: `rId${linkId}`
|
|
15376
|
+
} })
|
|
15377
|
+
});
|
|
15378
|
+
//#endregion
|
|
15337
15379
|
//#region src/file/drawing/doc-properties/non-visual-drawing-properties.ts
|
|
15338
15380
|
/**
|
|
15339
15381
|
* Non-visual drawing properties (`CT_NonVisualDrawingProps`) of the shapes, pictures and groups inside a drawing:
|
|
@@ -15528,7 +15570,7 @@ EXTERNAL: "External" };
|
|
|
15528
15570
|
} else for (let i = context.stack.length - 1; i >= 0; i--) {
|
|
15529
15571
|
const element = context.stack[i];
|
|
15530
15572
|
if (!(element instanceof ConcreteHyperlink)) continue;
|
|
15531
|
-
this.root.push(
|
|
15573
|
+
this.root.push(element.createDrawingClick(context, true));
|
|
15532
15574
|
break;
|
|
15533
15575
|
}
|
|
15534
15576
|
if (this.decorative) this.root.push(createDecorativeExtensionList(true));
|
|
@@ -15616,6 +15658,18 @@ EXTERNAL: "External" };
|
|
|
15616
15658
|
* @module
|
|
15617
15659
|
*/
|
|
15618
15660
|
/**
|
|
15661
|
+
* The largest width or height, in EMUs, Word opens a drawing at. The standard allows `ST_PositiveCoordinate` up to
|
|
15662
|
+
* 27273042316900, but Word and PowerPoint restrict it to 2147483647 and won't open a document with a larger drawing.
|
|
15663
|
+
*
|
|
15664
|
+
* Reference: [MS-OI29500] Part 1 Section 20.1.10.42, ST_PositiveCoordinate
|
|
15665
|
+
*/
|
|
15666
|
+
var MAX_EXTENT = 2147483647;
|
|
15667
|
+
var EMUS_PER_PIXEL = 9525;
|
|
15668
|
+
var checkExtent = (dimension, value) => {
|
|
15669
|
+
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`);
|
|
15670
|
+
return value;
|
|
15671
|
+
};
|
|
15672
|
+
/**
|
|
15619
15673
|
* Creates an extent element for inline drawings.
|
|
15620
15674
|
*
|
|
15621
15675
|
* This element specifies the extents of the parent DrawingML object within
|
|
@@ -15639,17 +15693,19 @@ EXTERNAL: "External" };
|
|
|
15639
15693
|
* y: 914400
|
|
15640
15694
|
* });
|
|
15641
15695
|
* ```
|
|
15696
|
+
*
|
|
15697
|
+
* @throws Error if the width or height is over 2147483647 EMUs, which Word won't open
|
|
15642
15698
|
*/
|
|
15643
15699
|
var createExtent = ({ x, y }) => new BuilderElement({
|
|
15644
15700
|
name: "wp:extent",
|
|
15645
15701
|
attributes: {
|
|
15646
15702
|
x: {
|
|
15647
15703
|
key: "cx",
|
|
15648
|
-
value: x
|
|
15704
|
+
value: checkExtent("width", x)
|
|
15649
15705
|
},
|
|
15650
15706
|
y: {
|
|
15651
15707
|
key: "cy",
|
|
15652
|
-
value: y
|
|
15708
|
+
value: checkExtent("height", y)
|
|
15653
15709
|
}
|
|
15654
15710
|
}
|
|
15655
15711
|
});
|
|
@@ -16041,7 +16097,6 @@ EXTERNAL: "External" };
|
|
|
16041
16097
|
var ImageRun = class extends XmlComponent {
|
|
16042
16098
|
constructor(options) {
|
|
16043
16099
|
var _options$insertion;
|
|
16044
|
-
var _super = (..._args) => (super(..._args), _defineProperty(this, "imageData", void 0), this);
|
|
16045
16100
|
const key = `${hashedId(options.data)}.${options.type}`;
|
|
16046
16101
|
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));
|
|
16047
16102
|
const drawing = new Drawing(imageData, {
|
|
@@ -16055,8 +16110,10 @@ EXTERNAL: "External" };
|
|
|
16055
16110
|
});
|
|
16056
16111
|
const properties = new RunProperties(options.run);
|
|
16057
16112
|
const revision = (_options$insertion = options.insertion) !== null && _options$insertion !== void 0 ? _options$insertion : options.deletion;
|
|
16113
|
+
const rootName = options.insertion ? "w:ins" : options.deletion ? "w:del" : "w:r";
|
|
16114
|
+
super(rootName);
|
|
16115
|
+
_defineProperty(this, "imageData", void 0);
|
|
16058
16116
|
if (revision) {
|
|
16059
|
-
_super(options.insertion ? "w:ins" : "w:del");
|
|
16060
16117
|
this.root.push(new ChangeAttributes({
|
|
16061
16118
|
id: revision.id,
|
|
16062
16119
|
author: revision.author,
|
|
@@ -16068,7 +16125,6 @@ EXTERNAL: "External" };
|
|
|
16068
16125
|
});
|
|
16069
16126
|
this.addChildElement(options.insertion && options.deletion ? createDeletion(options.deletion, run) : run);
|
|
16070
16127
|
} else {
|
|
16071
|
-
_super("w:r");
|
|
16072
16128
|
this.root.push(properties);
|
|
16073
16129
|
this.root.push(drawing);
|
|
16074
16130
|
}
|
|
@@ -16221,6 +16277,10 @@ EXTERNAL: "External" };
|
|
|
16221
16277
|
* Each identifier maintains its own sequence, allowing you to have separate numbering
|
|
16222
16278
|
* for figures, tables, equations, etc.
|
|
16223
16279
|
*
|
|
16280
|
+
* It is written dirty, so Word numbers it when it opens the document, after asking to update the fields. When the
|
|
16281
|
+
* document is given `pageNumbers`, it is written clean, with its number counted as Word counts it, or blank where
|
|
16282
|
+
* Word's count isn't known, and Word doesn't ask.
|
|
16283
|
+
*
|
|
16224
16284
|
* Reference: http://officeopenxml.com/WPrun.php
|
|
16225
16285
|
*
|
|
16226
16286
|
* @publicApi
|
|
@@ -16249,7 +16309,7 @@ EXTERNAL: "External" };
|
|
|
16249
16309
|
var SequentialIdentifier = class extends Run {
|
|
16250
16310
|
constructor(identifier) {
|
|
16251
16311
|
super({});
|
|
16252
|
-
this.root.push(
|
|
16312
|
+
this.root.push(createBeginDirtyWithoutPageNumbers());
|
|
16253
16313
|
this.root.push(new SequentialIdentifierInstruction(identifier));
|
|
16254
16314
|
this.root.push(createSeparate());
|
|
16255
16315
|
this.root.push(createEnd());
|
|
@@ -16274,7 +16334,10 @@ EXTERNAL: "External" };
|
|
|
16274
16334
|
var FldSimpleAttrs = class extends XmlAttributeComponent {
|
|
16275
16335
|
constructor(..._args) {
|
|
16276
16336
|
super(..._args);
|
|
16277
|
-
_defineProperty(this, "xmlKeys", {
|
|
16337
|
+
_defineProperty(this, "xmlKeys", {
|
|
16338
|
+
instr: "w:instr",
|
|
16339
|
+
fldLock: "w:fldLock"
|
|
16340
|
+
});
|
|
16278
16341
|
}
|
|
16279
16342
|
};
|
|
16280
16343
|
/**
|
|
@@ -16307,12 +16370,18 @@ EXTERNAL: "External" };
|
|
|
16307
16370
|
*
|
|
16308
16371
|
* // Simple field with cached value
|
|
16309
16372
|
* new SimpleField("DATE", "2024-01-01");
|
|
16373
|
+
*
|
|
16374
|
+
* // Locked field, Word keeps the cached value when fields are updated
|
|
16375
|
+
* new SimpleField("DATE", "2024-01-01", { locked: true });
|
|
16310
16376
|
* ```
|
|
16311
16377
|
*/
|
|
16312
16378
|
var SimpleField = class extends XmlComponent {
|
|
16313
|
-
constructor(instruction, cachedValue) {
|
|
16379
|
+
constructor(instruction, cachedValue, options = {}) {
|
|
16314
16380
|
super("w:fldSimple");
|
|
16315
|
-
this.root.push(new FldSimpleAttrs({
|
|
16381
|
+
this.root.push(new FldSimpleAttrs({
|
|
16382
|
+
instr: instruction,
|
|
16383
|
+
fldLock: options.locked ? true : void 0
|
|
16384
|
+
}));
|
|
16316
16385
|
if (cachedValue !== void 0) this.root.push(new TextRun(cachedValue));
|
|
16317
16386
|
}
|
|
16318
16387
|
};
|
|
@@ -16337,6 +16406,1035 @@ EXTERNAL: "External" };
|
|
|
16337
16406
|
}
|
|
16338
16407
|
};
|
|
16339
16408
|
//#endregion
|
|
16409
|
+
//#region src/file/document/body/field-number-formats.ts
|
|
16410
|
+
var LARGEST_ROMAN = 32767;
|
|
16411
|
+
var LARGEST_LETTERS = 780;
|
|
16412
|
+
var ROMAN = [
|
|
16413
|
+
[1e3, "M"],
|
|
16414
|
+
[900, "CM"],
|
|
16415
|
+
[500, "D"],
|
|
16416
|
+
[400, "CD"],
|
|
16417
|
+
[100, "C"],
|
|
16418
|
+
[90, "XC"],
|
|
16419
|
+
[50, "L"],
|
|
16420
|
+
[40, "XL"],
|
|
16421
|
+
[10, "X"],
|
|
16422
|
+
[9, "IX"],
|
|
16423
|
+
[5, "V"],
|
|
16424
|
+
[4, "IV"],
|
|
16425
|
+
[1, "I"]
|
|
16426
|
+
];
|
|
16427
|
+
var roman = (value) => value <= LARGEST_ROMAN ? ROMAN.reduce(({ rest, text }, [amount, numeral]) => ({
|
|
16428
|
+
rest: rest % amount,
|
|
16429
|
+
text: text + numeral.repeat(Math.floor(rest / amount))
|
|
16430
|
+
}), {
|
|
16431
|
+
rest: value,
|
|
16432
|
+
text: ""
|
|
16433
|
+
}).text : void 0;
|
|
16434
|
+
var letters = (value) => value === 0 ? "" : value <= LARGEST_LETTERS ? String.fromCharCode(65 + (value - 1) % 26).repeat(Math.ceil(value / 26)) : void 0;
|
|
16435
|
+
var ordinal = (value) => {
|
|
16436
|
+
var _ref;
|
|
16437
|
+
return `${value}${value % 100 >= 11 && value % 100 <= 13 ? "th" : (_ref = [
|
|
16438
|
+
"th",
|
|
16439
|
+
"st",
|
|
16440
|
+
"nd",
|
|
16441
|
+
"rd"
|
|
16442
|
+
][value % 10]) !== null && _ref !== void 0 ? _ref : "th"}`;
|
|
16443
|
+
};
|
|
16444
|
+
/**
|
|
16445
|
+
* The number formats of a field's `\*` switch that are written as Word writes them, by their names in any capitals.
|
|
16446
|
+
* Word writes roman numerals and letters in small letters when the name starts with a small letter, as `roman`, and in
|
|
16447
|
+
* capitals otherwise, as `Roman` and `ROMAN`
|
|
16448
|
+
*/
|
|
16449
|
+
var numberWriterOf = (format) => {
|
|
16450
|
+
const small = format.charAt(0) !== format.charAt(0).toUpperCase();
|
|
16451
|
+
const inCase = (write) => (value) => {
|
|
16452
|
+
var _write;
|
|
16453
|
+
return small ? (_write = write(value)) === null || _write === void 0 ? void 0 : _write.toLowerCase() : write(value);
|
|
16454
|
+
};
|
|
16455
|
+
switch (format.toLowerCase()) {
|
|
16456
|
+
case "arabic": return String;
|
|
16457
|
+
case "roman": return inCase(roman);
|
|
16458
|
+
case "alphabetic": return inCase(letters);
|
|
16459
|
+
case "ordinal": return (value) => value > 0 ? ordinal(value) : void 0;
|
|
16460
|
+
case "arabicdash": return (value) => `- ${value} -`;
|
|
16461
|
+
default: return;
|
|
16462
|
+
}
|
|
16463
|
+
};
|
|
16464
|
+
var PLAIN_FORMATS = /* @__PURE__ */ new Set([
|
|
16465
|
+
"mergeformat",
|
|
16466
|
+
"charformat",
|
|
16467
|
+
"mergeformatinet"
|
|
16468
|
+
]);
|
|
16469
|
+
var CASE_FORMATS = /* @__PURE__ */ new Set([
|
|
16470
|
+
"upper",
|
|
16471
|
+
"lower",
|
|
16472
|
+
"firstcap",
|
|
16473
|
+
"caps"
|
|
16474
|
+
]);
|
|
16475
|
+
/**
|
|
16476
|
+
* Whether Word's text for a picture of a field's `\#` switch is known: one of digits (`0`), digits only where the number
|
|
16477
|
+
* has them (`#`) and commas between thousands, as Word wrote `00`, `000`, `0`, `#` and `#,##0` for page numbers
|
|
16478
|
+
* (`scripts/layout-probes/word-page-fields.ts` PF5 to PF7)
|
|
16479
|
+
*/
|
|
16480
|
+
var isNumberPicture = (picture) => /^[#0,]*[#0][#0,]*$/.test(picture);
|
|
16481
|
+
/**
|
|
16482
|
+
* 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
|
|
16483
|
+
* its thousands between commas when it has one (1234 is 1,234 with `#,##0`). Undefined where a `#` has no digit of the
|
|
16484
|
+
* number, which Word writes as a space, not yet seen
|
|
16485
|
+
*/
|
|
16486
|
+
var inNumberPicture = (value, picture) => {
|
|
16487
|
+
const zeros = [...picture].filter((character) => character === "0").length;
|
|
16488
|
+
const places = zeros + [...picture].filter((character) => character === "#").length;
|
|
16489
|
+
const digits = String(value).padStart(zeros, "0");
|
|
16490
|
+
if (digits.length < places || zeros === 0 && value === 0) return;
|
|
16491
|
+
return picture.includes(",") ? digits.replace(/\B(?=(\d{3})+$)/g, ",") : digits;
|
|
16492
|
+
};
|
|
16493
|
+
/**
|
|
16494
|
+
* Text in the capitals of a field's switch, applied after its number's format, as Word wrote `\* roman \* Upper` as V,
|
|
16495
|
+
* `\* Ordinal \* Upper` as 5TH, and "above" with `\* Upper` as ABOVE (`word-page-fields.ts` PF3 and PF5)
|
|
16496
|
+
*/
|
|
16497
|
+
var inCapitals = (text, capitals) => {
|
|
16498
|
+
switch (capitals) {
|
|
16499
|
+
case "upper": return text.toUpperCase();
|
|
16500
|
+
case "lower": return text.toLowerCase();
|
|
16501
|
+
case "firstcap": return text.charAt(0).toUpperCase() + text.slice(1);
|
|
16502
|
+
default: return text;
|
|
16503
|
+
}
|
|
16504
|
+
};
|
|
16505
|
+
//#endregion
|
|
16506
|
+
//#region src/file/document/body/page-number-fields.ts
|
|
16507
|
+
/**
|
|
16508
|
+
* Writes estimated page numbers into the fields of a tree of elements that show them: those docx formats to write a
|
|
16509
|
+
* document, and those `patchDocument` parses from a template. Not part of the public API.
|
|
16510
|
+
*
|
|
16511
|
+
* A page reference is a PAGEREF field, and the numbers of pages of the document and of a section are NUMPAGES and
|
|
16512
|
+
* SECTIONPAGES fields. Each field's result is written just after its `separate` field character, and any result it had
|
|
16513
|
+
* is taken out.
|
|
16514
|
+
*
|
|
16515
|
+
* @module
|
|
16516
|
+
*/
|
|
16517
|
+
/** Reads a field that shows a page's number or a number of pages, or undefined for another field */
|
|
16518
|
+
var numberFieldOf = (instruction) => {
|
|
16519
|
+
var _match;
|
|
16520
|
+
const field = new RegExp("^\\s*(PAGEREF|NUMPAGES|SECTIONPAGES)\\b(.*)$", "is").exec(instruction);
|
|
16521
|
+
const reference = (field === null || field === void 0 ? void 0 : field[1].toUpperCase()) === "PAGEREF" ? new RegExp("^\\s*(\"?)([^\\s\"\\\\]+)\\1(.*)$", "s").exec(field[2]) : void 0;
|
|
16522
|
+
if (!field || field[1].toUpperCase() === "PAGEREF" && !reference) return;
|
|
16523
|
+
const parts = (_match = (reference ? reference[3] : field[2]).match(/"[^"]*"|\S+/g)) !== null && _match !== void 0 ? _match : [];
|
|
16524
|
+
let numberFormat;
|
|
16525
|
+
let picture;
|
|
16526
|
+
const capitals = [];
|
|
16527
|
+
let relative = false;
|
|
16528
|
+
let written = true;
|
|
16529
|
+
for (let index = 0; index < parts.length; index++) {
|
|
16530
|
+
const part = parts[index];
|
|
16531
|
+
const argument = () => {
|
|
16532
|
+
var _parts$index;
|
|
16533
|
+
return (part.length > 2 ? part.slice(2) : (_parts$index = parts[++index]) !== null && _parts$index !== void 0 ? _parts$index : "").replace(/^"(.*)"$/, "$1");
|
|
16534
|
+
};
|
|
16535
|
+
if (/^\\p$/i.test(part)) relative = true;
|
|
16536
|
+
else if (part.startsWith("\\#")) {
|
|
16537
|
+
var _picture;
|
|
16538
|
+
const value = argument();
|
|
16539
|
+
written && (written = picture === void 0 && isNumberPicture(value));
|
|
16540
|
+
(_picture = picture) !== null && _picture !== void 0 || (picture = value);
|
|
16541
|
+
} else if (part.startsWith("\\*")) {
|
|
16542
|
+
const name = argument();
|
|
16543
|
+
const lower = name.toLowerCase();
|
|
16544
|
+
if (CASE_FORMATS.has(lower)) capitals.push(lower);
|
|
16545
|
+
else if (name !== "" && !PLAIN_FORMATS.has(lower)) {
|
|
16546
|
+
var _numberFormat;
|
|
16547
|
+
written && (written = numberFormat === void 0 && numberWriterOf(name) !== void 0);
|
|
16548
|
+
(_numberFormat = numberFormat) !== null && _numberFormat !== void 0 || (numberFormat = name);
|
|
16549
|
+
}
|
|
16550
|
+
}
|
|
16551
|
+
}
|
|
16552
|
+
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) });
|
|
16553
|
+
return reference ? _objectSpread2({
|
|
16554
|
+
type: "pageReference",
|
|
16555
|
+
bookmark: reference[2],
|
|
16556
|
+
relative
|
|
16557
|
+
}, own) : _objectSpread2({
|
|
16558
|
+
type: "pageCount",
|
|
16559
|
+
scope: field[1].toUpperCase() === "NUMPAGES" ? "document" : "section"
|
|
16560
|
+
}, own);
|
|
16561
|
+
};
|
|
16562
|
+
/**
|
|
16563
|
+
* Whether a field is a table of contents that writes the number of a SEQ field before each page number (`\s`), such as
|
|
16564
|
+
* 2-5 for page 5 of chapter 2, which isn't written
|
|
16565
|
+
*/
|
|
16566
|
+
var prefixesPageNumbers = (instruction) => new RegExp("^\\s*TOC\\b.*\\\\s\\b", "is").test(instruction);
|
|
16567
|
+
/**
|
|
16568
|
+
* 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
|
|
16569
|
+
* 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
|
|
16570
|
+
* writes a SEQ field's number before it.
|
|
16571
|
+
*/
|
|
16572
|
+
var resultFrom = (instruction, { enclosing, within, inTextBox }, { estimate, sectionPageCount, blank, relativeTo }) => {
|
|
16573
|
+
const field = numberFieldOf(instruction);
|
|
16574
|
+
if (field === void 0) return;
|
|
16575
|
+
const { bookmarks, pageCount, bookmarkPageNumbers } = estimate;
|
|
16576
|
+
const { numberFormat, picture, capitals, written } = field;
|
|
16577
|
+
const writesNumber = numberFormat !== void 0 || picture !== void 0;
|
|
16578
|
+
/** A number in the field's format of its own, or as it is */
|
|
16579
|
+
const inFormat = (value) => value === void 0 ? void 0 : picture === void 0 ? numberWriterOf(numberFormat !== null && numberFormat !== void 0 ? numberFormat : "arabic")(value) : inNumberPicture(value, picture);
|
|
16580
|
+
const position = field.type === "pageReference" && field.relative && within === "counted" && !inTextBox ? relativeTo === null || relativeTo === void 0 ? void 0 : relativeTo(field.bookmark) : void 0;
|
|
16581
|
+
let result;
|
|
16582
|
+
if (!written) result = void 0;
|
|
16583
|
+
else if (field.type === "pageCount") result = inFormat(field.scope === "document" ? pageCount : sectionPageCount);
|
|
16584
|
+
else if (enclosing.some(prefixesPageNumbers)) result = void 0;
|
|
16585
|
+
else if (writesNumber) result = inFormat(bookmarkPageNumbers === null || bookmarkPageNumbers === void 0 ? void 0 : bookmarkPageNumbers.get(field.bookmark));
|
|
16586
|
+
else result = field.relative ? position : bookmarks.get(field.bookmark);
|
|
16587
|
+
return result === void 0 ? blank ? "" : void 0 : inCapitals(result, capitals);
|
|
16588
|
+
};
|
|
16589
|
+
/** Where the content of an element is: in what an application that doesn't read Word's own shows, or in deleted text */
|
|
16590
|
+
var placeIn = (name, within) => name === "mc:Fallback" || within === "fallback" ? "fallback" : name === "w:del" || name === "w:moveFrom" ? "deleted" : within;
|
|
16591
|
+
/**
|
|
16592
|
+
* Writes the results the filling works out into the fields in the elements, in order.
|
|
16593
|
+
*/
|
|
16594
|
+
var fillFields = (tree, elements, open, filling, within = "counted", inTextBox = false) => {
|
|
16595
|
+
for (let index = 0; index < elements.length; index++) {
|
|
16596
|
+
const element = elements[index];
|
|
16597
|
+
const name = tree.nameOf(element);
|
|
16598
|
+
if (name === void 0) continue;
|
|
16599
|
+
const current = open[open.length - 1];
|
|
16600
|
+
if (name === "w:fldChar") {
|
|
16601
|
+
const type = tree.attributeOf(element, "w:fldCharType");
|
|
16602
|
+
if (type === "begin") open.push({
|
|
16603
|
+
begin: element,
|
|
16604
|
+
instruction: "",
|
|
16605
|
+
inResult: false
|
|
16606
|
+
});
|
|
16607
|
+
else if (type === "separate" && current) {
|
|
16608
|
+
tree.writeClean(current.begin, current.instruction);
|
|
16609
|
+
current.inResult = true;
|
|
16610
|
+
current.result = filling.resultOf(current.instruction, {
|
|
16611
|
+
within,
|
|
16612
|
+
enclosing: open.slice(0, -1).map((field) => field.instruction),
|
|
16613
|
+
inTextBox
|
|
16614
|
+
});
|
|
16615
|
+
if (current.result !== void 0) {
|
|
16616
|
+
elements.splice(index + 1, 0, tree.textElement(current.result));
|
|
16617
|
+
index++;
|
|
16618
|
+
}
|
|
16619
|
+
} else if (type === "end") open.pop();
|
|
16620
|
+
} else if (name === "w:instrText" && current && !current.inResult) current.instruction += tree.textOf(element);
|
|
16621
|
+
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) {
|
|
16622
|
+
elements.splice(index, 1);
|
|
16623
|
+
index--;
|
|
16624
|
+
} else if (name === "w:fldSimple") {
|
|
16625
|
+
const result = filling.resultOf(String(tree.attributeOf(element, "w:instr")), {
|
|
16626
|
+
within,
|
|
16627
|
+
enclosing: open.map((field) => field.instruction),
|
|
16628
|
+
inTextBox
|
|
16629
|
+
});
|
|
16630
|
+
if (result === void 0) {
|
|
16631
|
+
var _tree$contentOf;
|
|
16632
|
+
fillFields(tree, (_tree$contentOf = tree.contentOf(element)) !== null && _tree$contentOf !== void 0 ? _tree$contentOf : [], [], filling, within, inTextBox);
|
|
16633
|
+
} else tree.setSimpleFieldResult(element, result);
|
|
16634
|
+
} else {
|
|
16635
|
+
var _tree$contentOf2;
|
|
16636
|
+
if (name === "w:p") {
|
|
16637
|
+
var _filling$beforeParagr;
|
|
16638
|
+
(_filling$beforeParagr = filling.beforeParagraph) === null || _filling$beforeParagr === void 0 || _filling$beforeParagr.call(filling, element);
|
|
16639
|
+
}
|
|
16640
|
+
fillFields(tree, (_tree$contentOf2 = tree.contentOf(element)) !== null && _tree$contentOf2 !== void 0 ? _tree$contentOf2 : [], open, filling, placeIn(name, within), inTextBox || name === "w:txbxContent");
|
|
16641
|
+
if (name === "w:p") filling.afterParagraph(element);
|
|
16642
|
+
}
|
|
16643
|
+
}
|
|
16644
|
+
};
|
|
16645
|
+
/** The section properties (`w:sectPr`) in the elements, in order: those of the paragraphs that end sections, and the last */
|
|
16646
|
+
var sectionPropertiesIn = (tree, elements) => elements.flatMap((element) => {
|
|
16647
|
+
var _tree$contentOf3;
|
|
16648
|
+
const name = tree.nameOf(element);
|
|
16649
|
+
if (name === void 0) return [];
|
|
16650
|
+
return name === "w:sectPr" ? [element] : sectionPropertiesIn(tree, (_tree$contentOf3 = tree.contentOf(element)) !== null && _tree$contentOf3 !== void 0 ? _tree$contentOf3 : []);
|
|
16651
|
+
});
|
|
16652
|
+
/** Whether a paragraph ends a section: whether its properties have the section's */
|
|
16653
|
+
var endsSection = (tree, paragraph) => {
|
|
16654
|
+
var _tree$contentOf4;
|
|
16655
|
+
return ((_tree$contentOf4 = tree.contentOf(paragraph)) !== null && _tree$contentOf4 !== void 0 ? _tree$contentOf4 : []).some((child) => {
|
|
16656
|
+
var _tree$contentOf5;
|
|
16657
|
+
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");
|
|
16658
|
+
});
|
|
16659
|
+
};
|
|
16660
|
+
/**
|
|
16661
|
+
* The number of pages each header and footer shows in its SECTIONPAGES fields, by the id of the relationship to it:
|
|
16662
|
+
* 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
|
|
16663
|
+
* has the one of the section before, as Word lays them out.
|
|
16664
|
+
*/
|
|
16665
|
+
var partPageCountsOf = (tree, body, sectionPageCounts) => {
|
|
16666
|
+
const countsOfParts = sectionPropertiesIn(tree, [body]).reduce((all, properties) => {
|
|
16667
|
+
var _tree$contentOf6, _all;
|
|
16668
|
+
const references = ((_tree$contentOf6 = tree.contentOf(properties)) !== null && _tree$contentOf6 !== void 0 ? _tree$contentOf6 : []).flatMap((child) => {
|
|
16669
|
+
const name = tree.nameOf(child);
|
|
16670
|
+
return name === "w:headerReference" || name === "w:footerReference" ? [[`${name} ${String(tree.attributeOf(child, "w:type"))}`, String(tree.attributeOf(child, "r:id"))]] : [];
|
|
16671
|
+
});
|
|
16672
|
+
return [...all, new Map([...(_all = all[all.length - 1]) !== null && _all !== void 0 ? _all : [], ...references])];
|
|
16673
|
+
}, []).reduce((counts, parts, section) => {
|
|
16674
|
+
for (const id of parts.values()) {
|
|
16675
|
+
var _counts$get;
|
|
16676
|
+
counts.set(id, [...(_counts$get = counts.get(id)) !== null && _counts$get !== void 0 ? _counts$get : [], sectionPageCounts[section]]);
|
|
16677
|
+
}
|
|
16678
|
+
return counts;
|
|
16679
|
+
}, /* @__PURE__ */ new Map());
|
|
16680
|
+
return new Map([...countsOfParts].flatMap(([id, [first, ...rest]]) => first !== void 0 && rest.every((count) => count === first) ? [[id, first]] : []));
|
|
16681
|
+
};
|
|
16682
|
+
/**
|
|
16683
|
+
* Writes the estimated page numbers into the fields of a document's body that show them: its PAGEREF fields, in its
|
|
16684
|
+
* tables of contents and elsewhere, and its NUMPAGES and SECTIONPAGES fields.
|
|
16685
|
+
*
|
|
16686
|
+
* @returns The number of pages each header and footer shows in its SECTIONPAGES fields, by the id of the relationship to it
|
|
16687
|
+
*/
|
|
16688
|
+
var fillBodyFields = (tree, body, estimate, { blank }) => {
|
|
16689
|
+
const { sectionPageCounts = [], relativePositions } = estimate;
|
|
16690
|
+
let section = 0;
|
|
16691
|
+
const relativeCounts = /* @__PURE__ */ new Map();
|
|
16692
|
+
const relativeTo = (bookmark) => {
|
|
16693
|
+
var _relativeCounts$get, _relativePositions$ge;
|
|
16694
|
+
const count = (_relativeCounts$get = relativeCounts.get(bookmark)) !== null && _relativeCounts$get !== void 0 ? _relativeCounts$get : 0;
|
|
16695
|
+
relativeCounts.set(bookmark, count + 1);
|
|
16696
|
+
return relativePositions === null || relativePositions === void 0 || (_relativePositions$ge = relativePositions.get(bookmark)) === null || _relativePositions$ge === void 0 ? void 0 : _relativePositions$ge[count];
|
|
16697
|
+
};
|
|
16698
|
+
fillFields(tree, [body], [], {
|
|
16699
|
+
resultOf: (instruction, place) => resultFrom(instruction, place, {
|
|
16700
|
+
estimate,
|
|
16701
|
+
sectionPageCount: sectionPageCounts[section],
|
|
16702
|
+
blank,
|
|
16703
|
+
relativeTo
|
|
16704
|
+
}),
|
|
16705
|
+
afterParagraph: (paragraph) => {
|
|
16706
|
+
section += endsSection(tree, paragraph) ? 1 : 0;
|
|
16707
|
+
}
|
|
16708
|
+
});
|
|
16709
|
+
return partPageCountsOf(tree, body, sectionPageCounts);
|
|
16710
|
+
};
|
|
16711
|
+
/**
|
|
16712
|
+
* Writes the estimated page numbers into the fields of a header, footer, footnote or endnote that show them, with the
|
|
16713
|
+
* number of pages its SECTIONPAGES fields show, if it is known. A page reference with `\p` in a footnote or endnote
|
|
16714
|
+
* (`notes`) writes "on page" and its bookmark's page, whatever page it is on, as Word writes it
|
|
16715
|
+
* (`word-page-fields.docx` PF8f, PF8g)
|
|
16716
|
+
*/
|
|
16717
|
+
var fillPartFields = (tree, part, estimate, { blank, sectionPageCount, notes = false }) => {
|
|
16718
|
+
const onPage = (bookmark) => {
|
|
16719
|
+
const page = estimate.bookmarks.get(bookmark);
|
|
16720
|
+
return page === void 0 ? void 0 : `on page ${page}`;
|
|
16721
|
+
};
|
|
16722
|
+
fillFields(tree, [part], [], {
|
|
16723
|
+
resultOf: (instruction, place) => resultFrom(instruction, place, _objectSpread2({
|
|
16724
|
+
estimate,
|
|
16725
|
+
sectionPageCount,
|
|
16726
|
+
blank
|
|
16727
|
+
}, notes ? { relativeTo: onPage } : {})),
|
|
16728
|
+
afterParagraph: () => void 0
|
|
16729
|
+
});
|
|
16730
|
+
};
|
|
16731
|
+
/** Writes the numbers of the SEQ fields of a document's body into them */
|
|
16732
|
+
var fillSequenceFields = (tree, body, { beforeParagraph, resultOf }) => fillFields(tree, [body], [], {
|
|
16733
|
+
resultOf: (instruction, { within }) => resultOf(instruction, within),
|
|
16734
|
+
beforeParagraph,
|
|
16735
|
+
afterParagraph: () => void 0
|
|
16736
|
+
});
|
|
16737
|
+
//#endregion
|
|
16738
|
+
//#region src/file/table-of-contents/field-instruction.ts
|
|
16739
|
+
/**
|
|
16740
|
+
* Field Instruction module for Table of Contents.
|
|
16741
|
+
*
|
|
16742
|
+
* This module handles the generation of TOC field instruction text
|
|
16743
|
+
* that controls how the table of contents is built.
|
|
16744
|
+
*
|
|
16745
|
+
* Reference: http://officeopenxml.com/WPfieldInstructions.php
|
|
16746
|
+
*
|
|
16747
|
+
* @module
|
|
16748
|
+
*/
|
|
16749
|
+
/**
|
|
16750
|
+
* Represents a field instruction for a Table of Contents.
|
|
16751
|
+
*
|
|
16752
|
+
* The FieldInstruction class generates the TOC field code string that Word uses
|
|
16753
|
+
* to determine how to build the table of contents, including which headings to include,
|
|
16754
|
+
* formatting options, and other TOC-specific settings.
|
|
16755
|
+
*
|
|
16756
|
+
* Reference: http://officeopenxml.com/WPfieldInstructions.php
|
|
16757
|
+
*
|
|
16758
|
+
* ## XSD Schema
|
|
16759
|
+
* ```xml
|
|
16760
|
+
* <xsd:element name="instrText" type="CT_Text"/>
|
|
16761
|
+
* ```
|
|
16762
|
+
*
|
|
16763
|
+
* @example
|
|
16764
|
+
* ```typescript
|
|
16765
|
+
* // Basic TOC field instruction
|
|
16766
|
+
* new FieldInstruction({ headingStyleRange: "1-3" });
|
|
16767
|
+
*
|
|
16768
|
+
* // TOC with hyperlinks and custom styles
|
|
16769
|
+
* new FieldInstruction({
|
|
16770
|
+
* hyperlink: true,
|
|
16771
|
+
* headingStyleRange: "1-3",
|
|
16772
|
+
* stylesWithLevels: [new StyleLevel("CustomStyle", 2)],
|
|
16773
|
+
* });
|
|
16774
|
+
* ```
|
|
16775
|
+
*/
|
|
16776
|
+
var FieldInstruction = class extends XmlComponent {
|
|
16777
|
+
constructor(properties = {}) {
|
|
16778
|
+
super("w:instrText");
|
|
16779
|
+
_defineProperty(this, "properties", void 0);
|
|
16780
|
+
this.properties = properties;
|
|
16781
|
+
this.root.push(new TextAttributes({ space: SpaceType.PRESERVE }));
|
|
16782
|
+
let instruction = "TOC";
|
|
16783
|
+
if (this.properties.captionLabel) instruction = `${instruction} \\a "${this.properties.captionLabel}"`;
|
|
16784
|
+
if (this.properties.entriesFromBookmark) instruction = `${instruction} \\b "${this.properties.entriesFromBookmark}"`;
|
|
16785
|
+
if (this.properties.captionLabelIncludingNumbers) instruction = `${instruction} \\c "${this.properties.captionLabelIncludingNumbers}"`;
|
|
16786
|
+
if (this.properties.sequenceAndPageNumbersSeparator) instruction = `${instruction} \\d "${this.properties.sequenceAndPageNumbersSeparator}"`;
|
|
16787
|
+
if (this.properties.tcFieldIdentifier) instruction = `${instruction} \\f "${this.properties.tcFieldIdentifier}"`;
|
|
16788
|
+
if (this.properties.hyperlink) instruction = `${instruction} \\h`;
|
|
16789
|
+
if (this.properties.tcFieldLevelRange) instruction = `${instruction} \\l "${this.properties.tcFieldLevelRange}"`;
|
|
16790
|
+
if (this.properties.pageNumbersEntryLevelsRange) instruction = `${instruction} \\n "${this.properties.pageNumbersEntryLevelsRange}"`;
|
|
16791
|
+
if (this.properties.headingStyleRange) instruction = `${instruction} \\o "${this.properties.headingStyleRange}"`;
|
|
16792
|
+
if (this.properties.entryAndPageNumberSeparator) instruction = `${instruction} \\p "${this.properties.entryAndPageNumberSeparator}"`;
|
|
16793
|
+
if (this.properties.seqFieldIdentifierForPrefix) instruction = `${instruction} \\s "${this.properties.seqFieldIdentifierForPrefix}"`;
|
|
16794
|
+
if (this.properties.stylesWithLevels && this.properties.stylesWithLevels.length) {
|
|
16795
|
+
const styles = this.properties.stylesWithLevels.map((sl) => `${sl.styleName},${sl.level}`).join(",");
|
|
16796
|
+
instruction = `${instruction} \\t "${styles}"`;
|
|
16797
|
+
}
|
|
16798
|
+
if (this.properties.useAppliedParagraphOutlineLevel) instruction = `${instruction} \\u`;
|
|
16799
|
+
if (this.properties.preserveTabInEntries) instruction = `${instruction} \\w`;
|
|
16800
|
+
if (this.properties.preserveNewLineInEntries) instruction = `${instruction} \\x`;
|
|
16801
|
+
if (this.properties.hideTabAndPageNumbersInWebView) instruction = `${instruction} \\z`;
|
|
16802
|
+
this.root.push(instruction);
|
|
16803
|
+
}
|
|
16804
|
+
};
|
|
16805
|
+
//#endregion
|
|
16806
|
+
//#region src/file/table-of-contents/sdt-content.ts
|
|
16807
|
+
/**
|
|
16808
|
+
* Structured Document Tag Content module.
|
|
16809
|
+
*
|
|
16810
|
+
* This module represents the content container for structured document tags,
|
|
16811
|
+
* including table of contents elements.
|
|
16812
|
+
*
|
|
16813
|
+
* Reference: http://officeopenxml.com/WPtableOfContents.php
|
|
16814
|
+
*
|
|
16815
|
+
* @module
|
|
16816
|
+
*/
|
|
16817
|
+
/**
|
|
16818
|
+
* Represents the content portion of a Structured Document Tag.
|
|
16819
|
+
*
|
|
16820
|
+
* The StructuredDocumentTagContent contains the actual content elements
|
|
16821
|
+
* (paragraphs, tables, etc.) within a structured document tag, such as
|
|
16822
|
+
* the paragraphs that make up a table of contents.
|
|
16823
|
+
*
|
|
16824
|
+
* Reference: http://officeopenxml.com/WPtableOfContents.php
|
|
16825
|
+
*
|
|
16826
|
+
* ## XSD Schema
|
|
16827
|
+
* ```xml
|
|
16828
|
+
* <xsd:complexType name="CT_SdtContentBlock">
|
|
16829
|
+
* <xsd:group ref="EG_ContentBlockContent" minOccurs="0" maxOccurs="unbounded"/>
|
|
16830
|
+
* </xsd:complexType>
|
|
16831
|
+
* ```
|
|
16832
|
+
*
|
|
16833
|
+
* @example
|
|
16834
|
+
* ```typescript
|
|
16835
|
+
* const content = new StructuredDocumentTagContent();
|
|
16836
|
+
* content.addChildElement(new Paragraph("Content"));
|
|
16837
|
+
* ```
|
|
16838
|
+
*/
|
|
16839
|
+
var StructuredDocumentTagContent = class extends XmlComponent {
|
|
16840
|
+
constructor() {
|
|
16841
|
+
super("w:sdtContent");
|
|
16842
|
+
}
|
|
16843
|
+
};
|
|
16844
|
+
//#endregion
|
|
16845
|
+
//#region src/file/table-of-contents/heading-entries.ts
|
|
16846
|
+
/**
|
|
16847
|
+
* Entries written into a table of contents from the headings of the document.
|
|
16848
|
+
*
|
|
16849
|
+
* A table of contents is a TOC field. Word fills in its entries when it updates the field. Until then, and in
|
|
16850
|
+
* applications that don't update it, such as LibreOffice, it shows the entries it was last filled in with, and without
|
|
16851
|
+
* any it is empty. So once the body is written, each table of contents that wasn't given `cachedEntries` or
|
|
16852
|
+
* `contentChildren` is filled in from the headings its switches include, the way Word fills it in: each heading is
|
|
16853
|
+
* bookmarked, and its entry links to the bookmark and gives its page with a PAGEREF field. The page numbers are left
|
|
16854
|
+
* empty, because they depend on how the document is laid out. Word fills them in when it updates the field, unless the
|
|
16855
|
+
* document's `pageNumbers` writes them.
|
|
16856
|
+
*
|
|
16857
|
+
* @module
|
|
16858
|
+
*/
|
|
16859
|
+
/**
|
|
16860
|
+
* The beginning of a table of contents' field: dirty or clean, as the caller set it, or else dirty unless the document
|
|
16861
|
+
* is given page numbers
|
|
16862
|
+
*/
|
|
16863
|
+
var beginOf = (beginDirty) => beginDirty === void 0 ? createBeginDirtyWithoutPageNumbers() : createBegin(beginDirty);
|
|
16864
|
+
/** The formatted tables of contents, with what each is filled in with, or undefined when it was given its content */
|
|
16865
|
+
var writtenTables = /* @__PURE__ */ new WeakMap();
|
|
16866
|
+
/**
|
|
16867
|
+
* Records a formatted table of contents, so the paragraphs in it aren't taken for headings, with what to fill it in
|
|
16868
|
+
* with from the headings once the body it is in is written. That is undefined when it was given its content.
|
|
16869
|
+
*/
|
|
16870
|
+
var recordTableOfContents = (table, fillWith) => {
|
|
16871
|
+
writtenTables.set(table, fillWith);
|
|
16872
|
+
};
|
|
16873
|
+
/**
|
|
16874
|
+
* The ids of the bookmarks on a body's headings: the first for its first bookmarked heading, and so on. Each is taken
|
|
16875
|
+
* from the counter every bookmark shares, the first time it is needed, so a document packed again is written the same.
|
|
16876
|
+
*/
|
|
16877
|
+
var HeadingBookmarkIds = class {
|
|
16878
|
+
constructor() {
|
|
16879
|
+
_defineProperty(this, "ids", []);
|
|
16880
|
+
}
|
|
16881
|
+
get(index) {
|
|
16882
|
+
var _this$ids, _this$ids$index;
|
|
16883
|
+
(_this$ids$index = (_this$ids = this.ids)[index]) !== null && _this$ids$index !== void 0 || (_this$ids[index] = bookmarkUniqueNumericId());
|
|
16884
|
+
return this.ids[index];
|
|
16885
|
+
}
|
|
16886
|
+
};
|
|
16887
|
+
/** The name of a formatted element, or `_attr` for its parent's attributes */
|
|
16888
|
+
var nameOf$2 = (element) => typeof element === "object" && element !== null ? Object.keys(element)[0] : void 0;
|
|
16889
|
+
/** The children of a formatted element. An element with only attributes has them as its one child */
|
|
16890
|
+
var childrenOf = (element) => {
|
|
16891
|
+
const name = nameOf$2(element);
|
|
16892
|
+
const content = name === void 0 ? void 0 : element[name];
|
|
16893
|
+
return Array.isArray(content) ? content : content === void 0 ? [] : [content];
|
|
16894
|
+
};
|
|
16895
|
+
var childOf = (element, name) => childrenOf(element).find((child) => nameOf$2(child) === name);
|
|
16896
|
+
var attributeOf = (element, attribute) => {
|
|
16897
|
+
var _childOf;
|
|
16898
|
+
return (_childOf = childOf(element, "_attr")) === null || _childOf === void 0 || (_childOf = _childOf._attr) === null || _childOf === void 0 ? void 0 : _childOf[attribute];
|
|
16899
|
+
};
|
|
16900
|
+
/** An attribute such as `w:val="2"` as a number. Imported XML gives it as a string */
|
|
16901
|
+
var numberAttributeOf = (element, attribute) => {
|
|
16902
|
+
const value = attributeOf(element, attribute);
|
|
16903
|
+
return value === void 0 ? void 0 : Number(value);
|
|
16904
|
+
};
|
|
16905
|
+
/** The block-level containers of paragraphs: tables, their rows and cells, and content controls */
|
|
16906
|
+
var BLOCK_CONTAINERS = /* @__PURE__ */ new Set([
|
|
16907
|
+
"w:tbl",
|
|
16908
|
+
"w:tr",
|
|
16909
|
+
"w:tc",
|
|
16910
|
+
"w:sdt",
|
|
16911
|
+
"w:sdtContent",
|
|
16912
|
+
"w:customXml"
|
|
16913
|
+
]);
|
|
16914
|
+
/**
|
|
16915
|
+
* The paragraphs and the tables of contents, in the order they are in the body. A table of contents isn't looked into,
|
|
16916
|
+
* so the paragraphs in it aren't taken for headings. Nor are paragraphs in text boxes, as in Word.
|
|
16917
|
+
*/
|
|
16918
|
+
var blocksOf = (elements) => elements.flatMap((element) => {
|
|
16919
|
+
const name = nameOf$2(element);
|
|
16920
|
+
if (name === "w:p" || writtenTables.has(element)) return [element];
|
|
16921
|
+
return name !== void 0 && BLOCK_CONTAINERS.has(name) ? blocksOf(childrenOf(element)) : [];
|
|
16922
|
+
});
|
|
16923
|
+
/** The elements in a paragraph that its text is in. Deleted text, field instructions and drawings aren't */
|
|
16924
|
+
var TEXT_CONTAINERS = /* @__PURE__ */ new Set([
|
|
16925
|
+
"w:r",
|
|
16926
|
+
"w:hyperlink",
|
|
16927
|
+
"w:ins",
|
|
16928
|
+
"w:moveTo",
|
|
16929
|
+
"w:smartTag",
|
|
16930
|
+
"w:customXml",
|
|
16931
|
+
"w:sdt",
|
|
16932
|
+
"w:sdtContent",
|
|
16933
|
+
"w:fldSimple",
|
|
16934
|
+
"w:dir",
|
|
16935
|
+
"w:bdo"
|
|
16936
|
+
]);
|
|
16937
|
+
/** The text an element in a run stands for, such as `\t` for a tab. A page or column break isn't text */
|
|
16938
|
+
var textOfRunContent = (element) => {
|
|
16939
|
+
switch (nameOf$2(element)) {
|
|
16940
|
+
case "w:t": return childrenOf(element).filter((child) => typeof child === "string").join("");
|
|
16941
|
+
case "w:tab": return " ";
|
|
16942
|
+
case "w:br": return [void 0, "textWrapping"].includes(attributeOf(element, "w:type")) ? "\n" : "";
|
|
16943
|
+
case "w:cr": return "\n";
|
|
16944
|
+
case "w:noBreakHyphen": return "-";
|
|
16945
|
+
default: return "";
|
|
16946
|
+
}
|
|
16947
|
+
};
|
|
16948
|
+
/** The text of a paragraph. Of a field, only its result is text, not its instruction */
|
|
16949
|
+
var textOf = (paragraph) => {
|
|
16950
|
+
const fields = [];
|
|
16951
|
+
const read = (element) => {
|
|
16952
|
+
const name = nameOf$2(element);
|
|
16953
|
+
if (name !== void 0 && TEXT_CONTAINERS.has(name)) return childrenOf(element).map(read).join("");
|
|
16954
|
+
if (name === "w:fldChar") {
|
|
16955
|
+
const type = attributeOf(element, "w:fldCharType");
|
|
16956
|
+
if (type === "begin") fields.push(false);
|
|
16957
|
+
else if (type === "separate") fields[fields.length - 1] = true;
|
|
16958
|
+
else fields.pop();
|
|
16959
|
+
return "";
|
|
16960
|
+
}
|
|
16961
|
+
return fields.every(Boolean) ? textOfRunContent(element) : "";
|
|
16962
|
+
};
|
|
16963
|
+
return childrenOf(paragraph).map(read).join("");
|
|
16964
|
+
};
|
|
16965
|
+
/** The bookmarks started and ended in an element, in order */
|
|
16966
|
+
var bookmarkMarksOf = (element) => {
|
|
16967
|
+
const name = nameOf$2(element);
|
|
16968
|
+
if (name === "w:bookmarkStart") return [{
|
|
16969
|
+
start: true,
|
|
16970
|
+
id: attributeOf(element, "w:id"),
|
|
16971
|
+
name: attributeOf(element, "w:name")
|
|
16972
|
+
}];
|
|
16973
|
+
if (name === "w:bookmarkEnd") return [{
|
|
16974
|
+
start: false,
|
|
16975
|
+
id: attributeOf(element, "w:id")
|
|
16976
|
+
}];
|
|
16977
|
+
return name === void 0 || name === "_attr" ? [] : childrenOf(element).flatMap(bookmarkMarksOf);
|
|
16978
|
+
};
|
|
16979
|
+
/**
|
|
16980
|
+
* The names of the bookmarks each paragraph is in, for the `\b` switch: those open where it starts, followed through the
|
|
16981
|
+
* body, and those that start in it.
|
|
16982
|
+
*/
|
|
16983
|
+
var bookmarksOf = (paragraphs) => {
|
|
16984
|
+
const open = /* @__PURE__ */ new Map();
|
|
16985
|
+
return paragraphs.map((paragraph) => {
|
|
16986
|
+
const marks = bookmarkMarksOf(paragraph);
|
|
16987
|
+
const names = /* @__PURE__ */ new Set([...open.values(), ...marks.flatMap((mark) => mark.start ? [mark.name] : [])]);
|
|
16988
|
+
for (const mark of marks) if (mark.start) open.set(mark.id, mark.name);
|
|
16989
|
+
else open.delete(mark.id);
|
|
16990
|
+
return names;
|
|
16991
|
+
});
|
|
16992
|
+
};
|
|
16993
|
+
/** The details of each paragraph that could be a heading. The bookmarks it is in are only followed when needed */
|
|
16994
|
+
var paragraphDetailsOf = (paragraphs, followBookmarks) => {
|
|
16995
|
+
const bookmarks = followBookmarks ? bookmarksOf(paragraphs) : [];
|
|
16996
|
+
return paragraphs.map((element, index) => {
|
|
16997
|
+
var _bookmarks$index;
|
|
16998
|
+
const properties = childOf(element, "w:pPr");
|
|
16999
|
+
return {
|
|
17000
|
+
element,
|
|
17001
|
+
styleId: attributeOf(childOf(properties, "w:pStyle"), "w:val"),
|
|
17002
|
+
outlineLevel: numberAttributeOf(childOf(properties, "w:outlineLvl"), "w:val"),
|
|
17003
|
+
text: textOf(element),
|
|
17004
|
+
bookmarks: (_bookmarks$index = bookmarks[index]) !== null && _bookmarks$index !== void 0 ? _bookmarks$index : /* @__PURE__ */ new Set()
|
|
17005
|
+
};
|
|
17006
|
+
});
|
|
17007
|
+
};
|
|
17008
|
+
/** The document's paragraph styles, by id, read from the styles as they are written */
|
|
17009
|
+
var stylesOf = (context) => {
|
|
17010
|
+
var _context$file;
|
|
17011
|
+
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);
|
|
17012
|
+
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"), {
|
|
17013
|
+
name: attributeOf(childOf(style, "w:name"), "w:val"),
|
|
17014
|
+
basedOn: attributeOf(childOf(style, "w:basedOn"), "w:val"),
|
|
17015
|
+
outlineLevel: numberAttributeOf(childOf(childOf(style, "w:pPr"), "w:outlineLvl"), "w:val")
|
|
17016
|
+
}]));
|
|
17017
|
+
};
|
|
17018
|
+
/** A range such as `1-3` */
|
|
17019
|
+
var parseRange = (range) => {
|
|
17020
|
+
const match = /^\s*(\d+)\s*-\s*(\d+)\s*$/.exec(range);
|
|
17021
|
+
return match ? [Number(match[1]), Number(match[2])] : void 0;
|
|
17022
|
+
};
|
|
17023
|
+
var isWithin = (level, [from, to]) => level >= from && level <= to;
|
|
17024
|
+
/** 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 */
|
|
17025
|
+
var headingLevelOf = (styleId, styles) => {
|
|
17026
|
+
var _styles$get$name, _styles$get;
|
|
17027
|
+
if (styleId === void 0) return;
|
|
17028
|
+
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);
|
|
17029
|
+
return match ? Number(match[1]) : void 0;
|
|
17030
|
+
};
|
|
17031
|
+
/**
|
|
17032
|
+
* 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
|
|
17033
|
+
* its heading's. Following the styles it is based on stops after as many as there are, in case they loop.
|
|
17034
|
+
*/
|
|
17035
|
+
var styleOutlineLevelOf = (styleId, styles, depth = 0) => {
|
|
17036
|
+
var _style$outlineLevel;
|
|
17037
|
+
if (styleId === void 0 || depth > styles.size) return;
|
|
17038
|
+
const style = styles.get(styleId);
|
|
17039
|
+
const heading = headingLevelOf(styleId, styles);
|
|
17040
|
+
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;
|
|
17041
|
+
};
|
|
17042
|
+
/**
|
|
17043
|
+
* Reads the heading level of the document's paragraphs, as the `\s` switch of a SEQ field follows it: the level of a
|
|
17044
|
+
* paragraph in a built-in heading style, Heading 1 to Heading 9. A paragraph whose outline level is another, or that has
|
|
17045
|
+
* one without a heading style, is `"unclear"`, as which of the two Word follows hasn't been checked. Other paragraphs
|
|
17046
|
+
* are undefined.
|
|
17047
|
+
*/
|
|
17048
|
+
var headingLevels = (context) => {
|
|
17049
|
+
const styles = stylesOf(context);
|
|
17050
|
+
return (paragraph) => {
|
|
17051
|
+
const properties = childOf(paragraph, "w:pPr");
|
|
17052
|
+
const styleId = attributeOf(childOf(properties, "w:pStyle"), "w:val");
|
|
17053
|
+
const heading = headingLevelOf(styleId, styles);
|
|
17054
|
+
const outlineLevel = outlineLevelOf({
|
|
17055
|
+
styleId,
|
|
17056
|
+
outlineLevel: numberAttributeOf(childOf(properties, "w:outlineLvl"), "w:val")
|
|
17057
|
+
}, styles);
|
|
17058
|
+
const outline = outlineLevel === void 0 || outlineLevel >= 9 ? void 0 : outlineLevel + 1;
|
|
17059
|
+
if (heading !== void 0 && (outline === void 0 || outline === heading)) return heading;
|
|
17060
|
+
return outline === void 0 ? void 0 : "unclear";
|
|
17061
|
+
};
|
|
17062
|
+
};
|
|
17063
|
+
/** A paragraph's outline level, from 0: its own, or else its style's */
|
|
17064
|
+
var outlineLevelOf = (paragraph, styles) => {
|
|
17065
|
+
var _paragraph$outlineLev;
|
|
17066
|
+
return (_paragraph$outlineLev = paragraph.outlineLevel) !== null && _paragraph$outlineLev !== void 0 ? _paragraph$outlineLev : styleOutlineLevelOf(paragraph.styleId, styles);
|
|
17067
|
+
};
|
|
17068
|
+
/** The level a table of contents gives a paragraph, or undefined when it doesn't include it */
|
|
17069
|
+
var levelIn = (properties, paragraph, styles) => {
|
|
17070
|
+
var _styles$get2;
|
|
17071
|
+
const { entriesFromBookmark, headingStyleRange, stylesWithLevels = [], useAppliedParagraphOutlineLevel } = properties;
|
|
17072
|
+
if (paragraph.text.trim() === "" || entriesFromBookmark && !paragraph.bookmarks.has(entriesFromBookmark)) return;
|
|
17073
|
+
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());
|
|
17074
|
+
const listed = stylesWithLevels.find((style) => names.includes(style.styleName.toLowerCase()));
|
|
17075
|
+
if (listed) return listed.level;
|
|
17076
|
+
const namesItsEntries = Boolean(headingStyleRange) || stylesWithLevels.length > 0 || Boolean(useAppliedParagraphOutlineLevel) || Boolean(properties.tcFieldIdentifier) || Boolean(properties.tcFieldLevelRange) || Boolean(properties.captionLabel) || Boolean(properties.captionLabelIncludingNumbers);
|
|
17077
|
+
const headingRange = headingStyleRange ? parseRange(headingStyleRange) : namesItsEntries ? void 0 : [1, 9];
|
|
17078
|
+
const heading = headingLevelOf(paragraph.styleId, styles);
|
|
17079
|
+
if (headingRange && heading !== void 0 && isWithin(heading, headingRange)) return heading;
|
|
17080
|
+
const outlineLevel = useAppliedParagraphOutlineLevel ? outlineLevelOf(paragraph, styles) : void 0;
|
|
17081
|
+
return outlineLevel !== void 0 && isWithin(outlineLevel + 1, headingRange !== null && headingRange !== void 0 ? headingRange : [1, 9]) ? outlineLevel + 1 : void 0;
|
|
17082
|
+
};
|
|
17083
|
+
/** The runs of an entry's title. Tabs and line breaks are kept only when the table of contents keeps them (\w and \x) */
|
|
17084
|
+
var titleRunsOf = (title, properties) => {
|
|
17085
|
+
const text = properties.preserveTabInEntries ? title : title.replace(/\t/g, " ");
|
|
17086
|
+
return (properties.preserveNewLineInEntries ? text.split("\n") : [text.replace(/\n/g, " ")]).map((line, index) => new TextRun({
|
|
17087
|
+
break: index > 0 ? 1 : void 0,
|
|
17088
|
+
children: line.split(" ").flatMap((part, partIndex) => [...partIndex > 0 ? [new Tab()] : [], ...part === "" ? [] : [part]])
|
|
17089
|
+
}));
|
|
17090
|
+
};
|
|
17091
|
+
/**
|
|
17092
|
+
* The paragraph style of the entries at a level: the built-in TOC style, found by its name, "toc 1" to "toc 9". When
|
|
17093
|
+
* the document doesn't have it, the entries are indented as Word's are, 220 twips a level.
|
|
17094
|
+
*/
|
|
17095
|
+
var entryStyleOf = (level, styles) => {
|
|
17096
|
+
var _find;
|
|
17097
|
+
const named = (_find = [...styles].find(([, style]) => {
|
|
17098
|
+
var _style$name;
|
|
17099
|
+
return ((_style$name = style.name) === null || _style$name === void 0 ? void 0 : _style$name.toLowerCase()) === `toc ${level}`;
|
|
17100
|
+
})) === null || _find === void 0 ? void 0 : _find[0];
|
|
17101
|
+
const id = named !== null && named !== void 0 ? named : `TOC${level}`;
|
|
17102
|
+
return named !== void 0 || styles.has(id) || level === 1 ? { id } : {
|
|
17103
|
+
id,
|
|
17104
|
+
indent: (level - 1) * 220
|
|
17105
|
+
};
|
|
17106
|
+
};
|
|
17107
|
+
/** The formatted content of a table of contents with its entries */
|
|
17108
|
+
var contentOf = ({ properties, beginDirty, textWidth }, entries, styles, context) => {
|
|
17109
|
+
var _parseRange;
|
|
17110
|
+
const withoutPageNumbers = properties.pageNumbersEntryLevelsRange ? (_parseRange = parseRange(properties.pageNumbersEntryLevelsRange)) !== null && _parseRange !== void 0 ? _parseRange : [1, 9] : void 0;
|
|
17111
|
+
const content = new StructuredDocumentTagContent();
|
|
17112
|
+
entries.forEach((entry, index) => {
|
|
17113
|
+
const hasPageNumber = withoutPageNumbers === void 0 || !isWithin(entry.level, withoutPageNumbers);
|
|
17114
|
+
const children = [...titleRunsOf(entry.title, properties), ...hasPageNumber ? [new TextRun({ children: [properties.entryAndPageNumberSeparator || new Tab()] }), new PageReference(entry.bookmark, { hyperlink: properties.hyperlink })] : []];
|
|
17115
|
+
const style = entryStyleOf(entry.level, styles);
|
|
17116
|
+
content.addChildElement(new Paragraph({
|
|
17117
|
+
style: style.id,
|
|
17118
|
+
indent: style.indent === void 0 ? void 0 : { left: style.indent },
|
|
17119
|
+
tabStops: [{
|
|
17120
|
+
type: "right",
|
|
17121
|
+
position: textWidth,
|
|
17122
|
+
leader: "dot"
|
|
17123
|
+
}],
|
|
17124
|
+
children: [...index === 0 ? [new Run({ children: [
|
|
17125
|
+
beginOf(beginDirty),
|
|
17126
|
+
new FieldInstruction(properties),
|
|
17127
|
+
createSeparate()
|
|
17128
|
+
] })] : [], ...properties.hyperlink ? [new InternalHyperlink({
|
|
17129
|
+
anchor: entry.bookmark,
|
|
17130
|
+
children
|
|
17131
|
+
})] : children]
|
|
17132
|
+
}));
|
|
17133
|
+
});
|
|
17134
|
+
content.addChildElement(new Paragraph({ children: [new Run({ children: [createEnd()] })] }));
|
|
17135
|
+
return content.prepForXml(context);
|
|
17136
|
+
};
|
|
17137
|
+
/** Puts a bookmark around the content of a formatted paragraph */
|
|
17138
|
+
var bookmark = (paragraph, name, id, context) => {
|
|
17139
|
+
const children = childrenOf(paragraph);
|
|
17140
|
+
const start = children.findIndex((child) => nameOf$2(child) === "w:pPr") + 1;
|
|
17141
|
+
paragraph["w:p"] = [
|
|
17142
|
+
...children.slice(0, start),
|
|
17143
|
+
new BookmarkStart(name, id).prepForXml(context),
|
|
17144
|
+
...children.slice(start),
|
|
17145
|
+
new BookmarkEnd(id).prepForXml(context)
|
|
17146
|
+
];
|
|
17147
|
+
};
|
|
17148
|
+
/**
|
|
17149
|
+
* Fills in the tables of contents in a formatted body from its headings, and bookmarks the headings they list. A
|
|
17150
|
+
* table of contents that doesn't list any heading is left empty, for Word to fill in.
|
|
17151
|
+
*/
|
|
17152
|
+
var fillTablesOfContents = (body, context, bookmarkIds) => {
|
|
17153
|
+
const blocks = blocksOf(childrenOf(body));
|
|
17154
|
+
const tables = blocks.flatMap((block) => {
|
|
17155
|
+
const options = writtenTables.get(block);
|
|
17156
|
+
return options ? [[block, options]] : [];
|
|
17157
|
+
});
|
|
17158
|
+
if (tables.length === 0) return;
|
|
17159
|
+
const styles = stylesOf(context);
|
|
17160
|
+
const followBookmarks = tables.some(([, { properties }]) => Boolean(properties.entriesFromBookmark));
|
|
17161
|
+
const headings = paragraphDetailsOf(blocks.filter((block) => nameOf$2(block) === "w:p"), followBookmarks).map((paragraph) => ({
|
|
17162
|
+
paragraph,
|
|
17163
|
+
levels: tables.map(([, { properties }]) => levelIn(properties, paragraph, styles))
|
|
17164
|
+
})).filter(({ levels }) => levels.some((level) => level !== void 0)).map((heading, index) => _objectSpread2(_objectSpread2({}, heading), {}, { id: bookmarkIds.get(index) }));
|
|
17165
|
+
for (const { paragraph, id } of headings) bookmark(paragraph.element, `_Toc${id}`, id, context);
|
|
17166
|
+
tables.forEach(([table, options], index) => {
|
|
17167
|
+
const entries = headings.flatMap(({ paragraph, levels, id }) => {
|
|
17168
|
+
const level = levels[index];
|
|
17169
|
+
return level === void 0 ? [] : [{
|
|
17170
|
+
title: paragraph.text,
|
|
17171
|
+
level,
|
|
17172
|
+
bookmark: `_Toc${id}`
|
|
17173
|
+
}];
|
|
17174
|
+
});
|
|
17175
|
+
if (entries.length === 0) return;
|
|
17176
|
+
table["w:sdt"] = childrenOf(table).map((child) => nameOf$2(child) === "w:sdtContent" ? contentOf(options, entries, styles, context) : child);
|
|
17177
|
+
});
|
|
17178
|
+
};
|
|
17179
|
+
//#endregion
|
|
17180
|
+
//#region src/file/document/body/sequence-numbers.ts
|
|
17181
|
+
/**
|
|
17182
|
+
* Caption numbers written into the SEQ fields of a document, such as the 2 of "Figure 2", when the document is given page
|
|
17183
|
+
* numbers.
|
|
17184
|
+
*
|
|
17185
|
+
* A SEQ field (`SequentialIdentifier`) shows how many SEQ fields of its identifier, such as "Figure", there are up to and
|
|
17186
|
+
* including it, so the number doesn't depend on how the pages are laid out. Its switches change the count: `\r 5` starts
|
|
17187
|
+
* it again from 5, `\c` repeats the number of the one before, `\s 1` starts it again after each Heading 1, `\h` hides the
|
|
17188
|
+
* number, and `\* ROMAN` writes it in roman numerals. `docx` writes SEQ fields dirty, for Word to number when it opens the
|
|
17189
|
+
* document, which makes Word ask to update the fields. When the document is given page numbers, each is written clean
|
|
17190
|
+
* with its number, counted as Word counts it. What Word does was read from its PDF of `scripts/layout-probes/word-seq.ts`.
|
|
17191
|
+
*
|
|
17192
|
+
* Word counts the SEQ fields of the body, those in text boxes and hidden text too, in order, and counts an identifier in
|
|
17193
|
+
* any capitals, or in quotes, as the same one. It writes the SEQ fields of headers, footers, footnotes and endnotes as an
|
|
17194
|
+
* error, "Error! Main Document Only.", and doesn't count them with the body's.
|
|
17195
|
+
*
|
|
17196
|
+
* Where Word's count isn't known, the field is left blank rather than given a number that could be wrong: a switch it
|
|
17197
|
+
* doesn't follow, a SEQ field in deleted text, and every SEQ field of an identifier that also has SEQ fields in a comment.
|
|
17198
|
+
* The fields of its identifier after one whose number isn't known are left blank too, until one starts the count again
|
|
17199
|
+
* with `\r`. A number in a format not followed is left blank, but the count goes on.
|
|
17200
|
+
*
|
|
17201
|
+
* @module
|
|
17202
|
+
*/
|
|
17203
|
+
var IDENTIFIER = new RegExp("^\\p{L}[\\p{L}\\p{N}_]*$", "u");
|
|
17204
|
+
/** Reads the switches of a SEQ field, and a bookmark before them, or undefined when one of them isn't followed */
|
|
17205
|
+
var sequenceOf = (switches) => {
|
|
17206
|
+
var _step, _format;
|
|
17207
|
+
let step;
|
|
17208
|
+
let hidden = false;
|
|
17209
|
+
let format;
|
|
17210
|
+
let caseFormat = false;
|
|
17211
|
+
let picture = false;
|
|
17212
|
+
for (let index = 0; index < switches.length; index++) {
|
|
17213
|
+
var _switches, _next;
|
|
17214
|
+
const name = switches[index];
|
|
17215
|
+
const argument = (_switches = switches[index + 1]) !== null && _switches !== void 0 ? _switches : "";
|
|
17216
|
+
let next;
|
|
17217
|
+
if (index === 0 && !name.startsWith("\\")) next = { type: "bookmark" };
|
|
17218
|
+
else if (name === "\\c" || name === "\\n") next = { type: name === "\\c" ? "repeat" : "next" };
|
|
17219
|
+
else if ((name === "\\r" || name === "\\s") && /^\d+$/.test(argument)) {
|
|
17220
|
+
index++;
|
|
17221
|
+
next = name === "\\r" ? {
|
|
17222
|
+
type: "reset",
|
|
17223
|
+
to: Number(argument)
|
|
17224
|
+
} : {
|
|
17225
|
+
type: "heading",
|
|
17226
|
+
level: Number(argument)
|
|
17227
|
+
};
|
|
17228
|
+
} else if (name === "\\h") hidden = true;
|
|
17229
|
+
else if (name === "\\#" && index + 1 < switches.length) {
|
|
17230
|
+
index++;
|
|
17231
|
+
picture = true;
|
|
17232
|
+
} else if (name === "\\*" && index + 1 < switches.length) {
|
|
17233
|
+
const value = switches[++index];
|
|
17234
|
+
if (CASE_FORMATS.has(value.toLowerCase())) caseFormat = true;
|
|
17235
|
+
else if (!PLAIN_FORMATS.has(value.toLowerCase())) {
|
|
17236
|
+
if (format !== void 0) return;
|
|
17237
|
+
format = value;
|
|
17238
|
+
}
|
|
17239
|
+
} else return;
|
|
17240
|
+
if (next && step) return;
|
|
17241
|
+
step = (_next = next) !== null && _next !== void 0 ? _next : step;
|
|
17242
|
+
}
|
|
17243
|
+
if ((step === null || step === void 0 ? void 0 : step.type) === "bookmark" && switches.length > 1) return;
|
|
17244
|
+
const written = !picture && !(caseFormat && format !== void 0 && format.toLowerCase() !== "arabic");
|
|
17245
|
+
return {
|
|
17246
|
+
step: (_step = step) !== null && _step !== void 0 ? _step : { type: "next" },
|
|
17247
|
+
hidden: hidden && format === void 0,
|
|
17248
|
+
format: written ? (_format = format) !== null && _format !== void 0 ? _format : "ARABIC" : ""
|
|
17249
|
+
};
|
|
17250
|
+
};
|
|
17251
|
+
/** Reads a SEQ field's instruction, or undefined when the field isn't a SEQ field */
|
|
17252
|
+
var sequenceFieldOf = (instruction) => {
|
|
17253
|
+
var _match$1$match;
|
|
17254
|
+
const match = new RegExp("^\\s*SEQ\\b(.*)$", "is").exec(instruction);
|
|
17255
|
+
if (!match) return;
|
|
17256
|
+
const [written, ...switches] = (_match$1$match = match[1].match(/"[^"]*"|\S+/g)) !== null && _match$1$match !== void 0 ? _match$1$match : [];
|
|
17257
|
+
if (written === void 0) return {};
|
|
17258
|
+
const identifier = written.replace(/^"(.*)"$/, "$1");
|
|
17259
|
+
return IDENTIFIER.test(identifier) ? {
|
|
17260
|
+
identifier,
|
|
17261
|
+
sequence: sequenceOf(switches)
|
|
17262
|
+
} : { identifier };
|
|
17263
|
+
};
|
|
17264
|
+
/** Whether a field's instruction is that of a SEQ field */
|
|
17265
|
+
var isSequenceField = (instruction) => sequenceFieldOf(instruction) !== void 0;
|
|
17266
|
+
/** The identifier, in small letters, of each SEQ field in the formatted elements */
|
|
17267
|
+
var identifiersIn = (element) => {
|
|
17268
|
+
if (typeof element !== "object" || element === null) return [];
|
|
17269
|
+
if (Array.isArray(element)) return element.flatMap(identifiersIn);
|
|
17270
|
+
return Object.entries(element).flatMap(([name, content]) => {
|
|
17271
|
+
return [...(name === "w:instrText" && Array.isArray(content) ? content : name === "_attr" ? [content["w:instr"]] : []).flatMap((instruction) => {
|
|
17272
|
+
const field = typeof instruction === "string" ? sequenceFieldOf(instruction) : void 0;
|
|
17273
|
+
return (field === null || field === void 0 ? void 0 : field.identifier) === void 0 ? [] : [field.identifier.toLowerCase()];
|
|
17274
|
+
}), ...identifiersIn(content)];
|
|
17275
|
+
});
|
|
17276
|
+
};
|
|
17277
|
+
/** The identifiers, in small letters, of the SEQ fields in the document's comments, whose count in Word isn't known */
|
|
17278
|
+
var identifiersInCommentsOf = (context) => {
|
|
17279
|
+
var _context$file;
|
|
17280
|
+
const comments = (_context$file = context.file) === null || _context$file === void 0 ? void 0 : _context$file.Comments;
|
|
17281
|
+
if (!comments) return /* @__PURE__ */ new Set();
|
|
17282
|
+
const wrapper = {
|
|
17283
|
+
View: comments,
|
|
17284
|
+
Relationships: comments.Relationships
|
|
17285
|
+
};
|
|
17286
|
+
return new Set(identifiersIn(comments.prepForXml(_objectSpread2(_objectSpread2({}, context), {}, {
|
|
17287
|
+
viewWrapper: wrapper,
|
|
17288
|
+
stack: []
|
|
17289
|
+
}))));
|
|
17290
|
+
};
|
|
17291
|
+
/** Counts the SEQ fields of a document's body, in order, as Word counts them */
|
|
17292
|
+
var sequenceNumbering = (context) => {
|
|
17293
|
+
const levelOf = headingLevels(context);
|
|
17294
|
+
const numbers = /* @__PURE__ */ new Map();
|
|
17295
|
+
const counted = /* @__PURE__ */ new Map();
|
|
17296
|
+
const headingsAt = [];
|
|
17297
|
+
let unclearAt = -1;
|
|
17298
|
+
let paragraph = -1;
|
|
17299
|
+
let unknown;
|
|
17300
|
+
/**
|
|
17301
|
+
* The number of a field that starts the count again after headings of a level or a higher one (`\s`): the number of
|
|
17302
|
+
* fields of its identifier since the last of them, with it, as Word counts them. It isn't known when a paragraph
|
|
17303
|
+
* whose level isn't clear came after that heading, or a field since it whose number didn't follow as the next one's
|
|
17304
|
+
*/
|
|
17305
|
+
const afterHeading = (key, level) => {
|
|
17306
|
+
var _counted$get;
|
|
17307
|
+
const headingAt = Math.max(-1, ...headingsAt.slice(1, level + 1).filter((at) => at !== void 0));
|
|
17308
|
+
const since = ((_counted$get = counted.get(key)) !== null && _counted$get !== void 0 ? _counted$get : []).filter((field) => field.paragraph >= headingAt);
|
|
17309
|
+
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);
|
|
17310
|
+
if (unclearAt > headingAt || !followed) return;
|
|
17311
|
+
return since.length + 1;
|
|
17312
|
+
};
|
|
17313
|
+
return {
|
|
17314
|
+
startParagraph: (element) => {
|
|
17315
|
+
paragraph++;
|
|
17316
|
+
const level = levelOf(element);
|
|
17317
|
+
if (level === "unclear") unclearAt = paragraph;
|
|
17318
|
+
else if (level !== void 0) headingsAt[level] = paragraph;
|
|
17319
|
+
},
|
|
17320
|
+
numberOf: (instruction, place) => {
|
|
17321
|
+
var _unknown, _counted$get2, _numberWriterOf;
|
|
17322
|
+
const { identifier, sequence } = sequenceFieldOf(instruction);
|
|
17323
|
+
if (identifier === void 0 || place === "fallback") return;
|
|
17324
|
+
(_unknown = unknown) !== null && _unknown !== void 0 || (unknown = identifiersInCommentsOf(context));
|
|
17325
|
+
const key = identifier.toLowerCase();
|
|
17326
|
+
if ((sequence === null || sequence === void 0 ? void 0 : sequence.step.type) === "bookmark" && place === "counted" && !unknown.has(key)) return;
|
|
17327
|
+
const before = numbers.has(key) ? numbers.get(key) : 0;
|
|
17328
|
+
const step = unknown.has(key) || place === "deleted" ? void 0 : sequence === null || sequence === void 0 ? void 0 : sequence.step;
|
|
17329
|
+
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;
|
|
17330
|
+
numbers.set(key, value);
|
|
17331
|
+
counted.set(key, [...(_counted$get2 = counted.get(key)) !== null && _counted$get2 !== void 0 ? _counted$get2 : [], _objectSpread2({ paragraph }, value === void 0 ? {} : { step })]);
|
|
17332
|
+
return value === void 0 || sequence === void 0 ? void 0 : sequence.hidden ? "" : (_numberWriterOf = numberWriterOf(sequence.format)) === null || _numberWriterOf === void 0 ? void 0 : _numberWriterOf(value);
|
|
17333
|
+
}
|
|
17334
|
+
};
|
|
17335
|
+
};
|
|
17336
|
+
//#endregion
|
|
17337
|
+
//#region src/file/document/body/page-numbers.ts
|
|
17338
|
+
/**
|
|
17339
|
+
* Page numbers written into the fields of a document that show them, when it is written, from an estimate of its pages.
|
|
17340
|
+
*
|
|
17341
|
+
* A page reference is a PAGEREF field, such as the page number of an entry in a table of contents, and the numbers of
|
|
17342
|
+
* pages of the document and of a section are NUMPAGES and SECTIONPAGES fields. Word works their results out when it
|
|
17343
|
+
* updates the fields, or lays the pages out, and until then, and in applications that don't, the fields show the results
|
|
17344
|
+
* they were written with. `docx` doesn't lay out pages, so it writes the results empty, unless the document is given a
|
|
17345
|
+
* {@link PageNumberEstimator}, such as `estimatePageNumbers` from `docx/layout`. Then, once the body is written, each of
|
|
17346
|
+
* those fields in the body, and then in the headers and footers, is given the number the estimator worked out.
|
|
17347
|
+
*
|
|
17348
|
+
* Page references and tables of contents are written dirty, so Word updates them when it opens the document, and asks
|
|
17349
|
+
* "This document contains fields that may refer to other files. Do you want to update the fields in this document?".
|
|
17350
|
+
* When the document is given page numbers, they are written clean, so Word shows them as they are and doesn't ask. A
|
|
17351
|
+
* page number the estimator didn't work out is left blank, until the fields are updated. So are SEQ fields, the numbers
|
|
17352
|
+
* of captions, which are given their numbers then too.
|
|
17353
|
+
*
|
|
17354
|
+
* @module
|
|
17355
|
+
*/
|
|
17356
|
+
var nameOf$1 = (element) => {
|
|
17357
|
+
const name = typeof element === "object" && element !== null && !Array.isArray(element) ? Object.keys(element)[0] : void 0;
|
|
17358
|
+
return name === "_attr" ? void 0 : name;
|
|
17359
|
+
};
|
|
17360
|
+
var textElement = (text) => ({ "w:t": [{ _attr: { "xml:space": "preserve" } }, text] });
|
|
17361
|
+
/** The elements docx formats to write a document */
|
|
17362
|
+
var FORMATTED = {
|
|
17363
|
+
nameOf: nameOf$1,
|
|
17364
|
+
contentOf: (element) => {
|
|
17365
|
+
const content = element[nameOf$1(element)];
|
|
17366
|
+
return Array.isArray(content) ? content : void 0;
|
|
17367
|
+
},
|
|
17368
|
+
attributeOf: (element, attribute) => {
|
|
17369
|
+
var _holder$_attr;
|
|
17370
|
+
const content = element[nameOf$1(element)];
|
|
17371
|
+
const holder = Array.isArray(content) ? content.find((child) => typeof child === "object" && child !== null && "_attr" in child) : content;
|
|
17372
|
+
return holder === null || holder === void 0 || (_holder$_attr = holder._attr) === null || _holder$_attr === void 0 ? void 0 : _holder$_attr[attribute];
|
|
17373
|
+
},
|
|
17374
|
+
textOf: (element) => FORMATTED.contentOf(element).filter((part) => typeof part === "string").join(""),
|
|
17375
|
+
textElement,
|
|
17376
|
+
writeClean: (begin) => {
|
|
17377
|
+
if (isDirtyWithoutPageNumbers(begin)) {
|
|
17378
|
+
const attributes = begin["w:fldChar"]._attr;
|
|
17379
|
+
begin["w:fldChar"] = { _attr: Object.fromEntries(Object.entries(attributes).filter(([key]) => key !== "w:dirty")) };
|
|
17380
|
+
}
|
|
17381
|
+
},
|
|
17382
|
+
setSimpleFieldResult: (element, text) => {
|
|
17383
|
+
const content = element["w:fldSimple"];
|
|
17384
|
+
element["w:fldSimple"] = [...(Array.isArray(content) ? content : [content]).filter((child) => typeof child === "object" && child !== null && "_attr" in child), { "w:r": [textElement(text)] }];
|
|
17385
|
+
}
|
|
17386
|
+
};
|
|
17387
|
+
/** The estimate of each document's pages, and the numbers of pages its headers and footers show, once its body is written */
|
|
17388
|
+
var estimates = /* @__PURE__ */ new WeakMap();
|
|
17389
|
+
/**
|
|
17390
|
+
* Writes the numbers of the SEQ fields of a formatted body into them, counted as Word counts them (see
|
|
17391
|
+
* {@link sequenceNumbering}), and writes them clean, whether or not their numbers were worked out. It is done after its
|
|
17392
|
+
* tables of contents are filled in from its headings, as Word leaves a heading's SEQ number out of its entry.
|
|
17393
|
+
*/
|
|
17394
|
+
var fillSequenceNumbers = (body, context) => {
|
|
17395
|
+
const { startParagraph, numberOf } = sequenceNumbering(context);
|
|
17396
|
+
fillSequenceFields(FORMATTED, body, {
|
|
17397
|
+
beforeParagraph: (paragraph) => startParagraph(paragraph),
|
|
17398
|
+
resultOf: (instruction, within) => isSequenceField(instruction) ? numberOf(instruction, within) : void 0
|
|
17399
|
+
});
|
|
17400
|
+
};
|
|
17401
|
+
/**
|
|
17402
|
+
* Writes the page numbers the estimator works out into the fields of a formatted body that show them: the PAGEREF fields
|
|
17403
|
+
* in its tables of contents and elsewhere, those with `\p` and in number formats of their own, and its NUMPAGES and
|
|
17404
|
+
* SECTIONPAGES fields. A field whose number the estimator didn't work out is left as it is. Page references and tables
|
|
17405
|
+
* of contents are written clean, whether or not their numbers were worked out. The estimate is kept for the document's
|
|
17406
|
+
* headers and footers.
|
|
17407
|
+
*/
|
|
17408
|
+
var fillPageNumbers = (body, context, estimator) => {
|
|
17409
|
+
const estimate = estimator(body, context);
|
|
17410
|
+
const partPageCounts = fillBodyFields(FORMATTED, body, estimate, { blank: false });
|
|
17411
|
+
if (context.file) estimates.set(context.file, {
|
|
17412
|
+
estimate,
|
|
17413
|
+
partPageCounts
|
|
17414
|
+
});
|
|
17415
|
+
};
|
|
17416
|
+
/**
|
|
17417
|
+
* Writes the page numbers worked out for the document a header, footer, footnote, endnote or comment is in into the
|
|
17418
|
+
* fields of the formatted part that show them, once the document's body is written. Its page references and SEQ fields
|
|
17419
|
+
* are written clean, and its SEQ fields are left blank: Word writes them as an error, "Error! Main Document Only.".
|
|
17420
|
+
*
|
|
17421
|
+
* @param part - The formatted part, if it has anything to write
|
|
17422
|
+
* @param context - The context it was formatted in, with the document it is in
|
|
17423
|
+
* @param referenceId - The number of the relationship to a header or footer. The SECTIONPAGES fields of the other parts
|
|
17424
|
+
* are left as they are
|
|
17425
|
+
*/
|
|
17426
|
+
var fillPartPageNumbers = (part, context, referenceId) => {
|
|
17427
|
+
const written = context.file && estimates.get(context.file);
|
|
17428
|
+
if (!part || !written) return;
|
|
17429
|
+
const sectionPageCount = referenceId === void 0 ? void 0 : written.partPageCounts.get(`rId${referenceId}`);
|
|
17430
|
+
const notes = "w:footnotes" in part || "w:endnotes" in part;
|
|
17431
|
+
fillPartFields(FORMATTED, part, written.estimate, {
|
|
17432
|
+
blank: false,
|
|
17433
|
+
sectionPageCount,
|
|
17434
|
+
notes
|
|
17435
|
+
});
|
|
17436
|
+
};
|
|
17437
|
+
//#endregion
|
|
16340
17438
|
//#region src/file/relationships/attributes.ts
|
|
16341
17439
|
/**
|
|
16342
17440
|
* Attributes for the Relationships element.
|
|
@@ -16386,7 +17484,7 @@ EXTERNAL: "External" };
|
|
|
16386
17484
|
* );
|
|
16387
17485
|
* ```
|
|
16388
17486
|
*/
|
|
16389
|
-
var Relationships = class extends XmlComponent {
|
|
17487
|
+
var Relationships = class Relationships extends XmlComponent {
|
|
16390
17488
|
constructor() {
|
|
16391
17489
|
super("Relationships");
|
|
16392
17490
|
this.root.push(new RelationshipsAttributes({ xmlns: "http://schemas.openxmlformats.org/package/2006/relationships" }));
|
|
@@ -16403,6 +17501,20 @@ EXTERNAL: "External" };
|
|
|
16403
17501
|
this.root.push(createRelationship(`rId${id}`, type, target, targetMode));
|
|
16404
17502
|
}
|
|
16405
17503
|
/**
|
|
17504
|
+
* Creates a copy of the relationships given. Relationships added to the copy aren't added to them, so the compiler
|
|
17505
|
+
* adds the ones it writes for a part, such as to its images, to a copy, and packing a document again doesn't add
|
|
17506
|
+
* them a second time.
|
|
17507
|
+
*
|
|
17508
|
+
* Static, as `IContext` is public and has `Relationships`, so a new instance member would change the public API.
|
|
17509
|
+
*
|
|
17510
|
+
* @param relationships - The relationships to copy
|
|
17511
|
+
*/
|
|
17512
|
+
static copy(relationships) {
|
|
17513
|
+
const copy = new Relationships();
|
|
17514
|
+
copy.root.push(...relationships.root.slice(1));
|
|
17515
|
+
return copy;
|
|
17516
|
+
}
|
|
17517
|
+
/**
|
|
16406
17518
|
* Gets the count of relationships in this collection.
|
|
16407
17519
|
* Excludes the attributes element from the count.
|
|
16408
17520
|
*/
|
|
@@ -16413,6 +17525,17 @@ EXTERNAL: "External" };
|
|
|
16413
17525
|
//#endregion
|
|
16414
17526
|
//#region src/file/paragraph/run/comment-run.ts
|
|
16415
17527
|
/**
|
|
17528
|
+
* Comment module for WordprocessingML documents.
|
|
17529
|
+
*
|
|
17530
|
+
* This module provides support for comments (annotations) in documents. Comments
|
|
17531
|
+
* consist of comment ranges (start/end markers), comment references, and the
|
|
17532
|
+
* actual comment content.
|
|
17533
|
+
*
|
|
17534
|
+
* Reference: http://officeopenxml.com/WPrun.php
|
|
17535
|
+
*
|
|
17536
|
+
* @module
|
|
17537
|
+
*/
|
|
17538
|
+
/**
|
|
16416
17539
|
* @internal
|
|
16417
17540
|
*/
|
|
16418
17541
|
var CommentAttributes = class extends XmlAttributeComponent {
|
|
@@ -16442,6 +17565,7 @@ EXTERNAL: "External" };
|
|
|
16442
17565
|
constructor(..._args3) {
|
|
16443
17566
|
super(..._args3);
|
|
16444
17567
|
_defineProperty(this, "xmlKeys", {
|
|
17568
|
+
"xmlns:wpc": "xmlns:wpc",
|
|
16445
17569
|
"xmlns:cx": "xmlns:cx",
|
|
16446
17570
|
"xmlns:cx1": "xmlns:cx1",
|
|
16447
17571
|
"xmlns:cx2": "xmlns:cx2",
|
|
@@ -16682,6 +17806,7 @@ EXTERNAL: "External" };
|
|
|
16682
17806
|
_defineProperty(this, "isEmpty", void 0);
|
|
16683
17807
|
this.isEmpty = children.length === 0;
|
|
16684
17808
|
this.root.push(new RootCommentsAttributes({
|
|
17809
|
+
"xmlns:wpc": "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
|
|
16685
17810
|
"xmlns:cx": "http://schemas.microsoft.com/office/drawing/2014/chartex",
|
|
16686
17811
|
"xmlns:cx1": "http://schemas.microsoft.com/office/drawing/2015/9/8/chartex",
|
|
16687
17812
|
"xmlns:cx2": "http://schemas.microsoft.com/office/drawing/2015/10/21/chartex",
|
|
@@ -16750,6 +17875,15 @@ EXTERNAL: "External" };
|
|
|
16750
17875
|
get IsEmpty() {
|
|
16751
17876
|
return this.isEmpty;
|
|
16752
17877
|
}
|
|
17878
|
+
/**
|
|
17879
|
+
* Formats the comments, with the page numbers worked out for their document written into their fields, when the
|
|
17880
|
+
* document's body is written with an estimate of its pages.
|
|
17881
|
+
*/
|
|
17882
|
+
prepForXml(context) {
|
|
17883
|
+
const xml = super.prepForXml(context);
|
|
17884
|
+
fillPartPageNumbers(xml, context);
|
|
17885
|
+
return xml;
|
|
17886
|
+
}
|
|
16753
17887
|
};
|
|
16754
17888
|
//#endregion
|
|
16755
17889
|
//#region src/file/paragraph/run/comments-extended.ts
|
|
@@ -17824,20 +18958,44 @@ MAX: 9026 };
|
|
|
17824
18958
|
* ```
|
|
17825
18959
|
*/
|
|
17826
18960
|
var ConcreteHyperlink = class extends XmlComponent {
|
|
17827
|
-
|
|
18961
|
+
/**
|
|
18962
|
+
* @param children - Inline content of the hyperlink
|
|
18963
|
+
* @param relationshipId - Id of the external relationship, without the rId prefix
|
|
18964
|
+
* @param anchor - Bookmark name or external URL fragment
|
|
18965
|
+
* @param externalLink - The full address of an external hyperlink, so the relationship id is kept alongside its anchor
|
|
18966
|
+
*/
|
|
18967
|
+
constructor(children, relationshipId, anchor, externalLink) {
|
|
17828
18968
|
super("w:hyperlink");
|
|
17829
18969
|
_defineProperty(this, "linkId", void 0);
|
|
18970
|
+
_defineProperty(this, "drawingLink", void 0);
|
|
17830
18971
|
this.linkId = relationshipId;
|
|
18972
|
+
this.drawingLink = anchor && externalLink !== void 0 ? new DrawingLink(externalLink) : void 0;
|
|
17831
18973
|
const attributes = new HyperlinkAttributes({
|
|
17832
18974
|
history: 1,
|
|
17833
18975
|
anchor: anchor ? anchor : void 0,
|
|
17834
|
-
id: !anchor ? `rId${this.linkId}` : void 0
|
|
18976
|
+
id: !anchor || externalLink !== void 0 ? `rId${this.linkId}` : void 0
|
|
17835
18977
|
});
|
|
17836
18978
|
this.root.push(attributes);
|
|
17837
18979
|
children.forEach((child) => {
|
|
17838
18980
|
this.root.push(child);
|
|
17839
18981
|
});
|
|
17840
18982
|
}
|
|
18983
|
+
/**
|
|
18984
|
+
* Creates the `a:hlinkClick` of a picture in the hyperlink, which links to the same address.
|
|
18985
|
+
*
|
|
18986
|
+
* The hyperlink decides which relationship its pictures use, rather than the pictures reading `linkId`, because only it
|
|
18987
|
+
* knows whether that relationship has lost the fragment to `w:anchor`. The picture's relationship is added as the
|
|
18988
|
+
* picture is written, through the context's relationships, so it lands in the part the picture is in, both when
|
|
18989
|
+
* packing and when patching.
|
|
18990
|
+
*
|
|
18991
|
+
* @param context - The context the picture is written in, whose relationships get the picture's link if it has its own
|
|
18992
|
+
* @param declareNamespace - Declares the DrawingML namespace, for elements outside `a:graphic` such as `wp:docPr`
|
|
18993
|
+
*/
|
|
18994
|
+
createDrawingClick(context, declareNamespace) {
|
|
18995
|
+
if (!this.drawingLink) return createHyperlinkClick(this.linkId, declareNamespace);
|
|
18996
|
+
this.drawingLink.addRelationship(context);
|
|
18997
|
+
return this.drawingLink.createClick(declareNamespace);
|
|
18998
|
+
}
|
|
17841
18999
|
};
|
|
17842
19000
|
/**
|
|
17843
19001
|
* Represents an internal hyperlink to a bookmark within the document.
|
|
@@ -17886,6 +19044,11 @@ MAX: 9026 };
|
|
|
17886
19044
|
* External hyperlinks create a relationship to an external resource (URL).
|
|
17887
19045
|
* The relationship is created during document preparation and the hyperlink
|
|
17888
19046
|
* is converted to a ConcreteHyperlink with the relationship ID.
|
|
19047
|
+
* URL fragments of at most 255 UTF-16 units are written as anchors, preserving any additional # characters.
|
|
19048
|
+
* Longer fragments stay in the original relationship URI to avoid exceeding Word's anchor limit;
|
|
19049
|
+
* those links retain the existing limitations for fragments with multiple # characters.
|
|
19050
|
+
* Word appends the anchor to the relationship target as described in MS-OI29500 §17.16.22:
|
|
19051
|
+
* https://learn.microsoft.com/en-us/openspecs/office_standards/ms-oi29500/df06e423-11a6-4a36-bfb3-82139e531781
|
|
17889
19052
|
*
|
|
17890
19053
|
* Reference: http://officeopenxml.com/WPhyperlink.php
|
|
17891
19054
|
*
|
|
@@ -17899,6 +19062,7 @@ MAX: 9026 };
|
|
|
17899
19062
|
* <xsd:group ref="EG_PContent" minOccurs="0" maxOccurs="unbounded"/>
|
|
17900
19063
|
* <xsd:attribute ref="r:id"/>
|
|
17901
19064
|
* <xsd:attribute name="history" type="s:ST_OnOff" use="optional"/>
|
|
19065
|
+
* <xsd:attribute name="anchor" type="s:ST_String" use="optional"/>
|
|
17902
19066
|
* </xsd:complexType>
|
|
17903
19067
|
* ```
|
|
17904
19068
|
*
|
|
@@ -18048,7 +19212,7 @@ MAX: 9026 };
|
|
|
18048
19212
|
* });
|
|
18049
19213
|
* ```
|
|
18050
19214
|
*/
|
|
18051
|
-
var Bookmark = class {
|
|
19215
|
+
var Bookmark = class Bookmark {
|
|
18052
19216
|
constructor(options) {
|
|
18053
19217
|
_defineProperty(this, "start", void 0);
|
|
18054
19218
|
_defineProperty(this, "children", void 0);
|
|
@@ -18058,6 +19222,19 @@ MAX: 9026 };
|
|
|
18058
19222
|
this.children = options.children;
|
|
18059
19223
|
this.end = new BookmarkEnd(linkId);
|
|
18060
19224
|
}
|
|
19225
|
+
/**
|
|
19226
|
+
* The components written in this bookmark's place: its start, its children and its end. A bookmark in its
|
|
19227
|
+
* children is written the same way, so one bookmark can hold another.
|
|
19228
|
+
*
|
|
19229
|
+
* @internal
|
|
19230
|
+
*/
|
|
19231
|
+
get writtenAs() {
|
|
19232
|
+
return [
|
|
19233
|
+
this.start,
|
|
19234
|
+
...this.children.flatMap((child) => child instanceof Bookmark ? child.writtenAs : [child]),
|
|
19235
|
+
this.end
|
|
19236
|
+
];
|
|
19237
|
+
}
|
|
18061
19238
|
};
|
|
18062
19239
|
/**
|
|
18063
19240
|
* Represents the start marker of a bookmark range.
|
|
@@ -18065,6 +19242,10 @@ MAX: 9026 };
|
|
|
18065
19242
|
* This element marks the beginning of a bookmarked region in the document.
|
|
18066
19243
|
* It must be paired with a corresponding BookmarkEnd element with the same id.
|
|
18067
19244
|
*
|
|
19245
|
+
* The id must be unique in the document. `Bookmark` takes its ids from
|
|
19246
|
+
* `bookmarkUniqueNumericId`, so take this one from it too, or it can be the
|
|
19247
|
+
* same as a `Bookmark`'s.
|
|
19248
|
+
*
|
|
18068
19249
|
* Reference: http://officeopenxml.com/WPbookmark.php
|
|
18069
19250
|
*
|
|
18070
19251
|
* ## XSD Schema
|
|
@@ -18082,7 +19263,10 @@ MAX: 9026 };
|
|
|
18082
19263
|
*
|
|
18083
19264
|
* @example
|
|
18084
19265
|
* ```typescript
|
|
18085
|
-
*
|
|
19266
|
+
* // A bookmark across two paragraphs
|
|
19267
|
+
* const id = bookmarkUniqueNumericId();
|
|
19268
|
+
* new Paragraph({ children: [new BookmarkStart("myBookmark", id), new TextRun("First")] });
|
|
19269
|
+
* new Paragraph({ children: [new TextRun("Last"), new BookmarkEnd(id)] });
|
|
18086
19270
|
* ```
|
|
18087
19271
|
*/
|
|
18088
19272
|
var BookmarkStart = class extends XmlComponent {
|
|
@@ -18099,7 +19283,8 @@ MAX: 9026 };
|
|
|
18099
19283
|
* Represents the end marker of a bookmark range.
|
|
18100
19284
|
*
|
|
18101
19285
|
* This element marks the end of a bookmarked region in the document.
|
|
18102
|
-
* It must be paired with a corresponding BookmarkStart element with the same id
|
|
19286
|
+
* It must be paired with a corresponding BookmarkStart element with the same id,
|
|
19287
|
+
* taken from `bookmarkUniqueNumericId` (see `BookmarkStart`).
|
|
18103
19288
|
*
|
|
18104
19289
|
* Reference: http://officeopenxml.com/WPbookmark.php
|
|
18105
19290
|
*
|
|
@@ -18118,7 +19303,9 @@ MAX: 9026 };
|
|
|
18118
19303
|
*
|
|
18119
19304
|
* @example
|
|
18120
19305
|
* ```typescript
|
|
18121
|
-
*
|
|
19306
|
+
* const id = bookmarkUniqueNumericId();
|
|
19307
|
+
* new BookmarkStart("myBookmark", id);
|
|
19308
|
+
* new BookmarkEnd(id);
|
|
18122
19309
|
* ```
|
|
18123
19310
|
*/
|
|
18124
19311
|
var BookmarkEnd = class extends XmlComponent {
|
|
@@ -18292,6 +19479,10 @@ MAX: 9026 };
|
|
|
18292
19479
|
* The PAGEREF field displays the page number of the page containing
|
|
18293
19480
|
* the specified bookmark, useful for cross-references like "see page 5".
|
|
18294
19481
|
*
|
|
19482
|
+
* It is written dirty, so Word fills in the page number when it opens the document, after asking to. When the
|
|
19483
|
+
* document is given `pageNumbers`, it is written clean, with the number they work out, or blank when they couldn't,
|
|
19484
|
+
* and Word doesn't ask.
|
|
19485
|
+
*
|
|
18295
19486
|
* @publicApi
|
|
18296
19487
|
*
|
|
18297
19488
|
* @example
|
|
@@ -18312,13 +19503,37 @@ MAX: 9026 };
|
|
|
18312
19503
|
var PageReference = class extends Run {
|
|
18313
19504
|
constructor(bookmarkId, options = {}) {
|
|
18314
19505
|
super({ children: [
|
|
18315
|
-
|
|
19506
|
+
createBeginDirtyWithoutPageNumbers(),
|
|
18316
19507
|
new PageReferenceFieldInstruction(bookmarkId, options),
|
|
19508
|
+
createSeparate(),
|
|
18317
19509
|
createEnd()
|
|
18318
19510
|
] });
|
|
18319
19511
|
}
|
|
18320
19512
|
};
|
|
18321
19513
|
//#endregion
|
|
19514
|
+
//#region src/file/paragraph/links/external-hyperlink-target.ts
|
|
19515
|
+
/**
|
|
19516
|
+
* External hyperlink targets and fragments for WordprocessingML.
|
|
19517
|
+
*
|
|
19518
|
+
* Word appends the anchor to the relationship target, separated by a # character.
|
|
19519
|
+
* Reference: https://learn.microsoft.com/en-us/openspecs/office_standards/ms-oi29500/df06e423-11a6-4a36-bfb3-82139e531781
|
|
19520
|
+
*
|
|
19521
|
+
* @module
|
|
19522
|
+
*/
|
|
19523
|
+
var MAX_ANCHOR_LENGTH = 255;
|
|
19524
|
+
/**
|
|
19525
|
+
* Splits a nonempty fragment that fits Word's anchor limit without decoding or normalizing either part.
|
|
19526
|
+
* Longer fragments stay in the original relationship URI, retaining its existing multi-hash limitations.
|
|
19527
|
+
*/
|
|
19528
|
+
var externalHyperlinkTarget = (link) => {
|
|
19529
|
+
const index = link.indexOf("#");
|
|
19530
|
+
const fragmentLength = link.length - index - 1;
|
|
19531
|
+
return index > 0 && fragmentLength > 0 && fragmentLength <= MAX_ANCHOR_LENGTH ? {
|
|
19532
|
+
target: link.slice(0, index),
|
|
19533
|
+
anchor: link.slice(index + 1)
|
|
19534
|
+
} : { target: link };
|
|
19535
|
+
};
|
|
19536
|
+
//#endregion
|
|
18322
19537
|
//#region src/file/fonts/font.ts
|
|
18323
19538
|
/**
|
|
18324
19539
|
* Font module for WordprocessingML documents.
|
|
@@ -18457,32 +19672,26 @@ MAX: 9026 };
|
|
|
18457
19672
|
]
|
|
18458
19673
|
});
|
|
18459
19674
|
//#endregion
|
|
18460
|
-
//#region src/file/fonts/create-
|
|
19675
|
+
//#region src/file/fonts/create-embedded-font.ts
|
|
18461
19676
|
/**
|
|
18462
|
-
* Creates
|
|
19677
|
+
* Creates an embedded font with default settings.
|
|
18463
19678
|
*
|
|
18464
19679
|
* This helper function creates a font definition with standard font signature
|
|
18465
19680
|
* values that work for most common fonts. The signature specifies Unicode
|
|
18466
19681
|
* and code page ranges supported by the font.
|
|
18467
19682
|
*
|
|
18468
|
-
* @param options - Font creation options
|
|
18469
|
-
* @param options.name - Font name
|
|
18470
|
-
* @param options.index - Font relationship index
|
|
18471
|
-
* @param options.fontKey - Unique font key (GUID) for obfuscation
|
|
18472
|
-
* @param options.characterSet - Optional character set identifier
|
|
18473
|
-
*
|
|
18474
19683
|
* @returns XmlComponent representing the font definition
|
|
18475
19684
|
*
|
|
18476
19685
|
* @example
|
|
18477
19686
|
* ```typescript
|
|
18478
|
-
* const font =
|
|
19687
|
+
* const font = createEmbeddedFont({
|
|
18479
19688
|
* name: "Arial",
|
|
18480
|
-
*
|
|
18481
|
-
* fontKey: "12345678-1234-1234-1234-
|
|
19689
|
+
* embedRegular: { id: "rId1", fontKey: "12345678-1234-1234-1234-123456789012" },
|
|
19690
|
+
* embedBold: { id: "rId2", fontKey: "12345678-1234-1234-1234-123456789013" },
|
|
18482
19691
|
* });
|
|
18483
19692
|
* ```
|
|
18484
19693
|
*/
|
|
18485
|
-
var
|
|
19694
|
+
var createEmbeddedFont = ({ name, characterSet, embedRegular, embedBold, embedItalic, embedBoldItalic }) => createFont({
|
|
18486
19695
|
name,
|
|
18487
19696
|
sig: {
|
|
18488
19697
|
usb0: "E0002AFF",
|
|
@@ -18495,10 +19704,10 @@ MAX: 9026 };
|
|
|
18495
19704
|
charset: characterSet,
|
|
18496
19705
|
family: "auto",
|
|
18497
19706
|
pitch: "variable",
|
|
18498
|
-
embedRegular
|
|
18499
|
-
|
|
18500
|
-
|
|
18501
|
-
|
|
19707
|
+
embedRegular,
|
|
19708
|
+
embedBold,
|
|
19709
|
+
embedItalic,
|
|
19710
|
+
embedBoldItalic
|
|
18502
19711
|
});
|
|
18503
19712
|
//#endregion
|
|
18504
19713
|
//#region src/file/fonts/font-table.ts
|
|
@@ -18576,25 +19785,47 @@ MAX: 9026 };
|
|
|
18576
19785
|
value: "w14 w15 w16se w16cid w16 w16cex w16sdtdh"
|
|
18577
19786
|
}
|
|
18578
19787
|
},
|
|
18579
|
-
children: fonts.map(
|
|
18580
|
-
name: font.name,
|
|
18581
|
-
index: i + 1,
|
|
18582
|
-
fontKey: font.fontKey,
|
|
18583
|
-
characterSet: font.characterSet
|
|
18584
|
-
}))
|
|
19788
|
+
children: fonts.map(createEmbeddedFont)
|
|
18585
19789
|
});
|
|
18586
19790
|
//#endregion
|
|
18587
19791
|
//#region src/file/fonts/font-wrapper.ts
|
|
19792
|
+
var FACES = [
|
|
19793
|
+
{
|
|
19794
|
+
option: "data",
|
|
19795
|
+
element: "embedRegular",
|
|
19796
|
+
bold: false,
|
|
19797
|
+
italic: false
|
|
19798
|
+
},
|
|
19799
|
+
{
|
|
19800
|
+
option: "bold",
|
|
19801
|
+
element: "embedBold",
|
|
19802
|
+
bold: true,
|
|
19803
|
+
italic: false
|
|
19804
|
+
},
|
|
19805
|
+
{
|
|
19806
|
+
option: "italic",
|
|
19807
|
+
element: "embedItalic",
|
|
19808
|
+
bold: false,
|
|
19809
|
+
italic: true
|
|
19810
|
+
},
|
|
19811
|
+
{
|
|
19812
|
+
option: "boldItalic",
|
|
19813
|
+
element: "embedBoldItalic",
|
|
19814
|
+
bold: true,
|
|
19815
|
+
italic: true
|
|
19816
|
+
}
|
|
19817
|
+
];
|
|
18588
19818
|
/**
|
|
18589
19819
|
* Wrapper class for managing the font table and its relationships.
|
|
18590
19820
|
*
|
|
18591
19821
|
* Creates a font table with embedded font files and manages the relationships
|
|
18592
|
-
* required for font embedding. Each font is
|
|
19822
|
+
* required for font embedding. Each face of a font is embedded as a file of its own,
|
|
19823
|
+
* with a unique key for obfuscation.
|
|
18593
19824
|
*
|
|
18594
19825
|
* @example
|
|
18595
19826
|
* ```typescript
|
|
18596
19827
|
* const fontWrapper = new FontWrapper([
|
|
18597
|
-
* { name: "CustomFont", data: fontBuffer }
|
|
19828
|
+
* { name: "CustomFont", data: fontBuffer, bold: boldFontBuffer }
|
|
18598
19829
|
* ]);
|
|
18599
19830
|
* ```
|
|
18600
19831
|
*/
|
|
@@ -18603,12 +19834,43 @@ MAX: 9026 };
|
|
|
18603
19834
|
_defineProperty(this, "options", void 0);
|
|
18604
19835
|
_defineProperty(this, "fontTable", void 0);
|
|
18605
19836
|
_defineProperty(this, "relationships", void 0);
|
|
18606
|
-
_defineProperty(
|
|
19837
|
+
_defineProperty(
|
|
19838
|
+
this,
|
|
19839
|
+
/** @deprecated Use `files`, which has the file and key of each face a font embeds, not only the regular face's key */
|
|
19840
|
+
"fontOptionsWithKey",
|
|
19841
|
+
[]
|
|
19842
|
+
);
|
|
19843
|
+
_defineProperty(
|
|
19844
|
+
this,
|
|
19845
|
+
/** The files of the faces the fonts embed, in order: the Nth is `fonts/font<N>.odttf`, with the relationship `rId<N>` */
|
|
19846
|
+
"files",
|
|
19847
|
+
[]
|
|
19848
|
+
);
|
|
18607
19849
|
this.options = options;
|
|
18608
|
-
|
|
18609
|
-
|
|
19850
|
+
const faces = options.map((font) => FACES.flatMap(({ option, element, bold, italic }) => {
|
|
19851
|
+
const data = font[option];
|
|
19852
|
+
return data ? [{
|
|
19853
|
+
element,
|
|
19854
|
+
file: {
|
|
19855
|
+
name: font.name,
|
|
19856
|
+
data,
|
|
19857
|
+
bold,
|
|
19858
|
+
italic,
|
|
19859
|
+
fontKey: uniqueUuid()
|
|
19860
|
+
}
|
|
19861
|
+
}] : [];
|
|
19862
|
+
}));
|
|
19863
|
+
this.files = faces.flatMap((ofFont) => ofFont.map(({ file }) => file));
|
|
19864
|
+
this.fontOptionsWithKey = options.map((font, index) => _objectSpread2(_objectSpread2({}, font), {}, { fontKey: faces[index][0].file.fontKey }));
|
|
19865
|
+
this.fontTable = createFontTable(options.map((font, index) => _objectSpread2({
|
|
19866
|
+
name: font.name,
|
|
19867
|
+
characterSet: font.characterSet
|
|
19868
|
+
}, Object.fromEntries(faces[index].map(({ element, file }) => [element, {
|
|
19869
|
+
id: `rId${this.files.indexOf(file) + 1}`,
|
|
19870
|
+
fontKey: file.fontKey
|
|
19871
|
+
}])))));
|
|
18610
19872
|
this.relationships = new Relationships();
|
|
18611
|
-
for (let i = 0; i <
|
|
19873
|
+
for (let i = 0; i < this.files.length; i++) this.relationships.addRelationship(i + 1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/font", `fonts/font${i + 1}.odttf`);
|
|
18612
19874
|
}
|
|
18613
19875
|
get View() {
|
|
18614
19876
|
return this.fontTable;
|
|
@@ -18828,17 +20090,18 @@ MAX: 9026 };
|
|
|
18828
20090
|
//#endregion
|
|
18829
20091
|
//#region src/file/paragraph/properties.ts
|
|
18830
20092
|
/**
|
|
18831
|
-
*
|
|
18832
|
-
*
|
|
18833
|
-
* This module provides the paragraph properties (pPr) element which specifies
|
|
18834
|
-
* the formatting applied to a paragraph.
|
|
18835
|
-
*
|
|
18836
|
-
* Reference: http://officeopenxml.com/WPparagraphProperties.php
|
|
20093
|
+
* The alignment to write for each side of the page in a right-to-left paragraph.
|
|
18837
20094
|
*
|
|
18838
|
-
*
|
|
18839
|
-
*
|
|
18840
|
-
*
|
|
20095
|
+
* Word and LibreOffice read `w:jc` `left` and `right` as the start and end of the paragraph, the same as
|
|
20096
|
+
* `start` and `end` (ISO/IEC 29500-4 maps the transitional `left` and `right` onto the strict `start` and `end`,
|
|
20097
|
+
* and [MS-OE376] 2.3.1.13 notes the same for Word 2007). So in a `w:bidi` paragraph `left` lands on the right
|
|
20098
|
+
* side of the page. Swapping keeps `AlignmentType.LEFT` and `AlignmentType.RIGHT` on the side of the page they name.
|
|
20099
|
+
* `left` and `right` are written rather than `end` and `start` because Word 2007 does not know `start` and `end`.
|
|
18841
20100
|
*/
|
|
20101
|
+
var RIGHT_TO_LEFT_ALIGNMENTS = {
|
|
20102
|
+
left: "right",
|
|
20103
|
+
right: "left"
|
|
20104
|
+
};
|
|
18842
20105
|
/**
|
|
18843
20106
|
* Represents paragraph properties (pPr) in a WordprocessingML document.
|
|
18844
20107
|
*
|
|
@@ -19002,7 +20265,7 @@ MAX: 9026 };
|
|
|
19002
20265
|
if (options.spacing) this.push(createSpacing(options.spacing));
|
|
19003
20266
|
if (options.indent) this.push(createIndent(options.indent));
|
|
19004
20267
|
if (options.contextualSpacing !== void 0) this.push(new OnOffElement("w:contextualSpacing", options.contextualSpacing));
|
|
19005
|
-
if (options.alignment) this.push(createAlignment(options.alignment));
|
|
20268
|
+
if (options.alignment) this.push(createAlignment(options.bidirectional && RIGHT_TO_LEFT_ALIGNMENTS[options.alignment] || options.alignment));
|
|
19006
20269
|
if (options.outlineLevel !== void 0) this.push(createOutlineLevel(options.outlineLevel));
|
|
19007
20270
|
if (options.suppressLineNumbers !== void 0) this.push(new OnOffElement("w:suppressLineNumbers", options.suppressLineNumbers));
|
|
19008
20271
|
if (options.autoSpaceEastAsianText !== void 0) this.push(new OnOffElement("w:autoSpaceDN", options.autoSpaceEastAsianText));
|
|
@@ -19018,6 +20281,31 @@ MAX: 9026 };
|
|
|
19018
20281
|
this.root.push(item);
|
|
19019
20282
|
}
|
|
19020
20283
|
/**
|
|
20284
|
+
* Adds the section properties (`w:sectPr`) of the section this paragraph ends.
|
|
20285
|
+
*
|
|
20286
|
+
* They go after the paragraph's run properties and before its revision (`w:pPrChange`),
|
|
20287
|
+
* the order CT_PPr gives them.
|
|
20288
|
+
*
|
|
20289
|
+
* @param sectionProperties - The properties of the section the paragraph ends
|
|
20290
|
+
*/
|
|
20291
|
+
addSectionProperties(sectionProperties) {
|
|
20292
|
+
const revisionIndex = this.root.findIndex((item) => item instanceof ParagraphPropertiesChange);
|
|
20293
|
+
if (revisionIndex === -1) {
|
|
20294
|
+
this.root.push(sectionProperties);
|
|
20295
|
+
return;
|
|
20296
|
+
}
|
|
20297
|
+
this.root.splice(revisionIndex, 0, sectionProperties);
|
|
20298
|
+
}
|
|
20299
|
+
/**
|
|
20300
|
+
* Removes the section properties added with {@link addSectionProperties}.
|
|
20301
|
+
*
|
|
20302
|
+
* @param sectionProperties - The properties of the section to remove
|
|
20303
|
+
*/
|
|
20304
|
+
removeSectionProperties(sectionProperties) {
|
|
20305
|
+
const index = this.root.indexOf(sectionProperties);
|
|
20306
|
+
if (index !== -1) this.root.splice(index, 1);
|
|
20307
|
+
}
|
|
20308
|
+
/**
|
|
19021
20309
|
* Prepares the paragraph properties for XML serialization.
|
|
19022
20310
|
*
|
|
19023
20311
|
* This method creates concrete numbering instances for any numbering references
|
|
@@ -19045,13 +20333,6 @@ MAX: 9026 };
|
|
|
19045
20333
|
//#endregion
|
|
19046
20334
|
//#region src/file/paragraph/paragraph.ts
|
|
19047
20335
|
/**
|
|
19048
|
-
* Paragraph module for WordprocessingML documents.
|
|
19049
|
-
*
|
|
19050
|
-
* Reference: http://officeopenxml.com/WPparagraph.php
|
|
19051
|
-
*
|
|
19052
|
-
* @module
|
|
19053
|
-
*/
|
|
19054
|
-
/**
|
|
19055
20336
|
* Represents a paragraph in a WordprocessingML document.
|
|
19056
20337
|
*
|
|
19057
20338
|
* A paragraph is the primary unit of block-level content in a document and can contain
|
|
@@ -19103,9 +20384,7 @@ MAX: 9026 };
|
|
|
19103
20384
|
if (options.text) this.root.push(new TextRun(options.text));
|
|
19104
20385
|
if (options.children) for (const child of options.children) {
|
|
19105
20386
|
if (child instanceof Bookmark) {
|
|
19106
|
-
this.root.push(child.
|
|
19107
|
-
for (const textRun of child.children) this.root.push(textRun);
|
|
19108
|
-
this.root.push(child.end);
|
|
20387
|
+
this.root.push(...child.writtenAs);
|
|
19109
20388
|
continue;
|
|
19110
20389
|
}
|
|
19111
20390
|
this.root.push(child);
|
|
@@ -19114,12 +20393,35 @@ MAX: 9026 };
|
|
|
19114
20393
|
prepForXml(context) {
|
|
19115
20394
|
for (const element of this.root) if (element instanceof ExternalHyperlink) {
|
|
19116
20395
|
const index = this.root.indexOf(element);
|
|
19117
|
-
const
|
|
19118
|
-
|
|
20396
|
+
const { target, anchor } = externalHyperlinkTarget(element.options.link);
|
|
20397
|
+
const concreteHyperlink = new ConcreteHyperlink(element.options.children, uniqueId(), anchor, element.options.link);
|
|
20398
|
+
context.viewWrapper.Relationships.addRelationship(concreteHyperlink.linkId, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", target, TargetModeType.EXTERNAL);
|
|
19119
20399
|
this.root[index] = concreteHyperlink;
|
|
19120
20400
|
}
|
|
19121
20401
|
return super.prepForXml(context);
|
|
19122
20402
|
}
|
|
20403
|
+
/**
|
|
20404
|
+
* Ends a section at this paragraph by adding the section's properties to the paragraph's properties,
|
|
20405
|
+
* as Word does with the last paragraph of each section but the last.
|
|
20406
|
+
*
|
|
20407
|
+
* The body adds them only while it is written and removes them afterwards with
|
|
20408
|
+
* {@link removeSectionProperties}, so the same paragraph can be used in other documents.
|
|
20409
|
+
*
|
|
20410
|
+
* @internal
|
|
20411
|
+
* @param sectionProperties - The properties of the section the paragraph ends
|
|
20412
|
+
*/
|
|
20413
|
+
addSectionProperties(sectionProperties) {
|
|
20414
|
+
this.properties.addSectionProperties(sectionProperties);
|
|
20415
|
+
}
|
|
20416
|
+
/**
|
|
20417
|
+
* Removes the section properties added with {@link addSectionProperties}.
|
|
20418
|
+
*
|
|
20419
|
+
* @internal
|
|
20420
|
+
* @param sectionProperties - The properties of the section to remove
|
|
20421
|
+
*/
|
|
20422
|
+
removeSectionProperties(sectionProperties) {
|
|
20423
|
+
this.properties.removeSectionProperties(sectionProperties);
|
|
20424
|
+
}
|
|
19123
20425
|
addRunToFront(run) {
|
|
19124
20426
|
this.root.splice(1, 0, run);
|
|
19125
20427
|
return this;
|
|
@@ -19212,7 +20514,7 @@ MAX: 9026 };
|
|
|
19212
20514
|
}
|
|
19213
20515
|
};
|
|
19214
20516
|
//#endregion
|
|
19215
|
-
//#region \0@oxc-project+runtime@0.
|
|
20517
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/objectWithoutPropertiesLoose.js
|
|
19216
20518
|
function _objectWithoutPropertiesLoose(r, e) {
|
|
19217
20519
|
if (null == r) return {};
|
|
19218
20520
|
var t = {};
|
|
@@ -19223,7 +20525,7 @@ MAX: 9026 };
|
|
|
19223
20525
|
return t;
|
|
19224
20526
|
}
|
|
19225
20527
|
//#endregion
|
|
19226
|
-
//#region \0@oxc-project+runtime@0.
|
|
20528
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/objectWithoutProperties.js
|
|
19227
20529
|
function _objectWithoutProperties(e, t) {
|
|
19228
20530
|
if (null == e) return {};
|
|
19229
20531
|
var o, r, i = _objectWithoutPropertiesLoose(e, t);
|
|
@@ -21176,6 +22478,168 @@ MAX: 9026 };
|
|
|
21176
22478
|
}
|
|
21177
22479
|
});
|
|
21178
22480
|
//#endregion
|
|
22481
|
+
//#region src/file/document/body/section-properties/properties/note-properties.ts
|
|
22482
|
+
/**
|
|
22483
|
+
* Where the footnotes of a section are placed.
|
|
22484
|
+
*
|
|
22485
|
+
* ## XSD Schema
|
|
22486
|
+
* ```xml
|
|
22487
|
+
* <xsd:simpleType name="ST_FtnPos">
|
|
22488
|
+
* <xsd:restriction base="xsd:string">
|
|
22489
|
+
* <xsd:enumeration value="pageBottom"/>
|
|
22490
|
+
* <xsd:enumeration value="beneathText"/>
|
|
22491
|
+
* <xsd:enumeration value="sectEnd"/>
|
|
22492
|
+
* <xsd:enumeration value="docEnd"/>
|
|
22493
|
+
* </xsd:restriction>
|
|
22494
|
+
* </xsd:simpleType>
|
|
22495
|
+
* ```
|
|
22496
|
+
*
|
|
22497
|
+
* @publicApi
|
|
22498
|
+
*/
|
|
22499
|
+
var FootnotePosition = {
|
|
22500
|
+
/** At the bottom of each page */
|
|
22501
|
+
PAGE_BOTTOM: "pageBottom",
|
|
22502
|
+
/** Directly below the text on each page */
|
|
22503
|
+
BENEATH_TEXT: "beneathText",
|
|
22504
|
+
/** At the end of the section */
|
|
22505
|
+
SECTION_END: "sectEnd",
|
|
22506
|
+
/** At the end of the document */
|
|
22507
|
+
DOCUMENT_END: "docEnd"
|
|
22508
|
+
};
|
|
22509
|
+
/**
|
|
22510
|
+
* Where the endnotes of a section are placed.
|
|
22511
|
+
*
|
|
22512
|
+
* ## XSD Schema
|
|
22513
|
+
* ```xml
|
|
22514
|
+
* <xsd:simpleType name="ST_EdnPos">
|
|
22515
|
+
* <xsd:restriction base="xsd:string">
|
|
22516
|
+
* <xsd:enumeration value="sectEnd"/>
|
|
22517
|
+
* <xsd:enumeration value="docEnd"/>
|
|
22518
|
+
* </xsd:restriction>
|
|
22519
|
+
* </xsd:simpleType>
|
|
22520
|
+
* ```
|
|
22521
|
+
*
|
|
22522
|
+
* @publicApi
|
|
22523
|
+
*/
|
|
22524
|
+
var EndnotePosition = {
|
|
22525
|
+
/** At the end of the section */
|
|
22526
|
+
SECTION_END: "sectEnd",
|
|
22527
|
+
/** At the end of the document */
|
|
22528
|
+
DOCUMENT_END: "docEnd"
|
|
22529
|
+
};
|
|
22530
|
+
/**
|
|
22531
|
+
* When the footnote or endnote numbering restarts.
|
|
22532
|
+
*
|
|
22533
|
+
* ## XSD Schema
|
|
22534
|
+
* ```xml
|
|
22535
|
+
* <xsd:simpleType name="ST_RestartNumber">
|
|
22536
|
+
* <xsd:restriction base="xsd:string">
|
|
22537
|
+
* <xsd:enumeration value="continuous"/>
|
|
22538
|
+
* <xsd:enumeration value="eachSect"/>
|
|
22539
|
+
* <xsd:enumeration value="eachPage"/>
|
|
22540
|
+
* </xsd:restriction>
|
|
22541
|
+
* </xsd:simpleType>
|
|
22542
|
+
* ```
|
|
22543
|
+
*
|
|
22544
|
+
* @publicApi
|
|
22545
|
+
*/
|
|
22546
|
+
var NoteNumberRestart = {
|
|
22547
|
+
/** Numbering never restarts */
|
|
22548
|
+
CONTINUOUS: "continuous",
|
|
22549
|
+
/** Numbering restarts in each section */
|
|
22550
|
+
EACH_SECTION: "eachSect",
|
|
22551
|
+
/** Numbering restarts on each page */
|
|
22552
|
+
EACH_PAGE: "eachPage"
|
|
22553
|
+
};
|
|
22554
|
+
var createNoteProperties = ({ name, position, numberFormat, start, restart }) => new BuilderElement({
|
|
22555
|
+
name,
|
|
22556
|
+
children: [
|
|
22557
|
+
...position === void 0 ? [] : [new BuilderElement({
|
|
22558
|
+
name: "w:pos",
|
|
22559
|
+
attributes: { val: {
|
|
22560
|
+
key: "w:val",
|
|
22561
|
+
value: position
|
|
22562
|
+
} }
|
|
22563
|
+
})],
|
|
22564
|
+
...numberFormat ? [new BuilderElement({
|
|
22565
|
+
name: "w:numFmt",
|
|
22566
|
+
attributes: {
|
|
22567
|
+
val: {
|
|
22568
|
+
key: "w:val",
|
|
22569
|
+
value: numberFormat.type
|
|
22570
|
+
},
|
|
22571
|
+
format: {
|
|
22572
|
+
key: "w:format",
|
|
22573
|
+
value: numberFormat.format
|
|
22574
|
+
}
|
|
22575
|
+
}
|
|
22576
|
+
})] : [],
|
|
22577
|
+
...start === void 0 ? [] : [new BuilderElement({
|
|
22578
|
+
name: "w:numStart",
|
|
22579
|
+
attributes: { val: {
|
|
22580
|
+
key: "w:val",
|
|
22581
|
+
value: decimalNumber(start)
|
|
22582
|
+
} }
|
|
22583
|
+
})],
|
|
22584
|
+
...restart === void 0 ? [] : [new BuilderElement({
|
|
22585
|
+
name: "w:numRestart",
|
|
22586
|
+
attributes: { val: {
|
|
22587
|
+
key: "w:val",
|
|
22588
|
+
value: restart
|
|
22589
|
+
} }
|
|
22590
|
+
})]
|
|
22591
|
+
]
|
|
22592
|
+
});
|
|
22593
|
+
/**
|
|
22594
|
+
* Creates the footnote properties (footnotePr) of a section.
|
|
22595
|
+
*
|
|
22596
|
+
* ## XSD Schema
|
|
22597
|
+
* ```xml
|
|
22598
|
+
* <xsd:complexType name="CT_FtnProps">
|
|
22599
|
+
* <xsd:sequence>
|
|
22600
|
+
* <xsd:element name="pos" type="CT_FtnPos" minOccurs="0"/>
|
|
22601
|
+
* <xsd:element name="numFmt" type="CT_NumFmt" minOccurs="0"/>
|
|
22602
|
+
* <xsd:group ref="EG_FtnEdnNumProps" minOccurs="0"/>
|
|
22603
|
+
* </xsd:sequence>
|
|
22604
|
+
* </xsd:complexType>
|
|
22605
|
+
* ```
|
|
22606
|
+
*
|
|
22607
|
+
* @example
|
|
22608
|
+
* ```typescript
|
|
22609
|
+
* // Footnotes at the end of the section, numbered a, b, c and restarting in each section
|
|
22610
|
+
* createFootnoteProperties({
|
|
22611
|
+
* position: FootnotePosition.SECTION_END,
|
|
22612
|
+
* numberFormat: { type: NumberFormat.LOWER_LETTER },
|
|
22613
|
+
* restart: NoteNumberRestart.EACH_SECTION,
|
|
22614
|
+
* });
|
|
22615
|
+
* ```
|
|
22616
|
+
*/
|
|
22617
|
+
var createFootnoteProperties = (options) => createNoteProperties(_objectSpread2({ name: "w:footnotePr" }, options));
|
|
22618
|
+
/**
|
|
22619
|
+
* Creates the endnote properties (endnotePr) of a section.
|
|
22620
|
+
*
|
|
22621
|
+
* ## XSD Schema
|
|
22622
|
+
* ```xml
|
|
22623
|
+
* <xsd:complexType name="CT_EdnProps">
|
|
22624
|
+
* <xsd:sequence>
|
|
22625
|
+
* <xsd:element name="pos" type="CT_EdnPos" minOccurs="0"/>
|
|
22626
|
+
* <xsd:element name="numFmt" type="CT_NumFmt" minOccurs="0"/>
|
|
22627
|
+
* <xsd:group ref="EG_FtnEdnNumProps" minOccurs="0"/>
|
|
22628
|
+
* </xsd:sequence>
|
|
22629
|
+
* </xsd:complexType>
|
|
22630
|
+
* ```
|
|
22631
|
+
*
|
|
22632
|
+
* @example
|
|
22633
|
+
* ```typescript
|
|
22634
|
+
* // Endnotes at the end of the document, numbered 001, 002, 003
|
|
22635
|
+
* createEndnoteProperties({
|
|
22636
|
+
* position: EndnotePosition.DOCUMENT_END,
|
|
22637
|
+
* numberFormat: { type: NumberFormat.CUSTOM, format: "001" },
|
|
22638
|
+
* });
|
|
22639
|
+
* ```
|
|
22640
|
+
*/
|
|
22641
|
+
var createEndnoteProperties = (options) => createNoteProperties(_objectSpread2({ name: "w:endnotePr" }, options));
|
|
22642
|
+
//#endregion
|
|
21179
22643
|
//#region src/file/document/body/section-properties/properties/page-borders.ts
|
|
21180
22644
|
/**
|
|
21181
22645
|
* Page borders module for WordprocessingML section properties.
|
|
@@ -21415,7 +22879,7 @@ MAX: 9026 };
|
|
|
21415
22879
|
COLON: "colon",
|
|
21416
22880
|
/** Em dash separator (—) */
|
|
21417
22881
|
EM_DASH: "emDash",
|
|
21418
|
-
/** En dash separator (–) */
|
|
22882
|
+
/** En dash separator (–), written as `enDash` */
|
|
21419
22883
|
EN_DASH: "endash"
|
|
21420
22884
|
};
|
|
21421
22885
|
/**
|
|
@@ -21445,7 +22909,7 @@ MAX: 9026 };
|
|
|
21445
22909
|
* });
|
|
21446
22910
|
* ```
|
|
21447
22911
|
*/
|
|
21448
|
-
var createPageNumberType = ({ start, formatType, separator }) => new BuilderElement({
|
|
22912
|
+
var createPageNumberType = ({ start, formatType, separator, chapterHeadingLevel }) => new BuilderElement({
|
|
21449
22913
|
name: "w:pgNumType",
|
|
21450
22914
|
attributes: {
|
|
21451
22915
|
start: {
|
|
@@ -21458,7 +22922,11 @@ MAX: 9026 };
|
|
|
21458
22922
|
},
|
|
21459
22923
|
separator: {
|
|
21460
22924
|
key: "w:chapSep",
|
|
21461
|
-
value: separator
|
|
22925
|
+
value: separator === PageNumberSeparator.EN_DASH ? "enDash" : separator
|
|
22926
|
+
},
|
|
22927
|
+
chapterHeadingLevel: {
|
|
22928
|
+
key: "w:chapStyle",
|
|
22929
|
+
value: chapterHeadingLevel === void 0 ? void 0 : decimalNumber(chapterHeadingLevel)
|
|
21462
22930
|
}
|
|
21463
22931
|
}
|
|
21464
22932
|
});
|
|
@@ -21762,7 +23230,7 @@ MAX: 9026 };
|
|
|
21762
23230
|
* ```
|
|
21763
23231
|
*/
|
|
21764
23232
|
var SectionProperties = class SectionProperties extends XmlComponent {
|
|
21765
|
-
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 } = {}) {
|
|
23233
|
+
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 } = {}) {
|
|
21766
23234
|
super("w:sectPr");
|
|
21767
23235
|
_defineProperty(
|
|
21768
23236
|
this,
|
|
@@ -21785,6 +23253,8 @@ MAX: 9026 };
|
|
|
21785
23253
|
});
|
|
21786
23254
|
this.addHeaderFooterGroup(HeaderFooterType.HEADER, headerWrapperGroup);
|
|
21787
23255
|
this.addHeaderFooterGroup(HeaderFooterType.FOOTER, footerWrapperGroup);
|
|
23256
|
+
if (footnoteProperties) this.root.push(createFootnoteProperties(footnoteProperties));
|
|
23257
|
+
if (endnoteProperties) this.root.push(createEndnoteProperties(endnoteProperties));
|
|
21788
23258
|
if (type) this.root.push(createSectionType(type));
|
|
21789
23259
|
this.root.push(createPageSize({
|
|
21790
23260
|
width,
|
|
@@ -21909,7 +23379,7 @@ MAX: 9026 };
|
|
|
21909
23379
|
* ```
|
|
21910
23380
|
*/
|
|
21911
23381
|
var Body = class extends XmlComponent {
|
|
21912
|
-
constructor() {
|
|
23382
|
+
constructor({ pageNumbers } = {}) {
|
|
21913
23383
|
super("w:body");
|
|
21914
23384
|
_defineProperty(this, "sections", []);
|
|
21915
23385
|
_defineProperty(
|
|
@@ -21917,11 +23387,15 @@ MAX: 9026 };
|
|
|
21917
23387
|
/**
|
|
21918
23388
|
* Section properties that were moved into a paragraph at the end of their section
|
|
21919
23389
|
* by {@link addSection}, keyed by that paragraph. Used to find the section that
|
|
21920
|
-
* governs a given child of the body
|
|
23390
|
+
* governs a given child of the body, and to write each section's properties into
|
|
23391
|
+
* its paragraph while the body is written.
|
|
21921
23392
|
*/
|
|
21922
23393
|
"sectionParagraphs",
|
|
21923
23394
|
/* @__PURE__ */ new Map()
|
|
21924
23395
|
);
|
|
23396
|
+
_defineProperty(this, "headingBookmarkIds", new HeadingBookmarkIds());
|
|
23397
|
+
_defineProperty(this, "pageNumbers", void 0);
|
|
23398
|
+
this.pageNumbers = pageNumbers;
|
|
21925
23399
|
}
|
|
21926
23400
|
/**
|
|
21927
23401
|
* Finds the section properties that govern a top-level child of the body.
|
|
@@ -21936,7 +23410,7 @@ MAX: 9026 };
|
|
|
21936
23410
|
* @returns The governing section properties, or undefined if the body has no sections
|
|
21937
23411
|
*/
|
|
21938
23412
|
getSectionPropertiesFor(child) {
|
|
21939
|
-
const start = child ? this.root.indexOf(child)
|
|
23413
|
+
const start = child ? Math.max(this.root.indexOf(child), 0) : 0;
|
|
21940
23414
|
for (let i = start; i < this.root.length; i++) {
|
|
21941
23415
|
const component = this.root[i];
|
|
21942
23416
|
if (component instanceof SectionProperties) return component;
|
|
@@ -21948,8 +23422,10 @@ MAX: 9026 };
|
|
|
21948
23422
|
/**
|
|
21949
23423
|
* Adds new section properties to the document body.
|
|
21950
23424
|
*
|
|
21951
|
-
* Creates a new section by moving the previous section's properties into
|
|
21952
|
-
*
|
|
23425
|
+
* Creates a new section by moving the previous section's properties into the last
|
|
23426
|
+
* paragraph of that section, and then adding the new section as the current section.
|
|
23427
|
+
* When that section doesn't end with a paragraph of its own (it ends with a table, or
|
|
23428
|
+
* it is empty), an empty paragraph is added to hold its properties.
|
|
21953
23429
|
*
|
|
21954
23430
|
* According to the OOXML specification:
|
|
21955
23431
|
* - Section properties for all sections except the last must be stored in a paragraph's
|
|
@@ -21960,16 +23436,24 @@ MAX: 9026 };
|
|
|
21960
23436
|
*/
|
|
21961
23437
|
addSection(options) {
|
|
21962
23438
|
const currentSection = this.sections.pop();
|
|
21963
|
-
const
|
|
21964
|
-
this.
|
|
21965
|
-
|
|
23439
|
+
const lastParagraph = this.lastParagraphOfSection();
|
|
23440
|
+
if (currentSection && lastParagraph) this.sectionParagraphs.set(lastParagraph, currentSection);
|
|
23441
|
+
else {
|
|
23442
|
+
const sectionParagraph = this.createSectionParagraph();
|
|
23443
|
+
this.root.push(sectionParagraph);
|
|
23444
|
+
if (currentSection) this.sectionParagraphs.set(sectionParagraph, currentSection);
|
|
23445
|
+
}
|
|
21966
23446
|
this.sections.push(new SectionProperties(options));
|
|
21967
23447
|
}
|
|
21968
23448
|
/**
|
|
21969
23449
|
* Prepares the body element for XML serialization.
|
|
21970
23450
|
*
|
|
21971
23451
|
* Ensures that the last section's properties are placed as a direct child of the body
|
|
21972
|
-
* element, as required by the OOXML specification.
|
|
23452
|
+
* element, as required by the OOXML specification. Once the body is written, its tables
|
|
23453
|
+
* of contents are filled in from its headings, and, when the body has a page number
|
|
23454
|
+
* estimator, its page references are given their page numbers. Its SEQ fields are given
|
|
23455
|
+
* their numbers after the tables of contents are filled in, as Word leaves a heading's SEQ
|
|
23456
|
+
* number out of its entry.
|
|
21973
23457
|
*
|
|
21974
23458
|
* @param context - The XML serialization context
|
|
21975
23459
|
* @returns The prepared XML object or undefined
|
|
@@ -21979,7 +23463,19 @@ MAX: 9026 };
|
|
|
21979
23463
|
this.root.splice(0, 1);
|
|
21980
23464
|
this.root.push(this.sections.pop());
|
|
21981
23465
|
}
|
|
21982
|
-
|
|
23466
|
+
for (const [paragraph, section] of this.sectionParagraphs) paragraph.addSectionProperties(section);
|
|
23467
|
+
let xml;
|
|
23468
|
+
try {
|
|
23469
|
+
xml = super.prepForXml(context);
|
|
23470
|
+
} finally {
|
|
23471
|
+
for (const [paragraph, section] of this.sectionParagraphs) paragraph.removeSectionProperties(section);
|
|
23472
|
+
}
|
|
23473
|
+
fillTablesOfContents(xml, context, this.headingBookmarkIds);
|
|
23474
|
+
if (this.pageNumbers) {
|
|
23475
|
+
fillSequenceNumbers(xml, context);
|
|
23476
|
+
fillPageNumbers(xml, context, this.pageNumbers);
|
|
23477
|
+
}
|
|
23478
|
+
return xml;
|
|
21983
23479
|
}
|
|
21984
23480
|
/**
|
|
21985
23481
|
* Adds a block-level component to the body.
|
|
@@ -21990,14 +23486,32 @@ MAX: 9026 };
|
|
|
21990
23486
|
* @param component - The XML component to add (paragraph, table, etc.)
|
|
21991
23487
|
*/
|
|
21992
23488
|
push(component) {
|
|
23489
|
+
const section = component instanceof Paragraph ? this.sectionParagraphs.get(component) : void 0;
|
|
23490
|
+
if (section) {
|
|
23491
|
+
const sectionParagraph = this.createSectionParagraph();
|
|
23492
|
+
this.root.splice(this.root.indexOf(component) + 1, 0, sectionParagraph);
|
|
23493
|
+
this.sectionParagraphs.delete(component);
|
|
23494
|
+
this.sectionParagraphs.set(sectionParagraph, section);
|
|
23495
|
+
}
|
|
21993
23496
|
this.root.push(component);
|
|
21994
23497
|
}
|
|
21995
|
-
|
|
21996
|
-
|
|
21997
|
-
|
|
21998
|
-
|
|
21999
|
-
|
|
22000
|
-
|
|
23498
|
+
/**
|
|
23499
|
+
* The paragraph the current section ends with, which can hold its properties.
|
|
23500
|
+
*
|
|
23501
|
+
* There is none when the section ends with something other than a paragraph, or is empty:
|
|
23502
|
+
* its last child is then the placeholder at the start of the body (removed when the body is
|
|
23503
|
+
* written) or the paragraph that ends the section before, which has properties of its own.
|
|
23504
|
+
*/
|
|
23505
|
+
lastParagraphOfSection() {
|
|
23506
|
+
const last = this.root[this.root.length - 1];
|
|
23507
|
+
return last instanceof Paragraph && last !== this.root[0] && !this.sectionParagraphs.has(last) && this.root.indexOf(last) === this.root.length - 1 ? last : void 0;
|
|
23508
|
+
}
|
|
23509
|
+
/**
|
|
23510
|
+
* An empty paragraph to end a section that has no paragraph of its own to end it. The section's
|
|
23511
|
+
* properties are written into it with the others, when the body is written.
|
|
23512
|
+
*/
|
|
23513
|
+
createSectionParagraph() {
|
|
23514
|
+
return new Paragraph({});
|
|
22001
23515
|
}
|
|
22002
23516
|
};
|
|
22003
23517
|
//#endregion
|
|
@@ -23109,6 +24623,9 @@ MAX: 9026 };
|
|
|
23109
24623
|
var TableCellProperties = class extends IgnoreIfEmptyXmlComponent {
|
|
23110
24624
|
constructor(options) {
|
|
23111
24625
|
super("w:tcPr", options.includeIfEmpty);
|
|
24626
|
+
_defineProperty(this, "hasWidth", void 0);
|
|
24627
|
+
_defineProperty(this, "hasColumnWidth", false);
|
|
24628
|
+
this.hasWidth = options.width !== void 0;
|
|
23112
24629
|
if (options.width) this.root.push(createTableWidthElement("w:tcW", options.width));
|
|
23113
24630
|
if (options.columnSpan) this.root.push(new GridSpan(options.columnSpan));
|
|
23114
24631
|
if (options.verticalMerge) this.root.push(new VerticalMerge(options.verticalMerge));
|
|
@@ -23126,6 +24643,19 @@ MAX: 9026 };
|
|
|
23126
24643
|
if (options.cellMerge) this.root.push(new CellMerge(options.cellMerge));
|
|
23127
24644
|
if (options.revision) this.root.push(new TableCellPropertiesChange(options.revision));
|
|
23128
24645
|
}
|
|
24646
|
+
/**
|
|
24647
|
+
* Gives a cell without a width of its own the width of the table's columns it spans, in twips.
|
|
24648
|
+
*
|
|
24649
|
+
* @internal
|
|
24650
|
+
*/
|
|
24651
|
+
setColumnWidth(twips) {
|
|
24652
|
+
if (this.hasWidth) return;
|
|
24653
|
+
this.root.splice(0, this.hasColumnWidth ? 1 : 0, createTableWidthElement("w:tcW", {
|
|
24654
|
+
size: twips,
|
|
24655
|
+
type: WidthType.DXA
|
|
24656
|
+
}));
|
|
24657
|
+
this.hasColumnWidth = true;
|
|
24658
|
+
}
|
|
23129
24659
|
};
|
|
23130
24660
|
var TableCellPropertiesChange = class extends XmlComponent {
|
|
23131
24661
|
constructor(options) {
|
|
@@ -23184,10 +24714,20 @@ MAX: 9026 };
|
|
|
23184
24714
|
"options",
|
|
23185
24715
|
void 0
|
|
23186
24716
|
);
|
|
24717
|
+
_defineProperty(this, "properties", void 0);
|
|
23187
24718
|
this.options = options;
|
|
23188
|
-
this.
|
|
24719
|
+
this.properties = new TableCellProperties(options);
|
|
24720
|
+
this.root.push(this.properties);
|
|
23189
24721
|
for (const child of options.children) this.root.push(child);
|
|
23190
24722
|
}
|
|
24723
|
+
/**
|
|
24724
|
+
* Gives the cell, unless it has a width of its own, the width of the table's columns it spans, in twips.
|
|
24725
|
+
*
|
|
24726
|
+
* @internal
|
|
24727
|
+
*/
|
|
24728
|
+
setColumnWidth(twips) {
|
|
24729
|
+
this.properties.setColumnWidth(twips);
|
|
24730
|
+
}
|
|
23191
24731
|
prepForXml(context) {
|
|
23192
24732
|
if (!(this.root[this.root.length - 1] instanceof Paragraph)) this.root.push(new Paragraph({}));
|
|
23193
24733
|
return super.prepForXml(context);
|
|
@@ -24051,6 +25591,7 @@ MAX: 9026 };
|
|
|
24051
25591
|
columnIndex += cell.options.columnSpan || 1;
|
|
24052
25592
|
});
|
|
24053
25593
|
});
|
|
25594
|
+
this.setCellWidths(DEFAULT_AVAILABLE_WIDTH);
|
|
24054
25595
|
this.resolvedColumnWidths = columnWidths !== null && columnWidths !== void 0 ? columnWidths : resolveColumnWidths({
|
|
24055
25596
|
rows,
|
|
24056
25597
|
width: this.width,
|
|
@@ -24107,6 +25648,7 @@ MAX: 9026 };
|
|
|
24107
25648
|
* serializing.
|
|
24108
25649
|
*/
|
|
24109
25650
|
prepForXml(context) {
|
|
25651
|
+
this.setCellWidths(this.resolveAvailableWidth(context));
|
|
24110
25652
|
if (this.columnWidths === void 0) {
|
|
24111
25653
|
this.resolvedColumnWidths = resolveColumnWidths({
|
|
24112
25654
|
rows: this.rows,
|
|
@@ -24119,6 +25661,29 @@ MAX: 9026 };
|
|
|
24119
25661
|
return super.prepForXml(context);
|
|
24120
25662
|
}
|
|
24121
25663
|
/**
|
|
25664
|
+
* Gives each cell without a width of its own the width of the `columnWidths` it spans, as Word sizes the columns of
|
|
25665
|
+
* cells without a width to their content, whatever the grid says. When the table's width is wider than the columns
|
|
25666
|
+
* add up to, they are scaled up to fill it, as Word and LibreOffice lay them out, so columns given as proportions
|
|
25667
|
+
* keep them.
|
|
25668
|
+
*/
|
|
25669
|
+
setCellWidths(availableWidth) {
|
|
25670
|
+
var _resolvePreferredWidt;
|
|
25671
|
+
if (this.columnWidths === void 0) return;
|
|
25672
|
+
const total = this.columnWidths.reduce((sum, columnWidth) => sum + columnWidth, 0);
|
|
25673
|
+
const tableWidth = (_resolvePreferredWidt = resolvePreferredWidth(this.width, availableWidth)) !== null && _resolvePreferredWidt !== void 0 ? _resolvePreferredWidt : 0;
|
|
25674
|
+
const scale = total > 0 && tableWidth > total ? tableWidth / total : 1;
|
|
25675
|
+
for (const row of this.rows) {
|
|
25676
|
+
let column = 0;
|
|
25677
|
+
for (const cell of row.cells) {
|
|
25678
|
+
const span = cell.options.columnSpan || 1;
|
|
25679
|
+
const spanned = this.columnWidths.slice(column, column + span);
|
|
25680
|
+
const cellWidth = Math.round(spanned.reduce((sum, columnWidth) => sum + columnWidth, 0) * scale);
|
|
25681
|
+
if (spanned.length === span && cellWidth > 0) cell.setColumnWidth(cellWidth);
|
|
25682
|
+
column += span;
|
|
25683
|
+
}
|
|
25684
|
+
}
|
|
25685
|
+
}
|
|
25686
|
+
/**
|
|
24122
25687
|
* Finds the width in twips available to this table from the serialization context:
|
|
24123
25688
|
* the parent cell for a nested table, otherwise the text width of the section the
|
|
24124
25689
|
* table belongs to (the first section for headers, footers and other parts). Falls
|
|
@@ -24731,7 +26296,7 @@ MAX: 9026 };
|
|
|
24731
26296
|
for (const property of properties) this.addCustomProperty(property);
|
|
24732
26297
|
}
|
|
24733
26298
|
prepForXml(context) {
|
|
24734
|
-
this.
|
|
26299
|
+
this.root.splice(1, this.root.length - 1, ...this.properties);
|
|
24735
26300
|
return super.prepForXml(context);
|
|
24736
26301
|
}
|
|
24737
26302
|
addCustomProperty(property) {
|
|
@@ -24993,7 +26558,7 @@ MAX: 9026 };
|
|
|
24993
26558
|
"w16sdtdh",
|
|
24994
26559
|
"w16se"
|
|
24995
26560
|
], "w14 w15 wp14"));
|
|
24996
|
-
this.body = new Body();
|
|
26561
|
+
this.body = new Body({ pageNumbers: options.pageNumbers });
|
|
24997
26562
|
if (options.background) this.root.push(new DocumentBackground(options.background));
|
|
24998
26563
|
this.root.push(this.body);
|
|
24999
26564
|
}
|
|
@@ -25291,6 +26856,15 @@ MAX: 9026 };
|
|
|
25291
26856
|
});
|
|
25292
26857
|
this.root.push(endnote);
|
|
25293
26858
|
}
|
|
26859
|
+
/**
|
|
26860
|
+
* Formats the endnotes, with the page numbers worked out for their document written into their fields, when the
|
|
26861
|
+
* document's body is written with an estimate of its pages.
|
|
26862
|
+
*/
|
|
26863
|
+
prepForXml(context) {
|
|
26864
|
+
const xml = super.prepForXml(context);
|
|
26865
|
+
fillPartPageNumbers(xml, context);
|
|
26866
|
+
return xml;
|
|
26867
|
+
}
|
|
25294
26868
|
};
|
|
25295
26869
|
//#endregion
|
|
25296
26870
|
//#region src/file/endnotes-wrapper.ts
|
|
@@ -25432,6 +27006,15 @@ MAX: 9026 };
|
|
|
25432
27006
|
add(item) {
|
|
25433
27007
|
this.root.push(item);
|
|
25434
27008
|
}
|
|
27009
|
+
/**
|
|
27010
|
+
* Formats the footer, with the page numbers worked out for its document written into its fields, when the document's
|
|
27011
|
+
* body is written with an estimate of its pages.
|
|
27012
|
+
*/
|
|
27013
|
+
prepForXml(context) {
|
|
27014
|
+
const xml = super.prepForXml(context);
|
|
27015
|
+
fillPartPageNumbers(xml, context, this.refId);
|
|
27016
|
+
return xml;
|
|
27017
|
+
}
|
|
25435
27018
|
};
|
|
25436
27019
|
//#endregion
|
|
25437
27020
|
//#region src/file/footer-wrapper.ts
|
|
@@ -25782,6 +27365,15 @@ MAX: 9026 };
|
|
|
25782
27365
|
});
|
|
25783
27366
|
this.root.push(footnote);
|
|
25784
27367
|
}
|
|
27368
|
+
/**
|
|
27369
|
+
* Formats the footnotes, with the page numbers worked out for their document written into their fields, when the
|
|
27370
|
+
* document's body is written with an estimate of its pages.
|
|
27371
|
+
*/
|
|
27372
|
+
prepForXml(context) {
|
|
27373
|
+
const xml = super.prepForXml(context);
|
|
27374
|
+
fillPartPageNumbers(xml, context);
|
|
27375
|
+
return xml;
|
|
27376
|
+
}
|
|
25785
27377
|
};
|
|
25786
27378
|
//#endregion
|
|
25787
27379
|
//#region src/file/footnotes-wrapper.ts
|
|
@@ -25955,6 +27547,15 @@ MAX: 9026 };
|
|
|
25955
27547
|
add(item) {
|
|
25956
27548
|
this.root.push(item);
|
|
25957
27549
|
}
|
|
27550
|
+
/**
|
|
27551
|
+
* Formats the header, with the page numbers worked out for its document written into its fields, when the document's
|
|
27552
|
+
* body is written with an estimate of its pages.
|
|
27553
|
+
*/
|
|
27554
|
+
prepForXml(context) {
|
|
27555
|
+
const xml = super.prepForXml(context);
|
|
27556
|
+
fillPartPageNumbers(xml, context, this.refId);
|
|
27557
|
+
return xml;
|
|
27558
|
+
}
|
|
25958
27559
|
};
|
|
25959
27560
|
//#endregion
|
|
25960
27561
|
//#region src/file/header-wrapper.ts
|
|
@@ -26959,8 +28560,7 @@ MAX: 9026 };
|
|
|
26959
28560
|
* @returns The prepared XML object
|
|
26960
28561
|
*/
|
|
26961
28562
|
prepForXml(context) {
|
|
26962
|
-
|
|
26963
|
-
for (const numbering of this.concreteNumberingMap.values()) this.root.push(numbering);
|
|
28563
|
+
this.root.splice(1, this.root.length - 1, ...this.abstractNumberingMap.values(), ...this.concreteNumberingMap.values());
|
|
26964
28564
|
return super.prepForXml(context);
|
|
26965
28565
|
}
|
|
26966
28566
|
/**
|
|
@@ -27014,6 +28614,7 @@ MAX: 9026 };
|
|
|
27014
28614
|
};
|
|
27015
28615
|
//#endregion
|
|
27016
28616
|
//#region src/file/package-part/package-part.ts
|
|
28617
|
+
var PATH_PART = /^[\w-]+$/;
|
|
27017
28618
|
var RESERVED_FOLDERS = /* @__PURE__ */ new Set([
|
|
27018
28619
|
"_rels",
|
|
27019
28620
|
"fonts",
|
|
@@ -27052,6 +28653,7 @@ MAX: 9026 };
|
|
|
27052
28653
|
var PackagePart = class {
|
|
27053
28654
|
/**
|
|
27054
28655
|
* @throws If the folder isn't a single folder name, or is one of the folders docx writes parts of its own in
|
|
28656
|
+
* @throws If the name or the extension isn't a single part of a file name, which could lead out of the folder
|
|
27055
28657
|
*/
|
|
27056
28658
|
constructor(options) {
|
|
27057
28659
|
_defineProperty(this, "options", void 0);
|
|
@@ -27064,7 +28666,9 @@ MAX: 9026 };
|
|
|
27064
28666
|
);
|
|
27065
28667
|
_defineProperty(this, "addedTo", /* @__PURE__ */ new WeakSet());
|
|
27066
28668
|
this.options = options;
|
|
27067
|
-
if (
|
|
28669
|
+
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"`);
|
|
28670
|
+
if (!PATH_PART.test(options.name)) throw new Error(`Invalid package part name "${options.name}". Expected letters, digits, "_" and "-", such as "chart"`);
|
|
28671
|
+
if (!PATH_PART.test(options.extension)) throw new Error(`Invalid package part extension "${options.extension}". Expected letters, digits, "_" and "-", such as "xml"`);
|
|
27068
28672
|
}
|
|
27069
28673
|
/**
|
|
27070
28674
|
* Adds the part to the package being written, once, and a relationship to it from the part being written.
|
|
@@ -27086,7 +28690,7 @@ MAX: 9026 };
|
|
|
27086
28690
|
/**
|
|
27087
28691
|
* @param contentTypes - Where each part's content type is added
|
|
27088
28692
|
* @param existingPaths - The paths under word/ of the parts the package already has, such as a template's charts,
|
|
27089
|
-
* which new parts
|
|
28693
|
+
* which new parts don't take
|
|
27090
28694
|
*/
|
|
27091
28695
|
constructor(contentTypes, existingPaths = /* @__PURE__ */ new Set()) {
|
|
27092
28696
|
_defineProperty(this, "contentTypes", void 0);
|
|
@@ -27385,6 +28989,7 @@ MAX: 9026 };
|
|
|
27385
28989
|
* ```xml
|
|
27386
28990
|
* <xsd:complexType name="CT_Settings">
|
|
27387
28991
|
* <xsd:sequence>
|
|
28992
|
+
* <xsd:element name="embedTrueTypeFonts" type="CT_OnOff" minOccurs="0"/>
|
|
27388
28993
|
* <xsd:element name="trackRevisions" type="CT_OnOff" minOccurs="0"/>
|
|
27389
28994
|
* <xsd:element name="defaultTabStop" type="CT_TwipsMeasure" minOccurs="0"/>
|
|
27390
28995
|
* <xsd:element name="autoHyphenation" type="CT_OnOff" minOccurs="0"/>
|
|
@@ -27443,6 +29048,7 @@ MAX: 9026 };
|
|
|
27443
29048
|
Ignorable: "w14 w15 wp14"
|
|
27444
29049
|
}));
|
|
27445
29050
|
this.root.push(new OnOffElement("w:displayBackgroundShape", true));
|
|
29051
|
+
if (options.embedFonts !== void 0) this.root.push(new OnOffElement("w:embedTrueTypeFonts", options.embedFonts));
|
|
27446
29052
|
if (options.trackRevisions !== void 0) this.root.push(new OnOffElement("w:trackRevisions", options.trackRevisions));
|
|
27447
29053
|
if (options.defaultTabStop !== void 0) this.root.push(new NumberValueElement("w:defaultTabStop", options.defaultTabStop));
|
|
27448
29054
|
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));
|
|
@@ -28031,6 +29637,39 @@ MAX: 9026 };
|
|
|
28031
29637
|
}, options));
|
|
28032
29638
|
}
|
|
28033
29639
|
};
|
|
29640
|
+
/**
|
|
29641
|
+
* Represents the Normal Table style, the default style of tables.
|
|
29642
|
+
*
|
|
29643
|
+
* It gives cells the margins Word gives the tables it makes: 108 twips (0.075 inches) on the left and right. Without a
|
|
29644
|
+
* default table style, Word gives cells no margins, so their text touches the borders, where LibreOffice and other
|
|
29645
|
+
* applications use these margins.
|
|
29646
|
+
*/
|
|
29647
|
+
var NormalTableStyle = class extends Style {
|
|
29648
|
+
constructor() {
|
|
29649
|
+
super({
|
|
29650
|
+
type: "table",
|
|
29651
|
+
styleId: "TableNormal",
|
|
29652
|
+
default: true
|
|
29653
|
+
}, {
|
|
29654
|
+
name: "Normal Table",
|
|
29655
|
+
uiPriority: 99,
|
|
29656
|
+
semiHidden: true,
|
|
29657
|
+
unhideWhenUsed: true
|
|
29658
|
+
});
|
|
29659
|
+
this.root.push(new TableProperties({
|
|
29660
|
+
indent: {
|
|
29661
|
+
size: 0,
|
|
29662
|
+
type: WidthType.DXA
|
|
29663
|
+
},
|
|
29664
|
+
cellMargin: {
|
|
29665
|
+
top: 0,
|
|
29666
|
+
left: 108,
|
|
29667
|
+
bottom: 0,
|
|
29668
|
+
right: 108
|
|
29669
|
+
}
|
|
29670
|
+
}));
|
|
29671
|
+
}
|
|
29672
|
+
};
|
|
28034
29673
|
//#endregion
|
|
28035
29674
|
//#region src/file/styles/styles.ts
|
|
28036
29675
|
/** The name of a formatted element, such as `w:style`, or `_attr` for its parent's attributes */
|
|
@@ -28323,6 +29962,7 @@ MAX: 9026 };
|
|
|
28323
29962
|
name: "Normal",
|
|
28324
29963
|
quickFormat: true
|
|
28325
29964
|
}),
|
|
29965
|
+
normalTable: new NormalTableStyle(),
|
|
28326
29966
|
document: new DocumentDefaults((_options$document = options.document) !== null && _options$document !== void 0 ? _options$document : {}),
|
|
28327
29967
|
title: new TitleStyle(_objectSpread2({ run: { size: 56 } }, options.title)),
|
|
28328
29968
|
heading1: new Heading1Style(_objectSpread2({ run: {
|
|
@@ -28997,7 +30637,7 @@ MAX: 9026 };
|
|
|
28997
30637
|
*/
|
|
28998
30638
|
var File = class {
|
|
28999
30639
|
constructor(options) {
|
|
29000
|
-
var _options$creator, _options$revision, _options$lastModified, _options$comments, _options$customProper, _options$features, _options$features2, _options$hyphenation, _options$hyphenation2, _options$hyphenation3, _options$hyphenation4, _options$
|
|
30640
|
+
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;
|
|
29001
30641
|
_defineProperty(this, "currentRelationshipId", 1);
|
|
29002
30642
|
_defineProperty(this, "documentWrapper", void 0);
|
|
29003
30643
|
_defineProperty(this, "headers", []);
|
|
@@ -29045,13 +30685,17 @@ MAX: 9026 };
|
|
|
29045
30685
|
this.endnotesWrapper = new EndnotesWrapper();
|
|
29046
30686
|
this.contentTypes = new ContentTypes();
|
|
29047
30687
|
this.packageParts = new PackageParts(this.contentTypes);
|
|
29048
|
-
this.documentWrapper = new DocumentWrapper({
|
|
30688
|
+
this.documentWrapper = new DocumentWrapper({
|
|
30689
|
+
background: options.background,
|
|
30690
|
+
pageNumbers: options.pageNumbers
|
|
30691
|
+
});
|
|
29049
30692
|
this.settings = new Settings({
|
|
29050
30693
|
compatibilityModeVersion: options.compatabilityModeVersion,
|
|
29051
30694
|
compatibility: options.compatibility,
|
|
29052
30695
|
evenAndOddHeaders: options.evenAndOddHeaderAndFooters ? true : false,
|
|
29053
30696
|
trackRevisions: (_options$features = options.features) === null || _options$features === void 0 ? void 0 : _options$features.trackRevisions,
|
|
29054
30697
|
updateFields: (_options$features2 = options.features) === null || _options$features2 === void 0 ? void 0 : _options$features2.updateFields,
|
|
30698
|
+
embedFonts: ((_options$fonts = options.fonts) === null || _options$fonts === void 0 ? void 0 : _options$fonts.length) ? true : void 0,
|
|
29055
30699
|
defaultTabStop: options.defaultTabStop,
|
|
29056
30700
|
hyphenation: {
|
|
29057
30701
|
autoHyphenation: (_options$hyphenation = options.hyphenation) === null || _options$hyphenation === void 0 ? void 0 : _options$hyphenation.autoHyphenation,
|
|
@@ -29062,16 +30706,20 @@ MAX: 9026 };
|
|
|
29062
30706
|
});
|
|
29063
30707
|
this.media = new Media();
|
|
29064
30708
|
if (options.externalStyles !== void 0) {
|
|
29065
|
-
var _options$styles$defau, _options$styles;
|
|
30709
|
+
var _options$styles$defau, _options$styles, _options$styles2, _options$styles3;
|
|
29066
30710
|
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 : {};
|
|
29067
30711
|
const defaultStyles = Object.entries(createDefaultStyles(given));
|
|
29068
30712
|
const isGiven = ([key]) => given[key] !== void 0;
|
|
29069
30713
|
const externalStyles = new ExternalStylesFactory().newInstance(options.externalStyles);
|
|
29070
|
-
this.styles = new Styles(_objectSpread2(_objectSpread2({}, externalStyles), {}, {
|
|
29071
|
-
|
|
29072
|
-
|
|
29073
|
-
|
|
29074
|
-
|
|
30714
|
+
this.styles = new Styles(_objectSpread2(_objectSpread2({}, externalStyles), {}, {
|
|
30715
|
+
paragraphStyles: (_options$styles2 = options.styles) === null || _options$styles2 === void 0 ? void 0 : _options$styles2.paragraphStyles,
|
|
30716
|
+
characterStyles: (_options$styles3 = options.styles) === null || _options$styles3 === void 0 ? void 0 : _options$styles3.characterStyles,
|
|
30717
|
+
importedStyles: [
|
|
30718
|
+
...defaultStyles.filter((entry) => !isGiven(entry)).map(([, style]) => style),
|
|
30719
|
+
...externalStyles.importedStyles,
|
|
30720
|
+
...defaultStyles.filter(isGiven).map(([, style]) => style)
|
|
30721
|
+
]
|
|
30722
|
+
}));
|
|
29075
30723
|
} else if (options.styles) {
|
|
29076
30724
|
const defaultStyles = new DefaultStylesFactory().newInstance(options.styles.default);
|
|
29077
30725
|
this.styles = new Styles(_objectSpread2(_objectSpread2({}, defaultStyles), options.styles));
|
|
@@ -29083,7 +30731,7 @@ MAX: 9026 };
|
|
|
29083
30731
|
for (const section of options.sections) this.addSection(section);
|
|
29084
30732
|
if (options.footnotes) for (const key in options.footnotes) this.footnotesWrapper.View.createFootNote(parseFloat(key), options.footnotes[key].children);
|
|
29085
30733
|
if (options.endnotes) for (const key in options.endnotes) this.endnotesWrapper.View.createEndnote(parseFloat(key), options.endnotes[key].children);
|
|
29086
|
-
this.fontWrapper = new FontWrapper((_options$
|
|
30734
|
+
this.fontWrapper = new FontWrapper((_options$fonts2 = options.fonts) !== null && _options$fonts2 !== void 0 ? _options$fonts2 : []);
|
|
29087
30735
|
this.theme = new Theme(options.theme);
|
|
29088
30736
|
this.documentWrapper.Relationships.addRelationship(this.currentRelationshipId++, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", "theme/theme1.xml");
|
|
29089
30737
|
}
|
|
@@ -29219,113 +30867,6 @@ MAX: 9026 };
|
|
|
29219
30867
|
}
|
|
29220
30868
|
};
|
|
29221
30869
|
//#endregion
|
|
29222
|
-
//#region src/file/table-of-contents/field-instruction.ts
|
|
29223
|
-
/**
|
|
29224
|
-
* Field Instruction module for Table of Contents.
|
|
29225
|
-
*
|
|
29226
|
-
* This module handles the generation of TOC field instruction text
|
|
29227
|
-
* that controls how the table of contents is built.
|
|
29228
|
-
*
|
|
29229
|
-
* Reference: http://officeopenxml.com/WPfieldInstructions.php
|
|
29230
|
-
*
|
|
29231
|
-
* @module
|
|
29232
|
-
*/
|
|
29233
|
-
/**
|
|
29234
|
-
* Represents a field instruction for a Table of Contents.
|
|
29235
|
-
*
|
|
29236
|
-
* The FieldInstruction class generates the TOC field code string that Word uses
|
|
29237
|
-
* to determine how to build the table of contents, including which headings to include,
|
|
29238
|
-
* formatting options, and other TOC-specific settings.
|
|
29239
|
-
*
|
|
29240
|
-
* Reference: http://officeopenxml.com/WPfieldInstructions.php
|
|
29241
|
-
*
|
|
29242
|
-
* ## XSD Schema
|
|
29243
|
-
* ```xml
|
|
29244
|
-
* <xsd:element name="instrText" type="CT_Text"/>
|
|
29245
|
-
* ```
|
|
29246
|
-
*
|
|
29247
|
-
* @example
|
|
29248
|
-
* ```typescript
|
|
29249
|
-
* // Basic TOC field instruction
|
|
29250
|
-
* new FieldInstruction({ headingStyleRange: "1-3" });
|
|
29251
|
-
*
|
|
29252
|
-
* // TOC with hyperlinks and custom styles
|
|
29253
|
-
* new FieldInstruction({
|
|
29254
|
-
* hyperlink: true,
|
|
29255
|
-
* headingStyleRange: "1-3",
|
|
29256
|
-
* stylesWithLevels: [new StyleLevel("CustomStyle", 2)],
|
|
29257
|
-
* });
|
|
29258
|
-
* ```
|
|
29259
|
-
*/
|
|
29260
|
-
var FieldInstruction = class extends XmlComponent {
|
|
29261
|
-
constructor(properties = {}) {
|
|
29262
|
-
super("w:instrText");
|
|
29263
|
-
_defineProperty(this, "properties", void 0);
|
|
29264
|
-
this.properties = properties;
|
|
29265
|
-
this.root.push(new TextAttributes({ space: SpaceType.PRESERVE }));
|
|
29266
|
-
let instruction = "TOC";
|
|
29267
|
-
if (this.properties.captionLabel) instruction = `${instruction} \\a "${this.properties.captionLabel}"`;
|
|
29268
|
-
if (this.properties.entriesFromBookmark) instruction = `${instruction} \\b "${this.properties.entriesFromBookmark}"`;
|
|
29269
|
-
if (this.properties.captionLabelIncludingNumbers) instruction = `${instruction} \\c "${this.properties.captionLabelIncludingNumbers}"`;
|
|
29270
|
-
if (this.properties.sequenceAndPageNumbersSeparator) instruction = `${instruction} \\d "${this.properties.sequenceAndPageNumbersSeparator}"`;
|
|
29271
|
-
if (this.properties.tcFieldIdentifier) instruction = `${instruction} \\f "${this.properties.tcFieldIdentifier}"`;
|
|
29272
|
-
if (this.properties.hyperlink) instruction = `${instruction} \\h`;
|
|
29273
|
-
if (this.properties.tcFieldLevelRange) instruction = `${instruction} \\l "${this.properties.tcFieldLevelRange}"`;
|
|
29274
|
-
if (this.properties.pageNumbersEntryLevelsRange) instruction = `${instruction} \\n "${this.properties.pageNumbersEntryLevelsRange}"`;
|
|
29275
|
-
if (this.properties.headingStyleRange) instruction = `${instruction} \\o "${this.properties.headingStyleRange}"`;
|
|
29276
|
-
if (this.properties.entryAndPageNumberSeparator) instruction = `${instruction} \\p "${this.properties.entryAndPageNumberSeparator}"`;
|
|
29277
|
-
if (this.properties.seqFieldIdentifierForPrefix) instruction = `${instruction} \\s "${this.properties.seqFieldIdentifierForPrefix}"`;
|
|
29278
|
-
if (this.properties.stylesWithLevels && this.properties.stylesWithLevels.length) {
|
|
29279
|
-
const styles = this.properties.stylesWithLevels.map((sl) => `${sl.styleName},${sl.level}`).join(",");
|
|
29280
|
-
instruction = `${instruction} \\t "${styles}"`;
|
|
29281
|
-
}
|
|
29282
|
-
if (this.properties.useAppliedParagraphOutlineLevel) instruction = `${instruction} \\u`;
|
|
29283
|
-
if (this.properties.preserveTabInEntries) instruction = `${instruction} \\w`;
|
|
29284
|
-
if (this.properties.preserveNewLineInEntries) instruction = `${instruction} \\x`;
|
|
29285
|
-
if (this.properties.hideTabAndPageNumbersInWebView) instruction = `${instruction} \\z`;
|
|
29286
|
-
this.root.push(instruction);
|
|
29287
|
-
}
|
|
29288
|
-
};
|
|
29289
|
-
//#endregion
|
|
29290
|
-
//#region src/file/table-of-contents/sdt-content.ts
|
|
29291
|
-
/**
|
|
29292
|
-
* Structured Document Tag Content module.
|
|
29293
|
-
*
|
|
29294
|
-
* This module represents the content container for structured document tags,
|
|
29295
|
-
* including table of contents elements.
|
|
29296
|
-
*
|
|
29297
|
-
* Reference: http://officeopenxml.com/WPtableOfContents.php
|
|
29298
|
-
*
|
|
29299
|
-
* @module
|
|
29300
|
-
*/
|
|
29301
|
-
/**
|
|
29302
|
-
* Represents the content portion of a Structured Document Tag.
|
|
29303
|
-
*
|
|
29304
|
-
* The StructuredDocumentTagContent contains the actual content elements
|
|
29305
|
-
* (paragraphs, tables, etc.) within a structured document tag, such as
|
|
29306
|
-
* the paragraphs that make up a table of contents.
|
|
29307
|
-
*
|
|
29308
|
-
* Reference: http://officeopenxml.com/WPtableOfContents.php
|
|
29309
|
-
*
|
|
29310
|
-
* ## XSD Schema
|
|
29311
|
-
* ```xml
|
|
29312
|
-
* <xsd:complexType name="CT_SdtContentBlock">
|
|
29313
|
-
* <xsd:group ref="EG_ContentBlockContent" minOccurs="0" maxOccurs="unbounded"/>
|
|
29314
|
-
* </xsd:complexType>
|
|
29315
|
-
* ```
|
|
29316
|
-
*
|
|
29317
|
-
* @example
|
|
29318
|
-
* ```typescript
|
|
29319
|
-
* const content = new StructuredDocumentTagContent();
|
|
29320
|
-
* content.addChildElement(new Paragraph("Content"));
|
|
29321
|
-
* ```
|
|
29322
|
-
*/
|
|
29323
|
-
var StructuredDocumentTagContent = class extends XmlComponent {
|
|
29324
|
-
constructor() {
|
|
29325
|
-
super("w:sdtContent");
|
|
29326
|
-
}
|
|
29327
|
-
};
|
|
29328
|
-
//#endregion
|
|
29329
30870
|
//#region src/file/table-of-contents/sdt-properties.ts
|
|
29330
30871
|
/**
|
|
29331
30872
|
* Structured Document Tag Properties module.
|
|
@@ -29405,6 +30946,12 @@ MAX: 9026 };
|
|
|
29405
30946
|
* TableOfContents creates an auto-generated list of document headings
|
|
29406
30947
|
* with page numbers. It uses a TOC field code to generate entries.
|
|
29407
30948
|
*
|
|
30949
|
+
* Unless it is given `cachedEntries` or `contentChildren`, it is written with an
|
|
30950
|
+
* entry for each heading its options include, linked to a bookmark on the heading,
|
|
30951
|
+
* so it isn't empty before Word updates it or in applications that don't update it.
|
|
30952
|
+
* The page numbers are left for Word to fill in when it updates the field, unless the document's `pageNumbers`
|
|
30953
|
+
* writes them.
|
|
30954
|
+
*
|
|
29408
30955
|
* Reference: http://officeopenxml.com/WPtableOfContents.php
|
|
29409
30956
|
*
|
|
29410
30957
|
* @publicApi
|
|
@@ -29430,12 +30977,18 @@ MAX: 9026 };
|
|
|
29430
30977
|
*/
|
|
29431
30978
|
var TableOfContents = class extends FileChild {
|
|
29432
30979
|
constructor(alias = "Table of Contents", _ref = {}) {
|
|
29433
|
-
let { contentChildren = [], cachedEntries = [], beginDirty
|
|
30980
|
+
let { contentChildren = [], cachedEntries = [], beginDirty } = _ref, properties = _objectWithoutProperties(_ref, _excluded$2);
|
|
29434
30981
|
super("w:sdt");
|
|
30982
|
+
_defineProperty(
|
|
30983
|
+
this,
|
|
30984
|
+
/** What it is filled in with from the headings, when it isn't given its content */
|
|
30985
|
+
"fromHeadings",
|
|
30986
|
+
void 0
|
|
30987
|
+
);
|
|
29435
30988
|
this.root.push(new StructuredDocumentTagProperties(alias));
|
|
29436
30989
|
const content = new StructuredDocumentTagContent();
|
|
29437
30990
|
const beginParagraphMandatoryChildren = [new Run({ children: [
|
|
29438
|
-
|
|
30991
|
+
beginOf(beginDirty),
|
|
29439
30992
|
new FieldInstruction(properties),
|
|
29440
30993
|
createSeparate()
|
|
29441
30994
|
] })];
|
|
@@ -29462,9 +31015,27 @@ MAX: 9026 };
|
|
|
29462
31015
|
for (const child of contentChildren) content.addChildElement(child);
|
|
29463
31016
|
const endParagraph = new Paragraph({ children: endParagraphMandatoryChildren });
|
|
29464
31017
|
content.addChildElement(endParagraph);
|
|
31018
|
+
if (contentChildren.length === 0) this.fromHeadings = {
|
|
31019
|
+
properties,
|
|
31020
|
+
beginDirty
|
|
31021
|
+
};
|
|
29465
31022
|
}
|
|
29466
31023
|
this.root.push(content);
|
|
29467
31024
|
}
|
|
31025
|
+
/**
|
|
31026
|
+
* Written empty, and filled in from the headings once the body it is in is written, unless it was given its content.
|
|
31027
|
+
* The page numbers are aligned to the right of the text in its section.
|
|
31028
|
+
*/
|
|
31029
|
+
prepForXml(context) {
|
|
31030
|
+
const xml = super.prepForXml(context);
|
|
31031
|
+
recordTableOfContents(xml, this.fromHeadings && _objectSpread2(_objectSpread2({}, this.fromHeadings), {}, { textWidth: this.textWidthIn(context) }));
|
|
31032
|
+
return xml;
|
|
31033
|
+
}
|
|
31034
|
+
/** The width of the text in the section it is in */
|
|
31035
|
+
textWidthIn(context) {
|
|
31036
|
+
var _context$file$Documen, _context$file;
|
|
31037
|
+
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;
|
|
31038
|
+
}
|
|
29468
31039
|
getTabStopsForLevel(level, pageWidth = 9025) {
|
|
29469
31040
|
return [{
|
|
29470
31041
|
type: "clear",
|
|
@@ -33878,11 +35449,11 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
33878
35449
|
*
|
|
33879
35450
|
* @module
|
|
33880
35451
|
*/
|
|
33881
|
-
var formatter$
|
|
35452
|
+
var formatter$3 = new Formatter();
|
|
33882
35453
|
/**
|
|
33883
35454
|
* Formats a part's XML, with the relationships that anything in it that refers to other parts adds to.
|
|
33884
35455
|
*/
|
|
33885
|
-
var xmlifyPart = (file, content, prettify, relationships, standalone = true) => (0, import_xml.default)(formatter$
|
|
35456
|
+
var xmlifyPart = (file, content, prettify, relationships, standalone = true) => (0, import_xml.default)(formatter$3.format(content, {
|
|
33886
35457
|
viewWrapper: {
|
|
33887
35458
|
View: content,
|
|
33888
35459
|
Relationships: relationships
|
|
@@ -33999,11 +35570,10 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
33999
35570
|
zip.file(`word/media/${data.fileName}`, data.data);
|
|
34000
35571
|
zip.file(`word/media/${data.fallback.fileName}`, data.fallback.data);
|
|
34001
35572
|
}
|
|
34002
|
-
for (const [i, { data: buffer, fontKey }] of file.FontTable.
|
|
35573
|
+
for (const [i, { data: buffer, fontKey }] of file.FontTable.files.entries()) zip.file(`word/fonts/font${i + 1}.odttf`, obfuscate(buffer, fontKey));
|
|
34003
35574
|
return zip;
|
|
34004
35575
|
}
|
|
34005
35576
|
xmlifyFile(file, prettify) {
|
|
34006
|
-
const documentRelationshipCount = file.Document.Relationships.RelationshipCount + 1;
|
|
34007
35577
|
const documentXmlData = (0, import_xml.default)(this.formatter.format(file.Document.View, {
|
|
34008
35578
|
viewWrapper: file.Document,
|
|
34009
35579
|
file,
|
|
@@ -34015,7 +35585,6 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34015
35585
|
encoding: "UTF-8"
|
|
34016
35586
|
}
|
|
34017
35587
|
});
|
|
34018
|
-
const commentRelationshipCount = file.Comments.Relationships.RelationshipCount + 1;
|
|
34019
35588
|
const commentXmlData = (0, import_xml.default)(this.formatter.format(file.Comments, {
|
|
34020
35589
|
viewWrapper: {
|
|
34021
35590
|
View: file.Comments,
|
|
@@ -34030,7 +35599,6 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34030
35599
|
encoding: "UTF-8"
|
|
34031
35600
|
}
|
|
34032
35601
|
});
|
|
34033
|
-
const footnoteRelationshipCount = file.FootNotes.Relationships.RelationshipCount + 1;
|
|
34034
35602
|
const footnoteXmlData = (0, import_xml.default)(this.formatter.format(file.FootNotes.View, {
|
|
34035
35603
|
viewWrapper: file.FootNotes,
|
|
34036
35604
|
file,
|
|
@@ -34042,17 +35610,31 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34042
35610
|
encoding: "UTF-8"
|
|
34043
35611
|
}
|
|
34044
35612
|
});
|
|
35613
|
+
const endnoteXmlData = (0, import_xml.default)(this.formatter.format(file.Endnotes.View, {
|
|
35614
|
+
viewWrapper: file.Endnotes,
|
|
35615
|
+
file,
|
|
35616
|
+
stack: []
|
|
35617
|
+
}), {
|
|
35618
|
+
indent: prettify,
|
|
35619
|
+
declaration: { encoding: "UTF-8" }
|
|
35620
|
+
});
|
|
35621
|
+
const documentRelationshipCount = file.Document.Relationships.RelationshipCount + 1;
|
|
35622
|
+
const commentRelationshipCount = file.Comments.Relationships.RelationshipCount + 1;
|
|
35623
|
+
const footnoteRelationshipCount = file.FootNotes.Relationships.RelationshipCount + 1;
|
|
35624
|
+
const endnoteRelationshipCount = file.Endnotes.Relationships.RelationshipCount + 1;
|
|
34045
35625
|
const documentMediaDatas = this.imageReplacer.getMediaData(documentXmlData, file.Media);
|
|
34046
35626
|
const commentMediaDatas = this.imageReplacer.getMediaData(commentXmlData, file.Media);
|
|
34047
35627
|
const footnoteMediaDatas = this.imageReplacer.getMediaData(footnoteXmlData, file.Media);
|
|
35628
|
+
const endnoteMediaDatas = this.imageReplacer.getMediaData(endnoteXmlData, file.Media);
|
|
34048
35629
|
return _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({
|
|
34049
35630
|
Relationships: {
|
|
34050
35631
|
data: (() => {
|
|
35632
|
+
const relationships = Relationships.copy(file.Document.Relationships);
|
|
34051
35633
|
documentMediaDatas.forEach((mediaData, i) => {
|
|
34052
|
-
|
|
35634
|
+
relationships.addRelationship(documentRelationshipCount + i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`);
|
|
34053
35635
|
});
|
|
34054
|
-
|
|
34055
|
-
return (0, import_xml.default)(this.formatter.format(
|
|
35636
|
+
relationships.addRelationship(relationships.RelationshipCount + 1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable", "fontTable.xml");
|
|
35637
|
+
return (0, import_xml.default)(this.formatter.format(relationships, {
|
|
34056
35638
|
viewWrapper: file.Document,
|
|
34057
35639
|
file,
|
|
34058
35640
|
stack: []
|
|
@@ -34101,20 +35683,6 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34101
35683
|
}),
|
|
34102
35684
|
path: "docProps/core.xml"
|
|
34103
35685
|
},
|
|
34104
|
-
Numbering: {
|
|
34105
|
-
data: (0, import_xml.default)(this.formatter.format(file.Numbering, {
|
|
34106
|
-
viewWrapper: file.Document,
|
|
34107
|
-
file,
|
|
34108
|
-
stack: []
|
|
34109
|
-
}), {
|
|
34110
|
-
indent: prettify,
|
|
34111
|
-
declaration: {
|
|
34112
|
-
standalone: "yes",
|
|
34113
|
-
encoding: "UTF-8"
|
|
34114
|
-
}
|
|
34115
|
-
}),
|
|
34116
|
-
path: "word/numbering.xml"
|
|
34117
|
-
},
|
|
34118
35686
|
FileRelationships: {
|
|
34119
35687
|
data: (0, import_xml.default)(this.formatter.format(file.FileRelationships, {
|
|
34120
35688
|
viewWrapper: file.Document,
|
|
@@ -34135,11 +35703,13 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34135
35703
|
indent: prettify,
|
|
34136
35704
|
declaration: { encoding: "UTF-8" }
|
|
34137
35705
|
});
|
|
34138
|
-
this.imageReplacer.getMediaData(xmlData, file.Media)
|
|
34139
|
-
|
|
35706
|
+
const mediaDatas = this.imageReplacer.getMediaData(xmlData, file.Media);
|
|
35707
|
+
const relationships = Relationships.copy(headerWrapper.Relationships);
|
|
35708
|
+
mediaDatas.forEach((mediaData, i) => {
|
|
35709
|
+
relationships.addRelationship(i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`);
|
|
34140
35710
|
});
|
|
34141
35711
|
return {
|
|
34142
|
-
data: (0, import_xml.default)(this.formatter.format(
|
|
35712
|
+
data: (0, import_xml.default)(this.formatter.format(relationships, {
|
|
34143
35713
|
viewWrapper: headerWrapper,
|
|
34144
35714
|
file,
|
|
34145
35715
|
stack: []
|
|
@@ -34159,11 +35729,13 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34159
35729
|
indent: prettify,
|
|
34160
35730
|
declaration: { encoding: "UTF-8" }
|
|
34161
35731
|
});
|
|
34162
|
-
this.imageReplacer.getMediaData(xmlData, file.Media)
|
|
34163
|
-
|
|
35732
|
+
const mediaDatas = this.imageReplacer.getMediaData(xmlData, file.Media);
|
|
35733
|
+
const relationships = Relationships.copy(footerWrapper.Relationships);
|
|
35734
|
+
mediaDatas.forEach((mediaData, i) => {
|
|
35735
|
+
relationships.addRelationship(i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`);
|
|
34164
35736
|
});
|
|
34165
35737
|
return {
|
|
34166
|
-
data: (0, import_xml.default)(this.formatter.format(
|
|
35738
|
+
data: (0, import_xml.default)(this.formatter.format(relationships, {
|
|
34167
35739
|
viewWrapper: footerWrapper,
|
|
34168
35740
|
file,
|
|
34169
35741
|
stack: []
|
|
@@ -34243,10 +35815,11 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34243
35815
|
},
|
|
34244
35816
|
FootNotesRelationships: {
|
|
34245
35817
|
data: (() => {
|
|
35818
|
+
const relationships = Relationships.copy(file.FootNotes.Relationships);
|
|
34246
35819
|
footnoteMediaDatas.forEach((mediaData, i) => {
|
|
34247
|
-
|
|
35820
|
+
relationships.addRelationship(footnoteRelationshipCount + i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`);
|
|
34248
35821
|
});
|
|
34249
|
-
return (0, import_xml.default)(this.formatter.format(
|
|
35822
|
+
return (0, import_xml.default)(this.formatter.format(relationships, {
|
|
34250
35823
|
viewWrapper: file.FootNotes,
|
|
34251
35824
|
file,
|
|
34252
35825
|
stack: []
|
|
@@ -34258,25 +35831,27 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34258
35831
|
path: "word/_rels/footnotes.xml.rels"
|
|
34259
35832
|
},
|
|
34260
35833
|
Endnotes: {
|
|
34261
|
-
data: (
|
|
34262
|
-
|
|
34263
|
-
file
|
|
34264
|
-
|
|
34265
|
-
}), {
|
|
34266
|
-
indent: prettify,
|
|
34267
|
-
declaration: { encoding: "UTF-8" }
|
|
34268
|
-
}),
|
|
35834
|
+
data: (() => {
|
|
35835
|
+
const xmlData = this.imageReplacer.replace(endnoteXmlData, endnoteMediaDatas, endnoteRelationshipCount);
|
|
35836
|
+
return this.numberingReplacer.replace(xmlData, file.Numbering.ConcreteNumbering);
|
|
35837
|
+
})(),
|
|
34269
35838
|
path: "word/endnotes.xml"
|
|
34270
35839
|
},
|
|
34271
35840
|
EndnotesRelationships: {
|
|
34272
|
-
data: (
|
|
34273
|
-
|
|
34274
|
-
|
|
34275
|
-
|
|
34276
|
-
|
|
34277
|
-
|
|
34278
|
-
|
|
34279
|
-
|
|
35841
|
+
data: (() => {
|
|
35842
|
+
const relationships = Relationships.copy(file.Endnotes.Relationships);
|
|
35843
|
+
endnoteMediaDatas.forEach((mediaData, i) => {
|
|
35844
|
+
relationships.addRelationship(endnoteRelationshipCount + i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`);
|
|
35845
|
+
});
|
|
35846
|
+
return (0, import_xml.default)(this.formatter.format(relationships, {
|
|
35847
|
+
viewWrapper: file.Endnotes,
|
|
35848
|
+
file,
|
|
35849
|
+
stack: []
|
|
35850
|
+
}), {
|
|
35851
|
+
indent: prettify,
|
|
35852
|
+
declaration: { encoding: "UTF-8" }
|
|
35853
|
+
});
|
|
35854
|
+
})(),
|
|
34280
35855
|
path: "word/_rels/endnotes.xml.rels"
|
|
34281
35856
|
},
|
|
34282
35857
|
Settings: {
|
|
@@ -34303,10 +35878,11 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34303
35878
|
},
|
|
34304
35879
|
CommentsRelationships: {
|
|
34305
35880
|
data: (() => {
|
|
35881
|
+
const relationships = Relationships.copy(file.Comments.Relationships);
|
|
34306
35882
|
commentMediaDatas.forEach((mediaData, i) => {
|
|
34307
|
-
|
|
35883
|
+
relationships.addRelationship(commentRelationshipCount + i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`);
|
|
34308
35884
|
});
|
|
34309
|
-
return (0, import_xml.default)(this.formatter.format(
|
|
35885
|
+
return (0, import_xml.default)(this.formatter.format(relationships, {
|
|
34310
35886
|
viewWrapper: {
|
|
34311
35887
|
View: file.Comments,
|
|
34312
35888
|
Relationships: file.Comments.Relationships
|
|
@@ -34393,6 +35969,20 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34393
35969
|
path: "word/theme/theme1.xml"
|
|
34394
35970
|
},
|
|
34395
35971
|
PackageParts: xmlifyPackageParts(file, prettify),
|
|
35972
|
+
Numbering: {
|
|
35973
|
+
data: (0, import_xml.default)(this.formatter.format(file.Numbering, {
|
|
35974
|
+
viewWrapper: file.Document,
|
|
35975
|
+
file,
|
|
35976
|
+
stack: []
|
|
35977
|
+
}), {
|
|
35978
|
+
indent: prettify,
|
|
35979
|
+
declaration: {
|
|
35980
|
+
standalone: "yes",
|
|
35981
|
+
encoding: "UTF-8"
|
|
35982
|
+
}
|
|
35983
|
+
}),
|
|
35984
|
+
path: "word/numbering.xml"
|
|
35985
|
+
},
|
|
34396
35986
|
ContentTypes: {
|
|
34397
35987
|
data: (0, import_xml.default)(this.formatter.format(file.ContentTypes, {
|
|
34398
35988
|
viewWrapper: file.Document,
|
|
@@ -34408,7 +35998,7 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34408
35998
|
}
|
|
34409
35999
|
};
|
|
34410
36000
|
//#endregion
|
|
34411
|
-
//#region \0@oxc-project+runtime@0.
|
|
36001
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/asyncToGenerator.js
|
|
34412
36002
|
function asyncGeneratorStep(n, t, e, r, o, a, c) {
|
|
34413
36003
|
try {
|
|
34414
36004
|
var i = n[a](c), u = i.value;
|
|
@@ -34578,13 +36168,62 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34578
36168
|
};
|
|
34579
36169
|
_defineProperty(Packer, "compiler", new Compiler());
|
|
34580
36170
|
//#endregion
|
|
36171
|
+
//#region src/patcher/bookmark-ids.ts
|
|
36172
|
+
var bookmarkIdOf = (element) => {
|
|
36173
|
+
var _element$attributes;
|
|
36174
|
+
if (element.name !== "w:bookmarkStart" && element.name !== "w:bookmarkEnd") return;
|
|
36175
|
+
const id = Number((_element$attributes = element.attributes) === null || _element$attributes === void 0 ? void 0 : _element$attributes["w:id"]);
|
|
36176
|
+
return Number.isInteger(id) ? id : void 0;
|
|
36177
|
+
};
|
|
36178
|
+
/**
|
|
36179
|
+
* Finds the id of every bookmark in an element, at any depth.
|
|
36180
|
+
*
|
|
36181
|
+
* @param element - The element to search, such as a part's root
|
|
36182
|
+
* @returns The ids, once for each bookmarkStart and bookmarkEnd
|
|
36183
|
+
*/
|
|
36184
|
+
var findBookmarkIds = (element) => {
|
|
36185
|
+
var _element$elements;
|
|
36186
|
+
const id = bookmarkIdOf(element);
|
|
36187
|
+
return [...id === void 0 ? [] : [id], ...((_element$elements = element.elements) !== null && _element$elements !== void 0 ? _element$elements : []).flatMap(findBookmarkIds)];
|
|
36188
|
+
};
|
|
36189
|
+
/**
|
|
36190
|
+
* Creates a function that renumbers the bookmarks in content being inserted, so none takes an id the document
|
|
36191
|
+
* already uses. Bookmark ids must be unique within a document, but a bookmark's id is chosen when it is created,
|
|
36192
|
+
* without knowing which ids the template has.
|
|
36193
|
+
*
|
|
36194
|
+
* A bookmark keeps its id if nothing in the document uses it yet, and otherwise gets the next unused one. An id is
|
|
36195
|
+
* renumbered the same way each time, so a bookmark's start and end still share one, even in separate patches.
|
|
36196
|
+
*
|
|
36197
|
+
* @param idsInDocument - The ids of the bookmarks already in the document
|
|
36198
|
+
* @returns A function that returns the elements with their bookmarks renumbered
|
|
36199
|
+
*/
|
|
36200
|
+
var renumberBookmarksAvoiding = (idsInDocument) => {
|
|
36201
|
+
const usedIds = new Set(idsInDocument);
|
|
36202
|
+
const newIds = /* @__PURE__ */ new Map();
|
|
36203
|
+
let highestId = idsInDocument.reduce((highest, id) => Math.max(highest, id), 0);
|
|
36204
|
+
const newIdFor = (id) => {
|
|
36205
|
+
const knownId = newIds.get(id);
|
|
36206
|
+
if (knownId !== void 0) return knownId;
|
|
36207
|
+
const newId = usedIds.has(id) ? highestId + 1 : id;
|
|
36208
|
+
highestId = Math.max(highestId, newId);
|
|
36209
|
+
usedIds.add(newId);
|
|
36210
|
+
newIds.set(id, newId);
|
|
36211
|
+
return newId;
|
|
36212
|
+
};
|
|
36213
|
+
const renumber = (element) => {
|
|
36214
|
+
const id = bookmarkIdOf(element);
|
|
36215
|
+
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) });
|
|
36216
|
+
};
|
|
36217
|
+
return (elements) => elements.map(renumber);
|
|
36218
|
+
};
|
|
36219
|
+
//#endregion
|
|
34581
36220
|
//#region src/patcher/util.ts
|
|
34582
36221
|
/**
|
|
34583
36222
|
* Utility functions for XML manipulation in document patching.
|
|
34584
36223
|
*
|
|
34585
36224
|
* @module
|
|
34586
36225
|
*/
|
|
34587
|
-
var formatter$
|
|
36226
|
+
var formatter$2 = new Formatter();
|
|
34588
36227
|
/**
|
|
34589
36228
|
* Converts XML string to JSON element structure.
|
|
34590
36229
|
*
|
|
@@ -34624,7 +36263,7 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34624
36263
|
*/
|
|
34625
36264
|
var createTextElementContents = (text) => {
|
|
34626
36265
|
var _textJson$elements$0$;
|
|
34627
|
-
return (_textJson$elements$0$ = toJson((0, import_xml.default)(formatter$
|
|
36266
|
+
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$ : [];
|
|
34628
36267
|
};
|
|
34629
36268
|
/**
|
|
34630
36269
|
* Adds xml:space="preserve" attribute to an element.
|
|
@@ -34759,6 +36398,11 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
34759
36398
|
/** Replace content within paragraphs (inline replacement) */
|
|
34760
36399
|
PARAGRAPH: "paragraph",
|
|
34761
36400
|
/**
|
|
36401
|
+
* Repeat the rows of a table that hold the placeholder's fields, such as `{{items.name}}`, once for each row of
|
|
36402
|
+
* data. See {@link TableRowsPatch}
|
|
36403
|
+
*/
|
|
36404
|
+
TABLE_ROWS: "tableRows",
|
|
36405
|
+
/**
|
|
34762
36406
|
* Change a drawing whose alt text holds the placeholder, and the parts it refers to, such as the data of a chart made
|
|
34763
36407
|
* in Word. See {@link DrawingPatch}
|
|
34764
36408
|
*/
|
|
@@ -35072,6 +36716,291 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35072
36716
|
for (const { drawing, patch } of found) patch.patch(drawing, createTemplatePackage(parts, binaryParts, file, createContext(drawing.part.path)));
|
|
35073
36717
|
};
|
|
35074
36718
|
//#endregion
|
|
36719
|
+
//#region src/patcher/notes.ts
|
|
36720
|
+
/**
|
|
36721
|
+
* Footnotes and endnotes for content inserted into an existing document.
|
|
36722
|
+
*
|
|
36723
|
+
* @module
|
|
36724
|
+
*/
|
|
36725
|
+
var formatter$1 = new Formatter();
|
|
36726
|
+
var DOCUMENT_PATH = "word/document.xml";
|
|
36727
|
+
var FOOTNOTES = {
|
|
36728
|
+
path: "word/footnotes.xml",
|
|
36729
|
+
rootName: "w:footnotes",
|
|
36730
|
+
noteName: "w:footnote",
|
|
36731
|
+
referenceName: "w:footnoteReference",
|
|
36732
|
+
contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml",
|
|
36733
|
+
relationshipType: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
|
|
36734
|
+
create: {
|
|
36735
|
+
part: () => new FootNotes(),
|
|
36736
|
+
mark: () => new FootnoteRefRun(),
|
|
36737
|
+
styles: () => [
|
|
36738
|
+
new FootnoteText({}),
|
|
36739
|
+
new FootnoteTextChar({}),
|
|
36740
|
+
new FootnoteReferenceStyle({})
|
|
36741
|
+
]
|
|
36742
|
+
}
|
|
36743
|
+
};
|
|
36744
|
+
var ENDNOTES = {
|
|
36745
|
+
path: "word/endnotes.xml",
|
|
36746
|
+
rootName: "w:endnotes",
|
|
36747
|
+
noteName: "w:endnote",
|
|
36748
|
+
referenceName: "w:endnoteReference",
|
|
36749
|
+
contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml",
|
|
36750
|
+
relationshipType: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes",
|
|
36751
|
+
create: {
|
|
36752
|
+
part: () => new Endnotes(),
|
|
36753
|
+
mark: () => new EndnoteRefRun(),
|
|
36754
|
+
styles: () => [
|
|
36755
|
+
new EndnoteText({}),
|
|
36756
|
+
new EndnoteTextChar({}),
|
|
36757
|
+
new EndnoteReferenceStyle({})
|
|
36758
|
+
]
|
|
36759
|
+
}
|
|
36760
|
+
};
|
|
36761
|
+
var formatElement = (component, context) => toJson((0, import_xml.default)(formatter$1.format(component, context))).elements[0];
|
|
36762
|
+
var findIds = (element, names) => {
|
|
36763
|
+
var _element$name, _element$attributes, _element$elements;
|
|
36764
|
+
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;
|
|
36765
|
+
return [...Number.isInteger(id) ? [id] : [], ...((_element$elements = element.elements) !== null && _element$elements !== void 0 ? _element$elements : []).flatMap((child) => findIds(child, names))];
|
|
36766
|
+
};
|
|
36767
|
+
var withMark = (paragraph, mark) => {
|
|
36768
|
+
var _paragraph$elements, _elements$;
|
|
36769
|
+
const elements = (_paragraph$elements = paragraph.elements) !== null && _paragraph$elements !== void 0 ? _paragraph$elements : [];
|
|
36770
|
+
const index = ((_elements$ = elements[0]) === null || _elements$ === void 0 ? void 0 : _elements$.name) === "w:pPr" ? 1 : 0;
|
|
36771
|
+
return _objectSpread2(_objectSpread2({}, paragraph), {}, { elements: [
|
|
36772
|
+
...elements.slice(0, index),
|
|
36773
|
+
mark,
|
|
36774
|
+
...elements.slice(index)
|
|
36775
|
+
] });
|
|
36776
|
+
};
|
|
36777
|
+
var patchNotesOfKind = (kind, notes, parts, { createContext, addContentTypeOverride, renumberBookmarks }) => {
|
|
36778
|
+
const givenNotes = new Map(Object.entries(notes).map(([id, note]) => [Number(id), note]));
|
|
36779
|
+
const noteOfId = /* @__PURE__ */ new Map();
|
|
36780
|
+
let highestId;
|
|
36781
|
+
const renumber = (element) => {
|
|
36782
|
+
var _element$attributes2, _highestId;
|
|
36783
|
+
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;
|
|
36784
|
+
if (note === void 0) return element.elements === void 0 ? element : _objectSpread2(_objectSpread2({}, element), {}, { elements: element.elements.map(renumber) });
|
|
36785
|
+
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;
|
|
36786
|
+
noteOfId.set(highestId, note);
|
|
36787
|
+
return _objectSpread2(_objectSpread2({}, element), {}, { attributes: _objectSpread2(_objectSpread2({}, element.attributes), {}, { "w:id": String(highestId) }) });
|
|
36788
|
+
};
|
|
36789
|
+
const findOrAddPart = () => {
|
|
36790
|
+
var _parts$get;
|
|
36791
|
+
const relationship = getFirstLevelElements((_parts$get = parts.get(relationshipsPathOf(DOCUMENT_PATH))) !== null && _parts$get !== void 0 ? _parts$get : {}, "Relationships").find((element) => {
|
|
36792
|
+
var _element$attributes3;
|
|
36793
|
+
return ((_element$attributes3 = element.attributes) === null || _element$attributes3 === void 0 ? void 0 : _element$attributes3.Type) === kind.relationshipType;
|
|
36794
|
+
});
|
|
36795
|
+
const path = relationship ? resolveTarget(DOCUMENT_PATH, String(relationship.attributes.Target)) : kind.path;
|
|
36796
|
+
if (!parts.has(path)) {
|
|
36797
|
+
parts.set(path, {
|
|
36798
|
+
declaration: { attributes: {
|
|
36799
|
+
version: "1.0",
|
|
36800
|
+
encoding: "UTF-8",
|
|
36801
|
+
standalone: "yes"
|
|
36802
|
+
} },
|
|
36803
|
+
elements: [formatElement(kind.create.part(), createContext(path))]
|
|
36804
|
+
});
|
|
36805
|
+
addContentTypeOverride(kind.contentType, `/${path}`);
|
|
36806
|
+
}
|
|
36807
|
+
if (!relationship) createContext(DOCUMENT_PATH).viewWrapper.Relationships.addRelationship(uniqueId(), kind.relationshipType, relativeTarget(DOCUMENT_PATH, path));
|
|
36808
|
+
return path;
|
|
36809
|
+
};
|
|
36810
|
+
const write = () => {
|
|
36811
|
+
if (noteOfId.size === 0) return;
|
|
36812
|
+
const path = findOrAddPart();
|
|
36813
|
+
const context = createContext(path);
|
|
36814
|
+
const contentOfNote = new Map([...new Set(noteOfId.values())].map((note) => {
|
|
36815
|
+
const mark = formatElement(kind.create.mark(), context);
|
|
36816
|
+
return [note, renumberBookmarks(note.children.map((paragraph) => formatElement(paragraph, context)).map((paragraph, index) => index === 0 ? withMark(paragraph, mark) : paragraph))];
|
|
36817
|
+
}));
|
|
36818
|
+
getFirstLevelElements(parts.get(path), kind.rootName).push(...[...noteOfId].map(([id, note]) => ({
|
|
36819
|
+
type: "element",
|
|
36820
|
+
name: kind.noteName,
|
|
36821
|
+
attributes: { "w:id": String(id) },
|
|
36822
|
+
elements: [...contentOfNote.get(note)]
|
|
36823
|
+
})));
|
|
36824
|
+
const stylesPart = parts.get("word/styles.xml");
|
|
36825
|
+
if (stylesPart) {
|
|
36826
|
+
const styles = getFirstLevelElements(stylesPart, "w:styles");
|
|
36827
|
+
const styleIds = new Set(styles.map((style) => {
|
|
36828
|
+
var _style$attributes;
|
|
36829
|
+
return (_style$attributes = style.attributes) === null || _style$attributes === void 0 ? void 0 : _style$attributes["w:styleId"];
|
|
36830
|
+
}));
|
|
36831
|
+
styles.push(...kind.create.styles().map((style) => formatElement(style, context)).filter((style) => {
|
|
36832
|
+
var _style$attributes2;
|
|
36833
|
+
return !styleIds.has((_style$attributes2 = style.attributes) === null || _style$attributes2 === void 0 ? void 0 : _style$attributes2["w:styleId"]);
|
|
36834
|
+
}));
|
|
36835
|
+
}
|
|
36836
|
+
};
|
|
36837
|
+
return {
|
|
36838
|
+
renumber: (elements) => elements.map(renumber),
|
|
36839
|
+
write
|
|
36840
|
+
};
|
|
36841
|
+
};
|
|
36842
|
+
/**
|
|
36843
|
+
* Creates the writer of the footnotes and endnotes that patches refer to.
|
|
36844
|
+
*
|
|
36845
|
+
* A patch refers to a note with a reference run, such as `new FootnoteReferenceRun(1)`, whose id is the note's in
|
|
36846
|
+
* `footnotes`. Only references to the given notes are renumbered, and only the notes that are referred to are written.
|
|
36847
|
+
*
|
|
36848
|
+
* @param notes - The footnotes and endnotes, by the id the patches' reference runs are given
|
|
36849
|
+
* @param parts - The document's XML parts, parsed, by their paths, which the notes are written to
|
|
36850
|
+
* @param helpers - The patcher's helpers for what the notes refer to
|
|
36851
|
+
*/
|
|
36852
|
+
var patchNotes = ({ footnotes = {}, endnotes = {} }, parts, helpers) => {
|
|
36853
|
+
const patchers = [patchNotesOfKind(FOOTNOTES, footnotes, parts, helpers), patchNotesOfKind(ENDNOTES, endnotes, parts, helpers)];
|
|
36854
|
+
return {
|
|
36855
|
+
renumber: (elements) => patchers.reduce((renumbered, patcher) => patcher.renumber(renumbered), elements),
|
|
36856
|
+
write: () => {
|
|
36857
|
+
for (const patcher of patchers) patcher.write();
|
|
36858
|
+
}
|
|
36859
|
+
};
|
|
36860
|
+
};
|
|
36861
|
+
//#endregion
|
|
36862
|
+
//#region src/patcher/page-numbers.ts
|
|
36863
|
+
/**
|
|
36864
|
+
* Page numbers written into a template's fields once `patchDocument` has patched it, from an estimate of its pages, as
|
|
36865
|
+
* a document's are when it is written with `pageNumbers`.
|
|
36866
|
+
*
|
|
36867
|
+
* @module
|
|
36868
|
+
*/
|
|
36869
|
+
/** The elements of a template, as xml-js parses them */
|
|
36870
|
+
var PARSED = {
|
|
36871
|
+
nameOf: (element) => element.type === "element" ? element.name : void 0,
|
|
36872
|
+
contentOf: (element) => element.elements,
|
|
36873
|
+
attributeOf: (element, attribute) => {
|
|
36874
|
+
var _element$attributes;
|
|
36875
|
+
return (_element$attributes = element.attributes) === null || _element$attributes === void 0 ? void 0 : _element$attributes[attribute];
|
|
36876
|
+
},
|
|
36877
|
+
textOf: (element) => {
|
|
36878
|
+
var _element$elements;
|
|
36879
|
+
return ((_element$elements = element.elements) !== null && _element$elements !== void 0 ? _element$elements : []).filter(({ type }) => type === "text").map(({ text }) => String(text)).join("");
|
|
36880
|
+
},
|
|
36881
|
+
textElement: (text) => ({
|
|
36882
|
+
type: "element",
|
|
36883
|
+
name: "w:t",
|
|
36884
|
+
attributes: { "xml:space": "preserve" },
|
|
36885
|
+
elements: [{
|
|
36886
|
+
type: "text",
|
|
36887
|
+
text
|
|
36888
|
+
}]
|
|
36889
|
+
}),
|
|
36890
|
+
writeClean: (begin, instruction) => {
|
|
36891
|
+
var _begin$attributes;
|
|
36892
|
+
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"));
|
|
36893
|
+
},
|
|
36894
|
+
setSimpleFieldResult: (element, text) => {
|
|
36895
|
+
element.elements = [{
|
|
36896
|
+
type: "element",
|
|
36897
|
+
name: "w:r",
|
|
36898
|
+
elements: [PARSED.textElement(text)]
|
|
36899
|
+
}];
|
|
36900
|
+
}
|
|
36901
|
+
};
|
|
36902
|
+
var DOCUMENT = "word/document.xml";
|
|
36903
|
+
var IMPORT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk";
|
|
36904
|
+
var ZIP = [
|
|
36905
|
+
80,
|
|
36906
|
+
75,
|
|
36907
|
+
3,
|
|
36908
|
+
4
|
|
36909
|
+
];
|
|
36910
|
+
/** A package's parts, from a zip file: its XML parts parsed, as patchDocument parses a template's, and the rest as bytes */
|
|
36911
|
+
var readPackage = function() {
|
|
36912
|
+
var _ref = _asyncToGenerator(function* (data) {
|
|
36913
|
+
if (!ZIP.every((byte, index) => data[index] === byte)) return;
|
|
36914
|
+
try {
|
|
36915
|
+
const zip = yield import_jszip_min.default.loadAsync(data);
|
|
36916
|
+
const parts = /* @__PURE__ */ new Map();
|
|
36917
|
+
const binaryParts = /* @__PURE__ */ new Map();
|
|
36918
|
+
for (const [path, file] of Object.entries(zip.files)) {
|
|
36919
|
+
if (file.dir) continue;
|
|
36920
|
+
if (/\.(xml|rels)$/.test(path)) parts.set(path, toJson(yield file.async("text")));
|
|
36921
|
+
else binaryParts.set(path, yield file.async("uint8array"));
|
|
36922
|
+
}
|
|
36923
|
+
const importedDocuments = yield readImportedDocuments(parts, binaryParts);
|
|
36924
|
+
return _objectSpread2({
|
|
36925
|
+
parts,
|
|
36926
|
+
binaryParts
|
|
36927
|
+
}, importedDocuments.size > 0 ? { importedDocuments } : {});
|
|
36928
|
+
} catch (_unused) {
|
|
36929
|
+
return;
|
|
36930
|
+
}
|
|
36931
|
+
});
|
|
36932
|
+
return function readPackage(_x) {
|
|
36933
|
+
return _ref.apply(this, arguments);
|
|
36934
|
+
};
|
|
36935
|
+
}();
|
|
36936
|
+
/**
|
|
36937
|
+
* Each .docx the parts of a package import (`w:altChunk`), by its path: the parts the relationships of each part refer to
|
|
36938
|
+
* as imported, which are zip files that can be read. Those in other formats, such as HTML, are left to the layout.
|
|
36939
|
+
*/
|
|
36940
|
+
var readImportedDocuments = function() {
|
|
36941
|
+
var _ref2 = _asyncToGenerator(function* (parts, binaryParts) {
|
|
36942
|
+
const imported = /* @__PURE__ */ new Map();
|
|
36943
|
+
for (const [path, relationships] of parts) {
|
|
36944
|
+
var _rootOf$elements, _rootOf;
|
|
36945
|
+
if (!path.endsWith(".rels")) continue;
|
|
36946
|
+
for (const { attributes = {} } of (_rootOf$elements = (_rootOf = rootOf(relationships)) === null || _rootOf === void 0 ? void 0 : _rootOf.elements) !== null && _rootOf$elements !== void 0 ? _rootOf$elements : []) {
|
|
36947
|
+
const target = resolveTarget(sourceOfRelationships(path), String(attributes.Target));
|
|
36948
|
+
const data = binaryParts.get(target);
|
|
36949
|
+
const read = attributes.Type === IMPORT && attributes.TargetMode !== "External" && data ? yield readPackage(data) : void 0;
|
|
36950
|
+
if (read) imported.set(target, read);
|
|
36951
|
+
}
|
|
36952
|
+
}
|
|
36953
|
+
return imported;
|
|
36954
|
+
});
|
|
36955
|
+
return function readImportedDocuments(_x2, _x3) {
|
|
36956
|
+
return _ref2.apply(this, arguments);
|
|
36957
|
+
};
|
|
36958
|
+
}();
|
|
36959
|
+
/** The root element of a part, such as `w:document` */
|
|
36960
|
+
var rootOf = (part) => {
|
|
36961
|
+
var _part$elements;
|
|
36962
|
+
return part === null || part === void 0 || (_part$elements = part.elements) === null || _part$elements === void 0 ? void 0 : _part$elements.find(({ type }) => type === "element");
|
|
36963
|
+
};
|
|
36964
|
+
/**
|
|
36965
|
+
* Writes the page numbers the estimator works out for a patched template into the fields of its body, headers and
|
|
36966
|
+
* footers that show them: its PAGEREF fields, in its tables of contents and elsewhere, and its NUMPAGES and SECTIONPAGES
|
|
36967
|
+
* fields. The results a field was written with are those of the template before it was patched, so a field whose number
|
|
36968
|
+
* the estimator doesn't work out is left blank, as it is in a document written with `pageNumbers`. Page references and
|
|
36969
|
+
* tables of contents are written clean, as they are in a document written with `pageNumbers`, so Word shows their numbers
|
|
36970
|
+
* as they are and doesn't ask to update the fields.
|
|
36971
|
+
*
|
|
36972
|
+
* The documents it imports (`w:altChunk`) as .docx files are unzipped for the estimator to read, as Word turns them into
|
|
36973
|
+
* paragraphs and tables of the template's own when it opens it.
|
|
36974
|
+
*
|
|
36975
|
+
* @param parts - The template's XML parts, parsed, by their paths, which are changed in place
|
|
36976
|
+
* @param binaryParts - Its other parts, by their paths, for the estimator to read the fonts it embeds and the documents
|
|
36977
|
+
* it imports
|
|
36978
|
+
*/
|
|
36979
|
+
var fillTemplatePageNumbers = function() {
|
|
36980
|
+
var _ref3 = _asyncToGenerator(function* (parts, estimator, binaryParts = /* @__PURE__ */ new Map()) {
|
|
36981
|
+
var _rootOf$elements2, _rootOf2;
|
|
36982
|
+
const document = rootOf(parts.get(DOCUMENT));
|
|
36983
|
+
if (!document) return;
|
|
36984
|
+
const importedDocuments = yield readImportedDocuments(parts, binaryParts);
|
|
36985
|
+
const estimate = estimator(_objectSpread2({
|
|
36986
|
+
parts,
|
|
36987
|
+
binaryParts
|
|
36988
|
+
}, importedDocuments.size > 0 ? { importedDocuments } : {}));
|
|
36989
|
+
const partPageCounts = fillBodyFields(PARSED, document, estimate, { blank: true });
|
|
36990
|
+
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 : [];
|
|
36991
|
+
for (const { attributes = {} } of relationships) {
|
|
36992
|
+
const part = /\/(header|footer)$/.test(String(attributes.Type)) ? rootOf(parts.get(resolveTarget(DOCUMENT, String(attributes.Target)))) : void 0;
|
|
36993
|
+
if (part) fillPartFields(PARSED, part, estimate, {
|
|
36994
|
+
blank: true,
|
|
36995
|
+
sectionPageCount: partPageCounts.get(String(attributes.Id))
|
|
36996
|
+
});
|
|
36997
|
+
}
|
|
36998
|
+
});
|
|
36999
|
+
return function fillTemplatePageNumbers(_x4, _x5) {
|
|
37000
|
+
return _ref3.apply(this, arguments);
|
|
37001
|
+
};
|
|
37002
|
+
}();
|
|
37003
|
+
//#endregion
|
|
35075
37004
|
//#region src/patcher/paragraph-split-inject.ts
|
|
35076
37005
|
var TokenNotFoundError = class extends Error {
|
|
35077
37006
|
constructor(token) {
|
|
@@ -35373,9 +37302,11 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35373
37302
|
* @param context - The document context for formatting
|
|
35374
37303
|
* @param keepOriginalStyles - Whether to preserve original text formatting
|
|
35375
37304
|
* @param recursive - Whether to replace every occurrence in a paragraph, rather than only the first
|
|
37305
|
+
* @param renumberIds - Renumbers the bookmarks and note references the patch inserts, so they don't take an id the
|
|
37306
|
+
* document uses
|
|
35376
37307
|
* @returns Result containing the modified element and whether a replacement occurred
|
|
35377
37308
|
*/
|
|
35378
|
-
var replacer = ({ json, patch, patchText, context, keepOriginalStyles = true, recursive = true }) => {
|
|
37309
|
+
var replacer = ({ json, patch, patchText, context, keepOriginalStyles = true, recursive = true, renumberIds = (elements) => elements }) => {
|
|
35379
37310
|
const renderedParagraphs = findLocationOfText(json, patchText);
|
|
35380
37311
|
if (renderedParagraphs.length === 0) return {
|
|
35381
37312
|
element: json,
|
|
@@ -35385,9 +37316,15 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35385
37316
|
const paragraphsToPatch = patch.type === PatchType.DOCUMENT ? withoutNestedParagraphs(paragraphsInPatchOrder) : paragraphsInPatchOrder;
|
|
35386
37317
|
for (const renderedParagraph of paragraphsToPatch) switch (patch.type) {
|
|
35387
37318
|
case PatchType.DOCUMENT: {
|
|
37319
|
+
var _children;
|
|
35388
37320
|
const parentElement = goToParentElementFromPath(json, renderedParagraph.pathToParagraph);
|
|
35389
37321
|
const elementIndex = getLastElementIndexFromPath(renderedParagraph.pathToParagraph);
|
|
35390
|
-
|
|
37322
|
+
const children = formatChildren(patch, context, renumberIds);
|
|
37323
|
+
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" ? [{
|
|
37324
|
+
type: "element",
|
|
37325
|
+
name: "w:p"
|
|
37326
|
+
}] : [];
|
|
37327
|
+
parentElement.elements.splice(elementIndex, 1, ...children, ...endParagraph);
|
|
35391
37328
|
break;
|
|
35392
37329
|
}
|
|
35393
37330
|
case PatchType.PARAGRAPH:
|
|
@@ -35401,7 +37338,7 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35401
37338
|
renderedParagraph: paragraph,
|
|
35402
37339
|
patchText,
|
|
35403
37340
|
fromIndex,
|
|
35404
|
-
children: formatChildren(patch, context),
|
|
37341
|
+
children: formatChildren(patch, context, renumberIds),
|
|
35405
37342
|
keepOriginalStyles
|
|
35406
37343
|
});
|
|
35407
37344
|
paragraph = renderParagraphNode({
|
|
@@ -35419,10 +37356,10 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35419
37356
|
didFindOccurrence: true
|
|
35420
37357
|
};
|
|
35421
37358
|
};
|
|
35422
|
-
var formatChildren = (patch, context) => patch.children.flatMap((c) => {
|
|
37359
|
+
var formatChildren = (patch, context, renumberIds) => renumberIds(patch.children.flatMap((c) => {
|
|
35423
37360
|
var _c$writtenAs;
|
|
35424
37361
|
return (_c$writtenAs = c.writtenAs) !== null && _c$writtenAs !== void 0 ? _c$writtenAs : c;
|
|
35425
|
-
}).map((c) => toJson((0, import_xml.default)(formatter.format(c, context)))).map((c) => c.elements[0]);
|
|
37362
|
+
}).map((c) => toJson((0, import_xml.default)(formatter.format(c, context)))).map((c) => c.elements[0]));
|
|
35426
37363
|
/**
|
|
35427
37364
|
* Replaces the first occurrence of the placeholder from `fromIndex` on, splitting the run it starts in.
|
|
35428
37365
|
*
|
|
@@ -35440,12 +37377,21 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35440
37377
|
const runElementToBeReplaced = paragraphElement.elements[index];
|
|
35441
37378
|
const { left, right } = splitRunElement(runElementToBeReplaced, SPLIT_TOKEN);
|
|
35442
37379
|
const runProperties = runElementToBeReplaced.elements.find((e) => e.type === "element" && e.name === "w:rPr");
|
|
35443
|
-
const newRunElements = keepOriginalStyles && runProperties ? children.map((e) =>
|
|
37380
|
+
const newRunElements = keepOriginalStyles && runProperties ? children.map((e) => withRunPropertiesOnRuns(e, runProperties)) : children;
|
|
35444
37381
|
const patchedRightElement = runProperties ? _objectSpread2(_objectSpread2({}, right), {}, { elements: [runProperties, ...right.elements] }) : right;
|
|
35445
37382
|
paragraphElement.elements.splice(index, 1, left, ...newRunElements, patchedRightElement);
|
|
35446
37383
|
return index + 1 + newRunElements.length;
|
|
35447
37384
|
};
|
|
35448
37385
|
/**
|
|
37386
|
+
* Gives the runs of inserted content the placeholder's run properties. Content such as a hyperlink can't take run
|
|
37387
|
+
* properties itself, so its runs take them, and its text is formatted as the text around it is. Runs inside a run, such
|
|
37388
|
+
* as in its text box, are that content's own, and are left alone.
|
|
37389
|
+
*/
|
|
37390
|
+
var withRunPropertiesOnRuns = (element, originalRunProperties) => {
|
|
37391
|
+
if (element.name === "w:r") return withRunProperties(element, originalRunProperties);
|
|
37392
|
+
return element.elements ? _objectSpread2(_objectSpread2({}, element), {}, { elements: element.elements.map((e) => withRunPropertiesOnRuns(e, originalRunProperties)) }) : element;
|
|
37393
|
+
};
|
|
37394
|
+
/**
|
|
35449
37395
|
* Gives a run the placeholder's run properties. A run can only have one w:rPr, so properties the run
|
|
35450
37396
|
* sets itself are kept, and the placeholder's fill in the rest.
|
|
35451
37397
|
*/
|
|
@@ -35537,6 +37483,118 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35537
37483
|
var goToParentElementFromPath = (json, path) => goToElementFromPath(json, path.slice(0, path.length - 1));
|
|
35538
37484
|
var getLastElementIndexFromPath = (path) => path[path.length - 1];
|
|
35539
37485
|
//#endregion
|
|
37486
|
+
//#region src/patcher/table-rows.ts
|
|
37487
|
+
var EMPTY = {
|
|
37488
|
+
type: PatchType.PARAGRAPH,
|
|
37489
|
+
children: []
|
|
37490
|
+
};
|
|
37491
|
+
/**
|
|
37492
|
+
* Repeats the rows of the tables in an element that hold the patch's fields, such as `{{items.name}}` for the key
|
|
37493
|
+
* "items", once for each of the patch's rows, and patches the fields in each copy with the row's patches.
|
|
37494
|
+
*
|
|
37495
|
+
* @param json - The element to patch, such as a part's root
|
|
37496
|
+
* @param key - The patch's key, such as "items"
|
|
37497
|
+
* @param patch - The rows of data
|
|
37498
|
+
* @param delimiters - The placeholders' delimiters
|
|
37499
|
+
* @param patchPlaceholder - Patches a field in a copy of the rows, as `patchDocument` patches a placeholder
|
|
37500
|
+
*/
|
|
37501
|
+
var patchTableRows = ({ json, key, patch, delimiters: { start, end }, patchPlaceholder }) => {
|
|
37502
|
+
const fieldStart = `${start}${key}.`;
|
|
37503
|
+
for (const rows of findRowsToRepeat(json, fieldStart)) {
|
|
37504
|
+
const fields = fieldsIn(rows.elements, fieldStart, end);
|
|
37505
|
+
const copies = patch.rows.flatMap((row, index) => {
|
|
37506
|
+
const copy = {
|
|
37507
|
+
type: "element",
|
|
37508
|
+
name: "w:tbl",
|
|
37509
|
+
elements: [...index === 0 ? rows.elements.map(copyOf) : withoutIds(rows.elements)]
|
|
37510
|
+
};
|
|
37511
|
+
const fieldPatches = new Map(Object.entries(row).flatMap(([field, p]) => p === void 0 ? [] : [[field, p]]));
|
|
37512
|
+
for (const [field, fieldPatch] of fieldPatches) patchPlaceholder(copy, `${key}.${field}`, fieldPatch);
|
|
37513
|
+
for (const field of fields.filter((f) => !fieldPatches.has(f))) patchPlaceholder(copy, `${key}.${field}`, EMPTY);
|
|
37514
|
+
return copy.elements;
|
|
37515
|
+
});
|
|
37516
|
+
rows.parent.elements.splice(rows.parent.elements.indexOf(rows.elements[0]), rows.elements.length, ...copies);
|
|
37517
|
+
if (rows.table && !hasRows(rows.table.element)) rows.table.parent.elements.splice(rows.table.parent.elements.indexOf(rows.table.element), 1);
|
|
37518
|
+
}
|
|
37519
|
+
};
|
|
37520
|
+
/**
|
|
37521
|
+
* The rows that hold a field, grouped into the rows next to each other in a table, which are repeated together.
|
|
37522
|
+
*/
|
|
37523
|
+
var findRowsToRepeat = (json, fieldStart) => {
|
|
37524
|
+
const found = findLocationOfText(json, fieldStart).flatMap((paragraph) => {
|
|
37525
|
+
const row = rowHolding(json, paragraph.pathToParagraph);
|
|
37526
|
+
return row ? [row] : [];
|
|
37527
|
+
});
|
|
37528
|
+
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);
|
|
37529
|
+
return [...new Set(rows.map((row) => row.parent))].flatMap((parent) => {
|
|
37530
|
+
const siblingRows = parent.elements.filter((e) => e.name === "w:tr");
|
|
37531
|
+
const positions = rows.filter((row) => row.parent === parent).map((row) => siblingRows.indexOf(row.row)).sort((a, b) => a - b);
|
|
37532
|
+
const { table } = rows.find((row) => row.parent === parent);
|
|
37533
|
+
return positions.reduce((all, position) => {
|
|
37534
|
+
const previous = all[all.length - 1];
|
|
37535
|
+
return (previous === null || previous === void 0 ? void 0 : previous[previous.length - 1]) === position - 1 ? [...all.slice(0, -1), [...previous, position]] : [...all, [position]];
|
|
37536
|
+
}, []).map((group) => {
|
|
37537
|
+
const first = parent.elements.indexOf(siblingRows[group[0]]);
|
|
37538
|
+
const last = parent.elements.indexOf(siblingRows[group[group.length - 1]]);
|
|
37539
|
+
return {
|
|
37540
|
+
parent,
|
|
37541
|
+
table,
|
|
37542
|
+
elements: parent.elements.slice(first, last + 1)
|
|
37543
|
+
};
|
|
37544
|
+
});
|
|
37545
|
+
});
|
|
37546
|
+
};
|
|
37547
|
+
/**
|
|
37548
|
+
* The row nearest to the paragraph at the end of the path that holds it, if it is in a table.
|
|
37549
|
+
*/
|
|
37550
|
+
var rowHolding = (json, pathToParagraph) => {
|
|
37551
|
+
let element = json;
|
|
37552
|
+
let row;
|
|
37553
|
+
let table;
|
|
37554
|
+
for (let i = 1; i < pathToParagraph.length; i++) {
|
|
37555
|
+
const child = element.elements[pathToParagraph[i]];
|
|
37556
|
+
if (child.name === "w:tbl") table = {
|
|
37557
|
+
element: child,
|
|
37558
|
+
parent: element
|
|
37559
|
+
};
|
|
37560
|
+
if (child.name === "w:tr") row = {
|
|
37561
|
+
parent: element,
|
|
37562
|
+
table,
|
|
37563
|
+
row: child,
|
|
37564
|
+
path: pathToParagraph.slice(0, i + 1)
|
|
37565
|
+
};
|
|
37566
|
+
element = child;
|
|
37567
|
+
}
|
|
37568
|
+
return row;
|
|
37569
|
+
};
|
|
37570
|
+
var isInside = (path, ancestorPath) => path.length > ancestorPath.length && ancestorPath.every((index, i) => path[i] === index);
|
|
37571
|
+
var hasRows = (table) => {
|
|
37572
|
+
var _table$elements;
|
|
37573
|
+
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));
|
|
37574
|
+
};
|
|
37575
|
+
/**
|
|
37576
|
+
* The names of the fields in the elements, such as "name" for `{{items.name}}`.
|
|
37577
|
+
*/
|
|
37578
|
+
var fieldsIn = (elements, fieldStart, end) => {
|
|
37579
|
+
const fields = findLocationOfText({ elements: [...elements] }, fieldStart).flatMap(({ text }) => text.split(fieldStart).slice(1).flatMap((after) => {
|
|
37580
|
+
const fieldEnd = after.indexOf(end);
|
|
37581
|
+
return fieldEnd > 0 ? [after.slice(0, fieldEnd)] : [];
|
|
37582
|
+
}));
|
|
37583
|
+
return [...new Set(fields)];
|
|
37584
|
+
};
|
|
37585
|
+
var copyOf = (element) => JSON.parse(JSON.stringify(element));
|
|
37586
|
+
var ATTRIBUTES_TO_REMOVE = ["w14:paraId", "w14:textId"];
|
|
37587
|
+
var ELEMENTS_TO_REMOVE = ["w:bookmarkStart", "w:bookmarkEnd"];
|
|
37588
|
+
/**
|
|
37589
|
+
* A copy of elements without what must be unique in a document, so they can be in the document more than once.
|
|
37590
|
+
*
|
|
37591
|
+
* @param parent - The elements' parent, as a content control's id is an element in its properties
|
|
37592
|
+
*/
|
|
37593
|
+
var withoutIds = (elements, parent) => elements.filter((e) => {
|
|
37594
|
+
var _e$name;
|
|
37595
|
+
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");
|
|
37596
|
+
}).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)] }));
|
|
37597
|
+
//#endregion
|
|
35540
37598
|
//#region src/patcher/theme-colors.ts
|
|
35541
37599
|
var THEME_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
|
|
35542
37600
|
var COLOR_NAMES = /* @__PURE__ */ new Map([
|
|
@@ -35595,7 +37653,7 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35595
37653
|
return ((_item$attributes3 = item.attributes) === null || _item$attributes3 === void 0 ? void 0 : _item$attributes3.Type) === THEME_RELATIONSHIP_TYPE;
|
|
35596
37654
|
});
|
|
35597
37655
|
const target = theme === null || theme === void 0 || (_theme$attributes = theme.attributes) === null || _theme$attributes === void 0 ? void 0 : _theme$attributes.Target;
|
|
35598
|
-
return typeof target === "string" ? readPart(zip,
|
|
37656
|
+
return typeof target === "string" ? readPart(zip, resolveTarget("word/document.xml", target)) : void 0;
|
|
35599
37657
|
});
|
|
35600
37658
|
return function readTheme(_x3) {
|
|
35601
37659
|
return _ref2.apply(this, arguments);
|
|
@@ -35634,6 +37692,23 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35634
37692
|
*
|
|
35635
37693
|
* @module
|
|
35636
37694
|
*/
|
|
37695
|
+
/**
|
|
37696
|
+
* 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
|
|
37697
|
+
* from JavaScript without its children.
|
|
37698
|
+
*
|
|
37699
|
+
* @param key - The patch's key, such as "items", or for a field of a row, such as "items.name"
|
|
37700
|
+
* @param inTableRow - Whether the patch is for a field of a row, where a drawing patch can't be
|
|
37701
|
+
*/
|
|
37702
|
+
var assertValidPatch = (key, patch, { inTableRow }) => {
|
|
37703
|
+
if ((patch === null || patch === void 0 ? void 0 : patch.type) === PatchType.TABLE_ROWS && Array.isArray(patch.rows)) {
|
|
37704
|
+
for (const row of patch.rows) {
|
|
37705
|
+
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`);
|
|
37706
|
+
for (const [field, fieldPatch] of Object.entries(row)) if (fieldPatch !== void 0) assertValidPatch(`${key}.${field}`, fieldPatch, { inTableRow: true });
|
|
37707
|
+
}
|
|
37708
|
+
return;
|
|
37709
|
+
}
|
|
37710
|
+
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"}`);
|
|
37711
|
+
};
|
|
35637
37712
|
var imageReplacer = new ImageReplacer();
|
|
35638
37713
|
var UTF16LE = new Uint8Array([255, 254]);
|
|
35639
37714
|
var UTF16BE = new Uint8Array([254, 255]);
|
|
@@ -35681,7 +37756,7 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35681
37756
|
var _ref = _asyncToGenerator(function* ({ outputType, data, patches, keepOriginalStyles, placeholderDelimiters = {
|
|
35682
37757
|
start: "{{",
|
|
35683
37758
|
end: "}}"
|
|
35684
|
-
}, recursive = true }) {
|
|
37759
|
+
}, recursive = true, footnotes, endnotes, pageNumbers }) {
|
|
35685
37760
|
const zipContent = data instanceof import_jszip_min.default ? data : yield import_jszip_min.default.loadAsync(data);
|
|
35686
37761
|
const contexts = /* @__PURE__ */ new Map();
|
|
35687
37762
|
const themeColors = yield readThemeColors(zipContent);
|
|
@@ -35701,7 +37776,7 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35701
37776
|
const binaryContentMap = /* @__PURE__ */ new Map();
|
|
35702
37777
|
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.");
|
|
35703
37778
|
const { start, end } = placeholderDelimiters;
|
|
35704
|
-
for (const [key, patch] of Object.entries(patches))
|
|
37779
|
+
for (const [key, patch] of Object.entries(patches)) assertValidPatch(key, patch, { inTableRow: false });
|
|
35705
37780
|
for (const [key, value] of Object.entries(zipContent.files)) {
|
|
35706
37781
|
const binaryValue = yield value.async("uint8array");
|
|
35707
37782
|
const startBytes = binaryValue.slice(0, 2);
|
|
@@ -35730,6 +37805,7 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35730
37805
|
}
|
|
35731
37806
|
map.set(key, json);
|
|
35732
37807
|
}
|
|
37808
|
+
const renumberBookmarks = renumberBookmarksAvoiding([...map.values()].flatMap(findBookmarkIds));
|
|
35733
37809
|
const createContext = (key) => ({
|
|
35734
37810
|
file,
|
|
35735
37811
|
viewWrapper: { Relationships: { addRelationship: (id, type, target, targetMode) => {
|
|
@@ -35743,6 +37819,17 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35743
37819
|
} } },
|
|
35744
37820
|
stack: []
|
|
35745
37821
|
});
|
|
37822
|
+
const notes = patchNotes({
|
|
37823
|
+
footnotes,
|
|
37824
|
+
endnotes
|
|
37825
|
+
}, map, {
|
|
37826
|
+
createContext,
|
|
37827
|
+
addContentTypeOverride: (contentType, partName) => contentTypeOverrides.push({
|
|
37828
|
+
contentType,
|
|
37829
|
+
partName
|
|
37830
|
+
}),
|
|
37831
|
+
renumberBookmarks
|
|
37832
|
+
});
|
|
35746
37833
|
patchDrawings({
|
|
35747
37834
|
parts: map,
|
|
35748
37835
|
binaryParts: binaryContentMap,
|
|
@@ -35753,35 +37840,57 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35753
37840
|
end
|
|
35754
37841
|
}
|
|
35755
37842
|
}, createContext);
|
|
37843
|
+
const textPatches = Object.entries(patches).flatMap(([key, patch]) => patch.type === PatchType.DRAWING ? [] : [[key, patch]]);
|
|
37844
|
+
const patchesInOrder = [...textPatches.filter(([, patch]) => patch.type === PatchType.TABLE_ROWS), ...textPatches.filter(([, patch]) => patch.type !== PatchType.TABLE_ROWS)];
|
|
35756
37845
|
for (const [key, json] of [...map]) {
|
|
35757
37846
|
if (!key.startsWith("word/") || key.endsWith(".xml.rels")) continue;
|
|
35758
37847
|
const context = createContext(key);
|
|
35759
37848
|
contexts.set(key, context);
|
|
35760
|
-
|
|
35761
|
-
if (patchValue.type === PatchType.
|
|
35762
|
-
|
|
35763
|
-
|
|
35764
|
-
|
|
35765
|
-
|
|
35766
|
-
|
|
35767
|
-
|
|
35768
|
-
|
|
37849
|
+
const patchPlaceholder = (element, patchKey, patchValue) => {
|
|
37850
|
+
if (patchValue.type === PatchType.TABLE_ROWS) {
|
|
37851
|
+
patchTableRows({
|
|
37852
|
+
json: element,
|
|
37853
|
+
key: patchKey,
|
|
37854
|
+
patch: patchValue,
|
|
37855
|
+
delimiters: {
|
|
37856
|
+
start,
|
|
37857
|
+
end
|
|
37858
|
+
},
|
|
37859
|
+
patchPlaceholder
|
|
37860
|
+
});
|
|
37861
|
+
return;
|
|
37862
|
+
}
|
|
37863
|
+
const hyperlinkRelationships = [];
|
|
37864
|
+
const { didFindOccurrence } = replacer({
|
|
37865
|
+
json: element,
|
|
37866
|
+
patch: _objectSpread2(_objectSpread2({}, patchValue), {}, { children: patchValue.children.flatMap((child) => child instanceof Bookmark ? child.writtenAs : [child]).map((child) => {
|
|
37867
|
+
if (child instanceof ExternalHyperlink) {
|
|
37868
|
+
const { target, anchor } = externalHyperlinkTarget(child.options.link);
|
|
37869
|
+
const concreteHyperlink = new ConcreteHyperlink(child.options.children, uniqueId(), anchor, child.options.link);
|
|
37870
|
+
hyperlinkRelationships.push({
|
|
35769
37871
|
key,
|
|
35770
37872
|
id: concreteHyperlink.linkId,
|
|
35771
37873
|
type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
|
|
35772
|
-
target
|
|
37874
|
+
target,
|
|
35773
37875
|
targetMode: TargetModeType.EXTERNAL
|
|
35774
37876
|
});
|
|
35775
37877
|
return concreteHyperlink;
|
|
35776
|
-
} else return
|
|
37878
|
+
} else return child;
|
|
35777
37879
|
}) }),
|
|
35778
|
-
patchText
|
|
37880
|
+
patchText: `${start}${patchKey}${end}`,
|
|
35779
37881
|
context,
|
|
35780
37882
|
keepOriginalStyles,
|
|
35781
|
-
recursive
|
|
37883
|
+
recursive,
|
|
37884
|
+
renumberIds: (elements) => notes.renumber(renumberBookmarks(elements))
|
|
35782
37885
|
});
|
|
35783
|
-
|
|
35784
|
-
|
|
37886
|
+
if (didFindOccurrence) relationshipAdditions.push(...hyperlinkRelationships);
|
|
37887
|
+
};
|
|
37888
|
+
for (const [patchKey, patchValue] of patchesInOrder) patchPlaceholder(json, patchKey, patchValue);
|
|
37889
|
+
}
|
|
37890
|
+
notes.write();
|
|
37891
|
+
for (const [key, json] of map) {
|
|
37892
|
+
if (!key.startsWith("word/") || key.endsWith(".xml.rels")) continue;
|
|
37893
|
+
const mediaDatas = imageReplacer.getMediaData(JSON.stringify(json), file.Media);
|
|
35785
37894
|
if (mediaDatas.length > 0) {
|
|
35786
37895
|
hasMedia = true;
|
|
35787
37896
|
imageRelationshipAdditions.push({
|
|
@@ -35810,6 +37919,7 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35810
37919
|
map.set(relationshipKey, relationshipsJson);
|
|
35811
37920
|
appendRelationship(relationshipsJson, id, type, target, targetMode);
|
|
35812
37921
|
}
|
|
37922
|
+
if (pageNumbers) yield fillTemplatePageNumbers(map, pageNumbers, binaryContentMap);
|
|
35813
37923
|
const packageParts = xmlifyPackageParts(file, void 0);
|
|
35814
37924
|
if (hasMedia || contentTypeOverrides.length > 0) {
|
|
35815
37925
|
const contentTypesJson = map.get("[Content_Types].xml");
|
|
@@ -35843,12 +37953,13 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35843
37953
|
};
|
|
35844
37954
|
}();
|
|
35845
37955
|
/**
|
|
35846
|
-
* The element with an extra escape on each "&" in its text. xml-js reads "&" in text as an "&"
|
|
35847
|
-
* would write a text's literal "&", such as in a document about HTML, as "&".
|
|
37956
|
+
* The element with an extra escape on each "&" in its text and attributes. xml-js reads "&" in text as an "&"
|
|
37957
|
+
* already escaped, and would write a text's literal "&", such as in a document about HTML, as "&". It escapes the
|
|
37958
|
+
* quotes in an attribute before `attributeValueFn` is given it, so that can't tell its """ from a literal one.
|
|
35848
37959
|
*/
|
|
35849
|
-
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)) });
|
|
37960
|
+
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)) });
|
|
35850
37961
|
var toXml = (jsonObj) => {
|
|
35851
|
-
return (0, import_lib.js2xml)(withAmpersandsEscaped(jsonObj), { attributeValueFn: (str) => String(str).replace(
|
|
37962
|
+
return (0, import_lib.js2xml)(withAmpersandsEscaped(jsonObj), { attributeValueFn: (str) => String(str).replace(/</g, "<").replace(/>/g, ">").replace(/'/g, "'") });
|
|
35852
37963
|
};
|
|
35853
37964
|
//#endregion
|
|
35854
37965
|
//#region src/patcher/patch-detector.ts
|
|
@@ -35963,6 +38074,7 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35963
38074
|
exports.EmphasisMarkType = EmphasisMarkType;
|
|
35964
38075
|
exports.EmptyElement = EmptyElement;
|
|
35965
38076
|
exports.EndnoteIdReference = EndnoteIdReference;
|
|
38077
|
+
exports.EndnotePosition = EndnotePosition;
|
|
35966
38078
|
exports.EndnoteReference = EndnoteReference;
|
|
35967
38079
|
exports.EndnoteReferenceRun = EndnoteReferenceRun;
|
|
35968
38080
|
exports.EndnoteReferenceRunAttributes = EndnoteReferenceRunAttributes;
|
|
@@ -35974,6 +38086,7 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
35974
38086
|
exports.FootNotes = FootNotes;
|
|
35975
38087
|
exports.Footer = Footer;
|
|
35976
38088
|
exports.FooterWrapper = FooterWrapper;
|
|
38089
|
+
exports.FootnotePosition = FootnotePosition;
|
|
35977
38090
|
exports.FootnoteReference = FootnoteReference;
|
|
35978
38091
|
exports.FootnoteReferenceElement = FootnoteReferenceElement;
|
|
35979
38092
|
exports.FootnoteReferenceRun = FootnoteReferenceRun;
|
|
@@ -36040,6 +38153,7 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
36040
38153
|
exports.NextAttributeComponent = NextAttributeComponent;
|
|
36041
38154
|
exports.NoBreakHyphen = NoBreakHyphen;
|
|
36042
38155
|
exports.NonVisualDrawingProperties = NonVisualDrawingProperties;
|
|
38156
|
+
exports.NoteNumberRestart = NoteNumberRestart;
|
|
36043
38157
|
exports.NumberFormat = NumberFormat;
|
|
36044
38158
|
exports.NumberProperties = NumberProperties;
|
|
36045
38159
|
exports.NumberValueElement = NumberValueElement;
|
|
@@ -36154,6 +38268,8 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
36154
38268
|
exports.createDocumentGrid = createDocumentGrid;
|
|
36155
38269
|
exports.createDotEmphasisMark = createDotEmphasisMark;
|
|
36156
38270
|
exports.createEmphasisMark = createEmphasisMark;
|
|
38271
|
+
exports.createEndnoteProperties = createEndnoteProperties;
|
|
38272
|
+
exports.createFootnoteProperties = createFootnoteProperties;
|
|
36157
38273
|
exports.createFrameProperties = createFrameProperties;
|
|
36158
38274
|
exports.createHeaderFooterReference = createHeaderFooterReference;
|
|
36159
38275
|
exports.createHorizontalPosition = createHorizontalPosition;
|
|
@@ -36203,6 +38319,9 @@ while (n === a[++i] && n === a[++i] && n === a[++i] && n === a[++i] && n === a[+
|
|
|
36203
38319
|
exports.docPropertiesUniqueNumericIdGen = docPropertiesUniqueNumericIdGen;
|
|
36204
38320
|
exports.eighthPointMeasureValue = eighthPointMeasureValue;
|
|
36205
38321
|
exports.encodeUtf8 = encodeUtf8;
|
|
38322
|
+
exports.fillPageNumbers = fillPageNumbers;
|
|
38323
|
+
exports.fillPartPageNumbers = fillPartPageNumbers;
|
|
38324
|
+
exports.fillSequenceNumbers = fillSequenceNumbers;
|
|
36206
38325
|
exports.hashedId = hashedId;
|
|
36207
38326
|
exports.hexColorValue = hexColorValue;
|
|
36208
38327
|
exports.hpsMeasureValue = hpsMeasureValue;
|