Skip to content

Commit c38fa46

Browse files
committed
Add special case for upper words with apostrophes
1 parent 4482c25 commit c38fa46

File tree

1 file changed

+61
-2
lines changed

1 file changed

+61
-2
lines changed

src/checker.rs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,42 @@ impl<'a, S: BuildHasher> Checker<'a, S> {
152152
return Some(flags);
153153
}
154154

155-
// TODO: handle apostrophes
155+
// Handle prefixes separated by an apostrophe. This is used for Catalan, French and
156+
// Italian. Nuspell gives the example: SANT'ELIA => Sant'+Elia. Find an apostrophe that
157+
// isn't at the very end of the word.
158+
if let Some(mut idx) = word.find('\'').filter(|idx| *idx != word.len() - 1) {
159+
// `find` returns the index of the found character. We want to include that apostrophe
160+
// in `part1` so move the index after the apostrophe.
161+
debug_assert_eq!("'".as_bytes().len(), 1);
162+
idx += 1;
163+
// Slice up the word into two parts: part1 has the apostrophe and part2 is the rest.
164+
let part1 = &word[..idx];
165+
let part2 = &word[idx..];
166+
167+
// Try two permutations: part1 as lowercase and part1 as titlecase with part2 always
168+
// being titlecase.
169+
let part2 = to_titlecase(part2);
170+
171+
let mut lower = part1.to_lowercase();
172+
lower.push_str(&part2);
173+
if let Some(flags) = self.check_word(
174+
&lower,
175+
Forceucase::AllowBadForceucase,
176+
HiddenHomonym::default(),
177+
) {
178+
return Some(flags);
179+
}
180+
181+
let mut title = to_titlecase(part1);
182+
title.push_str(&part2);
183+
if let Some(flags) = self.check_word(
184+
&title,
185+
Forceucase::AllowBadForceucase,
186+
HiddenHomonym::default(),
187+
) {
188+
return Some(flags);
189+
}
190+
}
156191

157192
// Special-case for sharps (ß).
158193
if self.aff.options.checksharps && word.contains("SS") {
@@ -1776,7 +1811,7 @@ mod test {
17761811
}
17771812

17781813
#[test]
1779-
fn check_sharp_casing() {
1814+
fn check_sharp_upper_casing() {
17801815
let aff = r#"
17811816
CHECKSHARPS
17821817
"#;
@@ -1793,6 +1828,30 @@ mod test {
17931828
assert!(dict.check("AUSSASS"));
17941829
}
17951830

1831+
#[test]
1832+
fn check_apostrophe_upper_casing() {
1833+
let aff = "";
1834+
// from it_IT
1835+
let dic = r#"4
1836+
cent'anni
1837+
d'Intelvi
1838+
Anch'Egli
1839+
anch'Ella
1840+
"#;
1841+
1842+
let dict = Dictionary::new_with_hasher(dic, aff, RandomState::new()).unwrap();
1843+
1844+
assert!(dict.check("cent'anni"));
1845+
assert!(dict.check("d'Intelvi"));
1846+
assert!(dict.check("Anch'Egli"));
1847+
assert!(dict.check("anch'Ella"));
1848+
1849+
assert!(dict.check("CENT'ANNI"));
1850+
assert!(dict.check("D'INTELVI"));
1851+
assert!(dict.check("ANCH'EGLI"));
1852+
assert!(dict.check("ANCH'ELLA"));
1853+
}
1854+
17961855
#[test]
17971856
fn false_prefix_test() {
17981857
// "un" is a prefix in en_US and "drink" is a stem. "drink"'s flags don't allow you to use

0 commit comments

Comments
 (0)