haqumei 0.6.8

Haqumei is a Japanese Grapheme-to-Phoneme (G2P) library implemented in Rust.
Documentation
use std::fs::Metadata;

use sha2::{Digest, Sha256};

use crate::NjdFeature;

/// カタカナをひらがなに変換する
pub fn kata2hira(s: &str) -> String {
    s.chars()
        .map(|c| match c {
            ''..='' | ''..='' => std::char::from_u32(c as u32 - 0x60).unwrap_or(c),
            _ => c,
        })
        .collect()
}

/// ひらがなをカタカナに変換する
pub fn hira2kata(s: &str) -> String {
    s.chars()
        .map(|c| match c {
            ''..='' | ''..='' => std::char::from_u32(c as u32 + 0x60).unwrap_or(c),
            _ => c,
        })
        .collect()
}

/// デフォルトの「pau を割り当てない記号」の判定関数。
/// 括弧類など、音声として休止を置くべきでなさそうな記号に対して `true` を返します。
#[rustfmt::skip]
pub fn default_is_non_pause_symbol(s: &str) -> bool {
    matches!(
        s,
        "" | "" | "" | "" | "" | "" | "(" | ")" |
        "" | "" | "" | "" | "[" | "]" | "" | "" |
        "" | "" | "" | "" | "" | "" | "{" | "}" |
        "\"" | "\'" | "" | "" | "" | ""
    )
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u8)]
pub(crate) enum Dan {
    ア段 = 0,
    イ段 = 1,
    ウ段 = 2,
    エ段 = 3,
    オ段 = 4,
}

#[inline]
pub(crate) const fn dan(c: char) -> Option<Dan> {
    match c {
        // ア段
        '' | '' | '' | '' | '' | '' | '' | '' | '' | '' | '' | ''
        | '' | '' | '' | '' => Some(Dan::ア段),

        // イ段
        '' | '' | '' | '' | '' | '' | '' | '' | '' | '' | '' | ''
        | '' | '' => Some(Dan::イ段),

        // ウ段
        '' | '' | '' | '' | '' | '' | '' | '' | '' | '' | '' | ''
        | '' | '' | '' | '' => Some(Dan::ウ段),

        // エ段
        '' | '' | '' | '' | '' | '' | '' | '' | '' | '' | '' | ''
        | '' | '' => Some(Dan::エ段),

        // オ段
        '' | '' | '' | '' | '' | '' | '' | '' | '' | '' | '' | ''
        | '' | '' | '' | '' => Some(Dan::オ段),

        _ => None,
    }
}

#[inline(always)]
pub(crate) fn is_kanji(c: char) -> bool {
    ('\u{4E00}'..='\u{9FFF}').contains(&c)
}

#[inline(always)]
pub(crate) fn is_kanji_feature(feaure: &NjdFeature) -> bool {
    feaure.pos != "記号" && feaure.orig.chars().any(is_kanji)
}

#[inline(always)]
pub(crate) fn is_single_kanji_feature(feaure: &NjdFeature) -> bool {
    is_kanji_feature(feaure)
        && feaure.orig.chars().count() == 1
        && is_kanji(feaure.orig.chars().next().unwrap())
}

#[inline(always)]
pub(crate) const fn is_small_kana(c: char) -> bool {
    matches!(c, '' | '' | '' | '' | '' | '' | '' | '')
}

/// 文字列をモーラ単位 (小書き文字を前の文字に結合) で分割する
#[inline(always)]
pub(crate) fn split_kana_mora(text: &str) -> Vec<String> {
    let chars: Vec<char> = text.chars().collect();
    let mut result = Vec::new();
    let mut i = 0;
    while i < chars.len() {
        let c = chars[i];
        if i + 1 < chars.len() && is_small_kana(chars[i + 1]) {
            result.push(format!("{}{}", c, chars[i + 1]));
            i += 2;
        } else {
            result.push(c.to_string());
            i += 1;
        }
    }
    result
}

/// 文字列の中に踊り字が含まれているかどうか
#[inline]
pub(crate) fn has_odori_chars(surface: &str) -> bool {
    surface
        .chars()
        .any(|c| matches!(c, '' | '' | '' | '' | ''))
}

