@docx4j/core-ts 0.4.0 → 0.6.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 (166) hide show
  1. package/NOTICE +4 -0
  2. package/README.md +34 -3
  3. package/dist/html/convert.mjs +40 -15
  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 +153 -19
  24. package/dist/model/content/Body.mjs +570 -131
  25. package/dist/model/content/Comment.d.mts +21 -3
  26. package/dist/model/content/Comment.mjs +202 -19
  27. package/dist/model/content/ContentControl.d.mts +197 -18
  28. package/dist/model/content/ContentControl.mjs +664 -95
  29. package/dist/model/content/Font.d.mts +67 -17
  30. package/dist/model/content/Font.mjs +114 -35
  31. package/dist/model/content/InlinePicture.d.mts +82 -7
  32. package/dist/model/content/InlinePicture.mjs +221 -28
  33. package/dist/model/content/List.mjs +13 -1
  34. package/dist/model/content/Paragraph.d.mts +213 -14
  35. package/dist/model/content/Paragraph.mjs +936 -100
  36. package/dist/model/content/Range.d.mts +242 -11
  37. package/dist/model/content/Range.mjs +975 -119
  38. package/dist/model/content/ResolvedView.d.mts +104 -0
  39. package/dist/model/content/ResolvedView.mjs +596 -0
  40. package/dist/model/content/Table.d.mts +29 -3
  41. package/dist/model/content/Table.mjs +109 -33
  42. package/dist/model/content/TrackedChange.d.mts +301 -16
  43. package/dist/model/content/TrackedChange.mjs +1284 -158
  44. package/dist/model/content/binder.d.mts +2 -1
  45. package/dist/model/content/binder.mjs +48 -1
  46. package/dist/model/content/comments.d.mts +20 -6
  47. package/dist/model/content/comments.mjs +67 -57
  48. package/dist/model/content/generalException.d.mts +18 -0
  49. package/dist/model/content/generalException.mjs +24 -0
  50. package/dist/model/content/index.d.mts +8 -3
  51. package/dist/model/content/index.mjs +7 -2
  52. package/dist/model/content/mathText.d.mts +21 -0
  53. package/dist/model/content/mathText.mjs +267 -0
  54. package/dist/model/content/officeText.d.mts +27 -0
  55. package/dist/model/content/officeText.mjs +74 -0
  56. package/dist/model/content/outline.d.mts +5 -0
  57. package/dist/model/content/outline.mjs +13 -0
  58. package/dist/model/content/placeholders.d.mts +110 -0
  59. package/dist/model/content/placeholders.mjs +253 -0
  60. package/dist/model/content/relationships.d.mts +30 -0
  61. package/dist/model/content/relationships.mjs +133 -0
  62. package/dist/model/content/search.d.mts +72 -0
  63. package/dist/model/content/search.mjs +204 -2
  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 +44 -0
  67. package/dist/model/content/story.mjs +92 -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 +100 -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 +28 -0
  79. package/dist/model/content/tracking.mjs +149 -10
  80. package/dist/model/content/tree.d.mts +212 -13
  81. package/dist/model/content/tree.mjs +356 -35
  82. package/dist/model/customxml/CustomXmlPartCollection.d.mts +8 -0
  83. package/dist/model/customxml/CustomXmlPartCollection.mjs +34 -11
  84. package/dist/model/customxml/XmlMapping.d.mts +1 -1
  85. package/dist/model/customxml/XmlMapping.mjs +11 -0
  86. package/dist/model/customxml/bindings.d.mts +21 -2
  87. package/dist/model/customxml/bindings.mjs +76 -32
  88. package/dist/model/customxml/kinds.d.mts +8 -3
  89. package/dist/model/customxml/kinds.mjs +26 -5
  90. package/dist/model/customxml/picturePlaceholder.d.mts +17 -0
  91. package/dist/model/customxml/picturePlaceholder.mjs +32 -0
  92. package/dist/model/customxml/pictures.d.mts +9 -5
  93. package/dist/model/customxml/pictures.mjs +31 -13
  94. package/dist/model/customxml/xhtml.mjs +8 -2
  95. package/dist/model/fonts/families.generated.mjs +2 -2
  96. package/dist/model/fonts/registry.mjs +7 -1
  97. package/dist/model/fonts/substitutions.generated.mjs +2 -2
  98. package/dist/model/fonts/themes.generated.mjs +1 -1
  99. package/dist/model/index.d.mts +2 -0
  100. package/dist/model/index.mjs +4 -0
  101. package/dist/model/listnumbering/Emulator.d.mts +37 -5
  102. package/dist/model/listnumbering/Emulator.mjs +63 -9
  103. package/dist/model/listnumbering/definitions.mjs +18 -0
  104. package/dist/model/properties/PropertyResolver.d.mts +87 -7
  105. package/dist/model/properties/PropertyResolver.mjs +197 -17
  106. package/dist/model/properties/catalogue.d.mts +32 -4
  107. package/dist/model/properties/catalogue.mjs +115 -36
  108. package/dist/model/properties/log.d.mts +1 -1
  109. package/dist/model/properties/log.mjs +5 -5
  110. package/dist/model/properties/table.d.mts +16 -2
  111. package/dist/model/properties/table.mjs +17 -5
  112. package/dist/model/text/Extractor.d.mts +289 -0
  113. package/dist/model/text/Extractor.mjs +2162 -0
  114. package/dist/model/text/LinkTargets.d.mts +45 -0
  115. package/dist/model/text/LinkTargets.mjs +170 -0
  116. package/dist/model/text/MarkdownExporter.d.mts +140 -0
  117. package/dist/model/text/MarkdownExporter.mjs +255 -0
  118. package/dist/model/text/PlainText.d.mts +29 -0
  119. package/dist/model/text/PlainText.mjs +539 -0
  120. package/dist/model/text/TextContext.d.mts +161 -0
  121. package/dist/model/text/TextContext.mjs +425 -0
  122. package/dist/model/text/TextOptions.d.mts +150 -0
  123. package/dist/model/text/TextOptions.mjs +278 -0
  124. package/dist/model/text/TextResult.d.mts +504 -0
  125. package/dist/model/text/TextResult.mjs +526 -0
  126. package/dist/model/text/Texts.d.mts +99 -0
  127. package/dist/model/text/Texts.mjs +187 -0
  128. package/dist/model/text/WmlToMarkdown.d.mts +120 -0
  129. package/dist/model/text/WmlToMarkdown.mjs +911 -0
  130. package/dist/model/text/commonmark.d.mts +121 -0
  131. package/dist/model/text/commonmark.mjs +655 -0
  132. package/dist/model/text/index.d.mts +7 -0
  133. package/dist/model/text/index.mjs +8 -0
  134. package/dist/model/text/normalize.d.mts +8 -0
  135. package/dist/model/text/normalize.mjs +13 -0
  136. package/dist/model/text/outline.d.mts +4 -0
  137. package/dist/model/text/outline.mjs +71 -0
  138. package/dist/office-js/fragment.d.mts +7 -5
  139. package/dist/office-js/fragment.mjs +63 -14
  140. package/dist/office-js/proxy.d.mts +8 -0
  141. package/dist/office-js/proxy.mjs +29 -0
  142. package/dist/office-js/run.mjs +2 -0
  143. package/dist/office-js/supported.generated.mjs +16 -0
  144. package/dist/office-js/toApiScript.mjs +21 -5
  145. package/dist/opc/Load.d.mts +9 -2
  146. package/dist/opc/Save.d.mts +17 -0
  147. package/dist/opc/Save.mjs +12 -2
  148. package/dist/opc/index.d.mts +3 -3
  149. package/dist/opc/index.mjs +2 -2
  150. package/dist/opc/mce/preprocessor.d.mts +88 -7
  151. package/dist/opc/mce/preprocessor.mjs +144 -37
  152. package/dist/opc/mce/understood.d.mts +34 -0
  153. package/dist/opc/mce/understood.mjs +55 -3
  154. package/dist/packages/OpcPackage.d.mts +20 -0
  155. package/dist/packages/OpcPackage.mjs +16 -3
  156. package/dist/packages/WordprocessingMLPackage.d.mts +77 -7
  157. package/dist/packages/WordprocessingMLPackage.mjs +242 -11
  158. package/dist/parts/DefaultXmlPart.mjs +2 -2
  159. package/dist/parts/Part.d.mts +10 -2
  160. package/dist/parts/XmlPart.d.mts +35 -32
  161. package/dist/parts/XmlPart.mjs +107 -107
  162. package/dist/parts/wml/comments.mjs +30 -0
  163. package/dist/parts/wml/index.mjs +12 -0
  164. package/dist/xml/dom.d.mts +7 -0
  165. package/dist/xml/dom.mjs +18 -0
  166. package/package.json +2 -2
