@docx4j/core-ts 0.1.0 → 0.1.2

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 (172) 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 +11 -0
  131. package/dist/opc/ContentTypes.mjs +14 -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/Namespaces.d.mts +18 -0
  151. package/dist/parts/Namespaces.mjs +20 -0
  152. package/dist/parts/Part.d.mts +6 -0
  153. package/dist/parts/Part.mjs +13 -0
  154. package/dist/parts/PartRegistry.mjs +13 -1
  155. package/dist/parts/XmlPart.d.mts +33 -0
  156. package/dist/parts/XmlPart.mjs +105 -2
  157. package/dist/parts/pml/defaults.d.mts +6 -0
  158. package/dist/parts/pml/defaults.mjs +53 -0
  159. package/dist/parts/pml/index.d.mts +66 -3
  160. package/dist/parts/pml/index.mjs +206 -7
  161. package/dist/parts/pml/placeholders.d.mts +71 -0
  162. package/dist/parts/pml/placeholders.mjs +141 -0
  163. package/dist/parts/sml/index.d.mts +80 -1
  164. package/dist/parts/sml/index.mjs +154 -1
  165. package/dist/parts/wml/comments.d.mts +1 -0
  166. package/dist/parts/wml/comments.mjs +179 -0
  167. package/dist/parts/wml/defaultNumbering.d.mts +1 -0
  168. package/dist/parts/wml/defaultNumbering.mjs +216 -0
  169. package/dist/parts/wml/index.d.mts +121 -0
  170. package/dist/parts/wml/index.mjs +291 -0
  171. package/dist/xml/dom.mjs +1 -2
  172. package/package.json +25 -4
