@build-qube/papyra 0.0.4 → 0.2.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 +129 -0
- package/dist/cache.d.ts +3 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js.map +1 -1
- package/dist/document.d.ts +251 -3
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +444 -16
- package/dist/document.js.map +1 -1
- package/dist/encode.d.ts +49 -0
- package/dist/encode.d.ts.map +1 -0
- package/dist/encode.js +71 -0
- package/dist/encode.js.map +1 -0
- package/dist/encoded.d.ts +91 -0
- package/dist/encoded.d.ts.map +1 -0
- package/dist/encoded.js +84 -0
- package/dist/encoded.js.map +1 -0
- package/dist/errors.d.ts +45 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +69 -0
- package/dist/errors.js.map +1 -0
- package/dist/fingerprint.d.ts +18 -0
- package/dist/fingerprint.d.ts.map +1 -0
- package/dist/fingerprint.js +48 -0
- package/dist/fingerprint.js.map +1 -0
- package/dist/index.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/links.d.ts +53 -0
- package/dist/links.d.ts.map +1 -0
- package/dist/links.js +26 -0
- package/dist/links.js.map +1 -0
- package/dist/outline.d.ts +72 -0
- package/dist/outline.d.ts.map +1 -0
- package/dist/outline.js +73 -0
- package/dist/outline.js.map +1 -0
- package/dist/runtime.d.ts +8 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +2 -0
- package/dist/runtime.js.map +1 -1
- package/dist/scheduler.d.ts +20 -2
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +15 -0
- package/dist/scheduler.js.map +1 -1
- package/dist/search.d.ts +50 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +151 -0
- package/dist/search.js.map +1 -0
- package/dist/text.d.ts +113 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +84 -0
- package/dist/text.js.map +1 -0
- package/dist/types.d.ts +96 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { OutlineDestination as NativeDestination, OutlineEntry as NativeEntry } from '@build-qube/papyra-native';
|
|
2
|
+
/** How a destination positions the page in the window (PDF 32000-1, 12.3.2.2). */
|
|
3
|
+
export type DestinationKind = 'XYZ' | 'Fit' | 'FitH' | 'FitV' | 'FitR' | 'FitB' | 'FitBH' | 'FitBV';
|
|
4
|
+
/**
|
|
5
|
+
* Where an outline entry points.
|
|
6
|
+
*
|
|
7
|
+
* Coordinates are PDF points measured from the page's bottom-left corner — the same
|
|
8
|
+
* space as {@link PageSize} — so converting to rendered pixels is
|
|
9
|
+
* `(pt / 72) * dpi`. `null` means "leave this axis as it is", which is how the spec
|
|
10
|
+
* spells a destination that scrolls vertically but not horizontally.
|
|
11
|
+
*/
|
|
12
|
+
export interface OutlineDestination {
|
|
13
|
+
/** 0-based page index. */
|
|
14
|
+
readonly page: number;
|
|
15
|
+
/** Which of the eight positioning modes the destination uses. */
|
|
16
|
+
readonly kind: DestinationKind;
|
|
17
|
+
/** Left edge, for `'XYZ'`, `'FitV'`, `'FitBV'` and `'FitR'`. */
|
|
18
|
+
readonly left: number | null;
|
|
19
|
+
/** Top edge, for `'XYZ'`, `'FitH'`, `'FitBH'` and `'FitR'`. */
|
|
20
|
+
readonly top: number | null;
|
|
21
|
+
/** Right edge. Only ever set for `'FitR'`. */
|
|
22
|
+
readonly right: number | null;
|
|
23
|
+
/** Bottom edge. Only ever set for `'FitR'`. */
|
|
24
|
+
readonly bottom: number | null;
|
|
25
|
+
/** Only ever set for `'XYZ'`. A zoom of 0 means "unchanged" and reads as `null`. */
|
|
26
|
+
readonly zoom: number | null;
|
|
27
|
+
}
|
|
28
|
+
/** A node in the document outline. */
|
|
29
|
+
export interface OutlineNode {
|
|
30
|
+
/** The entry's label, already decoded from UTF-16, UTF-8 or PDFDocEncoding. */
|
|
31
|
+
readonly title: string;
|
|
32
|
+
/**
|
|
33
|
+
* `null` for a container that groups children without pointing anywhere itself, and
|
|
34
|
+
* for entries whose action leaves this document (a URL, or another file).
|
|
35
|
+
*/
|
|
36
|
+
readonly dest: OutlineDestination | null;
|
|
37
|
+
/** `dest.page`, hoisted — the only field most viewers need. */
|
|
38
|
+
readonly page: number | null;
|
|
39
|
+
/** The document asks for this title to be drawn bold. */
|
|
40
|
+
readonly bold: boolean;
|
|
41
|
+
/** The document asks for this title to be drawn italic. */
|
|
42
|
+
readonly italic: boolean;
|
|
43
|
+
/** The document asks for this node to start expanded. */
|
|
44
|
+
readonly open: boolean;
|
|
45
|
+
/** Nested entries, empty for a leaf. */
|
|
46
|
+
readonly children: OutlineNode[];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* napi omits absent numbers rather than nulling them; normalise to one shape.
|
|
50
|
+
*
|
|
51
|
+
* Shared with the link reader, whose targets resolve to the same destinations.
|
|
52
|
+
*
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
export declare function toDestination(dest: NativeDestination | undefined): OutlineDestination | null;
|
|
56
|
+
/**
|
|
57
|
+
* Rebuild the tree from the flat pre-order list the bindings return.
|
|
58
|
+
*
|
|
59
|
+
* A stack indexed by level is enough because pre-order guarantees a node's parent is
|
|
60
|
+
* the most recent node one level shallower. Levels that skip a step cannot come from
|
|
61
|
+
* our own walker, but are clamped rather than trusted — a malformed document should
|
|
62
|
+
* produce a flatter outline, not a crash.
|
|
63
|
+
*/
|
|
64
|
+
export declare function buildOutlineTree(entries: readonly NativeEntry[]): OutlineNode[];
|
|
65
|
+
/** Walk an outline depth-first, yielding each node with its depth. */
|
|
66
|
+
export declare function walkOutline(nodes: readonly OutlineNode[], depth?: number): Generator<{
|
|
67
|
+
/** The entry. */
|
|
68
|
+
node: OutlineNode;
|
|
69
|
+
/** How deep it sits, 0 for a root. Useful as an indent. */
|
|
70
|
+
depth: number;
|
|
71
|
+
}>;
|
|
72
|
+
//# sourceMappingURL=outline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outline.d.ts","sourceRoot":"","sources":["../src/outline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,IAAI,iBAAiB,EACvC,YAAY,IAAI,WAAW,EAC5B,MAAM,2BAA2B,CAAC;AAEnC,kFAAkF;AAClF,MAAM,MAAM,eAAe,GACvB,KAAK,GACL,KAAK,GACL,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,OAAO,GACP,OAAO,CAAC;AAEZ;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,0BAA0B;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,gEAAgE;IAChE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACzC,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;CAClC;AAaD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,iBAAiB,GAAG,SAAS,GAClC,kBAAkB,GAAG,IAAI,CAa3B;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,SAAS,WAAW,EAAE,GAC9B,WAAW,EAAE,CAyBf;AAED,sEAAsE;AACtE,wBAAiB,WAAW,CAC1B,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,KAAK,SAAI,GACR,SAAS,CAAC;IACX,iBAAiB;IACjB,IAAI,EAAE,WAAW,CAAC;IAClB,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;CACf,CAAC,CAKD"}
|
package/dist/outline.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const KINDS = new Set([
|
|
2
|
+
'XYZ',
|
|
3
|
+
'Fit',
|
|
4
|
+
'FitH',
|
|
5
|
+
'FitV',
|
|
6
|
+
'FitR',
|
|
7
|
+
'FitB',
|
|
8
|
+
'FitBH',
|
|
9
|
+
'FitBV',
|
|
10
|
+
]);
|
|
11
|
+
/**
|
|
12
|
+
* napi omits absent numbers rather than nulling them; normalise to one shape.
|
|
13
|
+
*
|
|
14
|
+
* Shared with the link reader, whose targets resolve to the same destinations.
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export function toDestination(dest) {
|
|
19
|
+
if (!dest)
|
|
20
|
+
return null;
|
|
21
|
+
return {
|
|
22
|
+
page: dest.page,
|
|
23
|
+
// Unknown view kinds are read as `Fit` in Rust, so this only guards against a
|
|
24
|
+
// binding and a wrapper that have drifted apart.
|
|
25
|
+
kind: (KINDS.has(dest.kind) ? dest.kind : 'Fit'),
|
|
26
|
+
left: dest.left ?? null,
|
|
27
|
+
top: dest.top ?? null,
|
|
28
|
+
right: dest.right ?? null,
|
|
29
|
+
bottom: dest.bottom ?? null,
|
|
30
|
+
zoom: dest.zoom ?? null,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Rebuild the tree from the flat pre-order list the bindings return.
|
|
35
|
+
*
|
|
36
|
+
* A stack indexed by level is enough because pre-order guarantees a node's parent is
|
|
37
|
+
* the most recent node one level shallower. Levels that skip a step cannot come from
|
|
38
|
+
* our own walker, but are clamped rather than trusted — a malformed document should
|
|
39
|
+
* produce a flatter outline, not a crash.
|
|
40
|
+
*/
|
|
41
|
+
export function buildOutlineTree(entries) {
|
|
42
|
+
const roots = [];
|
|
43
|
+
const stack = [];
|
|
44
|
+
for (const entry of entries) {
|
|
45
|
+
const dest = toDestination(entry.dest);
|
|
46
|
+
const node = {
|
|
47
|
+
title: entry.title,
|
|
48
|
+
dest,
|
|
49
|
+
page: dest?.page ?? null,
|
|
50
|
+
bold: entry.bold,
|
|
51
|
+
italic: entry.italic,
|
|
52
|
+
open: entry.open,
|
|
53
|
+
children: [],
|
|
54
|
+
};
|
|
55
|
+
const level = Math.min(entry.level, stack.length);
|
|
56
|
+
stack.length = level;
|
|
57
|
+
const parent = stack[level - 1];
|
|
58
|
+
if (parent)
|
|
59
|
+
parent.children.push(node);
|
|
60
|
+
else
|
|
61
|
+
roots.push(node);
|
|
62
|
+
stack.push(node);
|
|
63
|
+
}
|
|
64
|
+
return roots;
|
|
65
|
+
}
|
|
66
|
+
/** Walk an outline depth-first, yielding each node with its depth. */
|
|
67
|
+
export function* walkOutline(nodes, depth = 0) {
|
|
68
|
+
for (const node of nodes) {
|
|
69
|
+
yield { node, depth };
|
|
70
|
+
yield* walkOutline(node.children, depth + 1);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=outline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outline.js","sourceRoot":"","sources":["../src/outline.ts"],"names":[],"mappings":"AA8DA,MAAM,KAAK,GAAG,IAAI,GAAG,CAAS;IAC5B,KAAK;IACL,KAAK;IACL,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;CACR,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAmC;IAEnC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,8EAA8E;QAC9E,iDAAiD;QACjD,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAoB;QACnE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;QACvB,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,IAAI;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI;QAC3B,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;KACxB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAA+B;IAE/B,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,MAAM,KAAK,GAAkB,EAAE,CAAC;IAEhC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,IAAI,GAAgB;YACxB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,IAAI;YACJ,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI;YACxB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE,EAAE;SACb,CAAC;QAEF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAClD,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;QACrB,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAChC,IAAI,MAAM;YAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;YAClC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,sEAAsE;AACtE,MAAM,SAAS,CAAC,CAAC,WAAW,CAC1B,KAA6B,EAC7B,KAAK,GAAG,CAAC;IAOT,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QACtB,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC"}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which build is loaded: the native addon, or wasm in a browser.
|
|
3
|
+
*
|
|
4
|
+
* Worth branching on only for concurrency and memory. The rendering API is identical
|
|
5
|
+
* on both, which is the point of the library.
|
|
6
|
+
*/
|
|
1
7
|
export type Runtime = 'native' | 'wasm';
|
|
2
8
|
/**
|
|
3
9
|
* Useful concurrency ceiling on wasm.
|
|
@@ -9,7 +15,9 @@ export type Runtime = 'native' | 'wasm';
|
|
|
9
15
|
export declare const MAX_WASM_CONCURRENCY = 4;
|
|
10
16
|
/** Best guess at how many renders this host can genuinely run at once. */
|
|
11
17
|
export declare function hardwareConcurrency(): number;
|
|
18
|
+
/** Which build is loaded. See {@link Runtime}. */
|
|
12
19
|
export declare function currentRuntime(): Runtime;
|
|
20
|
+
/** The rendering engine and version behind this build, for diagnostics and bug reports. */
|
|
13
21
|
export declare function backend(): string;
|
|
14
22
|
/**
|
|
15
23
|
* Prepare the rendering thread pool. Idempotent, and called automatically by
|
package/dist/runtime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAExC;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAItC,0EAA0E;AAC1E,wBAAgB,mBAAmB,IAAI,MAAM,CAY5C;AAED,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,IAAI,CAS7D"}
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAExC;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAItC,0EAA0E;AAC1E,wBAAgB,mBAAmB,IAAI,MAAM,CAY5C;AAED,kDAAkD;AAClD,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED,2FAA2F;AAC3F,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,IAAI,CAS7D"}
|
package/dist/runtime.js
CHANGED
|
@@ -22,9 +22,11 @@ export function hardwareConcurrency() {
|
|
|
22
22
|
const fromEnv = Number(proc?.env?.PAPYRA_THREADS);
|
|
23
23
|
return Number.isFinite(fromEnv) && fromEnv > 0 ? fromEnv : 4;
|
|
24
24
|
}
|
|
25
|
+
/** Which build is loaded. See {@link Runtime}. */
|
|
25
26
|
export function currentRuntime() {
|
|
26
27
|
return runtime() === 'wasm' ? 'wasm' : 'native';
|
|
27
28
|
}
|
|
29
|
+
/** The rendering engine and version behind this build, for diagnostics and bug reports. */
|
|
28
30
|
export function backend() {
|
|
29
31
|
return backendName();
|
|
30
32
|
}
|
package/dist/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,OAAO,GACR,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,OAAO,GACR,MAAM,2BAA2B,CAAC;AAUnC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAEtC,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,0EAA0E;AAC1E,MAAM,UAAU,mBAAmB;IACjC,MAAM,GAAG,GAAI,UAA+D;SACzE,SAAS,CAAC;IACb,IAAI,OAAO,GAAG,EAAE,mBAAmB,KAAK,QAAQ,EAAE,CAAC;QACjD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAC9C,CAAC;IACD,4EAA4E;IAC5E,kBAAkB;IAClB,MAAM,IAAI,GAAI,UAA6D;SACxE,OAAO,CAAC;IACX,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,cAAc,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,cAAc;IAC5B,OAAO,OAAO,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;AAClD,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,OAAO;IACrB,OAAO,WAAW,EAAE,CAAC;AACvB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAAC,OAAO,GAAyB,EAAE;IACrD,IAAI,WAAW;QAAE,OAAO;IACxB,WAAW,GAAG,IAAI,CAAC;IACnB,IAAI,cAAc,EAAE,KAAK,MAAM;QAAE,OAAO;IACxC,IAAI,CAAC;QACH,mBAAmB,CAAC,OAAO,CAAC,OAAO,IAAI,mBAAmB,EAAE,EAAE,SAAS,CAAC,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;IAC3E,CAAC;AACH,CAAC"}
|
package/dist/scheduler.d.ts
CHANGED
|
@@ -26,7 +26,9 @@ export interface JobTiming {
|
|
|
26
26
|
/** Started until it finished. */
|
|
27
27
|
runMs: number;
|
|
28
28
|
}
|
|
29
|
+
/** A submitted job: its result, its timings, and the two ways to change its fate. */
|
|
29
30
|
export interface JobHandle<T> {
|
|
31
|
+
/** The coalescing key. Two live requests sharing one render share this. */
|
|
30
32
|
readonly key: string;
|
|
31
33
|
/**
|
|
32
34
|
* Populated once the job settles, `null` before that.
|
|
@@ -38,6 +40,7 @@ export interface JobHandle<T> {
|
|
|
38
40
|
readonly timing: JobTiming | null;
|
|
39
41
|
/** Reassign urgency while the job is still pending. A no-op once it is running. */
|
|
40
42
|
setPriority(priority: number): void;
|
|
43
|
+
/** Resolves with the result, or rejects with {@link AbortError} if cancelled first. */
|
|
41
44
|
readonly promise: Promise<T>;
|
|
42
45
|
/**
|
|
43
46
|
* Detach from this job. If nothing else is waiting on it and it has not started,
|
|
@@ -45,7 +48,14 @@ export interface JobHandle<T> {
|
|
|
45
48
|
*/
|
|
46
49
|
cancel(reason?: string): void;
|
|
47
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Rejection reason for a job dropped before it started.
|
|
53
|
+
*
|
|
54
|
+
* Named `'AbortError'` to match `DOMException`, so existing `err.name === 'AbortError'`
|
|
55
|
+
* checks keep working across the two runtimes without a papyra-specific branch.
|
|
56
|
+
*/
|
|
48
57
|
export declare class AbortError extends Error {
|
|
58
|
+
/** Always `'AbortError'`. */
|
|
49
59
|
readonly name = "AbortError";
|
|
50
60
|
constructor(reason?: string);
|
|
51
61
|
}
|
|
@@ -63,13 +73,21 @@ export interface SchedulerOptions {
|
|
|
63
73
|
*/
|
|
64
74
|
yieldToUrgent?: boolean;
|
|
65
75
|
}
|
|
66
|
-
|
|
76
|
+
/**
|
|
77
|
+
* One queue for every kind of work a document does.
|
|
78
|
+
*
|
|
79
|
+
* Deliberately not parameterised by payload: renders and text extraction compete for
|
|
80
|
+
* the same cores, so they have to share a queue for priority to mean anything. Entries
|
|
81
|
+
* are stored opaquely and `submit` recovers the type — sound because coalescing is by
|
|
82
|
+
* key, and two jobs with the same key are by construction the same job.
|
|
83
|
+
*/
|
|
84
|
+
export declare class Scheduler {
|
|
67
85
|
#private;
|
|
68
86
|
constructor(limit: number, options?: SchedulerOptions);
|
|
69
87
|
get pendingCount(): number;
|
|
70
88
|
get runningCount(): number;
|
|
71
89
|
/** How long the longest-waiting pending job has been queued. */
|
|
72
90
|
get oldestWaitMs(): number;
|
|
73
|
-
submit(job: SchedulerJob<T>): JobHandle<T>;
|
|
91
|
+
submit<T>(job: SchedulerJob<T>): JobHandle<T>;
|
|
74
92
|
}
|
|
75
93
|
//# sourceMappingURL=scheduler.d.ts.map
|
package/dist/scheduler.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,qFAAqF;IACrF,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;CACvB;AAED,mDAAmD;AACnD,MAAM,WAAW,SAAS;IACxB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IAClC,mFAAmF;IACnF,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7B;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAkBD,qBAAa,UAAW,SAAQ,KAAK;IACnC,SAAkB,IAAI,gBAAgB;IACtC,YAAY,MAAM,SAAc,EAE/B;CACF;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,qBAAa,SAAS
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,qFAAqF;IACrF,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;CACvB;AAED,mDAAmD;AACnD,MAAM,WAAW,SAAS;IACxB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qFAAqF;AACrF,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IAClC,mFAAmF;IACnF,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,uFAAuF;IACvF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7B;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAkBD;;;;;GAKG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC,6BAA6B;IAC7B,SAAkB,IAAI,gBAAgB;IACtC,YAAY,MAAM,SAAc,EAE/B;CACF;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,qBAAa,SAAS;;IAOpB,YAAY,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,EAGxD;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IASD,gEAAgE;IAChE,IAAI,YAAY,IAAI,MAAM,CAOzB;IAED,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAkC5C;CAgFF"}
|
package/dist/scheduler.js
CHANGED
|
@@ -13,12 +13,27 @@
|
|
|
13
13
|
*/
|
|
14
14
|
/** Runs first. Lower is more urgent; the default is the most urgent tier. */
|
|
15
15
|
export const DEFAULT_PRIORITY = 0;
|
|
16
|
+
/**
|
|
17
|
+
* Rejection reason for a job dropped before it started.
|
|
18
|
+
*
|
|
19
|
+
* Named `'AbortError'` to match `DOMException`, so existing `err.name === 'AbortError'`
|
|
20
|
+
* checks keep working across the two runtimes without a papyra-specific branch.
|
|
21
|
+
*/
|
|
16
22
|
export class AbortError extends Error {
|
|
23
|
+
/** Always `'AbortError'`. */
|
|
17
24
|
name = 'AbortError';
|
|
18
25
|
constructor(reason = 'cancelled') {
|
|
19
26
|
super(reason);
|
|
20
27
|
}
|
|
21
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* One queue for every kind of work a document does.
|
|
31
|
+
*
|
|
32
|
+
* Deliberately not parameterised by payload: renders and text extraction compete for
|
|
33
|
+
* the same cores, so they have to share a queue for priority to mean anything. Entries
|
|
34
|
+
* are stored opaquely and `submit` recovers the type — sound because coalescing is by
|
|
35
|
+
* key, and two jobs with the same key are by construction the same job.
|
|
36
|
+
*/
|
|
22
37
|
export class Scheduler {
|
|
23
38
|
#limit;
|
|
24
39
|
#yieldToUrgent;
|
package/dist/scheduler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,6EAA6E;AAC7E,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type PageText, type Quad, type Rect } from './text.js';
|
|
2
|
+
/** How loosely a query is allowed to match. Shared by {@link findRanges} and search. */
|
|
3
|
+
export interface MatchOptions {
|
|
4
|
+
/** Default `false`. */
|
|
5
|
+
caseSensitive?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Treat `e` and `é` as the same letter. Default `true`.
|
|
8
|
+
*
|
|
9
|
+
* Users type what is on their keyboard, and a document written in French or German
|
|
10
|
+
* is otherwise unsearchable to most of them.
|
|
11
|
+
*/
|
|
12
|
+
ignoreDiacritics?: boolean;
|
|
13
|
+
/** Require the match to start and end at a word boundary. Default `false`. */
|
|
14
|
+
wholeWords?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** One occurrence of the query on a page. */
|
|
17
|
+
export interface SearchMatch {
|
|
18
|
+
/** 0-based index of the page the hit is on. */
|
|
19
|
+
readonly page: number;
|
|
20
|
+
/** The matched text exactly as the document writes it. */
|
|
21
|
+
readonly text: string;
|
|
22
|
+
/** Surrounding text, for showing the hit in a results list. */
|
|
23
|
+
readonly context: string;
|
|
24
|
+
/** Where the match sits inside {@link context}. */
|
|
25
|
+
readonly contextStart: number;
|
|
26
|
+
/** End of the match inside {@link context}, exclusive. */
|
|
27
|
+
readonly contextEnd: number;
|
|
28
|
+
/**
|
|
29
|
+
* One quadrilateral per line the match covers — more than one when a phrase runs
|
|
30
|
+
* over a line break. Coordinates are 72-DPI page space; see {@link PageText}.
|
|
31
|
+
*/
|
|
32
|
+
readonly quads: readonly Quad[];
|
|
33
|
+
/** {@link quads}, as upright bounding boxes. */
|
|
34
|
+
readonly rects: readonly Rect[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Where the query occurs in a page's text, as `[start, end)` in the *source* string.
|
|
38
|
+
*
|
|
39
|
+
* Exported for testing and for callers that hold their own page text.
|
|
40
|
+
*/
|
|
41
|
+
export declare function findRanges(source: string, query: string, options?: MatchOptions): Array<[number, number]>;
|
|
42
|
+
/**
|
|
43
|
+
* Find `query` in one page's already-extracted text.
|
|
44
|
+
*
|
|
45
|
+
* Matching runs over the whole page rather than line by line, so a phrase broken
|
|
46
|
+
* across a line break still matches — and comes back with one quadrilateral per line
|
|
47
|
+
* it covers, which is what a highlight needs.
|
|
48
|
+
*/
|
|
49
|
+
export declare function searchPageText(text: PageText, query: string, options?: MatchOptions): SearchMatch[];
|
|
50
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,IAAI,EAET,KAAK,IAAI,EAEV,MAAM,WAAW,CAAC;AAEnB,wFAAwF;AACxF,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,8EAA8E;IAC9E,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,6CAA6C;AAC7C,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,mDAAmD;IACnD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IAChC,gDAAgD;IAChD,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;CACjC;AAyFD;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,YAAiB,GACzB,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA6BzB;AAoBD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,YAAiB,GACzB,WAAW,EAAE,CAkCf"}
|
package/dist/search.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { lineQuad, quadBounds, } from './text.js';
|
|
2
|
+
/** How much of the surrounding line to keep either side of a hit. */
|
|
3
|
+
const CONTEXT_PADDING = 40;
|
|
4
|
+
/** Ligatures that carry no `ToUnicode` mapping arrive as a single character. */
|
|
5
|
+
const LIGATURES = {
|
|
6
|
+
ff: 'ff',
|
|
7
|
+
fi: 'fi',
|
|
8
|
+
fl: 'fl',
|
|
9
|
+
ffi: 'ffi',
|
|
10
|
+
ffl: 'ffl',
|
|
11
|
+
ſt: 'st',
|
|
12
|
+
st: 'st',
|
|
13
|
+
Æ: 'AE',
|
|
14
|
+
æ: 'ae',
|
|
15
|
+
Œ: 'OE',
|
|
16
|
+
œ: 'oe',
|
|
17
|
+
};
|
|
18
|
+
const COMBINING = /\p{M}/gu;
|
|
19
|
+
function fold(source, options) {
|
|
20
|
+
const { caseSensitive = false, ignoreDiacritics = true } = options;
|
|
21
|
+
let text = '';
|
|
22
|
+
const origin = [];
|
|
23
|
+
for (let i = 0; i < source.length; i++) {
|
|
24
|
+
let piece = source[i];
|
|
25
|
+
// A line break is a place where a phrase may continue, not a barrier. Searching
|
|
26
|
+
// for "dynamic languages" should find a title broken across two lines.
|
|
27
|
+
if (piece === '\n' || piece === '\t')
|
|
28
|
+
piece = ' ';
|
|
29
|
+
piece = LIGATURES[piece] ?? piece;
|
|
30
|
+
if (ignoreDiacritics) {
|
|
31
|
+
piece = piece.normalize('NFD').replace(COMBINING, '');
|
|
32
|
+
// A character that is *only* a combining mark folds away entirely.
|
|
33
|
+
if (piece === '')
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (!caseSensitive)
|
|
37
|
+
piece = piece.toLowerCase();
|
|
38
|
+
for (const c of piece) {
|
|
39
|
+
text += c;
|
|
40
|
+
origin.push(i);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { text, origin };
|
|
44
|
+
}
|
|
45
|
+
/** Collapse runs of whitespace so "Hello World" matches "Hello World". */
|
|
46
|
+
function squash(folded) {
|
|
47
|
+
let text = '';
|
|
48
|
+
const origin = [];
|
|
49
|
+
let previousWasSpace = false;
|
|
50
|
+
for (let i = 0; i < folded.text.length; i++) {
|
|
51
|
+
const c = folded.text[i];
|
|
52
|
+
const isSpace = c === ' ';
|
|
53
|
+
if (isSpace && previousWasSpace)
|
|
54
|
+
continue;
|
|
55
|
+
text += isSpace ? ' ' : c;
|
|
56
|
+
origin.push(folded.origin[i]);
|
|
57
|
+
previousWasSpace = isSpace;
|
|
58
|
+
}
|
|
59
|
+
return { text, origin };
|
|
60
|
+
}
|
|
61
|
+
const WORD = /[\p{L}\p{N}_]/u;
|
|
62
|
+
function isBoundary(text, index) {
|
|
63
|
+
if (index < 0 || index >= text.length)
|
|
64
|
+
return true;
|
|
65
|
+
return !WORD.test(text[index]);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Where the query occurs in a page's text, as `[start, end)` in the *source* string.
|
|
69
|
+
*
|
|
70
|
+
* Exported for testing and for callers that hold their own page text.
|
|
71
|
+
*/
|
|
72
|
+
export function findRanges(source, query, options = {}) {
|
|
73
|
+
const needle = squash(fold(query, options)).text.trim();
|
|
74
|
+
if (needle === '')
|
|
75
|
+
return [];
|
|
76
|
+
const haystack = squash(fold(source, options));
|
|
77
|
+
const ranges = [];
|
|
78
|
+
let at = 0;
|
|
79
|
+
for (;;) {
|
|
80
|
+
const found = haystack.text.indexOf(needle, at);
|
|
81
|
+
if (found === -1)
|
|
82
|
+
break;
|
|
83
|
+
const end = found + needle.length;
|
|
84
|
+
if (!options.wholeWords ||
|
|
85
|
+
(isBoundary(haystack.text, found - 1) && isBoundary(haystack.text, end))) {
|
|
86
|
+
const start = haystack.origin[found];
|
|
87
|
+
// `end` is exclusive, so the last folded character's origin is the last source
|
|
88
|
+
// character the match covers — and a source character may fold to several.
|
|
89
|
+
const lastSource = haystack.origin[end - 1];
|
|
90
|
+
ranges.push([start, lastSource + 1]);
|
|
91
|
+
}
|
|
92
|
+
// Advance past the start, not past the end: overlapping occurrences of a
|
|
93
|
+
// repetitive query ("aa" in "aaa") are still two hits.
|
|
94
|
+
at = found + 1;
|
|
95
|
+
}
|
|
96
|
+
return ranges;
|
|
97
|
+
}
|
|
98
|
+
function locate(lines, index) {
|
|
99
|
+
let start = 0;
|
|
100
|
+
for (let i = 0; i < lines.length; i++) {
|
|
101
|
+
const line = lines[i];
|
|
102
|
+
const end = start + line.text.length;
|
|
103
|
+
if (index < end)
|
|
104
|
+
return { line: i, offset: index - start };
|
|
105
|
+
// +1 for the '\n' the page string joins lines with.
|
|
106
|
+
start = end + 1;
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Find `query` in one page's already-extracted text.
|
|
112
|
+
*
|
|
113
|
+
* Matching runs over the whole page rather than line by line, so a phrase broken
|
|
114
|
+
* across a line break still matches — and comes back with one quadrilateral per line
|
|
115
|
+
* it covers, which is what a highlight needs.
|
|
116
|
+
*/
|
|
117
|
+
export function searchPageText(text, query, options = {}) {
|
|
118
|
+
const source = text.lines.map((line) => line.text).join('\n');
|
|
119
|
+
const matches = [];
|
|
120
|
+
for (const [start, end] of findRanges(source, query, options)) {
|
|
121
|
+
const from = locate(text.lines, start);
|
|
122
|
+
// `end` is exclusive; step back to a character that is really inside the match.
|
|
123
|
+
const to = locate(text.lines, end - 1);
|
|
124
|
+
if (!from || !to)
|
|
125
|
+
continue;
|
|
126
|
+
const quads = [];
|
|
127
|
+
for (let i = from.line; i <= to.line; i++) {
|
|
128
|
+
const line = text.lines[i];
|
|
129
|
+
const first = i === from.line ? from.offset : 0;
|
|
130
|
+
const last = i === to.line ? to.offset + 1 : line.text.length;
|
|
131
|
+
if (last > first)
|
|
132
|
+
quads.push(lineQuad(line, first, last));
|
|
133
|
+
}
|
|
134
|
+
if (quads.length === 0)
|
|
135
|
+
continue;
|
|
136
|
+
const contextStart = Math.max(0, start - CONTEXT_PADDING);
|
|
137
|
+
matches.push({
|
|
138
|
+
page: text.page,
|
|
139
|
+
text: source.slice(start, end),
|
|
140
|
+
context: source
|
|
141
|
+
.slice(contextStart, end + CONTEXT_PADDING)
|
|
142
|
+
.replace(/\n/g, ' '),
|
|
143
|
+
contextStart: start - contextStart,
|
|
144
|
+
contextEnd: end - contextStart,
|
|
145
|
+
quads,
|
|
146
|
+
rects: quads.map(quadBounds),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
return matches;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAGR,UAAU,GAGX,MAAM,WAAW,CAAC;AAsCnB,qEAAqE;AACrE,MAAM,eAAe,GAAG,EAAE,CAAC;AAgB3B,gFAAgF;AAChF,MAAM,SAAS,GAA2B;IACxC,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;CACR,CAAC;AAEF,MAAM,SAAS,GAAG,SAAS,CAAC;AAE5B,SAAS,IAAI,CAAC,MAAc,EAAE,OAAqB;IACjD,MAAM,EAAE,aAAa,GAAG,KAAK,EAAE,gBAAgB,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACnE,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,IAAI,KAAK,GAAG,MAAM,CAAC,CAAC,CAAW,CAAC;QAEhC,gFAAgF;QAChF,uEAAuE;QACvE,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI;YAAE,KAAK,GAAG,GAAG,CAAC;QAElD,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;QAClC,IAAI,gBAAgB,EAAE,CAAC;YACrB,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YACtD,mEAAmE;YACnE,IAAI,KAAK,KAAK,EAAE;gBAAE,SAAS;QAC7B,CAAC;QACD,IAAI,CAAC,aAAa;YAAE,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QAEhD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,IAAI,IAAI,CAAC,CAAC;YACV,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1B,CAAC;AAED,2EAA2E;AAC3E,SAAS,MAAM,CAAC,MAAc;IAC5B,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAW,CAAC;QACnC,MAAM,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC;QAC1B,IAAI,OAAO,IAAI,gBAAgB;YAAE,SAAS;QAC1C,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAW,CAAC,CAAC;QACxC,gBAAgB,GAAG,OAAO,CAAC;IAC7B,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,IAAI,GAAG,gBAAgB,CAAC;AAE9B,SAAS,UAAU,CAAC,IAAY,EAAE,KAAa;IAC7C,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAW,CAAC,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,MAAc,EACd,KAAa,EACb,OAAO,GAAiB,EAAE;IAE1B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACxD,IAAI,MAAM,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IAE7B,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,MAAM,MAAM,GAA4B,EAAE,CAAC;IAE3C,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,SAAS,CAAC;QACR,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAChD,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,MAAM;QACxB,MAAM,GAAG,GAAG,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;QAElC,IACE,CAAC,OAAO,CAAC,UAAU;YACnB,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EACxE,CAAC;YACD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAW,CAAC;YAC/C,+EAA+E;YAC/E,2EAA2E;YAC3E,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAW,CAAC;YACtD,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;QACD,yEAAyE;QACzE,uDAAuD;QACvD,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAQD,SAAS,MAAM,CAAC,KAA0B,EAAE,KAAa;IACvD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAa,CAAC;QAClC,MAAM,GAAG,GAAG,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QACrC,IAAI,KAAK,GAAG,GAAG;YAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;QAC3D,oDAAoD;QACpD,KAAK,GAAG,GAAG,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAc,EACd,KAAa,EACb,OAAO,GAAiB,EAAE;IAE1B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACvC,gFAAgF;QAChF,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;YAAE,SAAS;QAE3B,MAAM,KAAK,GAAW,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAa,CAAC;YACvC,MAAM,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAChD,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;YAC9D,IAAI,IAAI,GAAG,KAAK;gBAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAEjC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,eAAe,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC;YAC9B,OAAO,EAAE,MAAM;iBACZ,KAAK,CAAC,YAAY,EAAE,GAAG,GAAG,eAAe,CAAC;iBAC1C,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;YACtB,YAAY,EAAE,KAAK,GAAG,YAAY;YAClC,UAAU,EAAE,GAAG,GAAG,YAAY;YAC9B,KAAK;YACL,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/text.d.ts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { PageText as NativePageText } from '@build-qube/papyra-native';
|
|
2
|
+
/**
|
|
3
|
+
* A run of glyphs sharing one baseline.
|
|
4
|
+
*
|
|
5
|
+
* Geometry runs *along the baseline* rather than being a rectangle per character. A
|
|
6
|
+
* page is thousands of glyphs and four numbers each is far more than a search needs;
|
|
7
|
+
* an origin, a direction and a list of distances reconstruct any substring's
|
|
8
|
+
* quadrilateral exactly, and keep working when the text is rotated.
|
|
9
|
+
*/
|
|
10
|
+
export interface TextLine {
|
|
11
|
+
/** The line's characters, with spaces reinserted between glyph runs. */
|
|
12
|
+
readonly text: string;
|
|
13
|
+
/**
|
|
14
|
+
* Distance along the baseline to the start of each character, plus the end of the
|
|
15
|
+
* last — one entry more than `text.length`.
|
|
16
|
+
*/
|
|
17
|
+
readonly offsets: Float32Array;
|
|
18
|
+
/** Start of the baseline, x. */
|
|
19
|
+
readonly x: number;
|
|
20
|
+
/** Start of the baseline, y. */
|
|
21
|
+
readonly y: number;
|
|
22
|
+
/** Unit vector along the baseline, x. `(1, 0)` for ordinary horizontal text. */
|
|
23
|
+
readonly dx: number;
|
|
24
|
+
/** Unit vector along the baseline, y. */
|
|
25
|
+
readonly dy: number;
|
|
26
|
+
/** Extent above the baseline, perpendicular to it. */
|
|
27
|
+
readonly ascent: number;
|
|
28
|
+
/** Extent below the baseline. */
|
|
29
|
+
readonly descent: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The text of one page.
|
|
33
|
+
*
|
|
34
|
+
* Coordinates are **the page as rendered at 72 DPI**: pixels from the top-left corner
|
|
35
|
+
* with y increasing downwards, page rotation and crop box already applied. That makes
|
|
36
|
+
* them the same space as {@link PageSize}, so lining text up with a rendered bitmap is
|
|
37
|
+
* one multiply — `rendered.width / pageSize.width`, or equivalently `dpi / 72`.
|
|
38
|
+
*/
|
|
39
|
+
export interface PageText {
|
|
40
|
+
/** 0-based index of the page this text came from. */
|
|
41
|
+
readonly page: number;
|
|
42
|
+
/**
|
|
43
|
+
* The page's lines, in the order the content stream drew them — which is not
|
|
44
|
+
* necessarily reading order, because a PDF is under no obligation to draw text in
|
|
45
|
+
* the order a human reads it.
|
|
46
|
+
*/
|
|
47
|
+
readonly lines: readonly TextLine[];
|
|
48
|
+
/**
|
|
49
|
+
* Glyphs the page drew that no encoding could map back to Unicode.
|
|
50
|
+
*
|
|
51
|
+
* Non-zero **alongside lines** is the case worth warning about: a paper whose
|
|
52
|
+
* headings use a standard font and whose body uses an embedded subset with no
|
|
53
|
+
* `ToUnicode` cmap looks searchable and mostly is not. Non-zero with no lines is a
|
|
54
|
+
* page of text nothing can read; zero with no lines is a page with no text, which
|
|
55
|
+
* may be a scan. Telling a user which they are looking at is the difference between
|
|
56
|
+
* "no results" and "this cannot be searched".
|
|
57
|
+
*
|
|
58
|
+
* Weigh it against the characters actually extracted — a few undecodable ornaments
|
|
59
|
+
* are not a lost paragraph.
|
|
60
|
+
*/
|
|
61
|
+
readonly undecodedGlyphs: number;
|
|
62
|
+
}
|
|
63
|
+
/** Four corners, clockwise from the top-left of the text's own orientation. */
|
|
64
|
+
export interface Quad {
|
|
65
|
+
/** Top-left, x. */
|
|
66
|
+
readonly x0: number;
|
|
67
|
+
/** Top-left, y. */
|
|
68
|
+
readonly y0: number;
|
|
69
|
+
/** Top-right, x. */
|
|
70
|
+
readonly x1: number;
|
|
71
|
+
/** Top-right, y. */
|
|
72
|
+
readonly y1: number;
|
|
73
|
+
/** Bottom-right, x. */
|
|
74
|
+
readonly x2: number;
|
|
75
|
+
/** Bottom-right, y. */
|
|
76
|
+
readonly y2: number;
|
|
77
|
+
/** Bottom-left, x. */
|
|
78
|
+
readonly x3: number;
|
|
79
|
+
/** Bottom-left, y. */
|
|
80
|
+
readonly y3: number;
|
|
81
|
+
}
|
|
82
|
+
/** An axis-aligned rectangle. */
|
|
83
|
+
export interface Rect {
|
|
84
|
+
/** Left edge. */
|
|
85
|
+
readonly x: number;
|
|
86
|
+
/** Top edge — y increases downwards, so this is the smaller of the two. */
|
|
87
|
+
readonly y: number;
|
|
88
|
+
/** Width. */
|
|
89
|
+
readonly width: number;
|
|
90
|
+
/** Height. */
|
|
91
|
+
readonly height: number;
|
|
92
|
+
}
|
|
93
|
+
/** @internal */
|
|
94
|
+
export declare function toPageText(page: number, native: NativePageText): PageText;
|
|
95
|
+
/** Every character on the page a search can see. */
|
|
96
|
+
export declare function pageString(text: PageText): string;
|
|
97
|
+
/** Roughly how much memory a page's text holds, for cache accounting. */
|
|
98
|
+
export declare function pageTextBytes(text: PageText): number;
|
|
99
|
+
/**
|
|
100
|
+
* The quadrilateral covering `line`'s characters in `[start, end)`.
|
|
101
|
+
*
|
|
102
|
+
* Built from the baseline rather than from a stored rectangle, so rotated text — a
|
|
103
|
+
* drawing's vertical dimension labels, a sideways table header — gets a box at its own
|
|
104
|
+
* angle instead of an axis-aligned one that covers the wrong pixels.
|
|
105
|
+
*/
|
|
106
|
+
export declare function lineQuad(line: TextLine, start: number, end: number): Quad;
|
|
107
|
+
/** The smallest upright rectangle containing `quad`. */
|
|
108
|
+
export declare function quadBounds(quad: Quad): Rect;
|
|
109
|
+
/** Scale a rect from 72-DPI page space into a render's pixels. */
|
|
110
|
+
export declare function scaleRect(rect: Rect, scale: number): Rect;
|
|
111
|
+
/** Scale a quad from 72-DPI page space into a render's pixels. */
|
|
112
|
+
export declare function scaleQuad(quad: Quad, scale: number): Quad;
|
|
113
|
+
//# sourceMappingURL=text.d.ts.map
|