@@ -1,9 +1,12 @@
1
1
  import { deepCopy } from '@docx4j/generated-objects-ts';
2
- import { Docx4JException } from '../../opc/exceptions.mjs';
2
+ import { Docx4JException, PartUnmarshalException } from '../../opc/exceptions.mjs';
3
3
  import { log } from './log.mjs';
4
4
  import { NumberingDefinitions } from '../listnumbering/definitions.mjs';
5
5
  import { applyPPr, applyPPrBase, applyRPr, applyStyle, applyStyleLevel, applyTblPr, applyToggles, hasDirectFormattingPPr, hasDirectFormattingRPr, isCyclic, isEmptyStyle, } from './styleUtil.mjs';
6
6
  import { TableContext, enclosingCellOf } from './table.mjs';
7
+ import { ThemeColors } from '../color/ThemeColors.mjs';
8
+ import { WordColors } from '../color/WordColors.mjs';
9
+ import { themeOfSettings } from '../fonts/defaultTheme.mjs';
7
10
  /** The cache key for "no style" (a styles part with no default paragraph style). */
8
11
  const NO_STYLE = '';
9
12
  /** An empty table style: what a table with no style to apply contributes. Shared, never changed. */
@@ -75,6 +78,26 @@ export function headingLevelByName(style) {
75
78
  const match = HEADING_NAME.exec(name.trim());
76
79
  return match ? Number(match[1]) : -1;
77
80
  }
