src/ocr-tokens.ts (1349 bytes)
1 // Convert a tesseract.js page result to flat symbol tokens. Pure: no DOM. 2 3 import type Tesseract from 'tesseract.js'; 4 import type { OcrToken } from './align'; 5 6 /** Line ids are unique across pages: page * LINES_PER_PAGE + line. */ 7 export const LINES_PER_PAGE = 100000; 8 9 /** 10 * One token per recognized symbol (character). Symbol level works for 11 * both spaced scripts and CJK, where a Tesseract "word" can be a whole 12 * line or column. The UI merges tokens on one line into one box. The 13 * word id marks the word boundaries, so the book text keeps its spaces. 14 */ 15 export function pageToTokens(page: Pick<Tesseract.Page, 'blocks'>, pageIndex: number): OcrToken[] { 16 const tokens: OcrToken[] = []; 17 let line = 0; 18 let word = 0; 19 for (const block of page.blocks ?? []) { 20 for (const paragraph of block.paragraphs) { 21 for (const ln of paragraph.lines) { 22 const lineId = pageIndex * LINES_PER_PAGE + line; 23 line++; 24 for (const w of ln.words) { 25 const wordId = pageIndex * LINES_PER_PAGE + word; 26 word++; 27 for (const symbol of w.symbols) { 28 tokens.push({ 29 text: symbol.text, 30 page: pageIndex, 31 line: lineId, 32 word: wordId, 33 bbox: symbol.bbox, 34 }); 35 } 36 } 37 } 38 } 39 } 40 return tokens; 41 }