@docx4j/core-ts 0.1.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 (92) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +12 -0
  3. package/README.md +126 -0
  4. package/dist/index.d.mts +7 -0
  5. package/dist/index.mjs +10 -0
  6. package/dist/model/content/Body.d.mts +107 -0
  7. package/dist/model/content/Body.mjs +363 -0
  8. package/dist/model/content/Font.d.mts +46 -0
  9. package/dist/model/content/Font.mjs +50 -0
  10. package/dist/model/content/Paragraph.d.mts +99 -0
  11. package/dist/model/content/Paragraph.mjs +364 -0
  12. package/dist/model/content/Range.d.mts +34 -0
  13. package/dist/model/content/Range.mjs +94 -0
  14. package/dist/model/content/index.d.mts +7 -0
  15. package/dist/model/content/index.mjs +9 -0
  16. package/dist/model/content/search.d.mts +12 -0
  17. package/dist/model/content/search.mjs +68 -0
  18. package/dist/model/content/tree.d.mts +40 -0
  19. package/dist/model/content/tree.mjs +120 -0
  20. package/dist/model/index.d.mts +1 -0
  21. package/dist/model/index.mjs +2 -0
  22. package/dist/opc/ContentTypeManager.d.mts +37 -0
  23. package/dist/opc/ContentTypeManager.mjs +126 -0
  24. package/dist/opc/ContentTypes.d.mts +118 -0
  25. package/dist/opc/ContentTypes.mjs +139 -0
  26. package/dist/opc/FlatOpcPartStore.d.mts +42 -0
  27. package/dist/opc/FlatOpcPartStore.mjs +151 -0
  28. package/dist/opc/Load.d.mts +18 -0
  29. package/dist/opc/Load.mjs +123 -0
  30. package/dist/opc/PartName.d.mts +46 -0
  31. package/dist/opc/PartName.mjs +132 -0
  32. package/dist/opc/PartStore.d.mts +45 -0
  33. package/dist/opc/PartStore.mjs +54 -0
  34. package/dist/opc/Save.d.mts +9 -0
  35. package/dist/opc/Save.mjs +52 -0
  36. package/dist/opc/ZipPartStore.d.mts +32 -0
  37. package/dist/opc/ZipPartStore.mjs +117 -0
  38. package/dist/opc/exceptions.d.mts +17 -0
  39. package/dist/opc/exceptions.mjs +22 -0
  40. package/dist/opc/index.d.mts +12 -0
  41. package/dist/opc/index.mjs +13 -0
  42. package/dist/opc/mce/preprocessor.d.mts +15 -0
  43. package/dist/opc/mce/preprocessor.mjs +74 -0
  44. package/dist/opc/mce/understood.d.mts +1 -0
  45. package/dist/opc/mce/understood.mjs +98 -0
  46. package/dist/packages/OpcPackage.d.mts +62 -0
  47. package/dist/packages/OpcPackage.mjs +133 -0
  48. package/dist/packages/PresentationMLPackage.d.mts +12 -0
  49. package/dist/packages/PresentationMLPackage.mjs +39 -0
  50. package/dist/packages/SpreadsheetMLPackage.d.mts +12 -0
  51. package/dist/packages/SpreadsheetMLPackage.mjs +38 -0
  52. package/dist/packages/WordprocessingMLPackage.d.mts +49 -0
  53. package/dist/packages/WordprocessingMLPackage.mjs +130 -0
  54. package/dist/packages/index.d.mts +5 -0
  55. package/dist/packages/index.mjs +6 -0
  56. package/dist/packages/registry.d.mts +7 -0
  57. package/dist/packages/registry.mjs +18 -0
  58. package/dist/parts/BinaryPart.d.mts +38 -0
  59. package/dist/parts/BinaryPart.mjs +72 -0
  60. package/dist/parts/DefaultXmlPart.d.mts +29 -0
  61. package/dist/parts/DefaultXmlPart.mjs +63 -0
  62. package/dist/parts/Namespaces.d.mts +99 -0
  63. package/dist/parts/Namespaces.mjs +99 -0
  64. package/dist/parts/Part.d.mts +50 -0
  65. package/dist/parts/Part.mjs +68 -0
  66. package/dist/parts/PartRegistry.d.mts +20 -0
  67. package/dist/parts/PartRegistry.mjs +142 -0
  68. package/dist/parts/Parts.d.mts +13 -0
  69. package/dist/parts/Parts.mjs +28 -0
  70. package/dist/parts/RelationshipsPart.d.mts +66 -0
  71. package/dist/parts/RelationshipsPart.mjs +224 -0
  72. package/dist/parts/XmlPart.d.mts +46 -0
  73. package/dist/parts/XmlPart.mjs +87 -0
  74. package/dist/parts/customXml/index.d.mts +9 -0
  75. package/dist/parts/customXml/index.mjs +11 -0
  76. package/dist/parts/dml/index.d.mts +54 -0
  77. package/dist/parts/dml/index.mjs +83 -0
  78. package/dist/parts/docProps/index.d.mts +14 -0
  79. package/dist/parts/docProps/index.mjs +18 -0
  80. package/dist/parts/index.d.mts +14 -0
  81. package/dist/parts/index.mjs +15 -0
  82. package/dist/parts/pml/index.d.mts +53 -0
  83. package/dist/parts/pml/index.mjs +90 -0
  84. package/dist/parts/sml/index.d.mts +61 -0
  85. package/dist/parts/sml/index.mjs +107 -0
  86. package/dist/parts/wml/defaultStyles.d.mts +1 -0
  87. package/dist/parts/wml/defaultStyles.mjs +500 -0
  88. package/dist/parts/wml/index.d.mts +102 -0
  89. package/dist/parts/wml/index.mjs +213 -0
  90. package/dist/xml/dom.d.mts +22 -0
  91. package/dist/xml/dom.mjs +92 -0
  92. package/package.json +75 -0