#[inline(always)]
pub(crate) fn compute_metadata_key(meta: &Metadata) -> [u8; 32] {
    let mut hasher = Sha256::new();
    #[cfg(unix)]
    {
        use std::os::unix::fs::MetadataExt;
        hasher.update(meta.dev().to_le_bytes());
        hasher.update(meta.ino().to_le_bytes());
        hasher.update(meta.size().to_le_bytes());
        hasher.update(meta.mtime().to_le_bytes());
        hasher.update(meta.mtime_nsec().to_le_bytes());
    }

    #[cfg(windows)]
    {
        use std::os::windows::fs::MetadataExt;
        hasher.update(meta.file_size().to_le_bytes());
        hasher.update(meta.last_write_time().to_le_bytes());
        hasher.update(meta.creation_time().to_le_bytes());
        hasher.update(meta.file_attributes().to_le_bytes());
    }

    #[cfg(not(any(unix, windows)))]
    {
        use std::time::SystemTime;

        fn update_system_time(time: Result<SystemTime, std::io::Error>, hasher: &mut Sha256) {
            match time.and_then(|t| {
                t.duration_since(SystemTime::UNIX_EPOCH)
                    .map_err(|_| std::io::Error::from(std::io::ErrorKind::Other))
            }) {
                Ok(duration) => {
                    hasher.update(duration.as_secs().to_le_bytes());
                    hasher.update(duration.subsec_nanos().to_le_bytes());
                }
                Err(_) => {
                    hasher.update([0u8; 12]);
                }
            }
        }

        let file_type = meta.file_type();
        let type_byte: u8 = if file_type.is_file() {
            0x01
        } else if file_type.is_dir() {
            0x02
        } else if file_type.is_symlink() {
            0x03
        } else {
            0x00
        };
        hasher.update([type_byte]);

        let readonly_byte: u8 = if meta.permissions().readonly() {
            0x01
        } else {
            0x00
        };
        hasher.update([readonly_byte]);

        hasher.update(meta.len().to_le_bytes());

        update_system_time(meta.modified(), &mut hasher);

        update_system_time(meta.created(), &mut hasher);
    }

    hasher.finalize().into()
}

