Files
BadNote/lib/editor/search/search_text.dart

31 lines
1.5 KiB
Dart
Raw Normal View History

// lib/editor/search/search_text.dart
//
// Pure text normalization + matching for full-text search (F8). PDF text layers
// and OCR output are full of hard line breaks and irregular whitespace, so a
// query like "hello world" won't substring-match raw extracted text that reads
// "hello\nworld". Normalizing both sides (lowercase + collapse every whitespace
// run to a single space + trim) fixes that.
//
// CJK NOTE: this user writes Chinese. We deliberately do NOT word-tokenize —
// Chinese has no inter-word spaces, so a whitespace/punctuation tokenizer would
// mangle it. Substring matching over normalized text is correct for both Latin
// and CJK; word/段 segmentation belongs in the DB FTS tokenizer (trigram /
// unicode61), not here.
/// Matches any run of Unicode whitespace (spaces, tabs, newlines, NBSP, …).
final RegExp _whitespaceRun = RegExp(r'\s+');
/// Normalize [text] for indexing/matching: lowercase, collapse whitespace runs
/// (incl. the hard newlines PDF/OCR insert mid-sentence) to single spaces, trim.
String normalizeForIndex(String text) {
return text.toLowerCase().replaceAll(_whitespaceRun, ' ').trim();
}
/// Whether [source] contains [query] after both are normalized — so a match can
/// span the line breaks present in the raw text. Empty query never matches.
bool matchesNormalized(String source, String query) {
final q = normalizeForIndex(query);
if (q.isEmpty) return false;
return normalizeForIndex(source).contains(q);
}