mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-08 19:42:12 +00:00
CP2.2: review — British English takes an -ize spelling only when en-US or en-CA spells the word so
craft-libs#483 re-review (P2): ise_spelling turned any z between i/y and a vowel into s, so en-GB (and the other British Englishes) accepted misspellings whose -s- form is a word: wize, rize, noize, dizease, advize, surprize, exercize… (19 reproduced; Hunspell en-GB rejects them all). The -ize form now counts only when the word itself is in the en-US or en-CA SCOWL dictionary and its -ise form in en-GB's (organize, realization, colourize). English with no dialect no longer needs the swap (it reads all three). Test: british_ize_needs_a_real_ize_word (the 19, plus colorize, wrong in en-GB and en-AU; organize, realization, colourize, organizing, realizes right). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FypgCX8LsYYE8fsj4byBm2
This commit is contained in:
1 parent
0675d58341
commit
6e45fda67c
4 files changed
+44
-9
No files matched your search
@@ -74,8 +74,8 @@ English spelling uses the first of these that is there; `english_source(lang)` s
|
||||
dictionary knows it (or `en-extra.txt` does), never because another English's does
|
||||
(`colourblind` is wrong in en-US, `colorblind` in en-GB); suggestions come from the same
|
||||
dictionary. SCOWL's size-60 lists keep one spelling per dialect, and Word accepts more, so
|
||||
British English also takes the `-ize` spellings of its `-ise` words (`organize`,
|
||||
`realization`), and `en-variants.txt` flags the other dialect's spellings and accepts this
|
||||
British English also takes the `-ize` spellings of its `-ise` words that American or Canadian
|
||||
English spell so (`organize`, `realization`; never `wize` or `advize`), and `en-variants.txt` flags the other dialect's spellings and accepts this
|
||||
dialect's other spellings of known words (`judgement` in en-US). English with no dialect
|
||||
(`is_correct`) takes a word any of the three knows. Suggestions offer a missing space only
|
||||
between two lower-case words of three letters or more, after every one-word candidate, and no
|
||||
|
||||
@@ -290,7 +290,7 @@ fn generic(s: Speller) -> Speller {
|
||||
match s {
|
||||
Speller::Scowl(..) => {
|
||||
let all: Vec<_> = [ProofLang::En, ProofLang::EnGb, ProofLang::EnCa].into_iter().filter_map(crate::scowl::dict).collect();
|
||||
Speller::Scowl(all, true)
|
||||
Speller::Scowl(all, false)
|
||||
}
|
||||
other => other,
|
||||
}
|
||||
@@ -301,7 +301,12 @@ impl Speller {
|
||||
fn knows(&self, w: &str) -> bool {
|
||||
match self {
|
||||
Speller::Hunspell(d, _) => affix_correct(&[d.as_ref()], w, false),
|
||||
Speller::Scowl(ds, ise) => affix_correct(ds, w, true) || (*ise && ise_spelling(w).is_some_and(|x| affix_correct(ds, &x, true))),
|
||||
Speller::Scowl(ds, ise) => {
|
||||
affix_correct(ds, w, true)
|
||||
|| (*ise
|
||||
&& ise_spelling(w).is_some_and(|x| affix_correct(ds, &x, true))
|
||||
&& ize_elsewhere(w, |d, p| affix_correct(&[d], p, false)))
|
||||
}
|
||||
Speller::List => list_correct(w),
|
||||
}
|
||||
}
|
||||
@@ -310,7 +315,9 @@ impl Speller {
|
||||
fn knows_lower(&self, p: &str) -> bool {
|
||||
match self {
|
||||
Speller::Hunspell(d, _) => d.check(p),
|
||||
Speller::Scowl(ds, ise) => ds.iter().any(|d| d.check(p) || (*ise && ise_spelling(p).is_some_and(|x| d.check(&x)))),
|
||||
Speller::Scowl(ds, ise) => {
|
||||
ds.iter().any(|d| d.check(p) || (*ise && ise_spelling(p).is_some_and(|x| d.check(&x)) && ize_elsewhere(p, |d, p| d.check(p))))
|
||||
}
|
||||
Speller::List => crate::known_in_word_list(p),
|
||||
}
|
||||
}
|
||||
@@ -339,7 +346,8 @@ pub(crate) fn is_correct(word: &str, lang: ProofLang, opts: &Options, policy: bo
|
||||
/// `w` with its `-ize`/`-yze` endings (and their forms: `-ization`, `-izing`…) spelled `-ise`/
|
||||
/// `-yse`, when it has any: British English takes both (Word accepts `organize` and `organise` in
|
||||
/// en-GB), and SCOWL's en-GB dictionary has only `-ise`. A `z` between `i`/`y` and a vowel is
|
||||
/// swapped (`citizen` → `citisen`, which no dictionary knows, so that does no harm).
|
||||
/// swapped; the `-ize` form counts only when American or Canadian English spells the word so
|
||||
/// ([`ize_elsewhere`]), or `wize` would pass as `wise`.
|
||||
pub(crate) fn ise_spelling(w: &str) -> Option<String> {
|
||||
let b = w.as_bytes();
|
||||
let mut out = b.to_vec();
|
||||
@@ -361,6 +369,12 @@ pub(crate) fn ise_spelling(w: &str) -> Option<String> {
|
||||
if changed { String::from_utf8(out).ok() } else { None }
|
||||
}
|
||||
|
||||
/// Is `w` a word in American or Canadian English's SCOWL dictionary (`check` asks one): the
|
||||
/// `-ize` spellings British English takes are theirs (`organize`, never `advize` or `wize`).
|
||||
fn ize_elsewhere(w: &str, check: impl Fn(&AffixDict, &str) -> bool) -> bool {
|
||||
[ProofLang::En, ProofLang::EnCa].into_iter().filter_map(crate::scowl::dict).any(|d| check(d, w))
|
||||
}
|
||||
|
||||
/// Against affix dictionaries (any of them): the word, or each part of a hyphenated one; with
|
||||
/// `supplement`, our supplement's words count too.
|
||||
fn affix_correct(ds: &[&AffixDict], w: &str, supplement: bool) -> bool {
|
||||
|
||||
@@ -1781,6 +1781,26 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// craft-libs#483 re-review: British English takes the `-ize` spelling of an `-ise` word only
|
||||
/// when American or Canadian English spells it so; a misspelling whose `-s-` form is a word
|
||||
/// (`wize`, `advize`) stays wrong, as in Hunspell's en-GB.
|
||||
#[cfg_attr(not(craft_proof_data), ignore = "needs the Language data (CRAFT_I18N_DIR)")]
|
||||
#[test]
|
||||
fn british_ize_needs_a_real_ize_word() {
|
||||
let wrong = [
|
||||
"wize", "rize", "noize", "dizease", "advize", "rizing", "praize", "raize", "poize", "wizer", "surprize", "arize", "revize", "devize",
|
||||
"mizer", "concize", "precize", "exercize", "chaize",
|
||||
];
|
||||
for l in [ProofLang::EnGb, ProofLang::from_tag(Some("en-AU"))] {
|
||||
for w in wrong.iter().chain(&["colorize"]) {
|
||||
assert!(!is_correct_in(w, l), "{w} in {l:?}");
|
||||
}
|
||||
for w in ["organize", "realization", "colourize", "organizing", "realizes"] {
|
||||
assert!(is_correct_in(w, l), "{w} in {l:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(not(craft_proof_data), ignore = "needs the Language data (CRAFT_I18N_DIR)")]
|
||||
#[test]
|
||||
fn user_dictionary_accepts_the_other_dialects_spelling() {
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
//! come from its own dictionary, and a word is right when its own dictionary knows it: the other
|
||||
//! dialects' dictionaries are never asked (en-US would take `colourblind` from en-GB's). SCOWL
|
||||
//! picks one spelling per dialect (en-GB `-ise` has no `organize`, en-US no `judgement`), and Word
|
||||
//! accepts more, so British English also takes the `-ize` spellings of its `-ise` words, and
|
||||
//! `en-variants.txt` widens each dialect by its pairs (`crate::english`). An English dictionary in the dictionaries folder comes first; a SCOWL dictionary that isn't
|
||||
//! embedded, or fails to load, leaves that English to the next source (`crate::english`).
|
||||
//! accepts more, so British English also takes the `-ize` spellings of its `-ise` words that
|
||||
//! en-US or en-CA spells so, and `en-variants.txt` widens each dialect by its pairs
|
||||
//! (`crate::english`). An English dictionary in the dictionaries folder comes first; a SCOWL
|
||||
//! dictionary that isn't embedded, or fails to load, leaves that English to the next source (`crate::english`).
|
||||
//!
|
||||
//! SCOWL is under its own permissive licence and the affix files under Ispell's BSD licence;
|
||||
//! [`notice`] is the upstream text, for an About window.
|
||||
|
||||
Reference in new issue
Block a user