pub(crate) fn get_known_symbol_feature(c: &str) -> Option<&'static str> {
    match c {
        "£" => Some("記号,一般,*,*,*,*,£,ポンド,ポンド,1/3,*"),
        "¥" => Some("記号,一般,*,*,*,*,¥,エン,エン,1/2,*"),
        "¨" => Some("記号,一般,*,*,*,*,¨,¨,¨,*/*,*"),
        "´" => Some("記号,一般,*,*,*,*,´,´,´,*/*,*"),
        "×" => Some("記号,一般,*,*,*,*,×,カケル,カケル,2/3,*"),
        "÷" => Some("記号,一般,*,*,*,*,÷,ワル,ワル,0/2,*"),
        "Α" => Some("記号,アルファベット,*,*,*,*,Α,アルファ,アルファ,1/3,*"),
        "Β" => Some("記号,アルファベット,*,*,*,*,Β,ベータ,ベータ,1/3,*"),
        "Γ" => Some("記号,アルファベット,*,*,*,*,Γ,ガンマ,ガンマ,1/3,*"),
        "Δ" => Some("記号,アルファベット,*,*,*,*,Δ,デルタ,デルタ,1/3,*"),
        "Ε" => Some("記号,アルファベット,*,*,*,*,Ε,イプシロン,イプシロン,3/5,*"),
        "Ζ" => Some("記号,アルファベット,*,*,*,*,Ζ,ゼータ,ゼータ,1/3,*"),
        "Η" => Some("記号,アルファベット,*,*,*,*,Η,イータ,イータ,1/3,*"),
        "Θ" => Some("記号,アルファベット,*,*,*,*,Θ,シータ,シータ,1/3,*"),
        "Ι" => Some("記号,アルファベット,*,*,*,*,Ι,イオタ,イオタ,1/3,*"),
        "Κ" => Some("記号,アルファベット,*,*,*,*,Κ,カッパ,カッパ,1/3,*"),
        "Λ" => Some("記号,アルファベット,*,*,*,*,Λ,ラムダ,ラムダ,1/3,*"),
        "Μ" => Some("記号,アルファベット,*,*,*,*,Μ,ミュー,ミュー,1/2,*"),
        "Ν" => Some("記号,アルファベット,*,*,*,*,Ν,ニュー,ニュー,1/2,*"),
        "Ξ" => Some("記号,アルファベット,*,*,*,*,Ξ,クシー,クシー,1/3,*"),
        "Ο" => Some("記号,アルファベット,*,*,*,*,Ο,オミクロン,オミクロン,3/5,*"),
        "Π" => Some("記号,アルファベット,*,*,*,*,Π,パイ,パイ,1/2,*"),
        "Ρ" => Some("記号,アルファベット,*,*,*,*,Ρ,ロー,ロー,1/2,*"),
        "Σ" => Some("記号,アルファベット,*,*,*,*,Σ,シグマ,シグマ,1/3,*"),
        "Τ" => Some("記号,アルファベット,*,*,*,*,Τ,タウ,タウ,1/2,*"),
        "Υ" => Some("記号,アルファベット,*,*,*,*,Υ,ウプシロン,ウプシロン,3/5,*"),
        "Φ" => Some("記号,アルファベット,*,*,*,*,Φ,ファイ,ファイ,1/2,*"),
        "Χ" => Some("記号,アルファベット,*,*,*,*,Χ,カイ,カイ,1/2,*"),
        "Ψ" => Some("記号,アルファベット,*,*,*,*,Ψ,プサイ,プサイ,1/3,*"),
        "Ω" => Some("記号,アルファベット,*,*,*,*,Ω,オメガ,オメガ,1/3,*"),
        "α" => Some("記号,アルファベット,*,*,*,*,α,アルファ,アルファ,1/3,*"),
        "β" => Some("記号,アルファベット,*,*,*,*,β,ベータ,ベータ,1/3,*"),
        "γ" => Some("記号,アルファベット,*,*,*,*,γ,ガンマ,ガンマ,1/3,*"),
        "δ" => Some("記号,アルファベット,*,*,*,*,δ,デルタ,デルタ,1/3,*"),
        "ε" => Some("記号,アルファベット,*,*,*,*,ε,イプシロン,イプシロン,1/5,*"),
        "ζ" => Some("記号,アルファベット,*,*,*,*,ζ,ゼータ,ゼータ,1/3,*"),
        "η" => Some("記号,アルファベット,*,*,*,*,η,イータ,イータ,1/3,*"),
        "θ" => Some("記号,アルファベット,*,*,*,*,θ,シータ,シータ,1/3,*"),
        "ι" => Some("記号,アルファベット,*,*,*,*,ι,イオタ,イオタ,1/3,*"),
        "κ" => Some("記号,アルファベット,*,*,*,*,κ,カッパ,カッパ,1/3,*"),
        "λ" => Some("記号,アルファベット,*,*,*,*,λ,ラムダ,ラムダ,1/3,*"),
        "μ" => Some("記号,アルファベット,*,*,*,*,μ,ミュー,ミュー,1/2,*"),
        "ν" => Some("記号,アルファベット,*,*,*,*,ν,ニュー,ニュー,1/2,*"),
        "ξ" => Some("記号,アルファベット,*,*,*,*,ξ,クシー,クシー,1/3,*"),
        "ο" => Some("記号,アルファベット,*,*,*,*,ο,オミクロン,オミクロン,3/5,*"),
        "π" => Some("記号,アルファベット,*,*,*,*,π,パイ,パイ,1/2,*"),
        "ρ" => Some("記号,アルファベット,*,*,*,*,ρ,ロー,ロー,1/2,*"),
        "σ" => Some("記号,アルファベット,*,*,*,*,σ,シグマ,シグマ,1/3,*"),
        "τ" => Some("記号,アルファベット,*,*,*,*,τ,タウ,タウ,1/2,*"),
        "υ" => Some("記号,アルファベット,*,*,*,*,υ,ウプシロン,ウプシロン,1/5,*"),
        "φ" => Some("記号,アルファベット,*,*,*,*,φ,ファイ,ファイ,1/2,*"),
        "χ" => Some("記号,アルファベット,*,*,*,*,χ,カイ,カイ,1/2,*"),
        "ψ" => Some("記号,アルファベット,*,*,*,*,ψ,プサイ,プサイ,1/3,*"),
        "ω" => Some("記号,アルファベット,*,*,*,*,ω,オメガ,オメガ,1/3,*"),
        "" => Some("記号,一般,*,*,*,*,‐,‐,‐,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,—,—,—,*/*,*"),
        "——" => Some("記号,一般,*,*,*,*,——,——,——,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,‖,‖,‖,*/*,*"),
        "" => Some("記号,括弧開,*,*,*,*,‘,‘,‘,*/*,*"),
        "" => Some("記号,括弧閉,*,*,*,*,’,、,、,*/*,*"),
        "" => Some("記号,括弧開,*,*,*,*,“,“,“,*/*,*"),
        "" => Some("記号,括弧閉,*,*,*,*,”,”,”,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,‥,‥,‥,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,…,…,…,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,′,′,′,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,※,※,※,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,‾,‾,‾,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,←,←,←,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,↑,↑,↑,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,→,→,→,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,↓,↓,↓,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,−,−,−,*/*,*"),
        "−−" => Some("記号,一般,*,*,*,*,−−,−−,−−,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,─,─,─,*/*,*"),
        "──" => Some("記号,一般,*,*,*,*,──,──,──,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,■,■,■,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,□,□,□,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,▲,▲,▲,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,△,△,△,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,▼,▼,▼,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,▽,▽,▽,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,◆,◆,◆,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,◇,◇,◇,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,○,○,○,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,◎,◎,◎,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,●,●,●,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,★,★,★,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,☆,☆,☆,*/*,*"),
        " " => Some("記号,空白,*,*,*,*, , , ,*/*,*"),
        "" => Some("記号,読点,*,*,*,*,、,、,、,*/*,*"),
        "" => Some("記号,句点,*,*,*,*,。,。,。,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,〃,〃,〃,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,々,々,々,*/*,*"),
        "々々" => Some("記号,一般,*,*,*,*,々々,々々,々々,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,シメ,シメ,シメ,2/2,*"),
        "" => Some("記号,一般,*,*,*,*,〇,〇,〇,*/*,*"),
        "" => Some("記号,括弧開,*,*,*,*,〈,〈,〈,*/*,*"),
        "" => Some("記号,括弧閉,*,*,*,*,〉,〉,〉,*/*,*"),
        "" => Some("記号,括弧開,*,*,*,*,《,《,《,*/*,*"),
        "" => Some("記号,括弧閉,*,*,*,*,》,》,》,*/*,*"),
        "" => Some("記号,括弧開,*,*,*,*,「,「,「,*/*,*"),
        "" => Some("記号,括弧閉,*,*,*,*,」,」,」,*/*,*"),
        "" => Some("記号,括弧開,*,*,*,*,『,『,『,*/*,*"),
        "" => Some("記号,括弧閉,*,*,*,*,』,』,』,*/*,*"),
        "" => Some("記号,括弧開,*,*,*,*,【,【,【,*/*,*"),
        "" => Some("記号,括弧閉,*,*,*,*,】,】,】,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,〒,ユウビンバンゴウ,ユービンバンゴー,5/8,*"),
        "" => Some("記号,一般,*,*,*,*,〓,〓,〓,*/*,*"),
        "" => Some("記号,括弧開,*,*,*,*,〔,〔,〔,*/*,*"),
        "" => Some("記号,括弧閉,*,*,*,*,〕,〕,〕,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,〜,〜,〜,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,゛,゛,゛,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,゜,゜,゜,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,ゝ,ゝ,ゝ,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,ゞ,ゞ,ゞ,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,ノ,ノ,ノ,1/1,*"),
        "" => Some("記号,一般,*,*,*,*,・,・,・,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,ヽ,ヽ,ヽ,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,ヾ,ヾ,ヾ,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,シメ,シメ,シメ,2/2,*"),
        "" => Some("記号,一般,*,*,*,*,仝,仝,仝,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,!,!,!,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,#,#,#,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,$,$,$,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,%,%,%,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,&,アンド,アンド,0/3,*"),
        "" => Some("記号,括弧開,*,*,*,*,(,(,(,*/*,*"),
        "" => Some("記号,括弧閉,*,*,*,*,),),),*/*,*"),
        "" => Some("記号,一般,*,*,*,*,*,*,*,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,+,タス,タス,1/2,*"),
        "" => Some("記号,読点,*,*,*,*,,,,,,,*/*,*"),
        "" => Some("記号,句点,*,*,*,*,.,.,.,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,/,/,/,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,:,:,:,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,;,;,;,*/*,*"),
        "" => Some("記号,括弧開,*,*,*,*,<,<,<,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,=,=,=,*/*,*"),
        "" => Some("記号,括弧閉,*,*,*,*,>,>,>,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,?,?,?,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,@,アット,アット,1/3,*"),
        "" => Some("記号,アルファベット,*,*,*,*,A,エイ,エイ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,B,ビー,ビー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,C,シー,シー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,D,ディー,ディー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,E,イー,イー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,F,エフ,エフ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,G,ジー,ジー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,H,エイチ,エイチ,1/3,*"),
        "" => Some("記号,アルファベット,*,*,*,*,I,アイ,アイ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,J,ジェイ,ジェイ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,K,ケイ,ケイ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,L,エル,エル,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,M,エム,エム,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,N,エヌ,エヌ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,O,オー,オー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,P,ピー,ピー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,Q,キュー,キュー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,R,アール,アール,1/3,*"),
        "" => Some("記号,アルファベット,*,*,*,*,S,エス,エス,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,T,ティー,ティー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,U,ユー,ユー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,V,ブイ,ブイ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,W,ダブリュー,ダブリュー,1/4,*"),
        "" => Some("記号,アルファベット,*,*,*,*,X,エックス,エックス,1/4,*"),
        "" => Some("記号,アルファベット,*,*,*,*,Y,ワイ,ワイ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,Z,ゼット,ゼット,1/3,*"),
        "" => Some("記号,括弧開,*,*,*,*,[,[,[,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,\,\,\,*/*,*"),
        "" => Some("記号,括弧閉,*,*,*,*,],],],*/*,*"),
        "" => Some("記号,一般,*,*,*,*,^,^,^,*/*,*"),
        "_" => Some("記号,一般,*,*,*,*,_,_,_,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,`,`,`,*/*,*"),
        "" => Some("記号,アルファベット,*,*,*,*,a,エイ,エイ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,b,ビー,ビー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,c,シー,シー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,d,ディー,ディー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,e,イー,イー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,f,エフ,エフ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,g,ジー,ジー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,h,エイチ,エイチ,1/3,*"),
        "" => Some("記号,アルファベット,*,*,*,*,i,アイ,アイ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,j,ジェイ,ジェイ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,k,ケイ,ケイ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,l,エル,エル,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,m,エム,エム,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,n,エヌ,エヌ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,o,オー,オー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,p,ピー,ピー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,q,キュー,キュー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,r,アール,アール,1/3,*"),
        "" => Some("記号,アルファベット,*,*,*,*,s,エス,エス,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,t,ティー,ティー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,u,ユー,ユー,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,v,ブイ,ブイ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,w,ダブリュー,ダブリュー,1/4,*"),
        "" => Some("記号,アルファベット,*,*,*,*,x,エックス,エックス,1/4,*"),
        "" => Some("記号,アルファベット,*,*,*,*,y,ワイ,ワイ,1/2,*"),
        "" => Some("記号,アルファベット,*,*,*,*,z,ゼット,ゼット,1/3,*"),
        "" => Some("記号,括弧開,*,*,*,*,{,{,{,*/*,*"),
        "" => Some("記号,一般,*,*,*,*,|,|,|,*/*,*"),
        "" => Some("記号,括弧閉,*,*,*,*,},},},*/*,*"),
        "" => Some("記号,一般,*,*,*,*,¥,エン,エン,1/2,*"),
        _ => None,
    }
}