craft-proof cs, hr, it — a hyphenated word is looked up whole before its parts, and an elision (l'ex-amico) is read in each part (#496 review)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Martin BallandClaude Opus 5.5 committed 2026-11-02 21:56:44 +00:00
1 parent 9ef9185131
commit 61030150dc
3 files changed
+37 -3

No files matched your search

+10 -1
View File
@@ -63,7 +63,8 @@ fn check(d: &AffixDict, word: &str, opts: &crate::Options) -> bool {
return true;
};
if w.contains('-') {
return w.split('-').all(|p| p.chars().count() <= 1 || known(d, p));
// The whole word first, as Hunspell does: a hyphenated entry or user word.
return known(d, w) || w.split('-').all(|p| p.chars().count() <= 1 || known(d, p));
}
known(d, w)
}
@@ -142,6 +143,14 @@ mod tests {
}
}
/// craft-libs#496 review: a hyphenated dictionary entry is a word even when its parts aren't.
#[test]
fn a_hyphenated_entry_is_looked_up_whole() {
let d = AffixDict::from_hunspell("SET UTF-8\n", "1\ntic-tac\n", &[]).unwrap();
assert!(is_correct_with(&d, "tic-tac"));
assert!(!is_correct_with(&d, "tic-tacc"));
}
#[test]
fn missing_dictionary_and_ignored_inputs_are_quiet() {
let empty = AffixDict::default();
+10 -1
View File
@@ -65,7 +65,8 @@ fn check(d: &AffixDict, word: &str, opts: &crate::Options) -> bool {
return true;
};
if w.contains('-') {
return w.split('-').all(|p| p.chars().count() <= 1 || known(d, p));
// The whole word first, as Hunspell does: a hyphenated entry or user word.
return known(d, w) || w.split('-').all(|p| p.chars().count() <= 1 || known(d, p));
}
known(d, w)
}
@@ -105,6 +106,14 @@ mod tests {
}
}
/// craft-libs#496 review: a hyphenated dictionary entry is a word even when its parts aren't.
#[test]
fn a_hyphenated_entry_is_looked_up_whole() {
let d = AffixDict::from_hunspell("SET UTF-8\n", "1\ntic-tac\n", &[]).unwrap();
assert!(is_correct_with(&d, "tic-tac"));
assert!(!is_correct_with(&d, "tic-tacc"));
}
#[test]
fn missing_dictionary_is_silent() {
assert!(is_correct_with(&AffixDict::default(), "nepostojećariječ"));
+17 -1
View File
@@ -97,8 +97,14 @@ fn check(d: &AffixDict, word: &str, opts: &crate::Options) -> bool {
}
// The whole word first, as Hunspell does: a hyphenated entry or user word.
if w.contains('-') {
return known(d, w) || w.split('-').all(|p| p.chars().count() <= 1 || known(d, p));
return known(d, w) || w.split('-').all(|p| p.chars().count() <= 1 || known_elided(d, p));
}
known_elided(d, w)
}
/// [`known`] for a word that may start with an elided proclitic (`l'amico`, `l'ex`): the word after
/// the apostrophe is what gets checked.
fn known_elided(d: &AffixDict, w: &str) -> bool {
if let Some((head, tail)) = w.split_once(['\'', '’'])
&& PROCLITICS.contains(&head.to_lowercase().as_str())
&& !tail.is_empty()
@@ -148,6 +154,16 @@ mod tests {
assert!(!is_correct_with(&d, "tic-tacc"));
}
/// craft-libs#496 review: an elision inside a hyphenated word (`l'ex-amico`) is read per part.
#[test]
fn an_elision_in_a_hyphenated_part_is_read() {
let d = AffixDict::from_hunspell("SET UTF-8\n", "2\nex\namico\n", &[]).unwrap();
for w in ["l'ex-amico", "dell’ex-amico", "ex-amico"] {
assert!(is_correct_with(&d, w), "{w}");
}
assert!(!is_correct_with(&d, "l'exx-amico"));
}
#[test]
fn without_a_dictionary_nothing_is_flagged() {
let none = AffixDict::default();