Skip to content

Instantly share code, notes, and snippets.

@logue
Forked from Tenderfeel/hiragana-to-roman.js
Last active December 5, 2019 09:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save logue/052ecd4221c924433c04e99197489ce3 to your computer and use it in GitHub Desktop.
Save logue/052ecd4221c924433c04e99197489ce3 to your computer and use it in GitHub Desktop.
ひらがなをローマ字に変換するクラスをES6にしたやつ。
/**
* ひらがな → ローマ字変換クラス
* @author tenderfeel, Logue
* @license MIT
* @ver 1.3.1
* http://tenderfeel.xsrv.jp/
*
* ---MIT License--------------------------------------------
* Copyright (c) 2008 Tenderfeel all rights reserved.
* 2019 Modified by Masashi Yoshikawa <logue@hotmail.co.jp>
*
* 以下に定める条件に従い、本ソフトウェアおよび関連文書の
* ファイル(以下「ソフトウェア」)の複製を取得するすべての
* 人に対し、ソフトウェアを無制限に扱うことを無償で許可します。
* これには、ソフトウェアの複製を使用、複写、変更、結合、
* 掲載、頒布、サブライセンス、および/または販売する権利、
* およびソフトウェアを提供する相手に同じことを許可する権利も無制限に含まれます。
*
* 上記の著作権表示および本許諾表示を、
* ソフトウェアのすべての複製または重要な部分に記載するものとします。
*
* ソフトウェアは「現状のまま」で、明示であるか暗黙であるかを問わず、
* 何らの保証もなく提供されます。ここでいう保証とは、商品性、
* 特定の目的への適合性、および権利非侵害についての保証も含みますが、
* それに限定されるものではありません。作者または著作権者は、
* 契約行為、不法行為、またはそれ以外であろうと、
* ソフトウェアに起因または関連し、あるいはソフトウェアの使用
* またはその他の扱いによって生じる一切の請求、損害、
* その他の義務について何らの責任も負わないものとします。
* ----------------------------------------------------------
* ◆変換モード設定
*
* m1.か・く・こ: K or C
* m2.小文字ぁ行: L or X
*
* m3.ち行+小文字や行: TY or CH or CY
* m4.し行+小文字や行: SY or SH
* m5.じ行+小文字や行: J or ZY or JY
*
* m6.し: S or SH or C
* m7.じ: J or Z
* m8.つ: T or TS
* m9.ふ: H or F
* m10.ち: T or CH
* m11.ん: N or NN
*
* ----------------------------------------------------------
* @example
* const converter = new HiraganaToRoman('k', 'x', 'cy', 'sh', 'zy', 's', 'j', 't', 'h', 't', 'n');
* let txt = converter.convert('変換テキスト');
*/
export default class HiraganaToRoman {
constructor(m1 = 'k', m2 = 'x', m3 = 'cy', m4 = 'sh', m5 = 'jy', m6 = 'sh', m7 = 'j', m8 = 'ts', m9 = 'f', m10 = 'ch', m11 = 'n') {
this.mode_Krows = m1; // か・く・こ
this.mode_XArows = m2; // 小文字ぁ行と「っ」
this.mode_TYrows = m3; // ち行+小文字や行
this.mode_SYrows = m4; // し行+小文字や行
this.mode_JYrows = m5; // じ行+小文字や行
this.mode_Sstr = m6; // し
this.mode_Jstr = m7; // じ
this.mode_TUstr = m8; // つ
this.mode_FUstr = m9; // ふ
this.mode_TIstr = m10; // ち
this.mode_Nstr = m11; // ん
this.chop = false; // ローマ字文字列をアルファベット1文字ごとに分解するかどうか
this.vowel = ['a', 'i', 'u', 'e', 'o'];
this.child = ['a', 'k', 's', 't', 'n', 'h', 'm', 'y', 'r', 'w', 'g', 'z', 'd', 'b', 'p', 'x', 'y', 't', 'v'];
this.symbol = ['!', '?', '-', "'", ','];
this.number = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
this.cols_H = {
A: ['あ', 'か', 'さ', 'た', 'な', 'は', 'ま', 'や', 'ら', 'わ', 'が', 'ざ', 'だ', 'ば', 'ぱ', 'ぁ', 'ゃ'],
I: ['い', 'き', 'し', 'ち', 'に', 'ひ', 'み', '@', 'り', 'ゐ', 'ぎ', 'じ', 'ぢ', 'び', 'ぴ', 'ぃ'],
U: ['う', 'く', 'す', 'つ', 'ぬ', 'ふ', 'む', 'ゆ', 'る', 'ん', 'ぐ', 'ず', 'づ', 'ぶ', 'ぷ', 'ぅ', 'ゅ', 'っ', 'ゔ'],
E: ['え', 'け', 'せ', 'て', 'ね', 'へ', 'め', '@', 'れ', 'ゑ', 'げ', 'ぜ', 'で', 'べ', 'ぺ', 'ぇ'],
O: ['お', 'こ', 'そ', 'と', 'の', 'ほ', 'も', 'よ', 'ろ', 'を', 'ご', 'ぞ', 'ど', 'ぼ', 'ぽ', 'ぉ', 'ょ'],
};
}
/**
* 文字列分割→字数で分岐→ローマ字変換
* @param {Object} str
*/
convert(txt) {
const stack = this._TextSlice(txt.replace(/[ァ-ヶ]/g, (s) => {
// カタカナをカナにする。
return String.fromCharCode(s.charCodeAt(0) - 0x60);
}));
let out = [];
for (let i = 0; i < stack.length; i++) {
const str = stack[i].length === 1 ? this._baseOne(stack[i]) : this._baseTwo(stack[i]);
out.push(this.stringChopper(str));
}
return out.join('');
}
/**
* ローマ字文字列分解
* this.chopがtrueならアルファベット毎に分解
* @param {Object} str ローマ字(日本語1文字分)
*/
stringChopper(str) {
let out = [];
if (this.chop === true) {
for (let n = 0; n < str.length; n++) {
out.push(str.charAt(n));
}
return out;
}
return str;
}
/**
* 文章を1文字単位に分割する
* @param {Object} str 文章
*/
_TextSlice(txt) {
const max = txt.length;
let n = 0;
let array = [];
for (let i = 0; i < max; i++) {
n++; // 次
const str = txt.charAt(i); // 今の文字
const nxt = txt.charAt(n); // 次の文字
// 隣接する1文字目が小文字や行なら
if (nxt === 'ゃ' || nxt === 'ゅ' || nxt === 'ょ') {
array.push(str + nxt);
i++;
n++;
} else if (str === 'っ' && this.symbol.indexOf(nxt) === -1) {
if (this.number.indexOf(nxt) === -1) {
array.push(str + nxt);
i++;
n++;
} else {
array.push(str);
}
} else {
array.push(str);
}
}
return array;
}
/**
* 変換ベース(2文字)
* 小文字とセットで2文字になってる文字を判別して処理を分配する
* @param {Object} str 変換する文字(小文字とセットで2文字)
*/
_baseTwo(str) {
if (str.indexOf('っ') !== -1) {
if (str.length === 2) {
const txt = this._baseOne(str.charAt(1));
return txt.charAt(0) + txt;
}
return this._baseOne(str);
}
const first = this._baseOne(str.charAt(0));
const second = this._baseOne(str.charAt(1));
switch (str) {
case 'ちゃ':
return this.mode_TYrows + this.vowel[0];
case 'ちゅ':
return this.mode_TYrows + this.vowel[2];
case 'ちょ':
return this.mode_TYrows + this.vowel[4];
case 'しゃ':
return this.mode_SYrows + this.vowel[0];
case 'しゅ':
return this.mode_SYrows + this.vowel[2];
case 'しょ':
return this.mode_SYrows + this.vowel[4];
case 'じゃ':
return this.mode_JYrows + this.vowel[0];
case 'じゅ':
return this.mode_JYrows + this.vowel[2];
case 'じょ':
return this.mode_JYrows + this.vowel[4];
default:
return first.charAt(0) + second;
}
}
/**
* 変換ベース(1文字)
* あいうえお行の配列(cols_H,number,symbol)から文字が何かを判別して各関数へ処理を分配する
* @param {Object} str 変換する文字(1文字のみ)
*/
_baseOne(str) {
if (this.cols_H.A.indexOf(str) !== -1) {// あ行
return this._Change_A_Rows(this.cols_H.A.indexOf(str));
} else if (this.cols_H.I.indexOf(str) !== -1) {// い行
return this._Change_I_Rows(this.cols_H.I.indexOf(str));
} else if (this.cols_H.U.indexOf(str) !== -1) {// う行
return this._Change_U_Rows(this.cols_H.U.indexOf(str));
} else if (this.cols_H.E.indexOf(str) !== -1) {// え行
return this._Change_E_Rows(this.cols_H.E.indexOf(str));
} else if (this.cols_H.O.indexOf(str) !== -1) {// お行
return this._Change_O_Rows(this.cols_H.O.indexOf(str));
} else if (this.symbol.indexOf(str) !== -1) {// 記号
return this.symbol[this.symbol.indexOf(str)];
} else if (this.number.indexOf(str) !== -1) {// 数字
return str;
}
return null;
}
/**
* 単音あ行文字をローマ字に
* @param {Object} key ひらがな配列のキー番号
*/
_Change_A_Rows(key) {
if (key === 1) {// か行
return this.mode_Krows + this.vowel[0];
} else if (key === 15) {// 小文字ぁ行
return this.mode_XArows + this.vowel[0];
} else if (key === 0) {
return this.vowel[0];
}
return this.child[key] + this.vowel[0];
}
/**
* 単音い行文字をローマ字に
* @param {Object} key ひらがな配列のキー番号
*/
_Change_I_Rows(key) {
if (key === 0) {// 母音
return this.vowel[1];
} else if (key === 15) {// 小文字ぁ行
return this.mode_XArows + this.vowel[1];
} else if (key === 2) {// し
return this.mode_Sstr + this.vowel[1];
} else if (key === 11) {// じ
return this.mode_Jstr + this.vowel[1];
} else if (key === 3) {// ち
return this.mode_TIstr + this.vowel[1];
}
return this.child[key] + this.vowel[1];
}
/**
* 単音う行文字をローマ字に
* @param {Object} key ひらがな配列のキー番号
*/
_Change_U_Rows(key) {
if (key === 0) {// 母音
return this.vowel[2];
} else if (key === 1) {// く
return this.mode_Krows + this.vowel[2];
} else if (key === 15) {// 小文字ぁ行
return this.mode_XArows + this.vowel[2];
} else if (key === 3) {// つ
return this.mode_TUstr + this.vowel[2];
} else if (key === 5) {// ふ
return this.mode_FUstr + this.vowel[2];
} else if (key === 9) {// ん
return this.mode_Nstr;
} else if (key === 17) {// っ
return this.mode_XArows + this.mode_TUstr + this.vowel[2];
}
return this.child[key] + this.vowel[2];
}
/**
* 単音え行文字をローマ字に
* @param {Object} key ひらがな配列のキー番号
*/
_Change_E_Rows(key) {
if (key === 0) {// 母音
return this.vowel[3];
} else if (key === 15) {// 小文字ぁ行
return this.mode_XArows + this.vowel[3];
}
return this.child[key] + this.vowel[3];
}
/**
* 単音お行文字をローマ字に
* @param {Object} key ひらがな配列のキー番号
*/
_Change_O_Rows(key) {
if (key === 0) {// 母音
return this.vowel[4];
} else if (key === 1) {// こ
return this.mode_Krows + this.vowel[4];
} else if (key === 15) {// 小文字ぁ行
return this.mode_XArows + this.vowel[4];
}
return this.child[key] + this.vowel[4];
}
}
@logue
Copy link
Author

logue commented Dec 5, 2019

ゑ、ゐ、ゔに対応。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment