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:
@@ -379,6 +379,46 @@ void main() {
|
||||
expect(reparsed.background, isNull);
|
||||
});
|
||||
|
||||
test('pageText (PDF body / scanned-OCR text) round-trips through sidecar', () {
|
||||
final original = BadnoteSidecar(
|
||||
docType: 'pdf',
|
||||
sourceFile: 'scan.pdf',
|
||||
pageText: 'page one body\fpage two 第二页',
|
||||
);
|
||||
final reparsed = _roundTrip(original);
|
||||
expect(reparsed.pageText, 'page one body\fpage two 第二页');
|
||||
// ocrText (handwriting) and pageText (document body) are independent fields.
|
||||
expect(reparsed.ocrText, isNull);
|
||||
// Omitted when null/empty (no key bloat for legacy/annotation-only sidecars).
|
||||
expect(BadnoteSidecar().toJson().containsKey('pageText'), isFalse);
|
||||
});
|
||||
|
||||
test('missing pageText decodes to null (back-compat)', () {
|
||||
// A sidecar authored before the import-OCR feature simply omits pageText.
|
||||
final json = <String, dynamic>{
|
||||
'badnoteSidecarVersion': 1,
|
||||
'docType': 'pdf',
|
||||
'sourceFile': 'old.pdf',
|
||||
'strokes': <String, dynamic>{},
|
||||
'highlights': <String, dynamic>{},
|
||||
'bookmarks': <dynamic>[],
|
||||
'scratchLinks': <dynamic>[],
|
||||
};
|
||||
final reparsed = BadnoteSidecar.fromJson(json);
|
||||
expect(reparsed.pageText, isNull);
|
||||
});
|
||||
|
||||
test('pageText and ocrText coexist independently', () {
|
||||
final original = BadnoteSidecar(
|
||||
docType: 'pdf',
|
||||
ocrText: 'handwritten note',
|
||||
pageText: 'printed document body',
|
||||
);
|
||||
final reparsed = _roundTrip(original);
|
||||
expect(reparsed.ocrText, 'handwritten note');
|
||||
expect(reparsed.pageText, 'printed document body');
|
||||
});
|
||||
|
||||
test('missing scratchpad defaults to 4000x4000 empty pad', () {
|
||||
final json = SidecarScratchLink(
|
||||
link: const ScratchLink(
|
||||
|
||||
Reference in New Issue
Block a user