first hangul ime

This commit is contained in:
minjaesong
2021-10-22 15:40:41 +09:00
parent 026ea1d9f3
commit 1c370ac610
5 changed files with 560 additions and 27 deletions

View File

@@ -0,0 +1,377 @@
let states = {"keylayouts":[[""],[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
["\u110F",")"],
["\u11C2","\u11BD"],
["\u11BB","@"],
["\u11B8","#"],
["\u116D","$"],
["\u1172","%"],
["\u1163","^"],
["\u1168","&"],
["\u1174","*"],
["\u116E","("],
["*"],
["#"],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
["\u11BC","\u11AE"],
["\u116E","!"],
["\u1166","\u11B1"],
["\u1175","\u11B0"],
["\u1167","\u11BF"],
["\u1161","\u11A9"],
["\u1173","/"],
["\u1102","'"],
["\u1106","8"],
["\u110B","4"],
["\u1100","5"],
["\u110C","6"],
["\u1112","1"],
["\u1109","0"],
["\u110E","9"],
["\u1111",">"],
["\u11BA","\u11C1"],
["\u1162","\u1164"],
["\u11AB","\u11AD"],
["\u1165",";"],
["\u1103","7"],
["\u1169","\u11B6"],
["\u11AF","\u11C0"],
["\u11A8","\u11B9"],
["\u1105","<"],
["\u11B7","\u11BE"],
[",","2"],
[".","3"],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[" "],
[undefined],
[undefined],
[undefined],
["\n"],
["\x08"],
["`","~"],
["-","_"],
["=","+"],
["[","{"],
["]","}"],
["\\","|"],
["\u1107",":"],
["\u1110",'"'],
["\u1169","?"],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined]
],
"code":0,
"buf":[]}
let reset = () => {
states.code = 0
states.buf = []
}
let inRange = (s,a,b) => (a <= s && s <= b)
let isHangul = (s) => (s === undefined) ? false : inRange(s.charCodeAt(0), 0x1100, 0x11C2)
let isChoseong = (s) => (s === undefined) ? false : inRange(s.charCodeAt(0), 0x1100, 0x1112)
let isJungseong = (s) => (s === undefined) ? false : inRange(s.charCodeAt(0), 0x1161, 0x1175)
let isJongseong = (s) => (s === undefined) ? false : inRange(s.charCodeAt(0), 0x11A8, 0x11C2)
let isChoseongDigraph = (s) => (s === undefined) ? false : ([0x1100, 0x1103, 0x1107, 0x1109, 0x110C].includes(s.charCodeAt(0)))
let isJungseongDigraph1 = (s) => (s === undefined) ? false : ([0x1169, 0x116E].includes(s.charCodeAt(0)))
let isJungseongDigraphO = (s) => (s === undefined) ? false : ([0x1161, 0x1162, 0x1175].includes(s.charCodeAt(0)))
let isJungseongDigraphU = (s) => (s === undefined) ? false : ([0x1165, 0x1166, 0x1175].includes(s.charCodeAt(0)))
let isJungseongDigraphEU = (s) => (s === undefined) ? false : ([0x1175].includes(s.charCodeAt(0)))
let isJongseongDigraphG = (s) => (s === undefined) ? false : ([0x11A8, 0x11BA].includes(s.charCodeAt(0)))
let isJongseongDigraphN = (s) => (s === undefined) ? false : ([0x11BD, 0x11C2].includes(s.charCodeAt(0)))
let isJongseongDigraphR = (s) => (s === undefined) ? false : ([0x11A8, 0x11B7, 0x11B8, 0x11BA, 0x11C0, 0x11C1, 0x11C2].includes(s.charCodeAt(0)))
let isJongseongDigraphB = (s) => (s === undefined) ? false : ([0x11BA].includes(s.charCodeAt(0)))
let choseongDigraphs = {"\u1100":"\u1101", "\u1103":"\u1104", "\u1107":"\u1108", "\u1109":"\u110A", "\u110C":"\u110D"}
let jungseongDigraphsO = {"\u1161":"\u116A", "\u1162":"\u116B", "\u1175":"\u116C"}
let jungseongDigraphsU = {"\u1165":"\u116F", "\u1166":"\u1170", "\u1175":"\u1171"}
let jungseongDigraphsEU = {"\u1175":"\u1174"}
let jongseongDigraphsG = {"\u11A8":"\u11A9", "\u11BA":"\u11AA"}
let jongseongDigraphsN = {"\u11BD":"\u11AC", "\u11C2":"\u11AD"}
let jongseongDigraphsR = {"\u11A8":"\u11B0", "\u11B7":"\u11B1", "\u11B8":"\u11B2", "\u11BA":"\u11B3", "\u11C0":"\u11B4", "\u11C1":"\u11B5", "\u11C2":"\u11B6"}
let jongseongDigraphsB = {"\u11BA":"\u11B9"}
let bufAssemble = () => {
if (states.buf[0] === undefined && states.buf[1] === undefined && states.buf[2] === undefined)
return ''
else if (states.buf[1] === undefined && isHangul(states.buf[0]))
return [states.buf[0], "\u1160", states.buf[2]].join('')
else if (states.buf[0] === undefined && isHangul(states.buf[1]))
return ["\u115F", states.buf[1], states.buf[2]].join('')
else if (isHangul(states.buf[2]) && states.buf[0] === undefined && states.buf[1] === undefined )
return ["\u115F", "\u1160", states.buf[2]].join('')
else
return states.buf.join('')
}
Object.freeze({"n":"세벌식 3-90","states":states,
// return: [displayed output, composed output]
"accept":(keycodes,shiftin,altgrin)=>{
let layer = 1*shiftin// + 2*altgrin
states.code = 1
let purekeys = keycodes.filter(it => (
inRange(it,7,18) || // numeric
inRange(it,29,56) || // alph
it == 62 || // space
inRange(it,66,76) || // symbols
inRange(it,144,163) // numpad
))
let headkey = purekeys[0]
let s = states.keylayouts[headkey][layer]
let bufIndex = isJungseong(s) ? 1 : isJongseong(s) ? 2 : 0
console.log(`IME accepting keycodes ${keycodes}`)
if (isHangul(s)) {
// ㄲ ㄸ ㅃ ㅆ ㅉ
if (0 == bufIndex && isChoseongDigraph(states.buf[0]) && isChoseongDigraph(s)) {
states.buf[0] = choseongDigraphs[s]
}
// ㅘ ㅙ ㅚ
else if (1 == bufIndex && "\u1169" == states.buf[1] && isJungseongDigraphO(s)) {
states.buf[1] = jungseongDigraphsO[s]
}
// ㅝ ㅞ ㅟ
else if (1 == bufIndex && "\u116E" == states.buf[1] && isJungseongDigraphU(s)) {
states.buf[1] = jungseongDigraphsU[s]
}
// ㅢ
else if (1 == bufIndex && "\u1173" == states.buf[1] && isJungseongDigraphEU(s)) {
states.buf[1] = jungseongDigraphsEU[s]
}
// ㄲ ㄳ
else if (2 == bufIndex && "\u11A8" == states.buf[2] && isJongseongDigraphG(s)) {
states.buf[2] = jongseongDigraphsG[s]
}
// ㄵ ㄶ
else if (2 == bufIndex && "\u11AB" == states.buf[2] && isJongseongDigraphN(s)) {
states.buf[2] = jongseongDigraphsN[s]
}
// ㄺ ㄻ ㄼ ㄽ ㄾ ㄿ ㅀ
else if (2 == bufIndex && "\u11AF" == states.buf[2] && isJongseongDigraphR(s)) {
states.buf[2] = jongseongDigraphsR[s]
}
// ㅄ
else if (2 == bufIndex && "\u11B8" == states.buf[2] && isJongseongDigraphB(s)) {
states.buf[2] = jongseongDigraphsB[s]
}
// key inputs that bufIndex collides (end compose and accept incoming char as a new char state)
else if (states.buf[bufIndex] !== undefined) {
let sendout = bufAssemble(); reset()
states.buf[bufIndex] = s
console.log(`sending out: ${sendout}`)
return [bufAssemble(), sendout]
}
else {
states.buf[bufIndex] = s
console.log(`assembling: ${bufAssemble()}`)
}
return [bufAssemble(), ""]
}
else {
let sendout = bufAssemble() + s; reset()
console.log(`sending out: ${sendout}`)
return [bufAssemble(), sendout]
}
},
"end":()=>{
console.log(`end composing`)
reset()
return bufAssemble()
},
"reset":()=>{ reset() },
"composing":()=>(states.code!=0)
})