@@ -0,0 +1,363 @@
1
+ import { Docx4JException } from '../../opc/exceptions.mjs';
2
+ import { typeNameOf, childrenOf, linkParents, BLOCK_LEVEL_TYPES, textOf } from './tree.mjs';
3
+ import { wml as parseFragment, r as textRun, br as breakItem } from '@docx4j/generated-objects-ts/builders/wml';
4
+ import { runOf, paragraphOf } from './tree.mjs';
5
+ import { Paragraph } from './Paragraph.mjs';
6
+ /**
7
+ * A subset of Office JS `Word.Body` over any container with block-level content: the main
8
+ * document's body, a header, a footer, a footnote, a cell or a content control. A view: the
9
+ * tree is the state; `content` is the live array.
10
+ */
11
+ export class Body {
12
+ constructor(
13
+ /** The part whose tree this is; marks it for re-marshalling by being unmarshalled. */
14
+ part,
15
+ /** The container value: a Body, Hdr, Ftr, Tc, SdtContentBlock, ... */
16
+ container,
17
+ /** The address prefix: 'body', 'header:rId3', 'footer:rId4', 'footnote:2'. */
18
+ prefix = 'body', package_) {
19
+ this.part = part;
20
+ this.container = container;
21
+ this.prefix = prefix;
22
+ this.package_ = package_;
23
+ }
24
+ /** The live content array (docx4j getContent()); block-level elements only, sectPr excluded. */
25
+ get content() {
26
+ var _a;
27
+ var _b;
28
+ return ((_a = (_b = this.container).content) !== null && _a !== void 0 ? _a : (_b.content = []));
29
+ }
30
+ /** Every paragraph in document order, descending into tables and content controls. */
31
+ get paragraphs() {
32
+ const out = [];
33
+ const visit = (items) => {
34
+ var _a, _b, _c;
35
+ for (const el of items) {
36
+ const tn = typeNameOf(el);
37
+ if (tn === 'org_docx4j_wml.P')
38
+ out.push(new Paragraph(el, items, this));
39
+ else {
40
+ const v = el.value;
41
+ if (typeof v !== 'object' || v === null)
42
+ continue;
43
+ if (tn === 'org_docx4j_wml.Tbl') {
44
+ for (const row of (_a = childrenOf(v)) !== null && _a !== void 0 ? _a : [])
45
+ for (const cell of (_b = childrenOf(row.value)) !== null && _b !== void 0 ? _b : [])
46
+ visit((_c = childrenOf(cell.value)) !== null && _c !== void 0 ? _c : []);
47
+ }
48
+ else {
49
+ const children = childrenOf(v);
50
+ if (children)
51
+ visit(children);
52
+ }
53
+ }
54
+ }
55
+ };
56
+ visit(this.content);
57
+ return out;
58
+ }
59
+ /** The tables directly in this body (as elements; `Table` views are CR-002 Phase C). */
60
+ get tables() {
61
+ return this.content.filter((el) => typeNameOf(el) === 'org_docx4j_wml.Tbl').map((element) => ({ element, container: this.content }));
62
+ }
63
+ /** The text, a paragraph per line. */
64
+ get text() {
65
+ return this.paragraphs.map((p) => p.text).join('\n');
66
+ }
67
+ insertParagraph(text, location) {
68
+ const el = paragraphOf(text === '' ? [] : [textRun(text)]);
69
+ return this.insertElement(el, location);
70
+ }
71
+ /** Text at the start of the first paragraph, the end of the last, or replacing everything with one paragraph. */
72
+ insertText(text, location) {
73
+ const paragraphs = this.paragraphs;
74
+ if (location === 'Replace' || paragraphs.length === 0) {
75
+ this.clear();
76
+ const p = this.insertParagraph(text, 'End');
77
+ return p.getRange('Content');
78
+ }
79
+ if (location === 'Start')
80
+ return paragraphs[0].insertText(text, 'Start');
81
+ return paragraphs[paragraphs.length - 1].insertText(text, 'End');
82
+ }
83
+ insertBreak(type, location) {
84
+ const p = this.insertParagraph('', location);
85
+ p.p.content.push(runOf([breakItem(type === 'Page' ? 'page' : undefined)]));
86
+ linkParents(p.p.content, p.p);
87
+ }
88
+ /**
89
+ * Inserts block-level elements (docx4j addObject): at the start or end of this body, or
90
+ * before or after a target paragraph, element or address. Links PARENT. Rejects anything the
91
+ * body cannot hold, naming what was passed. Returns the view of the first inserted element.
92
+ */
93
+ insertElement(element, location, target) {
94
+ const elements = Array.isArray(element) ? element : [element];
95
+ if (elements.length === 0)
96
+ throw new Docx4JException('Nothing to insert');
97
+ for (const el of elements) {
98
+ const tn = typeNameOf(el);
99
+ if (tn === undefined || !BLOCK_LEVEL_TYPES.has(tn)) {
100
+ throw new Docx4JException(`A body cannot hold ${describe(el)}; block-level elements only (w:p, w:tbl, w:sdt, ...)`);
101
+ }
102
+ }
103
+ let container = this.content;
104
+ let index;
105
+ if (location === 'Start')
106
+ index = 0;
107
+ else if (location === 'End')
108
+ index = container.length;
109
+ else {
110
+ const t = this.resolveTarget(target);
111
+ container = t.container;
112
+ index = container.indexOf(t.element) + (location === 'After' ? 1 : 0);
113
+ }
114
+ container.splice(index, 0, ...elements);
115
+ const owner = this.ownerOf(container);
116
+ for (const el of elements) {
117
+ linkParents(el, owner);
118
+ if (typeNameOf(el) === 'org_docx4j_wml.P')
119
+ this.assignParaId(el.value);
120
+ }
121
+ const first = elements[0];
122
+ return typeNameOf(first) === 'org_docx4j_wml.P' ? new Paragraph(first, container, this) : { element: first, container };
123
+ }
124
+ /** Inserts a WML fragment (one or more w:p / w:tbl / ... as inside document.xml); the standard prefixes are declared for it. */
125
+ async insertXml(xml, location, target) {
126
+ var _a;
127
+ const preprocess = (_a = this.package_) === null || _a === void 0 ? void 0 : _a.loadOptions.preprocessor;
128
+ const elements = await parseFragment(xml, { wrapper: 'body', preprocess: preprocess ? (doc) => preprocess(doc) : undefined });
129
+ if (elements.length === 0)
130
+ return [];
131
+ this.insertElement(elements, location, target);
132
+ return elements.map((el) => typeNameOf(el) === 'org_docx4j_wml.P'
133
+ ? new Paragraph(el, this.containerOf(el), this)
134
+ : { element: el, container: this.containerOf(el) });
135
+ }
136
+ /** Matches over every paragraph, in document order. */
137
+ search(text, options) {
138
+ return this.paragraphs.flatMap((p) => p.search(text, options));
139
+ }
140
+ /** Removes everything (section properties stay). */
141
+ clear() {
142
+ this.content.length = 0;
143
+ }
144
+ /** The part's XML (extension; Office JS getOoxml wraps it in a package). */
145
+ async getXml() {
146
+ if (!this.part)
147
+ throw new Docx4JException('This body has no part');
148
+ return this.part.getXml();
149
+ }
150
+ // --- addresses (CR-002 section 3.3) ---
151
+ /** The element at an address: 'body/3' (fourth block), 'body/3/1/0/2' (table row 1, cell 0, block 2), a paraId, or a text match. */
152
+ elementAt(address) {
153
+ if (typeof address === 'string' && address.startsWith('w14:'))
154
+ address = { paraId: address.substring(4) };
155
+ if (typeof address === 'object') {
156
+ const p = 'paraId' in address
157
+ ? this.paragraphs.find((q) => { var _a; return ((_a = q.paraId) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === address.paraId.toLowerCase(); })
158
+ : this.paragraphs.find((q) => q.text.includes(address.contains));
159
+ return p ? { element: p.element, container: p.container } : undefined;
160
+ }
161
+ const parts = address.split('/');
162
+ const prefix = parts[0];
163
+ if (prefix !== this.prefix && !(prefix === 'body' && this.prefix === 'body'))
164
+ return undefined;
165
+ let current = this.container;
166
+ let container;
167
+ let element;
168
+ for (const seg of parts.slice(1)) {
169
+ container = childrenOf(current);
170
+ const i = Number(seg);
171
+ if (!container || !Number.isInteger(i) || i < 0 || i >= container.length)
172
+ return undefined;
173
+ element = container[i];
174
+ current = element.value;
175
+ }
176
+ return element && container ? { element, container } : undefined;
177
+ }
178
+ paragraphAt(address) {
179
+ const found = this.elementAt(address);
180
+ if (!found || typeNameOf(found.element) !== 'org_docx4j_wml.P')
181
+ return undefined;
182
+ return new Paragraph(found.element, found.container, this);
183
+ }
184
+ /** The ordinal address of a paragraph or element in this body, from PARENT links; undefined when it is not here. */
185
+ addressOf(target) {
186
+ const path = this.pathOf(target.element.value);
187
+ return path ? [this.prefix, ...path].join('/') : undefined;
188
+ }
189
+ /** What an agent asks for first: every paragraph and table with its address, style and text. */
190
+ outline() {
191
+ const paragraphs = [];
192
+ const tables = [];
193
+ const visit = (items, path) => {
194
+ items.forEach((el, i) => {
195
+ var _a, _b, _c, _d, _e;
196
+ const tn = typeNameOf(el);
197
+ const here = [...path, i];
198
+ const address = [this.prefix, ...here].join('/');
199
+ if (tn === 'org_docx4j_wml.P') {
200
+ const p = el.value;
201
+ const entry = { address, style: (_c = (_b = (_a = p.pPr) === null || _a === void 0 ? void 0 : _a.pStyle) === null || _b === void 0 ? void 0 : _b.val) !== null && _c !== void 0 ? _c : 'Normal', text: textOf(p) };
202
+ if (p.paraId)
203
+ entry.paraId = p.paraId;
204
+ paragraphs.push(entry);
205
+ }
206
+ else if (tn === 'org_docx4j_wml.Tbl') {
207
+ const rows = (_d = childrenOf(el.value)) !== null && _d !== void 0 ? _d : [];
208
+ const cols = rows.length ? ((_e = childrenOf(rows[0].value)) !== null && _e !== void 0 ? _e : []).filter((c) => typeNameOf(c) === 'org_docx4j_wml.Tc').length : 0;
209
+ tables.push({ address, rows: rows.filter((r) => typeNameOf(r) === 'org_docx4j_wml.Tr').length, cols });
210
+ rows.forEach((row, ri) => { var _a; return ((_a = childrenOf(row.value)) !== null && _a !== void 0 ? _a : []).forEach((cell, ci) => { var _a; return visit((_a = childrenOf(cell.value)) !== null && _a !== void 0 ? _a : [], [...here, ri, ci]); }); });
211
+ }
212
+ else if (typeof el.value === 'object' && el.value !== null) {
213
+ const children = childrenOf(el.value);
214
+ if (children)
215
+ visit(children, here);
216
+ }
217
+ });
218
+ };
219
+ visit(this.content, []);
220
+ return { paragraphs, tables };
221
+ }
222
+ // --- docx4j names ---
223
+ /** docx4j MainDocumentPart.addParagraphOfText. */
224
+ addParagraphOfText(text) {
225
+ return this.insertParagraph(text, 'End').p;
226
+ }
227
+ /** docx4j MainDocumentPart.addStyledParagraphOfText. */
228
+ addStyledParagraphOfText(styleId, text) {
229
+ const p = this.insertParagraph(text, 'End');
230
+ p.style = styleId;
231
+ return p.p;
232
+ }
233
+ /** docx4j addObject: appends a block-level element. */
234
+ addObject(element) {
235
+ this.insertElement(element, 'End');
236
+ }
237
+ /** docx4j getContent(). */
238
+ getContent() {
239
+ return this.content;
240
+ }
241
+ // --- internals ---
242
+ resolveTarget(target) {
243
+ if (target === undefined)
244
+ throw new Docx4JException("'Before' and 'After' need a target");
245
+ if (target instanceof Paragraph)
246
+ return { element: target.element, container: target.container };
247
+ if (typeof target === 'object' && 'element' in target)
248
+ return target;
249
+ const found = this.elementAt(target);
250
+ if (!found)
251
+ throw new Docx4JException(`No element at ${typeof target === 'string' ? target : JSON.stringify(target)}`);
252
+ return found;
253
+ }
254
+ /** The typed object whose content array this is, for PARENT links. */
255
+ ownerOf(container) {
256
+ if (container === this.container.content)
257
+ return this.container;
258
+ let owner = this.container;
259
+ const seek = (value) => {
260
+ var _a, _b;
261
+ const children = childrenOf(value);
262
+ if (!children)
263
+ return false;
264
+ if (children === container) {
265
+ owner = value;
266
+ return true;
267
+ }
268
+ for (const el of children) {
269
+ const v = el.value;
270
+ if (typeof v !== 'object' || v === null)
271
+ continue;
272
+ if (typeNameOf(el) === 'org_docx4j_wml.Tbl') {
273
+ for (const row of (_a = childrenOf(v)) !== null && _a !== void 0 ? _a : [])
274
+ for (const cell of (_b = childrenOf(row.value)) !== null && _b !== void 0 ? _b : [])
275
+ if (seek(cell.value))
276
+ return true;
277
+ }
278
+ else if (seek(v))
279
+ return true;
280
+ }
281
+ return false;
282
+ };
283
+ seek(this.container);
284
+ // SdtBlock: the content array belongs to its sdtContent
285
+ const o = owner;
286
+ return o.TYPE_NAME === 'org_docx4j_wml.SdtBlock' && o.sdtContent ? o.sdtContent : owner;
287
+ }
288
+ containerOf(element) {
289
+ let found = this.content;
290
+ const seek = (value) => {
291
+ var _a, _b;
292
+ const children = childrenOf(value);
293
+ if (!children)
294
+ return false;
295
+ if (children.includes(element)) {
296
+ found = children;
297
+ return true;
298
+ }
299
+ for (const el of children) {
300
+ const v = el.value;
301
+ if (typeof v !== 'object' || v === null)
302
+ continue;
303
+ if (typeNameOf(el) === 'org_docx4j_wml.Tbl') {
304
+ for (const row of (_a = childrenOf(v)) !== null && _a !== void 0 ? _a : [])
305
+ for (const cell of (_b = childrenOf(row.value)) !== null && _b !== void 0 ? _b : [])
306
+ if (seek(cell.value))
307
+ return true;
308
+ }
309
+ else if (seek(v))
310
+ return true;
311
+ }
312
+ return false;
313
+ };
314
+ seek(this.container);
315
+ return found;
316
+ }
317
+ pathOf(value) {
318
+ var _a;
319
+ const path = [];
320
+ let child = value;
321
+ for (let guard = 0; guard < 64; guard++) {
322
+ let parent = child.PARENT;
323
+ if (!parent)
324
+ return undefined;
325
+ // sdtContent is not a level of its own
326
+ if ((_a = parent.TYPE_NAME) === null || _a === void 0 ? void 0 : _a.endsWith('SdtContentBlock'))
327
+ parent = parent.PARENT;
328
+ if (!parent)
329
+ return undefined;
330
+ const children = childrenOf(parent);
331
+ if (!children)
332
+ return undefined;
333
+ const i = children.findIndex((el) => el.value === child);
334
+ if (i < 0)
335
+ return undefined;
336
+ path.unshift(i);
337
+ if (parent === this.container)
338
+ return path;
339
+ child = parent;
340
+ }
341
+ return undefined;
342
+ }
343
+ /** Gives a new paragraph a w14:paraId when the document already uses them. */
344
+ assignParaId(p) {
345
+ if (p.paraId)
346
+ return;
347
+ if (!this.usesParaIds())
348
+ return;
349
+ let id;
350
+ do {
351
+ id = Math.floor(Math.random() * 0x7fffffff).toString(16).toUpperCase().padStart(8, '0');
352
+ } while (this.paragraphs.some((q) => q.paraId === id));
353
+ p.paraId = id;
354
+ }
355
+ usesParaIds() {
356
+ return this.paragraphs.some((q) => q.paraId !== undefined);
357
+ }
358
+ }
359
+ function describe(el) {
360
+ var _a, _b;
361
+ const tn = typeNameOf(el);
362
+ return `${(_b = (_a = el.name) === null || _a === void 0 ? void 0 : _a.localPart) !== null && _b !== void 0 ? _b : '?'} (${tn !== null && tn !== void 0 ? tn : 'no TYPE_NAME'})`;
363
+ }
@@ -0,0 +1,46 @@
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';
3
+ export type { UnderlineType };
4
+ /** Something with run properties: a run, or the paragraph mark. */
5
+ export interface RPrHolder {
6
+ rPr?: wml.RPr;
7
+ }
8
+ /**
9
+ * A subset of Office JS `Word.Font`, over the direct run properties (w:rPr) of one or more
10
+ * runs. Reads report the first run's direct formatting (effective formatting through styles
11
+ * is CR-001 Phase B); writes apply to every run in scope. Both go through the objects
12
+ * package's one name-to-w:rPr mapping (`builders/wml` applyRunOptions / readRunOptions),
13
+ * which its `r(text, opts)` builder shares.
14
+ */
15
+ export declare class Font {
16
+ private readonly holders;
17
+ constructor(holders: () => RPrHolder[]);
18
+ private read;
19
+ private apply;
20
+ get bold(): boolean;
21
+ set bold(v: boolean);
22
+ get italic(): boolean;
23
+ set italic(v: boolean);
24
+ get underline(): UnderlineType;
25
+ set underline(v: UnderlineType);
26
+ get strikeThrough(): boolean;
27
+ set strikeThrough(v: boolean);
28
+ get doubleStrikeThrough(): boolean;
29
+ set doubleStrikeThrough(v: boolean);
30
+ get subscript(): boolean;
31
+ set subscript(v: boolean);
32
+ get superscript(): boolean;
33
+ set superscript(v: boolean);
34
+ /** The ASCII font name (w:rFonts/@w:ascii); '' when not set directly. */
35
+ get name(): string;
36
+ set name(v: string);
37
+ /** Size in points (w:sz is half-points); 0 when not set directly. */
38
+ get size(): number;
39
+ set size(v: number);
40
+ /** '#RRGGBB', or the raw value ('auto', a theme colour name) when it is not a hex triple; '' when not set. */
41
+ get color(): string;
42
+ set color(v: string);
43
+ /** '#RRGGBB' of the highlight, or null when there is none. */
44
+ get highlightColor(): string | null;
45
+ set highlightColor(v: string | null);
46
+ }
@@ -0,0 +1,50 @@
1
+ import { applyRunOptions, readRunOptions } from '@docx4j/generated-objects-ts/builders/wml';
2
+ /**
3
+ * A subset of Office JS `Word.Font`, over the direct run properties (w:rPr) of one or more
4
+ * runs. Reads report the first run's direct formatting (effective formatting through styles
5
+ * is CR-001 Phase B); writes apply to every run in scope. Both go through the objects
6
+ * package's one name-to-w:rPr mapping (`builders/wml` applyRunOptions / readRunOptions),
7
+ * which its `r(text, opts)` builder shares.
8
+ */
9
+ export class Font {
10
+ constructor(holders) {
11
+ this.holders = holders;
12
+ }
13
+ read() {
14
+ var _a;
15
+ return readRunOptions((_a = this.holders()[0]) === null || _a === void 0 ? void 0 : _a.rPr);
16
+ }
17
+ apply(opts) {
18
+ var _a;
19
+ for (const h of this.holders()) {
20
+ (_a = h.rPr) !== null && _a !== void 0 ? _a : (h.rPr = { TYPE_NAME: 'org_docx4j_wml.RPr' });
21
+ applyRunOptions(h.rPr, opts);
22
+ }
23
+ }
24
+ get bold() { return this.read().bold; }
25
+ set bold(v) { this.apply({ bold: v }); }
26
+ get italic() { return this.read().italic; }
27
+ set italic(v) { this.apply({ italic: v }); }
28
+ get underline() { return this.read().underline; }
29
+ set underline(v) { this.apply({ underline: v }); }
30
+ get strikeThrough() { return this.read().strikeThrough; }
31
+ set strikeThrough(v) { this.apply({ strikeThrough: v }); }
32
+ get doubleStrikeThrough() { return this.read().doubleStrikeThrough; }
33
+ set doubleStrikeThrough(v) { this.apply({ doubleStrikeThrough: v }); }
34
+ get subscript() { return this.read().subscript; }
35
+ set subscript(v) { this.apply({ subscript: v }); }
36
+ get superscript() { return this.read().superscript; }
37
+ set superscript(v) { this.apply({ superscript: v }); }
38
+ /** The ASCII font name (w:rFonts/@w:ascii); '' when not set directly. */
39
+ get name() { return this.read().name; }
40
+ set name(v) { this.apply({ name: v }); }
41
+ /** Size in points (w:sz is half-points); 0 when not set directly. */
42
+ get size() { return this.read().size; }
43
+ set size(v) { this.apply({ size: v }); }
44
+ /** '#RRGGBB', or the raw value ('auto', a theme colour name) when it is not a hex triple; '' when not set. */
45
+ get color() { return this.read().color; }
46
+ set color(v) { this.apply({ color: v }); }
47
+ /** '#RRGGBB' of the highlight, or null when there is none. */
48
+ get highlightColor() { return this.read().highlightColor; }
49
+ set highlightColor(v) { this.apply({ highlightColor: v }); }
50
+ }
@@ -0,0 +1,99 @@
1
+ import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
2
+ import { type Element, W_NS, type TextSegment } from './tree.mjs';
3
+ import { Font } from './Font.mjs';
4
+ import { Range } from './Range.mjs';
5
+ import { type SearchOptions } from './search.mjs';
6
+ import type { Body } from './Body.mjs';
7
+ /** Office JS Word.Alignment. */
8
+ export type Alignment = 'Unknown' | 'Left' | 'Centered' | 'Right' | 'Justified';
9
+ /**
10
+ * A subset of Office JS `Word.Paragraph` over a `w:p` in a body, cell, header, footer or
11
+ * content control. A light view: it holds the element and the array that contains it; nothing
12
+ * is cached, so views may be created and discarded freely. Every write mutates the tree in
13
+ * place and links PARENT on what it adds.
14
+ */
15
+ export declare class Paragraph {
16
+ /** The `w:p` element pair. */
17
+ readonly element: Element<wml.P>;
18
+ /** The content array holding the element (a body's, a cell's, a content control's). */
19
+ readonly container: Element[];
20
+ /** The nearest body view (the part's), for addresses and paragraph ids. */
21
+ readonly parentBody: Body;
22
+ constructor(
23
+ /** The `w:p` element pair. */
24
+ element: Element<wml.P>,
25
+ /** The content array holding the element (a body's, a cell's, a content control's). */
26
+ container: Element[],
27
+ /** The nearest body view (the part's), for addresses and paragraph ids. */
28
+ parentBody: Body);
29
+ /** The paragraph value (docx4j: the P). */
30
+ get p(): wml.P;
31
+ get index(): number;
32
+ /** The paragraph's text: runs joined, tabs as \t, breaks as \n; deleted text excluded. */
33
+ get text(): string;
34
+ /** Replaces the content with one run of the text, keeping the first run's formatting. */
35
+ set text(value: string);
36
+ /** The style id (w:pStyle); 'Normal' when none is set. */
37
+ get style(): string;
38
+ set style(id: string);
39
+ /** Word's display name of the style ('Heading 1'); mapped to and from ids by removing spaces. */
40
+ get styleBuiltIn(): string;
41
+ set styleBuiltIn(name: string);
42
+ get alignment(): Alignment;
43
+ set alignment(v: Alignment);
44
+ /** Indents and spacing in points, as Office JS; 0 when not set directly. */
45
+ get leftIndent(): number;
46
+ set leftIndent(pt: number);
47
+ get rightIndent(): number;
48
+ set rightIndent(pt: number);
49
+ /** First-line indent; negative for a hanging indent, as Office JS. */
50
+ get firstLineIndent(): number;
51
+ set firstLineIndent(pt: number);
52
+ get spaceBefore(): number;
53
+ set spaceBefore(pt: number);
54
+ get spaceAfter(): number;
55
+ set spaceAfter(pt: number);
56
+ /** Line spacing in points: w:line/240 lines of 12pt when the rule is auto, else w:line twips; 0 when not set. */
57
+ get lineSpacing(): number;
58
+ set lineSpacing(pt: number);
59
+ /** w:outlineLvl + 1 (1 to 9); 10 for body text, as Office JS. */
60
+ get outlineLevel(): number;
61
+ set outlineLevel(level: number);
62
+ /** Direct formatting of the runs: reads the first run, writes all (extension: `Font` is over runs, not the paragraph mark). */
63
+ get font(): Font;
64
+ /** w14:paraId, the stable address Word gives paragraphs. */
65
+ get paraId(): string | undefined;
66
+ set paraId(id: string | undefined);
67
+ /** The runs, direct and nested (hyperlinks, content controls, insertions), in order. */
68
+ get runs(): Element<wml.R>[];
69
+ /** Text inserted at the start, the end, or replacing the whole paragraph's text. */
70
+ insertText(text: string, location: 'Start' | 'End' | 'Replace'): Range;
71
+ /** A new paragraph of the text before or after this one, with this paragraph's properties (as Word). */
72
+ insertParagraph(text: string, location: 'Before' | 'After'): Paragraph;
73
+ insertBreak(type: 'Page' | 'Line', location: 'Before' | 'After' | 'Start' | 'End'): void;
74
+ /** Matches within this paragraph. */
75
+ search(text: string, options?: SearchOptions): Range[];
76
+ getRange(location?: 'Whole' | 'Start' | 'End' | 'Content'): Range;
77
+ /** Removes the paragraph from its container. */
78
+ delete(): void;
79
+ /** The paragraph as XML (extension; Office JS getOoxml wraps it in a package). */
80
+ getXml(): Promise<string>;
81
+ /** docx4j: the P's content list. */
82
+ getContent(): Element[];
83
+ private pPr;
84
+ private ind;
85
+ private spacing;
86
+ /** The text segments (w:t, w:tab, ...) with their offsets. */
87
+ segments(): TextSegment[];
88
+ /**
89
+ * Replaces the text in [start, end) with `text` and returns the range of the inserted text.
90
+ * Runs are edited in place: a w:t loses or gains characters, a tab or break inside the range
91
+ * is removed, a run left empty is removed. Text is inserted into the w:t at `start`,
92
+ * else into a new run with the formatting of the nearest run.
93
+ */
94
+ splice(start: number, end: number, text: string): Range;
95
+ /** Splits the run at a text offset so that [offset, ...) begins a run; returns nothing when the offset is already a boundary. */
96
+ splitAt(offset: number): void;
97
+ private removeEmptyRuns;
98
+ }
99
+ export { W_NS };