@docx4j/core-ts 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +4 -0
- package/README.md +34 -3
- package/dist/html/convert.mjs +40 -15
- package/dist/html/elements.mjs +2 -1
- package/dist/model/color/ColorMath.d.mts +29 -0
- package/dist/model/color/ColorMath.mjs +146 -0
- package/dist/model/color/ColorTables.d.mts +6 -0
- package/dist/model/color/ColorTables.mjs +83 -0
- package/dist/model/color/DrawingMLColors.d.mts +52 -0
- package/dist/model/color/DrawingMLColors.mjs +374 -0
- package/dist/model/color/ResolvedColor.d.mts +36 -0
- package/dist/model/color/ResolvedColor.mjs +65 -0
- package/dist/model/color/SpreadsheetColors.d.mts +36 -0
- package/dist/model/color/SpreadsheetColors.mjs +84 -0
- package/dist/model/color/StyleFill.d.mts +28 -0
- package/dist/model/color/StyleFill.mjs +21 -0
- package/dist/model/color/ThemeColors.d.mts +86 -0
- package/dist/model/color/ThemeColors.mjs +304 -0
- package/dist/model/color/WordColors.d.mts +71 -0
- package/dist/model/color/WordColors.mjs +121 -0
- package/dist/model/color/index.d.mts +6 -0
- package/dist/model/color/index.mjs +30 -0
- package/dist/model/content/Body.d.mts +153 -19
- package/dist/model/content/Body.mjs +570 -131
- package/dist/model/content/Comment.d.mts +21 -3
- package/dist/model/content/Comment.mjs +202 -19
- package/dist/model/content/ContentControl.d.mts +197 -18
- package/dist/model/content/ContentControl.mjs +664 -95
- package/dist/model/content/Font.d.mts +67 -17
- package/dist/model/content/Font.mjs +114 -35
- package/dist/model/content/InlinePicture.d.mts +82 -7
- package/dist/model/content/InlinePicture.mjs +221 -28
- package/dist/model/content/List.mjs +13 -1
- package/dist/model/content/Paragraph.d.mts +213 -14
- package/dist/model/content/Paragraph.mjs +936 -100
- package/dist/model/content/Range.d.mts +242 -11
- package/dist/model/content/Range.mjs +975 -119
- package/dist/model/content/ResolvedView.d.mts +104 -0
- package/dist/model/content/ResolvedView.mjs +596 -0
- package/dist/model/content/Table.d.mts +29 -3
- package/dist/model/content/Table.mjs +109 -33
- package/dist/model/content/TrackedChange.d.mts +301 -16
- package/dist/model/content/TrackedChange.mjs +1284 -158
- package/dist/model/content/binder.d.mts +2 -1
- package/dist/model/content/binder.mjs +48 -1
- package/dist/model/content/comments.d.mts +20 -6
- package/dist/model/content/comments.mjs +67 -57
- package/dist/model/content/generalException.d.mts +18 -0
- package/dist/model/content/generalException.mjs +24 -0
- package/dist/model/content/index.d.mts +8 -3
- package/dist/model/content/index.mjs +7 -2
- package/dist/model/content/mathText.d.mts +21 -0
- package/dist/model/content/mathText.mjs +267 -0
- package/dist/model/content/officeText.d.mts +27 -0
- package/dist/model/content/officeText.mjs +74 -0
- package/dist/model/content/outline.d.mts +5 -0
- package/dist/model/content/outline.mjs +13 -0
- package/dist/model/content/placeholders.d.mts +110 -0
- package/dist/model/content/placeholders.mjs +253 -0
- package/dist/model/content/relationships.d.mts +30 -0
- package/dist/model/content/relationships.mjs +133 -0
- package/dist/model/content/search.d.mts +72 -0
- package/dist/model/content/search.mjs +204 -2
- package/dist/model/content/spanEdits.d.mts +159 -0
- package/dist/model/content/spanEdits.mjs +728 -0
- package/dist/model/content/story.d.mts +44 -0
- package/dist/model/content/story.mjs +92 -0
- package/dist/model/content/tableColumns.d.mts +1 -1
- package/dist/model/content/tableColumns.mjs +108 -80
- package/dist/model/content/tableRevisions.d.mts +11 -3
- package/dist/model/content/tableRevisions.mjs +72 -42
- package/dist/model/content/tableRules.d.mts +30 -0
- package/dist/model/content/tableRules.mjs +100 -0
- package/dist/model/content/textBoxes.d.mts +18 -0
- package/dist/model/content/textBoxes.mjs +105 -0
- package/dist/model/content/trackedChangeFilter.d.mts +39 -0
- package/dist/model/content/trackedChangeFilter.mjs +81 -0
- package/dist/model/content/tracking.d.mts +28 -0
- package/dist/model/content/tracking.mjs +149 -10
- package/dist/model/content/tree.d.mts +212 -13
- package/dist/model/content/tree.mjs +356 -35
- package/dist/model/customxml/CustomXmlPartCollection.d.mts +8 -0
- package/dist/model/customxml/CustomXmlPartCollection.mjs +34 -11
- package/dist/model/customxml/XmlMapping.d.mts +1 -1
- package/dist/model/customxml/XmlMapping.mjs +11 -0
- package/dist/model/customxml/bindings.d.mts +21 -2
- package/dist/model/customxml/bindings.mjs +76 -32
- package/dist/model/customxml/kinds.d.mts +8 -3
- package/dist/model/customxml/kinds.mjs +26 -5
- package/dist/model/customxml/picturePlaceholder.d.mts +17 -0
- package/dist/model/customxml/picturePlaceholder.mjs +32 -0
- package/dist/model/customxml/pictures.d.mts +9 -5
- package/dist/model/customxml/pictures.mjs +31 -13
- package/dist/model/customxml/xhtml.mjs +8 -2
- package/dist/model/fonts/families.generated.mjs +2 -2
- package/dist/model/fonts/registry.mjs +7 -1
- package/dist/model/fonts/substitutions.generated.mjs +2 -2
- package/dist/model/fonts/themes.generated.mjs +1 -1
- package/dist/model/index.d.mts +2 -0
- package/dist/model/index.mjs +4 -0
- package/dist/model/listnumbering/Emulator.d.mts +37 -5
- package/dist/model/listnumbering/Emulator.mjs +63 -9
- package/dist/model/listnumbering/definitions.mjs +18 -0
- package/dist/model/properties/PropertyResolver.d.mts +87 -7
- package/dist/model/properties/PropertyResolver.mjs +197 -17
- package/dist/model/properties/catalogue.d.mts +32 -4
- package/dist/model/properties/catalogue.mjs +115 -36
- package/dist/model/properties/log.d.mts +1 -1
- package/dist/model/properties/log.mjs +5 -5
- package/dist/model/properties/table.d.mts +16 -2
- package/dist/model/properties/table.mjs +17 -5
- package/dist/model/text/Extractor.d.mts +289 -0
- package/dist/model/text/Extractor.mjs +2162 -0
- package/dist/model/text/LinkTargets.d.mts +45 -0
- package/dist/model/text/LinkTargets.mjs +170 -0
- package/dist/model/text/MarkdownExporter.d.mts +140 -0
- package/dist/model/text/MarkdownExporter.mjs +255 -0
- package/dist/model/text/PlainText.d.mts +29 -0
- package/dist/model/text/PlainText.mjs +539 -0
- package/dist/model/text/TextContext.d.mts +161 -0
- package/dist/model/text/TextContext.mjs +425 -0
- package/dist/model/text/TextOptions.d.mts +150 -0
- package/dist/model/text/TextOptions.mjs +278 -0
- package/dist/model/text/TextResult.d.mts +504 -0
- package/dist/model/text/TextResult.mjs +526 -0
- package/dist/model/text/Texts.d.mts +99 -0
- package/dist/model/text/Texts.mjs +187 -0
- package/dist/model/text/WmlToMarkdown.d.mts +120 -0
- package/dist/model/text/WmlToMarkdown.mjs +911 -0
- package/dist/model/text/commonmark.d.mts +121 -0
- package/dist/model/text/commonmark.mjs +655 -0
- package/dist/model/text/index.d.mts +7 -0
- package/dist/model/text/index.mjs +8 -0
- package/dist/model/text/normalize.d.mts +8 -0
- package/dist/model/text/normalize.mjs +13 -0
- package/dist/model/text/outline.d.mts +4 -0
- package/dist/model/text/outline.mjs +71 -0
- package/dist/office-js/fragment.d.mts +7 -5
- package/dist/office-js/fragment.mjs +63 -14
- package/dist/office-js/proxy.d.mts +8 -0
- package/dist/office-js/proxy.mjs +29 -0
- package/dist/office-js/run.mjs +2 -0
- package/dist/office-js/supported.generated.mjs +16 -0
- package/dist/office-js/toApiScript.mjs +21 -5
- package/dist/opc/Load.d.mts +9 -2
- package/dist/opc/Save.d.mts +17 -0
- package/dist/opc/Save.mjs +12 -2
- package/dist/opc/index.d.mts +3 -3
- package/dist/opc/index.mjs +2 -2
- package/dist/opc/mce/preprocessor.d.mts +88 -7
- package/dist/opc/mce/preprocessor.mjs +144 -37
- package/dist/opc/mce/understood.d.mts +34 -0
- package/dist/opc/mce/understood.mjs +55 -3
- package/dist/packages/OpcPackage.d.mts +20 -0
- package/dist/packages/OpcPackage.mjs +16 -3
- package/dist/packages/WordprocessingMLPackage.d.mts +77 -7
- package/dist/packages/WordprocessingMLPackage.mjs +242 -11
- package/dist/parts/DefaultXmlPart.mjs +2 -2
- package/dist/parts/Part.d.mts +10 -2
- package/dist/parts/XmlPart.d.mts +35 -32
- package/dist/parts/XmlPart.mjs +107 -107
- package/dist/parts/wml/comments.mjs +30 -0
- package/dist/parts/wml/index.mjs +12 -0
- package/dist/xml/dom.d.mts +7 -0
- package/dist/xml/dom.mjs +18 -0
- package/package.json +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Docx4JException } from '../../opc/exceptions.mjs';
|
|
2
|
+
import { NotSupportedError } from '../../office-js/errors.mjs';
|
|
2
3
|
/** A regular expression for a search text under the options; global so it can iterate matches. */
|
|
3
4
|
export function searchPattern(text, options = {}) {
|
|
4
5
|
if (options.matchRegExp && options.matchWildcards) {
|
|
@@ -19,10 +20,17 @@ export function searchPattern(text, options = {}) {
|
|
|
19
20
|
source = '';
|
|
20
21
|
for (let i = 0; i < text.length; i++) {
|
|
21
22
|
const c = text[i];
|
|
23
|
+
// a code point, a surrogate pair whole, as Word's ? matches an emoji (check 58 case 13; CR-002 section 32, K4);
|
|
24
|
+
// ? and * cross a paragraph's mark where a search reads one (`wildcardMatchesAcross`, check 59, K7)
|
|
22
25
|
if (c === '?')
|
|
23
|
-
source += '
|
|
26
|
+
source += '(?:[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\s\\S])';
|
|
24
27
|
else if (c === '*')
|
|
25
|
-
source += '
|
|
28
|
+
source += '[\\s\\S]*?';
|
|
29
|
+
// ^13, Word's wildcard code for a paragraph mark (check 59)
|
|
30
|
+
else if (c === '^' && text.startsWith('13', i + 1)) {
|
|
31
|
+
source += '\\r';
|
|
32
|
+
i += 2;
|
|
33
|
+
}
|
|
26
34
|
else if (c === '<')
|
|
27
35
|
source += '\\b(?=\\w)';
|
|
28
36
|
else if (c === '>')
|
|
@@ -143,3 +151,197 @@ export function expandReplacement(replacement, match, options = {}) {
|
|
|
143
151
|
}
|
|
144
152
|
return replacement;
|
|
145
153
|
}
|
|
154
|
+
/** The object replacement character: a picture's place in the text `search` reads, which `^g` matches. */
|
|
155
|
+
const OBJECT = '';
|
|
156
|
+
/**
|
|
157
|
+
* Word's Find codes a plain query may hold (check 48: each matched its character in Office JS's text):
|
|
158
|
+
* `^f` a footnote reference, `^e` an endnote reference, `^l` a line break, `^m` a page break, `^t` a tab,
|
|
159
|
+
* `^~` a non-breaking hyphen, `^-` an optional hyphen, `^g` a picture, `^^` a caret.
|
|
160
|
+
*/
|
|
161
|
+
const FIND_CODES = { f: '\u0002', e: '\u0002', l: '\u000B', m: '\u000C', t: '\t', '~': '\u001E', '-': '\u001F', g: OBJECT, '^': '^' };
|
|
162
|
+
/**
|
|
163
|
+
* Every match of a query in a paragraph's text by Office JS's rules (check 48, Word's default view): the
|
|
164
|
+
* text is `Paragraph.text` (hidden text left out, so a query matches across it and never in it), where a
|
|
165
|
+
* picture is a place of no text that a plain query doesn't match across and `^g` matches, and an optional
|
|
166
|
+
* hyphen is passed over unless the query names it (`^-`). A plain query takes Word's Find codes
|
|
167
|
+
* (`FIND_CODES`), and its `-` matches a non-breaking hyphen too. Wildcards read the same text, the codes
|
|
168
|
+
* not translated; a regular expression (`matchRegExp`, this package's extension) reads `Paragraph.text`
|
|
169
|
+
* itself. Only text in [from, to) is read: a range's search.
|
|
170
|
+
*/
|
|
171
|
+
export function officeMatches(segments, query, options = {}, from = 0, to = Number.POSITIVE_INFINITY) {
|
|
172
|
+
const plain = !options.matchRegExp && !options.matchWildcards;
|
|
173
|
+
const keepSoftHyphens = !plain || /\^-/.test(query.replace(/\^\^/g, ''));
|
|
174
|
+
let pattern;
|
|
175
|
+
let tokens = [];
|
|
176
|
+
if (plain) {
|
|
177
|
+
const translated = plainQuery(query);
|
|
178
|
+
tokens = translated.tokens;
|
|
179
|
+
pattern = patternOf(translated.source, options);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
pattern = searchPattern(query, options);
|
|
183
|
+
}
|
|
184
|
+
// the usual paragraph: nothing but text, no optional hyphen to pass over, no reference a code must tell
|
|
185
|
+
// apart, so the text searched is Paragraph.text's own [from, to), each offset itself
|
|
186
|
+
if (segments.every((seg) => !seg.object && !seg.hidden) && tokens.every((kind) => kind === undefined)) {
|
|
187
|
+
const whole = segments.map((seg) => seg.text).join('');
|
|
188
|
+
const start = Math.max(0, from);
|
|
189
|
+
const span = whole.substring(start, Math.min(whole.length, to));
|
|
190
|
+
if (keepSoftHyphens || !span.includes('\u001F')) {
|
|
191
|
+
return matchesOf(span, pattern).map((match) => ({ start: start + match.index, end: start + match.index + match[0].length, match }));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
let text = '';
|
|
195
|
+
const starts = [];
|
|
196
|
+
const ends = [];
|
|
197
|
+
const notes = [];
|
|
198
|
+
for (const seg of segments) {
|
|
199
|
+
if (seg.hidden)
|
|
200
|
+
continue;
|
|
201
|
+
if (seg.object) {
|
|
202
|
+
if (!options.matchRegExp && from < seg.start && seg.start < to) {
|
|
203
|
+
text += OBJECT;
|
|
204
|
+
starts.push(seg.start);
|
|
205
|
+
ends.push(seg.start);
|
|
206
|
+
notes.push(undefined);
|
|
207
|
+
}
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
for (let i = 0; i < seg.text.length; i++) {
|
|
211
|
+
const at = seg.start + i;
|
|
212
|
+
if (at < from || at >= to)
|
|
213
|
+
continue;
|
|
214
|
+
const c = seg.text[i];
|
|
215
|
+
if (c === '\u001F' && !keepSoftHyphens)
|
|
216
|
+
continue;
|
|
217
|
+
text += c;
|
|
218
|
+
starts.push(at);
|
|
219
|
+
ends.push(at + 1);
|
|
220
|
+
notes.push(c === '\u0002' ? seg.item.name.localPart : undefined);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const out = [];
|
|
224
|
+
for (const match of matchesOf(text, pattern)) {
|
|
225
|
+
const a = match.index;
|
|
226
|
+
const b = a + match[0].length;
|
|
227
|
+
// ^f and ^e both read U+0002: each matches only its own kind of reference
|
|
228
|
+
if (tokens.some((kind, i) => { var _a; return kind !== undefined && !((_a = notes[a + i]) !== null && _a !== void 0 ? _a : '').startsWith(kind); }))
|
|
229
|
+
continue;
|
|
230
|
+
out.push({ start: starts[a], end: ends[b - 1], match });
|
|
231
|
+
}
|
|
232
|
+
return out;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* A wildcard query's hits over consecutive paragraphs, each followed by its mark where `mark` says, as Word's wildcards
|
|
236
|
+
* match a paragraph mark (check 59; CR-002 section 32, K7): `?`, `*` and a class cross one, `^13` is one. The text read
|
|
237
|
+
* in each paragraph is `officeMatches`' for wildcards; the caller gives only paragraphs a hit may span (one cell's, or
|
|
238
|
+
* none's) and only the marks it may hold (a paragraph's own, never a cell's or a row's end).
|
|
239
|
+
*/
|
|
240
|
+
export function wildcardMatchesAcross(pieces, query, options) {
|
|
241
|
+
const pattern = searchPattern(query, { ...options, matchWildcards: true });
|
|
242
|
+
let text = '';
|
|
243
|
+
const starts = [];
|
|
244
|
+
const ends = [];
|
|
245
|
+
const marks = [];
|
|
246
|
+
const put = (c, k, start, end, mark) => { text += c; starts.push([k, start]); ends.push([k, end]); marks.push(mark); };
|
|
247
|
+
pieces.forEach((piece, k) => {
|
|
248
|
+
for (const seg of piece.segments) {
|
|
249
|
+
if (seg.hidden)
|
|
250
|
+
continue;
|
|
251
|
+
if (seg.object) {
|
|
252
|
+
if (piece.from < seg.start && seg.start < piece.to)
|
|
253
|
+
put(OBJECT, k, seg.start, seg.start, false);
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
for (let i = 0; i < seg.text.length; i++) {
|
|
257
|
+
const at = seg.start + i;
|
|
258
|
+
if (at >= piece.from && at < piece.to)
|
|
259
|
+
put(seg.text[i], k, at, at + 1, false);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (piece.mark)
|
|
263
|
+
put('\r', k, piece.length, piece.length, true);
|
|
264
|
+
});
|
|
265
|
+
return matchesOf(text, pattern).map((match) => {
|
|
266
|
+
const a = match.index;
|
|
267
|
+
const b = a + match[0].length;
|
|
268
|
+
return { first: starts[a][0], start: starts[a][1], last: ends[b - 1][0], end: ends[b - 1][1], mark: marks[b - 1], match };
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Refuses a wildcard replacement where a hit holds a paragraph mark (CR-002 section 32, K7): `search` finds it, as
|
|
273
|
+
* Word's does (check 59), but what replacing a mark leaves isn't measured, as for a plain `^p` (`refuseMarkReplacement`).
|
|
274
|
+
*/
|
|
275
|
+
export function refuseWildcardMarkReplacement(className, hits) {
|
|
276
|
+
if (!hits.some((hit) => hit.spansParagraphs || hit.holdsEndMark))
|
|
277
|
+
return;
|
|
278
|
+
throw new NotSupportedError(className, 'replaceText', "a hit holds a paragraph mark, which Word's wildcards match (check 59), and what replacing "
|
|
279
|
+
+ 'one does isn\'t measured (CR-002 section 32); search for the hits and edit their ranges');
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* A plain query split at Word's paragraph mark code, `^p`: its pieces, one more than the marks, each a plain
|
|
283
|
+
* query of its own (`^^` stays an escaped caret); undefined where the query holds no `^p`. What a `Range`'s search
|
|
284
|
+
* across paragraphs matches piece by piece (CR-014 phase 3).
|
|
285
|
+
*/
|
|
286
|
+
export function paragraphMarkPieces(query) {
|
|
287
|
+
const pieces = [];
|
|
288
|
+
let piece = '';
|
|
289
|
+
for (let i = 0; i < query.length; i++) {
|
|
290
|
+
const c = query[i];
|
|
291
|
+
if (c === '^' && query[i + 1] === 'p') {
|
|
292
|
+
pieces.push(piece);
|
|
293
|
+
piece = '';
|
|
294
|
+
i++;
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
if (c === '^' && i + 1 < query.length) {
|
|
298
|
+
piece += c + query[i + 1];
|
|
299
|
+
i++;
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
piece += c;
|
|
303
|
+
}
|
|
304
|
+
if (pieces.length === 0)
|
|
305
|
+
return undefined;
|
|
306
|
+
pieces.push(piece);
|
|
307
|
+
return pieces;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Refuses a replacement whose query holds `^p` (CR-014 phase 3): `search` finds such a hit, but what Office JS's
|
|
311
|
+
* replacement of a paragraph mark leaves isn't measured, and `insertText('Replace')` keeps a last mark (check 52).
|
|
312
|
+
* Until phase 3 such a query matched the two characters `^p`, where Word matches a mark.
|
|
313
|
+
*/
|
|
314
|
+
export function refuseMarkReplacement(className, find, options) {
|
|
315
|
+
if ((options === null || options === void 0 ? void 0 : options.matchWildcards) || (options === null || options === void 0 ? void 0 : options.matchRegExp) || !paragraphMarkPieces(find))
|
|
316
|
+
return;
|
|
317
|
+
throw new NotSupportedError(className, 'replaceText', "the query holds ^p, Word's paragraph mark, and what replacing one does isn't "
|
|
318
|
+
+ "measured (CR-014 phase 3); search for the hits and edit their ranges");
|
|
319
|
+
}
|
|
320
|
+
/** A plain query as an expression over `officeMatches`' text, and which of its characters are `^f` or `^e`. */
|
|
321
|
+
function plainQuery(query) {
|
|
322
|
+
let source = '';
|
|
323
|
+
const tokens = [];
|
|
324
|
+
for (let i = 0; i < query.length; i++) {
|
|
325
|
+
const c = query[i];
|
|
326
|
+
const code = c === '^' ? query[i + 1] : undefined;
|
|
327
|
+
if (code !== undefined && FIND_CODES[code] !== undefined) {
|
|
328
|
+
source += escapeRegExp(FIND_CODES[code]);
|
|
329
|
+
tokens.push(code === 'f' ? 'footnote' : code === 'e' ? 'endnote' : undefined);
|
|
330
|
+
i++;
|
|
331
|
+
}
|
|
332
|
+
else if (c === '-') {
|
|
333
|
+
source += '[-\\u001E]'; // a non-breaking hyphen is a hyphen to a plain query
|
|
334
|
+
tokens.push(undefined);
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
source += escapeRegExp(c);
|
|
338
|
+
tokens.push(undefined);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return { source, tokens };
|
|
342
|
+
}
|
|
343
|
+
/** `searchPattern`'s flags and whole-word guard over a source already written as an expression. */
|
|
344
|
+
function patternOf(source, options) {
|
|
345
|
+
const guarded = options.matchWholeWord ? `(?<![\\w])${source}(?![\\w])` : source;
|
|
346
|
+
return new RegExp(guarded, options.matchCase ? 'g' : 'gi');
|
|
347
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
|
|
2
|
+
import { type RunOptions } from '@docx4j/generated-objects-ts/builders/wml';
|
|
3
|
+
import { type Element } from './tree.mjs';
|
|
4
|
+
import type { Paragraph } from './Paragraph.mjs';
|
|
5
|
+
/** What a write needs of the `Range` it writes: its two ends, and whether it holds its last paragraph's mark. */
|
|
6
|
+
export interface Span {
|
|
7
|
+
readonly paragraph: Paragraph;
|
|
8
|
+
readonly endParagraph: Paragraph;
|
|
9
|
+
readonly start: number;
|
|
10
|
+
readonly end: number;
|
|
11
|
+
readonly whole: boolean;
|
|
12
|
+
/** The range holds its last paragraph's mark (a 'Whole' range), or a table's end in its place. */
|
|
13
|
+
readonly holdsEndMark: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Where a range's two ends stand in the innermost list of blocks holding both: the block holding the start and
|
|
17
|
+
* the block holding the end, each the end's paragraph itself, or a table or content control the range holds
|
|
18
|
+
* whole (a table's 'Whole' range, a body's that starts with a table).
|
|
19
|
+
*/
|
|
20
|
+
export interface Extent {
|
|
21
|
+
list: Element[];
|
|
22
|
+
first: number;
|
|
23
|
+
last: number;
|
|
24
|
+
/** The start's paragraph, where it is the first block itself (or in `headInside`); else that block goes whole. */
|
|
25
|
+
head?: Paragraph;
|
|
26
|
+
/** The end's paragraph, where it is the last block itself (or in `tailInside`); else that block goes whole. */
|
|
27
|
+
tail?: Paragraph;
|
|
28
|
+
/** Where the range starts inside a block content control at `first`: the control's list holding `head` (check 54 case 20). */
|
|
29
|
+
headInside?: Element[];
|
|
30
|
+
/** Where the range ends inside a block content control at `last`: the control's list holding `tail` (check 54 case 18). */
|
|
31
|
+
tailInside?: Element[];
|
|
32
|
+
}
|
|
33
|
+
/** Where a deletion closed up: the paragraph, and the offset in it a replacement's text goes at. */
|
|
34
|
+
export interface Landing {
|
|
35
|
+
paragraph: Paragraph;
|
|
36
|
+
offset: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The extent of a range, refusing one that starts or ends inside a block it doesn't hold whole. Inside a table
|
|
40
|
+
* that is Word's own refusal (check 52: `delete()` and `Replace` on a range from a cell to a paragraph after the
|
|
41
|
+
* table, or from a paragraph into a cell, threw `GeneralException` and changed nothing, tracked or not; D3).
|
|
42
|
+
* Inside a block content control, `crossControls` lets a range end in the control's own paragraphs, one level
|
|
43
|
+
* down, as `delete()` takes one (check 54 cases 18 to 20); anything else there is `NotSupportedError`.
|
|
44
|
+
*/
|
|
45
|
+
export declare function extentOf(span: Span, member: string, crossControls?: boolean): Extent;
|
|
46
|
+
/**
|
|
47
|
+
* Deletes a range across paragraphs, or one holding its last paragraph's mark, as Word does (check 52, cases 3 to
|
|
48
|
+
* 28; check 54, cases 5 to 20): the start's paragraph loses its text from the start, every block between goes whole
|
|
49
|
+
* (a table too), the end's paragraph loses its text to the end, and the two join in the end paragraph's properties,
|
|
50
|
+
* each run keeping its own formatting. A mark the range holds goes (`dropMark`): its paragraph joins the paragraph
|
|
51
|
+
* after it, in that one's properties (W1, W2; after a whole table the range took, case 5), or, with no paragraph
|
|
52
|
+
* after it, goes itself where its text went with the range (before a table, at a control's end: cases 8 and 12),
|
|
53
|
+
* a cell's last paragraph and a story's last kept (case 10). `keepLastMark` is `Replace`'s, which keeps it.
|
|
54
|
+
*
|
|
55
|
+
* A range ending (or starting) in a block content control's own paragraph, the other end outside it, joins
|
|
56
|
+
* nothing across the control's edge: the texts go, and the start's paragraph takes the end's paragraph properties
|
|
57
|
+
* (cases 18 to 20). A comment whose reference goes with the range goes too (case 27).
|
|
58
|
+
*
|
|
59
|
+
* Tracked, nothing is joined: the text is a `w:del`, every mark in the range is marked deleted but a last one the
|
|
60
|
+
* range doesn't hold, or that can't go (a cell's last), and a table's rows and its cells' marks are deleted, with no
|
|
61
|
+
* `w:pPrChange` (Word's markup in its save after check 52's run). Accepting gives the untracked answer.
|
|
62
|
+
*/
|
|
63
|
+
export declare function deleteSpan(span: Span, extent: Extent, keepLastMark: boolean): Landing | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Refuses, before anything changes, a tracked deletion of a range holding a whole `w:altChunk` or kept
|
|
66
|
+
* `mc:AlternateContent`: neither has a deleted form, and Accept All would leave it where the untracked deletion
|
|
67
|
+
* takes it, the paragraphs either side unjoined. A content control or custom XML element held whole is deleted as
|
|
68
|
+
* Word deletes one (check 54 cases 15 and 17: `markHolderDeleted`).
|
|
69
|
+
*/
|
|
70
|
+
export declare function assertTrackable(extent: Extent, member: string): void;
|
|
71
|
+
/** The first replaced character's run properties and where it stood, read before anything is deleted. */
|
|
72
|
+
export interface FirstCharacter {
|
|
73
|
+
rPr: wml.RPr | undefined;
|
|
74
|
+
pPr: wml.PPr | undefined;
|
|
75
|
+
p: wml.P;
|
|
76
|
+
}
|
|
77
|
+
/** The character at a range's start: its run's properties, or its paragraph's mark's where the range starts at the mark. */
|
|
78
|
+
export declare function firstCharacterOf(span: Span): FirstCharacter;
|
|
79
|
+
/**
|
|
80
|
+
* The run properties that give text in `into` the look the first replaced character had (check 52, cases 29 to
|
|
81
|
+
* 38): its run's own properties, and each property its paragraph's style gave it that `into`'s doesn't, written
|
|
82
|
+
* direct - a heading's font, size, colour and bold in a body paragraph (case 29), and a body paragraph's
|
|
83
|
+
* `w:b w:val="0"` and automatic colour in a heading (case 30). A property no style sets anywhere and `into`'s does
|
|
84
|
+
* is written as its neutral value where it has one (`NEUTRAL`).
|
|
85
|
+
*/
|
|
86
|
+
export declare function lookOf(first: FirstCharacter, into: Paragraph): wml.RPr | undefined;
|
|
87
|
+
/** The text of an untracked `Replace`, put where the deletion closed up, in the first replaced character's look. */
|
|
88
|
+
export declare function placeReplacement(landing: Landing, first: FirstCharacter, text: string): {
|
|
89
|
+
first: Paragraph;
|
|
90
|
+
last: Paragraph;
|
|
91
|
+
start: number;
|
|
92
|
+
end: number;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* A paragraph of `text` put at `offset` in `p`, as Word puts one where a range across paragraphs starts
|
|
96
|
+
* ('Before') or ends ('After') (check 52, cases 57 to 70): at the paragraph's start it goes before it and at its
|
|
97
|
+
* end after it, in its properties (`Paragraph.insertParagraph`); inside it `p` is split there (`splitParagraph`)
|
|
98
|
+
* and the new paragraph goes between the halves, its mark and its text in the formatting of the run before the
|
|
99
|
+
* split (case 63's italic). Tracked, the new paragraph and the first half's mark are inserted (cases 69 and 70).
|
|
100
|
+
* Returns the new paragraph, and the first half where `p` was split.
|
|
101
|
+
*/
|
|
102
|
+
export declare function insertParagraphAt(p: Paragraph, offset: number, text: string): {
|
|
103
|
+
inserted: Paragraph;
|
|
104
|
+
firstHalf?: Paragraph;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Paragraph breaks put into `p` at `offsets` (ascending, in its text), as Word's insertText writes a line feed or
|
|
108
|
+
* carriage return (CR-002 section 60 E1, check 55): at a split (`splitParagraph`), in the formatting of the run before
|
|
109
|
+
* it; at the paragraph's end an empty paragraph after it, at its start one before it, in its properties. Tracked, each
|
|
110
|
+
* new mark is inserted. Returns the first paragraph and the last, which holds what followed the last break.
|
|
111
|
+
*/
|
|
112
|
+
export declare function breakParagraphAt(p: Paragraph, offsets: readonly number[]): {
|
|
113
|
+
first: Paragraph;
|
|
114
|
+
last: Paragraph;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Splits `p` at `offset`, inside its text: what is before it becomes a new paragraph in front of `p`, in a copy of
|
|
118
|
+
* its properties with a mark of its own in `rPr`'s formatting, and `p` keeps the rest with its own mark, its
|
|
119
|
+
* section break and its identity, as Word keeps them (check 52 cases 57 and 63). A link, a revision or a smart tag
|
|
120
|
+
* the offset is inside is split into two of the same; a complex field's result is split, the field running across the
|
|
121
|
+
* two, and a `w:fldSimple` is made a complex field first, as Word makes it (check 57, CR-002 section 62.2 D1); a content
|
|
122
|
+
* control or a kept `mc:AlternateContent` there is refused, since its two halves would be two of it. Tracked, the new
|
|
123
|
+
* mark is inserted, as Word marks the first half's (cases 69 and 70). Returns the first half.
|
|
124
|
+
*/
|
|
125
|
+
export declare function splitParagraph(p: Paragraph, offset: number, rPr: wml.RPr | undefined): Paragraph;
|
|
126
|
+
/**
|
|
127
|
+
* Word's form of a table put after the paragraph a table cell ends with (check 52, cases 86 and 87; CR-002 section 55.6):
|
|
128
|
+
* that paragraph is split at its end, as a paragraph break there splits it (`splitAtEnd`), the table between the halves,
|
|
129
|
+
* so the cell's mark stays last. The paragraph keeps its text and becomes the first half, whose new mark takes the
|
|
130
|
+
* formatting of the text before it and, tracked, is the inserted one; its properties as they were go after the table, in
|
|
131
|
+
* an empty paragraph, unmarked. The paragraph keeps its text, not its mark, so that a view of it (a `Range`) still holds it.
|
|
132
|
+
*/
|
|
133
|
+
export declare function keepCellMarkLast(p: Paragraph, cellContent: Element[]): void;
|
|
134
|
+
/** The run holders a paragraph split may cut in two: each half is a whole one of the same. */
|
|
135
|
+
export declare const SPLITTABLE: Set<string>;
|
|
136
|
+
/** The run holders a paragraph break may be made inside: those it cuts in two, and a `w:fldSimple`, made a complex field first (D1). */
|
|
137
|
+
export declare const BREAKABLE: ReadonlySet<string>;
|
|
138
|
+
/**
|
|
139
|
+
* Every `w:fldSimple` a run is inside, below the paragraph, made a complex field, the innermost first: what Word does
|
|
140
|
+
* before a paragraph break inside a simple field's result (check 57 cases 2 and 4, CR-002 section 62.2 D1). The caller
|
|
141
|
+
* has checked that every other holder there can be cut in two.
|
|
142
|
+
*/
|
|
143
|
+
export declare function unfoldSimpleFieldsAround(run: object, p: object): void;
|
|
144
|
+
/** A piece of a range in one paragraph: its runs, and whether the range holds the paragraph's mark. */
|
|
145
|
+
export interface FontPiece {
|
|
146
|
+
paragraph: Paragraph;
|
|
147
|
+
start: number;
|
|
148
|
+
end: number;
|
|
149
|
+
runs: () => Element<wml.R>[];
|
|
150
|
+
holdsMark: boolean;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* A `font` write over a range across paragraphs (check 52, cases 49 to 56): every run in the range, a table's
|
|
154
|
+
* cells' too, split at the range's ends, and each mark the range holds, as Word formats them. A property goes only
|
|
155
|
+
* where a run or mark doesn't read the value already (`reads`): Word wrote `w:b` on none of a heading's runs, bold
|
|
156
|
+
* through its style, and tracked no change there; nor `w:sz` on a heading's 14-point runs (check 54). Tracked, each
|
|
157
|
+
* run and mark changed has its `w:rPrChange` (case 56: the body paragraph's mark's).
|
|
158
|
+
*/
|
|
159
|
+
export declare function formatSpan(pieces: FontPiece[], opts: RunOptions): void;
|