Implement kyujitai
This commit is contained in:
parent
ccba51e277
commit
3b7e03874f
4 changed files with 431 additions and 13 deletions
|
@ -4,6 +4,8 @@ use std::str::FromStr;
|
|||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde_yaml::Value;
|
||||
|
||||
use crate::kyujitai::{Kyujitai, self};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Challenge {
|
||||
pub japanese: Vec<Vec<Vec<ChallengeWord>>>,
|
||||
|
@ -44,23 +46,23 @@ impl<'de> Deserialize<'de> for ChallengeWord {
|
|||
));
|
||||
};
|
||||
let text = map.get("text").map(|value| match value {
|
||||
Value::String(string) => vec![Furigana {
|
||||
kanji: string.clone(),
|
||||
furigana: None,
|
||||
}],
|
||||
Value::String(string) => vec![Furigana::new(
|
||||
string.clone(),
|
||||
None,
|
||||
)],
|
||||
Value::Sequence(sequence) => sequence
|
||||
.iter()
|
||||
.map(|value| match value {
|
||||
Value::String(kanji) => Furigana {
|
||||
kanji: kanji.to_owned(),
|
||||
furigana: None,
|
||||
},
|
||||
Value::String(kanji) => Furigana::new(
|
||||
kanji.to_owned(),
|
||||
None,
|
||||
),
|
||||
Value::Mapping(mapping) => {
|
||||
let (kanji, furigana) = mapping.iter().next().unwrap();
|
||||
Furigana {
|
||||
kanji: kanji.as_str().unwrap().to_owned(),
|
||||
furigana: Some(furigana.as_str().unwrap().to_owned()),
|
||||
}
|
||||
Furigana::new(
|
||||
kanji.as_str().unwrap().to_owned(),
|
||||
Some(furigana.as_str().unwrap().to_owned())
|
||||
)
|
||||
}
|
||||
_ => panic!(),
|
||||
})
|
||||
|
@ -122,9 +124,23 @@ impl FromStr for PartOfSpeech {
|
|||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Furigana {
|
||||
pub kanji: String,
|
||||
pub kyujitai: Option<String>,
|
||||
pub furigana: Option<String>,
|
||||
}
|
||||
|
||||
impl Furigana {
|
||||
fn new(kanji: String, furigana: Option<String>) -> Self {
|
||||
Self {
|
||||
kyujitai: match kanji.to_kyujitai() {
|
||||
kyujitai if kyujitai.eq(&kanji) => None,
|
||||
kyujitai => Some(kyujitai),
|
||||
},
|
||||
kanji,
|
||||
furigana,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Translation {
|
||||
pub author: Option<String>,
|
||||
|
|
387
src/kyujitai.rs
Normal file
387
src/kyujitai.rs
Normal file
|
@ -0,0 +1,387 @@
|
|||
const KYUJITAI: &[(char, char)] = &[
|
||||
('万', '萬'),
|
||||
('与', '與'),
|
||||
('両', '兩'),
|
||||
('並', '竝'),
|
||||
('乗', '乘'),
|
||||
('乱', '亂'),
|
||||
('争', '爭'),
|
||||
('亜', '亞'),
|
||||
('仏', '佛'),
|
||||
('仮', '假'),
|
||||
('会', '會'),
|
||||
('伝', '傳'),
|
||||
('余', '餘'),
|
||||
('体', '體'),
|
||||
('価', '價'),
|
||||
('併', '倂'),
|
||||
('倹', '儉'),
|
||||
('偽', '僞'),
|
||||
('児', '兒'),
|
||||
('党', '黨'),
|
||||
('内', '內'),
|
||||
('円', '圓'),
|
||||
('冊', '册'),
|
||||
('写', '寫'),
|
||||
('冴', '冱'),
|
||||
('処', '處'),
|
||||
('剣', '劍'),
|
||||
('剤', '劑'),
|
||||
('剰', '剩'),
|
||||
('励', '勵'),
|
||||
('労', '勞'),
|
||||
('効', '效'),
|
||||
('勅', '敕'),
|
||||
('勧', '勸'),
|
||||
('勲', '勳'),
|
||||
('区', '區'),
|
||||
('医', '醫'),
|
||||
('即', '卽'),
|
||||
('巻', '卷'),
|
||||
('参', '參'),
|
||||
('収', '收'),
|
||||
('双', '雙'),
|
||||
('叙', '敍'),
|
||||
('号', '號'),
|
||||
('台', '臺'),
|
||||
('嘱', '囑'),
|
||||
('団', '團'),
|
||||
('囲', '圍'),
|
||||
('図', '圖'),
|
||||
('国', '國'),
|
||||
('圏', '圈'),
|
||||
('圧', '壓'),
|
||||
('尭', '堯'),
|
||||
('堕', '墮'),
|
||||
('塁', '壘'),
|
||||
('塩', '鹽'),
|
||||
('増', '增'),
|
||||
('壊', '壞'),
|
||||
('壌', '壤'),
|
||||
('壮', '壯'),
|
||||
('壱', '壹'),
|
||||
('売', '賣'),
|
||||
('声', '聲'),
|
||||
('変', '變'),
|
||||
('奥', '奧'),
|
||||
('奨', '奬'),
|
||||
('姫', '姬'),
|
||||
('婿', '壻'),
|
||||
('嬢', '孃'),
|
||||
('学', '學'),
|
||||
('実', '實'),
|
||||
('宝', '寶'),
|
||||
('寛', '寬'),
|
||||
('寝', '寢'),
|
||||
('寿', '壽'),
|
||||
('対', '對'),
|
||||
('専', '專'),
|
||||
('将', '將'),
|
||||
('当', '當'),
|
||||
('尚', '尙'),
|
||||
('単', '單'),
|
||||
('巣', '巢'),
|
||||
('営', '營'),
|
||||
('厳', '嚴'),
|
||||
('尽', '盡'),
|
||||
('届', '屆'),
|
||||
('属', '屬'),
|
||||
('岳', '嶽'),
|
||||
('峡', '峽'),
|
||||
('巌', '巖'),
|
||||
('帯', '帶'),
|
||||
('帰', '歸'),
|
||||
('広', '廣'),
|
||||
('庁', '廳'),
|
||||
('廃', '廢'),
|
||||
('弐', '貳'),
|
||||
('弥', '彌'),
|
||||
('弾', '彈'),
|
||||
('彦', '彥'),
|
||||
('径', '徑'),
|
||||
('従', '從'),
|
||||
('徴', '徵'),
|
||||
('徳', '德'),
|
||||
('応', '應'),
|
||||
('恒', '恆'),
|
||||
('恵', '惠'),
|
||||
('悩', '惱'),
|
||||
('恋', '戀'),
|
||||
('悪', '惡'),
|
||||
('悦', '悅'),
|
||||
('惨', '慘'),
|
||||
('慎', '愼'),
|
||||
('懐', '懷'),
|
||||
('戦', '戰'),
|
||||
('戯', '戲'),
|
||||
('戸', '戶'),
|
||||
('戻', '戾'),
|
||||
('払', '拂'),
|
||||
('抜', '拔'),
|
||||
('択', '擇'),
|
||||
('拝', '拜'),
|
||||
('担', '擔'),
|
||||
('拠', '據'),
|
||||
('拡', '擴'),
|
||||
('挟', '挾'),
|
||||
('挿', '插'),
|
||||
('捜', '搜'),
|
||||
('挙', '擧'),
|
||||
('掲', '揭'),
|
||||
('揺', '搖'),
|
||||
('摂', '攝'),
|
||||
('撃', '擊'),
|
||||
('教', '敎'),
|
||||
('数', '數'),
|
||||
('断', '斷'),
|
||||
('旧', '舊'),
|
||||
('昼', '晝'),
|
||||
('晋', '晉'),
|
||||
('晩', '晚'),
|
||||
('暁', '曉'),
|
||||
('暦', '曆'),
|
||||
('来', '來'),
|
||||
('条', '條'),
|
||||
('枢', '樞'),
|
||||
('栄', '榮'),
|
||||
('桟', '棧'),
|
||||
('桜', '櫻'),
|
||||
('検', '檢'),
|
||||
('楽', '樂'),
|
||||
('楼', '樓'),
|
||||
('槙', '槇'),
|
||||
('様', '樣'),
|
||||
('概', '槪'),
|
||||
('横', '橫'),
|
||||
('権', '權'),
|
||||
('欠', '缺'),
|
||||
('欧', '歐'),
|
||||
('歓', '歡'),
|
||||
('歩', '步'),
|
||||
('歴', '歷'),
|
||||
('残', '殘'),
|
||||
('殴', '毆'),
|
||||
('殻', '殼'),
|
||||
('毎', '每'),
|
||||
('気', '氣'),
|
||||
('没', '沒'),
|
||||
('沢', '澤'),
|
||||
('浄', '淨'),
|
||||
('浅', '淺'),
|
||||
('涙', '淚'),
|
||||
('浜', '濱'),
|
||||
('渉', '涉'),
|
||||
('渇', '渴'),
|
||||
('渓', '溪'),
|
||||
('渋', '澁'),
|
||||
('済', '濟'),
|
||||
('清', '淸'),
|
||||
('温', '溫'),
|
||||
('満', '滿'),
|
||||
('湿', '濕'),
|
||||
('湾', '灣'),
|
||||
('滞', '滯'),
|
||||
('滝', '瀧'),
|
||||
('潜', '潛'),
|
||||
('瀬', '瀨'),
|
||||
('灯', '燈'),
|
||||
('炉', '爐'),
|
||||
('為', '爲'),
|
||||
('点', '點'),
|
||||
('焼', '燒'),
|
||||
('犠', '犧'),
|
||||
('状', '狀'),
|
||||
('狭', '狹'),
|
||||
('独', '獨'),
|
||||
('猟', '獵'),
|
||||
('献', '獻'),
|
||||
('獣', '獸'),
|
||||
('瑶', '瑤'),
|
||||
('瓶', '甁'),
|
||||
('産', '產'),
|
||||
('画', '畫'),
|
||||
('畳', '疊'),
|
||||
('痴', '癡'),
|
||||
('発', '發'),
|
||||
('盗', '盜'),
|
||||
('県', '縣'),
|
||||
('真', '眞'),
|
||||
('研', '硏'),
|
||||
('砕', '碎'),
|
||||
('礼', '禮'),
|
||||
('禄', '祿'),
|
||||
('禅', '禪'),
|
||||
('秘', '祕'),
|
||||
('称', '稱'),
|
||||
('税', '稅'),
|
||||
('稲', '稻'),
|
||||
('穂', '穗'),
|
||||
('穏', '穩'),
|
||||
('穣', '穰'),
|
||||
('窃', '竊'),
|
||||
('粋', '粹'),
|
||||
('糸', '絲'),
|
||||
('経', '經'),
|
||||
('絵', '繪'),
|
||||
('続', '續'),
|
||||
('継', '繼'),
|
||||
('緒', '緖'),
|
||||
('緑', '綠'),
|
||||
('総', '總'),
|
||||
('縄', '繩'),
|
||||
('縁', '緣'),
|
||||
('縦', '縱'),
|
||||
('繊', '纖'),
|
||||
('缶', '罐'),
|
||||
('聡', '聰'),
|
||||
('聴', '聽'),
|
||||
('粛', '肅'),
|
||||
('胆', '膽'),
|
||||
('脱', '脫'),
|
||||
('脳', '腦'),
|
||||
('臓', '臟'),
|
||||
('舎', '舍'),
|
||||
('舗', '舖'),
|
||||
('艶', '艷'),
|
||||
('芸', '藝'),
|
||||
('茎', '莖'),
|
||||
('荘', '莊'),
|
||||
('蔵', '藏'),
|
||||
('薫', '薰'),
|
||||
('薬', '藥'),
|
||||
('虚', '虛'),
|
||||
('虫', '蟲'),
|
||||
('蚕', '蠶'),
|
||||
('蛍', '螢'),
|
||||
('蛮', '蠻'),
|
||||
('衛', '衞'),
|
||||
('装', '裝'),
|
||||
('褒', '襃'),
|
||||
('覇', '霸'),
|
||||
('覚', '覺'),
|
||||
('覧', '覽'),
|
||||
('観', '觀'),
|
||||
('触', '觸'),
|
||||
('訳', '譯'),
|
||||
('証', '證'),
|
||||
('誉', '譽'),
|
||||
('読', '讀'),
|
||||
('謡', '謠'),
|
||||
('譲', '讓'),
|
||||
('豊', '豐'),
|
||||
('賛', '贊'),
|
||||
('践', '踐'),
|
||||
('転', '轉'),
|
||||
('軽', '輕'),
|
||||
('辞', '辭'),
|
||||
('辺', '邊'),
|
||||
('逓', '遞'),
|
||||
('遥', '遙'),
|
||||
('遅', '遲'),
|
||||
('郎', '郞'),
|
||||
('郷', '鄕'),
|
||||
('酔', '醉'),
|
||||
('醸', '釀'),
|
||||
('釈', '釋'),
|
||||
('鉄', '鐵'),
|
||||
('鉱', '鑛'),
|
||||
('銭', '錢'),
|
||||
('鋭', '銳'),
|
||||
('鋳', '鑄'),
|
||||
('錬', '鍊'),
|
||||
('録', '錄'),
|
||||
('鎮', '鎭'),
|
||||
('関', '關'),
|
||||
('闘', '鬪'),
|
||||
('陥', '陷'),
|
||||
('険', '險'),
|
||||
('随', '隨'),
|
||||
('隠', '隱'),
|
||||
('隣', '鄰'),
|
||||
('隷', '隸'),
|
||||
('雑', '雜'),
|
||||
('霊', '靈'),
|
||||
('青', '靑'),
|
||||
('静', '靜'),
|
||||
('頼', '賴'),
|
||||
('顔', '顏'),
|
||||
('顕', '顯'),
|
||||
('飲', '飮'),
|
||||
('餅', '餠'),
|
||||
('駅', '驛'),
|
||||
('駆', '驅'),
|
||||
('騒', '騷'),
|
||||
('験', '驗'),
|
||||
('髄', '髓'),
|
||||
('髪', '髮'),
|
||||
('竜', '龍'),
|
||||
('鶏', '鷄'),
|
||||
('麦', '麥'),
|
||||
('黄', '黃'),
|
||||
('黒', '黑'),
|
||||
('黙', '默'),
|
||||
('斉', '齊'),
|
||||
('斎', '齋'),
|
||||
('歯', '齒'),
|
||||
('齢', '齡'),
|
||||
('亀', '龜'),
|
||||
('告', '吿'),
|
||||
('屡', '屢'),
|
||||
('湾', '灣'),
|
||||
('亘', '亙'),
|
||||
('凜', '凛'),
|
||||
('刃', '刄'),
|
||||
('呉', '吳'),
|
||||
('回', '囘'),
|
||||
('妊', '姙'),
|
||||
('娯', '娛'),
|
||||
('強', '强'),
|
||||
('携', '攜'),
|
||||
('曽', '曾'),
|
||||
('歳', '歲'),
|
||||
('粘', '黏'),
|
||||
('糾', '糺'),
|
||||
('絶', '絕'),
|
||||
('萌', '萠'),
|
||||
('説', '說'),
|
||||
('祷', '禱'),
|
||||
('鎌', '鐮'),
|
||||
('閲', '閱'),
|
||||
('麺', '麵'),
|
||||
('祢', '禰'),
|
||||
];
|
||||
|
||||
pub trait Kyujitai {
|
||||
fn to_kyujitai(&self) -> String;
|
||||
fn to_shinjitai(&self) -> String;
|
||||
}
|
||||
|
||||
impl Kyujitai for String {
|
||||
fn to_kyujitai(&self) -> String {
|
||||
let mut output = String::with_capacity(self.len());
|
||||
'outer: for shinjitai in self.chars() {
|
||||
for (other_shinjitai, kyujitai) in KYUJITAI {
|
||||
if shinjitai == *other_shinjitai {
|
||||
output.push(kyujitai.clone());
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
output.push(shinjitai.clone());
|
||||
}
|
||||
output
|
||||
}
|
||||
|
||||
fn to_shinjitai(&self) -> String {
|
||||
let mut output = String::with_capacity(self.len());
|
||||
'outer: for kyujitai in self.chars() {
|
||||
for (shinjitai, other_kyujitai) in KYUJITAI {
|
||||
if kyujitai == *other_kyujitai {
|
||||
output.push(shinjitai.clone());
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
output.push(kyujitai.clone());
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
|
@ -10,6 +10,8 @@ use sass_rocket_fairing::SassFairing;
|
|||
mod challenge;
|
||||
use challenge::Challenge;
|
||||
|
||||
mod kyujitai;
|
||||
|
||||
#[get("/<challenge>")]
|
||||
fn get_challenge(challenge: u32) -> Template {
|
||||
Template::render(
|
||||
|
|
|
@ -9,6 +9,18 @@
|
|||
<a href="/{{ challenge - 1 }}">Previous</a>
|
||||
<a href="/{{ challenge + 1 }}">Next</a>
|
||||
<div lang="ja">
|
||||
<script>
|
||||
let kyujitai = false;
|
||||
function kyujitaiToggle() {
|
||||
document.querySelectorAll("[data-kyujitai]").forEach(segment => {
|
||||
let newText = segment.getAttribute("data-kyujitai");
|
||||
segment.setAttribute("data-kyujitai", segment.firstChild.data);
|
||||
segment.firstChild.data = newText;
|
||||
})
|
||||
kyujitai = !kyujitai;
|
||||
}
|
||||
</script>
|
||||
<button onclick="kyujitaiToggle(); this.innerHTML = kyujitai ? '新字体' : '旧字体'"">旧字体</button>
|
||||
{% for line in content.japanese %}
|
||||
{% for subline in line %}
|
||||
<p>
|
||||
|
@ -17,7 +29,8 @@
|
|||
<a href="{{ word.dictionary }}" target="_blank"{% if word.pos %} class="{{ word.pos }}" title="{{ word.pos }}"{% endif %}>
|
||||
{% endif %}
|
||||
{% for segment in word.text %}
|
||||
<ruby>{{ segment.kanji }}<rp>(</rp><rt>{{ segment.furigana | safe }}</rt><rp>)</rp></ruby>
|
||||
<!-- TODO: Don't use ruby for all segments -->
|
||||
<ruby{% if segment.kyujitai %} data-kyujitai="{{ segment.kyujitai }}"{% endif %}>{{ segment.kanji }}<rp>(</rp><rt>{{ segment.furigana | safe }}</rt><rp>)</rp></ruby>
|
||||
{% endfor %}
|
||||
{% if word.dictionary %}
|
||||
</a>
|
||||
|
|
Loading…
Add table
Reference in a new issue