rtf-codec 1.0.0 → 1.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.
- package/README.md +39 -21
- package/dist/cell-format.cjs +142 -0
- package/dist/cell-format.d.cts +25 -0
- package/dist/cell-format.d.ts +25 -0
- package/dist/cell-format.js +137 -0
- package/dist/codec.d.cts +37 -1
- package/dist/codec.d.ts +37 -1
- package/dist/codepage.d.cts +1 -1
- package/dist/codepage.d.ts +1 -1
- package/dist/constructs.cjs +131 -0
- package/dist/constructs.d.cts +31 -0
- package/dist/constructs.d.ts +31 -0
- package/dist/constructs.js +121 -0
- package/dist/{diagnostics-DdDFJLNO.d.cts → diagnostics-BgG_KAiN.d.cts} +2 -1
- package/dist/{diagnostics-DdDFJLNO.d.ts → diagnostics-BgG_KAiN.d.ts} +2 -1
- package/dist/diagnostics.cjs +3 -2
- package/dist/diagnostics.d.cts +1 -1
- package/dist/diagnostics.d.ts +1 -1
- package/dist/diagnostics.js +3 -2
- package/dist/header.cjs +61 -6
- package/dist/header.d.cts +2 -1
- package/dist/header.d.ts +2 -1
- package/dist/header.js +61 -6
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/options.d.cts +1 -1
- package/dist/options.d.ts +1 -1
- package/dist/read.cjs +397 -40
- package/dist/read.d.cts +1 -1
- package/dist/read.d.ts +1 -1
- package/dist/read.js +397 -40
- package/dist/write.cjs +196 -28
- package/dist/write.js +196 -28
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { rtfBytesFromLatin1 } from "./bytes.cjs";
|
|
2
2
|
import { RtfBytesSchema, rtfCodec, rtfContentCodec } from "./codec.cjs";
|
|
3
|
-
import { a as RtfDiagnosticSink, c as RtfNotAnRtfDocumentError, d as RtfWriteError, i as RtfDiagnosticSeverity, l as RtfParseError, n as RtfDiagnostic, o as RtfInputTooLargeError, r as RtfDiagnosticCodes, s as RtfNestingLimitExceededError, t as NOOP_RTF_DIAGNOSTIC_SINK, u as RtfUnsupportedDocumentKindError } from "./diagnostics-
|
|
3
|
+
import { a as RtfDiagnosticSink, c as RtfNotAnRtfDocumentError, d as RtfWriteError, i as RtfDiagnosticSeverity, l as RtfParseError, n as RtfDiagnostic, o as RtfInputTooLargeError, r as RtfDiagnosticCodes, s as RtfNestingLimitExceededError, t as NOOP_RTF_DIAGNOSTIC_SINK, u as RtfUnsupportedDocumentKindError } from "./diagnostics-BgG_KAiN.cjs";
|
|
4
4
|
import { DEFAULT_MAX_GROUP_DEPTH, DEFAULT_MAX_INPUT_BYTES, ReadRtfOptions, RtfLineEnding, WriteRtfOptions } from "./options.cjs";
|
|
5
5
|
import { ReadRtfContentResult, ReadRtfResult, readRtf, readRtfContent } from "./read.cjs";
|
|
6
6
|
import { writeRtf, writeRtfContent } from "./write.cjs";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { rtfBytesFromLatin1 } from "./bytes.js";
|
|
2
2
|
import { RtfBytesSchema, rtfCodec, rtfContentCodec } from "./codec.js";
|
|
3
|
-
import { a as RtfDiagnosticSink, c as RtfNotAnRtfDocumentError, d as RtfWriteError, i as RtfDiagnosticSeverity, l as RtfParseError, n as RtfDiagnostic, o as RtfInputTooLargeError, r as RtfDiagnosticCodes, s as RtfNestingLimitExceededError, t as NOOP_RTF_DIAGNOSTIC_SINK, u as RtfUnsupportedDocumentKindError } from "./diagnostics-
|
|
3
|
+
import { a as RtfDiagnosticSink, c as RtfNotAnRtfDocumentError, d as RtfWriteError, i as RtfDiagnosticSeverity, l as RtfParseError, n as RtfDiagnostic, o as RtfInputTooLargeError, r as RtfDiagnosticCodes, s as RtfNestingLimitExceededError, t as NOOP_RTF_DIAGNOSTIC_SINK, u as RtfUnsupportedDocumentKindError } from "./diagnostics-BgG_KAiN.js";
|
|
4
4
|
import { DEFAULT_MAX_GROUP_DEPTH, DEFAULT_MAX_INPUT_BYTES, ReadRtfOptions, RtfLineEnding, WriteRtfOptions } from "./options.js";
|
|
5
5
|
import { ReadRtfContentResult, ReadRtfResult, readRtf, readRtfContent } from "./read.js";
|
|
6
6
|
import { writeRtf, writeRtfContent } from "./write.js";
|
package/dist/options.d.cts
CHANGED
package/dist/options.d.ts
CHANGED
package/dist/read.cjs
CHANGED
|
@@ -2,9 +2,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
const require_base64 = require("./base64.cjs");
|
|
3
3
|
const require_diagnostics = require("./diagnostics.cjs");
|
|
4
4
|
const require_bytes = require("./bytes.cjs");
|
|
5
|
+
const require_units = require("./units.cjs");
|
|
6
|
+
const require_cell_format = require("./cell-format.cjs");
|
|
7
|
+
const require_constructs = require("./constructs.cjs");
|
|
5
8
|
const require_codepage = require("./codepage.cjs");
|
|
6
9
|
const require_group = require("./group.cjs");
|
|
7
|
-
const require_units = require("./units.cjs");
|
|
8
10
|
const require_header = require("./header.cjs");
|
|
9
11
|
const require_list_id = require("./list-id.cjs");
|
|
10
12
|
require("./options.cjs");
|
|
@@ -43,8 +45,8 @@ const DESTINATION_KINDS = /* @__PURE__ */ new Map([
|
|
|
43
45
|
["atndate", "skip"],
|
|
44
46
|
["atnparent", "skip"],
|
|
45
47
|
["atnicn", "skip"],
|
|
46
|
-
["bkmkstart", "
|
|
47
|
-
["bkmkend", "
|
|
48
|
+
["bkmkstart", "bookmarkStart"],
|
|
49
|
+
["bkmkend", "bookmarkEnd"],
|
|
48
50
|
["object", "skip"],
|
|
49
51
|
["objdata", "skip"],
|
|
50
52
|
["objclass", "skip"],
|
|
@@ -129,6 +131,12 @@ const ALIGNMENTS = /* @__PURE__ */ new Map([
|
|
|
129
131
|
["qj", "justify"]
|
|
130
132
|
]);
|
|
131
133
|
const PICTURE_FORMATS = /* @__PURE__ */ new Map([["pngblip", "png"], ["jpegblip", "jpeg"]]);
|
|
134
|
+
const SECTION_BREAK_TYPES = /* @__PURE__ */ new Map([
|
|
135
|
+
["sbknone", "continuous"],
|
|
136
|
+
["sbkpage", void 0],
|
|
137
|
+
["sbkeven", "evenPage"],
|
|
138
|
+
["sbkodd", "oddPage"]
|
|
139
|
+
]);
|
|
132
140
|
function defaultCharacterState() {
|
|
133
141
|
return {
|
|
134
142
|
bold: false,
|
|
@@ -138,7 +146,8 @@ function defaultCharacterState() {
|
|
|
138
146
|
hidden: false,
|
|
139
147
|
fontIndex: void 0,
|
|
140
148
|
sizeHalfPoints: 24,
|
|
141
|
-
colorIndex: void 0
|
|
149
|
+
colorIndex: void 0,
|
|
150
|
+
revision: require_constructs.NO_REVISION
|
|
142
151
|
};
|
|
143
152
|
}
|
|
144
153
|
function defaultParagraphState() {
|
|
@@ -166,6 +175,7 @@ function cloneGroupState(state) {
|
|
|
166
175
|
para: { ...state.para },
|
|
167
176
|
field: state.field,
|
|
168
177
|
picture: state.picture,
|
|
178
|
+
bookmark: state.bookmark,
|
|
169
179
|
inUnicodeWrapper: state.inUnicodeWrapper
|
|
170
180
|
};
|
|
171
181
|
}
|
|
@@ -178,7 +188,8 @@ function runKey(char, fontName, color, hyperlink) {
|
|
|
178
188
|
fontName ?? "",
|
|
179
189
|
String(char.sizeHalfPoints),
|
|
180
190
|
color === void 0 ? "" : `${String(color.r)},${String(color.g)},${String(color.b)}`,
|
|
181
|
-
hyperlink ?? ""
|
|
191
|
+
hyperlink ?? "",
|
|
192
|
+
JSON.stringify(char.revision)
|
|
182
193
|
].join("|");
|
|
183
194
|
}
|
|
184
195
|
const HYPERLINK_TARGET = /HYPERLINK\s+"([^"]*)"/i;
|
|
@@ -218,6 +229,28 @@ function skipUnicodeFallback(tokens, from, count) {
|
|
|
218
229
|
textOffset
|
|
219
230
|
};
|
|
220
231
|
}
|
|
232
|
+
function insertConstructMarkers(blocks, extents) {
|
|
233
|
+
if (extents.length === 0) return [...blocks];
|
|
234
|
+
const ordered = [...extents].sort((left, right) => left.startIndex - right.startIndex || right.endIndex - left.endIndex);
|
|
235
|
+
const closing = [...ordered].reverse();
|
|
236
|
+
const out = [];
|
|
237
|
+
for (let index = 0; index <= blocks.length; index += 1) {
|
|
238
|
+
for (const extent of closing) if (extent.endIndex === index) out.push({ kind: "constructEnd" });
|
|
239
|
+
for (const extent of ordered) if (extent.startIndex === index) out.push({
|
|
240
|
+
kind: "constructStart",
|
|
241
|
+
descriptor: extent.descriptor
|
|
242
|
+
});
|
|
243
|
+
const block = blocks[index];
|
|
244
|
+
if (block !== void 0) out.push(block);
|
|
245
|
+
}
|
|
246
|
+
return out;
|
|
247
|
+
}
|
|
248
|
+
function horizontalSpanAt(definitions, index) {
|
|
249
|
+
if (definitions[index]?.horizontalMergeFirst !== true) return 1;
|
|
250
|
+
let span = 1;
|
|
251
|
+
while (definitions[index + span]?.horizontalMergeContinuation === true) span += 1;
|
|
252
|
+
return span;
|
|
253
|
+
}
|
|
221
254
|
var ContentBuilder = class {
|
|
222
255
|
header;
|
|
223
256
|
sink;
|
|
@@ -227,16 +260,63 @@ var ContentBuilder = class {
|
|
|
227
260
|
pendingRunKey;
|
|
228
261
|
pendingRunText = "";
|
|
229
262
|
pendingRunFields = {};
|
|
263
|
+
runProvenance = [];
|
|
264
|
+
pendingRunProvenance = [];
|
|
230
265
|
tableRows = [];
|
|
231
266
|
tableColumnRights = [];
|
|
232
267
|
rowCells = [];
|
|
233
268
|
cellBlocks = [];
|
|
234
269
|
pendingCellRights = [];
|
|
270
|
+
pendingCellDefinitions = [];
|
|
271
|
+
pendingCell = require_cell_format.newPendingCell();
|
|
235
272
|
rowLeftTwips = 0;
|
|
273
|
+
paragraphSerial = 0;
|
|
274
|
+
openBookmarks = /* @__PURE__ */ new Map();
|
|
275
|
+
sectionBlockExtents = [];
|
|
276
|
+
cellBlockExtents = [];
|
|
277
|
+
pendingRunConstructs = [];
|
|
278
|
+
closingBookmarks = [];
|
|
236
279
|
constructor(header, sink) {
|
|
237
280
|
this.header = header;
|
|
238
281
|
this.sink = sink;
|
|
239
282
|
}
|
|
283
|
+
startBookmark(bookmark, para) {
|
|
284
|
+
this.flushRun();
|
|
285
|
+
const name = bookmark.name;
|
|
286
|
+
if (name.length === 0) return;
|
|
287
|
+
this.openBookmarks.set(name, {
|
|
288
|
+
descriptor: require_constructs.bookmarkAnchorDescriptor(name, bookmark.columnFirst === void 0 && bookmark.columnLast === void 0 ? void 0 : {
|
|
289
|
+
first: bookmark.columnFirst,
|
|
290
|
+
last: bookmark.columnLast
|
|
291
|
+
}),
|
|
292
|
+
paragraphSerial: this.paragraphSerial,
|
|
293
|
+
runIndex: this.runs.length,
|
|
294
|
+
inTable: para.inTable,
|
|
295
|
+
blockIndex: void 0
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
endBookmark(name) {
|
|
299
|
+
this.flushRun();
|
|
300
|
+
const open = this.openBookmarks.get(name);
|
|
301
|
+
if (open === void 0) {
|
|
302
|
+
this.sink({
|
|
303
|
+
code: require_diagnostics.RtfDiagnosticCodes.BOOKMARK_UNPAIRED,
|
|
304
|
+
severity: "warning",
|
|
305
|
+
message: `a \\bkmkend named '${name}' has no matching \\bkmkstart, so no anchor construct is produced for it`
|
|
306
|
+
});
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
this.openBookmarks.delete(name);
|
|
310
|
+
if (open.paragraphSerial === this.paragraphSerial) {
|
|
311
|
+
this.pendingRunConstructs.push({
|
|
312
|
+
descriptor: open.descriptor,
|
|
313
|
+
startRun: open.runIndex,
|
|
314
|
+
endRun: this.runs.length
|
|
315
|
+
});
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
this.closingBookmarks.push(open);
|
|
319
|
+
}
|
|
240
320
|
appendText(text, char, hyperlink) {
|
|
241
321
|
if (text.length === 0 || char.hidden) return;
|
|
242
322
|
const fontName = char.fontIndex === void 0 ? void 0 : this.header.fonts.get(char.fontIndex)?.name;
|
|
@@ -246,32 +326,73 @@ var ContentBuilder = class {
|
|
|
246
326
|
this.flushRun();
|
|
247
327
|
this.pendingRunKey = key;
|
|
248
328
|
this.pendingRunFields = buildRunFields(char, fontName, color, hyperlink);
|
|
329
|
+
this.pendingRunProvenance = require_constructs.provenanceDescriptors(char.revision, this.header.revisionAuthors);
|
|
249
330
|
}
|
|
250
331
|
this.pendingRunText += text;
|
|
251
332
|
}
|
|
252
333
|
flushRun() {
|
|
253
|
-
if (this.pendingRunText.length > 0)
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
334
|
+
if (this.pendingRunText.length > 0) {
|
|
335
|
+
this.runs.push({
|
|
336
|
+
...this.pendingRunFields,
|
|
337
|
+
text: this.pendingRunText
|
|
338
|
+
});
|
|
339
|
+
this.runProvenance.push(this.pendingRunProvenance);
|
|
340
|
+
}
|
|
257
341
|
this.pendingRunText = "";
|
|
258
342
|
this.pendingRunKey = void 0;
|
|
259
343
|
this.pendingRunFields = {};
|
|
344
|
+
this.pendingRunProvenance = [];
|
|
260
345
|
}
|
|
261
346
|
endParagraph(para, force) {
|
|
262
347
|
this.flushRun();
|
|
263
348
|
if (!force && this.runs.length === 0) return;
|
|
264
349
|
const target = para.inTable ? this.cellBlocks : this.blocks;
|
|
265
350
|
if (!para.inTable) this.closeTable();
|
|
351
|
+
const blockIndex = target.length;
|
|
266
352
|
target.push(this.buildParagraph(para));
|
|
267
353
|
this.runs = [];
|
|
354
|
+
this.runProvenance = [];
|
|
355
|
+
this.resolveBookmarkPositions(para, blockIndex);
|
|
356
|
+
this.paragraphSerial += 1;
|
|
357
|
+
}
|
|
358
|
+
resolveBookmarkPositions(para, blockIndex) {
|
|
359
|
+
for (const open of this.openBookmarks.values()) if (open.blockIndex === void 0 && open.paragraphSerial === this.paragraphSerial) open.blockIndex = blockIndex;
|
|
360
|
+
this.flushClosingBookmarks(para.inTable, blockIndex + 1);
|
|
361
|
+
}
|
|
362
|
+
flushClosingBookmarks(inTable, endIndex) {
|
|
363
|
+
if (this.closingBookmarks.length === 0) return;
|
|
364
|
+
const target = inTable ? this.cellBlockExtents : this.sectionBlockExtents;
|
|
365
|
+
for (const closing of this.closingBookmarks) {
|
|
366
|
+
if (closing.inTable !== inTable) {
|
|
367
|
+
this.sink({
|
|
368
|
+
code: require_diagnostics.RtfDiagnosticCodes.BOOKMARK_UNPAIRED,
|
|
369
|
+
severity: "warning",
|
|
370
|
+
message: `the bookmark '${closing.descriptor.name}' spans a table cell boundary; a construct extent cannot straddle two block lists, so no anchor construct is produced for it`
|
|
371
|
+
});
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
target.push({
|
|
375
|
+
descriptor: closing.descriptor,
|
|
376
|
+
startIndex: closing.blockIndex ?? Math.max(0, endIndex - 1),
|
|
377
|
+
endIndex
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
this.closingBookmarks = [];
|
|
381
|
+
}
|
|
382
|
+
takeRunConstructs() {
|
|
383
|
+
const extents = [...this.pendingRunConstructs, ...require_constructs.coalesceRunConstructs(this.runProvenance)].filter((extent) => extent.endRun <= this.runs.length);
|
|
384
|
+
this.pendingRunConstructs = [];
|
|
385
|
+
this.runProvenance = [];
|
|
386
|
+
return extents.sort((left, right) => left.startRun - right.startRun || left.endRun - right.endRun);
|
|
268
387
|
}
|
|
269
388
|
buildParagraph(para) {
|
|
270
389
|
const style = para.styleIndex === void 0 ? void 0 : this.header.styles.get(para.styleIndex);
|
|
271
390
|
const headingLevel = para.outlineLevel === void 0 ? style?.headingLevel : para.outlineLevel + 1;
|
|
391
|
+
const constructs = this.takeRunConstructs();
|
|
272
392
|
const paragraph = {
|
|
273
393
|
kind: "paragraph",
|
|
274
|
-
runs: this.runs
|
|
394
|
+
runs: this.runs,
|
|
395
|
+
...constructs.length === 0 ? {} : { constructs }
|
|
275
396
|
};
|
|
276
397
|
const withStyle = style?.name === void 0 || style.name.length === 0 ? paragraph : {
|
|
277
398
|
...paragraph,
|
|
@@ -315,18 +436,27 @@ var ContentBuilder = class {
|
|
|
315
436
|
}
|
|
316
437
|
startRowDefinition() {
|
|
317
438
|
this.pendingCellRights = [];
|
|
439
|
+
this.pendingCellDefinitions = [];
|
|
440
|
+
this.pendingCell = require_cell_format.newPendingCell();
|
|
318
441
|
this.rowLeftTwips = 0;
|
|
319
442
|
}
|
|
320
443
|
setRowLeft(twips) {
|
|
321
444
|
this.rowLeftTwips = twips;
|
|
322
445
|
}
|
|
446
|
+
applyCellDefinition(name, param) {
|
|
447
|
+
return require_cell_format.applyCellDefinitionControlWord(name, param, this.pendingCell);
|
|
448
|
+
}
|
|
323
449
|
addCellBoundary(rightTwips) {
|
|
324
450
|
this.pendingCellRights.push(rightTwips);
|
|
451
|
+
this.pendingCellDefinitions.push(this.pendingCell);
|
|
452
|
+
this.pendingCell = require_cell_format.newPendingCell();
|
|
325
453
|
}
|
|
326
454
|
endCell(para) {
|
|
327
455
|
this.endParagraph(para, false);
|
|
328
|
-
this.
|
|
456
|
+
this.flushClosingBookmarks(true, this.cellBlocks.length);
|
|
457
|
+
this.rowCells.push({ blocks: insertConstructMarkers(this.cellBlocks, this.cellBlockExtents) });
|
|
329
458
|
this.cellBlocks = [];
|
|
459
|
+
this.cellBlockExtents = [];
|
|
330
460
|
}
|
|
331
461
|
endRow(para) {
|
|
332
462
|
if (this.cellBlocks.length > 0 || this.pendingRunText.length > 0) this.endCell(para);
|
|
@@ -338,21 +468,75 @@ var ContentBuilder = class {
|
|
|
338
468
|
});
|
|
339
469
|
return;
|
|
340
470
|
}
|
|
341
|
-
this.tableRows.push({
|
|
471
|
+
this.tableRows.push({
|
|
472
|
+
cells: this.rowCells,
|
|
473
|
+
definitions: this.pendingCellDefinitions
|
|
474
|
+
});
|
|
342
475
|
if (this.tableColumnRights.length === 0) this.tableColumnRights = [...this.pendingCellRights];
|
|
343
476
|
this.rowCells = [];
|
|
344
477
|
}
|
|
345
478
|
closeTable() {
|
|
346
479
|
if (this.tableRows.length === 0) return;
|
|
347
|
-
const
|
|
480
|
+
const rows = this.resolveRows();
|
|
481
|
+
const columnCount = Math.max(this.tableColumnRights.length, ...rows.map((row) => row.cells.reduce((total, cell) => total + (cell.colSpan ?? 1), 0)));
|
|
348
482
|
this.blocks.push({
|
|
349
483
|
kind: "table",
|
|
350
|
-
rows
|
|
484
|
+
rows,
|
|
351
485
|
columnWidthsPt: this.columnWidths(columnCount)
|
|
352
486
|
});
|
|
353
487
|
this.tableRows = [];
|
|
354
488
|
this.tableColumnRights = [];
|
|
355
489
|
}
|
|
490
|
+
resolveRows() {
|
|
491
|
+
const rows = this.tableRows;
|
|
492
|
+
const columnIndices = rows.map((row) => {
|
|
493
|
+
const indices = [];
|
|
494
|
+
let column = 0;
|
|
495
|
+
for (const [index] of row.cells.entries()) {
|
|
496
|
+
indices.push(column);
|
|
497
|
+
column += horizontalSpanAt(row.definitions, index);
|
|
498
|
+
}
|
|
499
|
+
return indices;
|
|
500
|
+
});
|
|
501
|
+
return rows.map((row, rowIndex) => ({ cells: row.cells.map((cell, cellIndex) => ({
|
|
502
|
+
cell,
|
|
503
|
+
cellIndex
|
|
504
|
+
})).filter(({ cellIndex }) => row.definitions[cellIndex]?.horizontalMergeContinuation !== true).map(({ cell, cellIndex }) => {
|
|
505
|
+
const definition = row.definitions[cellIndex];
|
|
506
|
+
if (definition?.verticalMergeContinuation === true) return { blocks: [] };
|
|
507
|
+
const colSpan = horizontalSpanAt(row.definitions, cellIndex);
|
|
508
|
+
const column = columnIndices[rowIndex]?.[cellIndex];
|
|
509
|
+
let rowSpan = 1;
|
|
510
|
+
if (definition?.verticalMergeFirst === true && column !== void 0) for (let next = rowIndex + 1; next < rows.length; next += 1) {
|
|
511
|
+
const matchIndex = columnIndices[next]?.indexOf(column) ?? -1;
|
|
512
|
+
if ((matchIndex === -1 ? void 0 : rows[next]?.definitions[matchIndex])?.verticalMergeContinuation !== true) break;
|
|
513
|
+
rowSpan += 1;
|
|
514
|
+
}
|
|
515
|
+
const borders = this.resolveBorders(definition);
|
|
516
|
+
const background = definition?.backgroundIndex === void 0 ? void 0 : this.header.colors[definition.backgroundIndex];
|
|
517
|
+
return {
|
|
518
|
+
blocks: cell.blocks,
|
|
519
|
+
...colSpan > 1 ? { colSpan } : {},
|
|
520
|
+
...rowSpan > 1 ? { rowSpan } : {},
|
|
521
|
+
...background === void 0 ? {} : { background },
|
|
522
|
+
...borders === void 0 ? {} : { borders }
|
|
523
|
+
};
|
|
524
|
+
}) }));
|
|
525
|
+
}
|
|
526
|
+
resolveBorders(definition) {
|
|
527
|
+
if (definition === void 0) return;
|
|
528
|
+
const colorAt = (index) => this.header.colors[index];
|
|
529
|
+
const present = [
|
|
530
|
+
"top",
|
|
531
|
+
"left",
|
|
532
|
+
"bottom",
|
|
533
|
+
"right"
|
|
534
|
+
].map((side) => {
|
|
535
|
+
const pending = definition.borders[side];
|
|
536
|
+
return [side, pending === void 0 ? void 0 : require_cell_format.resolveBorder(pending, colorAt)];
|
|
537
|
+
}).filter((entry) => entry[1] !== void 0);
|
|
538
|
+
return present.length === 0 ? void 0 : Object.fromEntries(present);
|
|
539
|
+
}
|
|
356
540
|
columnWidths(columnCount) {
|
|
357
541
|
const rights = this.tableColumnRights;
|
|
358
542
|
const widths = [];
|
|
@@ -376,22 +560,36 @@ var ContentBuilder = class {
|
|
|
376
560
|
this.flushRun();
|
|
377
561
|
this.blocks.push(block);
|
|
378
562
|
}
|
|
379
|
-
endSection(
|
|
563
|
+
endSection(section, para) {
|
|
380
564
|
this.endParagraph(para, false);
|
|
381
565
|
this.closeTable();
|
|
382
|
-
|
|
566
|
+
this.flushClosingBookmarks(false, this.blocks.length);
|
|
567
|
+
this.reportUnclosedBookmarks();
|
|
568
|
+
const blocks = insertConstructMarkers(this.blocks, this.sectionBlockExtents);
|
|
569
|
+
this.sectionBlockExtents = [];
|
|
570
|
+
if (blocks.length === 0 && this.sections.length > 0) {
|
|
571
|
+
this.blocks = [];
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
383
574
|
this.sections.push({
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
blocks
|
|
575
|
+
...sectionGeometry(section),
|
|
576
|
+
...section.breakType === void 0 ? {} : { breakType: section.breakType },
|
|
577
|
+
blocks
|
|
387
578
|
});
|
|
388
579
|
this.blocks = [];
|
|
389
580
|
}
|
|
390
|
-
|
|
391
|
-
this.
|
|
581
|
+
reportUnclosedBookmarks() {
|
|
582
|
+
for (const open of this.openBookmarks.values()) this.sink({
|
|
583
|
+
code: require_diagnostics.RtfDiagnosticCodes.BOOKMARK_UNPAIRED,
|
|
584
|
+
severity: "warning",
|
|
585
|
+
message: `the bookmark '${open.descriptor.name}' has no matching \\bkmkend within its own block flow, so no anchor construct is produced for it`
|
|
586
|
+
});
|
|
587
|
+
this.openBookmarks.clear();
|
|
588
|
+
}
|
|
589
|
+
finish(metadata, section, para) {
|
|
590
|
+
this.endSection(section, para);
|
|
392
591
|
if (this.sections.length === 0) this.sections.push({
|
|
393
|
-
|
|
394
|
-
margins,
|
|
592
|
+
...sectionGeometry(section),
|
|
395
593
|
blocks: []
|
|
396
594
|
});
|
|
397
595
|
return {
|
|
@@ -401,6 +599,31 @@ var ContentBuilder = class {
|
|
|
401
599
|
};
|
|
402
600
|
}
|
|
403
601
|
};
|
|
602
|
+
function sectionGeometry(section) {
|
|
603
|
+
return {
|
|
604
|
+
pageSize: {
|
|
605
|
+
widthPt: require_units.twipsToPoints(section.paperWidthTwips),
|
|
606
|
+
heightPt: require_units.twipsToPoints(section.paperHeightTwips)
|
|
607
|
+
},
|
|
608
|
+
margins: {
|
|
609
|
+
topPt: require_units.twipsToPoints(section.marginTopTwips),
|
|
610
|
+
rightPt: require_units.twipsToPoints(section.marginRightTwips),
|
|
611
|
+
bottomPt: require_units.twipsToPoints(section.marginBottomTwips),
|
|
612
|
+
leftPt: require_units.twipsToPoints(section.marginLeftTwips)
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
function defaultSectionState(header) {
|
|
617
|
+
return {
|
|
618
|
+
paperWidthTwips: header.page.paperWidthTwips,
|
|
619
|
+
paperHeightTwips: header.page.paperHeightTwips,
|
|
620
|
+
marginLeftTwips: header.page.marginLeftTwips,
|
|
621
|
+
marginRightTwips: header.page.marginRightTwips,
|
|
622
|
+
marginTopTwips: header.page.marginTopTwips,
|
|
623
|
+
marginBottomTwips: header.page.marginBottomTwips,
|
|
624
|
+
breakType: void 0
|
|
625
|
+
};
|
|
626
|
+
}
|
|
404
627
|
function buildRunFields(char, fontName, color, hyperlink) {
|
|
405
628
|
return {
|
|
406
629
|
...char.bold ? { bold: true } : {},
|
|
@@ -493,16 +716,7 @@ function readRtfDetail(input, options) {
|
|
|
493
716
|
assertRtfHeaderPresent(tokens);
|
|
494
717
|
const header = require_header.readRtfHeader(tokens, sink);
|
|
495
718
|
const builder = new ContentBuilder(header, sink);
|
|
496
|
-
const
|
|
497
|
-
widthPt: require_units.twipsToPoints(header.page.paperWidthTwips),
|
|
498
|
-
heightPt: require_units.twipsToPoints(header.page.paperHeightTwips)
|
|
499
|
-
};
|
|
500
|
-
const margins = {
|
|
501
|
-
topPt: require_units.twipsToPoints(header.page.marginTopTwips),
|
|
502
|
-
rightPt: require_units.twipsToPoints(header.page.marginRightTwips),
|
|
503
|
-
bottomPt: require_units.twipsToPoints(header.page.marginBottomTwips),
|
|
504
|
-
leftPt: require_units.twipsToPoints(header.page.marginLeftTwips)
|
|
505
|
-
};
|
|
719
|
+
const section = defaultSectionState(header);
|
|
506
720
|
const root = {
|
|
507
721
|
destination: "body",
|
|
508
722
|
uc: 1,
|
|
@@ -510,6 +724,7 @@ function readRtfDetail(input, options) {
|
|
|
510
724
|
para: defaultParagraphState(),
|
|
511
725
|
field: void 0,
|
|
512
726
|
picture: void 0,
|
|
727
|
+
bookmark: void 0,
|
|
513
728
|
inUnicodeWrapper: false
|
|
514
729
|
};
|
|
515
730
|
const stack = [root];
|
|
@@ -530,7 +745,14 @@ function readRtfDetail(input, options) {
|
|
|
530
745
|
builder.appendText(text, state.char, hyperlink);
|
|
531
746
|
return;
|
|
532
747
|
}
|
|
533
|
-
if (state.destination === "fieldInstruction" && state.field !== void 0)
|
|
748
|
+
if (state.destination === "fieldInstruction" && state.field !== void 0) {
|
|
749
|
+
state.field.instruction += text;
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
if ((state.destination === "bookmarkStart" || state.destination === "bookmarkEnd") && state.bookmark !== void 0) {
|
|
753
|
+
state.bookmark.name += text;
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
534
756
|
};
|
|
535
757
|
let index = 0;
|
|
536
758
|
let textOffset = 0;
|
|
@@ -568,6 +790,11 @@ function readRtfDetail(input, options) {
|
|
|
568
790
|
child.destination = kind;
|
|
569
791
|
if (head.destination === "field") child.field = { instruction: "" };
|
|
570
792
|
if (kind === "picture") child.picture = defaultPictureState();
|
|
793
|
+
if (kind === "bookmarkStart" || kind === "bookmarkEnd") child.bookmark = {
|
|
794
|
+
name: "",
|
|
795
|
+
columnFirst: void 0,
|
|
796
|
+
columnLast: void 0
|
|
797
|
+
};
|
|
571
798
|
index = head.contentStart;
|
|
572
799
|
} else index += 1;
|
|
573
800
|
stack.push(child);
|
|
@@ -581,6 +808,14 @@ function readRtfDetail(input, options) {
|
|
|
581
808
|
const image = buildPicture(state.picture, sink);
|
|
582
809
|
if (image !== void 0) builder.addBlock(image);
|
|
583
810
|
}
|
|
811
|
+
if (state.bookmark !== void 0) {
|
|
812
|
+
const bookmark = {
|
|
813
|
+
...state.bookmark,
|
|
814
|
+
name: state.bookmark.name.trim()
|
|
815
|
+
};
|
|
816
|
+
if (state.destination === "bookmarkStart") builder.startBookmark(bookmark, state.para);
|
|
817
|
+
else if (state.destination === "bookmarkEnd") builder.endBookmark(bookmark.name);
|
|
818
|
+
}
|
|
584
819
|
if (stack.length > 1) {
|
|
585
820
|
stack.pop();
|
|
586
821
|
const parent = stack[stack.length - 1];
|
|
@@ -643,7 +878,7 @@ function readRtfDetail(input, options) {
|
|
|
643
878
|
continue;
|
|
644
879
|
}
|
|
645
880
|
flushBytes();
|
|
646
|
-
applyControlWord(token.name, token.param, state, builder, header, sink);
|
|
881
|
+
applyControlWord(token.name, token.param, state, builder, header, section, sink);
|
|
647
882
|
index += 1;
|
|
648
883
|
}
|
|
649
884
|
flushBytes();
|
|
@@ -653,7 +888,7 @@ function readRtfDetail(input, options) {
|
|
|
653
888
|
message: `${String(stack.length - 1)} group(s) were still open at the end of the input; each is treated as closing there`
|
|
654
889
|
});
|
|
655
890
|
return {
|
|
656
|
-
document: builder.finish(header.metadata,
|
|
891
|
+
document: builder.finish(header.metadata, section, root.para),
|
|
657
892
|
diagnostics
|
|
658
893
|
};
|
|
659
894
|
}
|
|
@@ -730,6 +965,78 @@ function applyCharacterControlWord(name, param, state, header) {
|
|
|
730
965
|
case "uc":
|
|
731
966
|
if (param !== void 0 && param >= 0) state.uc = param;
|
|
732
967
|
return true;
|
|
968
|
+
case "revised":
|
|
969
|
+
state.char.revision = {
|
|
970
|
+
...state.char.revision,
|
|
971
|
+
revised: toggleValue(param)
|
|
972
|
+
};
|
|
973
|
+
return true;
|
|
974
|
+
case "revauth":
|
|
975
|
+
state.char.revision = {
|
|
976
|
+
...state.char.revision,
|
|
977
|
+
revisedAuthor: param
|
|
978
|
+
};
|
|
979
|
+
return true;
|
|
980
|
+
case "revdttm":
|
|
981
|
+
state.char.revision = {
|
|
982
|
+
...state.char.revision,
|
|
983
|
+
revisedDateTime: param
|
|
984
|
+
};
|
|
985
|
+
return true;
|
|
986
|
+
case "deleted":
|
|
987
|
+
state.char.revision = {
|
|
988
|
+
...state.char.revision,
|
|
989
|
+
deleted: toggleValue(param)
|
|
990
|
+
};
|
|
991
|
+
return true;
|
|
992
|
+
case "revauthdel":
|
|
993
|
+
state.char.revision = {
|
|
994
|
+
...state.char.revision,
|
|
995
|
+
deletedAuthor: param
|
|
996
|
+
};
|
|
997
|
+
return true;
|
|
998
|
+
case "revdttmdel":
|
|
999
|
+
state.char.revision = {
|
|
1000
|
+
...state.char.revision,
|
|
1001
|
+
deletedDateTime: param
|
|
1002
|
+
};
|
|
1003
|
+
return true;
|
|
1004
|
+
case "mvf":
|
|
1005
|
+
state.char.revision = {
|
|
1006
|
+
...state.char.revision,
|
|
1007
|
+
moved: toggleValue(param) ? "moveFrom" : void 0
|
|
1008
|
+
};
|
|
1009
|
+
return true;
|
|
1010
|
+
case "mvt":
|
|
1011
|
+
state.char.revision = {
|
|
1012
|
+
...state.char.revision,
|
|
1013
|
+
moved: toggleValue(param) ? "moveTo" : void 0
|
|
1014
|
+
};
|
|
1015
|
+
return true;
|
|
1016
|
+
case "mvauth":
|
|
1017
|
+
state.char.revision = {
|
|
1018
|
+
...state.char.revision,
|
|
1019
|
+
movedAuthor: param
|
|
1020
|
+
};
|
|
1021
|
+
return true;
|
|
1022
|
+
case "mvdate":
|
|
1023
|
+
state.char.revision = {
|
|
1024
|
+
...state.char.revision,
|
|
1025
|
+
movedDateTime: param
|
|
1026
|
+
};
|
|
1027
|
+
return true;
|
|
1028
|
+
case "crauth":
|
|
1029
|
+
state.char.revision = {
|
|
1030
|
+
...state.char.revision,
|
|
1031
|
+
formatAuthor: param
|
|
1032
|
+
};
|
|
1033
|
+
return true;
|
|
1034
|
+
case "crdate":
|
|
1035
|
+
state.char.revision = {
|
|
1036
|
+
...state.char.revision,
|
|
1037
|
+
formatDateTime: param
|
|
1038
|
+
};
|
|
1039
|
+
return true;
|
|
733
1040
|
default:
|
|
734
1041
|
if (name.startsWith("ul") && name !== "ulc") {
|
|
735
1042
|
state.char.underline = toggleValue(param);
|
|
@@ -788,7 +1095,48 @@ function applyParagraphControlWord(name, param, state) {
|
|
|
788
1095
|
default: return false;
|
|
789
1096
|
}
|
|
790
1097
|
}
|
|
791
|
-
function
|
|
1098
|
+
function applySectionControlWord(name, param, section, header, sink) {
|
|
1099
|
+
if (name === "sectd") {
|
|
1100
|
+
Object.assign(section, defaultSectionState(header));
|
|
1101
|
+
return true;
|
|
1102
|
+
}
|
|
1103
|
+
if (name === "sbkcol") {
|
|
1104
|
+
sink({
|
|
1105
|
+
code: require_diagnostics.RtfDiagnosticCodes.SECTION_BREAK_UNREPRESENTED,
|
|
1106
|
+
severity: "info",
|
|
1107
|
+
message: "\\sbkcol starts the section at a new column; ContentSection.breakType names page-level breaks only, so the break kind is dropped and the section itself is kept"
|
|
1108
|
+
});
|
|
1109
|
+
section.breakType = void 0;
|
|
1110
|
+
return true;
|
|
1111
|
+
}
|
|
1112
|
+
if (SECTION_BREAK_TYPES.has(name)) {
|
|
1113
|
+
section.breakType = SECTION_BREAK_TYPES.get(name);
|
|
1114
|
+
return true;
|
|
1115
|
+
}
|
|
1116
|
+
if (param === void 0) return false;
|
|
1117
|
+
switch (name) {
|
|
1118
|
+
case "pgwsxn":
|
|
1119
|
+
section.paperWidthTwips = param;
|
|
1120
|
+
return true;
|
|
1121
|
+
case "pghsxn":
|
|
1122
|
+
section.paperHeightTwips = param;
|
|
1123
|
+
return true;
|
|
1124
|
+
case "marglsxn":
|
|
1125
|
+
section.marginLeftTwips = param;
|
|
1126
|
+
return true;
|
|
1127
|
+
case "margrsxn":
|
|
1128
|
+
section.marginRightTwips = param;
|
|
1129
|
+
return true;
|
|
1130
|
+
case "margtsxn":
|
|
1131
|
+
section.marginTopTwips = param;
|
|
1132
|
+
return true;
|
|
1133
|
+
case "margbsxn":
|
|
1134
|
+
section.marginBottomTwips = param;
|
|
1135
|
+
return true;
|
|
1136
|
+
default: return false;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
function applyStructureControlWord(name, param, state, builder, section, sink) {
|
|
792
1140
|
switch (name) {
|
|
793
1141
|
case "par":
|
|
794
1142
|
builder.endParagraph(state.para, true);
|
|
@@ -824,20 +1172,29 @@ function applyStructureControlWord(name, param, state, builder, sink) {
|
|
|
824
1172
|
return true;
|
|
825
1173
|
case "sect":
|
|
826
1174
|
builder.endParagraph(state.para, true);
|
|
1175
|
+
builder.endSection(section, state.para);
|
|
827
1176
|
return true;
|
|
828
|
-
case "sectd": return true;
|
|
829
1177
|
default: return false;
|
|
830
1178
|
}
|
|
831
1179
|
}
|
|
832
|
-
function applyControlWord(name, param, state, builder, header, sink) {
|
|
1180
|
+
function applyControlWord(name, param, state, builder, header, section, sink) {
|
|
833
1181
|
const picture = state.picture;
|
|
834
1182
|
if (state.destination === "picture" && picture !== void 0) {
|
|
835
1183
|
applyPictureControlWord(name, param, picture);
|
|
836
1184
|
return;
|
|
837
1185
|
}
|
|
1186
|
+
const bookmark = state.bookmark;
|
|
1187
|
+
if (bookmark !== void 0 && state.destination === "bookmarkStart") {
|
|
1188
|
+
if (name === "bkmkcolf") bookmark.columnFirst = param;
|
|
1189
|
+
else if (name === "bkmkcoll") bookmark.columnLast = param;
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
if (state.destination === "bookmarkEnd") return;
|
|
838
1193
|
if (applyCharacterControlWord(name, param, state, header)) return;
|
|
1194
|
+
if (builder.applyCellDefinition(name, param)) return;
|
|
839
1195
|
if (applyParagraphControlWord(name, param, state)) return;
|
|
840
|
-
|
|
1196
|
+
if (applySectionControlWord(name, param, section, header, sink)) return;
|
|
1197
|
+
applyStructureControlWord(name, param, state, builder, section, sink);
|
|
841
1198
|
}
|
|
842
1199
|
function readRtfContent(input, options = {}) {
|
|
843
1200
|
return readRtfDetail(typeof input === "string" ? require_bytes.rtfBytesFromLatin1(input) : input, options);
|