@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
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type FontId = 'helv' | 'helvB' | 'helvI' | 'helvBI' | 'times' | 'timesB' | 'timesI' | 'timesBI' | 'cour' | 'courB';
|
|
2
|
+
export interface FontMetrics {
|
|
3
|
+
/** Indexed by WinAnsi byte. Sparse — undefined means "no glyph". */
|
|
4
|
+
widths: number[];
|
|
5
|
+
/** Used for codes with no glyph. They render as '?', which has a width. */
|
|
6
|
+
fallback: number;
|
|
7
|
+
}
|
|
8
|
+
export declare const FONT_METRICS: Record<FontId, FontMetrics>;
|
|
9
|
+
/** The four faces of one family, chosen by weight and slant. */
|
|
10
|
+
export interface FontFamily {
|
|
11
|
+
regular: FontId;
|
|
12
|
+
bold: FontId;
|
|
13
|
+
italic: FontId;
|
|
14
|
+
boldItalic: FontId;
|
|
15
|
+
}
|
|
16
|
+
export declare const SANS: FontFamily;
|
|
17
|
+
export declare const SERIF: FontFamily;
|
|
18
|
+
export declare const MONO: FontFamily;
|
|
19
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAuBA,MAAM,MAAM,MAAM,GACd,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GACrC,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GACzC,MAAM,GAAG,OAAO,CAAA;AAEpB,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAA;CACjB;AAuJD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAYpD,CAAA;AAED,gEAAgE;AAChE,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,IAAI,EAAE,UAAsF,CAAA;AACzG,eAAO,MAAM,KAAK,EAAE,UAA0F,CAAA;AAC9G,eAAO,MAAM,IAAI,EAAE,UAAoF,CAAA"}
|
package/dist/metrics.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Glyph widths for the base-14 PDF fonts.
|
|
3
|
+
//
|
|
4
|
+
// This table is the entire price of writing text without a PDF library. Every
|
|
5
|
+
// reader already HAS these fonts, so nothing is embedded and nothing is
|
|
6
|
+
// subsetted — but the writer still has to know how wide each character is, or
|
|
7
|
+
// it cannot break a line, centre a heading or size a table column.
|
|
8
|
+
//
|
|
9
|
+
// Widths are Adobe's own AFM values, in 1/1000 em: a character of width 556 at
|
|
10
|
+
// 11pt occupies 556 × 11 / 1000 = 6.116pt. They are given for WinAnsi code
|
|
11
|
+
// points, which is the encoding every font object here declares, so the index
|
|
12
|
+
// into these tables is the *byte* that ends up in the PDF, not the Unicode code
|
|
13
|
+
// point. The two agree below 127 and again from 160 to 255, and differ over
|
|
14
|
+
// 128–159 — the Windows-1252 block that holds smart quotes, dashes, the bullet
|
|
15
|
+
// and the ellipsis. That block is the one worth having: it is what a word
|
|
16
|
+
// processor actually emits.
|
|
17
|
+
//
|
|
18
|
+
// The oblique/italic faces of Helvetica are METRICALLY IDENTICAL to the upright
|
|
19
|
+
// ones — the glyphs are slanted, not redrawn — so they share a table. Times'
|
|
20
|
+
// italics are genuinely different designs and have their own. Courier is
|
|
21
|
+
// monospaced: every glyph is 600, which is why it needs no table at all.
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
/**
|
|
24
|
+
* Expand the compact form.
|
|
25
|
+
*
|
|
26
|
+
* `ascii` is 95 widths for codes 32–126, `high` is 96 for codes 160–255, and
|
|
27
|
+
* `extras` is the sparse 128–159 block written as `code:width` pairs. Three
|
|
28
|
+
* strings per font rather than a 224-entry literal each: the table is data, and
|
|
29
|
+
* data that takes six screens to scroll past is data nobody will ever check.
|
|
30
|
+
*/
|
|
31
|
+
function build(ascii, extras, high, fallback) {
|
|
32
|
+
const widths = [];
|
|
33
|
+
ascii.trim().split(/\s+/).forEach((w, i) => { widths[32 + i] = Number(w); });
|
|
34
|
+
high.trim().split(/\s+/).forEach((w, i) => { widths[160 + i] = Number(w); });
|
|
35
|
+
for (const pair of extras.trim().split(/\s+/)) {
|
|
36
|
+
const [code, width] = pair.split(':');
|
|
37
|
+
widths[Number(code)] = Number(width);
|
|
38
|
+
}
|
|
39
|
+
return { widths, fallback };
|
|
40
|
+
}
|
|
41
|
+
// ── Helvetica ────────────────────────────────────────────────────────────────
|
|
42
|
+
const HELVETICA = build(
|
|
43
|
+
// 32–126
|
|
44
|
+
`278 278 355 556 556 889 667 191 333 333 389 584 278 333 278 278
|
|
45
|
+
556 556 556 556 556 556 556 556 556 556 278 278 584 584 584 556
|
|
46
|
+
1015 667 667 722 722 667 611 778 722 278 500 667 556 833 722 778
|
|
47
|
+
667 778 722 667 611 722 667 944 667 667 611 278 278 278 469 556
|
|
48
|
+
333 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556
|
|
49
|
+
556 556 333 500 278 556 500 722 500 500 500 334 260 334 584`,
|
|
50
|
+
// 128–159
|
|
51
|
+
`128:556 130:222 131:556 132:333 133:1000 134:556 135:556 136:333
|
|
52
|
+
137:1000 138:667 139:333 140:1000 142:611 145:222 146:222 147:333
|
|
53
|
+
148:333 149:350 150:556 151:1000 152:333 153:1000 154:500 155:333
|
|
54
|
+
156:944 158:500 159:667`,
|
|
55
|
+
// 160–255
|
|
56
|
+
`278 333 556 556 556 556 260 556 333 737 370 556 584 333 737 333
|
|
57
|
+
400 584 333 333 333 556 537 278 333 333 365 556 834 834 834 611
|
|
58
|
+
667 667 667 667 667 667 1000 722 667 667 667 667 278 278 278 278
|
|
59
|
+
722 722 778 778 778 778 778 584 778 722 722 722 722 667 667 611
|
|
60
|
+
556 556 556 556 556 556 889 500 556 556 556 556 278 278 278 278
|
|
61
|
+
556 556 556 556 556 556 556 584 611 556 556 556 556 500 556 500`, 556);
|
|
62
|
+
const HELVETICA_BOLD = build(`278 333 474 556 556 889 722 238 333 333 389 584 278 333 278 278
|
|
63
|
+
556 556 556 556 556 556 556 556 556 556 333 333 584 584 584 611
|
|
64
|
+
975 722 722 722 722 667 611 778 722 278 556 722 611 833 722 778
|
|
65
|
+
667 778 722 667 611 722 667 944 667 667 611 333 278 333 584 556
|
|
66
|
+
333 556 611 556 611 556 333 611 611 278 278 556 278 889 611 611
|
|
67
|
+
611 611 389 556 333 611 556 778 556 556 500 389 280 389 584`, `128:556 130:278 131:556 132:500 133:1000 134:556 135:556 136:333
|
|
68
|
+
137:1000 138:667 139:333 140:1000 142:611 145:278 146:278 147:500
|
|
69
|
+
148:500 149:350 150:556 151:1000 152:333 153:1000 154:556 155:333
|
|
70
|
+
156:944 158:500 159:667`, `278 333 556 556 556 556 280 556 333 737 370 556 584 333 737 333
|
|
71
|
+
400 584 333 333 333 611 556 278 333 333 365 556 834 834 834 611
|
|
72
|
+
722 722 722 722 722 722 1000 722 667 667 667 667 278 278 278 278
|
|
73
|
+
722 722 778 778 778 778 778 584 778 722 722 722 722 667 667 611
|
|
74
|
+
556 556 556 556 556 556 889 556 556 556 556 556 278 278 278 278
|
|
75
|
+
611 611 611 611 611 611 611 584 611 611 611 611 611 556 611 556`, 556);
|
|
76
|
+
// ── Times ────────────────────────────────────────────────────────────────────
|
|
77
|
+
const TIMES = build(`250 333 408 500 500 833 778 180 333 333 500 564 250 333 250 278
|
|
78
|
+
500 500 500 500 500 500 500 500 500 500 278 278 564 564 564 444
|
|
79
|
+
921 722 667 667 722 611 556 722 722 333 389 722 611 889 722 722
|
|
80
|
+
556 722 667 556 611 722 722 944 722 722 611 333 278 333 469 500
|
|
81
|
+
333 444 500 444 500 444 333 500 500 278 278 500 278 778 500 500
|
|
82
|
+
500 500 333 389 278 500 500 722 500 500 444 480 200 480 541`, `128:500 130:333 131:500 132:444 133:1000 134:500 135:500 136:333
|
|
83
|
+
137:1000 138:556 139:333 140:889 142:611 145:333 146:333 147:444
|
|
84
|
+
148:444 149:350 150:500 151:1000 152:333 153:980 154:389 155:333
|
|
85
|
+
156:722 158:444 159:722`, `250 333 500 500 500 500 200 500 333 760 276 500 564 333 760 333
|
|
86
|
+
400 564 300 300 333 500 453 250 333 300 310 500 750 750 750 444
|
|
87
|
+
722 722 722 722 722 722 889 667 611 611 611 611 333 333 333 333
|
|
88
|
+
722 722 722 722 722 722 722 564 722 722 722 722 722 722 556 500
|
|
89
|
+
444 444 444 444 444 444 667 444 444 444 444 444 278 278 278 278
|
|
90
|
+
500 500 500 500 500 500 500 564 500 500 500 500 500 500 500 500`, 500);
|
|
91
|
+
const TIMES_BOLD = build(`250 333 555 500 500 1000 833 278 333 333 500 570 250 333 250 278
|
|
92
|
+
500 500 500 500 500 500 500 500 500 500 333 333 570 570 570 500
|
|
93
|
+
930 722 667 722 722 667 611 778 778 389 500 778 667 944 722 778
|
|
94
|
+
611 778 722 556 667 722 722 1000 722 722 667 333 278 333 581 500
|
|
95
|
+
333 500 556 444 556 444 333 500 556 278 333 556 278 833 556 500
|
|
96
|
+
556 556 444 389 333 556 500 722 500 500 444 394 220 394 520`, `128:500 130:333 131:500 132:500 133:1000 134:500 135:500 136:333
|
|
97
|
+
137:1000 138:556 139:333 140:1000 142:667 145:333 146:333 147:500
|
|
98
|
+
148:500 149:350 150:500 151:1000 152:333 153:1000 154:389 155:333
|
|
99
|
+
156:722 158:444 159:722`, `250 333 500 500 500 500 220 500 333 747 300 500 570 333 747 333
|
|
100
|
+
400 570 300 300 333 556 540 250 333 300 330 500 750 750 750 500
|
|
101
|
+
722 722 722 722 722 722 1000 722 667 667 667 667 389 389 389 389
|
|
102
|
+
722 722 778 778 778 778 778 570 778 722 722 722 722 722 611 556
|
|
103
|
+
500 500 500 500 500 500 722 444 444 444 444 444 278 278 278 278
|
|
104
|
+
500 556 500 500 500 500 500 570 500 556 556 556 556 500 556 500`, 500);
|
|
105
|
+
const TIMES_ITALIC = build(`250 333 420 500 500 833 778 214 333 333 500 675 250 333 250 278
|
|
106
|
+
500 500 500 500 500 500 500 500 500 500 333 333 675 675 675 500
|
|
107
|
+
920 611 611 667 722 611 611 722 722 333 444 667 556 833 667 722
|
|
108
|
+
611 722 611 500 556 722 611 833 611 556 556 389 278 389 422 500
|
|
109
|
+
333 500 500 444 500 444 278 500 500 278 278 444 278 722 500 500
|
|
110
|
+
500 500 389 389 278 500 444 667 444 444 389 400 275 400 541`, `128:500 130:333 131:500 132:556 133:889 134:500 135:500 136:333
|
|
111
|
+
137:1000 138:556 139:333 140:944 142:556 145:333 146:333 147:556
|
|
112
|
+
148:556 149:350 150:500 151:889 152:333 153:980 154:389 155:333
|
|
113
|
+
156:667 158:389 159:556`, `250 389 500 500 500 500 275 500 333 760 276 500 675 333 760 333
|
|
114
|
+
400 675 300 300 333 500 523 250 333 300 310 500 750 750 750 500
|
|
115
|
+
611 611 611 611 611 611 889 667 611 611 611 611 333 333 333 333
|
|
116
|
+
722 667 722 722 722 722 722 675 722 722 722 722 722 556 611 500
|
|
117
|
+
500 500 500 500 500 500 667 444 444 444 444 444 278 278 278 278
|
|
118
|
+
500 500 500 500 500 500 500 675 500 500 500 500 500 444 500 444`, 500);
|
|
119
|
+
const TIMES_BOLD_ITALIC = build(`250 389 555 500 500 833 778 278 333 333 500 570 250 333 250 278
|
|
120
|
+
500 500 500 500 500 500 500 500 500 500 333 333 570 570 570 500
|
|
121
|
+
832 667 667 667 722 667 667 722 778 389 500 667 611 889 722 722
|
|
122
|
+
611 722 667 556 611 722 667 889 667 611 611 333 278 333 570 500
|
|
123
|
+
333 500 500 444 500 444 333 500 556 278 278 500 278 778 556 500
|
|
124
|
+
500 500 389 389 278 556 444 667 500 444 389 348 220 348 570`, `128:500 130:333 131:500 132:500 133:1000 134:500 135:500 136:333
|
|
125
|
+
137:1000 138:556 139:333 140:944 142:611 145:333 146:333 147:500
|
|
126
|
+
148:500 149:350 150:500 151:1000 152:333 153:1000 154:389 155:333
|
|
127
|
+
156:722 158:389 159:611`, `250 389 500 500 500 500 220 500 333 747 266 500 606 333 747 333
|
|
128
|
+
400 570 300 300 333 576 500 250 333 300 300 500 750 750 750 500
|
|
129
|
+
667 667 667 667 667 667 944 667 667 667 667 667 389 389 389 389
|
|
130
|
+
722 722 722 722 722 722 722 570 722 722 722 722 722 611 611 500
|
|
131
|
+
500 500 500 500 500 500 722 444 444 444 444 444 278 278 278 278
|
|
132
|
+
500 556 500 500 500 500 500 570 500 556 556 556 556 444 500 444`, 500);
|
|
133
|
+
/** Courier is monospaced — 600 for everything, glyph or not. */
|
|
134
|
+
const COURIER = { widths: [], fallback: 600 };
|
|
135
|
+
export const FONT_METRICS = {
|
|
136
|
+
helv: HELVETICA,
|
|
137
|
+
helvB: HELVETICA_BOLD,
|
|
138
|
+
// Oblique is the same outlines on a slant, so the same advance widths.
|
|
139
|
+
helvI: HELVETICA,
|
|
140
|
+
helvBI: HELVETICA_BOLD,
|
|
141
|
+
times: TIMES,
|
|
142
|
+
timesB: TIMES_BOLD,
|
|
143
|
+
timesI: TIMES_ITALIC,
|
|
144
|
+
timesBI: TIMES_BOLD_ITALIC,
|
|
145
|
+
cour: COURIER,
|
|
146
|
+
courB: COURIER,
|
|
147
|
+
};
|
|
148
|
+
export const SANS = { regular: 'helv', bold: 'helvB', italic: 'helvI', boldItalic: 'helvBI' };
|
|
149
|
+
export const SERIF = { regular: 'times', bold: 'timesB', italic: 'timesI', boldItalic: 'timesBI' };
|
|
150
|
+
export const MONO = { regular: 'cour', bold: 'courB', italic: 'cour', boldItalic: 'courB' };
|
|
151
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
|
package/dist/model.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/** A stretch of text with its formatting. The atom of the model. */
|
|
2
|
+
export interface Run {
|
|
3
|
+
text: string;
|
|
4
|
+
bold?: boolean;
|
|
5
|
+
italic?: boolean;
|
|
6
|
+
/** Rendered in a monospaced face on a tinted plate. */
|
|
7
|
+
code?: boolean;
|
|
8
|
+
/** Underline is kept because Word documents genuinely use it for emphasis. */
|
|
9
|
+
underline?: boolean;
|
|
10
|
+
strike?: boolean;
|
|
11
|
+
/** An absolute URL. Becomes a real clickable annotation in the PDF. */
|
|
12
|
+
link?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ListItem {
|
|
15
|
+
runs: Run[];
|
|
16
|
+
/** 0 for a top-level bullet; each nested level indents once more. */
|
|
17
|
+
level: number;
|
|
18
|
+
}
|
|
19
|
+
export type Block = {
|
|
20
|
+
kind: 'heading';
|
|
21
|
+
level: 1 | 2 | 3 | 4;
|
|
22
|
+
runs: Run[];
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'paragraph';
|
|
25
|
+
runs: Run[];
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'list';
|
|
28
|
+
ordered: boolean;
|
|
29
|
+
items: ListItem[];
|
|
30
|
+
} | {
|
|
31
|
+
kind: 'quote';
|
|
32
|
+
runs: Run[];
|
|
33
|
+
} | {
|
|
34
|
+
kind: 'code';
|
|
35
|
+
text: string;
|
|
36
|
+
} | {
|
|
37
|
+
kind: 'rule';
|
|
38
|
+
} | {
|
|
39
|
+
kind: 'table';
|
|
40
|
+
header: Run[][] | null;
|
|
41
|
+
rows: Run[][][];
|
|
42
|
+
} | {
|
|
43
|
+
kind: 'image';
|
|
44
|
+
file: Blob;
|
|
45
|
+
alt: string;
|
|
46
|
+
} | {
|
|
47
|
+
kind: 'pagebreak';
|
|
48
|
+
} | {
|
|
49
|
+
kind: 'pagesetup';
|
|
50
|
+
width: number;
|
|
51
|
+
height: number;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Something the reader had to give up, or thinks you should know.
|
|
55
|
+
*
|
|
56
|
+
* Carried on the document rather than thrown, because these are not failures:
|
|
57
|
+
* a .doc that arrives as text is still a useful PDF, and the right move is to
|
|
58
|
+
* hand it over WITH the sentence attached, not to refuse it. The UI shows them
|
|
59
|
+
* on the finished row.
|
|
60
|
+
*/
|
|
61
|
+
export interface DocNotice {
|
|
62
|
+
/** One sentence, written for somebody who has never heard of a piece table. */
|
|
63
|
+
message: string;
|
|
64
|
+
/** 'loss' is something the file had and the result does not. */
|
|
65
|
+
severity: 'loss' | 'info';
|
|
66
|
+
}
|
|
67
|
+
export interface RichDoc {
|
|
68
|
+
blocks: Block[];
|
|
69
|
+
/** From the file's own metadata where it has any; falls back to the filename. */
|
|
70
|
+
title?: string;
|
|
71
|
+
author?: string;
|
|
72
|
+
notices: DocNotice[];
|
|
73
|
+
}
|
|
74
|
+
export declare function emptyDoc(): RichDoc;
|
|
75
|
+
/** A plain run of text, used constantly by the readers. */
|
|
76
|
+
export declare function text(value: string): Run[];
|
|
77
|
+
/** The plain text of a run list — what every non-PDF writer starts from. */
|
|
78
|
+
export declare function runsToText(runs: readonly Run[]): string;
|
|
79
|
+
/**
|
|
80
|
+
* Collapse runs that carry identical formatting.
|
|
81
|
+
*
|
|
82
|
+
* Word splits a sentence into a run per spell-check state, per revision, per
|
|
83
|
+
* rsid — a plain paragraph routinely arrives as thirty runs. Left alone, that
|
|
84
|
+
* is thirty `Tj` operators in the PDF and thirty `<span>`s in the HTML, and the
|
|
85
|
+
* line-breaker cannot kern across the joins either. This is the one bit of
|
|
86
|
+
* tidying every reader wants, so it lives here.
|
|
87
|
+
*/
|
|
88
|
+
export declare function mergeRuns(runs: readonly Run[]): Run[];
|
|
89
|
+
/**
|
|
90
|
+
* Drop empty paragraphs and merge every block's runs.
|
|
91
|
+
*
|
|
92
|
+
* A blank paragraph is how a Word user makes a gap, so ONE is kept as a
|
|
93
|
+
* paragraph with a single space — the writers turn that into a normal
|
|
94
|
+
* paragraph gap. Runs of them (a page's worth of Enter to push a heading down)
|
|
95
|
+
* collapse, because the PDF paginates on its own and reproducing somebody's
|
|
96
|
+
* manual pagination inside a different page size produces holes.
|
|
97
|
+
*/
|
|
98
|
+
export declare function tidy(doc: RichDoc): RichDoc;
|
|
99
|
+
export declare function addNotice(doc: RichDoc, message: string, severity?: DocNotice['severity']): void;
|
|
100
|
+
/**
|
|
101
|
+
* A grid, kept alongside `RichDoc` rather than inside it.
|
|
102
|
+
*
|
|
103
|
+
* CSV → JSON has no business going through a document model: it is rows of
|
|
104
|
+
* strings in and rows of strings out, and routing it through paragraphs and
|
|
105
|
+
* runs would lose the types on the way. Readers that have a genuine grid
|
|
106
|
+
* (`csv`, `json`) expose one as well as a `RichDoc`, and the data writers take
|
|
107
|
+
* the grid while the document writers take the doc.
|
|
108
|
+
*/
|
|
109
|
+
export interface Grid {
|
|
110
|
+
/** Column names. Empty when the source had no header row. */
|
|
111
|
+
header: string[];
|
|
112
|
+
rows: string[][];
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
|
package/dist/model.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// RichDoc — the shape every document passes through.
|
|
3
|
+
//
|
|
4
|
+
// WHY A MODEL AND NOT A PILE OF CONVERTERS
|
|
5
|
+
// ----------------------------------------
|
|
6
|
+
// The Files tab reads nine kinds of input and writes six kinds of output. Wired
|
|
7
|
+
// directly that is fifty-odd conversions; through one model it is nine readers
|
|
8
|
+
// and six writers, and adding a tenth input costs one file rather than six.
|
|
9
|
+
//
|
|
10
|
+
// The model is deliberately SMALL — headings, paragraphs, lists, tables, code,
|
|
11
|
+
// rules, images — because it is the intersection of what every format here can
|
|
12
|
+
// express, not the union. A DOCX can hold a text box rotated 3° over a chart;
|
|
13
|
+
// Markdown cannot, plain text cannot, and pretending otherwise means every
|
|
14
|
+
// writer grows a branch for something only one reader ever emits. Anything
|
|
15
|
+
// outside this vocabulary is flattened on the way IN, by the reader that knows
|
|
16
|
+
// what it meant, and the loss is reported (`DocNotice`) rather than discovered.
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
export function emptyDoc() {
|
|
19
|
+
return { blocks: [], notices: [] };
|
|
20
|
+
}
|
|
21
|
+
/** A plain run of text, used constantly by the readers. */
|
|
22
|
+
export function text(value) {
|
|
23
|
+
return [{ text: value }];
|
|
24
|
+
}
|
|
25
|
+
/** The plain text of a run list — what every non-PDF writer starts from. */
|
|
26
|
+
export function runsToText(runs) {
|
|
27
|
+
return runs.map((r) => r.text).join('');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Collapse runs that carry identical formatting.
|
|
31
|
+
*
|
|
32
|
+
* Word splits a sentence into a run per spell-check state, per revision, per
|
|
33
|
+
* rsid — a plain paragraph routinely arrives as thirty runs. Left alone, that
|
|
34
|
+
* is thirty `Tj` operators in the PDF and thirty `<span>`s in the HTML, and the
|
|
35
|
+
* line-breaker cannot kern across the joins either. This is the one bit of
|
|
36
|
+
* tidying every reader wants, so it lives here.
|
|
37
|
+
*/
|
|
38
|
+
export function mergeRuns(runs) {
|
|
39
|
+
const out = [];
|
|
40
|
+
for (const run of runs) {
|
|
41
|
+
if (!run.text)
|
|
42
|
+
continue;
|
|
43
|
+
const last = out[out.length - 1];
|
|
44
|
+
if (last && sameFormat(last, run))
|
|
45
|
+
last.text += run.text;
|
|
46
|
+
else
|
|
47
|
+
out.push({ ...run });
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
function sameFormat(a, b) {
|
|
52
|
+
return (!!a.bold === !!b.bold &&
|
|
53
|
+
!!a.italic === !!b.italic &&
|
|
54
|
+
!!a.code === !!b.code &&
|
|
55
|
+
!!a.underline === !!b.underline &&
|
|
56
|
+
!!a.strike === !!b.strike &&
|
|
57
|
+
a.link === b.link);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Drop empty paragraphs and merge every block's runs.
|
|
61
|
+
*
|
|
62
|
+
* A blank paragraph is how a Word user makes a gap, so ONE is kept as a
|
|
63
|
+
* paragraph with a single space — the writers turn that into a normal
|
|
64
|
+
* paragraph gap. Runs of them (a page's worth of Enter to push a heading down)
|
|
65
|
+
* collapse, because the PDF paginates on its own and reproducing somebody's
|
|
66
|
+
* manual pagination inside a different page size produces holes.
|
|
67
|
+
*/
|
|
68
|
+
export function tidy(doc) {
|
|
69
|
+
const blocks = [];
|
|
70
|
+
let blankRun = 0;
|
|
71
|
+
for (const block of doc.blocks) {
|
|
72
|
+
if ('runs' in block) {
|
|
73
|
+
const merged = mergeRuns(block.runs);
|
|
74
|
+
const isBlank = merged.every((r) => !r.text.trim());
|
|
75
|
+
if (isBlank && block.kind === 'paragraph') {
|
|
76
|
+
blankRun += 1;
|
|
77
|
+
if (blankRun === 1)
|
|
78
|
+
blocks.push({ kind: 'paragraph', runs: [{ text: ' ' }] });
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (isBlank)
|
|
82
|
+
continue;
|
|
83
|
+
blankRun = 0;
|
|
84
|
+
blocks.push({ ...block, runs: merged });
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
blankRun = 0;
|
|
88
|
+
if (block.kind === 'list') {
|
|
89
|
+
const items = block.items
|
|
90
|
+
.map((i) => ({ ...i, runs: mergeRuns(i.runs) }))
|
|
91
|
+
.filter((i) => runsToText(i.runs).trim());
|
|
92
|
+
if (items.length)
|
|
93
|
+
blocks.push({ ...block, items });
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (block.kind === 'table') {
|
|
97
|
+
blocks.push({
|
|
98
|
+
...block,
|
|
99
|
+
header: block.header ? block.header.map(mergeRuns) : null,
|
|
100
|
+
rows: block.rows.map((row) => row.map(mergeRuns)),
|
|
101
|
+
});
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
blocks.push(block);
|
|
105
|
+
}
|
|
106
|
+
// A leading or trailing gap is somebody's cursor, not their intent.
|
|
107
|
+
while (blocks.length && isSpacer(blocks[0]))
|
|
108
|
+
blocks.shift();
|
|
109
|
+
while (blocks.length && isSpacer(blocks[blocks.length - 1]))
|
|
110
|
+
blocks.pop();
|
|
111
|
+
return { ...doc, blocks };
|
|
112
|
+
}
|
|
113
|
+
function isSpacer(block) {
|
|
114
|
+
return block.kind === 'paragraph' && !runsToText(block.runs).trim();
|
|
115
|
+
}
|
|
116
|
+
export function addNotice(doc, message, severity = 'loss') {
|
|
117
|
+
if (doc.notices.some((n) => n.message === message))
|
|
118
|
+
return;
|
|
119
|
+
doc.notices.push({ message, severity });
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { type FontId } from './metrics.js';
|
|
2
|
+
export type { FontId };
|
|
3
|
+
export interface Rgb {
|
|
4
|
+
r: number;
|
|
5
|
+
g: number;
|
|
6
|
+
b: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function rgb(r: number, g: number, b: number): Rgb;
|
|
9
|
+
/** A JPEG ready to be embedded. `/DCTDecode` takes the compressed bytes as-is. */
|
|
10
|
+
export interface PdfImage {
|
|
11
|
+
jpeg: Uint8Array;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
}
|
|
15
|
+
export interface EncodeReport {
|
|
16
|
+
/** Distinct characters that could not be written at all. */
|
|
17
|
+
dropped: Set<string>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A JS string as WinAnsi bytes.
|
|
21
|
+
*
|
|
22
|
+
* Anything unrepresentable becomes '?' and is recorded on `report`, so the UI
|
|
23
|
+
* can say *which* characters went missing rather than leaving somebody to spot
|
|
24
|
+
* it themselves halfway down page four.
|
|
25
|
+
*/
|
|
26
|
+
export declare function toWinAnsi(text: string, report?: EncodeReport): number[];
|
|
27
|
+
/** The width of a string at a given size, in points. */
|
|
28
|
+
export declare function widthOfText(font: FontId, text: string, size: number): number;
|
|
29
|
+
interface LinkAnnot {
|
|
30
|
+
rect: [number, number, number, number];
|
|
31
|
+
url: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* One page, accumulating content-stream operators.
|
|
35
|
+
*
|
|
36
|
+
* The op list is built as strings and joined at save time. A page of dense text
|
|
37
|
+
* is a few thousand short strings, which is nothing next to the image bytes
|
|
38
|
+
* beside it, and the alternative — encoding to bytes per op — makes every
|
|
39
|
+
* drawing call allocate.
|
|
40
|
+
*/
|
|
41
|
+
export declare class PdfPage {
|
|
42
|
+
width: number;
|
|
43
|
+
height: number;
|
|
44
|
+
private ops;
|
|
45
|
+
private images;
|
|
46
|
+
private links;
|
|
47
|
+
/** Fonts actually used, so a page's /Resources only names what it draws. */
|
|
48
|
+
private usedFonts;
|
|
49
|
+
private report?;
|
|
50
|
+
constructor(width: number, height: number, report?: EncodeReport);
|
|
51
|
+
/**
|
|
52
|
+
* Change this page's paper size. See the note on `width`/`height` above:
|
|
53
|
+
* valid only before anything is drawn.
|
|
54
|
+
*/
|
|
55
|
+
setSize(width: number, height: number): void;
|
|
56
|
+
/**
|
|
57
|
+
* `y` is the BASELINE, and the origin is bottom-left — PDF's own convention,
|
|
58
|
+
* kept rather than flipped so the ported layout engine reads the same in both
|
|
59
|
+
* apps and a bug in one is recognisable in the other.
|
|
60
|
+
*/
|
|
61
|
+
drawText(text: string, opts: {
|
|
62
|
+
x: number;
|
|
63
|
+
y: number;
|
|
64
|
+
size: number;
|
|
65
|
+
font: FontId;
|
|
66
|
+
color: Rgb;
|
|
67
|
+
}): void;
|
|
68
|
+
drawRect(opts: {
|
|
69
|
+
x: number;
|
|
70
|
+
y: number;
|
|
71
|
+
width: number;
|
|
72
|
+
height: number;
|
|
73
|
+
color?: Rgb;
|
|
74
|
+
borderColor?: Rgb;
|
|
75
|
+
borderWidth?: number;
|
|
76
|
+
}): void;
|
|
77
|
+
drawImage(image: PdfImage, opts: {
|
|
78
|
+
x: number;
|
|
79
|
+
y: number;
|
|
80
|
+
width: number;
|
|
81
|
+
height: number;
|
|
82
|
+
}): void;
|
|
83
|
+
/**
|
|
84
|
+
* A clickable region. Kept separate from the drawing that makes it visible:
|
|
85
|
+
* a link's underline is content and its hotspot is an annotation, and the two
|
|
86
|
+
* are only in the same place because we put them there.
|
|
87
|
+
*/
|
|
88
|
+
addLink(x1: number, y1: number, x2: number, y2: number, url: string): void;
|
|
89
|
+
/** @internal */
|
|
90
|
+
build(): {
|
|
91
|
+
content: string;
|
|
92
|
+
images: PdfImage[];
|
|
93
|
+
links: LinkAnnot[];
|
|
94
|
+
fonts: FontId[];
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export interface PdfMeta {
|
|
98
|
+
title?: string;
|
|
99
|
+
author?: string;
|
|
100
|
+
/** Defaults to "Universal Converter". */
|
|
101
|
+
producer?: string;
|
|
102
|
+
}
|
|
103
|
+
export declare class PdfDocument {
|
|
104
|
+
private pages;
|
|
105
|
+
/** Collected across every page, so the UI can report it once at the end. */
|
|
106
|
+
readonly report: EncodeReport;
|
|
107
|
+
addPage(width: number, height: number): PdfPage;
|
|
108
|
+
get pageCount(): number;
|
|
109
|
+
/**
|
|
110
|
+
* Serialise. Object numbers are allocated as we go rather than computed from
|
|
111
|
+
* a formula — the old `3 + i * 3` arithmetic in `pdf.ts` was correct only
|
|
112
|
+
* while every page had exactly one image and no annotations, and a formula
|
|
113
|
+
* that has to be re-derived every time the object graph changes is a bug
|
|
114
|
+
* waiting for the next feature.
|
|
115
|
+
*/
|
|
116
|
+
save(meta?: PdfMeta): Blob;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=pdfcore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdfcore.d.ts","sourceRoot":"","sources":["../src/pdfcore.ts"],"names":[],"mappings":"AAqCA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAA;AAExD,YAAY,EAAE,MAAM,EAAE,CAAA;AAEtB,MAAM,WAAW,GAAG;IAClB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AAED,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,GAAG,CAExD;AAED,kFAAkF;AAClF,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,UAAU,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AA6DD,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,EAAE,CAuBvE;AAED,wDAAwD;AACxD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAK5E;AAoBD,UAAU,SAAS;IACjB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC,GAAG,EAAE,MAAM,CAAA;CACZ;AAED;;;;;;;GAOG;AACH,qBAAa,OAAO;IAQlB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,GAAG,CAAe;IAC1B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,KAAK,CAAkB;IAC/B,4EAA4E;IAC5E,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,MAAM,CAAC,CAAc;gBAEjB,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY;IAMhE;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ5C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,GAAG,IAAI;IAcpG,QAAQ,CAAC,IAAI,EAAE;QACb,CAAC,EAAE,MAAM,CAAA;QACT,CAAC,EAAE,MAAM,CAAA;QACT,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;QACd,KAAK,CAAC,EAAE,GAAG,CAAA;QACX,WAAW,CAAC,EAAE,GAAG,CAAA;QACjB,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,GAAG,IAAI;IAaR,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAW/F;;;;OAIG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAI1E,gBAAgB;IAChB,KAAK,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;QAAC,KAAK,EAAE,SAAS,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE;CAQtF;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAgB;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAyB;IAEtD,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAM/C,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED;;;;;;OAMG;IACH,IAAI,CAAC,IAAI,GAAE,OAAY,GAAG,IAAI;CA2I/B"}
|