@@ -0,0 +1,4 @@
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
+ export * from './styleUtil.mjs';
3
+ export { PropertyResolver, headingLevelByName, WORD_DEFAULT_CELL_MARGIN_TWIPS, type ResolverSource, } from './PropertyResolver.mjs';
4
+ export { setLogger, type Logger } from './log.mjs';
@@ -0,0 +1,9 @@
1
+ // CR-001 Phase B step 2: property resolution (docx4j `org.docx4j.model.PropertyResolver` and
2
+ // the catalogue-driven half of `org.docx4j.model.styles`).
3
+ //
4
+ // The tables' leaf merge and emptiness rules stay inside `catalogue.mts`: what a consumer
5
+ // needs is the tables, the generic operations over them, and the resolver.
6
+ export { 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';
7
+ export * from './styleUtil.mjs';
8
+ export { PropertyResolver, headingLevelByName, WORD_DEFAULT_CELL_MARGIN_TWIPS, } from './PropertyResolver.mjs';
9
+ export { setLogger } from './log.mjs';
@@ -0,0 +1,7 @@
1
+ export interface Logger {
2
+ warn(message: string): void;
3
+ }
4
+ /** The logger property resolution writes to. */
5
+ export declare const log: Logger;
6
+ /** Replaces the sink; pass nothing to go back to `console.warn`. */
7
+ export declare function setLogger(logger?: Logger): void;
@@ -0,0 +1,25 @@
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).
5
+ //
6
+ // Resolution logs a missing style *once per id* (a `w:pStyle` naming a deleted style is common
7
+ // in real documents, and docx4j used to log one ERROR per paragraph); the resolver keeps that
8
+ // set, not this module.
9
+ const consoleLogger = {
10
+ warn(message) {
11
+ // eslint-disable-next-line no-console
12
+ console.warn(message);
13
+ },
14
+ };
15
+ let sink = consoleLogger;
16
+ /** The logger property resolution writes to. */
17
+ export const log = {
18
+ warn(message) {
19
+ sink.warn(message);
20
+ },
21
+ };
22
+ /** Replaces the sink; pass nothing to go back to `console.warn`. */
23
+ export function setLogger(logger) {
24
+ sink = logger !== null && logger !== void 0 ? logger : consoleLogger;
25
+ }
@@ -0,0 +1,112 @@
1
+ import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
2
+ import { type RunProps } from './catalogue.mjs';
3
+ /** What the paragraph merge needs from the numbering part: a level's `w:ind`. */
4
+ export interface NumberingIndents {
5
+ /** The indent the level a `w:numPr` names contributes, or undefined. */
6
+ getInd(numPr: wml.PPrBase.NumPr): wml.PPrBase.Ind | undefined;
7
+ }
8
+ export declare function isEmptyRPr(rPr: RunProps | undefined): boolean;
9
+ export declare function isEmptyPPrBase(pPrBase: wml.PPrBase | undefined): boolean;
10
+ /** docx4j `isEmpty(PPr)`: the base members, the paragraph mark and the section. */
11
+ export declare function isEmptyPPr(pPr: wml.PPr | undefined): boolean;
12
+ export declare function isEmptyTblPr(tblPr: wml.CTTblPrBase | undefined): boolean;
13
+ export declare function isEmptyTcPr(tcPr: wml.TcPr | undefined): boolean;
14
+ export declare function isEmptyTrPr(trPr: wml.TrPr | undefined): boolean;
15
+ export declare function isEmptyTblStylePr(pr: wml.CTTblStylePr | undefined): boolean;
16
+ export declare function isEmptyTblStylePrList(list: readonly wml.CTTblStylePr[] | undefined): boolean;
17
+ export declare function isEmptyStyle(style: wml.Style | undefined): boolean;
18
+ /**
19
+ * Whether a run's `w:rPr` states any formatting of its own: any member of the run table other
20
+ * than the style reference is present (an element with no attributes counts: it was stated).
21
+ */
22
+ export declare function hasDirectFormattingRPr(rPr: RunProps | undefined): boolean;
23
+ /**
24
+ * Whether a paragraph's `w:pPr` states any formatting of its own. The paragraph mark's
25
+ * `w:rPr` and a `w:sectPr` are not formatting of the paragraph.
26
+ */
27
+ export declare function hasDirectFormattingPPr(pPr: wml.PPrBase | undefined): boolean;
28
+ export declare function unsetRPr(source: RunProps, destination: RunProps): void;
29
+ export declare function unsetPPrBase(source: wml.PPrBase, destination: wml.PPrBase): void;
30
+ /**
31
+ * Apply run properties over run properties (a `w:rPr` or a `w:pPr/w:rPr` over either), in
32
+ * place. Returns the destination, created when it was undefined and the source had something
33
+ * to say.
34
+ */
35
+ export declare function applyRPr<D extends RunProps>(source: RunProps | undefined, destination: D | undefined, create?: () => D): D | undefined;
36
+ /**
37
+ * Apply one **level** of the style hierarchy over the levels beneath it, combining the
38
+ * **toggle properties** as ECMA-376-1 §17.7.3 requires instead of overriding them.
39
+ *
40
+ * Only a level boundary goes through here - the table style's contribution against the
41
+ * paragraph style's, and the paragraph style's against the character style's. Within one
42
+ * level a style's `w:basedOn` chain is *not* XORed (§17.7.3 takes the first value found
43
+ * walking that chain, which is what merging the chain root-first with {@link applyRPr}
44
+ * gives), and direct formatting is not a level either: an explicit value there is used as it
45
+ * stands, so it goes through {@link applyRPr} too.
46
+ */
47
+ export declare function applyStyleLevel(source: RunProps | undefined, destination: RunProps | undefined, documentDefaults: RunProps | undefined): void;
48
+ /**
49
+ * Combine the twelve toggle properties of two levels of the style hierarchy and write the
50
+ * result into a third `w:rPr`. Nothing else of either is touched.
51
+ */
52
+ export declare function applyToggles(upper: RunProps | undefined, lower: RunProps | undefined, documentDefaults: RunProps | undefined, destination: RunProps | undefined): void;
53
+ /**
54
+ * One toggle property at one level boundary (ECMA-376-1 §17.7.3), as Word's `toggle-levels`
55
+ * golden settled it (docx4j CR-015, 2026-09-18):
56
+ *
57
+ * - an upper level that says nothing is no boundary at all, so the lower value stands and the
58
+ * document defaults' true is not forced back on (confirmed by the golden);
59
+ * - `w:docDefaults` is a base value, never a term of the XOR: where the defaults say true and
60
+ * the upper level states the property, the effective value is true;
61
+ * - an explicit false at a style level is a term of the XOR like any other value, so
62
+ * false XOR lower = lower and only a stated *true* inverts what is beneath it. Word draws a
63
+ * run in a character style stating `<w:b w:val="0"/>` over a bold paragraph style **bold**.
64
+ * Where no level beneath states the property, the one level's own false stands rather than
65
+ * the property going absent.
66
+ *
67
+ * Direct formatting never comes through here: an explicit value there wins outright.
68
+ */
69
+ export declare function toggle(upper: wml.BooleanDefaultTrue | undefined, lower: wml.BooleanDefaultTrue | undefined, documentDefault: wml.BooleanDefaultTrue | undefined): wml.BooleanDefaultTrue | undefined;
70
+ /** Whether this `w:numPr` says "not numbered" - `w:numId w:val="0"` (ECMA-376 17.9.18). */
71
+ export declare function numberingOff(numPr: wml.PPrBase.NumPr | undefined): boolean;
72
+ /**
73
+ * Apply paragraph properties over paragraph properties, in place: every member but `w:ind`,
74
+ * then the indent the numbering level this layer brings in contributes, then `w:ind` itself
75
+ * (an indent stated by the layer overrides the level's).
76
+ */
77
+ export declare function applyPPrBase(source: wml.PPrBase | undefined, destination: wml.PPrBase, numbering?: NumberingIndents): void;
78
+ /**
79
+ * Apply a `w:pPr` over a `w:pPr`: the base members and the paragraph mark's `w:rPr`. A
80
+ * `w:sectPr` is not a paragraph property and is not merged (CR-015 phase 4).
81
+ */
82
+ export declare function applyPPr(source: wml.PPr | undefined, destination: wml.PPr | undefined, numbering?: NumberingIndents): wml.PPr | undefined;
83
+ export declare function applyTblPr(source: wml.CTTblPrBase | undefined, destination: wml.CTTblPrBase | undefined): wml.CTTblPrBase | undefined;
84
+ export declare function applyTcPr(source: wml.TcPr | undefined, destination: wml.TcPr | undefined): wml.TcPr | undefined;
85
+ /**
86
+ * A row's properties, which the generated model keeps as one element list: an element of a
87
+ * name the destination already has replaces it, and one it lacks is added.
88
+ */
89
+ export declare function applyTrPr(source: wml.TrPr | undefined, destination: wml.TrPr | undefined): wml.TrPr | undefined;
90
+ /**
91
+ * Merge a table style's conditional formatting (`w:tblStylePr`) into another's, *per
92
+ * condition*: an entry for a condition the destination already has is applied on top of it,
93
+ * and one it lacks is added. So a style `w:basedOn` another inherits the conditions it does
94
+ * not restate, and restating a condition overrides only the properties it names.
95
+ */
96
+ export declare function applyTblStylePrList(source: readonly wml.CTTblStylePr[] | undefined, destination: wml.CTTblStylePr[] | undefined): void;
97
+ export declare function applyTblStylePr(source: wml.CTTblStylePr | undefined, destination: wml.CTTblStylePr | undefined): wml.CTTblStylePr | undefined;
98
+ /**
99
+ * Apply one style's own properties over another's (docx4j `apply(Style, Style)`). It does not
100
+ * climb the `w:basedOn` chain; `PropertyResolver.ancestry` does that.
101
+ */
102
+ export declare function applyStyle(source: wml.Style | undefined, destination: wml.Style): wml.Style;
103
+ /**
104
+ * Whether the chain has come back to a style it has already seen (or has gone deeper than
105
+ * {@link CYCLE_LIMIT}). The caller degrades gracefully by using as much of the hierarchy as it
106
+ * has; set {@link throwOnCyclicStyles} to throw instead (docx4j's
107
+ * `docx4j.openpackaging.exceptions.CyclicStylesException.throw` property).
108
+ */
109
+ export declare function isCyclic(styleId: string, seen: readonly string[]): boolean;
110
+ /** docx4j's `docx4j.openpackaging.exceptions.CyclicStylesException.throw`: off by default. */
111
+ export declare function throwOnCyclicStyles(value: boolean): void;
112
+ export declare function throwsOnCyclicStyles(): boolean;
@@ -0,0 +1,359 @@
1
+ import { RUN, PARAGRAPH, TABLE, CELL, TOGGLE_NAMES, TOGGLES, IND, applyCatalogue, unsetCatalogue, isEmptyOf, hasDirectFormattingOf, isTrue, copyLeaf, } from './catalogue.mjs';
2
+ import { CyclicStylesException } from '../../opc/exceptions.mjs';
3
+ import { log } from './log.mjs';
4
+ // ---------------------------------------------------------------- isEmpty
5
+ export function isEmptyRPr(rPr) {
6
+ return isEmptyOf(RUN, rPr);
7
+ }
8
+ export function isEmptyPPrBase(pPrBase) {
9
+ return isEmptyOf(PARAGRAPH, pPrBase);
10
+ }
11
+ /** docx4j `isEmpty(PPr)`: the base members, the paragraph mark and the section. */
12
+ export function isEmptyPPr(pPr) {
13
+ // isEmpty(SectPr) is "false for anything non-null" in docx4j ("implementation is quite basic")
14
+ return pPr === undefined
15
+ || (isEmptyPPrBase(pPr) && isEmptyRPr(pPr.rPr) && pPr.sectPr === undefined);
16
+ }
17
+ export function isEmptyTblPr(tblPr) {
18
+ return isEmptyOf(TABLE, tblPr);
19
+ }
20
+ export function isEmptyTcPr(tcPr) {
21
+ return isEmptyOf(CELL, tcPr);
22
+ }
23
+ export function isEmptyTrPr(trPr) {
24
+ return trPr === undefined || trPr.cnfStyleOrDivIdOrGridBefore === undefined
25
+ || trPr.cnfStyleOrDivIdOrGridBefore.length === 0;
26
+ }
27
+ export function isEmptyTblStylePr(pr) {
28
+ return pr === undefined
29
+ || (isEmptyPPr(pr.pPr) && isEmptyRPr(pr.rPr) && isEmptyTblPr(pr.tblPr)
30
+ && isEmptyTrPr(pr.trPr) && isEmptyTcPr(pr.tcPr) && pr.type === undefined);
31
+ }
32
+ export function isEmptyTblStylePrList(list) {
33
+ if (list === undefined || list.length === 0)
34
+ return true;
35
+ return !list.some((pr) => !isEmptyTblStylePr(pr));
36
+ }
37
+ const CHARACTER_STYLE = 'character';
38
+ const PARAGRAPH_STYLE = 'paragraph';
39
+ const NUMBERING_STYLE = 'numbering';
40
+ const TABLE_STYLE = 'table';
41
+ export function isEmptyStyle(style) {
42
+ if (style === undefined)
43
+ return true;
44
+ if (style.type === CHARACTER_STYLE)
45
+ return isEmptyRPr(style.rPr);
46
+ if (style.type === PARAGRAPH_STYLE || style.type === NUMBERING_STYLE) {
47
+ return isEmptyPPr(style.pPr) && isEmptyRPr(style.rPr);
48
+ }
49
+ return isEmptyPPr(style.pPr) && isEmptyRPr(style.rPr) && isEmptyTblPr(style.tblPr)
50
+ && isEmptyTcPr(style.tcPr) && isEmptyTblStylePrList(style.tblStylePr);
51
+ }
52
+ // ---------------------------------------------------------------- direct formatting
53
+ /**
54
+ * Whether a run's `w:rPr` states any formatting of its own: any member of the run table other
55
+ * than the style reference is present (an element with no attributes counts: it was stated).
56
+ */
57
+ export function hasDirectFormattingRPr(rPr) {
58
+ return hasDirectFormattingOf(RUN, rPr);
59
+ }
60
+ /**
61
+ * Whether a paragraph's `w:pPr` states any formatting of its own. The paragraph mark's
62
+ * `w:rPr` and a `w:sectPr` are not formatting of the paragraph.
63
+ */
64
+ export function hasDirectFormattingPPr(pPr) {
65
+ return hasDirectFormattingOf(PARAGRAPH, pPr);
66
+ }
67
+ // ---------------------------------------------------------------- unset
68
+ export function unsetRPr(source, destination) {
69
+ unsetCatalogue(RUN, source, destination);
70
+ }
71
+ export function unsetPPrBase(source, destination) {
72
+ unsetCatalogue(PARAGRAPH, source, destination);
73
+ }
74
+ // ---------------------------------------------------------------- apply: runs
75
+ /** A run properties source with nothing to say - except that a `w:rFonts` carrying only a `w:hint` still says something. */
76
+ function skipRun(source) {
77
+ if (source === undefined)
78
+ return true;
79
+ const hint = source.rFonts !== undefined && source.rFonts.hint !== undefined;
80
+ return isEmptyOf(RUN, source) && !hint;
81
+ }
82
+ /**
83
+ * Apply run properties over run properties (a `w:rPr` or a `w:pPr/w:rPr` over either), in
84
+ * place. Returns the destination, created when it was undefined and the source had something
85
+ * to say.
86
+ */
87
+ export function applyRPr(source, destination, create) {
88
+ if (skipRun(source))
89
+ return destination;
90
+ const out = destination !== null && destination !== void 0 ? destination : (create ? create() : { TYPE_NAME: 'org_docx4j_wml.RPr' });
91
+ applyCatalogue(RUN, source, out);
92
+ return out;
93
+ }
94
+ /**
95
+ * Apply one **level** of the style hierarchy over the levels beneath it, combining the
96
+ * **toggle properties** as ECMA-376-1 §17.7.3 requires instead of overriding them.
97
+ *
98
+ * Only a level boundary goes through here - the table style's contribution against the
99
+ * paragraph style's, and the paragraph style's against the character style's. Within one
100
+ * level a style's `w:basedOn` chain is *not* XORed (§17.7.3 takes the first value found
101
+ * walking that chain, which is what merging the chain root-first with {@link applyRPr}
102
+ * gives), and direct formatting is not a level either: an explicit value there is used as it
103
+ * stands, so it goes through {@link applyRPr} too.
104
+ */
105
+ export function applyStyleLevel(source, destination, documentDefaults) {
106
+ if (source === undefined || destination === undefined)
107
+ return;
108
+ applyCatalogue(RUN, source, destination, TOGGLE_NAMES);
109
+ applyToggles(source, destination, documentDefaults, destination);
110
+ }
111
+ /**
112
+ * Combine the twelve toggle properties of two levels of the style hierarchy and write the
113
+ * result into a third `w:rPr`. Nothing else of either is touched.
114
+ */
115
+ export function applyToggles(upper, lower, documentDefaults, destination) {
116
+ if (destination === undefined)
117
+ return;
118
+ for (const p of TOGGLES) {
119
+ const value = toggle(upper === undefined ? undefined : p.get(upper), lower === undefined ? undefined : p.get(lower), documentDefaults === undefined ? undefined : p.get(documentDefaults));
120
+ p.set(destination, value);
121
+ }
122
+ }
123
+ /**
124
+ * One toggle property at one level boundary (ECMA-376-1 §17.7.3), as Word's `toggle-levels`
125
+ * golden settled it (docx4j CR-015, 2026-09-18):
126
+ *
127
+ * - an upper level that says nothing is no boundary at all, so the lower value stands and the
128
+ * document defaults' true is not forced back on (confirmed by the golden);
129
+ * - `w:docDefaults` is a base value, never a term of the XOR: where the defaults say true and
130
+ * the upper level states the property, the effective value is true;
131
+ * - an explicit false at a style level is a term of the XOR like any other value, so
132
+ * false XOR lower = lower and only a stated *true* inverts what is beneath it. Word draws a
133
+ * run in a character style stating `<w:b w:val="0"/>` over a bold paragraph style **bold**.
134
+ * Where no level beneath states the property, the one level's own false stands rather than
135
+ * the property going absent.
136
+ *
137
+ * Direct formatting never comes through here: an explicit value there wins outright.
138
+ */
139
+ export function toggle(upper, lower, documentDefault) {
140
+ if (upper === undefined)
141
+ return lower;
142
+ if (documentDefault !== undefined && isTrue(documentDefault)) {
143
+ return copyLeaf(documentDefault);
144
+ }
145
+ // false XOR lower = lower; with no level beneath it, the level's own false stands
146
+ if (!isTrue(upper))
147
+ return lower !== undefined ? lower : upper;
148
+ const out = { TYPE_NAME: 'org_docx4j_wml.BooleanDefaultTrue' };
149
+ out.val = !isTrue(lower);
150
+ return out;
151
+ }
152
+ // ---------------------------------------------------------------- apply: paragraphs
153
+ /** Whether this `w:numPr` says "not numbered" - `w:numId w:val="0"` (ECMA-376 17.9.18). */
154
+ export function numberingOff(numPr) {
155
+ return numPr !== undefined && numPr.numId !== undefined && numPr.numId.val === 0;
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;
171
+ }
172
+ const IND_ONLY = new Set([IND]);
173
+ /**
174
+ * Apply paragraph properties over paragraph properties, in place: every member but `w:ind`,
175
+ * then the indent the numbering level this layer brings in contributes, then `w:ind` itself
176
+ * (an indent stated by the layer overrides the level's).
177
+ */
178
+ export function applyPPrBase(source, destination, numbering) {
179
+ if (source === undefined || isEmptyPPrBase(source))
180
+ return;
181
+ /* A snapshot: the numPr merge writes into the destination object, so holding a reference
182
+ * here would hand the numbering-off rule below the w:numId 0 it is looking past. */
183
+ let inheritedNumPr;
184
+ if (destination.numPr !== undefined) {
185
+ inheritedNumPr = { numId: destination.numPr.numId, ilvl: destination.numPr.ilvl };
186
+ }
187
+ 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. */
191
+ if (numbering !== undefined && numberingOff(source.numPr)
192
+ && 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
+ }
200
+ }
201
+ /* The indent of the level of the MERGED w:numPr, since a layer may state only w:ilvl (the
202
+ * list from the style) or only w:numId (the level from the style): CR-015 probe
203
+ * styles-numpr-ilvl-only. */
204
+ if (numbering !== undefined && source.numPr !== undefined
205
+ && destination.numPr !== undefined && !numberingOff(destination.numPr)) {
206
+ const numInd = numbering.getInd(destination.numPr);
207
+ if (numInd !== undefined) {
208
+ destination.ind = indProperty().merge(numInd, destination.ind);
209
+ }
210
+ }
211
+ // an indent in the layer overrides any the numbering brought in
212
+ destination.ind = indProperty().merge(source.ind, destination.ind);
213
+ }
214
+ let indEntry;
215
+ function indProperty() {
216
+ indEntry !== null && indEntry !== void 0 ? indEntry : (indEntry = PARAGRAPH.find((p) => p.name === IND));
217
+ return indEntry;
218
+ }
219
+ /**
220
+ * Apply a `w:pPr` over a `w:pPr`: the base members and the paragraph mark's `w:rPr`. A
221
+ * `w:sectPr` is not a paragraph property and is not merged (CR-015 phase 4).
222
+ */
223
+ export function applyPPr(source, destination, numbering) {
224
+ if (source === undefined || isEmptyPPr(source))
225
+ return destination;
226
+ const out = destination !== null && destination !== void 0 ? destination : { TYPE_NAME: 'org_docx4j_wml.PPr' };
227
+ applyPPrBase(source, out, numbering);
228
+ out.rPr = applyRPr(source.rPr, out.rPr, () => ({ TYPE_NAME: 'org_docx4j_wml.ParaRPr' }));
229
+ return out;
230
+ }
231
+ // ---------------------------------------------------------------- apply: tables
232
+ export function applyTblPr(source, destination) {
233
+ if (source === undefined || isEmptyTblPr(source))
234
+ return destination;
235
+ const out = destination !== null && destination !== void 0 ? destination : { TYPE_NAME: 'org_docx4j_wml.CTTblPrBase' };
236
+ applyCatalogue(TABLE, source, out);
237
+ return out;
238
+ }
239
+ export function applyTcPr(source, destination) {
240
+ if (source === undefined || isEmptyTcPr(source))
241
+ return destination;
242
+ const out = destination !== null && destination !== void 0 ? destination : { TYPE_NAME: 'org_docx4j_wml.TcPr' };
243
+ applyCatalogue(CELL, source, out);
244
+ return out;
245
+ }
246
+ /**
247
+ * A row's properties, which the generated model keeps as one element list: an element of a
248
+ * name the destination already has replaces it, and one it lacks is added.
249
+ */
250
+ export function applyTrPr(source, destination) {
251
+ var _a;
252
+ if (isEmptyTrPr(source))
253
+ return destination;
254
+ const out = destination !== null && destination !== void 0 ? destination : { TYPE_NAME: 'org_docx4j_wml.TrPr' };
255
+ const into = ((_a = out.cnfStyleOrDivIdOrGridBefore) !== null && _a !== void 0 ? _a : (out.cnfStyleOrDivIdOrGridBefore = []));
256
+ for (const element of source.cnfStyleOrDivIdOrGridBefore) {
257
+ const index = into.findIndex((existing) => existing.name.localPart === element.name.localPart
258
+ && existing.name.namespaceURI === element.name.namespaceURI);
259
+ if (index >= 0)
260
+ into.splice(index, 1);
261
+ into.push(copyLeaf(element));
262
+ }
263
+ return out;
264
+ }
265
+ /**
266
+ * Merge a table style's conditional formatting (`w:tblStylePr`) into another's, *per
267
+ * condition*: an entry for a condition the destination already has is applied on top of it,
268
+ * and one it lacks is added. So a style `w:basedOn` another inherits the conditions it does
269
+ * not restate, and restating a condition overrides only the properties it names.
270
+ */
271
+ export function applyTblStylePrList(source, destination) {
272
+ if (isEmptyTblStylePrList(source) || destination === undefined)
273
+ return;
274
+ for (const sourcePr of source) {
275
+ if (sourcePr === undefined)
276
+ continue;
277
+ let existing;
278
+ if (sourcePr.type !== undefined) {
279
+ existing = destination.find((d) => d !== undefined && d.type === sourcePr.type);
280
+ }
281
+ if (existing === undefined) {
282
+ const copy = applyTblStylePr(sourcePr, undefined);
283
+ if (copy !== undefined)
284
+ destination.push(copy);
285
+ }
286
+ else {
287
+ applyTblStylePr(sourcePr, existing);
288
+ }
289
+ }
290
+ }
291
+ export function applyTblStylePr(source, destination) {
292
+ if (isEmptyTblStylePr(source))
293
+ return destination;
294
+ const s = source;
295
+ const out = destination !== null && destination !== void 0 ? destination : { TYPE_NAME: 'org_docx4j_wml.CTTblStylePr' };
296
+ out.pPr = applyPPr(s.pPr, out.pPr);
297
+ out.rPr = applyRPr(s.rPr, out.rPr);
298
+ out.tblPr = applyTblPr(s.tblPr, out.tblPr);
299
+ out.tcPr = applyTcPr(s.tcPr, out.tcPr);
300
+ out.trPr = applyTrPr(s.trPr, out.trPr);
301
+ out.type = s.type;
302
+ return out;
303
+ }
304
+ /**
305
+ * Apply one style's own properties over another's (docx4j `apply(Style, Style)`). It does not
306
+ * climb the `w:basedOn` chain; `PropertyResolver.ancestry` does that.
307
+ */
308
+ export function applyStyle(source, destination) {
309
+ var _a;
310
+ if (isEmptyStyle(source))
311
+ return destination;
312
+ const s = source;
313
+ if (destination.type === undefined)
314
+ destination.type = s.type;
315
+ if (s.type === CHARACTER_STYLE) {
316
+ destination.rPr = applyRPr(s.rPr, destination.rPr);
317
+ return destination;
318
+ }
319
+ if (s.type === PARAGRAPH_STYLE || s.type === NUMBERING_STYLE) {
320
+ destination.pPr = applyPPr(s.pPr, destination.pPr);
321
+ destination.rPr = applyRPr(s.rPr, destination.rPr);
322
+ return destination;
323
+ }
324
+ destination.tblPr = applyTblPr(s.tblPr, destination.tblPr);
325
+ destination.trPr = applyTrPr(s.trPr, destination.trPr);
326
+ destination.tcPr = applyTcPr(s.tcPr, destination.tcPr);
327
+ (_a = destination.tblStylePr) !== null && _a !== void 0 ? _a : (destination.tblStylePr = []);
328
+ applyTblStylePrList(s.tblStylePr, destination.tblStylePr);
329
+ if (destination.tblStylePr.length === 0)
330
+ delete destination.tblStylePr;
331
+ destination.pPr = applyPPr(s.pPr, destination.pPr);
332
+ destination.rPr = applyRPr(s.rPr, destination.rPr);
333
+ return destination;
334
+ }
335
+ // ---------------------------------------------------------------- cycles
336
+ /** docx4j's hard limit on deep `w:basedOn` hierarchies. */
337
+ const CYCLE_LIMIT = 32;
338
+ /**
339
+ * Whether the chain has come back to a style it has already seen (or has gone deeper than
340
+ * {@link CYCLE_LIMIT}). The caller degrades gracefully by using as much of the hierarchy as it
341
+ * has; set {@link throwOnCyclicStyles} to throw instead (docx4j's
342
+ * `docx4j.openpackaging.exceptions.CyclicStylesException.throw` property).
343
+ */
344
+ export function isCyclic(styleId, seen) {
345
+ if (!seen.includes(styleId) && seen.length <= CYCLE_LIMIT)
346
+ return false;
347
+ log.warn(`Cycle detected in style basedOn hierarchy for: ${styleId} - stopping`);
348
+ if (throwOnCyclic)
349
+ throw new CyclicStylesException(`Cycle detected in style basedOn hierarchy for: ${styleId}`);
350
+ return true;
351
+ }
352
+ let throwOnCyclic = false;
353
+ /** docx4j's `docx4j.openpackaging.exceptions.CyclicStylesException.throw`: off by default. */
354
+ export function throwOnCyclicStyles(value) {
355
+ throwOnCyclic = value;
356
+ }
357
+ export function throwsOnCyclicStyles() {
358
+ return throwOnCyclic;
359
+ }
@@ -0,0 +1 @@
1
+ export { DirectoryPartStore, DirectoryPartSink } from '../opc/DirectoryPartStore.mjs';
@@ -0,0 +1,12 @@
1
+ // `@docx4j/core-ts/node`: the parts of the engine that need Node's own APIs.
2
+ //
3
+ // Everything else in this package runs unchanged in a browser or a Word add-in, which is why the
4
+ // `node:` imports are fenced off here: nothing under `.`, `./opc`, `./parts`, `./packages`,
5
+ // `./model` or `./office-js` reaches a Node builtin, so a bundle for the web never has to shim
6
+ // `node:fs`. Import this subpath only from code you know runs in Node.
7
+ //
8
+ // import { DirectoryPartStore, DirectoryPartSink } from '@docx4j/core-ts/node';
9
+ //
10
+ // const pkg = await WordprocessingMLPackage.load(await DirectoryPartStore.open('unzipped'));
11
+ // await pkg.saveTo(new DirectoryPartSink('unzipped-out'));
12
+ export { DirectoryPartStore, DirectoryPartSink } from '../opc/DirectoryPartStore.mjs';
@@ -0,0 +1,111 @@
1
+ import type { WordprocessingMLPackage } from '../packages/WordprocessingMLPackage.mjs';
2
+ import type { Body } from '../model/content/Body.mjs';
3
+ import type { Range } from '../model/content/Range.mjs';
4
+ import type { TrackedChange } from '../model/content/TrackedChange.mjs';
5
+ import type { ChangeTrackingModeValue } from './enums.mjs';
6
+ /** What `Word.run` was given: the selection to hand to `getSelection()`, and the preparation to do. */
7
+ export interface RunOptions {
8
+ /** The range `context.document.getSelection()` returns; there is no host selection in Node. */
9
+ selection?: Range;
10
+ /**
11
+ * Unmarshal the core and extended properties and the settings parts before the callback, so
12
+ * that `document.properties` and `document.changeTrackingMode` read synchronously as Office JS
13
+ * does (default true). False leaves those parts untouched, and reads of them then report
14
+ * nothing; a write throws.
15
+ */
16
+ unmarshalSideParts?: boolean;
17
+ }
18
+ /**
19
+ * A subset of Office JS `Word.DocumentProperties` over `docProps/core.xml` (docx4j
20
+ * DocPropsCorePart) and `docProps/app.xml` (DocPropsExtendedPart). Reads report '' or undefined
21
+ * when a property is absent; a write creates the part when the package has none.
22
+ */
23
+ export declare class DocumentProperties {
24
+ private readonly pkg;
25
+ constructor(pkg: WordprocessingMLPackage);
26
+ private coreProps;
27
+ private extendedProps;
28
+ /** dc:title. */
29
+ get title(): string;
30
+ set title(value: string);
31
+ /** dc:subject. */
32
+ get subject(): string;
33
+ set subject(value: string);
34
+ /** dc:creator (Office JS calls it the author). */
35
+ get author(): string;
36
+ set author(value: string);
37
+ /** dc:description (Office JS calls it comments). */
38
+ get comments(): string;
39
+ set comments(value: string);
40
+ /** cp:keywords. */
41
+ get keywords(): string;
42
+ set keywords(value: string);
43
+ /** cp:category. */
44
+ get category(): string;
45
+ set category(value: string);
46
+ /** cp:lastModifiedBy. */
47
+ get lastAuthor(): string;
48
+ set lastAuthor(value: string);
49
+ /** cp:revision. */
50
+ get revisionNumber(): string;
51
+ set revisionNumber(value: string);
52
+ /** dcterms:created. */
53
+ get creationDate(): Date | undefined;
54
+ set creationDate(value: Date | undefined);
55
+ /** dcterms:modified. */
56
+ get lastSaveTime(): Date | undefined;
57
+ set lastSaveTime(value: Date | undefined);
58
+ /** cp:lastPrinted. */
59
+ get lastPrintDate(): Date | undefined;
60
+ set lastPrintDate(value: Date | undefined);
61
+ /** Manager (extended properties). */
62
+ get manager(): string;
63
+ set manager(value: string);
64
+ /** Company (extended properties). */
65
+ get company(): string;
66
+ set company(value: string);
67
+ /** Application (extended properties). */
68
+ get applicationName(): string;
69
+ set applicationName(value: string);
70
+ /** Template (extended properties). */
71
+ get template(): string;
72
+ set template(value: string);
73
+ /** DocSecurity (extended properties); read only, as Office JS. */
74
+ get security(): number;
75
+ }
76
+ /**
77
+ * A subset of Office JS `Word.Document` over a package. `body` is the main document part's body;
78
+ * everything else is the document-level surface add-in code reaches for first.
79
+ */
80
+ export declare class Document {
81
+ /** The package this document is (extension: Office JS has no package). */
82
+ readonly package_: WordprocessingMLPackage;
83
+ private readonly options;
84
+ readonly properties: DocumentProperties;
85
+ constructor(
86
+ /** The package this document is (extension: Office JS has no package). */
87
+ package_: WordprocessingMLPackage, options?: RunOptions);
88
+ /** The main document part's body; `Word.run` unmarshalled the part before the callback. */
89
+ get body(): Body;
90
+ /** The caller's selection (`Word.run(pkg, fn, { selection })`); there is none in Node. */
91
+ getSelection(): Range;
92
+ /**
93
+ * Office JS `document.changeTrackingMode`: the package's, which is `w:trackRevisions` in the
94
+ * settings part and, while it is on, makes every edit through the content API write revision
95
+ * markup (CR-002 phase F). The shim adds nothing of its own; `Word.run` has unmarshalled the
96
+ * settings part, so both directions are synchronous here.
97
+ */
98
+ get changeTrackingMode(): ChangeTrackingModeValue;
99
+ set changeTrackingMode(mode: ChangeTrackingModeValue);
100
+ /** Office JS `document.getTrackedChanges()`: the body's, in document order (CR-002 phase F). */
101
+ getTrackedChanges(): TrackedChange[];
102
+ /**
103
+ * The comments of the document. CR-002 phase G puts `getComments()` on `Body`; until it lands
104
+ * this reports none, so add-in code that lists comments runs either way.
105
+ */
106
+ getComments(): unknown[] | Promise<unknown[]>;
107
+ /** The whole document as a flat OPC `pkg:package` string, as Office JS's `body.getOoxml()`. */
108
+ getOoxml(): Promise<string>;
109
+ /** The document as a docx (extension; Office JS's `save()` saves in the host). */
110
+ save(): Promise<Uint8Array>;
111
+ }