@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,6 +1,7 @@
1
1
  import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
2
- import { type UnderlineType } from '@docx4j/generated-objects-ts/builders/wml';
2
+ import { type RunOptions, type RunFormatting, type UnderlineType } from '@docx4j/generated-objects-ts/builders/wml';
3
3
  import type { ChangeTracker } from './tracking.mjs';
4
+ import type { ThemeColors } from '../color/ThemeColors.mjs';
4
5
  export type { UnderlineType };
5
6
  /** Something with run properties: a run, or the paragraph mark. */
6
7
  export interface RPrHolder {
@@ -12,13 +13,33 @@ export interface FontTracking {
12
13
  /** The runs that are this author's own insertion: Word changes those in place, with no w:rPrChange. */
13
14
  ownInsertions: ReadonlySet<object>;
14
15
  }
16
+ /** A run's formatting as a `Font` reads it: its properties, and its document font's name. */
17
+ export interface RunReading {
18
+ formatting: RunFormatting;
19
+ name: string;
20
+ }
21
+ /** A paragraph mark's run properties as a `Font` reads them: `w:pPr/w:rPr` without the mark's own revisions. */
22
+ export declare function markHolderOf(p: wml.P): RPrHolder;
23
+ /**
24
+ * A run's reading from its properties: in the effective view a theme colour the colour Word draws, given the
25
+ * document's theme colours (`w:themeColor`, tint and shade, over the `w:val` beside it, which is a cache: check 53,
26
+ * CR-008 phase 2), and an automatic colour (`w:val="auto"`, or none) `#000000`, as Office JS reads them (CR-002
27
+ * section 59); and `name` its document font where one is given.
28
+ */
29
+ export declare function readingOf(rPr: wml.RPr | undefined, effective: boolean, name?: string, themeColors?: ThemeColors): RunReading;
15
30
  /**
16
31
  * A subset of Office JS `Word.Font` over the run properties (`w:rPr`) of one or more runs.
17
32
  *
18
- * **Reads report effective formatting** (CR-001 Phase B step 2): the first run in scope
19
- * resolved through the document defaults, the paragraph style and the character style, which
20
- * is what Office JS reports. Pass an `effective` supplier for that; without one the view falls
21
- * back to direct formatting, which is what `getFont({ direct: true })` asks for.
33
+ * **Reads report effective formatting** (CR-001 Phase B step 2): each run in scope resolved through
34
+ * the document defaults, the paragraph style and the character style. Pass an `effective` supplier
35
+ * for that; without one the view reads direct formatting, which is what `getFont({ direct: true })`
36
+ * asks for. Where the runs differ a property reads as Office JS reads it (Word 365, checks 52 and 53;
37
+ * CR-002 section 59): `null`, `''` for the name, the colour and the highlight, and `Mixed` for the
38
+ * underline. Office JS's own types say `boolean` and `number` there, and so do these. With no run in
39
+ * scope, a paragraph with no text reads its mark's run properties (`w:pPr/w:rPr`, check 52 case 60),
40
+ * and an empty range its paragraph's style. An automatic colour (`w:val="auto"`, or none) reads
41
+ * `#000000` in the effective view, and a theme colour the colour Word draws (CR-008 phase 2), as Office JS reads them
42
+ * (check 53).
22
43
  *
23
44
  * **Writes are always direct**, and apply to every run in scope. Both directions go through
24
45
  * the objects package's one name-to-`w:rPr` mapping (`builders/wml` applyRunOptions /
@@ -31,27 +52,40 @@ export interface FontTracking {
31
52
  * package whose selector has not been built yet falls back to that.
32
53
  */
33
54
  export declare class Font {
55
+ /** The runs in scope; `write` is true for a write, which may split runs to have them, and false for a read, which must not. */
34
56
  private readonly holders;
35
57
  /** The change tracker and this author's own insertions, when the package is tracking changes. */
36
58
  private readonly tracking?;
37
- /** The effective `w:rPr` of the first run in scope; absent for a direct-formatting view. */
59
+ /** The effective `w:rPr` of a run in scope; absent for a direct-formatting view. */
38
60
  private readonly effective?;
39
61
  /** The document font of that effective `w:rPr` with its theme reference resolved
40
62
  * (`RunFontSelector.asciiFontName`); absent for a direct-formatting view, and undefined
41
63
  * where the package has no selector yet. */
42
64
  private readonly asciiFontName?;
43
- constructor(holders: () => RPrHolder[],
65
+ /** The paragraph mark, read where no run is in scope: a paragraph with no text (CR-002 section 59). */
66
+ private readonly mark?;
67
+ /** The document's theme colours, which a theme colour is read through (CR-008 phase 2); absent for a direct view. */
68
+ private readonly themeColors?;
69
+ constructor(
70
+ /** The runs in scope; `write` is true for a write, which may split runs to have them, and false for a read, which must not. */
71
+ holders: (write: boolean) => RPrHolder[],
44
72
  /** The change tracker and this author's own insertions, when the package is tracking changes. */
45
73
  tracking?: (() => FontTracking | undefined) | undefined,
46
- /** The effective `w:rPr` of the first run in scope; absent for a direct-formatting view. */
74
+ /** The effective `w:rPr` of a run in scope; absent for a direct-formatting view. */
47
75
  effective?: ((rPr: wml.RPr | undefined) => wml.RPr | undefined) | undefined,
48
76
  /** The document font of that effective `w:rPr` with its theme reference resolved
49
77
  * (`RunFontSelector.asciiFontName`); absent for a direct-formatting view, and undefined
50
78
  * where the package has no selector yet. */
51
- asciiFontName?: ((rPr: wml.RPr | undefined) => string | undefined) | undefined);
52
- private effectiveRPr;
53
- private read;
54
- private apply;
79
+ asciiFontName?: ((rPr: wml.RPr | undefined) => string | undefined) | undefined,
80
+ /** The paragraph mark, read where no run is in scope: a paragraph with no text (CR-002 section 59). */
81
+ mark?: (() => RPrHolder | undefined) | undefined,
82
+ /** The document's theme colours, which a theme colour is read through (CR-008 phase 2); absent for a direct view. */
83
+ themeColors?: (() => ThemeColors | undefined) | undefined);
84
+ /** Each run in scope, read; the mark's properties where there is none, else the paragraph's style's. */
85
+ protected readings(): RunReading[];
86
+ /** A property every reading agrees on, else `null` (also where nothing is read). */
87
+ private value;
88
+ protected apply(opts: RunOptions): void;
55
89
  get bold(): boolean;
56
90
  set bold(v: boolean);
57
91
  get italic(): boolean;
@@ -69,18 +103,37 @@ export declare class Font {
69
103
  /**
70
104
  * The document font formatting this run's Latin text: `w:rFonts/@w:ascii` of the effective
71
105
  * properties, the face `w:asciiTheme` names, else `w:hAnsi`, else the document default
72
- * (docx4j `RunFontSelector.asciiFontName`). '' only in a direct-formatting view with no
73
- * `w:ascii`, or where the package's `RunFontSelector` has not been built yet.
106
+ * (docx4j `RunFontSelector.asciiFontName`). '' where the runs differ, in a direct-formatting
107
+ * view with no `w:ascii`, or where the package's `RunFontSelector` has not been built yet.
74
108
  */
75
109
  get name(): string;
76
110
  set name(v: string);
77
- /** Size in points (w:sz is half-points); 0 only in a direct-formatting view with no w:sz. */
111
+ /**
112
+ * Size in points (w:sz is half-points); 0 only in a direct-formatting view with no w:sz; `null` where the runs differ. A
113
+ * size written is held to the range Word 365 stores w:sz in, 0 to 32767.5 pt (CR-002 section 65): outside it, `InvalidArgument`.
114
+ */
78
115
  get size(): number;
79
116
  set size(v: number);
80
- /** '#RRGGBB', or the raw value ('auto', a theme colour name) when it is not a hex triple; '' when not set. */
117
+ /**
118
+ * '#RRGGBB': in the effective view the colour Word draws, so a theme colour (`w:themeColor`, with its tint or shade)
119
+ * through the document's theme, as Office JS reads it (check 53; CR-008 phase 2), and `#000000` for automatic; in
120
+ * the direct view `w:val` as written, '' when not set; the raw value where it is not a hex triple and no theme
121
+ * colour applies; '' where the runs differ.
122
+ */
81
123
  get color(): string;
82
124
  set color(v: string);
83
- /** '#RRGGBB' of the highlight, or null when there is none. */
125
+ /** '#RRGGBB' of the highlight, or null when there is none; '' where the runs differ. */
84
126
  get highlightColor(): string | null;
85
127
  set highlightColor(v: string | null);
86
128
  }
129
+ /**
130
+ * The `Font` of a range across paragraphs (CR-014): each run read in its own paragraph, as `Font` reads them. A write
131
+ * goes to `write` (phase 2: every run and mark in the range, as Word formats them).
132
+ */
133
+ export declare class MixedFont extends Font {
134
+ private readonly reads;
135
+ private readonly write;
136
+ constructor(reads: () => RunReading[], write: (opts: RunOptions) => void);
137
+ protected readings(): RunReading[];
138
+ protected apply(opts: RunOptions): void;
139
+ }
@@ -1,11 +1,48 @@
1
1
  import { applyRunOptions, readRunOptions } from '@docx4j/generated-objects-ts/builders/wml';
2
+ import { withinWord, WORD_STORAGE } from './wordRange.mjs';
3
+ import { WordColors } from '../color/WordColors.mjs';
4
+ /** A paragraph mark's run properties as a `Font` reads them: `w:pPr/w:rPr` without the mark's own revisions. */
5
+ export function markHolderOf(p) {
6
+ var _a;
7
+ const rPr = (_a = p.pPr) === null || _a === void 0 ? void 0 : _a.rPr;
8
+ if (!rPr)
9
+ return {};
10
+ const { ins: _ins, del: _del, moveFrom: _from, moveTo: _to, rPrChange: _change, ...rest } = rPr;
11
+ return { rPr: { ...rest, TYPE_NAME: 'org_docx4j_wml.RPr' } };
12
+ }
13
+ /**
14
+ * A run's reading from its properties: in the effective view a theme colour the colour Word draws, given the
15
+ * document's theme colours (`w:themeColor`, tint and shade, over the `w:val` beside it, which is a cache: check 53,
16
+ * CR-008 phase 2), and an automatic colour (`w:val="auto"`, or none) `#000000`, as Office JS reads them (CR-002
17
+ * section 59); and `name` its document font where one is given.
18
+ */
19
+ export function readingOf(rPr, effective, name, themeColors) {
20
+ var _a;
21
+ const formatting = readRunOptions(rPr);
22
+ if (effective) {
23
+ const themed = (_a = rPr === null || rPr === void 0 ? void 0 : rPr.color) === null || _a === void 0 ? void 0 : _a.themeColor;
24
+ const drawn = themed === undefined || themed === null || themed === 'none' || themeColors === undefined
25
+ ? undefined : WordColors.of(rPr.color, themeColors);
26
+ if (drawn !== undefined)
27
+ formatting.color = `#${drawn.toHex()}`;
28
+ else if (formatting.color === '' || formatting.color === 'auto')
29
+ formatting.color = '#000000';
30
+ }
31
+ return { formatting, name: name !== null && name !== void 0 ? name : formatting.name };
32
+ }
2
33
  /**
3
34
  * A subset of Office JS `Word.Font` over the run properties (`w:rPr`) of one or more runs.
4
35
  *
5
- * **Reads report effective formatting** (CR-001 Phase B step 2): the first run in scope
6
- * resolved through the document defaults, the paragraph style and the character style, which
7
- * is what Office JS reports. Pass an `effective` supplier for that; without one the view falls
8
- * back to direct formatting, which is what `getFont({ direct: true })` asks for.
36
+ * **Reads report effective formatting** (CR-001 Phase B step 2): each run in scope resolved through
37
+ * the document defaults, the paragraph style and the character style. Pass an `effective` supplier
38
+ * for that; without one the view reads direct formatting, which is what `getFont({ direct: true })`
39
+ * asks for. Where the runs differ a property reads as Office JS reads it (Word 365, checks 52 and 53;
40
+ * CR-002 section 59): `null`, `''` for the name, the colour and the highlight, and `Mixed` for the
41
+ * underline. Office JS's own types say `boolean` and `number` there, and so do these. With no run in
42
+ * scope, a paragraph with no text reads its mark's run properties (`w:pPr/w:rPr`, check 52 case 60),
43
+ * and an empty range its paragraph's style. An automatic colour (`w:val="auto"`, or none) reads
44
+ * `#000000` in the effective view, and a theme colour the colour Word draws (CR-008 phase 2), as Office JS reads them
45
+ * (check 53).
9
46
  *
10
47
  * **Writes are always direct**, and apply to every run in scope. Both directions go through
11
48
  * the objects package's one name-to-`w:rPr` mapping (`builders/wml` applyRunOptions /
@@ -18,32 +55,52 @@ import { applyRunOptions, readRunOptions } from '@docx4j/generated-objects-ts/bu
18
55
  * package whose selector has not been built yet falls back to that.
19
56
  */
20
57
  export class Font {
21
- constructor(holders,
58
+ constructor(
59
+ /** The runs in scope; `write` is true for a write, which may split runs to have them, and false for a read, which must not. */
60
+ holders,
22
61
  /** The change tracker and this author's own insertions, when the package is tracking changes. */
23
62
  tracking,
24
- /** The effective `w:rPr` of the first run in scope; absent for a direct-formatting view. */
63
+ /** The effective `w:rPr` of a run in scope; absent for a direct-formatting view. */
25
64
  effective,
26
65
  /** The document font of that effective `w:rPr` with its theme reference resolved
27
66
  * (`RunFontSelector.asciiFontName`); absent for a direct-formatting view, and undefined
28
67
  * where the package has no selector yet. */
29
- asciiFontName) {
68
+ asciiFontName,
69
+ /** The paragraph mark, read where no run is in scope: a paragraph with no text (CR-002 section 59). */
70
+ mark,
71
+ /** The document's theme colours, which a theme colour is read through (CR-008 phase 2); absent for a direct view. */
72
+ themeColors) {
30
73
  this.holders = holders;
31
74
  this.tracking = tracking;
32
75
  this.effective = effective;
33
76
  this.asciiFontName = asciiFontName;
77
+ this.mark = mark;
78
+ this.themeColors = themeColors;
34
79
  }
35
- effectiveRPr() {
36
- var _a;
37
- const direct = (_a = this.holders()[0]) === null || _a === void 0 ? void 0 : _a.rPr;
38
- return this.effective ? this.effective(direct) : direct;
80
+ /** Each run in scope, read; the mark's properties where there is none, else the paragraph's style's. */
81
+ readings() {
82
+ var _a, _b, _c;
83
+ let holders = this.holders(false);
84
+ if (holders.length === 0)
85
+ holders = [(_b = (_a = this.mark) === null || _a === void 0 ? void 0 : _a.call(this)) !== null && _b !== void 0 ? _b : {}];
86
+ const themeColors = this.effective ? (_c = this.themeColors) === null || _c === void 0 ? void 0 : _c.call(this) : undefined;
87
+ return holders.map((h) => {
88
+ var _a;
89
+ const rPr = this.effective ? this.effective(h.rPr) : h.rPr;
90
+ return readingOf(rPr, this.effective !== undefined, (_a = this.asciiFontName) === null || _a === void 0 ? void 0 : _a.call(this, rPr), themeColors);
91
+ });
39
92
  }
40
- read() {
41
- return readRunOptions(this.effectiveRPr());
93
+ /** A property every reading agrees on, else `null` (also where nothing is read). */
94
+ value(key) {
95
+ const all = this.readings().map((r) => r.formatting[key]);
96
+ if (all.length === 0)
97
+ return null;
98
+ return all.every((v) => v === all[0]) ? all[0] : null;
42
99
  }
43
100
  apply(opts) {
44
101
  var _a, _b;
45
102
  const tracking = (_a = this.tracking) === null || _a === void 0 ? void 0 : _a.call(this);
46
- for (const h of this.holders()) {
103
+ for (const h of this.holders(true)) {
47
104
  (_b = h.rPr) !== null && _b !== void 0 ? _b : (h.rPr = { TYPE_NAME: 'org_docx4j_wml.RPr' });
48
105
  // the properties as they are now become w:rPrChange, unless this run is our own insertion
49
106
  if (tracking && !tracking.ownInsertions.has(h))
@@ -53,42 +110,68 @@ export class Font {
53
110
  tracking.tracker.settleRPrChange(h);
54
111
  }
55
112
  }
56
- get bold() { return this.read().bold; }
113
+ get bold() { return this.value('bold'); }
57
114
  set bold(v) { this.apply({ bold: v }); }
58
- get italic() { return this.read().italic; }
115
+ get italic() { return this.value('italic'); }
59
116
  set italic(v) { this.apply({ italic: v }); }
60
- get underline() { return this.read().underline; }
117
+ get underline() { var _a; return ((_a = this.value('underline')) !== null && _a !== void 0 ? _a : 'Mixed'); }
61
118
  set underline(v) { this.apply({ underline: v }); }
62
- get strikeThrough() { return this.read().strikeThrough; }
119
+ get strikeThrough() { return this.value('strikeThrough'); }
63
120
  set strikeThrough(v) { this.apply({ strikeThrough: v }); }
64
- get doubleStrikeThrough() { return this.read().doubleStrikeThrough; }
121
+ get doubleStrikeThrough() { return this.value('doubleStrikeThrough'); }
65
122
  set doubleStrikeThrough(v) { this.apply({ doubleStrikeThrough: v }); }
66
- get subscript() { return this.read().subscript; }
123
+ get subscript() { return this.value('subscript'); }
67
124
  set subscript(v) { this.apply({ subscript: v }); }
68
- get superscript() { return this.read().superscript; }
125
+ get superscript() { return this.value('superscript'); }
69
126
  set superscript(v) { this.apply({ superscript: v }); }
70
127
  /**
71
128
  * The document font formatting this run's Latin text: `w:rFonts/@w:ascii` of the effective
72
129
  * properties, the face `w:asciiTheme` names, else `w:hAnsi`, else the document default
73
- * (docx4j `RunFontSelector.asciiFontName`). '' only in a direct-formatting view with no
74
- * `w:ascii`, or where the package's `RunFontSelector` has not been built yet.
130
+ * (docx4j `RunFontSelector.asciiFontName`). '' where the runs differ, in a direct-formatting
131
+ * view with no `w:ascii`, or where the package's `RunFontSelector` has not been built yet.
75
132
  */
76
133
  get name() {
77
- if (this.asciiFontName !== undefined) {
78
- const resolved = this.asciiFontName(this.effectiveRPr());
79
- if (resolved !== undefined)
80
- return resolved;
81
- }
82
- return this.read().name;
134
+ const all = this.readings().map((r) => r.name);
135
+ return all.length > 0 && all.every((n) => n === all[0]) ? all[0] : '';
83
136
  }
84
137
  set name(v) { this.apply({ name: v }); }
85
- /** Size in points (w:sz is half-points); 0 only in a direct-formatting view with no w:sz. */
86
- get size() { return this.read().size; }
87
- set size(v) { this.apply({ size: v }); }
88
- /** '#RRGGBB', or the raw value ('auto', a theme colour name) when it is not a hex triple; '' when not set. */
89
- get color() { return this.read().color; }
138
+ /**
139
+ * Size in points (w:sz is half-points); 0 only in a direct-formatting view with no w:sz; `null` where the runs differ. A
140
+ * size written is held to the range Word 365 stores w:sz in, 0 to 32767.5 pt (CR-002 section 65): outside it, `InvalidArgument`.
141
+ */
142
+ get size() { return this.value('size'); }
143
+ set size(v) { withinWord('Font.size', v, WORD_STORAGE.sz); this.apply({ size: v }); }
144
+ /**
145
+ * '#RRGGBB': in the effective view the colour Word draws, so a theme colour (`w:themeColor`, with its tint or shade)
146
+ * through the document's theme, as Office JS reads it (check 53; CR-008 phase 2), and `#000000` for automatic; in
147
+ * the direct view `w:val` as written, '' when not set; the raw value where it is not a hex triple and no theme
148
+ * colour applies; '' where the runs differ.
149
+ */
150
+ get color() { var _a; return ((_a = this.value('color')) !== null && _a !== void 0 ? _a : ''); }
90
151
  set color(v) { this.apply({ color: v }); }
91
- /** '#RRGGBB' of the highlight, or null when there is none. */
92
- get highlightColor() { return this.read().highlightColor; }
152
+ /** '#RRGGBB' of the highlight, or null when there is none; '' where the runs differ. */
153
+ get highlightColor() {
154
+ const all = this.readings().map((r) => r.formatting.highlightColor);
155
+ if (all.length === 0)
156
+ return null;
157
+ return all.every((v) => v === all[0]) ? all[0] : '';
158
+ }
93
159
  set highlightColor(v) { this.apply({ highlightColor: v }); }
94
160
  }
161
+ /**
162
+ * The `Font` of a range across paragraphs (CR-014): each run read in its own paragraph, as `Font` reads them. A write
163
+ * goes to `write` (phase 2: every run and mark in the range, as Word formats them).
164
+ */
165
+ export class MixedFont extends Font {
166
+ constructor(reads, write) {
167
+ super(() => []);
168
+ this.reads = reads;
169
+ this.write = write;
170
+ }
171
+ readings() {
172
+ return this.reads();
173
+ }
174
+ apply(opts) {
175
+ this.write(opts);
176
+ }
177
+ }
@@ -71,6 +71,11 @@ export declare function addImagePart(source: Part, base64: string): NewImagePart
71
71
  * that shows it. docx4j: `BinaryPartAbstractImage.createImagePart` then `createImageInline`.
72
72
  */
73
73
  export declare function addImage(source: Part, base64: string, scope: object, maxCx: number | undefined, options?: InlinePictureOptions): NewPicture;
74
+ /**
75
+ * The run showing an image already related from the part as `relId`, an inline picture `cx` by `cy` EMU, its drawing id
76
+ * the next free one in `scope` and named `Picture <id>`, as `addImage` names one.
77
+ */
78
+ export declare function imageRunOf(relId: string, scope: object, cx: number, cy: number): Element<wml.R>;
74
79
  /** The writable width of a section in EMU (page width less the margins), for scaling. */
75
80
  export declare function writableWidthEmu(container: object): number | undefined;
76
81
  /** The `asvg:svgBlip` in a blip's `a:extLst`, if any: an SVG picture's SVG (CR-002 section 52). */
@@ -177,6 +182,12 @@ export declare class InlinePicture {
177
182
  /** The picture's run in a `w:del`, the picture split into a run of its own when the run held more. */
178
183
  private markDeleted;
179
184
  private pic;
185
+ /**
186
+ * Refuses a write to a picture in a paragraph in a branch of a kept block-, row- or cell-level
187
+ * `mc:AlternateContent` (CR-013 D4). A picture in a run-level element's branch is the run's own, and
188
+ * deleting it removes the element (CR-010 phase 3).
189
+ */
190
+ private assertWritable;
180
191
  private resize;
181
192
  }
182
193
  export { IMAGE_CONTENT_TYPES_BY_EXTENSION };
@@ -4,7 +4,7 @@ import { ContentTypes, IMAGE_CONTENT_TYPES_BY_EXTENSION } from '../../opc/Conten
4
4
  import { base64Decode, base64Encode, decodeXmlText } from '../../xml/dom.mjs';
5
5
  import { ImagePart } from '../../parts/BinaryPart.mjs';
6
6
  import { PartName } from '../../opc/PartName.mjs';
7
- import { find, runOf, linkParents, revisionKindOf, isElement, typeNameOf, isAlternateContent, selectedBranchOf } from './tree.mjs';
7
+ import { find, runOf, linkParents, revisionKindOf, isElement, typeNameOf, isAlternateContent, selectedBranchOf, assertOutsideBranch } from './tree.mjs';
8
8
  import { copyRPr } from './tracking.mjs';
9
9
  import { relationshipIdsIn, queueRelationshipRemovals } from './relationships.mjs';
10
10
  /** English Metric Units per inch, and per twip (docx4j UnitsOfMeasurement). */
@@ -229,6 +229,14 @@ function freeImageName(pkg, extension) {
229
229
  return name;
230
230
  }
231
231
  }
232
+ /**
233
+ * The run showing an image already related from the part as `relId`, an inline picture `cx` by `cy` EMU, its drawing id
234
+ * the next free one in `scope` and named `Picture <id>`, as `addImage` names one.
235
+ */
236
+ export function imageRunOf(relId, scope, cx, cy) {
237
+ const id = nextDrawingId(scope);
238
+ return runOf([inlinePicture(relId, { cx, cy, id, name: `Picture ${id}`, descr: '' })]);
239
+ }
232
240
  /** An id no other drawing in this part uses: wp:docPr and pic:cNvPr are the same type. */
233
241
  function nextDrawingId(scope) {
234
242
  let max = 0;
@@ -379,6 +387,7 @@ export class InlinePicture {
379
387
  return (_a = this.inline.docPr.descr) !== null && _a !== void 0 ? _a : '';
380
388
  }
381
389
  set altTextDescription(text) {
390
+ this.assertWritable();
382
391
  this.inline.docPr.descr = text;
383
392
  const p = this.pic();
384
393
  if (p)
@@ -390,6 +399,7 @@ export class InlinePicture {
390
399
  return (_a = this.inline.docPr.title) !== null && _a !== void 0 ? _a : '';
391
400
  }
392
401
  set altTextTitle(text) {
402
+ this.assertWritable();
393
403
  this.inline.docPr.title = text;
394
404
  }
395
405
  /**
@@ -466,6 +476,7 @@ export class InlinePicture {
466
476
  */
467
477
  delete() {
468
478
  var _a, _b;
479
+ this.assertWritable();
469
480
  const place = placeOf(this.paragraph.p, this.run);
470
481
  if (!place)
471
482
  return;
@@ -530,8 +541,17 @@ export class InlinePicture {
530
541
  const first = any === null || any === void 0 ? void 0 : any[0];
531
542
  return first && typeof first === 'object' && 'value' in first ? first.value : undefined;
532
543
  }
544
+ /**
545
+ * Refuses a write to a picture in a paragraph in a branch of a kept block-, row- or cell-level
546
+ * `mc:AlternateContent` (CR-013 D4). A picture in a run-level element's branch is the run's own, and
547
+ * deleting it removes the element (CR-010 phase 3).
548
+ */
549
+ assertWritable() {
550
+ assertOutsideBranch(this.paragraph.p, 'InlinePicture', 'this picture');
551
+ }
533
552
  resize(cx, cy) {
534
553
  var _a, _b;
554
+ this.assertWritable();
535
555
  const extent = this.inline.extent;
536
556
  const ratio = extent.cy / extent.cx;
537
557
  const w = cx !== null && cx !== void 0 ? cx : Math.max(1, Math.round(cy / ratio));
@@ -164,9 +164,12 @@ export declare class List {
164
164
  */
165
165
  setLevelBullet(level: number, listBullet: ListBullet, charCode?: number, fontName?: string): void;
166
166
  /**
167
- * Office JS `list.setLevelIndents(level, textIndent, bulletNumberPictureIndent)`, both in
168
- * points: the level's `w:ind/@w:left` is where the text sits and the label's position is the
169
- * hanging indent from it (or `w:firstLine` where the label sits to the right of the text).
167
+ * Office JS `list.setLevelIndents(level, textIndent, bulletNumberPictureIndent)`, both in points: the level's
168
+ * `w:ind/@w:left` is the text indent, and the label's indent is relative to it, "the same as paragraph first line
169
+ * indent": a first-line indent, or a hanging indent for a negative (check 71 case 86: Word wrote (-1, 0) as
170
+ * `w:left="-20" w:firstLine="0"`; until CR-002 section 65.5 it was taken as the label's absolute position).
171
+ * Each is held to the range Word stores it in (section 65); the text indent to Word's own setter's limit, short of
172
+ * 1584 pt either way (check 71b, section 65.9), the label's indent to its storage, unmeasured by Word's setter.
170
173
  */
171
174
  setLevelIndents(level: number, textIndent: number, bulletNumberPictureIndent: number): void;
172
175
  /** Office JS `list.setLevelAlignment(level, alignment)`: the level's `w:lvlJc`. */
@@ -7,6 +7,7 @@ import { NumberingState, storyKindOf } from '../listnumbering/state.mjs';
7
7
  import { LEVELS } from '../listnumbering/definitions.mjs';
8
8
  import { isElement, linkParents, selectedBranchOf, ALTERNATE_CONTENT } from './tree.mjs';
9
9
  import { Font } from './Font.mjs';
10
+ import { withinWord, WORD_STORAGE } from './wordRange.mjs';
10
11
  function packageOf(body) {
11
12
  const pkg = body.package_;
12
13
  return typeof (pkg === null || pkg === void 0 ? void 0 : pkg.getMainDocumentPart) === 'function' ? pkg : undefined;
@@ -164,6 +165,9 @@ function nullObject(className) {
164
165
  return () => ({ isNullObject: true });
165
166
  if (prop === 'then')
166
167
  return undefined;
168
+ // Office JS code loads a null object and syncs before reading isNullObject, as the shim's allows (CR-014 phase 1)
169
+ if (prop === 'load' || prop === 'track' || prop === 'untrack')
170
+ return () => proxy;
167
171
  return fail(prop);
168
172
  },
169
173
  set(_target, prop) {
@@ -347,24 +351,30 @@ export class List {
347
351
  this.written();
348
352
  }
349
353
  /**
350
- * Office JS `list.setLevelIndents(level, textIndent, bulletNumberPictureIndent)`, both in
351
- * points: the level's `w:ind/@w:left` is where the text sits and the label's position is the
352
- * hanging indent from it (or `w:firstLine` where the label sits to the right of the text).
354
+ * Office JS `list.setLevelIndents(level, textIndent, bulletNumberPictureIndent)`, both in points: the level's
355
+ * `w:ind/@w:left` is the text indent, and the label's indent is relative to it, "the same as paragraph first line
356
+ * indent": a first-line indent, or a hanging indent for a negative (check 71 case 86: Word wrote (-1, 0) as
357
+ * `w:left="-20" w:firstLine="0"`; until CR-002 section 65.5 it was taken as the label's absolute position).
358
+ * Each is held to the range Word stores it in (section 65); the text indent to Word's own setter's limit, short of
359
+ * 1584 pt either way (check 71b, section 65.9), the label's indent to its storage, unmeasured by Word's setter.
353
360
  */
354
361
  setLevelIndents(level, textIndent, bulletNumberPictureIndent) {
355
362
  var _a, _b;
363
+ // within the ranges Word 365 stores the level's w:ind in (CR-002 section 65), before anything changes
364
+ const left = withinWord('List.setLevelIndents (textIndent)', textIndent, WORD_STORAGE.lvlIndLeft);
365
+ const label = bulletNumberPictureIndent < 0
366
+ ? withinWord('List.setLevelIndents (a hanging bulletNumberPictureIndent)', -bulletNumberPictureIndent, WORD_STORAGE.indHanging)
367
+ : withinWord('List.setLevelIndents (bulletNumberPictureIndent)', bulletNumberPictureIndent, WORD_STORAGE.indFirstLine);
356
368
  const lvl = this.writableLvl(level);
357
369
  const pPr = ((_a = lvl.pPr) !== null && _a !== void 0 ? _a : (lvl.pPr = { TYPE_NAME: 'org_docx4j_wml.PPr' }));
358
370
  const ind = ((_b = pPr.ind) !== null && _b !== void 0 ? _b : (pPr.ind = f.createPPrBaseInd({})));
359
- const left = Math.round(textIndent * TWIPS_PER_POINT);
360
- const label = Math.round(bulletNumberPictureIndent * TWIPS_PER_POINT);
361
371
  ind.left = left;
362
- if (label <= left) {
363
- ind.hanging = left - label;
372
+ if (bulletNumberPictureIndent < 0) {
373
+ ind.hanging = label;
364
374
  delete ind.firstLine;
365
375
  }
366
376
  else {
367
- ind.firstLine = label - left;
377
+ ind.firstLine = label;
368
378
  delete ind.hanging;
369
379
  }
370
380
  linkParents(pPr, lvl);