@unisim/doc 0.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 +91 -0
- package/dist/convert.d.ts +54 -0
- package/dist/convert.d.ts.map +1 -0
- package/dist/convert.js +216 -0
- package/dist/convert.js.map +1 -0
- package/dist/image.d.ts +17 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +66 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/merge.d.ts +14 -0
- package/dist/merge.d.ts.map +1 -0
- package/dist/merge.js +51 -0
- package/dist/merge.js.map +1 -0
- package/dist/metrics.d.ts +19 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +151 -0
- package/dist/metrics.js.map +1 -0
- package/dist/model.d.ts +114 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +121 -0
- package/dist/model.js.map +1 -0
- package/dist/pdfcore.d.ts +118 -0
- package/dist/pdfcore.d.ts.map +1 -0
- package/dist/pdfcore.js +398 -0
- package/dist/pdfcore.js.map +1 -0
- package/dist/read/csv.d.ts +17 -0
- package/dist/read/csv.d.ts.map +1 -0
- package/dist/read/csv.js +167 -0
- package/dist/read/csv.js.map +1 -0
- package/dist/read/doc.d.ts +3 -0
- package/dist/read/doc.d.ts.map +1 -0
- package/dist/read/doc.js +360 -0
- package/dist/read/doc.js.map +1 -0
- package/dist/read/docx.d.ts +3 -0
- package/dist/read/docx.d.ts.map +1 -0
- package/dist/read/docx.js +455 -0
- package/dist/read/docx.js.map +1 -0
- package/dist/read/html.d.ts +4 -0
- package/dist/read/html.d.ts.map +1 -0
- package/dist/read/html.js +236 -0
- package/dist/read/html.js.map +1 -0
- package/dist/read/json.d.ts +9 -0
- package/dist/read/json.d.ts.map +1 -0
- package/dist/read/json.js +105 -0
- package/dist/read/json.js.map +1 -0
- package/dist/read/markdown.d.ts +4 -0
- package/dist/read/markdown.d.ts.map +1 -0
- package/dist/read/markdown.js +247 -0
- package/dist/read/markdown.js.map +1 -0
- package/dist/read/odt.d.ts +3 -0
- package/dist/read/odt.d.ts.map +1 -0
- package/dist/read/odt.js +359 -0
- package/dist/read/odt.js.map +1 -0
- package/dist/read/rtf.d.ts +3 -0
- package/dist/read/rtf.d.ts.map +1 -0
- package/dist/read/rtf.js +341 -0
- package/dist/read/rtf.js.map +1 -0
- package/dist/read/text.d.ts +4 -0
- package/dist/read/text.d.ts.map +1 -0
- package/dist/read/text.js +62 -0
- package/dist/read/text.js.map +1 -0
- package/dist/unzip.d.ts +23 -0
- package/dist/unzip.d.ts.map +1 -0
- package/dist/unzip.js +152 -0
- package/dist/unzip.js.map +1 -0
- package/dist/write/data.d.ts +16 -0
- package/dist/write/data.d.ts.map +1 -0
- package/dist/write/data.js +89 -0
- package/dist/write/data.js.map +1 -0
- package/dist/write/pdf.d.ts +10 -0
- package/dist/write/pdf.d.ts.map +1 -0
- package/dist/write/pdf.js +696 -0
- package/dist/write/pdf.js.map +1 -0
- package/dist/write/pdfSettings.d.ts +13 -0
- package/dist/write/pdfSettings.d.ts.map +1 -0
- package/dist/write/pdfSettings.js +26 -0
- package/dist/write/pdfSettings.js.map +1 -0
- package/dist/write/text.d.ts +5 -0
- package/dist/write/text.d.ts.map +1 -0
- package/dist/write/text.js +341 -0
- package/dist/write/text.js.map +1 -0
- package/dist/xml.d.ts +22 -0
- package/dist/xml.d.ts.map +1 -0
- package/dist/xml.js +83 -0
- package/dist/xml.js.map +1 -0
- package/package.json +31 -0
package/dist/pdfcore.js
ADDED
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// The PDF writer — objects, pages, fonts, text, rules and images.
|
|
3
|
+
//
|
|
4
|
+
// WHY THIS IS STILL HAND-WRITTEN
|
|
5
|
+
// ------------------------------
|
|
6
|
+
// `pdf.ts` used to end with a note saying that if text was ever wanted, the
|
|
7
|
+
// right move was to take a real PDF library rather than grow the writer. The
|
|
8
|
+
// Files tab is exactly that moment, and the note was re-read before it was
|
|
9
|
+
// overruled. What changed the answer:
|
|
10
|
+
//
|
|
11
|
+
// * The expensive half of "documents to PDF" is not the file format, it is
|
|
12
|
+
// the LAYOUT — line breaking, pagination, lists, tables. Universal PDF
|
|
13
|
+
// already has that engine (`src/lib/markdownToPdf.ts`), and only its bottom
|
|
14
|
+
// inch touches pdf-lib: `widthOfTextAtSize`, `drawText`, `drawRectangle`,
|
|
15
|
+
// `drawLine`. Porting it needed those four primitives, not a library.
|
|
16
|
+
// * The base-14 fonts are IN every PDF reader. Using them means no font
|
|
17
|
+
// embedding, no subsetting, no CMap — the genuinely hard parts of a PDF
|
|
18
|
+
// library — in exchange for one table of glyph widths per font (`doc/
|
|
19
|
+
// metrics.ts`).
|
|
20
|
+
// * pdf-lib is ~380 KB gzipped. This app's pitch is that it is small and runs
|
|
21
|
+
// offline from the first visit, and a lazily-fetched library breaks the
|
|
22
|
+
// second half of that: your first document conversion would need the
|
|
23
|
+
// network. LAME and libFLAC are fetched on demand because there is no other
|
|
24
|
+
// way to have MP3 and FLAC at all. There is another way to have text.
|
|
25
|
+
//
|
|
26
|
+
// WHAT THIS DELIBERATELY DOES NOT DO
|
|
27
|
+
// ----------------------------------
|
|
28
|
+
// * No font EMBEDDING, so only what WinAnsi can spell — Latin-1 plus the
|
|
29
|
+
// Windows-1252 extras (smart quotes, dashes, bullet, ellipsis, euro).
|
|
30
|
+
// Cyrillic, Greek, Hebrew, Arabic and CJK cannot be written at all. They
|
|
31
|
+
// are COUNTED and reported (`EncodeReport`) rather than silently replaced,
|
|
32
|
+
// because a document that comes back as ??? with no explanation is worse
|
|
33
|
+
// than one that refuses.
|
|
34
|
+
// * No reading or editing an existing PDF. That needs a parser, which is a
|
|
35
|
+
// different program. Universal PDF is the app for that.
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
import { FONT_METRICS } from './metrics.js';
|
|
38
|
+
export function rgb(r, g, b) {
|
|
39
|
+
return { r, g, b };
|
|
40
|
+
}
|
|
41
|
+
// ── WinAnsi encoding ─────────────────────────────────────────────────────────
|
|
42
|
+
// Codes 32–126 and 160–255 are Unicode's own values, so they need no table.
|
|
43
|
+
// 128–159 is where Windows-1252 differs from Latin-1, and it is the useful
|
|
44
|
+
// part: every smart quote, dash and bullet a word processor emits lives here.
|
|
45
|
+
// Universal PDF's markdown writer flattens these to ASCII ('’' → "'") because
|
|
46
|
+
// pdf-lib's standard fonts throw on them; we can spell them properly, so a
|
|
47
|
+
// converted document keeps its typography instead of losing it on the way out.
|
|
48
|
+
const WIN_ANSI_HIGH = {
|
|
49
|
+
'€': 0x80, // euro
|
|
50
|
+
'‚': 0x82, // single low quote
|
|
51
|
+
'ƒ': 0x83, // florin
|
|
52
|
+
'„': 0x84, // double low quote
|
|
53
|
+
'…': 0x85, // ellipsis
|
|
54
|
+
'†': 0x86, // dagger
|
|
55
|
+
'‡': 0x87, // double dagger
|
|
56
|
+
'ˆ': 0x88, // circumflex
|
|
57
|
+
'‰': 0x89, // per mille
|
|
58
|
+
'Š': 0x8a, // S caron
|
|
59
|
+
'‹': 0x8b, // single left guillemet
|
|
60
|
+
'Œ': 0x8c, // OE
|
|
61
|
+
'Ž': 0x8e, // Z caron
|
|
62
|
+
'‘': 0x91, // left single quote
|
|
63
|
+
'’': 0x92, // right single quote / apostrophe
|
|
64
|
+
'“': 0x93, // left double quote
|
|
65
|
+
'”': 0x94, // right double quote
|
|
66
|
+
'•': 0x95, // bullet
|
|
67
|
+
'–': 0x96, // en dash
|
|
68
|
+
'—': 0x97, // em dash
|
|
69
|
+
'˜': 0x98, // small tilde
|
|
70
|
+
'™': 0x99, // trademark
|
|
71
|
+
'š': 0x9a, // s caron
|
|
72
|
+
'›': 0x9b, // single right guillemet
|
|
73
|
+
'œ': 0x9c, // oe
|
|
74
|
+
'ž': 0x9e, // z caron
|
|
75
|
+
'Ÿ': 0x9f, // Y dieresis
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Characters that have no WinAnsi code but a fair ASCII stand-in. Losing the
|
|
79
|
+
* shape of an arrow is a much smaller loss than losing the line it was on, so
|
|
80
|
+
* these substitute silently and are NOT counted as dropped.
|
|
81
|
+
*/
|
|
82
|
+
const SUBSTITUTES = {
|
|
83
|
+
'→': '->', '←': '<-', '↔': '<->',
|
|
84
|
+
'⇒': '=>', '⇐': '<=',
|
|
85
|
+
'≤': '<=', '≥': '>=', '≠': '!=',
|
|
86
|
+
'−': '-', ' ': ' ', '': '', ' ': ' ', ' ': ' ',
|
|
87
|
+
'‑': '-', '‒': '-', '―': '-',
|
|
88
|
+
'′': "'", '″': '"',
|
|
89
|
+
'✓': 'v', '✔': 'v', '✗': 'x', '✘': 'x',
|
|
90
|
+
'●': '*', '○': 'o', '◦': 'o', '▪': '-', '▫': '-', '‣': '-', '⁃': '-',
|
|
91
|
+
'▶': '>', '◀': '<', '▸': '>',
|
|
92
|
+
'✅': '[ok]', '❌': '[x]',
|
|
93
|
+
'
': ' ', '
': ' ',
|
|
94
|
+
'fi': 'fi', 'fl': 'fl',
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* A JS string as WinAnsi bytes.
|
|
98
|
+
*
|
|
99
|
+
* Anything unrepresentable becomes '?' and is recorded on `report`, so the UI
|
|
100
|
+
* can say *which* characters went missing rather than leaving somebody to spot
|
|
101
|
+
* it themselves halfway down page four.
|
|
102
|
+
*/
|
|
103
|
+
export function toWinAnsi(text, report) {
|
|
104
|
+
const out = [];
|
|
105
|
+
for (const ch of text) {
|
|
106
|
+
const sub = SUBSTITUTES[ch];
|
|
107
|
+
if (sub !== undefined) {
|
|
108
|
+
for (const c of sub)
|
|
109
|
+
out.push(c.charCodeAt(0));
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const code = ch.codePointAt(0);
|
|
113
|
+
if (code === 9) {
|
|
114
|
+
out.push(32);
|
|
115
|
+
continue;
|
|
116
|
+
} // tab — the layout owns indentation
|
|
117
|
+
if ((code >= 32 && code <= 126) || (code >= 160 && code <= 255)) {
|
|
118
|
+
out.push(code);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const high = WIN_ANSI_HIGH[ch];
|
|
122
|
+
if (high !== undefined) {
|
|
123
|
+
out.push(high);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
report?.dropped.add(ch);
|
|
127
|
+
out.push(0x3f); // '?'
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
/** The width of a string at a given size, in points. */
|
|
132
|
+
export function widthOfText(font, text, size) {
|
|
133
|
+
const metrics = FONT_METRICS[font];
|
|
134
|
+
let units = 0;
|
|
135
|
+
for (const code of toWinAnsi(text))
|
|
136
|
+
units += metrics.widths[code] ?? metrics.fallback;
|
|
137
|
+
return (units * size) / 1000;
|
|
138
|
+
}
|
|
139
|
+
// ── The document ─────────────────────────────────────────────────────────────
|
|
140
|
+
/** The base-14 names, in the order font objects are written. */
|
|
141
|
+
const FONT_NAMES = {
|
|
142
|
+
helv: 'Helvetica',
|
|
143
|
+
helvB: 'Helvetica-Bold',
|
|
144
|
+
helvI: 'Helvetica-Oblique',
|
|
145
|
+
helvBI: 'Helvetica-BoldOblique',
|
|
146
|
+
times: 'Times-Roman',
|
|
147
|
+
timesB: 'Times-Bold',
|
|
148
|
+
timesI: 'Times-Italic',
|
|
149
|
+
timesBI: 'Times-BoldItalic',
|
|
150
|
+
cour: 'Courier',
|
|
151
|
+
courB: 'Courier-Bold',
|
|
152
|
+
};
|
|
153
|
+
const FONT_IDS = Object.keys(FONT_NAMES);
|
|
154
|
+
/**
|
|
155
|
+
* One page, accumulating content-stream operators.
|
|
156
|
+
*
|
|
157
|
+
* The op list is built as strings and joined at save time. A page of dense text
|
|
158
|
+
* is a few thousand short strings, which is nothing next to the image bytes
|
|
159
|
+
* beside it, and the alternative — encoding to bytes per op — makes every
|
|
160
|
+
* drawing call allocate.
|
|
161
|
+
*/
|
|
162
|
+
export class PdfPage {
|
|
163
|
+
// ⚠️ NOT `readonly` any more, and only `setSize` may change them. A page that
|
|
164
|
+
// has been drawn on cannot be resized — the content stream's coordinates are
|
|
165
|
+
// already in terms of the old box — which is why the caller in `write/pdf.ts`
|
|
166
|
+
// only ever calls it on an untouched page. Kept mutable for exactly that one
|
|
167
|
+
// case: a document whose FIRST section is landscape has to change the page
|
|
168
|
+
// the constructor already opened, or every landscape document gains a blank
|
|
169
|
+
// portrait sheet in front of it.
|
|
170
|
+
width;
|
|
171
|
+
height;
|
|
172
|
+
ops = [];
|
|
173
|
+
images = [];
|
|
174
|
+
links = [];
|
|
175
|
+
/** Fonts actually used, so a page's /Resources only names what it draws. */
|
|
176
|
+
usedFonts = new Set();
|
|
177
|
+
report;
|
|
178
|
+
constructor(width, height, report) {
|
|
179
|
+
this.width = width;
|
|
180
|
+
this.height = height;
|
|
181
|
+
this.report = report;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Change this page's paper size. See the note on `width`/`height` above:
|
|
185
|
+
* valid only before anything is drawn.
|
|
186
|
+
*/
|
|
187
|
+
setSize(width, height) {
|
|
188
|
+
if (this.ops.length) {
|
|
189
|
+
throw new Error('A page that has been drawn on cannot be resized.');
|
|
190
|
+
}
|
|
191
|
+
this.width = width;
|
|
192
|
+
this.height = height;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* `y` is the BASELINE, and the origin is bottom-left — PDF's own convention,
|
|
196
|
+
* kept rather than flipped so the ported layout engine reads the same in both
|
|
197
|
+
* apps and a bug in one is recognisable in the other.
|
|
198
|
+
*/
|
|
199
|
+
drawText(text, opts) {
|
|
200
|
+
if (!text)
|
|
201
|
+
return;
|
|
202
|
+
this.usedFonts.add(opts.font);
|
|
203
|
+
const bytes = toWinAnsi(text, this.report);
|
|
204
|
+
this.ops.push('BT', `${num(opts.color.r)} ${num(opts.color.g)} ${num(opts.color.b)} rg`, `/${opts.font} ${num(opts.size)} Tf`, `${num(opts.x)} ${num(opts.y)} Td`, `${pdfStringFromBytes(bytes)} Tj`, 'ET');
|
|
205
|
+
}
|
|
206
|
+
drawRect(opts) {
|
|
207
|
+
if (opts.width <= 0 || opts.height <= 0)
|
|
208
|
+
return;
|
|
209
|
+
const rectOp = `${num(opts.x)} ${num(opts.y)} ${num(opts.width)} ${num(opts.height)} re`;
|
|
210
|
+
if (opts.color)
|
|
211
|
+
this.ops.push(`${num(opts.color.r)} ${num(opts.color.g)} ${num(opts.color.b)} rg`);
|
|
212
|
+
if (opts.borderColor) {
|
|
213
|
+
this.ops.push(`${num(opts.borderColor.r)} ${num(opts.borderColor.g)} ${num(opts.borderColor.b)} RG`, `${num(opts.borderWidth ?? 1)} w`);
|
|
214
|
+
}
|
|
215
|
+
this.ops.push(rectOp, opts.color && opts.borderColor ? 'B' : opts.color ? 'f' : 'S');
|
|
216
|
+
}
|
|
217
|
+
drawImage(image, opts) {
|
|
218
|
+
const index = this.images.length;
|
|
219
|
+
this.images.push(image);
|
|
220
|
+
this.ops.push('q', `${num(opts.width)} 0 0 ${num(opts.height)} ${num(opts.x)} ${num(opts.y)} cm`, `/Im${index} Do`, 'Q');
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* A clickable region. Kept separate from the drawing that makes it visible:
|
|
224
|
+
* a link's underline is content and its hotspot is an annotation, and the two
|
|
225
|
+
* are only in the same place because we put them there.
|
|
226
|
+
*/
|
|
227
|
+
addLink(x1, y1, x2, y2, url) {
|
|
228
|
+
this.links.push({ rect: [x1, y1, x2, y2], url });
|
|
229
|
+
}
|
|
230
|
+
/** @internal */
|
|
231
|
+
build() {
|
|
232
|
+
return {
|
|
233
|
+
content: this.ops.join('\n') + '\n',
|
|
234
|
+
images: this.images,
|
|
235
|
+
links: this.links,
|
|
236
|
+
fonts: [...this.usedFonts],
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
export class PdfDocument {
|
|
241
|
+
pages = [];
|
|
242
|
+
/** Collected across every page, so the UI can report it once at the end. */
|
|
243
|
+
report = { dropped: new Set() };
|
|
244
|
+
addPage(width, height) {
|
|
245
|
+
const page = new PdfPage(width, height, this.report);
|
|
246
|
+
this.pages.push(page);
|
|
247
|
+
return page;
|
|
248
|
+
}
|
|
249
|
+
get pageCount() {
|
|
250
|
+
return this.pages.length;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Serialise. Object numbers are allocated as we go rather than computed from
|
|
254
|
+
* a formula — the old `3 + i * 3` arithmetic in `pdf.ts` was correct only
|
|
255
|
+
* while every page had exactly one image and no annotations, and a formula
|
|
256
|
+
* that has to be re-derived every time the object graph changes is a bug
|
|
257
|
+
* waiting for the next feature.
|
|
258
|
+
*/
|
|
259
|
+
save(meta = {}) {
|
|
260
|
+
if (!this.pages.length)
|
|
261
|
+
throw new Error('A PDF needs at least one page.');
|
|
262
|
+
const chunks = [];
|
|
263
|
+
const offsets = [];
|
|
264
|
+
let length = 0;
|
|
265
|
+
let nextObject = 1;
|
|
266
|
+
const push = (data) => {
|
|
267
|
+
const bytes = typeof data === 'string' ? latin1(data) : data;
|
|
268
|
+
chunks.push(bytes);
|
|
269
|
+
length += bytes.length;
|
|
270
|
+
};
|
|
271
|
+
const alloc = () => nextObject++;
|
|
272
|
+
const begin = (n) => {
|
|
273
|
+
offsets[n] = length;
|
|
274
|
+
push(`${n} 0 obj\n`);
|
|
275
|
+
};
|
|
276
|
+
const end = () => push('endobj\n');
|
|
277
|
+
push('%PDF-1.4\n');
|
|
278
|
+
// A comment of high bytes — what tells a transfer that treats the file as
|
|
279
|
+
// text that it is binary. Every writer emits it; leaving it out breaks the
|
|
280
|
+
// file on exactly the systems that are hardest to debug.
|
|
281
|
+
push(new Uint8Array([0x25, 0xe2, 0xe3, 0xcf, 0xd3, 0x0a]));
|
|
282
|
+
const catalogId = alloc();
|
|
283
|
+
const pagesId = alloc();
|
|
284
|
+
// One font object per base-14 face, shared by every page. Ten small
|
|
285
|
+
// dictionaries is less machinery than tracking which page wants which.
|
|
286
|
+
const fontIds = new Map();
|
|
287
|
+
for (const id of FONT_IDS) {
|
|
288
|
+
const objectId = alloc();
|
|
289
|
+
fontIds.set(id, objectId);
|
|
290
|
+
begin(objectId);
|
|
291
|
+
push(`<< /Type /Font /Subtype /Type1 /BaseFont /${FONT_NAMES[id]} ` +
|
|
292
|
+
`/Encoding /WinAnsiEncoding >>\n`);
|
|
293
|
+
end();
|
|
294
|
+
}
|
|
295
|
+
const pageIds = [];
|
|
296
|
+
for (const page of this.pages) {
|
|
297
|
+
const built = page.build();
|
|
298
|
+
const pageId = alloc();
|
|
299
|
+
pageIds.push(pageId);
|
|
300
|
+
const contentId = alloc();
|
|
301
|
+
const imageIds = built.images.map(() => alloc());
|
|
302
|
+
const linkIds = built.links.map(() => alloc());
|
|
303
|
+
const fontResources = built.fonts
|
|
304
|
+
.map((f) => `/${f} ${fontIds.get(f)} 0 R`)
|
|
305
|
+
.join(' ');
|
|
306
|
+
const xobjectResources = imageIds
|
|
307
|
+
.map((id, i) => `/Im${i} ${id} 0 R`)
|
|
308
|
+
.join(' ');
|
|
309
|
+
const resources = `<< ${fontResources ? `/Font << ${fontResources} >> ` : ''}` +
|
|
310
|
+
`${xobjectResources ? `/XObject << ${xobjectResources} >> ` : ''}>>`;
|
|
311
|
+
begin(pageId);
|
|
312
|
+
push(`<< /Type /Page /Parent ${pagesId} 0 R ` +
|
|
313
|
+
`/MediaBox [0 0 ${num(page.width)} ${num(page.height)}] ` +
|
|
314
|
+
`/Resources ${resources} /Contents ${contentId} 0 R` +
|
|
315
|
+
(linkIds.length ? ` /Annots [${linkIds.map((id) => `${id} 0 R`).join(' ')}]` : '') +
|
|
316
|
+
` >>\n`);
|
|
317
|
+
end();
|
|
318
|
+
const contentBytes = latin1(built.content);
|
|
319
|
+
begin(contentId);
|
|
320
|
+
push(`<< /Length ${contentBytes.length} >>\nstream\n`);
|
|
321
|
+
push(contentBytes);
|
|
322
|
+
push('\nendstream\n');
|
|
323
|
+
end();
|
|
324
|
+
built.images.forEach((image, i) => {
|
|
325
|
+
begin(imageIds[i]);
|
|
326
|
+
push(`<< /Type /XObject /Subtype /Image /Width ${image.width} /Height ${image.height} ` +
|
|
327
|
+
`/ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode ` +
|
|
328
|
+
`/Length ${image.jpeg.length} >>\nstream\n`);
|
|
329
|
+
push(image.jpeg);
|
|
330
|
+
push('\nendstream\n');
|
|
331
|
+
end();
|
|
332
|
+
});
|
|
333
|
+
built.links.forEach((link, i) => {
|
|
334
|
+
begin(linkIds[i]);
|
|
335
|
+
push(`<< /Type /Annot /Subtype /Link /Rect [${link.rect.map(num).join(' ')}] ` +
|
|
336
|
+
`/Border [0 0 0] /A << /Type /Action /S /URI /URI ${pdfString(link.url)} >> >>\n`);
|
|
337
|
+
end();
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
begin(pagesId);
|
|
341
|
+
push(`<< /Type /Pages /Count ${pageIds.length} ` +
|
|
342
|
+
`/Kids [${pageIds.map((id) => `${id} 0 R`).join(' ')}] >>\n`);
|
|
343
|
+
end();
|
|
344
|
+
begin(catalogId);
|
|
345
|
+
push(`<< /Type /Catalog /Pages ${pagesId} 0 R >>\n`);
|
|
346
|
+
end();
|
|
347
|
+
const infoId = alloc();
|
|
348
|
+
begin(infoId);
|
|
349
|
+
push(`<< ${meta.title ? `/Title ${pdfString(meta.title)} ` : ''}` +
|
|
350
|
+
`${meta.author ? `/Author ${pdfString(meta.author)} ` : ''}` +
|
|
351
|
+
`/Producer ${pdfString(meta.producer ?? 'Universal Converter')} ` +
|
|
352
|
+
`/Creator ${pdfString(meta.producer ?? 'Universal Converter')} >>\n`);
|
|
353
|
+
end();
|
|
354
|
+
const xrefAt = length;
|
|
355
|
+
const count = nextObject;
|
|
356
|
+
push(`xref\n0 ${count}\n`);
|
|
357
|
+
push('0000000000 65535 f \n');
|
|
358
|
+
for (let n = 1; n < count; n += 1) {
|
|
359
|
+
push(`${String(offsets[n] ?? 0).padStart(10, '0')} 00000 n \n`);
|
|
360
|
+
}
|
|
361
|
+
push(`trailer\n<< /Size ${count} /Root ${catalogId} 0 R /Info ${infoId} 0 R >>\n` +
|
|
362
|
+
`startxref\n${xrefAt}\n%%EOF\n`);
|
|
363
|
+
return new Blob(chunks, { type: 'application/pdf' });
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
// ── Serialisation helpers ────────────────────────────────────────────────────
|
|
367
|
+
/**
|
|
368
|
+
* Numbers in a content stream. Fixed to 2dp and stripped of a trailing '.00':
|
|
369
|
+
* a raw JS float can serialise as `1e-7`, which is not a PDF number and makes
|
|
370
|
+
* the whole stream unparseable from that operator on.
|
|
371
|
+
*/
|
|
372
|
+
function num(value) {
|
|
373
|
+
if (!Number.isFinite(value))
|
|
374
|
+
return '0';
|
|
375
|
+
const fixed = value.toFixed(2);
|
|
376
|
+
return fixed.replace(/\.?0+$/, '') || '0';
|
|
377
|
+
}
|
|
378
|
+
/** A PDF literal string from already-encoded WinAnsi bytes. */
|
|
379
|
+
function pdfStringFromBytes(bytes) {
|
|
380
|
+
let out = '(';
|
|
381
|
+
for (const b of bytes) {
|
|
382
|
+
if (b === 0x28 || b === 0x29 || b === 0x5c)
|
|
383
|
+
out += '\\';
|
|
384
|
+
out += String.fromCharCode(b);
|
|
385
|
+
}
|
|
386
|
+
return out + ')';
|
|
387
|
+
}
|
|
388
|
+
function pdfString(text) {
|
|
389
|
+
return pdfStringFromBytes(toWinAnsi(text));
|
|
390
|
+
}
|
|
391
|
+
/** Latin-1 bytes. Every string that reaches this is already WinAnsi or ASCII. */
|
|
392
|
+
function latin1(s) {
|
|
393
|
+
const out = new Uint8Array(s.length);
|
|
394
|
+
for (let i = 0; i < s.length; i += 1)
|
|
395
|
+
out[i] = s.charCodeAt(i) & 0xff;
|
|
396
|
+
return out;
|
|
397
|
+
}
|
|
398
|
+
//# sourceMappingURL=pdfcore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdfcore.js","sourceRoot":"","sources":["../src/pdfcore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Grid, type RichDoc } from '../model.js';
|
|
2
|
+
export interface CsvResult {
|
|
3
|
+
doc: RichDoc;
|
|
4
|
+
grid: Grid;
|
|
5
|
+
}
|
|
6
|
+
export declare function readCsv(file: File): Promise<CsvResult>;
|
|
7
|
+
export declare function parseCsvFile(source: string, filename?: string): CsvResult;
|
|
8
|
+
/**
|
|
9
|
+
* Split a CSV into rows and fields.
|
|
10
|
+
*
|
|
11
|
+
* One pass, one state flag. `inQuotes` decides what every character means, and
|
|
12
|
+
* the doubled-quote rule is handled by peeking one ahead rather than by a
|
|
13
|
+
* second flag — inside quotes, `""` is a literal quote and a lone `"` ends the
|
|
14
|
+
* field.
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseCsv(text: string, delimiter: string): string[][];
|
|
17
|
+
//# sourceMappingURL=csv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv.d.ts","sourceRoot":"","sources":["../../src/read/csv.ts"],"names":[],"mappings":"AAcA,OAAO,EAAoB,KAAK,IAAI,EAAE,KAAK,OAAO,EAAY,MAAM,aAAa,CAAA;AAEjF,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,OAAO,CAAA;IACZ,IAAI,EAAE,IAAI,CAAA;CACX;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAE5D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CA0BzE;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAiDpE"}
|
package/dist/read/csv.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// CSV → Grid (and a RichDoc table).
|
|
3
|
+
//
|
|
4
|
+
// A real RFC 4180 parser rather than `split(',')`, because the split version
|
|
5
|
+
// works on every file you test it with and fails on the first real one: a
|
|
6
|
+
// quoted field can contain the delimiter, a newline, and — the part that trips
|
|
7
|
+
// most hand-rolled parsers — an escaped quote, written as TWO quotes inside a
|
|
8
|
+
// quoted field. `"He said ""no"", then left"` is one field.
|
|
9
|
+
//
|
|
10
|
+
// The delimiter is SNIFFED rather than assumed. A "CSV" exported from Excel in
|
|
11
|
+
// most of Europe is semicolon-separated, because the comma is the decimal point
|
|
12
|
+
// there, and a tab-separated file is routinely named .csv too.
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
import { tidy } from '../model.js';
|
|
15
|
+
export async function readCsv(file) {
|
|
16
|
+
return parseCsvFile(await file.text(), file.name);
|
|
17
|
+
}
|
|
18
|
+
export function parseCsvFile(source, filename) {
|
|
19
|
+
const text = source.replace(/^/, ''); // strip a UTF-8 BOM from Excel
|
|
20
|
+
const delimiter = sniffDelimiter(text);
|
|
21
|
+
const rows = parseCsv(text, delimiter);
|
|
22
|
+
if (!rows.length)
|
|
23
|
+
throw new Error('That CSV has no rows in it.');
|
|
24
|
+
const hasHeader = looksLikeHeader(rows);
|
|
25
|
+
const header = hasHeader ? rows[0] : [];
|
|
26
|
+
const body = hasHeader ? rows.slice(1) : rows;
|
|
27
|
+
const grid = { header, rows: body };
|
|
28
|
+
const blocks = [
|
|
29
|
+
{
|
|
30
|
+
kind: 'table',
|
|
31
|
+
header: hasHeader ? header.map((cell) => [{ text: cell }]) : null,
|
|
32
|
+
rows: body.map((row) => row.map((cell) => [{ text: cell }])),
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
const doc = tidy({
|
|
36
|
+
blocks,
|
|
37
|
+
notices: [],
|
|
38
|
+
title: filename?.replace(/\.(csv|tsv|tab)$/i, ''),
|
|
39
|
+
});
|
|
40
|
+
return { doc, grid };
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Split a CSV into rows and fields.
|
|
44
|
+
*
|
|
45
|
+
* One pass, one state flag. `inQuotes` decides what every character means, and
|
|
46
|
+
* the doubled-quote rule is handled by peeking one ahead rather than by a
|
|
47
|
+
* second flag — inside quotes, `""` is a literal quote and a lone `"` ends the
|
|
48
|
+
* field.
|
|
49
|
+
*/
|
|
50
|
+
export function parseCsv(text, delimiter) {
|
|
51
|
+
const rows = [];
|
|
52
|
+
let row = [];
|
|
53
|
+
let field = '';
|
|
54
|
+
let inQuotes = false;
|
|
55
|
+
let i = 0;
|
|
56
|
+
while (i < text.length) {
|
|
57
|
+
const ch = text[i];
|
|
58
|
+
if (inQuotes) {
|
|
59
|
+
if (ch === '"') {
|
|
60
|
+
if (text[i + 1] === '"') {
|
|
61
|
+
field += '"';
|
|
62
|
+
i += 2;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
inQuotes = false;
|
|
66
|
+
i += 1;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
field += ch;
|
|
70
|
+
i += 1;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (ch === '"' && field === '') {
|
|
74
|
+
inQuotes = true;
|
|
75
|
+
i += 1;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (ch === delimiter) {
|
|
79
|
+
row.push(field);
|
|
80
|
+
field = '';
|
|
81
|
+
i += 1;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (ch === '\r') {
|
|
85
|
+
i += 1;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (ch === '\n') {
|
|
89
|
+
row.push(field);
|
|
90
|
+
rows.push(row);
|
|
91
|
+
row = [];
|
|
92
|
+
field = '';
|
|
93
|
+
i += 1;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
field += ch;
|
|
97
|
+
i += 1;
|
|
98
|
+
}
|
|
99
|
+
if (field !== '' || row.length) {
|
|
100
|
+
row.push(field);
|
|
101
|
+
rows.push(row);
|
|
102
|
+
}
|
|
103
|
+
// A trailing newline gives a final row of one empty field. Dropping it is
|
|
104
|
+
// right; dropping a genuinely empty row in the MIDDLE would not be, so this
|
|
105
|
+
// only looks at the last.
|
|
106
|
+
const last = rows[rows.length - 1];
|
|
107
|
+
if (last && last.length === 1 && last[0] === '')
|
|
108
|
+
rows.pop();
|
|
109
|
+
return rows;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Which delimiter is this file using?
|
|
113
|
+
*
|
|
114
|
+
* Counted over the first few lines OUTSIDE quotes — a comma inside a quoted
|
|
115
|
+
* address would otherwise outvote the semicolons actually separating the
|
|
116
|
+
* fields. Whichever candidate divides the file into the most consistent number
|
|
117
|
+
* of columns wins, which beats a raw count when one character is simply common
|
|
118
|
+
* in the prose.
|
|
119
|
+
*/
|
|
120
|
+
function sniffDelimiter(text) {
|
|
121
|
+
const sample = text.split('\n').slice(0, 20).join('\n');
|
|
122
|
+
let best = ',';
|
|
123
|
+
let bestScore = -1;
|
|
124
|
+
for (const candidate of [',', ';', '\t', '|']) {
|
|
125
|
+
const rows = parseCsv(sample, candidate).filter((r) => r.length > 0);
|
|
126
|
+
if (rows.length < 1)
|
|
127
|
+
continue;
|
|
128
|
+
const columns = rows[0].length;
|
|
129
|
+
if (columns < 2)
|
|
130
|
+
continue;
|
|
131
|
+
const consistent = rows.filter((r) => r.length === columns).length / rows.length;
|
|
132
|
+
// Columns break ties: two candidates can both split every row evenly, and
|
|
133
|
+
// the one producing more fields is the one actually delimiting.
|
|
134
|
+
const score = consistent * 100 + Math.min(columns, 50);
|
|
135
|
+
if (score > bestScore) {
|
|
136
|
+
bestScore = score;
|
|
137
|
+
best = candidate;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return best;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Is row 0 a header?
|
|
144
|
+
*
|
|
145
|
+
* The signal that works: a header's cells are non-empty text, and the rows
|
|
146
|
+
* below it contain numbers or dates where the header has words. A file whose
|
|
147
|
+
* first row looks exactly like every other row probably has no header.
|
|
148
|
+
*/
|
|
149
|
+
function looksLikeHeader(rows) {
|
|
150
|
+
if (rows.length < 2)
|
|
151
|
+
return true;
|
|
152
|
+
const first = rows[0];
|
|
153
|
+
if (first.some((c) => !c.trim()))
|
|
154
|
+
return false;
|
|
155
|
+
if (first.every((c) => isNumeric(c)))
|
|
156
|
+
return false;
|
|
157
|
+
const numericBelow = rows.slice(1, 20).some((row) => row.some((c) => isNumeric(c)));
|
|
158
|
+
const numericInHeader = first.some((c) => isNumeric(c));
|
|
159
|
+
return numericBelow ? !numericInHeader : true;
|
|
160
|
+
}
|
|
161
|
+
function isNumeric(value) {
|
|
162
|
+
const trimmed = value.trim();
|
|
163
|
+
if (!trimmed)
|
|
164
|
+
return false;
|
|
165
|
+
return /^-?[\d.,]+%?$/.test(trimmed) && /\d/.test(trimmed);
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=csv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv.js","sourceRoot":"","sources":["../../src/read/csv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doc.d.ts","sourceRoot":"","sources":["../../src/read/doc.ts"],"names":[],"mappings":"AAwBA,OAAO,EAA+B,KAAK,OAAO,EAAE,MAAM,aAAa,CAAA;AAiBvE,wBAAsB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAmD1D"}
|