@docx4j/core-ts 0.1.0 → 0.1.1

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.
Files changed (168) hide show
  1. package/README.md +410 -10
  2. package/dist/model/content/Body.d.mts +109 -4
  3. package/dist/model/content/Body.mjs +300 -29
  4. package/dist/model/content/Comment.d.mts +78 -0
  5. package/dist/model/content/Comment.mjs +429 -0
  6. package/dist/model/content/ContentControl.d.mts +173 -0
  7. package/dist/model/content/ContentControl.mjs +638 -0
  8. package/dist/model/content/Font.d.mts +48 -8
  9. package/dist/model/content/Font.mjs +55 -13
  10. package/dist/model/content/InlinePicture.d.mts +103 -0
  11. package/dist/model/content/InlinePicture.mjs +361 -0
  12. package/dist/model/content/List.d.mts +253 -0
  13. package/dist/model/content/List.mjs +778 -0
  14. package/dist/model/content/Paragraph.d.mts +213 -16
  15. package/dist/model/content/Paragraph.mjs +611 -57
  16. package/dist/model/content/Range.d.mts +48 -4
  17. package/dist/model/content/Range.mjs +161 -4
  18. package/dist/model/content/Table.d.mts +130 -0
  19. package/dist/model/content/Table.mjs +429 -0
  20. package/dist/model/content/TrackedChange.d.mts +96 -0
  21. package/dist/model/content/TrackedChange.mjs +352 -0
  22. package/dist/model/content/comments.d.mts +122 -0
  23. package/dist/model/content/comments.mjs +248 -0
  24. package/dist/model/content/index.d.mts +13 -3
  25. package/dist/model/content/index.mjs +15 -3
  26. package/dist/model/content/ooxml.d.mts +17 -0
  27. package/dist/model/content/ooxml.mjs +214 -0
  28. package/dist/model/content/styles.d.mts +21 -0
  29. package/dist/model/content/styles.mjs +86 -0
  30. package/dist/model/content/tracking.d.mts +104 -0
  31. package/dist/model/content/tracking.mjs +313 -0
  32. package/dist/model/content/tree.d.mts +56 -9
  33. package/dist/model/content/tree.mjs +104 -31
  34. package/dist/model/customxml/CustomXmlPart.d.mts +158 -0
  35. package/dist/model/customxml/CustomXmlPart.mjs +415 -0
  36. package/dist/model/customxml/CustomXmlPartCollection.d.mts +68 -0
  37. package/dist/model/customxml/CustomXmlPartCollection.mjs +183 -0
  38. package/dist/model/customxml/XmlMapping.d.mts +46 -0
  39. package/dist/model/customxml/XmlMapping.mjs +98 -0
  40. package/dist/model/customxml/bindings.d.mts +41 -0
  41. package/dist/model/customxml/bindings.mjs +230 -0
  42. package/dist/model/customxml/index.d.mts +7 -0
  43. package/dist/model/customxml/index.mjs +9 -0
  44. package/dist/model/customxml/insert.d.mts +20 -0
  45. package/dist/model/customxml/insert.mjs +22 -0
  46. package/dist/model/customxml/kinds.d.mts +103 -0
  47. package/dist/model/customxml/kinds.mjs +267 -0
  48. package/dist/model/customxml/xpath.d.mts +52 -0
  49. package/dist/model/customxml/xpath.mjs +205 -0
  50. package/dist/model/fonts/CJKToEnglish.d.mts +2 -0
  51. package/dist/model/fonts/CJKToEnglish.mjs +16 -0
  52. package/dist/model/fonts/FontFallback.d.mts +58 -0
  53. package/dist/model/fonts/FontFallback.mjs +219 -0
  54. package/dist/model/fonts/IdentityPlusMapper.d.mts +7 -0
  55. package/dist/model/fonts/IdentityPlusMapper.mjs +19 -0
  56. package/dist/model/fonts/LanguageTagToScriptMapping.d.mts +7 -0
  57. package/dist/model/fonts/LanguageTagToScriptMapping.mjs +67 -0
  58. package/dist/model/fonts/Mapper.d.mts +190 -0
  59. package/dist/model/fonts/Mapper.mjs +481 -0
  60. package/dist/model/fonts/PhysicalFont.d.mts +34 -0
  61. package/dist/model/fonts/PhysicalFont.mjs +62 -0
  62. package/dist/model/fonts/RunFontSelector.d.mts +194 -0
  63. package/dist/model/fonts/RunFontSelector.mjs +441 -0
  64. package/dist/model/fonts/ThemeFonts.d.mts +17 -0
  65. package/dist/model/fonts/ThemeFonts.mjs +76 -0
  66. package/dist/model/fonts/defaultTheme.d.mts +37 -0
  67. package/dist/model/fonts/defaultTheme.mjs +57 -0
  68. package/dist/model/fonts/families.generated.d.mts +11 -0
  69. package/dist/model/fonts/families.generated.mjs +17 -0
  70. package/dist/model/fonts/fontsInUse.d.mts +39 -0
  71. package/dist/model/fonts/fontsInUse.mjs +183 -0
  72. package/dist/model/fonts/index.d.mts +14 -0
  73. package/dist/model/fonts/index.mjs +29 -0
  74. package/dist/model/fonts/lookup.d.mts +5 -0
  75. package/dist/model/fonts/lookup.mjs +12 -0
  76. package/dist/model/fonts/registry.d.mts +31 -0
  77. package/dist/model/fonts/registry.mjs +103 -0
  78. package/dist/model/fonts/scripts.d.mts +2 -0
  79. package/dist/model/fonts/scripts.mjs +78 -0
  80. package/dist/model/fonts/substitutions.generated.d.mts +30 -0
  81. package/dist/model/fonts/substitutions.generated.mjs +12 -0
  82. package/dist/model/fonts/themes.generated.d.mts +6 -0
  83. package/dist/model/fonts/themes.generated.mjs +11 -0
  84. package/dist/model/index.d.mts +5 -0
  85. package/dist/model/index.mjs +13 -1
  86. package/dist/model/listnumbering/Emulator.d.mts +187 -0
  87. package/dist/model/listnumbering/Emulator.mjs +332 -0
  88. package/dist/model/listnumbering/definitions.d.mts +251 -0
  89. package/dist/model/listnumbering/definitions.mjs +571 -0
  90. package/dist/model/listnumbering/formats.d.mts +25 -0
  91. package/dist/model/listnumbering/formats.mjs +320 -0
  92. package/dist/model/listnumbering/index.d.mts +4 -0
  93. package/dist/model/listnumbering/index.mjs +15 -0
  94. package/dist/model/listnumbering/state.d.mts +97 -0
  95. package/dist/model/listnumbering/state.mjs +179 -0
  96. package/dist/model/properties/PropertyResolver.d.mts +216 -0
  97. package/dist/model/properties/PropertyResolver.mjs +524 -0
  98. package/dist/model/properties/catalogue.d.mts +179 -0
  99. package/dist/model/properties/catalogue.mjs +860 -0
  100. package/dist/model/properties/index.d.mts +4 -0
  101. package/dist/model/properties/index.mjs +9 -0
  102. package/dist/model/properties/log.d.mts +7 -0
  103. package/dist/model/properties/log.mjs +25 -0
  104. package/dist/model/properties/styleUtil.d.mts +112 -0
  105. package/dist/model/properties/styleUtil.mjs +359 -0
  106. package/dist/node/index.d.mts +1 -0
  107. package/dist/node/index.mjs +12 -0
  108. package/dist/office-js/document.d.mts +111 -0
  109. package/dist/office-js/document.mjs +267 -0
  110. package/dist/office-js/enums.d.mts +187 -0
  111. package/dist/office-js/enums.mjs +176 -0
  112. package/dist/office-js/errors.d.mts +29 -0
  113. package/dist/office-js/errors.mjs +39 -0
  114. package/dist/office-js/extras.d.mts +5 -0
  115. package/dist/office-js/extras.mjs +29 -0
  116. package/dist/office-js/fragment.d.mts +10 -0
  117. package/dist/office-js/fragment.mjs +23 -0
  118. package/dist/office-js/index.d.mts +183 -0
  119. package/dist/office-js/index.mjs +54 -0
  120. package/dist/office-js/proxy.d.mts +72 -0
  121. package/dist/office-js/proxy.mjs +279 -0
  122. package/dist/office-js/run.d.mts +32 -0
  123. package/dist/office-js/run.mjs +66 -0
  124. package/dist/office-js/supported.d.mts +7 -0
  125. package/dist/office-js/supported.generated.d.mts +1 -0
  126. package/dist/office-js/supported.generated.mjs +235 -0
  127. package/dist/office-js/supported.mjs +53 -0
  128. package/dist/office-js/toApiScript.d.mts +25 -0
  129. package/dist/office-js/toApiScript.mjs +394 -0
  130. package/dist/opc/ContentTypes.d.mts +1 -0
  131. package/dist/opc/ContentTypes.mjs +1 -0
  132. package/dist/opc/DirectoryPartStore.d.mts +47 -0
  133. package/dist/opc/DirectoryPartStore.mjs +123 -0
  134. package/dist/opc/exceptions.d.mts +30 -0
  135. package/dist/opc/exceptions.mjs +38 -0
  136. package/dist/opc/index.d.mts +1 -1
  137. package/dist/opc/index.mjs +1 -1
  138. package/dist/packages/OpcPackage.d.mts +19 -1
  139. package/dist/packages/OpcPackage.mjs +29 -0
  140. package/dist/packages/PresentationMLPackage.d.mts +71 -1
  141. package/dist/packages/PresentationMLPackage.mjs +179 -0
  142. package/dist/packages/SpreadsheetMLPackage.d.mts +30 -1
  143. package/dist/packages/SpreadsheetMLPackage.mjs +78 -0
  144. package/dist/packages/WordprocessingMLPackage.d.mts +124 -2
  145. package/dist/packages/WordprocessingMLPackage.mjs +309 -2
  146. package/dist/packages/index.d.mts +1 -1
  147. package/dist/packages/index.mjs +1 -1
  148. package/dist/parts/DefaultXmlPart.d.mts +18 -0
  149. package/dist/parts/DefaultXmlPart.mjs +34 -5
  150. package/dist/parts/PartRegistry.mjs +1 -0
  151. package/dist/parts/XmlPart.d.mts +33 -0
  152. package/dist/parts/XmlPart.mjs +105 -2
  153. package/dist/parts/pml/defaults.d.mts +6 -0
  154. package/dist/parts/pml/defaults.mjs +53 -0
  155. package/dist/parts/pml/index.d.mts +66 -3
  156. package/dist/parts/pml/index.mjs +206 -7
  157. package/dist/parts/pml/placeholders.d.mts +71 -0
  158. package/dist/parts/pml/placeholders.mjs +141 -0
  159. package/dist/parts/sml/index.d.mts +19 -1
  160. package/dist/parts/sml/index.mjs +60 -1
  161. package/dist/parts/wml/comments.d.mts +1 -0
  162. package/dist/parts/wml/comments.mjs +179 -0
  163. package/dist/parts/wml/defaultNumbering.d.mts +1 -0
  164. package/dist/parts/wml/defaultNumbering.mjs +216 -0
  165. package/dist/parts/wml/index.d.mts +121 -0
  166. package/dist/parts/wml/index.mjs +291 -0
  167. package/dist/xml/dom.mjs +1 -2
  168. package/package.json +25 -4
