rtf-codec 1.0.0 → 1.1.1
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/write.cjs
CHANGED
|
@@ -2,6 +2,8 @@ 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_units = require("./units.cjs");
|
|
5
|
+
const require_cell_format = require("./cell-format.cjs");
|
|
6
|
+
const require_constructs = require("./constructs.cjs");
|
|
5
7
|
const require_list_id = require("./list-id.cjs");
|
|
6
8
|
let document_schema_js = require("document-schema.js");
|
|
7
9
|
//#region src/write.ts
|
|
@@ -12,28 +14,47 @@ const LIST_MARKER_HANG_TWIPS = 360;
|
|
|
12
14
|
const BULLET_LEVEL_TEXT = "\\'01\\u183 ?";
|
|
13
15
|
const ARABIC_LEVEL_TEXT = "\\'02\\'00.";
|
|
14
16
|
const OUTPUT_CODEPAGE = 1252;
|
|
17
|
+
const SECTION_BREAK_CONTROL_WORDS = /* @__PURE__ */ new Map([
|
|
18
|
+
["continuous", "\\sbknone"],
|
|
19
|
+
["evenPage", "\\sbkeven"],
|
|
20
|
+
["oddPage", "\\sbkodd"]
|
|
21
|
+
]);
|
|
15
22
|
const ALIGNMENT_CONTROL_WORDS = /* @__PURE__ */ new Map([
|
|
16
23
|
["left", "\\ql"],
|
|
17
24
|
["center", "\\qc"],
|
|
18
25
|
["right", "\\qr"],
|
|
19
26
|
["justify", "\\qj"]
|
|
20
27
|
]);
|
|
28
|
+
const UNKNOWN_REVISION_AUTHOR = "Unknown";
|
|
21
29
|
const DEFAULT_FONT_NAME = "Times New Roman";
|
|
22
30
|
function collectTables(document) {
|
|
23
31
|
const fonts = /* @__PURE__ */ new Map([[DEFAULT_FONT_NAME, 0]]);
|
|
24
32
|
const colors = /* @__PURE__ */ new Map();
|
|
25
33
|
const headingStyles = /* @__PURE__ */ new Map();
|
|
26
34
|
const lists = /* @__PURE__ */ new Map();
|
|
35
|
+
const revisionAuthors = /* @__PURE__ */ new Map([[UNKNOWN_REVISION_AUTHOR, 0]]);
|
|
36
|
+
const noteDescriptor = (descriptor) => {
|
|
37
|
+
if (descriptor.kind !== "provenance") return;
|
|
38
|
+
const author = descriptor.author;
|
|
39
|
+
if (author !== void 0 && !revisionAuthors.has(author)) revisionAuthors.set(author, revisionAuthors.size);
|
|
40
|
+
};
|
|
41
|
+
const noteColor = (color) => {
|
|
42
|
+
if (color === void 0) return;
|
|
43
|
+
const hex = (0, document_schema_js.colorToRgbHex)(color);
|
|
44
|
+
if (!colors.has(hex)) colors.set(hex, colors.size + 1);
|
|
45
|
+
};
|
|
27
46
|
const noteRun = (run) => {
|
|
28
47
|
if (run.fontFamily !== void 0 && !fonts.has(run.fontFamily)) fonts.set(run.fontFamily, fonts.size);
|
|
29
|
-
|
|
30
|
-
const hex = (0, document_schema_js.colorToRgbHex)(run.color);
|
|
31
|
-
if (!colors.has(hex)) colors.set(hex, colors.size + 1);
|
|
32
|
-
}
|
|
48
|
+
noteColor(run.color);
|
|
33
49
|
};
|
|
34
50
|
const noteBlock = (block) => {
|
|
51
|
+
if (block.kind === "constructStart") {
|
|
52
|
+
noteDescriptor(block.descriptor);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
35
55
|
if (block.kind === "paragraph") {
|
|
36
56
|
for (const run of block.runs) noteRun(run);
|
|
57
|
+
for (const extent of block.constructs ?? []) noteDescriptor(extent.descriptor);
|
|
37
58
|
if (block.headingLevel !== void 0) {
|
|
38
59
|
const level = (0, document_schema_js.clampHeadingLevel)(block.headingLevel);
|
|
39
60
|
if (!headingStyles.has(level)) headingStyles.set(level, level);
|
|
@@ -51,14 +72,19 @@ function collectTables(document) {
|
|
|
51
72
|
}
|
|
52
73
|
return;
|
|
53
74
|
}
|
|
54
|
-
if (block.kind === "table") for (const row of block.rows) for (const cell of row.cells)
|
|
75
|
+
if (block.kind === "table") for (const row of block.rows) for (const cell of row.cells) {
|
|
76
|
+
noteColor(cell.background);
|
|
77
|
+
for (const side of CELL_BORDER_ORDER) noteColor(cell.borders?.[side]?.color);
|
|
78
|
+
for (const inner of cell.blocks) noteBlock(inner);
|
|
79
|
+
}
|
|
55
80
|
};
|
|
56
81
|
if (document.kind === "wordprocessing") for (const section of document.sections) for (const block of section.blocks) noteBlock(block);
|
|
57
82
|
return {
|
|
58
83
|
fonts,
|
|
59
84
|
colors,
|
|
60
85
|
headingStyles,
|
|
61
|
-
lists
|
|
86
|
+
lists,
|
|
87
|
+
revisionAuthors
|
|
62
88
|
};
|
|
63
89
|
}
|
|
64
90
|
function escapeText(text) {
|
|
@@ -95,11 +121,76 @@ function escapeText(text) {
|
|
|
95
121
|
}
|
|
96
122
|
return out;
|
|
97
123
|
}
|
|
124
|
+
function bookmarkStartGroup(descriptor) {
|
|
125
|
+
if (!require_constructs.isBookmarkAnchor(descriptor)) return "";
|
|
126
|
+
return `{\\*\\bkmkstart${require_constructs.bookmarkResidueControlWords(descriptor)} ${escapeText(descriptor.name)}}`;
|
|
127
|
+
}
|
|
128
|
+
const CHREV_CONTROL_WORDS = {
|
|
129
|
+
insertion: {
|
|
130
|
+
flag: "\\revised",
|
|
131
|
+
author: "revauth",
|
|
132
|
+
date: "revdttm"
|
|
133
|
+
},
|
|
134
|
+
deletion: {
|
|
135
|
+
flag: "\\deleted",
|
|
136
|
+
author: "revauthdel",
|
|
137
|
+
date: "revdttmdel"
|
|
138
|
+
},
|
|
139
|
+
moveFrom: {
|
|
140
|
+
flag: "\\mvf",
|
|
141
|
+
author: "mvauth",
|
|
142
|
+
date: "mvdate"
|
|
143
|
+
},
|
|
144
|
+
moveTo: {
|
|
145
|
+
flag: "\\mvt",
|
|
146
|
+
author: "mvauth",
|
|
147
|
+
date: "mvdate"
|
|
148
|
+
},
|
|
149
|
+
formatChange: {
|
|
150
|
+
flag: "",
|
|
151
|
+
author: "crauth",
|
|
152
|
+
date: "crdate"
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
function revisionsCovering(extents, index) {
|
|
156
|
+
return extents.filter((extent) => extent.descriptor.kind === "provenance" && extent.startRun <= index && index < extent.endRun).map((extent) => extent.descriptor).filter((descriptor) => descriptor.kind === "provenance");
|
|
157
|
+
}
|
|
158
|
+
const CELL_BORDER_ORDER = [
|
|
159
|
+
"top",
|
|
160
|
+
"left",
|
|
161
|
+
"bottom",
|
|
162
|
+
"right"
|
|
163
|
+
];
|
|
164
|
+
function verticalMergeCoverage(table) {
|
|
165
|
+
const covered = table.rows.map((row) => row.cells.map(() => false));
|
|
166
|
+
for (const [rowIndex, row] of table.rows.entries()) for (const [cellIndex, cell] of row.cells.entries()) {
|
|
167
|
+
const rowSpan = cell.rowSpan ?? 1;
|
|
168
|
+
for (let next = 1; next < rowSpan; next += 1) {
|
|
169
|
+
const target = covered[rowIndex + next];
|
|
170
|
+
if (target !== void 0 && cellIndex < target.length) target[cellIndex] = true;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return covered;
|
|
174
|
+
}
|
|
175
|
+
function nameOf(descriptor) {
|
|
176
|
+
return require_constructs.isBookmarkAnchor(descriptor) ? descriptor.name : "";
|
|
177
|
+
}
|
|
178
|
+
function describeConstructGap(descriptor) {
|
|
179
|
+
switch (descriptor.kind) {
|
|
180
|
+
case "contentControl": return "structured-document-tag equivalent; its own \\*\\formfield production is a narrower construct this writer does not yet mint";
|
|
181
|
+
case "provenance": return "block-scoped revision mark: its <chrev> production is a character property, so a tracked change reaches RTF only as a run-level extent";
|
|
182
|
+
case "anchor": return `spelling for a '${descriptor.anchorType}' anchor, whose body would need the note or annotation destination this reader does not place`;
|
|
183
|
+
case "field": return "block-scoped field: a field is a character-stream construct, written from a run's own hyperlink rather than from a block marker";
|
|
184
|
+
case "link": return "block-scoped link; an external target rides ContentRun.hyperlink instead";
|
|
185
|
+
default: return "equivalent construct";
|
|
186
|
+
}
|
|
187
|
+
}
|
|
98
188
|
var RtfWriter = class {
|
|
99
189
|
tables;
|
|
100
190
|
sink;
|
|
101
191
|
lineEnding;
|
|
102
192
|
out = "";
|
|
193
|
+
openConstructs = [];
|
|
103
194
|
constructor(tables, sink, lineEnding) {
|
|
104
195
|
this.tables = tables;
|
|
105
196
|
this.sink = sink;
|
|
@@ -116,10 +207,12 @@ var RtfWriter = class {
|
|
|
116
207
|
}
|
|
117
208
|
writeHeader(document) {
|
|
118
209
|
this.raw(`{\\rtf1\\ansi\\ansicpg${String(OUTPUT_CODEPAGE)}\\deff0\\uc1`);
|
|
210
|
+
this.writeDocumentGeometry(document);
|
|
119
211
|
this.writeFontTable();
|
|
120
212
|
this.writeColorTable();
|
|
121
213
|
this.writeStyleSheet();
|
|
122
214
|
this.writeListTables();
|
|
215
|
+
this.writeRevisionTable();
|
|
123
216
|
this.writeInfoGroup(document);
|
|
124
217
|
this.line("");
|
|
125
218
|
}
|
|
@@ -165,6 +258,12 @@ var RtfWriter = class {
|
|
|
165
258
|
for (const entry of entries) this.raw(`{\\listoverride\\listid${String(1e3 + entry.index)}\\listoverridecount0\\ls${String(entry.index)}}`);
|
|
166
259
|
this.raw("}");
|
|
167
260
|
}
|
|
261
|
+
writeRevisionTable() {
|
|
262
|
+
if (this.tables.revisionAuthors.size <= 1) return;
|
|
263
|
+
this.raw("{\\*\\revtbl");
|
|
264
|
+
for (const [author] of [...this.tables.revisionAuthors].sort((left, right) => left[1] - right[1])) this.raw(`{${escapeText(author)};}`);
|
|
265
|
+
this.raw("}");
|
|
266
|
+
}
|
|
168
267
|
writeInfoGroup(document) {
|
|
169
268
|
const { title, author, subject, keywords } = document.metadata;
|
|
170
269
|
const fields = [];
|
|
@@ -174,9 +273,14 @@ var RtfWriter = class {
|
|
|
174
273
|
if (keywords !== void 0 && keywords.length > 0) fields.push(`{\\keywords ${escapeText(keywords.join("; "))}}`);
|
|
175
274
|
if (fields.length > 0) this.raw(`{\\info${fields.join("")}}`);
|
|
176
275
|
}
|
|
276
|
+
writeDocumentGeometry(document) {
|
|
277
|
+
const first = document.sections[0];
|
|
278
|
+
if (first === void 0) return;
|
|
279
|
+
this.raw(`\\paperw${String(require_units.pointsToTwips(first.pageSize.widthPt))}\\paperh${String(require_units.pointsToTwips(first.pageSize.heightPt))}\\margl${String(require_units.pointsToTwips(first.margins.leftPt))}\\margr${String(require_units.pointsToTwips(first.margins.rightPt))}\\margt${String(require_units.pointsToTwips(first.margins.topPt))}\\margb${String(require_units.pointsToTwips(first.margins.bottomPt))}`);
|
|
280
|
+
}
|
|
177
281
|
writeSection(section, isFirst) {
|
|
178
282
|
if (!isFirst) this.line("\\sect");
|
|
179
|
-
this.line(`\\sectd\\
|
|
283
|
+
this.line(`\\sectd${SECTION_BREAK_CONTROL_WORDS.get(section.breakType ?? "") ?? ""}\\pgwsxn${String(require_units.pointsToTwips(section.pageSize.widthPt))}\\pghsxn${String(require_units.pointsToTwips(section.pageSize.heightPt))}\\marglsxn${String(require_units.pointsToTwips(section.margins.leftPt))}\\margrsxn${String(require_units.pointsToTwips(section.margins.rightPt))}\\margtsxn${String(require_units.pointsToTwips(section.margins.topPt))}\\margbsxn${String(require_units.pointsToTwips(section.margins.bottomPt))}`);
|
|
180
284
|
this.writeBlocks(section.blocks);
|
|
181
285
|
}
|
|
182
286
|
writeBlocks(blocks) {
|
|
@@ -204,24 +308,52 @@ var RtfWriter = class {
|
|
|
204
308
|
});
|
|
205
309
|
return;
|
|
206
310
|
case "constructStart":
|
|
311
|
+
this.openConstruct(block.descriptor);
|
|
312
|
+
return;
|
|
207
313
|
case "constructEnd":
|
|
208
|
-
this.
|
|
209
|
-
code: require_diagnostics.RtfDiagnosticCodes.CONSTRUCT_UNREPRESENTED,
|
|
210
|
-
severity: "warning",
|
|
211
|
-
message: `a ${block.kind} boundary marker is dropped; this writer emits no RTF construct for the fidelity-construct vocabulary`
|
|
212
|
-
});
|
|
314
|
+
this.closeConstruct();
|
|
213
315
|
return;
|
|
214
316
|
default: return;
|
|
215
317
|
}
|
|
216
318
|
}
|
|
319
|
+
openConstruct(descriptor) {
|
|
320
|
+
if (!require_constructs.isBookmarkAnchor(descriptor)) {
|
|
321
|
+
this.sink({
|
|
322
|
+
code: require_diagnostics.RtfDiagnosticCodes.CONSTRUCT_UNREPRESENTED,
|
|
323
|
+
severity: "warning",
|
|
324
|
+
message: `a ${descriptor.kind} construct is dropped: RTF has no ${describeConstructGap(descriptor)}`
|
|
325
|
+
});
|
|
326
|
+
this.openConstructs.push(void 0);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
this.openConstructs.push(descriptor.name);
|
|
330
|
+
this.line(bookmarkStartGroup(descriptor));
|
|
331
|
+
}
|
|
332
|
+
closeConstruct() {
|
|
333
|
+
const name = this.openConstructs.pop();
|
|
334
|
+
if (name !== void 0) this.line(`{\\*\\bkmkend ${escapeText(name)}}`);
|
|
335
|
+
}
|
|
217
336
|
writeParagraph(paragraph, inTable) {
|
|
218
337
|
this.raw("\\pard\\plain");
|
|
219
338
|
if (inTable) this.raw("\\intbl");
|
|
220
339
|
this.raw(this.paragraphProperties(paragraph));
|
|
221
340
|
this.raw(" ");
|
|
222
|
-
|
|
341
|
+
const bookmarks = (paragraph.constructs ?? []).filter((extent) => require_constructs.isBookmarkAnchor(extent.descriptor));
|
|
342
|
+
const revisions = (paragraph.constructs ?? []).filter((extent) => extent.descriptor.kind === "provenance");
|
|
343
|
+
for (const [index, run] of paragraph.runs.entries()) {
|
|
344
|
+
this.writeRunBoundaries(bookmarks, index);
|
|
345
|
+
this.writeRun(run, revisionsCovering(revisions, index));
|
|
346
|
+
}
|
|
347
|
+
this.writeRunBoundaries(bookmarks, paragraph.runs.length);
|
|
223
348
|
if (!inTable) this.line("\\par");
|
|
224
349
|
}
|
|
350
|
+
writeRunBoundaries(extents, position) {
|
|
351
|
+
for (const extent of extents) if (extent.endRun === position && extent.startRun !== position) this.raw(`{\\*\\bkmkend ${escapeText(nameOf(extent.descriptor))}}`);
|
|
352
|
+
for (const extent of extents) if (extent.startRun === position) {
|
|
353
|
+
this.raw(bookmarkStartGroup(extent.descriptor));
|
|
354
|
+
if (extent.endRun === position) this.raw(`{\\*\\bkmkend ${escapeText(nameOf(extent.descriptor))}}`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
225
357
|
paragraphProperties(paragraph) {
|
|
226
358
|
let out = "";
|
|
227
359
|
const level = paragraph.headingLevel === void 0 ? void 0 : (0, document_schema_js.clampHeadingLevel)(paragraph.headingLevel);
|
|
@@ -251,8 +383,8 @@ var RtfWriter = class {
|
|
|
251
383
|
if (paragraph.pageBreakBefore === true) out += "\\pagebb";
|
|
252
384
|
return out;
|
|
253
385
|
}
|
|
254
|
-
writeRun(run) {
|
|
255
|
-
const properties = this.runProperties(run);
|
|
386
|
+
writeRun(run, revisions = []) {
|
|
387
|
+
const properties = this.runProperties(run) + this.revisionProperties(revisions);
|
|
256
388
|
const body = `${properties}${properties.length > 0 ? " " : ""}${escapeText(run.text)}`;
|
|
257
389
|
if (run.hyperlink === void 0) {
|
|
258
390
|
this.raw(`{${body}}`);
|
|
@@ -260,6 +392,19 @@ var RtfWriter = class {
|
|
|
260
392
|
}
|
|
261
393
|
this.raw(`{\\field{\\*\\fldinst{HYPERLINK "${escapeText(run.hyperlink)}"}}{\\fldrslt{${body}}}}`);
|
|
262
394
|
}
|
|
395
|
+
revisionProperties(revisions) {
|
|
396
|
+
let out = "";
|
|
397
|
+
for (const descriptor of revisions) {
|
|
398
|
+
const author = descriptor.author;
|
|
399
|
+
const authorIndex = author === void 0 ? void 0 : this.tables.revisionAuthors.get(author);
|
|
400
|
+
const dttm = descriptor.dateIso === void 0 ? void 0 : require_constructs.dttmFromIso(descriptor.dateIso);
|
|
401
|
+
const words = CHREV_CONTROL_WORDS[descriptor.change];
|
|
402
|
+
out += words.flag;
|
|
403
|
+
if (authorIndex !== void 0) out += `\\${words.author}${String(authorIndex)}`;
|
|
404
|
+
if (dttm !== void 0) out += `\\${words.date}${String(dttm)}`;
|
|
405
|
+
}
|
|
406
|
+
return out;
|
|
407
|
+
}
|
|
263
408
|
runProperties(run) {
|
|
264
409
|
let out = "";
|
|
265
410
|
const fontIndex = run.fontFamily === void 0 ? void 0 : this.tables.fonts.get(run.fontFamily);
|
|
@@ -275,28 +420,51 @@ var RtfWriter = class {
|
|
|
275
420
|
return out;
|
|
276
421
|
}
|
|
277
422
|
writeTable(table) {
|
|
278
|
-
|
|
423
|
+
const covered = verticalMergeCoverage(table);
|
|
424
|
+
for (const [rowIndex, row] of table.rows.entries()) {
|
|
279
425
|
let right = 0;
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
426
|
+
let column = 0;
|
|
427
|
+
const definitions = [];
|
|
428
|
+
const marks = [];
|
|
429
|
+
for (const [cellIndex, cell] of row.cells.entries()) {
|
|
430
|
+
const colSpan = cell.colSpan ?? 1;
|
|
431
|
+
for (let offset = 0; offset < colSpan; offset += 1) {
|
|
432
|
+
right += require_units.pointsToTwips(table.columnWidthsPt[column] ?? 0);
|
|
433
|
+
column += 1;
|
|
434
|
+
definitions.push(this.cellDefinition(cell, covered[rowIndex]?.[cellIndex] === true, colSpan > 1 ? offset === 0 ? "mergeFirst" : "mergeContinuation" : "single", right));
|
|
435
|
+
marks.push({
|
|
436
|
+
cell,
|
|
437
|
+
empty: offset > 0
|
|
438
|
+
});
|
|
439
|
+
}
|
|
284
440
|
}
|
|
285
|
-
const rowDefinition = `\\trowd\\trgaph108\\trleft0${
|
|
441
|
+
const rowDefinition = `\\trowd\\trgaph108\\trleft0${definitions.join("")}`;
|
|
286
442
|
this.line(rowDefinition);
|
|
287
|
-
for (const
|
|
288
|
-
|
|
289
|
-
code: require_diagnostics.RtfDiagnosticCodes.CELL_BORDER_DROPPED,
|
|
290
|
-
severity: "info",
|
|
291
|
-
message: "a table cell's borders or background are dropped; this writer emits cell boundaries only"
|
|
292
|
-
});
|
|
293
|
-
this.writeCellBlocks(cell.blocks);
|
|
443
|
+
for (const mark of marks) {
|
|
444
|
+
this.writeCellBlocks(mark.empty ? [] : mark.cell.blocks);
|
|
294
445
|
this.raw("\\cell");
|
|
295
446
|
}
|
|
296
447
|
this.line(`${rowDefinition}\\row`);
|
|
297
448
|
}
|
|
298
449
|
this.line("\\pard");
|
|
299
450
|
}
|
|
451
|
+
cellDefinition(cell, isVerticalContinuation, horizontal, rightTwips) {
|
|
452
|
+
let out = "";
|
|
453
|
+
if (isVerticalContinuation) out += "\\clvmrg";
|
|
454
|
+
else if ((cell.rowSpan ?? 1) > 1) out += "\\clvmgf";
|
|
455
|
+
if (horizontal === "mergeFirst") out += "\\clmgf";
|
|
456
|
+
else if (horizontal === "mergeContinuation") return `${out}\\clmrg\\cellx${String(rightTwips)}`;
|
|
457
|
+
const borders = cell.borders;
|
|
458
|
+
if (borders !== void 0) for (const side of CELL_BORDER_ORDER) {
|
|
459
|
+
const border = borders[side];
|
|
460
|
+
if (border !== void 0) out += require_cell_format.borderControlWords(side, border, colorIndexOf(border.color, this.tables.colors));
|
|
461
|
+
}
|
|
462
|
+
if (cell.background !== void 0) {
|
|
463
|
+
const index = colorIndexOf(cell.background, this.tables.colors);
|
|
464
|
+
if (index !== void 0) out += `\\clcbpat${String(index)}`;
|
|
465
|
+
}
|
|
466
|
+
return `${out}\\cellx${String(rightTwips)}`;
|
|
467
|
+
}
|
|
300
468
|
writeCellBlocks(blocks) {
|
|
301
469
|
const paragraphs = blocks.filter((block) => block.kind === "paragraph");
|
|
302
470
|
if (paragraphs.length === 0) {
|