UNPKG

@daeinc/hangul

Version:
475 lines (462 loc) 14.6 kB
import { assemble as assemble$1, canBeJongseong as canBeJongseong$1, disassembleCompleteCharacter, disassemble as disassemble$1 } from 'es-hangul'; /*! @daeinc/hangul@0.10.0 by Daeinc - MIT */ /*! * @daeinc/hangul v0.10.0 | MIT * Find third-party licenses in LICENSE.txt */ // src/consonants.ts var CHOSEONGS = [ "\u3131", "\u3132", "\u3134", "\u3137", "\u3138", "\u3139", "\u3141", "\u3142", "\u3143", "\u3145", "\u3146", "\u3147", "\u3148", "\u3149", "\u314A", "\u314B", "\u314C", "\u314D", "\u314E" ]; var JUNGSEONGS = [ "\u314F", "\u3150", "\u3151", "\u3152", "\u3153", "\u3154", "\u3155", "\u3156", "\u3157", "\u3157\u314F", "\u3157\u3150", "\u3157\u3163", "\u315B", "\u315C", "\u315C\u3153", "\u315C\u3154", "\u315C\u3163", "\u3160", "\u3161", "\u3161\u3163", "\u3163" ]; var JONGSEONGS_DISASSEMBLED = [ "", "\u3131", "\u3132", "\u3131\u3145", "\u3134", "\u3134\u3148", "\u3134\u314E", "\u3137", "\u3139", "\u3139\u3131", "\u3139\u3141", "\u3139\u3142", "\u3139\u3145", "\u3139\u314C", "\u3139\u314D", "\u3139\u314E", "\u3141", "\u3142", "\u3142\u3145", "\u3145", "\u3146", "\u3147", "\u3148", "\u314A", "\u314B", "\u314C", "\u314D", "\u314E" ]; var VOWELS_VERTICAL = [ "\u314F", "\u3150", "\u3151", "\u3152", "\u3153", "\u3154", "\u3155", "\u3156", "\u3163" ]; var VOWELS_HORIZONTAL = ["\u3157", "\u315B", "\u315C", "\u3160", "\u3161"]; var VOWELS_COMPOUND = [ "\u3158", "\u3159", "\u315A", "\u315D", "\u315E", "\u315F", "\u3162" ]; var HANGUL_SYLLABLES_START_CHARCODE = 44032; var HANGUL_SYLLABLES_END_CHARCODE = 55215; var HANGUL_COMPAT_JAMO_START_CHARCODE = 12592; var HANGUL_COMPAT_JAMO_END_CHARCODE = 12687; var HANGUL_COMPAT_CONSONANT_START_CHARCODE = 12593; var HANGUL_COMPAT_CONSONANT_END_CHARCODE = 12622; var HANGUL_COMPAT_VOWEL_START_CHARCODE = 12623; var HANGUL_COMPAT_VOWEL_END_CHARCODE = 12643; var HANGUL_COMPAT_OLD_CONSONANT_START_CHARCODE = 12645; var HANGUL_COMPAT_OLD_CONSONANT_END_CHARCODE = 12678; var HANGUL_COMPAT_OLD_VOWEL_START_CHARCODE = 12679; var HANGUL_COMPAT_OLD_VOWEL_END_CHARCODE = 12686; var HANGUL_JAMO_START_CHARCODE = 4352; var HANGUL_JAMO_END_CHARCODE = 4607; var HANGUL_JAMO_INITIAL_CONSONANT_START_CHARCODE = 4352; var HANGUL_JAMO_INITIAL_CONSONANT_END_CHARCODE = 4370; var HANGUL_JAMO_OLD_INITIAL_CONSONANT_START_CHARCODE = 4371; var HANGUL_JAMO_OLD_INITIAL_CONSONANT_END_CHARCODE = 4446; var HANGUL_JAMO_VOWEL_START_CHARCODE = 4449; var HANGUL_JAMO_VOWEL_END_CHARCODE = 4469; var HANGUL_JAMO_OLD_VOWEL_START_CHARCODE = 4470; var HANGUL_JAMO_OLD_VOWEL_END_CHARCODE = 4519; var HANGUL_JAMO_FINAL_CONSONANT_START_CHARCODE = 4520; var HANGUL_JAMO_FINAL_CONSONANT_END_CHARCODE = 4546; var HANGUL_JAMO_OLD_FINAL_CONSONANT_START_CHARCODE = 4547; var HANGUL_JAMO_OLD_FINAL_CONSONANT_END_CHARCODE = 4607; var HANGUL_JAMO_EXTENDED_A_START_CHARCODE = 43360; var HANGUL_JAMO_EXTENDED_A_END_CHARCODE = 43391; var HANGUL_JAMO_EXTENDED_B_START_CHARCODE = 55216; var HANGUL_JAMO_EXTENDED_B_END_CHARCODE = 55295; var HANGUL_JAMO_EXTENDED_B_VOWEL_START_CHARCODE = 55216; var HANGUL_JAMO_EXTENDED_B_VOWEL_END_CHARCODE = 55238; var HANGUL_JAMO_EXTENDED_B_CONSONANT_START_CHARCODE = 55243; var HANGUL_JAMO_EXTENDED_B_CONSONANT_END_CHARCODE = 55291; // src/isHangul/isHangul.ts var isHangul = (ch, opts) => { if (ch.length > 1) { console.warn(`Only the first character ("${ch[0]}") will be processed.`); ch = ch[0]; } const options = { jamo: false, jamoExtendedA: false, jamoExtendedB: false, compatJamo: true, syllable: true, ...opts }; return options.syllable && isHangulSyllable(ch) || options.jamo && isHangulJamo(ch) || options.compatJamo && isHangulCompatJamo(ch) || options.jamoExtendedA && isHangulJamoExtendedA(ch) || options.jamoExtendedB && isHangulJamoExtendedB(ch); }; var isHangulSyllable = (ch) => { const code = ch.charCodeAt(0); return code >= HANGUL_SYLLABLES_START_CHARCODE && code <= HANGUL_SYLLABLES_END_CHARCODE; }; var isHangulJamo = (ch) => { const code = ch.charCodeAt(0); return code >= HANGUL_JAMO_START_CHARCODE && code <= HANGUL_JAMO_END_CHARCODE; }; var isHangulCompatJamo = (ch) => { const code = ch.charCodeAt(0); return code >= HANGUL_COMPAT_JAMO_START_CHARCODE && code <= HANGUL_COMPAT_JAMO_END_CHARCODE; }; var isHangulJamoExtendedA = (ch) => { const code = ch.charCodeAt(0); return code >= HANGUL_JAMO_EXTENDED_A_START_CHARCODE && code <= HANGUL_JAMO_EXTENDED_A_END_CHARCODE; }; var isHangulJamoExtendedB = (ch) => { const code = ch.charCodeAt(0); return code >= HANGUL_JAMO_EXTENDED_B_START_CHARCODE && code <= HANGUL_JAMO_EXTENDED_B_END_CHARCODE; }; var isConsonant = (ch) => { return /^[ㄱ-ㅎ]$/.test(ch); }; var isVowel = (ch, opts) => { if (!/^[ㅏ-ㅣ]$/.test(ch)) return false; const options = { vertical: true, horizontal: true, compound: true, ...opts }; if (VOWELS_VERTICAL.includes(ch) && !options.vertical) return false; if (VOWELS_HORIZONTAL.includes(ch) && !options.horizontal) return false; if (VOWELS_COMPOUND.includes(ch) && !options.compound) return false; return true; }; // src/assemble/assemble.ts var assemble = (strArr) => { const str = strArr.join(""); const result = []; let i = 0; while (i < str.length) { const ch = str[i]; if (isHangul(ch)) { const hangulChars = [ch]; let j = i + 1; while (j < str.length && isHangul(str[j])) { hangulChars.push(str[j]); j++; } let numAccChars = hangulChars.length; while (numAccChars > 0) { const charsToTry = hangulChars.slice(0, numAccChars); try { const assembledEsh = assemble$1(charsToTry); result.push(assembledEsh); if (numAccChars < hangulChars.length) { const remaining = hangulChars.slice(numAccChars); const assembledRemaining = assemble(remaining); result.push(assembledRemaining); } break; } catch (err) { numAccChars--; } } i = j; } else { result.push(ch); i++; } } return result.join(""); }; var _assemble = (strArr) => { const str = strArr.join(""); const result = []; let i = 0; while (i < str.length) { const ch = str[i]; if (isHangul(ch)) { const hangulChars = [ch]; let j = i + 1; while (j < str.length && isHangul(str[j])) { hangulChars.push(str[j]); j++; } result.push(assemble$1(hangulChars)); i = j; } else { result.push(ch); i++; } } return result.join(""); }; var canBeJongseong = (str) => { return canBeJongseong$1(str); }; // src/isJaOrMo/isJaOrMo.ts var isJaOrMo = (ch) => { if (ch.length > 1) { console.warn(`Only the first character ("${ch[0]}") will be processed.`); ch = ch[0]; } const code = ch.charCodeAt(0); if (isHangulJamo(ch)) { if (code >= HANGUL_JAMO_INITIAL_CONSONANT_START_CHARCODE && code <= HANGUL_JAMO_OLD_INITIAL_CONSONANT_END_CHARCODE || code >= HANGUL_JAMO_FINAL_CONSONANT_START_CHARCODE && code <= HANGUL_JAMO_OLD_FINAL_CONSONANT_END_CHARCODE) { return "ja"; } if (code >= HANGUL_JAMO_VOWEL_START_CHARCODE && code <= HANGUL_JAMO_OLD_VOWEL_END_CHARCODE) { return "mo"; } } if (isHangulCompatJamo(ch)) { if (code >= HANGUL_COMPAT_CONSONANT_START_CHARCODE && code <= HANGUL_COMPAT_CONSONANT_END_CHARCODE) { return "ja"; } if (code >= HANGUL_COMPAT_VOWEL_START_CHARCODE && code <= HANGUL_COMPAT_VOWEL_END_CHARCODE) { return "mo"; } } if (isHangulSyllable(ch)) { return "syllable"; } return "other"; }; // src/disassemble/disassemble.ts var disassemble = (str) => { return Array.from(str).map((ch) => { if (!isHangul(ch)) { return ch; } const disassembled = disassembleCompleteCharacter(ch); if (disassembled) { return disassembled; } else { const jamo = isJaOrMo(ch); if (jamo === "ja") { return { // disassemble for consonants such as "ㄳ" choseong: disassemble$1(ch), jungseong: "", jongseong: "" }; } else if (jamo === "mo") { return { choseong: "", jungseong: disassemble$1(ch), jongseong: "" }; } } return ch; }); }; // src/disassembleToJamoString/disassembleToJamoString.ts var disassembleToJamoString = (phrase) => { return disassemble(phrase).map( (v) => typeof v === "object" ? `${v.choseong}${v.jungseong}${v.jongseong}` : v ).join(""); }; // src/hangul-syllable/hangul-syllable.ts var HangulSyllable = class _HangulSyllable { char; disassembled; id; constructor(char) { if (!isHangul(char)) { console.warn( `It may be a mistake to store "${char}" in HangulSyllable object` ); } this.id = -1; this.char = char; if (char) { this.disassembled = disassemble(char)[0]; } else { this.disassembled = { choseong: "", jungseong: "", jongseong: "" }; } } setId(id) { this.id = id; } clone() { return new _HangulSyllable(this.char); } isEmpty() { return !this.hasComponent(); } hasComponent() { return this.hasChoseong() || this.hasJungseong() || this.hasJongseong(); } hasChoseong() { return this.disassembled.choseong.length > 0; } hasJungseong() { return this.disassembled.jungseong.length > 0; } hasJongseong() { return this.disassembled.jongseong.length > 0; } /** * Removes a single component starting from jongseong, jungseong to choseong. * If it has a double jongseong or jungseong, it will remove a single one each time. * * @example * const syl = new HangulSyllable("깖"); * syl.removeSingleComponent() // syl.char == "깔" * syl.removeSingleComponent() // "까" * syl.removeSingleComponent() // "ㄲ" * syl.removeSingleComponent() // "" */ removeSingleComponent() { if (this.disassembled.jongseong) { this.disassembled.jongseong = this.disassembled.jongseong.slice(0, -1); } else if (this.disassembled.jungseong) { this.disassembled.jungseong = this.disassembled.jungseong.slice(0, -1); } else { this.disassembled.choseong = this.disassembled.choseong.slice(0, -1); } this.char = assemble(this.getDisassembledStringArray()); } /** * @example * const syl = new HangulSyllable("깖"); * syl.removeSingleJongseong() // syl.char == "깔" * * @example * const syl = new HangulSyllable("깔"); * syl.removeSingleJongseong() // syl.char == "까" */ removeSingleJongseong() { this.disassembled.jongseong = this.disassembled.jongseong.slice(0, -1); this.char = assemble(this.getDisassembledStringArray()); } /** * Updates `this.char` and `this.disassembled` according to the input `char` * * @param char - */ updateSyllable(char) { this.char = char; if (char) { this.disassembled = disassemble(char)[0]; } else { this.disassembled = { choseong: "", jungseong: "", jongseong: "" }; } } /** * Returns an object with Hangul components * * @example * const syl = new HangulSyllable("깖"); * syl.getDisassembled() // {choseong: "ㄲ", jungseong: "ㅏ", jongseong: "ㄹㅁ"} */ getDisassembled() { return this.disassembled; } /** * Returns an array of each Hangul component. Note that a double Jongseong is broken down. * * @example * const syl = new HangulSyllable("깖"); * syl.getDisassembledStringArray() // ["ㄲ", "ㅏ", "ㄹㅁ"] */ getDisassembledStringArray() { return Object.values(this.disassembled).map((v) => v); } /** * Returns a flattened string each Hangul component. Note that a double Jongseong is broken down. * * @example * const syl = new HangulSyllable("깖"); * syl.getDisassembledString() // "ㄲㅏㄹㅁ" */ getDisassembledString() { return Object.values(this.disassembled).join(""); } }; // src/isFirstSyllableReady/isFirstSyllableReady.ts var isFirstSyllableReady = (first, second) => { if (!second) return false; if (first.length > 1 || second.length > 1) { console.warn( `the input string to "isFirstSyllableReady()" is greater than 1` ); } first = first[0]; second = second[0]; if (!isHangul(first) || !isHangul(second)) return true; const firstDisass = disassemble(first)[0]; const secondDisass = disassemble(second)[0]; if (typeof firstDisass === "object" && typeof secondDisass === "object") { if (secondDisass.choseong.length > 0 || secondDisass.jungseong.length > 0) { return true; } } return false; }; export { CHOSEONGS, HANGUL_COMPAT_CONSONANT_END_CHARCODE, HANGUL_COMPAT_CONSONANT_START_CHARCODE, HANGUL_COMPAT_JAMO_END_CHARCODE, HANGUL_COMPAT_JAMO_START_CHARCODE, HANGUL_COMPAT_OLD_CONSONANT_END_CHARCODE, HANGUL_COMPAT_OLD_CONSONANT_START_CHARCODE, HANGUL_COMPAT_OLD_VOWEL_END_CHARCODE, HANGUL_COMPAT_OLD_VOWEL_START_CHARCODE, HANGUL_COMPAT_VOWEL_END_CHARCODE, HANGUL_COMPAT_VOWEL_START_CHARCODE, HANGUL_JAMO_END_CHARCODE, HANGUL_JAMO_EXTENDED_A_END_CHARCODE, HANGUL_JAMO_EXTENDED_A_START_CHARCODE, HANGUL_JAMO_EXTENDED_B_CONSONANT_END_CHARCODE, HANGUL_JAMO_EXTENDED_B_CONSONANT_START_CHARCODE, HANGUL_JAMO_EXTENDED_B_END_CHARCODE, HANGUL_JAMO_EXTENDED_B_START_CHARCODE, HANGUL_JAMO_EXTENDED_B_VOWEL_END_CHARCODE, HANGUL_JAMO_EXTENDED_B_VOWEL_START_CHARCODE, HANGUL_JAMO_FINAL_CONSONANT_END_CHARCODE, HANGUL_JAMO_FINAL_CONSONANT_START_CHARCODE, HANGUL_JAMO_INITIAL_CONSONANT_END_CHARCODE, HANGUL_JAMO_INITIAL_CONSONANT_START_CHARCODE, HANGUL_JAMO_OLD_FINAL_CONSONANT_END_CHARCODE, HANGUL_JAMO_OLD_FINAL_CONSONANT_START_CHARCODE, HANGUL_JAMO_OLD_INITIAL_CONSONANT_END_CHARCODE, HANGUL_JAMO_OLD_INITIAL_CONSONANT_START_CHARCODE, HANGUL_JAMO_OLD_VOWEL_END_CHARCODE, HANGUL_JAMO_OLD_VOWEL_START_CHARCODE, HANGUL_JAMO_START_CHARCODE, HANGUL_JAMO_VOWEL_END_CHARCODE, HANGUL_JAMO_VOWEL_START_CHARCODE, HANGUL_SYLLABLES_END_CHARCODE, HANGUL_SYLLABLES_START_CHARCODE, HangulSyllable, JONGSEONGS_DISASSEMBLED, JUNGSEONGS, VOWELS_COMPOUND, VOWELS_HORIZONTAL, VOWELS_VERTICAL, _assemble, assemble, canBeJongseong, disassemble, disassembleToJamoString, isConsonant, isFirstSyllableReady, isHangul, isHangulCompatJamo, isHangulJamo, isHangulJamoExtendedA, isHangulJamoExtendedB, isHangulSyllable, isJaOrMo, isVowel };