@office-open/docx 0.9.2 → 0.9.4
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/{context-CERMOUn0.mjs → context-CA7wUvmY.mjs} +1608 -1043
- package/dist/context-CA7wUvmY.mjs.map +1 -0
- package/dist/{core-properties-Bh8_D5Kh.d.mts → core-properties-CR-T1Wqh.d.mts} +59 -10
- package/dist/core-properties-CR-T1Wqh.d.mts.map +1 -0
- package/dist/{document-CeM-U6J3.mjs → document-B_uvEH8b.mjs} +705 -83
- package/dist/document-B_uvEH8b.mjs.map +1 -0
- package/dist/{generate-DiDgl0bc.mjs → generate-_AmBlI4o.mjs} +4 -4
- package/dist/generate-_AmBlI4o.mjs.map +1 -0
- package/dist/generate.d.mts +1 -1
- package/dist/generate.mjs +1 -1
- package/dist/index.d.mts +3 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +5 -34
- package/dist/index.mjs.map +1 -1
- package/dist/{parse-BIJM6_8Y.mjs → parse-7SJ1sm-D.mjs} +17 -4
- package/dist/parse-7SJ1sm-D.mjs.map +1 -0
- package/dist/parse.d.mts +1 -1
- package/dist/parse.mjs +1 -1
- package/dist/patch/index.d.mts +1 -1
- package/dist/patch/index.mjs +1 -1
- package/package.json +3 -3
- package/dist/context-CERMOUn0.mjs.map +0 -1
- package/dist/core-properties-Bh8_D5Kh.d.mts.map +0 -1
- package/dist/document-CeM-U6J3.mjs.map +0 -1
- package/dist/generate-DiDgl0bc.mjs.map +0 -1
- package/dist/parse-BIJM6_8Y.mjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as stringifyParagraphProperties, D as stringifyChildDispatch, E as tableDesc,
|
|
2
|
-
import { Relationships, convertInchesToTwip, decimalNumber, derivePasswordHash, hexColorValue, toUint8Array, uCharHexNumber, uniqueId, uniqueNumericIdCreator, uniqueUuid } from "@office-open/core";
|
|
3
|
-
import { attr, attrBool, attrNum, children, colorAttr,
|
|
1
|
+
import { A as stringifyParagraphProperties, D as stringifyChildDispatch, E as tableDesc, I as parseDrawingRun, M as stringifyRunPropertiesInner, N as parseMathChildren, O as stringifyParagraphInline, X as BorderStyle, j as stringifyRunProperties, lt as Media, n as sectionPropertiesDesc, tt as parseFormFieldData, ut as createTransformation } from "./document-B_uvEH8b.mjs";
|
|
2
|
+
import { Relationships, ThemeColor, convertInchesToTwip, decimalNumber, derivePasswordHash, hexColorValue, toUint8Array, uCharHexNumber, uniqueId, uniqueNumericIdCreator, uniqueUuid } from "@office-open/core";
|
|
3
|
+
import { attr, attrBool, attrNum, children, colorAttr, escapeXml, findChild, js2xml, textOf, xml2js } from "@office-open/xml";
|
|
4
4
|
import { ChartCollection } from "@office-open/core/chart";
|
|
5
5
|
import { SmartArtCollection } from "@office-open/core/smartart";
|
|
6
6
|
//#region src/parts/paragraph/formatting/alignment.ts
|
|
@@ -74,6 +74,35 @@ const AlignmentType = {
|
|
|
74
74
|
JUSTIFIED: "both"
|
|
75
75
|
};
|
|
76
76
|
//#endregion
|
|
77
|
+
//#region src/parts/paragraph/formatting/spacing.ts
|
|
78
|
+
/**
|
|
79
|
+
* Paragraph spacing module for WordprocessingML documents.
|
|
80
|
+
*
|
|
81
|
+
* This module provides spacing options for paragraphs including space before,
|
|
82
|
+
* space after, and line spacing.
|
|
83
|
+
*
|
|
84
|
+
* Reference: http://officeopenxml.com/WPspacing.php
|
|
85
|
+
*
|
|
86
|
+
* @module
|
|
87
|
+
*/
|
|
88
|
+
/**
|
|
89
|
+
* Line spacing rule types.
|
|
90
|
+
*
|
|
91
|
+
* Specifies how the line height is calculated.
|
|
92
|
+
*
|
|
93
|
+
* @publicApi
|
|
94
|
+
*/
|
|
95
|
+
const LineRuleType = {
|
|
96
|
+
/** Line spacing is at least the specified value */
|
|
97
|
+
AT_LEAST: "atLeast",
|
|
98
|
+
/** Line spacing is exactly the specified value */
|
|
99
|
+
EXACTLY: "exactly",
|
|
100
|
+
/** Line spacing is exactly the specified value (alias for EXACTLY) */
|
|
101
|
+
EXACT: "exact",
|
|
102
|
+
/** Line spacing is automatically determined based on content */
|
|
103
|
+
AUTO: "auto"
|
|
104
|
+
};
|
|
105
|
+
//#endregion
|
|
77
106
|
//#region src/parts/paragraph/formatting/style.ts
|
|
78
107
|
/**
|
|
79
108
|
* Paragraph style module for WordprocessingML documents.
|
|
@@ -440,154 +469,6 @@ const RubyAlign = {
|
|
|
440
469
|
RIGHT_VERTICAL: "rightVertical"
|
|
441
470
|
};
|
|
442
471
|
//#endregion
|
|
443
|
-
//#region src/parts/paragraph/run/form-field.ts
|
|
444
|
-
/**
|
|
445
|
-
* Form field module for WordprocessingML documents.
|
|
446
|
-
*
|
|
447
|
-
* Form fields allow creating interactive controls (checkboxes, dropdown lists,
|
|
448
|
-
* text inputs) within a document. Each form field is wrapped in a field code
|
|
449
|
-
* region delimited by fldChar elements (begin/separate/end), with ffData
|
|
450
|
-
* attached to the begin fldChar.
|
|
451
|
-
*
|
|
452
|
-
* Reference: ISO/IEC 29500-4, wml.xsd, CT_FFData, CT_FFCheckBox, CT_FFDDList, CT_FFTextInput
|
|
453
|
-
*
|
|
454
|
-
* @module
|
|
455
|
-
*/
|
|
456
|
-
/**
|
|
457
|
-
* Text input field type (ST_FFTextType).
|
|
458
|
-
*
|
|
459
|
-
* ## XSD Schema
|
|
460
|
-
* ```xml
|
|
461
|
-
* <xsd:simpleType name="ST_FFTextType">
|
|
462
|
-
* <xsd:restriction base="xsd:string">
|
|
463
|
-
* <xsd:enumeration value="regular"/>
|
|
464
|
-
* <xsd:enumeration value="number"/>
|
|
465
|
-
* <xsd:enumeration value="date"/>
|
|
466
|
-
* <xsd:enumeration value="currentTime"/>
|
|
467
|
-
* <xsd:enumeration value="currentDate"/>
|
|
468
|
-
* <xsd:enumeration value="calculated"/>
|
|
469
|
-
* </xsd:restriction>
|
|
470
|
-
* </xsd:simpleType>
|
|
471
|
-
* ```
|
|
472
|
-
*/
|
|
473
|
-
const FormFieldTextType = {
|
|
474
|
-
/** Regular text input */
|
|
475
|
-
REGULAR: "regular",
|
|
476
|
-
/** Numeric input */
|
|
477
|
-
NUMBER: "number",
|
|
478
|
-
/** Date input */
|
|
479
|
-
DATE: "date",
|
|
480
|
-
/** Current time */
|
|
481
|
-
CURRENT_TIME: "currentTime",
|
|
482
|
-
/** Current date */
|
|
483
|
-
CURRENT_DATE: "currentDate",
|
|
484
|
-
/** Calculated value */
|
|
485
|
-
CALCULATED: "calculated"
|
|
486
|
-
};
|
|
487
|
-
/** Build a w:val-style element with a single attribute. */
|
|
488
|
-
const valElement = (name, val) => `<${name} w:val="${val}"/>`;
|
|
489
|
-
/**
|
|
490
|
-
* Creates a help or status text element.
|
|
491
|
-
*/
|
|
492
|
-
const createFormFieldText = (name, options) => `<${name} w:type="${options.type}" w:val="${options.value}"/>`;
|
|
493
|
-
/**
|
|
494
|
-
* Creates a checkbox form field element (w:checkBox).
|
|
495
|
-
*/
|
|
496
|
-
const createCheckBox = (options) => {
|
|
497
|
-
const children = [];
|
|
498
|
-
if (options.size !== void 0) children.push(valElement("w:size", options.size));
|
|
499
|
-
else if (options.sizeAuto !== void 0) children.push(`<w:sizeAuto/>`);
|
|
500
|
-
if (options.default !== void 0) children.push(`<w:default/>`);
|
|
501
|
-
if (options.checked !== void 0) children.push(`<w:checked/>`);
|
|
502
|
-
return element("w:checkBox", void 0, children);
|
|
503
|
-
};
|
|
504
|
-
/**
|
|
505
|
-
* Creates a dropdown list form field element (w:ddList).
|
|
506
|
-
*/
|
|
507
|
-
const createDropDownList = (options) => {
|
|
508
|
-
const children = [];
|
|
509
|
-
if (options.result !== void 0) children.push(valElement("w:result", options.result));
|
|
510
|
-
if (options.default !== void 0) children.push(valElement("w:default", options.default));
|
|
511
|
-
for (const entry of options.entries) children.push(valElement("w:listEntry", entry));
|
|
512
|
-
return element("w:ddList", void 0, children);
|
|
513
|
-
};
|
|
514
|
-
/**
|
|
515
|
-
* Creates a text input form field element (w:textInput).
|
|
516
|
-
*/
|
|
517
|
-
const createTextInput = (options) => {
|
|
518
|
-
const children = [];
|
|
519
|
-
if (options.type !== void 0) children.push(valElement("w:type", options.type));
|
|
520
|
-
if (options.default !== void 0) children.push(valElement("w:default", options.default));
|
|
521
|
-
if (options.maxLength !== void 0) children.push(valElement("w:maxLength", options.maxLength));
|
|
522
|
-
if (options.format !== void 0) children.push(valElement("w:format", options.format));
|
|
523
|
-
return element("w:textInput", void 0, children);
|
|
524
|
-
};
|
|
525
|
-
/**
|
|
526
|
-
* Creates a form field data element (w:ffData).
|
|
527
|
-
*
|
|
528
|
-
* This element contains the definition for an interactive form field
|
|
529
|
-
* (checkbox, dropdown list, or text input) within a document.
|
|
530
|
-
*
|
|
531
|
-
* ## XSD Schema
|
|
532
|
-
* ```xml
|
|
533
|
-
* <xsd:complexType name="CT_FFData">
|
|
534
|
-
* <xsd:choice maxOccurs="unbounded">
|
|
535
|
-
* <xsd:element name="name" type="CT_FFName"/>
|
|
536
|
-
* <xsd:element name="label" type="CT_DecimalNumber"/>
|
|
537
|
-
* <xsd:element name="tabIndex" type="CT_UnsignedDecimalNumber"/>
|
|
538
|
-
* <xsd:element name="enabled" type="CT_OnOff"/>
|
|
539
|
-
* <xsd:element name="calcOnExit" type="CT_OnOff"/>
|
|
540
|
-
* <xsd:element name="entryMacro" type="CT_MacroName"/>
|
|
541
|
-
* <xsd:element name="exitMacro" type="CT_MacroName"/>
|
|
542
|
-
* <xsd:element name="helpText" type="CT_FFHelpText"/>
|
|
543
|
-
* <xsd:element name="statusText" type="CT_FFStatusText"/>
|
|
544
|
-
* <xsd:choice>
|
|
545
|
-
* <xsd:element name="checkBox" type="CT_FFCheckBox"/>
|
|
546
|
-
* <xsd:element name="ddList" type="CT_FFDDList"/>
|
|
547
|
-
* <xsd:element name="textInput" type="CT_FFTextInput"/>
|
|
548
|
-
* </xsd:choice>
|
|
549
|
-
* </xsd:choice>
|
|
550
|
-
* </xsd:complexType>
|
|
551
|
-
* ```
|
|
552
|
-
*
|
|
553
|
-
* @example
|
|
554
|
-
* ```typescript
|
|
555
|
-
* // Checkbox
|
|
556
|
-
* createFormFieldData({
|
|
557
|
-
* name: "Check1",
|
|
558
|
-
* checkBox: { checked: true, sizeAuto: true },
|
|
559
|
-
* });
|
|
560
|
-
*
|
|
561
|
-
* // Dropdown
|
|
562
|
-
* createFormFieldData({
|
|
563
|
-
* name: "DropDown1",
|
|
564
|
-
* dropDownList: { entries: ["Option A", "Option B", "Option C"], result: 0 },
|
|
565
|
-
* });
|
|
566
|
-
*
|
|
567
|
-
* // Text input
|
|
568
|
-
* createFormFieldData({
|
|
569
|
-
* name: "Text1",
|
|
570
|
-
* textInput: { type: "regular", default: "Enter text here" },
|
|
571
|
-
* });
|
|
572
|
-
* ```
|
|
573
|
-
*/
|
|
574
|
-
const createFormFieldData = (options) => {
|
|
575
|
-
const children = [];
|
|
576
|
-
if (options.name !== void 0) children.push(valElement("w:name", options.name));
|
|
577
|
-
if (options.label !== void 0) children.push(valElement("w:label", options.label));
|
|
578
|
-
if (options.tabIndex !== void 0) children.push(valElement("w:tabIndex", options.tabIndex));
|
|
579
|
-
if (options.enabled !== void 0) children.push(`<w:enabled/>`);
|
|
580
|
-
if (options.calcOnExit !== void 0) children.push(`<w:calcOnExit/>`);
|
|
581
|
-
if (options.entryMacro !== void 0) children.push(valElement("w:entryMacro", options.entryMacro));
|
|
582
|
-
if (options.exitMacro !== void 0) children.push(valElement("w:exitMacro", options.exitMacro));
|
|
583
|
-
if (options.helpText) children.push(createFormFieldText("w:helpText", options.helpText));
|
|
584
|
-
if (options.statusText) children.push(createFormFieldText("w:statusText", options.statusText));
|
|
585
|
-
if (options.checkBox) children.push(createCheckBox(options.checkBox));
|
|
586
|
-
else if (options.dropDownList) children.push(createDropDownList(options.dropDownList));
|
|
587
|
-
else if (options.textInput) children.push(createTextInput(options.textInput));
|
|
588
|
-
return element("w:ffData", void 0, children);
|
|
589
|
-
};
|
|
590
|
-
//#endregion
|
|
591
472
|
//#region src/parts/paragraph/run/proof-error.ts
|
|
592
473
|
/**
|
|
593
474
|
* Proof error types for WordprocessingML documents.
|
|
@@ -717,202 +598,658 @@ const TABLE_BORDERS_NONE = {
|
|
|
717
598
|
top: NONE_BORDER
|
|
718
599
|
};
|
|
719
600
|
//#endregion
|
|
720
|
-
//#region src/parts/
|
|
721
|
-
/**
|
|
722
|
-
* Number format types for list levels.
|
|
723
|
-
*
|
|
724
|
-
* Defines the various numbering formats available for list levels, including
|
|
725
|
-
* decimal, roman numerals, letters, and various international formats.
|
|
726
|
-
*
|
|
727
|
-
* Reference: http://officeopenxml.com/WPnumbering-numFmt.php
|
|
728
|
-
*
|
|
729
|
-
* @publicApi
|
|
730
|
-
*/
|
|
731
|
-
const LevelFormat = {
|
|
732
|
-
/** Decimal numbering (1, 2, 3...). */
|
|
733
|
-
DECIMAL: "decimal",
|
|
734
|
-
/** Uppercase roman numerals (I, II, III...). */
|
|
735
|
-
UPPER_ROMAN: "upperRoman",
|
|
736
|
-
/** Lowercase roman numerals (i, ii, iii...). */
|
|
737
|
-
LOWER_ROMAN: "lowerRoman",
|
|
738
|
-
/** Uppercase letters (A, B, C...). */
|
|
739
|
-
UPPER_LETTER: "upperLetter",
|
|
740
|
-
/** Lowercase letters (a, b, c...). */
|
|
741
|
-
LOWER_LETTER: "lowerLetter",
|
|
742
|
-
/** Ordinal numbers (1st, 2nd, 3rd...). */
|
|
743
|
-
ORDINAL: "ordinal",
|
|
744
|
-
/** Cardinal text (one, two, three...). */
|
|
745
|
-
CARDINAL_TEXT: "cardinalText",
|
|
746
|
-
/** Ordinal text (first, second, third...). */
|
|
747
|
-
ORDINAL_TEXT: "ordinalText",
|
|
748
|
-
/** Hexadecimal numbering. */
|
|
749
|
-
HEX: "hex",
|
|
750
|
-
/** Chicago Manual of Style numbering. */
|
|
751
|
-
CHICAGO: "chicago",
|
|
752
|
-
/** Ideograph digital numbering. */
|
|
753
|
-
IDEOGRAPH__DIGITAL: "ideographDigital",
|
|
754
|
-
/** Japanese counting system. */
|
|
755
|
-
JAPANESE_COUNTING: "japaneseCounting",
|
|
756
|
-
/** Japanese aiueo ordering. */
|
|
757
|
-
AIUEO: "aiueo",
|
|
758
|
-
/** Japanese iroha ordering. */
|
|
759
|
-
IROHA: "iroha",
|
|
760
|
-
/** Full-width decimal numbering. */
|
|
761
|
-
DECIMAL_FULL_WIDTH: "decimalFullWidth",
|
|
762
|
-
/** Half-width decimal numbering. */
|
|
763
|
-
DECIMAL_HALF_WIDTH: "decimalHalfWidth",
|
|
764
|
-
/** Japanese legal numbering. */
|
|
765
|
-
JAPANESE_LEGAL: "japaneseLegal",
|
|
766
|
-
/** Japanese digital ten thousand numbering. */
|
|
767
|
-
JAPANESE_DIGITAL_TEN_THOUSAND: "japaneseDigitalTenThousand",
|
|
768
|
-
/** Decimal numbers enclosed in circles. */
|
|
769
|
-
DECIMAL_ENCLOSED_CIRCLE: "decimalEnclosedCircle",
|
|
770
|
-
/** Full-width decimal numbering variant 2. */
|
|
771
|
-
DECIMAL_FULL_WIDTH2: "decimalFullWidth2",
|
|
772
|
-
/** Full-width aiueo ordering. */
|
|
773
|
-
AIUEO_FULL_WIDTH: "aiueoFullWidth",
|
|
774
|
-
/** Full-width iroha ordering. */
|
|
775
|
-
IROHA_FULL_WIDTH: "irohaFullWidth",
|
|
776
|
-
/** Decimal with leading zeros. */
|
|
777
|
-
DECIMAL_ZERO: "decimalZero",
|
|
778
|
-
/** Bullet points. */
|
|
779
|
-
BULLET: "bullet",
|
|
780
|
-
/** Korean ganada ordering. */
|
|
781
|
-
GANADA: "ganada",
|
|
782
|
-
/** Korean chosung ordering. */
|
|
783
|
-
CHOSUNG: "chosung",
|
|
784
|
-
/** Decimal enclosed with fullstop. */
|
|
785
|
-
DECIMAL_ENCLOSED_FULLSTOP: "decimalEnclosedFullstop",
|
|
786
|
-
/** Decimal enclosed in parentheses. */
|
|
787
|
-
DECIMAL_ENCLOSED_PARENTHESES: "decimalEnclosedParen",
|
|
788
|
-
/** Decimal enclosed in circles (Chinese). */
|
|
789
|
-
DECIMAL_ENCLOSED_CIRCLE_CHINESE: "decimalEnclosedCircleChinese",
|
|
790
|
-
/** Ideograph enclosed in circles. */
|
|
791
|
-
IDEOGRAPH_ENCLOSED_CIRCLE: "ideographEnclosedCircle",
|
|
792
|
-
/** Traditional ideograph numbering. */
|
|
793
|
-
IDEOGRAPH_TRADITIONAL: "ideographTraditional",
|
|
794
|
-
/** Ideograph zodiac numbering. */
|
|
795
|
-
IDEOGRAPH_ZODIAC: "ideographZodiac",
|
|
796
|
-
/** Traditional ideograph zodiac numbering. */
|
|
797
|
-
IDEOGRAPH_ZODIAC_TRADITIONAL: "ideographZodiacTraditional",
|
|
798
|
-
/** Taiwanese counting system. */
|
|
799
|
-
TAIWANESE_COUNTING: "taiwaneseCounting",
|
|
800
|
-
/** Traditional ideograph legal numbering. */
|
|
801
|
-
IDEOGRAPH_LEGAL_TRADITIONAL: "ideographLegalTraditional",
|
|
802
|
-
/** Taiwanese counting thousand system. */
|
|
803
|
-
TAIWANESE_COUNTING_THOUSAND: "taiwaneseCountingThousand",
|
|
804
|
-
/** Taiwanese digital numbering. */
|
|
805
|
-
TAIWANESE_DIGITAL: "taiwaneseDigital",
|
|
806
|
-
/** Chinese counting system. */
|
|
807
|
-
CHINESE_COUNTING: "chineseCounting",
|
|
808
|
-
/** Simplified Chinese legal numbering. */
|
|
809
|
-
CHINESE_LEGAL_SIMPLIFIED: "chineseLegalSimplified",
|
|
810
|
-
/** Chinese counting thousand system. */
|
|
811
|
-
CHINESE_COUNTING_THOUSAND: "chineseCountingThousand",
|
|
812
|
-
/** Korean digital numbering. */
|
|
813
|
-
KOREAN_DIGITAL: "koreanDigital",
|
|
814
|
-
/** Korean counting system. */
|
|
815
|
-
KOREAN_COUNTING: "koreanCounting",
|
|
816
|
-
/** Korean legal numbering. */
|
|
817
|
-
KOREAN_LEGAL: "koreanLegal",
|
|
818
|
-
/** Korean digital numbering variant 2. */
|
|
819
|
-
KOREAN_DIGITAL2: "koreanDigital2",
|
|
820
|
-
/** Vietnamese counting system. */
|
|
821
|
-
VIETNAMESE_COUNTING: "vietnameseCounting",
|
|
822
|
-
/** Russian lowercase numbering. */
|
|
823
|
-
RUSSIAN_LOWER: "russianLower",
|
|
824
|
-
/** Russian uppercase numbering. */
|
|
825
|
-
RUSSIAN_UPPER: "russianUpper",
|
|
826
|
-
/** No numbering. */
|
|
827
|
-
NONE: "none",
|
|
828
|
-
/** Number enclosed in dashes. */
|
|
829
|
-
NUMBER_IN_DASH: "numberInDash",
|
|
830
|
-
/** Hebrew numbering variant 1. */
|
|
831
|
-
HEBREW1: "hebrew1",
|
|
832
|
-
/** Hebrew numbering variant 2. */
|
|
833
|
-
HEBREW2: "hebrew2",
|
|
834
|
-
/** Arabic alpha numbering. */
|
|
835
|
-
ARABIC_ALPHA: "arabicAlpha",
|
|
836
|
-
/** Arabic abjad numbering. */
|
|
837
|
-
ARABIC_ABJAD: "arabicAbjad",
|
|
838
|
-
/** Hindi vowels. */
|
|
839
|
-
HINDI_VOWELS: "hindiVowels",
|
|
840
|
-
/** Hindi consonants. */
|
|
841
|
-
HINDI_CONSONANTS: "hindiConsonants",
|
|
842
|
-
/** Hindi numbers. */
|
|
843
|
-
HINDI_NUMBERS: "hindiNumbers",
|
|
844
|
-
/** Hindi counting system. */
|
|
845
|
-
HINDI_COUNTING: "hindiCounting",
|
|
846
|
-
/** Thai letters. */
|
|
847
|
-
THAI_LETTERS: "thaiLetters",
|
|
848
|
-
/** Thai numbers. */
|
|
849
|
-
THAI_NUMBERS: "thaiNumbers",
|
|
850
|
-
/** Thai counting system. */
|
|
851
|
-
THAI_COUNTING: "thaiCounting",
|
|
852
|
-
/** Thai Baht text. */
|
|
853
|
-
BAHT_TEXT: "bahtText",
|
|
854
|
-
/** Dollar text. */
|
|
855
|
-
DOLLAR_TEXT: "dollarText",
|
|
856
|
-
/** Custom numbering format. */
|
|
857
|
-
CUSTOM: "custom"
|
|
858
|
-
};
|
|
601
|
+
//#region src/parts/paragraph/run/run-parse.ts
|
|
859
602
|
/**
|
|
860
|
-
*
|
|
603
|
+
* Run properties parser for DOCX documents.
|
|
861
604
|
*
|
|
862
|
-
*
|
|
605
|
+
* Parses w:rPr Element trees into RunPropertiesOptions objects.
|
|
863
606
|
*
|
|
864
|
-
* @
|
|
607
|
+
* @module
|
|
865
608
|
*/
|
|
866
|
-
const LevelSuffix = {
|
|
867
|
-
/** No separator after the numbering. */
|
|
868
|
-
NOTHING: "nothing",
|
|
869
|
-
/** Space character after the numbering. */
|
|
870
|
-
SPACE: "space",
|
|
871
|
-
/** Tab character after the numbering. */
|
|
872
|
-
TAB: "tab"
|
|
873
|
-
};
|
|
874
|
-
//#endregion
|
|
875
|
-
//#region src/parts/numbering/numbering.ts
|
|
876
609
|
/**
|
|
877
|
-
*
|
|
878
|
-
*
|
|
879
|
-
* Numbering provides support for numbered and bulleted lists.
|
|
880
|
-
* Pure string serialization — no XmlComponent inheritance.
|
|
881
|
-
*
|
|
882
|
-
* Reference: http://officeopenxml.com/WPnumbering.php
|
|
883
|
-
*
|
|
884
|
-
* @module
|
|
610
|
+
* Parse a w:rPr element into RunPropertiesOptions.
|
|
885
611
|
*/
|
|
886
|
-
|
|
887
|
-
const
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
612
|
+
function parseRunProperties(el) {
|
|
613
|
+
const opts = {};
|
|
614
|
+
const rStyle = findChild(el, "w:rStyle");
|
|
615
|
+
if (rStyle) opts.style = attr(rStyle, "w:val");
|
|
616
|
+
const font = findChild(el, "w:rFonts");
|
|
617
|
+
if (font) {
|
|
618
|
+
const ascii = attr(font, "w:ascii");
|
|
619
|
+
const eastAsia = attr(font, "w:eastAsia");
|
|
620
|
+
const hAnsi = attr(font, "w:hAnsi");
|
|
621
|
+
const cs = attr(font, "w:cs");
|
|
622
|
+
const hint = attr(font, "w:hint");
|
|
623
|
+
if (ascii && !eastAsia && !hAnsi && !cs) opts.font = hint ? {
|
|
624
|
+
name: ascii,
|
|
625
|
+
hint
|
|
626
|
+
} : ascii;
|
|
627
|
+
else {
|
|
628
|
+
const fontObj = {};
|
|
629
|
+
if (ascii) fontObj.ascii = ascii;
|
|
630
|
+
if (eastAsia) fontObj.eastAsia = eastAsia;
|
|
631
|
+
if (hAnsi) fontObj.hAnsi = hAnsi;
|
|
632
|
+
if (cs) fontObj.cs = cs;
|
|
633
|
+
if (hint) fontObj.hint = hint;
|
|
634
|
+
opts.font = fontObj;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
const bold = findChild(el, "w:b");
|
|
638
|
+
if (bold) opts.bold = attrBool(bold, "w:val") ?? true;
|
|
639
|
+
const boldCs = findChild(el, "w:bCs");
|
|
640
|
+
if (boldCs) opts.boldComplexScript = attrBool(boldCs, "w:val") ?? true;
|
|
641
|
+
const italic = findChild(el, "w:i");
|
|
642
|
+
if (italic) opts.italic = attrBool(italic, "w:val") ?? true;
|
|
643
|
+
const italicCs = findChild(el, "w:iCs");
|
|
644
|
+
if (italicCs) opts.italicComplexScript = attrBool(italicCs, "w:val") ?? true;
|
|
645
|
+
const underline = findChild(el, "w:u");
|
|
646
|
+
if (underline) {
|
|
647
|
+
const ul = {};
|
|
648
|
+
const uType = attr(underline, "w:val");
|
|
649
|
+
if (uType) ul.type = uType;
|
|
650
|
+
const uColor = colorAttr(underline, "w:color");
|
|
651
|
+
if (uColor) ul.color = uColor;
|
|
652
|
+
opts.underline = ul;
|
|
653
|
+
}
|
|
654
|
+
for (const [name, optKey] of [
|
|
655
|
+
["w:strike", "strike"],
|
|
656
|
+
["w:dstrike", "doubleStrike"],
|
|
657
|
+
["w:outline", "outline"],
|
|
658
|
+
["w:shadow", "shadow"],
|
|
659
|
+
["w:emboss", "emboss"],
|
|
660
|
+
["w:imprint", "imprint"],
|
|
661
|
+
["w:vanish", "vanish"],
|
|
662
|
+
["w:webHidden", "webHidden"],
|
|
663
|
+
["w:noProof", "noProof"],
|
|
664
|
+
["w:snapToGrid", "snapToGrid"],
|
|
665
|
+
["w:smallCaps", "smallCaps"],
|
|
666
|
+
["w:caps", "allCaps"],
|
|
667
|
+
["w:rtl", "rightToLeft"],
|
|
668
|
+
["w:cs", "complexScript"],
|
|
669
|
+
["w:specVanish", "specVanish"],
|
|
670
|
+
["w:oMath", "math"]
|
|
671
|
+
]) {
|
|
672
|
+
const child = findChild(el, name);
|
|
673
|
+
if (child) opts[optKey] = attrBool(child, "w:val") ?? true;
|
|
674
|
+
}
|
|
675
|
+
const color = findChild(el, "w:color");
|
|
676
|
+
if (color) {
|
|
677
|
+
const c = colorAttr(color, "w:val");
|
|
678
|
+
const themeColor = attr(color, "w:themeColor");
|
|
679
|
+
const themeTint = attr(color, "w:themeTint");
|
|
680
|
+
const themeShade = attr(color, "w:themeShade");
|
|
681
|
+
if (themeColor || themeTint || themeShade) {
|
|
682
|
+
const colorObj = {};
|
|
683
|
+
if (c) colorObj.val = c;
|
|
684
|
+
if (themeColor) colorObj.themeColor = themeColor;
|
|
685
|
+
if (themeTint) colorObj.themeTint = themeTint;
|
|
686
|
+
if (themeShade) colorObj.themeShade = themeShade;
|
|
687
|
+
opts.color = colorObj;
|
|
688
|
+
} else if (c) opts.color = c;
|
|
689
|
+
}
|
|
690
|
+
const sz = findChild(el, "w:sz");
|
|
691
|
+
if (sz) {
|
|
692
|
+
const halfPts = attrNum(sz, "w:val");
|
|
693
|
+
if (halfPts !== void 0) opts.size = halfPts / 2;
|
|
694
|
+
}
|
|
695
|
+
const szCs = findChild(el, "w:szCs");
|
|
696
|
+
if (szCs) {
|
|
697
|
+
const halfPts = attrNum(szCs, "w:val");
|
|
698
|
+
if (halfPts !== void 0) opts.sizeComplexScript = halfPts / 2;
|
|
699
|
+
}
|
|
700
|
+
const highlight = findChild(el, "w:highlight");
|
|
701
|
+
if (highlight) {
|
|
702
|
+
const val = attr(highlight, "w:val");
|
|
703
|
+
if (val) opts.highlight = val;
|
|
704
|
+
}
|
|
705
|
+
const highlightCs = findChild(el, "w:highlightCs");
|
|
706
|
+
if (highlightCs) {
|
|
707
|
+
const val = attr(highlightCs, "w:val");
|
|
708
|
+
if (val) opts.highlightComplexScript = val;
|
|
709
|
+
}
|
|
710
|
+
const vertAlign = findChild(el, "w:vertAlign");
|
|
711
|
+
if (vertAlign) {
|
|
712
|
+
const val = attr(vertAlign, "w:val");
|
|
713
|
+
if (val === "subscript") opts.subScript = true;
|
|
714
|
+
else if (val === "superscript") opts.superScript = true;
|
|
715
|
+
}
|
|
716
|
+
const effect = findChild(el, "w:effect");
|
|
717
|
+
if (effect) {
|
|
718
|
+
const val = attr(effect, "w:val");
|
|
719
|
+
if (val) opts.effect = val;
|
|
720
|
+
}
|
|
721
|
+
const emphasisMark = findChild(el, "w:em");
|
|
722
|
+
if (emphasisMark) {
|
|
723
|
+
const val = attr(emphasisMark, "w:val");
|
|
724
|
+
if (val) opts.emphasisMark = { type: val };
|
|
725
|
+
}
|
|
726
|
+
const spacing = findChild(el, "w:spacing");
|
|
727
|
+
if (spacing) {
|
|
728
|
+
const val = attrNum(spacing, "w:val");
|
|
729
|
+
if (val !== void 0) opts.characterSpacing = val;
|
|
730
|
+
}
|
|
731
|
+
const scale = findChild(el, "w:w");
|
|
732
|
+
if (scale) {
|
|
733
|
+
const val = attrNum(scale, "w:val");
|
|
734
|
+
if (val !== void 0) opts.scale = val;
|
|
735
|
+
}
|
|
736
|
+
const kern = findChild(el, "w:kern");
|
|
737
|
+
if (kern) {
|
|
738
|
+
const val = attrNum(kern, "w:val");
|
|
739
|
+
if (val !== void 0) opts.kern = val;
|
|
740
|
+
}
|
|
741
|
+
const position = findChild(el, "w:position");
|
|
742
|
+
if (position) {
|
|
743
|
+
const val = attr(position, "w:val");
|
|
744
|
+
if (val !== void 0) opts.position = val;
|
|
745
|
+
}
|
|
746
|
+
const fitText = findChild(el, "w:fitText");
|
|
747
|
+
if (fitText) {
|
|
748
|
+
const val = attrNum(fitText, "w:val");
|
|
749
|
+
if (val !== void 0) opts.fitText = val;
|
|
750
|
+
}
|
|
751
|
+
const lang = findChild(el, "w:lang");
|
|
752
|
+
if (lang) {
|
|
753
|
+
const langObj = {};
|
|
754
|
+
const val = attr(lang, "w:val");
|
|
755
|
+
if (val) langObj.value = val;
|
|
756
|
+
const eastAsia = attr(lang, "w:eastAsia");
|
|
757
|
+
if (eastAsia) langObj.eastAsia = eastAsia;
|
|
758
|
+
const bidi = attr(lang, "w:bidi");
|
|
759
|
+
if (bidi) langObj.bidirectional = bidi;
|
|
760
|
+
if (Object.keys(langObj).length > 0) opts.language = langObj;
|
|
761
|
+
}
|
|
762
|
+
const bdr = findChild(el, "w:bdr");
|
|
763
|
+
if (bdr) opts.border = parseBorder(bdr);
|
|
764
|
+
const shd = findChild(el, "w:shd");
|
|
765
|
+
if (shd) opts.shading = parseShading(shd);
|
|
766
|
+
const eastAsianLayout = findChild(el, "w:eastAsianLayout");
|
|
767
|
+
if (eastAsianLayout) opts.eastAsianLayout = parseEastAsianLayout(eastAsianLayout);
|
|
768
|
+
const contentPart = findChild(el, "w:contentPart");
|
|
769
|
+
if (contentPart) {
|
|
770
|
+
const rId = attr(contentPart, "r:id");
|
|
771
|
+
if (rId) opts.contentPartRId = rId;
|
|
772
|
+
}
|
|
773
|
+
const rPrChange = findChild(el, "w:rPrChange");
|
|
774
|
+
if (rPrChange) {
|
|
775
|
+
const rev = {};
|
|
776
|
+
const author = attr(rPrChange, "w:author");
|
|
777
|
+
if (author) rev.author = author;
|
|
778
|
+
const date = attr(rPrChange, "w:date");
|
|
779
|
+
if (date) rev.date = date;
|
|
780
|
+
const id = attrNum(rPrChange, "w:id");
|
|
781
|
+
if (id !== void 0) rev.id = id;
|
|
782
|
+
const innerRPr = findChild(rPrChange, "w:rPr");
|
|
783
|
+
if (innerRPr) Object.assign(rev, parseRunProperties(innerRPr));
|
|
784
|
+
if (Object.keys(rev).length > 0) opts.revision = rev;
|
|
785
|
+
}
|
|
786
|
+
return opts;
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* Parse a w:bdr element into BorderOptions.
|
|
790
|
+
*/
|
|
791
|
+
function parseBorder(el) {
|
|
792
|
+
const opts = {};
|
|
793
|
+
const style = attr(el, "w:val");
|
|
794
|
+
if (style) opts.style = style;
|
|
795
|
+
const color = colorAttr(el, "w:color");
|
|
796
|
+
if (color) opts.color = color;
|
|
797
|
+
const size = attrNum(el, "w:sz");
|
|
798
|
+
if (size !== void 0) opts.size = size;
|
|
799
|
+
const space = attrNum(el, "w:space");
|
|
800
|
+
if (space !== void 0) opts.space = space;
|
|
801
|
+
const shadow = attrBool(el, "w:shadow");
|
|
802
|
+
if (shadow !== void 0) opts.shadow = shadow;
|
|
803
|
+
const frame = attrBool(el, "w:frame");
|
|
804
|
+
if (frame !== void 0) opts.frame = frame;
|
|
805
|
+
return opts;
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Parse a w:shd element into ShadingAttributesProperties.
|
|
809
|
+
*/
|
|
810
|
+
function parseShading(el) {
|
|
811
|
+
const opts = {};
|
|
812
|
+
const fill = colorAttr(el, "w:fill");
|
|
813
|
+
if (fill) opts.fill = fill;
|
|
814
|
+
const color = colorAttr(el, "w:color");
|
|
815
|
+
if (color) opts.color = color;
|
|
816
|
+
const type = attr(el, "w:val");
|
|
817
|
+
if (type) opts.type = type;
|
|
818
|
+
return opts;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Parse a w:eastAsianLayout element into EastAsianLayoutOptions.
|
|
822
|
+
*/
|
|
823
|
+
function parseEastAsianLayout(el) {
|
|
824
|
+
const opts = {};
|
|
825
|
+
const id = attrNum(el, "w:id");
|
|
826
|
+
if (id !== void 0) opts.id = id;
|
|
827
|
+
const combine = attrBool(el, "w:combine");
|
|
828
|
+
if (combine !== void 0) opts.combine = combine;
|
|
829
|
+
const combineBrackets = attr(el, "w:combineBrackets");
|
|
830
|
+
if (combineBrackets) opts.combineBrackets = combineBrackets;
|
|
831
|
+
const vert = attrBool(el, "w:vert");
|
|
832
|
+
if (vert !== void 0) opts.vert = vert;
|
|
833
|
+
const vertCompress = attrBool(el, "w:vertCompress");
|
|
834
|
+
if (vertCompress !== void 0) opts.vertCompress = vertCompress;
|
|
835
|
+
return opts;
|
|
836
|
+
}
|
|
837
|
+
/** Matches w:br[@w:type="page"] → PageBreak */
|
|
838
|
+
const PARSED_PAGE_BREAK = Symbol("PageBreak");
|
|
839
|
+
/** Matches w:br (line break) */
|
|
840
|
+
const PARSED_LINE_BREAK = Symbol("LineBreak");
|
|
841
|
+
/** Matches w:tab */
|
|
842
|
+
const PARSED_TAB = Symbol("Tab");
|
|
843
|
+
/** Matches w:cr */
|
|
844
|
+
const PARSED_CR = Symbol("CarriageReturn");
|
|
845
|
+
/** Matches w:noBreakHyphen */
|
|
846
|
+
const PARSED_NO_BREAK_HYPHEN = Symbol("NoBreakHyphen");
|
|
847
|
+
/** Matches w:softHyphen */
|
|
848
|
+
const PARSED_SOFT_HYPHEN = Symbol("SoftHyphen");
|
|
849
|
+
/** Matches w:footnoteRef — auto-generated by Footnote class */
|
|
850
|
+
const PARSED_FOOTNOTE_REF = Symbol("FootnoteRef");
|
|
851
|
+
/** Matches w:br[@w:type="column"] */
|
|
852
|
+
const PARSED_COLUMN_BREAK = Symbol("ColumnBreak");
|
|
853
|
+
/** Matches w:dayShort */
|
|
854
|
+
const PARSED_DAY_SHORT = Symbol("DayShort");
|
|
855
|
+
/** Matches w:monthShort */
|
|
856
|
+
const PARSED_MONTH_SHORT = Symbol("MonthShort");
|
|
857
|
+
/** Matches w:yearShort */
|
|
858
|
+
const PARSED_YEAR_SHORT = Symbol("YearShort");
|
|
859
|
+
/** Matches w:dayLong */
|
|
860
|
+
const PARSED_DAY_LONG = Symbol("DayLong");
|
|
861
|
+
/** Matches w:monthLong */
|
|
862
|
+
const PARSED_MONTH_LONG = Symbol("MonthLong");
|
|
863
|
+
/** Matches w:yearLong */
|
|
864
|
+
const PARSED_YEAR_LONG = Symbol("YearLong");
|
|
865
|
+
/** Matches w:annotationRef */
|
|
866
|
+
const PARSED_ANNOTATION_REF = Symbol("AnnotationRef");
|
|
867
|
+
/** Matches w:separator */
|
|
868
|
+
const PARSED_SEPARATOR = Symbol("Separator");
|
|
869
|
+
/** Matches w:continuationSeparator */
|
|
870
|
+
const PARSED_CONTINUATION_SEPARATOR = Symbol("ContinuationSeparator");
|
|
871
|
+
/** Matches w:pgNum */
|
|
872
|
+
const PARSED_PG_NUM = Symbol("PgNum");
|
|
873
|
+
/** Matches w:lastRenderedPageBreak */
|
|
874
|
+
const PARSED_LAST_RENDERED_PAGE_BREAK = Symbol("LastRenderedPageBreak");
|
|
875
|
+
/**
|
|
876
|
+
* Parse a w:r element into run data.
|
|
877
|
+
* Returns { properties, children } where children are parsed run content items.
|
|
878
|
+
*/
|
|
879
|
+
function parseRun(el, _ctx) {
|
|
880
|
+
const rPr = findChild(el, "w:rPr");
|
|
881
|
+
const properties = rPr ? parseRunProperties(rPr) : void 0;
|
|
882
|
+
const children = [];
|
|
883
|
+
for (const child of el.elements ?? []) switch (child.name) {
|
|
884
|
+
case "w:rPr": break;
|
|
885
|
+
case "w:t": {
|
|
886
|
+
const preserveSpace = attrBool(child, "xml:space");
|
|
887
|
+
let text = textOf(child);
|
|
888
|
+
if (preserveSpace && text) {}
|
|
889
|
+
children.push(text);
|
|
890
|
+
break;
|
|
891
|
+
}
|
|
892
|
+
case "w:delText": {
|
|
893
|
+
const text = textOf(child);
|
|
894
|
+
if (text) children.push(text);
|
|
895
|
+
break;
|
|
896
|
+
}
|
|
897
|
+
case "w:br": {
|
|
898
|
+
const brType = attr(child, "w:type");
|
|
899
|
+
if (brType === "page") children.push(PARSED_PAGE_BREAK);
|
|
900
|
+
else if (brType === "column") children.push(PARSED_COLUMN_BREAK);
|
|
901
|
+
else children.push(PARSED_LINE_BREAK);
|
|
902
|
+
break;
|
|
903
|
+
}
|
|
904
|
+
case "w:tab":
|
|
905
|
+
children.push(PARSED_TAB);
|
|
906
|
+
break;
|
|
907
|
+
case "w:cr":
|
|
908
|
+
children.push(PARSED_CR);
|
|
909
|
+
break;
|
|
910
|
+
case "w:noBreakHyphen":
|
|
911
|
+
children.push(PARSED_NO_BREAK_HYPHEN);
|
|
912
|
+
break;
|
|
913
|
+
case "w:softHyphen":
|
|
914
|
+
children.push(PARSED_SOFT_HYPHEN);
|
|
915
|
+
break;
|
|
916
|
+
case "w:commentReference": {
|
|
917
|
+
const id = attrNum(child, "w:id");
|
|
918
|
+
if (id !== void 0) children.push({ commentReference: id });
|
|
919
|
+
break;
|
|
920
|
+
}
|
|
921
|
+
case "w:drawing":
|
|
922
|
+
case "w:pict": break;
|
|
923
|
+
case "w:sym": {
|
|
924
|
+
const charVal = attr(child, "w:char");
|
|
925
|
+
const fontVal = attr(child, "w:font");
|
|
926
|
+
if (charVal) children.push({ symbolRun: {
|
|
927
|
+
char: charVal,
|
|
928
|
+
symbolfont: fontVal ?? "Wingdings"
|
|
929
|
+
} });
|
|
930
|
+
break;
|
|
931
|
+
}
|
|
932
|
+
case "w:footnoteReference": {
|
|
933
|
+
const id = attrNum(child, "w:id");
|
|
934
|
+
if (id !== void 0) children.push({ footnoteReference: id });
|
|
935
|
+
break;
|
|
936
|
+
}
|
|
937
|
+
case "w:endnoteReference": {
|
|
938
|
+
const id = attrNum(child, "w:id");
|
|
939
|
+
if (id !== void 0) children.push({ endnoteReference: id });
|
|
940
|
+
break;
|
|
941
|
+
}
|
|
942
|
+
case "w:footnoteRef":
|
|
943
|
+
case "w:endnoteRef":
|
|
944
|
+
children.push(PARSED_FOOTNOTE_REF);
|
|
945
|
+
break;
|
|
946
|
+
case "w:dayShort":
|
|
947
|
+
children.push(PARSED_DAY_SHORT);
|
|
948
|
+
break;
|
|
949
|
+
case "w:monthShort":
|
|
950
|
+
children.push(PARSED_MONTH_SHORT);
|
|
951
|
+
break;
|
|
952
|
+
case "w:yearShort":
|
|
953
|
+
children.push(PARSED_YEAR_SHORT);
|
|
954
|
+
break;
|
|
955
|
+
case "w:dayLong":
|
|
956
|
+
children.push(PARSED_DAY_LONG);
|
|
957
|
+
break;
|
|
958
|
+
case "w:monthLong":
|
|
959
|
+
children.push(PARSED_MONTH_LONG);
|
|
960
|
+
break;
|
|
961
|
+
case "w:yearLong":
|
|
962
|
+
children.push(PARSED_YEAR_LONG);
|
|
963
|
+
break;
|
|
964
|
+
case "w:annotationRef":
|
|
965
|
+
children.push(PARSED_ANNOTATION_REF);
|
|
966
|
+
break;
|
|
967
|
+
case "w:separator":
|
|
968
|
+
children.push(PARSED_SEPARATOR);
|
|
969
|
+
break;
|
|
970
|
+
case "w:continuationSeparator":
|
|
971
|
+
children.push(PARSED_CONTINUATION_SEPARATOR);
|
|
972
|
+
break;
|
|
973
|
+
case "w:pgNum":
|
|
974
|
+
children.push(PARSED_PG_NUM);
|
|
975
|
+
break;
|
|
976
|
+
case "w:lastRenderedPageBreak":
|
|
977
|
+
children.push(PARSED_LAST_RENDERED_PAGE_BREAK);
|
|
978
|
+
break;
|
|
979
|
+
default: break;
|
|
980
|
+
}
|
|
981
|
+
return {
|
|
982
|
+
properties,
|
|
983
|
+
children
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Convert parsed run data into an RunOptions suitable for the Document constructor.
|
|
988
|
+
* Simplifies the parsed children into text + break format.
|
|
989
|
+
* If the run contains only a commentReference, returns { commentReference: id } instead.
|
|
990
|
+
* If the run only contains footnoteRef/endnoteRef (auto-generated), returns empty options.
|
|
991
|
+
*
|
|
992
|
+
* When empty run elements (tab, noBreakHyphen, date fields, etc.) are present,
|
|
993
|
+
* uses children[] format to preserve them for round-trip fidelity.
|
|
994
|
+
*/
|
|
995
|
+
/** Mapping from parse symbols to RunOptions child objects for empty elements. */
|
|
996
|
+
const SYMBOL_TO_CHILD = new Map([
|
|
997
|
+
[PARSED_TAB, { tab: true }],
|
|
998
|
+
[PARSED_CR, { carriageReturn: true }],
|
|
999
|
+
[PARSED_NO_BREAK_HYPHEN, { noBreakHyphen: true }],
|
|
1000
|
+
[PARSED_SOFT_HYPHEN, { softHyphen: true }],
|
|
1001
|
+
[PARSED_DAY_SHORT, { dayShort: true }],
|
|
1002
|
+
[PARSED_MONTH_SHORT, { monthShort: true }],
|
|
1003
|
+
[PARSED_YEAR_SHORT, { yearShort: true }],
|
|
1004
|
+
[PARSED_DAY_LONG, { dayLong: true }],
|
|
1005
|
+
[PARSED_MONTH_LONG, { monthLong: true }],
|
|
1006
|
+
[PARSED_YEAR_LONG, { yearLong: true }],
|
|
1007
|
+
[PARSED_ANNOTATION_REF, { annotationRef: true }],
|
|
1008
|
+
[PARSED_SEPARATOR, { separator: true }],
|
|
1009
|
+
[PARSED_CONTINUATION_SEPARATOR, { continuationSeparator: true }],
|
|
1010
|
+
[PARSED_PG_NUM, { pgNum: true }],
|
|
1011
|
+
[PARSED_LAST_RENDERED_PAGE_BREAK, { lastRenderedPageBreak: true }]
|
|
1012
|
+
]);
|
|
1013
|
+
function parsedRunToOptions(parsed) {
|
|
1014
|
+
const contentChildren = parsed.children.filter((c) => c !== PARSED_FOOTNOTE_REF);
|
|
1015
|
+
if (contentChildren.length === 0 && parsed.children.some((c) => c === PARSED_FOOTNOTE_REF)) return null;
|
|
1016
|
+
const opts = { ...parsed.properties };
|
|
1017
|
+
const isRefChild = (c) => typeof c === "object" && c !== null && ("commentReference" in c || "footnoteReference" in c || "endnoteReference" in c);
|
|
1018
|
+
const refChildren = contentChildren.filter(isRefChild);
|
|
1019
|
+
const nonRefChildren = contentChildren.filter((c) => !isRefChild(c));
|
|
1020
|
+
if (refChildren.length > 0 && nonRefChildren.length === 0) return refChildren[0];
|
|
1021
|
+
const symbolIdx = nonRefChildren.findIndex((c) => typeof c === "object" && c !== null && "symbolRun" in c);
|
|
1022
|
+
if (symbolIdx >= 0 && nonRefChildren.length === 1 && !parsed.properties) return nonRefChildren[symbolIdx];
|
|
1023
|
+
const textParts = [];
|
|
1024
|
+
let breakCount = 0;
|
|
1025
|
+
let hasPageBreak = false;
|
|
1026
|
+
let hasColumnBreak = false;
|
|
1027
|
+
const extraChildren = [];
|
|
1028
|
+
for (const child of nonRefChildren) if (typeof child === "string") textParts.push(child);
|
|
1029
|
+
else if (child === PARSED_LINE_BREAK) breakCount++;
|
|
1030
|
+
else if (child === PARSED_PAGE_BREAK) hasPageBreak = true;
|
|
1031
|
+
else if (child === PARSED_COLUMN_BREAK) hasColumnBreak = true;
|
|
1032
|
+
else {
|
|
1033
|
+
const mapped = SYMBOL_TO_CHILD.get(child);
|
|
1034
|
+
if (mapped) extraChildren.push(mapped);
|
|
1035
|
+
}
|
|
1036
|
+
if (extraChildren.length > 0) {
|
|
1037
|
+
const children = [];
|
|
1038
|
+
for (const child of nonRefChildren) if (typeof child === "string") children.push(child);
|
|
1039
|
+
else if (child === PARSED_LINE_BREAK) children.push({ break: 1 });
|
|
1040
|
+
else if (child === PARSED_PAGE_BREAK) children.push({ pageBreak: true });
|
|
1041
|
+
else if (child === PARSED_COLUMN_BREAK) children.push({ columnBreak: true });
|
|
1042
|
+
else {
|
|
1043
|
+
const mapped = SYMBOL_TO_CHILD.get(child);
|
|
1044
|
+
if (mapped) children.push(mapped);
|
|
1045
|
+
}
|
|
1046
|
+
opts.children = children;
|
|
1047
|
+
} else {
|
|
1048
|
+
if (textParts.length > 0) opts.text = textParts.join("");
|
|
1049
|
+
if (breakCount > 0) opts.break = breakCount;
|
|
1050
|
+
if (hasPageBreak) opts.pageBreak = true;
|
|
1051
|
+
if (hasColumnBreak) opts.columnBreak = true;
|
|
1052
|
+
}
|
|
1053
|
+
if (Object.keys(opts).length === 0 && textParts.length === 0 && breakCount === 0 && !hasPageBreak && !hasColumnBreak && extraChildren.length === 0) return null;
|
|
1054
|
+
return opts;
|
|
1055
|
+
}
|
|
1056
|
+
//#endregion
|
|
1057
|
+
//#region src/parts/numbering/level.ts
|
|
1058
|
+
/**
|
|
1059
|
+
* Number format types for list levels.
|
|
1060
|
+
*
|
|
1061
|
+
* Defines the various numbering formats available for list levels, including
|
|
1062
|
+
* decimal, roman numerals, letters, and various international formats.
|
|
1063
|
+
*
|
|
1064
|
+
* Reference: http://officeopenxml.com/WPnumbering-numFmt.php
|
|
1065
|
+
*
|
|
1066
|
+
* @publicApi
|
|
1067
|
+
*/
|
|
1068
|
+
const LevelFormat = {
|
|
1069
|
+
/** Decimal numbering (1, 2, 3...). */
|
|
1070
|
+
DECIMAL: "decimal",
|
|
1071
|
+
/** Uppercase roman numerals (I, II, III...). */
|
|
1072
|
+
UPPER_ROMAN: "upperRoman",
|
|
1073
|
+
/** Lowercase roman numerals (i, ii, iii...). */
|
|
1074
|
+
LOWER_ROMAN: "lowerRoman",
|
|
1075
|
+
/** Uppercase letters (A, B, C...). */
|
|
1076
|
+
UPPER_LETTER: "upperLetter",
|
|
1077
|
+
/** Lowercase letters (a, b, c...). */
|
|
1078
|
+
LOWER_LETTER: "lowerLetter",
|
|
1079
|
+
/** Ordinal numbers (1st, 2nd, 3rd...). */
|
|
1080
|
+
ORDINAL: "ordinal",
|
|
1081
|
+
/** Cardinal text (one, two, three...). */
|
|
1082
|
+
CARDINAL_TEXT: "cardinalText",
|
|
1083
|
+
/** Ordinal text (first, second, third...). */
|
|
1084
|
+
ORDINAL_TEXT: "ordinalText",
|
|
1085
|
+
/** Hexadecimal numbering. */
|
|
1086
|
+
HEX: "hex",
|
|
1087
|
+
/** Chicago Manual of Style numbering. */
|
|
1088
|
+
CHICAGO: "chicago",
|
|
1089
|
+
/** Ideograph digital numbering. */
|
|
1090
|
+
IDEOGRAPH__DIGITAL: "ideographDigital",
|
|
1091
|
+
/** Japanese counting system. */
|
|
1092
|
+
JAPANESE_COUNTING: "japaneseCounting",
|
|
1093
|
+
/** Japanese aiueo ordering. */
|
|
1094
|
+
AIUEO: "aiueo",
|
|
1095
|
+
/** Japanese iroha ordering. */
|
|
1096
|
+
IROHA: "iroha",
|
|
1097
|
+
/** Full-width decimal numbering. */
|
|
1098
|
+
DECIMAL_FULL_WIDTH: "decimalFullWidth",
|
|
1099
|
+
/** Half-width decimal numbering. */
|
|
1100
|
+
DECIMAL_HALF_WIDTH: "decimalHalfWidth",
|
|
1101
|
+
/** Japanese legal numbering. */
|
|
1102
|
+
JAPANESE_LEGAL: "japaneseLegal",
|
|
1103
|
+
/** Japanese digital ten thousand numbering. */
|
|
1104
|
+
JAPANESE_DIGITAL_TEN_THOUSAND: "japaneseDigitalTenThousand",
|
|
1105
|
+
/** Decimal numbers enclosed in circles. */
|
|
1106
|
+
DECIMAL_ENCLOSED_CIRCLE: "decimalEnclosedCircle",
|
|
1107
|
+
/** Full-width decimal numbering variant 2. */
|
|
1108
|
+
DECIMAL_FULL_WIDTH2: "decimalFullWidth2",
|
|
1109
|
+
/** Full-width aiueo ordering. */
|
|
1110
|
+
AIUEO_FULL_WIDTH: "aiueoFullWidth",
|
|
1111
|
+
/** Full-width iroha ordering. */
|
|
1112
|
+
IROHA_FULL_WIDTH: "irohaFullWidth",
|
|
1113
|
+
/** Decimal with leading zeros. */
|
|
1114
|
+
DECIMAL_ZERO: "decimalZero",
|
|
1115
|
+
/** Bullet points. */
|
|
1116
|
+
BULLET: "bullet",
|
|
1117
|
+
/** Korean ganada ordering. */
|
|
1118
|
+
GANADA: "ganada",
|
|
1119
|
+
/** Korean chosung ordering. */
|
|
1120
|
+
CHOSUNG: "chosung",
|
|
1121
|
+
/** Decimal enclosed with fullstop. */
|
|
1122
|
+
DECIMAL_ENCLOSED_FULLSTOP: "decimalEnclosedFullstop",
|
|
1123
|
+
/** Decimal enclosed in parentheses. */
|
|
1124
|
+
DECIMAL_ENCLOSED_PARENTHESES: "decimalEnclosedParen",
|
|
1125
|
+
/** Decimal enclosed in circles (Chinese). */
|
|
1126
|
+
DECIMAL_ENCLOSED_CIRCLE_CHINESE: "decimalEnclosedCircleChinese",
|
|
1127
|
+
/** Ideograph enclosed in circles. */
|
|
1128
|
+
IDEOGRAPH_ENCLOSED_CIRCLE: "ideographEnclosedCircle",
|
|
1129
|
+
/** Traditional ideograph numbering. */
|
|
1130
|
+
IDEOGRAPH_TRADITIONAL: "ideographTraditional",
|
|
1131
|
+
/** Ideograph zodiac numbering. */
|
|
1132
|
+
IDEOGRAPH_ZODIAC: "ideographZodiac",
|
|
1133
|
+
/** Traditional ideograph zodiac numbering. */
|
|
1134
|
+
IDEOGRAPH_ZODIAC_TRADITIONAL: "ideographZodiacTraditional",
|
|
1135
|
+
/** Taiwanese counting system. */
|
|
1136
|
+
TAIWANESE_COUNTING: "taiwaneseCounting",
|
|
1137
|
+
/** Traditional ideograph legal numbering. */
|
|
1138
|
+
IDEOGRAPH_LEGAL_TRADITIONAL: "ideographLegalTraditional",
|
|
1139
|
+
/** Taiwanese counting thousand system. */
|
|
1140
|
+
TAIWANESE_COUNTING_THOUSAND: "taiwaneseCountingThousand",
|
|
1141
|
+
/** Taiwanese digital numbering. */
|
|
1142
|
+
TAIWANESE_DIGITAL: "taiwaneseDigital",
|
|
1143
|
+
/** Chinese counting system. */
|
|
1144
|
+
CHINESE_COUNTING: "chineseCounting",
|
|
1145
|
+
/** Simplified Chinese legal numbering. */
|
|
1146
|
+
CHINESE_LEGAL_SIMPLIFIED: "chineseLegalSimplified",
|
|
1147
|
+
/** Chinese counting thousand system. */
|
|
1148
|
+
CHINESE_COUNTING_THOUSAND: "chineseCountingThousand",
|
|
1149
|
+
/** Korean digital numbering. */
|
|
1150
|
+
KOREAN_DIGITAL: "koreanDigital",
|
|
1151
|
+
/** Korean counting system. */
|
|
1152
|
+
KOREAN_COUNTING: "koreanCounting",
|
|
1153
|
+
/** Korean legal numbering. */
|
|
1154
|
+
KOREAN_LEGAL: "koreanLegal",
|
|
1155
|
+
/** Korean digital numbering variant 2. */
|
|
1156
|
+
KOREAN_DIGITAL2: "koreanDigital2",
|
|
1157
|
+
/** Vietnamese counting system. */
|
|
1158
|
+
VIETNAMESE_COUNTING: "vietnameseCounting",
|
|
1159
|
+
/** Russian lowercase numbering. */
|
|
1160
|
+
RUSSIAN_LOWER: "russianLower",
|
|
1161
|
+
/** Russian uppercase numbering. */
|
|
1162
|
+
RUSSIAN_UPPER: "russianUpper",
|
|
1163
|
+
/** No numbering. */
|
|
1164
|
+
NONE: "none",
|
|
1165
|
+
/** Number enclosed in dashes. */
|
|
1166
|
+
NUMBER_IN_DASH: "numberInDash",
|
|
1167
|
+
/** Hebrew numbering variant 1. */
|
|
1168
|
+
HEBREW1: "hebrew1",
|
|
1169
|
+
/** Hebrew numbering variant 2. */
|
|
1170
|
+
HEBREW2: "hebrew2",
|
|
1171
|
+
/** Arabic alpha numbering. */
|
|
1172
|
+
ARABIC_ALPHA: "arabicAlpha",
|
|
1173
|
+
/** Arabic abjad numbering. */
|
|
1174
|
+
ARABIC_ABJAD: "arabicAbjad",
|
|
1175
|
+
/** Hindi vowels. */
|
|
1176
|
+
HINDI_VOWELS: "hindiVowels",
|
|
1177
|
+
/** Hindi consonants. */
|
|
1178
|
+
HINDI_CONSONANTS: "hindiConsonants",
|
|
1179
|
+
/** Hindi numbers. */
|
|
1180
|
+
HINDI_NUMBERS: "hindiNumbers",
|
|
1181
|
+
/** Hindi counting system. */
|
|
1182
|
+
HINDI_COUNTING: "hindiCounting",
|
|
1183
|
+
/** Thai letters. */
|
|
1184
|
+
THAI_LETTERS: "thaiLetters",
|
|
1185
|
+
/** Thai numbers. */
|
|
1186
|
+
THAI_NUMBERS: "thaiNumbers",
|
|
1187
|
+
/** Thai counting system. */
|
|
1188
|
+
THAI_COUNTING: "thaiCounting",
|
|
1189
|
+
/** Thai Baht text. */
|
|
1190
|
+
BAHT_TEXT: "bahtText",
|
|
1191
|
+
/** Dollar text. */
|
|
1192
|
+
DOLLAR_TEXT: "dollarText",
|
|
1193
|
+
/** Custom numbering format. */
|
|
1194
|
+
CUSTOM: "custom"
|
|
1195
|
+
};
|
|
1196
|
+
/**
|
|
1197
|
+
* Suffix types for list levels.
|
|
1198
|
+
*
|
|
1199
|
+
* Defines what follows the numbering text (tab, space, or nothing).
|
|
1200
|
+
*
|
|
1201
|
+
* @publicApi
|
|
1202
|
+
*/
|
|
1203
|
+
const LevelSuffix = {
|
|
1204
|
+
/** No separator after the numbering. */
|
|
1205
|
+
NOTHING: "nothing",
|
|
1206
|
+
/** Space character after the numbering. */
|
|
1207
|
+
SPACE: "space",
|
|
1208
|
+
/** Tab character after the numbering. */
|
|
1209
|
+
TAB: "tab"
|
|
1210
|
+
};
|
|
1211
|
+
//#endregion
|
|
1212
|
+
//#region src/parts/numbering/numbering.ts
|
|
1213
|
+
/**
|
|
1214
|
+
* Numbering module for WordprocessingML documents.
|
|
1215
|
+
*
|
|
1216
|
+
* Numbering provides support for numbered and bulleted lists.
|
|
1217
|
+
* Pure string serialization — no XmlComponent inheritance.
|
|
1218
|
+
*
|
|
1219
|
+
* Reference: http://officeopenxml.com/WPnumbering.php
|
|
1220
|
+
*
|
|
1221
|
+
* @module
|
|
1222
|
+
*/
|
|
1223
|
+
/** Namespace attributes for w:numbering (pre-computed constant). */
|
|
1224
|
+
const NUMBERING_ATTRS = "xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" mc:Ignorable=\"w14 w15 wp14\"";
|
|
1225
|
+
/** Default bullet levels (9 levels: 0-8). */
|
|
1226
|
+
const DEFAULT_BULLET_LEVELS = [
|
|
1227
|
+
{
|
|
1228
|
+
alignment: AlignmentType.LEFT,
|
|
1229
|
+
format: LevelFormat.BULLET,
|
|
1230
|
+
level: 0,
|
|
1231
|
+
style: { paragraph: { indent: {
|
|
1232
|
+
hanging: convertInchesToTwip(.25),
|
|
1233
|
+
left: convertInchesToTwip(.5)
|
|
1234
|
+
} } },
|
|
1235
|
+
text: "●"
|
|
1236
|
+
},
|
|
1237
|
+
{
|
|
1238
|
+
alignment: AlignmentType.LEFT,
|
|
1239
|
+
format: LevelFormat.BULLET,
|
|
1240
|
+
level: 1,
|
|
1241
|
+
style: { paragraph: { indent: {
|
|
1242
|
+
hanging: convertInchesToTwip(.25),
|
|
1243
|
+
left: convertInchesToTwip(1)
|
|
1244
|
+
} } },
|
|
1245
|
+
text: "○"
|
|
1246
|
+
},
|
|
1247
|
+
{
|
|
1248
|
+
alignment: AlignmentType.LEFT,
|
|
1249
|
+
format: LevelFormat.BULLET,
|
|
1250
|
+
level: 2,
|
|
1251
|
+
style: { paragraph: { indent: {
|
|
1252
|
+
hanging: convertInchesToTwip(.25),
|
|
916
1253
|
left: 2160
|
|
917
1254
|
} } },
|
|
918
1255
|
text: "■"
|
|
@@ -976,656 +1313,243 @@ const DEFAULT_BULLET_LEVELS = [
|
|
|
976
1313
|
left: 6480
|
|
977
1314
|
} } },
|
|
978
1315
|
text: "●"
|
|
979
|
-
}
|
|
980
|
-
];
|
|
981
|
-
/**
|
|
982
|
-
* Numbering definitions for a WordprocessingML document.
|
|
983
|
-
*
|
|
984
|
-
* Pure data accumulator — no XmlComponent inheritance.
|
|
985
|
-
* Serializes via `serialize()` producing a complete XML part.
|
|
986
|
-
*/
|
|
987
|
-
var Numbering = class {
|
|
988
|
-
abstractNumberingData = /* @__PURE__ */ new Map();
|
|
989
|
-
concreteNumberingData = /* @__PURE__ */ new Map();
|
|
990
|
-
referenceConfigMap = /* @__PURE__ */ new Map();
|
|
991
|
-
abstractNumUniqueNumericId = uniqueNumericIdCreator();
|
|
992
|
-
concreteNumUniqueNumericId = uniqueNumericIdCreator(1);
|
|
993
|
-
_numIdMacAtCleanup;
|
|
994
|
-
_numPicBullets;
|
|
995
|
-
constructor(options) {
|
|
996
|
-
this._numIdMacAtCleanup = options.numIdMacAtCleanup;
|
|
997
|
-
this._numPicBullets = options.numPicBullets;
|
|
998
|
-
const defaultAbstractId = this.abstractNumUniqueNumericId();
|
|
999
|
-
this.abstractNumberingData.set("default-bullet-numbering", {
|
|
1000
|
-
id: defaultAbstractId,
|
|
1001
|
-
levels: DEFAULT_BULLET_LEVELS
|
|
1002
|
-
});
|
|
1003
|
-
this.concreteNumberingData.set("default-bullet-numbering", {
|
|
1004
|
-
abstractNumId: defaultAbstractId,
|
|
1005
|
-
instance: 0,
|
|
1006
|
-
numId: 1,
|
|
1007
|
-
overrideLevels: [{
|
|
1008
|
-
num: 0,
|
|
1009
|
-
start: 1
|
|
1010
|
-
}],
|
|
1011
|
-
reference: "default-bullet-numbering"
|
|
1012
|
-
});
|
|
1013
|
-
for (const con of options.config) {
|
|
1014
|
-
this.abstractNumberingData.set(con.reference, {
|
|
1015
|
-
id: this.abstractNumUniqueNumericId(),
|
|
1016
|
-
levels: con.levels
|
|
1017
|
-
});
|
|
1018
|
-
this.referenceConfigMap.set(con.reference, con.levels);
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
/** Serialize to word/numbering.xml content (with XML declaration). */
|
|
1022
|
-
serialize() {
|
|
1023
|
-
const parts = [];
|
|
1024
|
-
parts.push(`<w:numbering ${NUMBERING_ATTRS}>`);
|
|
1025
|
-
if (this._numPicBullets) for (const bullet of this._numPicBullets) if (bullet.pict) parts.push(`<w:numPicBullet w:numPicBulletId="${bullet.numPicBulletId}">${bullet.pict}</w:numPicBullet>`);
|
|
1026
|
-
else parts.push(`<w:numPicBullet w:numPicBulletId="${bullet.numPicBulletId}"/>`);
|
|
1027
|
-
for (const an of this.abstractNumberingData.values()) parts.push(stringifyAbstractNumbering(an.id, an.levels, an.extraOptions));
|
|
1028
|
-
for (const cn of this.concreteNumberingData.values()) parts.push(stringifyConcreteNumbering(cn));
|
|
1029
|
-
if (this._numIdMacAtCleanup !== void 0) parts.push(`<w:numIdMacAtCleanup w:val="${decimalNumber(this._numIdMacAtCleanup)}"/>`);
|
|
1030
|
-
parts.push("</w:numbering>");
|
|
1031
|
-
return "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + parts.join("");
|
|
1032
|
-
}
|
|
1033
|
-
/**
|
|
1034
|
-
* Creates a concrete numbering instance from an abstract numbering definition.
|
|
1035
|
-
*/
|
|
1036
|
-
createConcreteNumberingInstance(reference, instance) {
|
|
1037
|
-
const abstractNumbering = this.abstractNumberingData.get(reference);
|
|
1038
|
-
if (!abstractNumbering) return;
|
|
1039
|
-
const fullReference = `${reference}-${instance}`;
|
|
1040
|
-
if (this.concreteNumberingData.has(fullReference)) return;
|
|
1041
|
-
const referenceConfigLevels = this.referenceConfigMap.get(reference);
|
|
1042
|
-
const firstLevelStartNumber = referenceConfigLevels && referenceConfigLevels[0].start;
|
|
1043
|
-
this.concreteNumberingData.set(fullReference, {
|
|
1044
|
-
abstractNumId: abstractNumbering.id,
|
|
1045
|
-
instance,
|
|
1046
|
-
numId: this.concreteNumUniqueNumericId(),
|
|
1047
|
-
overrideLevels: [typeof firstLevelStartNumber === "number" && Number.isInteger(firstLevelStartNumber) ? {
|
|
1048
|
-
num: 0,
|
|
1049
|
-
start: firstLevelStartNumber
|
|
1050
|
-
} : {
|
|
1051
|
-
num: 0,
|
|
1052
|
-
start: 1
|
|
1053
|
-
}],
|
|
1054
|
-
reference
|
|
1055
|
-
});
|
|
1056
|
-
}
|
|
1057
|
-
/** Gets all concrete numbering instances. */
|
|
1058
|
-
get concreteNumbering() {
|
|
1059
|
-
return [...this.concreteNumberingData.values()];
|
|
1060
|
-
}
|
|
1061
|
-
/** Gets all reference configurations. */
|
|
1062
|
-
get referenceConfig() {
|
|
1063
|
-
return [...this.referenceConfigMap.values()];
|
|
1064
|
-
}
|
|
1065
|
-
};
|
|
1066
|
-
function stringifyAbstractNumbering(id, levels, extraOptions) {
|
|
1067
|
-
const parts = [];
|
|
1068
|
-
parts.push(`<w:abstractNum w:abstractNumId="${decimalNumber(id)}" w15:restartNumberingAfterBreak="0">`);
|
|
1069
|
-
if (extraOptions?.nsid !== void 0) parts.push(`<w:nsid w:val="${extraOptions.nsid}"/>`);
|
|
1070
|
-
parts.push(`<w:multiLevelType w:val="hybridMultilevel"/>`);
|
|
1071
|
-
if (extraOptions?.tmpl !== void 0) parts.push(`<w:tmpl w:val="${extraOptions.tmpl}"/>`);
|
|
1072
|
-
if (extraOptions?.name !== void 0) parts.push(`<w:name w:val="${extraOptions.name}"/>`);
|
|
1073
|
-
if (extraOptions?.styleLink !== void 0) parts.push(`<w:styleLink w:val="${extraOptions.styleLink}"/>`);
|
|
1074
|
-
if (extraOptions?.numStyleLink !== void 0) parts.push(`<w:numStyleLink w:val="${extraOptions.numStyleLink}"/>`);
|
|
1075
|
-
for (const level of levels) parts.push(stringifyLevel(level));
|
|
1076
|
-
parts.push("</w:abstractNum>");
|
|
1077
|
-
return parts.join("");
|
|
1078
|
-
}
|
|
1079
|
-
function stringifyConcreteNumbering(cn) {
|
|
1080
|
-
const parts = [];
|
|
1081
|
-
parts.push(`<w:num w:numId="${decimalNumber(cn.numId)}">`);
|
|
1082
|
-
parts.push(`<w:abstractNumId w:val="${decimalNumber(cn.abstractNumId)}"/>`);
|
|
1083
|
-
if (cn.overrideLevels) for (const level of cn.overrideLevels) if (level.start !== void 0) parts.push(`<w:lvlOverride w:ilvl="${level.num}"><w:startOverride w:val="${level.start}"/></w:lvlOverride>`);
|
|
1084
|
-
else parts.push(`<w:lvlOverride w:ilvl="${level.num}"/>`);
|
|
1085
|
-
parts.push("</w:num>");
|
|
1086
|
-
return parts.join("");
|
|
1087
|
-
}
|
|
1088
|
-
function stringifyLevel(opts) {
|
|
1089
|
-
const children = [];
|
|
1090
|
-
children.push(`<w:start w:val="${decimalNumber(opts.start ?? 1)}"/>`);
|
|
1091
|
-
if (opts.format) children.push(`<w:numFmt w:val="${opts.format}"/>`);
|
|
1092
|
-
if (opts.lvlRestart !== void 0) children.push(`<w:lvlRestart w:val="${decimalNumber(opts.lvlRestart)}"/>`);
|
|
1093
|
-
if (opts.suffix) children.push(`<w:suff w:val="${opts.suffix}"/>`);
|
|
1094
|
-
if (opts.isLegalNumberingStyle) children.push("<w:isLgl/>");
|
|
1095
|
-
if (opts.text) children.push(`<w:lvlText w:val="${opts.text}"/>`);
|
|
1096
|
-
if (opts.lvlPicBulletId !== void 0) children.push(`<w:lvlPicBulletId w:val="${decimalNumber(opts.lvlPicBulletId)}"/>`);
|
|
1097
|
-
if (opts.legacy !== void 0) {
|
|
1098
|
-
const legacyAttrs = [];
|
|
1099
|
-
if (opts.legacy.space !== void 0) legacyAttrs.push(`w:legacySpace="${opts.legacy.space}"`);
|
|
1100
|
-
if (opts.legacy.indent !== void 0) legacyAttrs.push(`w:legacyIndent="${opts.legacy.indent}"`);
|
|
1101
|
-
children.push(`<w:legacy ${legacyAttrs.join(" ")}/>`);
|
|
1102
|
-
}
|
|
1103
|
-
children.push(`<w:lvlJc w:val="${opts.alignment ?? AlignmentType.START}"/>`);
|
|
1104
|
-
const pPrXml = stringifyParagraphProperties(opts.style && opts.style.paragraph).xml;
|
|
1105
|
-
const rPrXml = stringifyRunProperties(opts.style && opts.style.run);
|
|
1106
|
-
if (pPrXml) children.push(pPrXml);
|
|
1107
|
-
if (rPrXml) children.push(rPrXml);
|
|
1108
|
-
const lvlAttrs = [`w:ilvl="${decimalNumber(Math.min(opts.level, 9))}"`, `w15:tentative="1"`];
|
|
1109
|
-
if (opts.templateCode !== void 0) lvlAttrs.push(`w:tplc="${opts.templateCode}"`);
|
|
1110
|
-
if (opts.tentative !== void 0) lvlAttrs.push(`w:tentative="${opts.tentative ? 1 : 0}"`);
|
|
1111
|
-
return `<w:lvl ${lvlAttrs.join(" ")}>${children.join("")}</w:lvl>`;
|
|
1112
|
-
}
|
|
1113
|
-
/**
|
|
1114
|
-
* Parse w:numbering element into NumberingOptions.
|
|
1115
|
-
*/
|
|
1116
|
-
function parseNumberingDefinitions(el) {
|
|
1117
|
-
const abstractNums = /* @__PURE__ */ new Map();
|
|
1118
|
-
for (const child of el.elements ?? []) {
|
|
1119
|
-
if (child.name !== "w:abstractNum") continue;
|
|
1120
|
-
const id = attr(child, "w:abstractNumId");
|
|
1121
|
-
if (id !== void 0) abstractNums.set(id, child);
|
|
1122
|
-
}
|
|
1123
|
-
const numToAbstract = /* @__PURE__ */ new Map();
|
|
1124
|
-
for (const child of el.elements ?? []) {
|
|
1125
|
-
if (child.name !== "w:num") continue;
|
|
1126
|
-
const numId = attr(child, "w:numId");
|
|
1127
|
-
const abstractRef = findChild(child, "w:abstractNumId");
|
|
1128
|
-
const abstractId = abstractRef ? attr(abstractRef, "w:val") : void 0;
|
|
1129
|
-
if (numId !== void 0 && abstractId !== void 0) numToAbstract.set(numId, abstractId);
|
|
1130
|
-
}
|
|
1131
|
-
const configs = [];
|
|
1132
|
-
for (const [numId, abstractId] of numToAbstract) {
|
|
1133
|
-
const abstractEl = abstractNums.get(abstractId);
|
|
1134
|
-
if (!abstractEl) continue;
|
|
1135
|
-
const levels = [];
|
|
1136
|
-
for (const child of abstractEl.elements ?? []) {
|
|
1137
|
-
if (child.name !== "w:lvl") continue;
|
|
1138
|
-
const levelOpts = parseLevelEl(child);
|
|
1139
|
-
if (levelOpts) levels.push(levelOpts);
|
|
1140
|
-
}
|
|
1141
|
-
if (levels.length > 0 && levels.every((l) => l.format === LevelFormat.BULLET)) continue;
|
|
1142
|
-
if (levels.length > 0) configs.push({
|
|
1143
|
-
reference: `list_${numId}`,
|
|
1144
|
-
levels
|
|
1145
|
-
});
|
|
1146
|
-
}
|
|
1147
|
-
if (configs.length === 0) return void 0;
|
|
1148
|
-
return { config: configs };
|
|
1149
|
-
}
|
|
1150
|
-
function parseLevelEl(el) {
|
|
1151
|
-
const opts = {};
|
|
1152
|
-
const level = attrNum(el, "w:ilvl");
|
|
1153
|
-
if (level !== void 0) opts.level = level;
|
|
1154
|
-
const start = findChild(el, "w:start");
|
|
1155
|
-
if (start) {
|
|
1156
|
-
const val = attrNum(start, "w:val");
|
|
1157
|
-
if (val !== void 0) opts.start = val;
|
|
1158
|
-
}
|
|
1159
|
-
const numFmt = findChild(el, "w:numFmt");
|
|
1160
|
-
if (numFmt) {
|
|
1161
|
-
const val = attr(numFmt, "w:val");
|
|
1162
|
-
if (val) opts.format = val;
|
|
1163
|
-
}
|
|
1164
|
-
const lvlText = findChild(el, "w:lvlText");
|
|
1165
|
-
if (lvlText) {
|
|
1166
|
-
const val = attr(lvlText, "w:val");
|
|
1167
|
-
if (val) opts.text = val;
|
|
1168
|
-
}
|
|
1169
|
-
const lvlJc = findChild(el, "w:lvlJc");
|
|
1170
|
-
if (lvlJc) {
|
|
1171
|
-
const val = attr(lvlJc, "w:val");
|
|
1172
|
-
if (val) opts.alignment = val;
|
|
1173
|
-
}
|
|
1174
|
-
const suff = findChild(el, "w:suff");
|
|
1175
|
-
if (suff) {
|
|
1176
|
-
const val = attr(suff, "w:val");
|
|
1177
|
-
if (val) opts.suffix = val;
|
|
1178
|
-
}
|
|
1179
|
-
if (findChild(el, "w:isLgl")) opts.isLegalNumberingStyle = true;
|
|
1180
|
-
const rPr = findChild(el, "w:rPr");
|
|
1181
|
-
if (rPr) {
|
|
1182
|
-
const style = {};
|
|
1183
|
-
const sz = findChild(rPr, "w:sz");
|
|
1184
|
-
if (sz) {
|
|
1185
|
-
const val = attrNum(sz, "w:val");
|
|
1186
|
-
if (val !== void 0) {
|
|
1187
|
-
if (!style.run) style.run = {};
|
|
1188
|
-
style.run.size = val;
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
const rFonts = findChild(rPr, "w:rFonts");
|
|
1192
|
-
if (rFonts) {
|
|
1193
|
-
const ascii = attr(rFonts, "w:ascii");
|
|
1194
|
-
if (ascii) {
|
|
1195
|
-
if (!style.run) style.run = {};
|
|
1196
|
-
style.run.font = ascii;
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
if (Object.keys(style).length > 0) opts.style = style;
|
|
1200
|
-
}
|
|
1201
|
-
const pPr = findChild(el, "w:pPr");
|
|
1202
|
-
if (pPr) {
|
|
1203
|
-
const style = opts.style ?? {};
|
|
1204
|
-
const paraStyle = {};
|
|
1205
|
-
const ind = findChild(pPr, "w:ind");
|
|
1206
|
-
if (ind) {
|
|
1207
|
-
const indent = {};
|
|
1208
|
-
const left = attrNum(ind, "w:left");
|
|
1209
|
-
if (left !== void 0) indent.left = left;
|
|
1210
|
-
const hanging = attrNum(ind, "w:hanging");
|
|
1211
|
-
if (hanging !== void 0) indent.hanging = hanging;
|
|
1212
|
-
if (Object.keys(indent).length > 0) paraStyle.indent = indent;
|
|
1213
|
-
}
|
|
1214
|
-
if (Object.keys(paraStyle).length > 0) {
|
|
1215
|
-
style.paragraph = paraStyle;
|
|
1216
|
-
opts.style = style;
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
return Object.keys(opts).length > 0 ? opts : void 0;
|
|
1220
|
-
}
|
|
1221
|
-
//#endregion
|
|
1222
|
-
//#region src/parts/paragraph/run/run-parse.ts
|
|
1316
|
+
}
|
|
1317
|
+
];
|
|
1223
1318
|
/**
|
|
1224
|
-
*
|
|
1225
|
-
*
|
|
1226
|
-
* Parses w:rPr Element trees into RunPropertiesOptions objects.
|
|
1319
|
+
* Numbering definitions for a WordprocessingML document.
|
|
1227
1320
|
*
|
|
1228
|
-
*
|
|
1229
|
-
|
|
1230
|
-
/**
|
|
1231
|
-
* Parse a w:rPr element into RunPropertiesOptions.
|
|
1321
|
+
* Pure data accumulator — no XmlComponent inheritance.
|
|
1322
|
+
* Serializes via `serialize()` producing a complete XML part.
|
|
1232
1323
|
*/
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1324
|
+
var Numbering = class {
|
|
1325
|
+
abstractNumberingData = /* @__PURE__ */ new Map();
|
|
1326
|
+
concreteNumberingData = /* @__PURE__ */ new Map();
|
|
1327
|
+
referenceConfigMap = /* @__PURE__ */ new Map();
|
|
1328
|
+
abstractNumUniqueNumericId = uniqueNumericIdCreator();
|
|
1329
|
+
concreteNumUniqueNumericId = uniqueNumericIdCreator(1);
|
|
1330
|
+
_numIdMacAtCleanup;
|
|
1331
|
+
_numPicBullets;
|
|
1332
|
+
constructor(options) {
|
|
1333
|
+
this._numIdMacAtCleanup = options.numIdMacAtCleanup;
|
|
1334
|
+
this._numPicBullets = options.numPicBullets;
|
|
1335
|
+
const defaultAbstractId = this.abstractNumUniqueNumericId();
|
|
1336
|
+
this.abstractNumberingData.set("default-bullet-numbering", {
|
|
1337
|
+
id: defaultAbstractId,
|
|
1338
|
+
levels: DEFAULT_BULLET_LEVELS
|
|
1339
|
+
});
|
|
1340
|
+
this.concreteNumberingData.set("default-bullet-numbering", {
|
|
1341
|
+
abstractNumId: defaultAbstractId,
|
|
1342
|
+
instance: 0,
|
|
1343
|
+
numId: 1,
|
|
1344
|
+
overrideLevels: [{
|
|
1345
|
+
num: 0,
|
|
1346
|
+
start: 1
|
|
1347
|
+
}],
|
|
1348
|
+
reference: "default-bullet-numbering"
|
|
1349
|
+
});
|
|
1350
|
+
for (const con of options.config) {
|
|
1351
|
+
this.abstractNumberingData.set(con.reference, {
|
|
1352
|
+
id: this.abstractNumUniqueNumericId(),
|
|
1353
|
+
levels: con.levels
|
|
1354
|
+
});
|
|
1355
|
+
this.referenceConfigMap.set(con.reference, con.levels);
|
|
1256
1356
|
}
|
|
1257
1357
|
}
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
const uType = attr(underline, "w:val");
|
|
1270
|
-
if (uType) ul.type = uType;
|
|
1271
|
-
const uColor = colorAttr(underline, "w:color");
|
|
1272
|
-
if (uColor) ul.color = uColor;
|
|
1273
|
-
opts.underline = ul;
|
|
1274
|
-
}
|
|
1275
|
-
for (const [name, optKey] of [
|
|
1276
|
-
["w:strike", "strike"],
|
|
1277
|
-
["w:dstrike", "doubleStrike"],
|
|
1278
|
-
["w:outline", "outline"],
|
|
1279
|
-
["w:shadow", "shadow"],
|
|
1280
|
-
["w:emboss", "emboss"],
|
|
1281
|
-
["w:imprint", "imprint"],
|
|
1282
|
-
["w:vanish", "vanish"],
|
|
1283
|
-
["w:webHidden", "webHidden"],
|
|
1284
|
-
["w:noProof", "noProof"],
|
|
1285
|
-
["w:snapToGrid", "snapToGrid"],
|
|
1286
|
-
["w:smallCaps", "smallCaps"],
|
|
1287
|
-
["w:caps", "allCaps"],
|
|
1288
|
-
["w:rtl", "rightToLeft"],
|
|
1289
|
-
["w:cs", "complexScript"],
|
|
1290
|
-
["w:specVanish", "specVanish"],
|
|
1291
|
-
["w:math", "math"]
|
|
1292
|
-
]) {
|
|
1293
|
-
const child = findChild(el, name);
|
|
1294
|
-
if (child) opts[optKey] = attrBool(child, "w:val") ?? true;
|
|
1295
|
-
}
|
|
1296
|
-
const color = findChild(el, "w:color");
|
|
1297
|
-
if (color) {
|
|
1298
|
-
const c = colorAttr(color, "w:val");
|
|
1299
|
-
if (c) opts.color = c;
|
|
1300
|
-
}
|
|
1301
|
-
const sz = findChild(el, "w:sz");
|
|
1302
|
-
if (sz) {
|
|
1303
|
-
const halfPts = attrNum(sz, "w:val");
|
|
1304
|
-
if (halfPts !== void 0) opts.size = halfPts / 2;
|
|
1305
|
-
}
|
|
1306
|
-
const szCs = findChild(el, "w:szCs");
|
|
1307
|
-
if (szCs) {
|
|
1308
|
-
const halfPts = attrNum(szCs, "w:val");
|
|
1309
|
-
if (halfPts !== void 0) opts.sizeComplexScript = halfPts / 2;
|
|
1310
|
-
}
|
|
1311
|
-
const highlight = findChild(el, "w:highlight");
|
|
1312
|
-
if (highlight) {
|
|
1313
|
-
const val = attr(highlight, "w:val");
|
|
1314
|
-
if (val) opts.highlight = val;
|
|
1315
|
-
}
|
|
1316
|
-
const highlightCs = findChild(el, "w:highlightCs");
|
|
1317
|
-
if (highlightCs) {
|
|
1318
|
-
const val = attr(highlightCs, "w:val");
|
|
1319
|
-
if (val) opts.highlightComplexScript = val;
|
|
1320
|
-
}
|
|
1321
|
-
const vertAlign = findChild(el, "w:vertAlign");
|
|
1322
|
-
if (vertAlign) {
|
|
1323
|
-
const val = attr(vertAlign, "w:val");
|
|
1324
|
-
if (val === "subscript") opts.subScript = true;
|
|
1325
|
-
else if (val === "superscript") opts.superScript = true;
|
|
1326
|
-
}
|
|
1327
|
-
const effect = findChild(el, "w:effect");
|
|
1328
|
-
if (effect) {
|
|
1329
|
-
const val = attr(effect, "w:val");
|
|
1330
|
-
if (val) opts.effect = val;
|
|
1331
|
-
}
|
|
1332
|
-
const emphasisMark = findChild(el, "w:em");
|
|
1333
|
-
if (emphasisMark) {
|
|
1334
|
-
const val = attr(emphasisMark, "w:val");
|
|
1335
|
-
if (val) opts.emphasisMark = { type: val };
|
|
1336
|
-
}
|
|
1337
|
-
const spacing = findChild(el, "w:spacing");
|
|
1338
|
-
if (spacing) {
|
|
1339
|
-
const val = attrNum(spacing, "w:val");
|
|
1340
|
-
if (val !== void 0) opts.characterSpacing = val;
|
|
1341
|
-
}
|
|
1342
|
-
const scale = findChild(el, "w:w");
|
|
1343
|
-
if (scale) {
|
|
1344
|
-
const val = attrNum(scale, "w:val");
|
|
1345
|
-
if (val !== void 0) opts.scale = val;
|
|
1346
|
-
}
|
|
1347
|
-
const kern = findChild(el, "w:kern");
|
|
1348
|
-
if (kern) {
|
|
1349
|
-
const val = attrNum(kern, "w:val");
|
|
1350
|
-
if (val !== void 0) opts.kern = val;
|
|
1358
|
+
/** Serialize to word/numbering.xml content (with XML declaration). */
|
|
1359
|
+
serialize() {
|
|
1360
|
+
const parts = [];
|
|
1361
|
+
parts.push(`<w:numbering ${NUMBERING_ATTRS}>`);
|
|
1362
|
+
if (this._numPicBullets) for (const bullet of this._numPicBullets) if (bullet.pict) parts.push(`<w:numPicBullet w:numPicBulletId="${bullet.numPicBulletId}">${bullet.pict}</w:numPicBullet>`);
|
|
1363
|
+
else parts.push(`<w:numPicBullet w:numPicBulletId="${bullet.numPicBulletId}"/>`);
|
|
1364
|
+
for (const an of this.abstractNumberingData.values()) parts.push(stringifyAbstractNumbering(an.id, an.levels, an.extraOptions));
|
|
1365
|
+
for (const cn of this.concreteNumberingData.values()) parts.push(stringifyConcreteNumbering(cn));
|
|
1366
|
+
if (this._numIdMacAtCleanup !== void 0) parts.push(`<w:numIdMacAtCleanup w:val="${decimalNumber(this._numIdMacAtCleanup)}"/>`);
|
|
1367
|
+
parts.push("</w:numbering>");
|
|
1368
|
+
return "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + parts.join("");
|
|
1351
1369
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1370
|
+
/**
|
|
1371
|
+
* Creates a concrete numbering instance from an abstract numbering definition.
|
|
1372
|
+
*/
|
|
1373
|
+
createConcreteNumberingInstance(reference, instance) {
|
|
1374
|
+
const abstractNumbering = this.abstractNumberingData.get(reference);
|
|
1375
|
+
if (!abstractNumbering) return;
|
|
1376
|
+
const fullReference = `${reference}-${instance}`;
|
|
1377
|
+
if (this.concreteNumberingData.has(fullReference)) return;
|
|
1378
|
+
const referenceConfigLevels = this.referenceConfigMap.get(reference);
|
|
1379
|
+
const firstLevelStartNumber = referenceConfigLevels && referenceConfigLevels[0].start;
|
|
1380
|
+
this.concreteNumberingData.set(fullReference, {
|
|
1381
|
+
abstractNumId: abstractNumbering.id,
|
|
1382
|
+
instance,
|
|
1383
|
+
numId: this.concreteNumUniqueNumericId(),
|
|
1384
|
+
overrideLevels: [typeof firstLevelStartNumber === "number" && Number.isInteger(firstLevelStartNumber) ? {
|
|
1385
|
+
num: 0,
|
|
1386
|
+
start: firstLevelStartNumber
|
|
1387
|
+
} : {
|
|
1388
|
+
num: 0,
|
|
1389
|
+
start: 1
|
|
1390
|
+
}],
|
|
1391
|
+
reference
|
|
1392
|
+
});
|
|
1356
1393
|
}
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
if (val !== void 0) opts.fitText = val;
|
|
1394
|
+
/** Gets all concrete numbering instances. */
|
|
1395
|
+
get concreteNumbering() {
|
|
1396
|
+
return [...this.concreteNumberingData.values()];
|
|
1361
1397
|
}
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
const val = attr(lang, "w:val");
|
|
1366
|
-
if (val) langObj.val = val;
|
|
1367
|
-
const eastAsia = attr(lang, "w:eastAsia");
|
|
1368
|
-
if (eastAsia) langObj.eastAsia = eastAsia;
|
|
1369
|
-
const bidi = attr(lang, "w:bidi");
|
|
1370
|
-
if (bidi) langObj.bidi = bidi;
|
|
1371
|
-
if (Object.keys(langObj).length > 0) opts.language = langObj;
|
|
1398
|
+
/** Gets all reference configurations. */
|
|
1399
|
+
get referenceConfig() {
|
|
1400
|
+
return [...this.referenceConfigMap.values()];
|
|
1372
1401
|
}
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
const
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
const
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
const color = colorAttr(el, "w:color");
|
|
1387
|
-
if (color) opts.color = color;
|
|
1388
|
-
const size = attrNum(el, "w:sz");
|
|
1389
|
-
if (size !== void 0) opts.size = size;
|
|
1390
|
-
const space = attrNum(el, "w:space");
|
|
1391
|
-
if (space !== void 0) opts.space = space;
|
|
1392
|
-
const shadow = attrBool(el, "w:shadow");
|
|
1393
|
-
if (shadow !== void 0) opts.shadow = shadow;
|
|
1394
|
-
const frame = attrBool(el, "w:frame");
|
|
1395
|
-
if (frame !== void 0) opts.frame = frame;
|
|
1396
|
-
return opts;
|
|
1397
|
-
}
|
|
1398
|
-
/**
|
|
1399
|
-
* Parse a w:shd element into ShadingAttributesProperties.
|
|
1400
|
-
*/
|
|
1401
|
-
function parseShading(el) {
|
|
1402
|
-
const opts = {};
|
|
1403
|
-
const fill = colorAttr(el, "w:fill");
|
|
1404
|
-
if (fill) opts.fill = fill;
|
|
1405
|
-
const color = colorAttr(el, "w:color");
|
|
1406
|
-
if (color) opts.color = color;
|
|
1407
|
-
const type = attr(el, "w:val");
|
|
1408
|
-
if (type) opts.type = type;
|
|
1409
|
-
return opts;
|
|
1402
|
+
};
|
|
1403
|
+
function stringifyAbstractNumbering(id, levels, extraOptions) {
|
|
1404
|
+
const parts = [];
|
|
1405
|
+
parts.push(`<w:abstractNum w:abstractNumId="${decimalNumber(id)}" w15:restartNumberingAfterBreak="0">`);
|
|
1406
|
+
if (extraOptions?.nsid !== void 0) parts.push(`<w:nsid w:val="${extraOptions.nsid}"/>`);
|
|
1407
|
+
parts.push(`<w:multiLevelType w:val="hybridMultilevel"/>`);
|
|
1408
|
+
if (extraOptions?.tmpl !== void 0) parts.push(`<w:tmpl w:val="${extraOptions.tmpl}"/>`);
|
|
1409
|
+
if (extraOptions?.name !== void 0) parts.push(`<w:name w:val="${extraOptions.name}"/>`);
|
|
1410
|
+
if (extraOptions?.styleLink !== void 0) parts.push(`<w:styleLink w:val="${extraOptions.styleLink}"/>`);
|
|
1411
|
+
if (extraOptions?.numStyleLink !== void 0) parts.push(`<w:numStyleLink w:val="${extraOptions.numStyleLink}"/>`);
|
|
1412
|
+
for (const level of levels) parts.push(stringifyLevel(level));
|
|
1413
|
+
parts.push("</w:abstractNum>");
|
|
1414
|
+
return parts.join("");
|
|
1410
1415
|
}
|
|
1411
|
-
|
|
1412
|
-
const
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
/** Matches w:softHyphen */
|
|
1422
|
-
const PARSED_SOFT_HYPHEN = Symbol("SoftHyphen");
|
|
1423
|
-
/** Matches w:footnoteRef — auto-generated by Footnote class */
|
|
1424
|
-
const PARSED_FOOTNOTE_REF = Symbol("FootnoteRef");
|
|
1425
|
-
/** Matches w:br[@w:type="column"] */
|
|
1426
|
-
const PARSED_COLUMN_BREAK = Symbol("ColumnBreak");
|
|
1427
|
-
/** Matches w:dayShort */
|
|
1428
|
-
const PARSED_DAY_SHORT = Symbol("DayShort");
|
|
1429
|
-
/** Matches w:monthShort */
|
|
1430
|
-
const PARSED_MONTH_SHORT = Symbol("MonthShort");
|
|
1431
|
-
/** Matches w:yearShort */
|
|
1432
|
-
const PARSED_YEAR_SHORT = Symbol("YearShort");
|
|
1433
|
-
/** Matches w:dayLong */
|
|
1434
|
-
const PARSED_DAY_LONG = Symbol("DayLong");
|
|
1435
|
-
/** Matches w:monthLong */
|
|
1436
|
-
const PARSED_MONTH_LONG = Symbol("MonthLong");
|
|
1437
|
-
/** Matches w:yearLong */
|
|
1438
|
-
const PARSED_YEAR_LONG = Symbol("YearLong");
|
|
1439
|
-
/** Matches w:annotationRef */
|
|
1440
|
-
const PARSED_ANNOTATION_REF = Symbol("AnnotationRef");
|
|
1441
|
-
/** Matches w:separator */
|
|
1442
|
-
const PARSED_SEPARATOR = Symbol("Separator");
|
|
1443
|
-
/** Matches w:continuationSeparator */
|
|
1444
|
-
const PARSED_CONTINUATION_SEPARATOR = Symbol("ContinuationSeparator");
|
|
1445
|
-
/** Matches w:pgNum */
|
|
1446
|
-
const PARSED_PG_NUM = Symbol("PgNum");
|
|
1447
|
-
/** Matches w:lastRenderedPageBreak */
|
|
1448
|
-
const PARSED_LAST_RENDERED_PAGE_BREAK = Symbol("LastRenderedPageBreak");
|
|
1449
|
-
/**
|
|
1450
|
-
* Parse a w:r element into run data.
|
|
1451
|
-
* Returns { properties, children } where children are parsed run content items.
|
|
1452
|
-
*/
|
|
1453
|
-
function parseRun(el, _ctx) {
|
|
1454
|
-
const rPr = findChild(el, "w:rPr");
|
|
1455
|
-
const properties = rPr ? parseRunProperties(rPr) : void 0;
|
|
1416
|
+
function stringifyConcreteNumbering(cn) {
|
|
1417
|
+
const parts = [];
|
|
1418
|
+
parts.push(`<w:num w:numId="${decimalNumber(cn.numId)}">`);
|
|
1419
|
+
parts.push(`<w:abstractNumId w:val="${decimalNumber(cn.abstractNumId)}"/>`);
|
|
1420
|
+
if (cn.overrideLevels) for (const level of cn.overrideLevels) if (level.start !== void 0) parts.push(`<w:lvlOverride w:ilvl="${level.num}"><w:startOverride w:val="${level.start}"/></w:lvlOverride>`);
|
|
1421
|
+
else parts.push(`<w:lvlOverride w:ilvl="${level.num}"/>`);
|
|
1422
|
+
parts.push("</w:num>");
|
|
1423
|
+
return parts.join("");
|
|
1424
|
+
}
|
|
1425
|
+
function stringifyLevel(opts) {
|
|
1456
1426
|
const children = [];
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
break;
|
|
1470
|
-
}
|
|
1471
|
-
case "w:br": {
|
|
1472
|
-
const brType = attr(child, "w:type");
|
|
1473
|
-
if (brType === "page") children.push(PARSED_PAGE_BREAK);
|
|
1474
|
-
else if (brType === "column") children.push(PARSED_COLUMN_BREAK);
|
|
1475
|
-
else children.push(PARSED_LINE_BREAK);
|
|
1476
|
-
break;
|
|
1477
|
-
}
|
|
1478
|
-
case "w:tab":
|
|
1479
|
-
children.push(PARSED_TAB);
|
|
1480
|
-
break;
|
|
1481
|
-
case "w:cr":
|
|
1482
|
-
children.push(PARSED_CR);
|
|
1483
|
-
break;
|
|
1484
|
-
case "w:noBreakHyphen":
|
|
1485
|
-
children.push(PARSED_NO_BREAK_HYPHEN);
|
|
1486
|
-
break;
|
|
1487
|
-
case "w:softHyphen":
|
|
1488
|
-
children.push(PARSED_SOFT_HYPHEN);
|
|
1489
|
-
break;
|
|
1490
|
-
case "w:commentReference": {
|
|
1491
|
-
const id = attrNum(child, "w:id");
|
|
1492
|
-
if (id !== void 0) children.push({ commentReference: id });
|
|
1493
|
-
break;
|
|
1494
|
-
}
|
|
1495
|
-
case "w:drawing":
|
|
1496
|
-
case "w:pict": break;
|
|
1497
|
-
case "w:sym": {
|
|
1498
|
-
const charVal = attr(child, "w:char");
|
|
1499
|
-
const fontVal = attr(child, "w:font");
|
|
1500
|
-
if (charVal) children.push({ symbolRun: {
|
|
1501
|
-
char: charVal,
|
|
1502
|
-
symbolfont: fontVal ?? "Wingdings"
|
|
1503
|
-
} });
|
|
1504
|
-
break;
|
|
1505
|
-
}
|
|
1506
|
-
case "w:footnoteReference": {
|
|
1507
|
-
const id = attrNum(child, "w:id");
|
|
1508
|
-
if (id !== void 0) children.push({ footnoteReference: id });
|
|
1509
|
-
break;
|
|
1510
|
-
}
|
|
1511
|
-
case "w:endnoteReference": {
|
|
1512
|
-
const id = attrNum(child, "w:id");
|
|
1513
|
-
if (id !== void 0) children.push({ endnoteReference: id });
|
|
1514
|
-
break;
|
|
1515
|
-
}
|
|
1516
|
-
case "w:footnoteRef":
|
|
1517
|
-
case "w:endnoteRef":
|
|
1518
|
-
children.push(PARSED_FOOTNOTE_REF);
|
|
1519
|
-
break;
|
|
1520
|
-
case "w:dayShort":
|
|
1521
|
-
children.push(PARSED_DAY_SHORT);
|
|
1522
|
-
break;
|
|
1523
|
-
case "w:monthShort":
|
|
1524
|
-
children.push(PARSED_MONTH_SHORT);
|
|
1525
|
-
break;
|
|
1526
|
-
case "w:yearShort":
|
|
1527
|
-
children.push(PARSED_YEAR_SHORT);
|
|
1528
|
-
break;
|
|
1529
|
-
case "w:dayLong":
|
|
1530
|
-
children.push(PARSED_DAY_LONG);
|
|
1531
|
-
break;
|
|
1532
|
-
case "w:monthLong":
|
|
1533
|
-
children.push(PARSED_MONTH_LONG);
|
|
1534
|
-
break;
|
|
1535
|
-
case "w:yearLong":
|
|
1536
|
-
children.push(PARSED_YEAR_LONG);
|
|
1537
|
-
break;
|
|
1538
|
-
case "w:annotationRef":
|
|
1539
|
-
children.push(PARSED_ANNOTATION_REF);
|
|
1540
|
-
break;
|
|
1541
|
-
case "w:separator":
|
|
1542
|
-
children.push(PARSED_SEPARATOR);
|
|
1543
|
-
break;
|
|
1544
|
-
case "w:continuationSeparator":
|
|
1545
|
-
children.push(PARSED_CONTINUATION_SEPARATOR);
|
|
1546
|
-
break;
|
|
1547
|
-
case "w:pgNum":
|
|
1548
|
-
children.push(PARSED_PG_NUM);
|
|
1549
|
-
break;
|
|
1550
|
-
case "w:lastRenderedPageBreak":
|
|
1551
|
-
children.push(PARSED_LAST_RENDERED_PAGE_BREAK);
|
|
1552
|
-
break;
|
|
1553
|
-
default: break;
|
|
1427
|
+
children.push(`<w:start w:val="${decimalNumber(opts.start ?? 1)}"/>`);
|
|
1428
|
+
if (opts.format) children.push(`<w:numFmt w:val="${opts.format}"/>`);
|
|
1429
|
+
if (opts.lvlRestart !== void 0) children.push(`<w:lvlRestart w:val="${decimalNumber(opts.lvlRestart)}"/>`);
|
|
1430
|
+
if (opts.suffix) children.push(`<w:suff w:val="${opts.suffix}"/>`);
|
|
1431
|
+
if (opts.isLegalNumberingStyle) children.push("<w:isLgl/>");
|
|
1432
|
+
if (opts.text) children.push(`<w:lvlText w:val="${opts.text}"/>`);
|
|
1433
|
+
if (opts.lvlPicBulletId !== void 0) children.push(`<w:lvlPicBulletId w:val="${decimalNumber(opts.lvlPicBulletId)}"/>`);
|
|
1434
|
+
if (opts.legacy !== void 0) {
|
|
1435
|
+
const legacyAttrs = [];
|
|
1436
|
+
if (opts.legacy.space !== void 0) legacyAttrs.push(`w:legacySpace="${opts.legacy.space}"`);
|
|
1437
|
+
if (opts.legacy.indent !== void 0) legacyAttrs.push(`w:legacyIndent="${opts.legacy.indent}"`);
|
|
1438
|
+
children.push(`<w:legacy ${legacyAttrs.join(" ")}/>`);
|
|
1554
1439
|
}
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1440
|
+
children.push(`<w:lvlJc w:val="${opts.alignment ?? AlignmentType.START}"/>`);
|
|
1441
|
+
const pPrXml = stringifyParagraphProperties(opts.style && opts.style.paragraph).xml;
|
|
1442
|
+
const rPrXml = stringifyRunProperties(opts.style && opts.style.run);
|
|
1443
|
+
if (pPrXml) children.push(pPrXml);
|
|
1444
|
+
if (rPrXml) children.push(rPrXml);
|
|
1445
|
+
const lvlAttrs = [`w:ilvl="${decimalNumber(Math.min(opts.level, 9))}"`, `w15:tentative="1"`];
|
|
1446
|
+
if (opts.templateCode !== void 0) lvlAttrs.push(`w:tplc="${opts.templateCode}"`);
|
|
1447
|
+
if (opts.tentative !== void 0) lvlAttrs.push(`w:tentative="${opts.tentative ? 1 : 0}"`);
|
|
1448
|
+
return `<w:lvl ${lvlAttrs.join(" ")}>${children.join("")}</w:lvl>`;
|
|
1559
1449
|
}
|
|
1560
1450
|
/**
|
|
1561
|
-
*
|
|
1562
|
-
* Simplifies the parsed children into text + break format.
|
|
1563
|
-
* If the run contains only a commentReference, returns { commentReference: id } instead.
|
|
1564
|
-
* If the run only contains footnoteRef/endnoteRef (auto-generated), returns empty options.
|
|
1565
|
-
*
|
|
1566
|
-
* When empty run elements (tab, noBreakHyphen, date fields, etc.) are present,
|
|
1567
|
-
* uses children[] format to preserve them for round-trip fidelity.
|
|
1451
|
+
* Parse w:numbering element into NumberingOptions.
|
|
1568
1452
|
*/
|
|
1569
|
-
|
|
1570
|
-
const
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
[PARSED_DAY_SHORT, { dayShort: true }],
|
|
1576
|
-
[PARSED_MONTH_SHORT, { monthShort: true }],
|
|
1577
|
-
[PARSED_YEAR_SHORT, { yearShort: true }],
|
|
1578
|
-
[PARSED_DAY_LONG, { dayLong: true }],
|
|
1579
|
-
[PARSED_MONTH_LONG, { monthLong: true }],
|
|
1580
|
-
[PARSED_YEAR_LONG, { yearLong: true }],
|
|
1581
|
-
[PARSED_ANNOTATION_REF, { annotationRef: true }],
|
|
1582
|
-
[PARSED_SEPARATOR, { separator: true }],
|
|
1583
|
-
[PARSED_CONTINUATION_SEPARATOR, { continuationSeparator: true }],
|
|
1584
|
-
[PARSED_PG_NUM, { pgNum: true }],
|
|
1585
|
-
[PARSED_LAST_RENDERED_PAGE_BREAK, { lastRenderedPageBreak: true }]
|
|
1586
|
-
]);
|
|
1587
|
-
function parsedRunToOptions(parsed) {
|
|
1588
|
-
const contentChildren = parsed.children.filter((c) => c !== PARSED_FOOTNOTE_REF);
|
|
1589
|
-
if (contentChildren.length === 0 && parsed.children.some((c) => c === PARSED_FOOTNOTE_REF)) return null;
|
|
1590
|
-
const opts = { ...parsed.properties };
|
|
1591
|
-
const isRefChild = (c) => typeof c === "object" && c !== null && ("commentReference" in c || "footnoteReference" in c || "endnoteReference" in c);
|
|
1592
|
-
const refChildren = contentChildren.filter(isRefChild);
|
|
1593
|
-
const nonRefChildren = contentChildren.filter((c) => !isRefChild(c));
|
|
1594
|
-
if (refChildren.length > 0 && nonRefChildren.length === 0) return refChildren[0];
|
|
1595
|
-
const symbolIdx = nonRefChildren.findIndex((c) => typeof c === "object" && c !== null && "symbolRun" in c);
|
|
1596
|
-
if (symbolIdx >= 0 && nonRefChildren.length === 1 && !parsed.properties) return nonRefChildren[symbolIdx];
|
|
1597
|
-
const textParts = [];
|
|
1598
|
-
let breakCount = 0;
|
|
1599
|
-
let hasPageBreak = false;
|
|
1600
|
-
let hasColumnBreak = false;
|
|
1601
|
-
const extraChildren = [];
|
|
1602
|
-
for (const child of nonRefChildren) if (typeof child === "string") textParts.push(child);
|
|
1603
|
-
else if (child === PARSED_LINE_BREAK) breakCount++;
|
|
1604
|
-
else if (child === PARSED_PAGE_BREAK) hasPageBreak = true;
|
|
1605
|
-
else if (child === PARSED_COLUMN_BREAK) hasColumnBreak = true;
|
|
1606
|
-
else {
|
|
1607
|
-
const mapped = SYMBOL_TO_CHILD.get(child);
|
|
1608
|
-
if (mapped) extraChildren.push(mapped);
|
|
1453
|
+
function parseNumberingDefinitions(el, parseParagraphProperties, ctx) {
|
|
1454
|
+
const abstractNums = /* @__PURE__ */ new Map();
|
|
1455
|
+
for (const child of el.elements ?? []) {
|
|
1456
|
+
if (child.name !== "w:abstractNum") continue;
|
|
1457
|
+
const id = attr(child, "w:abstractNumId");
|
|
1458
|
+
if (id !== void 0) abstractNums.set(id, child);
|
|
1609
1459
|
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1460
|
+
const numToAbstract = /* @__PURE__ */ new Map();
|
|
1461
|
+
for (const child of el.elements ?? []) {
|
|
1462
|
+
if (child.name !== "w:num") continue;
|
|
1463
|
+
const numId = attr(child, "w:numId");
|
|
1464
|
+
const abstractRef = findChild(child, "w:abstractNumId");
|
|
1465
|
+
const abstractId = abstractRef ? attr(abstractRef, "w:val") : void 0;
|
|
1466
|
+
if (numId !== void 0 && abstractId !== void 0) numToAbstract.set(numId, abstractId);
|
|
1467
|
+
}
|
|
1468
|
+
const configs = [];
|
|
1469
|
+
for (const [numId, abstractId] of numToAbstract) {
|
|
1470
|
+
const abstractEl = abstractNums.get(abstractId);
|
|
1471
|
+
if (!abstractEl) continue;
|
|
1472
|
+
const levels = [];
|
|
1473
|
+
for (const child of abstractEl.elements ?? []) {
|
|
1474
|
+
if (child.name !== "w:lvl") continue;
|
|
1475
|
+
const levelOpts = parseLevelEl(child, parseParagraphProperties, ctx);
|
|
1476
|
+
if (levelOpts) levels.push(levelOpts);
|
|
1619
1477
|
}
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
if (hasColumnBreak) opts.columnBreak = true;
|
|
1478
|
+
if (levels.length > 0 && levels.every((l) => l.format === LevelFormat.BULLET)) continue;
|
|
1479
|
+
if (levels.length > 0) configs.push({
|
|
1480
|
+
reference: `list_${numId}`,
|
|
1481
|
+
levels
|
|
1482
|
+
});
|
|
1626
1483
|
}
|
|
1627
|
-
if (
|
|
1628
|
-
return
|
|
1484
|
+
if (configs.length === 0) return void 0;
|
|
1485
|
+
return { config: configs };
|
|
1486
|
+
}
|
|
1487
|
+
function parseLevelEl(el, parseParagraphProperties, ctx) {
|
|
1488
|
+
const opts = {};
|
|
1489
|
+
const level = attrNum(el, "w:ilvl");
|
|
1490
|
+
if (level !== void 0) opts.level = level;
|
|
1491
|
+
const start = findChild(el, "w:start");
|
|
1492
|
+
if (start) {
|
|
1493
|
+
const val = attrNum(start, "w:val");
|
|
1494
|
+
if (val !== void 0) opts.start = val;
|
|
1495
|
+
}
|
|
1496
|
+
const lvlRestart = findChild(el, "w:lvlRestart");
|
|
1497
|
+
if (lvlRestart) {
|
|
1498
|
+
const val = attrNum(lvlRestart, "w:val");
|
|
1499
|
+
if (val !== void 0) opts.lvlRestart = val;
|
|
1500
|
+
}
|
|
1501
|
+
const numFmt = findChild(el, "w:numFmt");
|
|
1502
|
+
if (numFmt) {
|
|
1503
|
+
const val = attr(numFmt, "w:val");
|
|
1504
|
+
if (val) opts.format = val;
|
|
1505
|
+
}
|
|
1506
|
+
const suff = findChild(el, "w:suff");
|
|
1507
|
+
if (suff) {
|
|
1508
|
+
const val = attr(suff, "w:val");
|
|
1509
|
+
if (val) opts.suffix = val;
|
|
1510
|
+
}
|
|
1511
|
+
if (findChild(el, "w:isLgl")) opts.isLegalNumberingStyle = true;
|
|
1512
|
+
const lvlText = findChild(el, "w:lvlText");
|
|
1513
|
+
if (lvlText) {
|
|
1514
|
+
const val = attr(lvlText, "w:val");
|
|
1515
|
+
if (val) opts.text = val;
|
|
1516
|
+
}
|
|
1517
|
+
const lvlPicBulletId = findChild(el, "w:lvlPicBulletId");
|
|
1518
|
+
if (lvlPicBulletId) {
|
|
1519
|
+
const val = attrNum(lvlPicBulletId, "w:val");
|
|
1520
|
+
if (val !== void 0) opts.lvlPicBulletId = val;
|
|
1521
|
+
}
|
|
1522
|
+
const legacyEl = findChild(el, "w:legacy");
|
|
1523
|
+
if (legacyEl) {
|
|
1524
|
+
const legacy = {};
|
|
1525
|
+
const space = attrNum(legacyEl, "w:legacySpace");
|
|
1526
|
+
if (space !== void 0) legacy.space = space;
|
|
1527
|
+
const indent = attrNum(legacyEl, "w:legacyIndent");
|
|
1528
|
+
if (indent !== void 0) legacy.indent = indent;
|
|
1529
|
+
if (Object.keys(legacy).length > 0) opts.legacy = legacy;
|
|
1530
|
+
}
|
|
1531
|
+
const lvlJc = findChild(el, "w:lvlJc");
|
|
1532
|
+
if (lvlJc) {
|
|
1533
|
+
const val = attr(lvlJc, "w:val");
|
|
1534
|
+
if (val) opts.alignment = val;
|
|
1535
|
+
}
|
|
1536
|
+
const tplc = attr(el, "w:tplc");
|
|
1537
|
+
if (tplc) opts.templateCode = tplc;
|
|
1538
|
+
const tentative = attrBool(el, "w:tentative");
|
|
1539
|
+
if (tentative !== void 0) opts.tentative = tentative;
|
|
1540
|
+
const style = {};
|
|
1541
|
+
const rPr = findChild(el, "w:rPr");
|
|
1542
|
+
if (rPr) {
|
|
1543
|
+
const runOpts = parseRunProperties(rPr);
|
|
1544
|
+
if (Object.keys(runOpts).length > 0) style.run = runOpts;
|
|
1545
|
+
}
|
|
1546
|
+
const pPr = findChild(el, "w:pPr");
|
|
1547
|
+
if (pPr) {
|
|
1548
|
+
const paraOpts = parseParagraphProperties(pPr, ctx);
|
|
1549
|
+
if (Object.keys(paraOpts).length > 0) style.paragraph = paraOpts;
|
|
1550
|
+
}
|
|
1551
|
+
if (Object.keys(style).length > 0) opts.style = style;
|
|
1552
|
+
return Object.keys(opts).length > 0 ? opts : void 0;
|
|
1629
1553
|
}
|
|
1630
1554
|
//#endregion
|
|
1631
1555
|
//#region src/parts/styles/factory.ts
|
|
@@ -2034,7 +1958,7 @@ function buildNumberingCache(numberingEl) {
|
|
|
2034
1958
|
return cache;
|
|
2035
1959
|
}
|
|
2036
1960
|
/**
|
|
2037
|
-
* Parse w:styles element into StylesOptions
|
|
1961
|
+
* Parse w:styles element into StylesOptions.
|
|
2038
1962
|
*
|
|
2039
1963
|
* Skips built-in styles that DefaultStylesFactory already generates,
|
|
2040
1964
|
* keeping only user-defined custom styles for round-trip fidelity.
|
|
@@ -2044,13 +1968,12 @@ function parseStyleDefinitions(el, parseParagraphProperties, ctx) {
|
|
|
2044
1968
|
const paragraphStyles = [];
|
|
2045
1969
|
const characterStyles = [];
|
|
2046
1970
|
for (const child of el.elements ?? []) if (child.name === "w:docDefaults") {
|
|
2047
|
-
const defOpts = parseDocDefaults(child);
|
|
1971
|
+
const defOpts = parseDocDefaults(child, parseParagraphProperties, ctx);
|
|
2048
1972
|
if (defOpts) opts.default = defOpts;
|
|
2049
1973
|
} else if (child.name === "w:style") {
|
|
2050
1974
|
const styleOpts = parseStyleElement(child, parseParagraphProperties, ctx);
|
|
2051
|
-
if (!styleOpts) continue;
|
|
2052
|
-
|
|
2053
|
-
if (styleId && BUILTIN_STYLE_IDS.has(styleId)) continue;
|
|
1975
|
+
if (!styleOpts?._type || !styleOpts.id) continue;
|
|
1976
|
+
if (BUILTIN_STYLE_IDS.has(styleOpts.id)) continue;
|
|
2054
1977
|
const type = styleOpts._type;
|
|
2055
1978
|
delete styleOpts._type;
|
|
2056
1979
|
if (type === "paragraph") paragraphStyles.push(styleOpts);
|
|
@@ -2060,38 +1983,25 @@ function parseStyleDefinitions(el, parseParagraphProperties, ctx) {
|
|
|
2060
1983
|
if (characterStyles.length > 0) opts.characterStyles = characterStyles;
|
|
2061
1984
|
return Object.keys(opts).length > 0 ? opts : void 0;
|
|
2062
1985
|
}
|
|
2063
|
-
function parseDocDefaults(el) {
|
|
2064
|
-
const
|
|
2065
|
-
const docDefaults = {};
|
|
1986
|
+
function parseDocDefaults(el, parseParagraphProperties, ctx) {
|
|
1987
|
+
const document = {};
|
|
2066
1988
|
const rPrDefault = findChild(el, "w:rPrDefault");
|
|
2067
1989
|
if (rPrDefault) {
|
|
2068
1990
|
const rPr = findChild(rPrDefault, "w:rPr");
|
|
2069
1991
|
if (rPr) {
|
|
2070
1992
|
const runDefaults = parseRunProperties(rPr);
|
|
2071
|
-
if (Object.keys(runDefaults).length > 0)
|
|
1993
|
+
if (Object.keys(runDefaults).length > 0) document.run = runDefaults;
|
|
2072
1994
|
}
|
|
2073
1995
|
}
|
|
2074
1996
|
const pPrDefault = findChild(el, "w:pPrDefault");
|
|
2075
1997
|
if (pPrDefault) {
|
|
2076
1998
|
const pPr = findChild(pPrDefault, "w:pPr");
|
|
2077
1999
|
if (pPr) {
|
|
2078
|
-
const paraDefaults =
|
|
2079
|
-
|
|
2080
|
-
if (spacing) {
|
|
2081
|
-
const sp = {};
|
|
2082
|
-
const before = attrNum(spacing, "w:before");
|
|
2083
|
-
if (before !== void 0) sp.before = before;
|
|
2084
|
-
const after = attrNum(spacing, "w:after");
|
|
2085
|
-
if (after !== void 0) sp.after = after;
|
|
2086
|
-
const line = attrNum(spacing, "w:line");
|
|
2087
|
-
if (line !== void 0) sp.line = line;
|
|
2088
|
-
if (Object.keys(sp).length > 0) paraDefaults.spacing = sp;
|
|
2089
|
-
}
|
|
2090
|
-
if (Object.keys(paraDefaults).length > 0) docDefaults.paragraph = paraDefaults;
|
|
2000
|
+
const paraDefaults = parseParagraphProperties(pPr, ctx);
|
|
2001
|
+
if (Object.keys(paraDefaults).length > 0) document.paragraph = paraDefaults;
|
|
2091
2002
|
}
|
|
2092
2003
|
}
|
|
2093
|
-
|
|
2094
|
-
return Object.keys(result).length > 0 ? result : void 0;
|
|
2004
|
+
return Object.keys(document).length > 0 ? { document } : void 0;
|
|
2095
2005
|
}
|
|
2096
2006
|
function parseStyleElement(el, parseParagraphProperties, ctx) {
|
|
2097
2007
|
const opts = {};
|
|
@@ -2195,6 +2105,14 @@ function compatSetting(name, val) {
|
|
|
2195
2105
|
function maybeDerive(password, hashValue) {
|
|
2196
2106
|
return password !== void 0 && hashValue === void 0 ? derivePasswordHash(password) : void 0;
|
|
2197
2107
|
}
|
|
2108
|
+
/** Valid w:documentProtection/@w:edit values (ST_DocProtect). */
|
|
2109
|
+
const DOC_PROTECT_EDITS = [
|
|
2110
|
+
"none",
|
|
2111
|
+
"readOnly",
|
|
2112
|
+
"comments",
|
|
2113
|
+
"trackedChanges",
|
|
2114
|
+
"forms"
|
|
2115
|
+
];
|
|
2198
2116
|
function stringifyDocProtect(opts) {
|
|
2199
2117
|
const derived = maybeDerive(opts.password, opts.hashValue);
|
|
2200
2118
|
const attrs = { "w:enforcement": "1" };
|
|
@@ -2540,7 +2458,7 @@ const settingsDesc = {
|
|
|
2540
2458
|
p.push(onOff("w:autoFormatOverride", opts.autoFormatOverride));
|
|
2541
2459
|
p.push(onOff("w:styleLockTheme", opts.styleLockTheme));
|
|
2542
2460
|
p.push(onOff("w:styleLockQFSet", opts.styleLockQFSet));
|
|
2543
|
-
p.push(numVal("w:defaultTabStop", opts.defaultTabStop
|
|
2461
|
+
if (opts.defaultTabStop !== void 0) p.push(numVal("w:defaultTabStop", opts.defaultTabStop));
|
|
2544
2462
|
p.push(onOff("w:autoHyphenation", opts.hyphenation?.autoHyphenation));
|
|
2545
2463
|
p.push(numVal("w:consecutiveHyphenLimit", opts.hyphenation?.consecutiveHyphenLimit));
|
|
2546
2464
|
p.push(numVal("w:hyphenationZone", opts.hyphenation?.hyphenationZone));
|
|
@@ -2561,7 +2479,7 @@ const settingsDesc = {
|
|
|
2561
2479
|
p.push(numVal("w:drawingGridVerticalOrigin", opts.drawingGridVerticalOrigin));
|
|
2562
2480
|
p.push(onOff("w:doNotUseMarginsForDrawingGridOrigin", opts.doNotUseMarginsForDrawingGridOrigin));
|
|
2563
2481
|
p.push(onOff("w:doNotShadeFormData", opts.doNotShadeFormData));
|
|
2564
|
-
p.push(strVal("w:characterSpacingControl", opts.characterSpacingControl
|
|
2482
|
+
if (opts.characterSpacingControl !== void 0) p.push(strVal("w:characterSpacingControl", opts.characterSpacingControl));
|
|
2565
2483
|
p.push(onOff("w:noPunctuationKerning", opts.noPunctuationKerning));
|
|
2566
2484
|
p.push(onOff("w:printTwoOnOne", opts.printTwoOnOne));
|
|
2567
2485
|
p.push(onOff("w:strictFirstAndLastChars", opts.strictFirstAndLastChars));
|
|
@@ -2598,20 +2516,11 @@ const settingsDesc = {
|
|
|
2598
2516
|
if (opts.hdrShapeDefaults !== void 0) p.push("<w:hdrShapeDefaults/>");
|
|
2599
2517
|
if (opts.footnotePr !== void 0) p.push(stringifyFootnotePr(opts.footnotePr));
|
|
2600
2518
|
if (opts.endnotePr !== void 0) p.push(stringifyEndnotePr(opts.endnotePr));
|
|
2601
|
-
|
|
2519
|
+
const compatXml = stringifyCompatibility({
|
|
2602
2520
|
...opts.compatibility,
|
|
2603
|
-
version: opts.compatibility?.version ?? opts.compatibilityModeVersion
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
doNotLeaveBackslashAlone: opts.compatibility?.doNotLeaveBackslashAlone ?? true,
|
|
2607
|
-
underlineTrailingSpaces: opts.compatibility?.underlineTrailingSpaces ?? true,
|
|
2608
|
-
doNotExpandShiftReturn: opts.compatibility?.doNotExpandShiftReturn ?? true,
|
|
2609
|
-
adjustLineHeightInTable: opts.compatibility?.adjustLineHeightInTable ?? true,
|
|
2610
|
-
useFELayout: opts.compatibility?.useFELayout ?? true,
|
|
2611
|
-
overrideTableStyleFontSizeAndJustification: opts.compatibility?.overrideTableStyleFontSizeAndJustification ?? true,
|
|
2612
|
-
enableOpenTypeFeatures: opts.compatibility?.enableOpenTypeFeatures ?? true,
|
|
2613
|
-
doNotFlipMirrorIndents: opts.compatibility?.doNotFlipMirrorIndents ?? true
|
|
2614
|
-
}));
|
|
2521
|
+
version: opts.compatibility?.version ?? opts.compatibilityModeVersion
|
|
2522
|
+
});
|
|
2523
|
+
if (compatXml) p.push(compatXml);
|
|
2615
2524
|
if (opts.docVars?.length) {
|
|
2616
2525
|
const vars = opts.docVars.map((v) => attrEl("w:docVar", {
|
|
2617
2526
|
"w:name": v.name,
|
|
@@ -2669,14 +2578,16 @@ const settingsDesc = {
|
|
|
2669
2578
|
const val = attr(tabStopEl, "w:val");
|
|
2670
2579
|
if (val) opts.defaultTabStop = parseInt(val, 10);
|
|
2671
2580
|
}
|
|
2672
|
-
|
|
2581
|
+
const trackRevEl = findChild(el, "w:trackRevisions");
|
|
2582
|
+
if (trackRevEl) {
|
|
2673
2583
|
const features = opts.features ?? {};
|
|
2674
|
-
features.trackRevisions = true;
|
|
2584
|
+
features.trackRevisions = attrBool(trackRevEl, "w:val") ?? true;
|
|
2675
2585
|
opts.features = features;
|
|
2676
2586
|
}
|
|
2677
|
-
|
|
2587
|
+
const updateFieldsEl = findChild(el, "w:updateFields");
|
|
2588
|
+
if (updateFieldsEl) {
|
|
2678
2589
|
const features = opts.features ?? {};
|
|
2679
|
-
features.updateFields = true;
|
|
2590
|
+
features.updateFields = attrBool(updateFieldsEl, "w:val") ?? true;
|
|
2680
2591
|
opts.features = features;
|
|
2681
2592
|
}
|
|
2682
2593
|
const compatEl = findChild(el, "w:compat");
|
|
@@ -2833,7 +2744,7 @@ const settingsDesc = {
|
|
|
2833
2744
|
if (docProtEl) {
|
|
2834
2745
|
const prot = {};
|
|
2835
2746
|
const edit = attr(docProtEl, "w:edit");
|
|
2836
|
-
if (edit) prot.edit = edit;
|
|
2747
|
+
if (edit && DOC_PROTECT_EDITS.includes(edit)) prot.edit = edit;
|
|
2837
2748
|
if (attr(docProtEl, "w:enforcement") !== void 0) {
|
|
2838
2749
|
const hash = attr(docProtEl, "w:hash");
|
|
2839
2750
|
if (hash) prot.hash = hash;
|
|
@@ -2860,10 +2771,16 @@ const settingsDesc = {
|
|
|
2860
2771
|
const formatting = attr(docProtEl, "w:formatting");
|
|
2861
2772
|
if (formatting !== void 0) prot.formatting = formatting === "1" || formatting === "true";
|
|
2862
2773
|
}
|
|
2863
|
-
if (Object.keys(prot).length > 0)
|
|
2774
|
+
if (Object.keys(prot).length > 0) {
|
|
2775
|
+
const features = opts.features ?? {};
|
|
2776
|
+
features.documentProtection = prot;
|
|
2777
|
+
opts.features = features;
|
|
2778
|
+
}
|
|
2864
2779
|
}
|
|
2865
|
-
|
|
2866
|
-
if (
|
|
2780
|
+
const noMovesEl = findChild(el, "w:doNotTrackMoves");
|
|
2781
|
+
if (noMovesEl) opts.doNotTrackMoves = attrBool(noMovesEl, "w:val") ?? true;
|
|
2782
|
+
const noFmtEl = findChild(el, "w:doNotTrackFormatting");
|
|
2783
|
+
if (noFmtEl) opts.doNotTrackFormatting = attrBool(noFmtEl, "w:val") ?? true;
|
|
2867
2784
|
return opts;
|
|
2868
2785
|
}
|
|
2869
2786
|
};
|
|
@@ -3001,6 +2918,19 @@ function parseTocFieldInstruction(instruction, opts) {
|
|
|
3001
2918
|
if (switches["o"]) opts.headingStyleRange = switches["o"];
|
|
3002
2919
|
if (switches["p"]) opts.entryAndPageNumberSeparator = switches["p"];
|
|
3003
2920
|
if (switches["s"]) opts.seqFieldIdentifierForPrefix = switches["s"];
|
|
2921
|
+
if (switches["t"]) {
|
|
2922
|
+
const parts = switches["t"].split(",");
|
|
2923
|
+
const stylesWithLevels = [];
|
|
2924
|
+
for (let i = 0; i + 1 < parts.length; i += 2) {
|
|
2925
|
+
const styleName = parts[i];
|
|
2926
|
+
const level = parseInt(parts[i + 1], 10);
|
|
2927
|
+
if (styleName && !Number.isNaN(level)) stylesWithLevels.push({
|
|
2928
|
+
styleName,
|
|
2929
|
+
level
|
|
2930
|
+
});
|
|
2931
|
+
}
|
|
2932
|
+
if (stylesWithLevels.length > 0) opts.stylesWithLevels = stylesWithLevels;
|
|
2933
|
+
}
|
|
3004
2934
|
if ("u" in switches) opts.useAppliedParagraphOutlineLevel = true;
|
|
3005
2935
|
if ("w" in switches) opts.preserveTabInEntries = true;
|
|
3006
2936
|
if ("x" in switches) opts.preserveNewLineInEntries = true;
|
|
@@ -3365,6 +3295,22 @@ const HEADING_MAP = {
|
|
|
3365
3295
|
Heading6: HeadingLevel.HEADING_6,
|
|
3366
3296
|
Title: HeadingLevel.TITLE
|
|
3367
3297
|
};
|
|
3298
|
+
/** Valid w:spacing/@w:lineRule values (ST_LineSpacingRule). */
|
|
3299
|
+
const LINE_RULES = Object.values(LineRuleType);
|
|
3300
|
+
/** Valid border @w:val values (ST_Border). */
|
|
3301
|
+
const BORDER_STYLES = Object.values(BorderStyle);
|
|
3302
|
+
/** Valid border @w:themeColor values (ST_ThemeColor). */
|
|
3303
|
+
const THEME_COLORS = Object.values(ThemeColor);
|
|
3304
|
+
/**
|
|
3305
|
+
* Reverse of inline.ts's deleted-page-number field map: maps a w:delInstrText
|
|
3306
|
+
* field code to the PageNumber placeholder a deletion run uses on the stringify
|
|
3307
|
+
* side, so deleted page-number fields round-trip instead of being dropped.
|
|
3308
|
+
*/
|
|
3309
|
+
const DELETED_PAGE_FIELD = {
|
|
3310
|
+
PAGE: "CURRENT",
|
|
3311
|
+
NUMPAGES: "TOTAL_PAGES",
|
|
3312
|
+
SECTIONPAGES: "TOTAL_PAGES_IN_SECTION"
|
|
3313
|
+
};
|
|
3368
3314
|
/**
|
|
3369
3315
|
* Parse w:pPr element into paragraph properties (without children).
|
|
3370
3316
|
*/
|
|
@@ -3391,11 +3337,15 @@ function parseParagraphProperties(el, ctx) {
|
|
|
3391
3337
|
const line = attrNum(spacing, "w:line");
|
|
3392
3338
|
if (line !== void 0) sp.line = line;
|
|
3393
3339
|
const lineRule = attr(spacing, "w:lineRule");
|
|
3394
|
-
if (lineRule) sp.lineRule = lineRule;
|
|
3395
|
-
const
|
|
3396
|
-
if (
|
|
3397
|
-
const
|
|
3398
|
-
if (
|
|
3340
|
+
if (lineRule && LINE_RULES.includes(lineRule)) sp.lineRule = lineRule;
|
|
3341
|
+
const beforeAutoSpacing = attrBool(spacing, "w:beforeAutospacing");
|
|
3342
|
+
if (beforeAutoSpacing !== void 0) sp.beforeAutoSpacing = beforeAutoSpacing;
|
|
3343
|
+
const afterAutoSpacing = attrBool(spacing, "w:afterAutospacing");
|
|
3344
|
+
if (afterAutoSpacing !== void 0) sp.afterAutoSpacing = afterAutoSpacing;
|
|
3345
|
+
const beforeLines = attrNum(spacing, "w:beforeLines");
|
|
3346
|
+
if (beforeLines !== void 0) sp.beforeLines = beforeLines;
|
|
3347
|
+
const afterLines = attrNum(spacing, "w:afterLines");
|
|
3348
|
+
if (afterLines !== void 0) sp.afterLines = afterLines;
|
|
3399
3349
|
if (Object.keys(sp).length > 0) opts.spacing = sp;
|
|
3400
3350
|
}
|
|
3401
3351
|
const ind = findChild(el, "w:ind");
|
|
@@ -3403,16 +3353,28 @@ function parseParagraphProperties(el, ctx) {
|
|
|
3403
3353
|
const indentObj = {};
|
|
3404
3354
|
const left = attrNum(ind, "w:left");
|
|
3405
3355
|
if (left !== void 0) indentObj.left = left;
|
|
3356
|
+
const leftChars = attrNum(ind, "w:leftChars");
|
|
3357
|
+
if (leftChars !== void 0) indentObj.leftChars = leftChars;
|
|
3406
3358
|
const right = attrNum(ind, "w:right");
|
|
3407
3359
|
if (right !== void 0) indentObj.right = right;
|
|
3360
|
+
const rightChars = attrNum(ind, "w:rightChars");
|
|
3361
|
+
if (rightChars !== void 0) indentObj.rightChars = rightChars;
|
|
3408
3362
|
const start = attrNum(ind, "w:start");
|
|
3409
3363
|
if (start !== void 0) indentObj.start = start;
|
|
3364
|
+
const startChars = attrNum(ind, "w:startChars");
|
|
3365
|
+
if (startChars !== void 0) indentObj.startChars = startChars;
|
|
3410
3366
|
const end = attrNum(ind, "w:end");
|
|
3411
3367
|
if (end !== void 0) indentObj.end = end;
|
|
3368
|
+
const endChars = attrNum(ind, "w:endChars");
|
|
3369
|
+
if (endChars !== void 0) indentObj.endChars = endChars;
|
|
3412
3370
|
const hanging = attrNum(ind, "w:hanging");
|
|
3413
3371
|
if (hanging !== void 0) indentObj.hanging = hanging;
|
|
3372
|
+
const hangingChars = attrNum(ind, "w:hangingChars");
|
|
3373
|
+
if (hangingChars !== void 0) indentObj.hangingChars = hangingChars;
|
|
3414
3374
|
const firstLine = attrNum(ind, "w:firstLine");
|
|
3415
3375
|
if (firstLine !== void 0) indentObj.firstLine = firstLine;
|
|
3376
|
+
const firstLineChars = attrNum(ind, "w:firstLineChars");
|
|
3377
|
+
if (firstLineChars !== void 0) indentObj.firstLineChars = firstLineChars;
|
|
3416
3378
|
if (Object.keys(indentObj).length > 0) opts.indent = indentObj;
|
|
3417
3379
|
}
|
|
3418
3380
|
const numPr = findChild(el, "w:numPr");
|
|
@@ -3473,6 +3435,7 @@ function parseParagraphProperties(el, ctx) {
|
|
|
3473
3435
|
["w:kinsoku", "kinsoku"],
|
|
3474
3436
|
["w:topLinePunct", "topLinePunct"],
|
|
3475
3437
|
["w:autoSpaceDE", "autoSpaceDE"],
|
|
3438
|
+
["w:autoSpaceDN", "autoSpaceEastAsianText"],
|
|
3476
3439
|
["w:overflowPunct", "overflowPunctuation"],
|
|
3477
3440
|
["w:suppressOverlap", "suppressOverlap"]
|
|
3478
3441
|
]) {
|
|
@@ -3486,21 +3449,32 @@ function parseParagraphProperties(el, ctx) {
|
|
|
3486
3449
|
"top",
|
|
3487
3450
|
"bottom",
|
|
3488
3451
|
"left",
|
|
3489
|
-
"right"
|
|
3452
|
+
"right",
|
|
3453
|
+
"between",
|
|
3454
|
+
"bar"
|
|
3490
3455
|
]) {
|
|
3491
3456
|
const sideEl = findChild(pBdr, `w:${side}`);
|
|
3492
|
-
if (sideEl)
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3457
|
+
if (!sideEl) continue;
|
|
3458
|
+
const style = attr(sideEl, "w:val");
|
|
3459
|
+
if (!style || !BORDER_STYLES.includes(style)) continue;
|
|
3460
|
+
const sideOpts = { style };
|
|
3461
|
+
const color = attr(sideEl, "w:color");
|
|
3462
|
+
if (color) sideOpts.color = color;
|
|
3463
|
+
const size = attrNum(sideEl, "w:sz");
|
|
3464
|
+
if (size !== void 0) sideOpts.size = size;
|
|
3465
|
+
const space = attrNum(sideEl, "w:space");
|
|
3466
|
+
if (space !== void 0) sideOpts.space = space;
|
|
3467
|
+
const themeColor = attr(sideEl, "w:themeColor");
|
|
3468
|
+
if (themeColor && THEME_COLORS.includes(themeColor)) sideOpts.themeColor = themeColor;
|
|
3469
|
+
const themeTint = attr(sideEl, "w:themeTint");
|
|
3470
|
+
if (themeTint) sideOpts.themeTint = themeTint;
|
|
3471
|
+
const themeShade = attr(sideEl, "w:themeShade");
|
|
3472
|
+
if (themeShade) sideOpts.themeShade = themeShade;
|
|
3473
|
+
const shadow = attrBool(sideEl, "w:shadow");
|
|
3474
|
+
if (shadow !== void 0) sideOpts.shadow = shadow;
|
|
3475
|
+
const frame = attrBool(sideEl, "w:frame");
|
|
3476
|
+
if (frame !== void 0) sideOpts.frame = frame;
|
|
3477
|
+
border[side] = sideOpts;
|
|
3504
3478
|
}
|
|
3505
3479
|
if (Object.keys(border).length > 0) opts.border = border;
|
|
3506
3480
|
}
|
|
@@ -3545,6 +3519,24 @@ function parseParagraphProperties(el, ctx) {
|
|
|
3545
3519
|
const val = attr(framePr, attrName);
|
|
3546
3520
|
if (val !== void 0) frame[optName] = val;
|
|
3547
3521
|
}
|
|
3522
|
+
const xAlign = attr(framePr, "w:xAlign");
|
|
3523
|
+
const yAlign = attr(framePr, "w:yAlign");
|
|
3524
|
+
if (xAlign || yAlign) {
|
|
3525
|
+
const alignment = {};
|
|
3526
|
+
if (xAlign) alignment.x = xAlign;
|
|
3527
|
+
if (yAlign) alignment.y = yAlign;
|
|
3528
|
+
frame.alignment = alignment;
|
|
3529
|
+
}
|
|
3530
|
+
const hAnchor = attr(framePr, "w:hAnchor");
|
|
3531
|
+
const vAnchor = attr(framePr, "w:vAnchor");
|
|
3532
|
+
if (hAnchor || vAnchor) {
|
|
3533
|
+
const anchor = {};
|
|
3534
|
+
if (hAnchor) anchor.horizontal = hAnchor;
|
|
3535
|
+
if (vAnchor) anchor.vertical = vAnchor;
|
|
3536
|
+
frame.anchor = anchor;
|
|
3537
|
+
}
|
|
3538
|
+
const anchorLock = attrBool(framePr, "w:anchorLock");
|
|
3539
|
+
if (anchorLock !== void 0) frame.anchorLock = anchorLock;
|
|
3548
3540
|
const w = attrNum(framePr, "w:w");
|
|
3549
3541
|
if (w !== void 0) frame.width = w;
|
|
3550
3542
|
const h = attrNum(framePr, "w:h");
|
|
@@ -3554,6 +3546,136 @@ function parseParagraphProperties(el, ctx) {
|
|
|
3554
3546
|
return opts;
|
|
3555
3547
|
}
|
|
3556
3548
|
/**
|
|
3549
|
+
* Concatenate `<w:t>` text in a run element.
|
|
3550
|
+
*
|
|
3551
|
+
* Used to capture a textInput form field's current value from the result run
|
|
3552
|
+
* (the runs between the `separate` and `end` fldChars). Only `<w:t>` is read —
|
|
3553
|
+
* `<w:tab>`/`<w:br>` in results are ignored as rare for user-entered text.
|
|
3554
|
+
*/
|
|
3555
|
+
function collectRunText(el) {
|
|
3556
|
+
let text = "";
|
|
3557
|
+
for (const c of el.elements ?? []) if (c.name === "w:t") text += textOf(c);
|
|
3558
|
+
return text;
|
|
3559
|
+
}
|
|
3560
|
+
/** Concatenate `<w:t>` text across all `<w:r>` children of a container (rt/rubyBase). */
|
|
3561
|
+
function collectRunsText(el) {
|
|
3562
|
+
let text = "";
|
|
3563
|
+
for (const r of el.elements ?? []) if (r.name === "w:r") text += collectRunText(r);
|
|
3564
|
+
return text;
|
|
3565
|
+
}
|
|
3566
|
+
/**
|
|
3567
|
+
* Parse the inline children of a smartTag/customXml container (recursive).
|
|
3568
|
+
*
|
|
3569
|
+
* Handles runs and nested smartTag/customXml. Form fields, hyperlinks and
|
|
3570
|
+
* other paragraph-level constructs are rare inside these containers and are
|
|
3571
|
+
* not handled here.
|
|
3572
|
+
*/
|
|
3573
|
+
function parseContainerChildren(el, ctx) {
|
|
3574
|
+
const children = [];
|
|
3575
|
+
for (const sub of el.elements ?? []) switch (sub.name) {
|
|
3576
|
+
case "w:r": {
|
|
3577
|
+
const runOpts = parsedRunToOptions(parseRun(sub, ctx));
|
|
3578
|
+
if (runOpts !== null) children.push(runOpts);
|
|
3579
|
+
break;
|
|
3580
|
+
}
|
|
3581
|
+
case "w:smartTag":
|
|
3582
|
+
children.push({ smartTag: parseSmartTagInline(sub, ctx) });
|
|
3583
|
+
break;
|
|
3584
|
+
case "w:customXml":
|
|
3585
|
+
children.push({ customXml: parseCustomXmlInline(sub, ctx) });
|
|
3586
|
+
break;
|
|
3587
|
+
default: break;
|
|
3588
|
+
}
|
|
3589
|
+
return children;
|
|
3590
|
+
}
|
|
3591
|
+
/** Parse a w:smartTag element into its ParagraphChild form. */
|
|
3592
|
+
function parseSmartTagInline(el, ctx) {
|
|
3593
|
+
const st = {};
|
|
3594
|
+
const element = attr(el, "w:element");
|
|
3595
|
+
if (element) st.element = element;
|
|
3596
|
+
const uri = attr(el, "w:uri");
|
|
3597
|
+
if (uri) st.uri = uri;
|
|
3598
|
+
const pr = findChild(el, "w:smartTagPr");
|
|
3599
|
+
if (pr) {
|
|
3600
|
+
const props = [];
|
|
3601
|
+
for (const a of pr.elements ?? []) {
|
|
3602
|
+
if (a.name !== "w:attr") continue;
|
|
3603
|
+
const prop = {
|
|
3604
|
+
name: attr(a, "w:name") ?? "",
|
|
3605
|
+
val: attr(a, "w:val") ?? ""
|
|
3606
|
+
};
|
|
3607
|
+
const auri = attr(a, "w:uri");
|
|
3608
|
+
if (auri) prop.uri = auri;
|
|
3609
|
+
props.push(prop);
|
|
3610
|
+
}
|
|
3611
|
+
if (props.length > 0) st.properties = props;
|
|
3612
|
+
}
|
|
3613
|
+
const content = parseContainerChildren(el, ctx);
|
|
3614
|
+
if (content.length > 0) st.children = content;
|
|
3615
|
+
return st;
|
|
3616
|
+
}
|
|
3617
|
+
/** Parse an inline w:customXml element into its ParagraphChild form. */
|
|
3618
|
+
function parseCustomXmlInline(el, ctx) {
|
|
3619
|
+
const cx = {};
|
|
3620
|
+
const element = attr(el, "w:element");
|
|
3621
|
+
if (element) cx.element = element;
|
|
3622
|
+
const uri = attr(el, "w:uri");
|
|
3623
|
+
if (uri) cx.uri = uri;
|
|
3624
|
+
const pr = findChild(el, "w:customXmlPr");
|
|
3625
|
+
if (pr) {
|
|
3626
|
+
const cxPr = {};
|
|
3627
|
+
const placeholder = findChild(pr, "w:placeholder");
|
|
3628
|
+
if (placeholder) {
|
|
3629
|
+
const pval = attr(placeholder, "w:val");
|
|
3630
|
+
if (pval) cxPr.placeholder = pval;
|
|
3631
|
+
}
|
|
3632
|
+
const attrsList = [];
|
|
3633
|
+
for (const a of pr.elements ?? []) {
|
|
3634
|
+
if (a.name !== "w:attr") continue;
|
|
3635
|
+
const name = attr(a, "w:name");
|
|
3636
|
+
const val = attr(a, "w:val");
|
|
3637
|
+
if (name && val) {
|
|
3638
|
+
const ao = {
|
|
3639
|
+
name,
|
|
3640
|
+
val
|
|
3641
|
+
};
|
|
3642
|
+
const auri = attr(a, "w:uri");
|
|
3643
|
+
if (auri) ao.uri = auri;
|
|
3644
|
+
attrsList.push(ao);
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
if (attrsList.length > 0) cxPr.attrs = attrsList;
|
|
3648
|
+
if (cxPr.placeholder !== void 0 || cxPr.attrs !== void 0) cx.customXmlPr = cxPr;
|
|
3649
|
+
}
|
|
3650
|
+
const content = parseContainerChildren(el, ctx);
|
|
3651
|
+
if (content.length > 0) cx.children = content;
|
|
3652
|
+
return cx;
|
|
3653
|
+
}
|
|
3654
|
+
/** Parse a move-revision range start (w:moveFromRangeStart / w:moveToRangeStart). */
|
|
3655
|
+
function parseMoveRangeStart(el) {
|
|
3656
|
+
const id = attrNum(el, "w:id");
|
|
3657
|
+
if (id === void 0) return null;
|
|
3658
|
+
const m = { id };
|
|
3659
|
+
const name = attr(el, "w:name");
|
|
3660
|
+
if (name !== void 0) m.name = name;
|
|
3661
|
+
const author = attr(el, "w:author");
|
|
3662
|
+
if (author !== void 0) m.author = author;
|
|
3663
|
+
const date = attr(el, "w:date");
|
|
3664
|
+
if (date !== void 0) m.date = date;
|
|
3665
|
+
return m;
|
|
3666
|
+
}
|
|
3667
|
+
/** Parse a customXml range start (Ins/Del/MoveFrom/MoveTo). */
|
|
3668
|
+
function parseCustomXmlRangeStart(el) {
|
|
3669
|
+
const id = attrNum(el, "w:id");
|
|
3670
|
+
if (id === void 0) return null;
|
|
3671
|
+
const m = { id };
|
|
3672
|
+
const author = attr(el, "w:author");
|
|
3673
|
+
if (author !== void 0) m.author = author;
|
|
3674
|
+
const date = attr(el, "w:date");
|
|
3675
|
+
if (date !== void 0) m.date = date;
|
|
3676
|
+
return m;
|
|
3677
|
+
}
|
|
3678
|
+
/**
|
|
3557
3679
|
* Parse a w:p element into ParagraphOptions.
|
|
3558
3680
|
*/
|
|
3559
3681
|
function parseParagraph(el, ctx) {
|
|
@@ -3561,9 +3683,57 @@ function parseParagraph(el, ctx) {
|
|
|
3561
3683
|
const pPr = findChild(el, "w:pPr");
|
|
3562
3684
|
if (pPr) Object.assign(opts, parseParagraphProperties(pPr, ctx));
|
|
3563
3685
|
const childList = [];
|
|
3686
|
+
let fieldKind = null;
|
|
3687
|
+
let pendingFormField = null;
|
|
3688
|
+
let pendingInstruction = "";
|
|
3689
|
+
let pendingResult = "";
|
|
3690
|
+
let collectingResult = false;
|
|
3564
3691
|
for (const child of el.elements ?? []) switch (child.name) {
|
|
3565
3692
|
case "w:pPr": break;
|
|
3566
3693
|
case "w:r": {
|
|
3694
|
+
const fldCharEl = findChild(child, "w:fldChar");
|
|
3695
|
+
if (fldCharEl) {
|
|
3696
|
+
const fctype = attr(fldCharEl, "w:fldCharType");
|
|
3697
|
+
if (fctype === "begin") {
|
|
3698
|
+
const ffDataEl = findChild(fldCharEl, "w:ffData");
|
|
3699
|
+
if (ffDataEl) {
|
|
3700
|
+
fieldKind = "form";
|
|
3701
|
+
pendingFormField = parseFormFieldData(ffDataEl);
|
|
3702
|
+
} else {
|
|
3703
|
+
fieldKind = "complex";
|
|
3704
|
+
pendingInstruction = "";
|
|
3705
|
+
pendingResult = "";
|
|
3706
|
+
}
|
|
3707
|
+
collectingResult = false;
|
|
3708
|
+
} else if (fctype === "separate") collectingResult = true;
|
|
3709
|
+
else if (fctype === "end" && fieldKind) {
|
|
3710
|
+
if (fieldKind === "form" && pendingFormField) childList.push({ formField: pendingFormField });
|
|
3711
|
+
else if (fieldKind === "complex") {
|
|
3712
|
+
const cf = { instruction: pendingInstruction };
|
|
3713
|
+
if (pendingResult) cf.result = pendingResult;
|
|
3714
|
+
childList.push({ complexField: cf });
|
|
3715
|
+
}
|
|
3716
|
+
fieldKind = null;
|
|
3717
|
+
pendingFormField = null;
|
|
3718
|
+
collectingResult = false;
|
|
3719
|
+
}
|
|
3720
|
+
break;
|
|
3721
|
+
}
|
|
3722
|
+
if (fieldKind) {
|
|
3723
|
+
if (fieldKind === "complex") if (collectingResult) pendingResult += collectRunText(child);
|
|
3724
|
+
else {
|
|
3725
|
+
const instrEl = findChild(child, "w:instrText");
|
|
3726
|
+
if (instrEl) pendingInstruction += textOf(instrEl);
|
|
3727
|
+
}
|
|
3728
|
+
else if (collectingResult && pendingFormField?.textInput) {
|
|
3729
|
+
const text = collectRunText(child);
|
|
3730
|
+
if (text) {
|
|
3731
|
+
const ti = pendingFormField.textInput;
|
|
3732
|
+
ti.value = (ti.value ?? "") + text;
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3735
|
+
break;
|
|
3736
|
+
}
|
|
3567
3737
|
const drawingEl = findChild(child, "w:drawing");
|
|
3568
3738
|
if (drawingEl) {
|
|
3569
3739
|
const drawingChild = parseDrawingRun(drawingEl, ctx);
|
|
@@ -3646,6 +3816,24 @@ function parseParagraph(el, ctx) {
|
|
|
3646
3816
|
break;
|
|
3647
3817
|
}
|
|
3648
3818
|
case "w:del": {
|
|
3819
|
+
let delFieldPlaceholder;
|
|
3820
|
+
for (const sub of child.elements ?? []) {
|
|
3821
|
+
if (sub.name !== "w:r") continue;
|
|
3822
|
+
const delInstrEl = findChild(sub, "w:delInstrText");
|
|
3823
|
+
if (delInstrEl) {
|
|
3824
|
+
delFieldPlaceholder = DELETED_PAGE_FIELD[(textOf(delInstrEl) ?? "").trim()];
|
|
3825
|
+
if (delFieldPlaceholder) break;
|
|
3826
|
+
}
|
|
3827
|
+
}
|
|
3828
|
+
if (delFieldPlaceholder) {
|
|
3829
|
+
childList.push({ deletion: {
|
|
3830
|
+
id: attrNum(child, "w:id") ?? 0,
|
|
3831
|
+
author: attr(child, "w:author") ?? "",
|
|
3832
|
+
date: attr(child, "w:date") ?? "",
|
|
3833
|
+
children: [delFieldPlaceholder]
|
|
3834
|
+
} });
|
|
3835
|
+
break;
|
|
3836
|
+
}
|
|
3649
3837
|
const delRun = findChild(child, "w:r");
|
|
3650
3838
|
if (delRun) {
|
|
3651
3839
|
const runOpts = parsedRunToOptions(parseRun(delRun, ctx));
|
|
@@ -3658,6 +3846,208 @@ function parseParagraph(el, ctx) {
|
|
|
3658
3846
|
}
|
|
3659
3847
|
break;
|
|
3660
3848
|
}
|
|
3849
|
+
case "w:moveFrom": {
|
|
3850
|
+
const runEl = findChild(child, "w:r");
|
|
3851
|
+
if (runEl) {
|
|
3852
|
+
const runOpts = parsedRunToOptions(parseRun(runEl, ctx));
|
|
3853
|
+
if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) childList.push({ movedFrom: {
|
|
3854
|
+
id: attrNum(child, "w:id") ?? 0,
|
|
3855
|
+
author: attr(child, "w:author") ?? "",
|
|
3856
|
+
date: attr(child, "w:date") ?? "",
|
|
3857
|
+
...runOpts
|
|
3858
|
+
} });
|
|
3859
|
+
}
|
|
3860
|
+
break;
|
|
3861
|
+
}
|
|
3862
|
+
case "w:moveTo": {
|
|
3863
|
+
const runEl = findChild(child, "w:r");
|
|
3864
|
+
if (runEl) {
|
|
3865
|
+
const runOpts = parsedRunToOptions(parseRun(runEl, ctx));
|
|
3866
|
+
if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) childList.push({ movedTo: {
|
|
3867
|
+
id: attrNum(child, "w:id") ?? 0,
|
|
3868
|
+
author: attr(child, "w:author") ?? "",
|
|
3869
|
+
date: attr(child, "w:date") ?? "",
|
|
3870
|
+
...runOpts
|
|
3871
|
+
} });
|
|
3872
|
+
}
|
|
3873
|
+
break;
|
|
3874
|
+
}
|
|
3875
|
+
case "w:fldSimple": {
|
|
3876
|
+
const instruction = attr(child, "w:instr");
|
|
3877
|
+
if (instruction) {
|
|
3878
|
+
const sf = { instruction };
|
|
3879
|
+
let cachedValue = "";
|
|
3880
|
+
for (const sub of child.elements ?? []) if (sub.name === "w:r") cachedValue += collectRunText(sub);
|
|
3881
|
+
if (cachedValue) sf.cachedValue = cachedValue;
|
|
3882
|
+
childList.push({ simpleField: sf });
|
|
3883
|
+
}
|
|
3884
|
+
break;
|
|
3885
|
+
}
|
|
3886
|
+
case "w:smartTag": {
|
|
3887
|
+
const st = parseSmartTagInline(child, ctx);
|
|
3888
|
+
if (st.element) childList.push({ smartTag: st });
|
|
3889
|
+
break;
|
|
3890
|
+
}
|
|
3891
|
+
case "w:customXml": {
|
|
3892
|
+
const cx = parseCustomXmlInline(child, ctx);
|
|
3893
|
+
if (cx.element) childList.push({ customXml: cx });
|
|
3894
|
+
break;
|
|
3895
|
+
}
|
|
3896
|
+
case "w:dir": {
|
|
3897
|
+
const val = attr(child, "w:val");
|
|
3898
|
+
if (val) {
|
|
3899
|
+
const dir = { val };
|
|
3900
|
+
const content = parseContainerChildren(child, ctx);
|
|
3901
|
+
if (content.length > 0) dir.children = content;
|
|
3902
|
+
childList.push({ dir });
|
|
3903
|
+
}
|
|
3904
|
+
break;
|
|
3905
|
+
}
|
|
3906
|
+
case "w:bdo": {
|
|
3907
|
+
const val = attr(child, "w:val");
|
|
3908
|
+
if (val) {
|
|
3909
|
+
const bdo = { val };
|
|
3910
|
+
const content = parseContainerChildren(child, ctx);
|
|
3911
|
+
if (content.length > 0) bdo.children = content;
|
|
3912
|
+
childList.push({ bdo });
|
|
3913
|
+
}
|
|
3914
|
+
break;
|
|
3915
|
+
}
|
|
3916
|
+
case "w:ruby": {
|
|
3917
|
+
const ruby = {};
|
|
3918
|
+
const pr = findChild(child, "w:rubyPr");
|
|
3919
|
+
if (pr) {
|
|
3920
|
+
const alignEl = findChild(pr, "w:rubyAlign");
|
|
3921
|
+
if (alignEl) {
|
|
3922
|
+
const v = attr(alignEl, "w:val");
|
|
3923
|
+
if (v) ruby.alignment = v;
|
|
3924
|
+
}
|
|
3925
|
+
const hpsEl = findChild(pr, "w:hps");
|
|
3926
|
+
if (hpsEl) {
|
|
3927
|
+
const v = attrNum(hpsEl, "w:val");
|
|
3928
|
+
if (v !== void 0) ruby.fontSize = v / 2;
|
|
3929
|
+
}
|
|
3930
|
+
const hpsRaiseEl = findChild(pr, "w:hpsRaise");
|
|
3931
|
+
if (hpsRaiseEl) {
|
|
3932
|
+
const v = attrNum(hpsRaiseEl, "w:val");
|
|
3933
|
+
if (v !== void 0) ruby.raise = v / 2;
|
|
3934
|
+
}
|
|
3935
|
+
const hpsBaseEl = findChild(pr, "w:hpsBaseText");
|
|
3936
|
+
if (hpsBaseEl) {
|
|
3937
|
+
const v = attrNum(hpsBaseEl, "w:val");
|
|
3938
|
+
if (v !== void 0) ruby.baseFontSize = v / 2;
|
|
3939
|
+
}
|
|
3940
|
+
const lidEl = findChild(pr, "w:lid");
|
|
3941
|
+
if (lidEl) {
|
|
3942
|
+
const v = attr(lidEl, "w:val");
|
|
3943
|
+
if (v) ruby.languageId = v;
|
|
3944
|
+
}
|
|
3945
|
+
if (findChild(pr, "w:dirty")) ruby.dirty = true;
|
|
3946
|
+
}
|
|
3947
|
+
const rt = findChild(child, "w:rt");
|
|
3948
|
+
if (rt) ruby.text = collectRunsText(rt);
|
|
3949
|
+
const rubyBase = findChild(child, "w:rubyBase");
|
|
3950
|
+
if (rubyBase) ruby.base = collectRunsText(rubyBase);
|
|
3951
|
+
if (ruby.text !== void 0 && ruby.base !== void 0) childList.push({ ruby });
|
|
3952
|
+
break;
|
|
3953
|
+
}
|
|
3954
|
+
case "w:proofErr": {
|
|
3955
|
+
const type = attr(child, "w:type");
|
|
3956
|
+
if (type) childList.push({ proofErr: type });
|
|
3957
|
+
break;
|
|
3958
|
+
}
|
|
3959
|
+
case "w:ptab": {
|
|
3960
|
+
const alignment = attr(child, "w:alignment");
|
|
3961
|
+
const leader = attr(child, "w:leader");
|
|
3962
|
+
const relativeTo = attr(child, "w:relativeTo");
|
|
3963
|
+
if (alignment !== void 0 && leader !== void 0 && relativeTo !== void 0) childList.push({ positionalTab: {
|
|
3964
|
+
alignment,
|
|
3965
|
+
leader,
|
|
3966
|
+
relativeTo
|
|
3967
|
+
} });
|
|
3968
|
+
break;
|
|
3969
|
+
}
|
|
3970
|
+
case "w:permStart": {
|
|
3971
|
+
const id = attr(child, "w:id");
|
|
3972
|
+
if (id !== void 0) {
|
|
3973
|
+
const ps = { id };
|
|
3974
|
+
const ed = attr(child, "w:ed");
|
|
3975
|
+
if (ed !== void 0) ps.ed = ed;
|
|
3976
|
+
const editGroup = attr(child, "w:edGrp");
|
|
3977
|
+
if (editGroup !== void 0) ps.editGroup = editGroup;
|
|
3978
|
+
const colFirst = attrNum(child, "w:colFirst");
|
|
3979
|
+
if (colFirst !== void 0) ps.colFirst = colFirst;
|
|
3980
|
+
const colLast = attrNum(child, "w:colLast");
|
|
3981
|
+
if (colLast !== void 0) ps.colLast = colLast;
|
|
3982
|
+
childList.push({ permStart: ps });
|
|
3983
|
+
}
|
|
3984
|
+
break;
|
|
3985
|
+
}
|
|
3986
|
+
case "w:permEnd": {
|
|
3987
|
+
const id = attr(child, "w:id");
|
|
3988
|
+
if (id !== void 0) childList.push({ permEnd: id });
|
|
3989
|
+
break;
|
|
3990
|
+
}
|
|
3991
|
+
case "w:moveFromRangeStart": {
|
|
3992
|
+
const m = parseMoveRangeStart(child);
|
|
3993
|
+
if (m) childList.push({ moveFromRangeStart: m });
|
|
3994
|
+
break;
|
|
3995
|
+
}
|
|
3996
|
+
case "w:moveFromRangeEnd": {
|
|
3997
|
+
const id = attrNum(child, "w:id");
|
|
3998
|
+
if (id !== void 0) childList.push({ moveFromRangeEnd: id });
|
|
3999
|
+
break;
|
|
4000
|
+
}
|
|
4001
|
+
case "w:moveToRangeStart": {
|
|
4002
|
+
const m = parseMoveRangeStart(child);
|
|
4003
|
+
if (m) childList.push({ moveToRangeStart: m });
|
|
4004
|
+
break;
|
|
4005
|
+
}
|
|
4006
|
+
case "w:moveToRangeEnd": {
|
|
4007
|
+
const id = attrNum(child, "w:id");
|
|
4008
|
+
if (id !== void 0) childList.push({ moveToRangeEnd: id });
|
|
4009
|
+
break;
|
|
4010
|
+
}
|
|
4011
|
+
case "w:customXmlInsRangeStart": {
|
|
4012
|
+
const m = parseCustomXmlRangeStart(child);
|
|
4013
|
+
if (m) childList.push({ customXmlInsRangeStart: m });
|
|
4014
|
+
break;
|
|
4015
|
+
}
|
|
4016
|
+
case "w:customXmlInsRangeEnd": {
|
|
4017
|
+
const id = attrNum(child, "w:id");
|
|
4018
|
+
if (id !== void 0) childList.push({ customXmlInsRangeEnd: id });
|
|
4019
|
+
break;
|
|
4020
|
+
}
|
|
4021
|
+
case "w:customXmlDelRangeStart": {
|
|
4022
|
+
const m = parseCustomXmlRangeStart(child);
|
|
4023
|
+
if (m) childList.push({ customXmlDelRangeStart: m });
|
|
4024
|
+
break;
|
|
4025
|
+
}
|
|
4026
|
+
case "w:customXmlDelRangeEnd": {
|
|
4027
|
+
const id = attrNum(child, "w:id");
|
|
4028
|
+
if (id !== void 0) childList.push({ customXmlDelRangeEnd: id });
|
|
4029
|
+
break;
|
|
4030
|
+
}
|
|
4031
|
+
case "w:customXmlMoveFromRangeStart": {
|
|
4032
|
+
const m = parseCustomXmlRangeStart(child);
|
|
4033
|
+
if (m) childList.push({ customXmlMoveFromRangeStart: m });
|
|
4034
|
+
break;
|
|
4035
|
+
}
|
|
4036
|
+
case "w:customXmlMoveFromRangeEnd": {
|
|
4037
|
+
const id = attrNum(child, "w:id");
|
|
4038
|
+
if (id !== void 0) childList.push({ customXmlMoveFromRangeEnd: id });
|
|
4039
|
+
break;
|
|
4040
|
+
}
|
|
4041
|
+
case "w:customXmlMoveToRangeStart": {
|
|
4042
|
+
const m = parseCustomXmlRangeStart(child);
|
|
4043
|
+
if (m) childList.push({ customXmlMoveToRangeStart: m });
|
|
4044
|
+
break;
|
|
4045
|
+
}
|
|
4046
|
+
case "w:customXmlMoveToRangeEnd": {
|
|
4047
|
+
const id = attrNum(child, "w:id");
|
|
4048
|
+
if (id !== void 0) childList.push({ customXmlMoveToRangeEnd: id });
|
|
4049
|
+
break;
|
|
4050
|
+
}
|
|
3661
4051
|
default: break;
|
|
3662
4052
|
}
|
|
3663
4053
|
if (childList.length > 0) {
|
|
@@ -3873,6 +4263,22 @@ function parseSdtProperties(el) {
|
|
|
3873
4263
|
if (gallery) opts.docPartList.gallery = attr(gallery, "w:val");
|
|
3874
4264
|
const category = findChild(dp, "w:docPartCategory");
|
|
3875
4265
|
if (category) opts.docPartList.category = attr(category, "w:val");
|
|
4266
|
+
} else if (findChild(el, "w14:checkbox")) {
|
|
4267
|
+
const cb = findChild(el, "w14:checkbox");
|
|
4268
|
+
const cbObj = {};
|
|
4269
|
+
const checked = findChild(cb, "w14:checked");
|
|
4270
|
+
if (checked) cbObj.checked = attrBool(checked, "w14:val") ?? true;
|
|
4271
|
+
const checkedState = findChild(cb, "w14:checkedState");
|
|
4272
|
+
if (checkedState) cbObj.checkedState = {
|
|
4273
|
+
val: attr(checkedState, "w14:val") ?? "",
|
|
4274
|
+
font: attr(checkedState, "w14:font")
|
|
4275
|
+
};
|
|
4276
|
+
const uncheckedState = findChild(cb, "w14:uncheckedState");
|
|
4277
|
+
if (uncheckedState) cbObj.uncheckedState = {
|
|
4278
|
+
val: attr(uncheckedState, "w14:val") ?? "",
|
|
4279
|
+
font: attr(uncheckedState, "w14:font")
|
|
4280
|
+
};
|
|
4281
|
+
opts.checkbox = cbObj;
|
|
3876
4282
|
}
|
|
3877
4283
|
return opts;
|
|
3878
4284
|
}
|
|
@@ -4714,6 +5120,28 @@ function sdtDocPartXml(name, options) {
|
|
|
4714
5120
|
function onOffAttr(name, val) {
|
|
4715
5121
|
return val ? `<${name}/>` : `<${name} w:val="0"/>`;
|
|
4716
5122
|
}
|
|
5123
|
+
const W14_NS = "xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\"";
|
|
5124
|
+
/** Default symbol font for checkbox content controls (CT_SdtCheckboxSymbol). */
|
|
5125
|
+
const CHECKBOX_FONT = "MS Gothic";
|
|
5126
|
+
const DEFAULT_CHECKED = {
|
|
5127
|
+
val: "2612",
|
|
5128
|
+
font: CHECKBOX_FONT
|
|
5129
|
+
};
|
|
5130
|
+
const DEFAULT_UNCHECKED = {
|
|
5131
|
+
val: "2610",
|
|
5132
|
+
font: CHECKBOX_FONT
|
|
5133
|
+
};
|
|
5134
|
+
/**
|
|
5135
|
+
* Build a w14:checkbox element (Word 2010+ content control checkbox).
|
|
5136
|
+
*
|
|
5137
|
+
* Lives in the w14 extension namespace; emitted with an inline xmlns:w14 so it
|
|
5138
|
+
* is valid wherever w:sdtPr appears. validate.ts tolerates the w14 namespace.
|
|
5139
|
+
*/
|
|
5140
|
+
function sdtCheckboxXml(opts) {
|
|
5141
|
+
const checked = opts.checkedState ?? DEFAULT_CHECKED;
|
|
5142
|
+
const unchecked = opts.uncheckedState ?? DEFAULT_UNCHECKED;
|
|
5143
|
+
return `<w14:checkbox ${W14_NS}>${(opts.checked ? "<w14:checked/>" : "<w14:checked w14:val=\"0\"/>") + `<w14:checkedState w14:val="${escapeXml$1(checked.val)}" w14:font="${escapeXml$1(checked.font ?? CHECKBOX_FONT)}"/><w14:uncheckedState w14:val="${escapeXml$1(unchecked.val)}" w14:font="${escapeXml$1(unchecked.font ?? CHECKBOX_FONT)}"/>`}</w14:checkbox>`;
|
|
5144
|
+
}
|
|
4717
5145
|
function stringifySdtPr(opts) {
|
|
4718
5146
|
const parts = [];
|
|
4719
5147
|
if (opts.alias !== void 0) parts.push(`<w:alias w:val="${escapeXml$1(opts.alias)}"/>`);
|
|
@@ -4740,6 +5168,7 @@ function stringifySdtPr(opts) {
|
|
|
4740
5168
|
} else if (opts.citation) parts.push("<w:citation/>");
|
|
4741
5169
|
else if (opts.group) parts.push("<w:group/>");
|
|
4742
5170
|
else if (opts.bibliography) parts.push("<w:bibliography/>");
|
|
5171
|
+
else if (opts.checkbox) parts.push(sdtCheckboxXml(opts.checkbox));
|
|
4743
5172
|
return parts.length ? `<w:sdtPr>${parts.join("")}</w:sdtPr>` : "<w:sdtPr/>";
|
|
4744
5173
|
}
|
|
4745
5174
|
/** Parse w:sdtPr element into SdtPropertiesOptions. */
|
|
@@ -4843,6 +5272,23 @@ function parseSdtPr(el) {
|
|
|
4843
5272
|
else if (findChild(el, "w:citation")) opts.citation = true;
|
|
4844
5273
|
else if (findChild(el, "w:group")) opts.group = true;
|
|
4845
5274
|
else if (findChild(el, "w:bibliography")) opts.bibliography = true;
|
|
5275
|
+
else if (findChild(el, "w14:checkbox")) {
|
|
5276
|
+
const cb = findChild(el, "w14:checkbox");
|
|
5277
|
+
const cbObj = {};
|
|
5278
|
+
const checked = findChild(cb, "w14:checked");
|
|
5279
|
+
if (checked) cbObj.checked = attrBool(checked, "w14:val") ?? true;
|
|
5280
|
+
const checkedState = findChild(cb, "w14:checkedState");
|
|
5281
|
+
if (checkedState) cbObj.checkedState = {
|
|
5282
|
+
val: attr(checkedState, "w14:val") ?? "",
|
|
5283
|
+
font: attr(checkedState, "w14:font")
|
|
5284
|
+
};
|
|
5285
|
+
const uncheckedState = findChild(cb, "w14:uncheckedState");
|
|
5286
|
+
if (uncheckedState) cbObj.uncheckedState = {
|
|
5287
|
+
val: attr(uncheckedState, "w14:val") ?? "",
|
|
5288
|
+
font: attr(uncheckedState, "w14:font")
|
|
5289
|
+
};
|
|
5290
|
+
opts.checkbox = cbObj;
|
|
5291
|
+
}
|
|
4846
5292
|
return opts;
|
|
4847
5293
|
}
|
|
4848
5294
|
/** Parse w:customXmlPr element into CustomXmlPrOptions. */
|
|
@@ -4888,8 +5334,15 @@ const sdtBlockDesc = {
|
|
|
4888
5334
|
stringify(opts, ctx) {
|
|
4889
5335
|
const parts = ["<w:sdt>"];
|
|
4890
5336
|
parts.push(stringifySdtPr(opts.properties));
|
|
4891
|
-
|
|
4892
|
-
|
|
5337
|
+
const endPrInner = opts.endProperties ? stringifyRunPropertiesInner(opts.endProperties) : void 0;
|
|
5338
|
+
parts.push(endPrInner ? `<w:sdtEndPr>${endPrInner}</w:sdtEndPr>` : "<w:sdtEndPr/>");
|
|
5339
|
+
if (opts.properties.checkbox) {
|
|
5340
|
+
const cb = opts.properties.checkbox;
|
|
5341
|
+
const symbol = cb.checked ?? false ? cb.checkedState ?? DEFAULT_CHECKED : cb.uncheckedState ?? DEFAULT_UNCHECKED;
|
|
5342
|
+
const font = escapeXml$1(symbol.font ?? CHECKBOX_FONT);
|
|
5343
|
+
const char = escapeXml$1(String.fromCodePoint(parseInt(symbol.val, 16)));
|
|
5344
|
+
parts.push(`<w:sdtContent><w:p><w:r><w:rPr><w:rFonts w:ascii="${font}" w:hAnsi="${font}"/></w:rPr><w:t>${char}</w:t></w:r></w:p></w:sdtContent>`);
|
|
5345
|
+
} else if (opts.children && opts.children.length > 0) {
|
|
4893
5346
|
const contentParts = [];
|
|
4894
5347
|
for (const child of opts.children) contentParts.push(ctx.stringifyChild(child, ctx));
|
|
4895
5348
|
const contentBody = contentParts.join("");
|
|
@@ -4902,6 +5355,9 @@ const sdtBlockDesc = {
|
|
|
4902
5355
|
const dctx = ctx;
|
|
4903
5356
|
const sdtPr = findChild(el, "w:sdtPr");
|
|
4904
5357
|
const properties = sdtPr ? parseSdtPr(sdtPr) : {};
|
|
5358
|
+
let endProperties;
|
|
5359
|
+
const sdtEndPr = findChild(el, "w:sdtEndPr");
|
|
5360
|
+
if (sdtEndPr) endProperties = parseRunProperties(sdtEndPr);
|
|
4905
5361
|
const sdtContent = findChild(el, "w:sdtContent");
|
|
4906
5362
|
let childList;
|
|
4907
5363
|
if (sdtContent && sdtContent.elements?.length) {
|
|
@@ -4910,7 +5366,8 @@ const sdtBlockDesc = {
|
|
|
4910
5366
|
}
|
|
4911
5367
|
return {
|
|
4912
5368
|
properties,
|
|
4913
|
-
children: childList
|
|
5369
|
+
children: childList,
|
|
5370
|
+
endProperties
|
|
4914
5371
|
};
|
|
4915
5372
|
}
|
|
4916
5373
|
};
|
|
@@ -5037,6 +5494,114 @@ const customPropertiesDesc = {
|
|
|
5037
5494
|
}
|
|
5038
5495
|
};
|
|
5039
5496
|
//#endregion
|
|
5497
|
+
//#region src/parts/app-properties.ts
|
|
5498
|
+
const appPropertiesDesc = {
|
|
5499
|
+
kind: "custom",
|
|
5500
|
+
stringify(opts, _ctx) {
|
|
5501
|
+
const p = ["<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">"];
|
|
5502
|
+
if (opts.template !== void 0) p.push(`<Template>${escapeXml(opts.template)}</Template>`);
|
|
5503
|
+
if (opts.manager !== void 0) p.push(`<Manager>${escapeXml(opts.manager)}</Manager>`);
|
|
5504
|
+
if (opts.company !== void 0) p.push(`<Company>${escapeXml(opts.company)}</Company>`);
|
|
5505
|
+
if (opts.pages !== void 0) p.push(`<Pages>${opts.pages}</Pages>`);
|
|
5506
|
+
if (opts.words !== void 0) p.push(`<Words>${opts.words}</Words>`);
|
|
5507
|
+
if (opts.characters !== void 0) p.push(`<Characters>${opts.characters}</Characters>`);
|
|
5508
|
+
if (opts.lines !== void 0) p.push(`<Lines>${opts.lines}</Lines>`);
|
|
5509
|
+
if (opts.paragraphs !== void 0) p.push(`<Paragraphs>${opts.paragraphs}</Paragraphs>`);
|
|
5510
|
+
if (opts.slides !== void 0) p.push(`<Slides>${opts.slides}</Slides>`);
|
|
5511
|
+
if (opts.notes !== void 0) p.push(`<Notes>${opts.notes}</Notes>`);
|
|
5512
|
+
if (opts.totalTime !== void 0) p.push(`<TotalTime>${opts.totalTime}</TotalTime>`);
|
|
5513
|
+
if (opts.hiddenSlides !== void 0) p.push(`<HiddenSlides>${opts.hiddenSlides}</HiddenSlides>`);
|
|
5514
|
+
if (opts.mmClips !== void 0) p.push(`<MMClips>${opts.mmClips}</MMClips>`);
|
|
5515
|
+
if (opts.scaleCrop !== void 0) p.push(`<ScaleCrop>${opts.scaleCrop ? 1 : 0}</ScaleCrop>`);
|
|
5516
|
+
if (opts.linksUpToDate !== void 0) p.push(`<LinksUpToDate>${opts.linksUpToDate ? 1 : 0}</LinksUpToDate>`);
|
|
5517
|
+
if (opts.charactersWithSpaces !== void 0) p.push(`<CharactersWithSpaces>${opts.charactersWithSpaces}</CharactersWithSpaces>`);
|
|
5518
|
+
if (opts.sharedDoc !== void 0) p.push(`<SharedDoc>${opts.sharedDoc ? 1 : 0}</SharedDoc>`);
|
|
5519
|
+
if (opts.hyperlinkBase !== void 0) p.push(`<HyperlinkBase>${escapeXml(opts.hyperlinkBase)}</HyperlinkBase>`);
|
|
5520
|
+
if (opts.hyperlinksChanged !== void 0) p.push(`<HyperlinksChanged>${opts.hyperlinksChanged ? 1 : 0}</HyperlinksChanged>`);
|
|
5521
|
+
if (opts.application !== void 0) p.push(`<Application>${escapeXml(opts.application)}</Application>`);
|
|
5522
|
+
if (opts.appVersion !== void 0) p.push(`<AppVersion>${escapeXml(opts.appVersion)}</AppVersion>`);
|
|
5523
|
+
if (opts.docSecurity !== void 0) p.push(`<DocSecurity>${opts.docSecurity}</DocSecurity>`);
|
|
5524
|
+
p.push("</Properties>");
|
|
5525
|
+
return p.join("");
|
|
5526
|
+
},
|
|
5527
|
+
parse(el, _ctx) {
|
|
5528
|
+
const result = {};
|
|
5529
|
+
for (const child of el.elements ?? []) {
|
|
5530
|
+
if (typeof child.name !== "string") continue;
|
|
5531
|
+
const text = child.elements?.[0]?.text;
|
|
5532
|
+
switch (child.name) {
|
|
5533
|
+
case "Template":
|
|
5534
|
+
if (typeof text === "string") result.template = text;
|
|
5535
|
+
break;
|
|
5536
|
+
case "Manager":
|
|
5537
|
+
if (typeof text === "string") result.manager = text;
|
|
5538
|
+
break;
|
|
5539
|
+
case "Company":
|
|
5540
|
+
if (typeof text === "string") result.company = text;
|
|
5541
|
+
break;
|
|
5542
|
+
case "Pages":
|
|
5543
|
+
if (typeof text === "string") result.pages = Number(text);
|
|
5544
|
+
break;
|
|
5545
|
+
case "Words":
|
|
5546
|
+
if (typeof text === "string") result.words = Number(text);
|
|
5547
|
+
break;
|
|
5548
|
+
case "Characters":
|
|
5549
|
+
if (typeof text === "string") result.characters = Number(text);
|
|
5550
|
+
break;
|
|
5551
|
+
case "Lines":
|
|
5552
|
+
if (typeof text === "string") result.lines = Number(text);
|
|
5553
|
+
break;
|
|
5554
|
+
case "Paragraphs":
|
|
5555
|
+
if (typeof text === "string") result.paragraphs = Number(text);
|
|
5556
|
+
break;
|
|
5557
|
+
case "Slides":
|
|
5558
|
+
if (typeof text === "string") result.slides = Number(text);
|
|
5559
|
+
break;
|
|
5560
|
+
case "Notes":
|
|
5561
|
+
if (typeof text === "string") result.notes = Number(text);
|
|
5562
|
+
break;
|
|
5563
|
+
case "TotalTime":
|
|
5564
|
+
if (typeof text === "string") result.totalTime = Number(text);
|
|
5565
|
+
break;
|
|
5566
|
+
case "HiddenSlides":
|
|
5567
|
+
if (typeof text === "string") result.hiddenSlides = Number(text);
|
|
5568
|
+
break;
|
|
5569
|
+
case "MMClips":
|
|
5570
|
+
if (typeof text === "string") result.mmClips = Number(text);
|
|
5571
|
+
break;
|
|
5572
|
+
case "ScaleCrop":
|
|
5573
|
+
if (typeof text === "string") result.scaleCrop = text === "1" || text === "true";
|
|
5574
|
+
break;
|
|
5575
|
+
case "LinksUpToDate":
|
|
5576
|
+
if (typeof text === "string") result.linksUpToDate = text === "1" || text === "true";
|
|
5577
|
+
break;
|
|
5578
|
+
case "CharactersWithSpaces":
|
|
5579
|
+
if (typeof text === "string") result.charactersWithSpaces = Number(text);
|
|
5580
|
+
break;
|
|
5581
|
+
case "SharedDoc":
|
|
5582
|
+
if (typeof text === "string") result.sharedDoc = text === "1" || text === "true";
|
|
5583
|
+
break;
|
|
5584
|
+
case "HyperlinkBase":
|
|
5585
|
+
if (typeof text === "string") result.hyperlinkBase = text;
|
|
5586
|
+
break;
|
|
5587
|
+
case "HyperlinksChanged":
|
|
5588
|
+
if (typeof text === "string") result.hyperlinksChanged = text === "1" || text === "true";
|
|
5589
|
+
break;
|
|
5590
|
+
case "Application":
|
|
5591
|
+
if (typeof text === "string") result.application = text;
|
|
5592
|
+
break;
|
|
5593
|
+
case "AppVersion":
|
|
5594
|
+
if (typeof text === "string") result.appVersion = text;
|
|
5595
|
+
break;
|
|
5596
|
+
case "DocSecurity":
|
|
5597
|
+
if (typeof text === "string") result.docSecurity = Number(text);
|
|
5598
|
+
break;
|
|
5599
|
+
}
|
|
5600
|
+
}
|
|
5601
|
+
return result;
|
|
5602
|
+
}
|
|
5603
|
+
};
|
|
5604
|
+
//#endregion
|
|
5040
5605
|
//#region src/parts/web-settings.ts
|
|
5041
5606
|
/**
|
|
5042
5607
|
* Screen size types for web settings target.
|
|
@@ -5579,6 +6144,6 @@ var DocxReadContext = class {
|
|
|
5579
6144
|
}
|
|
5580
6145
|
};
|
|
5581
6146
|
//#endregion
|
|
5582
|
-
export {
|
|
6147
|
+
export { RelativeHorizontalPosition as $, endnotesDesc as A, StyleLevel as B, bibliographyDesc as C, AltChunkCollection as D, SubDocCollection as E, stringifyDocumentXml as F, parseStyleDefinitions as G, Styles as H, stringifyTableOfContents as I, LevelFormat as J, Numbering as K, parseToc as L, parseParagraph as M, parseParagraphProperties as N, EditGroupType as O, stringifyBodyChild as P, OverlapType as Q, SdtDateMappingType as R, glossaryDesc as S, CharacterSet as T, buildNumberingCache as U, settingsDesc as V, buildStyleCache as W, TABLE_BORDERS_NONE as X, LevelSuffix as Y, TableLayoutType as Z, contentTypesDesc as _, AlignmentType as _t, framesetXml as a, PositionalTabLeader as at, DocPartGallery as b, customPropertiesDesc as c, UnderlineType as ct, customXmlBlockDesc as d, TextEffect as dt, RelativeVerticalPosition as et, sdtBlockDesc as f, PageNumber as ft, buildContentTypes as g, LineRuleType as gt, relationshipsDesc as h, HeadingLevel as ht, frameXml as i, PositionalTabAlignment as it, footnotesDesc as j, parseSdtBlock as k, corePropertiesDesc as l, createImageData as lt, subDocDesc as m, TextboxTightWrapType as mt, DocxWriteContext as n, ProofErrorType as nt, webSettingsDesc as o, PositionalTabRelativeTo as ot, setBodyParseChild as p, TextAlignmentType as pt, parseNumberingDefinitions as q, TargetScreenSize as r, RubyAlign as rt, appPropertiesDesc as s, EmphasisMarkType as st, DocxReadContext as t, TableAnchorType as tt, altChunkDesc as u, HighlightColor as ut, commentsDesc as v, fontTableDesc as w, DocPartType as x, DocPartBehavior as y, SdtLock as z };
|
|
5583
6148
|
|
|
5584
|
-
//# sourceMappingURL=context-
|
|
6149
|
+
//# sourceMappingURL=context-CA7wUvmY.mjs.map
|