/* * Nabi on Javascript 0.1 * This program is based on Nabi 0.13 * nskystars at yahoo dot com */ /* user defined functions: function user_commit(Array buf); function user_commit_keyval(char keyval); function user_preedit_insert(Array buf); function user_preedit_update(Array buf); call nabi_automata_2(char keyval) to use hangul_automata TODO: Support for Sebulsik(390, final...), Dvorak keyboards */ /* hangul.c */ function hangul_is_choseong(ch) { return (ch >= 0x1100 && ch <= 0x1159) ? 1 : 0; } function hangul_is_jungseong(ch) { return (ch >= 0x1161 && ch <= 0x11a2) ? 1 : 0; } function hangul_is_jongseong(ch) { return (ch >= 0x11a7 && ch <= 0x11f9) ? 1 : 0; } function hangul_choseong_to_cjamo(ch) { var table = new Array( 0x3131, /* 0x1100 */ 0x3132, /* 0x1101 */ 0x3134, 0x3137, 0x3138, 0x3139, 0x3141, 0x3142, 0x3143, 0x3145, 0x3146, 0x3147, 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, /* 0x1111 */ 0x314e /* 0x1112 */ ); if(ch < 0x1100 || ch > 0x1112) return ch; return table[ch - 0x1100]; } function hangul_jungseong_to_cjamo(ch) { var table = new Array( 0x314f, /* 0x1161 */ 0x3150, /* 0x1162 */ 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 0x3160, 0x3161, 0x3162, /* 0x1174 */ 0x3163 /* 0x1175 */ ); if(ch < 0x1161 || ch > 0x1175) return 0; return table[ch - 0x1161]; } function hangul_jongseong_to_cjamo(ch) { var table = new Array( 0x3131, /* 0x11a8 */ 0x3132, /* 0x11a9 */ 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 0x3140, 0x3141, 0x3142, 0x3144, 0x3145, 0x3146, 0x3147, 0x3148, 0x314a, 0x314b, 0x314c, 0x314d, /* 0x11c1 */ 0x314e /* 0x11c2 */ ); if(ch < 0x11a8 || ch > 0x11c2) return 0; return table[ch - 0x11a8]; } function hangul_choseong_to_jongseong(ch) { var table = new Array( 0x11a8, /* kiyeok */ 0x11a9, 0x11ab, 0x11ae, 0x0, 0x11af, 0x11b7, 0x11b8, 0x0, 0x11ba, 0x11bb, 0x11bc, 0x11bd, 0x0, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2 ); if(ch < 0x1100 || ch > 0x1112) return 0; return table[ch - 0x1100]; } function hangul_jongseong_to_choseong(ch) { var table = new Array( 0x1100, /* kiyeok */ 0x1101, 0x1109, 0x1102, 0x110c, 0x1112, 0x1103, 0x1105, 0x1100, 0x1106, 0x1107, 0x1109, 0x1110, 0x1111, 0x1112, 0x1106, 0x1107, 0x1109, 0x1109, 0x110a, 0x110b, 0x110c, 0x110e, 0x110f, 0x1110, 0x1111, 0x1112 ); if(ch < 0x11a8 || ch > 0x11c2) return 0; return table[ch - 0x11a8]; } function hangul_jongseong_dicompose(ch) { var table = new Array( 0, 0x1100, /* jong kiyeok = cho kiyeok */ 0x11a8, 0x1100, 0x11a8, 0x1109, 0, 0x1102, 0x11ab, 0x110c, 0x11ab, 0x1112, 0, 0x1103, 0, 0x1105, 0x11af, 0x1100, 0x11af, 0x1106, 0x11af, 0x1107, 0x11af, 0x1109, 0x11af, 0x1110, 0x11af, 0x1111, 0x11af, 0x1112, 0, 0x1106, 0, 0x1107, 0x11b8, 0x1109, 0, 0x1109, 0x11ba, 0x1109, 0, 0x110b, 0, 0x110c, 0, 0x110e, 0, 0x110f, 0, 0x1110, 0, 0x1111, 0, 0x1112 ); jong = table[(ch - 0x11a8) * 2]; cho = table[(ch - 0x11a8) * 2 + 1]; return new Array(jong, cho); } function hangul_jamo_to_syllable(loc_choseong, loc_jungseong, loc_jongseong) { var hangul_base = 0xac00; var choseong_base = 0x1100; var jungseong_base = 0x1161; var jongseong_base = 0x11a7; var njungseong = 21; var njongseong = 28; var ch; if(loc_jongseong == 0) loc_jongseong = 0x11a7; if(!(loc_choseong >= 0x1100 && loc_choseong <= 0x1112)) return 0; if(!(loc_jungseong >= 0x1161 && loc_jungseong <= 0x1175)) return 0; if(!(loc_jongseong >= 0x11a7 && loc_jongseong <= 0x11c2)) return 0; loc_choseong -= choseong_base; loc_jungseong -= jungseong_base; loc_jongseong -= jongseong_base; ch = ((loc_choseong * njungseong) + loc_jungseong) * njongseong + loc_jongseong + hangul_base; return ch; } /* keyboard.h */ var keyboard_map_2 = new Array( 0x0021, // exclam 0x0022, // dbl quotes 0x0023, // sharp 0x0024, // dollar 0x0025, // percent 0x0026, // ampersand 0x0027, // single quotes 0x0028, // small bracket open 0x0029, // small bracket close 0x002A, // star 0x002B, // plus 0x002C, // comma 0x002D, // minus 0x002E, // period 0x002F, // slash 0x0030, // 0 0x0031, // 1 0x0032, // 2 0x0033, // 3 0x0034, // 4 0x0035, // 5 0x0036, // 6 0x0037, // 7 0x0038, // 8 0x0039, // 9 0x003A, // colon 0x003B, // semicolon 0x003C, // greater than 0x003D, // eq 0x003E, // less than 0x003F, // question 0x0040, // at 0x1106, // mi-eum 0x1172, // yu 0x110E, // che-ot 0x110B, // i-ung 0x1104, // ssang di-gut 0x1105, // ri-eul 0x1112, // hi-eut 0x1169, // oh 0x1163, // ya 0x1165, // euh 0x1161, // a 0x1175, // i 0x1173, // eu 0x116E, // u 0x1164, // ssang a, i 0x1168, // ssang euo, i 0x1108, // ssang bi-eup 0x1101, // ssang gi-eok 0x1102, // ni-eun 0x110A, // ssang si-eot 0x1167, // yeo 0x1111, // pi-eup 0x110D, // ssang ji-eut 0x1110, // ti-eut 0x116D, // yo 0x110F, // ki-euk 0x005B, // large bracket open 0x005C, // backslash 0x005D, // large bracket close 0x005E, // power 0x005F, // underscore 0x0060, // backquote 0x1106, // mi-eum 0x1172, // yu 0x110E, // che-ot 0x110B, // i-ung 0x1103, // di-gut 0x1105, // ri-eul 0x1112, // hi-eut 0x1169, // oh 0x1163, // ya 0x1165, // euh 0x1161, // a 0x1175, // i 0x1173, // eu 0x116E, // u 0x1162, // a, i 0x1166, // euo, i 0x1107, // bi-eup 0x1100, // gi-eok 0x1102, // ni-eun 0x1109, // si-eot 0x1167, // yeo 0x1111, // pi-eup 0x110C, // ji-eut 0x1110, // ti-eut 0x116D, // yo 0x110F, // ki-euk 0x007B, // med bracket open 0x007C, // strgt line vert 0x007D, // med bracket close 0x007E // tilde ); /* ic.h */ // NabiIC var index; var stack = new Array(); var choseong = new Array(); var jungseong = new Array(); var jongseong = new Array(); function nabi_ic_is_empty() { return (choseong[0] == 0 && jungseong[0] == 0 && jongseong[0] == 0) ? 1 : 0; } /* ic.c */ function nabi_ic_push(ch) { stack[++index] = ch; } function nabi_ic_peek() { if(index < 0) return 0; return stack[index]; } function nabi_ic_pop() { if(index < 0) return 0; return stack[index--]; } function nabi_ic_buf_clear() { index = -1; stack[0] = 0; stack[1] = 0; stack[2] = 0; stack[3] = 0; stack[4] = 0; stack[5] = 0; stack[6] = 0; stack[7] = 0; stack[8] = 0; stack[9] = 0; stack[10] = 0; stack[11] = 0; choseong[0] = 0; choseong[1] = 0; choseong[2] = 0; choseong[3] = 0; jungseong[0] = 0; jungseong[1] = 0; jungseong[2] = 0; jungseong[3] = 0; jongseong[0] = 0; jongseong[1] = 0; jongseong[2] = 0; jongseong[3] = 0; } function nabi_ic_commit() { var buf = new Array(); if(nabi_ic_is_empty()) { return 0; } var n = 0; var ch; ch = hangul_jamo_to_syllable(choseong[0], jungseong[0], jongseong[0]); if(ch) buf[n++] = ch; else { if(choseong[0]) { ch = hangul_choseong_to_cjamo(choseong[0]); buf[n++] = ch; } if(jungseong[0]) { ch = hangul_jungseong_to_cjamo(jungseong[0]); buf[n++] = ch; } if(jongseong[0]) { ch = hangul_jongseong_to_cjamo(jongseong[0]); buf[n++] = ch; } } user_commit(buf); nabi_ic_buf_clear(); } function nabi_ic_commit_keyval(keyval) { user_commit_keyval(keyval); } function nabi_ic_get_preedit_string() { var ch; var buf = new Array(); var n = 0; if(choseong[0]) { if(jungseong[0]) { ch = hangul_jamo_to_syllable(choseong[0], jungseong[0], jongseong[0]); buf[n++] = ch; } else { if(jongseong[0]) { ch = hangul_choseong_to_cjamo(choseong[0]); buf[n++] = ch; ch = hangul_jongseong_to_cjamo(jongseong[0]); buf[n++] = ch; } else { ch = hangul_choseong_to_cjamo(choseong[0]); buf[n++] = ch; } } } else { if(jungseong[0]) { if(jongseong[0]) { ch = hangul_jungseong_to_cjamo(jungseong[0]); buf[n++] = ch; ch = hangul_jongseong_to_cjamo(jongseong[0]); buf[n++] = ch; } else { ch = hangul_jungseong_to_cjamo(jungseong[0]); buf[n++] = ch; } } else { if(jongseong[0]) { ch = hangul_jongseong_to_cjamo(jongseong[0]); buf[n++] = ch; } else { ; /* have nothing */ } } } return buf; } function nabi_ic_preedit_insert() { buf = nabi_ic_get_preedit_string(); user_preedit_insert(buf); } function nabi_ic_preedit_update() { buf = nabi_ic_get_preedit_string(); user_preedit_update(buf); } /* compose table from iiimf-hangul */ var compose_table_default = new Array( 0x1100, 0x1100, 0x1101, /* chosung kiyeok + kiyeok = ssangkiyeok */ 0x1103, 0x1103, 0x1104, 0x1107, 0x1107, 0x1108, 0x1109, 0x1109, 0x110A, 0x110C, 0x110C, 0x110D, 0x1169, 0x1161, 0x116A, 0x1169, 0x1162, 0x116B, 0x1169, 0x1175, 0x116C, 0x116E, 0x1165, 0x116F, 0x116E, 0x1166, 0x1170, 0x116E, 0x1175, 0x1171, 0x1173, 0x1175, 0x1174, 0x11A8, 0x11A8, 0x11A9, 0x11A8, 0x11BA, 0x11AA, 0x11AB, 0x11BD, 0x11AC, 0x11AB, 0x11C2, 0x11AD, 0x11AF, 0x11A8, 0x11B0, 0x11AF, 0x11B7, 0x11B1, 0x11AF, 0x11B8, 0x11B2, 0x11AF, 0x11BA, 0x11B3, 0x11AF, 0x11C0, 0x11B4, 0x11AF, 0x11C1, 0x11B5, 0x11AF, 0x11C2, 0x11B6, 0x11B8, 0x11BA, 0x11B9, 0x11BA, 0x11BA, 0x11BB ); /* automata.c */ function hangul_compose(first, last) { var cpr; for(cpr in compose_table_default) { if(compose_table_default[cpr * 3] == first && compose_table_default[cpr * 3 + 1] == last) { return compose_table_default[cpr * 3 + 2]; } } return 0; } function nabi_keyboard_mapping(keyval) { return keyboard_map_2[keyval - 0x0021]; } function nabi_automata_2(keyval) { var ch; ch = nabi_keyboard_mapping(keyval.charCodeAt(0)); if(jongseong[0]) { if(hangul_is_choseong(ch)) { jong_ch = hangul_choseong_to_jongseong(ch); comp_ch = hangul_compose(jongseong[0], jong_ch); if(hangul_is_jongseong(comp_ch)) { jongseong[0] = comp_ch; nabi_ic_push(comp_ch); } else { nabi_ic_commit(); choseong[0] = ch; nabi_ic_push(ch); nabi_ic_preedit_insert(); return 0; } nabi_ic_preedit_update(); return 0; } if(hangul_is_jungseong(ch)) { var pop, peek; pop = nabi_ic_pop(); peek = nabi_ic_peek(); if(hangul_is_jungseong(peek)) { jongseong[0] = 0; nabi_ic_commit(); choseong[0] = hangul_jongseong_to_choseong(pop); jungseong[0] = ch; nabi_ic_push(choseong[0]); nabi_ic_push(ch); } else { var loc_choseong, loc_jongseong; ret_arr = hangul_jongseong_dicompose(jongseong[0]); loc_jongseong = ret_arr[0]; loc_choseong = ret_arr[1]; jongseong[0] = loc_jongseong; nabi_ic_commit(); choseong[0] = loc_choseong; jungseong[0] = ch; nabi_ic_push(loc_choseong); nabi_ic_push(ch); } nabi_ic_preedit_insert(); return 0; } } else if(jungseong[0]) { if(hangul_is_choseong(ch)) { if(choseong[0]) { jong_ch = hangul_choseong_to_jongseong(ch); if(hangul_is_jongseong(jong_ch)) { jongseong[0] = jong_ch; nabi_ic_push(jong_ch); } else { nabi_ic_commit(); choseong[0] = ch; nabi_ic_push(ch); nabi_ic_preedit_insert(); return 0; } } else { choseong[0] = ch; nabi_ic_push(ch); } nabi_ic_preedit_update(); return 0; } if(hangul_is_jungseong(ch)) { comp_ch = hangul_compose(jungseong[0], ch); if(hangul_is_jungseong(comp_ch)) { jungseong[0] = comp_ch; nabi_ic_push(comp_ch); } else { nabi_ic_commit(); jongseong[0] = ch; nabi_ic_push(ch); nabi_ic_preedit_insert(); return 0; } nabi_ic_preedit_update(); return 0; } } else if(choseong[0]) { if(hangul_is_choseong(ch)) { comp_ch = hangul_compose(choseong[0], ch); if(hangul_is_choseong(comp_ch)) { choseong[0] = comp_ch; nabi_ic_push(comp_ch); } else { nabi_ic_commit(); choseong[0] = ch; nabi_ic_push(ch); nabi_ic_preedit_insert(); return 0; } nabi_ic_preedit_update(); return 0; } if(hangul_is_jungseong(ch)) { jungseong[0] = ch; nabi_ic_push(ch); nabi_ic_preedit_update(); return 0; } } else { if(hangul_is_choseong(ch)) { choseong[0] = ch; nabi_ic_push(ch); nabi_ic_preedit_insert(); return 0; } else if(hangul_is_jungseong(ch)) { jungseong[0] = ch; nabi_ic_push(ch); nabi_ic_preedit_insert(); return 0; } } nabi_ic_commit(); nabi_ic_commit_keyval(keyval); return 0; } /* debug */ function debug_output() { alert_str = "OUTPUT\n" + "stack[0]: " + stack[0] + "\n" + "stack[1]: " + stack[1] + "\n" + "stack[2]: " + stack[2] + "\n" + "stack[3]: " + stack[3] + "\n" + "stack[4]: " + stack[4] + "\n" + "stack[5]: " + stack[5] + "\n" + "stack[6]: " + stack[6] + "\n" + "stack[7]: " + stack[7] + "\n" + "stack[8]: " + stack[8] + "\n" + "stack[9]: " + stack[9] + "\n" + "stack[10]: " + stack[10] + "\n" + "stack[11]: " + stack[11] + "\n" + "choseong[0]: " + choseong[0] + "\n" + "choseong[1]: " + choseong[1] + "\n" + "choseong[2]: " + choseong[2] + "\n" + "choseong[3]: " + choseong[3] + "\n" + "jungseong[0]: " + jungseong[0] + "\n" + "jungseong[1]: " + jungseong[1] + "\n" + "jungseong[2]: " + jungseong[2] + "\n" + "jungseong[3]: " + jungseong[3] + "\n" + "jongseong[0]: " + jongseong[0] + "\n" + "jongseong[1]: " + jongseong[1] + "\n" + "jongseong[2]: " + jongseong[2] + "\n" + "jongseong[3]: " + jongseong[3]; alert(alert_str); }