use phf::{phf_map, phf_set, Map, Set};
pub fn normalize_text_for_naist_jdic(input_text: &str) -> String {
let (mut s, c) = input_text
.chars()
.map(|c| {
if let Some(replacement) = HALFWIDTH.get(&c) {
*replacement
} else if '\u{0020}' < c && c < '\u{007f}' {
char::from_u32((c as u32) + 0xfee0).unwrap()
} else {
c
}
})
.fold(
(String::with_capacity(input_text.len()), None),
|(mut acc, prev), curr| {
let semivoiced = SEMIVOICED_SOUND_MARK.contains(&curr);
let voiced = VOICED_SOUND_MARK.contains(&curr);
let combined = if semivoiced {
prev.and_then(|p| SEMIVOICED.get(&p))
} else if voiced {
prev.and_then(|p| VOICED.get(&p))
} else {
None
};
if let Some(combined) = combined {
acc.push(*combined);
} else if let Some(prev_char) = prev {
acc.push(prev_char);
}
if semivoiced || voiced {
(acc, None)
} else {
(acc, Some(curr))
}
},
);
if let Some(c) = c {
s.push(c);
}
s
}
const HALFWIDTH: Map<char, char> = phf_map! {
' ' => '\u{3000}', '\u{a5}' => '\u{FFE5}', '\\' => '\u{FFE5}', '-' => '\u{2212}', '~' => '\u{301C}', '`' => '\u{2018}', '\"' => '\u{201D}', '\'' => '\u{2019}', '\u{FF61}' => '\u{3002}', '\u{FF62}' => '\u{300C}', '\u{FF63}' => '\u{300D}', '\u{FF64}' => '\u{3001}', '\u{FF65}' => '\u{30FB}', 'ヲ' => 'ヲ',
'ァ' => 'ァ',
'ィ' => 'ィ',
'ゥ' => 'ゥ',
'ェ' => 'ェ',
'ォ' => 'ォ',
'ャ' => 'ャ',
'ュ' => 'ュ',
'ョ' => 'ョ',
'ッ' => 'ッ',
'ー' => 'ー',
'ア' => 'ア',
'イ' => 'イ',
'ウ' => 'ウ',
'エ' => 'エ',
'オ' => 'オ',
'カ' => 'カ',
'キ' => 'キ',
'ク' => 'ク',
'ケ' => 'ケ',
'コ' => 'コ',
'サ' => 'サ',
'シ' => 'シ',
'ス' => 'ス',
'セ' => 'セ',
'ソ' => 'ソ',
'タ' => 'タ',
'チ' => 'チ',
'ツ' => 'ツ',
'テ' => 'テ',
'ト' => 'ト',
'ナ' => 'ナ',
'ニ' => 'ニ',
'ヌ' => 'ヌ',
'ネ' => 'ネ',
'ノ' => 'ノ',
'ハ' => 'ハ',
'ヒ' => 'ヒ',
'フ' => 'フ',
'ヘ' => 'ヘ',
'ホ' => 'ホ',
'マ' => 'マ',
'ミ' => 'ミ',
'ム' => 'ム',
'メ' => 'メ',
'モ' => 'モ',
'ヤ' => 'ヤ',
'ユ' => 'ユ',
'ヨ' => 'ヨ',
'ラ' => 'ラ',
'リ' => 'リ',
'ル' => 'ル',
'レ' => 'レ',
'ロ' => 'ロ',
'ワ' => 'ワ',
'ン' => 'ン',
};
const SEMIVOICED_SOUND_MARK: Set<char> = phf_set! {
'\u{309A}', '\u{309C}', '\u{FF9F}', };
const SEMIVOICED: Map<char, char> = phf_map! {
'ハ' => 'パ',
'ヒ' => 'ピ',
'フ' => 'プ',
'ヘ' => 'ペ',
'ホ' => 'ポ',
'は' => 'ぱ',
'ひ' => 'ぴ',
'ふ' => 'ぷ',
'へ' => 'ぺ',
'ほ' => 'ぽ',
};
const VOICED_SOUND_MARK: Set<char> = phf_set! {
'\u{3099}', '\u{309B}', '\u{FF9E}', };
const VOICED: Map<char, char> = phf_map! {
'カ' => 'ガ',
'キ' => 'ギ',
'ク' => 'グ',
'ケ' => 'ゲ',
'コ' => 'ゴ',
'サ' => 'ザ',
'シ' => 'ジ',
'ス' => 'ズ',
'セ' => 'ゼ',
'ソ' => 'ゾ',
'タ' => 'ダ',
'チ' => 'ヂ',
'ツ' => 'ヅ',
'テ' => 'デ',
'ト' => 'ド',
'ハ' => 'バ',
'ヒ' => 'ビ',
'フ' => 'ブ',
'ヘ' => 'ベ',
'ホ' => 'ボ',
'ウ' => 'ヴ',
'ワ' => 'ヷ',
'ヰ' => 'ヸ',
'ヱ' => 'ヹ',
'ヲ' => 'ヺ',
'ヽ' => 'ヾ',
'か' => 'が',
'き' => 'ぎ',
'く' => 'ぐ',
'け' => 'げ',
'こ' => 'ご',
'さ' => 'ざ',
'し' => 'じ',
'す' => 'ず',
'せ' => 'ぜ',
'そ' => 'ぞ',
'た' => 'だ',
'ち' => 'ぢ',
'つ' => 'づ',
'て' => 'で',
'と' => 'ど',
'は' => 'ば',
'ひ' => 'び',
'ふ' => 'ぶ',
'へ' => 'べ',
'ほ' => 'ぼ',
'う' => 'ゔ',
};
#[cfg(test)]
mod tests {
use crate::normalize_text_for_naist_jdic;
#[test]
fn ascii() {
assert_eq!(
normalize_text_for_naist_jdic(" !\"#$%&'()*+,-./"),
" !”#$%&’()*+,−./"
);
assert_eq!(
normalize_text_for_naist_jdic("0123456789"),
"0123456789"
);
assert_eq!(normalize_text_for_naist_jdic(":;<=>?@"), ":;<=>?@");
assert_eq!(
normalize_text_for_naist_jdic("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
);
assert_eq!(normalize_text_for_naist_jdic("[\\]^_`"), "[¥]^_‘");
assert_eq!(
normalize_text_for_naist_jdic("abcdefghijklmnopqrstuvwxyz"),
"abcdefghijklmnopqrstuvwxyz"
);
assert_eq!(normalize_text_for_naist_jdic("{|}~"), "{|}〜");
}
#[test]
fn kana() {
assert_eq!(
normalize_text_for_naist_jdic("ヴガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポ"),
"ヴガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポ"
);
assert_eq!(normalize_text_for_naist_jdic("。「」、・"), "。「」、・");
assert_eq!(
normalize_text_for_naist_jdic("ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン"),
"ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン"
);
}
#[test]
fn diacritical() {
assert_eq!(normalize_text_for_naist_jdic("゙゚"), "");
assert_eq!(normalize_text_for_naist_jdic("あ゛"), "あ");
assert_eq!(normalize_text_for_naist_jdic("あ゜"), "あ");
assert_eq!(normalize_text_for_naist_jdic("は゛"), "ば");
assert_eq!(normalize_text_for_naist_jdic("は゜"), "ぱ");
}
}