カタカナをヘボン式ローマ字に変換するVSCode Macrosマクロ

開発プロジェクトのコーディング規約でローマ字方式が指定されている場合などに便利な、カタカナをローマ字に変換するだけのVSCodeマクロを作成してみましたので紹介します。

本マクロでは外務省のパスポート用のヘボン式ローマ字をベースとしていますが、ヘボン式といってもプロジェクトによって微妙に変換ルールが異なる場合もあるため、仕様に合わせて適宜修正してください。また幾つかの単語で簡単に動作を確認しただけで十分テストしていませんので、利用する際は結果が仕様通りになっているか十分確認してからご利用ください(At your own risk)。


マクロのサンプルソースコード

const vscode = require('vscode');

/**
 * マクロコンフィギュレーション(環境に合わせてお好みで設定)
 */
module.exports.macroCommands = {
    'カナ→ヘボン式ローマ字': {
        no: 1,
        func: toHepburn
    },
};

async function toHepburn() {
    const editor = vscode.window.activeTextEditor;
    if (!editor) {
        return 'Editor is not open.';
    }

    // 選択範囲のテキストを取得
    const document = editor.document;
    const selection = editor.selection;
    const text = document.getText(selection);

    let kanaText = '';
    if (text.length) {
        kanaText = text;
    } else {
        kanaText = await vscode.window.showInputBox({ title: 'ローマ字変換する文字を全角カナで入力' });
        if (!kanaText) {
            return '';
        }
    }

    const romaji = kanaToHepburnRomanization(kanaText);

    editor.edit(editBuilder => {
        // 処理結果を選択範囲に書き戻す
        editBuilder.replace(selection, romaji);
    });
}

function kanaToHepburnRomanization(kana) {
    const kanaHepburnMap = {
        'ア': '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', 'ヰ': 'i', 'ヱ': 'e', 'ヲ': 'o', 'ン': 'n',
        'ガ': 'ga', 'ギ': 'gi', 'グ': 'gu', 'ゲ': 'ge', 'ゴ': 'go',
        'ザ': 'za', 'ジ': 'ji', 'ズ': 'zu', 'ゼ': 'ze', 'ゾ': 'zo',
        'ダ': 'da', 'ヂ': 'ji', 'ヅ': 'zu', 'デ': 'de', 'ド': 'do',
        'バ': 'ba', 'ビ': 'bi', 'ブ': 'bu', 'ベ': 'be', 'ボ': 'bo',
        'パ': 'pa', 'ピ': 'pi', 'プ': 'pu', 'ペ': 'pe', 'ポ': 'po',
        'キャ': 'kya', 'キュ': 'kyu', 'キョ': 'kyo',
        'シャ': 'sha', 'シュ': 'shu', 'ショ': 'sho',
        'チャ': 'cha', 'チュ': 'chu', 'チョ': 'cho',
        'ニャ': 'nya', 'ニュ': 'nyu', 'ニョ': 'nyo',
        'ヒャ': 'hya', 'ヒュ': 'hyu', 'ヒョ': 'hyo',
        'ミャ': 'mya', 'ミュ': 'myu', 'ミョ': 'myo',
        'リャ': 'rya', 'リュ': 'ryu', 'リョ': 'ryo',
        'ギャ': 'gya', 'ギュ': 'gyu', 'ギョ': 'gyo',
        'ジャ': 'ja', 'ジュ': 'ju', 'ジョ': 'jo',
        'ビャ': 'bya', 'ビュ': 'byu', 'ビョ': 'byo',
        'ピャ': 'pya', 'ピュ': 'pyu', 'ピョ': 'pyo',
        'シェ': 'she', 'チェ': 'che', 'ティ': 'ti', 'ニィ': 'ni', 'ニェ': 'nye',
        'ファ': 'fa', 'フィ': 'fi', 'フェ': 'fe', 'フォ': 'fo', 'ジェ': 'je',
        'ディ': 'di', 'デュ': 'dyu', 'ウィ': 'wi', 'ウェ': 'we', 'ウォ': 'wo',
        'ヴァ': 'va', 'ヴィ': 'vi', 'ヴェ': 've', 'ヴォ': 'vo',
        'ー': ''
    };

    function getRomaji(t) {
        return kanaHepburnMap[t] ?? '';
    }

    let romaji = '';
    for (let i = 0; i < kana.length; i++) {

        const currentChar = kana[i]
        const nextChar = kana[i + 1] ?? '';

        if (currentChar === 'ン') {
            // 撥音
            if (['バ', 'ビ', 'ブ', 'ベ', 'ボ', 'パ', 'ピ', 'プ', 'ペ', 'ポ', 'マ', 'ミ', 'ム', 'メ', 'モ'].includes(nextChar)) {
                // :B/M/Pの前の「ん」はMで表現
                romaji += 'm';
            } else {
                // nで表現
                romaji += 'n';
            }
        } else if (currentChar === 'ッ') {
            // 促音
            if (['チ', 'チャ', 'チュ', 'チョ'].includes(nextChar)) {
                // チ(chi)/チャ(cha)/チュ(chu)/チョ(cho)の場合はtを付加
                romaji += 't';
            } else {
                // 子音を重ねる
                romaji += getRomaji(nextChar)[0] ?? '';
            }
        }
        else {
            // 撥音・促音以外
            let hepburn = getRomaji(currentChar + nextChar);
            if (hepburn && nextChar) {
                // 2文字処理した場合は次の文字をスキップ
                ++i;
            } else {
                // そのまま出力
                hepburn = getRomaji(currentChar);
            }
            romaji += hepburn;
        }
    }

    // 「オ」を含む長音オオ(oo)の場合はoを重ねない
    romaji = romaji.replace(/oo(?!$)/g, 'o');
    // 「ウ」を含む長音ウウ(uu))の場合はuを重ねない
    romaji = romaji.replace(/uu/g, 'u');
    // 「オウ」音でヨミカタが「ウ」の場合uを付加しない
    romaji = romaji.replace(/ou/g, 'o');

    return romaji;
}

GitHub Gist


マクロの動作イメージ

・テキストエディタ上でローマ字変換したい全角カタカナ文字を選択してマクロを実行すると選択文字をローマ字に置換。
・テキストにカーソルを合わせた状態でマクロを実行するとテキストボックスに入力した全角カタカナ文字をローマ字で挿入。


プログラムコード中のスペルミスはリファクタリング機能などを使えば参照を含めて一気に変更できたりしますが、DBのテーブル名やカラム名のスペルミスの場合、それらを利用するSQLやO/Rマッパーの名称などをgrepして手作業で置換する必要があるなど無駄なコストをかけてしまうこともあるため、こういった即席ツールを活用してミスを減らしていきたいところです。


参考ウェブサイトなど

  • 外務省
    ヘボン式ローマ字綴方表

以上です。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする