@docx4j/core-ts 0.5.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 (155) hide show
  1. package/NOTICE +4 -0
  2. package/README.md +32 -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 +509 -141
  25. package/dist/model/content/Comment.d.mts +21 -3
  26. package/dist/model/content/Comment.mjs +195 -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 +11 -0
  32. package/dist/model/content/InlinePicture.mjs +21 -1
  33. package/dist/model/content/List.mjs +3 -0
  34. package/dist/model/content/Paragraph.d.mts +189 -13
  35. package/dist/model/content/Paragraph.mjs +870 -74
  36. package/dist/model/content/Range.d.mts +227 -12
  37. package/dist/model/content/Range.mjs +785 -59
  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 +172 -13
  43. package/dist/model/content/TrackedChange.mjs +728 -167
  44. package/dist/model/content/comments.d.mts +20 -6
  45. package/dist/model/content/comments.mjs +67 -57
  46. package/dist/model/content/generalException.d.mts +18 -0
  47. package/dist/model/content/generalException.mjs +24 -0
  48. package/dist/model/content/index.d.mts +8 -3
  49. package/dist/model/content/index.mjs +7 -2
  50. package/dist/model/content/mathText.d.mts +21 -0
  51. package/dist/model/content/mathText.mjs +267 -0
  52. package/dist/model/content/officeText.d.mts +27 -0
  53. package/dist/model/content/officeText.mjs +74 -0
  54. package/dist/model/content/outline.d.mts +5 -0
  55. package/dist/model/content/outline.mjs +13 -0
  56. package/dist/model/content/placeholders.d.mts +110 -0
  57. package/dist/model/content/placeholders.mjs +253 -0
  58. package/dist/model/content/search.d.mts +72 -0
  59. package/dist/model/content/search.mjs +204 -2
  60. package/dist/model/content/spanEdits.d.mts +159 -0
  61. package/dist/model/content/spanEdits.mjs +728 -0
  62. package/dist/model/content/story.d.mts +44 -0
  63. package/dist/model/content/story.mjs +92 -0
  64. package/dist/model/content/tableColumns.d.mts +1 -1
  65. package/dist/model/content/tableColumns.mjs +108 -80
  66. package/dist/model/content/tableRevisions.d.mts +11 -3
  67. package/dist/model/content/tableRevisions.mjs +72 -42
  68. package/dist/model/content/tableRules.d.mts +30 -0
  69. package/dist/model/content/tableRules.mjs +100 -0
  70. package/dist/model/content/textBoxes.d.mts +18 -0
  71. package/dist/model/content/textBoxes.mjs +105 -0
  72. package/dist/model/content/trackedChangeFilter.d.mts +39 -0
  73. package/dist/model/content/trackedChangeFilter.mjs +81 -0
  74. package/dist/model/content/tracking.d.mts +28 -0
  75. package/dist/model/content/tracking.mjs +149 -10
  76. package/dist/model/content/tree.d.mts +171 -22
  77. package/dist/model/content/tree.mjs +329 -53
  78. package/dist/model/customxml/CustomXmlPartCollection.d.mts +8 -0
  79. package/dist/model/customxml/CustomXmlPartCollection.mjs +34 -11
  80. package/dist/model/customxml/XmlMapping.d.mts +1 -1
  81. package/dist/model/customxml/XmlMapping.mjs +11 -0
  82. package/dist/model/customxml/bindings.d.mts +21 -2
  83. package/dist/model/customxml/bindings.mjs +76 -32
  84. package/dist/model/customxml/kinds.d.mts +8 -3
  85. package/dist/model/customxml/kinds.mjs +26 -5
  86. package/dist/model/customxml/picturePlaceholder.d.mts +17 -0
  87. package/dist/model/customxml/picturePlaceholder.mjs +32 -0
  88. package/dist/model/customxml/pictures.d.mts +4 -3
  89. package/dist/model/customxml/pictures.mjs +18 -6
  90. package/dist/model/customxml/xhtml.mjs +8 -2
  91. package/dist/model/index.d.mts +2 -0
  92. package/dist/model/index.mjs +4 -0
  93. package/dist/model/listnumbering/Emulator.d.mts +37 -5
  94. package/dist/model/listnumbering/Emulator.mjs +63 -9
  95. package/dist/model/properties/PropertyResolver.d.mts +60 -1
  96. package/dist/model/properties/PropertyResolver.mjs +115 -2
  97. package/dist/model/properties/catalogue.d.mts +19 -5
  98. package/dist/model/properties/catalogue.mjs +41 -15
  99. package/dist/model/properties/log.d.mts +1 -1
  100. package/dist/model/properties/log.mjs +5 -5
  101. package/dist/model/properties/table.mjs +4 -2
  102. package/dist/model/text/Extractor.d.mts +289 -0
  103. package/dist/model/text/Extractor.mjs +2162 -0
  104. package/dist/model/text/LinkTargets.d.mts +45 -0
  105. package/dist/model/text/LinkTargets.mjs +170 -0
  106. package/dist/model/text/MarkdownExporter.d.mts +140 -0
  107. package/dist/model/text/MarkdownExporter.mjs +255 -0
  108. package/dist/model/text/PlainText.d.mts +29 -0
  109. package/dist/model/text/PlainText.mjs +539 -0
  110. package/dist/model/text/TextContext.d.mts +161 -0
  111. package/dist/model/text/TextContext.mjs +425 -0
  112. package/dist/model/text/TextOptions.d.mts +150 -0
  113. package/dist/model/text/TextOptions.mjs +278 -0
  114. package/dist/model/text/TextResult.d.mts +504 -0
  115. package/dist/model/text/TextResult.mjs +526 -0
  116. package/dist/model/text/Texts.d.mts +99 -0
  117. package/dist/model/text/Texts.mjs +187 -0
  118. package/dist/model/text/WmlToMarkdown.d.mts +120 -0
  119. package/dist/model/text/WmlToMarkdown.mjs +911 -0
  120. package/dist/model/text/commonmark.d.mts +121 -0
  121. package/dist/model/text/commonmark.mjs +655 -0
  122. package/dist/model/text/index.d.mts +7 -0
  123. package/dist/model/text/index.mjs +8 -0
  124. package/dist/model/text/normalize.d.mts +8 -0
  125. package/dist/model/text/normalize.mjs +13 -0
  126. package/dist/model/text/outline.d.mts +4 -0
  127. package/dist/model/text/outline.mjs +71 -0
  128. package/dist/office-js/fragment.d.mts +7 -5
  129. package/dist/office-js/fragment.mjs +63 -14
  130. package/dist/office-js/proxy.d.mts +8 -0
  131. package/dist/office-js/proxy.mjs +29 -0
  132. package/dist/office-js/run.mjs +2 -0
  133. package/dist/office-js/supported.generated.mjs +16 -0
  134. package/dist/office-js/toApiScript.mjs +21 -5
  135. package/dist/opc/Save.d.mts +17 -0
  136. package/dist/opc/Save.mjs +12 -2
  137. package/dist/opc/index.d.mts +3 -3
  138. package/dist/opc/index.mjs +1 -1
  139. package/dist/opc/mce/preprocessor.d.mts +28 -3
  140. package/dist/opc/mce/preprocessor.mjs +4 -4
  141. package/dist/opc/mce/understood.d.mts +30 -6
  142. package/dist/opc/mce/understood.mjs +37 -7
  143. package/dist/packages/OpcPackage.d.mts +13 -0
  144. package/dist/packages/OpcPackage.mjs +1 -0
  145. package/dist/packages/WordprocessingMLPackage.d.mts +45 -8
  146. package/dist/packages/WordprocessingMLPackage.mjs +155 -20
  147. package/dist/parts/DefaultXmlPart.mjs +2 -2
  148. package/dist/parts/Part.d.mts +10 -2
  149. package/dist/parts/XmlPart.d.mts +12 -30
  150. package/dist/parts/XmlPart.mjs +44 -93
  151. package/dist/parts/wml/comments.mjs +30 -0
  152. package/dist/parts/wml/index.mjs +12 -0
  153. package/dist/xml/dom.d.mts +7 -0
  154. package/dist/xml/dom.mjs +18 -0
  155. package/package.json +2 -2
