rtf-codec 0.0.0 → 1.0.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/LICENSE +21 -0
- package/README.md +208 -0
- package/dist/base64.cjs +66 -0
- package/dist/base64.d.cts +7 -0
- package/dist/base64.d.ts +7 -0
- package/dist/base64.js +62 -0
- package/dist/bytes.cjs +25 -0
- package/dist/bytes.d.cts +6 -0
- package/dist/bytes.d.ts +6 -0
- package/dist/bytes.js +22 -0
- package/dist/codec.cjs +29 -0
- package/dist/codec.d.cts +2308 -0
- package/dist/codec.d.ts +2308 -0
- package/dist/codec.js +26 -0
- package/dist/codepage.cjs +98 -0
- package/dist/codepage.d.cts +10 -0
- package/dist/codepage.d.ts +10 -0
- package/dist/codepage.js +92 -0
- package/dist/diagnostics-DdDFJLNO.d.cts +51 -0
- package/dist/diagnostics-DdDFJLNO.d.ts +51 -0
- package/dist/diagnostics.cjs +75 -0
- package/dist/diagnostics.d.cts +2 -0
- package/dist/diagnostics.d.ts +2 -0
- package/dist/diagnostics.js +67 -0
- package/dist/group.cjs +40 -0
- package/dist/group.d.cts +11 -0
- package/dist/group.d.ts +11 -0
- package/dist/group.js +38 -0
- package/dist/header.cjs +378 -0
- package/dist/header.d.cts +43 -0
- package/dist/header.d.ts +43 -0
- package/dist/header.js +376 -0
- package/dist/index.cjs +28 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/list-id.cjs +30 -0
- package/dist/list-id.d.cts +16 -0
- package/dist/list-id.d.ts +16 -0
- package/dist/list-id.js +27 -0
- package/dist/options.cjs +7 -0
- package/dist/options.d.cts +18 -0
- package/dist/options.d.ts +18 -0
- package/dist/options.js +5 -0
- package/dist/read.cjs +854 -0
- package/dist/read.d.cts +16 -0
- package/dist/read.d.ts +16 -0
- package/dist/read.js +852 -0
- package/dist/tokenize.cjs +155 -0
- package/dist/tokenize.d.cts +25 -0
- package/dist/tokenize.d.ts +25 -0
- package/dist/tokenize.js +154 -0
- package/dist/units.cjs +43 -0
- package/dist/units.d.cts +17 -0
- package/dist/units.d.ts +17 -0
- package/dist/units.js +29 -0
- package/dist/write.cjs +364 -0
- package/dist/write.d.cts +7 -0
- package/dist/write.d.ts +7 -0
- package/dist/write.js +362 -0
- package/package.json +95 -2
package/dist/write.cjs
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_base64 = require("./base64.cjs");
|
|
3
|
+
const require_diagnostics = require("./diagnostics.cjs");
|
|
4
|
+
const require_units = require("./units.cjs");
|
|
5
|
+
const require_list_id = require("./list-id.cjs");
|
|
6
|
+
let document_schema_js = require("document-schema.js");
|
|
7
|
+
//#region src/write.ts
|
|
8
|
+
const LEVEL_NUMBER_FORMAT_BULLET = 23;
|
|
9
|
+
const LEVEL_NUMBER_FORMAT_ARABIC = 0;
|
|
10
|
+
const LIST_LEVEL_INDENT_TWIPS = 720;
|
|
11
|
+
const LIST_MARKER_HANG_TWIPS = 360;
|
|
12
|
+
const BULLET_LEVEL_TEXT = "\\'01\\u183 ?";
|
|
13
|
+
const ARABIC_LEVEL_TEXT = "\\'02\\'00.";
|
|
14
|
+
const OUTPUT_CODEPAGE = 1252;
|
|
15
|
+
const ALIGNMENT_CONTROL_WORDS = /* @__PURE__ */ new Map([
|
|
16
|
+
["left", "\\ql"],
|
|
17
|
+
["center", "\\qc"],
|
|
18
|
+
["right", "\\qr"],
|
|
19
|
+
["justify", "\\qj"]
|
|
20
|
+
]);
|
|
21
|
+
const DEFAULT_FONT_NAME = "Times New Roman";
|
|
22
|
+
function collectTables(document) {
|
|
23
|
+
const fonts = /* @__PURE__ */ new Map([[DEFAULT_FONT_NAME, 0]]);
|
|
24
|
+
const colors = /* @__PURE__ */ new Map();
|
|
25
|
+
const headingStyles = /* @__PURE__ */ new Map();
|
|
26
|
+
const lists = /* @__PURE__ */ new Map();
|
|
27
|
+
const noteRun = (run) => {
|
|
28
|
+
if (run.fontFamily !== void 0 && !fonts.has(run.fontFamily)) fonts.set(run.fontFamily, fonts.size);
|
|
29
|
+
if (run.color !== void 0) {
|
|
30
|
+
const hex = (0, document_schema_js.colorToRgbHex)(run.color);
|
|
31
|
+
if (!colors.has(hex)) colors.set(hex, colors.size + 1);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const noteBlock = (block) => {
|
|
35
|
+
if (block.kind === "paragraph") {
|
|
36
|
+
for (const run of block.runs) noteRun(run);
|
|
37
|
+
if (block.headingLevel !== void 0) {
|
|
38
|
+
const level = (0, document_schema_js.clampHeadingLevel)(block.headingLevel);
|
|
39
|
+
if (!headingStyles.has(level)) headingStyles.set(level, level);
|
|
40
|
+
}
|
|
41
|
+
const numId = block.list?.numId;
|
|
42
|
+
if (numId !== void 0 && !lists.has(numId)) {
|
|
43
|
+
const parsed = require_list_id.parseRtfListNumId(numId);
|
|
44
|
+
lists.set(numId, {
|
|
45
|
+
index: lists.size + 1,
|
|
46
|
+
definition: {
|
|
47
|
+
type: parsed?.type ?? "bullet",
|
|
48
|
+
start: parsed?.start ?? 1
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (block.kind === "table") for (const row of block.rows) for (const cell of row.cells) for (const inner of cell.blocks) noteBlock(inner);
|
|
55
|
+
};
|
|
56
|
+
if (document.kind === "wordprocessing") for (const section of document.sections) for (const block of section.blocks) noteBlock(block);
|
|
57
|
+
return {
|
|
58
|
+
fonts,
|
|
59
|
+
colors,
|
|
60
|
+
headingStyles,
|
|
61
|
+
lists
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function escapeText(text) {
|
|
65
|
+
let out = "";
|
|
66
|
+
for (const character of text) {
|
|
67
|
+
switch (character) {
|
|
68
|
+
case "\\":
|
|
69
|
+
out += "\\\\";
|
|
70
|
+
continue;
|
|
71
|
+
case "{":
|
|
72
|
+
out += "\\{";
|
|
73
|
+
continue;
|
|
74
|
+
case "}":
|
|
75
|
+
out += "\\}";
|
|
76
|
+
continue;
|
|
77
|
+
case " ":
|
|
78
|
+
out += "\\tab ";
|
|
79
|
+
continue;
|
|
80
|
+
case "\n":
|
|
81
|
+
case "\r":
|
|
82
|
+
out += "\\line ";
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const code = character.codePointAt(0) ?? 0;
|
|
86
|
+
if (code >= 32 && code < 127) {
|
|
87
|
+
out += character;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
for (let unit = 0; unit < character.length; unit += 1) {
|
|
91
|
+
const value = character.charCodeAt(unit);
|
|
92
|
+
const signed = value > 32767 ? value - 65536 : value;
|
|
93
|
+
out += `\\u${String(signed)} ?`;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
var RtfWriter = class {
|
|
99
|
+
tables;
|
|
100
|
+
sink;
|
|
101
|
+
lineEnding;
|
|
102
|
+
out = "";
|
|
103
|
+
constructor(tables, sink, lineEnding) {
|
|
104
|
+
this.tables = tables;
|
|
105
|
+
this.sink = sink;
|
|
106
|
+
this.lineEnding = lineEnding;
|
|
107
|
+
}
|
|
108
|
+
raw(text) {
|
|
109
|
+
this.out += text;
|
|
110
|
+
}
|
|
111
|
+
line(text) {
|
|
112
|
+
this.out += text + this.lineEnding;
|
|
113
|
+
}
|
|
114
|
+
get text() {
|
|
115
|
+
return this.out;
|
|
116
|
+
}
|
|
117
|
+
writeHeader(document) {
|
|
118
|
+
this.raw(`{\\rtf1\\ansi\\ansicpg${String(OUTPUT_CODEPAGE)}\\deff0\\uc1`);
|
|
119
|
+
this.writeFontTable();
|
|
120
|
+
this.writeColorTable();
|
|
121
|
+
this.writeStyleSheet();
|
|
122
|
+
this.writeListTables();
|
|
123
|
+
this.writeInfoGroup(document);
|
|
124
|
+
this.line("");
|
|
125
|
+
}
|
|
126
|
+
writeFontTable() {
|
|
127
|
+
this.raw("{\\fonttbl");
|
|
128
|
+
for (const [name, index] of [...this.tables.fonts].sort((left, right) => left[1] - right[1])) this.raw(`{\\f${String(index)}\\fnil\\fcharset0 ${escapeText(name)};}`);
|
|
129
|
+
this.raw("}");
|
|
130
|
+
}
|
|
131
|
+
writeColorTable() {
|
|
132
|
+
if (this.tables.colors.size === 0) return;
|
|
133
|
+
this.raw("{\\colortbl;");
|
|
134
|
+
for (const [hex] of [...this.tables.colors].sort((left, right) => left[1] - right[1])) {
|
|
135
|
+
const red = Number.parseInt(hex.slice(0, 2), 16);
|
|
136
|
+
const green = Number.parseInt(hex.slice(2, 4), 16);
|
|
137
|
+
const blue = Number.parseInt(hex.slice(4, 6), 16);
|
|
138
|
+
this.raw(`\\red${String(red)}\\green${String(green)}\\blue${String(blue)};`);
|
|
139
|
+
}
|
|
140
|
+
this.raw("}");
|
|
141
|
+
}
|
|
142
|
+
writeStyleSheet() {
|
|
143
|
+
if (this.tables.headingStyles.size === 0) return;
|
|
144
|
+
this.raw("{\\stylesheet{\\s0\\snext0 Normal;}");
|
|
145
|
+
for (const [level, handle] of [...this.tables.headingStyles].sort((left, right) => left[0] - right[0])) this.raw(`{\\s${String(handle)}\\sbasedon0\\snext0\\outlinelevel${String(level - 1)} heading ${String(level)};}`);
|
|
146
|
+
this.raw("}");
|
|
147
|
+
}
|
|
148
|
+
writeListTables() {
|
|
149
|
+
if (this.tables.lists.size === 0) return;
|
|
150
|
+
const entries = [...this.tables.lists.values()].sort((left, right) => left.index - right.index);
|
|
151
|
+
this.raw("{\\*\\listtable");
|
|
152
|
+
for (const entry of entries) {
|
|
153
|
+
const bullet = entry.definition.type === "bullet";
|
|
154
|
+
const numberFormat = bullet ? LEVEL_NUMBER_FORMAT_BULLET : LEVEL_NUMBER_FORMAT_ARABIC;
|
|
155
|
+
const levelText = bullet ? BULLET_LEVEL_TEXT : ARABIC_LEVEL_TEXT;
|
|
156
|
+
const levelNumbers = bullet ? "" : "\\'01";
|
|
157
|
+
this.raw(`{\\list\\listtemplateid${String(entry.index)}\\listhybrid`);
|
|
158
|
+
for (let level = 0; level < 9; level += 1) {
|
|
159
|
+
const indent = LIST_LEVEL_INDENT_TWIPS * (level + 1);
|
|
160
|
+
this.raw(`{\\listlevel\\levelnfc${String(numberFormat)}\\levelnfcn${String(numberFormat)}\\leveljc0\\leveljcn0\\levelfollow0\\levelstartat${String(entry.definition.start)}\\levelspace0\\levelindent0{\\leveltext${levelText};}{\\levelnumbers${levelNumbers};}\\fi-${String(LIST_MARKER_HANG_TWIPS)}\\li${String(indent)}\\lin${String(indent)}}`);
|
|
161
|
+
}
|
|
162
|
+
this.raw(`\\listid${String(1e3 + entry.index)}}`);
|
|
163
|
+
}
|
|
164
|
+
this.raw("}{\\*\\listoverridetable");
|
|
165
|
+
for (const entry of entries) this.raw(`{\\listoverride\\listid${String(1e3 + entry.index)}\\listoverridecount0\\ls${String(entry.index)}}`);
|
|
166
|
+
this.raw("}");
|
|
167
|
+
}
|
|
168
|
+
writeInfoGroup(document) {
|
|
169
|
+
const { title, author, subject, keywords } = document.metadata;
|
|
170
|
+
const fields = [];
|
|
171
|
+
if (title !== void 0) fields.push(`{\\title ${escapeText(title)}}`);
|
|
172
|
+
if (author !== void 0) fields.push(`{\\author ${escapeText(author)}}`);
|
|
173
|
+
if (subject !== void 0) fields.push(`{\\subject ${escapeText(subject)}}`);
|
|
174
|
+
if (keywords !== void 0 && keywords.length > 0) fields.push(`{\\keywords ${escapeText(keywords.join("; "))}}`);
|
|
175
|
+
if (fields.length > 0) this.raw(`{\\info${fields.join("")}}`);
|
|
176
|
+
}
|
|
177
|
+
writeSection(section, isFirst) {
|
|
178
|
+
if (!isFirst) this.line("\\sect");
|
|
179
|
+
this.line(`\\sectd\\paperw${String(require_units.pointsToTwips(section.pageSize.widthPt))}\\paperh${String(require_units.pointsToTwips(section.pageSize.heightPt))}\\margl${String(require_units.pointsToTwips(section.margins.leftPt))}\\margr${String(require_units.pointsToTwips(section.margins.rightPt))}\\margt${String(require_units.pointsToTwips(section.margins.topPt))}\\margb${String(require_units.pointsToTwips(section.margins.bottomPt))}`);
|
|
180
|
+
this.writeBlocks(section.blocks);
|
|
181
|
+
}
|
|
182
|
+
writeBlocks(blocks) {
|
|
183
|
+
for (const block of blocks) this.writeBlock(block);
|
|
184
|
+
}
|
|
185
|
+
writeBlock(block) {
|
|
186
|
+
switch (block.kind) {
|
|
187
|
+
case "paragraph":
|
|
188
|
+
this.writeParagraph(block, false);
|
|
189
|
+
return;
|
|
190
|
+
case "table":
|
|
191
|
+
this.writeTable(block);
|
|
192
|
+
return;
|
|
193
|
+
case "image":
|
|
194
|
+
this.writeImageParagraph(block.base64, block);
|
|
195
|
+
return;
|
|
196
|
+
case "pageBreak":
|
|
197
|
+
this.line("\\page\\pard");
|
|
198
|
+
return;
|
|
199
|
+
case "embeddedObject":
|
|
200
|
+
this.sink({
|
|
201
|
+
code: require_diagnostics.RtfDiagnosticCodes.EMBEDDED_OBJECT_DROPPED,
|
|
202
|
+
severity: "warning",
|
|
203
|
+
message: `an embedded ${block.objectKind} object is dropped: writing it as an RTF \\object would need the OLE container this package does not build`
|
|
204
|
+
});
|
|
205
|
+
return;
|
|
206
|
+
case "constructStart":
|
|
207
|
+
case "constructEnd":
|
|
208
|
+
this.sink({
|
|
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
|
+
});
|
|
213
|
+
return;
|
|
214
|
+
default: return;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
writeParagraph(paragraph, inTable) {
|
|
218
|
+
this.raw("\\pard\\plain");
|
|
219
|
+
if (inTable) this.raw("\\intbl");
|
|
220
|
+
this.raw(this.paragraphProperties(paragraph));
|
|
221
|
+
this.raw(" ");
|
|
222
|
+
for (const run of paragraph.runs) this.writeRun(run);
|
|
223
|
+
if (!inTable) this.line("\\par");
|
|
224
|
+
}
|
|
225
|
+
paragraphProperties(paragraph) {
|
|
226
|
+
let out = "";
|
|
227
|
+
const level = paragraph.headingLevel === void 0 ? void 0 : (0, document_schema_js.clampHeadingLevel)(paragraph.headingLevel);
|
|
228
|
+
const styleHandle = level === void 0 ? void 0 : this.tables.headingStyles.get(level);
|
|
229
|
+
if (styleHandle !== void 0 && level !== void 0) out += `\\s${String(styleHandle)}\\outlinelevel${String(level - 1)}`;
|
|
230
|
+
const alignment = paragraph.alignment === void 0 ? void 0 : ALIGNMENT_CONTROL_WORDS.get(paragraph.alignment);
|
|
231
|
+
if (alignment !== void 0) out += alignment;
|
|
232
|
+
const list = paragraph.list;
|
|
233
|
+
if (list !== void 0) {
|
|
234
|
+
const numId = list.numId;
|
|
235
|
+
const entry = numId === void 0 ? void 0 : this.tables.lists.get(numId);
|
|
236
|
+
if (entry === void 0) this.sink({
|
|
237
|
+
code: require_diagnostics.RtfDiagnosticCodes.CONSTRUCT_UNREPRESENTED,
|
|
238
|
+
severity: "info",
|
|
239
|
+
message: "a list membership carries no numId this writer minted a list for; the paragraph keeps its indentation but no list marker"
|
|
240
|
+
});
|
|
241
|
+
else {
|
|
242
|
+
const indent = LIST_LEVEL_INDENT_TWIPS * (list.level + 1);
|
|
243
|
+
out += `\\ls${String(entry.index)}\\ilvl${String(list.level)}\\fi-${String(LIST_MARKER_HANG_TWIPS)}\\li${String(indent)}`;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (paragraph.indentLeftPt !== void 0) out += `\\li${String(require_units.pointsToTwips(paragraph.indentLeftPt))}`;
|
|
247
|
+
if (paragraph.indentFirstLinePt !== void 0) out += `\\fi${String(require_units.pointsToTwips(paragraph.indentFirstLinePt))}`;
|
|
248
|
+
if (paragraph.spacingBeforePt !== void 0) out += `\\sb${String(require_units.pointsToTwips(paragraph.spacingBeforePt))}`;
|
|
249
|
+
if (paragraph.spacingAfterPt !== void 0) out += `\\sa${String(require_units.pointsToTwips(paragraph.spacingAfterPt))}`;
|
|
250
|
+
if (paragraph.lineSpacing !== void 0) out += `\\sl${String(Math.round(paragraph.lineSpacing * 240))}\\slmult1`;
|
|
251
|
+
if (paragraph.pageBreakBefore === true) out += "\\pagebb";
|
|
252
|
+
return out;
|
|
253
|
+
}
|
|
254
|
+
writeRun(run) {
|
|
255
|
+
const properties = this.runProperties(run);
|
|
256
|
+
const body = `${properties}${properties.length > 0 ? " " : ""}${escapeText(run.text)}`;
|
|
257
|
+
if (run.hyperlink === void 0) {
|
|
258
|
+
this.raw(`{${body}}`);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
this.raw(`{\\field{\\*\\fldinst{HYPERLINK "${escapeText(run.hyperlink)}"}}{\\fldrslt{${body}}}}`);
|
|
262
|
+
}
|
|
263
|
+
runProperties(run) {
|
|
264
|
+
let out = "";
|
|
265
|
+
const fontIndex = run.fontFamily === void 0 ? void 0 : this.tables.fonts.get(run.fontFamily);
|
|
266
|
+
if (fontIndex !== void 0 && fontIndex !== 0) out += `\\f${String(fontIndex)}`;
|
|
267
|
+
const halfPoints = run.sizePt === void 0 ? 24 : require_units.pointsToHalfPoints(run.sizePt);
|
|
268
|
+
if (halfPoints !== 24) out += `\\fs${String(halfPoints)}`;
|
|
269
|
+
if (run.bold === true) out += "\\b";
|
|
270
|
+
if (run.italic === true) out += "\\i";
|
|
271
|
+
if (run.underline === true) out += "\\ul";
|
|
272
|
+
if (run.strike === true) out += "\\strike";
|
|
273
|
+
const colorIndex = colorIndexOf(run.color, this.tables.colors);
|
|
274
|
+
if (colorIndex !== void 0) out += `\\cf${String(colorIndex)}`;
|
|
275
|
+
return out;
|
|
276
|
+
}
|
|
277
|
+
writeTable(table) {
|
|
278
|
+
for (const row of table.rows) {
|
|
279
|
+
let right = 0;
|
|
280
|
+
const boundaries = [];
|
|
281
|
+
for (let column = 0; column < row.cells.length; column += 1) {
|
|
282
|
+
right += require_units.pointsToTwips(table.columnWidthsPt[column] ?? 0);
|
|
283
|
+
boundaries.push(right);
|
|
284
|
+
}
|
|
285
|
+
const rowDefinition = `\\trowd\\trgaph108\\trleft0${boundaries.map((boundary) => `\\cellx${String(boundary)}`).join("")}`;
|
|
286
|
+
this.line(rowDefinition);
|
|
287
|
+
for (const cell of row.cells) {
|
|
288
|
+
if (cell.borders !== void 0 || cell.background !== void 0) this.sink({
|
|
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);
|
|
294
|
+
this.raw("\\cell");
|
|
295
|
+
}
|
|
296
|
+
this.line(`${rowDefinition}\\row`);
|
|
297
|
+
}
|
|
298
|
+
this.line("\\pard");
|
|
299
|
+
}
|
|
300
|
+
writeCellBlocks(blocks) {
|
|
301
|
+
const paragraphs = blocks.filter((block) => block.kind === "paragraph");
|
|
302
|
+
if (paragraphs.length === 0) {
|
|
303
|
+
this.raw("\\pard\\plain\\intbl ");
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
for (const [index, paragraph] of paragraphs.entries()) {
|
|
307
|
+
this.writeParagraph(paragraph, true);
|
|
308
|
+
if (index < paragraphs.length - 1) this.raw("\\par");
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
writeImageParagraph(base64, image) {
|
|
312
|
+
const bytes = require_base64.base64ToBytes(base64);
|
|
313
|
+
if (bytes === void 0 || bytes.length === 0) {
|
|
314
|
+
this.sink({
|
|
315
|
+
code: require_diagnostics.RtfDiagnosticCodes.UNSUPPORTED_PICTURE_FORMAT,
|
|
316
|
+
severity: "warning",
|
|
317
|
+
message: "an image block's base64 payload could not be decoded, so no \\pict destination is written for it"
|
|
318
|
+
});
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const widthTwips = require_units.pointsToTwips(image.widthPt);
|
|
322
|
+
const heightTwips = require_units.pointsToTwips(image.heightPt);
|
|
323
|
+
this.line(`\\pard\\plain {\\*\\shppict{\\pict\\${image.format === "png" ? "pngblip" : "jpegblip"}\\picwgoal${String(widthTwips)}\\pichgoal${String(heightTwips)}${this.lineEnding}${wrapHex(require_base64.bytesToHex(bytes), this.lineEnding)}}}\\par`);
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
function colorIndexOf(color, colors) {
|
|
327
|
+
return color === void 0 ? void 0 : colors.get((0, document_schema_js.colorToRgbHex)(color));
|
|
328
|
+
}
|
|
329
|
+
const HEX_LINE_LENGTH = 128;
|
|
330
|
+
function wrapHex(hex, lineEnding) {
|
|
331
|
+
const lines = [];
|
|
332
|
+
for (let index = 0; index < hex.length; index += HEX_LINE_LENGTH) lines.push(hex.slice(index, index + HEX_LINE_LENGTH));
|
|
333
|
+
return lines.join(lineEnding);
|
|
334
|
+
}
|
|
335
|
+
function encodeAscii(text) {
|
|
336
|
+
const out = new Uint8Array(text.length);
|
|
337
|
+
for (let index = 0; index < text.length; index += 1) out[index] = text.charCodeAt(index) & 127;
|
|
338
|
+
return out;
|
|
339
|
+
}
|
|
340
|
+
function writeRtfContent(document, options = {}) {
|
|
341
|
+
options.signal?.throwIfAborted();
|
|
342
|
+
if (document.kind !== "wordprocessing") throw new require_diagnostics.RtfUnsupportedDocumentKindError(document.kind);
|
|
343
|
+
const sink = options.sink ?? (() => {});
|
|
344
|
+
const writer = new RtfWriter(collectTables(document), sink, options.lineEnding ?? "\n");
|
|
345
|
+
writer.writeHeader(document);
|
|
346
|
+
for (const [index, section] of document.sections.entries()) writer.writeSection(section, index === 0);
|
|
347
|
+
writer.raw("}");
|
|
348
|
+
return encodeAscii(writer.text);
|
|
349
|
+
}
|
|
350
|
+
function writeRtf(documentPackage, options = {}) {
|
|
351
|
+
const sink = options.sink;
|
|
352
|
+
if (sink !== void 0 && hasPackageTables(documentPackage)) sink({
|
|
353
|
+
code: require_diagnostics.RtfDiagnosticCodes.PACKAGE_TABLE_DROPPED,
|
|
354
|
+
severity: "info",
|
|
355
|
+
message: "the package's definitions/layers/attachments/destinations tables are dropped: flattening resolves style refs, and RTF has no destination for the remaining tenants"
|
|
356
|
+
});
|
|
357
|
+
return writeRtfContent((0, document_schema_js.flattenTree)(documentPackage), options);
|
|
358
|
+
}
|
|
359
|
+
function hasPackageTables(documentPackage) {
|
|
360
|
+
return documentPackage.definitions !== void 0 || documentPackage.layers !== void 0 || documentPackage.attachments !== void 0 || documentPackage.destinations !== void 0;
|
|
361
|
+
}
|
|
362
|
+
//#endregion
|
|
363
|
+
exports.writeRtf = writeRtf;
|
|
364
|
+
exports.writeRtfContent = writeRtfContent;
|
package/dist/write.d.cts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { WriteRtfOptions } from "./options.cjs";
|
|
2
|
+
import { ContentDocument, DocumentTree } from "document-schema.js";
|
|
3
|
+
//#region src/write.d.ts
|
|
4
|
+
declare function writeRtfContent(document: ContentDocument, options?: WriteRtfOptions): Uint8Array<ArrayBuffer>;
|
|
5
|
+
declare function writeRtf(documentPackage: DocumentTree, options?: WriteRtfOptions): Uint8Array<ArrayBuffer>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { writeRtf, writeRtfContent };
|
package/dist/write.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { WriteRtfOptions } from "./options.js";
|
|
2
|
+
import { ContentDocument, DocumentTree } from "document-schema.js";
|
|
3
|
+
//#region src/write.d.ts
|
|
4
|
+
declare function writeRtfContent(document: ContentDocument, options?: WriteRtfOptions): Uint8Array<ArrayBuffer>;
|
|
5
|
+
declare function writeRtf(documentPackage: DocumentTree, options?: WriteRtfOptions): Uint8Array<ArrayBuffer>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { writeRtf, writeRtfContent };
|