Last active
May 7, 2022 13:55
-
-
Save RanolP/ccd8edb2a06aa03afa242f710013a76f to your computer and use it in GitHub Desktop.
rke(I like to call it '갇'), Replace Korean Entities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type TailId = -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27; | |
function tailIdOf(word: string): TailId { | |
if (word.length === 0) { | |
return -1; | |
} | |
const last = word[word.length - 1]; | |
if (last < '가' || '힣' < last) { | |
return -1; | |
} | |
// 위의 if 문에서 '가' <= last이므로 last.charCodeAt(0)은 양의 정수고 | |
// 그 값을 28로 나눈 나머지이므로 0 ~ 27 범위입니다. | |
// 따라서 TailId라고 단언할 수 있습니다. | |
return (last.charCodeAt(0) - 44032) % 28 as TailId; | |
} | |
export function rke(template: TemplateStringsArray, ...args: unknown[]): string { | |
let result = ''; | |
for (let i = 0; i < template.raw.length; i++) { | |
const argument = i == 0 ? null : String(args[i - 1]); | |
if (argument !== null) { | |
result += argument; | |
} | |
const current = template.raw[i]; | |
if (current.length === 0) { | |
continue; | |
} | |
const [head, ...splitted] = current.split('\\'); | |
result += head; | |
for (const token of splitted) { | |
const tail = tailIdOf(result); | |
switch (token[0]) { | |
case '은': | |
case '는': | |
result += tail === -1 ? '은(는)' : tail !== 0 ? '은' : '는'; | |
result += token.slice(1); | |
break; | |
case '이': | |
if (token.length > 1 && token[1] != ' ') { | |
result += tail === -1 ? '(이)' : tail !== 0 ? '이' : ''; | |
result += token.slice(1); | |
break; | |
} | |
case '가': | |
result += tail === -1 ? '이(가)' : tail !== 0 ? '이' : '가'; | |
result += token.slice(1); | |
break; | |
case '을': | |
case '를': | |
result += tail === -1 ? '을(를)' : tail !== 0 ? '을' : '를'; | |
result += token.slice(1); | |
break; | |
case '와': | |
case '과': | |
result += tail === -1 ? '와(과)' : tail !== 0 ? '과' : '와'; | |
result += token.slice(1); | |
break; | |
case '으': | |
result += tail === -1 ? '(으)' : tail !== 0 && tail !== 8 ? '으' : ''; | |
result += token.slice(1); | |
break; | |
default: | |
result += token; | |
continue; | |
} | |
} | |
} | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
아래 코드를 복사해서 콘솔에서 테스트해보세요! (압축한 버전과 타입을 제거한 버전입니다, 둘 중 하나를 쓰세요)