Chunks (phrase selection)#
The chunker finds short, reading-order phrases on a page — the candidate "kept words" of an erasure — and selects a spread of the strongest ones. See Concepts → Chunks for the idea.
H.chunks(opts?)#
All matching chunks on the page. Each chunk is a Word[] in reading order.
Two shallow POS patterns are matched greedily, longest-first, over
adjacency runs (words within one line of each other, |Δ lineIdx| ≤ 1):
NP := ADP? (DET|PRON|VERB)? (ADJ|ADV|NUM)* (NOUN|PROPN)+
VP := ADV* (VERB|AUX) (ADJ|ADV|NUM|AUX|PART)*
A leading VERB inside NP captures gerund/participial modifiers
("embracing thoughts").
ChunksOptions:
| Field | Type | Default | Notes |
|---|---|---|---|
maxLen |
number? |
4 |
Maximum words per chunk. |
candidates |
Word[]? |
passesCandidacy filter |
Pre-filtered candidate words. |
By default the candidate list is every word that passes
passesCandidacy (header lines and the
running page number are excluded automatically).
H.selectChunks(opts?)#
Scores every chunk with chunkScore and picks the best
few, spread across the page so they don't clump on adjacent lines. The
result is sorted by (lineIdx, x0).
SelectChunksOptions extends ChunksOptions and adds:
| Field | Type | Default | Notes |
|---|---|---|---|
nSeeds |
number? |
3 |
How many chunks to pick. |
minLineDist |
number? |
2 |
Minimum line distance between picks. |
seed |
number? |
42 |
PRNG seed for the shuffle. |
variation |
number? |
0 |
0 = pure top-N, 1 = light shuffle, 2 = wider shuffle. |
const phrases = H.selectChunks({ nSeeds: 4, minLineDist: 3, seed: 42 });
// each phrase is a Word[]; turn it into a balloon outline to render:
const outlines = phrases.map((ph) => H.geom.balloon(H.bboxOf(ph), { wobble: 0.15 }));
With variation: 0 (the default) you get the deterministic top-N. Raising it
shuffles among the strongest candidates using seed, so different seeds yield
different — but still strong — selections.
H.chunkScore(chunk)#
The heuristic selectChunks ranks by. Higher is better:
- +
rarityof each word (rarer words score higher); - +0.4 per content word; a chunk with no content word scores −999 (effectively disqualified);
- −0.4 for each banned cliché (
heart,soul,love,dream,hope,darkness,light,shadow); - a length bonus: 2 words
+0.7, 3 words+0.6, 4 words+0.2, 1 word+0, longer−0.4; - +0.4 if the last word is a
NOUNorPROPN.
H.passesCandidacy(word, headerLines?)#
Whether a word is eligible to appear in a chunk. Rejects: a small plot-name
blocklist, words with conf < 0.7, single characters other than I/a/O,
the page number / header digits (numbers on line ≤ 1), and words on detected
header lines. headerLines defaults to an empty set; H.chunks computes and
passes the real header lines for you.
POS helpers#
The UPOS tag constants and two convenience predicates (over a word's pos):