From b669d029eddcb4b5d5aa56e67fe09d5af0045e3b Mon Sep 17 00:00:00 2001 From: chanhyuk-park Date: Thu, 5 Sep 2024 23:21:59 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=ED=8F=B4=EB=8D=94=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=ED=94=8C=EB=9E=AB=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../amountToHangul.spec.ts | 0 src/{ => amountToHangul}/amountToHangul.ts | 0 src/amountToHangul/index.ts | 1 + src/{ => assemble}/assemble.spec.ts | 0 src/{ => assemble}/assemble.ts | 0 src/assemble/index.ts | 1 + src/{ => canBe}/canBe.spec.ts | 0 src/{ => canBe}/canBe.ts | 0 src/canBe/index.ts | 1 + .../combineCharacter.spec.ts | 0 .../combineCharacter.ts | 0 src/combineCharacter/index.ts | 1 + .../convertQwertyToAlphabet.spec.ts | 0 .../convertQwertyToAlphabet.ts | 0 src/convertQwertyToAlphabet/index.ts | 1 + src/date/date.spec.ts | 36 ---- src/{date => days}/days.constants.ts | 0 src/days/days.spec.ts | 34 ++++ src/{date/index.ts => days/days.ts} | 0 src/days/index.ts | 1 + src/{ => disassemble}/disassemble.spec.ts | 0 src/{ => disassemble}/disassemble.ts | 0 src/disassemble/index.ts | 1 + .../disassembleCompleteCharacter.spec.ts | 0 .../disassembleCompleteCharacter.ts | 0 src/disassembleCompleteCharacter/index.ts | 1 + ...disassembleCompleteHangulCharacter.spec.ts | 40 ----- src/{ => getChoseong}/getChoseong.spec.ts | 0 src/{ => getChoseong}/getChoseong.ts | 0 src/getChoseong/index.ts | 1 + src/{ => hasBatchim}/hasBatchim.spec.ts | 0 src/{ => hasBatchim}/hasBatchim.ts | 0 src/hasBatchim/index.ts | 1 + src/index.ts | 2 +- src/josa/index.ts | 1 + src/{ => josa}/josa.spec.ts | 0 src/{ => josa}/josa.ts | 0 src/removeLastCharacter/index.ts | 1 + .../removeLastCharacter.spec.ts | 0 .../removeLastCharacter.ts | 0 src/romanize/index.ts | 1 + src/{ => romanize}/romanize.spec.ts | 0 src/{ => romanize}/romanize.ts | 0 src/standardizePronunciation/index.ts | 157 +----------------- .../standardizePronunciation.ts | 156 +++++++++++++++++ src/susa/index.ts | 1 + src/{ => susa}/susa.spec.ts | 0 src/{ => susa}/susa.ts | 0 48 files changed, 206 insertions(+), 233 deletions(-) rename src/{ => amountToHangul}/amountToHangul.spec.ts (100%) rename src/{ => amountToHangul}/amountToHangul.ts (100%) create mode 100644 src/amountToHangul/index.ts rename src/{ => assemble}/assemble.spec.ts (100%) rename src/{ => assemble}/assemble.ts (100%) create mode 100644 src/assemble/index.ts rename src/{ => canBe}/canBe.spec.ts (100%) rename src/{ => canBe}/canBe.ts (100%) create mode 100644 src/canBe/index.ts rename src/{ => combineCharacter}/combineCharacter.spec.ts (100%) rename src/{ => combineCharacter}/combineCharacter.ts (100%) create mode 100644 src/combineCharacter/index.ts rename src/{ => convertQwertyToAlphabet}/convertQwertyToAlphabet.spec.ts (100%) rename src/{ => convertQwertyToAlphabet}/convertQwertyToAlphabet.ts (100%) create mode 100644 src/convertQwertyToAlphabet/index.ts delete mode 100644 src/date/date.spec.ts rename src/{date => days}/days.constants.ts (100%) create mode 100644 src/days/days.spec.ts rename src/{date/index.ts => days/days.ts} (100%) create mode 100644 src/days/index.ts rename src/{ => disassemble}/disassemble.spec.ts (100%) rename src/{ => disassemble}/disassemble.ts (100%) create mode 100644 src/disassemble/index.ts rename src/{ => disassembleCompleteCharacter}/disassembleCompleteCharacter.spec.ts (100%) rename src/{ => disassembleCompleteCharacter}/disassembleCompleteCharacter.ts (100%) create mode 100644 src/disassembleCompleteCharacter/index.ts delete mode 100644 src/disassembleCompleteHangulCharacter.spec.ts rename src/{ => getChoseong}/getChoseong.spec.ts (100%) rename src/{ => getChoseong}/getChoseong.ts (100%) create mode 100644 src/getChoseong/index.ts rename src/{ => hasBatchim}/hasBatchim.spec.ts (100%) rename src/{ => hasBatchim}/hasBatchim.ts (100%) create mode 100644 src/hasBatchim/index.ts create mode 100644 src/josa/index.ts rename src/{ => josa}/josa.spec.ts (100%) rename src/{ => josa}/josa.ts (100%) create mode 100644 src/removeLastCharacter/index.ts rename src/{ => removeLastCharacter}/removeLastCharacter.spec.ts (100%) rename src/{ => removeLastCharacter}/removeLastCharacter.ts (100%) create mode 100644 src/romanize/index.ts rename src/{ => romanize}/romanize.spec.ts (100%) rename src/{ => romanize}/romanize.ts (100%) create mode 100644 src/standardizePronunciation/standardizePronunciation.ts create mode 100644 src/susa/index.ts rename src/{ => susa}/susa.spec.ts (100%) rename src/{ => susa}/susa.ts (100%) diff --git a/src/amountToHangul.spec.ts b/src/amountToHangul/amountToHangul.spec.ts similarity index 100% rename from src/amountToHangul.spec.ts rename to src/amountToHangul/amountToHangul.spec.ts diff --git a/src/amountToHangul.ts b/src/amountToHangul/amountToHangul.ts similarity index 100% rename from src/amountToHangul.ts rename to src/amountToHangul/amountToHangul.ts diff --git a/src/amountToHangul/index.ts b/src/amountToHangul/index.ts new file mode 100644 index 00000000..53d9de8f --- /dev/null +++ b/src/amountToHangul/index.ts @@ -0,0 +1 @@ +export * from './amountToHangul'; diff --git a/src/assemble.spec.ts b/src/assemble/assemble.spec.ts similarity index 100% rename from src/assemble.spec.ts rename to src/assemble/assemble.spec.ts diff --git a/src/assemble.ts b/src/assemble/assemble.ts similarity index 100% rename from src/assemble.ts rename to src/assemble/assemble.ts diff --git a/src/assemble/index.ts b/src/assemble/index.ts new file mode 100644 index 00000000..cd75a46b --- /dev/null +++ b/src/assemble/index.ts @@ -0,0 +1 @@ +export * from './assemble'; diff --git a/src/canBe.spec.ts b/src/canBe/canBe.spec.ts similarity index 100% rename from src/canBe.spec.ts rename to src/canBe/canBe.spec.ts diff --git a/src/canBe.ts b/src/canBe/canBe.ts similarity index 100% rename from src/canBe.ts rename to src/canBe/canBe.ts diff --git a/src/canBe/index.ts b/src/canBe/index.ts new file mode 100644 index 00000000..a0f5c68e --- /dev/null +++ b/src/canBe/index.ts @@ -0,0 +1 @@ +export * from './canBe'; diff --git a/src/combineCharacter.spec.ts b/src/combineCharacter/combineCharacter.spec.ts similarity index 100% rename from src/combineCharacter.spec.ts rename to src/combineCharacter/combineCharacter.spec.ts diff --git a/src/combineCharacter.ts b/src/combineCharacter/combineCharacter.ts similarity index 100% rename from src/combineCharacter.ts rename to src/combineCharacter/combineCharacter.ts diff --git a/src/combineCharacter/index.ts b/src/combineCharacter/index.ts new file mode 100644 index 00000000..854b2d0b --- /dev/null +++ b/src/combineCharacter/index.ts @@ -0,0 +1 @@ +export * from './combineCharacter'; diff --git a/src/convertQwertyToAlphabet.spec.ts b/src/convertQwertyToAlphabet/convertQwertyToAlphabet.spec.ts similarity index 100% rename from src/convertQwertyToAlphabet.spec.ts rename to src/convertQwertyToAlphabet/convertQwertyToAlphabet.spec.ts diff --git a/src/convertQwertyToAlphabet.ts b/src/convertQwertyToAlphabet/convertQwertyToAlphabet.ts similarity index 100% rename from src/convertQwertyToAlphabet.ts rename to src/convertQwertyToAlphabet/convertQwertyToAlphabet.ts diff --git a/src/convertQwertyToAlphabet/index.ts b/src/convertQwertyToAlphabet/index.ts new file mode 100644 index 00000000..af11794f --- /dev/null +++ b/src/convertQwertyToAlphabet/index.ts @@ -0,0 +1 @@ +export * from './convertQwertyToAlphabet'; diff --git a/src/date/date.spec.ts b/src/date/date.spec.ts deleted file mode 100644 index 9dc1ff85..00000000 --- a/src/date/date.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { days } from '.'; - -describe('date', () => { - describe('days', () => { - const validNumbers = [ - { num: 1, word: '하루' }, - { num: 2, word: '이틀' }, - { num: 3, word: '사흘' }, - { num: 4, word: '나흘' }, - { num: 5, word: '닷새' }, - { num: 6, word: '엿새' }, - { num: 7, word: '이레' }, - { num: 8, word: '여드레' }, - { num: 9, word: '아흐레' }, - { num: 10, word: '열흘' }, - { num: 11, word: '열하루' }, - { num: 20, word: '스무날' }, - { num: 21, word: '스무하루' }, - { num: 30, word: '서른날' }, - ]; - - const invalidNumbers = [0, -1, 31, 1.1, -1.1, Infinity, -Infinity, NaN]; - - validNumbers.forEach(({ num, word }) => { - it(`${num} - 순 우리말 날짜 ${word}로 바꿔 반환해야 한다.`, () => { - expect(days(num)).toBe(word); - }); - }); - - invalidNumbers.forEach(num => { - it(`유효하지 않은 숫자 ${num}에 대해 오류를 발생시켜야 한다.`, () => { - expect(() => days(num)).toThrow('지원하지 않는 숫자입니다.'); - }); - }); - }); -}); diff --git a/src/date/days.constants.ts b/src/days/days.constants.ts similarity index 100% rename from src/date/days.constants.ts rename to src/days/days.constants.ts diff --git a/src/days/days.spec.ts b/src/days/days.spec.ts new file mode 100644 index 00000000..d59e69f7 --- /dev/null +++ b/src/days/days.spec.ts @@ -0,0 +1,34 @@ +import { days } from '.'; + +describe('days', () => { + const validNumbers = [ + { num: 1, word: '하루' }, + { num: 2, word: '이틀' }, + { num: 3, word: '사흘' }, + { num: 4, word: '나흘' }, + { num: 5, word: '닷새' }, + { num: 6, word: '엿새' }, + { num: 7, word: '이레' }, + { num: 8, word: '여드레' }, + { num: 9, word: '아흐레' }, + { num: 10, word: '열흘' }, + { num: 11, word: '열하루' }, + { num: 20, word: '스무날' }, + { num: 21, word: '스무하루' }, + { num: 30, word: '서른날' }, + ]; + + const invalidNumbers = [0, -1, 31, 1.1, -1.1, Infinity, -Infinity, NaN]; + + validNumbers.forEach(({ num, word }) => { + it(`${num} - 순 우리말 날짜 ${word}로 바꿔 반환해야 한다.`, () => { + expect(days(num)).toBe(word); + }); + }); + + invalidNumbers.forEach(num => { + it(`유효하지 않은 숫자 ${num}에 대해 오류를 발생시켜야 한다.`, () => { + expect(() => days(num)).toThrow('지원하지 않는 숫자입니다.'); + }); + }); +}); diff --git a/src/date/index.ts b/src/days/days.ts similarity index 100% rename from src/date/index.ts rename to src/days/days.ts diff --git a/src/days/index.ts b/src/days/index.ts new file mode 100644 index 00000000..28306d0b --- /dev/null +++ b/src/days/index.ts @@ -0,0 +1 @@ +export * from './days'; diff --git a/src/disassemble.spec.ts b/src/disassemble/disassemble.spec.ts similarity index 100% rename from src/disassemble.spec.ts rename to src/disassemble/disassemble.spec.ts diff --git a/src/disassemble.ts b/src/disassemble/disassemble.ts similarity index 100% rename from src/disassemble.ts rename to src/disassemble/disassemble.ts diff --git a/src/disassemble/index.ts b/src/disassemble/index.ts new file mode 100644 index 00000000..e578eede --- /dev/null +++ b/src/disassemble/index.ts @@ -0,0 +1 @@ +export * from './disassemble'; diff --git a/src/disassembleCompleteCharacter.spec.ts b/src/disassembleCompleteCharacter/disassembleCompleteCharacter.spec.ts similarity index 100% rename from src/disassembleCompleteCharacter.spec.ts rename to src/disassembleCompleteCharacter/disassembleCompleteCharacter.spec.ts diff --git a/src/disassembleCompleteCharacter.ts b/src/disassembleCompleteCharacter/disassembleCompleteCharacter.ts similarity index 100% rename from src/disassembleCompleteCharacter.ts rename to src/disassembleCompleteCharacter/disassembleCompleteCharacter.ts diff --git a/src/disassembleCompleteCharacter/index.ts b/src/disassembleCompleteCharacter/index.ts new file mode 100644 index 00000000..cc91d918 --- /dev/null +++ b/src/disassembleCompleteCharacter/index.ts @@ -0,0 +1 @@ +export * from './disassembleCompleteCharacter'; diff --git a/src/disassembleCompleteHangulCharacter.spec.ts b/src/disassembleCompleteHangulCharacter.spec.ts deleted file mode 100644 index 62be5230..00000000 --- a/src/disassembleCompleteHangulCharacter.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; - -describe('disassembleCompleteCharacter', () => { - it('값', () => { - expect(disassembleCompleteCharacter('값')).toEqual({ - choseong: 'ㄱ', - jungseong: 'ㅏ', - jongseong: 'ㅂㅅ', - }); - }); - - it('리', () => { - expect(disassembleCompleteCharacter('리')).toEqual({ - choseong: 'ㄹ', - jungseong: 'ㅣ', - jongseong: '', - }); - }); - - it('빚', () => { - expect(disassembleCompleteCharacter('빚')).toEqual({ - choseong: 'ㅂ', - jungseong: 'ㅣ', - jongseong: 'ㅈ', - }); - }); - - it('박', () => { - expect(disassembleCompleteCharacter('박')).toEqual({ - choseong: 'ㅂ', - jungseong: 'ㅏ', - jongseong: 'ㄱ', - }); - }); - - it('완전한 한글 문자열이 아니면 undefined를 반환해야 합니다.', () => { - expect(disassembleCompleteCharacter('ㄱ')).toBeUndefined; - expect(disassembleCompleteCharacter('ㅏ')).toBeUndefined; - }); -}); diff --git a/src/getChoseong.spec.ts b/src/getChoseong/getChoseong.spec.ts similarity index 100% rename from src/getChoseong.spec.ts rename to src/getChoseong/getChoseong.spec.ts diff --git a/src/getChoseong.ts b/src/getChoseong/getChoseong.ts similarity index 100% rename from src/getChoseong.ts rename to src/getChoseong/getChoseong.ts diff --git a/src/getChoseong/index.ts b/src/getChoseong/index.ts new file mode 100644 index 00000000..474ffdba --- /dev/null +++ b/src/getChoseong/index.ts @@ -0,0 +1 @@ +export * from './getChoseong'; diff --git a/src/hasBatchim.spec.ts b/src/hasBatchim/hasBatchim.spec.ts similarity index 100% rename from src/hasBatchim.spec.ts rename to src/hasBatchim/hasBatchim.spec.ts diff --git a/src/hasBatchim.ts b/src/hasBatchim/hasBatchim.ts similarity index 100% rename from src/hasBatchim.ts rename to src/hasBatchim/hasBatchim.ts diff --git a/src/hasBatchim/index.ts b/src/hasBatchim/index.ts new file mode 100644 index 00000000..149e8743 --- /dev/null +++ b/src/hasBatchim/index.ts @@ -0,0 +1 @@ +export * from './hasBatchim'; diff --git a/src/index.ts b/src/index.ts index c1a6cd7a..7c6daa94 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ export { assemble } from './assemble'; export { combineCharacter, combineVowels } from './combineCharacter'; export { convertQwertyToHangul, convertQwertyToAlphabet } from './convertQwertyToAlphabet'; -export { days } from './date'; +export { days } from './days'; export { disassemble, disassembleToGroups } from './disassemble'; export { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; export { josa } from './josa'; diff --git a/src/josa/index.ts b/src/josa/index.ts new file mode 100644 index 00000000..8df27078 --- /dev/null +++ b/src/josa/index.ts @@ -0,0 +1 @@ +export * from './josa'; diff --git a/src/josa.spec.ts b/src/josa/josa.spec.ts similarity index 100% rename from src/josa.spec.ts rename to src/josa/josa.spec.ts diff --git a/src/josa.ts b/src/josa/josa.ts similarity index 100% rename from src/josa.ts rename to src/josa/josa.ts diff --git a/src/removeLastCharacter/index.ts b/src/removeLastCharacter/index.ts new file mode 100644 index 00000000..c6c9b336 --- /dev/null +++ b/src/removeLastCharacter/index.ts @@ -0,0 +1 @@ +export * from './removeLastCharacter'; diff --git a/src/removeLastCharacter.spec.ts b/src/removeLastCharacter/removeLastCharacter.spec.ts similarity index 100% rename from src/removeLastCharacter.spec.ts rename to src/removeLastCharacter/removeLastCharacter.spec.ts diff --git a/src/removeLastCharacter.ts b/src/removeLastCharacter/removeLastCharacter.ts similarity index 100% rename from src/removeLastCharacter.ts rename to src/removeLastCharacter/removeLastCharacter.ts diff --git a/src/romanize/index.ts b/src/romanize/index.ts new file mode 100644 index 00000000..9968d159 --- /dev/null +++ b/src/romanize/index.ts @@ -0,0 +1 @@ +export * from './romanize'; diff --git a/src/romanize.spec.ts b/src/romanize/romanize.spec.ts similarity index 100% rename from src/romanize.spec.ts rename to src/romanize/romanize.spec.ts diff --git a/src/romanize.ts b/src/romanize/romanize.ts similarity index 100% rename from src/romanize.ts rename to src/romanize/romanize.ts diff --git a/src/standardizePronunciation/index.ts b/src/standardizePronunciation/index.ts index 7fd2ad36..f14b5f13 100644 --- a/src/standardizePronunciation/index.ts +++ b/src/standardizePronunciation/index.ts @@ -1,156 +1 @@ -import { isNotUndefined, joinString } from '../_internal'; -import { isHangulAlphabet, isHangulCharacter } from '../_internal/hangul'; -import { combineCharacter } from '../combineCharacter'; -import { disassembleCompleteCharacter } from '../disassembleCompleteCharacter'; -import { - transform12th, - transform13And14th, - transform16th, - transform17th, - transform18th, - transform19th, - transform20th, - transform9And10And11th, - transformHardConversion, - transformNLAssimilation, - type Nullable, - type Syllable, -} from './rules'; - -type Options = { - hardConversion: boolean; -}; - -type NotHangul = { - index: number; - syllable: string; -}; - -/** - * 주어진 한글 문자열을 표준 발음으로 변환합니다. - * @param hangul 한글 문자열을 입력합니다. - * @param options 변환 옵션을 설정합니다. - * @param options.hardConversion 경음화 등의 된소리를 적용할지 여부를 설정합니다. 기본값은 true입니다. - * @returns 변환된 표준 발음 문자열을 반환합니다. - */ -export function standardizePronunciation(hangul: string, options: Options = { hardConversion: true }): string { - if (!hangul) { - return ''; - } - - const processSyllables = (syllables: Syllable[], phrase: string, options: Options) => - syllables.map((currentSyllable, index, array) => { - const nextSyllable = index < array.length - 1 ? array[index + 1] : null; - - const { current, next } = applyRules({ - currentSyllable, - phrase, - index, - nextSyllable, - options, - }); - - if (next) { - array[index + 1] = next; - } - - return current; - }); - - const transformHangulPhrase = (phrase: string, options: Options): string => { - const { notHangulPhrase, disassembleHangul } = 음절분해(phrase); - const processedSyllables = processSyllables(disassembleHangul, phrase, options); - - return assembleChangedHangul(processedSyllables, notHangulPhrase); - }; - - return hangul - .split(' ') - .map(phrase => transformHangulPhrase(phrase, options)) - .join(' '); -} - -function 음절분해(hangulPhrase: string): { - notHangulPhrase: NotHangul[]; - disassembleHangul: Syllable[]; -} { - const notHangulPhrase: NotHangul[] = []; - const disassembleHangul = Array.from(hangulPhrase) - .filter((syllable, index) => { - if (!isHangulCharacter(syllable) || isHangulAlphabet(syllable)) { - notHangulPhrase.push({ - index, - syllable, - }); - - return false; - } - - return true; - }) - .map(disassembleCompleteCharacter) - .filter(isNotUndefined); - - return { notHangulPhrase, disassembleHangul }; -} - -type ApplyParameters = { - currentSyllable: Syllable; - nextSyllable: Nullable; - index: number; - phrase: string; - options: NonNullable[1]>; -}; - -function applyRules(params: ApplyParameters): { - current: Syllable; - next: Nullable; -} { - const { currentSyllable, nextSyllable, index, phrase, options } = params; - - let current = { ...currentSyllable }; - let next = nextSyllable ? { ...nextSyllable } : nextSyllable; - - if (next && options.hardConversion) { - ({ next } = transformHardConversion(current, next)); - } - - if (next) { - ({ current, next } = transform16th({ - currentSyllable: current, - nextSyllable: next, - index, - phrase, - })); - ({ current, next } = transform17th(current, next)); - ({ next } = transform19th(current, next)); - ({ current, next } = transformNLAssimilation(current, next)); - ({ current } = transform18th(current, next)); - ({ current, next } = transform20th(current, next)); - } - - ({ current, next } = transform12th(current, next)); - - if (next) { - ({ current, next } = transform13And14th(current, next)); - } - - ({ current } = transform9And10And11th(current, next)); - - return { - current, - next, - }; -} - -function assembleChangedHangul(disassembleHangul: Syllable[], notHangulPhrase: NotHangul[]): string { - const changedSyllables = disassembleHangul - .filter(isNotUndefined) - .map(syllable => combineCharacter(syllable.choseong, syllable.jungseong, syllable.jongseong)); - - for (const { index, syllable } of notHangulPhrase) { - changedSyllables.splice(index, 0, syllable); - } - - return joinString(...changedSyllables); -} +export * from './standardizePronunciation'; diff --git a/src/standardizePronunciation/standardizePronunciation.ts b/src/standardizePronunciation/standardizePronunciation.ts new file mode 100644 index 00000000..7fd2ad36 --- /dev/null +++ b/src/standardizePronunciation/standardizePronunciation.ts @@ -0,0 +1,156 @@ +import { isNotUndefined, joinString } from '../_internal'; +import { isHangulAlphabet, isHangulCharacter } from '../_internal/hangul'; +import { combineCharacter } from '../combineCharacter'; +import { disassembleCompleteCharacter } from '../disassembleCompleteCharacter'; +import { + transform12th, + transform13And14th, + transform16th, + transform17th, + transform18th, + transform19th, + transform20th, + transform9And10And11th, + transformHardConversion, + transformNLAssimilation, + type Nullable, + type Syllable, +} from './rules'; + +type Options = { + hardConversion: boolean; +}; + +type NotHangul = { + index: number; + syllable: string; +}; + +/** + * 주어진 한글 문자열을 표준 발음으로 변환합니다. + * @param hangul 한글 문자열을 입력합니다. + * @param options 변환 옵션을 설정합니다. + * @param options.hardConversion 경음화 등의 된소리를 적용할지 여부를 설정합니다. 기본값은 true입니다. + * @returns 변환된 표준 발음 문자열을 반환합니다. + */ +export function standardizePronunciation(hangul: string, options: Options = { hardConversion: true }): string { + if (!hangul) { + return ''; + } + + const processSyllables = (syllables: Syllable[], phrase: string, options: Options) => + syllables.map((currentSyllable, index, array) => { + const nextSyllable = index < array.length - 1 ? array[index + 1] : null; + + const { current, next } = applyRules({ + currentSyllable, + phrase, + index, + nextSyllable, + options, + }); + + if (next) { + array[index + 1] = next; + } + + return current; + }); + + const transformHangulPhrase = (phrase: string, options: Options): string => { + const { notHangulPhrase, disassembleHangul } = 음절분해(phrase); + const processedSyllables = processSyllables(disassembleHangul, phrase, options); + + return assembleChangedHangul(processedSyllables, notHangulPhrase); + }; + + return hangul + .split(' ') + .map(phrase => transformHangulPhrase(phrase, options)) + .join(' '); +} + +function 음절분해(hangulPhrase: string): { + notHangulPhrase: NotHangul[]; + disassembleHangul: Syllable[]; +} { + const notHangulPhrase: NotHangul[] = []; + const disassembleHangul = Array.from(hangulPhrase) + .filter((syllable, index) => { + if (!isHangulCharacter(syllable) || isHangulAlphabet(syllable)) { + notHangulPhrase.push({ + index, + syllable, + }); + + return false; + } + + return true; + }) + .map(disassembleCompleteCharacter) + .filter(isNotUndefined); + + return { notHangulPhrase, disassembleHangul }; +} + +type ApplyParameters = { + currentSyllable: Syllable; + nextSyllable: Nullable; + index: number; + phrase: string; + options: NonNullable[1]>; +}; + +function applyRules(params: ApplyParameters): { + current: Syllable; + next: Nullable; +} { + const { currentSyllable, nextSyllable, index, phrase, options } = params; + + let current = { ...currentSyllable }; + let next = nextSyllable ? { ...nextSyllable } : nextSyllable; + + if (next && options.hardConversion) { + ({ next } = transformHardConversion(current, next)); + } + + if (next) { + ({ current, next } = transform16th({ + currentSyllable: current, + nextSyllable: next, + index, + phrase, + })); + ({ current, next } = transform17th(current, next)); + ({ next } = transform19th(current, next)); + ({ current, next } = transformNLAssimilation(current, next)); + ({ current } = transform18th(current, next)); + ({ current, next } = transform20th(current, next)); + } + + ({ current, next } = transform12th(current, next)); + + if (next) { + ({ current, next } = transform13And14th(current, next)); + } + + ({ current } = transform9And10And11th(current, next)); + + return { + current, + next, + }; +} + +function assembleChangedHangul(disassembleHangul: Syllable[], notHangulPhrase: NotHangul[]): string { + const changedSyllables = disassembleHangul + .filter(isNotUndefined) + .map(syllable => combineCharacter(syllable.choseong, syllable.jungseong, syllable.jongseong)); + + for (const { index, syllable } of notHangulPhrase) { + changedSyllables.splice(index, 0, syllable); + } + + return joinString(...changedSyllables); +} diff --git a/src/susa/index.ts b/src/susa/index.ts new file mode 100644 index 00000000..6bbc1afa --- /dev/null +++ b/src/susa/index.ts @@ -0,0 +1 @@ +export * from './susa'; diff --git a/src/susa.spec.ts b/src/susa/susa.spec.ts similarity index 100% rename from src/susa.spec.ts rename to src/susa/susa.spec.ts diff --git a/src/susa.ts b/src/susa/susa.ts similarity index 100% rename from src/susa.ts rename to src/susa/susa.ts From e1b511f293609ca504f1e14307baab10e9ae43f0 Mon Sep 17 00:00:00 2001 From: chanhyuk-park Date: Thu, 5 Sep 2024 23:26:13 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=ED=8F=B4=EB=8D=94=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assemble/assemble.ts | 4 ++-- src/canBe/canBe.ts | 4 ++-- src/combineCharacter/combineCharacter.ts | 4 ++-- .../convertQwertyToAlphabet.ts | 6 +++--- src/disassemble/disassemble.ts | 6 +++--- .../disassembleCompleteCharacter.ts | 2 +- src/getChoseong/getChoseong.ts | 2 +- src/hasBatchim/hasBatchim.ts | 2 +- src/josa/josa.ts | 4 ++-- src/removeLastCharacter/removeLastCharacter.ts | 8 ++++---- src/romanize/romanize.ts | 12 ++++++------ src/susa/susa.ts | 4 ++-- 12 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/assemble/assemble.ts b/src/assemble/assemble.ts index 66ebbf06..051d2db2 100644 --- a/src/assemble/assemble.ts +++ b/src/assemble/assemble.ts @@ -1,5 +1,5 @@ -import { disassemble } from './disassemble'; -import { binaryAssemble } from './_internal/hangul'; +import { disassemble } from '../disassemble'; +import { binaryAssemble } from '../_internal/hangul'; /** * @name assemble diff --git a/src/canBe/canBe.ts b/src/canBe/canBe.ts index 050c9e55..db09c50f 100644 --- a/src/canBe/canBe.ts +++ b/src/canBe/canBe.ts @@ -1,5 +1,5 @@ -import { hasValueInReadOnlyStringList } from './_internal'; -import { CHOSEONGS, JONGSEONGS, JUNSEONGS } from './constants'; +import { hasValueInReadOnlyStringList } from '../_internal'; +import { CHOSEONGS, JONGSEONGS, JUNSEONGS } from '../constants'; /** * @name canBeChoseong diff --git a/src/combineCharacter/combineCharacter.ts b/src/combineCharacter/combineCharacter.ts index 75647f38..e3ce0a21 100644 --- a/src/combineCharacter/combineCharacter.ts +++ b/src/combineCharacter/combineCharacter.ts @@ -1,11 +1,11 @@ -import { canBeChoseong, canBeJongseong, canBeJungseong } from './canBe'; +import { canBeChoseong, canBeJongseong, canBeJungseong } from '../canBe'; import { COMPLETE_HANGUL_START_CHARCODE, DISASSEMBLED_VOWELS_BY_VOWEL, CHOSEONGS, JONGSEONGS, JUNSEONGS, -} from './constants'; +} from '../constants'; /** * @name combineCharacter diff --git a/src/convertQwertyToAlphabet/convertQwertyToAlphabet.ts b/src/convertQwertyToAlphabet/convertQwertyToAlphabet.ts index b4c1ae3f..5c3b2037 100644 --- a/src/convertQwertyToAlphabet/convertQwertyToAlphabet.ts +++ b/src/convertQwertyToAlphabet/convertQwertyToAlphabet.ts @@ -1,6 +1,6 @@ -import { hasProperty } from './_internal'; -import { assemble } from './assemble'; -import { QWERTY_KEYBOARD_MAP } from './constants'; +import { hasProperty } from '../_internal'; +import { assemble } from '../assemble'; +import { QWERTY_KEYBOARD_MAP } from '../constants'; /** * @name convertQwertyToAlphabet diff --git a/src/disassemble/disassemble.ts b/src/disassemble/disassemble.ts index 4f0b9b3f..32b06457 100644 --- a/src/disassemble/disassemble.ts +++ b/src/disassemble/disassemble.ts @@ -1,6 +1,6 @@ -import { hasProperty } from './_internal'; -import { DISASSEMBLED_CONSONANTS_BY_CONSONANT, DISASSEMBLED_VOWELS_BY_VOWEL } from './constants'; -import { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; +import { hasProperty } from '../_internal'; +import { DISASSEMBLED_CONSONANTS_BY_CONSONANT, DISASSEMBLED_VOWELS_BY_VOWEL } from '../constants'; +import { disassembleCompleteCharacter } from '../disassembleCompleteCharacter'; export function disassembleToGroups(str: string) { /* diff --git a/src/disassembleCompleteCharacter/disassembleCompleteCharacter.ts b/src/disassembleCompleteCharacter/disassembleCompleteCharacter.ts index 4a4337cb..99258a18 100644 --- a/src/disassembleCompleteCharacter/disassembleCompleteCharacter.ts +++ b/src/disassembleCompleteCharacter/disassembleCompleteCharacter.ts @@ -6,7 +6,7 @@ import { JUNSEONGS, NUMBER_OF_JONGSEONG, NUMBER_OF_JUNGSEONG, -} from './constants'; +} from '../constants'; interface ReturnTypeDisassembleCompleteCharacter { choseong: (typeof CHOSEONGS)[number]; diff --git a/src/getChoseong/getChoseong.ts b/src/getChoseong/getChoseong.ts index 17cedf59..85f2d5e1 100644 --- a/src/getChoseong/getChoseong.ts +++ b/src/getChoseong/getChoseong.ts @@ -1,4 +1,4 @@ -import { CHOSEONGS, JASO_HANGUL_NFD } from './constants'; +import { CHOSEONGS, JASO_HANGUL_NFD } from '../constants'; /** * @name getChoseong diff --git a/src/hasBatchim/hasBatchim.ts b/src/hasBatchim/hasBatchim.ts index 02e44c5f..fd7ebd58 100644 --- a/src/hasBatchim/hasBatchim.ts +++ b/src/hasBatchim/hasBatchim.ts @@ -3,7 +3,7 @@ import { COMPLETE_HANGUL_START_CHARCODE, JONGSEONGS, NUMBER_OF_JONGSEONG, -} from './constants'; +} from '../constants'; /** * @name hasBatchim diff --git a/src/josa/josa.ts b/src/josa/josa.ts index 906c0b3e..5ff5d499 100644 --- a/src/josa/josa.ts +++ b/src/josa/josa.ts @@ -1,5 +1,5 @@ -import { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; -import { hasBatchim } from './hasBatchim'; +import { disassembleCompleteCharacter } from '../disassembleCompleteCharacter'; +import { hasBatchim } from '../hasBatchim'; type JosaOption = | '이/가' diff --git a/src/removeLastCharacter/removeLastCharacter.ts b/src/removeLastCharacter/removeLastCharacter.ts index 0aed34fe..6c237551 100644 --- a/src/removeLastCharacter/removeLastCharacter.ts +++ b/src/removeLastCharacter/removeLastCharacter.ts @@ -1,7 +1,7 @@ -import { combineCharacter } from './combineCharacter'; -import { excludeLastElement } from './_internal'; -import { canBeJungseong } from './canBe'; -import { disassembleToGroups } from './disassemble'; +import { combineCharacter } from '../combineCharacter'; +import { excludeLastElement } from '../_internal'; +import { canBeJungseong } from '../canBe'; +import { disassembleToGroups } from '../disassemble'; /** * @name removeLastCharacter diff --git a/src/romanize/romanize.ts b/src/romanize/romanize.ts index 4ff0c0fd..0515b4eb 100644 --- a/src/romanize/romanize.ts +++ b/src/romanize/romanize.ts @@ -1,9 +1,9 @@ -import { isHangulCharacter } from './_internal/hangul'; -import { assemble } from './assemble'; -import { canBeChoseong } from './canBe'; -import { 종성_알파벳_발음, 중성_알파벳_발음, 초성_알파벳_발음 } from './constants'; -import { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; -import { standardizePronunciation } from './standardizePronunciation'; +import { isHangulCharacter } from '../_internal/hangul'; +import { assemble } from '../assemble'; +import { canBeChoseong } from '../canBe'; +import { 종성_알파벳_발음, 중성_알파벳_발음, 초성_알파벳_발음 } from '../constants'; +import { disassembleCompleteCharacter } from '../disassembleCompleteCharacter'; +import { standardizePronunciation } from '../standardizePronunciation'; /** * 주어진 한글 문자열을 로마자로 변환합니다. diff --git a/src/susa/susa.ts b/src/susa/susa.ts index 342c2ad7..b0012f12 100644 --- a/src/susa/susa.ts +++ b/src/susa/susa.ts @@ -1,5 +1,5 @@ -import { hasProperty } from './_internal'; -import { SUSA_MAP, SUSA_CLASSIFIER_MAP } from './constants'; +import { hasProperty } from '../_internal'; +import { SUSA_MAP, SUSA_CLASSIFIER_MAP } from '../constants'; export function susa(num: number, classifier?: boolean): string { validateNumber(num); From 73241804ca339fe2e5c2c5e780708cb6c6885187 Mon Sep 17 00:00:00 2001 From: chanhyuk-park Date: Fri, 6 Sep 2024 01:39:50 +0900 Subject: [PATCH 3/4] =?UTF-8?q?constant=20=ED=8C=8C=EC=9D=BC=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/_internal/constants.ts | 136 ++++++++ src/canBe/canBe.ts | 2 +- src/combineCharacter/combineCharacter.ts | 6 +- src/constants.ts | 300 ------------------ src/convertQwertyToAlphabet/constants.ts | 57 ++++ .../convertQwertyToAlphabet.ts | 2 +- src/disassemble/disassemble.ts | 2 +- src/disassembleCompleteCharacter/constants.ts | 1 + .../disassembleCompleteCharacter.ts | 4 +- src/getChoseong/constants.ts | 10 + src/getChoseong/getChoseong.ts | 3 +- src/hasBatchim/hasBatchim.ts | 2 +- src/romanize/constants.ts | 68 ++++ src/romanize/romanize.ts | 2 +- src/susa/constants.ts | 29 ++ src/susa/susa.ts | 2 +- tsconfig.json | 6 +- 17 files changed, 319 insertions(+), 313 deletions(-) create mode 100644 src/_internal/constants.ts delete mode 100644 src/constants.ts create mode 100644 src/convertQwertyToAlphabet/constants.ts create mode 100644 src/disassembleCompleteCharacter/constants.ts create mode 100644 src/getChoseong/constants.ts create mode 100644 src/romanize/constants.ts create mode 100644 src/susa/constants.ts diff --git a/src/_internal/constants.ts b/src/_internal/constants.ts new file mode 100644 index 00000000..16dac59e --- /dev/null +++ b/src/_internal/constants.ts @@ -0,0 +1,136 @@ +export const _JASO_HANGUL_NFD = [...'각힣'.normalize('NFD')].map(char => char.charCodeAt(0)); // NFC 에 정의되지 않은 문자는 포함하지 않음 + +export const COMPLETE_HANGUL_START_CHARCODE = '가'.charCodeAt(0); +export const COMPLETE_HANGUL_END_CHARCODE = '힣'.charCodeAt(0); + +export const NUMBER_OF_JONGSEONG = 28; +export const NUMBER_OF_JUNGSEONG = 21; + +/** + * ㄱ -> 'ㄱ' + * ㄳ -> 'ㄱㅅ' 으로 나눈다. + */ +export const DISASSEMBLED_CONSONANTS_BY_CONSONANT = { + // 종성이 없는 경우 '빈' 초성으로 관리하는 것이 편리하여, 빈 문자열도 포함한다. + '': '', + ㄱ: 'ㄱ', + ㄲ: 'ㄲ', + ㄳ: 'ㄱㅅ', + ㄴ: 'ㄴ', + ㄵ: 'ㄴㅈ', + ㄶ: 'ㄴㅎ', + ㄷ: 'ㄷ', + ㄸ: 'ㄸ', + ㄹ: 'ㄹ', + ㄺ: 'ㄹㄱ', + ㄻ: 'ㄹㅁ', + ㄼ: 'ㄹㅂ', + ㄽ: 'ㄹㅅ', + ㄾ: 'ㄹㅌ', + ㄿ: 'ㄹㅍ', + ㅀ: 'ㄹㅎ', + ㅁ: 'ㅁ', + ㅂ: 'ㅂ', + ㅃ: 'ㅃ', + ㅄ: 'ㅂㅅ', + ㅅ: 'ㅅ', + ㅆ: 'ㅆ', + ㅇ: 'ㅇ', + ㅈ: 'ㅈ', + ㅉ: 'ㅉ', + ㅊ: 'ㅊ', + ㅋ: 'ㅋ', + ㅌ: 'ㅌ', + ㅍ: 'ㅍ', + ㅎ: 'ㅎ', +} as const; + +export const DISASSEMBLED_VOWELS_BY_VOWEL = { + ㅏ: 'ㅏ', + ㅐ: 'ㅐ', + ㅑ: 'ㅑ', + ㅒ: 'ㅒ', + ㅓ: 'ㅓ', + ㅔ: 'ㅔ', + ㅕ: 'ㅕ', + ㅖ: 'ㅖ', + ㅗ: 'ㅗ', + ㅘ: 'ㅗㅏ', + ㅙ: 'ㅗㅐ', + ㅚ: 'ㅗㅣ', + ㅛ: 'ㅛ', + ㅜ: 'ㅜ', + ㅝ: 'ㅜㅓ', + ㅞ: 'ㅜㅔ', + ㅟ: 'ㅜㅣ', + ㅠ: 'ㅠ', + ㅡ: 'ㅡ', + ㅢ: 'ㅡㅣ', + ㅣ: 'ㅣ', +} as const; + +/** + * 초성으로 올 수 있는 한글 글자 + */ +export const CHOSEONGS = [ + 'ㄱ', + 'ㄲ', + 'ㄴ', + 'ㄷ', + 'ㄸ', + 'ㄹ', + 'ㅁ', + 'ㅂ', + 'ㅃ', + 'ㅅ', + 'ㅆ', + 'ㅇ', + 'ㅈ', + 'ㅉ', + 'ㅊ', + 'ㅋ', + 'ㅌ', + 'ㅍ', + 'ㅎ', +] as const; + +/** + * 중성으로 올 수 있는 한글 글자 + */ +export const JUNSEONGS = Object.values(DISASSEMBLED_VOWELS_BY_VOWEL); + +/** + * 종성으로 올 수 있는 한글 글자 + */ +export const JONGSEONGS = ( + [ + '', + 'ㄱ', + 'ㄲ', + 'ㄳ', + 'ㄴ', + 'ㄵ', + 'ㄶ', + 'ㄷ', + 'ㄹ', + 'ㄺ', + 'ㄻ', + 'ㄼ', + 'ㄽ', + 'ㄾ', + 'ㄿ', + 'ㅀ', + 'ㅁ', + 'ㅂ', + 'ㅄ', + 'ㅅ', + 'ㅆ', + 'ㅇ', + 'ㅈ', + 'ㅊ', + 'ㅋ', + 'ㅌ', + 'ㅍ', + 'ㅎ', + ] as const +).map(consonant => DISASSEMBLED_CONSONANTS_BY_CONSONANT[consonant]); diff --git a/src/canBe/canBe.ts b/src/canBe/canBe.ts index db09c50f..fea93e3e 100644 --- a/src/canBe/canBe.ts +++ b/src/canBe/canBe.ts @@ -1,5 +1,5 @@ +import { CHOSEONGS, JONGSEONGS, JUNSEONGS } from '@/_internal/constants'; import { hasValueInReadOnlyStringList } from '../_internal'; -import { CHOSEONGS, JONGSEONGS, JUNSEONGS } from '../constants'; /** * @name canBeChoseong diff --git a/src/combineCharacter/combineCharacter.ts b/src/combineCharacter/combineCharacter.ts index e3ce0a21..01ac0d70 100644 --- a/src/combineCharacter/combineCharacter.ts +++ b/src/combineCharacter/combineCharacter.ts @@ -1,11 +1,11 @@ -import { canBeChoseong, canBeJongseong, canBeJungseong } from '../canBe'; import { + CHOSEONGS, COMPLETE_HANGUL_START_CHARCODE, DISASSEMBLED_VOWELS_BY_VOWEL, - CHOSEONGS, JONGSEONGS, JUNSEONGS, -} from '../constants'; +} from '@/_internal/constants'; +import { canBeChoseong, canBeJongseong, canBeJungseong } from '../canBe'; /** * @name combineCharacter diff --git a/src/constants.ts b/src/constants.ts deleted file mode 100644 index e9704ff9..00000000 --- a/src/constants.ts +++ /dev/null @@ -1,300 +0,0 @@ -export const COMPLETE_HANGUL_START_CHARCODE = '가'.charCodeAt(0); -export const COMPLETE_HANGUL_END_CHARCODE = '힣'.charCodeAt(0); -export const NUMBER_OF_JONGSEONG = 28; -export const NUMBER_OF_JUNGSEONG = 21; - -const _JASO_HANGUL_NFD = [...'각힣'.normalize('NFD')].map(char => char.charCodeAt(0)); // NFC 에 정의되지 않은 문자는 포함하지 않음 -export const JASO_HANGUL_NFD = { - START_CHOSEONG: _JASO_HANGUL_NFD[0], // ㄱ - START_JUNGSEONG: _JASO_HANGUL_NFD[1], // ㅏ - START_JONGSEONG: _JASO_HANGUL_NFD[2], // ㄱ - END_CHOSEONG: _JASO_HANGUL_NFD[3], // ㅎ - END_JUNGSEONG: _JASO_HANGUL_NFD[4], // ㅣ - END_JONGSEONG: _JASO_HANGUL_NFD[5], // ㅎ -}; - -/** - * ㄱ -> 'ㄱ' - * ㄳ -> 'ㄱㅅ' 으로 나눈다. - */ -export const DISASSEMBLED_CONSONANTS_BY_CONSONANT = { - // 종성이 없는 경우 '빈' 초성으로 관리하는 것이 편리하여, 빈 문자열도 포함한다. - '': '', - ㄱ: 'ㄱ', - ㄲ: 'ㄲ', - ㄳ: 'ㄱㅅ', - ㄴ: 'ㄴ', - ㄵ: 'ㄴㅈ', - ㄶ: 'ㄴㅎ', - ㄷ: 'ㄷ', - ㄸ: 'ㄸ', - ㄹ: 'ㄹ', - ㄺ: 'ㄹㄱ', - ㄻ: 'ㄹㅁ', - ㄼ: 'ㄹㅂ', - ㄽ: 'ㄹㅅ', - ㄾ: 'ㄹㅌ', - ㄿ: 'ㄹㅍ', - ㅀ: 'ㄹㅎ', - ㅁ: 'ㅁ', - ㅂ: 'ㅂ', - ㅃ: 'ㅃ', - ㅄ: 'ㅂㅅ', - ㅅ: 'ㅅ', - ㅆ: 'ㅆ', - ㅇ: 'ㅇ', - ㅈ: 'ㅈ', - ㅉ: 'ㅉ', - ㅊ: 'ㅊ', - ㅋ: 'ㅋ', - ㅌ: 'ㅌ', - ㅍ: 'ㅍ', - ㅎ: 'ㅎ', -} as const; - -export const DISASSEMBLED_VOWELS_BY_VOWEL = { - ㅏ: 'ㅏ', - ㅐ: 'ㅐ', - ㅑ: 'ㅑ', - ㅒ: 'ㅒ', - ㅓ: 'ㅓ', - ㅔ: 'ㅔ', - ㅕ: 'ㅕ', - ㅖ: 'ㅖ', - ㅗ: 'ㅗ', - ㅘ: 'ㅗㅏ', - ㅙ: 'ㅗㅐ', - ㅚ: 'ㅗㅣ', - ㅛ: 'ㅛ', - ㅜ: 'ㅜ', - ㅝ: 'ㅜㅓ', - ㅞ: 'ㅜㅔ', - ㅟ: 'ㅜㅣ', - ㅠ: 'ㅠ', - ㅡ: 'ㅡ', - ㅢ: 'ㅡㅣ', - ㅣ: 'ㅣ', -} as const; - -/** - * 초성으로 올 수 있는 한글 글자 - */ -export const CHOSEONGS = [ - 'ㄱ', - 'ㄲ', - 'ㄴ', - 'ㄷ', - 'ㄸ', - 'ㄹ', - 'ㅁ', - 'ㅂ', - 'ㅃ', - 'ㅅ', - 'ㅆ', - 'ㅇ', - 'ㅈ', - 'ㅉ', - 'ㅊ', - 'ㅋ', - 'ㅌ', - 'ㅍ', - 'ㅎ', -] as const; - -/** - * 중성으로 올 수 있는 한글 글자 - */ -export const JUNSEONGS = Object.values(DISASSEMBLED_VOWELS_BY_VOWEL); - -/** - * 종성으로 올 수 있는 한글 글자 - */ -export const JONGSEONGS = ( - [ - '', - 'ㄱ', - 'ㄲ', - 'ㄳ', - 'ㄴ', - 'ㄵ', - 'ㄶ', - 'ㄷ', - 'ㄹ', - 'ㄺ', - 'ㄻ', - 'ㄼ', - 'ㄽ', - 'ㄾ', - 'ㄿ', - 'ㅀ', - 'ㅁ', - 'ㅂ', - 'ㅄ', - 'ㅅ', - 'ㅆ', - 'ㅇ', - 'ㅈ', - 'ㅊ', - 'ㅋ', - 'ㅌ', - 'ㅍ', - 'ㅎ', - ] as const -).map(consonant => DISASSEMBLED_CONSONANTS_BY_CONSONANT[consonant]); - -/** - * qwerty 키보드 자판의 대소문자를 구분한 영어 알파벳을 한글 음소와 맵핑한 객체 - */ -export const QWERTY_KEYBOARD_MAP = { - q: 'ㅂ', - Q: 'ㅃ', - w: 'ㅈ', - W: 'ㅉ', - e: 'ㄷ', - E: 'ㄸ', - r: 'ㄱ', - R: 'ㄲ', - t: 'ㅅ', - T: 'ㅆ', - y: 'ㅛ', - Y: 'ㅛ', - u: 'ㅕ', - U: 'ㅕ', - i: 'ㅑ', - I: 'ㅑ', - o: 'ㅐ', - O: 'ㅒ', - p: 'ㅔ', - P: 'ㅖ', - a: 'ㅁ', - A: 'ㅁ', - s: 'ㄴ', - S: 'ㄴ', - d: 'ㅇ', - D: 'ㅇ', - f: 'ㄹ', - F: 'ㄹ', - g: 'ㅎ', - G: 'ㅎ', - h: 'ㅗ', - H: 'ㅗ', - j: 'ㅓ', - J: 'ㅓ', - k: 'ㅏ', - K: 'ㅏ', - l: 'ㅣ', - L: 'ㅣ', - z: 'ㅋ', - Z: 'ㅋ', - x: 'ㅌ', - X: 'ㅌ', - c: 'ㅊ', - C: 'ㅊ', - v: 'ㅍ', - V: 'ㅍ', - b: 'ㅠ', - B: 'ㅠ', - n: 'ㅜ', - N: 'ㅜ', - m: 'ㅡ', - M: 'ㅡ', -} as const; - -export const 중성_알파벳_발음 = { - // ------- 단모음 - ㅏ: 'a', - ㅓ: 'eo', - ㅗ: 'o', - ㅜ: 'u', - ㅡ: 'eu', - ㅣ: 'i', - ㅐ: 'ae', - ㅔ: 'e', - ㅚ: 'oe', - ㅟ: 'wi', - // ------- - // ------- 이중모음 - ㅑ: 'ya', - ㅕ: 'yeo', - ㅛ: 'yo', - ㅠ: 'yu', - ㅒ: 'yae', - ㅖ: 'ye', - ㅘ: 'wa', - ㅙ: 'wae', - ㅝ: 'wo', - ㅞ: 'we', - ㅢ: 'ui', -} as const; - -export const 초성_알파벳_발음 = { - // ------- 파열음 - ㄱ: 'g', - ㄲ: 'kk', - ㅋ: 'k', - ㄷ: 'd', - ㄸ: 'tt', - ㅌ: 't', - ㅂ: 'b', - ㅃ: 'pp', - ㅍ: 'p', - // ------- - // ------- 파찰음 - ㅈ: 'j', - ㅉ: 'jj', - ㅊ: 'ch', - // ------- - // ------- 마찰음 - ㅅ: 's', - ㅆ: 'ss', - ㅎ: 'h', - // ------- - // ------- 비음 - ㄴ: 'n', - ㅁ: 'm', - ㅇ: '', - // ------- - // ------- 유음 - ㄹ: 'r', -} as const; - -export const 종성_알파벳_발음 = { - ㄱ: 'k', - ㄴ: 'n', - ㄷ: 't', - ㄹ: 'l', - ㅁ: 'm', - ㅂ: 'p', - ㅇ: 'ng', - '': '', -} as const; - -export const SUSA_MAP = { - 1: '하나', - 2: '둘', - 3: '셋', - 4: '넷', - 5: '다섯', - 6: '여섯', - 7: '일곱', - 8: '여덟', - 9: '아홉', - 10: '열', - 20: '스물', - 30: '서른', - 40: '마흔', - 50: '쉰', - 60: '예순', - 70: '일흔', - 80: '여든', - 90: '아흔', - 100: '백', -} as const; - -export const SUSA_CLASSIFIER_MAP = { - 1: '한', - 2: '두', - 3: '세', - 4: '네', - 20: '스무', -} as const; diff --git a/src/convertQwertyToAlphabet/constants.ts b/src/convertQwertyToAlphabet/constants.ts new file mode 100644 index 00000000..094acd59 --- /dev/null +++ b/src/convertQwertyToAlphabet/constants.ts @@ -0,0 +1,57 @@ +/** + * qwerty 키보드 자판의 대소문자를 구분한 영어 알파벳을 한글 음소와 맵핑한 객체 + */ +export const QWERTY_KEYBOARD_MAP = { + q: 'ㅂ', + Q: 'ㅃ', + w: 'ㅈ', + W: 'ㅉ', + e: 'ㄷ', + E: 'ㄸ', + r: 'ㄱ', + R: 'ㄲ', + t: 'ㅅ', + T: 'ㅆ', + y: 'ㅛ', + Y: 'ㅛ', + u: 'ㅕ', + U: 'ㅕ', + i: 'ㅑ', + I: 'ㅑ', + o: 'ㅐ', + O: 'ㅒ', + p: 'ㅔ', + P: 'ㅖ', + a: 'ㅁ', + A: 'ㅁ', + s: 'ㄴ', + S: 'ㄴ', + d: 'ㅇ', + D: 'ㅇ', + f: 'ㄹ', + F: 'ㄹ', + g: 'ㅎ', + G: 'ㅎ', + h: 'ㅗ', + H: 'ㅗ', + j: 'ㅓ', + J: 'ㅓ', + k: 'ㅏ', + K: 'ㅏ', + l: 'ㅣ', + L: 'ㅣ', + z: 'ㅋ', + Z: 'ㅋ', + x: 'ㅌ', + X: 'ㅌ', + c: 'ㅊ', + C: 'ㅊ', + v: 'ㅍ', + V: 'ㅍ', + b: 'ㅠ', + B: 'ㅠ', + n: 'ㅜ', + N: 'ㅜ', + m: 'ㅡ', + M: 'ㅡ', +} as const; diff --git a/src/convertQwertyToAlphabet/convertQwertyToAlphabet.ts b/src/convertQwertyToAlphabet/convertQwertyToAlphabet.ts index 5c3b2037..a0c1cda8 100644 --- a/src/convertQwertyToAlphabet/convertQwertyToAlphabet.ts +++ b/src/convertQwertyToAlphabet/convertQwertyToAlphabet.ts @@ -1,6 +1,6 @@ import { hasProperty } from '../_internal'; import { assemble } from '../assemble'; -import { QWERTY_KEYBOARD_MAP } from '../constants'; +import { QWERTY_KEYBOARD_MAP } from './constants'; /** * @name convertQwertyToAlphabet diff --git a/src/disassemble/disassemble.ts b/src/disassemble/disassemble.ts index 32b06457..61dd0701 100644 --- a/src/disassemble/disassemble.ts +++ b/src/disassemble/disassemble.ts @@ -1,5 +1,5 @@ +import { DISASSEMBLED_CONSONANTS_BY_CONSONANT, DISASSEMBLED_VOWELS_BY_VOWEL } from '@/_internal/constants'; import { hasProperty } from '../_internal'; -import { DISASSEMBLED_CONSONANTS_BY_CONSONANT, DISASSEMBLED_VOWELS_BY_VOWEL } from '../constants'; import { disassembleCompleteCharacter } from '../disassembleCompleteCharacter'; export function disassembleToGroups(str: string) { diff --git a/src/disassembleCompleteCharacter/constants.ts b/src/disassembleCompleteCharacter/constants.ts new file mode 100644 index 00000000..99888570 --- /dev/null +++ b/src/disassembleCompleteCharacter/constants.ts @@ -0,0 +1 @@ +export const NUMBER_OF_JUNGSEONG = 21; diff --git a/src/disassembleCompleteCharacter/disassembleCompleteCharacter.ts b/src/disassembleCompleteCharacter/disassembleCompleteCharacter.ts index 99258a18..73006c59 100644 --- a/src/disassembleCompleteCharacter/disassembleCompleteCharacter.ts +++ b/src/disassembleCompleteCharacter/disassembleCompleteCharacter.ts @@ -1,12 +1,12 @@ import { + CHOSEONGS, COMPLETE_HANGUL_END_CHARCODE, COMPLETE_HANGUL_START_CHARCODE, - CHOSEONGS, JONGSEONGS, JUNSEONGS, NUMBER_OF_JONGSEONG, NUMBER_OF_JUNGSEONG, -} from '../constants'; +} from '@/_internal/constants'; interface ReturnTypeDisassembleCompleteCharacter { choseong: (typeof CHOSEONGS)[number]; diff --git a/src/getChoseong/constants.ts b/src/getChoseong/constants.ts new file mode 100644 index 00000000..2819316a --- /dev/null +++ b/src/getChoseong/constants.ts @@ -0,0 +1,10 @@ +import { _JASO_HANGUL_NFD } from '@/_internal/constants'; + +export const JASO_HANGUL_NFD = { + START_CHOSEONG: _JASO_HANGUL_NFD[0], // ㄱ + START_JUNGSEONG: _JASO_HANGUL_NFD[1], // ㅏ + START_JONGSEONG: _JASO_HANGUL_NFD[2], // ㄱ + END_CHOSEONG: _JASO_HANGUL_NFD[3], // ㅎ + END_JUNGSEONG: _JASO_HANGUL_NFD[4], // ㅣ + END_JONGSEONG: _JASO_HANGUL_NFD[5], // ㅎ +}; diff --git a/src/getChoseong/getChoseong.ts b/src/getChoseong/getChoseong.ts index 85f2d5e1..ad7542ec 100644 --- a/src/getChoseong/getChoseong.ts +++ b/src/getChoseong/getChoseong.ts @@ -1,4 +1,5 @@ -import { CHOSEONGS, JASO_HANGUL_NFD } from '../constants'; +import { CHOSEONGS } from '@/_internal/constants'; +import { JASO_HANGUL_NFD } from './constants'; /** * @name getChoseong diff --git a/src/hasBatchim/hasBatchim.ts b/src/hasBatchim/hasBatchim.ts index fd7ebd58..c004a0aa 100644 --- a/src/hasBatchim/hasBatchim.ts +++ b/src/hasBatchim/hasBatchim.ts @@ -3,7 +3,7 @@ import { COMPLETE_HANGUL_START_CHARCODE, JONGSEONGS, NUMBER_OF_JONGSEONG, -} from '../constants'; +} from '@/_internal/constants'; /** * @name hasBatchim diff --git a/src/romanize/constants.ts b/src/romanize/constants.ts new file mode 100644 index 00000000..55004aa8 --- /dev/null +++ b/src/romanize/constants.ts @@ -0,0 +1,68 @@ +export const 중성_알파벳_발음 = { + // ------- 단모음 + ㅏ: 'a', + ㅓ: 'eo', + ㅗ: 'o', + ㅜ: 'u', + ㅡ: 'eu', + ㅣ: 'i', + ㅐ: 'ae', + ㅔ: 'e', + ㅚ: 'oe', + ㅟ: 'wi', + // ------- + // ------- 이중모음 + ㅑ: 'ya', + ㅕ: 'yeo', + ㅛ: 'yo', + ㅠ: 'yu', + ㅒ: 'yae', + ㅖ: 'ye', + ㅘ: 'wa', + ㅙ: 'wae', + ㅝ: 'wo', + ㅞ: 'we', + ㅢ: 'ui', +} as const; + +export const 초성_알파벳_발음 = { + // ------- 파열음 + ㄱ: 'g', + ㄲ: 'kk', + ㅋ: 'k', + ㄷ: 'd', + ㄸ: 'tt', + ㅌ: 't', + ㅂ: 'b', + ㅃ: 'pp', + ㅍ: 'p', + // ------- + // ------- 파찰음 + ㅈ: 'j', + ㅉ: 'jj', + ㅊ: 'ch', + // ------- + // ------- 마찰음 + ㅅ: 's', + ㅆ: 'ss', + ㅎ: 'h', + // ------- + // ------- 비음 + ㄴ: 'n', + ㅁ: 'm', + ㅇ: '', + // ------- + // ------- 유음 + ㄹ: 'r', +} as const; + +export const 종성_알파벳_발음 = { + ㄱ: 'k', + ㄴ: 'n', + ㄷ: 't', + ㄹ: 'l', + ㅁ: 'm', + ㅂ: 'p', + ㅇ: 'ng', + '': '', +} as const; diff --git a/src/romanize/romanize.ts b/src/romanize/romanize.ts index 0515b4eb..0147ba05 100644 --- a/src/romanize/romanize.ts +++ b/src/romanize/romanize.ts @@ -1,9 +1,9 @@ import { isHangulCharacter } from '../_internal/hangul'; import { assemble } from '../assemble'; import { canBeChoseong } from '../canBe'; -import { 종성_알파벳_발음, 중성_알파벳_발음, 초성_알파벳_발음 } from '../constants'; import { disassembleCompleteCharacter } from '../disassembleCompleteCharacter'; import { standardizePronunciation } from '../standardizePronunciation'; +import { 종성_알파벳_발음, 중성_알파벳_발음, 초성_알파벳_발음 } from './constants'; /** * 주어진 한글 문자열을 로마자로 변환합니다. diff --git a/src/susa/constants.ts b/src/susa/constants.ts new file mode 100644 index 00000000..46bf6210 --- /dev/null +++ b/src/susa/constants.ts @@ -0,0 +1,29 @@ +export const SUSA_MAP = { + 1: '하나', + 2: '둘', + 3: '셋', + 4: '넷', + 5: '다섯', + 6: '여섯', + 7: '일곱', + 8: '여덟', + 9: '아홉', + 10: '열', + 20: '스물', + 30: '서른', + 40: '마흔', + 50: '쉰', + 60: '예순', + 70: '일흔', + 80: '여든', + 90: '아흔', + 100: '백', +} as const; + +export const SUSA_CLASSIFIER_MAP = { + 1: '한', + 2: '두', + 3: '세', + 4: '네', + 20: '스무', +} as const; diff --git a/src/susa/susa.ts b/src/susa/susa.ts index b0012f12..e0f30d02 100644 --- a/src/susa/susa.ts +++ b/src/susa/susa.ts @@ -1,5 +1,5 @@ import { hasProperty } from '../_internal'; -import { SUSA_MAP, SUSA_CLASSIFIER_MAP } from '../constants'; +import { SUSA_MAP, SUSA_CLASSIFIER_MAP } from './constants'; export function susa(num: number, classifier?: boolean): string { validateNumber(num); diff --git a/tsconfig.json b/tsconfig.json index 567408a1..f11811bc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,11 @@ "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, - "resolveJsonModule": true + "resolveJsonModule": true, + "baseUrl": "./", + "paths": { + "@/*": ["src/*"] + } }, "include": ["src", ".eslintrc.js", "packlint.config.mjs", "vitest.config.mts"] } From b72ac247c0db03dc6e988170d7cd791cf9f5b91c Mon Sep 17 00:00:00 2001 From: chanhyuk-park Date: Fri, 6 Sep 2024 01:42:03 +0900 Subject: [PATCH 4/4] vitest absoulte path --- vitest.config.mts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vitest.config.mts b/vitest.config.mts index 1cb8bfc5..a5d42242 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -1,7 +1,13 @@ import { defineConfig } from 'vitest/config'; import packageJson from './package.json'; +import path from 'path'; export default defineConfig({ + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, test: { name: packageJson.name, dir: './src',