@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,860 @@
1
+ // ---------------------------------------------------------------- copying
2
+ /**
3
+ * A structural copy of a leaf value, without its `PARENT` link: what the merges store, so
4
+ * that nothing in an effective `w:pPr` or `w:rPr` is a styles-part object.
5
+ */
6
+ export function copyLeaf(value) {
7
+ if (value === null || typeof value !== 'object')
8
+ return value;
9
+ if (Array.isArray(value))
10
+ return value.map((item) => copyLeaf(item));
11
+ const out = {};
12
+ for (const key of Object.keys(value)) {
13
+ if (key === 'PARENT')
14
+ continue;
15
+ out[key] = copyLeaf(value[key]);
16
+ }
17
+ return out;
18
+ }
19
+ // ---------------------------------------------------------------- emptiness of scalars
20
+ /** docx4j `StyleUtil.isEmpty(String)`: null or the empty string. */
21
+ function emptyString(value) {
22
+ return value === undefined || value === '';
23
+ }
24
+ /** docx4j `StyleUtil.isEmpty(STThemeColor)`: null or `none`. */
25
+ function emptyThemeColor(value) {
26
+ return value === undefined || value === 'none';
27
+ }
28
+ /** docx4j `StyleUtil.apply(String, String)` and friends: the source where it states one. */
29
+ function attr(source, destination) {
30
+ return source === undefined ? destination : source;
31
+ }
32
+ /** docx4j `StyleUtil.apply(STThemeColor, STThemeColor)`: `none` does not override. */
33
+ function themeColor(source, destination) {
34
+ return emptyThemeColor(source) ? destination : source;
35
+ }
36
+ /** A merge with no per-attribute rule: a copy of the source where it has one, else the inherited. */
37
+ export function mergeReplace(source, destination) {
38
+ return source === undefined ? destination : copyLeaf(source);
39
+ }
40
+ /** Never carried: docx4j's `apply` for the owning element does not mention this member. */
41
+ function notCarried(_source, destination) {
42
+ return destination;
43
+ }
44
+ /** Never empty in itself: `undefined` only. */
45
+ function isNull(value) {
46
+ return value === undefined;
47
+ }
48
+ // ---------------------------------------------------------------- leaf emptiness
49
+ /** `<w:b/>` and `<w:b w:val="0"/>` both count: an explicit false is applied. */
50
+ export function isEmptyBool(value) {
51
+ return value === undefined;
52
+ }
53
+ /** A `BooleanDefaultTrue`'s value: absent `w:val` means true (docx4j `isVal()`). */
54
+ export function isTrue(value) {
55
+ return value !== undefined && value.val !== false;
56
+ }
57
+ function isEmptyVal(value) {
58
+ return value === undefined || value.val === undefined;
59
+ }
60
+ function isEmptyStringVal(value) {
61
+ return value === undefined || emptyString(value.val);
62
+ }
63
+ export function isEmptyRStyle(value) {
64
+ return isEmptyStringVal(value);
65
+ }
66
+ /** docx4j `isEmpty(RFonts)`: insensitive to a `w:hint` (which `apply` still carries). */
67
+ export function isEmptyRFonts(value) {
68
+ return value === undefined
69
+ || (emptyString(value.ascii) && value.asciiTheme === undefined
70
+ && emptyString(value.cs) && value.cstheme === undefined
71
+ && emptyString(value.eastAsia) && value.eastAsiaTheme === undefined
72
+ && emptyString(value.hAnsi) && value.hAnsiTheme === undefined);
73
+ }
74
+ export function isEmptyColor(value) {
75
+ return value === undefined || emptyString(value.val);
76
+ }
77
+ export function isEmptyU(value) {
78
+ return value === undefined || (value.val === undefined && emptyString(value.color));
79
+ }
80
+ export function isEmptyHighlight(value) {
81
+ return value === undefined || emptyString(value.val);
82
+ }
83
+ /** @since CR-015 phase 1: a style stating only `w:lang` used to count as empty and was never applied. */
84
+ export function isEmptyLang(value) {
85
+ return value === undefined || (emptyString(value.val) && emptyString(value.eastAsia) && emptyString(value.bidi));
86
+ }
87
+ export function isEmptyShd(value) {
88
+ return value === undefined
89
+ || (emptyString(value.color) && emptyString(value.themeTint) && emptyString(value.themeShade)
90
+ && emptyString(value.fill) && emptyString(value.themeFillTint) && emptyString(value.themeFillShade)
91
+ && value.themeColor === undefined && value.themeFill === undefined && value.val === undefined);
92
+ }
93
+ export function isEmptyBorder(value) {
94
+ return value === undefined
95
+ || (emptyString(value.color) && value.space === undefined && value.sz === undefined
96
+ && value.themeColor === undefined && emptyString(value.themeShade) && emptyString(value.themeTint)
97
+ && value.val === undefined);
98
+ }
99
+ export function isEmptyPBdr(value) {
100
+ return value === undefined
101
+ || (isEmptyBorder(value.top) && isEmptyBorder(value.left) && isEmptyBorder(value.bottom)
102
+ && isEmptyBorder(value.right) && isEmptyBorder(value.between) && isEmptyBorder(value.bar));
103
+ }
104
+ /**
105
+ * docx4j `isEmpty(Ind)`: `w:start`/`w:end` (the strict-conformance spellings) count too
106
+ * (17.0.5); dropping them lost them in style resolution.
107
+ */
108
+ export function isEmptyInd(value) {
109
+ return value === undefined
110
+ || (value.firstLine === undefined && value.firstLineChars === undefined
111
+ && value.hanging === undefined && value.hangingChars === undefined
112
+ && value.left === undefined && value.leftChars === undefined
113
+ && value.right === undefined && value.rightChars === undefined
114
+ && value.start === undefined && value.startChars === undefined
115
+ && value.end === undefined && value.endChars === undefined);
116
+ }
117
+ /** An explicit `w:beforeAutospacing`/`w:afterAutospacing` of either value is a statement too. */
118
+ export function isEmptySpacing(value) {
119
+ return value === undefined
120
+ || (value.after === undefined && value.afterLines === undefined
121
+ && value.before === undefined && value.beforeLines === undefined
122
+ && value.line === undefined && value.lineRule === undefined
123
+ && value.beforeAutospacing === undefined && value.afterAutospacing === undefined);
124
+ }
125
+ function isEmptyTabStop(value) {
126
+ return value === undefined || (value.pos === undefined && value.val === undefined && value.leader === undefined);
127
+ }
128
+ export function isEmptyTabs(value) {
129
+ if (value === undefined || value.tab === undefined || value.tab.length === 0)
130
+ return true;
131
+ return !value.tab.some((stop) => !isEmptyTabStop(stop));
132
+ }
133
+ /**
134
+ * A `w:numPr` is empty only when it states neither `w:numId` nor `w:ilvl`: each inherits on
135
+ * its own (CR-015 probe styles-numpr-ilvl-only).
136
+ */
137
+ export function isEmptyNumPr(value) {
138
+ return value === undefined
139
+ || ((value.numId === undefined || value.numId.val === undefined)
140
+ && (value.ilvl === undefined || value.ilvl.val === undefined));
141
+ }
142
+ /** `w:anchorLock` defaults to true, so only an explicit `w:anchorLock="0"` makes a frame non-empty by itself. */
143
+ export function isEmptyFramePr(value) {
144
+ var _a;
145
+ return value === undefined
146
+ || (value.dropCap === undefined && value.lines === undefined && value.w === undefined
147
+ && value.h === undefined && value.vSpace === undefined && value.hSpace === undefined
148
+ && value.wrap === undefined && value.hAnchor === undefined && value.vAnchor === undefined
149
+ && value.x === undefined && value.xAlign === undefined
150
+ && value.y === undefined && value.yAlign === undefined && value.hRule === undefined
151
+ && ((_a = value.anchorLock) !== null && _a !== void 0 ? _a : true));
152
+ }
153
+ function isEmptyTblWidth(value) {
154
+ // @w:type is ignored, as docx4j does
155
+ return value === undefined || value.w === undefined;
156
+ }
157
+ function isEmptyTblCellMar(value) {
158
+ // w:start/w:end are not read, as docx4j's isEmpty/apply pair does not read them
159
+ return value === undefined
160
+ || (isEmptyTblWidth(value.bottom) && isEmptyTblWidth(value.left)
161
+ && isEmptyTblWidth(value.right) && isEmptyTblWidth(value.top));
162
+ }
163
+ function isEmptyTblBorders(value) {
164
+ return value === undefined
165
+ || (isEmptyBorder(value.bottom) && isEmptyBorder(value.left) && isEmptyBorder(value.right)
166
+ && isEmptyBorder(value.top) && isEmptyBorder(value.insideH) && isEmptyBorder(value.insideV));
167
+ }
168
+ function isEmptyTcBorders(value) {
169
+ return value === undefined
170
+ || (isEmptyBorder(value.bottom) && isEmptyBorder(value.left) && isEmptyBorder(value.right)
171
+ && isEmptyBorder(value.top) && isEmptyBorder(value.insideH) && isEmptyBorder(value.insideV)
172
+ && isEmptyBorder(value.tl2Br) && isEmptyBorder(value.tr2Bl));
173
+ }
174
+ function isEmptyTcMar(value) {
175
+ return value === undefined
176
+ || (isEmptyTblWidth(value.bottom) && isEmptyTblWidth(value.left)
177
+ && isEmptyTblWidth(value.right) && isEmptyTblWidth(value.top));
178
+ }
179
+ function isEmptyTblLook(value) {
180
+ return value === undefined
181
+ || (value.firstColumn === undefined && value.firstRow === undefined
182
+ && value.lastColumn === undefined && value.lastRow === undefined
183
+ && value.noHBand === undefined && value.noVBand === undefined && value.val === undefined);
184
+ }
185
+ function isEmptyTblPPr(value) {
186
+ return value === undefined
187
+ || (value.leftFromText === undefined && value.rightFromText === undefined
188
+ && value.topFromText === undefined && value.bottomFromText === undefined
189
+ && value.vertAnchor === undefined && value.horzAnchor === undefined
190
+ && value.tblpXSpec === undefined && value.tblpX === undefined
191
+ && value.tblpYSpec === undefined && value.tblpY === undefined);
192
+ }
193
+ function isEmptyCnf(value) {
194
+ return isEmptyStringVal(value);
195
+ }
196
+ // ---------------------------------------------------------------- leaf merges
197
+ /** docx4j `apply(BooleanDefaultTrue, BooleanDefaultTrue)`: a copy of the source where it states one. */
198
+ export function mergeBool(source, destination) {
199
+ return source === undefined ? destination : copyLeaf(source);
200
+ }
201
+ /** A leaf whose only content is `w:val`, taken whole when the source states it. */
202
+ function mergeVal(isEmptyOf) {
203
+ return (source, destination) => {
204
+ if (source === undefined || isEmptyOf(source))
205
+ return destination;
206
+ const out = (destination !== null && destination !== void 0 ? destination : {});
207
+ out.val = source.val;
208
+ return out;
209
+ };
210
+ }
211
+ export const mergeRStyle = mergeVal(isEmptyRStyle);
212
+ export const mergeHighlight = mergeVal(isEmptyHighlight);
213
+ export const mergeEm = mergeVal(isEmptyVal);
214
+ export const mergeVertAlign = mergeVal(isEmptyVal);
215
+ export const mergeEffect = mergeVal(isEmptyVal);
216
+ export const mergeHps = mergeVal(isEmptyVal);
217
+ export const mergeSignedHps = mergeVal(isEmptyVal);
218
+ export const mergeSignedTwips = mergeVal(isEmptyVal);
219
+ export const mergeTextScale = mergeVal(isEmptyVal);
220
+ export const mergeJc = mergeVal(isEmptyVal);
221
+ export const mergeOutlineLvl = mergeVal(isEmptyVal);
222
+ export const mergeTextAlignment = mergeVal(isEmptyVal);
223
+ export const mergeTextDirection = mergeVal(isEmptyVal);
224
+ export const mergeTextboxTightWrap = mergeVal(isEmptyVal);
225
+ export const mergeCnf = mergeVal(isEmptyCnf);
226
+ export const mergePStyle = mergeVal(isEmptyStringVal);
227
+ const mergeTblStyle = mergeVal(isEmptyStringVal);
228
+ const mergeRowBandSize = mergeVal(isEmptyVal);
229
+ const mergeColBandSize = mergeVal(isEmptyVal);
230
+ const mergeTblOverlap = mergeVal(isEmptyVal);
231
+ const mergeVAlign = mergeVal(isEmptyVal);
232
+ const mergeGridSpan = mergeVal(isEmptyVal);
233
+ const mergeHMerge = mergeVal(isEmptyStringVal);
234
+ const mergeVMerge = mergeVal(isEmptyStringVal);
235
+ const mergeTblLayout = (source, destination) => {
236
+ if (source === undefined || source.type === undefined)
237
+ return destination;
238
+ const out = destination !== null && destination !== void 0 ? destination : {};
239
+ out.type = source.type;
240
+ return out;
241
+ };
242
+ /**
243
+ * `w:rFonts`: a theme reference trumps an explicit face within one element, and a source with
244
+ * only a `w:hint` still says something. A null source leaves the destination alone (until
245
+ * CR-015 phase 1 it was given an empty `w:rFonts`, so every merged `w:rPr` read as directly
246
+ * formatted).
247
+ */
248
+ export const mergeRFonts = (source, destination) => {
249
+ if (source === undefined)
250
+ return destination;
251
+ const out = destination !== null && destination !== void 0 ? destination : {};
252
+ if (isEmptyRFonts(source)) {
253
+ if (source.hint !== undefined)
254
+ out.hint = source.hint;
255
+ // else: keep the (possibly empty) element, which RunFontSelector relies on
256
+ return out;
257
+ }
258
+ if (source.ascii !== undefined) {
259
+ out.ascii = source.ascii;
260
+ delete out.asciiTheme;
261
+ }
262
+ if (source.cs !== undefined) {
263
+ out.cs = source.cs;
264
+ delete out.cstheme;
265
+ }
266
+ if (source.eastAsia !== undefined) {
267
+ out.eastAsia = source.eastAsia;
268
+ delete out.eastAsiaTheme;
269
+ }
270
+ if (source.hAnsi !== undefined) {
271
+ out.hAnsi = source.hAnsi;
272
+ delete out.hAnsiTheme;
273
+ }
274
+ if (source.asciiTheme !== undefined) {
275
+ out.asciiTheme = source.asciiTheme;
276
+ delete out.ascii;
277
+ }
278
+ if (source.cstheme !== undefined) {
279
+ out.cstheme = source.cstheme;
280
+ delete out.cs;
281
+ }
282
+ if (source.eastAsiaTheme !== undefined) {
283
+ out.eastAsiaTheme = source.eastAsiaTheme;
284
+ delete out.eastAsia;
285
+ }
286
+ if (source.hAnsiTheme !== undefined) {
287
+ out.hAnsiTheme = source.hAnsiTheme;
288
+ delete out.hAnsi;
289
+ }
290
+ if (source.hint !== undefined)
291
+ out.hint = source.hint;
292
+ return out;
293
+ };
294
+ export const mergeColor = (source, destination) => {
295
+ if (isEmptyColor(source))
296
+ return destination;
297
+ const s = source;
298
+ const out = (destination !== null && destination !== void 0 ? destination : {});
299
+ out.themeColor = themeColor(s.themeColor, out.themeColor);
300
+ out.themeShade = attr(s.themeShade, out.themeShade);
301
+ out.themeTint = attr(s.themeTint, out.themeTint);
302
+ out.val = attr(s.val, out.val);
303
+ return out;
304
+ };
305
+ /** `w:val` and the colour attributes each inherit on their own (CR-015 phase 1). */
306
+ export const mergeU = (source, destination) => {
307
+ if (isEmptyU(source))
308
+ return destination;
309
+ const s = source;
310
+ const out = destination !== null && destination !== void 0 ? destination : {};
311
+ out.val = attr(s.val, out.val);
312
+ out.color = attr(s.color, out.color);
313
+ out.themeColor = themeColor(s.themeColor, out.themeColor);
314
+ out.themeTint = attr(s.themeTint, out.themeTint);
315
+ out.themeShade = attr(s.themeShade, out.themeShade);
316
+ return out;
317
+ };
318
+ /** `w:val`, `w:eastAsia` and `w:bidi` each name the language of one script range and each inherits. */
319
+ export const mergeLang = (source, destination) => {
320
+ if (isEmptyLang(source))
321
+ return destination;
322
+ const s = source;
323
+ const out = destination !== null && destination !== void 0 ? destination : {};
324
+ out.val = attr(s.val, out.val);
325
+ out.eastAsia = attr(s.eastAsia, out.eastAsia);
326
+ out.bidi = attr(s.bidi, out.bidi);
327
+ return out;
328
+ };
329
+ export const mergeShd = (source, destination) => {
330
+ if (isEmptyShd(source))
331
+ return destination;
332
+ const s = source;
333
+ const out = (destination !== null && destination !== void 0 ? destination : {});
334
+ out.color = attr(s.color, out.color);
335
+ out.fill = attr(s.fill, out.fill);
336
+ out.val = attr(s.val, out.val);
337
+ out.themeTint = attr(s.themeTint, out.themeTint);
338
+ out.themeShade = attr(s.themeShade, out.themeShade);
339
+ out.themeFillTint = attr(s.themeFillTint, out.themeFillTint);
340
+ out.themeFillShade = attr(s.themeFillShade, out.themeFillShade);
341
+ // the enums only when the source states them (until CR-015 a null source cleared them)
342
+ out.themeColor = themeColor(s.themeColor, out.themeColor);
343
+ out.themeFill = themeColor(s.themeFill, out.themeFill);
344
+ return out;
345
+ };
346
+ export const mergeBorder = (source, destination) => {
347
+ if (isEmptyBorder(source))
348
+ return destination;
349
+ const s = source;
350
+ const out = (destination !== null && destination !== void 0 ? destination : {});
351
+ out.color = attr(s.color, out.color);
352
+ out.space = attr(s.space, out.space);
353
+ out.sz = attr(s.sz, out.sz);
354
+ out.themeColor = themeColor(s.themeColor, out.themeColor);
355
+ out.themeShade = attr(s.themeShade, out.themeShade);
356
+ out.themeTint = attr(s.themeTint, out.themeTint);
357
+ out.val = attr(s.val, out.val);
358
+ return out;
359
+ };
360
+ export const mergePBdr = (source, destination) => {
361
+ if (isEmptyPBdr(source))
362
+ return destination;
363
+ const s = source;
364
+ const out = destination !== null && destination !== void 0 ? destination : {};
365
+ out.top = mergeBorder(s.top, out.top);
366
+ out.left = mergeBorder(s.left, out.left);
367
+ out.bottom = mergeBorder(s.bottom, out.bottom);
368
+ out.right = mergeBorder(s.right, out.right);
369
+ out.between = mergeBorder(s.between, out.between);
370
+ out.bar = mergeBorder(s.bar, out.bar);
371
+ return out;
372
+ };
373
+ /** `w:numId` and `w:ilvl` each inherit on their own; see {@link isEmptyNumPr}. */
374
+ export const mergeNumPr = (source, destination) => {
375
+ if (isEmptyNumPr(source))
376
+ return destination;
377
+ const s = source;
378
+ const out = destination !== null && destination !== void 0 ? destination : {};
379
+ if (s.numId !== undefined && s.numId.val !== undefined)
380
+ out.numId = copyLeaf(s.numId);
381
+ if (s.ilvl !== undefined && s.ilvl.val !== undefined)
382
+ out.ilvl = copyLeaf(s.ilvl);
383
+ return out;
384
+ };
385
+ /**
386
+ * `w:ind`: `w:firstLine` and `w:hanging` are two spellings of one property (ECMA-376
387
+ * 17.3.1.12), so whichever of the two the more specific `w:ind` states replaces both; the
388
+ * rest inherit per attribute.
389
+ */
390
+ export const mergeInd = (source, destination) => {
391
+ if (isEmptyInd(source))
392
+ return destination;
393
+ const s = source;
394
+ const out = destination !== null && destination !== void 0 ? destination : {};
395
+ const sourceFirstLine = s.firstLine !== undefined || s.firstLineChars !== undefined;
396
+ const sourceHanging = s.hanging !== undefined || s.hangingChars !== undefined;
397
+ if (sourceFirstLine && !sourceHanging) {
398
+ delete out.hanging;
399
+ delete out.hangingChars;
400
+ }
401
+ else if (sourceHanging && !sourceFirstLine) {
402
+ delete out.firstLine;
403
+ delete out.firstLineChars;
404
+ }
405
+ out.firstLine = attr(s.firstLine, out.firstLine);
406
+ out.firstLineChars = attr(s.firstLineChars, out.firstLineChars);
407
+ out.hanging = attr(s.hanging, out.hanging);
408
+ out.hangingChars = attr(s.hangingChars, out.hangingChars);
409
+ out.left = attr(s.left, out.left);
410
+ out.leftChars = attr(s.leftChars, out.leftChars);
411
+ out.right = attr(s.right, out.right);
412
+ out.rightChars = attr(s.rightChars, out.rightChars);
413
+ out.start = attr(s.start, out.start);
414
+ out.startChars = attr(s.startChars, out.startChars);
415
+ out.end = attr(s.end, out.end);
416
+ out.endChars = attr(s.endChars, out.endChars);
417
+ return out;
418
+ };
419
+ /**
420
+ * `w:spacing`: the autospacing attributes survive the merge, and `w:lineRule` qualifies
421
+ * `w:line` - a source stating `w:line` states a rule too (auto when it names none), and a
422
+ * source stating no `w:line` leaves both inherited (CR-015 probe styles-linerule).
423
+ */
424
+ export const mergeSpacing = (source, destination) => {
425
+ var _a;
426
+ if (source === undefined)
427
+ return destination;
428
+ let out = destination;
429
+ if (source.beforeAutospacing !== undefined || source.afterAutospacing !== undefined) {
430
+ out !== null && out !== void 0 ? out : (out = {});
431
+ if (source.beforeAutospacing !== undefined)
432
+ out.beforeAutospacing = source.beforeAutospacing;
433
+ if (source.afterAutospacing !== undefined)
434
+ out.afterAutospacing = source.afterAutospacing;
435
+ }
436
+ if (!isEmptySpacing(source)) {
437
+ out !== null && out !== void 0 ? out : (out = {});
438
+ out.after = attr(source.after, out.after);
439
+ out.afterLines = attr(source.afterLines, out.afterLines);
440
+ out.before = attr(source.before, out.before);
441
+ out.beforeLines = attr(source.beforeLines, out.beforeLines);
442
+ if (source.line !== undefined) {
443
+ out.line = source.line;
444
+ out.lineRule = (_a = source.lineRule) !== null && _a !== void 0 ? _a : 'auto';
445
+ }
446
+ else if (source.lineRule !== undefined) {
447
+ out.lineRule = source.lineRule;
448
+ }
449
+ }
450
+ return out;
451
+ };
452
+ /**
453
+ * `w:tabs`: the custom tab stops are the union of those declared and those inherited, a stop
454
+ * at the same position replaces the inherited one, and `w:val="clear"` only removes
455
+ * (ECMA-376 17.3.1.38, 17.3.1.37). Word holds them in ascending position order.
456
+ */
457
+ export const mergeTabs = (source, destination) => {
458
+ var _a;
459
+ if (isEmptyTabs(source))
460
+ return destination;
461
+ const out = destination !== null && destination !== void 0 ? destination : { tab: [] };
462
+ (_a = out.tab) !== null && _a !== void 0 ? _a : (out.tab = []);
463
+ for (const stop of source.tab) {
464
+ const pos = stop.pos;
465
+ if (pos !== undefined) {
466
+ for (let i = out.tab.length - 1; i >= 0; i--) {
467
+ if (out.tab[i].pos === pos)
468
+ out.tab.splice(i, 1);
469
+ }
470
+ }
471
+ if (stop.val === 'clear')
472
+ continue;
473
+ out.tab.push({ leader: stop.leader, pos, val: stop.val });
474
+ }
475
+ out.tab.sort((a, b) => {
476
+ if (a.pos === undefined)
477
+ return b.pos === undefined ? 0 : -1;
478
+ if (b.pos === undefined)
479
+ return 1;
480
+ return a.pos - b.pos;
481
+ });
482
+ return out;
483
+ };
484
+ /**
485
+ * `w:framePr`'s attributes each inherit on their own: a paragraph whose direct `w:framePr`
486
+ * gives only `w:x`/`w:y` keeps the anchors its style states. `w:anchorLock` defaults to true,
487
+ * and docx4j's merge writes that default out explicitly.
488
+ */
489
+ export const mergeFramePr = (source, destination) => {
490
+ var _a;
491
+ if (isEmptyFramePr(source))
492
+ return destination;
493
+ const s = source;
494
+ const out = destination !== null && destination !== void 0 ? destination : {};
495
+ out.dropCap = attr(s.dropCap, out.dropCap);
496
+ out.lines = attr(s.lines, out.lines);
497
+ out.w = attr(s.w, out.w);
498
+ out.h = attr(s.h, out.h);
499
+ out.vSpace = attr(s.vSpace, out.vSpace);
500
+ out.hSpace = attr(s.hSpace, out.hSpace);
501
+ out.wrap = attr(s.wrap, out.wrap);
502
+ out.hAnchor = attr(s.hAnchor, out.hAnchor);
503
+ out.vAnchor = attr(s.vAnchor, out.vAnchor);
504
+ out.x = attr(s.x, out.x);
505
+ out.xAlign = attr(s.xAlign, out.xAlign);
506
+ out.y = attr(s.y, out.y);
507
+ out.yAlign = attr(s.yAlign, out.yAlign);
508
+ out.hRule = attr(s.hRule, out.hRule);
509
+ // docx4j reads this through isAnchorLock(), which answers true when the attribute is absent
510
+ out.anchorLock = (_a = s.anchorLock) !== null && _a !== void 0 ? _a : true;
511
+ return out;
512
+ };
513
+ const mergeTblWidth = (source, destination) => {
514
+ if (source === undefined || source.w === undefined)
515
+ return destination;
516
+ const out = destination !== null && destination !== void 0 ? destination : {};
517
+ out.w = source.w;
518
+ // "if @w:type is omitted, its value shall be assumed to be dxa"
519
+ out.type = source.type;
520
+ return out;
521
+ };
522
+ const mergeTblCellMar = (source, destination) => {
523
+ if (isEmptyTblCellMar(source))
524
+ return destination;
525
+ const s = source;
526
+ const out = destination !== null && destination !== void 0 ? destination : {};
527
+ out.bottom = mergeTblWidth(s.bottom, out.bottom);
528
+ out.left = mergeTblWidth(s.left, out.left);
529
+ out.right = mergeTblWidth(s.right, out.right);
530
+ out.top = mergeTblWidth(s.top, out.top);
531
+ return out;
532
+ };
533
+ const mergeTblBorders = (source, destination) => {
534
+ if (isEmptyTblBorders(source))
535
+ return destination;
536
+ const s = source;
537
+ const out = destination !== null && destination !== void 0 ? destination : {};
538
+ out.bottom = mergeBorder(s.bottom, out.bottom);
539
+ out.left = mergeBorder(s.left, out.left);
540
+ out.right = mergeBorder(s.right, out.right);
541
+ out.top = mergeBorder(s.top, out.top);
542
+ out.insideH = mergeBorder(s.insideH, out.insideH);
543
+ out.insideV = mergeBorder(s.insideV, out.insideV);
544
+ return out;
545
+ };
546
+ const mergeTcBorders = (source, destination) => {
547
+ if (isEmptyTcBorders(source))
548
+ return destination;
549
+ const s = source;
550
+ const out = destination !== null && destination !== void 0 ? destination : {};
551
+ out.bottom = mergeBorder(s.bottom, out.bottom);
552
+ out.left = mergeBorder(s.left, out.left);
553
+ out.right = mergeBorder(s.right, out.right);
554
+ out.top = mergeBorder(s.top, out.top);
555
+ out.insideH = mergeBorder(s.insideH, out.insideH);
556
+ out.insideV = mergeBorder(s.insideV, out.insideV);
557
+ out.tl2Br = mergeBorder(s.tl2Br, out.tl2Br);
558
+ out.tr2Bl = mergeBorder(s.tr2Bl, out.tr2Bl);
559
+ return out;
560
+ };
561
+ const mergeTcMar = (source, destination) => {
562
+ if (isEmptyTcMar(source))
563
+ return destination;
564
+ const s = source;
565
+ const out = destination !== null && destination !== void 0 ? destination : {};
566
+ out.bottom = mergeTblWidth(s.bottom, out.bottom);
567
+ out.left = mergeTblWidth(s.left, out.left);
568
+ out.right = mergeTblWidth(s.right, out.right);
569
+ out.top = mergeTblWidth(s.top, out.top);
570
+ return out;
571
+ };
572
+ const mergeTblLook = (source, destination) => {
573
+ if (isEmptyTblLook(source))
574
+ return destination;
575
+ const s = source;
576
+ const out = destination !== null && destination !== void 0 ? destination : {};
577
+ out.firstColumn = attr(s.firstColumn, out.firstColumn);
578
+ out.firstRow = attr(s.firstRow, out.firstRow);
579
+ out.lastColumn = attr(s.lastColumn, out.lastColumn);
580
+ out.lastRow = attr(s.lastRow, out.lastRow);
581
+ out.noHBand = attr(s.noHBand, out.noHBand);
582
+ out.noVBand = attr(s.noVBand, out.noVBand);
583
+ out.val = attr(s.val, out.val);
584
+ return out;
585
+ };
586
+ /**
587
+ * `w:tblpPr`: the anchors and the `*Spec` enums only when the source states them - a
588
+ * `w:tblpPr` stating only `w:tblpX` keeps its inherited anchors in Word.
589
+ */
590
+ const mergeTblPPr = (source, destination) => {
591
+ if (isEmptyTblPPr(source))
592
+ return destination;
593
+ const s = source;
594
+ const out = destination !== null && destination !== void 0 ? destination : {};
595
+ out.leftFromText = attr(s.leftFromText, out.leftFromText);
596
+ out.rightFromText = attr(s.rightFromText, out.rightFromText);
597
+ out.topFromText = attr(s.topFromText, out.topFromText);
598
+ out.bottomFromText = attr(s.bottomFromText, out.bottomFromText);
599
+ if (s.vertAnchor !== undefined)
600
+ out.vertAnchor = s.vertAnchor;
601
+ if (s.horzAnchor !== undefined)
602
+ out.horzAnchor = s.horzAnchor;
603
+ if (s.tblpXSpec !== undefined)
604
+ out.tblpXSpec = s.tblpXSpec;
605
+ out.tblpX = attr(s.tblpX, out.tblpX);
606
+ if (s.tblpYSpec !== undefined)
607
+ out.tblpYSpec = s.tblpYSpec;
608
+ out.tblpY = attr(s.tblpY, out.tblpY);
609
+ return out;
610
+ };
611
+ /**
612
+ * One entry. The accessors are by member name, which is the same on `RPr` and `ParaRPr`
613
+ * (docx4j needs an accessor pair per class there; here the two generated interfaces have the
614
+ * same members, so one pair serves both).
615
+ */
616
+ function prop(name, merge, isEmpty, copyOf, options) {
617
+ var _a, _b;
618
+ return {
619
+ name,
620
+ isFormatting: (_a = options === null || options === void 0 ? void 0 : options.formatting) !== null && _a !== void 0 ? _a : true,
621
+ countsEmpty: (_b = options === null || options === void 0 ? void 0 : options.countsEmpty) !== null && _b !== void 0 ? _b : true,
622
+ get: (owner) => owner[name],
623
+ set: (owner, value) => {
624
+ const record = owner;
625
+ if (value === undefined)
626
+ delete record[name];
627
+ else
628
+ record[name] = value;
629
+ },
630
+ merge,
631
+ isEmpty,
632
+ copyOf,
633
+ };
634
+ }
635
+ /** A `BooleanDefaultTrue` member. */
636
+ function bool(name, options) {
637
+ return prop(name, mergeBool, isEmptyBool, copyLeaf, options);
638
+ }
639
+ /** A w14 member (Office 2010 text effects and OpenType features): replaced whole. */
640
+ function w14(name) {
641
+ return prop(name, mergeReplace, isNull, copyLeaf);
642
+ }
643
+ /**
644
+ * The members of `w:rPr` (17.3.2) and of the paragraph mark's `w:pPr/w:rPr`, in schema order,
645
+ * plus the w14 extensions the generated interfaces carry. Not listed: `w:rPrChange` and the
646
+ * paragraph mark's `w:ins`/`w:del`/`w:moveFrom`/`w:moveTo`, which record revisions and are
647
+ * never inherited.
648
+ */
649
+ export const RUN = [
650
+ prop('rStyle', mergeRStyle, isEmptyRStyle, copyLeaf, { formatting: false }),
651
+ prop('rFonts', mergeRFonts, isEmptyRFonts, copyLeaf),
652
+ bool('b'),
653
+ bool('bCs'),
654
+ bool('i'),
655
+ bool('iCs'),
656
+ bool('caps'),
657
+ bool('smallCaps'),
658
+ bool('strike'),
659
+ bool('dstrike'),
660
+ bool('outline'),
661
+ bool('shadow'),
662
+ bool('emboss'),
663
+ bool('imprint'),
664
+ bool('noProof'),
665
+ bool('snapToGrid'),
666
+ bool('vanish'),
667
+ bool('webHidden'),
668
+ prop('color', mergeColor, isEmptyColor, copyLeaf),
669
+ prop('spacing', mergeSignedTwips, isEmptyVal, copyLeaf),
670
+ prop('w', mergeTextScale, isEmptyVal, copyLeaf),
671
+ prop('kern', mergeHps, isEmptyVal, copyLeaf),
672
+ prop('position', mergeSignedHps, isEmptyVal, copyLeaf),
673
+ prop('sz', mergeHps, isEmptyVal, copyLeaf),
674
+ prop('szCs', mergeHps, isEmptyVal, copyLeaf),
675
+ prop('highlight', mergeHighlight, isEmptyHighlight, copyLeaf),
676
+ prop('u', mergeU, isEmptyU, copyLeaf),
677
+ prop('effect', mergeEffect, isEmptyVal, copyLeaf),
678
+ prop('bdr', mergeBorder, isEmptyBorder, copyLeaf),
679
+ prop('shd', mergeShd, isEmptyShd, copyLeaf),
680
+ prop('fitText', mergeReplace, isNull, copyLeaf),
681
+ prop('vertAlign', mergeVertAlign, isEmptyVal, copyLeaf),
682
+ bool('rtl'),
683
+ bool('cs'),
684
+ prop('em', mergeEm, isEmptyVal, copyLeaf),
685
+ prop('lang', mergeLang, isEmptyLang, copyLeaf),
686
+ prop('eastAsianLayout', mergeReplace, isNull, copyLeaf),
687
+ bool('specVanish'),
688
+ bool('oMath'),
689
+ // w14 (Office 2010 text effects and OpenType features)
690
+ w14('glow'),
691
+ w14('shadow14'),
692
+ w14('reflection'),
693
+ w14('textOutline'),
694
+ w14('textFill'),
695
+ w14('scene3D'),
696
+ w14('props3D'),
697
+ w14('ligatures'),
698
+ w14('numForm'),
699
+ w14('numSpacing'),
700
+ w14('stylisticSets'),
701
+ w14('cntxtAlts'),
702
+ ];
703
+ /** Members of `w:rPr` and `w:pPr/w:rPr` that are not in {@link RUN} (revision records). */
704
+ export const RUN_EXCLUDED = ['rPrChange', 'ins', 'del', 'moveFrom', 'moveTo'];
705
+ /**
706
+ * The names of the **toggle properties** of `w:rPr`, in the order ECMA-376-1 §17.7.3 lists
707
+ * them. Twelve, and no more: `w:dstrike`, `w:noProof`, `w:snapToGrid`, `w:webHidden`,
708
+ * `w:rtl`, `w:cs`, `w:specVanish` and `w:oMath` are Boolean but are not toggles.
709
+ */
710
+ export const TOGGLE_NAMES = new Set([
711
+ 'b', 'bCs', 'caps', 'emboss', 'i', 'iCs', 'imprint', 'outline',
712
+ 'shadow', 'smallCaps', 'strike', 'vanish',
713
+ ]);
714
+ /** {@link TOGGLE_NAMES} as members of {@link RUN}. */
715
+ export const TOGGLES = [...TOGGLE_NAMES].map((name) => {
716
+ const found = RUN.find((p) => p.name === name);
717
+ if (!found)
718
+ throw new Error(`no w:rPr member named ${name}`);
719
+ return found;
720
+ });
721
+ /** The `w:ind` member's name: the paragraph merge applies it last, after the numbering level's. */
722
+ export const IND = 'ind';
723
+ /**
724
+ * The members of `w:pPr` shared with a style's `w:pPr` (`PPrBase`, 17.3.1), in schema order.
725
+ * Not formatting: `w:pStyle` (the style reference), `w:divId` (an HTML import artefact),
726
+ * `w:cnfStyle` (Word's cache of the table conditions that apply) and `w14:collapsed` (the
727
+ * outline view's state). A `w:pPr`'s own `w:rPr` (the paragraph mark) and `w:sectPr` are
728
+ * outside `PPrBase` and outside this list.
729
+ */
730
+ export const PARAGRAPH = [
731
+ prop('pStyle', mergePStyle, isEmptyStringVal, copyLeaf, { formatting: false }),
732
+ bool('keepNext'),
733
+ bool('keepLines'),
734
+ bool('pageBreakBefore'),
735
+ prop('framePr', mergeFramePr, isEmptyFramePr, copyLeaf),
736
+ bool('widowControl'),
737
+ prop('numPr', mergeNumPr, isEmptyNumPr, copyLeaf),
738
+ bool('suppressLineNumbers'),
739
+ prop('pBdr', mergePBdr, isEmptyPBdr, copyLeaf),
740
+ prop('shd', mergeShd, isEmptyShd, copyLeaf),
741
+ prop('tabs', mergeTabs, isEmptyTabs, copyLeaf),
742
+ bool('suppressAutoHyphens'),
743
+ bool('kinsoku'),
744
+ bool('wordWrap'),
745
+ bool('overflowPunct'),
746
+ bool('topLinePunct'),
747
+ bool('autoSpaceDE'),
748
+ bool('autoSpaceDN'),
749
+ bool('bidi'),
750
+ bool('adjustRightInd'),
751
+ bool('snapToGrid'),
752
+ prop('spacing', mergeSpacing, isEmptySpacing, copyLeaf),
753
+ prop(IND, mergeInd, isEmptyInd, copyLeaf),
754
+ bool('contextualSpacing'),
755
+ bool('mirrorIndents'),
756
+ bool('suppressOverlap'),
757
+ prop('jc', mergeJc, isEmptyVal, copyLeaf),
758
+ prop('textDirection', mergeTextDirection, isEmptyVal, copyLeaf),
759
+ prop('textAlignment', mergeTextAlignment, isEmptyVal, copyLeaf),
760
+ prop('textboxTightWrap', mergeTextboxTightWrap, isEmptyVal, copyLeaf),
761
+ prop('outlineLvl', mergeOutlineLvl, isEmptyVal, copyLeaf),
762
+ prop('divId', mergeReplace, isNull, copyLeaf, { formatting: false }),
763
+ prop('cnfStyle', mergeCnf, isEmptyCnf, copyLeaf, { formatting: false }),
764
+ bool('collapsed', { formatting: false }),
765
+ ];
766
+ /** Members of `w:pPr` that are not in {@link PARAGRAPH}: the mark, the section, the revision. */
767
+ export const PARAGRAPH_EXCLUDED = ['rPr', 'sectPr', 'pPrChange'];
768
+ /**
769
+ * The members of `w:tblPr` (`CTTblPrBase`, 17.4.60), in schema order.
770
+ *
771
+ * Three quirks of docx4j's hand-written pair are reproduced and flagged: `w:bidiVisual` is
772
+ * applied but not counted by `isEmpty`, and `w:tblCaption` and `w:tblDescription` are neither
773
+ * applied nor counted (they are a table's accessibility text, not formatting a style carries).
774
+ */
775
+ export const TABLE = [
776
+ prop('tblStyle', mergeTblStyle, isEmptyStringVal, copyLeaf, { formatting: false }),
777
+ prop('tblpPr', mergeTblPPr, isEmptyTblPPr, copyLeaf),
778
+ prop('tblOverlap', mergeTblOverlap, isEmptyVal, copyLeaf),
779
+ bool('bidiVisual', { countsEmpty: false }),
780
+ prop('tblStyleRowBandSize', mergeRowBandSize, isEmptyVal, copyLeaf),
781
+ prop('tblStyleColBandSize', mergeColBandSize, isEmptyVal, copyLeaf),
782
+ prop('tblW', mergeTblWidth, isEmptyTblWidth, copyLeaf),
783
+ prop('jc', mergeJc, isEmptyVal, copyLeaf),
784
+ prop('tblCellSpacing', mergeTblWidth, isEmptyTblWidth, copyLeaf),
785
+ prop('tblInd', mergeTblWidth, isEmptyTblWidth, copyLeaf),
786
+ prop('tblBorders', mergeTblBorders, isEmptyTblBorders, copyLeaf),
787
+ prop('shd', mergeShd, isEmptyShd, copyLeaf),
788
+ prop('tblLayout', mergeTblLayout, (v) => v === undefined || v.type === undefined, copyLeaf),
789
+ prop('tblCellMar', mergeTblCellMar, isEmptyTblCellMar, copyLeaf),
790
+ prop('tblLook', mergeTblLook, isEmptyTblLook, copyLeaf),
791
+ prop('tblCaption', notCarried, isNull, copyLeaf, { countsEmpty: false }),
792
+ prop('tblDescription', notCarried, isNull, copyLeaf, { countsEmpty: false }),
793
+ ];
794
+ export const TABLE_EXCLUDED = ['tblPrChange'];
795
+ /**
796
+ * The members of `w:tcPr` (`TcPr`, 17.4.68), in schema order. `w:cellIns`, `w:cellDel`,
797
+ * `w:cellMerge` and `w:tcPrChange` record revisions and are excluded.
798
+ */
799
+ export const CELL = [
800
+ prop('cnfStyle', mergeCnf, isEmptyCnf, copyLeaf, { formatting: false }),
801
+ prop('tcW', mergeTblWidth, isEmptyTblWidth, copyLeaf),
802
+ prop('gridSpan', mergeGridSpan, isEmptyVal, copyLeaf),
803
+ prop('hMerge', mergeHMerge, isEmptyStringVal, copyLeaf),
804
+ prop('vMerge', mergeVMerge, isEmptyStringVal, copyLeaf),
805
+ prop('tcBorders', mergeTcBorders, isEmptyTcBorders, copyLeaf),
806
+ prop('shd', mergeShd, isEmptyShd, copyLeaf),
807
+ bool('noWrap'),
808
+ prop('tcMar', mergeTcMar, isEmptyTcMar, copyLeaf),
809
+ prop('textDirection', mergeTextDirection, isEmptyVal, copyLeaf),
810
+ bool('tcFitText'),
811
+ prop('vAlign', mergeVAlign, isEmptyVal, copyLeaf),
812
+ bool('hideMark'),
813
+ ];
814
+ export const CELL_EXCLUDED = ['cellIns', 'cellDel', 'cellMerge', 'tcPrChange'];
815
+ // ---------------------------------------------------------------- generic operations
816
+ /** The member of that name, or undefined. */
817
+ export function namedProperty(catalogue, name) {
818
+ return catalogue.find((p) => p.name === name);
819
+ }
820
+ /** Whether every member of `owner` is empty. */
821
+ export function isEmptyOf(catalogue, owner) {
822
+ if (owner === undefined || owner === null)
823
+ return true;
824
+ for (const p of catalogue) {
825
+ if (!p.countsEmpty)
826
+ continue;
827
+ if (!p.isEmpty(p.get(owner)))
828
+ return false;
829
+ }
830
+ return true;
831
+ }
832
+ /** Whether any formatting member is present (an element that is there, even with no attributes, counts: it was stated). */
833
+ export function hasDirectFormattingOf(catalogue, owner) {
834
+ if (owner === undefined || owner === null)
835
+ return false;
836
+ for (const p of catalogue) {
837
+ if (p.isFormatting && p.get(owner) !== undefined)
838
+ return true;
839
+ }
840
+ return false;
841
+ }
842
+ /** Apply every member of `source` over `destination`, in place, except those named. */
843
+ export function applyCatalogue(catalogue, source, destination, except) {
844
+ for (const p of catalogue) {
845
+ if (except === null || except === void 0 ? void 0 : except.has(p.name))
846
+ continue;
847
+ applyProperty(p, source, destination);
848
+ }
849
+ }
850
+ /** Apply one member of `source` over `destination`. */
851
+ export function applyProperty(p, source, destination) {
852
+ p.set(destination, p.merge(p.get(source), p.get(destination)));
853
+ }
854
+ /** Unset in `destination` every member that `source` states. */
855
+ export function unsetCatalogue(catalogue, source, destination) {
856
+ for (const p of catalogue) {
857
+ if (p.get(source) !== undefined)
858
+ p.set(destination, undefined);
859
+ }
860
+ }