monaco-editor-core
Version:
A browser based code editor
320 lines (319 loc) • 12.4 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// allow-any-unicode-comment-file
/**
* Gets alternative Korean characters for the character code. This will return the ascii
* character code(s) that a Hangul character may have been input with using a qwerty layout.
*
* This only aims to cover modern (not archaic) Hangul syllables.
*
* @param code The character code to get alternate characters for
*/
export function getKoreanAltChars(code) {
const result = disassembleKorean(code);
if (result && result.length > 0) {
return new Uint32Array(result);
}
return undefined;
}
let codeBufferLength = 0;
const codeBuffer = new Uint32Array(10);
function disassembleKorean(code) {
codeBufferLength = 0;
// Initial consonants (초성)
getCodesFromArray(code, modernConsonants, 4352 /* HangulRangeStartCode.InitialConsonant */);
if (codeBufferLength > 0) {
return codeBuffer.subarray(0, codeBufferLength);
}
// Vowels (중성)
getCodesFromArray(code, modernVowels, 4449 /* HangulRangeStartCode.Vowel */);
if (codeBufferLength > 0) {
return codeBuffer.subarray(0, codeBufferLength);
}
// Final consonants (종성)
getCodesFromArray(code, modernFinalConsonants, 4520 /* HangulRangeStartCode.FinalConsonant */);
if (codeBufferLength > 0) {
return codeBuffer.subarray(0, codeBufferLength);
}
// Hangul Compatibility Jamo
getCodesFromArray(code, compatibilityJamo, 12593 /* HangulRangeStartCode.CompatibilityJamo */);
if (codeBufferLength) {
return codeBuffer.subarray(0, codeBufferLength);
}
// Hangul Syllables
if (code >= 0xAC00 && code <= 0xD7A3) {
const hangulIndex = code - 0xAC00;
const vowelAndFinalConsonantProduct = hangulIndex % 588;
// 0-based starting at 0x1100
const initialConsonantIndex = Math.floor(hangulIndex / 588);
// 0-based starting at 0x1161
const vowelIndex = Math.floor(vowelAndFinalConsonantProduct / 28);
// 0-based starting at 0x11A8
// Subtract 1 as the standard algorithm uses the 0 index to represent no
// final consonant
const finalConsonantIndex = vowelAndFinalConsonantProduct % 28 - 1;
if (initialConsonantIndex < modernConsonants.length) {
getCodesFromArray(initialConsonantIndex, modernConsonants, 0);
}
else if (4352 /* HangulRangeStartCode.InitialConsonant */ + initialConsonantIndex - 12593 /* HangulRangeStartCode.CompatibilityJamo */ < compatibilityJamo.length) {
getCodesFromArray(4352 /* HangulRangeStartCode.InitialConsonant */ + initialConsonantIndex, compatibilityJamo, 12593 /* HangulRangeStartCode.CompatibilityJamo */);
}
if (vowelIndex < modernVowels.length) {
getCodesFromArray(vowelIndex, modernVowels, 0);
}
else if (4449 /* HangulRangeStartCode.Vowel */ + vowelIndex - 12593 /* HangulRangeStartCode.CompatibilityJamo */ < compatibilityJamo.length) {
getCodesFromArray(4449 /* HangulRangeStartCode.Vowel */ + vowelIndex - 12593 /* HangulRangeStartCode.CompatibilityJamo */, compatibilityJamo, 12593 /* HangulRangeStartCode.CompatibilityJamo */);
}
if (finalConsonantIndex >= 0) {
if (finalConsonantIndex < modernFinalConsonants.length) {
getCodesFromArray(finalConsonantIndex, modernFinalConsonants, 0);
}
else if (4520 /* HangulRangeStartCode.FinalConsonant */ + finalConsonantIndex - 12593 /* HangulRangeStartCode.CompatibilityJamo */ < compatibilityJamo.length) {
getCodesFromArray(4520 /* HangulRangeStartCode.FinalConsonant */ + finalConsonantIndex - 12593 /* HangulRangeStartCode.CompatibilityJamo */, compatibilityJamo, 12593 /* HangulRangeStartCode.CompatibilityJamo */);
}
}
if (codeBufferLength > 0) {
return codeBuffer.subarray(0, codeBufferLength);
}
}
return undefined;
}
function getCodesFromArray(code, array, arrayStartIndex) {
// Verify the code is within the array's range
if (code >= arrayStartIndex && code < arrayStartIndex + array.length) {
addCodesToBuffer(array[code - arrayStartIndex]);
}
}
function addCodesToBuffer(codes) {
// NUL is ignored, this is used for archaic characters to avoid using a Map
// for the data
if (codes === 0 /* AsciiCode.NUL */) {
return;
}
// Number stored in format: OptionalThirdCode << 16 | OptionalSecondCode << 8 | Code
codeBuffer[codeBufferLength++] = codes & 0xFF;
if (codes >> 8) {
codeBuffer[codeBufferLength++] = (codes >> 8) & 0xFF;
}
if (codes >> 16) {
codeBuffer[codeBufferLength++] = (codes >> 16) & 0xFF;
}
}
/**
* Hangul Jamo - Modern consonants #1
*
* Range U+1100..U+1112
*
* | | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
* |--------|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
* | U+110x | ᄀ | ᄁ | ᄂ | ᄃ | ᄄ | ᄅ | ᄆ | ᄇ | ᄈ | ᄉ | ᄊ | ᄋ | ᄌ | ᄍ | ᄎ | ᄏ |
* | U+111x | ᄐ | ᄑ | ᄒ |
*/
const modernConsonants = new Uint8Array([
114 /* AsciiCode.r */, // ㄱ
82 /* AsciiCode.R */, // ㄲ
115 /* AsciiCode.s */, // ㄴ
101 /* AsciiCode.e */, // ㄷ
69 /* AsciiCode.E */, // ㄸ
102 /* AsciiCode.f */, // ㄹ
97 /* AsciiCode.a */, // ㅁ
113 /* AsciiCode.q */, // ㅂ
81 /* AsciiCode.Q */, // ㅃ
116 /* AsciiCode.t */, // ㅅ
84 /* AsciiCode.T */, // ㅆ
100 /* AsciiCode.d */, // ㅇ
119 /* AsciiCode.w */, // ㅈ
87 /* AsciiCode.W */, // ㅉ
99 /* AsciiCode.c */, // ㅊ
122 /* AsciiCode.z */, // ㅋ
120 /* AsciiCode.x */, // ㅌ
118 /* AsciiCode.v */, // ㅍ
103 /* AsciiCode.g */, // ㅎ
]);
/**
* Hangul Jamo - Modern Vowels
*
* Range U+1161..U+1175
*
* | | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
* |--------|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
* | U+116x | | ᅡ | ᅢ | ᅣ | ᅤ | ᅥ | ᅦ | ᅧ | ᅨ | ᅩ | ᅪ | ᅫ | ᅬ | ᅭ | ᅮ | ᅯ |
* | U+117x | ᅰ | ᅱ | ᅲ | ᅳ | ᅴ | ᅵ |
*/
const modernVowels = new Uint16Array([
107 /* AsciiCode.k */, // -> ㅏ
111 /* AsciiCode.o */, // -> ㅐ
105 /* AsciiCode.i */, // -> ㅑ
79 /* AsciiCode.O */, // -> ㅒ
106 /* AsciiCode.j */, // -> ㅓ
112 /* AsciiCode.p */, // -> ㅔ
117 /* AsciiCode.u */, // -> ㅕ
80 /* AsciiCode.P */, // -> ㅖ
104 /* AsciiCode.h */, // -> ㅗ
27496 /* AsciiCodeCombo.hk */, // -> ㅘ
28520 /* AsciiCodeCombo.ho */, // -> ㅙ
27752 /* AsciiCodeCombo.hl */, // -> ㅚ
121 /* AsciiCode.y */, // -> ㅛ
110 /* AsciiCode.n */, // -> ㅜ
27246 /* AsciiCodeCombo.nj */, // -> ㅝ
28782 /* AsciiCodeCombo.np */, // -> ㅞ
27758 /* AsciiCodeCombo.nl */, // -> ㅟ
98 /* AsciiCode.b */, // -> ㅠ
109 /* AsciiCode.m */, // -> ㅡ
27757 /* AsciiCodeCombo.ml */, // -> ㅢ
108 /* AsciiCode.l */, // -> ㅣ
]);
/**
* Hangul Jamo - Modern Consonants #2
*
* Range U+11A8..U+11C2
*
* | | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
* |--------|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
* | U+11Ax | | | | | | | | | ᆨ | ᆩ | ᆪ | ᆫ | ᆬ | ᆭ | ᆮ | ᆯ |
* | U+11Bx | ᆰ | ᆱ | ᆲ | ᆳ | ᆴ | ᆵ | ᆶ | ᆷ | ᆸ | ᆹ | ᆺ | ᆻ | ᆼ | ᆽ | ᆾ | ᆿ |
* | U+11Cx | ᇀ | ᇁ | ᇂ |
*/
const modernFinalConsonants = new Uint16Array([
114 /* AsciiCode.r */, // ㄱ
82 /* AsciiCode.R */, // ㄲ
29810 /* AsciiCodeCombo.rt */, // ㄳ
115 /* AsciiCode.s */, // ㄴ
30579 /* AsciiCodeCombo.sw */, // ㄵ
26483 /* AsciiCodeCombo.sg */, // ㄶ
101 /* AsciiCode.e */, // ㄷ
102 /* AsciiCode.f */, // ㄹ
29286 /* AsciiCodeCombo.fr */, // ㄺ
24934 /* AsciiCodeCombo.fa */, // ㄻ
29030 /* AsciiCodeCombo.fq */, // ㄼ
29798 /* AsciiCodeCombo.ft */, // ㄽ
30822 /* AsciiCodeCombo.fx */, // ㄾ
30310 /* AsciiCodeCombo.fv */, // ㄿ
26470 /* AsciiCodeCombo.fg */, // ㅀ
97 /* AsciiCode.a */, // ㅁ
113 /* AsciiCode.q */, // ㅂ
29809 /* AsciiCodeCombo.qt */, // ㅄ
116 /* AsciiCode.t */, // ㅅ
84 /* AsciiCode.T */, // ㅆ
100 /* AsciiCode.d */, // ㅇ
119 /* AsciiCode.w */, // ㅈ
99 /* AsciiCode.c */, // ㅊ
122 /* AsciiCode.z */, // ㅋ
120 /* AsciiCode.x */, // ㅌ
118 /* AsciiCode.v */, // ㅍ
103 /* AsciiCode.g */, // ㅎ
]);
/**
* Hangul Compatibility Jamo
*
* Range U+3131..U+318F
*
* This includes range includes archaic jamo which we don't consider, these are
* given the NUL character code in order to be ignored.
*
* | | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
* |--------|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
* | U+313x | | ㄱ | ㄲ | ㄳ | ㄴ | ㄵ | ㄶ | ㄷ | ㄸ | ㄹ | ㄺ | ㄻ | ㄼ | ㄽ | ㄾ | ㄿ |
* | U+314x | ㅀ | ㅁ | ㅂ | ㅃ | ㅄ | ㅅ | ㅆ | ㅇ | ㅈ | ㅉ | ㅊ | ㅋ | ㅌ | ㅍ | ㅎ | ㅏ |
* | U+315x | ㅐ | ㅑ | ㅒ | ㅓ | ㅔ | ㅕ | ㅖ | ㅗ | ㅘ | ㅙ | ㅚ | ㅛ | ㅜ | ㅝ | ㅞ | ㅟ |
* | U+316x | ㅠ | ㅡ | ㅢ | ㅣ | HF | ㅥ | ㅦ | ㅧ | ㅨ | ㅩ | ㅪ | ㅫ | ㅬ | ㅭ | ㅮ | ㅯ |
* | U+317x | ㅰ | ㅱ | ㅲ | ㅳ | ㅴ | ㅵ | ㅶ | ㅷ | ㅸ | ㅹ | ㅺ | ㅻ | ㅼ | ㅽ | ㅾ | ㅿ |
* | U+318x | ㆀ | ㆁ | ㆂ | ㆃ | ㆄ | ㆅ | ㆆ | ㆇ | ㆈ | ㆉ | ㆊ | ㆋ | ㆌ | ㆍ | ㆎ |
*/
const compatibilityJamo = new Uint16Array([
114 /* AsciiCode.r */, // ㄱ
82 /* AsciiCode.R */, // ㄲ
29810 /* AsciiCodeCombo.rt */, // ㄳ
115 /* AsciiCode.s */, // ㄴ
30579 /* AsciiCodeCombo.sw */, // ㄵ
26483 /* AsciiCodeCombo.sg */, // ㄶ
101 /* AsciiCode.e */, // ㄷ
69 /* AsciiCode.E */, // ㄸ
102 /* AsciiCode.f */, // ㄹ
29286 /* AsciiCodeCombo.fr */, // ㄺ
24934 /* AsciiCodeCombo.fa */, // ㄻ
29030 /* AsciiCodeCombo.fq */, // ㄼ
29798 /* AsciiCodeCombo.ft */, // ㄽ
30822 /* AsciiCodeCombo.fx */, // ㄾ
30310 /* AsciiCodeCombo.fv */, // ㄿ
26470 /* AsciiCodeCombo.fg */, // ㅀ
97 /* AsciiCode.a */, // ㅁ
113 /* AsciiCode.q */, // ㅂ
81 /* AsciiCode.Q */, // ㅃ
29809 /* AsciiCodeCombo.qt */, // ㅄ
116 /* AsciiCode.t */, // ㅅ
84 /* AsciiCode.T */, // ㅆ
100 /* AsciiCode.d */, // ㅇ
119 /* AsciiCode.w */, // ㅈ
87 /* AsciiCode.W */, // ㅉ
99 /* AsciiCode.c */, // ㅊ
122 /* AsciiCode.z */, // ㅋ
120 /* AsciiCode.x */, // ㅌ
118 /* AsciiCode.v */, // ㅍ
103 /* AsciiCode.g */, // ㅎ
107 /* AsciiCode.k */, // ㅏ
111 /* AsciiCode.o */, // ㅐ
105 /* AsciiCode.i */, // ㅑ
79 /* AsciiCode.O */, // ㅒ
106 /* AsciiCode.j */, // ㅓ
112 /* AsciiCode.p */, // ㅔ
117 /* AsciiCode.u */, // ㅕ
80 /* AsciiCode.P */, // ㅖ
104 /* AsciiCode.h */, // ㅗ
27496 /* AsciiCodeCombo.hk */, // ㅘ
28520 /* AsciiCodeCombo.ho */, // ㅙ
27752 /* AsciiCodeCombo.hl */, // ㅚ
121 /* AsciiCode.y */, // ㅛ
110 /* AsciiCode.n */, // ㅜ
27246 /* AsciiCodeCombo.nj */, // ㅝ
28782 /* AsciiCodeCombo.np */, // ㅞ
27758 /* AsciiCodeCombo.nl */, // ㅟ
98 /* AsciiCode.b */, // ㅠ
109 /* AsciiCode.m */, // ㅡ
27757 /* AsciiCodeCombo.ml */, // ㅢ
108 /* AsciiCode.l */, // ㅣ
// HF: Hangul Filler (everything after this is archaic)
// ㅥ
// ㅦ
// ㅧ
// ㅨ
// ㅩ
// ㅪ
// ㅫ
// ㅬ
// ㅮ
// ㅯ
// ㅰ
// ㅱ
// ㅲ
// ㅳ
// ㅴ
// ㅵ
// ㅶ
// ㅷ
// ㅸ
// ㅹ
// ㅺ
// ㅻ
// ㅼ
// ㅽ
// ㅾ
// ㅿ
// ㆀ
// ㆁ
// ㆂ
// ㆃ
// ㆄ
// ㆅ
// ㆆ
// ㆇ
// ㆈ
// ㆉ
// ㆊ
// ㆋ
// ㆌ
// ㆍ
// ㆎ
]);