fix(card): a search for blue no longer finds blunt
The card browser looked for a query also with every ae, oe and ue made a, o and u, so that maedchen found Mädchen: in any language, so blue found blunt, Spanish que found aquí, and ue nearly everything. A card's umlauts are written out on its side instead, beside its folded text, and a query is matched as typed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
4eb2640be6
commit
31eed85aff
2 changed files with 29 additions and 8 deletions
|
|
@ -109,7 +109,7 @@ typedef BrowsedCard = ({
|
|||
/// `たべる` finds た.べる).
|
||||
String searchTextOf(Card card, List<Tag> tags) {
|
||||
final content = card.content;
|
||||
return searchFolded(
|
||||
return searchableText(
|
||||
[
|
||||
content.front.plainText,
|
||||
content.back.plainText,
|
||||
|
|
@ -126,6 +126,26 @@ String searchTextOf(Card card, List<Tag> tags) {
|
|||
);
|
||||
}
|
||||
|
||||
/// [text] as a card's search text holds it: folded ([searchFolded]), and
|
||||
/// where it has German's umlauts, folded once more with them written out,
|
||||
/// so `maedchen` finds Mädchen as `madchen` does. Written out on the card's
|
||||
/// side, not the query's: a query's own `ue` stays as typed, and `blue`
|
||||
/// doesn't find blunt, nor Spanish `que` aquí.
|
||||
String searchableText(String text) {
|
||||
final folded = searchFolded(text);
|
||||
final lower = text.toLowerCase();
|
||||
if (!lower.contains(_umlaut)) {
|
||||
return folded;
|
||||
}
|
||||
final written = lower
|
||||
.replaceAll('ä', 'ae')
|
||||
.replaceAll('ö', 'oe')
|
||||
.replaceAll('ü', 'ue');
|
||||
return '$folded\n${searchFolded(written)}';
|
||||
}
|
||||
|
||||
final _umlaut = RegExp('[äöü]');
|
||||
|
||||
/// [text] as searches compare it and A–Z orders it: in lower case,
|
||||
/// katakana as hiragana, without accents and tone marks (Latin and Greek
|
||||
/// letters, pinyin's vowels), ß as ss and Greek's final sigma as σ; so
|
||||
|
|
@ -177,18 +197,14 @@ final _bare = {
|
|||
};
|
||||
|
||||
/// Whether a card whose [searchText] is [searchTextOf] holds [query]: as
|
||||
/// typed, with German's umlauts written out as typed without them
|
||||
/// (`maedchen` finds Mädchen), or romaji typed for its kana (`taberu`
|
||||
/// finds たべる).
|
||||
/// typed (German's umlauts written out or not, see [searchableText]), or
|
||||
/// romaji typed for its kana (`taberu` finds たべる).
|
||||
bool matchesQuery(String searchText, String query) {
|
||||
final typed = searchFolded(query.trim());
|
||||
if (typed.isEmpty) {
|
||||
return true;
|
||||
}
|
||||
return searchText.contains(typed) ||
|
||||
searchText.contains(
|
||||
typed.replaceAll('ae', 'a').replaceAll('oe', 'o').replaceAll('ue', 'u'),
|
||||
) ||
|
||||
searchText.contains(romajiToHiragana(typed, finished: true));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ void main() {
|
|||
test('a search finds words of any language as typed on any keyboard: '
|
||||
'without accents, tone marks or umlauts, ß as ss, kana by romaji', () {
|
||||
bool finds(String text, String query) =>
|
||||
matchesQuery(searchFolded(text), query);
|
||||
matchesQuery(searchableText(text), query);
|
||||
|
||||
expect(finds('Straße', 'strasse'), isTrue);
|
||||
expect(finds('Mädchen', 'madchen'), isTrue);
|
||||
|
|
@ -18,6 +18,11 @@ void main() {
|
|||
expect(finds('たべる', 'taberu'), isTrue);
|
||||
expect(finds('テレビ', 'てれび'), isTrue);
|
||||
expect(finds('Haus', 'maus'), isFalse);
|
||||
// Only a card's umlauts are written out, never a query's ue, oe or ae.
|
||||
expect(finds('Müller', 'mueller'), isTrue);
|
||||
expect(finds('blunt', 'blue'), isFalse);
|
||||
expect(finds('aquí', 'que'), isFalse);
|
||||
expect(finds('god', 'goed'), isFalse);
|
||||
});
|
||||
|
||||
test('A–Z compares letters as their bare ones: Ärger among the a, xué '
|
||||
|
|
|
|||
Loading…
Reference in a new issue