nuvra 0.7.1 → 0.7.2
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 +16 -5
- package/dist/components/document-editor.vue.d.ts +6 -1
- package/dist/components/editor-outline.vue.d.ts +12 -3
- package/dist/components/editor-toolbar.vue.d.ts +6 -4
- package/dist/core/dates.d.ts +1 -4
- package/dist/core/engine/engine.d.ts +15 -4
- package/dist/core/labels.d.ts +3 -5
- package/dist/core/locales/uz.d.ts +6 -0
- package/dist/core/numbers.d.ts +1 -1
- package/dist/core/pdf-import/content.d.ts +59 -0
- package/dist/core/pdf-import/document.d.ts +61 -0
- package/dist/core/pdf-import/encodings.d.ts +17 -0
- package/dist/core/pdf-import/errors.d.ts +11 -0
- package/dist/core/pdf-import/filters.d.ts +18 -0
- package/dist/core/pdf-import/fonts.d.ts +66 -0
- package/dist/core/pdf-import/images.d.ts +9 -0
- package/dist/core/pdf-import/index.d.ts +22 -0
- package/dist/core/pdf-import/inflate.d.ts +11 -0
- package/dist/core/pdf-import/layout.d.ts +16 -0
- package/dist/core/pdf-import/load.d.ts +12 -0
- package/dist/core/pdf-import/objects.d.ts +89 -0
- package/dist/core/types.d.ts +6 -1
- package/dist/errors-tHVeiwWt.js +15 -0
- package/dist/errors-tHVeiwWt.js.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +3198 -3048
- package/dist/index.js.map +1 -1
- package/dist/pdf-import-Cu3c_cO5.js +2348 -0
- package/dist/pdf-import-Cu3c_cO5.js.map +1 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/dist/core/locales/uz-cyrl.d.ts +0 -3
package/README.md
CHANGED
|
@@ -19,8 +19,8 @@ files (`.docx`) you can open again.
|
|
|
19
19
|
the editor shows them, and the Word export uses Word's own header, footer and page fields.
|
|
20
20
|
- A ruler above the page for the margins and for the first line, left and right indents of a paragraph.
|
|
21
21
|
- A page watermark such as DRAFT or COPY, drawn behind the text of every page and carried into print, HTML and Word.
|
|
22
|
-
- Real `.docx` export and import, PDF download without the print dialog, multilevel
|
|
23
|
-
contents and a navigation pane with headings and page thumbnails.
|
|
22
|
+
- Real `.docx` export and import, PDF import as editable text, PDF download without the print dialog, multilevel
|
|
23
|
+
(1.1.1) numbering, a table of contents and a navigation pane with headings and page thumbnails.
|
|
24
24
|
- Footnotes at the bottom of their page, carried into print and Word.
|
|
25
25
|
- Comments with replies, tracked changes that round-trip with Word, a comparison of two versions, and templates
|
|
26
26
|
filled in as a form.
|
|
@@ -135,7 +135,7 @@ Numbers are pixels; strings are used as CSS lengths (`'100%'`, `'50vh'`).
|
|
|
135
135
|
| `focus` | — | The document received focus. |
|
|
136
136
|
| `blur` | — | The document lost focus; the model is up to date. |
|
|
137
137
|
| `uploadError` | `error: unknown` | An image was rejected or its upload failed. |
|
|
138
|
-
| `importError` | `error: unknown` | A Word file could not be read.
|
|
138
|
+
| `importError` | `error: unknown` | A Word or PDF file could not be read. |
|
|
139
139
|
| `exportError` | `error: unknown` | The PDF could not be drawn; no file is downloaded. |
|
|
140
140
|
| `selectionChange` | `selection: SelectionOffsets \| null` | The caret or selection moved; `null` when it left the document. |
|
|
141
141
|
|
|
@@ -148,6 +148,7 @@ Numbers are pixels; strings are used as CSS lengths (`'100%'`, `'50vh'`).
|
|
|
148
148
|
| `insertVariable(name)` | Inserts a template variable at the selection. |
|
|
149
149
|
| `updateTableOfContents()` | Inserts or refreshes the table of contents. |
|
|
150
150
|
| `importWord(file)` | Replaces the document with the content of a `.docx` file. |
|
|
151
|
+
| `importPdf(file)` | Replaces the document with the content of a `.pdf` file. |
|
|
151
152
|
| `print()` | Opens the browser print dialog. |
|
|
152
153
|
| `exportHtml()` | Downloads the document as an HTML page. |
|
|
153
154
|
| `exportWord()` | Downloads the document as a Word file (`.docx`). |
|
|
@@ -221,6 +222,16 @@ included; a file that cannot be read emits `importError`. `buildDocx` and `readD
|
|
|
221
222
|
document with several sections takes the page setup of its first section, and every further section starts with a
|
|
222
223
|
section break; the content of a different first page header is not imported.
|
|
223
224
|
|
|
225
|
+
"Open PDF file (.pdf)" (or `importPdf(file)`) turns a PDF into an editable document that can then be saved as Word.
|
|
226
|
+
PDF keeps positioned glyphs rather than paragraphs, so the structure is rebuilt from the layout: paragraphs with their
|
|
227
|
+
alignment, first-line indent and spacing, headings by font size, bulleted and numbered lists, tables from aligned
|
|
228
|
+
columns (bordered when the PDF draws borders, signature tables otherwise), bold, italic, colour, size and font, the
|
|
229
|
+
running header and footer with page numbers, pictures, and the page size and margins. Latin and Cyrillic text of
|
|
230
|
+
embedded and standard fonts is read, including Uzbek letters. Scanned pages come in as their pictures, since reading
|
|
231
|
+
them would take OCR, and encrypted files emit `importError`. The reader has no dependencies and loads on demand;
|
|
232
|
+
`readPdf` does the same in your own code and rejects with a `PdfImportError` whose `reason` is `'invalid'`,
|
|
233
|
+
`'encrypted'` or `'empty'`.
|
|
234
|
+
|
|
224
235
|
Tables longer than a page break between their rows in the page view, in print and in the PDF, as in Word: the rows
|
|
225
236
|
that do not fit continue at the top of the next page, and rows joined by a merged cell stay together.
|
|
226
237
|
|
|
@@ -380,8 +391,8 @@ underline and more), `textCase`, `color`, `highlight`, `align`, `lineHeight`, `d
|
|
|
380
391
|
|
|
381
392
|
## Languages
|
|
382
393
|
|
|
383
|
-
The interface ships in Uzbek (`uz`, the default),
|
|
384
|
-
|
|
394
|
+
The interface ships in Uzbek (`uz`, the default), English (`en`) and Russian (`ru`). The translations are part of the
|
|
395
|
+
package and cannot be changed from outside; an app only picks the language.
|
|
385
396
|
|
|
386
397
|
For one editor, pass the locale (or just its code) to the `locale` prop:
|
|
387
398
|
|
|
@@ -5,7 +5,7 @@ import { type EditorLocaleInput } from '../core/labels';
|
|
|
5
5
|
import { type DocumentViewMode, type PageSettings } from '../core/page';
|
|
6
6
|
import type { SlashCommand } from '../core/slash-commands';
|
|
7
7
|
import type { TemplateVariable } from '../core/templates';
|
|
8
|
-
import type { DocumentImageUploadHandler, ToolbarTool } from '../core/types';
|
|
8
|
+
import type { DocumentImageUploadHandler, ToolbarLayout, ToolbarTool } from '../core/types';
|
|
9
9
|
import { type EditorUiState } from '../core/ui-state';
|
|
10
10
|
import '../styles/document-content.css';
|
|
11
11
|
import '../styles/editor-ui.css';
|
|
@@ -49,6 +49,8 @@ interface Props {
|
|
|
49
49
|
* shortcuts, the `/` menu and the right-click menu are not affected.
|
|
50
50
|
*/
|
|
51
51
|
tools?: readonly ToolbarTool[];
|
|
52
|
+
/** `row` keeps every tool in one row; `tabs` splits them into Home, Insert, Layout and Review tabs. */
|
|
53
|
+
toolbarLayout?: ToolbarLayout;
|
|
52
54
|
/** Uploads an inserted image and resolves with its URL; without it images are embedded as data URLs. */
|
|
53
55
|
uploadImage?: DocumentImageUploadHandler;
|
|
54
56
|
/** Template variables the user can insert; typing `{{name}}` of one of them inserts it as well. */
|
|
@@ -92,6 +94,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
92
94
|
getHTML: () => string;
|
|
93
95
|
/** Replaces the document with the content and page setup of a `.docx` file. */
|
|
94
96
|
importWord: (file: File) => Promise<void>;
|
|
97
|
+
/** Replaces the document with the content and page setup of a `.pdf` file, rebuilt as editable text. */
|
|
98
|
+
importPdf: (file: File) => Promise<void>;
|
|
95
99
|
/** Inserts the chip of a template variable at the selection. */
|
|
96
100
|
insertVariable: (name: string) => void | undefined;
|
|
97
101
|
/** Inserts the table of contents at the selection, or refreshes the existing one. */
|
|
@@ -139,6 +143,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
139
143
|
defaultViewMode: DocumentViewMode;
|
|
140
144
|
maxImageSizeMb: number;
|
|
141
145
|
slashCommands: readonly SlashCommand[];
|
|
146
|
+
toolbarLayout: ToolbarLayout;
|
|
142
147
|
uploadImage: DocumentImageUploadHandler;
|
|
143
148
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
144
149
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import type { OutlineHeading, OutlineView } from '../core/outline';
|
|
2
2
|
import type { PageMetrics } from '../core/page';
|
|
3
3
|
import type { SheetGeometry } from '../core/pagination';
|
|
4
|
+
type Heading = OutlineHeading & {
|
|
5
|
+
page: number | null;
|
|
6
|
+
};
|
|
4
7
|
interface Props {
|
|
5
8
|
/** Headings of the document with the page each starts on, `null` outside the page view. */
|
|
6
|
-
headings:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
headings: readonly Heading[];
|
|
10
|
+
/** Heading the caret is in or after, marked in the tree. */
|
|
11
|
+
active: HTMLElement | null;
|
|
9
12
|
/** Clean HTML of every sheet, shown as page thumbnails; empty outside the page view. */
|
|
10
13
|
pages: readonly string[];
|
|
14
|
+
/** Page that holds the caret, counted from 1; its thumbnail is marked. */
|
|
15
|
+
currentPage: number;
|
|
11
16
|
/** Page geometry the thumbnails are scaled from. */
|
|
12
17
|
metrics: PageMetrics;
|
|
13
18
|
/** Size of every sheet; a sheet turned by a section break gets a turned thumbnail. */
|
|
@@ -19,6 +24,8 @@ type __VLS_Props = Props;
|
|
|
19
24
|
type __VLS_ModelProps = {
|
|
20
25
|
/** Which list is shown; the editor reads it to lay out thumbnails only while they are visible. */
|
|
21
26
|
'view'?: OutlineView;
|
|
27
|
+
/** Width of the panel in pixels; the editor keeps the document beside it. */
|
|
28
|
+
'width'?: number;
|
|
22
29
|
};
|
|
23
30
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
24
31
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
@@ -26,11 +33,13 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
26
33
|
close: () => any;
|
|
27
34
|
selectPage: (index: number) => any;
|
|
28
35
|
"update:view": (value: OutlineView) => any;
|
|
36
|
+
"update:width": (value: number) => any;
|
|
29
37
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
30
38
|
onSelect?: ((heading: HTMLElement) => any) | undefined;
|
|
31
39
|
onClose?: (() => any) | undefined;
|
|
32
40
|
onSelectPage?: ((index: number) => any) | undefined;
|
|
33
41
|
"onUpdate:view"?: ((value: OutlineView) => any) | undefined;
|
|
42
|
+
"onUpdate:width"?: ((value: number) => any) | undefined;
|
|
34
43
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
35
44
|
declare const _default: typeof __VLS_export;
|
|
36
45
|
export default _default;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { DocumentEngine } from '../core/engine/engine';
|
|
2
2
|
import { type PageSettings } from '../core/page';
|
|
3
3
|
import type { TemplateVariable } from '../core/templates';
|
|
4
|
-
import { type DocumentMenuAction, type ToolbarTool } from '../core/types';
|
|
4
|
+
import { type DocumentMenuAction, type ToolbarLayout, type ToolbarTool } from '../core/types';
|
|
5
5
|
import { type EditorUiState } from '../core/ui-state';
|
|
6
6
|
interface Props {
|
|
7
7
|
/** Read-only document: every editing control is disabled. */
|
|
@@ -38,14 +38,16 @@ interface Props {
|
|
|
38
38
|
variables: ReadonlyArray<TemplateVariable>;
|
|
39
39
|
/** Tools to show; every tool without a list. */
|
|
40
40
|
tools: readonly ToolbarTool[] | undefined;
|
|
41
|
+
/** One row with every tool, or tabs that show one group of tools at a time. */
|
|
42
|
+
layout: ToolbarLayout;
|
|
41
43
|
}
|
|
42
|
-
declare var
|
|
44
|
+
declare var __VLS_661: {};
|
|
43
45
|
type __VLS_Slots = {} & {
|
|
44
|
-
default?: (props: typeof
|
|
46
|
+
default?: (props: typeof __VLS_661) => any;
|
|
45
47
|
};
|
|
46
48
|
declare const __VLS_base: import("vue").DefineComponent<Props, {
|
|
47
49
|
/** Opens the link popover. */
|
|
48
|
-
openLink: () => void
|
|
50
|
+
openLink: () => Promise<void>;
|
|
49
51
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
50
52
|
menu: (action: DocumentMenuAction) => any;
|
|
51
53
|
find: () => any;
|
package/dist/core/dates.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import type { NumberWordsLocale } from './numbers';
|
|
2
2
|
/** A date as `dd.mm.yyyy`, the short form of Uzbek and Russian documents. */
|
|
3
3
|
export declare const formatShortDate: (date: Date) => string;
|
|
4
|
-
/**
|
|
5
|
-
* A date written out as official documents do: `2026-yil 14-sentabr`, `2026 йил 14 сентябрь`, `14 сентября 2026 г.`
|
|
6
|
-
* or `14 September 2026`.
|
|
7
|
-
*/
|
|
4
|
+
/** A date written out as official documents do: `2026-yil 14-sentabr`, `14 сентября 2026 г.` or `14 September 2026`. */
|
|
8
5
|
export declare const formatLongDate: (date: Date, locale?: NumberWordsLocale) => string;
|
|
@@ -10,7 +10,7 @@ import { type TextBookmark } from './selection';
|
|
|
10
10
|
import { type TableCell } from './tables';
|
|
11
11
|
/** A tracked insertion or deletion; the parts of one edit are joined. */
|
|
12
12
|
export interface TrackedChange {
|
|
13
|
-
/**
|
|
13
|
+
/** id shared by the parts of the edit. */
|
|
14
14
|
id: string;
|
|
15
15
|
/** Whether text was inserted or deleted. */
|
|
16
16
|
type: 'insert' | 'delete';
|
|
@@ -97,6 +97,8 @@ export declare class DocumentEngine {
|
|
|
97
97
|
readonly history: EditorHistory;
|
|
98
98
|
/** Find and replace over the document text. */
|
|
99
99
|
readonly search: SearchController;
|
|
100
|
+
/** Removes the mark of the heading last reached from the navigation panel. */
|
|
101
|
+
private jumpTimer;
|
|
100
102
|
/** Registered listeners per event. */
|
|
101
103
|
private readonly listeners;
|
|
102
104
|
/** Removes every DOM listener added by the engine. */
|
|
@@ -157,9 +159,12 @@ export declare class DocumentEngine {
|
|
|
157
159
|
/** Clean HTML of the document, without caret placeholders or other editor-only markup. */
|
|
158
160
|
getHTML(): string;
|
|
159
161
|
/**
|
|
160
|
-
* Replaces the whole document with
|
|
162
|
+
* Replaces the whole document with sanitized HTML.
|
|
161
163
|
*
|
|
162
164
|
* @param html New content; scripts, handlers and unsupported markup are dropped.
|
|
165
|
+
* @param addToHistory
|
|
166
|
+
* @param emitUpdate
|
|
167
|
+
* @param keepSelection
|
|
163
168
|
* @param options.addToHistory Record the replacement as an undo step instead of clearing the history.
|
|
164
169
|
* @param options.emitUpdate Emit `update` so the host saves the new content.
|
|
165
170
|
*/
|
|
@@ -414,7 +419,7 @@ export declare class DocumentEngine {
|
|
|
414
419
|
/** Inserts a manual page break. */
|
|
415
420
|
insertPageBreak(): void;
|
|
416
421
|
/**
|
|
417
|
-
* Inserts sanitised HTML at the selection as one undo step. By default it flows into the current line the way pasting
|
|
422
|
+
* Inserts sanitised HTML at the selection as one undo step. By default, it flows into the current line the way pasting
|
|
418
423
|
* does; with `asBlocks` the content starts on a line of its own after a non-empty paragraph, as prepared fragments
|
|
419
424
|
* such as signature blocks and document templates should.
|
|
420
425
|
*/
|
|
@@ -433,8 +438,14 @@ export declare class DocumentEngine {
|
|
|
433
438
|
setTableOfContents(html: string, { addToHistory }?: {
|
|
434
439
|
addToHistory?: boolean | undefined;
|
|
435
440
|
}): void;
|
|
436
|
-
/**
|
|
441
|
+
/**
|
|
442
|
+
* Scrolls a heading to the middle of the view, clear of the sticky ruler, puts the caret at its start and briefly
|
|
443
|
+
* marks its text, so the eye finds where the jump landed.
|
|
444
|
+
*/
|
|
437
445
|
goToHeading(heading: HTMLElement): void;
|
|
446
|
+
/** Paints the jump mark over a heading and fades it out after a moment; browsers without CSS highlights skip it. */
|
|
447
|
+
private markJump;
|
|
448
|
+
private clearJumpMark;
|
|
438
449
|
/**
|
|
439
450
|
* Inserts a footnote reference with its text at the selection, replacing selected content, as one undo step.
|
|
440
451
|
* @returns the new reference, or `null` when nothing could be inserted (for example in a code block).
|
package/dist/core/labels.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type EditorLabelKey } from './locales/uz';
|
|
2
2
|
export type { EditorLabelKey };
|
|
3
|
-
/** Languages the editor interface is available in: Uzbek
|
|
4
|
-
export type EditorLocaleCode = 'uz' | '
|
|
3
|
+
/** Languages the editor interface is available in: Uzbek, English and Russian. */
|
|
4
|
+
export type EditorLocaleCode = 'uz' | 'en' | 'ru';
|
|
5
5
|
/**
|
|
6
6
|
* A built-in interface language. Locales only select one of the translations shipped with the editor; the texts
|
|
7
7
|
* themselves cannot be changed from outside.
|
|
@@ -14,10 +14,8 @@ export interface EditorLocale {
|
|
|
14
14
|
}
|
|
15
15
|
/** A locale object, or just its code. */
|
|
16
16
|
export type EditorLocaleInput = EditorLocale | EditorLocaleCode;
|
|
17
|
-
/** Uzbek
|
|
17
|
+
/** Uzbek interface. */
|
|
18
18
|
export declare const uzLocale: EditorLocale;
|
|
19
|
-
/** Uzbek (Cyrillic) interface. */
|
|
20
|
-
export declare const uzCyrlLocale: EditorLocale;
|
|
21
19
|
/** English interface. */
|
|
22
20
|
export declare const enLocale: EditorLocale;
|
|
23
21
|
/** Russian interface. */
|
|
@@ -92,6 +92,7 @@ export declare const uz: {
|
|
|
92
92
|
readonly 'editor.imageSizeError': "Rasm hajmi {size} MB dan oshmasligi kerak";
|
|
93
93
|
readonly 'editor.imageTypeError': "Faqat rasm fayllarini qo‘shish mumkin";
|
|
94
94
|
readonly 'editor.imageUploadError': "Rasmni yuklab bo‘lmadi";
|
|
95
|
+
readonly 'editor.importPdf': "PDF faylini ochish (.pdf)";
|
|
95
96
|
readonly 'editor.importWord': "Word faylini ochish (.docx)";
|
|
96
97
|
readonly 'editor.increaseFontSize': "Shriftni kattalashtirish";
|
|
97
98
|
readonly 'editor.indent': "Chekinishni oshirish";
|
|
@@ -208,6 +209,11 @@ export declare const uz: {
|
|
|
208
209
|
readonly 'editor.table.pickSize': "O‘lchamni tanlang";
|
|
209
210
|
readonly 'editor.table.splitCell': "Katakni ajratish";
|
|
210
211
|
readonly 'editor.table.title': "Jadval";
|
|
212
|
+
readonly 'editor.tabs': "Asboblar bo‘limlari";
|
|
213
|
+
readonly 'editor.tabs.home': "Asosiy";
|
|
214
|
+
readonly 'editor.tabs.insert': "Qo‘shish";
|
|
215
|
+
readonly 'editor.tabs.layout': "Sahifa";
|
|
216
|
+
readonly 'editor.tabs.review': "Ko‘rib chiqish";
|
|
211
217
|
readonly 'editor.taskList': "Vazifalar ro‘yxati";
|
|
212
218
|
readonly 'editor.templates': "Hujjat shablonlari";
|
|
213
219
|
readonly 'editor.templates.act': "Dalolatnoma";
|
package/dist/core/numbers.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Languages numbers can be written out in. */
|
|
2
|
-
export type NumberWordsLocale = 'uz' | '
|
|
2
|
+
export type NumberWordsLocale = 'uz' | 'ru' | 'en';
|
|
3
3
|
/**
|
|
4
4
|
* Writes a whole number out in words, for example `15 000 000` as `o‘n besh million`. Fractions are dropped; negative
|
|
5
5
|
* numbers get a minus word.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs page content streams far enough to know where text and pictures land: the graphics and text state, font
|
|
3
|
+
* changes, form XObjects and the page rotation. Glyphs that continue each other merge into text spans, so the layout
|
|
4
|
+
* step works with words and phrases instead of single characters. Coordinates are page points from the top-left
|
|
5
|
+
* corner of the page as it is displayed.
|
|
6
|
+
*/
|
|
7
|
+
import type { PdfDocument, PdfPage } from './document';
|
|
8
|
+
import { PdfFont } from './fonts';
|
|
9
|
+
import { type PdfDict, type PdfStream } from './objects';
|
|
10
|
+
/** A run of text in one style on one baseline. */
|
|
11
|
+
export interface TextSpan {
|
|
12
|
+
text: string;
|
|
13
|
+
/** Left edge and baseline, in points from the top-left corner. */
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
width: number;
|
|
17
|
+
/** Font size in points as displayed. */
|
|
18
|
+
size: number;
|
|
19
|
+
bold: boolean;
|
|
20
|
+
italic: boolean;
|
|
21
|
+
family: string | undefined;
|
|
22
|
+
/** Fill colour as `#rrggbb`. */
|
|
23
|
+
color: string;
|
|
24
|
+
}
|
|
25
|
+
/** A picture placed on the page. */
|
|
26
|
+
export interface PageImage {
|
|
27
|
+
src: string;
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
width: number;
|
|
31
|
+
height: number;
|
|
32
|
+
}
|
|
33
|
+
/** A painted rectangle, such as a table border or a rule, in page points from the top-left corner. */
|
|
34
|
+
export interface Box {
|
|
35
|
+
x: number;
|
|
36
|
+
y: number;
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
}
|
|
40
|
+
/** What one page shows. */
|
|
41
|
+
export interface PageContent {
|
|
42
|
+
width: number;
|
|
43
|
+
height: number;
|
|
44
|
+
spans: TextSpan[];
|
|
45
|
+
images: PageImage[];
|
|
46
|
+
/** Thin painted lines: table borders, underlines and separators. */
|
|
47
|
+
rules: Box[];
|
|
48
|
+
}
|
|
49
|
+
/** Reads the text spans and pictures of pages; fonts and pictures are shared across pages. */
|
|
50
|
+
export declare class ContentReader {
|
|
51
|
+
private readonly doc;
|
|
52
|
+
private readonly fonts;
|
|
53
|
+
private readonly images;
|
|
54
|
+
constructor(doc: PdfDocument);
|
|
55
|
+
read(page: PdfPage): PageContent;
|
|
56
|
+
get document(): PdfDocument;
|
|
57
|
+
font(dict: PdfDict): PdfFont;
|
|
58
|
+
image(stream: PdfStream): string | null;
|
|
59
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { PdfDict, type PdfObject, PdfStream } from './objects';
|
|
2
|
+
/** A page with the attributes it inherits from the page tree. */
|
|
3
|
+
export interface PdfPage {
|
|
4
|
+
dict: PdfDict;
|
|
5
|
+
resources: PdfDict;
|
|
6
|
+
/** Visible area in default user space: `[x0, y0, x1, y1]`. */
|
|
7
|
+
box: [number, number, number, number];
|
|
8
|
+
/** Clockwise rotation in degrees: 0, 90, 180 or 270. */
|
|
9
|
+
rotate: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class PdfDocument {
|
|
12
|
+
readonly data: Uint8Array;
|
|
13
|
+
private readonly xref;
|
|
14
|
+
private readonly cache;
|
|
15
|
+
/** Objects being loaded, to stop reference loops such as a `/Length` pointing back at its stream. */
|
|
16
|
+
private readonly loading;
|
|
17
|
+
private readonly objectStreams;
|
|
18
|
+
private trailer;
|
|
19
|
+
/** Whether the cross-references were rebuilt by scanning, which is done at most once. */
|
|
20
|
+
private repaired;
|
|
21
|
+
constructor(data: Uint8Array);
|
|
22
|
+
/** Resolves a reference; other values are returned as they are. */
|
|
23
|
+
get(value: PdfObject | undefined): PdfObject | undefined;
|
|
24
|
+
dict(value: PdfObject | undefined): PdfDict | undefined;
|
|
25
|
+
number(value: PdfObject | undefined): number | undefined;
|
|
26
|
+
name(value: PdfObject | undefined): string | undefined;
|
|
27
|
+
array(value: PdfObject | undefined): PdfObject[] | undefined;
|
|
28
|
+
numbers(value: PdfObject | undefined): number[] | undefined;
|
|
29
|
+
stream(value: PdfObject | undefined): PdfStream | undefined;
|
|
30
|
+
/** Filter names of a stream, in the order they are applied. */
|
|
31
|
+
filters(stream: PdfStream): string[];
|
|
32
|
+
/**
|
|
33
|
+
* Decoded stream data. Decoding stops in front of an image codec, so a JPEG picture comes back as its JPEG bytes;
|
|
34
|
+
* `imageFilter` then names that codec.
|
|
35
|
+
*/
|
|
36
|
+
decode(stream: PdfStream): {
|
|
37
|
+
data: Uint8Array;
|
|
38
|
+
imageFilter?: string;
|
|
39
|
+
};
|
|
40
|
+
/** Decoded data of a stream, or an empty array when it cannot be decoded. */
|
|
41
|
+
bytes(value: PdfObject | undefined): Uint8Array;
|
|
42
|
+
private predictor;
|
|
43
|
+
/** The pages in order, with inherited resources, boxes and rotation applied. */
|
|
44
|
+
pages(): PdfPage[];
|
|
45
|
+
private box;
|
|
46
|
+
/** Concatenated, decoded content streams of a page. */
|
|
47
|
+
contents(page: PdfPage): Uint8Array;
|
|
48
|
+
private object;
|
|
49
|
+
private parserAt;
|
|
50
|
+
/** Parses `num gen obj … endobj` at an offset; `undefined` when the offset does not hold that object. */
|
|
51
|
+
private objectAt;
|
|
52
|
+
private compressedObject;
|
|
53
|
+
/** Follows `startxref` and every `/Prev`; entries of newer sections win. */
|
|
54
|
+
private readXrefChain;
|
|
55
|
+
private readXrefSection;
|
|
56
|
+
private readXrefTable;
|
|
57
|
+
private readXrefStream;
|
|
58
|
+
/** Rebuilds the cross-references by scanning the file for `num gen obj`; later definitions win. */
|
|
59
|
+
private rebuildXref;
|
|
60
|
+
private indexObjectStream;
|
|
61
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Character encodings of simple PDF fonts: the predefined encodings, glyph names from `/Differences` mapped to
|
|
3
|
+
* Unicode, and the glyph widths of the standard fonts, which PDF files may use without embedding or measuring them.
|
|
4
|
+
*/
|
|
5
|
+
/** Unicode text of each code 0..255 of a simple font encoding; `''` for unused codes. */
|
|
6
|
+
export type Encoding = readonly string[];
|
|
7
|
+
export declare const WIN_ANSI: Encoding;
|
|
8
|
+
export declare const MAC_ROMAN: Encoding;
|
|
9
|
+
/** Adobe StandardEncoding: ASCII with curly quotes, plus its own upper half. */
|
|
10
|
+
export declare const STANDARD: Encoding;
|
|
11
|
+
/** Unicode text of a glyph name, or `undefined` for names that carry no meaning, such as `g42`. */
|
|
12
|
+
export declare const glyphToUnicode: (name: string) => string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Width of a character in a standard font that the file does not measure, in thousandths of the font size. Only the
|
|
15
|
+
* ASCII range is tabulated; other characters take the font's average width.
|
|
16
|
+
*/
|
|
17
|
+
export declare const standardWidth: (fontName: string, text: string) => number;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The error of the PDF reader, kept apart from the reader so it can be exported and checked with `instanceof`
|
|
3
|
+
* without loading the reader itself.
|
|
4
|
+
*/
|
|
5
|
+
/** Why a PDF file could not be opened. */
|
|
6
|
+
export type PdfImportErrorReason = 'invalid' | 'encrypted' | 'empty';
|
|
7
|
+
/** Thrown for PDF files this reader cannot open; the message names the reason. */
|
|
8
|
+
export declare class PdfImportError extends Error {
|
|
9
|
+
readonly reason: PdfImportErrorReason;
|
|
10
|
+
constructor(reason: PdfImportErrorReason);
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Filters whose output is an image format; decoding stops in front of them. */
|
|
2
|
+
export declare const IMAGE_FILTERS: Set<string>;
|
|
3
|
+
/** Predictor settings from a filter's `DecodeParms`. */
|
|
4
|
+
export interface PredictorParams {
|
|
5
|
+
predictor: number;
|
|
6
|
+
colors: number;
|
|
7
|
+
bitsPerComponent: number;
|
|
8
|
+
columns: number;
|
|
9
|
+
/** LZW only: whether code widths grow one code early, as the specification's default. */
|
|
10
|
+
earlyChange: number;
|
|
11
|
+
}
|
|
12
|
+
export declare const DEFAULT_PREDICTOR: PredictorParams;
|
|
13
|
+
/**
|
|
14
|
+
* Applies one decoding filter.
|
|
15
|
+
*
|
|
16
|
+
* @throws Error for a filter this reader does not implement.
|
|
17
|
+
*/
|
|
18
|
+
export declare const applyFilter: (name: string, data: Uint8Array, params: PredictorParams) => Uint8Array;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fonts as the text extractor needs them: how a string splits into character codes, the Unicode text and advance
|
|
3
|
+
* width of every code, and the style the font name and descriptor imply. Composite (Type0) fonts are read through
|
|
4
|
+
* their CMaps; simple fonts through `/ToUnicode`, their encoding and `/Differences`.
|
|
5
|
+
*/
|
|
6
|
+
import type { PdfDocument } from './document';
|
|
7
|
+
import { type PdfDict } from './objects';
|
|
8
|
+
/** One shown character code. */
|
|
9
|
+
export interface Glyph {
|
|
10
|
+
/** Unicode text; empty for codes without a known meaning. */
|
|
11
|
+
text: string;
|
|
12
|
+
/** Advance width in thousandths of the font size. */
|
|
13
|
+
width: number;
|
|
14
|
+
/** Whether word spacing applies: single-byte code 32. */
|
|
15
|
+
wordSpace: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** A range of valid codes of one byte length. */
|
|
18
|
+
interface CodespaceRange {
|
|
19
|
+
length: number;
|
|
20
|
+
low: number;
|
|
21
|
+
high: number;
|
|
22
|
+
}
|
|
23
|
+
/** What a CMap stream maps codes to. */
|
|
24
|
+
interface CMap {
|
|
25
|
+
codespaces: CodespaceRange[];
|
|
26
|
+
/** Unicode text per code (ToUnicode CMaps). */
|
|
27
|
+
unicode: Map<number, string>;
|
|
28
|
+
/** CID per code (encoding CMaps of composite fonts). */
|
|
29
|
+
cids: Map<number, number>;
|
|
30
|
+
}
|
|
31
|
+
/** Parses a CMap stream: code space, `bfchar`/`bfrange` to Unicode and `cidchar`/`cidrange` to CIDs. */
|
|
32
|
+
export declare const parseCMap: (data: Uint8Array) => CMap;
|
|
33
|
+
export declare class PdfFont {
|
|
34
|
+
/** Font name without the subset prefix, such as `TimesNewRomanPS-BoldMT`. */
|
|
35
|
+
readonly name: string;
|
|
36
|
+
readonly bold: boolean;
|
|
37
|
+
readonly italic: boolean;
|
|
38
|
+
/** CSS family of the editor's font list, when the font is one of them. */
|
|
39
|
+
readonly family: string | undefined;
|
|
40
|
+
/** Factor from the text space size to the displayed size; Type3 fonts scale glyphs by their own matrix. */
|
|
41
|
+
readonly sizeScale: number;
|
|
42
|
+
/** Whether the font is a composite (Type0) font with multibyte codes. */
|
|
43
|
+
private readonly composite;
|
|
44
|
+
private readonly codespaces;
|
|
45
|
+
private readonly toUnicode;
|
|
46
|
+
private readonly cids;
|
|
47
|
+
private readonly encoding;
|
|
48
|
+
private readonly differences;
|
|
49
|
+
private readonly widths;
|
|
50
|
+
private readonly defaultWidth;
|
|
51
|
+
/** Scale of widths into thousandths of the font size; Type3 fonts have their own glyph space. */
|
|
52
|
+
private readonly widthScale;
|
|
53
|
+
/** Whether the font carries no widths, as unembedded standard fonts may. */
|
|
54
|
+
private readonly measuredByName;
|
|
55
|
+
private readonly glyphCache;
|
|
56
|
+
constructor(doc: PdfDocument, dict: PdfDict);
|
|
57
|
+
private readEncoding;
|
|
58
|
+
private readCidWidths;
|
|
59
|
+
/** Splits a shown string into its character codes and describes each one. */
|
|
60
|
+
decode(bytes: Uint8Array): Glyph[];
|
|
61
|
+
private codeLength;
|
|
62
|
+
private describe;
|
|
63
|
+
private unicodeOf;
|
|
64
|
+
private widthOf;
|
|
65
|
+
}
|
|
66
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pictures of a PDF as `data:` URLs: JPEG data is embedded as it is, and decoded pixel data (gray, RGB, CMYK, ICC
|
|
3
|
+
* based and indexed color, 1 to 16 bits per component, with a soft mask) is painted into a canvas and saved as PNG.
|
|
4
|
+
* Without a DOM canvas, as in tests or workers, only JPEG pictures come through.
|
|
5
|
+
*/
|
|
6
|
+
import type { PdfDocument } from './document';
|
|
7
|
+
import { PdfStream } from './objects';
|
|
8
|
+
/** `data:` URL of an image XObject, or `null` when it cannot be shown. */
|
|
9
|
+
export declare const imageSource: (doc: PdfDocument, stream: PdfStream) => string | null;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opens a PDF document as editable content: text with its formatting, headings, lists, tables and pictures, plus the
|
|
3
|
+
* page setup. PDF stores positioned glyphs rather than paragraphs, so the structure is reconstructed from the layout;
|
|
4
|
+
* text drawn as pictures (scanned pages) comes through as the pictures themselves. Encrypted files are refused.
|
|
5
|
+
*/
|
|
6
|
+
import type { PageSettings } from '../page';
|
|
7
|
+
import { PdfImportError } from './errors';
|
|
8
|
+
export { PdfImportError };
|
|
9
|
+
export type { PdfImportErrorReason } from './errors';
|
|
10
|
+
/** What was read from a PDF document. */
|
|
11
|
+
export interface PdfImport {
|
|
12
|
+
/** Document content as HTML; the editor's sanitiser still runs over it. */
|
|
13
|
+
html: string;
|
|
14
|
+
/** Paper size, orientation, margins and running header and footer of the document. */
|
|
15
|
+
page: PageSettings;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Reads a `.pdf` file into editor HTML and page settings.
|
|
19
|
+
*
|
|
20
|
+
* @throws PdfImportError when the file is not a PDF, is encrypted, or shows neither text nor pictures.
|
|
21
|
+
*/
|
|
22
|
+
export declare const readPdf: (data: ArrayBuffer | Uint8Array) => Promise<PdfImport>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synchronous zlib/DEFLATE decoder (RFC 1950/1951). PDF streams are decoded while objects are resolved, which keeps
|
|
3
|
+
* the whole reader synchronous; the browser's `DecompressionStream` is asynchronous and rejects the truncated or
|
|
4
|
+
* checksum-less streams that many PDF writers produce. Decoding is lenient: a damaged stream yields the bytes read so
|
|
5
|
+
* far instead of an error.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Decodes zlib data, or raw DEFLATE data when the zlib header is missing. The Adler-32 checksum is not verified:
|
|
9
|
+
* PDF writers get it wrong often enough that checking it would only lose content.
|
|
10
|
+
*/
|
|
11
|
+
export declare const inflate: (data: Uint8Array) => Uint8Array;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rebuilds document structure from positioned text: spans become lines, repeated lines at the page edges become the
|
|
3
|
+
* header and footer, aligned columns become tables, and lines become paragraphs, headings and lists with their
|
|
4
|
+
* alignment, indents and spacing. The result is editor HTML and the page setup the text was laid out on.
|
|
5
|
+
*/
|
|
6
|
+
import { type PageSettings } from '../page';
|
|
7
|
+
import type { PageContent } from './content';
|
|
8
|
+
/** What the layout step produces. */
|
|
9
|
+
export interface LayoutResult {
|
|
10
|
+
html: string;
|
|
11
|
+
page: PageSettings;
|
|
12
|
+
/** Number of text characters read, to tell a scanned document from an empty one. */
|
|
13
|
+
characters: number;
|
|
14
|
+
}
|
|
15
|
+
/** Turns the content of every page into editor HTML and page settings. */
|
|
16
|
+
export declare const layoutPages: (contents: PageContent[]) => LayoutResult;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The public entry of the PDF reader. The reader is loaded on the first call, so applications that never open a PDF
|
|
3
|
+
* do not carry it in their main bundle.
|
|
4
|
+
*/
|
|
5
|
+
import type { PdfImport } from '.';
|
|
6
|
+
/**
|
|
7
|
+
* Reads a `.pdf` file into editor HTML and page settings: text with its formatting, headings, lists, tables and
|
|
8
|
+
* pictures, rebuilt from the layout of the pages. Scanned pages come through as their pictures.
|
|
9
|
+
*
|
|
10
|
+
* @throws PdfImportError when the file is not a PDF, is encrypted, or shows neither text nor pictures.
|
|
11
|
+
*/
|
|
12
|
+
export declare const readPdf: (data: ArrayBuffer | Uint8Array) => Promise<PdfImport>;
|