@@ -0,0 +1,571 @@
1
+ import { log } from '../properties/log.mjs';
2
+ import { formatValue } from './formats.mjs';
3
+ /** How many levels a list definition may have (ECMA-376: `w:ilvl` 0 to 8). */
4
+ export const LEVELS = 9;
5
+ /**
6
+ * One `w:lvl`: the abstract definition's level, and - for a level of a `w:num` - the instance's
7
+ * `w:lvlOverride/w:lvl` applied over it. docx4j `ListLevel`; the count lives in a
8
+ * {@link NumberingState}, keyed by {@link abstractNumId} and {@link ilvl}.
9
+ *
10
+ * Five members are **merged** attribute by attribute, as docx4j's `setOverrides` merges them -
11
+ * the override replaces each only where it states one: `w:start`, `w:lvlRestart`, `w:lvlText`,
12
+ * `w:numFmt` (and so `isBullet`), and the `w:hAnsi` of the level's `w:rPr/w:rFonts`. Everything
13
+ * else is read off **one** `w:lvl`, the override where the instance has one and the abstract
14
+ * level otherwise ({@link controllingLvl}): `w:isLgl` (docx4j's rule, measured through
15
+ * `IsLglTest`), `w:pStyle`, `w:suff`, `w:lvlJc` and `w:lvlPicBulletId`. `w:ind` and the label's
16
+ * `w:rPr` have rules of their own; see {@link ind} and {@link labelRPr}.
17
+ */
18
+ export class LevelDefinition {
19
+ constructor(ilvl, lvl) {
20
+ /** The **referencing** `w:abstractNum` (the counter's key; never the `w:numStyleLink` target's). */
21
+ this.abstractNumId = '';
22
+ /** `w:start` **less one**, since every fetch increments first. */
23
+ this.startValue = 0;
24
+ /** This instance level carries a `w:startOverride`, spent on the `w:num`'s first use. */
25
+ this.hasStartOverride = false;
26
+ /** Whether `w:numFmt` is `bullet`. */
27
+ this.isBullet = false;
28
+ this.ilvl = ilvl;
29
+ this.abstractLvl = lvl;
30
+ if (lvl !== undefined)
31
+ this.read(lvl);
32
+ }
33
+ /** Take from a `w:lvl` whatever it states; leave the rest alone. docx4j's constructor body. */
34
+ read(lvl) {
35
+ var _a, _b, _c;
36
+ if (lvl.start !== undefined) {
37
+ // one less than the user set it to, since whenever we fetch the number we first increment
38
+ this.startValue = lvl.start.val - 1;
39
+ }
40
+ if (((_a = lvl.lvlRestart) === null || _a === void 0 ? void 0 : _a.val) !== undefined)
41
+ this.lvlRestart = lvl.lvlRestart.val;
42
+ if (lvl.lvlText !== undefined)
43
+ this.lvlText = lvl.lvlText.val;
44
+ const hAnsi = (_c = (_b = lvl.rPr) === null || _b === void 0 ? void 0 : _b.rFonts) === null || _c === void 0 ? void 0 : _c.hAnsi;
45
+ if (hAnsi !== undefined)
46
+ this.font = hAnsi;
47
+ if (lvl.numFmt !== undefined) {
48
+ this.numFmt = lvl.numFmt.val;
49
+ this.isBullet = lvl.numFmt.val === 'bullet';
50
+ }
51
+ }
52
+ /** A copy for an instance definition. docx4j's copy constructor: no override, no owner. */
53
+ copy() {
54
+ const other = new LevelDefinition(this.ilvl);
55
+ other.abstractLvl = this.abstractLvl;
56
+ other.abstractNumId = this.abstractNumId; // the counter is shared through the state, by this key
57
+ other.startValue = this.startValue;
58
+ other.lvlRestart = this.lvlRestart;
59
+ other.lvlText = this.lvlText;
60
+ other.numFmt = this.numFmt;
61
+ other.isBullet = this.isBullet;
62
+ other.font = this.font;
63
+ return other;
64
+ }
65
+ /** Applies the instance's `w:lvlOverride/w:lvl`. docx4j `setOverrides`. */
66
+ applyOverride(lvl) {
67
+ this.overrideLvl = lvl;
68
+ this.read(lvl);
69
+ }
70
+ /** A `w:startOverride`: given effect on the first use of this `w:num` in a story. */
71
+ setStartValue(value) {
72
+ this.startValue = value;
73
+ this.hasStartOverride = true;
74
+ }
75
+ /** `w:ilvl` as a number. */
76
+ get level() {
77
+ const n = Number(this.ilvl);
78
+ return Number.isFinite(n) ? n : 0;
79
+ }
80
+ /**
81
+ * The one `w:lvl` the members docx4j does not merge are read from: the instance's override
82
+ * where there is one, else the abstract level's.
83
+ */
84
+ get controllingLvl() {
85
+ var _a;
86
+ return (_a = this.overrideLvl) !== null && _a !== void 0 ? _a : this.abstractLvl;
87
+ }
88
+ /** `w:start` as the document states it (one more than {@link startValue}). */
89
+ get start() {
90
+ return this.abstractLvl === undefined && this.overrideLvl === undefined ? undefined : this.startValue + 1;
91
+ }
92
+ /**
93
+ * `w:isLgl`: the levels this number *inherits* print in decimal whatever their own `w:numFmt`
94
+ * (Word's "legal style numbering": "Section 1.01" and not "Section I.01").
95
+ */
96
+ get isLgl() {
97
+ var _a;
98
+ const isLgl = (_a = this.controllingLvl) === null || _a === void 0 ? void 0 : _a.isLgl;
99
+ return isLgl !== undefined && isLgl.val !== false;
100
+ }
101
+ /** The `w:pStyle` this level is linked to (ECMA-376 17.9.24), or undefined. */
102
+ get pStyle() {
103
+ var _a, _b;
104
+ const override = this.overrideLvl;
105
+ if (override !== undefined && override.pStyle !== undefined)
106
+ return override.pStyle.val;
107
+ return (_b = (_a = this.abstractLvl) === null || _a === void 0 ? void 0 : _a.pStyle) === null || _b === void 0 ? void 0 : _b.val;
108
+ }
109
+ /** `w:suff`: what separates the label from the text (tab, space, nothing). */
110
+ get suff() {
111
+ var _a, _b;
112
+ return (_b = (_a = this.controllingLvl) === null || _a === void 0 ? void 0 : _a.suff) === null || _b === void 0 ? void 0 : _b.val;
113
+ }
114
+ /** `w:lvlJc`: how the label is justified in its column. */
115
+ get lvlJc() {
116
+ var _a, _b;
117
+ return (_b = (_a = this.controllingLvl) === null || _a === void 0 ? void 0 : _a.lvlJc) === null || _b === void 0 ? void 0 : _b.val;
118
+ }
119
+ /** `w:lvlPicBulletId`: the `w:numPicBullet` a picture bullet level names. */
120
+ get lvlPicBulletId() {
121
+ var _a, _b;
122
+ return (_b = (_a = this.controllingLvl) === null || _a === void 0 ? void 0 : _a.lvlPicBulletId) === null || _b === void 0 ? void 0 : _b.val;
123
+ }
124
+ /** The level's `w:pPr`: the override's where it has one, else the abstract level's. */
125
+ get pPr() {
126
+ var _a, _b, _c;
127
+ return (_b = (_a = this.overrideLvl) === null || _a === void 0 ? void 0 : _a.pPr) !== null && _b !== void 0 ? _b : (_c = this.abstractLvl) === null || _c === void 0 ? void 0 : _c.pPr;
128
+ }
129
+ /**
130
+ * The level's **own** `w:ind`: the instance's override level's where *it* states one, else the
131
+ * abstract level's (docx4j `Emulator.getNumber`'s `triple.ind`, since 17.1.0). The linked
132
+ * `w:pStyle`'s is not consulted here; {@link NumberingDefinitions.getInd} does that.
133
+ */
134
+ get ind() {
135
+ var _a, _b, _c, _d, _e;
136
+ return (_c = (_b = (_a = this.overrideLvl) === null || _a === void 0 ? void 0 : _a.pPr) === null || _b === void 0 ? void 0 : _b.ind) !== null && _c !== void 0 ? _c : (_e = (_d = this.abstractLvl) === null || _d === void 0 ? void 0 : _d.pPr) === null || _e === void 0 ? void 0 : _e.ind;
137
+ }
138
+ /** The **abstract** level's `w:rPr`, never the override's. docx4j `NumberingResult.getRPr()`. */
139
+ get rPr() {
140
+ var _a;
141
+ return (_a = this.abstractLvl) === null || _a === void 0 ? void 0 : _a.rPr;
142
+ }
143
+ /**
144
+ * The `w:rPr` the label is drawn with: the `w:lvlOverride/w:lvl`'s where the instance
145
+ * overrides this level with one carrying an rPr, else the abstract level's - one or the other,
146
+ * as Word applies them (CR-014 probe P3, measured: an abstract `w:i` under an override
147
+ * `w:b` + `w:sz 36` gives a bold 18pt label with no italic anywhere). It formats the number
148
+ * alone, never the paragraph's text (ECMA-376 17.9.24).
149
+ */
150
+ get labelRPr() {
151
+ const override = this.overrideLvl;
152
+ return override !== undefined && override.rPr !== undefined ? override.rPr : this.rPr;
153
+ }
154
+ /** This level's counter in the given state. */
155
+ counter(state) {
156
+ return state.counter(this.abstractNumId, this.ilvl, this.startValue);
157
+ }
158
+ /**
159
+ * One more item at this level. docx4j `incrementCounter(state)`.
160
+ *
161
+ * The shared counter takes this level's start value the first time it is met in the state, and
162
+ * again the first time this instance level's `w:num` is met there when that `w:num` overrides
163
+ * the start - deferred until then, since otherwise earlier numbering over the same abstract
164
+ * list would use it.
165
+ */
166
+ incrementCounter(state) {
167
+ const counter = this.counter(state);
168
+ const overridePending = this.hasStartOverride && this.ownerNumId !== undefined
169
+ && !state.startOverrideApplied(this.ownerNumId, this.ilvl);
170
+ if (overridePending || !counter.encounteredAlready) {
171
+ counter.value = this.startValue;
172
+ counter.encounteredAlready = true;
173
+ counter.resetPending = false;
174
+ if (this.ownerNumId !== undefined)
175
+ state.markStartOverrideApplied(this.ownerNumId, this.ilvl);
176
+ }
177
+ if (counter.resetPending) {
178
+ // the reset already placed the counter at its start value (see resetCounter)
179
+ counter.resetPending = false;
180
+ return;
181
+ }
182
+ counter.increment();
183
+ }
184
+ /**
185
+ * A shallower level was used: the level shows its start value from now until it is next used,
186
+ * and that first use does not increment it (CR-014 probe P8; before, the counter went to
187
+ * start-1 and a deeper label printed "2.0.1" where Word prints "2.1.1").
188
+ */
189
+ resetCounter(state) {
190
+ const counter = this.counter(state);
191
+ counter.value = this.startValue + 1;
192
+ counter.resetPending = true;
193
+ }
194
+ /**
195
+ * Whether using `shallowerIlvl` (0-based) restarts this level. ECMA-376 17.9.11: without
196
+ * `w:lvlRestart` any shallower level restarts it; `w:val="0"` means none does; `w:val="n"`
197
+ * means levels 1..n (1-based, so ilvl 0..n-1) do and deeper ones do not. Measured, P8.
198
+ */
199
+ restartsAfter(shallowerIlvl) {
200
+ if (this.lvlRestart === undefined)
201
+ return true;
202
+ if (this.lvlRestart <= 0)
203
+ return false;
204
+ return shallowerIlvl <= this.lvlRestart - 1;
205
+ }
206
+ /** The count at this level, in this level's `w:numFmt`. */
207
+ currentValueFormatted(state, where) {
208
+ return formatValue(this.numFmt, this.counter(state).value, where === undefined ? undefined : `${where} ilvl ${this.ilvl}`);
209
+ }
210
+ /** The count at this level as a decimal, whatever its `w:numFmt` (what `w:isLgl` shows). */
211
+ currentValueUnformatted(state) {
212
+ return String(this.counter(state).value);
213
+ }
214
+ toString() {
215
+ var _a, _b;
216
+ return `LevelDefinition ${this.ilvl} ${(_a = this.numFmt) !== null && _a !== void 0 ? _a : '-'} ${JSON.stringify((_b = this.lvlText) !== null && _b !== void 0 ? _b : '')}`;
217
+ }
218
+ }
219
+ /**
220
+ * One `w:abstractNum`: its levels, and - where it carries `w:numStyleLink` - the numbering style
221
+ * whose definition it takes them from. docx4j `AbstractListNumberingDefinition`.
222
+ */
223
+ export class AbstractListDefinition {
224
+ constructor(abstractNum) {
225
+ var _a, _b;
226
+ this.abstractNum = abstractNum;
227
+ /** The levels, keyed by `w:ilvl` ("0" to "8"). */
228
+ this.levels = new Map();
229
+ this.id = String(abstractNum.abstractNumId);
230
+ this.linkedStyleId = (_a = abstractNum.numStyleLink) === null || _a === void 0 ? void 0 : _a.val;
231
+ this.styleLink = (_b = abstractNum.styleLink) === null || _b === void 0 ? void 0 : _b.val;
232
+ this.readLevels(abstractNum);
233
+ }
234
+ readLevels(abstractNum) {
235
+ var _a;
236
+ for (const lvl of (_a = abstractNum.lvl) !== null && _a !== void 0 ? _a : [])
237
+ this.readLevel(lvl);
238
+ }
239
+ /** Adds (or replaces) the level read from this `w:lvl`. docx4j `readLevel`. */
240
+ readLevel(lvl) {
241
+ const level = new LevelDefinition(String(lvl.ilvl), lvl);
242
+ // the REFERENCING abstract list: a w:numStyleLink definition counts on its own (P2)
243
+ level.abstractNumId = this.id;
244
+ this.levels.set(level.ilvl, level);
245
+ }
246
+ /**
247
+ * The second pass for a definition carrying `w:numStyleLink`: read its levels from the
248
+ * abstract definition the numbering style's own `w:num` names. They count under **this**
249
+ * definition's id, not the linked one's. docx4j `updateDefinitionFromLinkedStyle`.
250
+ */
251
+ updateFromLinkedStyle(linked) {
252
+ if (!this.hasLinkedStyle)
253
+ return;
254
+ this.readLevels(linked);
255
+ }
256
+ /** Whether this definition carries `w:numStyleLink`. */
257
+ get hasLinkedStyle() {
258
+ return this.linkedStyleId !== undefined && this.linkedStyleId !== '';
259
+ }
260
+ /** How many levels are defined; 0 for an unresolved `w:numStyleLink` definition. */
261
+ get levelCount() {
262
+ return this.levels.size;
263
+ }
264
+ }
265
+ /**
266
+ * One `w:num`: the abstract definition it names, with its `w:lvlOverride`s applied to copies of
267
+ * that definition's levels, and the counting. docx4j `ListNumberingDefinition`.
268
+ */
269
+ export class ListDefinition {
270
+ constructor(num, abstracts, resolveLinkedStyle) {
271
+ var _a, _b;
272
+ this.num = num;
273
+ /** The levels, with this instance's overrides applied. */
274
+ this.levels = new Map();
275
+ this.numId = String(num.numId);
276
+ const abstractNumId = num.abstractNumId;
277
+ if (abstractNumId === undefined) {
278
+ log.warn(`No abstractNumId on w:numId=${this.numId}`);
279
+ return;
280
+ }
281
+ const abstract = abstracts.get(String(abstractNumId.val));
282
+ this.abstractDefinition = abstract;
283
+ if (abstract === undefined) {
284
+ log.warn(`No abstractListDefinition for w:numId=${this.numId}`);
285
+ return;
286
+ }
287
+ if (abstract.levelCount === 0 && abstract.hasLinkedStyle && !resolveLinkedStyle) {
288
+ // resolved on the second pass, once the numbering style is known
289
+ return;
290
+ }
291
+ for (const [ilvl, level] of abstract.levels) {
292
+ const instance = level.copy();
293
+ instance.ownerNumId = this.numId;
294
+ this.levels.set(ilvl, instance);
295
+ }
296
+ for (const override of (_a = num.lvlOverride) !== null && _a !== void 0 ? _a : []) {
297
+ if (override.ilvl === undefined) {
298
+ log.warn(`Missing @w:ilvl on a w:lvlOverride of w:numId=${this.numId}`);
299
+ continue;
300
+ }
301
+ const ilvl = String(override.ilvl);
302
+ const level = this.levels.get(ilvl);
303
+ // the w:startOverride first, as docx4j applies them: an override w:lvl stating its own
304
+ // w:start then replaces the value, but the level still counts as start-overridden
305
+ const start = (_b = override.startOverride) === null || _b === void 0 ? void 0 : _b.val;
306
+ if (start !== undefined) {
307
+ if (level === undefined) {
308
+ log.warn(`level ${ilvl} missing for abstractNum ${abstract.id}, referenced from w:num ${this.numId}`);
309
+ }
310
+ else {
311
+ level.setStartValue(start - 1);
312
+ }
313
+ }
314
+ if (override.lvl !== undefined && level !== undefined)
315
+ level.applyOverride(override.lvl);
316
+ }
317
+ }
318
+ /** The level with this `w:ilvl`, or undefined. */
319
+ level(ilvl) {
320
+ return this.levels.get(String(ilvl));
321
+ }
322
+ /** Whether the level exists: Word writes `w:num`s whose abstract definition or level is missing. */
323
+ levelExists(ilvl) {
324
+ return this.levels.has(String(ilvl));
325
+ }
326
+ /** Whether the level's `w:numFmt` is `bullet`. */
327
+ isBullet(ilvl) {
328
+ var _a, _b;
329
+ return (_b = (_a = this.level(ilvl)) === null || _a === void 0 ? void 0 : _a.isBullet) !== null && _b !== void 0 ? _b : false;
330
+ }
331
+ /** The `w:hAnsi` font the level's `w:rPr` names, or undefined. */
332
+ font(ilvl) {
333
+ var _a;
334
+ return (_a = this.level(ilvl)) === null || _a === void 0 ? void 0 : _a.font;
335
+ }
336
+ /**
337
+ * One more item at a level, and the deeper levels that restart after it reset.
338
+ * docx4j `incrementCounter(level, state)`.
339
+ */
340
+ incrementCounter(ilvl, state) {
341
+ const levelInt = Number(ilvl);
342
+ const thisLevel = this.level(levelInt);
343
+ if (thisLevel === undefined)
344
+ return; // guarded by levelExists
345
+ if (!thisLevel.counter(state).encounteredAlready) {
346
+ // make sure the shallower levels have been initialised
347
+ for (let shallower = levelInt - 1; shallower >= 0; shallower--) {
348
+ const level = this.level(shallower);
349
+ if (level === undefined || level.counter(state).encounteredAlready)
350
+ break;
351
+ level.incrementCounter(state);
352
+ }
353
+ }
354
+ thisLevel.incrementCounter(state);
355
+ // the deeper levels go back to their start - each unless its w:lvlRestart says this level
356
+ // does not restart it (ECMA-376 17.9.11, CR-014 phase 2)
357
+ for (let deeper = levelInt + 1;; deeper++) {
358
+ const level = this.level(deeper);
359
+ if (level === undefined)
360
+ break;
361
+ if (level.restartsAfter(levelInt))
362
+ level.resetCounter(state);
363
+ }
364
+ }
365
+ /**
366
+ * The label of a level: its `w:lvlText` with the counters filled in ("1.2.", "(c)").
367
+ * docx4j `getCurrentNumberString(level, state)`.
368
+ *
369
+ * `w:isLgl` at **any** level shows the levels this number *inherits* in decimal whatever their
370
+ * own `w:numFmt`, the level carrying it keeping its own: Word's Article / Section numbering
371
+ * prints "Section 1.01" where the plain reading would print "Section I.01".
372
+ */
373
+ currentNumberString(ilvl, state) {
374
+ var _a;
375
+ const controlling = this.level(ilvl);
376
+ if (controlling === undefined)
377
+ return ''; // guarded by levelExists
378
+ const isLegal = controlling.isLgl;
379
+ const thisLevel = Number.isFinite(Number(ilvl)) ? Number(ilvl) : -1;
380
+ const format = (_a = controlling.lvlText) !== null && _a !== void 0 ? _a : '';
381
+ let out = '';
382
+ for (let i = 0; i < format.length; i++) {
383
+ const char = format.charAt(i);
384
+ if (char !== '%') {
385
+ out += char;
386
+ continue;
387
+ }
388
+ // a trailing '%' names no level and is dropped, as docx4j's loop drops it
389
+ if (i >= format.length - 1)
390
+ continue;
391
+ const digit = format.charAt(i + 1);
392
+ if (digit < '0' || digit > '9') {
393
+ // docx4j throws NumberFormatException here; a malformed w:lvlText is not worth an
394
+ // exception, so the two characters stand as they are written
395
+ out += char;
396
+ continue;
397
+ }
398
+ i++;
399
+ const levelId = Number(digit) - 1; // the format string is 1-based
400
+ const level = this.level(levelId);
401
+ if (level === undefined)
402
+ continue; // Word's referential-integrity bugs (docx4j NPEs here)
403
+ out += (isLegal && levelId < thisLevel)
404
+ ? level.currentValueUnformatted(state)
405
+ : level.currentValueFormatted(state, `numId ${this.numId}`);
406
+ }
407
+ return out;
408
+ }
409
+ }
410
+ /**
411
+ * The definitions of one `w:numbering`: every `w:abstractNum` and every `w:num`, with
412
+ * `w:numStyleLink` resolved. docx4j `NumberingDefinitionsPart.initialiseMaps` and the two maps
413
+ * it fills, plus `getInd` and `getLinkedStyleId`.
414
+ *
415
+ * Immutable once built; the numbering part rebuilds it when its tree changes.
416
+ */
417
+ export class NumberingDefinitions {
418
+ /**
419
+ * @param numbering the `w:numbering` tree, or undefined for a package with no numbering part
420
+ * @param getStyle a style by id, for `w:numStyleLink` and a level's linked `w:pStyle`
421
+ */
422
+ constructor(numbering, getStyle = () => undefined) {
423
+ var _a;
424
+ this.numbering = numbering;
425
+ this.getStyle = getStyle;
426
+ /** `w:abstractNumId` -> the definition. docx4j `getAbstractListDefinitions()`. */
427
+ this.abstractListDefinitions = new Map();
428
+ /** `w:numId` -> the definition. docx4j `getInstanceListDefinitions()`. */
429
+ this.instanceListDefinitions = new Map();
430
+ if (numbering === undefined)
431
+ return;
432
+ // pass 1: every w:abstractNum, then every w:num
433
+ let needSecondPass = false;
434
+ for (const abstractNum of (_a = numbering.abstractNum) !== null && _a !== void 0 ? _a : []) {
435
+ const definition = new AbstractListDefinition(abstractNum);
436
+ this.abstractListDefinitions.set(definition.id, definition);
437
+ if (abstractNum.numStyleLink !== undefined)
438
+ needSecondPass = true;
439
+ }
440
+ this.readInstances(numbering, false);
441
+ if (!needSecondPass)
442
+ return;
443
+ // pass 2: resolveLinkedAbstractNum, then the instances again (which overwrites them)
444
+ for (const definition of this.abstractListDefinitions.values())
445
+ this.resolveLinkedAbstractNum(definition);
446
+ this.readInstances(numbering, true);
447
+ }
448
+ readInstances(numbering, resolveLinkedStyle) {
449
+ var _a;
450
+ for (const num of (_a = numbering.num) !== null && _a !== void 0 ? _a : []) {
451
+ const definition = new ListDefinition(num, this.abstractListDefinitions, resolveLinkedStyle);
452
+ this.instanceListDefinitions.set(definition.numId, definition);
453
+ }
454
+ }
455
+ /**
456
+ * docx4j `resolveLinkedAbstractNum`: the numbering style `w:numStyleLink` names, the `w:num`
457
+ * its `w:numPr` points at, and *that* `w:num`'s abstract definition, whose levels this one
458
+ * takes while counting under its own id - "treated as a separate list by Word (ie its numbers
459
+ * are incremented independently), and this code honours that".
460
+ */
461
+ resolveLinkedAbstractNum(definition) {
462
+ var _a, _b;
463
+ if (!definition.hasLinkedStyle)
464
+ return;
465
+ const numStyleId = definition.linkedStyleId;
466
+ const style = this.getStyle(numStyleId);
467
+ if (style === undefined) {
468
+ log.warn(`For w:numStyleLink, couldn't find style ${numStyleId}`);
469
+ return;
470
+ }
471
+ const numPr = (_a = style.pPr) === null || _a === void 0 ? void 0 : _a.numPr;
472
+ if (numPr === undefined) {
473
+ log.warn(`For w:numStyleLink, style ${numStyleId} has no w:numPr`);
474
+ return;
475
+ }
476
+ if (((_b = numPr.numId) === null || _b === void 0 ? void 0 : _b.val) === undefined) {
477
+ log.warn(`For w:numStyleLink, style ${numStyleId} w:numPr has no w:numId`);
478
+ return;
479
+ }
480
+ const concrete = String(numPr.numId.val);
481
+ const target = this.instanceListDefinitions.get(concrete);
482
+ if (target === undefined) {
483
+ log.warn(`No ListDefinition entry with ID ${concrete}`);
484
+ return;
485
+ }
486
+ const linked = target.abstractDefinition;
487
+ if (linked === undefined || linked === definition)
488
+ return;
489
+ definition.updateFromLinkedStyle(linked.abstractNum);
490
+ // docx4j also copies the levels into the underlying w:abstractNum object here; this port
491
+ // does not, so that a numbering part nobody has edited still saves byte for byte
492
+ }
493
+ /** The definition of a `w:numId`, or undefined. */
494
+ list(numId) {
495
+ return numId === undefined ? undefined : this.instanceListDefinitions.get(String(numId));
496
+ }
497
+ /** The level of a `w:numId` / `w:ilvl`, or undefined. */
498
+ level(numId, ilvl) {
499
+ var _a;
500
+ return (_a = this.list(numId)) === null || _a === void 0 ? void 0 : _a.level(ilvl === undefined || ilvl === '' ? '0' : ilvl);
501
+ }
502
+ /**
503
+ * The paragraph style this level is linked to - the `w:pStyle` of ECMA-376 17.9.24, on the
504
+ * instance's `w:lvlOverride/w:lvl` where it has one and on the abstract level otherwise - or
505
+ * undefined. docx4j `NumberingDefinitionsPart.getLinkedStyleId`.
506
+ */
507
+ getLinkedStyleId(numId, ilvl) {
508
+ var _a;
509
+ return (_a = this.level(numId, ilvl)) === null || _a === void 0 ? void 0 : _a.pStyle;
510
+ }
511
+ /** docx4j `NumberingDefinitionsPart.getInd(NumPr)`: `w:ilvl` is optional and means level 0. */
512
+ getInd(numPr) {
513
+ var _a, _b;
514
+ if (((_a = numPr.numId) === null || _a === void 0 ? void 0 : _a.val) === undefined)
515
+ return undefined;
516
+ const ilvl = ((_b = numPr.ilvl) === null || _b === void 0 ? void 0 : _b.val) === undefined ? '0' : String(numPr.ilvl.val);
517
+ return this.indOf(String(numPr.numId.val), ilvl);
518
+ }
519
+ /**
520
+ * The indent this level contributes. docx4j `NumberingDefinitionsPart.getInd(String, String)`:
521
+ * the instance's override level first, then the abstract level, each read by
522
+ * {@link indFromLvl}.
523
+ */
524
+ indOf(numId, ilvl) {
525
+ const list = this.list(numId);
526
+ if (list === undefined)
527
+ return undefined;
528
+ const level = list.level(ilvl !== null && ilvl !== void 0 ? ilvl : '0');
529
+ if (level === undefined)
530
+ return undefined;
531
+ if (level.overrideLvl !== undefined) {
532
+ const ind = this.indFromLvl(level.overrideLvl);
533
+ if (ind !== undefined)
534
+ return ind;
535
+ }
536
+ return level.abstractLvl === undefined ? undefined : this.indFromLvl(level.abstractLvl);
537
+ }
538
+ /**
539
+ * **The level's own `w:pPr/w:ind` comes first** (ECMA-376 17.9.24: a `w:lvl/w:pPr` states the
540
+ * paragraph properties applied to a paragraph at this level). A `w:lvl/w:pStyle` only *links*
541
+ * the level to a paragraph style; it does not make that style's indent the level's. Where the
542
+ * level states no indent of its own the linked style's is still used, following `w:basedOn` as
543
+ * every other property a style contributes does (docx4j 17.1.0 and 17.1.1; CR-014 claim 7,
544
+ * measured, and probe P5).
545
+ *
546
+ * A style reference in the level's `w:pPr`, but not also as a sibling of `w:pPr`, contributes
547
+ * nothing here - and numbers nothing (CR-014 P4; `Emulator.resolve` decides "not numbered").
548
+ */
549
+ indFromLvl(lvl) {
550
+ var _a, _b, _c, _d;
551
+ if (((_a = lvl.pPr) === null || _a === void 0 ? void 0 : _a.ind) !== undefined)
552
+ return lvl.pPr.ind;
553
+ const linked = (_b = lvl.pStyle) === null || _b === void 0 ? void 0 : _b.val;
554
+ if (linked === undefined)
555
+ return undefined;
556
+ const seen = new Set();
557
+ let id = linked;
558
+ while (id !== undefined && !seen.has(id)) {
559
+ seen.add(id);
560
+ const style = this.getStyle(id);
561
+ if (style === undefined) {
562
+ log.warn(`Couldn't find style ${id}`);
563
+ return undefined;
564
+ }
565
+ if (((_c = style.pPr) === null || _c === void 0 ? void 0 : _c.ind) !== undefined)
566
+ return style.pPr.ind;
567
+ id = (_d = style.basedOn) === null || _d === void 0 ? void 0 : _d.val;
568
+ }
569
+ return undefined;
570
+ }
571
+ }
@@ -0,0 +1,25 @@
1
+ import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
2
+ /**
3
+ * Turns a list counter into the label text of one `w:numFmt`: 3 into "iii", "C", "3rd",
4
+ * "Three", "Third", "03", "③". docx4j `LabelFormatter.format(int)`.
5
+ *
6
+ * Throws `RangeError` where the format has no label for the value; {@link formatValue}
7
+ * substitutes the decimal label.
8
+ */
9
+ export type LabelFormatter = (value: number) => string;
10
+ /** Adds or replaces the formatter for a `w:numFmt`; `undefined` removes it. docx4j `register`. */
11
+ export declare function register(numFmt: wml.NumberFormat, formatter: LabelFormatter | undefined): void;
12
+ /** The formatter registered for a `w:numFmt`, or undefined. docx4j `NumberFormatter.get`. */
13
+ export declare function formatterFor(numFmt: wml.NumberFormat | undefined): LabelFormatter | undefined;
14
+ /** Every `w:numFmt` this package can format (a test's, and a caller's, inventory). */
15
+ export declare function registeredFormats(): wml.NumberFormat[];
16
+ /** Forgets which formats have been warned about; a test that asserts on the warning needs it. */
17
+ export declare function resetWarnings(): void;
18
+ /**
19
+ * A counter as its label. docx4j `NumberFormatter.getCurrentValueFormatted(numFmt, current, where)`.
20
+ *
21
+ * A `w:numFmt` of undefined is decimal; so is a format with no formatter, and a value the
22
+ * formatter cannot express - with one warning per format naming `where` ("numId 3 ilvl 0") it
23
+ * first happened.
24
+ */
25
+ export declare function formatValue(numFmt: wml.NumberFormat | undefined, value: number, where?: string): string;