👻

【マッピング】半角カナ返還をリアルタイムで行う入力欄の作成【死闘】

に公開

死闘

onChangeイベント使うと単純なマッピングだと濁点半濁点などで失敗する
ひらがな、英字どっちで入力してもローマ字入力をすべて半角カナに変換するマッピングをすべて書くやり方で実装

実装(途中)

"use client";
import React, { useState } from "react";
import { TextField } from "@mui/material";
import { HighQualityOutlined } from "@mui/icons-material";

const RomajiToHankanaConverter = () => {
  const [input, setInput] = useState("");
  const [output, setOutput] = useState("");

  const romajiToHankana = (str) => {
    let romajiMap = {
      //   1. 1文字での入力
      a: "ア",
      i: "イ",
      u: "ウ",
      e: "エ",
      o: "オ",
      ka: "カ",
      ki: "キ",
      ku: "ク",
      ke: "ケ",
      ko: "コ",
      sa: "サ",
      shi: "シ",
      su: "ス",
      se: "セ",
      so: "ソ",
      ta: "タ",
      chi: "チ",
      tsu: "ツ",
      te: "テ",
      to: "ト",
      na: "ナ",
      ni: "ニ",
      nu: "ヌ",
      ne: "ネ",
      no: "ノ",
      ha: "ハ",
      hi: "ヒ",
      fu: "フ",
      he: "ヘ",
      ho: "ホ",
      ma: "マ",
      mi: "ミ",
      mu: "ム",
      me: "メ",
      mo: "モ",
      ya: "ヤ",
      yu: "ユ",
      yo: "ヨ",
      ra: "ラ",
      ri: "リ",
      ru: "ル",
      re: "レ",
      ro: "ロ",
      wa: "ワ",
      wo: "ヲ",
      nn: "ン",
      //2. 特殊な英字入力空の変換
      //ga done
      ga: "ガ",
      kka: "ッカ",
      gga: "ッガ",
      kya: "キャ",
      gya: "ギャ",
      kkya: "ッキャ",
      ggya: "ッギャ",
      gi: "ギ",
      kki: "ッキ",
      ggi: "ッギ",
      gu: "グ",
      kku: "ック",
      ggu: "ッグ",
      kkyu: "ッキュ",
      ggyu: "ッギュ",
      ge: "ゲ",
      kke: "ッケ",
      gge: "ッゲ",
      go: "ゴ",
      kko: "ッコ",
      ggo: "ッゴ",
      kyo: "キョ",
      gyo: "ギョ",
      kkyo: "ッキョ",
      ggyo: "ッギョ",
      //   za : doing(testする)
      za: "ザ",
      zi: "ジ",
      zu: "ズ",
      ze: "ゼ",
      zo: "ゾ",
      ssa: "ッサ",
      ssi: "ッシ",
      ssu: "ッス",
      sse: "ッセ",
      sso: "ッソ",
      zza: "ッザ",
      zzi: "ッジ",
      zzu: "ッズ",
      zze: "ッゼ",
      zzo: "ッゾ",
      sha: "シャ",
      shi: "シ",
      shu: "シュ",
      she: "シェ",
      sho: "ショ",
      sya: "シャ",
      syi: "シィ",
      syu: "シュ",
      sye: "シェ",
      syo: "ショ",
      ssha: "ッシャ",
      sshi: "ッシ",
      sshu: "ッシュ",
      sshe: "ッシェ",
      ssho: "ッショ",
      ssya: "ッシャ",
      ssyi: "ッシィ",
      ssyu: "ッシュ",
      ssye: "ッシェ",
      ssyo: "ッショ",
      ja: "ジャ",
      ji: "ジ",
      ju: "ジュ",
      je: "ジェ",
      jo: "ジョ",
      jja: "ッジャ",
      jji: "ッジ",
      jju: "ッジュ",
      jje: "ッジェ",
      jjo: "ッジョ",
      // da: doing
      da: "ダ",
      di: "ヂ",
      du: "ヅ",
      de: "デ",
      do: "ド",
      tta: "ッタ",
      tti: "ッチ",
      ttu: "ッツ",
      tte: "ッテ",
      tto: "ット",
      dda: "ッダ",
      ddi: "ッヂ",
      ddu: "ッヅ",
      dde: "ッデ",
      ddo: "ッド",

      tya: "チャ",
      tyi: "チィ",
      tyu: "チュ",
      tye: "チェ",
      tyo: "チョ",

      tha: "テャ",
      thi: "ティ",
      thu: "テュ",
      the: "テェ",
      tho: "テョ",

      cha: "チャ",
      chi: "チ",
      chu: "チュ",
      che: "チェ",
      cho: "チョ",
      cya: "チャ",
      cyi: "チィ",
      cyu: "チュ",
      cye: "チェ",
      cyo: "チョ",
      dya: "ヂャ",
      dyi: "ヂイ",
      dyu: "ヂュ",
      dye: "ヂェ",
      dyo: "ヂョ",
      dha: "デャ",
      dhi: "ディ",
      dhu: "デュ",
      dhe: "デェ",
      dho: "デョ",
      ddya: "ッヂャ",
      ddyi: "ッヂイ",
      ddyu: "ッヂュ",
      ddye: "ッヂェ",
      ddyo: "ッヂョ",
      // na
      nya: "ニャ",
      nyu: "ニュ",
      nyo: "ニョ",
      //ha
      hya: "ヒャ",
      hyi: "ヒィ",
      hyu: "ヒュ",
      hye: "ヒェ",
      hyo: "ヒョ",
      hha: "ッハ",
      hhi: "ッヒ",
      hhu: "ッフ",
      hhe: "ッヘ",
      hho: "ッホ",
      hhya: "ッヒャ",
      hhyi: "ッヒィ",
      hhyu: "ッヒュ",
      hhye: "ッヒェ",
      hhyo: "ッヒョ",

      // pa
      pa: "パ",
      pi: "ピ",
      pu: "プ",
      pe: "ペ",
      po: "ポ",
      pya: "ピャ",
      pyi: "ピィ",
      pyu: "ピュ",
      pye: "ピェ",
      pyo: "ピョ",
      ppa: "ッパ",
      ppi: "ッピ",
      ppu: "ップ",
      ppe: "ッペ",
      ppo: "ッポ",
      ppya: "ッピャ",
      ppyi: "ッピィ",
      ppyu: "ッピュ",
      ppye: "ッピェ",
      ppyo: "ッピョ",

      //ba
      ba: "バ",
      bi: "ビ",
      bu: "ブ",
      be: "ベ",
      bo: "ボ",
      bba: "ッバ",
      bbi: "ッビ",
      bbu: "ッブ",
      bbe: "ッベ",
      bbo: "ッボ",
      bbya: "ッビャ",
      bbyi: "ッビィ",
      bbyu: "ッビュ",
      bbye: "ッビェ",
      bbyo: "ッビョ",

      bya: "ビャ",
      byi: "ビィ",
      byu: "ビュ",
      bye: "ビェ",
      byo: "ビョ",

      //ma
      mma: "ッマ",
      mmi: "ッミ",
      mmu: "ッム",
      mme: "ッメ",
      mmo: "ッモ",
      mmya: "ッミャ",
      mmyi: "ッミィ",
      mmyu: "ッミュ",
      mmye: "ッミェ",
      mmyo: "ッミョ",
      //ra done
      rra: "ッラ",
      rri: "ッリ",
      rru: "ッル",
      rre: "ッレ",
      rro: "ッロ",
      rya: "リャ",
      ryi: "リィ",
      ryu: "リュ",
      rye: "リェ",
      ryo: "リョ",
      // qa
      qya: "クャ",
      qyu: "クュ",
      qye: "クェ",
      qyo: "クョ",
      //la
      la: "ァ",
      li: "ィ",
      lu: "ゥ",
      le: "ェ",
      lo: "ォ",
      lla: "ッァ",
      lli: "ッィ",
      llu: "ッゥ",
      lle: "ッェ",
      llo: "ッォ",
      llya: "ッャ",
      llyi: "ッィ",
      llyu: "ッュ",
      llye: "ッェ",
      llyo: "ッョ",
      //   TODO: 上記英字入力はたぶん完成したので、以下のひらがな入力の足りない分を補完する
      あ: "ア",
      い: "イ",
      う: "ウ",
      え: "エ",
      お: "オ",
      か: "カ",
      き: "キ",
      く: "ク",
      け: "ケ",
      こ: "コ",
      さ: "サ",
      し: "シ",
      す: "ス",
      せ: "セ",
      そ: "ソ",
      た: "タ",
      ち: "チ",
      つ: "ツ",
      て: "テ",
      と: "ト",
      な: "ナ",
      に: "ニ",
      ぬ: "ヌ",
      ね: "ネ",
      の: "ノ",
      は: "ハ",
      ひ: "ヒ",
      ふ: "フ",
      へ: "ヘ",
      ほ: "ホ",
      ま: "マ",
      み: "ミ",
      む: "ム",
      め: "メ",
      も: "モ",
      や: "ヤ",
      ゆ: "ユ",
      よ: "ヨ",
      ら: "ラ",
      り: "リ",
      る: "ル",
      れ: "レ",
      ろ: "ロ",
      わ: "ワ",
      を: "ヲ",
      ん: "ン",

      が: "ガ",
      っか: "ッカ",
      っが: "ッガ",
      きゃ: "キャ",
      ぎゃ: "ギャ",
      っきゃ: "ッキャ",
      っぎゃ: "ッギャ",
      ぎ: "ギ",
      っき: "ッキ",
      っぎ: "ッギ",
      ぐ: "グ",
      っく: "ック",
      っぐ: "ッグ",
      っきゅ: "ッキュ",
      っぎゅ: "ッギュ",
      げ: "ゲ",
      っけ: "ッケ",
      っげ: "ッゲ",
      ご: "ゴ",
      っこ: "ッコ",
      っご: "ッゴ",
      きょ: "キョ",
      ぎょ: "ギョ",
      っきょ: "ッキョ",
      っぎょ: "ッギョ",
      //   za : doing(testする)
      ざ: "ザ",
      じ: "ジ",
      ず: "ズ",
      ぜ: "ゼ",
      ぞ: "ゾ",
      っさ: "ッサ",
      っし: "ッシ",
      っす: "ッス",
      っせ: "ッセ",
      っそ: "ッソ",
      っざ: "ッザ",
      っじ: "ッジ",
      っず: "ッズ",
      っぜ: "ッゼ",
      っぞ: "ッゾ",
      しゃ: "シャ",
      し: "シ",
      しゅ: "シュ",
      しぇ: "シェ",
      しょ: "ショ",
      しゃ: "シャ",
      しぃ: "シィ",
      しゅ: "シュ",
      しぇ: "シェ",
      しょ: "ショ",
      っしゃ: "ッシャ",
      っし: "ッシ",
      っしゅ: "ッシュ",
      っしぇ: "ッシェ",
      っしょ: "ッショ",
      っしゃ: "ッシャ",
      っしぃ: "ッシィ",
      っしゅ: "ッシュ",
      っしぇ: "ッシェ",
      っしょ: "ッショ",
      じゃ: "ジャ",
      じ: "ジ",
      じゅ: "ジュ",
      じぇ: "ジェ",
      じょ: "ジョ",
      っじゃ: "ッジャ",
      っじ: "ッジ",
      っじゅ: "ッジュ",
      っじぇ: "ッジェ",
      っじょ: "ッジョ",

      // na
      な: "ナ",
      に: "ニ",
      ぬ: "ヌ",
      ね: "ネ",
      の: "ノ",
      にゃ: "ニャ",
      にゅ: "ニュ",
      にょ: "ニョ",
      // ha
      ひゃ: "ヒャ",
      ひゅ: "ヒュ",
      ひょ: "ヒョ",
      // ba
      ば: "バ",
      び: "ビ",
      ぶ: "ブ",
      べ: "ベ",
      ぼ: "ボ",
      びゃ: "ビャ",
      びゅ: "ビュ",
      びょ: "ビョ",
      // pa
      ぱ: "パ",
      ぴ: "ピ",
      ぷ: "プ",
      ぺ: "ペ",
      ぽ: "ポ",
      ぴゃ: "ピャ",
      ぴゅ: "ピュ",
      ぴょ: "ピョ",
      // ma
      みゃ: "ミャ",
      みゅ: "ミュ",
      みょ: "ミョ",
      //ra
      りゃ: "リャ",
      りゅ: "リュ",
      りょ: "リョ",
      //doine: q
      くゃ: "クャ",
      くぃ: "クィ",
      くゅ: "クュ",
      くぇ: "クェ",
      くょ: "クョ",
      //la
      ぁ: "ァ",
      ぃ: "ィ",
      ぅ: "ゥ",
      ぇ: "ェ",
      ぉ: "ォ",
      ー: "-",
      "*": "*",
      //   TODO: ひらがなとローマ字入力の時両方のマッピングを書く
      // 他のローマ字とカタカナのマッピングを追加...
    };

    var reg = new RegExp("(" + Object.keys(romajiMap).join("|") + ")", "g");
    return str.replace(reg, function (match) {
      return romajiMap[match];
    });
  };

  const handleInputChange = (event) => {
    var inputVal = event.target.value;
    var hankana = romajiToHankana(inputVal);
    setInput(inputVal);
    setOutput(hankana);
  };

  return (
    <div>
      <TextField
        type="text"
        value={output}
        onChange={handleInputChange}
        sx={{ imeMode: "inactive" }}
      />
      <p>{output}</p>
    </div>
  );
};

export default RomajiToHankanaConverter;

続きの書き方

英字のマッピング完成させてから、
ひらがなのマッピング部分を完成させる
英字のマッピング部分を完成させたらすべてコピペし、左側の英字をひらがなに書きなおす方法が一番早い

英語のマッピングは完成したと思いきや、いの小文字が入る系が怪しいので確認thi, dhi, dyiとか

まとめ

onBlueを使えば早いが、リアルタイムで入力したいので死闘になってしまった

Discussion