rtf-codec 0.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/LICENSE +21 -0
- package/README.md +226 -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/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.cjs +29 -0
- package/dist/codec.d.cts +2344 -0
- package/dist/codec.d.ts +2344 -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/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-BgG_KAiN.d.cts +52 -0
- package/dist/diagnostics-BgG_KAiN.d.ts +52 -0
- package/dist/diagnostics.cjs +76 -0
- package/dist/diagnostics.d.cts +2 -0
- package/dist/diagnostics.d.ts +2 -0
- package/dist/diagnostics.js +68 -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 +433 -0
- package/dist/header.d.cts +44 -0
- package/dist/header.d.ts +44 -0
- package/dist/header.js +431 -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 +1211 -0
- package/dist/read.d.cts +16 -0
- package/dist/read.d.ts +16 -0
- package/dist/read.js +1209 -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 +532 -0
- package/dist/write.d.cts +7 -0
- package/dist/write.d.ts +7 -0
- package/dist/write.js +530 -0
- package/package.json +95 -2
package/dist/header.js
ADDED
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
import { appendBytes } from "./bytes.js";
|
|
2
|
+
import { DEFAULT_MARGIN_BOTTOM_TWIPS, DEFAULT_MARGIN_LEFT_TWIPS, DEFAULT_MARGIN_RIGHT_TWIPS, DEFAULT_MARGIN_TOP_TWIPS, DEFAULT_PAPER_HEIGHT_TWIPS, DEFAULT_PAPER_WIDTH_TWIPS } from "./units.js";
|
|
3
|
+
import { DEFAULT_CODEPAGE, DOCUMENT_CHARSET_CODEPAGES, codepageForFontCharset, decodeCodepageBytes } from "./codepage.js";
|
|
4
|
+
import { groupHead, matchingGroupEnd } from "./group.js";
|
|
5
|
+
//#region src/header.ts
|
|
6
|
+
const RGB_MAX = 255;
|
|
7
|
+
const FONT_FAMILIES = /* @__PURE__ */ new Set([
|
|
8
|
+
"fnil",
|
|
9
|
+
"froman",
|
|
10
|
+
"fswiss",
|
|
11
|
+
"fmodern",
|
|
12
|
+
"fscript",
|
|
13
|
+
"fdecor",
|
|
14
|
+
"ftech",
|
|
15
|
+
"fbidi"
|
|
16
|
+
]);
|
|
17
|
+
const HEADING_STYLE_NAME = /^heading[ -]?([1-9])$/i;
|
|
18
|
+
const DEFAULT_LIST_LEVEL = {
|
|
19
|
+
numberFormat: 0,
|
|
20
|
+
startAt: 1
|
|
21
|
+
};
|
|
22
|
+
const HEADER_DESTINATIONS = /* @__PURE__ */ new Set([
|
|
23
|
+
"fonttbl",
|
|
24
|
+
"colortbl",
|
|
25
|
+
"stylesheet",
|
|
26
|
+
"listtable",
|
|
27
|
+
"listoverridetable",
|
|
28
|
+
"info",
|
|
29
|
+
"filetbl",
|
|
30
|
+
"revtbl",
|
|
31
|
+
"rsidtbl",
|
|
32
|
+
"generator",
|
|
33
|
+
"pgptbl",
|
|
34
|
+
"themedata",
|
|
35
|
+
"colorschememapping",
|
|
36
|
+
"latentstyles",
|
|
37
|
+
"listtextoverride",
|
|
38
|
+
"xmlnstbl",
|
|
39
|
+
"wgrffmtfilter",
|
|
40
|
+
"datastore",
|
|
41
|
+
"protusertbl",
|
|
42
|
+
"mmathPr",
|
|
43
|
+
"stylerestrictions",
|
|
44
|
+
"userprops"
|
|
45
|
+
]);
|
|
46
|
+
function collectPlainText(tokens, start, end, codepage, sink) {
|
|
47
|
+
const pending = [];
|
|
48
|
+
let out = "";
|
|
49
|
+
const flush = () => {
|
|
50
|
+
if (pending.length === 0) return;
|
|
51
|
+
out += decodeCodepageBytes(Uint8Array.from(pending), codepage, sink);
|
|
52
|
+
pending.length = 0;
|
|
53
|
+
};
|
|
54
|
+
for (let index = start; index < end; index += 1) {
|
|
55
|
+
const token = tokens[index];
|
|
56
|
+
if (token === void 0) break;
|
|
57
|
+
if (token.kind === "groupStart") {
|
|
58
|
+
flush();
|
|
59
|
+
index = matchingGroupEnd(tokens, index);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (token.kind === "text") {
|
|
63
|
+
appendBytes(pending, token.bytes);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (token.kind === "hex") {
|
|
67
|
+
pending.push(token.byte);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (token.kind === "controlWord" && token.name === "u") {
|
|
71
|
+
flush();
|
|
72
|
+
const code = token.param;
|
|
73
|
+
if (code !== void 0) out += String.fromCodePoint(code < 0 ? code + 65536 : code);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
flush();
|
|
77
|
+
return out.replace(/;\s*$/, "").trim();
|
|
78
|
+
}
|
|
79
|
+
function parseFontTable(tokens, contentStart, end, documentCodepage, fonts, sink) {
|
|
80
|
+
let index = contentStart;
|
|
81
|
+
let sawBracedEntry = false;
|
|
82
|
+
while (index < end) {
|
|
83
|
+
if (tokens[index]?.kind !== "groupStart") {
|
|
84
|
+
index += 1;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
sawBracedEntry = true;
|
|
88
|
+
const entryEnd = Math.min(matchingGroupEnd(tokens, index), end);
|
|
89
|
+
readFontInfo(tokens, index + 1, entryEnd, documentCodepage, fonts, sink);
|
|
90
|
+
index = entryEnd + 1;
|
|
91
|
+
}
|
|
92
|
+
if (!sawBracedEntry) readFontInfo(tokens, contentStart, end, documentCodepage, fonts, sink);
|
|
93
|
+
}
|
|
94
|
+
function readFontInfo(tokens, start, end, documentCodepage, fonts, sink) {
|
|
95
|
+
let number;
|
|
96
|
+
let family;
|
|
97
|
+
let charsetPage;
|
|
98
|
+
let explicitPage;
|
|
99
|
+
let nameStart = start;
|
|
100
|
+
for (let index = start; index < end; index += 1) {
|
|
101
|
+
const token = tokens[index];
|
|
102
|
+
if (token === void 0) break;
|
|
103
|
+
if (token.kind !== "controlWord") continue;
|
|
104
|
+
if (token.name === "f" && token.param !== void 0) {
|
|
105
|
+
number = token.param;
|
|
106
|
+
nameStart = index + 1;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (FONT_FAMILIES.has(token.name)) {
|
|
110
|
+
family = token.name.slice(1);
|
|
111
|
+
nameStart = index + 1;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (token.name === "fcharset" && token.param !== void 0) {
|
|
115
|
+
charsetPage = codepageForFontCharset(token.param);
|
|
116
|
+
nameStart = index + 1;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (token.name === "cpg" && token.param !== void 0) {
|
|
120
|
+
explicitPage = token.param;
|
|
121
|
+
nameStart = index + 1;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (token.name === "fprq" || token.name === "fbias") nameStart = index + 1;
|
|
125
|
+
}
|
|
126
|
+
if (number === void 0) return;
|
|
127
|
+
const name = collectPlainText(tokens, nameStart, end, explicitPage ?? charsetPage ?? documentCodepage, sink);
|
|
128
|
+
fonts.set(number, {
|
|
129
|
+
name,
|
|
130
|
+
family,
|
|
131
|
+
codepage: explicitPage ?? charsetPage
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function parseColorTable(tokens, contentStart, end, colors) {
|
|
135
|
+
let red;
|
|
136
|
+
let green;
|
|
137
|
+
let blue;
|
|
138
|
+
const finishEntry = () => {
|
|
139
|
+
colors.push(red === void 0 && green === void 0 && blue === void 0 ? void 0 : {
|
|
140
|
+
r: (red ?? 0) / RGB_MAX,
|
|
141
|
+
g: (green ?? 0) / RGB_MAX,
|
|
142
|
+
b: (blue ?? 0) / RGB_MAX
|
|
143
|
+
});
|
|
144
|
+
red = void 0;
|
|
145
|
+
green = void 0;
|
|
146
|
+
blue = void 0;
|
|
147
|
+
};
|
|
148
|
+
for (let index = contentStart; index < end; index += 1) {
|
|
149
|
+
const token = tokens[index];
|
|
150
|
+
if (token === void 0) break;
|
|
151
|
+
if (token.kind === "controlWord") {
|
|
152
|
+
if (token.name === "red") red = token.param ?? 0;
|
|
153
|
+
else if (token.name === "green") green = token.param ?? 0;
|
|
154
|
+
else if (token.name === "blue") blue = token.param ?? 0;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (token.kind === "text") {
|
|
158
|
+
for (const byte of token.bytes) if (byte === 59) finishEntry();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function parseStyleSheet(tokens, contentStart, end, documentCodepage, styles, sink) {
|
|
163
|
+
for (let index = contentStart; index < end; index += 1) {
|
|
164
|
+
if (tokens[index]?.kind !== "groupStart") continue;
|
|
165
|
+
const entryEnd = Math.min(matchingGroupEnd(tokens, index), end);
|
|
166
|
+
readStyle(tokens, index, entryEnd, documentCodepage, styles, sink);
|
|
167
|
+
index = entryEnd;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function readStyle(tokens, start, end, documentCodepage, styles, sink) {
|
|
171
|
+
const head = groupHead(tokens, start);
|
|
172
|
+
if (head.ignorable) return;
|
|
173
|
+
let handle = 0;
|
|
174
|
+
let outlineLevel;
|
|
175
|
+
let nameStart = head.contentStart;
|
|
176
|
+
for (let index = start + 1; index < end; index += 1) {
|
|
177
|
+
const token = tokens[index];
|
|
178
|
+
if (token === void 0) break;
|
|
179
|
+
if (token.kind === "groupStart") {
|
|
180
|
+
index = Math.min(matchingGroupEnd(tokens, index), end);
|
|
181
|
+
nameStart = index + 1;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (token.kind !== "controlWord") continue;
|
|
185
|
+
if (token.name === "s" && token.param !== void 0) handle = token.param;
|
|
186
|
+
else if (token.name === "outlinelevel" && token.param !== void 0) outlineLevel = token.param;
|
|
187
|
+
nameStart = index + 1;
|
|
188
|
+
}
|
|
189
|
+
const name = collectPlainText(tokens, nameStart, end, documentCodepage, sink);
|
|
190
|
+
const fromName = HEADING_STYLE_NAME.exec(name)?.[1];
|
|
191
|
+
const headingLevel = outlineLevel === void 0 ? fromName === void 0 ? void 0 : Number(fromName) : outlineLevel + 1;
|
|
192
|
+
styles.set(handle, {
|
|
193
|
+
name,
|
|
194
|
+
headingLevel
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
function parseListTable(tokens, contentStart, end, listsById) {
|
|
198
|
+
for (let index = contentStart; index < end; index += 1) {
|
|
199
|
+
if (tokens[index]?.kind !== "groupStart") continue;
|
|
200
|
+
const entryEnd = Math.min(matchingGroupEnd(tokens, index), end);
|
|
201
|
+
if (groupHead(tokens, index).destination === "list") readListDefinition(tokens, index, entryEnd, listsById);
|
|
202
|
+
index = entryEnd;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function readListDefinition(tokens, start, end, listsById) {
|
|
206
|
+
const levels = [];
|
|
207
|
+
let listId;
|
|
208
|
+
for (let index = start + 1; index < end; index += 1) {
|
|
209
|
+
const token = tokens[index];
|
|
210
|
+
if (token === void 0) break;
|
|
211
|
+
if (token.kind === "groupStart") {
|
|
212
|
+
const inner = Math.min(matchingGroupEnd(tokens, index), end);
|
|
213
|
+
if (groupHead(tokens, index).destination === "listlevel") levels.push(readListLevel(tokens, index, inner));
|
|
214
|
+
index = inner;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (token.kind === "controlWord" && token.name === "listid" && token.param !== void 0) listId = token.param;
|
|
218
|
+
}
|
|
219
|
+
if (listId === void 0) return;
|
|
220
|
+
listsById.set(listId, { levels });
|
|
221
|
+
return listId;
|
|
222
|
+
}
|
|
223
|
+
function readListLevel(tokens, start, end) {
|
|
224
|
+
let numberFormat = 0;
|
|
225
|
+
let startAt = 1;
|
|
226
|
+
for (let index = start + 1; index < end; index += 1) {
|
|
227
|
+
const token = tokens[index];
|
|
228
|
+
if (token === void 0) break;
|
|
229
|
+
if (token.kind === "groupStart") {
|
|
230
|
+
index = Math.min(matchingGroupEnd(tokens, index), end);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (token.kind !== "controlWord") continue;
|
|
234
|
+
if (token.name === "levelnfc" && token.param !== void 0) numberFormat = token.param;
|
|
235
|
+
else if (token.name === "levelstartat" && token.param !== void 0) startAt = token.param;
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
numberFormat,
|
|
239
|
+
startAt
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function parseListOverrideTable(tokens, contentStart, end, overrides) {
|
|
243
|
+
for (let index = contentStart; index < end; index += 1) {
|
|
244
|
+
if (tokens[index]?.kind !== "groupStart") continue;
|
|
245
|
+
const entryEnd = Math.min(matchingGroupEnd(tokens, index), end);
|
|
246
|
+
let listId;
|
|
247
|
+
let overrideIndex;
|
|
248
|
+
const levelOverrides = [];
|
|
249
|
+
for (let inner = index + 1; inner < entryEnd; inner += 1) {
|
|
250
|
+
const child = tokens[inner];
|
|
251
|
+
if (child?.kind === "groupStart") {
|
|
252
|
+
const childEnd = Math.min(matchingGroupEnd(tokens, inner), entryEnd);
|
|
253
|
+
if (groupHead(tokens, inner).destination === "lfolevel") levelOverrides.push(readLevelOverride(tokens, inner, childEnd));
|
|
254
|
+
inner = childEnd;
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
if (child?.kind !== "controlWord" || child.param === void 0) continue;
|
|
258
|
+
if (child.name === "listid") listId = child.param;
|
|
259
|
+
else if (child.name === "ls") overrideIndex = child.param;
|
|
260
|
+
}
|
|
261
|
+
if (listId !== void 0 && overrideIndex !== void 0) overrides.set(overrideIndex, {
|
|
262
|
+
listId,
|
|
263
|
+
levelOverrides
|
|
264
|
+
});
|
|
265
|
+
index = entryEnd;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function readLevelOverride(tokens, start, end) {
|
|
269
|
+
let level;
|
|
270
|
+
let startAt;
|
|
271
|
+
for (let index = start + 1; index < end; index += 1) {
|
|
272
|
+
const token = tokens[index];
|
|
273
|
+
if (token === void 0) break;
|
|
274
|
+
if (token.kind === "groupStart") {
|
|
275
|
+
const inner = Math.min(matchingGroupEnd(tokens, index), end);
|
|
276
|
+
if (groupHead(tokens, index).destination === "listlevel") level = readListLevel(tokens, index, inner);
|
|
277
|
+
index = inner;
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
if (token.kind === "controlWord" && token.name === "levelstartat" && token.param !== void 0) startAt = token.param;
|
|
281
|
+
}
|
|
282
|
+
return {
|
|
283
|
+
...level === void 0 ? {} : { level },
|
|
284
|
+
...startAt === void 0 ? {} : { startAt }
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function applyListOverride(list, levelOverrides) {
|
|
288
|
+
if (levelOverrides.length === 0) return list;
|
|
289
|
+
const levels = [...list.levels];
|
|
290
|
+
for (const [index, override] of levelOverrides.entries()) {
|
|
291
|
+
const base = override.level ?? levels[index] ?? DEFAULT_LIST_LEVEL;
|
|
292
|
+
levels[index] = override.level === void 0 && override.startAt !== void 0 ? {
|
|
293
|
+
...base,
|
|
294
|
+
startAt: override.startAt
|
|
295
|
+
} : base;
|
|
296
|
+
}
|
|
297
|
+
return { levels };
|
|
298
|
+
}
|
|
299
|
+
function parseRevisionTable(tokens, contentStart, end, codepage, authors, sink) {
|
|
300
|
+
for (let index = contentStart; index < end; index += 1) {
|
|
301
|
+
if (tokens[index]?.kind !== "groupStart") continue;
|
|
302
|
+
const entryEnd = Math.min(matchingGroupEnd(tokens, index), end);
|
|
303
|
+
const value = collectPlainText(tokens, index + 1, entryEnd, codepage, sink);
|
|
304
|
+
authors.push(value.split("\0")[0]?.trim() ?? "");
|
|
305
|
+
index = entryEnd;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function parseInfoGroup(tokens, contentStart, end, codepage, sink) {
|
|
309
|
+
const metadata = {};
|
|
310
|
+
for (let index = contentStart; index < end; index += 1) {
|
|
311
|
+
if (tokens[index]?.kind !== "groupStart") continue;
|
|
312
|
+
const fieldEnd = Math.min(matchingGroupEnd(tokens, index), end);
|
|
313
|
+
const head = groupHead(tokens, index);
|
|
314
|
+
const value = collectPlainText(tokens, head.contentStart, fieldEnd, codepage, sink);
|
|
315
|
+
if (value.length > 0) {
|
|
316
|
+
if (head.destination === "title") metadata.title = value;
|
|
317
|
+
else if (head.destination === "author") metadata.author = value;
|
|
318
|
+
else if (head.destination === "subject") metadata.subject = value;
|
|
319
|
+
else if (head.destination === "keywords") metadata.keywords = value.split(/[;,]\s*/).filter((k) => k.length > 0);
|
|
320
|
+
else if (head.destination === "operator") metadata.creator = value;
|
|
321
|
+
}
|
|
322
|
+
index = fieldEnd;
|
|
323
|
+
}
|
|
324
|
+
return metadata;
|
|
325
|
+
}
|
|
326
|
+
function readRtfHeader(tokens, sink) {
|
|
327
|
+
const fonts = /* @__PURE__ */ new Map();
|
|
328
|
+
const colors = [];
|
|
329
|
+
const styles = /* @__PURE__ */ new Map();
|
|
330
|
+
const listsById = /* @__PURE__ */ new Map();
|
|
331
|
+
const overrides = /* @__PURE__ */ new Map();
|
|
332
|
+
const revisionAuthors = [];
|
|
333
|
+
const page = {
|
|
334
|
+
paperWidthTwips: DEFAULT_PAPER_WIDTH_TWIPS,
|
|
335
|
+
paperHeightTwips: DEFAULT_PAPER_HEIGHT_TWIPS,
|
|
336
|
+
marginLeftTwips: DEFAULT_MARGIN_LEFT_TWIPS,
|
|
337
|
+
marginRightTwips: DEFAULT_MARGIN_RIGHT_TWIPS,
|
|
338
|
+
marginTopTwips: DEFAULT_MARGIN_TOP_TWIPS,
|
|
339
|
+
marginBottomTwips: DEFAULT_MARGIN_BOTTOM_TWIPS
|
|
340
|
+
};
|
|
341
|
+
let metadata = {};
|
|
342
|
+
let codepage = DEFAULT_CODEPAGE;
|
|
343
|
+
let defaultFontIndex;
|
|
344
|
+
let bodyStartIndex = 0;
|
|
345
|
+
const fileGroupEnd = matchingGroupEnd(tokens, 0);
|
|
346
|
+
for (let index = 0; index < fileGroupEnd; index += 1) {
|
|
347
|
+
const token = tokens[index];
|
|
348
|
+
if (token?.kind === "groupStart" && index > 0) {
|
|
349
|
+
index = Math.min(matchingGroupEnd(tokens, index), fileGroupEnd);
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
if (token?.kind !== "controlWord") continue;
|
|
353
|
+
const charsetPage = DOCUMENT_CHARSET_CODEPAGES.get(token.name);
|
|
354
|
+
if (charsetPage !== void 0) {
|
|
355
|
+
codepage = charsetPage;
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
if (token.param === void 0) continue;
|
|
359
|
+
switch (token.name) {
|
|
360
|
+
case "ansicpg":
|
|
361
|
+
codepage = token.param;
|
|
362
|
+
break;
|
|
363
|
+
case "deff":
|
|
364
|
+
defaultFontIndex = token.param;
|
|
365
|
+
break;
|
|
366
|
+
case "paperw":
|
|
367
|
+
page.paperWidthTwips = token.param;
|
|
368
|
+
break;
|
|
369
|
+
case "paperh":
|
|
370
|
+
page.paperHeightTwips = token.param;
|
|
371
|
+
break;
|
|
372
|
+
case "margl":
|
|
373
|
+
page.marginLeftTwips = token.param;
|
|
374
|
+
break;
|
|
375
|
+
case "margr":
|
|
376
|
+
page.marginRightTwips = token.param;
|
|
377
|
+
break;
|
|
378
|
+
case "margt":
|
|
379
|
+
page.marginTopTwips = token.param;
|
|
380
|
+
break;
|
|
381
|
+
case "margb": page.marginBottomTwips = token.param;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
for (let index = 1; index < fileGroupEnd; index += 1) {
|
|
385
|
+
if (tokens[index]?.kind !== "groupStart") continue;
|
|
386
|
+
const groupEnd = Math.min(matchingGroupEnd(tokens, index), fileGroupEnd);
|
|
387
|
+
const head = groupHead(tokens, index);
|
|
388
|
+
switch (head.destination) {
|
|
389
|
+
case "fonttbl":
|
|
390
|
+
parseFontTable(tokens, head.contentStart, groupEnd, codepage, fonts, sink);
|
|
391
|
+
break;
|
|
392
|
+
case "colortbl":
|
|
393
|
+
parseColorTable(tokens, head.contentStart, groupEnd, colors);
|
|
394
|
+
break;
|
|
395
|
+
case "stylesheet":
|
|
396
|
+
parseStyleSheet(tokens, head.contentStart, groupEnd, codepage, styles, sink);
|
|
397
|
+
break;
|
|
398
|
+
case "listtable":
|
|
399
|
+
parseListTable(tokens, head.contentStart, groupEnd, listsById);
|
|
400
|
+
break;
|
|
401
|
+
case "listoverridetable":
|
|
402
|
+
parseListOverrideTable(tokens, head.contentStart, groupEnd, overrides);
|
|
403
|
+
break;
|
|
404
|
+
case "revtbl":
|
|
405
|
+
parseRevisionTable(tokens, head.contentStart, groupEnd, codepage, revisionAuthors, sink);
|
|
406
|
+
break;
|
|
407
|
+
case "info": metadata = parseInfoGroup(tokens, head.contentStart, groupEnd, codepage, sink);
|
|
408
|
+
}
|
|
409
|
+
if (head.destination !== void 0 && HEADER_DESTINATIONS.has(head.destination)) bodyStartIndex = Math.max(bodyStartIndex, groupEnd + 1);
|
|
410
|
+
index = groupEnd;
|
|
411
|
+
}
|
|
412
|
+
const lists = /* @__PURE__ */ new Map();
|
|
413
|
+
for (const [overrideIndex, override] of overrides) {
|
|
414
|
+
const list = listsById.get(override.listId);
|
|
415
|
+
if (list !== void 0) lists.set(overrideIndex, applyListOverride(list, override.levelOverrides));
|
|
416
|
+
}
|
|
417
|
+
return {
|
|
418
|
+
codepage,
|
|
419
|
+
defaultFontIndex,
|
|
420
|
+
fonts,
|
|
421
|
+
colors,
|
|
422
|
+
styles,
|
|
423
|
+
lists,
|
|
424
|
+
revisionAuthors,
|
|
425
|
+
page,
|
|
426
|
+
metadata,
|
|
427
|
+
bodyStartIndex
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
//#endregion
|
|
431
|
+
export { HEADER_DESTINATIONS, readRtfHeader };
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_diagnostics = require("./diagnostics.cjs");
|
|
3
|
+
const require_bytes = require("./bytes.cjs");
|
|
4
|
+
const require_list_id = require("./list-id.cjs");
|
|
5
|
+
const require_options = require("./options.cjs");
|
|
6
|
+
const require_read = require("./read.cjs");
|
|
7
|
+
const require_write = require("./write.cjs");
|
|
8
|
+
const require_codec = require("./codec.cjs");
|
|
9
|
+
exports.DEFAULT_MAX_GROUP_DEPTH = require_options.DEFAULT_MAX_GROUP_DEPTH;
|
|
10
|
+
exports.DEFAULT_MAX_INPUT_BYTES = require_options.DEFAULT_MAX_INPUT_BYTES;
|
|
11
|
+
exports.NOOP_RTF_DIAGNOSTIC_SINK = require_diagnostics.NOOP_RTF_DIAGNOSTIC_SINK;
|
|
12
|
+
exports.RtfBytesSchema = require_codec.RtfBytesSchema;
|
|
13
|
+
exports.RtfDiagnosticCodes = require_diagnostics.RtfDiagnosticCodes;
|
|
14
|
+
exports.RtfInputTooLargeError = require_diagnostics.RtfInputTooLargeError;
|
|
15
|
+
exports.RtfNestingLimitExceededError = require_diagnostics.RtfNestingLimitExceededError;
|
|
16
|
+
exports.RtfNotAnRtfDocumentError = require_diagnostics.RtfNotAnRtfDocumentError;
|
|
17
|
+
exports.RtfParseError = require_diagnostics.RtfParseError;
|
|
18
|
+
exports.RtfUnsupportedDocumentKindError = require_diagnostics.RtfUnsupportedDocumentKindError;
|
|
19
|
+
exports.RtfWriteError = require_diagnostics.RtfWriteError;
|
|
20
|
+
exports.mintRtfListNumId = require_list_id.mintRtfListNumId;
|
|
21
|
+
exports.parseRtfListNumId = require_list_id.parseRtfListNumId;
|
|
22
|
+
exports.readRtf = require_read.readRtf;
|
|
23
|
+
exports.readRtfContent = require_read.readRtfContent;
|
|
24
|
+
exports.rtfBytesFromLatin1 = require_bytes.rtfBytesFromLatin1;
|
|
25
|
+
exports.rtfCodec = require_codec.rtfCodec;
|
|
26
|
+
exports.rtfContentCodec = require_codec.rtfContentCodec;
|
|
27
|
+
exports.writeRtf = require_write.writeRtf;
|
|
28
|
+
exports.writeRtfContent = require_write.writeRtfContent;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { rtfBytesFromLatin1 } from "./bytes.cjs";
|
|
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-BgG_KAiN.cjs";
|
|
4
|
+
import { DEFAULT_MAX_GROUP_DEPTH, DEFAULT_MAX_INPUT_BYTES, ReadRtfOptions, RtfLineEnding, WriteRtfOptions } from "./options.cjs";
|
|
5
|
+
import { ReadRtfContentResult, ReadRtfResult, readRtf, readRtfContent } from "./read.cjs";
|
|
6
|
+
import { writeRtf, writeRtfContent } from "./write.cjs";
|
|
7
|
+
import { RtfListNumIdInfo, RtfListType, mintRtfListNumId, parseRtfListNumId } from "./list-id.cjs";
|
|
8
|
+
export { DEFAULT_MAX_GROUP_DEPTH, DEFAULT_MAX_INPUT_BYTES, NOOP_RTF_DIAGNOSTIC_SINK, type ReadRtfContentResult, type ReadRtfOptions, type ReadRtfResult, RtfBytesSchema, type RtfDiagnostic, RtfDiagnosticCodes, type RtfDiagnosticSeverity, type RtfDiagnosticSink, RtfInputTooLargeError, type RtfLineEnding, type RtfListNumIdInfo, type RtfListType, RtfNestingLimitExceededError, RtfNotAnRtfDocumentError, RtfParseError, RtfUnsupportedDocumentKindError, RtfWriteError, type WriteRtfOptions, mintRtfListNumId, parseRtfListNumId, readRtf, readRtfContent, rtfBytesFromLatin1, rtfCodec, rtfContentCodec, writeRtf, writeRtfContent };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { rtfBytesFromLatin1 } from "./bytes.js";
|
|
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-BgG_KAiN.js";
|
|
4
|
+
import { DEFAULT_MAX_GROUP_DEPTH, DEFAULT_MAX_INPUT_BYTES, ReadRtfOptions, RtfLineEnding, WriteRtfOptions } from "./options.js";
|
|
5
|
+
import { ReadRtfContentResult, ReadRtfResult, readRtf, readRtfContent } from "./read.js";
|
|
6
|
+
import { writeRtf, writeRtfContent } from "./write.js";
|
|
7
|
+
import { RtfListNumIdInfo, RtfListType, mintRtfListNumId, parseRtfListNumId } from "./list-id.js";
|
|
8
|
+
export { DEFAULT_MAX_GROUP_DEPTH, DEFAULT_MAX_INPUT_BYTES, NOOP_RTF_DIAGNOSTIC_SINK, type ReadRtfContentResult, type ReadRtfOptions, type ReadRtfResult, RtfBytesSchema, type RtfDiagnostic, RtfDiagnosticCodes, type RtfDiagnosticSeverity, type RtfDiagnosticSink, RtfInputTooLargeError, type RtfLineEnding, type RtfListNumIdInfo, type RtfListType, RtfNestingLimitExceededError, RtfNotAnRtfDocumentError, RtfParseError, RtfUnsupportedDocumentKindError, RtfWriteError, type WriteRtfOptions, mintRtfListNumId, parseRtfListNumId, readRtf, readRtfContent, rtfBytesFromLatin1, rtfCodec, rtfContentCodec, writeRtf, writeRtfContent };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { NOOP_RTF_DIAGNOSTIC_SINK, RtfDiagnosticCodes, RtfInputTooLargeError, RtfNestingLimitExceededError, RtfNotAnRtfDocumentError, RtfParseError, RtfUnsupportedDocumentKindError, RtfWriteError } from "./diagnostics.js";
|
|
2
|
+
import { rtfBytesFromLatin1 } from "./bytes.js";
|
|
3
|
+
import { mintRtfListNumId, parseRtfListNumId } from "./list-id.js";
|
|
4
|
+
import { DEFAULT_MAX_GROUP_DEPTH, DEFAULT_MAX_INPUT_BYTES } from "./options.js";
|
|
5
|
+
import { readRtf, readRtfContent } from "./read.js";
|
|
6
|
+
import { writeRtf, writeRtfContent } from "./write.js";
|
|
7
|
+
import { RtfBytesSchema, rtfCodec, rtfContentCodec } from "./codec.js";
|
|
8
|
+
export { DEFAULT_MAX_GROUP_DEPTH, DEFAULT_MAX_INPUT_BYTES, NOOP_RTF_DIAGNOSTIC_SINK, RtfBytesSchema, RtfDiagnosticCodes, RtfInputTooLargeError, RtfNestingLimitExceededError, RtfNotAnRtfDocumentError, RtfParseError, RtfUnsupportedDocumentKindError, RtfWriteError, mintRtfListNumId, parseRtfListNumId, readRtf, readRtfContent, rtfBytesFromLatin1, rtfCodec, rtfContentCodec, writeRtf, writeRtfContent };
|
package/dist/list-id.cjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/list-id.ts
|
|
3
|
+
const NUMID_PATTERN = /^rtf(\d+):(bullet|ordered)(?:@(\d+))?$/;
|
|
4
|
+
const DEFAULT_ORDERED_START = 1;
|
|
5
|
+
const LEVEL_NUMBER_FORMAT_BULLET = 23;
|
|
6
|
+
function mintRtfListNumId(options) {
|
|
7
|
+
const startSuffix = options.type === "ordered" && options.start !== void 0 && options.start !== DEFAULT_ORDERED_START ? `@${String(options.start)}` : "";
|
|
8
|
+
return `rtf${String(options.listOverrideIndex)}:${options.type}${startSuffix}`;
|
|
9
|
+
}
|
|
10
|
+
function parseRtfListNumId(numId) {
|
|
11
|
+
const match = NUMID_PATTERN.exec(numId);
|
|
12
|
+
if (match === null) return;
|
|
13
|
+
const index = match[1];
|
|
14
|
+
const type = match[2];
|
|
15
|
+
if (index === void 0) return;
|
|
16
|
+
if (type !== "bullet" && type !== "ordered") return;
|
|
17
|
+
const start = match[3];
|
|
18
|
+
return start === void 0 ? {
|
|
19
|
+
listOverrideIndex: Number(index),
|
|
20
|
+
type
|
|
21
|
+
} : {
|
|
22
|
+
listOverrideIndex: Number(index),
|
|
23
|
+
type,
|
|
24
|
+
start: Number(start)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
exports.LEVEL_NUMBER_FORMAT_BULLET = LEVEL_NUMBER_FORMAT_BULLET;
|
|
29
|
+
exports.mintRtfListNumId = mintRtfListNumId;
|
|
30
|
+
exports.parseRtfListNumId = parseRtfListNumId;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/list-id.d.ts
|
|
2
|
+
declare const LEVEL_NUMBER_FORMAT_BULLET = 23;
|
|
3
|
+
type RtfListType = "bullet" | "ordered";
|
|
4
|
+
interface RtfListNumIdInfo {
|
|
5
|
+
readonly listOverrideIndex: number;
|
|
6
|
+
readonly type: RtfListType;
|
|
7
|
+
readonly start?: number;
|
|
8
|
+
}
|
|
9
|
+
declare function mintRtfListNumId(options: {
|
|
10
|
+
readonly listOverrideIndex: number;
|
|
11
|
+
readonly type: RtfListType;
|
|
12
|
+
readonly start?: number;
|
|
13
|
+
}): string;
|
|
14
|
+
declare function parseRtfListNumId(numId: string): RtfListNumIdInfo | undefined;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { LEVEL_NUMBER_FORMAT_BULLET, RtfListNumIdInfo, RtfListType, mintRtfListNumId, parseRtfListNumId };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/list-id.d.ts
|
|
2
|
+
declare const LEVEL_NUMBER_FORMAT_BULLET = 23;
|
|
3
|
+
type RtfListType = "bullet" | "ordered";
|
|
4
|
+
interface RtfListNumIdInfo {
|
|
5
|
+
readonly listOverrideIndex: number;
|
|
6
|
+
readonly type: RtfListType;
|
|
7
|
+
readonly start?: number;
|
|
8
|
+
}
|
|
9
|
+
declare function mintRtfListNumId(options: {
|
|
10
|
+
readonly listOverrideIndex: number;
|
|
11
|
+
readonly type: RtfListType;
|
|
12
|
+
readonly start?: number;
|
|
13
|
+
}): string;
|
|
14
|
+
declare function parseRtfListNumId(numId: string): RtfListNumIdInfo | undefined;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { LEVEL_NUMBER_FORMAT_BULLET, RtfListNumIdInfo, RtfListType, mintRtfListNumId, parseRtfListNumId };
|
package/dist/list-id.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/list-id.ts
|
|
2
|
+
const NUMID_PATTERN = /^rtf(\d+):(bullet|ordered)(?:@(\d+))?$/;
|
|
3
|
+
const DEFAULT_ORDERED_START = 1;
|
|
4
|
+
const LEVEL_NUMBER_FORMAT_BULLET = 23;
|
|
5
|
+
function mintRtfListNumId(options) {
|
|
6
|
+
const startSuffix = options.type === "ordered" && options.start !== void 0 && options.start !== DEFAULT_ORDERED_START ? `@${String(options.start)}` : "";
|
|
7
|
+
return `rtf${String(options.listOverrideIndex)}:${options.type}${startSuffix}`;
|
|
8
|
+
}
|
|
9
|
+
function parseRtfListNumId(numId) {
|
|
10
|
+
const match = NUMID_PATTERN.exec(numId);
|
|
11
|
+
if (match === null) return;
|
|
12
|
+
const index = match[1];
|
|
13
|
+
const type = match[2];
|
|
14
|
+
if (index === void 0) return;
|
|
15
|
+
if (type !== "bullet" && type !== "ordered") return;
|
|
16
|
+
const start = match[3];
|
|
17
|
+
return start === void 0 ? {
|
|
18
|
+
listOverrideIndex: Number(index),
|
|
19
|
+
type
|
|
20
|
+
} : {
|
|
21
|
+
listOverrideIndex: Number(index),
|
|
22
|
+
type,
|
|
23
|
+
start: Number(start)
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { LEVEL_NUMBER_FORMAT_BULLET, mintRtfListNumId, parseRtfListNumId };
|
package/dist/options.cjs
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/options.ts
|
|
3
|
+
const DEFAULT_MAX_INPUT_BYTES = 67108864;
|
|
4
|
+
const DEFAULT_MAX_GROUP_DEPTH = 256;
|
|
5
|
+
//#endregion
|
|
6
|
+
exports.DEFAULT_MAX_GROUP_DEPTH = DEFAULT_MAX_GROUP_DEPTH;
|
|
7
|
+
exports.DEFAULT_MAX_INPUT_BYTES = DEFAULT_MAX_INPUT_BYTES;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { a as RtfDiagnosticSink } from "./diagnostics-BgG_KAiN.cjs";
|
|
2
|
+
//#region src/options.d.ts
|
|
3
|
+
declare const DEFAULT_MAX_INPUT_BYTES: number;
|
|
4
|
+
declare const DEFAULT_MAX_GROUP_DEPTH = 256;
|
|
5
|
+
interface ReadRtfOptions {
|
|
6
|
+
readonly signal?: AbortSignal;
|
|
7
|
+
readonly sink?: RtfDiagnosticSink;
|
|
8
|
+
readonly maxInputBytes?: number;
|
|
9
|
+
readonly maxGroupDepth?: number;
|
|
10
|
+
}
|
|
11
|
+
type RtfLineEnding = "\n" | "\r\n";
|
|
12
|
+
interface WriteRtfOptions {
|
|
13
|
+
readonly signal?: AbortSignal;
|
|
14
|
+
readonly sink?: RtfDiagnosticSink;
|
|
15
|
+
readonly lineEnding?: RtfLineEnding;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { DEFAULT_MAX_GROUP_DEPTH, DEFAULT_MAX_INPUT_BYTES, ReadRtfOptions, RtfLineEnding, WriteRtfOptions };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { a as RtfDiagnosticSink } from "./diagnostics-BgG_KAiN.js";
|
|
2
|
+
//#region src/options.d.ts
|
|
3
|
+
declare const DEFAULT_MAX_INPUT_BYTES: number;
|
|
4
|
+
declare const DEFAULT_MAX_GROUP_DEPTH = 256;
|
|
5
|
+
interface ReadRtfOptions {
|
|
6
|
+
readonly signal?: AbortSignal;
|
|
7
|
+
readonly sink?: RtfDiagnosticSink;
|
|
8
|
+
readonly maxInputBytes?: number;
|
|
9
|
+
readonly maxGroupDepth?: number;
|
|
10
|
+
}
|
|
11
|
+
type RtfLineEnding = "\n" | "\r\n";
|
|
12
|
+
interface WriteRtfOptions {
|
|
13
|
+
readonly signal?: AbortSignal;
|
|
14
|
+
readonly sink?: RtfDiagnosticSink;
|
|
15
|
+
readonly lineEnding?: RtfLineEnding;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { DEFAULT_MAX_GROUP_DEPTH, DEFAULT_MAX_INPUT_BYTES, ReadRtfOptions, RtfLineEnding, WriteRtfOptions };
|