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 入出力
|
にゅうしゅつりょく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 phfbin_gen;
|
||||||
mod testconv;
|
|
||||||
|
|
||||||
use std::{borrow::Cow, collections::HashMap, path::Path};
|
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))
|
.or_else(|| context.map(str::to_owned))
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
) {
|
) {
|
||||||
std::collections::hash_map::Entry::Occupied(_) => {
|
std::collections::hash_map::Entry::Occupied(mut e) => {
|
||||||
/*
|
// Replace reading if the new one is longer
|
||||||
// Replace reading if the new one is shorter
|
|
||||||
let val = e.get_mut();
|
let val = e.get_mut();
|
||||||
if val.len() > reading.len() {
|
if val.len() < reading.len() {
|
||||||
*val = reading.to_owned();
|
*val = reading.to_owned();
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
std::collections::hash_map::Entry::Vacant(e) => {
|
std::collections::hash_map::Entry::Vacant(e) => {
|
||||||
e.insert(reading.to_owned());
|
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> {
|
fn generate_kanji_dict() -> Vec<u8> {
|
||||||
let mut records = Records::default();
|
let mut records = Records::default();
|
||||||
parse_dict(&mut records, Path::new("dict/kakasidict.utf8"));
|
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();
|
let mut phfmap = phfbin_gen::Map::<KanjiString, Readings>::default();
|
||||||
for (kanji, readings) in records {
|
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};
|
use types::{KanjiString, Readings};
|
||||||
|
|
||||||
const KANJI_DICT: &[u8] = include_bytes!("./kanji_dict.bin");
|
const KANJI_DICT: &[u8] = include_bytes!("./kanji_dict.bin");
|
||||||
const MAX_KANJI_LEN: usize = 7;
|
|
||||||
|
|
||||||
static CLETTERS: phf::Map<u8, &[char]> = phf::phf_map!(
|
static CLETTERS: phf::Map<u8, &[char]> = phf::phf_map!(
|
||||||
b'a' => &['あ', 'ぁ', 'っ', 'わ', 'ゎ'],
|
b'a' => &['あ', 'ぁ', 'っ', 'わ', 'ゎ'],
|
||||||
|
@ -40,20 +39,6 @@ static CLETTERS: phf::Map<u8, &[char]> = phf::phf_map!(
|
||||||
b'v' => &['ゔ'],
|
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 {
|
pub fn convert(text: &str) -> KakasiResult {
|
||||||
let dict = PhfMap::new(KANJI_DICT);
|
let dict = PhfMap::new(KANJI_DICT);
|
||||||
|
|
||||||
|
@ -61,131 +46,12 @@ pub fn convert(text: &str) -> KakasiResult {
|
||||||
let text = text.nfkc().collect::<String>();
|
let text = text.nfkc().collect::<String>();
|
||||||
let text = convert_syn(&text);
|
let text = convert_syn(&text);
|
||||||
|
|
||||||
let mut char_indices = text.char_indices();
|
let hiragana = convert_kanji(&text, "", &dict).0;
|
||||||
let mut kana_text = String::new();
|
let romaji = wana_kana::to_romaji::to_romaji(&hiragana);
|
||||||
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();
|
|
||||||
|
|
||||||
KakasiResult { hiragana, romaji }
|
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
|
/// Convert the leading kanji from the input string to hiragana
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
@ -195,7 +61,7 @@ fn convert_kana(text: &str) -> String {
|
||||||
/// The input needs to be NFKC-normalized and synonymous kanji need to be
|
/// The input needs to be NFKC-normalized and synonymous kanji need to be
|
||||||
/// replaced using [`convert_syn`].
|
/// replaced using [`convert_syn`].
|
||||||
///
|
///
|
||||||
/// * `btext` - Buffer string (leading kana)
|
/// * `btext` -
|
||||||
///
|
///
|
||||||
/// # Return
|
/// # Return
|
||||||
///
|
///
|
||||||
|
@ -203,7 +69,6 @@ fn convert_kana(text: &str) -> String {
|
||||||
/// * `1` - Number of converted chars from the input string
|
/// * `1` - Number of converted chars from the input string
|
||||||
fn convert_kanji(text: &str, btext: &str, dict: &PhfMap) -> (String, usize) {
|
fn convert_kanji(text: &str, btext: &str, dict: &PhfMap) -> (String, usize) {
|
||||||
let mut translation = None;
|
let mut translation = None;
|
||||||
let mut i_c = 0;
|
|
||||||
let mut n_c = 0;
|
let mut n_c = 0;
|
||||||
let mut char_indices = text.char_indices().peekable();
|
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| {
|
CLETTERS.get(&ch).and_then(|cltr| {
|
||||||
if cltr.contains(next_c) {
|
if cltr.contains(next_c) {
|
||||||
// Add the next character to the char count
|
// Add the next character to the char count
|
||||||
i_c += 1;
|
n_c += 1;
|
||||||
hira.push(*next_c);
|
hira.push(*next_c);
|
||||||
Some(hira)
|
Some(hira)
|
||||||
} else {
|
} else {
|
||||||
|
@ -244,14 +109,11 @@ fn convert_kanji(text: &str, btext: &str, dict: &PhfMap) -> (String, usize) {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
i_c += 1;
|
match this_tl {
|
||||||
if let Some(tl) = this_tl {
|
Some(this_tl) => translation = Some(this_tl),
|
||||||
translation = Some(tl);
|
None => break,
|
||||||
n_c = i_c;
|
|
||||||
}
|
|
||||||
if i_c >= MAX_KANJI_LEN {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
n_c += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
translation
|
translation
|
||||||
|
@ -303,9 +165,6 @@ mod tests {
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
#[case("会っAbc", "あっ", 2)]
|
#[case("会っAbc", "あっ", 2)]
|
||||||
#[case("渋谷", "しぶや", 2)]
|
|
||||||
// #[case("渋谷公会堂", "しぶやこうかいどう", 5)]
|
|
||||||
// #[case("家畜衛生試験場", "かちくえいせいしけんじょう", 7)]
|
|
||||||
fn t_convert_kanji(#[case] text: &str, #[case] expect: &str, #[case] expect_n: usize) {
|
fn t_convert_kanji(#[case] text: &str, #[case] expect: &str, #[case] expect_n: usize) {
|
||||||
let dict = PhfMap::new(KANJI_DICT);
|
let dict = PhfMap::new(KANJI_DICT);
|
||||||
let (res, n) = convert_kanji(text, "", &dict);
|
let (res, n) = convert_kanji(text, "", &dict);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
for line in std::io::stdin().lines() {
|
for line in std::io::stdin().lines() {
|
||||||
let res = kakasi::convert(&line.unwrap());
|
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