81
+ /**
82
+ * A styles or numbering part the resolver can't do without: when it can't be read, nothing in the
83
+ * document can be given its formatting, so the document is refused (Jason, 2026-10-17), and the
84
+ * error says so before it says what was wrong where. A `PartUnmarshalException` stays one, with its
85
+ * part, location, line and column, so a caller showing the fault reads the same fields as for any
86
+ * part.
87
+ */
88
+ async function readOrRefuse(part, role) {
89
+ try {
90
+ return await part.readContents();
91
+ }
92
+ catch (e) {
93
+ const why = role === 'styles' ? "every paragraph's formatting depends on it" : "its lists' numbers and indents depend on it";
94
+ const lead = `The document cannot be opened: its ${role} part could not be read, and ${why}.`;
95
+ if (e instanceof PartUnmarshalException) {
96
+ throw new PartUnmarshalException(`${lead} ${e.message}`, e.partName, { cause: e, location: e.location, line: e.line, column: e.column });
97
+ }
98
+ throw new Docx4JException(`${lead} ${e instanceof Error ? e.message : String(e)}`, { cause: e });
99
+ }
100
+ }
78
101
  export class PropertyResolver {
79
102
  constructor(provider,
80
103
  /** Set when the styles tree the resolver holds is not the styles part's own. */
@@ -90,6 +113,8 @@ export class PropertyResolver {
90
113
  /** A style's `w:basedOn` chain merged root-first, WITHOUT the document defaults, per style id. */
91
114
  this.chainPPrCache = new Map();
92
115
  this.chainRPrCache = new Map();
116
+ /** A character style's chain as it applies to a run, where it differs from its chain: see {@link characterLevel}. */
117
+ this.characterLevelCache = new Map();
93
118
  /** The document defaults with the chain applied over them: what the style overloads return. */
94
119
  this.effectivePPrByStyle = new Map();
95
120
  this.effectiveRPrByStyle = new Map();
@@ -104,6 +129,14 @@ export class PropertyResolver {
104
129
  this.composedRPrCache = new CompositionCache();
105
130
  /** See {@link appliesTableStyleSizeJcException}; read once per `refresh()`. */
106
131
  this.tableStyleSizeJcException = true;
132
+ /**
133
+ * Whether the document's own `w:docDefaults` state a size, rather than the 10pt the resolver
134
+ * makes explicit where they do not: the size exception takes the document defaults' size only
135
+ * where they state one. Read once per `refresh()`.
136
+ */
137
+ this.docDefaultsStateSize = false;
138
+ /** Whether a paragraph style and a character style hide a run, by paragraph style then character style (`isVanishedByStyles`). */
139
+ this.vanishCache = new Map();
107
140
  /** Missing styles are logged once each per resolver. */
108
141
  this.missingLogged = new Set();
109
142
  this.source = provider();
@@ -132,8 +165,8 @@ export class PropertyResolver {
132
165
  }
133
166
  const stylesPart = main.styleDefinitionsPart;
134
167
  const numberingPart = main.numberingDefinitionsPart;
135
- const privateStyles = stylesPart === undefined ? undefined : await stylesPart.readContents();
136
- const privateNumbering = numberingPart === undefined ? undefined : await numberingPart.readContents();
168
+ const privateStyles = stylesPart === undefined ? undefined : await readOrRefuse(stylesPart, 'styles');
169
+ const privateNumbering = numberingPart === undefined ? undefined : await readOrRefuse(numberingPart, 'numbering');
137
170
  // the settings are read for two compatibility values (CR-007), privately, as the others are
138
171
  const settingsPart = main.documentSettingsPart;
139
172
  let privateSettings;
@@ -143,10 +176,24 @@ export class PropertyResolver {
143
176
  catch (e) {
144
177
  log.warn(`The settings part could not be read; taking compatibility mode ${DEFAULT_COMPATIBILITY_MODE}: ${String(e)}`);
145
178
  }
179
+ // the theme, for its colours (CR-008), privately too; where there is none, or it can't be read, the bundled theme
180
+ // the package names, parsed now so that getThemeColors() needn't wait
181
+ const themePart = main.themePart;
182
+ let privateTheme;
183
+ try {
184
+ privateTheme = themePart === undefined ? undefined : await themePart.readContents();
185
+ }
186
+ catch (e) {
187
+ log.warn(`The theme part could not be read; its colours are the default theme's: ${String(e)}`);
188
+ }
189
+ const defaultTheme = themeOfSettings(pkg.fonts);
190
+ await ThemeColors.loadDefaultTheme(defaultTheme);
146
191
  return new PropertyResolver(() => ({
147
192
  styles: (stylesPart === null || stylesPart === void 0 ? void 0 : stylesPart.isUnmarshalled) === true ? stylesPart.contents : privateStyles,
148
193
  numbering: (numberingPart === null || numberingPart === void 0 ? void 0 : numberingPart.isUnmarshalled) === true ? numberingPart.contents : privateNumbering,
149
194
  settings: (settingsPart === null || settingsPart === void 0 ? void 0 : settingsPart.isUnmarshalled) === true ? settingsPart.contents : privateSettings,
195
+ theme: (themePart === null || themePart === void 0 ? void 0 : themePart.isUnmarshalled) === true ? themePart.contents : privateTheme,
196
+ defaultTheme,
150
197
  }), () => stylesPart !== undefined && !stylesPart.isUnmarshalled);
151
198
  }
152
199
  /** Builds a resolver over object trees directly (a test, or parts already in hand). */
@@ -189,6 +236,7 @@ export class PropertyResolver {
189
236
  ? { TYPE_NAME: 'org_docx4j_wml.PPr' } : deepCopy(docDefaults.pPrDefault.pPr);
190
237
  this.documentDefaultRPr = ((_f = docDefaults === null || docDefaults === void 0 ? void 0 : docDefaults.rPrDefault) === null || _f === void 0 ? void 0 : _f.rPr) === undefined
191
238
  ? { TYPE_NAME: 'org_docx4j_wml.RPr' } : deepCopy(docDefaults.rPrDefault.rPr);
239
+ this.docDefaultsStateSize = this.documentDefaultRPr.sz !== undefined;
192
240
  if (this.documentDefaultRPr.sz === undefined) {
193
241
  // Word's default made explicit: 10pt where nothing states a size (measured, CR-015 probe
194
242
  // styles-no-size-anywhere: identical to an explicit 10pt run)
@@ -239,13 +287,52 @@ export class PropertyResolver {
239
287
  refresh() {
240
288
  this.chainPPrCache.clear();
241
289
  this.chainRPrCache.clear();
290
+ this.characterLevelCache.clear();
242
291
  this.effectivePPrByStyle.clear();
243
292
  this.effectiveRPrByStyle.clear();
293
+ this.vanishCache.clear();
244
294
  this.clearTableCaches();
245
295
  this.missingLogged.clear();
296
+ this.themeColors = undefined;
246
297
  this.source = this.provider();
247
298
  this.init();
248
299
  }
300
+ /**
301
+ * The document's theme colours: its theme part (or the bundled theme `pkg.fonts.defaultTheme` names where it has
302
+ * none) and the settings' `w:clrSchemeMapping`. Read once per `refresh()`. A resolver made `fromSource` with no
303
+ * theme parses the bundled one, which needs the objects package's context built (`ThemeColors.loadDefaultTheme()`).
304
+ */
305
+ getThemeColors() {
306
+ var _a, _b;
307
+ (_a = this.themeColors) !== null && _a !== void 0 ? _a : (this.themeColors = ThemeColors.ofTheme(this.source.theme, this.source.defaultTheme)
308
+ .withWordMapping((_b = this.source.settings) === null || _b === void 0 ? void 0 : _b.clrSchemeMapping));
309
+ return this.themeColors;
310
+ }
311
+ /**
312
+ * The colour Word draws for a run's `w:color`: its theme reference where it has one (the value beside it is a
313
+ * cache), else its value.
314
+ *
315
+ * @returns undefined for automatic: the caller's default (black text, as a rule)
316
+ */
317
+ resolveColor(color) {
318
+ return WordColors.of(color, this.getThemeColors());
319
+ }
320
+ /** A border's colour, as {@link resolveColor}; undefined for automatic. docx4j `resolveColor(CTBorder)`. */
321
+ resolveBorderColor(border) {
322
+ return WordColors.ofBorder(border, this.getThemeColors());
323
+ }
324
+ /** An underline's colour, as {@link resolveColor}; undefined for automatic (the text's). docx4j `resolveColor(U)`. */
325
+ resolveUnderlineColor(u) {
326
+ return WordColors.ofUnderline(u, this.getThemeColors());
327
+ }
328
+ /** A shading's fill (`w:fill`, `w:themeFill`); undefined for automatic. */
329
+ resolveFill(shd) {
330
+ return WordColors.fill(shd, this.getThemeColors());
331
+ }
332
+ /** A shading's pattern colour (`w:color`, `w:themeColor`); undefined for automatic. */
333
+ resolvePatternColor(shd) {
334
+ return WordColors.pattern(shd, this.getThemeColors());
335
+ }
249
336
  // ------------------------------------------------------------------ defaults
250
337
  getDocumentDefaultPPr() {
251
338
  return this.documentDefaultPPr;
@@ -265,6 +352,16 @@ export class PropertyResolver {
265
352
  getStyle(styleId) {
266
353
  return this.getLiveStyle(styleId);
267
354
  }
355
+ /**
356
+ * The styles part's `w:style` elements in document order, from the tree this resolver reads (its
357
+ * private copy, or the part's own once that is unmarshalled); empty where there is no styles part.
358
+ * docx4j reads `StyleDefinitionsPart.getJaxbElement().getStyle()` where order matters
359
+ * (`Emulator.levelStyleId`: the first paragraph style in styles.xml carrying a level owns it).
360
+ */
361
+ getStylesInOrder() {
362
+ var _a, _b;
363
+ return (_b = (_a = this.source.styles) === null || _a === void 0 ? void 0 : _a.style) !== null && _b !== void 0 ? _b : [];
364
+ }
268
365
  /**
269
366
  * The list definitions of the numbering part this resolver read (CR-001 Phase B step 3), or
270
367
  * undefined where the package has none. The resolver builds them because the paragraph merge
@@ -339,6 +436,24 @@ export class PropertyResolver {
339
436
  this.chainRPrCache.set(styleId, chain);
340
437
  return chain;
341
438
  }
439
+ /**
440
+ * A character style's chain as a level over a run or a paragraph mark: {@link getChainRPr} without its highlight,
441
+ * since Word draws no highlight from a character style (docx4j CR-060 section 13, round 6: alone, with bold, or
442
+ * through `w:basedOn`; its save writes `w:highlight="none"` on such a run). A paragraph style's highlight and a
443
+ * run's own are drawn. docx4j `characterLevel` (1d1b824a9). Cached; live: copy before changing.
444
+ */
445
+ characterLevel(styleId) {
446
+ const chain = this.getChainRPr(styleId);
447
+ if (chain.highlight === undefined)
448
+ return chain;
449
+ let level = this.characterLevelCache.get(styleId);
450
+ if (level === undefined) {
451
+ level = deepCopy(chain);
452
+ delete level.highlight;
453
+ this.characterLevelCache.set(styleId, level);
454
+ }
455
+ return level;
456
+ }
342
457
  /**
343
458
  * A style's own `w:pPr` as a layer of its chain. The built-in heading styles have a fixed
344
459
  * outline level, which Word takes from the style's built-in NAME ("heading 1" ...
@@ -384,7 +499,7 @@ export class PropertyResolver {
384
499
  return styleId;
385
500
  }
386
501
  getEffectivePPr(arg, cellContext) {
387
- if (cellContext !== undefined && cellContext.formatsText && typeof arg !== 'string') {
502
+ if (this.composes(cellContext) && typeof arg !== 'string') {
388
503
  const composed = this.composedPPr(this.paragraphStyleOf(arg), cellContext);
389
504
  if (!hasDirectFormattingPPr(arg))
390
505
  return composed;
@@ -415,7 +530,7 @@ export class PropertyResolver {
415
530
  getEffectiveRPr(arg, pPr, cellContext) {
416
531
  if (typeof arg === 'string')
417
532
  return this.effectiveRPrOfStyle(arg);
418
- if (cellContext !== undefined && cellContext.formatsText) {
533
+ if (this.composes(cellContext)) {
419
534
  const inTable = deepCopy(this.composedRPr(this.paragraphStyleOf(pPr), cellContext));
420
535
  this.applyCharacterStyleAndDirect(arg, inTable);
421
536
  return inTable;
@@ -425,6 +540,30 @@ export class PropertyResolver {
425
540
  this.applyCharacterStyleAndDirect(arg, effective);
426
541
  return effective;
427
542
  }
543
+ /**
544
+ * Whether a run with no `w:vanish` of its own is hidden by its styles: the effective `w:vanish` of its
545
+ * paragraph style (undefined: the default paragraph style) and its character style, the table style left
546
+ * out, as the text model's hidden rule has it (REQ-507). What `Paragraph.text` leaves out, as Office JS
547
+ * does (CR-012 phase 4, check 48b case 20). Cached per pair; a pair naming a style the part lacks is
548
+ * not cached, so that adding the style is seen.
549
+ */
550
+ isVanishedByStyles(paragraphStyleId, runStyleId) {
551
+ let byRunStyle = this.vanishCache.get(paragraphStyleId);
552
+ const cached = byRunStyle === null || byRunStyle === void 0 ? void 0 : byRunStyle.get(runStyleId);
553
+ if (cached !== undefined)
554
+ return cached;
555
+ const rPr = runStyleId === undefined ? undefined : { TYPE_NAME: 'org_docx4j_wml.RPr', rStyle: { TYPE_NAME: 'org_docx4j_wml.RStyle', val: runStyleId } };
556
+ const pPr = paragraphStyleId === undefined ? undefined : { TYPE_NAME: 'org_docx4j_wml.PPr', pStyle: { TYPE_NAME: 'org_docx4j_wml.PPrBase.PStyle', val: paragraphStyleId } };
557
+ const vanish = this.getEffectiveRPr(rPr, pPr).vanish;
558
+ const hidden = vanish !== undefined && vanish !== null && vanish.val !== false;
559
+ if ((paragraphStyleId === undefined || this.getLiveStyle(paragraphStyleId) !== undefined)
560
+ && (runStyleId === undefined || this.getLiveStyle(runStyleId) !== undefined)) {
561
+ if (!byRunStyle)
562
+ this.vanishCache.set(paragraphStyleId, byRunStyle = new Map());
563
+ byRunStyle.set(runStyleId, hidden);
564
+ }
565
+ return hidden;
566
+ }
428
567
  effectiveRPrOfStyle(styleId) {
429
568
  const cached = this.effectiveRPrByStyle.get(styleId);
430
569
  if (cached !== undefined)
@@ -454,7 +593,7 @@ export class PropertyResolver {
454
593
  this.logMissing(runStyleId);
455
594
  }
456
595
  else {
457
- applyStyleLevel(this.getChainRPr(runStyleId), effective, this.documentDefaultRPr);
596
+ applyStyleLevel(this.characterLevel(runStyleId), effective, this.documentDefaultRPr);
458
597
  }
459
598
  }
460
599
  if (hasDirectFormattingRPr(rPr))
@@ -462,23 +601,43 @@ export class PropertyResolver {
462
601
  }
463
602
  /**
464
603
  * The run properties of the paragraph mark: document defaults, the paragraph style's run
465
- * properties, then the `w:pPr`'s own `w:rPr`. What sizes an empty paragraph, and what a list
466
- * label starts from.
604
+ * properties, the mark's character style, then the `w:pPr`'s own `w:rPr`. What sizes an empty
605
+ * paragraph, and what a list label starts from.
467
606
  */
468
607
  getEffectiveParagraphMarkRPr(pPr, cellContext) {
469
- if (cellContext !== undefined && cellContext.formatsText) {
608
+ if (this.composes(cellContext)) {
470
609
  // in a table cell: the table level beneath the paragraph style's (CR-007)
471
610
  const inTable = deepCopy(this.composedRPr(this.paragraphStyleOf(pPr), cellContext));
472
611
  if ((pPr === null || pPr === void 0 ? void 0 : pPr.rPr) !== undefined)
473
- applyRPr(pPr.rPr, inTable);
612
+ this.applyMarkRPr(pPr.rPr, inTable);
474
613
  return inTable;
475
614
  }
476
615
  const effective = deepCopy(this.documentDefaultRPr);
477
616
  applyRPr(this.getChainRPr(this.paragraphStyleOf(pPr)), effective);
478
617
  if ((pPr === null || pPr === void 0 ? void 0 : pPr.rPr) !== undefined)
479
- applyRPr(pPr.rPr, effective);
618
+ this.applyMarkRPr(pPr.rPr, effective);
480
619
  return effective;
481
620
  }
621
+ /**
622
+ * The paragraph mark's character style (`w:pPr/w:rPr/w:rStyle`) as a level over what is
623
+ * beneath it, then the mark's direct formatting: the order {@link applyCharacterStyleAndDirect}
624
+ * gives a run. docx4j `applyMarkRPr`, since 17.3.2 (fb2a764f7: until then the mark's
625
+ * `w:rStyle` was copied as an attribute and never resolved, so an empty paragraph whose mark
626
+ * names a 9pt character style was sized at its paragraph style's 12pt).
627
+ */
628
+ applyMarkRPr(mark, effective) {
629
+ var _a;
630
+ const runStyleId = (_a = mark.rStyle) === null || _a === void 0 ? void 0 : _a.val;
631
+ if (runStyleId !== undefined) {
632
+ if (this.getLiveStyle(runStyleId) === undefined) {
633
+ this.logMissing(runStyleId);
634
+ }
635
+ else {
636
+ applyStyleLevel(this.characterLevel(runStyleId), effective, this.documentDefaultRPr);
637
+ }
638
+ }
639
+ applyRPr(mark, effective);
640
+ }
482
641
  /** Whether the run states any formatting of its own (docx4j's deprecated `hasDirectRPrFormatting`). */
483
642
  hasDirectRPrFormatting(rPr) {
484
643
  return hasDirectFormattingRPr(rPr);
@@ -609,6 +768,15 @@ export class PropertyResolver {
609
768
  const found = enclosingCellOf(p);
610
769
  return found === undefined ? undefined : this.tableContext(found.tbl).forParagraph(found.tr, found.tc, p.pPr);
611
770
  }
771
+ /**
772
+ * Whether a paragraph in this context is composed over its table level: where the table style
773
+ * gives it text formatting, or, under [MS-DOCX]'s size exception, where the style formats text
774
+ * anywhere ({@link CellContext.styleFormatsText}). docx4j `composes` (900b6a212, 17.3.2).
775
+ */
776
+ composes(cellContext) {
777
+ return cellContext !== undefined && (cellContext.formatsText
778
+ || (this.tableStyleSizeJcException && cellContext.styleFormatsText));
779
+ }
612
780
  clearTableCaches() {
613
781
  this.tableStyleChains.clear();
614
782
  this.composedPPrCache.clear();
@@ -663,18 +831,29 @@ export class PropertyResolver {
663
831
  // the table and the paragraph style are two levels of the hierarchy: the twelve toggles
664
832
  // combine across them rather than the paragraph's overriding (17.7.3)
665
833
  applyToggles(paragraphLevel, tableLevel, this.documentDefaultRPr, composed);
666
- if (this.tableStyleSizeJcException && (tableOnly === null || tableOnly === void 0 ? void 0 : tableOnly.sz) !== undefined
834
+ // The size the table level gives is its own where the table style states one, else the
835
+ // document defaults' where they state one: Word applies the exception wherever the table
836
+ // style formats text at all, not only where it states a size (docx4j 900b6a212, measured on
837
+ // its table-style-size-trigger probes: in mode 12, with docDefaults 11pt and Normal 12pt, a
838
+ // table style with only a w:pPr, only an rPr colour, or only a firstRow format sets its
839
+ // table's paragraphs at 11pt; with none of these, at Normal's 12pt). But where neither the
840
+ // table style nor the docDefaults state a size, Normal keeps its 12pt, not the 10pt Word
841
+ // falls back to (docx4j's corpus documents 10244 and 12723).
842
+ const tableStatesSize = (tableOnly === null || tableOnly === void 0 ? void 0 : tableOnly.sz) !== undefined;
843
+ if (this.tableStyleSizeJcException && ctx.styleFormatsText && tableLevel.sz !== undefined
844
+ && (tableStatesSize || this.docDefaultsStateSize)
667
845
  && this.paragraphStyleGivesWay(styleId, true)) {
668
- composed.sz = deepCopy(tableOnly.sz);
846
+ composed.sz = deepCopy(tableLevel.sz);
669
847
  }
670
848
  this.composedRPrCache.set(styleId, ctx.key, composed);
671
849
  return composed;
672
850
  }
673
851
  /**
674
- * [MS-DOCX]'s exception, for a paragraph in a table whose style states a size (or a
675
- * justification): the paragraph's style gives way to it if the style is the default paragraph
676
- * style, or states no size (justification) of its own, and resolves to 12pt (left). A style of
677
- * the paragraph's own which states one keeps it.
852
+ * [MS-DOCX]'s exception, for a paragraph in a table whose style formats text (for the size: the
853
+ * style need not state one, since docx4j 17.3.2) or states a justification: the paragraph's
854
+ * style gives way to it if the style is the default paragraph style, or states no size
855
+ * (justification) of its own, and resolves to 12pt (left). A style of the paragraph's own which
856
+ * states one keeps it.
678
857
  */
679
858
  paragraphStyleGivesWay(styleId, size) {
680
859
  var _a, _b, _c, _d;
@@ -763,6 +942,7 @@ export class PropertyResolver {
763
942
  // resolution of this style (and of anything based on it) has to be recomputed
764
943
  this.chainPPrCache.clear();
765
944
  this.chainRPrCache.clear();
945
+ this.characterLevelCache.clear();
766
946
  this.effectivePPrByStyle.clear();
767
947
  this.effectiveRPrByStyle.clear();
768
948
  this.clearTableCaches();
@@ -39,8 +39,24 @@ export declare function isTrue(value: wml.BooleanDefaultTrue | undefined): boole
39
39
  export declare function isEmptyRStyle(value: wml.RStyle | undefined): boolean;
40
40
  /** docx4j `isEmpty(RFonts)`: insensitive to a `w:hint` (which `apply` still carries). */
41
41
  export declare function isEmptyRFonts(value: wml.RFonts | undefined): boolean;
42
+ /**
43
+ * A `w:color` stating only a theme colour is not empty: it is inherited, where until docx4j CR-034
44
+ * (2e381ef26) it was dropped. A value Word reads as absent (`F00`, `bogus`, `Auto`) is empty, so a style's
45
+ * colour beneath still shows, and only exactly `auto` overrides it (docx4j CR-060, {@link WordColors.stated};
46
+ * CR-015 section 2, rules 4 and 5).
47
+ */
42
48
  export declare function isEmptyColor(value: wml.Color | undefined): boolean;
49
+ /**
50
+ * The underline's colour attributes count, the theme ones too (docx4j CR-034, 2e381ef26); a colour Word reads as
51
+ * absent doesn't (docx4j CR-060, {@link WordColors.stated}).
52
+ */
43
53
  export declare function isEmptyU(value: wml.U | undefined): boolean;
54
+ /** Whether a `w:highlight` value is one of `ST_HighlightColor`'s, compared case-exactly, as Word does (docx4j `WordRepairs.isHighlightColor`). */
55
+ export declare function isHighlightColor(val: string | undefined): boolean;
56
+ /**
57
+ * A value outside `ST_HighlightColor` (`YELLOW`, `bogus`), or none, is empty: Word's repair drops it, so a style's
58
+ * highlight beneath still shows (docx4j CR-060, its `StyleUtil.isEmpty(Highlight)`).
59
+ */
44
60
  export declare function isEmptyHighlight(value: wml.Highlight | undefined): boolean;
45
61
  /** @since CR-015 phase 1: a style stating only `w:lang` used to count as empty and was never applied. */
46
62
  export declare function isEmptyLang(value: wml.CTLanguage | undefined): boolean;
@@ -60,7 +76,10 @@ export declare function isEmptyTabs(value: wml.Tabs | undefined): boolean;
60
76
  * its own (CR-015 probe styles-numpr-ilvl-only).
61
77
  */
62
78
  export declare function isEmptyNumPr(value: wml.PPrBase.NumPr | undefined): boolean;
63
- /** `w:anchorLock` defaults to true, so only an explicit `w:anchorLock="0"` makes a frame non-empty by itself. */
79
+ /**
80
+ * Empty only with `w:anchorLock` absent too, as docx4j 82c64bf14 reads it (its CR-059: until then
81
+ * `isAnchorLock()`, which the schema's old `default="true"` made true for an absent attribute).
82
+ */
64
83
  export declare function isEmptyFramePr(value: wml.CTFramePr | undefined): boolean;
65
84
  /** docx4j `apply(BooleanDefaultTrue, BooleanDefaultTrue)`: a copy of the source where it states one. */
66
85
  export declare function mergeBool(source: wml.BooleanDefaultTrue | undefined, destination: wml.BooleanDefaultTrue | undefined): wml.BooleanDefaultTrue | undefined;
@@ -87,8 +106,17 @@ export declare const mergePStyle: Merge<wml.PPrBase.PStyle>;
87
106
  * formatted).
88
107
  */
89
108
  export declare const mergeRFonts: Merge<wml.RFonts>;
109
+ /**
110
+ * A colour inherits as one (docx4j CR-034, 2e381ef26): where the source states a value or a theme
111
+ * reference, its value, theme colour, tint and shade replace the destination's together. Word
112
+ * draws a theme reference over the value written beside it, so taken one by one, a run's
113
+ * `w:val="FF0000"` under a style's `w:themeColor="accent1"` would keep the style's reference and
114
+ * draw accent1, where Word draws red. A tint or shade stated alone still inherits on its own. The
115
+ * same holds for the colours of `w:u`, `w:shd` (its pattern colour and its fill) and the borders.
116
+ * (Attribute by attribute until then, CR-015 phase 1.)
117
+ */
90
118
  export declare const mergeColor: Merge<wml.Color>;
91
- /** `w:val` and the colour attributes each inherit on their own (CR-015 phase 1). */
119
+ /** `w:val` and the colour inherit on their own (CR-015 phase 1), the colour as one ({@link mergeColor}). */
92
120
  export declare const mergeU: Merge<wml.U>;
93
121
  /** `w:val`, `w:eastAsia` and `w:bidi` each name the language of one script range and each inherits. */
94
122
  export declare const mergeLang: Merge<wml.CTLanguage>;
@@ -117,8 +145,8 @@ export declare const mergeSpacing: Merge<wml.PPrBase.Spacing>;
117
145
  export declare const mergeTabs: Merge<wml.Tabs>;
118
146
  /**
119
147
  * `w:framePr`'s attributes each inherit on their own: a paragraph whose direct `w:framePr`
120
- * gives only `w:x`/`w:y` keeps the anchors its style states. `w:anchorLock` defaults to true,
121
- * and docx4j's merge writes that default out explicitly.
148
+ * gives only `w:x`/`w:y` keeps the anchors its style states, `w:anchorLock` among them (docx4j
149
+ * 82c64bf14 merges it as stated; until then its merge wrote `isAnchorLock()`'s default out).
122
150
  */
123
151
  export declare const mergeFramePr: Merge<wml.CTFramePr>;
124
152
  /**