Compare commits
No commits in common. "2cbe8462ae53448490e366a6e44662f56d491318" and "4fb005ce09d60066c9d46b8e15b01ffa8f1833a8" have entirely different histories.
2cbe8462ae
...
4fb005ce09
6 changed files with 33 additions and 406 deletions
|
@ -8317,6 +8317,7 @@
|
|||
おうようじょう 応用上
|
||||
おうようじょうほう 応用情報
|
||||
おうようじょうほうがく 応用情報学
|
||||
おうじょうけん 応用情報学研究センター
|
||||
おうようすいしんか 応用推進課
|
||||
おうようすうがく 応用数学
|
||||
おうようすうがっか 応用数学科
|
||||
|
@ -14907,6 +14908,7 @@
|
|||
かんいしんぱん 簡易新版
|
||||
かんいてき 簡易的
|
||||
かんいほけん 簡易保険
|
||||
かんいほけんほーる 簡易保険ホール
|
||||
かんいほうしき 簡易方式
|
||||
かんいむせん 簡易無線
|
||||
かんけつ 簡潔
|
||||
|
@ -42586,6 +42588,7 @@
|
|||
しょせきるい 書籍類
|
||||
しょせん 書泉
|
||||
しょせんぐらんで 書泉グランデ
|
||||
しょせんぶっくまーと 書泉ブックマート
|
||||
しょたい 書体
|
||||
しょだな 書棚
|
||||
かきおき 書置
|
||||
|
@ -46958,6 +46961,7 @@
|
|||
しんにっぽん 新日本
|
||||
しんにほんしょうけん 新日本証券
|
||||
しんにほんせいてつ 新日本製鉄
|
||||
しんにってつ 新日本製鉄株式会社
|
||||
しんにほんせいてつ 新日本製鐵
|
||||
しんにっぽんせいてつ 新日本製鐵
|
||||
しんにってつ 新日鐵
|
||||
|
@ -54137,6 +54141,7 @@
|
|||
せんこうちゅう 選考中
|
||||
せんこうび 選考日
|
||||
せんこう 選鉱
|
||||
せんけん 選鉱精錬研究所
|
||||
せんじゃ 選者
|
||||
せんしゅ 選手
|
||||
せんしゅいちらん 選手一覧
|
||||
|
@ -62102,6 +62107,7 @@
|
|||
ちゅうがくせいばん 中学生版
|
||||
ちゅうがくにゅうしもんだい 中学入試問題
|
||||
ちゅうかっこ 中括弧
|
||||
なかま 中間
|
||||
ちゅうかんれべるがくしゅう 中間レベル学習
|
||||
ちゅうかんえき 中間駅
|
||||
ちゅうかんえきしはつ 中間駅始発
|
||||
|
@ -66465,6 +66471,7 @@
|
|||
でんしききぶ 電子機器部
|
||||
でんしぎじゅつ 電子技術
|
||||
でんしぎじゅつしゃ 電子技術者
|
||||
でんそうけん 電子技術総合研究所
|
||||
でんしきょう 電子協
|
||||
でんしけいじばん 電子掲示板
|
||||
でんしけい 電子系
|
||||
|
@ -66479,6 +66486,7 @@
|
|||
でんしこうがくきょうしつ 電子工学教室
|
||||
でんしこうがくせんこう 電子工学専攻
|
||||
でんしこうぎょう 電子工業
|
||||
でんしきょう 電子工業振興協会
|
||||
でんしこうさく 電子工作
|
||||
でんしざいりょう 電子材料
|
||||
でんししき 電子式
|
||||
|
@ -67633,6 +67641,7 @@
|
|||
とうきょうがす 東京ガス
|
||||
とうきょうすたいる 東京スタイル
|
||||
とうきょうてあとる 東京テアトル
|
||||
とうきょうべいえぬけーほーる 東京ベイNKホール
|
||||
とうきょういがい 東京以外
|
||||
とうきょういち 東京一
|
||||
とうきょうえき 東京駅
|
||||
|
@ -68458,6 +68467,7 @@
|
|||
とうけいしょり 統計処理
|
||||
とうけいじょうほう 統計情報
|
||||
とうけいすうがく 統計数学
|
||||
とうすうけん 統計数理研究所
|
||||
とうけいち 統計値
|
||||
とうけいてき 統計的
|
||||
とうけいてきぱたあん 統計的パターン
|
||||
|
@ -71459,10 +71469,12 @@
|
|||
にっぽんとむそん 日本トムソン
|
||||
にっぽんはむ 日本ハム
|
||||
にほんはむ 日本ハム
|
||||
にっぽんひゅーむかん 日本ヒューム管
|
||||
にっぽんびくたー 日本ビクター
|
||||
にっぽんぺいんと 日本ペイント
|
||||
にっぽんゆにばっく 日本ユニバック
|
||||
にっぽんれーす 日本レース
|
||||
にほんろぼっとがっかい 日本ロボット学会
|
||||
にほんいがい 日本以外
|
||||
にほんいじょう 日本以上
|
||||
にほんいち 日本一
|
||||
|
@ -72020,6 +72032,8 @@
|
|||
にゅうしゅつりょく 入出力
|
||||
にゅうしゅつりょくh 入出力
|
||||
にゅうしゅつりょくせっと 入出力セット
|
||||
にゅうしゅつりょくぱ 入出力パターン
|
||||
にゅうしゅつりょくぱたーん 入出力パターン
|
||||
にゅうしゅつりょくかんけい 入出力関係
|
||||
にゅうしゅつりょくけい 入出力系
|
||||
にゅうしゅつりょくそうち 入出力装置
|
||||
|
@ -79662,6 +79676,7 @@
|
|||
ぶんいちそうごうしゅっぱん 文一総合出版
|
||||
ぶんえんどう 文苑堂
|
||||
ぶんか 文化
|
||||
ぶんかしゃったー 文化シャッター
|
||||
ぶんかかい 文化会
|
||||
ぶんかかいかん 文化会館
|
||||
ぶんかかいかん 文化会舘
|
||||
|
@ -80063,6 +80078,7 @@
|
|||
へいおん 平温
|
||||
へいおん 平穏
|
||||
ひらかな 平仮名
|
||||
ひらかなかくていにゅうりょく 平仮名確定入力
|
||||
へいか 平価
|
||||
へいけ 平家
|
||||
へいけものがたり 平家物語
|
||||
|
@ -110762,6 +110778,7 @@
|
|||
せんせいよう 先生用
|
||||
せんせんげつ 先先月
|
||||
せんたんいりょう 先端医療
|
||||
せんたんかがくぎじゅつけんきゅうせんたー 先端科学技術研究センター
|
||||
せんたんぎじゅつけんきゅう 先端技術研究
|
||||
せんたんきょうふしょう 先端恐怖症
|
||||
せんたんけん 先端研
|
||||
|
@ -114496,6 +114513,7 @@
|
|||
でんしききるい 電子機器類
|
||||
でんしきどう 電子軌道
|
||||
でんしぎじゅつかんけい 電子技術関係
|
||||
でんしぎじゅつそうごうけんきゅうしょ 電子技術総合研究所
|
||||
でんしけいじばん 電子掲示版
|
||||
でんしけいさんきしつ 電子計算機室
|
||||
でんしこうさくよう 電子工作用
|
||||
|
@ -116004,6 +116022,7 @@
|
|||
にほんちんぼつ 日本沈没
|
||||
にほんていえん 日本庭園
|
||||
にほんてつどう 日本鉄道
|
||||
にほんにんちかがくかい 日本認知科学会
|
||||
にほんねこ 日本猫
|
||||
にほんばんじまく 日本版字幕
|
||||
にほんぶっきょう 日本仏教
|
||||
|
@ -116096,6 +116115,7 @@
|
|||
にゅうよくざい 入浴剤
|
||||
にゅうよくはっぽうき 入浴発泡器
|
||||
にゅうらい 入来
|
||||
にゅうりょくぱらめーた 入力パラメータ
|
||||
にゅうりょくかんじ 入力漢字
|
||||
にゅうりょくかんきょう 入力環境
|
||||
にゅうりょくじたい 入力自体
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
mod phfbin_gen;
|
||||
mod testconv;
|
||||
|
||||
use std::{borrow::Cow, collections::HashMap, path::Path};
|
||||
|
||||
|
@ -67,13 +66,12 @@ fn parse_dict_ln(records: &mut Records, line: &str, ln: usize) {
|
|||
.or_else(|| context.map(str::to_owned))
|
||||
.unwrap_or_default(),
|
||||
) {
|
||||
std::collections::hash_map::Entry::Occupied(_) => {
|
||||
/*
|
||||
// Replace reading if the new one is shorter
|
||||
std::collections::hash_map::Entry::Occupied(mut e) => {
|
||||
// Replace reading if the new one is longer
|
||||
let val = e.get_mut();
|
||||
if val.len() > reading.len() {
|
||||
if val.len() < reading.len() {
|
||||
*val = reading.to_owned();
|
||||
}*/
|
||||
}
|
||||
}
|
||||
std::collections::hash_map::Entry::Vacant(e) => {
|
||||
e.insert(reading.to_owned());
|
||||
|
@ -200,63 +198,9 @@ impl Encodable for Readings {
|
|||
}
|
||||
}
|
||||
|
||||
fn find_redundant_compounds(dict: &Records) -> Records {
|
||||
let mut wdict = dict.clone();
|
||||
|
||||
for (kanji, readings) in dict {
|
||||
if kanji.chars().count() <= 3 {
|
||||
continue;
|
||||
}
|
||||
if readings.len() != 1 {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(reading) = readings.get("") {
|
||||
// Try to convert the entry without it being present
|
||||
let entry = wdict.remove_entry(kanji).unwrap();
|
||||
let res = testconv::convert(kanji, &wdict);
|
||||
|
||||
if &res == reading || to_romaji_nodc(&res) == to_romaji_nodc(reading) {
|
||||
println!("Redundant: {} - {}", kanji, reading);
|
||||
} else {
|
||||
// Put the entry back if it is necessary
|
||||
wdict.insert(entry.0, entry.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
wdict
|
||||
}
|
||||
|
||||
/// Romanize and remove double consonants
|
||||
fn to_romaji_nodc(text: &str) -> String {
|
||||
let rom = wana_kana::to_romaji::to_romaji(text);
|
||||
|
||||
let mut buf = String::new();
|
||||
let mut citer = rom.chars().peekable();
|
||||
|
||||
while let Some(c) = citer.next() {
|
||||
if matches!(c, 'a' | 'e' | 'i' | 'o' | 'u') {
|
||||
match citer.peek() {
|
||||
Some(nc) => {
|
||||
if &c != nc {
|
||||
buf.push(c);
|
||||
}
|
||||
}
|
||||
None => buf.push(c),
|
||||
}
|
||||
} else {
|
||||
buf.push(c);
|
||||
}
|
||||
}
|
||||
buf
|
||||
}
|
||||
|
||||
fn generate_kanji_dict() -> Vec<u8> {
|
||||
let mut records = Records::default();
|
||||
parse_dict(&mut records, Path::new("dict/kakasidict.utf8"));
|
||||
records = find_redundant_compounds(&records);
|
||||
|
||||
println!("kanji_dict: {} entries", records.len());
|
||||
|
||||
let mut phfmap = phfbin_gen::Map::<KanjiString, Readings>::default();
|
||||
for (kanji, readings) in records {
|
||||
|
|
|
@ -1,196 +0,0 @@
|
|||
use crate::{Records, CLETTERS};
|
||||
|
||||
const ENDMARK: [char; 11] = [
|
||||
')', ']', '!', '.', ',', '\u{3001}', '\u{3002}', '\u{ff1f}', '\u{ff10}', '\u{ff1e}', '\u{ff1c}',
|
||||
];
|
||||
const DASH_SYMBOLS: [char; 4] = ['\u{30FC}', '\u{2015}', '\u{2212}', '\u{FF70}'];
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum CharType {
|
||||
Kanji,
|
||||
Katakana,
|
||||
Hiragana,
|
||||
Symbol,
|
||||
Alpha,
|
||||
}
|
||||
|
||||
pub fn convert(text: &str, dict: &Records) -> String {
|
||||
// TODO: char conversion should be done with iterators
|
||||
let mut char_indices = text.char_indices();
|
||||
let mut kana_text = String::new();
|
||||
let mut hiragana = String::new();
|
||||
let mut prev_type = CharType::Kanji;
|
||||
|
||||
// output_flag
|
||||
// means (output buffer?, output text[i]?, copy to buffer and increment i?)
|
||||
// possible (False, True, True), (True, False, False), (True, True, True)
|
||||
// (False, False, True)
|
||||
|
||||
while let Some((i, c)) = char_indices.next() {
|
||||
let output_flag = if ENDMARK.contains(&c) {
|
||||
(CharType::Symbol, true, true, true)
|
||||
} else if DASH_SYMBOLS.contains(&c) {
|
||||
(prev_type, false, false, true)
|
||||
} else if is_sym(c) {
|
||||
if prev_type != CharType::Symbol {
|
||||
(CharType::Symbol, true, false, true)
|
||||
} else {
|
||||
(CharType::Symbol, false, true, true)
|
||||
}
|
||||
} else if wana_kana::utils::is_char_katakana(c) {
|
||||
(
|
||||
CharType::Katakana,
|
||||
prev_type != CharType::Katakana,
|
||||
false,
|
||||
true,
|
||||
)
|
||||
} else if wana_kana::utils::is_char_hiragana(c) {
|
||||
(
|
||||
CharType::Hiragana,
|
||||
prev_type != CharType::Hiragana,
|
||||
false,
|
||||
true,
|
||||
)
|
||||
} else if c.is_ascii() {
|
||||
(CharType::Alpha, prev_type != CharType::Alpha, false, true)
|
||||
} else if wana_kana::utils::is_char_kanji(c) {
|
||||
if !kana_text.is_empty() {
|
||||
hiragana.push_str(&convert_kana(&kana_text));
|
||||
}
|
||||
let (t, n) = convert_kanji(&text[i..], &kana_text, &dict);
|
||||
|
||||
if n > 0 {
|
||||
kana_text = t;
|
||||
for _ in 1..n {
|
||||
char_indices.next();
|
||||
}
|
||||
(CharType::Kanji, false, false, false)
|
||||
} else {
|
||||
// Unknown kanji
|
||||
kana_text.clear();
|
||||
// TODO: FOR TESTING
|
||||
hiragana.push_str("🯄");
|
||||
(CharType::Kanji, true, false, false)
|
||||
}
|
||||
} else if matches!(c as u32, 0xf000..=0xfffd | 0x10000..=0x10ffd) {
|
||||
// PUA: ignore and drop
|
||||
if !kana_text.is_empty() {
|
||||
hiragana.push_str(&convert_kana(&kana_text));
|
||||
}
|
||||
(prev_type, false, false, false)
|
||||
} else {
|
||||
(prev_type, true, true, true)
|
||||
};
|
||||
|
||||
prev_type = output_flag.0;
|
||||
|
||||
if output_flag.1 && output_flag.2 {
|
||||
kana_text.push(c);
|
||||
hiragana.push_str(&convert_kana(&kana_text));
|
||||
kana_text.clear()
|
||||
} else if output_flag.1 && output_flag.3 {
|
||||
if !kana_text.is_empty() {
|
||||
hiragana.push_str(&convert_kana(&kana_text));
|
||||
}
|
||||
kana_text = c.to_string();
|
||||
} else if output_flag.3 {
|
||||
kana_text.push(c);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert last word
|
||||
if !kana_text.is_empty() {
|
||||
hiragana.push_str(&convert_kana(&kana_text));
|
||||
}
|
||||
|
||||
hiragana
|
||||
}
|
||||
|
||||
fn is_sym(c: char) -> bool {
|
||||
matches!(c as u32,
|
||||
0x3000..=0x3020 |
|
||||
0x3030..=0x303F |
|
||||
0x0391..=0x03A1 |
|
||||
0x03A3..=0x03A9 |
|
||||
0x03B1..=0x03C9 |
|
||||
0x0410..= 0x044F |
|
||||
0xFF01..=0xFF1A |
|
||||
0x00A1..=0x00FF |
|
||||
0xFF20..=0xFF5E |
|
||||
0x0451 |
|
||||
0x0401
|
||||
)
|
||||
}
|
||||
|
||||
fn convert_kana(text: &str) -> String {
|
||||
wana_kana::to_hiragana::to_hiragana_with_opt(
|
||||
text,
|
||||
wana_kana::Options {
|
||||
use_obsolete_kana: false,
|
||||
pass_romaji: true,
|
||||
upcase_katakana: false,
|
||||
imemode: false,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Convert the leading kanji from the input string to hiragana
|
||||
fn convert_kanji(text: &str, btext: &str, dict: &Records) -> (String, usize) {
|
||||
let mut translation: Option<String> = None;
|
||||
let mut i_c = 0;
|
||||
let mut n_c = 0;
|
||||
let mut char_indices = text.char_indices().peekable();
|
||||
|
||||
while let Some((i, c)) = char_indices.next() {
|
||||
let kanji = &text[0..i + c.len_utf8()];
|
||||
|
||||
let this_tl = dict.get(kanji).and_then(|readings| {
|
||||
readings
|
||||
.iter()
|
||||
.find_map(|(k, reading)| {
|
||||
if k.is_empty() {
|
||||
None
|
||||
} else if let Some(cltr) = CLETTERS.get(&k.chars().next().unwrap_or_default()) {
|
||||
char_indices.peek().and_then(|(_, next_c)| {
|
||||
// Shortcut if the next character is not hiragana
|
||||
if wana_kana::utils::is_char_hiragana(*next_c) {
|
||||
if cltr.contains(&&next_c.to_string().as_str()) {
|
||||
// Add the next character to the char count
|
||||
i_c += 1;
|
||||
let mut hira = reading.to_owned();
|
||||
hira.push(*next_c);
|
||||
return Some(hira);
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
} else if wana_kana::is_hiragana::is_hiragana(&k) {
|
||||
if btext.contains(reading) {
|
||||
Some(reading.to_owned())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
panic!("invalid reading key")
|
||||
}
|
||||
})
|
||||
.or_else(|| readings.get("").cloned())
|
||||
});
|
||||
|
||||
i_c += 1;
|
||||
if let Some(tl) = this_tl {
|
||||
translation = Some(tl);
|
||||
n_c = i_c;
|
||||
}
|
||||
if i_c >= 12 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
translation
|
||||
.map(|tl| (tl.to_owned(), n_c))
|
||||
.unwrap_or_default()
|
||||
}
|
Binary file not shown.
157
src/lib.rs
157
src/lib.rs
|
@ -12,7 +12,6 @@ use phfbin::PhfMap;
|
|||
use types::{KanjiString, Readings};
|
||||
|
||||
const KANJI_DICT: &[u8] = include_bytes!("./kanji_dict.bin");
|
||||
const MAX_KANJI_LEN: usize = 7;
|
||||
|
||||
static CLETTERS: phf::Map<u8, &[char]> = phf::phf_map!(
|
||||
b'a' => &['あ', 'ぁ', 'っ', 'わ', 'ゎ'],
|
||||
|
@ -40,20 +39,6 @@ static CLETTERS: phf::Map<u8, &[char]> = phf::phf_map!(
|
|||
b'v' => &['ゔ'],
|
||||
);
|
||||
|
||||
const ENDMARK: [char; 11] = [
|
||||
')', ']', '!', '.', ',', '\u{3001}', '\u{3002}', '\u{ff1f}', '\u{ff10}', '\u{ff1e}', '\u{ff1c}',
|
||||
];
|
||||
const DASH_SYMBOLS: [char; 4] = ['\u{30FC}', '\u{2015}', '\u{2212}', '\u{FF70}'];
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum CharType {
|
||||
Kanji,
|
||||
Katakana,
|
||||
Hiragana,
|
||||
Symbol,
|
||||
Alpha,
|
||||
}
|
||||
|
||||
pub fn convert(text: &str) -> KakasiResult {
|
||||
let dict = PhfMap::new(KANJI_DICT);
|
||||
|
||||
|
@ -61,131 +46,12 @@ pub fn convert(text: &str) -> KakasiResult {
|
|||
let text = text.nfkc().collect::<String>();
|
||||
let text = convert_syn(&text);
|
||||
|
||||
let mut char_indices = text.char_indices();
|
||||
let mut kana_text = String::new();
|
||||
let mut prev_type = CharType::Kanji;
|
||||
|
||||
let mut hiragana = String::new();
|
||||
let mut romaji = String::new();
|
||||
|
||||
let conv_kana_txt = |kana_text: &mut String, hiragana: &mut String, romaji: &mut String| {
|
||||
if !kana_text.is_empty() {
|
||||
let h = convert_kana(&kana_text);
|
||||
hiragana.push_str(&h);
|
||||
romaji.push_str(&wana_kana::to_romaji::to_romaji(&h));
|
||||
romaji.push(' ');
|
||||
}
|
||||
};
|
||||
|
||||
// output_flag
|
||||
// means (output buffer?, output text[i]?, copy to buffer and increment i?)
|
||||
// possible (False, True, True), (True, False, False), (True, True, True)
|
||||
// (False, False, True)
|
||||
|
||||
while let Some((i, c)) = char_indices.next() {
|
||||
let output_flag = if ENDMARK.contains(&c) {
|
||||
(CharType::Symbol, true, true, true)
|
||||
} else if DASH_SYMBOLS.contains(&c) {
|
||||
(prev_type, false, false, true)
|
||||
} else if is_sym(c) {
|
||||
if prev_type != CharType::Symbol {
|
||||
(CharType::Symbol, true, false, true)
|
||||
} else {
|
||||
(CharType::Symbol, false, true, true)
|
||||
}
|
||||
} else if wana_kana::utils::is_char_katakana(c) {
|
||||
(
|
||||
CharType::Katakana,
|
||||
prev_type != CharType::Katakana,
|
||||
false,
|
||||
true,
|
||||
)
|
||||
} else if wana_kana::utils::is_char_hiragana(c) {
|
||||
(
|
||||
CharType::Hiragana,
|
||||
prev_type != CharType::Hiragana,
|
||||
false,
|
||||
true,
|
||||
)
|
||||
} else if c.is_ascii() {
|
||||
(CharType::Alpha, prev_type != CharType::Alpha, false, true)
|
||||
} else if wana_kana::utils::is_char_kanji(c) {
|
||||
conv_kana_txt(&mut kana_text, &mut hiragana, &mut romaji);
|
||||
let (t, n) = convert_kanji(&text[i..], &kana_text, &dict);
|
||||
|
||||
if n > 0 {
|
||||
kana_text = t;
|
||||
for _ in 1..n {
|
||||
char_indices.next();
|
||||
}
|
||||
(CharType::Kanji, false, false, false)
|
||||
} else {
|
||||
// Unknown kanji
|
||||
kana_text.clear();
|
||||
// TODO: FOR TESTING
|
||||
hiragana.push_str("🯄");
|
||||
romaji.push_str("🯄");
|
||||
(CharType::Kanji, true, false, false)
|
||||
}
|
||||
} else if matches!(c as u32, 0xf000..=0xfffd | 0x10000..=0x10ffd) {
|
||||
// PUA: ignore and drop
|
||||
conv_kana_txt(&mut kana_text, &mut hiragana, &mut romaji);
|
||||
kana_text.clear();
|
||||
(prev_type, false, false, false)
|
||||
} else {
|
||||
(prev_type, true, true, true)
|
||||
};
|
||||
|
||||
prev_type = output_flag.0;
|
||||
|
||||
if output_flag.1 && output_flag.2 {
|
||||
kana_text.push(c);
|
||||
conv_kana_txt(&mut kana_text, &mut hiragana, &mut romaji);
|
||||
kana_text.clear()
|
||||
} else if output_flag.1 && output_flag.3 {
|
||||
conv_kana_txt(&mut kana_text, &mut hiragana, &mut romaji);
|
||||
kana_text = c.to_string();
|
||||
} else if output_flag.3 {
|
||||
kana_text.push(c);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert last word
|
||||
conv_kana_txt(&mut kana_text, &mut hiragana, &mut romaji);
|
||||
// Remove trailing space
|
||||
romaji.pop();
|
||||
let hiragana = convert_kanji(&text, "", &dict).0;
|
||||
let romaji = wana_kana::to_romaji::to_romaji(&hiragana);
|
||||
|
||||
KakasiResult { hiragana, romaji }
|
||||
}
|
||||
|
||||
fn is_sym(c: char) -> bool {
|
||||
matches!(c as u32,
|
||||
0x3000..=0x3020 |
|
||||
0x3030..=0x303F |
|
||||
0x0391..=0x03A1 |
|
||||
0x03A3..=0x03A9 |
|
||||
0x03B1..=0x03C9 |
|
||||
0x0410..= 0x044F |
|
||||
0xFF01..=0xFF1A |
|
||||
0x00A1..=0x00FF |
|
||||
0xFF20..=0xFF5E |
|
||||
0x0451 |
|
||||
0x0401
|
||||
)
|
||||
}
|
||||
|
||||
fn convert_kana(text: &str) -> String {
|
||||
wana_kana::to_hiragana::to_hiragana_with_opt(
|
||||
text,
|
||||
wana_kana::Options {
|
||||
use_obsolete_kana: false,
|
||||
pass_romaji: true,
|
||||
upcase_katakana: false,
|
||||
imemode: false,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Convert the leading kanji from the input string to hiragana
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -195,7 +61,7 @@ fn convert_kana(text: &str) -> String {
|
|||
/// The input needs to be NFKC-normalized and synonymous kanji need to be
|
||||
/// replaced using [`convert_syn`].
|
||||
///
|
||||
/// * `btext` - Buffer string (leading kana)
|
||||
/// * `btext` -
|
||||
///
|
||||
/// # Return
|
||||
///
|
||||
|
@ -203,7 +69,6 @@ fn convert_kana(text: &str) -> String {
|
|||
/// * `1` - Number of converted chars from the input string
|
||||
fn convert_kanji(text: &str, btext: &str, dict: &PhfMap) -> (String, usize) {
|
||||
let mut translation = None;
|
||||
let mut i_c = 0;
|
||||
let mut n_c = 0;
|
||||
let mut char_indices = text.char_indices().peekable();
|
||||
|
||||
|
@ -222,7 +87,7 @@ fn convert_kanji(text: &str, btext: &str, dict: &PhfMap) -> (String, usize) {
|
|||
CLETTERS.get(&ch).and_then(|cltr| {
|
||||
if cltr.contains(next_c) {
|
||||
// Add the next character to the char count
|
||||
i_c += 1;
|
||||
n_c += 1;
|
||||
hira.push(*next_c);
|
||||
Some(hira)
|
||||
} else {
|
||||
|
@ -244,14 +109,11 @@ fn convert_kanji(text: &str, btext: &str, dict: &PhfMap) -> (String, usize) {
|
|||
})
|
||||
});
|
||||
|
||||
i_c += 1;
|
||||
if let Some(tl) = this_tl {
|
||||
translation = Some(tl);
|
||||
n_c = i_c;
|
||||
}
|
||||
if i_c >= MAX_KANJI_LEN {
|
||||
break;
|
||||
match this_tl {
|
||||
Some(this_tl) => translation = Some(this_tl),
|
||||
None => break,
|
||||
}
|
||||
n_c += 1;
|
||||
}
|
||||
|
||||
translation
|
||||
|
@ -303,9 +165,6 @@ mod tests {
|
|||
|
||||
#[rstest]
|
||||
#[case("会っAbc", "あっ", 2)]
|
||||
#[case("渋谷", "しぶや", 2)]
|
||||
// #[case("渋谷公会堂", "しぶやこうかいどう", 5)]
|
||||
// #[case("家畜衛生試験場", "かちくえいせいしけんじょう", 7)]
|
||||
fn t_convert_kanji(#[case] text: &str, #[case] expect: &str, #[case] expect_n: usize) {
|
||||
let dict = PhfMap::new(KANJI_DICT);
|
||||
let (res, n) = convert_kanji(text, "", &dict);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
fn main() {
|
||||
for line in std::io::stdin().lines() {
|
||||
let res = kakasi::convert(&line.unwrap());
|
||||
println!("{}\n{}\n\n", res.hiragana, res.romaji);
|
||||
println!("{} - {}", res.hiragana, res.romaji);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue