UNPKG

hangul-tools

Version:

A Hangul library for various Hangul/Korean operations including reading numbers, adding josa, and converting between different keyboards

327 lines (300 loc) 11.8 kB
"use strict"; (function(){ var _extend = function _extend(parent, f){ var child = f ? function _extended(){ f.apply(this, arguments); } : function _extended(){}; child.prototype = new parent(); child.prototype.constructor = parent; return child; }; var _push_multi = function _push_multi(a, p){ p.forEach(function(e){a.push(e)}); }; var QWERTY_SHIFT = { '`': '~', '1': '!', '2': '@', '3': '#', '4': '$', '5': '%', '6': '^', '7': '&', '8': '*', '9': '(', '0': ')', '-': '_', '=': '+', '\\': '|', '[': '{', ']': '}', ';': ':', '\'': '\"', ',': '<', '.': '>', '/': '?' }, QWERTY_SHIFT_INV = {}; var _qwerty_key = function(c){ if('A' <= c && c <= 'Z') return [c.toLowerCase(), true]; else if(c in QWERTY_SHIFT_INV) return [QWERTY_SHIFT_INV[c], true]; else return [c, false]; }, _qwerty_key_inv = function(key){ if('a' <= key[0] && key[0] <= 'z') return key[1] ? key[0].toUpperCase() : key[0]; else if(key[1] && key[0] in QWERTY_SHIFT) return QWERTY_SHIFT[key[0]]; else return key[0]; }; var _key_map_convert = function(s){ return s ? s.split('').map(function(c){return _qwerty_key(c);}) : []; }; var DUBEOLSIK_MAP = [ "rRseEfaqQtTdwWczxvg".split('').map(function(c){ return c <= 'Z' ? [[c.toLowerCase(), true]] : [[c, false]]; }), "k o i O j p u P h hk ho hl y n nj np nl b m ml l".split(' ').map(_key_map_convert), " r R rt s sw sg e f fr fa fq ft fx fv fg a q qt t T d w c z x v g".split(' ').map(_key_map_convert) ], DUBEOLSIK_MAP_INV = "ㅁㅠㅊㅇㄷㄹㅎㅗㅑㅓㅏㅣㅡㅜㅐㅔㅂㄱㄴㅅㅕㅍㅈㅌㅛㅋ"; var SEBEOLSIK_390_MAP = [ "k kk h u uu y i ; ;; n nn j l ll o 0 \' p m".split(' ').map(_key_map_convert), "f r 6 R t c e 7 v /f /r /d 4 b 9t 9c 9d 5 g 8 d".split(' ').map(_key_map_convert), " x F xq s s! S A w D C w3 wq wW wQ V z 3 X q 2 a ! Z E W Q 1".split(' ').map(_key_map_convert) ]; var _composible_hangul = function(x, y){ switch(x+y){ case "ㄱㄱ": return "ㄲ"; case "ㄱㅅ": return "ㄳ"; case "ㄴㅈ": return "ㄵ"; case "ㄴㅎ": return "ㄶ"; case "ㄷㄷ": return "ㄸ"; case "ㄹㄱ": return "ㄺ"; case "ㄹㅁ": return "ㄻ"; case "ㄹㅂ": return "ㄼ"; case "ㄹㅅ": return "ㄽ"; case "ㄹㅌ": return "ㄾ"; case "ㄹㅍ": return "ㄿ"; case "ㄹㅎ": return "ㅀ"; case "ㅂㅂ": return "ㅃ"; case "ㅂㅅ": return "ㅄ"; case "ㅅㅅ": return "ㅆ"; case "ㅈㅈ": return "ㅉ"; case "ㅗㅏ": return "ㅘ"; case "ㅗㅐ": return "ㅙ"; case "ㅗㅣ": return "ㅚ"; case "ㅜㅓ": return "ㅝ"; case "ㅜㅔ": return "ㅞ"; case "ㅜㅣ": return "ㅟ"; case "ㅡㅣ": return "ㅢ"; default: return null; } }; (function init_dict(){ for(var key in QWERTY_SHIFT) QWERTY_SHIFT_INV[QWERTY_SHIFT[key]] = key; })(); var root = this; var _old_hantools_keyboard = this.HanTools_Keyboard; var HanTools_Keyboard = function INIT_HANTOOLS_KEYBOARD(HanTools){ var _kor_key = function(map, c){ var ind = HanTools.CHOSEONG.indexOf(c); if(ind >= 0) return map[0][ind]; ind = HanTools.JUNGSEONG.indexOf(c); if(ind >= 0) return map[1][ind]; ind = HanTools.JONGSEONG.indexOf(c); if(ind >= 0) return map[2][ind]; return map[3] && c in map[3] ? map[3][c] : [_qwerty_key(c)]; }; var Keyboard = function Keyboard(){ this.output = ""; this.buffer = []; }; Keyboard.prototype.type = function(){return this;}; Keyboard.prototype.getBufferString = function(){return this.buffer.join('');}; Keyboard.prototype.getString = function(){return this.output + this.getBufferString();}; Keyboard.prototype.flushBuffer = function(){this.output += this.getBufferString(); this.buffer.splice(0, this.buffer.length);}; Keyboard.type = function Keyboard_type(seq){ return (new this()).type(seq).getString(); }; Keyboard.QWERTY = _extend(Keyboard, Keyboard); Keyboard.QWERTY.getKeySequence = function QWERTY_getKeySequence(str){ var i, seq = []; for(i=0; i<str.length; i++) seq.push(_qwerty_key(str[i])); return seq; }; Keyboard.QWERTY.type = Keyboard.type; Keyboard.QWERTY.prototype.type = function QWERTY$type(seq){ seq.forEach(function(key){ this.buffer.push(_qwerty_key_inv(key)); }, this); this.flushBuffer(); return this; }; Keyboard.DUBEOLSIK = _extend(Keyboard, Keyboard); Keyboard.DUBEOLSIK.getKeySequence = function DUBEOLSIK_getKeySequence(str){ var seq = []; str.split('').map(HanTools.disintegrate).forEach(function(part){ var ind; if(typeof part == 'string') _push_multi(seq, _kor_key(DUBEOLSIK_MAP, part)); else part.forEach(function(c){_push_multi(seq, _kor_key(DUBEOLSIK_MAP, c));}); }); return seq; }; Keyboard.DUBEOLSIK.type = Keyboard.type.bind(Keyboard.DUBEOLSIK); Keyboard.DUBEOLSIK.prototype.getBufferString = function DUBEOLSIK$getBufferString(){ if(this.buffer.length == 4){ var _c = _composible_hangul(this.buffer[2], this.buffer[3]); if(_c){ this.buffer[2] = _c; this.buffer.pop(); } } return HanTools.compose(this.buffer); }; Keyboard.DUBEOLSIK.prototype.type = function DUBEOLSIK$type(seq){ seq.forEach(function(key){ var ch = key[0]; if('a' <= ch && ch <= 'z'){ ch = DUBEOLSIK_MAP_INV[ch.charCodeAt(0)-97]; if(key[1]){ if(ch == 'ㄱ') ch = 'ㄲ'; else if(ch == 'ㄷ') ch = 'ㄸ'; else if(ch == 'ㅂ') ch = 'ㅃ'; else if(ch == 'ㅅ') ch = 'ㅆ'; else if(ch == 'ㅈ') ch = 'ㅉ'; else if(ch == 'ㅐ') ch = 'ㅒ'; else if(ch == 'ㅔ') ch = 'ㅖ'; } var p, _c = _composible_hangul(this.buffer[this.buffer.length-1], ch), v = HanTools.JUNGSEONG.indexOf(ch) >= 0; if(v){ if(_c){ this.buffer[this.buffer.length-1] = _c; return; } if(this.buffer.length >= 3){ p = this.buffer.pop(); this.flushBuffer(); this.buffer.push(p, ch); }else if(this.buffer.length == 2){ this.flushBuffer(); this.buffer.push(null, ch); }else{ if(this.buffer.length == 0) this.buffer.push(null); this.buffer.push(ch); } }else{ if(this.buffer.length == 0) this.buffer.push(ch); else if(this.buffer[0] == null){ this.flushBuffer(); this.buffer.push(ch); }else if(this.buffer.length == 1 && _c) this.buffer[0] = _c; else if(this.buffer.length == 2 || this.buffer.length == 3 && _c) this.buffer.push(ch); else{ this.flushBuffer(); this.buffer.push(ch); } } }else{ this.flushBuffer(); this.output += _qwerty_key_inv(key); } }, this); return this; }; Keyboard.SEBEOLSIK_390 = _extend(Keyboard, Keyboard); Keyboard.SEBEOLSIK_390.getKeySequence = function SEBEOLSIK_390_getKeySequence(str){ var seq = []; str.split('').map(HanTools.disintegrate).forEach(function(part){ var ind; if(typeof part == 'string'){ switch(part){ case 'ㅘ': seq.push(['v', false], ['f', false]); break; case 'ㅙ': seq.push(['v', false], ['r', false]); break; case 'ㅚ': seq.push(['v', false], ['d', false]); break; case 'ㅝ': seq.push(['b', false], ['f', false]); break; case 'ㅞ': seq.push(['b', false], ['c', false]); break; case 'ㅟ': seq.push(['b', false], ['d', false]); break; default: _push_multi(seq, _kor_key(SEBEOLSIK_390_MAP, part)); } }else{ _push_multi(seq, SEBEOLSIK_390_MAP[0][HanTools.CHOSEONG.indexOf(part[0])]); _push_multi(seq, SEBEOLSIK_390_MAP[1][HanTools.JUNGSEONG.indexOf(part[1])]); if(part.length == 3) _push_multi(seq, SEBEOLSIK_390_MAP[2][HanTools.JONGSEONG.indexOf(part[2])]); } }); return seq; }; Keyboard.SEBEOLSIK_390.type = Keyboard.type.bind(Keyboard.SEBEOLSIK_390); Keyboard.SEBEOLSIK_390.prototype.getBufferString = function SEBEOLSIK_390$getBufferString(){ return HanTools.compose(this.buffer); }; Keyboard.SEBEOLSIK_390.prototype.type = function SEBEOLSIK_390$type(seq){ seq.forEach(function(key){ var ch, part=0, _c; switch(ch=_qwerty_key_inv(key)){ case 'a': ch='ㅇ'; part=3; break; case 'A': ch='ㄷ'; part=3; break; case 'b': ch='ㅜ'; part=2; break; case 'B': ch='!'; part=0; break; case 'c': ch='ㅔ'; part=2; break; case 'C': ch='ㄻ'; part=3; break; case 'd': ch='ㅣ'; part=2; break; case 'D': ch='ㄺ'; part=3; break; case 'e': ch='ㅕ'; part=2; break; case 'E': ch='ㅋ'; part=3; break; case 'f': ch='ㅏ'; part=2; break; case 'F': ch='ㄲ'; part=3; break; case 'g': ch='ㅡ'; part=2; break; case 'G': ch='/'; part=3; break; case 'h': ch='ㄴ'; part=1; break; case 'H': ch='\''; part=0; break; case 'i': ch='ㅁ'; part=1; break; case 'I': ch='8'; part=0; break; case 'j': ch='ㅇ'; part=1; break; case 'J': ch='4'; part=0; break; case 'k': ch='ㄱ'; part=1; break; case 'K': ch='5'; part=0; break; case 'l': ch='ㅈ'; part=1; break; case 'L': ch='6'; part=0; break; case 'm': ch='ㅎ'; part=1; break; case 'M': ch='1'; part=0; break; case 'n': ch='ㅅ'; part=1; break; case 'N': ch='0'; part=0; break; case 'o': ch='ㅊ'; part=1; break; case 'O': ch='9'; part=0; break; case 'p': ch='ㅍ'; part=1; break; case 'P': ch='>'; part=0; break; case 'q': ch='ㅅ'; part=3; break; case 'Q': ch='ㅍ'; part=3; break; case 'r': ch='ㅐ'; part=2; break; case 'R': ch='ㅒ'; part=2; break; case 's': ch='ㄴ'; part=3; break; case 'S': ch='ㄶ'; part=3; break; case 't': ch='ㅓ'; part=2; break; case 'T': ch=';'; part=0; break; case 'u': ch='ㄷ'; part=1; break; case 'U': ch='7'; part=0; break; case 'v': ch='ㅗ'; part=2; break; case 'V': ch='ㅀ'; part=3; break; case 'w': ch='ㄹ'; part=3; break; case 'W': ch='ㅌ'; part=3; break; case 'x': ch='ㄱ'; part=3; break; case 'X': ch='ㅄ'; part=3; break; case 'y': ch='ㄹ'; part=1; break; case 'Y': ch='<'; part=0; break; case 'z': ch='ㅁ'; part=3; break; case 'Z': ch='ㅊ'; part=3; break; case '1': ch='ㅎ'; part=3; break; case '!': ch='ㅈ'; part=3; break; case '2': ch='ㅆ'; part=3; break; case '3': ch='ㅂ'; part=3; break; case '4': ch='ㅛ'; part=2; break; case '5': ch='ㅠ'; part=2; break; case '6': ch='ㅖ'; part=2; break; case '7': ch='ㅖ'; part=2; break; case '8': ch='ㅢ'; part=2; break; case '9': ch='ㅜ'; part=2; break; case '0': ch='ㅋ'; part=1; break; case '<': ch='2'; part=0; break; case '>': ch='3'; part=0; break; case ';': ch='ㅂ'; part=1; break; case '\'': ch='ㅌ'; part=1; break; case '/': if(this.buffer.length == 1){ch='ㅗ'; part=2;} break; default: part = 0; } if(part == 0){ this.flushBuffer(); this.output += ch; }else if(part == 1){ if(this.buffer[0]){ _c = !this.buffer[1] && this.buffer[0] == ch && _composible_hangul(this.buffer[0], ch); if(_c) this.buffer[0] = _c; else{ this.flushBuffer(); this.buffer.push(ch); } }else{ this.buffer[0] = ch; } }else if(part == 2){ if(this.buffer[1]){ _c = _composible_hangul(this.buffer[1], ch); if(_c) this.buffer[1] = _c; else{ this.flushBuffer(); this.buffer.push(null, ch); } }else{ if(!this.buffer[0]) this.buffer[0] = null; this.buffer[1] = ch; } }else if(part == 3){ if(this.buffer[2]){ _c = this.buffer[2] != ch || ch == 'ㄱ' || ch == 'ㅅ' ? _composible_hangul(this.buffer[2], ch) : null; if(_c) this.buffer[2] = _c; else{ this.flushBuffer(); this.buffer.push(null, null, ch); } }else{ if(!this.buffer[0]) this.buffer[0] = null; if(!this.buffer[1]) this.buffer[1] = null; this.buffer[2] = ch; } } }, this); return this; }; Keyboard.getKeySequence = Keyboard.QWERTY.getKeySequence; Keyboard.convert = function Keyboard_convert(text, from, to){ if(from == null) from = Keyboard.QWERTY; if(to == null) to = Keyboard.QWERTY; return to.type(from.getKeySequence(text)); }; return Keyboard; }; if((typeof exports) != 'undefined'){ if((typeof module) != 'undefined' && module.exports){ exports = module.exports = HanTools_Keyboard; } exports.HanTools_Keyboard = HanTools_Keyboard; }else{ root.HanTools_Keyboard = HanTools_Keyboard; } }).call(this);