ktrans: correct Korean input (thanks npmania!)

This patch implements two specific behaviors of Dubeolsik layout.

dubeollkup function makes Jongseong(final consonant) to be treated as
Choseong(initial consonant) when possible. For example, QWERTY input
"zhem" in Dubeolsik has to be "코드", not "콛ㅡ" where switched
Jongseong is "ㄷ".

dubeolbksp function emits out syllable remaining after single
backspace. So when user presses backspace on "코드", the expected output
is "코ㄷ", still allowing user to edit latter syllable, rather than
"코" without dubeolbksp. This should only apply to last syllable
considering it's de facto in Dubeolsik implementations.
This commit is contained in:
Jacob Moody 2024-04-02 03:55:16 +00:00
parent f4122cfbc9
commit 68512a3f66
4 changed files with 11246 additions and 2366 deletions

File diff suppressed because it is too large Load diff

View file

@ -51,7 +51,7 @@ Chinese.
ctl-c and zh
.TP
Korean.
ctl-k and ko
ctl-s and ko
.TP
Vietnamese.
ctl-v and vn
@ -199,8 +199,8 @@ Implicit conversion is modeled after Telex, supporting
standard diacritic suffixes.
.SS KOREAN
Mapping is done by emulating a Dubeolsik layout, with each Latin
character mapping to a single Jamo. Sequences of up to three Jamo
are automatically converted to Hangul syllables.
character mapping to a single Jamo. Sequences of Jamo are automatically
converted to Hangul syllables.
.SH EXAMPLES
To type the following Japanese text:

View file

@ -670,6 +670,59 @@ telexlkup(Str *line)
}
}
static void
dubeolbksp(Str *line)
{
Map lkup;
popstr(line);
/* lookup and emit remaining Jamo to output */
if(hmapget(hangul, line->b, &lkup) < 0)
return;
emitutf(output, lkup.kana, 0);
}
static void
dubeollkup(Str *line)
{
Map lkup;
char buf[UTFmax*2];
char *e2, *e1;
e1 = peekstr(line->p, line->b);
if(e1 != line->b){
e2 = peekstr(e1, line->b);
pushutf(buf, buf+sizeof buf, e2, utflen(e2));
}else
pushutf(buf, buf+sizeof buf, e1, utflen(e1));
if(hmapget(hangul, line->b, &lkup) < 0){
if(hmapget(hangul, buf, &lkup) < 0){
resetstr(line, nil);
line->p = pushutf(line->p, strend(line), e1, utflen(e1));
if(hmapget(hangul, line->b, &lkup) < 0)
return;
}else{
/* treat Jongseong as Choseong when it matches with new Jamo */
popstr(line);
popstr(line);
hmapget(hangul, line->b, &lkup);
emitutf(output, backspace, 2);
emitutf(output, lkup.kana, 0);
hmapget(hangul, buf, &lkup);
emitutf(output, lkup.kana, 0);
line->p = pushutf(line->b, strend(line), buf, utflen(buf));
return;
}
}
if(utflen(line->b) == 1)
emitutf(output, backspace, 1);
else
emitutf(output, backspace, 2);
emitutf(output, lkup.kana, 0);
}
static void
keythread(void*)
{
@ -737,6 +790,10 @@ keythread(void*)
resetstr(&line, nil);
continue;
} else if(r == '\b'){
if(lang == LangKO){
dubeolbksp(&line);
continue;
}
popstr(&line);
continue;
}
@ -745,6 +802,9 @@ keythread(void*)
if(lang == LangVN){
telexlkup(&line);
continue;
}else if(lang == LangKO){
dubeollkup(&line);
continue;
}
if(maplkup(lang, line.b, &lkup) < 0){
resetstr(&line, nil);

View file

@ -43,6 +43,10 @@ struct {
" ddaua", L"đâu",
" hoir", L"hỏi",
" gi of", L"giò",
"gpffhdnjfemsms wlruqwksw\bgdk, wha tlstjsgks rj djqtdj?",
L"헬로월드는 지겹잖아, 좀 신선한 거 없어?",
};
char*