@@ -0,0 +1,526 @@
1
+ // The tree objects a block or run was read from: kept out of the block model's JSON (REQ-706 holds no
2
+ // tree objects; CR-012 section 4.4), so held here rather than as properties.
3
+ const blockSources = new WeakMap();
4
+ const blockJoins = new WeakMap();
5
+ const runSources = new WeakMap();
6
+ /**
7
+ * A run's revision in the `markup` view (WD REQ-706): `w:ins` and `w:moveTo` are insertions, `w:del`
8
+ * and `w:moveFrom` deletions, with their author and date as written. docx4j `TextRevision`.
9
+ */
10
+ export class TextRevision {
11
+ constructor(type, author,
12
+ /** The date as the package wrote it (`w:date`), or undefined. */
13
+ date) {
14
+ this.type = type;
15
+ this.author = author;
16
+ this.date = date;
17
+ }
18
+ equals(o) {
19
+ return o !== undefined && this.type === o.type && this.author === o.author && this.date === o.date;
20
+ }
21
+ toString() {
22
+ return this.type + (this.author === undefined ? '' : ` by ${this.author}`) + (this.date === undefined ? '' : ` ${this.date}`);
23
+ }
24
+ }
25
+ /**
26
+ * An image's description (WD REQ-514) and where it came from: the document's author, or a describer
27
+ * that generated it. Plain text writes it `[image: ...]` or `[image, generated: ...]` under
28
+ * `alt_text: true` (REQ-707). docx4j `ImageDescription`.
29
+ */
30
+ export class ImageDescription {
31
+ constructor(text, provenance) {
32
+ this.text = text;
33
+ this.provenance = provenance;
34
+ }
35
+ /** An author's description. */
36
+ static author(text) {
37
+ return new ImageDescription(text, 'AUTHOR');
38
+ }
39
+ /** A generated description. */
40
+ static generated(text) {
41
+ return new ImageDescription(text, 'GENERATED');
42
+ }
43
+ toString() {
44
+ return this.provenance === 'GENERATED' ? `generated: ${this.text}` : this.text;
45
+ }
46
+ }
47
+ /**
48
+ * A picture as the document gives it, for an `ImageDescriber` (WD REQ-514): its alt text
49
+ * (`wp:docPr/@descr`, or VML's `v:shape/@alt`), its name and title, whether it is marked decorative
50
+ * (`adec:decorative`), and its image part where the package holds one. The title is never read as text.
51
+ * docx4j `TextImage`.
52
+ */
53
+ export class TextImage {
54
+ constructor(
55
+ /**
56
+ * The alt text: `wp:docPr/@descr` (or a nested picture's `pic:cNvPr/@descr`), `''` where a DrawingML picture has
57
+ * none (the schema's default); VML `v:shape/@alt`.
58
+ */
59
+ descr,
60
+ /** `wp:docPr/@name` (`pic:cNvPr/@name`); undefined for a VML picture. */
61
+ name,
62
+ /** `wp:docPr/@title`, `''` where it has none (the schema's default); undefined for a VML picture. */
63
+ title,
64
+ /** True for a picture marked decorative (`adec:decorative val="1"` in `wp:docPr`'s extensions). */
65
+ decorative,
66
+ /** True for a VML picture (`v:shape` with `v:imagedata`). */
67
+ vml,
68
+ /**
69
+ * The image part (`a:blip/@r:embed`, else its `asvg:svgBlip`'s; `v:imagedata/@r:id`), or undefined
70
+ * for a linked or missing one.
71
+ */
72
+ part,
73
+ /** The tree object the picture is read from: a `wp:inline`, `wp:anchor`, `pic:pic` or `v:shape`. */
74
+ source) {
75
+ this.descr = descr;
76
+ this.name = name;
77
+ this.title = title;
78
+ this.decorative = decorative;
79
+ this.vml = vml;
80
+ this.part = part;
81
+ this.source = source;
82
+ }
83
+ toJSON() {
84
+ var _a;
85
+ return { descr: this.descr, name: this.name, title: this.title, decorative: this.decorative, vml: this.vml, part: (_a = this.part) === null || _a === void 0 ? void 0 : _a.partName.name };
86
+ }
87
+ }
88
+ /**
89
+ * The default `ImageDescriber` (WD REQ-514): the author's alt text, `wp:docPr/@descr`, else the
90
+ * picture's `@name`; for VML, `v:shape/@alt`; nothing for a picture marked decorative.
91
+ * docx4j `AltTextDescriber`.
92
+ */
93
+ export const AltTextDescriber = {
94
+ INSTANCE: ((image) => {
95
+ if (!image || image.decorative)
96
+ return undefined;
97
+ if (image.descr)
98
+ return ImageDescription.author(image.descr);
99
+ if (image.name)
100
+ return ImageDescription.author(image.name);
101
+ return undefined;
102
+ }),
103
+ };
104
+ /**
105
+ * A piece of a block's content (WD REQ-706): document text, or a typed item whose text, if any, the
106
+ * serialiser adds (a note reference is written `[n]` in plain text, REQ-707; it is a field of the run
107
+ * here, never text). docx4j `TextRun`.
108
+ *
109
+ * `source` and `officeOffset` are this package's (CR-012 section 4.4; WD REQ-202's emulated-API
110
+ * exemption): where the run's text was read from, and where it lies in its paragraph's `Paragraph.text`.
111
+ */
112
+ export class TextRun {
113
+ constructor(kind,
114
+ /** The text: the document's for `TEXT`, `FIELD_CODE` and `LIST_LABEL`; empty for the others. */
115
+ text,
116
+ /** The run's revision in the `markup` view; undefined in the other views and for an unrevised run. */
117
+ revision) {
118
+ this.kind = kind;
119
+ this.text = text;
120
+ this.revision = revision;
121
+ /** True for hidden text included under `hidden: true` (REQ-507). */
122
+ this.hidden = false;
123
+ /** True for a content control's placeholder text (REQ-508). */
124
+ this.placeholder = false;
125
+ /** For a note reference or mark: its number in reference order, from 1; 0 for a custom mark. */
126
+ this.noteNumber = 0;
127
+ /** For a page marker: the number of the page that begins there, from 2. */
128
+ this.pageNumber = 0;
129
+ /** Bold where its paragraph's style is not: the run's `w:b`, else its styles' (CR-046 phase 3). */
130
+ this.bold = false;
131
+ /** Italic where its paragraph's style is not. */
132
+ this.italic = false;
133
+ /** Struck through where its paragraph's style is not. */
134
+ this.strike = false;
135
+ /** In a monospaced font where its paragraph's style is not in one. */
136
+ this.monospace = false;
137
+ /** True for an equation (REQ-604). */
138
+ this.math = false;
139
+ /** True for a display equation (`m:oMathPara`). */
140
+ this.displayMath = false;
141
+ }
142
+ /** Where the run's text was read from (not in the JSON). */
143
+ get source() {
144
+ return runSources.get(this);
145
+ }
146
+ set source(value) {
147
+ if (value)
148
+ runSources.set(this, value);
149
+ else
150
+ runSources.delete(this);
151
+ }
152
+ /** Whether two runs' text can be one run: the same formatting, link and equation. */
153
+ sameFormat(o) {
154
+ return this.bold === o.bold && this.italic === o.italic && this.strike === o.strike && this.monospace === o.monospace
155
+ && this.link === o.link && this.math === o.math && this.displayMath === o.displayMath;
156
+ }
157
+ copyFormat(from) {
158
+ this.bold = from.bold;
159
+ this.italic = from.italic;
160
+ this.strike = from.strike;
161
+ this.monospace = from.monospace;
162
+ this.link = from.link;
163
+ this.math = from.math;
164
+ this.displayMath = from.displayMath;
165
+ }
166
+ toString() {
167
+ return this.kind + (this.text === '' ? '' : ` '${this.text}'`) + (this.revision ? ` [${this.revision.toString()}]` : '');
168
+ }
169
+ }
170
+ /**
171
+ * A field in a block (WD REQ-505): its instruction, and its cached result, undefined where it has none.
172
+ * docx4j `TextField`.
173
+ */
174
+ export class TextField {
175
+ constructor(
176
+ /** The instruction (`w:instrText`, `w:fldSimple/@instr`), as written. */
177
+ instr,
178
+ /** The cached result's text in the view; undefined for a field with none. */
179
+ result,
180
+ /** True when the result was computed under `fields: update` (REQ-506), rather than cached. */
181
+ updated = false) {
182
+ this.instr = instr;
183
+ this.result = result;
184
+ this.updated = updated;
185
+ }
186
+ toString() {
187
+ return `field{${this.instr}${this.updated ? ' => ' : ' -> '}${String(this.result)}}`;
188
+ }
189
+ }
190
+ /**
191
+ * A paragraph's numbering, as its effective `w:numPr` and the numbering definitions give it: what
192
+ * Markdown's list markers are made from (WD REQ-510, REQ-703). The label itself is the block's
193
+ * `listLabel`, under `list_labels: true`. docx4j `TextNumbering`.
194
+ */
195
+ export class TextNumbering {
196
+ constructor(
197
+ /** The `w:numId`. */
198
+ numId,
199
+ /** The level, `w:ilvl`: 0 to 8. */
200
+ level,
201
+ /** The level's `w:numFmt` value, or undefined where the definitions don't give one. */
202
+ format,
203
+ /** The level's `w:lvlText` value, or undefined. */
204
+ levelText,
205
+ /** The level's `w:start`: 1 where it has none. */
206
+ start) {
207
+ this.numId = numId;
208
+ this.level = level;
209
+ this.format = format;
210
+ this.levelText = levelText;
211
+ this.start = start;
212
+ }
213
+ /** True for a bullet level. */
214
+ get bullet() {
215
+ return this.format === 'bullet';
216
+ }
217
+ /** True for a level that is a label rather than a number: not a bullet, and its format `none` or its text with no `%n`. */
218
+ get label() {
219
+ if (this.bullet || (this.format === undefined && this.levelText === undefined))
220
+ return false;
221
+ return this.format === 'none' || this.levelText === undefined || !this.levelText.includes('%');
222
+ }
223
+ toString() {
224
+ return `${this.numId}/${this.level} ${String(this.format)} '${String(this.levelText)}' from ${this.start}${this.value === undefined ? '' : ` = ${this.value}`}`;
225
+ }
226
+ }
227
+ /**
228
+ * A table row of the block model: its cells, and whether it is a header row (`w:tblHeader`).
229
+ * docx4j `TextRow`.
230
+ */
231
+ export class TextRow {
232
+ constructor(address) {
233
+ this.address = address;
234
+ this.cells = [];
235
+ /** True for a row marked `w:tblHeader`. */
236
+ this.header = false;
237
+ }
238
+ }
239
+ /**
240
+ * A table cell of the block model: its blocks (paragraphs, and nested tables), how many grid columns it
241
+ * spans, and whether it is in a vertical merge. docx4j `TextCell`.
242
+ */
243
+ export class TextCell {
244
+ constructor(address) {
245
+ this.address = address;
246
+ this.blocks = [];
247
+ /** `w:gridSpan`, 1 by default. */
248
+ this.gridSpan = 1;
249
+ /** True for a cell continuing a vertical merge (`w:vMerge` without `restart`). */
250
+ this.mergeContinue = false;
251
+ /** True for a cell starting a vertical merge (`w:vMerge w:val="restart"`). */
252
+ this.mergeRestart = false;
253
+ }
254
+ }
255
+ /**
256
+ * A block of the block model (WD REQ-706): a paragraph, a table whose cells hold blocks, or a chart. A
257
+ * paragraph's text is its runs' in the view; what an extractor adds in plain text (note numbers, a
258
+ * table-format note, an image's bracket) is not in it, but carried as fields (REQ-707). docx4j `TextBlock`.
259
+ *
260
+ * Addresses are CR-002 section 3.3's ordinal form, on the unresolved document (REQ-405, REQ-518):
261
+ * `body/3`, `body/4/1/0/2` (a table's row 1, cell 0, block 2), `header:rId3/0`, `footnote:2/0`,
262
+ * `comment:5/0`, and what follows an anchoring paragraph is addressed from it, each kind counted apart
263
+ * (REQ-519): `body/3/textbox:0/1` (legacy WordArt too), `body/3/chart:0`, `body/3/smartart:0/1`,
264
+ * `body/3/object:0/...`, `body/7/altchunk:0/...`; the glossary's `glossary:0/1`. A paragraph joined to
265
+ * the next in the `accepted` view (a deleted mark) takes the first paragraph's address and `w14:paraId`.
266
+ */
267
+ export class TextBlock {
268
+ constructor(kind,
269
+ /** The story; not readonly, since an embedded package's or a chunk's content takes the story it is read into. */
270
+ story, address) {
271
+ this.kind = kind;
272
+ this.story = story;
273
+ this.address = address;
274
+ this.runs = [];
275
+ /** The fields whose result or instruction is in the block (REQ-505). */
276
+ this.fields = [];
277
+ /** A table's rows; empty for a paragraph. */
278
+ this.rows = [];
279
+ /** True for a hidden paragraph included under `hidden: true`: its runs and mark are hidden (REQ-507). */
280
+ this.hidden = false;
281
+ /** How many revisions (run-level revisions and paragraph marks) the block's paragraphs hold, in any view. */
282
+ this.revisions = 0;
283
+ /** True when every text run is in a monospaced font, and at least one is. */
284
+ this.monospace = false;
285
+ /** True when the paragraph has a bottom border of its own (`w:pBdr/w:bottom` in its `w:pPr`). */
286
+ this.bottomBorder = false;
287
+ /** For a note's block: the note's number in reference order; else 0. */
288
+ this.noteNumber = 0;
289
+ /** The section the block ends or is in (main story only). */
290
+ this.section = 0;
291
+ /** For a table: always written in REQ-605's simple form (an embedded workbook's sheet). */
292
+ this.simpleForm = false;
293
+ /** For a chart: its table's column headings. */
294
+ this.chartHeader = [];
295
+ /** For a chart: its table's rows. */
296
+ this.chartRows = [];
297
+ }
298
+ /**
299
+ * What the block was read from (CR-012 section 4.4; not in the JSON): a paragraph's `w:p` (a joined
300
+ * block's first, as its paraId is, REQ-405), a table's `w:tbl`, a bound control's `w:sdt`; undefined
301
+ * for a block the model makes (a chart, a WordArt line).
302
+ */
303
+ get source() {
304
+ return blockSources.get(this);
305
+ }
306
+ set source(value) {
307
+ if (value)
308
+ blockSources.set(this, value);
309
+ else
310
+ blockSources.delete(this);
311
+ }
312
+ /**
313
+ * For a paragraph the view joins to the paragraphs after it (a deleted mark in `accepted`, an inserted one
314
+ * in `original`), their addresses, in order; empty for any other block (CR-012 section 17.13; not in the JSON).
315
+ */
316
+ get joined() {
317
+ var _a;
318
+ return (_a = blockJoins.get(this)) !== null && _a !== void 0 ? _a : [];
319
+ }
320
+ set joined(value) {
321
+ if (value.length > 0)
322
+ blockJoins.set(this, value);
323
+ else
324
+ blockJoins.delete(this);
325
+ }
326
+ /** True when the block holds placeholder text (REQ-508). */
327
+ get placeholder() {
328
+ return this.runs.some((r) => r.placeholder);
329
+ }
330
+ /** True for a block in a text box (REQ-518). */
331
+ get textbox() {
332
+ return this.story === 'TEXT_BOX';
333
+ }
334
+ /** True for a paragraph whose only content is one or more pictures marked decorative (REQ-514). */
335
+ get decorative() {
336
+ let decorative = false;
337
+ for (const r of this.runs) {
338
+ if (r.kind === 'IMAGE') {
339
+ if (!r.image || !r.image.decorative)
340
+ return false;
341
+ decorative = true;
342
+ }
343
+ else if (r.kind === 'TEXT' && r.text !== '') {
344
+ return false;
345
+ }
346
+ }
347
+ return decorative;
348
+ }
349
+ /**
350
+ * The block's text in the view: its text runs (and field codes, where included); for a table, its
351
+ * rows a line apart, their cells a tab apart. No list label, note number or comment.
352
+ */
353
+ get text() {
354
+ var _a;
355
+ if (this.kind === 'CHART') {
356
+ let out = (_a = this.chartTitle) !== null && _a !== void 0 ? _a : '';
357
+ if (this.chartHeader.length > 0)
358
+ out += (out === '' ? '' : '\n') + this.chartHeader.join('\t');
359
+ for (const row of this.chartRows)
360
+ out += `\n${row.join('\t')}`;
361
+ return out;
362
+ }
363
+ if (this.kind === 'TABLE') {
364
+ return this.rows.map((row) => row.cells.map((cell) => cell.blocks.map((b) => b.text).join(' ')).join('\t')).join('\n');
365
+ }
366
+ let out = '';
367
+ for (const r of this.runs)
368
+ if (r.kind === 'TEXT' || r.kind === 'FIELD_CODE')
369
+ out += r.text;
370
+ return out;
371
+ }
372
+ /** The block model's JSON (REQ-706): the fields, the text and the flags; never a tree object. */
373
+ toJSON() {
374
+ const out = { ...this, text: this.text, placeholder: this.placeholder, textbox: this.textbox, decorative: this.decorative };
375
+ if (this.kind !== 'CHART') {
376
+ delete out.chartTitle;
377
+ delete out.chart;
378
+ delete out.chartHeader;
379
+ delete out.chartRows;
380
+ }
381
+ return out;
382
+ }
383
+ toString() {
384
+ return `${this.address} ${this.story} '${this.text}'`;
385
+ }
386
+ }
387
+ /**
388
+ * A comment (WD REQ-504): its author, date and blocks, the comment it replies to, and whether it is
389
+ * resolved (`w15:done`). Plain text renders a comment at its reference, replies after it. docx4j `TextComment`.
390
+ */
391
+ export class TextComment {
392
+ constructor(/** The comment's `w:id`. */ id) {
393
+ this.id = id;
394
+ /** True when the comment is resolved (`w15:done`). */
395
+ this.resolved = false;
396
+ this.blocks = [];
397
+ /** The replies, in the comments part's order. */
398
+ this.replies = [];
399
+ }
400
+ /** The comment's text: its blocks a line apart. */
401
+ get text() {
402
+ return this.blocks.map((b) => b.text).join('\n');
403
+ }
404
+ toJSON() {
405
+ return { id: this.id, author: this.author, initials: this.initials, date: this.date, parentId: this.parentId, resolved: this.resolved, blocks: this.blocks, replies: this.replies.map((r) => r.id) };
406
+ }
407
+ }
408
+ /**
409
+ * Where a result is not the whole document (WD section 8, REQ-801): a kind, the address it is at where
410
+ * there is one, and its selector: for `mce.branches_differ` the name of the branch selected, for
411
+ * `altchunk.not_expanded` the chunk's content type, for `content.not_read` and `image.not_described` the
412
+ * part's name. Never the document's text (REQ-802). docx4j `TextWarning`.
413
+ */
414
+ export class TextWarning {
415
+ constructor(kind,
416
+ /** The address of the block it is in (REQ-518's grammar), or undefined. */
417
+ address,
418
+ /** For `mce.branches_differ`, the selected branch (`mc:Choice Requires="wps"`, `mc:Fallback`). */
419
+ branch,
420
+ /** For `altchunk.not_expanded`, the chunk's content type as the package declares it. */
421
+ contentType,
422
+ /** For `content.not_read` and `image.not_described`, the part's name. */
423
+ partName) {
424
+ this.kind = kind;
425
+ this.address = address;
426
+ this.branch = branch;
427
+ this.contentType = contentType;
428
+ this.partName = partName;
429
+ }
430
+ /** The selector of REQ-801: the branch, the content type or the part's name, whichever the kind has. */
431
+ get selector() {
432
+ var _a, _b;
433
+ return (_b = (_a = this.branch) !== null && _a !== void 0 ? _a : this.contentType) !== null && _b !== void 0 ? _b : this.partName;
434
+ }
435
+ /** The identity a result keeps each warning once by. */
436
+ get key() {
437
+ return [this.kind, this.address, this.branch, this.contentType, this.partName].map((v) => v !== null && v !== void 0 ? v : '\u0000').join('\u0001');
438
+ }
439
+ toJSON() {
440
+ return { kind: this.kind, address: this.address, selector: this.selector };
441
+ }
442
+ toString() {
443
+ return this.kind + (this.address === undefined ? '' : ` at ${this.address}`) + (this.branch === undefined ? '' : ` (${this.branch})`)
444
+ + (this.contentType === undefined ? '' : ` (${this.contentType})`) + (this.partName === undefined ? '' : ` (${this.partName})`);
445
+ }
446
+ }
447
+ /** Both branches of an `mc:AlternateContent` hold text, and the texts differ (REQ-307). */
448
+ TextWarning.MCE_BRANCHES_DIFFER = 'mce.branches_differ';
449
+ /** A field with no cached result (REQ-505). */
450
+ TextWarning.FIELD_NO_RESULT = 'field.no_result';
451
+ /** A data-bound control whose surface differs from its bound value (REQ-509). */
452
+ TextWarning.SDT_BINDING_DIFFERS = 'sdt.binding_differs';
453
+ /** An `altChunk` not expanded (REQ-513). */
454
+ TextWarning.ALTCHUNK_NOT_EXPANDED = 'altchunk.not_expanded';
455
+ /** A chart, a SmartArt data part, or an embedded package or a part inside it, that can't be read. */
456
+ TextWarning.CONTENT_NOT_READ = 'content.not_read';
457
+ /** An image the `ImageDescriber` failed to describe (REQ-514). */
458
+ TextWarning.IMAGE_NOT_DESCRIBED = 'image.not_described';
459
+ /**
460
+ * A text in the block model (WD sections 7.4 and 8): the blocks in reading order, the comments, the
461
+ * warnings and the metadata. Plain text (`PlainText`) and the other serialisations are written from it
462
+ * (REQ-202). docx4j `TextResult`.
463
+ */
464
+ export class TextResult {
465
+ constructor(
466
+ /** The blocks in reading order (REQ-501, REQ-502, REQ-518, REQ-606). Comments are not among them. */
467
+ blocks,
468
+ /** The comments the view includes, by `w:id`, in the comments part's order (REQ-504). */
469
+ comments,
470
+ /** The warnings raised (REQ-801), never with the document's text (REQ-802). */
471
+ warnings,
472
+ /**
473
+ * The result's metadata (REQ-801, REQ-515), whatever the options: `fields_update_on_open`, and the
474
+ * document properties under `core`, `app` and `custom`, each a record, present when the package has
475
+ * that part. Property values are document text, in the text stream only under `metadata: true`.
476
+ */
477
+ metadata,
478
+ /** The options the result was made with. */
479
+ options) {
480
+ this.blocks = blocks;
481
+ this.comments = comments;
482
+ this.warnings = warnings;
483
+ this.metadata = metadata;
484
+ this.options = options;
485
+ }
486
+ /**
487
+ * Several results as one, in the order given (CR-012 section 4.4): the blocks one after another, the
488
+ * comments together, each warning once, the metadata and options the first's. What the editor
489
+ * assembles from its per-part calls under one `TextContext`.
490
+ */
491
+ static concat(...results) {
492
+ if (results.length === 0)
493
+ throw new RangeError('TextResult.concat needs a result');
494
+ const blocks = [];
495
+ const comments = new Map();
496
+ const warnings = [];
497
+ const seen = new Set();
498
+ const metadata = {};
499
+ for (const r of results) {
500
+ blocks.push(...r.blocks);
501
+ for (const [id, c] of r.comments)
502
+ if (!comments.has(id))
503
+ comments.set(id, c);
504
+ for (const w of r.warnings)
505
+ if (!seen.has(w.key)) {
506
+ seen.add(w.key);
507
+ warnings.push(w);
508
+ }
509
+ for (const [k, v] of Object.entries(r.metadata))
510
+ if (!(k in metadata))
511
+ metadata[k] = v;
512
+ }
513
+ return new TextResult(blocks, comments, warnings, metadata, results[0].options);
514
+ }
515
+ toJSON() {
516
+ return { blocks: this.blocks, comments: Object.fromEntries(this.comments), warnings: this.warnings, metadata: this.metadata, options: this.options };
517
+ }
518
+ }
519
+ /** The metadata's key for the settings' `w:updateFields` (REQ-506, REQ-801): a boolean. */
520
+ TextResult.FIELDS_UPDATE_ON_OPEN = 'fields_update_on_open';
521
+ /** The metadata's key for the core properties (REQ-515): each property's element name to its value. */
522
+ TextResult.CORE = 'core';
523
+ /** The metadata's key for the application properties (REQ-515), the statistics left out. */
524
+ TextResult.APP = 'app';
525
+ /** The metadata's key for the custom properties (REQ-515): each property's name to its typed value. */
526
+ TextResult.CUSTOM = 'custom';
@@ -0,0 +1,99 @@
1
+ import { Part } from '../../parts/Part.mjs';
2
+ import { TextOptions, type TextOptionsInit } from './TextOptions.mjs';
3
+ import { TextResult } from './TextResult.mjs';
4
+ import { TextContext, type TextPackage } from './TextContext.mjs';
5
+ type Options = TextOptionsInit | TextOptions | undefined;
6
+ declare function optionsOf(options: Options): TextOptions;
7
+ declare function isPackage(value: unknown): value is TextPackage;
8
+ /**
9
+ * docx4j's text model (its CR-046; the portfolio's *WordprocessingML Text Extraction*, WD): a text is
10
+ * `serialize(scope(view(resolve(package))))` (WD REQ-201). `Texts.of` makes the block model
11
+ * (`TextResult`); `PlainText.of` writes plain text from it.
12
+ *
13
+ * ```ts
14
+ * const result = await Texts.of(pkg, { view: 'markup', include: ['headers', 'footers'], hidden: true });
15
+ * PlainText.of(result);
16
+ * result.warnings;
17
+ * ```
18
+ *
19
+ * - **resolve**: each `mc:AlternateContent` is read from the branch the content API reads
20
+ * (`selectedBranchOf`, CR-010), so that the text model and `Paragraph.text` take the same branch.
21
+ * - **view**: `accepted` (the default), `original` or `markup`; the first two are the text of the document
22
+ * `acceptAllRevisions` or `rejectAllRevisions` leaves, worked out without resolving anything
23
+ * (`ResolvedView`), held equal to that copy route by the agreement test (REQ-406).
24
+ * - **scope**: the main story, each text box once after its anchoring paragraph (after the table for one in
25
+ * a cell), then the footnotes and endnotes in reference order; headers, footers and comments where
26
+ * included, and the glossary, last, under `include: glossary`; hidden text excluded; placeholders
27
+ * included; a bound control's value from its custom XML part; images' descriptions by an
28
+ * `ImageDescriber`; the document properties in the metadata.
29
+ *
30
+ * **Not yet** (CR-012 section 5): `fields: update` and `embedded: true` are refused (REQ-1001); an equation
31
+ * is its text inside `$...$`, not LaTeX (phase 5b); a chart or SmartArt contributes nothing (5c); an
32
+ * `altChunk` is not expanded and raises `altchunk.not_expanded` (5e).
33
+ *
34
+ * **The package is never changed** (REQ-204): every part is read with `readContents()`, the live tree where
35
+ * the part is unmarshalled and a private one where it is not, so a save afterwards is byte for byte where it
36
+ * was before.
37
+ *
38
+ * **Cost.** Each call reads every story and, in the `accepted` and `original` views, their tracked changes
39
+ * once, whether it reads the whole package or one paragraph of it. A `TextContext` (`contextOf`) holds what
40
+ * was read, so calls under one context read it once.
41
+ *
42
+ * **Not Office JS's text.** `Paragraph.text` and the other Office JS readers keep Office JS's text (CR-012
43
+ * D2, REQ-202's emulated-API exemption); each `TextRun` records where its text lies in its paragraph's
44
+ * `Paragraph.text` (`officeOffset`), so that the two map onto each other.
45
+ */
46
+ export declare class Texts {
47
+ private constructor();
48
+ /** The text of a package (REQ-501's scope), or of one story part, or of content in a package. */
49
+ static of(pkg: TextPackage, options?: Options, context?: TextContext): Promise<TextResult>;
50
+ /**
51
+ * The text of one story part, as its own story: the main document part (its story and text boxes; the
52
+ * notes it references numbered in the context, not read), a header or a footer (addressed
53
+ * `header:rId3/...`), the footnotes or endnotes part (the notes the context's stories referenced, in
54
+ * reference order; under a context that has not read the main story, the main story is read first, for
55
+ * the order alone), or the comments part (the comments the view includes, in `TextResult.comments`).
56
+ * The part must belong to a package. Read them in REQ-501's order under one context and
57
+ * `TextResult.concat` the results to have the package's text.
58
+ */
59
+ static of(part: Part, options?: Options, context?: TextContext): Promise<TextResult>;
60
+ /**
61
+ * The text of content in a package (a paragraph, a table, a body, a header's content), as the main story:
62
+ * the view is the package's, so a join or a move is resolved as in the whole document. Its addresses
63
+ * start `content`. The content is the package's own tree, its part unmarshalled (`getContents()`): a part
64
+ * that is not is read privately, afresh for each context, and the views' plan is made over that reading.
65
+ */
66
+ static of(pkg: TextPackage, content: object, options?: Options, context?: TextContext): Promise<TextResult>;
67
+ /**
68
+ * The text of content with no package: in the `accepted` and `original` views only run-level revisions
69
+ * are resolved (no paragraph is joined, a move is its two halves), and hidden text is only what the runs
70
+ * themselves hide, since there are no styles.
71
+ */
72
+ static of(content: object, options?: Options): Promise<TextResult>;
73
+ private static ofContent;
74
+ private static ofPart;
75
+ /**
76
+ * The text of a package that `acceptAllRevisions` or `rejectAllRevisions` has already resolved, read with
77
+ * no view logic: the copy route of WD REQ-406, which the views of `Texts.of` are held equal to. The
78
+ * options' view says which resolution it was (`accepted` or `original`).
79
+ */
80
+ static ofResolved(resolved: TextPackage, options?: Options): Promise<TextResult>;
81
+ /** Plain text of a package (WD section 7.1): `PlainText.of(await Texts.of(pkg, options))`. */
82
+ static plainText(pkg: TextPackage, options?: Options): Promise<string>;
83
+ /**
84
+ * A context for calls over one package (CR-012 section 4.4): it reads the package's stories once, makes
85
+ * each view's plan once, and carries the note numbers, numbering states and bookmarks from one call to the
86
+ * next. A snapshot: after the package changes, make another.
87
+ */
88
+ static contextOf(pkg: TextPackage): Promise<TextContext>;
89
+ /** WD REQ-1201's normalisation, under which texts are compared. */
90
+ static normalize(value: string | undefined | null): string;
91
+ private static context;
92
+ }
93
+ /**
94
+ * The context a call reads under: the one given, checked against the package and the view, or a new one
95
+ * (internal: `Texts` and the outline reader share it).
96
+ */
97
+ export declare function contextFor(pkg: TextPackage, given: TextContext | undefined, o: TextOptions): Promise<TextContext>;
98
+ /** Options checked as `Texts.of` checks them (internal). */
99
+ export { optionsOf, isPackage };