inko-no-warn
Version:
영타를 한글로 쳤을 때, 혹은 한타를 영어로 변환해주는 기능을 가진 자바스크립트 오픈소스 라이브러리입니다.
362 lines (322 loc) • 12.7 kB
JavaScript
// (c) 2018 Jon Jee
// Inko may be freely distributed or modified under the MIT license.
(function () {
// constants
var 영어 = 'rRseEfaqQtTdwWczxvgASDFGZXCVkoiOjpuPhynbmlYUIHJKLBNM'; // 33 + 19개
var 한글 =
'ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎㅁㄴㅇㄹㅎㅋㅌㅊㅍㅏㅐㅑㅒㅓㅔㅕㅖㅗㅛㅜㅠㅡㅣㅛㅕㅑㅗㅓㅏㅣㅠㅜㅡ'; // 33 + 19개
var 초성 = 'ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ'; // 19개
var 중성 = 'ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ'; // 21개
var 종성 = 'ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ'; // 27개
var 첫모음 = 28;
var 가 = 44032;
var 힣 = 55203;
var ㄱ = 12593;
var ㅣ = 12643;
var 영어index = (function (en) {
var x = {};
for (var i = 0; i < en.length; ++i) x[en[i]] = i;
return x;
})(영어);
var 한글index = (function (kr) {
var x = {};
for (var i = 0; i < kr.length; ++i) x[kr[i]] = i;
return x;
})(한글);
var connectableConsonant = {
ㄱㅅ: 'ㄳ',
ㄴㅈ: 'ㄵ',
ㄴㅎ: 'ㄶ',
ㄹㄱ: 'ㄺ',
ㄹㅁ: 'ㄻ',
ㄹㅂ: 'ㄼ',
ㄹㅅ: 'ㄽ',
ㄹㅌ: 'ㄾ',
ㄹㅍ: 'ㄿ',
ㄹㅎ: 'ㅀ',
ㅂㅅ: 'ㅄ',
};
var connectableVowel = {
ㅗㅏ: 'ㅘ',
ㅗㅐ: 'ㅙ',
ㅗㅣ: 'ㅚ',
ㅜㅓ: 'ㅝ',
ㅜㅔ: 'ㅞ',
ㅜㅣ: 'ㅟ',
ㅡㅣ: 'ㅢ',
};
var isVowel = function (e) {
return 한글index[e] >= 첫모음;
};
// constructor
function Inko(_option) {
var option = _option || {};
this._allowDoubleConsonant =
typeof option.allowDoubleConsonant !== 'undefined'
? option.allowDoubleConsonant
: false;
return this;
}
Inko.prototype.config = function (_option) {
var option = _option || {};
this._allowDoubleConsonant =
typeof option.allowDoubleConsonant !== 'undefined'
? option.allowDoubleConsonant
: false;
};
Inko.prototype.VERSION = '1.1.1';
Inko.prototype.en2ko = function (input, _option) {
var option = _option || {};
var allowDoubleConsonant =
typeof option.allowDoubleConsonant !== 'undefined'
? option.allowDoubleConsonant
: this._allowDoubleConsonant;
var self = this;
var stateLength = [0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5];
var transitions = [
[1, 1, 2, 2], // 0, EMPTY
[3, 1, 4, 4], // 1, 자
[1, 1, 5, 2], // 2, 모
[3, 1, 4, -1], // 3, 자자
[6, 1, 7, 2], // 4, 자모
[1, 1, 2, 2], // 5, 모모
[9, 1, 4, 4], // 6, 자모자
[9, 1, 2, 2], // 7, 자모모
[1, 1, 4, 4], // 8, 자모자자
[10, 1, 4, 4], // 9, 자모모자
[1, 1, 4, 4], // 10, 자모모자자
];
var last = function (list) {
return list[list.length - 1];
};
var combine = function (arr) {
var group = [];
arr.forEach(function (cur, i) {
var h = 한글[cur];
if (i === 0 || isVowel(last(group)[0]) !== isVowel(h)) {
group.push([]);
}
last(group).push(h);
});
group = group.map(function connect(e) {
var w = e.join('');
return connectableConsonant[w] || connectableVowel[w] || w;
});
if (group.length === 1) return group[0];
var charSet = [초성, 중성, 종성];
var code = group.map(function (w, i) {
return charSet[i].indexOf(w);
});
if (code.length < 3) code.push(-1);
return self.한글생성.apply(self, code);
};
return (function () {
var length = input.length;
var last = -1;
var result = [];
var state = 0;
var tmp = [];
var flush = function () {
if (tmp.length > 0) result.push(combine(tmp));
tmp = [];
};
for (var i = 0; i < length; ++i) {
var chr = input[i];
var cur = 영어index[chr];
if (typeof cur === 'undefined') {
state = 0;
flush();
result.push(chr);
} else {
var transition = (function () {
var c = (한글[last] || '') + 한글[cur];
var lastIsVowel = isVowel(한글[last]);
var curIsVowel = isVowel(한글[cur]);
if (!curIsVowel) {
if (lastIsVowel) {
return 'ㄸㅃㅉ'.indexOf(한글[cur]) === -1 ? 0 : 1;
}
if (state === 1 && !allowDoubleConsonant) return 1;
return connectableConsonant[c] ? 0 : 1;
} else if (lastIsVowel) {
return connectableVowel[c] ? 2 : 3;
}
return 2;
})();
var nxtState = transitions[state][transition];
tmp.push(cur);
var diff = tmp.length - stateLength[nxtState];
if (diff) result.push(combine(tmp.splice(0, diff)));
state = nxtState;
last = cur;
}
}
flush();
return result.join('');
})();
};
Inko.prototype.ko2en = function (input) {
var result = '';
if (input === '' || input === undefined) return result;
var _분리 = [-1, -1, -1, -1, -1];
for (var i = 0; i < input.length; i++) {
var _한글 = input[i];
var _코드 = _한글.charCodeAt();
// 가 ~ 힣 사이에 있는 한글이라면
if ((_코드 >= 가 && _코드 <= 힣) || (_코드 >= ㄱ && _코드 <= ㅣ)) {
_분리 = this.한글분리(_한글);
}
// 한글이 아니라면
else {
result += _한글;
// 분리 배열 초기화
_분리 = [-1, -1, -1, -1, -1];
}
for (var j = 0; j < _분리.length; j++) {
if (_분리[j] !== -1) result += 영어[_분리[j]];
}
}
return result;
};
// 초성, 중성, 종성의 charCode를 받아서 합친 한글의 charCode를 반환함
Inko.prototype.한글생성 = function (초, 중, 종) {
return String.fromCharCode(44032 + 초 * 588 + 중 * 28 + 종 + 1);
};
// 한글 입력값으로 받아서 초성, 중성, 종성 분리해줌
Inko.prototype.한글분리 = function (_한글) {
var 코드 = _한글.charCodeAt();
if (코드 >= 가 && 코드 <= 힣) {
var 초 = Math.floor((코드 - 가) / 588);
var 중 = Math.floor((코드 - 가 - 초 * 588) / 28);
var 종 = 코드 - 가 - 초 * 588 - 중 * 28 - 1;
var 중1 = 중,
중2 = -1,
종1 = 종,
종2 = -1;
if (중 == 중성.indexOf('ㅘ'))
(중1 = 한글.indexOf('ㅗ')), (중2 = 한글.indexOf('ㅏ'));
else if (중 == 중성.indexOf('ㅙ'))
(중1 = 한글.indexOf('ㅗ')), (중2 = 한글.indexOf('ㅐ'));
else if (중 == 중성.indexOf('ㅚ'))
(중1 = 한글.indexOf('ㅗ')), (중2 = 한글.indexOf('ㅣ'));
else if (중 == 중성.indexOf('ㅝ'))
(중1 = 한글.indexOf('ㅜ')), (중2 = 한글.indexOf('ㅓ'));
else if (중 == 중성.indexOf('ㅞ'))
(중1 = 한글.indexOf('ㅜ')), (중2 = 한글.indexOf('ㅔ'));
else if (중 == 중성.indexOf('ㅟ'))
(중1 = 한글.indexOf('ㅜ')), (중2 = 한글.indexOf('ㅣ'));
else if (중 == 중성.indexOf('ㅢ'))
(중1 = 한글.indexOf('ㅡ')), (중2 = 한글.indexOf('ㅣ'));
if (종 == 종성.indexOf('ㄳ'))
(종1 = 한글.indexOf('ㄱ')), (종2 = 한글.indexOf('ㅅ'));
else if (종 == 종성.indexOf('ㄵ'))
(종1 = 한글.indexOf('ㄴ')), (종2 = 한글.indexOf('ㅈ'));
else if (종 == 종성.indexOf('ㄶ'))
(종1 = 한글.indexOf('ㄴ')), (종2 = 한글.indexOf('ㅎ'));
else if (종 == 종성.indexOf('ㄺ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㄱ'));
else if (종 == 종성.indexOf('ㄻ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㅁ'));
else if (종 == 종성.indexOf('ㄼ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㅂ'));
else if (종 == 종성.indexOf('ㄽ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㅅ'));
else if (종 == 종성.indexOf('ㄾ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㅌ'));
else if (종 == 종성.indexOf('ㄿ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㅍ'));
else if (종 == 종성.indexOf('ㅀ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㅎ'));
else if (종 == 종성.indexOf('ㅄ'))
(종1 = 한글.indexOf('ㅂ')), (종2 = 한글.indexOf('ㅅ'));
// 복모음이 아니라면
if (중2 === -1) 중1 = 한글.indexOf(중성[중]);
// 복자음이 아니라면
if (종2 === -1) 종1 = 한글.indexOf(종성[종]);
return [초, 중1, 중2, 종1, 종2];
} else if (코드 >= ㄱ && 코드 <= ㅣ) {
if (초성.indexOf(_한글) > -1) {
var 초 = 한글.indexOf(_한글);
return [초, -1, -1, -1, -1];
} else if (중성.indexOf(_한글) > -1) {
var 중 = 중성.indexOf(_한글);
var 중1 = 중,
중2 = -1;
if (중 == 중성.indexOf('ㅘ'))
(중1 = 한글.indexOf('ㅗ')), (중2 = 한글.indexOf('ㅏ'));
else if (중 == 중성.indexOf('ㅙ'))
(중1 = 한글.indexOf('ㅗ')), (중2 = 한글.indexOf('ㅐ'));
else if (중 == 중성.indexOf('ㅚ'))
(중1 = 한글.indexOf('ㅗ')), (중2 = 한글.indexOf('ㅣ'));
else if (중 == 중성.indexOf('ㅝ'))
(중1 = 한글.indexOf('ㅜ')), (중2 = 한글.indexOf('ㅓ'));
else if (중 == 중성.indexOf('ㅞ'))
(중1 = 한글.indexOf('ㅜ')), (중2 = 한글.indexOf('ㅔ'));
else if (중 == 중성.indexOf('ㅟ'))
(중1 = 한글.indexOf('ㅜ')), (중2 = 한글.indexOf('ㅣ'));
else if (중 == 중성.indexOf('ㅢ'))
(중1 = 한글.indexOf('ㅡ')), (중2 = 한글.indexOf('ㅣ'));
// 복모음이 아니라면
if (중2 === -1) 중1 = 한글.indexOf(중성[중]);
return [-1, 중1, 중2, -1, -1];
} else if (종성.indexOf(_한글) > -1) {
var 종 = 종성.indexOf(_한글);
var 종1 = 종,
종2 = -1;
if (종 == 종성.indexOf('ㄳ'))
(종1 = 한글.indexOf('ㄱ')), (종2 = 한글.indexOf('ㅅ'));
else if (종 == 종성.indexOf('ㄵ'))
(종1 = 한글.indexOf('ㄴ')), (종2 = 한글.indexOf('ㅈ'));
else if (종 == 종성.indexOf('ㄶ'))
(종1 = 한글.indexOf('ㄴ')), (종2 = 한글.indexOf('ㅎ'));
else if (종 == 종성.indexOf('ㄺ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㄱ'));
else if (종 == 종성.indexOf('ㄻ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㅁ'));
else if (종 == 종성.indexOf('ㄼ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㅂ'));
else if (종 == 종성.indexOf('ㄽ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㅅ'));
else if (종 == 종성.indexOf('ㄾ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㅌ'));
else if (종 == 종성.indexOf('ㄿ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㅍ'));
else if (종 == 종성.indexOf('ㅀ'))
(종1 = 한글.indexOf('ㄹ')), (종2 = 한글.indexOf('ㅎ'));
else if (종 == 종성.indexOf('ㅄ'))
(종1 = 한글.indexOf('ㅂ')), (종2 = 한글.indexOf('ㅅ'));
return [종1, 종2, -1, -1, -1];
}
}
return [-1, -1, -1, -1, -1];
};
Inko.prototype.is한글 = function (char) {
if (char.length > 1) throw new Error('한 글자가 아닙니다.');
return /[ㄱ-ㅎㅏ-ㅣ가-힣]/.test(char);
};
// CommonJS module
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = Inko;
}
exports.Inko = Inko;
}
// Register as an anonymous AMD module
if (typeof define === 'function' && define.amd) {
define([], function () {
return Inko;
});
}
// if there is a importScripts object define chance for worker
// allows worker to use full Chance functionality with seed
if (typeof importScripts !== 'undefined') {
inko = new Inko();
self.Inko = Inko;
}
// If there is a window object, that at least has a document property,
// instantiate and define chance on the window
if (typeof window === 'object' && typeof window.document === 'object') {
window.Inko = Inko;
window.inko = new Inko();
}
})();