@docx4j/core-ts 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/NOTICE +4 -0
  2. package/README.md +92 -4
  3. package/dist/html/convert.mjs +2 -1
  4. package/dist/html/elements.mjs +2 -1
  5. package/dist/model/color/ColorMath.d.mts +29 -0
  6. package/dist/model/color/ColorMath.mjs +146 -0
  7. package/dist/model/color/ColorTables.d.mts +6 -0
  8. package/dist/model/color/ColorTables.mjs +83 -0
  9. package/dist/model/color/DrawingMLColors.d.mts +52 -0
  10. package/dist/model/color/DrawingMLColors.mjs +374 -0
  11. package/dist/model/color/ResolvedColor.d.mts +36 -0
  12. package/dist/model/color/ResolvedColor.mjs +65 -0
  13. package/dist/model/color/SpreadsheetColors.d.mts +36 -0
  14. package/dist/model/color/SpreadsheetColors.mjs +84 -0
  15. package/dist/model/color/StyleFill.d.mts +28 -0
  16. package/dist/model/color/StyleFill.mjs +21 -0
  17. package/dist/model/color/ThemeColors.d.mts +86 -0
  18. package/dist/model/color/ThemeColors.mjs +304 -0
  19. package/dist/model/color/WordColors.d.mts +71 -0
  20. package/dist/model/color/WordColors.mjs +121 -0
  21. package/dist/model/color/index.d.mts +6 -0
  22. package/dist/model/color/index.mjs +30 -0
  23. package/dist/model/content/Body.d.mts +145 -23
  24. package/dist/model/content/Body.mjs +507 -150
  25. package/dist/model/content/Comment.d.mts +23 -5
  26. package/dist/model/content/Comment.mjs +207 -26
  27. package/dist/model/content/ContentControl.d.mts +198 -19
  28. package/dist/model/content/ContentControl.mjs +672 -99
  29. package/dist/model/content/Font.d.mts +70 -17
  30. package/dist/model/content/Font.mjs +119 -36
  31. package/dist/model/content/InlinePicture.d.mts +11 -0
  32. package/dist/model/content/InlinePicture.mjs +21 -1
  33. package/dist/model/content/List.d.mts +6 -3
  34. package/dist/model/content/List.mjs +18 -8
  35. package/dist/model/content/Paragraph.d.mts +200 -14
  36. package/dist/model/content/Paragraph.mjs +898 -82
  37. package/dist/model/content/Range.d.mts +227 -12
  38. package/dist/model/content/Range.mjs +785 -59
  39. package/dist/model/content/ResolvedView.d.mts +104 -0
  40. package/dist/model/content/ResolvedView.mjs +596 -0
  41. package/dist/model/content/Table.d.mts +29 -3
  42. package/dist/model/content/Table.mjs +135 -49
  43. package/dist/model/content/TrackedChange.d.mts +174 -15
  44. package/dist/model/content/TrackedChange.mjs +734 -170
  45. package/dist/model/content/comments.d.mts +20 -6
  46. package/dist/model/content/comments.mjs +67 -57
  47. package/dist/model/content/generalException.d.mts +18 -0
  48. package/dist/model/content/generalException.mjs +24 -0
  49. package/dist/model/content/index.d.mts +10 -3
  50. package/dist/model/content/index.mjs +10 -2
  51. package/dist/model/content/mathText.d.mts +21 -0
  52. package/dist/model/content/mathText.mjs +267 -0
  53. package/dist/model/content/officeText.d.mts +27 -0
  54. package/dist/model/content/officeText.mjs +74 -0
  55. package/dist/model/content/ooxml.mjs +12 -1
  56. package/dist/model/content/outline.d.mts +5 -0
  57. package/dist/model/content/outline.mjs +13 -0
  58. package/dist/model/content/paraIds.d.mts +5 -0
  59. package/dist/model/content/paraIds.mjs +54 -0
  60. package/dist/model/content/placeholders.d.mts +110 -0
  61. package/dist/model/content/placeholders.mjs +253 -0
  62. package/dist/model/content/search.d.mts +74 -0
  63. package/dist/model/content/search.mjs +255 -9
  64. package/dist/model/content/spanEdits.d.mts +159 -0
  65. package/dist/model/content/spanEdits.mjs +728 -0
  66. package/dist/model/content/story.d.mts +47 -0
  67. package/dist/model/content/story.mjs +95 -0
  68. package/dist/model/content/tableColumns.d.mts +1 -1
  69. package/dist/model/content/tableColumns.mjs +108 -80
  70. package/dist/model/content/tableRevisions.d.mts +11 -3
  71. package/dist/model/content/tableRevisions.mjs +72 -42
  72. package/dist/model/content/tableRules.d.mts +30 -0
  73. package/dist/model/content/tableRules.mjs +102 -0
  74. package/dist/model/content/textBoxes.d.mts +18 -0
  75. package/dist/model/content/textBoxes.mjs +105 -0
  76. package/dist/model/content/trackedChangeFilter.d.mts +39 -0
  77. package/dist/model/content/trackedChangeFilter.mjs +81 -0
  78. package/dist/model/content/tracking.d.mts +63 -6
  79. package/dist/model/content/tracking.mjs +242 -22
  80. package/dist/model/content/tree.d.mts +172 -24
  81. package/dist/model/content/tree.mjs +328 -54
  82. package/dist/model/content/wordRange.d.mts +48 -0
  83. package/dist/model/content/wordRange.mjs +97 -0
  84. package/dist/model/customxml/CustomXmlPartCollection.d.mts +30 -1
  85. package/dist/model/customxml/CustomXmlPartCollection.mjs +81 -12
  86. package/dist/model/customxml/XmlMapping.d.mts +32 -8
  87. package/dist/model/customxml/XmlMapping.mjs +64 -10
  88. package/dist/model/customxml/bindings.d.mts +33 -4
  89. package/dist/model/customxml/bindings.mjs +171 -45
  90. package/dist/model/customxml/index.d.mts +1 -0
  91. package/dist/model/customxml/index.mjs +1 -0
  92. package/dist/model/customxml/kinds.d.mts +8 -3
  93. package/dist/model/customxml/kinds.mjs +26 -5
  94. package/dist/model/customxml/opendope.d.mts +4 -1
  95. package/dist/model/customxml/opendope.mjs +9 -6
  96. package/dist/model/customxml/picturePlaceholder.d.mts +17 -0
  97. package/dist/model/customxml/picturePlaceholder.mjs +32 -0
  98. package/dist/model/customxml/pictures.d.mts +4 -3
  99. package/dist/model/customxml/pictures.mjs +22 -8
  100. package/dist/model/customxml/storeItems.d.mts +57 -0
  101. package/dist/model/customxml/storeItems.mjs +122 -0
  102. package/dist/model/customxml/xhtml.mjs +23 -22
  103. package/dist/model/dateZone.d.mts +25 -0
  104. package/dist/model/dateZone.mjs +57 -0
  105. package/dist/model/index.d.mts +3 -0
  106. package/dist/model/index.mjs +5 -0
  107. package/dist/model/listnumbering/Emulator.d.mts +37 -5
  108. package/dist/model/listnumbering/Emulator.mjs +63 -9
  109. package/dist/model/properties/PropertyResolver.d.mts +74 -2
  110. package/dist/model/properties/PropertyResolver.mjs +133 -5
  111. package/dist/model/properties/catalogue.d.mts +19 -5
  112. package/dist/model/properties/catalogue.mjs +41 -15
  113. package/dist/model/properties/index.d.mts +1 -1
  114. package/dist/model/properties/log.d.mts +1 -1
  115. package/dist/model/properties/log.mjs +5 -5
  116. package/dist/model/properties/styleUtil.d.mts +3 -1
  117. package/dist/model/properties/styleUtil.mjs +20 -24
  118. package/dist/model/properties/table.mjs +4 -2
  119. package/dist/model/text/CaseMapping.d.mts +38 -0
  120. package/dist/model/text/CaseMapping.mjs +86 -0
  121. package/dist/model/text/Extractor.d.mts +349 -0
  122. package/dist/model/text/Extractor.mjs +2406 -0
  123. package/dist/model/text/LinkTargets.d.mts +45 -0
  124. package/dist/model/text/LinkTargets.mjs +170 -0
  125. package/dist/model/text/MarkdownExporter.d.mts +140 -0
  126. package/dist/model/text/MarkdownExporter.mjs +255 -0
  127. package/dist/model/text/PlainText.d.mts +29 -0
  128. package/dist/model/text/PlainText.mjs +542 -0
  129. package/dist/model/text/TextContext.d.mts +256 -0
  130. package/dist/model/text/TextContext.mjs +600 -0
  131. package/dist/model/text/TextOptions.d.mts +233 -0
  132. package/dist/model/text/TextOptions.mjs +419 -0
  133. package/dist/model/text/TextResult.d.mts +621 -0
  134. package/dist/model/text/TextResult.mjs +629 -0
  135. package/dist/model/text/Texts.d.mts +99 -0
  136. package/dist/model/text/Texts.mjs +187 -0
  137. package/dist/model/text/WmlToMarkdown.d.mts +120 -0
  138. package/dist/model/text/WmlToMarkdown.mjs +936 -0
  139. package/dist/model/text/caseMapping.generated.d.mts +7 -0
  140. package/dist/model/text/caseMapping.generated.mjs +214 -0
  141. package/dist/model/text/commonmark.d.mts +121 -0
  142. package/dist/model/text/commonmark.mjs +655 -0
  143. package/dist/model/text/index.d.mts +8 -0
  144. package/dist/model/text/index.mjs +9 -0
  145. package/dist/model/text/normalize.d.mts +8 -0
  146. package/dist/model/text/normalize.mjs +13 -0
  147. package/dist/model/text/outline.d.mts +4 -0
  148. package/dist/model/text/outline.mjs +71 -0
  149. package/dist/model/wordIntegers.d.mts +29 -0
  150. package/dist/model/wordIntegers.mjs +78 -0
  151. package/dist/office-js/document.mjs +15 -1
  152. package/dist/office-js/fragment.d.mts +7 -5
  153. package/dist/office-js/fragment.mjs +63 -14
  154. package/dist/office-js/proxy.d.mts +8 -0
  155. package/dist/office-js/proxy.mjs +29 -0
  156. package/dist/office-js/run.mjs +2 -0
  157. package/dist/office-js/supported.generated.mjs +16 -0
  158. package/dist/office-js/toApiScript.mjs +29 -12
  159. package/dist/opc/DirectoryPartStore.d.mts +6 -2
  160. package/dist/opc/DirectoryPartStore.mjs +11 -4
  161. package/dist/opc/FlatOpcPartStore.d.mts +4 -2
  162. package/dist/opc/FlatOpcPartStore.mjs +11 -8
  163. package/dist/opc/Load.d.mts +32 -0
  164. package/dist/opc/Load.mjs +115 -5
  165. package/dist/opc/PartStore.d.mts +34 -1
  166. package/dist/opc/PartStore.mjs +71 -8
  167. package/dist/opc/Save.d.mts +32 -0
  168. package/dist/opc/Save.mjs +110 -4
  169. package/dist/opc/ZipPartStore.d.mts +4 -2
  170. package/dist/opc/ZipPartStore.mjs +12 -7
  171. package/dist/opc/exceptions.d.mts +140 -0
  172. package/dist/opc/exceptions.mjs +108 -0
  173. package/dist/opc/index.d.mts +8 -5
  174. package/dist/opc/index.mjs +5 -3
  175. package/dist/opc/mce/preprocessor.d.mts +141 -5
  176. package/dist/opc/mce/preprocessor.mjs +119 -18
  177. package/dist/opc/mce/understood.d.mts +3 -11
  178. package/dist/opc/mce/understood.mjs +27 -23
  179. package/dist/opc/repair/breaks.d.mts +23 -0
  180. package/dist/opc/repair/breaks.mjs +288 -0
  181. package/dist/opc/repair/hosts.d.mts +12 -0
  182. package/dist/opc/repair/hosts.mjs +33 -0
  183. package/dist/opc/repair/mainRoot.d.mts +19 -0
  184. package/dist/opc/repair/mainRoot.mjs +168 -0
  185. package/dist/opc/repair/unknownElements.d.mts +8 -0
  186. package/dist/opc/repair/unknownElements.mjs +180 -0
  187. package/dist/opc/repair/wmlNames.generated.d.mts +2 -0
  188. package/dist/opc/repair/wmlNames.generated.mjs +80 -0
  189. package/dist/opc/skipped.d.mts +50 -0
  190. package/dist/opc/skipped.mjs +140 -0
  191. package/dist/packages/OpcPackage.d.mts +110 -4
  192. package/dist/packages/OpcPackage.mjs +123 -7
  193. package/dist/packages/WordprocessingMLPackage.d.mts +45 -8
  194. package/dist/packages/WordprocessingMLPackage.mjs +158 -21
  195. package/dist/packages/index.d.mts +1 -1
  196. package/dist/parts/DefaultXmlPart.mjs +2 -2
  197. package/dist/parts/Part.d.mts +14 -2
  198. package/dist/parts/RelationshipsPart.d.mts +15 -0
  199. package/dist/parts/RelationshipsPart.mjs +66 -1
  200. package/dist/parts/XmlPart.d.mts +63 -32
  201. package/dist/parts/XmlPart.mjs +240 -96
  202. package/dist/parts/wml/comments.mjs +30 -0
  203. package/dist/parts/wml/index.d.mts +12 -1
  204. package/dist/parts/wml/index.mjs +37 -1
  205. package/dist/xml/dom.d.mts +7 -0
  206. package/dist/xml/dom.mjs +18 -0
  207. package/package.json +2 -2
@@ -1,3 +1,4 @@
1
+ import { WordColors } from '../color/WordColors.mjs';
1
2
  // ---------------------------------------------------------------- copying
2
3
  /**
3
4
  * A structural copy of a leaf value, without its `PARENT` link: what the merges store, so
@@ -36,6 +37,15 @@ function attr(source, destination) {
36
37
  function statesColour(val, theme) {
37
38
  return !emptyString(val) || !emptyThemeColor(theme);
38
39
  }
40
+ /**
41
+ * docx4j `StyleUtil.statesWordColour` (its CR-060, 1d1b824a9): as {@link statesColour}, for a text or underline
42
+ * colour, whose value Word reads as absent where it rejects it ({@link WordColors.stated}: `F00`, `bogus`, `Auto`).
43
+ * A fill's or a border's colour keeps {@link statesColour}: Word reads any value there, one it rejects as automatic,
44
+ * which overrides a style's (CR-015 section 2, rule 5).
45
+ */
46
+ function statesWordColour(val, theme) {
47
+ return WordColors.stated(val) || !emptyThemeColor(theme);
48
+ }
39
49
  /** A merge with no per-attribute rule: a copy of the source where it has one, else the inherited. */
40
50
  export function mergeReplace(source, destination) {
41
51
  return source === undefined ? destination : copyLeaf(source);
@@ -76,21 +86,37 @@ export function isEmptyRFonts(value) {
76
86
  }
77
87
  /**
78
88
  * A `w:color` stating only a theme colour is not empty: it is inherited, where until docx4j CR-034
79
- * (2e381ef26) it was dropped.
89
+ * (2e381ef26) it was dropped. A value Word reads as absent (`F00`, `bogus`, `Auto`) is empty, so a style's
90
+ * colour beneath still shows, and only exactly `auto` overrides it (docx4j CR-060, {@link WordColors.stated};
91
+ * CR-015 section 2, rules 4 and 5).
80
92
  */
81
93
  export function isEmptyColor(value) {
82
94
  return value === undefined
83
- || (emptyString(value.val) && value.themeColor === undefined
95
+ || (!WordColors.stated(value.val) && value.themeColor === undefined
84
96
  && emptyString(value.themeTint) && emptyString(value.themeShade));
85
97
  }
86
- /** The underline's colour attributes count, the theme ones too (docx4j CR-034, 2e381ef26). */
98
+ /**
99
+ * The underline's colour attributes count, the theme ones too (docx4j CR-034, 2e381ef26); a colour Word reads as
100
+ * absent doesn't (docx4j CR-060, {@link WordColors.stated}).
101
+ */
87
102
  export function isEmptyU(value) {
88
103
  return value === undefined
89
- || (value.val === undefined && emptyString(value.color) && value.themeColor === undefined
104
+ || (value.val === undefined && !WordColors.stated(value.color) && value.themeColor === undefined
90
105
  && emptyString(value.themeTint) && emptyString(value.themeShade));
91
106
  }
107
+ /** `ST_HighlightColor`'s values, which Word compares case-exactly (docx4j `WordRepairs`). */
108
+ const HIGHLIGHT_COLORS = new Set(['black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow',
109
+ 'white', 'darkBlue', 'darkCyan', 'darkGreen', 'darkMagenta', 'darkRed', 'darkYellow', 'darkGray', 'lightGray', 'none']);
110
+ /** Whether a `w:highlight` value is one of `ST_HighlightColor`'s, compared case-exactly, as Word does (docx4j `WordRepairs.isHighlightColor`). */
111
+ export function isHighlightColor(val) {
112
+ return val !== undefined && HIGHLIGHT_COLORS.has(val);
113
+ }
114
+ /**
115
+ * A value outside `ST_HighlightColor` (`YELLOW`, `bogus`), or none, is empty: Word's repair drops it, so a style's
116
+ * highlight beneath still shows (docx4j CR-060, its `StyleUtil.isEmpty(Highlight)`).
117
+ */
92
118
  export function isEmptyHighlight(value) {
93
- return value === undefined || emptyString(value.val);
119
+ return value === undefined || !isHighlightColor(value.val);
94
120
  }
95
121
  /** @since CR-015 phase 1: a style stating only `w:lang` used to count as empty and was never applied. */
96
122
  export function isEmptyLang(value) {
@@ -151,16 +177,18 @@ export function isEmptyNumPr(value) {
151
177
  || ((value.numId === undefined || value.numId.val === undefined)
152
178
  && (value.ilvl === undefined || value.ilvl.val === undefined));
153
179
  }
154
- /** `w:anchorLock` defaults to true, so only an explicit `w:anchorLock="0"` makes a frame non-empty by itself. */
180
+ /**
181
+ * Empty only with `w:anchorLock` absent too, as docx4j 82c64bf14 reads it (its CR-059: until then
182
+ * `isAnchorLock()`, which the schema's old `default="true"` made true for an absent attribute).
183
+ */
155
184
  export function isEmptyFramePr(value) {
156
- var _a;
157
185
  return value === undefined
158
186
  || (value.dropCap === undefined && value.lines === undefined && value.w === undefined
159
187
  && value.h === undefined && value.vSpace === undefined && value.hSpace === undefined
160
188
  && value.wrap === undefined && value.hAnchor === undefined && value.vAnchor === undefined
161
189
  && value.x === undefined && value.xAlign === undefined
162
190
  && value.y === undefined && value.yAlign === undefined && value.hRule === undefined
163
- && ((_a = value.anchorLock) !== null && _a !== void 0 ? _a : true));
191
+ && value.anchorLock === undefined);
164
192
  }
165
193
  function isEmptyTblWidth(value) {
166
194
  // @w:type is ignored, as docx4j does
@@ -317,7 +345,7 @@ export const mergeColor = (source, destination) => {
317
345
  return destination;
318
346
  const s = source;
319
347
  const out = (destination !== null && destination !== void 0 ? destination : {});
320
- if (statesColour(s.val, s.themeColor)) {
348
+ if (statesWordColour(s.val, s.themeColor)) {
321
349
  out.val = s.val;
322
350
  out.themeColor = s.themeColor;
323
351
  out.themeTint = s.themeTint;
@@ -336,7 +364,7 @@ export const mergeU = (source, destination) => {
336
364
  const s = source;
337
365
  const out = destination !== null && destination !== void 0 ? destination : {};
338
366
  out.val = attr(s.val, out.val);
339
- if (statesColour(s.color, s.themeColor)) {
367
+ if (statesWordColour(s.color, s.themeColor)) {
340
368
  out.color = s.color;
341
369
  out.themeColor = s.themeColor;
342
370
  out.themeTint = s.themeTint;
@@ -536,11 +564,10 @@ export const mergeTabs = (source, destination) => {
536
564
  };
537
565
  /**
538
566
  * `w:framePr`'s attributes each inherit on their own: a paragraph whose direct `w:framePr`
539
- * gives only `w:x`/`w:y` keeps the anchors its style states. `w:anchorLock` defaults to true,
540
- * and docx4j's merge writes that default out explicitly.
567
+ * gives only `w:x`/`w:y` keeps the anchors its style states, `w:anchorLock` among them (docx4j
568
+ * 82c64bf14 merges it as stated; until then its merge wrote `isAnchorLock()`'s default out).
541
569
  */
542
570
  export const mergeFramePr = (source, destination) => {
543
- var _a;
544
571
  if (isEmptyFramePr(source))
545
572
  return destination;
546
573
  const s = source;
@@ -559,8 +586,7 @@ export const mergeFramePr = (source, destination) => {
559
586
  out.y = attr(s.y, out.y);
560
587
  out.yAlign = attr(s.yAlign, out.yAlign);
561
588
  out.hRule = attr(s.hRule, out.hRule);
562
- // docx4j reads this through isAnchorLock(), which answers true when the attribute is absent
563
- out.anchorLock = (_a = s.anchorLock) !== null && _a !== void 0 ? _a : true;
589
+ out.anchorLock = attr(s.anchorLock, out.anchorLock);
564
590
  return out;
565
591
  };
566
592
  const mergeTblWidth = (source, destination) => {
@@ -1,6 +1,6 @@
1
1
  export { type Property, type RunProps, type Merge, RUN, PARAGRAPH, TABLE, CELL, TOGGLES, TOGGLE_NAMES, IND, RUN_EXCLUDED, PARAGRAPH_EXCLUDED, TABLE_EXCLUDED, CELL_EXCLUDED, namedProperty, isEmptyOf, hasDirectFormattingOf, applyCatalogue, applyProperty, unsetCatalogue, copyLeaf, } from './catalogue.mjs';
2
2
  export * from './styleUtil.mjs';
3
- export { PropertyResolver, headingLevelByName, WORD_DEFAULT_CELL_MARGIN_TWIPS, type ResolverSource, } from './PropertyResolver.mjs';
3
+ export { PropertyResolver, headingLevelByName, WORD_DEFAULT_CELL_MARGIN_TWIPS, type ResolverSource, type PropertyResolverCreateOptions, } from './PropertyResolver.mjs';
4
4
  export * as TableStyleConditions from './tableStyleConditions.mjs';
5
5
  export { type Condition, type Look } from './tableStyleConditions.mjs';
6
6
  export { type TableStyleSource, type TableContextSource, CellContextKey, CellContext, TableContext, TableContextTracker, enclosingCellOf, } from './table.mjs';
@@ -1,7 +1,7 @@
1
1
  export interface Logger {
2
2
  warn(message: string): void;
3
3
  }
4
- /** The logger property resolution writes to. */
4
+ /** The logger property resolution and the Markdown export write to. */
5
5
  export declare const log: Logger;
6
6
  /** Replaces the sink; pass nothing to go back to `console.warn`. */
7
7
  export declare function setLogger(logger?: Logger): void;
@@ -1,7 +1,7 @@
1
- // The one place property resolution writes a diagnostic. docx4j logs through SLF4J; this
2
- // package has no logging framework, so a missing style or a style cycle goes to `console.warn`
3
- // behind a settable sink (an add-in that must stay silent, or a test that wants to assert what
4
- // was logged, replaces it).
1
+ // The one place property resolution writes a diagnostic, the Markdown export a refused link
2
+ // target (CR-012 section 21), and the text options a deprecated spelling (section 29). docx4j logs through SLF4J; this package has no logging framework, so
3
+ // a missing style, a style cycle or a refused link goes to `console.warn` behind a settable sink
4
+ // (an add-in that must stay silent, or a test that wants to assert what was logged, replaces it).
5
5
  //
6
6
  // Resolution logs a missing style *once per id* (a `w:pStyle` naming a deleted style is common
7
7
  // in real documents, and docx4j used to log one ERROR per paragraph); the resolver keeps that
@@ -13,7 +13,7 @@ const consoleLogger = {
13
13
  },
14
14
  };
15
15
  let sink = consoleLogger;
16
- /** The logger property resolution writes to. */
16
+ /** The logger property resolution and the Markdown export write to. */
17
17
  export const log = {
18
18
  warn(message) {
19
19
  sink.warn(message);
@@ -1,9 +1,11 @@
1
1
  import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
2
2
  import { type RunProps } from './catalogue.mjs';
3
- /** What the paragraph merge needs from the numbering part: a level's `w:ind`. */
3
+ /** What the paragraph merge needs from the numbering part: a level's `w:ind`, and whether a list exists. */
4
4
  export interface NumberingIndents {
5
5
  /** The indent the level a `w:numPr` names contributes, or undefined. */
6
6
  getInd(numPr: wml.PPrBase.NumPr): wml.PPrBase.Ind | undefined;
7
+ /** The lists by `w:numId`, as a string. */
8
+ readonly instanceListDefinitions: ReadonlyMap<string, unknown>;
7
9
  }
8
10
  export declare function isEmptyRPr(rPr: RunProps | undefined): boolean;
9
11
  export declare function isEmptyPPrBase(pPrBase: wml.PPrBase | undefined): boolean;
@@ -154,20 +154,16 @@ export function toggle(upper, lower, documentDefault) {
154
154
  export function numberingOff(numPr) {
155
155
  return numPr !== undefined && numPr.numId !== undefined && numPr.numId.val === 0;
156
156
  }
157
- /** Take out of an indent the components a numbering level contributed. */
158
- function dropNumberingInd(ind, fromLevel) {
159
- if (fromLevel.left !== undefined && fromLevel.left === ind.left)
160
- delete ind.left;
161
- if (fromLevel.right !== undefined && fromLevel.right === ind.right)
162
- delete ind.right;
163
- if (fromLevel.hanging !== undefined && fromLevel.hanging === ind.hanging)
164
- delete ind.hanging;
165
- if (fromLevel.firstLine !== undefined && fromLevel.firstLine === ind.firstLine)
166
- delete ind.firstLine;
167
- if (fromLevel.start !== undefined && fromLevel.start === ind.start)
168
- delete ind.start;
169
- if (fromLevel.end !== undefined && fromLevel.end === ind.end)
170
- delete ind.end;
157
+ /** What `w:numId 0` leaves of the indent it inherits: the right one. docx4j `dropLeftAndFirstLine`. */
158
+ function dropLeftAndFirstLine(ind) {
159
+ delete ind.left;
160
+ delete ind.leftChars;
161
+ delete ind.start;
162
+ delete ind.startChars;
163
+ delete ind.hanging;
164
+ delete ind.hangingChars;
165
+ delete ind.firstLine;
166
+ delete ind.firstLineChars;
171
167
  }
172
168
  const IND_ONLY = new Set([IND]);
173
169
  /**
@@ -185,18 +181,18 @@ export function applyPPrBase(source, destination, numbering) {
185
181
  inheritedNumPr = { numId: destination.numPr.numId, ilvl: destination.numPr.ilvl };
186
182
  }
187
183
  applyCatalogue(PARAGRAPH, source, destination, IND_ONLY);
188
- /* ECMA-376 17.9.18: w:numId w:val="0" takes the paragraph out of the list, so neither the
189
- * level's label nor its w:ind applies - only the paragraph's own. Only the components the
190
- * inherited level contributed are dropped, so a w:ind the style states itself survives. */
184
+ /* ECMA-376 17.9.18: w:numId w:val="0" takes the paragraph out of the list, so neither the level's
185
+ * label nor any left, hanging or first-line indent inherited so far applies, wherever it was stated.
186
+ * The right indent stays, and a w:ind stated with the w:numId 0 or below it counts, since it is merged
187
+ * after this. Where the inherited w:numPr names no list the rule doesn't apply. docx4j 9e3100351,
188
+ * its probe numbering-off-style-ind, Word's goldens of 5 November 2026; CR-027. */
191
189
  if (numbering !== undefined && numberingOff(source.numPr)
192
190
  && inheritedNumPr !== undefined && inheritedNumPr.numId !== undefined
193
- && !numberingOff(inheritedNumPr) && destination.ind !== undefined) {
194
- const fromLevel = numbering.getInd(inheritedNumPr);
195
- if (fromLevel !== undefined) {
196
- const own = copyLeaf(destination.ind);
197
- dropNumberingInd(own, fromLevel);
198
- destination.ind = own;
199
- }
191
+ && !numberingOff(inheritedNumPr) && destination.ind !== undefined
192
+ && numbering.instanceListDefinitions.has(String(inheritedNumPr.numId.val))) {
193
+ const own = copyLeaf(destination.ind);
194
+ dropLeftAndFirstLine(own);
195
+ destination.ind = own;
200
196
  }
201
197
  /* The indent of the level of the MERGED w:numPr, since a layer may state only w:ilvl (the
202
198
  * list from the style) or only w:numId (the level from the style): CR-015 probe
@@ -110,14 +110,16 @@ export class TableContext {
110
110
  this.look = DEFAULT_LOOK;
111
111
  this.rowBandSize = (tblPr === null || tblPr === void 0 ? void 0 : tblPr.tblStyleRowBandSize) !== undefined ? rowBandSize(tblPr) : rowBandSize(stylePr);
112
112
  this.colBandSize = (tblPr === null || tblPr === void 0 ? void 0 : tblPr.tblStyleColBandSize) !== undefined ? colBandSize(tblPr) : colBandSize(stylePr);
113
- const rows = rowsOf(tbl);
113
+ // the rows and cells Word reads: a kept row- or cell-level mc:AlternateContent's selected branch (CR-013
114
+ // phase 2), so that its rows count for the first row, the last and the bands
115
+ const rows = rowsOf(tbl, 'read');
114
116
  let cols = 0;
115
117
  rows.forEach((located, r) => {
116
118
  var _a, _b;
117
119
  const tr = located.element.value;
118
120
  this.rowIndex.set(tr, r);
119
121
  let c = gridOf(tr, 'gridBefore');
120
- for (const cell of cellsOf(tr)) {
122
+ for (const cell of cellsOf(tr, 'read')) {
121
123
  const tc = cell.element.value;
122
124
  const val = (_b = (_a = tc.tcPr) === null || _a === void 0 ? void 0 : _a.gridSpan) === null || _b === void 0 ? void 0 : _b.val;
123
125
  const span = typeof val === 'number' ? Math.max(1, Math.trunc(val)) : 1;
@@ -0,0 +1,38 @@
1
+ import type { TextOptions } from './TextOptions.mjs';
2
+ import { TextBlock, TextComment, TextRun } from './TextResult.mjs';
3
+ /**
4
+ * The capitals Word shows for `w:caps`, written by the plain-text and Markdown writers (WD REQ-607; docx4j CR-069): each
5
+ * code point mapped to its single uppercase code point (Unicode's simple mapping, Java's `Character.toUpperCase(int)`),
6
+ * by the run's language, so that Turkish and Azeri `i` gives `İ` (U+0130); nothing expands, so `ß` stays `ß`, the
7
+ * ligature `fi` stays `fi`, and `dž` gives `DŽ`, not the titlecase `Dž`. Measured in Word for Microsoft 365 on 31 October 2026
8
+ * (docx4j's `caps-lang` probes, `test/text-extraction/suite/dpp/caps/`). Not `toUpperCase()` or `toLocaleUpperCase()`,
9
+ * whose full mapping expands `ß` to `SS` and `fi` to `FI`, which Word does not.
10
+ *
11
+ * A small-caps run is written as its stored characters, unless `small_caps: upper` is set, when it is mapped as a caps run
12
+ * is. The block model keeps the stored characters (`TextRun.text`), so that addresses, offsets and `officeOffset` refer to
13
+ * them; the mapping is the writers', and it keeps the length, in code points and in UTF-16 units.
14
+ *
15
+ * The Unicode version is 15.0 (`UNICODE_VERSION`), the version docx4j's tests run (JDK 21), from a table generated by
16
+ * `scripts/generate-case-mapping.mjs` (CR-012 section 24.1, D4), never the runtime's: Node's ICU is a later Unicode,
17
+ * whose simple mapping JavaScript doesn't expose, and which differs across Node versions. A case pair added after 15.0 is
18
+ * left unmapped, U+1C8A (Unicode 16.0) for one, as WD 0.52's REQ-607 has it. docx4j `CaseMapping`.
19
+ */
20
+ export declare const CaseMapping: {
21
+ /** The language of last resort (docx4j `DEFAULT_LANGUAGE`). */
22
+ DEFAULT_LANGUAGE: string;
23
+ /** The Unicode version of the mapping. */
24
+ UNICODE_VERSION: string;
25
+ /**
26
+ * A text in capitals by a language (`w:lang/@w:val`, a BCP 47 tag such as `tr-TR`; undefined for `DEFAULT_LANGUAGE`):
27
+ * each code point to its single uppercase code point, `i` to `İ` where the language is Turkish or Azeri. A code point
28
+ * whose uppercase would change its length in UTF-16 is kept (none at 15.0; the generator leaves such a pair out).
29
+ */
30
+ upper(text: string, language?: string): string;
31
+ /** Whether a writer writes a run in capitals: a caps run, or a small-caps one under `small_caps: upper`. */
32
+ isUpper(run: TextRun, options: TextOptions | undefined): boolean;
33
+ /**
34
+ * As the writers write it: a run's stored text, in capitals where `isUpper`; a block's text (`TextBlock.text`) with each
35
+ * run's so; a comment's text (`TextComment.text`), its blocks a line apart, each so.
36
+ */
37
+ written(item: TextRun | TextBlock | TextComment, options: TextOptions | undefined): string;
38
+ };
@@ -0,0 +1,86 @@
1
+ // CR-012 section 24: the capitals Word shows for w:caps (WD REQ-607), docx4j's org.docx4j.model.text.CaseMapping
2
+ // (its CR-069 phase 1, released in 17.3.5).
3
+ import { CASE_MAPPING_UNICODE_VERSION, UPPERCASE_RUNS } from './caseMapping.generated.mjs';
4
+ import { TextBlock, TextRun } from './TextResult.mjs';
5
+ /** `default_language`'s default, the language where a run, its styles and the document defaults name none (WD 0.80's REQ-607). */
6
+ const DEFAULT_LANGUAGE = 'en-US';
7
+ /** The code point's simple uppercase mapping, by binary search over the generated runs; itself where it has none. */
8
+ function upperOf(cp) {
9
+ let lo = 0;
10
+ let hi = UPPERCASE_RUNS.length / 4 - 1;
11
+ while (lo <= hi) {
12
+ const mid = (lo + hi) >> 1;
13
+ const start = UPPERCASE_RUNS[mid * 4];
14
+ if (cp < start) {
15
+ hi = mid - 1;
16
+ }
17
+ else if (cp > UPPERCASE_RUNS[mid * 4 + 1]) {
18
+ lo = mid + 1;
19
+ }
20
+ else {
21
+ return (cp - start) % UPPERCASE_RUNS[mid * 4 + 3] === 0 ? cp + UPPERCASE_RUNS[mid * 4 + 2] : cp;
22
+ }
23
+ }
24
+ return cp;
25
+ }
26
+ /**
27
+ * The capitals Word shows for `w:caps`, written by the plain-text and Markdown writers (WD REQ-607; docx4j CR-069): each
28
+ * code point mapped to its single uppercase code point (Unicode's simple mapping, Java's `Character.toUpperCase(int)`),
29
+ * by the run's language, so that Turkish and Azeri `i` gives `İ` (U+0130); nothing expands, so `ß` stays `ß`, the
30
+ * ligature `fi` stays `fi`, and `dž` gives `DŽ`, not the titlecase `Dž`. Measured in Word for Microsoft 365 on 31 October 2026
31
+ * (docx4j's `caps-lang` probes, `test/text-extraction/suite/dpp/caps/`). Not `toUpperCase()` or `toLocaleUpperCase()`,
32
+ * whose full mapping expands `ß` to `SS` and `fi` to `FI`, which Word does not.
33
+ *
34
+ * A small-caps run is written as its stored characters, unless `small_caps: upper` is set, when it is mapped as a caps run
35
+ * is. The block model keeps the stored characters (`TextRun.text`), so that addresses, offsets and `officeOffset` refer to
36
+ * them; the mapping is the writers', and it keeps the length, in code points and in UTF-16 units.
37
+ *
38
+ * The Unicode version is 15.0 (`UNICODE_VERSION`), the version docx4j's tests run (JDK 21), from a table generated by
39
+ * `scripts/generate-case-mapping.mjs` (CR-012 section 24.1, D4), never the runtime's: Node's ICU is a later Unicode,
40
+ * whose simple mapping JavaScript doesn't expose, and which differs across Node versions. A case pair added after 15.0 is
41
+ * left unmapped, U+1C8A (Unicode 16.0) for one, as WD 0.52's REQ-607 has it. docx4j `CaseMapping`.
42
+ */
43
+ export const CaseMapping = {
44
+ /** The language of last resort (docx4j `DEFAULT_LANGUAGE`). */
45
+ DEFAULT_LANGUAGE,
46
+ /** The Unicode version of the mapping. */
47
+ UNICODE_VERSION: CASE_MAPPING_UNICODE_VERSION,
48
+ /**
49
+ * A text in capitals by a language (`w:lang/@w:val`, a BCP 47 tag such as `tr-TR`; undefined for `DEFAULT_LANGUAGE`):
50
+ * each code point to its single uppercase code point, `i` to `İ` where the language is Turkish or Azeri. A code point
51
+ * whose uppercase would change its length in UTF-16 is kept (none at 15.0; the generator leaves such a pair out).
52
+ */
53
+ upper(text, language) {
54
+ if (text === '')
55
+ return text;
56
+ const dotted = dottedI(language);
57
+ let out = '';
58
+ for (const ch of text) {
59
+ const cp = ch.codePointAt(0);
60
+ out += String.fromCodePoint(dotted && cp === 0x69 ? 0x130 : upperOf(cp));
61
+ }
62
+ return out;
63
+ },
64
+ /** Whether a writer writes a run in capitals: a caps run, or a small-caps one under `small_caps: upper`. */
65
+ isUpper(run, options) {
66
+ return run.caps || (run.smallCaps && (options === null || options === void 0 ? void 0 : options.smallCaps) === 'upper');
67
+ },
68
+ /**
69
+ * As the writers write it: a run's stored text, in capitals where `isUpper`; a block's text (`TextBlock.text`) with each
70
+ * run's so; a comment's text (`TextComment.text`), its blocks a line apart, each so.
71
+ */
72
+ written(item, options) {
73
+ if (item instanceof TextRun)
74
+ return CaseMapping.isUpper(item, options) ? CaseMapping.upper(item.text, item.language) : item.text;
75
+ if (item instanceof TextBlock)
76
+ return item.textWith((r) => CaseMapping.written(r, options));
77
+ return item.blocks.map((b) => CaseMapping.written(b, options)).join('\n');
78
+ },
79
+ };
80
+ /** Whether a language's capital of `i` is the dotted `İ`: Turkish and Azeri, as Java's own casing has it. */
81
+ function dottedI(language) {
82
+ if (language === undefined)
83
+ return false;
84
+ const primary = language.trim().split(/[-_]/, 1)[0].toLowerCase();
85
+ return primary === 'tr' || primary === 'az';
86
+ }