feat(search): index PDF text, OCR scanned PDFs on import
All checks were successful
CI / Windows build (push) Successful in 15m50s
All checks were successful
CI / Windows build (push) Successful in 15m50s
Search now covers handwriting, the PDF text layer, AND scanned (rasterized) PDFs. - PdfTextIndexer runs at import: sums the embedded text layer across pages; if present it stores that as the document body, otherwise the PDF is rasterized and its rendered pages are OCR'd in the background. The result lands in the sidecar `pageText` field (distinct from `ocrText`, the handwriting OCR). Idempotent (skips a sidecar that already has pageText); degrades gracefully with no OCR engine. - pdfrx_page_text_source abstracts text/render so it's testable. - VaultSearchIndex now harvests title + typed text + handwriting OCR + PDF pageText, so search finds notes, typed PDFs and scanned PDFs. analyze clean, 409 tests green.
This commit is contained in:
@@ -313,6 +313,7 @@ class BadnoteSidecar {
|
||||
List<SidecarScratchLink>? scratchLinks,
|
||||
Map<int, String>? legacyAnnotations,
|
||||
this.ocrText,
|
||||
this.pageText,
|
||||
this.legacyId,
|
||||
this.background,
|
||||
}) : strokes = strokes ?? <int, List<EditorStroke>>{},
|
||||
@@ -368,6 +369,17 @@ class BadnoteSidecar {
|
||||
/// the notebook has no handwriting or OCR hasn't run.
|
||||
final String? ocrText;
|
||||
|
||||
/// Searchable text of the underlying DOCUMENT BODY for a file-backed notebook
|
||||
/// (a PDF), captured ONCE at import time so the vault-scan search index covers
|
||||
/// the document — not just the user's annotations. It is either the PDF's
|
||||
/// embedded (printed) text layer, or — for a RASTERIZED / scanned PDF with no
|
||||
/// text layer — the result of a background OCR pass over the rendered pages.
|
||||
/// Pages are joined with `\f` (form feed) but the index treats it as a flat
|
||||
/// blob. Null when the document has not been indexed yet (back-compat: an old
|
||||
/// sidecar simply omits the field) or has no extractable/recognized text. This
|
||||
/// is distinct from [ocrText], which holds ONLY handwriting OCR.
|
||||
final String? pageText;
|
||||
|
||||
/// The legacy SQLite row id this sidecar was migrated from (a `documents.id`
|
||||
/// or `notes.id`). Set ONLY by the one-time migration; it makes the migration
|
||||
/// idempotent (a re-run recognizes an already-migrated item by this id even if
|
||||
@@ -413,6 +425,7 @@ class BadnoteSidecar {
|
||||
entry.key.toString(): entry.value,
|
||||
},
|
||||
if (ocrText != null && ocrText!.isNotEmpty) 'ocrText': ocrText,
|
||||
if (pageText != null && pageText!.isNotEmpty) 'pageText': pageText,
|
||||
if (legacyId != null) 'legacyId': legacyId,
|
||||
if (background != null) 'background': background,
|
||||
};
|
||||
@@ -470,6 +483,7 @@ class BadnoteSidecar {
|
||||
return out;
|
||||
}(),
|
||||
ocrText: json['ocrText'] as String?,
|
||||
pageText: json['pageText'] as String?,
|
||||
legacyId: json['legacyId'] as String?,
|
||||
background: json['background'] as String?,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user