From 8a97fffbaf1c4c68c228d10c4b8972f4e507e70e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=B0=AC=ED=98=81?= Date: Sun, 14 Jul 2024 16:25:28 +0900 Subject: [PATCH 01/21] =?UTF-8?q?feat:=20=EB=AC=B8=EC=9E=90=EC=97=B4?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=ED=95=9C=EA=B8=80=EC=9D=84=20=EC=B6=94?= =?UTF-8?q?=EC=B6=9C=ED=95=B4=EC=A3=BC=EB=8A=94=20extractHangul=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=EB=A5=BC=20=EC=A0=9C=EA=B1=B0=ED=95=A9?= =?UTF-8?q?=EB=8B=88=EB=8B=A4=20(#185)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove extrachHangul * Create cyan-tigers-sneeze.md --------- Co-authored-by: Jonghyeon Ko --- .changeset/cyan-tigers-sneeze.md | 5 ++++ docs/src/pages/docs/api/extractHangul.en.md | 23 ------------------ docs/src/pages/docs/api/extractHangul.ko.md | 23 ------------------ src/extractHangul.spec.ts | 27 --------------------- src/extractHangul.ts | 18 -------------- src/index.ts | 2 -- 6 files changed, 5 insertions(+), 93 deletions(-) create mode 100644 .changeset/cyan-tigers-sneeze.md delete mode 100644 docs/src/pages/docs/api/extractHangul.en.md delete mode 100644 docs/src/pages/docs/api/extractHangul.ko.md delete mode 100644 src/extractHangul.spec.ts delete mode 100644 src/extractHangul.ts diff --git a/.changeset/cyan-tigers-sneeze.md b/.changeset/cyan-tigers-sneeze.md new file mode 100644 index 00000000..931532d6 --- /dev/null +++ b/.changeset/cyan-tigers-sneeze.md @@ -0,0 +1,5 @@ +--- +"es-hangul": major +--- + +feat: 문자열에서 한글을 추출해주는 extractHangul 함수를 제거합니다 diff --git a/docs/src/pages/docs/api/extractHangul.en.md b/docs/src/pages/docs/api/extractHangul.en.md deleted file mode 100644 index c685c84a..00000000 --- a/docs/src/pages/docs/api/extractHangul.en.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: extractHangul ---- - -# extractHangul - -Extracts and returns only Korean characters from the string. - -For detailed examples, see below. - -```typescript -function extractHangul(str: string): string; -``` - -## Examples - -```tsx -extractHangul('안녕하세요1234abc'); // '안녕하세요' -extractHangul('abcde'); // '' -extractHangul('안녕하세요ㄱㄴ'); // '안녕하세요ㄱㄴ' -extractHangul('안녕하세요 만나서 반갑습니다'); // '안녕하세요 만나서 반갑습니다' -extractHangul('가나다!-29~라마바.,,사'); // '가나다라마바사' -``` diff --git a/docs/src/pages/docs/api/extractHangul.ko.md b/docs/src/pages/docs/api/extractHangul.ko.md deleted file mode 100644 index dc089bdb..00000000 --- a/docs/src/pages/docs/api/extractHangul.ko.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: extractHangul ---- - -# extractHangul - -문자열에서 한글만 추출하여 반환합니다. - -자세한 예시는 아래 Example을 참고하세요. - -```typescript -function extractHangul(str: string): string; -``` - -## Examples - -```tsx -extractHangul('안녕하세요1234abc'); // '안녕하세요' -extractHangul('abcde'); // '' -extractHangul('안녕하세요ㄱㄴ'); // '안녕하세요ㄱㄴ' -extractHangul('안녕하세요 만나서 반갑습니다'); // '안녕하세요 만나서 반갑습니다' -extractHangul('가나다!-29~라마바.,,사'); // '가나다라마바사' -``` diff --git a/src/extractHangul.spec.ts b/src/extractHangul.spec.ts deleted file mode 100644 index b3fd84dd..00000000 --- a/src/extractHangul.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { extractHangul } from './extractHangul'; - -describe('extractHangul', () => { - it('숫자와 알파벳과 특수문자를 제외한 한글 반환', () => { - expect(extractHangul('안녕하세요1234abc!@#')).toBe('안녕하세요'); - }); - - it('한글이 없는 문자열', () => { - expect(extractHangul('1234abc')).toBe(''); - }); - - it('한글과 공백을 제외한 다른 문자는 제거', () => { - expect(extractHangul('한글과 영어가 섞인 문장입니다. Hello!')).toBe('한글과 영어가 섞인 문장입니다 '); - }); - - it('escape 문자열 유지', () => { - expect(extractHangul('한글과\n\t줄바꿈')).toBe('한글과\n\t줄바꿈'); - }); - - it('모음은 제거하지 않음', () => { - expect(extractHangul('ㅠㅠ')).toBe('ㅠㅠ'); - }); - - it('자음은 제거하지 않음', () => { - expect(extractHangul('ㄱㄴㄱㄴ')).toBe('ㄱㄴㄱㄴ'); - }); -}); diff --git a/src/extractHangul.ts b/src/extractHangul.ts deleted file mode 100644 index d023a674..00000000 --- a/src/extractHangul.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @name extractHangul - * @description - * 문자열을 입력받고 한글만 추출해 반환합니다. - * - * @param {string} chars 모든 문자열 - * - * @example - * extractHangul('안녕하세요1234abc') // '안녕하세요' - * extractHangul('abcde') // '' - * extractHangul('안녕하세요ㄱㄴ') // '안녕하세요ㄱㄴ' - * extractHangul('안녕하세요 만나서 반갑습니다') // '안녕하세요 만나서 반갑습니다' - * extractHangul('가나다!-29~라마바.,,사') // '가나다라마바사' - */ - -export function extractHangul(str: string): string { - return str.replace(/[^ㄱ-ㅎㅏ-ㅣ가-힣\s]+/g, ''); -} diff --git a/src/index.ts b/src/index.ts index 12bccb38..c9ffaee6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,3 @@ -export { acronymizeHangul } from './acronymizeHangul'; export { assembleHangul } from './assemble'; export { choseongIncludes } from './choseongIncludes'; export { chosungIncludes } from './chosungIncludes'; @@ -6,7 +5,6 @@ export { combineHangulCharacter, combineVowels, curriedCombineHangulCharacter } export { convertQwertyToHangul, convertQwertyToHangulAlphabet } from './convertQwertyToHangulAlphabet'; export { disassembleHangul, disassembleHangulToGroups } from './disassemble'; export { disassembleCompleteHangulCharacter } from './disassembleCompleteHangulCharacter'; -export { extractHangul } from './extractHangul'; export { hangulIncludes } from './hangulIncludes'; export { josa } from './josa'; export { removeLastHangulCharacter } from './removeLastHangulCharacter'; From 6456f7989abd06d8abda29a3aadd460e5393e11b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=B0=AC=ED=98=81?= Date: Sun, 14 Jul 2024 16:46:30 +0900 Subject: [PATCH 02/21] =?UTF-8?q?feat:=20disassembleHangul,=20disassemble,?= =?UTF-8?q?=20disassembleHangulToGroup=20=ED=95=A8=EC=88=98=EC=97=90?= =?UTF-8?q?=EC=84=9C=20hangul=EC=9D=B4=EB=9D=BC=EB=8A=94=20=EA=B8=80?= =?UTF-8?q?=EC=9E=90=EB=A5=BC=20=EC=A0=9C=EA=B1=B0=ED=95=A9=EB=8B=88?= =?UTF-8?q?=EB=8B=A4=20(#184)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * dissemble관련 메서드에서 hangul이름을 제거합니다 * 누락된 부분 수정 * resolve conflit * Create late-beers-hang.md * diassembleHangul to diassemble --------- Co-authored-by: Jonghyeon Ko --- .changeset/late-beers-hang.md | 5 +++ ...assembleHangul.en.md => disassemble.en.md} | 14 +++---- ...assembleHangul.ko.md => disassemble.ko.md} | 14 +++---- ...Groups.en.md => disassembleToGroups.en.md} | 12 +++--- ...Groups.ko.md => disassembleToGroups.ko.md} | 12 +++--- docs/src/pages/docs/introduction.en.mdx | 8 ++-- docs/src/pages/docs/introduction.ko.mdx | 8 ++-- src/_internal/hangul.ts | 6 +-- src/assemble.ts | 4 +- src/choseongIncludes.ts | 4 +- src/disassemble.spec.ts | 26 ++++++------ src/disassemble.ts | 10 ++--- src/disassembleCompleteCharacter.spec.ts | 40 +++++++++++++++++++ ...ter.ts => disassembleCompleteCharacter.ts} | 16 ++++---- ...disassembleCompleteHangulCharacter.spec.ts | 40 ------------------- src/hangulIncludes.ts | 6 +-- src/index.ts | 4 +- src/josa.ts | 4 +- src/removeLastHangulCharacter.ts | 6 +-- src/utils.ts | 4 +- 20 files changed, 123 insertions(+), 120 deletions(-) create mode 100644 .changeset/late-beers-hang.md rename docs/src/pages/docs/api/{disassembleHangul.en.md => disassemble.en.md} (52%) rename docs/src/pages/docs/api/{disassembleHangul.ko.md => disassemble.ko.md} (51%) rename docs/src/pages/docs/api/{disassembleHangulToGroups.en.md => disassembleToGroups.en.md} (62%) rename docs/src/pages/docs/api/{disassembleHangulToGroups.ko.md => disassembleToGroups.ko.md} (59%) create mode 100644 src/disassembleCompleteCharacter.spec.ts rename src/{disassembleCompleteHangulCharacter.ts => disassembleCompleteCharacter.ts} (69%) delete mode 100644 src/disassembleCompleteHangulCharacter.spec.ts diff --git a/.changeset/late-beers-hang.md b/.changeset/late-beers-hang.md new file mode 100644 index 00000000..05bca1b0 --- /dev/null +++ b/.changeset/late-beers-hang.md @@ -0,0 +1,5 @@ +--- +"es-hangul": major +--- + +feat: disassembleHangul, disassemble, disassembleHangulToGroup 함수에서 hangul이라는 글자를 제거합니다 diff --git a/docs/src/pages/docs/api/disassembleHangul.en.md b/docs/src/pages/docs/api/disassemble.en.md similarity index 52% rename from docs/src/pages/docs/api/disassembleHangul.en.md rename to docs/src/pages/docs/api/disassemble.en.md index 6cf2867f..66d499ce 100644 --- a/docs/src/pages/docs/api/disassembleHangul.en.md +++ b/docs/src/pages/docs/api/disassemble.en.md @@ -1,15 +1,15 @@ --- -title: disassembleHangul +title: disassemble --- -# disassembleHangul +# disassemble Completely separates a Hangul string into its individual characters by initial consonants, medial vowels, and final consonants, creating a single string. For detailed examples, see below. ```typescript -function disassembleHangul( +function disassemble( // The Korean string to be disassembled str: string ): string; @@ -18,8 +18,8 @@ function disassembleHangul( ## Examples ```tsx -disassembleHangul('값'); // 'ㄱㅏㅂㅅ' -disassembleHangul('값이 비싸다'); // 'ㄱㅏㅂㅅㅇㅣ ㅂㅣㅆㅏㄷㅏ' -disassembleHangul('ㅘ'); // 'ㅗㅏ' -disassembleHangul('ㄵ'); // 'ㄴㅈ' +disassemble('값'); // 'ㄱㅏㅂㅅ' +disassemble('값이 비싸다'); // 'ㄱㅏㅂㅅㅇㅣ ㅂㅣㅆㅏㄷㅏ' +disassemble('ㅘ'); // 'ㅗㅏ' +disassemble('ㄵ'); // 'ㄴㅈ' ``` diff --git a/docs/src/pages/docs/api/disassembleHangul.ko.md b/docs/src/pages/docs/api/disassemble.ko.md similarity index 51% rename from docs/src/pages/docs/api/disassembleHangul.ko.md rename to docs/src/pages/docs/api/disassemble.ko.md index 207b1c67..acc0d849 100644 --- a/docs/src/pages/docs/api/disassembleHangul.ko.md +++ b/docs/src/pages/docs/api/disassemble.ko.md @@ -1,15 +1,15 @@ --- -title: disassembleHangul +title: disassemble --- -# disassembleHangul +# disassemble 한글 문자열을 글자별로 초성/중성/종성 단위로 완전히 분리하여, 하나의 문자열로 만듭니다. 자세한 예시는 아래 Example을 참고하세요. ```typescript -function disassembleHangul( +function disassemble( // 분리할 한글 문자열 str: string ): string; @@ -18,8 +18,8 @@ function disassembleHangul( ## Examples ```tsx -disassembleHangul('값'); // 'ㄱㅏㅂㅅ' -disassembleHangul('값이 비싸다'); // 'ㄱㅏㅂㅅㅇㅣ ㅂㅣㅆㅏㄷㅏ' -disassembleHangul('ㅘ'); // 'ㅗㅏ' -disassembleHangul('ㄵ'); // 'ㄴㅈ' +disassemble('값'); // 'ㄱㅏㅂㅅ' +disassemble('값이 비싸다'); // 'ㄱㅏㅂㅅㅇㅣ ㅂㅣㅆㅏㄷㅏ' +disassemble('ㅘ'); // 'ㅗㅏ' +disassemble('ㄵ'); // 'ㄴㅈ' ``` diff --git a/docs/src/pages/docs/api/disassembleHangulToGroups.en.md b/docs/src/pages/docs/api/disassembleToGroups.en.md similarity index 62% rename from docs/src/pages/docs/api/disassembleHangulToGroups.en.md rename to docs/src/pages/docs/api/disassembleToGroups.en.md index 8485fba1..c4213014 100644 --- a/docs/src/pages/docs/api/disassembleHangulToGroups.en.md +++ b/docs/src/pages/docs/api/disassembleToGroups.en.md @@ -1,8 +1,8 @@ --- -title: disassembleHangulToGroups +title: disassembleToGroups --- -# disassembleHangulToGroups +# disassembleToGroups Completely separate a Hangul string into individual characters based on the initial consonant, medial vowel, and final consonant. @@ -11,7 +11,7 @@ Complex consonants like `ㄵ` are split into `['ㄴ', 'ㅈ']`, and complex vowel For detailed examples, please refer to the section below. ```typescript -function disassembleHangulToGroups( +function disassembleToGroups( // The Korean string to be disassembled str: string ): string[][]; @@ -20,7 +20,7 @@ function disassembleHangulToGroups( ## Examples ```typescript -disassembleHangulToGroups('값'); // [['ㄱ', 'ㅏ', 'ㅂ', 'ㅅ']] -disassembleHangulToGroups('ㅘ'); // [['ㅗ', 'ㅏ']] -disassembleHangulToGroups('ㄵ'); // [['ㄴ', 'ㅈ']] +disassembleToGroups('값'); // [['ㄱ', 'ㅏ', 'ㅂ', 'ㅅ']] +disassembleToGroups('ㅘ'); // [['ㅗ', 'ㅏ']] +disassembleToGroups('ㄵ'); // [['ㄴ', 'ㅈ']] ``` diff --git a/docs/src/pages/docs/api/disassembleHangulToGroups.ko.md b/docs/src/pages/docs/api/disassembleToGroups.ko.md similarity index 59% rename from docs/src/pages/docs/api/disassembleHangulToGroups.ko.md rename to docs/src/pages/docs/api/disassembleToGroups.ko.md index 31b8d8d8..131bc1c6 100644 --- a/docs/src/pages/docs/api/disassembleHangulToGroups.ko.md +++ b/docs/src/pages/docs/api/disassembleToGroups.ko.md @@ -1,8 +1,8 @@ --- -title: disassembleHangulToGroups +title: disassembleToGroups --- -# disassembleHangulToGroups +# disassembleToGroups 한글 문자열을 글자별로 초성/중성/종성 단위로 완전히 분리합니다. @@ -11,7 +11,7 @@ title: disassembleHangulToGroups 자세한 예시는 아래 Example을 참고하세요. ```typescript -function disassembleHangulToGroups( +function disassembleToGroups( // 분리할 한글 문자열 str: string ): string[][]; @@ -20,7 +20,7 @@ function disassembleHangulToGroups( ## Examples ```typescript -disassembleHangulToGroups('값'); // [['ㄱ', 'ㅏ', 'ㅂ', 'ㅅ']] -disassembleHangulToGroups('ㅘ'); // [['ㅗ', 'ㅏ']] -disassembleHangulToGroups('ㄵ'); // [['ㄴ', 'ㅈ']] +disassembleToGroups('값'); // [['ㄱ', 'ㅏ', 'ㅂ', 'ㅅ']] +disassembleToGroups('ㅘ'); // [['ㅗ', 'ㅏ']] +disassembleToGroups('ㄵ'); // [['ㄴ', 'ㅈ']] ``` diff --git a/docs/src/pages/docs/introduction.en.mdx b/docs/src/pages/docs/introduction.en.mdx index f4c78802..6459c362 100644 --- a/docs/src/pages/docs/introduction.en.mdx +++ b/docs/src/pages/docs/introduction.en.mdx @@ -48,15 +48,15 @@ const result = choseongIncludes(searchWord, userInput); console.log(result); // true ``` -#### Disassembling Hangul Characters ([disassembleHangul](./api/disassembleHangul)) +#### Disassembling Hangul Characters ([disassemble](./api/disassemble)) You can decompose a given Hangul string into initial consonants, vowels, and final consonants, and return it in array form to allow for more detailed analysis or modification of the string. -```tsx /disassembleHangul/ -import { disassembleHangul } from 'es-hangul'; +```tsx /disassemble/ +import { disassemble } from 'es-hangul'; const word = '안녕하세요'; -const disassembled = disassembleHangul(word); +const disassembled = disassemble(word); console.log(disassembled); // 'ㅇㅏㄴㄴㅕㅇㅎㅏㅅㅔㅇㅛ' ``` diff --git a/docs/src/pages/docs/introduction.ko.mdx b/docs/src/pages/docs/introduction.ko.mdx index fb3b3094..6e351612 100644 --- a/docs/src/pages/docs/introduction.ko.mdx +++ b/docs/src/pages/docs/introduction.ko.mdx @@ -48,15 +48,15 @@ const result = choseongIncludes(searchWord, userInput); console.log(result); // true ``` -#### 초/중/종성 분해 ([disassembleHangul](./api/disassembleHangul)) +#### 초/중/종성 분해 ([disassemble](./api/disassemble)) 주어진 한글 문자열을 초성, 중성, 종성으로 분해하여 배열 형태로 반환해 문자열을 더 세밀하게 분석하거나 수정할 수 있습니다. -```tsx /disassembleHangul/ -import { disassembleHangul } from 'es-hangul'; +```tsx /disassemble/ +import { disassemble } from 'es-hangul'; const word = '안녕하세요'; -const disassembled = disassembleHangul(word); +const disassembled = disassemble(word); console.log(disassembled); // 'ㅇㅏㄴㄴㅕㅇㅎㅏㅅㅔㅇㅛ' ``` diff --git a/src/_internal/hangul.ts b/src/_internal/hangul.ts index 882af421..2d925549 100644 --- a/src/_internal/hangul.ts +++ b/src/_internal/hangul.ts @@ -1,6 +1,6 @@ import assert, { excludeLastElement, isBlank, joinString } from '.'; import { combineHangulCharacter, combineVowels, curriedCombineHangulCharacter } from '../combineHangulCharacter'; -import { disassembleHangulToGroups } from '../disassemble'; +import { disassembleToGroups } from '../disassemble'; import { removeLastHangulCharacter } from '../removeLastHangulCharacter'; import { canBeChoseong, canBeJongseong, canBeJungseong, hasSingleBatchim } from '../utils'; @@ -75,7 +75,7 @@ export function binaryAssembleHangulAlphabets(source: string, nextCharacter: str * 연음 법칙을 적용하여 두 개의 한글 문자를 연결합니다. */ export function linkHangulCharacters(source: string, nextCharacter: string) { - const sourceJamo = disassembleHangulToGroups(source)[0]; + const sourceJamo = disassembleToGroups(source)[0]; const [, lastJamo] = excludeLastElement(sourceJamo); return joinString(removeLastHangulCharacter(source), combineHangulCharacter(lastJamo, nextCharacter)); @@ -109,7 +109,7 @@ export function binaryAssembleHangulCharacters(source: string, nextCharacter: st `Invalid next character: ${nextCharacter}. Next character must be one of the choseong, jungseong, or jongseong.` ); - const sourceJamos = disassembleHangulToGroups(source)[0]; + const sourceJamos = disassembleToGroups(source)[0]; const isSingleCharacter = sourceJamos.length === 1; if (isSingleCharacter) { diff --git a/src/assemble.ts b/src/assemble.ts index ced978aa..554fa8ea 100644 --- a/src/assemble.ts +++ b/src/assemble.ts @@ -1,4 +1,4 @@ -import { disassembleHangul } from './disassemble'; +import { disassemble } from './disassemble'; import { binaryAssembleHangul } from './_internal/hangul'; /** @@ -17,6 +17,6 @@ import { binaryAssembleHangul } from './_internal/hangul'; * assembleHangul(['ㅇ', 'ㅏ', 'ㅂ', 'ㅓ', 'ㅈ', 'ㅣ']) // 아버지 */ export function assembleHangul(words: string[]) { - const disassembled = disassembleHangul(words.join('')).split(''); + const disassembled = disassemble(words.join('')).split(''); return disassembled.reduce(binaryAssembleHangul); } diff --git a/src/choseongIncludes.ts b/src/choseongIncludes.ts index 3dee936b..de13a893 100644 --- a/src/choseongIncludes.ts +++ b/src/choseongIncludes.ts @@ -1,4 +1,4 @@ -import { disassembleHangulToGroups } from './disassemble'; +import { disassembleToGroups } from './disassemble'; import { canBeChoseong, getChoseong } from './utils'; export function choseongIncludes(x: string, y: string) { @@ -18,7 +18,7 @@ export function choseongIncludes(x: string, y: string) { * @description 문자열이 한글초성으로만 주어진 경우 */ export function isOnlyChoseong(str: string) { - const groups = disassembleHangulToGroups(str); + const groups = disassembleToGroups(str); if (groups.length === 0) { return false; } diff --git a/src/disassemble.spec.ts b/src/disassemble.spec.ts index d4d59c60..57e7ff20 100644 --- a/src/disassemble.spec.ts +++ b/src/disassemble.spec.ts @@ -1,12 +1,12 @@ -import { disassembleHangul, disassembleHangulToGroups } from './disassemble'; +import { disassemble, disassembleToGroups } from './disassemble'; -describe('disassembleHangulToGroups', () => { +describe('disassembleToGroups', () => { it('값', () => { - expect(disassembleHangulToGroups('값')).toEqual([['ㄱ', 'ㅏ', 'ㅂ', 'ㅅ']]); + expect(disassembleToGroups('값')).toEqual([['ㄱ', 'ㅏ', 'ㅂ', 'ㅅ']]); }); it('값이 비싸다', () => { - expect(disassembleHangulToGroups('값이 비싸다')).toEqual([ + expect(disassembleToGroups('값이 비싸다')).toEqual([ ['ㄱ', 'ㅏ', 'ㅂ', 'ㅅ'], ['ㅇ', 'ㅣ'], [' '], @@ -17,36 +17,36 @@ describe('disassembleHangulToGroups', () => { }); it('사과 짱', () => { - expect(disassembleHangulToGroups('사과 짱')).toEqual([['ㅅ', 'ㅏ'], ['ㄱ', 'ㅗ', 'ㅏ'], [' '], ['ㅉ', 'ㅏ', 'ㅇ']]); + expect(disassembleToGroups('사과 짱')).toEqual([['ㅅ', 'ㅏ'], ['ㄱ', 'ㅗ', 'ㅏ'], [' '], ['ㅉ', 'ㅏ', 'ㅇ']]); }); it('ㄵ', () => { - expect(disassembleHangulToGroups('ㄵ')).toEqual([['ㄴ', 'ㅈ']]); + expect(disassembleToGroups('ㄵ')).toEqual([['ㄴ', 'ㅈ']]); }); it('ㅘ', () => { - expect(disassembleHangulToGroups('ㅘ')).toEqual([['ㅗ', 'ㅏ']]); + expect(disassembleToGroups('ㅘ')).toEqual([['ㅗ', 'ㅏ']]); }); }); -describe('disassembleHangul', () => { +describe('disassemble', () => { it('값', () => { - expect(disassembleHangul('값')).toEqual('ㄱㅏㅂㅅ'); + expect(disassemble('값')).toEqual('ㄱㅏㅂㅅ'); }); it('값이 비싸다', () => { - expect(disassembleHangul('값이 비싸다')).toEqual('ㄱㅏㅂㅅㅇㅣ ㅂㅣㅆㅏㄷㅏ'); + expect(disassemble('값이 비싸다')).toEqual('ㄱㅏㅂㅅㅇㅣ ㅂㅣㅆㅏㄷㅏ'); }); it('사과 짱', () => { - expect(disassembleHangul('사과 짱')).toEqual('ㅅㅏㄱㅗㅏ ㅉㅏㅇ'); + expect(disassemble('사과 짱')).toEqual('ㅅㅏㄱㅗㅏ ㅉㅏㅇ'); }); it('ㄵ', () => { - expect(disassembleHangul('ㄵ')).toEqual('ㄴㅈ'); + expect(disassemble('ㄵ')).toEqual('ㄴㅈ'); }); it('ㅘ', () => { - expect(disassembleHangul('ㅘ')).toEqual('ㅗㅏ'); + expect(disassemble('ㅘ')).toEqual('ㅗㅏ'); }); }); diff --git a/src/disassemble.ts b/src/disassemble.ts index a38432ca..9c9ee461 100644 --- a/src/disassemble.ts +++ b/src/disassemble.ts @@ -1,8 +1,8 @@ import { DISASSEMBLED_CONSONANTS_BY_CONSONANT, DISASSEMBLED_VOWELS_BY_VOWEL } from './constants'; -import { disassembleCompleteHangulCharacter } from './disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; import { hasProperty } from './utils'; -export function disassembleHangulToGroups(str: string) { +export function disassembleToGroups(str: string) { /* * FIXME(@raon0211): * Array#map을 사용하는 경우 Safari에서 'Array size is not a small enough positive integer' 오류가 발생함. @@ -13,7 +13,7 @@ export function disassembleHangulToGroups(str: string) { const result: string[][] = []; for (const letter of str) { - const disassembledComplete = disassembleCompleteHangulCharacter(letter); + const disassembledComplete = disassembleCompleteCharacter(letter); if (disassembledComplete != null) { result.push([...disassembledComplete.first, ...disassembledComplete.middle, ...disassembledComplete.last]); @@ -40,6 +40,6 @@ export function disassembleHangulToGroups(str: string) { return result; } -export function disassembleHangul(str: string) { - return disassembleHangulToGroups(str).reduce((hanguls, disassembleds) => `${hanguls}${disassembleds.join('')}`, ''); +export function disassemble(str: string) { + return disassembleToGroups(str).reduce((hanguls, disassembleds) => `${hanguls}${disassembleds.join('')}`, ''); } diff --git a/src/disassembleCompleteCharacter.spec.ts b/src/disassembleCompleteCharacter.spec.ts new file mode 100644 index 00000000..716e3a25 --- /dev/null +++ b/src/disassembleCompleteCharacter.spec.ts @@ -0,0 +1,40 @@ +import { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; + +describe('disassembleCompleteCharacter', () => { + it('값', () => { + expect(disassembleCompleteCharacter('값')).toEqual({ + first: 'ㄱ', + middle: 'ㅏ', + last: 'ㅂㅅ', + }); + }); + + it('리', () => { + expect(disassembleCompleteCharacter('리')).toEqual({ + first: 'ㄹ', + middle: 'ㅣ', + last: '', + }); + }); + + it('빚', () => { + expect(disassembleCompleteCharacter('빚')).toEqual({ + first: 'ㅂ', + middle: 'ㅣ', + last: 'ㅈ', + }); + }); + + it('박', () => { + expect(disassembleCompleteCharacter('박')).toEqual({ + first: 'ㅂ', + middle: 'ㅏ', + last: 'ㄱ', + }); + }); + + it('완전한 한글 문자열이 아니면 undefined를 반환해야 합니다.', () => { + expect(disassembleCompleteCharacter('ㄱ')).toBeUndefined; + expect(disassembleCompleteCharacter('ㅏ')).toBeUndefined; + }); +}); diff --git a/src/disassembleCompleteHangulCharacter.ts b/src/disassembleCompleteCharacter.ts similarity index 69% rename from src/disassembleCompleteHangulCharacter.ts rename to src/disassembleCompleteCharacter.ts index 252eee2d..43e54900 100644 --- a/src/disassembleCompleteHangulCharacter.ts +++ b/src/disassembleCompleteCharacter.ts @@ -8,29 +8,27 @@ import { NUMBER_OF_JUNGSEONG, } from './constants'; -interface ReturnTypeDisassembleCompleteHangulCharacter { +interface ReturnTypeDisassembleCompleteCharacter { first: (typeof HANGUL_CHARACTERS_BY_FIRST_INDEX)[number]; middle: (typeof HANGUL_CHARACTERS_BY_MIDDLE_INDEX)[number]; last: (typeof HANGUL_CHARACTERS_BY_LAST_INDEX)[number]; } /** - * @name disassembleCompleteHangulCharacter + * @name disassembleCompleteCharacter * @description * 완전한 한글 문자열을 초성, 중성, 종성으로 분리합니다. * * @param {string} letter 분리하고자 하는 완전한 한글 문자열 * * @example - * disassembleCompleteHangulCharacter('값') // { first: 'ㄱ', middle: 'ㅏ', last: 'ㅂㅅ' } - * disassembleCompleteHangulCharacter('리') // { first: 'ㄹ', middle: 'ㅣ', last: '' } - * disassembleCompleteHangulCharacter('빚') // { first: 'ㅂ', middle: 'ㅣ', last: 'ㅈ' } - * disassembleCompleteHangulCharacter('박') // { first: 'ㅂ', middle: 'ㅏ', last: 'ㄱ' } + * disassembleCompleteCharacter('값') // { first: 'ㄱ', middle: 'ㅏ', last: 'ㅂㅅ' } + * disassembleCompleteCharacter('리') // { first: 'ㄹ', middle: 'ㅣ', last: '' } + * disassembleCompleteCharacter('빚') // { first: 'ㅂ', middle: 'ㅣ', last: 'ㅈ' } + * disassembleCompleteCharacter('박') // { first: 'ㅂ', middle: 'ㅏ', last: 'ㄱ' } */ -export function disassembleCompleteHangulCharacter( - letter: string -): ReturnTypeDisassembleCompleteHangulCharacter | undefined { +export function disassembleCompleteCharacter(letter: string): ReturnTypeDisassembleCompleteCharacter | undefined { const charCode = letter.charCodeAt(0); const isCompleteHangul = COMPLETE_HANGUL_START_CHARCODE <= charCode && charCode <= COMPLETE_HANGUL_END_CHARCODE; diff --git a/src/disassembleCompleteHangulCharacter.spec.ts b/src/disassembleCompleteHangulCharacter.spec.ts deleted file mode 100644 index 97880110..00000000 --- a/src/disassembleCompleteHangulCharacter.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { disassembleCompleteHangulCharacter } from './disassembleCompleteHangulCharacter'; - -describe('disassembleCompleteHangulCharacter', () => { - it('값', () => { - expect(disassembleCompleteHangulCharacter('값')).toEqual({ - first: 'ㄱ', - middle: 'ㅏ', - last: 'ㅂㅅ', - }); - }); - - it('리', () => { - expect(disassembleCompleteHangulCharacter('리')).toEqual({ - first: 'ㄹ', - middle: 'ㅣ', - last: '', - }); - }); - - it('빚', () => { - expect(disassembleCompleteHangulCharacter('빚')).toEqual({ - first: 'ㅂ', - middle: 'ㅣ', - last: 'ㅈ', - }); - }); - - it('박', () => { - expect(disassembleCompleteHangulCharacter('박')).toEqual({ - first: 'ㅂ', - middle: 'ㅏ', - last: 'ㄱ', - }); - }); - - it('완전한 한글 문자열이 아니면 undefined를 반환해야 합니다.', () => { - expect(disassembleCompleteHangulCharacter('ㄱ')).toBeUndefined; - expect(disassembleCompleteHangulCharacter('ㅏ')).toBeUndefined; - }); -}); diff --git a/src/hangulIncludes.ts b/src/hangulIncludes.ts index f1376334..0f1d26ae 100644 --- a/src/hangulIncludes.ts +++ b/src/hangulIncludes.ts @@ -1,8 +1,8 @@ -import { disassembleHangul } from './disassemble'; +import { disassemble } from './disassemble'; export function hangulIncludes(x: string, y: string) { - const disassembledX = disassembleHangul(x); - const disassembledY = disassembleHangul(y); + const disassembledX = disassemble(x); + const disassembledY = disassemble(y); return disassembledX.includes(disassembledY); } diff --git a/src/index.ts b/src/index.ts index c9ffaee6..6a6e1ff7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,8 +3,8 @@ export { choseongIncludes } from './choseongIncludes'; export { chosungIncludes } from './chosungIncludes'; export { combineHangulCharacter, combineVowels, curriedCombineHangulCharacter } from './combineHangulCharacter'; export { convertQwertyToHangul, convertQwertyToHangulAlphabet } from './convertQwertyToHangulAlphabet'; -export { disassembleHangul, disassembleHangulToGroups } from './disassemble'; -export { disassembleCompleteHangulCharacter } from './disassembleCompleteHangulCharacter'; +export { disassemble, disassembleToGroups } from './disassemble'; +export { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; export { hangulIncludes } from './hangulIncludes'; export { josa } from './josa'; export { removeLastHangulCharacter } from './removeLastHangulCharacter'; diff --git a/src/josa.ts b/src/josa.ts index 6fc5c007..30df72e8 100644 --- a/src/josa.ts +++ b/src/josa.ts @@ -1,4 +1,4 @@ -import { disassembleCompleteHangulCharacter } from './disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; import { hasBatchim } from './utils'; type JosaOption = @@ -37,7 +37,7 @@ function josaPicker(word: string, josa: JosaOption): string { const has받침 = hasBatchim(word); let index = has받침 ? 0 : 1; - const is종성ㄹ = disassembleCompleteHangulCharacter(word[word.length - 1])?.last === 'ㄹ'; + const is종성ㄹ = disassembleCompleteCharacter(word[word.length - 1])?.last === 'ㄹ'; const isCaseOf로 = has받침 && is종성ㄹ && 로_조사.includes(josa); diff --git a/src/removeLastHangulCharacter.ts b/src/removeLastHangulCharacter.ts index 5ac9c780..16bf38eb 100644 --- a/src/removeLastHangulCharacter.ts +++ b/src/removeLastHangulCharacter.ts @@ -1,7 +1,7 @@ import { combineHangulCharacter } from './combineHangulCharacter'; -import { disassembleHangulToGroups } from './disassemble'; import { excludeLastElement } from './_internal'; import { canBeJungsung } from './utils'; +import { disassembleToGroups } from './disassemble'; /** * @name removeLastHangulCharacter @@ -25,9 +25,9 @@ export function removeLastHangulCharacter(words: string) { if (lastCharacter == null) { return ''; } - + const result = (() => { - const disassembleLastCharacter = disassembleHangulToGroups(lastCharacter); + const disassembleLastCharacter = disassembleToGroups(lastCharacter); const [lastCharacterWithoutLastAlphabet] = excludeLastElement(disassembleLastCharacter[0]); if (lastCharacterWithoutLastAlphabet.length <= 3) { const [first, middle, last] = lastCharacterWithoutLastAlphabet; diff --git a/src/utils.ts b/src/utils.ts index feef565b..ad4b9f82 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -8,7 +8,7 @@ import { JASO_HANGUL_NFD, NUMBER_OF_JONGSEONG, } from './constants'; -import { disassembleHangulToGroups } from './disassemble'; +import { disassembleToGroups } from './disassemble'; const EXTRACT_CHOSEONG_REGEX = new RegExp( `[^\\u${JASO_HANGUL_NFD.START_CHOSEONG.toString(16)}-\\u${JASO_HANGUL_NFD.END_CHOSEONG.toString(16)}ㄱ-ㅎ\\s]+`, @@ -143,7 +143,7 @@ export function getChoseong(word: string) { * getFirstConsonants('띄어 쓰기') // 'ㄸㅇ ㅆㄱ' */ export function getFirstConsonants(word: string) { - return disassembleHangulToGroups(word).reduce((firstConsonants, [consonant]) => { + return disassembleToGroups(word).reduce((firstConsonants, [consonant]) => { return `${firstConsonants}${consonant}`; }, ''); } From 642a3e449ecea1312b73679049b0a49efb7da161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=B0=AC=ED=98=81?= Date: Sun, 14 Jul 2024 16:50:21 +0900 Subject: [PATCH 03/21] remove hangulIncludes (#188) --- .changeset/smooth-rings-mix.md | 5 ++++ docs/src/pages/docs/api/hangulIncludes.en.md | 28 ------------------ docs/src/pages/docs/api/hangulIncludes.ko.md | 28 ------------------ src/hangulIncludes.spec.ts | 30 -------------------- src/hangulIncludes.ts | 8 ------ src/index.ts | 1 - 6 files changed, 5 insertions(+), 95 deletions(-) create mode 100644 .changeset/smooth-rings-mix.md delete mode 100644 docs/src/pages/docs/api/hangulIncludes.en.md delete mode 100644 docs/src/pages/docs/api/hangulIncludes.ko.md delete mode 100644 src/hangulIncludes.spec.ts delete mode 100644 src/hangulIncludes.ts diff --git a/.changeset/smooth-rings-mix.md b/.changeset/smooth-rings-mix.md new file mode 100644 index 00000000..3545a98d --- /dev/null +++ b/.changeset/smooth-rings-mix.md @@ -0,0 +1,5 @@ +--- +"es-hangul": major +--- + +hangulIncludes 함수를 제거합니다 diff --git a/docs/src/pages/docs/api/hangulIncludes.en.md b/docs/src/pages/docs/api/hangulIncludes.en.md deleted file mode 100644 index 80009d67..00000000 --- a/docs/src/pages/docs/api/hangulIncludes.en.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: hangulIncludes ---- - -# hangulIncludes - -Checks if a Hangul string contains another Hangul string. - -For example, `사과` contains `삭`, and `값이 비싸다` contains `갑` or `빘`. - -```typescript -function hangulIncludes( - // The string to be checked for containing the second argument y - x: string, - // The string to be checked for inclusion in the first argument x - y: string -): boolean; -``` - -## Examples - -```typescript -hangulIncludes('사과', ''); // true -hangulIncludes('사과', 'ㅅ'); // true -hangulIncludes('사과', '삭'); // true -hangulIncludes('사과', '삽'); // false -hangulIncludes('사과', '사과'); // true -``` diff --git a/docs/src/pages/docs/api/hangulIncludes.ko.md b/docs/src/pages/docs/api/hangulIncludes.ko.md deleted file mode 100644 index e80c7da6..00000000 --- a/docs/src/pages/docs/api/hangulIncludes.ko.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: hangulIncludes ---- - -# hangulIncludes - -한글 문자열이 다른 한글 문자열을 포함하는지 검사합니다. - -예를 들어서, `사과` 는 `삭` 을 포함하고, `값이 비싸다` 는 `갑` 또는 `빘`을 포함합니다. - -```typescript -function hangulIncludes( - // 두 번째 인자 y를 포함하는지 검사할 문자열 - x: string, - // 첫 번째 인자 x에 포함되는지 검사할 문자열 - y: string -): boolean; -``` - -## Examples - -```typescript -hangulIncludes('사과', ''); // true -hangulIncludes('사과', 'ㅅ'); // true -hangulIncludes('사과', '삭'); // true -hangulIncludes('사과', '삽'); // false -hangulIncludes('사과', '사과'); // true -``` diff --git a/src/hangulIncludes.spec.ts b/src/hangulIncludes.spec.ts deleted file mode 100644 index 451fb4ec..00000000 --- a/src/hangulIncludes.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { hangulIncludes } from './hangulIncludes'; - -describe('hangulIncludes', () => { - describe('한글이 포함되어있다고 판단되는 경우', () => { - it('사과', () => { - expect(hangulIncludes('사과', '')).toBe(true); - expect(hangulIncludes('사과', 'ㅅ')).toBe(true); - expect(hangulIncludes('사과', '삭')).toBe(true); - expect(hangulIncludes('사과', '사과')).toBe(true); - }); - - it('프론트엔드', () => { - expect(hangulIncludes('프론트엔드', '')).toBe(true); - expect(hangulIncludes('프론트엔드', '플')).toBe(true); - expect(hangulIncludes('프론트엔드', '틍')).toBe(true); - expect(hangulIncludes('프론트엔드', '플')).toBe(true); - expect(hangulIncludes('프론트엔드', '프로')).toBe(true); - }); - }); - - describe('한글이 포함되어있다고 판단되지 않는 경우', () => { - it('사과', () => { - expect(hangulIncludes('사과', '삽')).toBe(false); - }); - - it('프론트엔드', () => { - expect(hangulIncludes('프론트엔드', '픏')).toBe(false); - }); - }); -}); diff --git a/src/hangulIncludes.ts b/src/hangulIncludes.ts deleted file mode 100644 index 0f1d26ae..00000000 --- a/src/hangulIncludes.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { disassemble } from './disassemble'; - -export function hangulIncludes(x: string, y: string) { - const disassembledX = disassemble(x); - const disassembledY = disassemble(y); - - return disassembledX.includes(disassembledY); -} diff --git a/src/index.ts b/src/index.ts index 6a6e1ff7..4c1c9512 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,7 +5,6 @@ export { combineHangulCharacter, combineVowels, curriedCombineHangulCharacter } export { convertQwertyToHangul, convertQwertyToHangulAlphabet } from './convertQwertyToHangulAlphabet'; export { disassemble, disassembleToGroups } from './disassemble'; export { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; -export { hangulIncludes } from './hangulIncludes'; export { josa } from './josa'; export { removeLastHangulCharacter } from './removeLastHangulCharacter'; export { romanize } from './romanize'; From 9f8dd1b84cfbc941c19e105daff316d3d8afeffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=B0=AC=ED=98=81?= Date: Sun, 14 Jul 2024 16:53:10 +0900 Subject: [PATCH 04/21] =?UTF-8?q?feat:=20=ED=95=9C=EA=B8=80=EC=9D=98=20?= =?UTF-8?q?=EB=91=90=EC=9D=8C=EC=9D=84=20=EB=B0=98=ED=99=98=ED=95=B4?= =?UTF-8?q?=EC=A3=BC=EB=8A=94=20acronymizeHangul=20=ED=95=A8=EC=88=98?= =?UTF-8?q?=EB=A5=BC=20=EC=A0=9C=EA=B1=B0=ED=95=A9=EB=8B=88=EB=8B=A4.=20(#?= =?UTF-8?q?180)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove acronymize * Create weak-walls-sniff.md --------- Co-authored-by: Jonghyeon Ko --- .changeset/weak-walls-sniff.md | 5 +++++ .../src/pages/docs/api/acronymizeHangul.en.mdx | 16 ---------------- .../src/pages/docs/api/acronymizeHangul.ko.mdx | 16 ---------------- src/acronymizeHangul.spec.ts | 18 ------------------ src/acronymizeHangul.ts | 12 ------------ 5 files changed, 5 insertions(+), 62 deletions(-) create mode 100644 .changeset/weak-walls-sniff.md delete mode 100644 docs/src/pages/docs/api/acronymizeHangul.en.mdx delete mode 100644 docs/src/pages/docs/api/acronymizeHangul.ko.mdx delete mode 100644 src/acronymizeHangul.spec.ts delete mode 100644 src/acronymizeHangul.ts diff --git a/.changeset/weak-walls-sniff.md b/.changeset/weak-walls-sniff.md new file mode 100644 index 00000000..975a6db5 --- /dev/null +++ b/.changeset/weak-walls-sniff.md @@ -0,0 +1,5 @@ +--- +"es-hangul": major +--- + +feat: 한글의 두음을 반환해주는 acronymizeHangul 함수를 제거합니다. diff --git a/docs/src/pages/docs/api/acronymizeHangul.en.mdx b/docs/src/pages/docs/api/acronymizeHangul.en.mdx deleted file mode 100644 index 9f2f9007..00000000 --- a/docs/src/pages/docs/api/acronymizeHangul.en.mdx +++ /dev/null @@ -1,16 +0,0 @@ -# acronymizeHangul - -It receives the Korean sentence and returns the first letter of that Korean sentence. -(We don't deal with non-Korean sentences; we don't deal with additional Korean + English sentences.) - -```typescript -function acronymizeHangul( - // String consisting of plural nouns (e.g. '버스 충전', '치킨과 맥주') - hangul: string -): string[]; -``` - -```typescript -acronymizeHangul('치킨과 맥주').join(''); //치맥 -acronymizeHangul('버스 충전 카드').join(''); //버충카 -``` diff --git a/docs/src/pages/docs/api/acronymizeHangul.ko.mdx b/docs/src/pages/docs/api/acronymizeHangul.ko.mdx deleted file mode 100644 index c1b576a4..00000000 --- a/docs/src/pages/docs/api/acronymizeHangul.ko.mdx +++ /dev/null @@ -1,16 +0,0 @@ -# acronymizeHangul - -한글 문장을 입력받아서, 해당 한글 문장의 첫글자를 리턴해줍니다. -(한글 문장이 아닌, 문장은 취급하지않습니다. 추가로 한글 문장 + 영어 문장의 경우에도 취급하지않습니다.) - -```typescript -function acronymizeHangul( - // 복수 명사로 이루어진 문자열 (e.g. '버스 충전', '치킨과 맥주') - hangul: string -): string[]; -``` - -```typescript -acronymizeHangul('치킨과 맥주').join(''); //치맥 -acronymizeHangul('버스 충전 카드').join(''); //버충카 -``` diff --git a/src/acronymizeHangul.spec.ts b/src/acronymizeHangul.spec.ts deleted file mode 100644 index a4d8b91e..00000000 --- a/src/acronymizeHangul.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { acronymizeHangul } from './acronymizeHangul'; - -describe('acronymizeHangul', () => { - it('한글 문장 단어중 첫 문자만 뽑은 리스트를 반환', () => { - expect(acronymizeHangul('치킨과 맥주')).toHaveLength(2); - expect(acronymizeHangul('치킨과 맥주').join('')).toBe('치맥'); - - expect(acronymizeHangul('버스 충전 카드')).toHaveLength(3); - expect(acronymizeHangul('버스 충전 카드').join('')).toBe('버충카'); - }); - it('한글이 아닌 문장 넣었을 때', () => { - expect(() => acronymizeHangul('test test')).toThrowError('"test test" is not a valid hangul string'); - }); - - it('한글과 영어가 섞인 문장을 넣었을 때', () => { - expect(() => acronymizeHangul('고기와 Cheese')).toThrowError('"고기와 Cheese" is not a valid hangul string'); - }); -}); diff --git a/src/acronymizeHangul.ts b/src/acronymizeHangul.ts deleted file mode 100644 index 9103ec40..00000000 --- a/src/acronymizeHangul.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { parseHangul } from './_internal/hangul'; - -/** - * - * @param getHangulAcronym - * @description - * 한글 문장을 입력받아서, 해당 한글 문장의 초성을을 리턴해줍니다. - * 한글 문장이 아닌, 문장은 취급하지않습니다. 추가로 한글 문장 + 영어 문장의 경우에도 취급하지않습니다. - */ -export function acronymizeHangul(hangul: string) { -return parseHangul(hangul).split(' ').map(word => word.charAt(0)); -} From a5ff8d298e6ffc019bebf786cafa899c9cace581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=B0=AC=ED=98=81?= Date: Tue, 23 Jul 2024 11:52:17 +0900 Subject: [PATCH 05/21] =?UTF-8?q?feat:=20getChoseng=EC=9D=84=20utils?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=B3=84=EB=8F=84=20=ED=95=A8=EC=88=98?= =?UTF-8?q?=EB=A1=9C=20=EB=B6=84=EB=A6=AC=ED=95=A9=EB=8B=88=EB=8B=A4.=20(#?= =?UTF-8?q?192)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * getChoseong분리 * write test code * getChoseong import * remove useless import statemenet * remove unused file --- docs/src/pages/docs/api/getChoseong.en.mdx | 19 ++++++ docs/src/pages/docs/api/getChoseong.ko.mdx | 20 ++++++ src/choseongIncludes.ts | 3 +- src/chosungIncludes.ts | 2 +- src/getChoseong.spec.ts | 20 ++++++ src/getChoseong.ts | 32 +++++++++ src/index.ts | 11 +-- src/utils.spec.ts | 40 ----------- src/utils.ts | 78 ---------------------- 9 files changed, 95 insertions(+), 130 deletions(-) create mode 100644 docs/src/pages/docs/api/getChoseong.en.mdx create mode 100644 docs/src/pages/docs/api/getChoseong.ko.mdx create mode 100644 src/getChoseong.spec.ts create mode 100644 src/getChoseong.ts diff --git a/docs/src/pages/docs/api/getChoseong.en.mdx b/docs/src/pages/docs/api/getChoseong.en.mdx new file mode 100644 index 00000000..7f9b9c99 --- /dev/null +++ b/docs/src/pages/docs/api/getChoseong.en.mdx @@ -0,0 +1,19 @@ +# getChoseong + + +Extracts the Choseong from a Korean word. (Example: 사과 -> 'ㅅㄱ') + +```typescript +function getChoseong( + // Korean string from which to extract the choseong + word: string +): string; +``` + +## Examples + +```tsx +getChoseong('사과') // 'ㅅㄱ' +getChoseong('리액트') // 'ㄹㅇㅌ' +getChoseong('띄어 쓰기') // 'ㄸㅇ ㅆㄱ' +``` diff --git a/docs/src/pages/docs/api/getChoseong.ko.mdx b/docs/src/pages/docs/api/getChoseong.ko.mdx new file mode 100644 index 00000000..72137500 --- /dev/null +++ b/docs/src/pages/docs/api/getChoseong.ko.mdx @@ -0,0 +1,20 @@ +# getChoseong + +단어에서 초성을 추출합니다. (예: `사과` -> `'ㅅㄱ'`) + +자세한 예시는 아래 Example을 참고하세요. + +```typescript +function getChoseong( + // 초성을 추출 할 한글 문자열 + word: string +): string; +``` + +## Examples + +```tsx +getChoseong('사과') // 'ㅅㄱ' +getChoseong('리액트') // 'ㄹㅇㅌ' +getChoseong('띄어 쓰기') // 'ㄸㅇ ㅆㄱ' +``` diff --git a/src/choseongIncludes.ts b/src/choseongIncludes.ts index de13a893..fbaf6407 100644 --- a/src/choseongIncludes.ts +++ b/src/choseongIncludes.ts @@ -1,5 +1,6 @@ import { disassembleToGroups } from './disassemble'; -import { canBeChoseong, getChoseong } from './utils'; +import { getChoseong } from './getChoseong'; +import { canBeChoseong } from './utils'; export function choseongIncludes(x: string, y: string) { const trimmedY = y.replace(/\s/g, ''); diff --git a/src/chosungIncludes.ts b/src/chosungIncludes.ts index 3c8f0ec1..7f775256 100644 --- a/src/chosungIncludes.ts +++ b/src/chosungIncludes.ts @@ -1,5 +1,5 @@ import { isOnlyChoseong } from './choseongIncludes'; -import { getChoseong } from './utils'; +import { getChoseong } from './getChoseong'; /** * @deprecated choseongIncludes를 사용해 주세요. diff --git a/src/getChoseong.spec.ts b/src/getChoseong.spec.ts new file mode 100644 index 00000000..ae1ddc4c --- /dev/null +++ b/src/getChoseong.spec.ts @@ -0,0 +1,20 @@ +import { getChoseong } from './getChoseong'; + +describe('getChoseong', () => { + it('"사과" 단어에서 초성 "ㅅㄱ"을 추출한다.', () => { + expect(getChoseong('사과')).toBe('ㅅㄱ'); + }); + it('"프론트엔드" 단어에서 초성 "ㅍㄹㅌㅇㄷ"을 추출한다.', () => { + expect(getChoseong('프론트엔드')).toBe('ㅍㄹㅌㅇㄷ'); + }); + it('"ㄴㅈ" 문자에서 초성 "ㄴㅈ"을 추출한다.', () => { + expect(getChoseong('ㄴㅈ')).toBe('ㄴㅈ'); + }); + it('"리액트" 단어에서 초성 "ㄹㅇㅌ"을 추출한다.', () => { + expect(getChoseong('리액트')).toBe('ㄹㅇㅌ'); + }); + + it('"띄어 쓰기" 문장에서 초성 "ㄸㅇ ㅆㄱ"을 추출한다.', () => { + expect(getChoseong('띄어 쓰기')).toBe('ㄸㅇ ㅆㄱ'); + }); +}); diff --git a/src/getChoseong.ts b/src/getChoseong.ts new file mode 100644 index 00000000..2889733f --- /dev/null +++ b/src/getChoseong.ts @@ -0,0 +1,32 @@ +import { HANGUL_CHARACTERS_BY_FIRST_INDEX, JASO_HANGUL_NFD } from './constants'; + +/** + * @name getChoseong + * @description + * 단어에서 초성을 추출합니다. (예: `사과` -> `'ㅅㄱ'`) + * ```typescript + * getChoseong( + * // 초성을 추출할 단어 + * word: string + * ): string + * ``` + * @example + * getChoseong('사과') // 'ㅅㄱ' + * getChoseong('리액트') // 'ㄹㅇㅌ' + * getChoseong('띄어 쓰기') // 'ㄸㅇ ㅆㄱ' + */ +export function getChoseong(word: string) { + return word + .normalize('NFD') + .replace(EXTRACT_CHOSEONG_REGEX, '') // NFD ㄱ-ㅎ, NFC ㄱ-ㅎ 외 문자 삭제 + .replace(CHOOSE_NFD_CHOSEONG_REGEX, $0 => HANGUL_CHARACTERS_BY_FIRST_INDEX[$0.charCodeAt(0) - 0x1100]); // NFD to NFC +} + +const EXTRACT_CHOSEONG_REGEX = new RegExp( + `[^\\u${JASO_HANGUL_NFD.START_CHOSEONG.toString(16)}-\\u${JASO_HANGUL_NFD.END_CHOSEONG.toString(16)}ㄱ-ㅎ\\s]+`, + 'ug' +); +const CHOOSE_NFD_CHOSEONG_REGEX = new RegExp( + `[\\u${JASO_HANGUL_NFD.START_CHOSEONG.toString(16)}-\\u${JASO_HANGUL_NFD.END_CHOSEONG.toString(16)}]`, + 'g' +); diff --git a/src/index.ts b/src/index.ts index 4c1c9512..0ae93d58 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,13 +10,4 @@ export { removeLastHangulCharacter } from './removeLastHangulCharacter'; export { romanize } from './romanize'; export { standardizePronunciation } from './standardizePronunciation'; export { susa } from './susa'; -export { - canBeChosung, - canBeJongsung, - canBeJungsung, - getChosung, - hasBatchim, - hasProperty, - hasSingleBatchim, - hasValueInReadOnlyStringList, -} from './utils'; +export { getChoseong } from './getChoseong'; diff --git a/src/utils.spec.ts b/src/utils.spec.ts index 5edaa379..e9dffafe 100644 --- a/src/utils.spec.ts +++ b/src/utils.spec.ts @@ -3,8 +3,6 @@ import { canBeChoseong, canBeJongseong, canBeJungseong, - getChoseong, - getFirstConsonants, hasBatchim, hasProperty, hasSingleBatchim, @@ -86,44 +84,6 @@ describe('hasSingleBatchim', () => { }); }); -describe('getChoseong', () => { - it('"사과" 단어에서 초성 "ㅅㄱ"을 추출한다.', () => { - expect(getChoseong('사과')).toBe('ㅅㄱ'); - }); - it('"프론트엔드" 단어에서 초성 "ㅍㄹㅌㅇㄷ"을 추출한다.', () => { - expect(getChoseong('프론트엔드')).toBe('ㅍㄹㅌㅇㄷ'); - }); - it('"ㄴㅈ" 문자에서 초성 "ㄴㅈ"을 추출한다.', () => { - expect(getChoseong('ㄴㅈ')).toBe('ㄴㅈ'); - }); - it('"리액트" 단어에서 초성 "ㄹㅇㅌ"을 추출한다.', () => { - expect(getChoseong('리액트')).toBe('ㄹㅇㅌ'); - }); - - it('"띄어 쓰기" 문장에서 초성 "ㄸㅇ ㅆㄱ"을 추출한다.', () => { - expect(getChoseong('띄어 쓰기')).toBe('ㄸㅇ ㅆㄱ'); - }); -}); - -describe('getFirstConsonants', () => { - it('"사과" 단어에서 초성 "ㅅㄱ"을 추출한다.', () => { - expect(getFirstConsonants('사과')).toBe('ㅅㄱ'); - }); - it('"프론트엔드" 단어에서 초성 "ㅍㄹㅌㅇㄷ"을 추출한다.', () => { - expect(getFirstConsonants('프론트엔드')).toBe('ㅍㄹㅌㅇㄷ'); - }); - it('"ㄴㅈ" 문자에서 초성 "ㄴㅈ"을 추출한다.', () => { - expect(getFirstConsonants('ㄴㅈ')).toBe('ㄴㅈ'); - }); - it('"리액트" 단어에서 초성 "ㄹㅇㅌ"을 추출한다.', () => { - expect(getFirstConsonants('리액트')).toBe('ㄹㅇㅌ'); - }); - - it('"띄어 쓰기" 문장에서 초성 "ㄸㅇ ㅆㄱ"을 추출된다.', () => { - expect(getFirstConsonants('띄어 쓰기')).toBe('ㄸㅇ ㅆㄱ'); - }); -}); - describe('hasValueInReadOnlyStringList', () => { const testReadonlyList = ['ㄱ', 'ㄴ', 'ㄷ'] as const; diff --git a/src/utils.ts b/src/utils.ts index ad4b9f82..bf8be026 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -5,19 +5,8 @@ import { HANGUL_CHARACTERS_BY_FIRST_INDEX, HANGUL_CHARACTERS_BY_LAST_INDEX, HANGUL_CHARACTERS_BY_MIDDLE_INDEX, - JASO_HANGUL_NFD, NUMBER_OF_JONGSEONG, } from './constants'; -import { disassembleToGroups } from './disassemble'; - -const EXTRACT_CHOSEONG_REGEX = new RegExp( - `[^\\u${JASO_HANGUL_NFD.START_CHOSEONG.toString(16)}-\\u${JASO_HANGUL_NFD.END_CHOSEONG.toString(16)}ㄱ-ㅎ\\s]+`, - 'ug' -); -const CHOOSE_NFD_CHOSEONG_REGEX = new RegExp( - `[\\u${JASO_HANGUL_NFD.START_CHOSEONG.toString(16)}-\\u${JASO_HANGUL_NFD.END_CHOSEONG.toString(16)}]`, - 'g' -); /** * @name hasBatchim @@ -81,73 +70,6 @@ export function hasSingleBatchim(str: string) { return HANGUL_CHARACTERS_BY_LAST_INDEX[batchimCode].length === 1; } -/** - * @name getChosung - * @deprecated getChoseong을 사용해 주세요. - * @description - * 단어에서 초성을 추출합니다. (예: `사과` -> `'ㅅㄱ'`) - * ```typescript - * getChoseong( - * // 초성을 추출할 단어 - * word: string - * ): string - * ``` - * @example - * getChoseong('사과') // 'ㅅㄱ' - * getChoseong('리액트') // 'ㄹㅇㅌ' - * getChoseong('띄어 쓰기') // 'ㄸㅇ ㅆㄱ' - */ -export function getChosung(word: string) { - return word - .normalize('NFD') - .replace(EXTRACT_CHOSEONG_REGEX, '') // NFD ㄱ-ㅎ, NFC ㄱ-ㅎ 외 문자 삭제 - .replace(CHOOSE_NFD_CHOSEONG_REGEX, $0 => HANGUL_CHARACTERS_BY_FIRST_INDEX[$0.charCodeAt(0) - 0x1100]); // NFD to NFC -} - -/** - * @name getChoseong - * @description - * 단어에서 초성을 추출합니다. (예: `사과` -> `'ㅅㄱ'`) - * ```typescript - * getChoseong( - * // 초성을 추출할 단어 - * word: string - * ): string - * ``` - * @example - * getChoseong('사과') // 'ㅅㄱ' - * getChoseong('리액트') // 'ㄹㅇㅌ' - * getChoseong('띄어 쓰기') // 'ㄸㅇ ㅆㄱ' - */ -export function getChoseong(word: string) { - return word - .normalize('NFD') - .replace(EXTRACT_CHOSEONG_REGEX, '') // NFD ㄱ-ㅎ, NFC ㄱ-ㅎ 외 문자 삭제 - .replace(CHOOSE_NFD_CHOSEONG_REGEX, $0 => HANGUL_CHARACTERS_BY_FIRST_INDEX[$0.charCodeAt(0) - 0x1100]); // NFD to NFC -} - -/** - * @name getFirstConsonants - * @deprecated getChoseong을 사용해 주세요. - * @description - * 단어에서 초성을 추출합니다. (예: `사과` -> `'ㅅㄱ'`) - * ```typescript - * getFirstConsonants( - * // 초성을 추출할 단어 - * word: string - * ): string - * ``` - * @example - * getFirstConsonants('사과') // 'ㅅㄱ' - * getFirstConsonants('리액트') // 'ㄹㅇㅌ' - * getFirstConsonants('띄어 쓰기') // 'ㄸㅇ ㅆㄱ' - */ -export function getFirstConsonants(word: string) { - return disassembleToGroups(word).reduce((firstConsonants, [consonant]) => { - return `${firstConsonants}${consonant}`; - }, ''); -} - /** * @name canBeChosung * @deprecated canBeChoseong을 사용해 주세요. From 7ed39acc775e1ea0002a052b7403050c04be1341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=B0=AC=ED=98=81?= Date: Tue, 23 Jul 2024 11:59:54 +0900 Subject: [PATCH 06/21] =?UTF-8?q?feat:=20`canBeChoseong`,=20`canBeJungseon?= =?UTF-8?q?g`,=20`canBeJongseong`=20=EC=9D=84=20utils=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=B3=84=EB=8F=84=20=ED=95=A8=EC=88=98=EB=A1=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=ED=95=A9=EB=8B=88=EB=8B=A4.=20(#193)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * canBe series를 별도 함수로 분리합니다 * add change set --- .changeset/pretty-apes-destroy.md | 5 + docs/src/pages/docs/api/canBe.en.md | 49 ++++++ docs/src/pages/docs/api/canBe.ko.md | 49 ++++++ src/_internal/hangul.ts | 3 +- src/canBe.spec.ts | 79 +++++++++ src/canBe.ts | 71 ++++++++ src/choseongIncludes.ts | 2 +- src/combineHangulCharacter.ts | 2 +- src/index.ts | 3 +- src/removeLastHangulCharacter.ts | 4 +- src/utils.spec.ts | 260 ---------------------------- src/utils.ts | 212 ----------------------- 12 files changed, 261 insertions(+), 478 deletions(-) create mode 100644 .changeset/pretty-apes-destroy.md create mode 100644 docs/src/pages/docs/api/canBe.en.md create mode 100644 docs/src/pages/docs/api/canBe.ko.md create mode 100644 src/canBe.spec.ts create mode 100644 src/canBe.ts delete mode 100644 src/utils.spec.ts delete mode 100644 src/utils.ts diff --git a/.changeset/pretty-apes-destroy.md b/.changeset/pretty-apes-destroy.md new file mode 100644 index 00000000..bbe3e536 --- /dev/null +++ b/.changeset/pretty-apes-destroy.md @@ -0,0 +1,5 @@ +--- +"es-hangul": major +--- + +canBeChoseong, canBeJungseong, canBeJongseong 을 utils에서 별도 함수로 분리합니다. diff --git a/docs/src/pages/docs/api/canBe.en.md b/docs/src/pages/docs/api/canBe.en.md new file mode 100644 index 00000000..1fc0e18f --- /dev/null +++ b/docs/src/pages/docs/api/canBe.en.md @@ -0,0 +1,49 @@ +# canBeChoseong + +Check if a given character can be a choseong in Korean. + +```typescript +function canBeChoseong(character: string): boolean; +``` + +```typescript +canBeChoseong('ㄱ'); // true +canBeChoseong('ㅃ'); // true +canBeChoseong('ㄱㅅ'); // false +canBeChoseong('ㅏ'); // false +canBeChoseong('가'); // false +``` + +# canBeJungseong + +Check if a given character can be a jungseong in Korean. + +```typescript +function canBeJungseong(character: string): boolean; +``` + +```typescript +canBeJungseong('ㅏ'); // true +canBeJungseong('ㅗㅏ'); // true +canBeJungseong('ㅏㅗ'); // false +canBeJungseong('ㄱ'); // false +canBeJungseong('ㄱㅅ'); // false +canBeJungseong('가'); // false +``` + +# canBeJongseong + +Check if a given character can be a jongseong in Korean. + +```typescript +function canBeJongseong(character: string): boolean; +``` + +```typescript +canBeJongseong('ㄱ'); // true +canBeJongseong('ㄱㅅ'); // true +canBeJongseong('ㅎㄹ'); // false +canBeJongseong('가'); // false +canBeJongseong('ㅏ'); // false +canBeJongseong('ㅗㅏ'); // false +``` diff --git a/docs/src/pages/docs/api/canBe.ko.md b/docs/src/pages/docs/api/canBe.ko.md new file mode 100644 index 00000000..f6c38712 --- /dev/null +++ b/docs/src/pages/docs/api/canBe.ko.md @@ -0,0 +1,49 @@ +# canBeChoseong + +인자로 받은 문자가 초성으로 위치할 수 있는 문자인지 검사합니다. + +```typescript +function canBeChoseong(character: string): boolean; +``` + +```typescript +canBeChoseong('ㄱ'); // true +canBeChoseong('ㅃ'); // true +canBeChoseong('ㄱㅅ'); // false +canBeChoseong('ㅏ'); // false +canBeChoseong('가'); // false +``` + +# canBeJungseong + +인자로 받은 문자가 중성으로 위치할 수 있는 문자인지 검사합니다. + +```typescript +function canBeJungseong(character: string): boolean; +``` + +```typescript +canBeJungseong('ㅏ'); // true +canBeJungseong('ㅗㅏ'); // true +canBeJungseong('ㅏㅗ'); // false +canBeJungseong('ㄱ'); // false +canBeJungseong('ㄱㅅ'); // false +canBeJungseong('가'); // false +``` + +# canBeJongseong + +인자로 받은 문자가 종성으로 위치할 수 있는 문자인지 검사합니다. + +```typescript +function canBeJongseong(character: string): boolean; +``` + +```typescript +canBeJongseong('ㄱ'); // true +canBeJongseong('ㄱㅅ'); // true +canBeJongseong('ㅎㄹ'); // false +canBeJongseong('가'); // false +canBeJongseong('ㅏ'); // false +canBeJongseong('ㅗㅏ'); // false +``` diff --git a/src/_internal/hangul.ts b/src/_internal/hangul.ts index 2d925549..aed4ea17 100644 --- a/src/_internal/hangul.ts +++ b/src/_internal/hangul.ts @@ -1,8 +1,9 @@ import assert, { excludeLastElement, isBlank, joinString } from '.'; +import { canBeChoseong, canBeJungseong, canBeJongseong } from '../canBe'; import { combineHangulCharacter, combineVowels, curriedCombineHangulCharacter } from '../combineHangulCharacter'; import { disassembleToGroups } from '../disassemble'; import { removeLastHangulCharacter } from '../removeLastHangulCharacter'; -import { canBeChoseong, canBeJongseong, canBeJungseong, hasSingleBatchim } from '../utils'; +import { hasSingleBatchim } from '../utils'; export function isHangulCharacter(character: string) { return /^[가-힣]$/.test(character); diff --git a/src/canBe.spec.ts b/src/canBe.spec.ts new file mode 100644 index 00000000..1ace262d --- /dev/null +++ b/src/canBe.spec.ts @@ -0,0 +1,79 @@ +import { canBeChoseong, canBeJongseong, canBeJungseong } from './canBe'; + +describe('canBeChoseong', () => { + describe('초성이 될 수 있다고 판단되는 경우', () => { + it('ㄱ', () => { + expect(canBeChoseong('ㄱ')).toBe(true); + }); + it('ㅃ', () => { + expect(canBeChoseong('ㅃ')).toBe(true); + }); + }); + + describe('초성이 될 수 없다고 판단되는 경우', () => { + it('ㅏ', () => { + expect(canBeChoseong('ㅏ')).toBe(false); + }); + it('ㅘ', () => { + expect(canBeChoseong('ㅘ')).toBe(false); + }); + it('ㄱㅅ', () => { + expect(canBeChoseong('ㄱㅅ')).toBe(false); + }); + it('가', () => { + expect(canBeChoseong('가')).toBe(false); + }); + }); +}); + +describe('canBeJungseong', () => { + describe('중성이 될 수 있다고 판단되는 경우', () => { + it('ㅗㅏ', () => { + expect(canBeJungseong('ㅗㅏ')).toBe(true); + }); + it('ㅏ', () => { + expect(canBeJungseong('ㅏ')).toBe(true); + }); + }); + + describe('중성이 될 수 없다고 판단되는 경우', () => { + it('ㄱ', () => { + expect(canBeJungseong('ㄱ')).toBe(false); + }); + it('ㄱㅅ', () => { + expect(canBeJungseong('ㄱㅅ')).toBe(false); + }); + it('가', () => { + expect(canBeJungseong('가')).toBe(false); + }); + }); +}); + +describe('canBeJongseong', () => { + describe('종성이 될 수 있다고 판단되는 경우', () => { + it('ㄱ', () => { + expect(canBeJongseong('ㄱ')).toBe(true); + }); + it('ㄱㅅ', () => { + expect(canBeJongseong('ㄱㅅ')).toBe(true); + }); + it('ㅂㅅ', () => { + expect(canBeJongseong('ㅂㅅ')).toBe(true); + }); + }); + + describe('종성이 될 수 없다고 판단되는 경우', () => { + it('ㅎㄹ', () => { + expect(canBeJongseong('ㅎㄹ')).toBe(false); + }); + it('ㅗㅏ', () => { + expect(canBeJongseong('ㅗㅏ')).toBe(false); + }); + it('ㅏ', () => { + expect(canBeJongseong('ㅏ')).toBe(false); + }); + it('가', () => { + expect(canBeJongseong('ㅏ')).toBe(false); + }); + }); +}); diff --git a/src/canBe.ts b/src/canBe.ts new file mode 100644 index 00000000..438b8e5b --- /dev/null +++ b/src/canBe.ts @@ -0,0 +1,71 @@ +import { + HANGUL_CHARACTERS_BY_FIRST_INDEX, + HANGUL_CHARACTERS_BY_LAST_INDEX, + HANGUL_CHARACTERS_BY_MIDDLE_INDEX, +} from './constants'; +import { hasValueInReadOnlyStringList } from './utils'; + +/** + * @name canBeChoseong + * @description + * 인자로 받은 문자가 초성으로 위치할 수 있는 문자인지 검사합니다. + * ```typescript + * canBeChoseong( + * // 대상 문자 + * character: string + * ): boolean + * ``` + * @example + * canBeChoseong('ㄱ') // true + * canBeChoseong('ㅃ') // true + * canBeChoseong('ㄱㅅ') // false + * canBeChoseong('ㅏ') // false + * canBeChoseong('가') // false + */ +export function canBeChoseong(character: string): character is (typeof HANGUL_CHARACTERS_BY_FIRST_INDEX)[number] { + return hasValueInReadOnlyStringList(HANGUL_CHARACTERS_BY_FIRST_INDEX, character); +} + +/** + * @name canBeJungseong + * @description + * 인자로 받은 문자가 중성으로 위치할 수 있는 문자인지 검사합니다. + * ```typescript + * canBeJungseong( + * // 대상 문자 + * character: string + * ): boolean + * ``` + * @example + * canBeJungseong('ㅏ') // true + * canBeJungseong('ㅗㅏ') // true + * canBeJungseong('ㅏㅗ') // false + * canBeJungseong('ㄱ') // false + * canBeJungseong('ㄱㅅ') // false + * canBeJungseong('가') // false + */ +export function canBeJungseong(character: string): character is (typeof HANGUL_CHARACTERS_BY_MIDDLE_INDEX)[number] { + return hasValueInReadOnlyStringList(HANGUL_CHARACTERS_BY_MIDDLE_INDEX, character); +} + +/** + * @name canBeJongseong + * @description + * 인자로 받은 문자가 종성으로 위치할 수 있는 문자인지 검사합니다. + * ```typescript + * canBeJongseong( + * // 대상 문자 + * character: string + * ): boolean + * ``` + * @example + * canBeJongseong('ㄱ') // true + * canBeJongseong('ㄱㅅ') // true + * canBeJongseong('ㅎㄹ') // false + * canBeJongseong('가') // false + * canBeJongseong('ㅏ') // false + * canBeJongseong('ㅗㅏ') // false + */ +export function canBeJongseong(character: string): character is (typeof HANGUL_CHARACTERS_BY_LAST_INDEX)[number] { + return hasValueInReadOnlyStringList(HANGUL_CHARACTERS_BY_LAST_INDEX, character); +} diff --git a/src/choseongIncludes.ts b/src/choseongIncludes.ts index fbaf6407..714691ba 100644 --- a/src/choseongIncludes.ts +++ b/src/choseongIncludes.ts @@ -1,6 +1,6 @@ +import { canBeChoseong } from './canBe'; import { disassembleToGroups } from './disassemble'; import { getChoseong } from './getChoseong'; -import { canBeChoseong } from './utils'; export function choseongIncludes(x: string, y: string) { const trimmedY = y.replace(/\s/g, ''); diff --git a/src/combineHangulCharacter.ts b/src/combineHangulCharacter.ts index 7ace284c..79e890c3 100644 --- a/src/combineHangulCharacter.ts +++ b/src/combineHangulCharacter.ts @@ -1,3 +1,4 @@ +import { canBeChoseong, canBeJongseong, canBeJungseong } from './canBe'; import { COMPLETE_HANGUL_START_CHARCODE, DISASSEMBLED_VOWELS_BY_VOWEL, @@ -5,7 +6,6 @@ import { HANGUL_CHARACTERS_BY_LAST_INDEX, HANGUL_CHARACTERS_BY_MIDDLE_INDEX, } from './constants'; -import { canBeChoseong, canBeJongseong, canBeJungseong } from './utils'; /** * @name combineHangulCharacter diff --git a/src/index.ts b/src/index.ts index 0ae93d58..c403e18a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,14 @@ export { assembleHangul } from './assemble'; +export { canBeChoseong, canBeJongseong, canBeJungseong } from './canBe'; export { choseongIncludes } from './choseongIncludes'; export { chosungIncludes } from './chosungIncludes'; export { combineHangulCharacter, combineVowels, curriedCombineHangulCharacter } from './combineHangulCharacter'; export { convertQwertyToHangul, convertQwertyToHangulAlphabet } from './convertQwertyToHangulAlphabet'; export { disassemble, disassembleToGroups } from './disassemble'; export { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; +export { getChoseong } from './getChoseong'; export { josa } from './josa'; export { removeLastHangulCharacter } from './removeLastHangulCharacter'; export { romanize } from './romanize'; export { standardizePronunciation } from './standardizePronunciation'; export { susa } from './susa'; -export { getChoseong } from './getChoseong'; diff --git a/src/removeLastHangulCharacter.ts b/src/removeLastHangulCharacter.ts index 16bf38eb..07160aca 100644 --- a/src/removeLastHangulCharacter.ts +++ b/src/removeLastHangulCharacter.ts @@ -1,6 +1,6 @@ import { combineHangulCharacter } from './combineHangulCharacter'; import { excludeLastElement } from './_internal'; -import { canBeJungsung } from './utils'; +import { canBeJungseong } from './canBe'; import { disassembleToGroups } from './disassemble'; /** @@ -32,7 +32,7 @@ export function removeLastHangulCharacter(words: string) { if (lastCharacterWithoutLastAlphabet.length <= 3) { const [first, middle, last] = lastCharacterWithoutLastAlphabet; if (middle != null) { - return canBeJungsung(last) + return canBeJungseong(last) ? combineHangulCharacter(first, `${middle}${last}`) : combineHangulCharacter(first, middle, last); } diff --git a/src/utils.spec.ts b/src/utils.spec.ts deleted file mode 100644 index e9dffafe..00000000 --- a/src/utils.spec.ts +++ /dev/null @@ -1,260 +0,0 @@ -import { arrayIncludes, isNotUndefined } from './_internal'; -import { - canBeChoseong, - canBeJongseong, - canBeJungseong, - hasBatchim, - hasProperty, - hasSingleBatchim, - hasValueInReadOnlyStringList, -} from './utils'; - -describe('hasBatchim', () => { - describe('받침이 있다고 판단되는 경우', () => { - it('"값" 문자에서 받침이 있으므로 true를 반환한다.', () => { - expect(hasBatchim('값')).toBe(true); - }); - it('"공" 문자에서 받침이 있으므로 true를 반환한다.', () => { - expect(hasBatchim('공')).toBe(true); - }); - it('"읊" 문자에서 받침이 있으므로 true를 반환한다.', () => { - expect(hasBatchim('읊')).toBe(true); - }); - }); - - describe('받침이 없다고 판단되는 경우', () => { - it('"토" 문자에서 받침이 없으므로 false를 반환한다.', () => { - expect(hasBatchim('토')).toBe(false); - }); - it('"서" 문자에서 받침이 없으므로 false를 반환한다.', () => { - expect(hasBatchim('서')).toBe(false); - expect(hasBatchim('')).toBe(false); - }); - it('빈 문자열은 받침이 없으므로 false를 반환한다.', () => { - expect(hasBatchim('')).toBe(false); - }); - }); - - describe('완성된 한글이 아닌 경우', () => { - it('한글이 자음 또는 모음으로만 구성된 경우 false를 반환한다.', () => { - expect(hasBatchim('ㄱ')).toBe(false); - expect(hasBatchim('ㅏ')).toBe(false); - }); - - it('한글 외의 문자를 입력하면 false를 반환한다', () => { - expect(hasBatchim('cat')).toBe(false); - expect(hasBatchim('!')).toBe(false); - }); - }); -}); - -describe('hasSingleBatchim', () => { - it('홑받침을 받으면 true를 반환한다.', () => { - expect(hasSingleBatchim('공')).toBe(true); - expect(hasSingleBatchim('핫')).toBe(true); - expect(hasSingleBatchim('양')).toBe(true); - expect(hasSingleBatchim('신')).toBe(true); - expect(hasSingleBatchim('확')).toBe(true); - }); - - describe('홑받침이 아니라고 판단되는 경우', () => { - it('겹받침을 받으면 false를 반환한다.', () => { - expect(hasSingleBatchim('값')).toBe(false); - expect(hasSingleBatchim('읊')).toBe(false); - expect(hasSingleBatchim('웱')).toBe(false); - }); - - it('받침이 없는 문자를 받으면 false를 반환한다.', () => { - expect(hasSingleBatchim('토')).toBe(false); - expect(hasSingleBatchim('서')).toBe(false); - expect(hasSingleBatchim('와')).toBe(false); - }); - - it('한글 외의 문자를 입력하면 false를 반환한다.', () => { - expect(hasSingleBatchim('cat')).toBe(false); - expect(hasSingleBatchim('')).toBe(false); - expect(hasSingleBatchim('?')).toBe(false); - }); - - it('한글 외의 문자를 입력하면 false를 반환한다.', () => { - expect(hasSingleBatchim('cat')).toBe(false); - expect(hasSingleBatchim('')).toBe(false); - expect(hasSingleBatchim('?')).toBe(false); - }); - }); -}); - -describe('hasValueInReadOnlyStringList', () => { - const testReadonlyList = ['ㄱ', 'ㄴ', 'ㄷ'] as const; - - it('read-only 문자열 리스트에 요소가 존재한다면 true를 반환한다.', () => { - const testValue = 'ㄱ'; - - expect(hasValueInReadOnlyStringList(testReadonlyList, testValue)).toBeTruthy(); - }); - - it('read-only 문자열 리스트에 요소가 존재하지 않으면 false를 반환한다.', () => { - const testValue = 'ㄹ'; - - expect(hasValueInReadOnlyStringList(testReadonlyList, testValue)).toBeFalsy(); - }); - - it('read-only 문자열 리스트에 요소가 존재한다면 두 번째 인자의 타입을 좁힌다.', () => { - const testValue = 'ㄱ' as string; - - if (hasValueInReadOnlyStringList(testReadonlyList, testValue)) { - expectTypeOf(testValue).toEqualTypeOf<'ㄱ' | 'ㄴ' | 'ㄷ'>(); - } else { - expectTypeOf(testValue).toEqualTypeOf(); - } - }); -}); - -describe('hasProperty', () => { - const testObj = { ㄱ: 'ㄱ', ㄴ: 'ㄴ', ㄷ: 'ㄷ' } as const; - - it('객체에 속성이 존재하면 true를 반환한다.', () => { - const testKey = 'ㄱ'; - - expect(hasProperty(testObj, testKey)).toBeTruthy(); - }); - - it('객체에 속성이 존재하지 않으면 false를 반환한다.', () => { - const testKey = 'ㄹ'; - - expect(hasProperty(testObj, testKey)).toBeFalsy(); - }); - - it('객체에 속성이 존재한다면 두 번째 인자의 타입을 좁힌다.', () => { - const testKey = 'ㄱ' as string; - - if (hasProperty(testObj, testKey)) { - expectTypeOf(testKey).toEqualTypeOf<'ㄱ' | 'ㄴ' | 'ㄷ'>(); - } else { - expectTypeOf(testKey).toEqualTypeOf(); - } - }); -}); - -describe('canBeChoseong', () => { - describe('초성이 될 수 있다고 판단되는 경우', () => { - it('ㄱ', () => { - expect(canBeChoseong('ㄱ')).toBe(true); - }); - it('ㅃ', () => { - expect(canBeChoseong('ㅃ')).toBe(true); - }); - }); - - describe('초성이 될 수 없다고 판단되는 경우', () => { - it('ㅏ', () => { - expect(canBeChoseong('ㅏ')).toBe(false); - }); - it('ㅘ', () => { - expect(canBeChoseong('ㅘ')).toBe(false); - }); - it('ㄱㅅ', () => { - expect(canBeChoseong('ㄱㅅ')).toBe(false); - }); - it('가', () => { - expect(canBeChoseong('가')).toBe(false); - }); - }); -}); - -describe('canBeJungseong', () => { - describe('중성이 될 수 있다고 판단되는 경우', () => { - it('ㅗㅏ', () => { - expect(canBeJungseong('ㅗㅏ')).toBe(true); - }); - it('ㅏ', () => { - expect(canBeJungseong('ㅏ')).toBe(true); - }); - }); - - describe('중성이 될 수 없다고 판단되는 경우', () => { - it('ㄱ', () => { - expect(canBeJungseong('ㄱ')).toBe(false); - }); - it('ㄱㅅ', () => { - expect(canBeJungseong('ㄱㅅ')).toBe(false); - }); - it('가', () => { - expect(canBeJungseong('가')).toBe(false); - }); - }); -}); - -describe('canBeJongseong', () => { - describe('종성이 될 수 있다고 판단되는 경우', () => { - it('ㄱ', () => { - expect(canBeJongseong('ㄱ')).toBe(true); - }); - it('ㄱㅅ', () => { - expect(canBeJongseong('ㄱㅅ')).toBe(true); - }); - it('ㅂㅅ', () => { - expect(canBeJongseong('ㅂㅅ')).toBe(true); - }); - }); - - describe('종성이 될 수 없다고 판단되는 경우', () => { - it('ㅎㄹ', () => { - expect(canBeJongseong('ㅎㄹ')).toBe(false); - }); - it('ㅗㅏ', () => { - expect(canBeJongseong('ㅗㅏ')).toBe(false); - }); - it('ㅏ', () => { - expect(canBeJongseong('ㅏ')).toBe(false); - }); - it('가', () => { - expect(canBeJongseong('ㅏ')).toBe(false); - }); - }); -}); - -describe('isNotUndefined', () => { - it('정의된 값에 대해 true를 반환해야 한다', () => { - expect(isNotUndefined(5)).toBe(true); - expect(isNotUndefined('test')).toBe(true); - expect(isNotUndefined({})).toBe(true); - expect(isNotUndefined([])).toBe(true); - expect(isNotUndefined(null)).toBe(true); - }); - - it('undefined에 대해 false를 반환해야 한다', () => { - expect(isNotUndefined(undefined)).toBe(false); - }); -}); - -describe('arrayIncludes', () => { - it('값이 배열에 포함된 경우 true를 반환해야 한다', () => { - const array = ['a', 'b', 'c'] as const; - const value = 'a'; - const result = arrayIncludes(array, value); - expect(result).toBe(true); - }); - - it('값이 배열에 포함되지 않은 경우 false를 반환해야 한다', () => { - const array = ['a', 'b', 'c'] as const; - const value = 'd'; - const result = arrayIncludes(array, value); - expect(result).toBe(false); - }); - - it('undefined 값에 대해 false를 반환해야 합니다', () => { - const array = ['a', 'b', 'c'] as const; - const value = undefined; - const result = arrayIncludes(array, value); - expect(result).toBe(false); - }); - - it('검색을 시작할 인덱스를 기반으로 값을 반환합니다', () => { - const array: Array<'a' | 'b' | 'c'> = ['a', 'b', 'c']; - - const element = 'a'; - expect(arrayIncludes(array, element, 0)).toBe(true); - expect(arrayIncludes(array, element, 1)).toBe(false); - }); -}); diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index bf8be026..00000000 --- a/src/utils.ts +++ /dev/null @@ -1,212 +0,0 @@ -import assert from './_internal'; -import { - COMPLETE_HANGUL_END_CHARCODE, - COMPLETE_HANGUL_START_CHARCODE, - HANGUL_CHARACTERS_BY_FIRST_INDEX, - HANGUL_CHARACTERS_BY_LAST_INDEX, - HANGUL_CHARACTERS_BY_MIDDLE_INDEX, - NUMBER_OF_JONGSEONG, -} from './constants'; - -/** - * @name hasBatchim - * @description - * 한글 문자열의 마지막 글자가 받침이 있는지 확인합니다. - * ```typescript - * hasBatchim( - * // 글자에 받침이 있는지 확인하고 싶은 문자열 - * str: string - * ): boolean - * ``` - * @example - * hasBatchim('값') // true - * hasBatchim('토') // false - */ -export function hasBatchim(str: string) { - const lastChar = str[str.length - 1]; - - if (lastChar == null) { - return false; - } - const charCode = lastChar.charCodeAt(0); - const isCompleteHangul = COMPLETE_HANGUL_START_CHARCODE <= charCode && charCode <= COMPLETE_HANGUL_END_CHARCODE; - - if (!isCompleteHangul) { - return false; - } - - return (charCode - COMPLETE_HANGUL_START_CHARCODE) % NUMBER_OF_JONGSEONG > 0; -} - -/** - * @name hasSingleBatchim - * @description - * 한글 문자열의 마지막 글자가 홑받침이 있는지 확인합니다. - * ```typescript - * hasSingleBatchim( - * // 글자에 받침이 있는지 확인하고 싶은 문자열 - * str: string - * ): boolean - * ``` - * @example - * hasSingleBatchim('갑') // true - * hasSingleBatchim('값') // false - * hasSingleBatchim('토') // false - */ -export function hasSingleBatchim(str: string) { - const lastChar = str[str.length - 1]; - - if (lastChar == null) { - return false; - } - const charCode = lastChar.charCodeAt(0); - const isCompleteHangul = COMPLETE_HANGUL_START_CHARCODE <= charCode && charCode <= COMPLETE_HANGUL_END_CHARCODE; - - if (!isCompleteHangul) { - return false; - } - - const batchimCode = (charCode - COMPLETE_HANGUL_START_CHARCODE) % NUMBER_OF_JONGSEONG; - return HANGUL_CHARACTERS_BY_LAST_INDEX[batchimCode].length === 1; -} - -/** - * @name canBeChosung - * @deprecated canBeChoseong을 사용해 주세요. - * @description - * 인자로 받은 문자가 초성으로 위치할 수 있는 문자인지 검사합니다. - * ```typescript - * canBeChosung( - * // 대상 문자 - * character: string - * ): boolean - * ``` - * @example - * canBeChosung('ㄱ') // true - * canBeChosung('ㅃ') // true - * canBeChosung('ㄱㅅ') // false - * canBeChosung('ㅏ') // false - * canBeChosung('가') // false - */ -export function canBeChosung(character: string): character is (typeof HANGUL_CHARACTERS_BY_FIRST_INDEX)[number] { - return hasValueInReadOnlyStringList(HANGUL_CHARACTERS_BY_FIRST_INDEX, character); -} - -/** - * @name canBeChoseong - * @description - * 인자로 받은 문자가 초성으로 위치할 수 있는 문자인지 검사합니다. - * ```typescript - * canBeChoseong( - * // 대상 문자 - * character: string - * ): boolean - * ``` - * @example - * canBeChoseong('ㄱ') // true - * canBeChoseong('ㅃ') // true - * canBeChoseong('ㄱㅅ') // false - * canBeChoseong('ㅏ') // false - * canBeChoseong('가') // false - */ -export function canBeChoseong(character: string): character is (typeof HANGUL_CHARACTERS_BY_FIRST_INDEX)[number] { - return hasValueInReadOnlyStringList(HANGUL_CHARACTERS_BY_FIRST_INDEX, character); -} - -/** - * @name canBeJungsung - * @deprecated canBeJungseong을 사용해 주세요. - * @description - * 인자로 받은 문자가 중성으로 위치할 수 있는 문자인지 검사합니다. - * ```typescript - * canBeJungsung( - * // 대상 문자 - * character: string - * ): boolean - * ``` - * @example - * canBeJungsung('ㅏ') // true - * canBeJungsung('ㅗㅏ') // true - * canBeJungsung('ㅏㅗ') // false - * canBeJungsung('ㄱ') // false - * canBeJungsung('ㄱㅅ') // false - * canBeJungsung('가') // false - */ -export function canBeJungsung(character: string): character is (typeof HANGUL_CHARACTERS_BY_MIDDLE_INDEX)[number] { - return hasValueInReadOnlyStringList(HANGUL_CHARACTERS_BY_MIDDLE_INDEX, character); -} - -/** - * @name canBeJungseong - * @description - * 인자로 받은 문자가 중성으로 위치할 수 있는 문자인지 검사합니다. - * ```typescript - * canBeJungseong( - * // 대상 문자 - * character: string - * ): boolean - * ``` - * @example - * canBeJungseong('ㅏ') // true - * canBeJungseong('ㅗㅏ') // true - * canBeJungseong('ㅏㅗ') // false - * canBeJungseong('ㄱ') // false - * canBeJungseong('ㄱㅅ') // false - * canBeJungseong('가') // false - */ -export function canBeJungseong(character: string): character is (typeof HANGUL_CHARACTERS_BY_MIDDLE_INDEX)[number] { - return hasValueInReadOnlyStringList(HANGUL_CHARACTERS_BY_MIDDLE_INDEX, character); -} - -/** - * @name canBeJongsung - * @deprecated canBeJongseong을 사용해 주세요. - * @description - * 인자로 받은 문자가 종성으로 위치할 수 있는 문자인지 검사합니다. - * ```typescript - * canBeJongsung( - * // 대상 문자 - * character: string - * ): boolean - * ``` - * @example - * canBeJongsung('ㄱ') // true - * canBeJongsung('ㄱㅅ') // true - * canBeJongsung('ㅎㄹ') // false - * canBeJongsung('가') // false - * canBeJongsung('ㅏ') // false - * canBeJongsung('ㅗㅏ') // false - */ -export function canBeJongsung(character: string): character is (typeof HANGUL_CHARACTERS_BY_LAST_INDEX)[number] { - return hasValueInReadOnlyStringList(HANGUL_CHARACTERS_BY_LAST_INDEX, character); -} - -/** - * @name canBeJongseong - * @description - * 인자로 받은 문자가 종성으로 위치할 수 있는 문자인지 검사합니다. - * ```typescript - * canBeJongseong( - * // 대상 문자 - * character: string - * ): boolean - * ``` - * @example - * canBeJongseong('ㄱ') // true - * canBeJongseong('ㄱㅅ') // true - * canBeJongseong('ㅎㄹ') // false - * canBeJongseong('가') // false - * canBeJongseong('ㅏ') // false - * canBeJongseong('ㅗㅏ') // false - */ -export function canBeJongseong(character: string): character is (typeof HANGUL_CHARACTERS_BY_LAST_INDEX)[number] { - return hasValueInReadOnlyStringList(HANGUL_CHARACTERS_BY_LAST_INDEX, character); -} - -export function hasValueInReadOnlyStringList(list: readonly T[], value: string): value is T { - return list.some(item => item === value); -} - -export function hasProperty(obj: T, key: K): key is K & keyof T { - return Object.prototype.hasOwnProperty.call(obj, key); -} From 7a33c1e2701471628582af3dd051e5ba1cc4c1f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=B0=AC=ED=98=81?= Date: Tue, 23 Jul 2024 12:15:22 +0900 Subject: [PATCH 07/21] =?UTF-8?q?feat:=20`hasBatchim`=20=EC=9D=84=20utils?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=B3=84=EB=8F=84=20=ED=95=A8=EC=88=98?= =?UTF-8?q?=EB=A1=9C=20=EB=B6=84=EB=A6=AC=ED=95=A9=EB=8B=88=EB=8B=A4.=20(#?= =?UTF-8?q?195)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * hasBatchim * resolve type error * add change set * hasProperty, hasValueInReadOnlyStringList를 internal folder 로 옮깁니다 * resolve test error * move with test code --- .changeset/honest-roses-flow.md | 5 ++ docs/src/pages/docs/api/hasBatchim.en.mdx | 18 +++++ docs/src/pages/docs/api/hasBatchim.ko.mdx | 21 +++++ src/_internal/hangul.ts | 9 ++- src/_internal/index.spec.ts | 54 ++++++++++++- src/_internal/index.ts | 8 ++ src/canBe.ts | 2 +- src/convertQwertyToHangulAlphabet.ts | 2 +- src/disassemble.ts | 2 +- src/hasBatchim.spec.ts | 99 +++++++++++++++++++++++ src/hasBatchim.ts | 47 +++++++++++ src/index.ts | 5 +- src/josa.ts | 2 +- 13 files changed, 265 insertions(+), 9 deletions(-) create mode 100644 .changeset/honest-roses-flow.md create mode 100644 docs/src/pages/docs/api/hasBatchim.en.mdx create mode 100644 docs/src/pages/docs/api/hasBatchim.ko.mdx create mode 100644 src/hasBatchim.spec.ts create mode 100644 src/hasBatchim.ts diff --git a/.changeset/honest-roses-flow.md b/.changeset/honest-roses-flow.md new file mode 100644 index 00000000..b4a20c9c --- /dev/null +++ b/.changeset/honest-roses-flow.md @@ -0,0 +1,5 @@ +--- +"es-hangul": major +--- + +feat: hasBatchim 을 utils에서 별도 함수로 분리합니다. diff --git a/docs/src/pages/docs/api/hasBatchim.en.mdx b/docs/src/pages/docs/api/hasBatchim.en.mdx new file mode 100644 index 00000000..c2444395 --- /dev/null +++ b/docs/src/pages/docs/api/hasBatchim.en.mdx @@ -0,0 +1,18 @@ +# hasBatchim +Checks if the last character of a Korean string has a batchim (jongseong). + +```typescript +hasBatchim( + str: string, + // checking for single batchim + options?: { single?: boolean } +): boolean + + + ```typescript + hasBatchim('값') // true + hasBatchim('토') // false + hasBatchim('갑', { single: true }) // true + hasBatchim('값', { single: true }) // false + hasBatchim('토', { single: true }) // false + ```` diff --git a/docs/src/pages/docs/api/hasBatchim.ko.mdx b/docs/src/pages/docs/api/hasBatchim.ko.mdx new file mode 100644 index 00000000..a239fdc2 --- /dev/null +++ b/docs/src/pages/docs/api/hasBatchim.ko.mdx @@ -0,0 +1,21 @@ +# hasBatchim + + +한글 문자열의 마지막 글자가 받침이 있는지 확인합니다. + + +```typescript +hasBatchim( + str: string, + // 홑받침 여부를 확인할지 여부 + options?: { single?: boolean } +): boolean + + + ```typescript + hasBatchim('값') // true + hasBatchim('토') // false + hasBatchim('갑', { single: true }) // true + hasBatchim('값', { single: true }) // false + hasBatchim('토', { single: true }) // false + ```` diff --git a/src/_internal/hangul.ts b/src/_internal/hangul.ts index aed4ea17..5d2c5a7e 100644 --- a/src/_internal/hangul.ts +++ b/src/_internal/hangul.ts @@ -2,8 +2,8 @@ import assert, { excludeLastElement, isBlank, joinString } from '.'; import { canBeChoseong, canBeJungseong, canBeJongseong } from '../canBe'; import { combineHangulCharacter, combineVowels, curriedCombineHangulCharacter } from '../combineHangulCharacter'; import { disassembleToGroups } from '../disassemble'; +import { hasBatchim } from '../hasBatchim'; import { removeLastHangulCharacter } from '../removeLastHangulCharacter'; -import { hasSingleBatchim } from '../utils'; export function isHangulCharacter(character: string) { return /^[가-힣]$/.test(character); @@ -149,7 +149,12 @@ export function binaryAssembleHangulCharacters(source: string, nextCharacter: st const lastConsonant = lastJamo; - if (hasSingleBatchim(source) && canBeJongseong(`${lastConsonant}${nextCharacter}`)) { + if ( + hasBatchim(source, { + single: true, + }) && + canBeJongseong(`${lastConsonant}${nextCharacter}`) + ) { return combineJongseong(`${lastConsonant}${nextCharacter}`); } diff --git a/src/_internal/index.spec.ts b/src/_internal/index.spec.ts index 6c6bc393..e2e02b6c 100644 --- a/src/_internal/index.spec.ts +++ b/src/_internal/index.spec.ts @@ -1,4 +1,4 @@ -import assert, { excludeLastElement, isBlank, joinString } from './index'; +import assert, { excludeLastElement, hasProperty, hasValueInReadOnlyStringList, isBlank, joinString } from './index'; describe('excludeLastElement', () => { it('마지막 요소를 제외한 모든 요소와 마지막 요소를 반환한다', () => { @@ -59,3 +59,55 @@ describe('assert', () => { expect(() => assert(false, customMessage)).toThrowError(customMessage); }); }); + +describe('hasValueInReadOnlyStringList', () => { + const testReadonlyList = ['ㄱ', 'ㄴ', 'ㄷ'] as const; + + it('read-only 문자열 리스트에 요소가 존재한다면 true를 반환한다.', () => { + const testValue = 'ㄱ'; + + expect(hasValueInReadOnlyStringList(testReadonlyList, testValue)).toBeTruthy(); + }); + + it('read-only 문자열 리스트에 요소가 존재하지 않으면 false를 반환한다.', () => { + const testValue = 'ㄹ'; + + expect(hasValueInReadOnlyStringList(testReadonlyList, testValue)).toBeFalsy(); + }); + + it('read-only 문자열 리스트에 요소가 존재한다면 두 번째 인자의 타입을 좁힌다.', () => { + const testValue = 'ㄱ' as string; + + if (hasValueInReadOnlyStringList(testReadonlyList, testValue)) { + expectTypeOf(testValue).toEqualTypeOf<'ㄱ' | 'ㄴ' | 'ㄷ'>(); + } else { + expectTypeOf(testValue).toEqualTypeOf(); + } + }); +}); + +describe('hasProperty', () => { + const testObj = { ㄱ: 'ㄱ', ㄴ: 'ㄴ', ㄷ: 'ㄷ' } as const; + + it('객체에 속성이 존재하면 true를 반환한다.', () => { + const testKey = 'ㄱ'; + + expect(hasProperty(testObj, testKey)).toBeTruthy(); + }); + + it('객체에 속성이 존재하지 않으면 false를 반환한다.', () => { + const testKey = 'ㄹ'; + + expect(hasProperty(testObj, testKey)).toBeFalsy(); + }); + + it('객체에 속성이 존재한다면 두 번째 인자의 타입을 좁힌다.', () => { + const testKey = 'ㄱ' as string; + + if (hasProperty(testObj, testKey)) { + expectTypeOf(testKey).toEqualTypeOf<'ㄱ' | 'ㄴ' | 'ㄷ'>(); + } else { + expectTypeOf(testKey).toEqualTypeOf(); + } + }); +}); diff --git a/src/_internal/index.ts b/src/_internal/index.ts index 4020b7b2..fa05d5b0 100644 --- a/src/_internal/index.ts +++ b/src/_internal/index.ts @@ -30,3 +30,11 @@ export function defined(value: T | undefined): T { export function arrayIncludes(array: Type[] | readonly Type[], item: unknown, fromIndex?: number): item is Type { return array.includes(item as Type, fromIndex); } + +export function hasValueInReadOnlyStringList(list: readonly T[], value: string): value is T { + return list.some(item => item === value); +} + +export function hasProperty(obj: T, key: K): key is K & keyof T { + return Object.prototype.hasOwnProperty.call(obj, key); +} diff --git a/src/canBe.ts b/src/canBe.ts index 438b8e5b..0e8d7b05 100644 --- a/src/canBe.ts +++ b/src/canBe.ts @@ -1,9 +1,9 @@ +import { hasValueInReadOnlyStringList } from './_internal'; import { HANGUL_CHARACTERS_BY_FIRST_INDEX, HANGUL_CHARACTERS_BY_LAST_INDEX, HANGUL_CHARACTERS_BY_MIDDLE_INDEX, } from './constants'; -import { hasValueInReadOnlyStringList } from './utils'; /** * @name canBeChoseong diff --git a/src/convertQwertyToHangulAlphabet.ts b/src/convertQwertyToHangulAlphabet.ts index bcc4aa81..e57af259 100644 --- a/src/convertQwertyToHangulAlphabet.ts +++ b/src/convertQwertyToHangulAlphabet.ts @@ -1,6 +1,6 @@ +import { hasProperty } from './_internal'; import { assembleHangul } from './assemble'; import { QWERTY_KEYBOARD_MAP } from './constants'; -import { hasProperty } from './utils'; /** * @name convertQwertyToHangulAlphabet diff --git a/src/disassemble.ts b/src/disassemble.ts index 9c9ee461..f16e0b42 100644 --- a/src/disassemble.ts +++ b/src/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 './utils'; export function disassembleToGroups(str: string) { /* diff --git a/src/hasBatchim.spec.ts b/src/hasBatchim.spec.ts new file mode 100644 index 00000000..02de88dc --- /dev/null +++ b/src/hasBatchim.spec.ts @@ -0,0 +1,99 @@ +import { hasBatchim } from './hasBatchim'; + +describe('hasBatchim', () => { + describe('받침이 있다고 판단되는 경우', () => { + it('"값" 문자에서 받침이 있으므로 true를 반환한다.', () => { + expect(hasBatchim('값')).toBe(true); + }); + it('"공" 문자에서 받침이 있으므로 true를 반환한다.', () => { + expect(hasBatchim('공')).toBe(true); + }); + it('"읊" 문자에서 받침이 있으므로 true를 반환한다.', () => { + expect(hasBatchim('읊')).toBe(true); + }); + }); + + describe('받침이 없다고 판단되는 경우', () => { + it('"토" 문자에서 받침이 없으므로 false를 반환한다.', () => { + expect(hasBatchim('토')).toBe(false); + }); + it('"서" 문자에서 받침이 없으므로 false를 반환한다.', () => { + expect(hasBatchim('서')).toBe(false); + }); + it('빈 문자열은 받침이 없으므로 false를 반환한다.', () => { + expect(hasBatchim('')).toBe(false); + }); + }); + + describe('완성된 한글이 아닌 경우', () => { + it('한글이 자음 또는 모음으로만 구성된 경우 false를 반환한다.', () => { + expect(hasBatchim('ㄱ')).toBe(false); + expect(hasBatchim('ㅏ')).toBe(false); + }); + + it('한글 외의 문자를 입력하면 false를 반환한다', () => { + expect(hasBatchim('cat')).toBe(false); + expect(hasBatchim('!')).toBe(false); + }); + }); +}); + +describe('홑받침', () => { + it('홑받침을 받으면 true를 반환한다.', () => { + expect( + hasBatchim('공', { + single: true, + }) + ).toBe(true); + + expect( + hasBatchim('핫', { + single: true, + }) + ).toBe(true); + + expect( + hasBatchim('양', { + single: true, + }) + ).toBe(true); + + expect( + hasBatchim('신', { + single: true, + }) + ).toBe(true); + + expect( + hasBatchim('확', { + single: true, + }) + ).toBe(true); + }); + + describe('홑받침이 아니라고 판단되는 경우', () => { + it('겹받침을 받으면 false를 반환한다.', () => { + expect( + hasBatchim('값', { + single: true, + }) + ).toBe(false); + + expect(hasBatchim('읊', { single: true })).toBe(false); + + expect(hasBatchim('웱', { single: true })).toBe(false); + }); + + it('받침이 없는 문자를 받으면 false를 반환한다.', () => { + expect(hasBatchim('토', { single: true })).toBe(false); + expect(hasBatchim('서', { single: true })).toBe(false); + expect(hasBatchim('와', { single: true })).toBe(false); + }); + + it('한글 외의 문자를 입력하면 false를 반환한다.', () => { + expect(hasBatchim('cat', { single: true })).toBe(false); + expect(hasBatchim('', { single: true })).toBe(false); + expect(hasBatchim('?', { single: true })).toBe(false); + }); + }); +}); diff --git a/src/hasBatchim.ts b/src/hasBatchim.ts new file mode 100644 index 00000000..6ad7a287 --- /dev/null +++ b/src/hasBatchim.ts @@ -0,0 +1,47 @@ +import { + COMPLETE_HANGUL_END_CHARCODE, + COMPLETE_HANGUL_START_CHARCODE, + HANGUL_CHARACTERS_BY_LAST_INDEX, + NUMBER_OF_JONGSEONG, +} from './constants'; + +/** + * @name hasBatchim + * @description + * 한글 문자열의 마지막 글자가 받침이 있는지 확인합니다. + * ```typescript + * hasBatchim( + * // 글자에 받침이 있는지 확인하고 싶은 문자열 + * str: string, + * // 옵션 객체로 홑받침 여부를 확인 + * options?: { single?: boolean } + * ): boolean + * ``` + * @example + * hasBatchim('값') // true + * hasBatchim('토') // false + * hasBatchim('갑', { single: true }) // true + * hasBatchim('값', { single: true }) // false + * hasBatchim('토', { single: true }) // false + */ +export function hasBatchim(str: string, options?: { single?: boolean }) { + const lastChar = str[str.length - 1]; + + if (lastChar == null) { + return false; + } + const charCode = lastChar.charCodeAt(0); + const isCompleteHangul = COMPLETE_HANGUL_START_CHARCODE <= charCode && charCode <= COMPLETE_HANGUL_END_CHARCODE; + + if (!isCompleteHangul) { + return false; + } + + const batchimCode = (charCode - COMPLETE_HANGUL_START_CHARCODE) % NUMBER_OF_JONGSEONG; + + if (options?.single) { + return HANGUL_CHARACTERS_BY_LAST_INDEX[batchimCode].length === 1; + } + + return batchimCode > 0; +} diff --git a/src/index.ts b/src/index.ts index c403e18a..80ef88f7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,14 +1,15 @@ export { assembleHangul } from './assemble'; -export { canBeChoseong, canBeJongseong, canBeJungseong } from './canBe'; export { choseongIncludes } from './choseongIncludes'; export { chosungIncludes } from './chosungIncludes'; export { combineHangulCharacter, combineVowels, curriedCombineHangulCharacter } from './combineHangulCharacter'; export { convertQwertyToHangul, convertQwertyToHangulAlphabet } from './convertQwertyToHangulAlphabet'; export { disassemble, disassembleToGroups } from './disassemble'; export { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; -export { getChoseong } from './getChoseong'; export { josa } from './josa'; export { removeLastHangulCharacter } from './removeLastHangulCharacter'; export { romanize } from './romanize'; export { standardizePronunciation } from './standardizePronunciation'; export { susa } from './susa'; +export { hasBatchim } from './hasBatchim'; +export { canBeChoseong, canBeJongseong, canBeJungseong } from './canBe'; +export { getChoseong } from './getChoseong'; diff --git a/src/josa.ts b/src/josa.ts index 30df72e8..8f5de283 100644 --- a/src/josa.ts +++ b/src/josa.ts @@ -1,5 +1,5 @@ import { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; -import { hasBatchim } from './utils'; +import { hasBatchim } from './hasBatchim'; type JosaOption = | '이/가' From cbf3e4ac2765b427d1c40b3cf7bb1ef059681747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=B0=AC=ED=98=81?= Date: Tue, 23 Jul 2024 12:37:28 +0900 Subject: [PATCH 08/21] =?UTF-8?q?feat:=20choseongIncludes=ED=95=A8?= =?UTF-8?q?=EC=88=98=EB=A5=BC=20=EC=A0=9C=EA=B1=B0=ED=95=A9=EB=8B=88?= =?UTF-8?q?=EB=8B=A4.=20(#197)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove choseongIncludes Co-authored-by: 서동휘 <8275026+suhdonghwi@users.noreply.github.com> --- .changeset/mighty-paws-grow.md | 5 +++ README-en_us.md | 8 +++-- README.md | 10 ++++-- .../pages/docs/api/choseongIncludes.en.mdx | 35 ------------------- .../pages/docs/api/choseongIncludes.ko.mdx | 35 ------------------- .../src/pages/docs/api/chosungIncludes.en.mdx | 35 ------------------- .../src/pages/docs/api/chosungIncludes.ko.mdx | 35 ------------------- docs/src/pages/docs/introduction.en.mdx | 18 ++++++---- docs/src/pages/docs/introduction.ko.mdx | 17 +++++---- docs/src/pages/index.en.mdx | 10 ++++-- docs/src/pages/index.ko.mdx | 10 ++++-- src/choseongIncludes.spec.ts | 35 ------------------- src/choseongIncludes.ts | 30 ---------------- src/chosungIncludes.ts | 18 ---------- src/index.ts | 2 -- 15 files changed, 53 insertions(+), 250 deletions(-) create mode 100644 .changeset/mighty-paws-grow.md delete mode 100644 docs/src/pages/docs/api/choseongIncludes.en.mdx delete mode 100644 docs/src/pages/docs/api/choseongIncludes.ko.mdx delete mode 100644 docs/src/pages/docs/api/chosungIncludes.en.mdx delete mode 100644 docs/src/pages/docs/api/chosungIncludes.ko.mdx delete mode 100644 src/choseongIncludes.spec.ts delete mode 100644 src/choseongIncludes.ts delete mode 100644 src/chosungIncludes.ts diff --git a/.changeset/mighty-paws-grow.md b/.changeset/mighty-paws-grow.md new file mode 100644 index 00000000..8f14ff4c --- /dev/null +++ b/.changeset/mighty-paws-grow.md @@ -0,0 +1,5 @@ +--- +"es-hangul": major +--- + +feat: choseongIncludes함수를 제거합니다. diff --git a/README-en_us.md b/README-en_us.md index a629726c..8173fb62 100644 --- a/README-en_us.md +++ b/README-en_us.md @@ -11,12 +11,16 @@ es-hangul is a library that makes it easy to handle [Hangul](https://en.wikipedi You can easily implement tasks related to Hangul, such as initial consonant search and attaching particles(josas). ```tsx -import { choseongIncludes } from 'es-hangul'; +import { getChoseong } from 'es-hangul'; const searchWord = '라면'; const userInput = 'ㄹㅁ'; -const result = choseongIncludes(searchWord, userInput); // true +const result = getChoseong(searchWord); // ㄹㅁ + +if (result === userInput) { + // do something +} ``` ```tsx diff --git a/README.md b/README.md index c91c9048..faf7b845 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,19 @@ ## 사용 예시 -초성 검색, 조사 붙이기와 같은 한글 작업을 간단히 할 수 있습니다. +문자열 초성화 , 조사 붙이기와 같은 한글 작업을 간단히 할 수 있습니다. ```tsx -import { choseongIncludes } from 'es-hangul'; +import { getChoseong } from 'es-hangul'; const searchWord = '라면'; const userInput = 'ㄹㅁ'; -const result = choseongIncludes(searchWord, userInput); // true +const result = getChoseong(searchWord); // ㄹㅁ + +if (result === userInput) { + // 일치한다면 if문이 실행 +} ``` ```tsx diff --git a/docs/src/pages/docs/api/choseongIncludes.en.mdx b/docs/src/pages/docs/api/choseongIncludes.en.mdx deleted file mode 100644 index 1daf7792..00000000 --- a/docs/src/pages/docs/api/choseongIncludes.en.mdx +++ /dev/null @@ -1,35 +0,0 @@ -import { Sandpack } from '@/components/Sandpack'; - -# choseongIncludes - -Performs a search for matches in the initial consonants of a string. - -```typescript -function choseongIncludes( - // The string to be checked for matching initial consonants (e.g., '프론트엔드') - x: string, - // Initial consonant string (e.g., 'ㅍㄹㅌㅇㄷ') - y: string -): boolean; -``` - -```typescript -choseongIncludes('프론트엔드', 'ㅍㄹㅌ'); // true -choseongIncludes('00프론트엔드', 'ㅍㄹㅌ'); // true -choseongIncludes('프론트엔드', 'ㅍㅌ'); // false -choseongIncludes('프론트엔드', '푸롴트'); // false -``` - -## Demo - -
- - - -```ts index.ts -import { choseongIncludes } from 'es-hangul'; - -console.log(choseongIncludes('프론트엔드', 'ㅍㄹㅌ')); -``` - - diff --git a/docs/src/pages/docs/api/choseongIncludes.ko.mdx b/docs/src/pages/docs/api/choseongIncludes.ko.mdx deleted file mode 100644 index 509e9250..00000000 --- a/docs/src/pages/docs/api/choseongIncludes.ko.mdx +++ /dev/null @@ -1,35 +0,0 @@ -import { Sandpack } from '@/components/Sandpack'; - -# choseongIncludes - -문자열의 초성 일치 검색을 수행합니다. - -```typescript -function choseongIncludes( - // 초성 일치하는지 검사할 문자열 (e.g. '프론트엔드') - x: string, - // 초성 문자열 (e.g. 'ㅍㄹㅌㅇㄷ') - y: string -): boolean; -``` - -```typescript -choseongIncludes('프론트엔드', 'ㅍㄹㅌ'); // true -choseongIncludes('00프론트엔드', 'ㅍㄹㅌ'); // true -choseongIncludes('프론트엔드', 'ㅍㅌ'); // false -choseongIncludes('프론트엔드', '푸롴트'); // false -``` - -## 사용해보기 - -
- - - -```ts index.ts -import { choseongIncludes } from 'es-hangul'; - -console.log(choseongIncludes('프론트엔드', 'ㅍㄹㅌ')); -``` - - diff --git a/docs/src/pages/docs/api/chosungIncludes.en.mdx b/docs/src/pages/docs/api/chosungIncludes.en.mdx deleted file mode 100644 index a635871b..00000000 --- a/docs/src/pages/docs/api/chosungIncludes.en.mdx +++ /dev/null @@ -1,35 +0,0 @@ -import { Sandpack } from '@/components/Sandpack'; - -# chosungIncludes (deprecated, Please use choseongIncludes) - -Performs a search for matches in the initial consonants of a string. - -```typescript -function chosungIncludes( - // The string to be checked for matching initial consonants (e.g., '프론트엔드') - x: string, - // Initial consonant string (e.g., 'ㅍㄹㅌㅇㄷ') - y: string -): boolean; -``` - -```typescript -chosungIncludes('프론트엔드', 'ㅍㄹㅌ'); // true -chosungIncludes('00프론트엔드', 'ㅍㄹㅌ'); // true -chosungIncludes('프론트엔드', 'ㅍㅌ'); // false -chosungIncludes('프론트엔드', '푸롴트'); // false -``` - -## Demo - -
- - - -```ts index.ts -import { choseongIncludes } from 'es-hangul'; - -console.log(choseongIncludes('프론트엔드', 'ㅍㄹㅌ')); -``` - - diff --git a/docs/src/pages/docs/api/chosungIncludes.ko.mdx b/docs/src/pages/docs/api/chosungIncludes.ko.mdx deleted file mode 100644 index 9211e965..00000000 --- a/docs/src/pages/docs/api/chosungIncludes.ko.mdx +++ /dev/null @@ -1,35 +0,0 @@ -import { Sandpack } from '@/components/Sandpack'; - -# chosungIncludes (deprecated, choseongIncludes를 사용해주세요) - -문자열의 초성 일치 검색을 수행합니다. - -```typescript -function chosungIncludes( - // 초성 일치하는지 검사할 문자열 (e.g. '프론트엔드') - x: string, - // 초성 문자열 (e.g. 'ㅍㄹㅌㅇㄷ') - y: string -): boolean; -``` - -```typescript -chosungIncludes('프론트엔드', 'ㅍㄹㅌ'); // true -chosungIncludes('00프론트엔드', 'ㅍㄹㅌ'); // true -chosungIncludes('프론트엔드', 'ㅍㅌ'); // false -chosungIncludes('프론트엔드', '푸롴트'); // false -``` - -## 사용해보기 - -
- - - -```ts index.ts -import { choseongIncludes } from 'es-hangul'; - -console.log(choseongIncludes('프론트엔드', 'ㅍㄹㅌ')); -``` - - diff --git a/docs/src/pages/docs/introduction.en.mdx b/docs/src/pages/docs/introduction.en.mdx index 6459c362..891c0844 100644 --- a/docs/src/pages/docs/introduction.en.mdx +++ b/docs/src/pages/docs/introduction.en.mdx @@ -32,22 +32,26 @@ Our library provides strong typing, allowing for easy detection of type errors d ### Full Support for Hangul-related Features -Our library provides a [modern API](./api/choseongIncludes) that can be conveniently used in various applications. +Our library provides a [modern API](./api/getChoseong) that can be conveniently used in various applications. -#### First Consonant Search ([choseongIncludes](./api/choseongIncludes)) +#### First Consonant Search ([getChoseong](./api/getChoseong)) -It checks whether an initial consonant is included in a specific word. For example, you can easily find out if the word '라면' (ramyeon) contains the initial consonants 'ㄹㅁ'. +It can get choseong from specific word. For example, you can easily find out if the word '라면' (ramyeon) contains the choseong 'ㄹㅁ'. -```tsx /choseongIncludes/ -import { choseongIncludes } from 'es-hangul'; +```tsx /getChoseong/ +import { getChoseong } from 'es-hangul'; const searchWord = '라면'; const userInput = 'ㄹㅁ'; -const result = choseongIncludes(searchWord, userInput); -console.log(result); // true +const result = getChoseong(searchWord); // ㄹㅁ + +if (result === userInput) { + // do something +} ``` + #### Disassembling Hangul Characters ([disassemble](./api/disassemble)) You can decompose a given Hangul string into initial consonants, vowels, and final consonants, and return it in array form to allow for more detailed analysis or modification of the string. diff --git a/docs/src/pages/docs/introduction.ko.mdx b/docs/src/pages/docs/introduction.ko.mdx index 6e351612..13c448de 100644 --- a/docs/src/pages/docs/introduction.ko.mdx +++ b/docs/src/pages/docs/introduction.ko.mdx @@ -32,20 +32,23 @@ ECMAScript Modules를 이용하여 사용하는 함수만 애플리케이션에 ### 한글을 위한 모든 인터페이스를 제공하는 것을 목표합니다 -다양한 애플리케이션에서 편리하게 사용할 수 있는 [현대적인 API](./api/choseongIncludes)를 제공합니다. +다양한 애플리케이션에서 편리하게 사용할 수 있는 [현대적인 API](./api/getChoseong)를 제공합니다. -#### 초성 검색 ([choseongIncludes](./api/choseongIncludes)) +#### 초성 검색 ([getChoseong](./api/getChoseong)) -초성이 특정 단어에 포함되어 있는지 검사합니다. 예를 들어, '라면'이라는 단어가 'ㄹㅁ'으로 시작하는 초성을 포함하는지 쉽게 알 수 있습니다. +특정 단어에서 초성을 얻을 수 있습니다. 예를 들어, '라면'이라는 단어가 'ㄹㅁ'으로 시작하는 초성을 포함하는지 쉽게 알 수 있습니다. -```tsx /choseongIncludes/ -import { choseongIncludes } from 'es-hangul'; +```tsx /getChoseong/ +import { getChoseong } from 'es-hangul'; const searchWord = '라면'; const userInput = 'ㄹㅁ'; -const result = choseongIncludes(searchWord, userInput); -console.log(result); // true +const result = getChoseong(searchWord); // ㄹㅁ + +if (result === userInput) { + // 일치한다면 if문이 실행 +} ``` #### 초/중/종성 분해 ([disassemble](./api/disassemble)) diff --git a/docs/src/pages/index.en.mdx b/docs/src/pages/index.en.mdx index 083f0d6c..0c26dffc 100644 --- a/docs/src/pages/index.en.mdx +++ b/docs/src/pages/index.en.mdx @@ -33,15 +33,19 @@ import { Callout, useTheme, Steps } from 'nextra-theme-docs'; ```tsx -import { choseongIncludes } from 'es-hangul'; +import { getChoseong } from 'es-hangul'; const searchWord = '라면'; const userInput = 'ㄹㅁ'; -const result = choseongIncludes(searchWord, userInput); -console.log(result); // true +const result = getChoseong(searchWord); // ㄹㅁ + +if(result === userInput){ + // do something +} ``` + ```tsx import { josa } from 'es-hangul'; diff --git a/docs/src/pages/index.ko.mdx b/docs/src/pages/index.ko.mdx index dffc4dec..03e8fb12 100644 --- a/docs/src/pages/index.ko.mdx +++ b/docs/src/pages/index.ko.mdx @@ -33,15 +33,19 @@ import { Callout, useTheme, Steps } from 'nextra-theme-docs'; ```tsx -import { choseongIncludes } from 'es-hangul'; +import { getChoseong } from 'es-hangul'; const searchWord = '라면'; const userInput = 'ㄹㅁ'; -const result = choseongIncludes(searchWord, userInput); -console.log(result); // true +const result = getChoseong(searchWord); // ㄹㅁ + +if(result === userInput){ + // 일치한다면 if문이 실행 +} ``` + ```tsx import { josa } from 'es-hangul'; diff --git a/src/choseongIncludes.spec.ts b/src/choseongIncludes.spec.ts deleted file mode 100644 index 245b891f..00000000 --- a/src/choseongIncludes.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { choseongIncludes } from './choseongIncludes'; - -describe('choseongIncludes', () => { - describe('초성이 포함되어있다고 판단되는 경우', () => { - it('"ㅍㄹㅌ" 문자열로 "프론트엔드"를 검색하면 true를 반환한다.', () => { - expect(choseongIncludes('프론트엔드', 'ㅍㄹㅌ')).toBe(true); - }); - - it('"ㅍㄹㅌ" 문자열로 "00프론트엔드"를 검색하면 true를 반환한다.', () => { - expect(choseongIncludes('00프론트엔드', 'ㅍㄹㅌ')).toBe(true); - }); - - it('"ㅍㄹㅌㅇㄷㄱㅂㅈ" 문자열로 "프론트엔드 개발자"를 검색하면 true를 반환한다.', () => { - expect(choseongIncludes('프론트엔드 개발자', 'ㅍㄹㅌㅇㄷㄱㅂㅈ')).toBe(true); - }); - - it('"ㅍㄹㅌㅇㄷ ㄱㅂㅈ" 문자열로 "프론트엔드 개발자"를 검색하면 true를 반환한다.', () => { - expect(choseongIncludes('프론트엔드 개발자', 'ㅍㄹㅌㅇㄷ ㄱㅂㅈ')).toBe(true); - }); - }); - - describe('초성이 포함되어있다고 판단되지 않는 경우', () => { - it('"ㅍㅌ" 문자열로 "프론트엔드"를 검색하면 false를 반환한다.', () => { - expect(choseongIncludes('프론트엔드', 'ㅍㅌ')).toBe(false); - }); - - it('빈 문자열로 "프론트엔드 개발자"를 검색하면 false를 반환한다.', () => { - expect(choseongIncludes('프론트엔드 개발자', ' ')).toBe(false); - }); - - it('"푸롴트" 문자열로 "프론트엔드"를 검색하면 초성으로만 구성되어 있지 않아 false를 반환한다.', () => { - expect(choseongIncludes('프론트엔드', '푸롴트')).toBe(false); - }); - }); -}); diff --git a/src/choseongIncludes.ts b/src/choseongIncludes.ts deleted file mode 100644 index 714691ba..00000000 --- a/src/choseongIncludes.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { canBeChoseong } from './canBe'; -import { disassembleToGroups } from './disassemble'; -import { getChoseong } from './getChoseong'; - -export function choseongIncludes(x: string, y: string) { - const trimmedY = y.replace(/\s/g, ''); - - if (!isOnlyChoseong(trimmedY)) { - return false; - } - - const choseongX = getChoseong(x).replace(/\s/g, ''); - const choseongY = trimmedY; - - return choseongX.includes(choseongY); -} - -/* - * @description 문자열이 한글초성으로만 주어진 경우 - */ -export function isOnlyChoseong(str: string) { - const groups = disassembleToGroups(str); - if (groups.length === 0) { - return false; - } - - return groups.every(disassembled => { - return disassembled.length === 1 && canBeChoseong(disassembled[0]); - }); -} diff --git a/src/chosungIncludes.ts b/src/chosungIncludes.ts deleted file mode 100644 index 7f775256..00000000 --- a/src/chosungIncludes.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { isOnlyChoseong } from './choseongIncludes'; -import { getChoseong } from './getChoseong'; - -/** - * @deprecated choseongIncludes를 사용해 주세요. - */ -export function chosungIncludes(x: string, y: string) { - const trimmedY = y.replace(/\s+/g, ''); - - if (!isOnlyChoseong(trimmedY)) { - return false; - } - - const choseongX = getChoseong(x).replace(/\s/g, ''); - const choseongY = trimmedY; - - return choseongX.includes(choseongY); -} diff --git a/src/index.ts b/src/index.ts index 80ef88f7..3c4b6048 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,4 @@ export { assembleHangul } from './assemble'; -export { choseongIncludes } from './choseongIncludes'; -export { chosungIncludes } from './chosungIncludes'; export { combineHangulCharacter, combineVowels, curriedCombineHangulCharacter } from './combineHangulCharacter'; export { convertQwertyToHangul, convertQwertyToHangulAlphabet } from './convertQwertyToHangulAlphabet'; export { disassemble, disassembleToGroups } from './disassemble'; From 88088fc4681eb674c8b6ae9198c926a45ab79888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=B0=AC=ED=98=81?= Date: Sun, 4 Aug 2024 12:45:47 +0900 Subject: [PATCH 09/21] =?UTF-8?q?docs:=20API=20=EB=A9=94=EB=89=B4=ED=8A=B8?= =?UTF-8?q?=EB=A6=AC=EC=97=90=EC=84=9C=20=ED=95=A8=EC=88=98=EB=AA=85?= =?UTF-8?q?=EC=9D=B4=20=EC=B9=B4=EB=A9=9C=EC=BC=80=EC=9D=B4=EC=8A=A4?= =?UTF-8?q?=EB=A1=9C=20=EB=82=98=EC=98=A4=EB=8F=84=EB=A1=9D=ED=95=A9?= =?UTF-8?q?=EB=8B=88=EB=8B=A4=20(#215)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * menu tree 에서 소문자로 나오게 합니다 * getChoseong --- docs/src/pages/docs/api/canBe.en.md | 4 ++++ docs/src/pages/docs/api/canBe.ko.md | 4 ++++ docs/src/pages/docs/api/getChoseong.en.mdx | 5 ++++- docs/src/pages/docs/api/getChoseong.ko.mdx | 4 ++++ docs/src/pages/docs/api/hasBatchim.en.mdx | 4 ++++ docs/src/pages/docs/api/hasBatchim.ko.mdx | 5 ++++- 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/src/pages/docs/api/canBe.en.md b/docs/src/pages/docs/api/canBe.en.md index 1fc0e18f..1338188f 100644 --- a/docs/src/pages/docs/api/canBe.en.md +++ b/docs/src/pages/docs/api/canBe.en.md @@ -1,3 +1,7 @@ +--- +title: canBe +--- + # canBeChoseong Check if a given character can be a choseong in Korean. diff --git a/docs/src/pages/docs/api/canBe.ko.md b/docs/src/pages/docs/api/canBe.ko.md index f6c38712..ede91e95 100644 --- a/docs/src/pages/docs/api/canBe.ko.md +++ b/docs/src/pages/docs/api/canBe.ko.md @@ -1,3 +1,7 @@ +--- +title: canBe +--- + # canBeChoseong 인자로 받은 문자가 초성으로 위치할 수 있는 문자인지 검사합니다. diff --git a/docs/src/pages/docs/api/getChoseong.en.mdx b/docs/src/pages/docs/api/getChoseong.en.mdx index 7f9b9c99..0d479ea5 100644 --- a/docs/src/pages/docs/api/getChoseong.en.mdx +++ b/docs/src/pages/docs/api/getChoseong.en.mdx @@ -1,5 +1,8 @@ -# getChoseong +--- +title: getChoseong +--- +# getChoseong Extracts the Choseong from a Korean word. (Example: 사과 -> 'ㅅㄱ') diff --git a/docs/src/pages/docs/api/getChoseong.ko.mdx b/docs/src/pages/docs/api/getChoseong.ko.mdx index 72137500..35fd374a 100644 --- a/docs/src/pages/docs/api/getChoseong.ko.mdx +++ b/docs/src/pages/docs/api/getChoseong.ko.mdx @@ -1,3 +1,7 @@ +--- +title: getChoseong +--- + # getChoseong 단어에서 초성을 추출합니다. (예: `사과` -> `'ㅅㄱ'`) diff --git a/docs/src/pages/docs/api/hasBatchim.en.mdx b/docs/src/pages/docs/api/hasBatchim.en.mdx index c2444395..4e1c22c8 100644 --- a/docs/src/pages/docs/api/hasBatchim.en.mdx +++ b/docs/src/pages/docs/api/hasBatchim.en.mdx @@ -1,3 +1,7 @@ +--- +title: hasBatchim +--- + # hasBatchim Checks if the last character of a Korean string has a batchim (jongseong). diff --git a/docs/src/pages/docs/api/hasBatchim.ko.mdx b/docs/src/pages/docs/api/hasBatchim.ko.mdx index a239fdc2..73cf58c5 100644 --- a/docs/src/pages/docs/api/hasBatchim.ko.mdx +++ b/docs/src/pages/docs/api/hasBatchim.ko.mdx @@ -1,5 +1,8 @@ -# hasBatchim +--- +title: hasBatchim +--- +# hasBatchim 한글 문자열의 마지막 글자가 받침이 있는지 확인합니다. From 2592ca4788bb9e7991012380e79fce7cb2d7ca17 Mon Sep 17 00:00:00 2001 From: chanhyuk-park Date: Sun, 4 Aug 2024 12:54:17 +0900 Subject: [PATCH 10/21] =?UTF-8?q?susa=20=EC=9D=98=20hasProprty=EB=A5=BC=20?= =?UTF-8?q?utils=EA=B0=80=20=EC=95=84=EB=8B=8C=20internal=20=ED=8F=B4?= =?UTF-8?q?=EB=8D=94=EC=97=90=EC=84=9C=20=EA=B0=80=EC=A0=B8=EC=98=B5?= =?UTF-8?q?=EB=8B=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/susa.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/susa.ts b/src/susa.ts index 6edb7a2a..342c2ad7 100644 --- a/src/susa.ts +++ b/src/susa.ts @@ -1,5 +1,5 @@ +import { hasProperty } from './_internal'; import { SUSA_MAP, SUSA_CLASSIFIER_MAP } from './constants'; -import { hasProperty } from './utils'; export function susa(num: number, classifier?: boolean): string { validateNumber(num); From 01843b8ddc5e0bc2140dfc13aad7df911dd8bf81 Mon Sep 17 00:00:00 2001 From: chanhyuk-park Date: Sun, 4 Aug 2024 20:05:36 +0900 Subject: [PATCH 11/21] remove curriedCombineHangulCharacter in index.ts --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 3c4b6048..37c1ebad 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ export { assembleHangul } from './assemble'; -export { combineHangulCharacter, combineVowels, curriedCombineHangulCharacter } from './combineHangulCharacter'; +export { combineHangulCharacter, combineVowels } from './combineHangulCharacter'; export { convertQwertyToHangul, convertQwertyToHangulAlphabet } from './convertQwertyToHangulAlphabet'; export { disassemble, disassembleToGroups } from './disassemble'; export { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; From 82e03c33182d248d7f6c8bfcb9241234464a37c8 Mon Sep 17 00:00:00 2001 From: SeongMin Kim <86355699+Collection50@users.noreply.github.com> Date: Tue, 6 Aug 2024 02:06:41 +0900 Subject: [PATCH 12/21] =?UTF-8?q?fix:=20=EC=9D=BC=EA=B4=80=EB=90=9C=20?= =?UTF-8?q?=ED=95=9C=EA=B8=80=20=EC=9D=B4=EB=A6=84=20=EA=B7=9C=EC=B9=99=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20(to=20v2)=20(#204)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 문자열에서 한글을 추출해주는 extractHangul 함수를 제거합니다 (#185) * remove extrachHangul * Create cyan-tigers-sneeze.md --------- Co-authored-by: Jonghyeon Ko * feat: disassembleHangul, disassemble, disassembleHangulToGroup 함수에서 hangul이라는 글자를 제거합니다 (#184) * dissemble관련 메서드에서 hangul이름을 제거합니다 * 누락된 부분 수정 * resolve conflit * Create late-beers-hang.md * diassembleHangul to diassemble --------- Co-authored-by: Jonghyeon Ko * remove hangulIncludes (#188) * feat: 한글의 두음을 반환해주는 acronymizeHangul 함수를 제거합니다. (#180) * remove acronymize * Create weak-walls-sniff.md --------- Co-authored-by: Jonghyeon Ko * feat: getChoseng을 utils에서 별도 함수로 분리합니다. (#192) * getChoseong분리 * write test code * getChoseong import * remove useless import statemenet * remove unused file * feat: `canBeChoseong`, `canBeJungseong`, `canBeJongseong` 을 utils에서 별도 함수로 분리합니다. (#193) * canBe series를 별도 함수로 분리합니다 * add change set * feat: `hasBatchim` 을 utils에서 별도 함수로 분리합니다. (#195) * hasBatchim * resolve type error * add change set * hasProperty, hasValueInReadOnlyStringList를 internal folder 로 옮깁니다 * resolve test error * move with test code * feat: choseongIncludes함수를 제거합니다. (#197) * remove choseongIncludes Co-authored-by: 서동휘 <8275026+suhdonghwi@users.noreply.github.com> * fix: remove 한글 * fix: amountToMoneyCurrency로 함수명 변경 * fix: amountToHangul로 함수명 수정 * fix: conflict * fix: filepath * fix: import 방식 변경 및 CHANGELOG restore * Create kind-birds-provide.md --------- Co-authored-by: 박찬혁 Co-authored-by: Jonghyeon Ko Co-authored-by: 서동휘 <8275026+suhdonghwi@users.noreply.github.com> --- .changeset/kind-birds-provide.md | 5 ++ .github/CONTRIBUTING.md | 2 +- docs/src/pages/docs/api/getChoseong.en.mdx | 8 +-- docs/src/pages/docs/api/getChoseong.ko.mdx | 6 +- docs/src/pages/docs/api/hasBatchim.en.mdx | 11 ++-- docs/src/pages/docs/api/hasBatchim.ko.mdx | 9 ++- src/_internal/hangul.spec.ts | 60 +++++++++---------- src/_internal/hangul.ts | 50 ++++++++-------- src/assemble.spec.ts | 10 ++-- src/assemble.ts | 16 ++--- ...acter.spec.ts => combineCharacter.spec.ts} | 18 +++--- ...HangulCharacter.ts => combineCharacter.ts} | 20 +++---- ...pec.ts => convertQwertyToAlphabet.spec.ts} | 20 +++---- ...Alphabet.ts => convertQwertyToAlphabet.ts} | 8 +-- src/index.ts | 9 +-- ...er.spec.ts => removeLastCharacter.spec.ts} | 38 ++++++------ src/removeLastCharacter.ts | 49 +++++++++++++++ src/removeLastHangulCharacter.ts | 24 ++++---- src/romanize.ts | 14 ++--- src/standardizePronunciation/index.ts | 8 +-- .../rules/rules.types.ts | 4 +- .../rules/transform12th.spec.ts | 28 ++++----- .../rules/transform13And14th.spec.ts | 10 ++-- .../rules/transform16th.spec.ts | 10 ++-- .../rules/transform17th.spec.ts | 10 ++-- .../rules/transform17th.ts | 2 +- .../rules/transform18th.spec.ts | 14 ++--- .../rules/transform19th.spec.ts | 10 ++-- .../rules/transform20th.spec.ts | 10 ++-- .../rules/transform9And10And11th.spec.ts | 14 ++--- .../rules/transform9And10And11th.ts | 2 +- .../rules/transformHardConversion.spec.ts | 14 ++--- .../rules/transformHardConversion.ts | 2 +- .../rules/transformNLAssimilation.spec.ts | 14 ++--- 34 files changed, 291 insertions(+), 238 deletions(-) create mode 100644 .changeset/kind-birds-provide.md rename src/{combineHangulCharacter.spec.ts => combineCharacter.spec.ts} (66%) rename src/{combineHangulCharacter.ts => combineCharacter.ts} (81%) rename src/{convertQwertyToHangulAlphabet.spec.ts => convertQwertyToAlphabet.spec.ts} (68%) rename src/{convertQwertyToHangulAlphabet.ts => convertQwertyToAlphabet.ts} (81%) rename src/{removeLastHangulCharacter.spec.ts => removeLastCharacter.spec.ts} (52%) create mode 100644 src/removeLastCharacter.ts diff --git a/.changeset/kind-birds-provide.md b/.changeset/kind-birds-provide.md new file mode 100644 index 00000000..589c9a22 --- /dev/null +++ b/.changeset/kind-birds-provide.md @@ -0,0 +1,5 @@ +--- +"es-hangul": major +--- + +fix: 일관된 한글 이름 규칙 설정 함수명에서 꼭 필요하지 않다면 hangul이라는 워딩을 제거합니다 diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 1bba496f..3a80ad0e 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -74,4 +74,4 @@ import hangul from 'es-hangul' // hangul default export에 묶어서도 제공 hangul.getSimilarity(...) hangul.disassemble(...) hangul.josa(...) - +``` diff --git a/docs/src/pages/docs/api/getChoseong.en.mdx b/docs/src/pages/docs/api/getChoseong.en.mdx index 0d479ea5..9335dc86 100644 --- a/docs/src/pages/docs/api/getChoseong.en.mdx +++ b/docs/src/pages/docs/api/getChoseong.en.mdx @@ -8,7 +8,7 @@ Extracts the Choseong from a Korean word. (Example: 사과 -> 'ㅅㄱ') ```typescript function getChoseong( - // Korean string from which to extract the choseong + // Korean string from which to extract the choseong word: string ): string; ``` @@ -16,7 +16,7 @@ function getChoseong( ## Examples ```tsx -getChoseong('사과') // 'ㅅㄱ' -getChoseong('리액트') // 'ㄹㅇㅌ' -getChoseong('띄어 쓰기') // 'ㄸㅇ ㅆㄱ' +getChoseong('사과'); // 'ㅅㄱ' +getChoseong('리액트'); // 'ㄹㅇㅌ' +getChoseong('띄어 쓰기'); // 'ㄸㅇ ㅆㄱ' ``` diff --git a/docs/src/pages/docs/api/getChoseong.ko.mdx b/docs/src/pages/docs/api/getChoseong.ko.mdx index 35fd374a..acab11d2 100644 --- a/docs/src/pages/docs/api/getChoseong.ko.mdx +++ b/docs/src/pages/docs/api/getChoseong.ko.mdx @@ -18,7 +18,7 @@ function getChoseong( ## Examples ```tsx -getChoseong('사과') // 'ㅅㄱ' -getChoseong('리액트') // 'ㄹㅇㅌ' -getChoseong('띄어 쓰기') // 'ㄸㅇ ㅆㄱ' +getChoseong('사과'); // 'ㅅㄱ' +getChoseong('리액트'); // 'ㄹㅇㅌ' +getChoseong('띄어 쓰기'); // 'ㄸㅇ ㅆㄱ' ``` diff --git a/docs/src/pages/docs/api/hasBatchim.en.mdx b/docs/src/pages/docs/api/hasBatchim.en.mdx index 4e1c22c8..b5fe9e55 100644 --- a/docs/src/pages/docs/api/hasBatchim.en.mdx +++ b/docs/src/pages/docs/api/hasBatchim.en.mdx @@ -3,20 +3,21 @@ title: hasBatchim --- # hasBatchim + Checks if the last character of a Korean string has a batchim (jongseong). -```typescript +````typescript hasBatchim( - str: string, - // checking for single batchim + str: string, + // checking for single batchim options?: { single?: boolean } ): boolean - + ```typescript hasBatchim('값') // true hasBatchim('토') // false hasBatchim('갑', { single: true }) // true hasBatchim('값', { single: true }) // false hasBatchim('토', { single: true }) // false - ```` +```` diff --git a/docs/src/pages/docs/api/hasBatchim.ko.mdx b/docs/src/pages/docs/api/hasBatchim.ko.mdx index 73cf58c5..73eac438 100644 --- a/docs/src/pages/docs/api/hasBatchim.ko.mdx +++ b/docs/src/pages/docs/api/hasBatchim.ko.mdx @@ -6,19 +6,18 @@ title: hasBatchim 한글 문자열의 마지막 글자가 받침이 있는지 확인합니다. - -```typescript +````typescript hasBatchim( - str: string, + str: string, // 홑받침 여부를 확인할지 여부 options?: { single?: boolean } ): boolean - + ```typescript hasBatchim('값') // true hasBatchim('토') // false hasBatchim('갑', { single: true }) // true hasBatchim('값', { single: true }) // false hasBatchim('토', { single: true }) // false - ```` +```` diff --git a/src/_internal/hangul.spec.ts b/src/_internal/hangul.spec.ts index 684f9272..a2ce1c9f 100644 --- a/src/_internal/hangul.spec.ts +++ b/src/_internal/hangul.spec.ts @@ -1,6 +1,6 @@ import { - binaryAssembleHangulCharacters, - binaryAssembleHangul, + binaryAssembleCharacters, + binaryAssemble, isHangulAlphabet, isHangulCharacter, isHangul, @@ -72,102 +72,102 @@ describe('parse', () => { }); }); -describe('binaryAssembleHangulCharacters', () => { +describe('binaryAssembleCharacters', () => { it('초성과 중성만 조합', () => { - expect(binaryAssembleHangulCharacters('ㄱ', 'ㅏ')).toEqual('가'); + expect(binaryAssembleCharacters('ㄱ', 'ㅏ')).toEqual('가'); }); it('초성과 중성이 합쳐진 문자와 종성을 조합', () => { - expect(binaryAssembleHangulCharacters('가', 'ㅇ')).toEqual('강'); + expect(binaryAssembleCharacters('가', 'ㅇ')).toEqual('강'); }); it('초성과 중성과 종성이 합쳐진 문자와 자음을 조합하여 겹받침 만들기', () => { - expect(binaryAssembleHangulCharacters('갑', 'ㅅ')).toEqual('값'); + expect(binaryAssembleCharacters('갑', 'ㅅ')).toEqual('값'); }); it('초성과 중성이 합쳐진 문자와 모음을 조립하여 겹모음 만들기', () => { - expect(binaryAssembleHangulCharacters('고', 'ㅏ')).toEqual('과'); + expect(binaryAssembleCharacters('고', 'ㅏ')).toEqual('과'); }); it('초성과 중성(겹모음)이 합쳐진 문자와 자음을 조합', () => { - expect(binaryAssembleHangulCharacters('과', 'ㄱ')).toEqual('곽'); + expect(binaryAssembleCharacters('과', 'ㄱ')).toEqual('곽'); }); it('초성과 중성(겹모음)과 종성이 합쳐진 문자와 자음을 조합하여 겹받침 만들기', () => { - expect(binaryAssembleHangulCharacters('완', 'ㅈ')).toEqual('왅'); + expect(binaryAssembleCharacters('완', 'ㅈ')).toEqual('왅'); }); it('모음만 있는 문자와 모음을 조합하여 겹모음 만들기', () => { - expect(binaryAssembleHangulCharacters('ㅗ', 'ㅏ')).toEqual('ㅘ'); + expect(binaryAssembleCharacters('ㅗ', 'ㅏ')).toEqual('ㅘ'); }); it('초성과 중성과 종성이 합쳐진 문자의 연음 법칙', () => { - expect(binaryAssembleHangulCharacters('톳', 'ㅡ')).toEqual('토스'); + expect(binaryAssembleCharacters('톳', 'ㅡ')).toEqual('토스'); }); it('초성과 종성(겹모음)과 종성이 합쳐진 문자의 연음 법칙', () => { - expect(binaryAssembleHangulCharacters('왅', 'ㅓ')).toEqual('완저'); + expect(binaryAssembleCharacters('왅', 'ㅓ')).toEqual('완저'); }); it('초성과 중성과 종성(겹받침)이 합쳐진 문자의 연음 법칙', () => { - expect(binaryAssembleHangulCharacters('닭', 'ㅏ')).toEqual('달가'); - expect(binaryAssembleHangulCharacters('깎', 'ㅏ')).toEqual('까까'); + expect(binaryAssembleCharacters('닭', 'ㅏ')).toEqual('달가'); + expect(binaryAssembleCharacters('깎', 'ㅏ')).toEqual('까까'); }); it('문법에 맞지 않는 문자를 조합하면 단순 Join 한다. (문법 순서 틀림)', () => { - expect(binaryAssembleHangulCharacters('ㅏ', 'ㄱ')).toEqual('ㅏㄱ'); - expect(binaryAssembleHangulCharacters('까', 'ㅃ')).toEqual('까ㅃ'); - expect(binaryAssembleHangulCharacters('ㅘ', 'ㅏ')).toEqual('ㅘㅏ'); + expect(binaryAssembleCharacters('ㅏ', 'ㄱ')).toEqual('ㅏㄱ'); + expect(binaryAssembleCharacters('까', 'ㅃ')).toEqual('까ㅃ'); + expect(binaryAssembleCharacters('ㅘ', 'ㅏ')).toEqual('ㅘㅏ'); }); it('순서대로 입력했을 때 조합이 불가능한 문자라면 단순 Join 한다.', () => { - expect(binaryAssembleHangulCharacters('뼈', 'ㅣ')).toEqual('뼈ㅣ'); + expect(binaryAssembleCharacters('뼈', 'ㅣ')).toEqual('뼈ㅣ'); }); it('소스가 두 글자 이상이라면 Invalid source 에러를 발생시킨다.', () => { - expect(() => binaryAssembleHangulCharacters('가나', 'ㄴ')).toThrowError( + expect(() => binaryAssembleCharacters('가나', 'ㄴ')).toThrowError( 'Invalid source character: 가나. Source must be one character.' ); - expect(() => binaryAssembleHangulCharacters('ㄱㄴ', 'ㅏ')).toThrowError( + expect(() => binaryAssembleCharacters('ㄱㄴ', 'ㅏ')).toThrowError( 'Invalid source character: ㄱㄴ. Source must be one character.' ); }); it('다음 문자가 한글 문자 한 글자가 아니라면 Invalid next character 에러를 발생시킨다.', () => { assert.throws( - () => binaryAssembleHangulCharacters('ㄱ', 'a'), + () => binaryAssembleCharacters('ㄱ', 'a'), Error, 'Invalid next character: a. Next character must be one of the choseong, jungseong, or jongseong.' ); assert.throws( - () => binaryAssembleHangulCharacters('ㄱ', 'ㅡㅏ'), + () => binaryAssembleCharacters('ㄱ', 'ㅡㅏ'), Error, 'Invalid next character: ㅡㅏ. Next character must be one of the choseong, jungseong, or jongseong.' ); }); }); -describe('binaryAssembleHangul', () => { +describe('binaryAssemble', () => { it('문장과 모음을 조합하여 다음 글자를 생성한다.', () => { - expect(binaryAssembleHangul('저는 고양이를 좋아합닏', 'ㅏ')).toEqual('저는 고양이를 좋아합니다'); + expect(binaryAssemble('저는 고양이를 좋아합닏', 'ㅏ')).toEqual('저는 고양이를 좋아합니다'); }); it('문장과 자음을 조합하여 홑받침을 생성한다.', () => { - expect(binaryAssembleHangul('저는 고양이를 좋아하', 'ㅂ')).toEqual('저는 고양이를 좋아합'); + expect(binaryAssemble('저는 고양이를 좋아하', 'ㅂ')).toEqual('저는 고양이를 좋아합'); }); it('문장과 자음을 조합하여 겹받침을 생성한다.', () => { - expect(binaryAssembleHangul('저는 고양이를 좋아합', 'ㅅ')).toEqual('저는 고양이를 좋아핪'); + expect(binaryAssemble('저는 고양이를 좋아합', 'ㅅ')).toEqual('저는 고양이를 좋아핪'); }); it('조합이 불가능한 자음이 입력되면 단순 Join 한다.', () => { - expect(binaryAssembleHangul('저는 고양이를 좋아합', 'ㄲ')).toEqual('저는 고양이를 좋아합ㄲ'); - expect(binaryAssembleHangul('저는 고양이를 좋아합', 'ㅂ')).toEqual('저는 고양이를 좋아합ㅂ'); + expect(binaryAssemble('저는 고양이를 좋아합', 'ㄲ')).toEqual('저는 고양이를 좋아합ㄲ'); + expect(binaryAssemble('저는 고양이를 좋아합', 'ㅂ')).toEqual('저는 고양이를 좋아합ㅂ'); }); it('조합이 불가능한 모음이 입력되면 단순 Join 한다.', () => { - expect(binaryAssembleHangul('저는 고양이를 좋아하', 'ㅏ')).toEqual('저는 고양이를 좋아하ㅏ'); - expect(binaryAssembleHangul('저는 고양이를 좋아합니다', 'ㅜ')).toEqual('저는 고양이를 좋아합니다ㅜ'); + expect(binaryAssemble('저는 고양이를 좋아하', 'ㅏ')).toEqual('저는 고양이를 좋아하ㅏ'); + expect(binaryAssemble('저는 고양이를 좋아합니다', 'ㅜ')).toEqual('저는 고양이를 좋아합니다ㅜ'); }); describe('assertHangul', () => { diff --git a/src/_internal/hangul.ts b/src/_internal/hangul.ts index 5d2c5a7e..00601a21 100644 --- a/src/_internal/hangul.ts +++ b/src/_internal/hangul.ts @@ -1,9 +1,9 @@ import assert, { excludeLastElement, isBlank, joinString } from '.'; import { canBeChoseong, canBeJungseong, canBeJongseong } from '../canBe'; -import { combineHangulCharacter, combineVowels, curriedCombineHangulCharacter } from '../combineHangulCharacter'; +import { combineCharacter, combineVowels, curriedCombineCharacter } from '../combineCharacter'; import { disassembleToGroups } from '../disassemble'; import { hasBatchim } from '../hasBatchim'; -import { removeLastHangulCharacter } from '../removeLastHangulCharacter'; +import { removeLastCharacter } from '../removeLastCharacter'; export function isHangulCharacter(character: string) { return /^[가-힣]$/.test(character); @@ -48,23 +48,23 @@ export function safeParseHangul(actual: unknown): SafeParseSuccess | SafeParseEr } /** - * @name binaryAssembleHangulAlphabets + * @name binaryAssembleAlphabets * @description * 두 개의 한글 자모를 합칩니다. 완성된 한글 문자는 취급하지 않습니다. * @example * ``` - * binaryAssembleHangulAlphabets('ㄱ', 'ㅏ') // 가 - * binaryAssembleHangulAlphabets('ㅗ', 'ㅏ') // ㅘ + * binaryAssembleAlphabets('ㄱ', 'ㅏ') // 가 + * binaryAssembleAlphabets('ㅗ', 'ㅏ') // ㅘ * ``` */ -export function binaryAssembleHangulAlphabets(source: string, nextCharacter: string) { +export function binaryAssembleAlphabets(source: string, nextCharacter: string) { if (canBeJungseong(`${source}${nextCharacter}`)) { return combineVowels(source, nextCharacter); } const isConsonantSource = canBeJungseong(source) === false; if (isConsonantSource && canBeJungseong(nextCharacter)) { - return combineHangulCharacter(source, nextCharacter); + return combineCharacter(source, nextCharacter); } return joinString(source, nextCharacter); @@ -79,15 +79,15 @@ export function linkHangulCharacters(source: string, nextCharacter: string) { const sourceJamo = disassembleToGroups(source)[0]; const [, lastJamo] = excludeLastElement(sourceJamo); - return joinString(removeLastHangulCharacter(source), combineHangulCharacter(lastJamo, nextCharacter)); + return joinString(removeLastCharacter(source), combineCharacter(lastJamo, nextCharacter)); } /** - * @name binaryAssembleHangulCharacters + * @name binaryAssembleCharacters * @description * 인자로 받은 한글 문자 2개를 합성합니다. * ```typescript - * binaryAssembleHangulCharacters( + * binaryAssembleCharacters( * // 소스 문자 * source: string * // 다음 문자 @@ -95,12 +95,12 @@ export function linkHangulCharacters(source: string, nextCharacter: string) { * ): string * ``` * @example - * binaryAssembleHangulCharacters('ㄱ', 'ㅏ') // 가 - * binaryAssembleHangulCharacters('가', 'ㅇ') // 강 - * binaryAssembleHangulCharacters('갑', 'ㅅ') // 값 - * binaryAssembleHangulCharacters('깎', 'ㅏ') // 까까 + * binaryAssembleCharacters('ㄱ', 'ㅏ') // 가 + * binaryAssembleCharacters('가', 'ㅇ') // 강 + * binaryAssembleCharacters('갑', 'ㅅ') // 값 + * binaryAssembleCharacters('깎', 'ㅏ') // 까까 */ -export function binaryAssembleHangulCharacters(source: string, nextCharacter: string) { +export function binaryAssembleCharacters(source: string, nextCharacter: string) { assert( isHangulCharacter(source) || isHangulAlphabet(source), `Invalid source character: ${source}. Source must be one character.` @@ -115,7 +115,7 @@ export function binaryAssembleHangulCharacters(source: string, nextCharacter: st const isSingleCharacter = sourceJamos.length === 1; if (isSingleCharacter) { const sourceCharacter = sourceJamos[0]; - return binaryAssembleHangulAlphabets(sourceCharacter, nextCharacter); + return binaryAssembleAlphabets(sourceCharacter, nextCharacter); } const [restJamos, lastJamo] = excludeLastElement(sourceJamos); @@ -126,7 +126,7 @@ export function binaryAssembleHangulCharacters(source: string, nextCharacter: st return linkHangulCharacters(source, nextCharacter); } - const fixConsonant = curriedCombineHangulCharacter; + const fixConsonant = curriedCombineCharacter; const combineJungseong = fixConsonant(restJamos[0]); if (canBeJungseong(`${lastJamo}${nextCharacter}`)) { @@ -162,11 +162,11 @@ export function binaryAssembleHangulCharacters(source: string, nextCharacter: st } /** - * @name binaryAssembleHangul + * @name binaryAssemble * @description * 인자로 받은 한글 문장과 한글 문자 하나를 합성합니다. * ```typescript - * binaryAssembleHangul( + * binaryAssemble( * // 한글 문장 * source: string * // 한글 문자 @@ -174,18 +174,16 @@ export function binaryAssembleHangulCharacters(source: string, nextCharacter: st * ): string * ``` * @example - * binaryAssembleHangul('저는 고양이를 좋아합닏', 'ㅏ') // 저는 고양이를 좋아합니다 - * binaryAssembleHangul('저는 고양이를 좋아합', 'ㅅ') // 저는 고양이를 좋아핪 - * binaryAssembleHangul('저는 고양이를 좋아하', 'ㅏ') // 저는 고양이를 좋아하ㅏ + * binaryAssemble('저는 고양이를 좋아합닏', 'ㅏ') // 저는 고양이를 좋아합니다 + * binaryAssemble('저는 고양이를 좋아합', 'ㅅ') // 저는 고양이를 좋아핪 + * binaryAssemble('저는 고양이를 좋아하', 'ㅏ') // 저는 고양이를 좋아하ㅏ */ -export function binaryAssembleHangul(source: string, nextCharacter: string) { +export function binaryAssemble(source: string, nextCharacter: string) { const [rest, lastCharacter] = excludeLastElement(source.split('')); const needJoinString = isBlank(lastCharacter) || isBlank(nextCharacter); return joinString( ...rest, - needJoinString - ? joinString(lastCharacter, nextCharacter) - : binaryAssembleHangulCharacters(lastCharacter, nextCharacter) + needJoinString ? joinString(lastCharacter, nextCharacter) : binaryAssembleCharacters(lastCharacter, nextCharacter) ); } diff --git a/src/assemble.spec.ts b/src/assemble.spec.ts index 831a698b..2c4448c5 100644 --- a/src/assemble.spec.ts +++ b/src/assemble.spec.ts @@ -1,13 +1,13 @@ -import { assembleHangul } from './assemble'; +import { assemble } from './assemble'; -describe('assembleHangul', () => { +describe('assemble', () => { it('온전한 한글과 한글 문자 조합', () => { - expect(assembleHangul(['아버지가', ' ', '방ㅇ', 'ㅔ ', '들ㅇ', 'ㅓ갑니다'])).toEqual('아버지가 방에 들어갑니다'); + expect(assemble(['아버지가', ' ', '방ㅇ', 'ㅔ ', '들ㅇ', 'ㅓ갑니다'])).toEqual('아버지가 방에 들어갑니다'); }); it('온전한 한글만 조합', () => { - expect(assembleHangul(['아버지가', ' ', '방에 ', '들어갑니다'])).toEqual('아버지가 방에 들어갑니다'); + expect(assemble(['아버지가', ' ', '방에 ', '들어갑니다'])).toEqual('아버지가 방에 들어갑니다'); }); it('온전하지 않은 한글만 조합', () => { - expect(assembleHangul(['ㅇ', 'ㅏ', 'ㅂ', 'ㅓ', 'ㅈ', 'ㅣ'])).toEqual('아버지'); + expect(assemble(['ㅇ', 'ㅏ', 'ㅂ', 'ㅓ', 'ㅈ', 'ㅣ'])).toEqual('아버지'); }); }); diff --git a/src/assemble.ts b/src/assemble.ts index 554fa8ea..66ebbf06 100644 --- a/src/assemble.ts +++ b/src/assemble.ts @@ -1,22 +1,22 @@ import { disassemble } from './disassemble'; -import { binaryAssembleHangul } from './_internal/hangul'; +import { binaryAssemble } from './_internal/hangul'; /** - * @name assembleHangul + * @name assemble * @description * 인자로 받은 배열에 담긴 한글 문장과 문자를 한글 규칙에 맞게 합성합니다. * ```typescript - * assembleHangul( + * assemble( * // 한글 문자와 문장을 담고 있는 배열 * words: string[] * ): string * ``` * @example - * assembleHangul(['아버지가', ' ', '방ㅇ', 'ㅔ ', '들ㅇ', 'ㅓ갑니다']) // 아버지가 방에 들어갑니다 - * assembleHangul(['아버지가', ' ', '방에 ', '들어갑니다']) // 아버지가 방에 들어갑니다 - * assembleHangul(['ㅇ', 'ㅏ', 'ㅂ', 'ㅓ', 'ㅈ', 'ㅣ']) // 아버지 + * assemble(['아버지가', ' ', '방ㅇ', 'ㅔ ', '들ㅇ', 'ㅓ갑니다']) // 아버지가 방에 들어갑니다 + * assemble(['아버지가', ' ', '방에 ', '들어갑니다']) // 아버지가 방에 들어갑니다 + * assemble(['ㅇ', 'ㅏ', 'ㅂ', 'ㅓ', 'ㅈ', 'ㅣ']) // 아버지 */ -export function assembleHangul(words: string[]) { +export function assemble(words: string[]) { const disassembled = disassemble(words.join('')).split(''); - return disassembled.reduce(binaryAssembleHangul); + return disassembled.reduce(binaryAssemble); } diff --git a/src/combineHangulCharacter.spec.ts b/src/combineCharacter.spec.ts similarity index 66% rename from src/combineHangulCharacter.spec.ts rename to src/combineCharacter.spec.ts index 5bd0845c..1e7e4f24 100644 --- a/src/combineHangulCharacter.spec.ts +++ b/src/combineCharacter.spec.ts @@ -1,32 +1,32 @@ -import { combineHangulCharacter, combineVowels } from './combineHangulCharacter'; +import { combineCharacter, combineVowels } from './combineCharacter'; -describe('combineHangulCharacter', () => { +describe('combineCharacter', () => { it('종성으로 겹받침으로 구성될 수 있는 문자 두 개를 받으면 겹받침을 생성한다. (ㄱ, ㅏ, ㅂㅅ)', () => { - expect(combineHangulCharacter('ㄱ', 'ㅏ', 'ㅂㅅ')).toEqual('값'); + expect(combineCharacter('ㄱ', 'ㅏ', 'ㅂㅅ')).toEqual('값'); }); it('종성이 입력되지 않았다면 받침이 없는 문자로 합성한다. (ㅌ, ㅗ)', () => { - expect(combineHangulCharacter('ㅌ', 'ㅗ')).toEqual('토'); + expect(combineCharacter('ㅌ', 'ㅗ')).toEqual('토'); }); it('종성이 입력되었다면 받침을 추가한다. (ㅌ, ㅗ, ㅅ)', () => { - expect(combineHangulCharacter('ㅌ', 'ㅗ', 'ㅅ')).toEqual('톳'); + expect(combineCharacter('ㅌ', 'ㅗ', 'ㅅ')).toEqual('톳'); }); it('초성이 될 수 없는 문자가 초성으로 입력되면 에러를 반환한다. (ㅏ, ㅏ, ㄱ)', () => { - expect(() => combineHangulCharacter('ㅏ', 'ㅏ', 'ㄱ')).toThrowError('Invalid hangul Characters: ㅏ, ㅏ, ㄱ'); + expect(() => combineCharacter('ㅏ', 'ㅏ', 'ㄱ')).toThrowError('Invalid hangul Characters: ㅏ, ㅏ, ㄱ'); }); it('중성이 될 수 없는 문자가 중성으로 입력되면 에러를 반환한다. (ㄱ, ㄴ, ㅃ)', () => { - expect(() => combineHangulCharacter('ㄱ', 'ㄴ', 'ㅃ')).toThrowError('Invalid hangul Characters: ㄱ, ㄴ, ㅃ'); + expect(() => combineCharacter('ㄱ', 'ㄴ', 'ㅃ')).toThrowError('Invalid hangul Characters: ㄱ, ㄴ, ㅃ'); }); it('종성이 될 수 없는 문자가 종성으로 입력되면 에러를 반환한다. (ㄱ, ㅏ, ㅃ)', () => { - expect(() => combineHangulCharacter('ㄱ', 'ㅏ', 'ㅃ')).toThrowError('Invalid hangul Characters: ㄱ, ㅏ, ㅃ'); + expect(() => combineCharacter('ㄱ', 'ㅏ', 'ㅃ')).toThrowError('Invalid hangul Characters: ㄱ, ㅏ, ㅃ'); }); it('온전한 한글 문자가 하나라도 입력되면 에러를 반환한다. (가, ㅏ, ㄱ)', () => { - expect(() => combineHangulCharacter('가', 'ㅏ', 'ㄱ')).toThrowError('Invalid hangul Characters: 가, ㅏ, ㄱ'); + expect(() => combineCharacter('가', 'ㅏ', 'ㄱ')).toThrowError('Invalid hangul Characters: 가, ㅏ, ㄱ'); }); }); diff --git a/src/combineHangulCharacter.ts b/src/combineCharacter.ts similarity index 81% rename from src/combineHangulCharacter.ts rename to src/combineCharacter.ts index 79e890c3..762d8145 100644 --- a/src/combineHangulCharacter.ts +++ b/src/combineCharacter.ts @@ -8,11 +8,11 @@ import { } from './constants'; /** - * @name combineHangulCharacter + * @name combineCharacter * @description * 인자로 초성, 중성, 종성을 받아 하나의 한글 문자를 반환합니다. * ```typescript - * combineHangulCharacter( + * combineCharacter( * // 초성 * firstCharacter: string * // 중성 @@ -22,10 +22,10 @@ import { * ): string * ``` * @example - * combineHangulCharacter('ㄱ', 'ㅏ', 'ㅂㅅ') // '값' - * combineHangulCharacter('ㅌ', 'ㅗ') // '토' + * combineCharacter('ㄱ', 'ㅏ', 'ㅂㅅ') // '값' + * combineCharacter('ㅌ', 'ㅗ') // '토' */ -export function combineHangulCharacter(firstCharacter: string, middleCharacter: string, lastCharacter = '') { +export function combineCharacter(firstCharacter: string, middleCharacter: string, lastCharacter = '') { if ( canBeChoseong(firstCharacter) === false || canBeJungseong(middleCharacter) === false || @@ -51,19 +51,19 @@ export function combineHangulCharacter(firstCharacter: string, middleCharacter: } /** - * @name curriedCombineHangulCharacter + * @name curriedCombineCharacter * @description - * 인자로 초성, 중성, 종성을 받아 하나의 한글 문자를 반환하는 `combineHangulCharacter` 함수의 커링된 버전입니다. + * 인자로 초성, 중성, 종성을 받아 하나의 한글 문자를 반환하는 `combineCharacter` 함수의 커링된 버전입니다. * @example - * const combineMiddleHangulCharacter = curriedCombineHangulCharacter('ㄱ') + * const combineMiddleHangulCharacter = curriedCombineCharacter('ㄱ') * const combineLastHangulCharacter = combineMiddleHangulCharacter('ㅏ') * combineLastHangulCharacter('ㄱ') // '각' */ -export const curriedCombineHangulCharacter = +export const curriedCombineCharacter = (firstCharacter: string) => (middleCharacter: string) => (lastCharacter = '') => - combineHangulCharacter(firstCharacter, middleCharacter, lastCharacter); + combineCharacter(firstCharacter, middleCharacter, lastCharacter); /** * @name combineVowels diff --git a/src/convertQwertyToHangulAlphabet.spec.ts b/src/convertQwertyToAlphabet.spec.ts similarity index 68% rename from src/convertQwertyToHangulAlphabet.spec.ts rename to src/convertQwertyToAlphabet.spec.ts index 0130e75f..07e1cf2d 100644 --- a/src/convertQwertyToHangulAlphabet.spec.ts +++ b/src/convertQwertyToAlphabet.spec.ts @@ -1,33 +1,33 @@ -import { convertQwertyToHangul, convertQwertyToHangulAlphabet } from './convertQwertyToHangulAlphabet'; +import { convertQwertyToHangul, convertQwertyToAlphabet } from './convertQwertyToAlphabet'; -describe('convertQwertyToHangulAlphabet', () => { +describe('convertQwertyToAlphabet', () => { it('영어 알파벳을 한글 음소로 바꾼다.', () => { - expect(convertQwertyToHangulAlphabet('abc')).toBe('ㅁㅠㅊ'); + expect(convertQwertyToAlphabet('abc')).toBe('ㅁㅠㅊ'); }); it('쌍/자모음에 대응하지 않는 영어 알파벳을 한글 음소로 바꾼다.', () => { - expect(convertQwertyToHangulAlphabet('ABC')).toBe('ㅁㅠㅊ'); + expect(convertQwertyToAlphabet('ABC')).toBe('ㅁㅠㅊ'); }); it('영어 알파벳은 한글 음소로 바꾸고, 한글 음절은 유지한다.', () => { - expect(convertQwertyToHangulAlphabet('vm론트')).toBe('ㅍㅡ론트'); + expect(convertQwertyToAlphabet('vm론트')).toBe('ㅍㅡ론트'); }); it('분해된 한글 음소는 유지한다.', () => { - expect(convertQwertyToHangulAlphabet('ㅍㅡㄹㅗㄴㅌㅡ')).toBe('ㅍㅡㄹㅗㄴㅌㅡ'); + expect(convertQwertyToAlphabet('ㅍㅡㄹㅗㄴㅌㅡ')).toBe('ㅍㅡㄹㅗㄴㅌㅡ'); }); it('영어 알파벳이 아닌 입력은 유지한다.', () => { - expect(convertQwertyToHangulAlphabet('4월/20dlf!')).toBe('4월/20ㅇㅣㄹ!'); + expect(convertQwertyToAlphabet('4월/20dlf!')).toBe('4월/20ㅇㅣㄹ!'); }); it('영문 대문자는 쌍자/모음으로 바꾼다.', () => { - expect(convertQwertyToHangulAlphabet('RㅏㄱEㅜrl')).toBe('ㄲㅏㄱㄸㅜㄱㅣ'); - expect(convertQwertyToHangulAlphabet('ㅇPdml')).toBe('ㅇㅖㅇㅡㅣ'); + expect(convertQwertyToAlphabet('RㅏㄱEㅜrl')).toBe('ㄲㅏㄱㄸㅜㄱㅣ'); + expect(convertQwertyToAlphabet('ㅇPdml')).toBe('ㅇㅖㅇㅡㅣ'); }); it('빈 문자열은 빈 문자열을 반환한다.', () => { - expect(convertQwertyToHangulAlphabet('')).toBe(''); + expect(convertQwertyToAlphabet('')).toBe(''); }); }); diff --git a/src/convertQwertyToHangulAlphabet.ts b/src/convertQwertyToAlphabet.ts similarity index 81% rename from src/convertQwertyToHangulAlphabet.ts rename to src/convertQwertyToAlphabet.ts index e57af259..b4c1ae3f 100644 --- a/src/convertQwertyToHangulAlphabet.ts +++ b/src/convertQwertyToAlphabet.ts @@ -1,15 +1,15 @@ import { hasProperty } from './_internal'; -import { assembleHangul } from './assemble'; +import { assemble } from './assemble'; import { QWERTY_KEYBOARD_MAP } from './constants'; /** - * @name convertQwertyToHangulAlphabet + * @name convertQwertyToAlphabet * @description * 영어 알파벳을 qwerty 자판과 매칭되는 한글 음소로 변환합니다. * @param word 한글 음소로 변환하고자 하는 영문 * @returns 영어 알파벳이 포함되지 않은 한글 음소, 음절, 기타 문자로 이루어진 문자열 */ -export function convertQwertyToHangulAlphabet(word: string): string { +export function convertQwertyToAlphabet(word: string): string { return word .split('') .map(inputText => (hasProperty(QWERTY_KEYBOARD_MAP, inputText) ? QWERTY_KEYBOARD_MAP[inputText] : inputText)) @@ -27,5 +27,5 @@ export function convertQwertyToHangul(word: string): string { if (!word) { return ''; } - return assembleHangul([...convertQwertyToHangulAlphabet(word)]); + return assemble([...convertQwertyToAlphabet(word)]); } diff --git a/src/index.ts b/src/index.ts index 37c1ebad..44ab09b2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,14 @@ -export { assembleHangul } from './assemble'; -export { combineHangulCharacter, combineVowels } from './combineHangulCharacter'; -export { convertQwertyToHangul, convertQwertyToHangulAlphabet } from './convertQwertyToHangulAlphabet'; +export { assemble } from './assemble'; +export { combineCharacter, combineVowels } from './combineCharacter'; +export { convertQwertyToHangul, convertQwertyToAlphabet } from './convertQwertyToAlphabet'; export { disassemble, disassembleToGroups } from './disassemble'; export { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; export { josa } from './josa'; -export { removeLastHangulCharacter } from './removeLastHangulCharacter'; +export { removeLastCharacter } from './removeLastCharacter'; export { romanize } from './romanize'; export { standardizePronunciation } from './standardizePronunciation'; export { susa } from './susa'; export { hasBatchim } from './hasBatchim'; export { canBeChoseong, canBeJongseong, canBeJungseong } from './canBe'; export { getChoseong } from './getChoseong'; +export { amountToHangul } from './amountToHangul'; diff --git a/src/removeLastHangulCharacter.spec.ts b/src/removeLastCharacter.spec.ts similarity index 52% rename from src/removeLastHangulCharacter.spec.ts rename to src/removeLastCharacter.spec.ts index 49e74fb9..ded3c260 100644 --- a/src/removeLastHangulCharacter.spec.ts +++ b/src/removeLastCharacter.spec.ts @@ -1,37 +1,37 @@ -import { removeLastHangulCharacter } from './removeLastHangulCharacter'; +import { removeLastCharacter } from './removeLastCharacter'; -describe('removeLastHangulCharacter', () => { +describe('removeLastCharacter', () => { it('마지막 문자가 겹받침인 경우 홑받침으로 바꾼다.', () => { - expect(removeLastHangulCharacter('안녕하세요 값')).toBe('안녕하세요 갑'); - expect(removeLastHangulCharacter('안녕하세요 값이')).toBe('안녕하세요 값ㅇ'); + expect(removeLastCharacter('안녕하세요 값')).toBe('안녕하세요 갑'); + expect(removeLastCharacter('안녕하세요 값이')).toBe('안녕하세요 값ㅇ'); }); it('마지막 문자가 초성과 중성의 조합으로 끝날 경우 초성만 남긴다.', () => { - expect(removeLastHangulCharacter('프론트엔드')).toBe('프론트엔ㄷ'); - expect(removeLastHangulCharacter('끓다')).toBe('끓ㄷ'); - expect(removeLastHangulCharacter('관사')).toBe('관ㅅ'); - expect(removeLastHangulCharacter('괴사')).toBe('괴ㅅ'); + expect(removeLastCharacter('프론트엔드')).toBe('프론트엔ㄷ'); + expect(removeLastCharacter('끓다')).toBe('끓ㄷ'); + expect(removeLastCharacter('관사')).toBe('관ㅅ'); + expect(removeLastCharacter('괴사')).toBe('괴ㅅ'); }); it('마지막 문자가 초성과 중성과 종성의 조합으로 끝날 경우 초성과 중성이 조합된 문자만 남긴다.', () => { - expect(removeLastHangulCharacter('일요일')).toBe('일요이'); - expect(removeLastHangulCharacter('완전')).toBe('완저'); - expect(removeLastHangulCharacter('왅전')).toBe('왅저'); - expect(removeLastHangulCharacter('깎')).toBe('까'); + expect(removeLastCharacter('일요일')).toBe('일요이'); + expect(removeLastCharacter('완전')).toBe('완저'); + expect(removeLastCharacter('왅전')).toBe('왅저'); + expect(removeLastCharacter('깎')).toBe('까'); }); it('마지막 문자가 초성과 중성의 조합으로 끝나며, 중성 입력 시 국제 표준 한글 레이아웃 기준 단일키로 처리되지 않는 이중모음 (ㅗ/ㅜ/ㅡ 계 이중모음) 인 경우 초성과 중성의 시작 모음만 남긴다.', () => { - expect(removeLastHangulCharacter('전화')).toBe('전호'); - expect(removeLastHangulCharacter('예의')).toBe('예으'); - expect(removeLastHangulCharacter('신세계')).toBe('신세ㄱ'); // 'ㅖ'의 경우 단일키 처리가 가능한 이중모음이므로 모음이 남지 않는다. + expect(removeLastCharacter('전화')).toBe('전호'); + expect(removeLastCharacter('예의')).toBe('예으'); + expect(removeLastCharacter('신세계')).toBe('신세ㄱ'); // 'ㅖ'의 경우 단일키 처리가 가능한 이중모음이므로 모음이 남지 않는다. }); it('마지막 문자가 초성과 중성과 종성의 조합으로 끝나며, 중성 입력 시 국제 표준 한글 레이아웃 기준 단일키로 처리되지 않는 이중모음 (ㅗ/ㅜ/ㅡ 계 이중모음) 인 경우 초성과 중성만 남긴다.', () => { - expect(removeLastHangulCharacter('수확')).toBe('수화'); + expect(removeLastCharacter('수확')).toBe('수화'); }); it('마지막 문자가 초성과 중성과 종성의 조합으로 끝나며, 종성이 겹자음인 경우 초성과 중성과 종성의 시작 자음만 남긴다.', () => { - expect(removeLastHangulCharacter('끓')).toBe('끌'); + expect(removeLastCharacter('끓')).toBe('끌'); }); it('마지막 문자가 초성과 중성과 종성의 조합으로 끝나며, 중성 입력 시 국제 표준 한글 레이아웃 기준 단일키로 처리되지 않는 이중모음 (ㅗ/ㅜ/ㅡ 계 이중모음)이고 종성이 겹자음인 경우 초성과 중성과 종성의 시작 자음만 남긴다.', () => { - expect(removeLastHangulCharacter('왅')).toBe('완'); + expect(removeLastCharacter('왅')).toBe('완'); }); it('빈 문자열일 경우 빈 문자열을 반환한다.', () => { - expect(removeLastHangulCharacter('')).toBe(''); + expect(removeLastCharacter('')).toBe(''); }); }); diff --git a/src/removeLastCharacter.ts b/src/removeLastCharacter.ts new file mode 100644 index 00000000..0aed34fe --- /dev/null +++ b/src/removeLastCharacter.ts @@ -0,0 +1,49 @@ +import { combineCharacter } from './combineCharacter'; +import { excludeLastElement } from './_internal'; +import { canBeJungseong } from './canBe'; +import { disassembleToGroups } from './disassemble'; + +/** + * @name removeLastCharacter + * @description + * 인자로 주어진 한글 문자열에서 가장 마지막 문자 하나를 제거하여 반환합니다. + * ```typescript + * removeLastCharacter( + * // 한글 문자열 + * words: string + * ): string + * ``` + * @example + * removeLastCharacter('안녕하세요 값') // 안녕하세요 갑 + * removeLastCharacter('프론트엔드') // 프론트엔ㄷ + * removeLastCharacter('일요일') // 일요이 + * removeLastCharacter('전화') // 전호 + * removeLastCharacter('신세계') // 신세ㄱ + */ +export function removeLastCharacter(words: string) { + const lastCharacter = words[words.length - 1]; + if (lastCharacter == null) { + return ''; + } + + const result = (() => { + const disassembleLastCharacter = disassembleToGroups(lastCharacter); + const [lastCharacterWithoutLastAlphabet] = excludeLastElement(disassembleLastCharacter[0]); + if (lastCharacterWithoutLastAlphabet.length <= 3) { + const [first, middle, last] = lastCharacterWithoutLastAlphabet; + if (middle != null) { + return canBeJungseong(last) + ? combineCharacter(first, `${middle}${last}`) + : combineCharacter(first, middle, last); + } + + return first; + } else { + const [first, firstJungsung, secondJungsung, firstJongsung] = lastCharacterWithoutLastAlphabet; + + return combineCharacter(first, `${firstJungsung}${secondJungsung}`, firstJongsung); + } + })(); + + return [words.substring(0, words.length - 1), result].join(''); +} diff --git a/src/removeLastHangulCharacter.ts b/src/removeLastHangulCharacter.ts index 07160aca..0aed34fe 100644 --- a/src/removeLastHangulCharacter.ts +++ b/src/removeLastHangulCharacter.ts @@ -1,26 +1,26 @@ -import { combineHangulCharacter } from './combineHangulCharacter'; +import { combineCharacter } from './combineCharacter'; import { excludeLastElement } from './_internal'; import { canBeJungseong } from './canBe'; import { disassembleToGroups } from './disassemble'; /** - * @name removeLastHangulCharacter + * @name removeLastCharacter * @description * 인자로 주어진 한글 문자열에서 가장 마지막 문자 하나를 제거하여 반환합니다. * ```typescript - * removeLastHangulCharacter( + * removeLastCharacter( * // 한글 문자열 * words: string * ): string * ``` * @example - * removeLastHangulCharacter('안녕하세요 값') // 안녕하세요 갑 - * removeLastHangulCharacter('프론트엔드') // 프론트엔ㄷ - * removeLastHangulCharacter('일요일') // 일요이 - * removeLastHangulCharacter('전화') // 전호 - * removeLastHangulCharacter('신세계') // 신세ㄱ + * removeLastCharacter('안녕하세요 값') // 안녕하세요 갑 + * removeLastCharacter('프론트엔드') // 프론트엔ㄷ + * removeLastCharacter('일요일') // 일요이 + * removeLastCharacter('전화') // 전호 + * removeLastCharacter('신세계') // 신세ㄱ */ -export function removeLastHangulCharacter(words: string) { +export function removeLastCharacter(words: string) { const lastCharacter = words[words.length - 1]; if (lastCharacter == null) { return ''; @@ -33,15 +33,15 @@ export function removeLastHangulCharacter(words: string) { const [first, middle, last] = lastCharacterWithoutLastAlphabet; if (middle != null) { return canBeJungseong(last) - ? combineHangulCharacter(first, `${middle}${last}`) - : combineHangulCharacter(first, middle, last); + ? combineCharacter(first, `${middle}${last}`) + : combineCharacter(first, middle, last); } return first; } else { const [first, firstJungsung, secondJungsung, firstJongsung] = lastCharacterWithoutLastAlphabet; - return combineHangulCharacter(first, `${firstJungsung}${secondJungsung}`, firstJongsung); + return combineCharacter(first, `${firstJungsung}${secondJungsung}`, firstJongsung); } })(); diff --git a/src/romanize.ts b/src/romanize.ts index 14955228..f2d5f7a7 100644 --- a/src/romanize.ts +++ b/src/romanize.ts @@ -1,9 +1,9 @@ import { isHangulCharacter } from './_internal/hangul'; -import { assembleHangul } from './assemble'; +import { assemble } from './assemble'; +import { canBeChoseong } from './canBe'; import { 종성_알파벳_발음, 중성_알파벳_발음, 초성_알파벳_발음 } from './constants'; -import { disassembleCompleteHangulCharacter } from './disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; import { standardizePronunciation } from './standardizePronunciation'; -import { canBeChoseong } from './utils'; /** * 주어진 한글 문자열을 로마자로 변환합니다. @@ -23,17 +23,17 @@ const romanizeSyllableHangul = (arrayHangul: string[], index: number): string => const syllable = arrayHangul[index]; if (isHangulCharacter(syllable)) { - const disassemble = disassembleCompleteHangulCharacter(syllable) as NonNullable< - ReturnType + const disassemble = disassembleCompleteCharacter(syllable) as NonNullable< + ReturnType >; let choseong: (typeof 초성_알파벳_발음)[keyof typeof 초성_알파벳_발음] | 'l' = 초성_알파벳_발음[disassemble.first]; - const jungseong = 중성_알파벳_발음[assembleHangul([disassemble.middle]) as keyof typeof 중성_알파벳_발음]; + const jungseong = 중성_알파벳_발음[assemble([disassemble.middle]) as keyof typeof 중성_알파벳_발음]; const jongseong = 종성_알파벳_발음[disassemble.last as keyof typeof 종성_알파벳_발음]; // 'ㄹ'은 모음 앞에서는 'r'로, 자음 앞이나 어말에서는 'l'로 적는다. 단, 'ㄹㄹ'은 'll'로 적는다. (ex.울릉, 대관령), if (disassemble.first === 'ㄹ' && index > 0 && isHangulCharacter(arrayHangul[index - 1])) { - const prevDisassemble = disassembleCompleteHangulCharacter(arrayHangul[index - 1]); + const prevDisassemble = disassembleCompleteCharacter(arrayHangul[index - 1]); if (prevDisassemble?.last === 'ㄹ') { choseong = 'l'; diff --git a/src/standardizePronunciation/index.ts b/src/standardizePronunciation/index.ts index 847ef6b4..5700f1fd 100644 --- a/src/standardizePronunciation/index.ts +++ b/src/standardizePronunciation/index.ts @@ -1,7 +1,7 @@ import { isNotUndefined, joinString } from '../_internal'; import { isHangulAlphabet, isHangulCharacter } from '../_internal/hangul'; -import { combineHangulCharacter } from '../combineHangulCharacter'; -import { disassembleCompleteHangulCharacter } from '../disassembleCompleteHangulCharacter'; +import { combineCharacter } from '../combineCharacter'; +import { disassembleCompleteCharacter } from '../disassembleCompleteCharacter'; import { transform12th, transform13And14th, @@ -88,7 +88,7 @@ function 음절분해(hangulPhrase: string): { return true; }) - .map(disassembleCompleteHangulCharacter) + .map(disassembleCompleteCharacter) .filter(isNotUndefined); return { notHangulPhrase, disassembleHangul }; @@ -146,7 +146,7 @@ function applyRules(params: ApplyParameters): { function assembleChangedHangul(disassembleHangul: Syllable[], notHangulPhrase: NotHangul[]): string { const changedSyllables = disassembleHangul .filter(isNotUndefined) - .map(syllable => combineHangulCharacter(syllable.first, syllable.middle, syllable.last)); + .map(syllable => combineCharacter(syllable.first, syllable.middle, syllable.last)); for (const { index, syllable } of notHangulPhrase) { changedSyllables.splice(index, 0, syllable); diff --git a/src/standardizePronunciation/rules/rules.types.ts b/src/standardizePronunciation/rules/rules.types.ts index 46eca0d6..53cf6fbb 100644 --- a/src/standardizePronunciation/rules/rules.types.ts +++ b/src/standardizePronunciation/rules/rules.types.ts @@ -1,8 +1,8 @@ -import { disassembleCompleteHangulCharacter } from '../../disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from '../../disassembleCompleteCharacter'; export type NonUndefined = T extends undefined ? never : T; export type Nullable = T | null | undefined; -export type Syllable = NonUndefined>; +export type Syllable = NonUndefined>; export type ReturnSyllables = { current: Syllable; next: Syllable; diff --git a/src/standardizePronunciation/rules/transform12th.spec.ts b/src/standardizePronunciation/rules/transform12th.spec.ts index be0c23d3..5a649def 100644 --- a/src/standardizePronunciation/rules/transform12th.spec.ts +++ b/src/standardizePronunciation/rules/transform12th.spec.ts @@ -1,11 +1,11 @@ import { defined } from '../../_internal'; -import { disassembleCompleteHangulCharacter } from '../../disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from '../../disassembleCompleteCharacter'; import { transform12th } from './transform12th'; describe('transform12th', () => { it('"ㅎ, ㄶ, ㅀ" 뒤에 "ㄱ, ㄷ, ㅈ"이 결합되는 경우에는, 뒤 음절 첫소리와 합쳐서 "ㅋ, ㅌ, ㅊ"으로 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('놓')); - const next = defined(disassembleCompleteHangulCharacter('고')); + const current = defined(disassembleCompleteCharacter('놓')); + const next = defined(disassembleCompleteCharacter('고')); expect(transform12th(current, next)).toEqual({ current: { @@ -22,8 +22,8 @@ describe('transform12th', () => { }); it('받침 "ㄱ, ㄺ, ㄷ, ㅂ, ㄼ, ㅈ, ㄵ"이 뒤 음절 첫소리 "ㅎ"과 결합되는 경우에도, 역시 두 음을 합쳐서 "ㅋ, ㅌ, ㅍ, ㅊ"으로 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('각')); - const next = defined(disassembleCompleteHangulCharacter('하')); + const current = defined(disassembleCompleteCharacter('각')); + const next = defined(disassembleCompleteCharacter('하')); expect(transform12th(current, next)).toEqual({ current: { @@ -40,8 +40,8 @@ describe('transform12th', () => { }); it('"ㅎ, ㄶ, ㅀ" 뒤에 "ㅅ"이 결합되는 경우에는, "ㅅ"을 "ㅆ"으로 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('닿')); - const next = defined(disassembleCompleteHangulCharacter('소')); + const current = defined(disassembleCompleteCharacter('닿')); + const next = defined(disassembleCompleteCharacter('소')); expect(transform12th(current, next)).toEqual({ current: { @@ -58,8 +58,8 @@ describe('transform12th', () => { }); it('"ㅎ" 뒤에 "ㄴ"이 결합되는 경우에는 "ㄴ"으로 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('놓')); - const next = defined(disassembleCompleteHangulCharacter('는')); + const current = defined(disassembleCompleteCharacter('놓')); + const next = defined(disassembleCompleteCharacter('는')); expect(transform12th(current, next)).toEqual({ current: { @@ -76,8 +76,8 @@ describe('transform12th', () => { }); it('"ㄶ, ㅀ" 뒤에 "ㄴ"이 결합되는 경우에는, "ㅎ"을 발음하지 않는다', () => { - const current = defined(disassembleCompleteHangulCharacter('않')); - const next = defined(disassembleCompleteHangulCharacter('네')); + const current = defined(disassembleCompleteCharacter('않')); + const next = defined(disassembleCompleteCharacter('네')); expect(transform12th(current, next)).toEqual({ current: { @@ -94,8 +94,8 @@ describe('transform12th', () => { }); it('"ㅎ, ㄶ, ㅀ" 뒤에 모음으로 시작된 어미나 접미사가 결합되는 경우에는 "ㅎ"을 발음하지 않는다', () => { - const current = defined(disassembleCompleteHangulCharacter('낳')); - const next = defined(disassembleCompleteHangulCharacter('은')); + const current = defined(disassembleCompleteCharacter('낳')); + const next = defined(disassembleCompleteCharacter('은')); expect(transform12th(current, next)).toEqual({ current: { @@ -112,7 +112,7 @@ describe('transform12th', () => { }); it('"ㅎ, ㄶ, ㅀ" 뒤에 모음으로 시작된 어미나 접미사가 결합되는 경우에는 "ㅎ"을 발음하지 않는다', () => { - const current = defined(disassembleCompleteHangulCharacter('많')); + const current = defined(disassembleCompleteCharacter('많')); const next = null; expect(transform12th(current, next)).toEqual({ diff --git a/src/standardizePronunciation/rules/transform13And14th.spec.ts b/src/standardizePronunciation/rules/transform13And14th.spec.ts index 671b9687..f09e636a 100644 --- a/src/standardizePronunciation/rules/transform13And14th.spec.ts +++ b/src/standardizePronunciation/rules/transform13And14th.spec.ts @@ -1,11 +1,11 @@ import { defined } from '../../_internal'; -import { disassembleCompleteHangulCharacter } from '../../disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from '../../disassembleCompleteCharacter'; import { transform13And14th } from './transform13And14th'; describe('transform13And14th', () => { it('13항을 적용합니다.', () => { - const current = defined(disassembleCompleteHangulCharacter('깎')); - const next = defined(disassembleCompleteHangulCharacter('아')); + const current = defined(disassembleCompleteCharacter('깎')); + const next = defined(disassembleCompleteCharacter('아')); expect(transform13And14th(current, next)).toEqual({ current: { @@ -22,8 +22,8 @@ describe('transform13And14th', () => { }); it('14항을 적용합니다.', () => { - const current = defined(disassembleCompleteHangulCharacter('닭')); - const next = defined(disassembleCompleteHangulCharacter('을')); + const current = defined(disassembleCompleteCharacter('닭')); + const next = defined(disassembleCompleteCharacter('을')); expect(transform13And14th(current, next)).toEqual({ current: { diff --git a/src/standardizePronunciation/rules/transform16th.spec.ts b/src/standardizePronunciation/rules/transform16th.spec.ts index e226bdd1..ee38a500 100644 --- a/src/standardizePronunciation/rules/transform16th.spec.ts +++ b/src/standardizePronunciation/rules/transform16th.spec.ts @@ -1,11 +1,11 @@ import { defined } from '../../_internal'; -import { disassembleCompleteHangulCharacter } from '../../disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from '../../disassembleCompleteCharacter'; import { transform16th } from './transform16th'; describe('transform16th', () => { it('한글 자모의 이름은 그 받침소리를 연음하되, "ㄷ, ㅈ, ㅊ, ㅋ, ㅌ, ㅍ, ㅎ"의 경우에는 특별히 다음과 같이 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('귿')); - const next = defined(disassembleCompleteHangulCharacter('이')); + const current = defined(disassembleCompleteCharacter('귿')); + const next = defined(disassembleCompleteCharacter('이')); const phrase = '디귿이'; const index = 1; @@ -31,8 +31,8 @@ describe('transform16th', () => { }); it('자모의 이름이 "ㄱ, ㄴ, ㄹ, ㅁ, ㅂ, ㅅ, ㅇ"일 경우', () => { - const current = defined(disassembleCompleteHangulCharacter('역')); - const next = defined(disassembleCompleteHangulCharacter('이')); + const current = defined(disassembleCompleteCharacter('역')); + const next = defined(disassembleCompleteCharacter('이')); const phrase = '기역이'; const index = 1; diff --git a/src/standardizePronunciation/rules/transform17th.spec.ts b/src/standardizePronunciation/rules/transform17th.spec.ts index aab32447..a371d420 100644 --- a/src/standardizePronunciation/rules/transform17th.spec.ts +++ b/src/standardizePronunciation/rules/transform17th.spec.ts @@ -1,11 +1,11 @@ import { defined } from '../../_internal'; -import { disassembleCompleteHangulCharacter } from '../../disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from '../../disassembleCompleteCharacter'; import { transform17th } from './transform17th'; describe('transform17th', () => { it('받침 "ㄷ", "ㅌ(ㄾ)"이 조사나 접미사의 모음 "ㅣ"와 결합되는 경우에는, "ㅈ", "ㅊ"으로 바꾸어서 뒤 음절 첫소리로 옮겨 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('굳')); - const next = defined(disassembleCompleteHangulCharacter('이')); + const current = defined(disassembleCompleteCharacter('굳')); + const next = defined(disassembleCompleteCharacter('이')); expect(transform17th(current, next)).toEqual({ current: { @@ -22,8 +22,8 @@ describe('transform17th', () => { }); it('"ㄷ" 뒤에 접미사 "히"가 결합되어 "티"를 이루는 것은 "치"로 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('굳')); - const next = defined(disassembleCompleteHangulCharacter('히')); + const current = defined(disassembleCompleteCharacter('굳')); + const next = defined(disassembleCompleteCharacter('히')); expect(transform17th(current, next)).toEqual({ current: { diff --git a/src/standardizePronunciation/rules/transform17th.ts b/src/standardizePronunciation/rules/transform17th.ts index bf3ab074..094a714c 100644 --- a/src/standardizePronunciation/rules/transform17th.ts +++ b/src/standardizePronunciation/rules/transform17th.ts @@ -1,4 +1,4 @@ -import { hasProperty } from '../../utils'; +import { hasProperty } from '../../_internal'; import { 음의_동화_받침 } from '../standardizePronunciation.constants'; import { ReturnSyllables, Syllable } from './rules.types'; diff --git a/src/standardizePronunciation/rules/transform18th.spec.ts b/src/standardizePronunciation/rules/transform18th.spec.ts index f7146469..c8f0da0d 100644 --- a/src/standardizePronunciation/rules/transform18th.spec.ts +++ b/src/standardizePronunciation/rules/transform18th.spec.ts @@ -1,11 +1,11 @@ import { defined } from '../../_internal'; -import { disassembleCompleteHangulCharacter } from '../../disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from '../../disassembleCompleteCharacter'; import { transform18th } from './transform18th'; describe('transform18th', () => { it('받침 "ㄱ, ㄲ, ㅋ, ㄳ, ㄺ"일 경우', () => { - const current = defined(disassembleCompleteHangulCharacter('먹')); - const next = defined(disassembleCompleteHangulCharacter('는')); + const current = defined(disassembleCompleteCharacter('먹')); + const next = defined(disassembleCompleteCharacter('는')); expect(transform18th(current, next)).toEqual({ current: { @@ -17,8 +17,8 @@ describe('transform18th', () => { }); it('받침 "ㄷ, ㅅ, ㅆ, ㅈ, ㅊ, ㅌ, ㅎ"일 경우', () => { - const current = defined(disassembleCompleteHangulCharacter('닫')); - const next = defined(disassembleCompleteHangulCharacter('는')); + const current = defined(disassembleCompleteCharacter('닫')); + const next = defined(disassembleCompleteCharacter('는')); expect(transform18th(current, next)).toEqual({ current: { @@ -30,8 +30,8 @@ describe('transform18th', () => { }); it('받침 "ㅂ, ㅍ, ㄼ, ㄿ, ㅄ"일 경우', () => { - const current = defined(disassembleCompleteHangulCharacter('잡')); - const next = defined(disassembleCompleteHangulCharacter('는')); + const current = defined(disassembleCompleteCharacter('잡')); + const next = defined(disassembleCompleteCharacter('는')); expect(transform18th(current, next)).toEqual({ current: { diff --git a/src/standardizePronunciation/rules/transform19th.spec.ts b/src/standardizePronunciation/rules/transform19th.spec.ts index b15c3434..f7858357 100644 --- a/src/standardizePronunciation/rules/transform19th.spec.ts +++ b/src/standardizePronunciation/rules/transform19th.spec.ts @@ -1,11 +1,11 @@ import { defined } from '../../_internal'; -import { disassembleCompleteHangulCharacter } from '../../disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from '../../disassembleCompleteCharacter'; import { transform19th } from './transform19th'; describe('transform19th', () => { it('받침 "ㅁ, ㅇ" 뒤에 연결되는 "ㄹ"은 "ㄴ"으로 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('담')); - const next = defined(disassembleCompleteHangulCharacter('력')); + const current = defined(disassembleCompleteCharacter('담')); + const next = defined(disassembleCompleteCharacter('력')); expect(transform19th(current, next)).toEqual({ next: { @@ -17,8 +17,8 @@ describe('transform19th', () => { }); it('받침 "ㄱ, ㅂ" 뒤에 연결되는 "ㄹ"도 "ㄴ"으로 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('막')); - const next = defined(disassembleCompleteHangulCharacter('론')); + const current = defined(disassembleCompleteCharacter('막')); + const next = defined(disassembleCompleteCharacter('론')); expect(transform19th(current, next)).toEqual({ next: { diff --git a/src/standardizePronunciation/rules/transform20th.spec.ts b/src/standardizePronunciation/rules/transform20th.spec.ts index c61ad2e0..9efd4335 100644 --- a/src/standardizePronunciation/rules/transform20th.spec.ts +++ b/src/standardizePronunciation/rules/transform20th.spec.ts @@ -1,11 +1,11 @@ import { defined } from '../../_internal'; -import { disassembleCompleteHangulCharacter } from '../../disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from '../../disassembleCompleteCharacter'; import { transform20th } from './transform20th'; describe('transform20th', () => { it('"ㄴ"은 "ㄹ"의 앞이나 뒤에서 "ㄹ"로 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('난')); - const next = defined(disassembleCompleteHangulCharacter('로')); + const current = defined(disassembleCompleteCharacter('난')); + const next = defined(disassembleCompleteCharacter('로')); expect(transform20th(current, next)).toEqual({ current: { @@ -22,8 +22,8 @@ describe('transform20th', () => { }); it('첫소리 "ㄴ"이 "ㅀ, ㄾ" 뒤에 연결되는 경우에도 "ㄹ"로 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('닳')); - const next = defined(disassembleCompleteHangulCharacter('는')); + const current = defined(disassembleCompleteCharacter('닳')); + const next = defined(disassembleCompleteCharacter('는')); expect(transform20th(current, next)).toEqual({ current: { diff --git a/src/standardizePronunciation/rules/transform9And10And11th.spec.ts b/src/standardizePronunciation/rules/transform9And10And11th.spec.ts index b19a7d43..6f10d4de 100644 --- a/src/standardizePronunciation/rules/transform9And10And11th.spec.ts +++ b/src/standardizePronunciation/rules/transform9And10And11th.spec.ts @@ -1,11 +1,11 @@ import { defined } from '../../_internal'; -import { disassembleCompleteHangulCharacter } from '../../disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from '../../disassembleCompleteCharacter'; import { transform9And10And11th } from './transform9And10And11th'; describe('transform9And10And11th', () => { it('9항 - 받침 "ㄲ, ㅋ" / "ㅅ, ㅆ, ㅈ, ㅊ, ㅌ" / "ㅍ"은 어말 또는 자음 앞에서 각각 대표음 "ㄱ, ㄷ, ㅂ"으로 발음한다.', () => { - const current = defined(disassembleCompleteHangulCharacter('닦')); - const next = disassembleCompleteHangulCharacter('다'); + const current = defined(disassembleCompleteCharacter('닦')); + const next = disassembleCompleteCharacter('다'); expect(transform9And10And11th(current, next)).toEqual({ current: { @@ -17,8 +17,8 @@ describe('transform9And10And11th', () => { }); it('10항 - 겹받침 "ㄳ" / "ㄵ" / "ㄼ, ㄽ, ㄾ" / "ㅄ"은 어말 또는 자음 앞에서 각각 "ㄱ, ㄴ, ㄹ, ㅂ"으로 발음한다.', () => { - const current = defined(disassembleCompleteHangulCharacter('앉')); - const next = disassembleCompleteHangulCharacter('다'); + const current = defined(disassembleCompleteCharacter('앉')); + const next = disassembleCompleteCharacter('다'); expect(transform9And10And11th(current, next)).toEqual({ current: { @@ -30,8 +30,8 @@ describe('transform9And10And11th', () => { }); it('11항 - 겹받침 "ㄺ" / "ㄻ" / "ㄿ"은 어말 또는 자음 앞에서 각각 "ㄱ, ㅁ, ㅂ"으로 발음한다.', () => { - const current = defined(disassembleCompleteHangulCharacter('흙')); - const next = disassembleCompleteHangulCharacter('과'); + const current = defined(disassembleCompleteCharacter('흙')); + const next = disassembleCompleteCharacter('과'); expect(transform9And10And11th(current, next)).toEqual({ current: { diff --git a/src/standardizePronunciation/rules/transform9And10And11th.ts b/src/standardizePronunciation/rules/transform9And10And11th.ts index 5886c250..65643fbe 100644 --- a/src/standardizePronunciation/rules/transform9And10And11th.ts +++ b/src/standardizePronunciation/rules/transform9And10And11th.ts @@ -1,4 +1,4 @@ -import { hasProperty } from '../../utils'; +import { hasProperty } from '../../_internal'; import { 받침_대표음_발음, 음가가_없는_자음 } from '../standardizePronunciation.constants'; import { Nullable, ReturnSyllables, Syllable } from './rules.types'; diff --git a/src/standardizePronunciation/rules/transformHardConversion.spec.ts b/src/standardizePronunciation/rules/transformHardConversion.spec.ts index 827f85a5..39323f48 100644 --- a/src/standardizePronunciation/rules/transformHardConversion.spec.ts +++ b/src/standardizePronunciation/rules/transformHardConversion.spec.ts @@ -1,11 +1,11 @@ import { defined } from '../../_internal'; -import { disassembleCompleteHangulCharacter } from '../../disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from '../../disassembleCompleteCharacter'; import { transformHardConversion } from './transformHardConversion'; describe('transformHardConversion', () => { it('23항 - 받침 "ㄱ(ㄲ, ㅋ, ㄳ, ㄺ), ㄷ(ㅅ, ㅆ, ㅈ, ㅊ, ㅌ), ㅂ(ㅍ, ㄼ, ㄿ, ㅄ)" 뒤에 연결되는 "ㄱ, ㄷ, ㅂ, ㅅ, ㅈ"은 된소리로 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('국')); - const next = defined(disassembleCompleteHangulCharacter('밥')); + const current = defined(disassembleCompleteCharacter('국')); + const next = defined(disassembleCompleteCharacter('밥')); expect(transformHardConversion(current, next)).toEqual({ next: { @@ -17,8 +17,8 @@ describe('transformHardConversion', () => { }); it('24항 - 어간 받침 "ㄴ(ㄵ), ㅁ(ㄻ)" 뒤에 결합되는 어미의 첫소리 "ㄱ, ㄷ, ㅅ, ㅈ"은 된소리로 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('신')); - const next = defined(disassembleCompleteHangulCharacter('고')); + const current = defined(disassembleCompleteCharacter('신')); + const next = defined(disassembleCompleteCharacter('고')); expect(transformHardConversion(current, next)).toEqual({ next: { @@ -30,8 +30,8 @@ describe('transformHardConversion', () => { }); it('25항 - 어간 받침 "ㄼ, ㄾ" 뒤에 결합되는 어미의 첫소리 "ㄱ, ㄷ, ㅅ, ㅈ"은 된소리로 발음한다', () => { - const current = defined(disassembleCompleteHangulCharacter('넓')); - const next = defined(disassembleCompleteHangulCharacter('게')); + const current = defined(disassembleCompleteCharacter('넓')); + const next = defined(disassembleCompleteCharacter('게')); expect(transformHardConversion(current, next)).toEqual({ next: { diff --git a/src/standardizePronunciation/rules/transformHardConversion.ts b/src/standardizePronunciation/rules/transformHardConversion.ts index 3062ba46..53275f1d 100644 --- a/src/standardizePronunciation/rules/transformHardConversion.ts +++ b/src/standardizePronunciation/rules/transformHardConversion.ts @@ -1,5 +1,5 @@ import { arrayIncludes } from '../../_internal'; -import { hasProperty } from '../../utils'; +import { hasProperty } from '../../_internal'; import { 된소리, 된소리_받침, 어간_받침 } from '../standardizePronunciation.constants'; import { ReturnSyllables, Syllable } from './rules.types'; diff --git a/src/standardizePronunciation/rules/transformNLAssimilation.spec.ts b/src/standardizePronunciation/rules/transformNLAssimilation.spec.ts index 6ae0dfce..5c183a80 100644 --- a/src/standardizePronunciation/rules/transformNLAssimilation.spec.ts +++ b/src/standardizePronunciation/rules/transformNLAssimilation.spec.ts @@ -1,11 +1,11 @@ import { defined } from '../../_internal'; -import { disassembleCompleteHangulCharacter } from '../../disassembleCompleteHangulCharacter'; +import { disassembleCompleteCharacter } from '../../disassembleCompleteCharacter'; import { transformNLAssimilation } from './transformNLAssimilation'; describe('transformNLAssimilation', () => { it('받침이 "ㄱ, ㄴ, ㄷ, ㅁ, ㅂ, ㅇ"이고 다음 음절이 "야, 여, 요, 유, 이, 얘, 예"로 이어지는 경우', () => { - const current = defined(disassembleCompleteHangulCharacter('맨')); - const next = defined(disassembleCompleteHangulCharacter('입')); + const current = defined(disassembleCompleteCharacter('맨')); + const next = defined(disassembleCompleteCharacter('입')); expect(transformNLAssimilation(current, next)).toEqual({ current: { @@ -22,8 +22,8 @@ describe('transformNLAssimilation', () => { }); it('받침이 "ㄹ"이고 다음 음절이 "야, 여, 요, 유, 이, 얘, 예"로 이어지는 경우', () => { - const current = defined(disassembleCompleteHangulCharacter('알')); - const next = defined(disassembleCompleteHangulCharacter('약')); + const current = defined(disassembleCompleteCharacter('알')); + const next = defined(disassembleCompleteCharacter('약')); expect(transformNLAssimilation(current, next)).toEqual({ current: { @@ -40,8 +40,8 @@ describe('transformNLAssimilation', () => { }); it('ㄴ/ㄹ이 되기 위한 조건이지만 현재 음절의 중성의 ∙(아래아)가 하나가 아닐 경우에는 덧나지 않고 연음규칙이 적용된다', () => { - const current = defined(disassembleCompleteHangulCharacter('양')); - const next = defined(disassembleCompleteHangulCharacter('이')); + const current = defined(disassembleCompleteCharacter('양')); + const next = defined(disassembleCompleteCharacter('이')); expect(transformNLAssimilation(current, next)).toEqual({ current: { From 82540704475b37824234527a379c55ebd15980b1 Mon Sep 17 00:00:00 2001 From: chanhyuk-park Date: Tue, 6 Aug 2024 02:10:45 +0900 Subject: [PATCH 13/21] chore: add co-authors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 서동휘 <8275026+suhdonghwi@users.noreply.github.com> Co-authored-by: minsuKang <90169703+minchodang@users.noreply.github.com> Co-authored-by: chaerim kim <89721027+chaaerim@users.noreply.github.com> From ee46e7b35a979aa0b990eaed88df1786de3f494a Mon Sep 17 00:00:00 2001 From: chanhyuk-park Date: Tue, 6 Aug 2024 02:16:18 +0900 Subject: [PATCH 14/21] remove choseongIncludes --- .../demo/choseong-includes-demo.tsx | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 docs/src/components/demo/choseong-includes-demo.tsx diff --git a/docs/src/components/demo/choseong-includes-demo.tsx b/docs/src/components/demo/choseong-includes-demo.tsx deleted file mode 100644 index faaf8c8c..00000000 --- a/docs/src/components/demo/choseong-includes-demo.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React, { useState } from 'react'; -import { choseongIncludes } from 'es-hangul'; - -export function ChoseongIncludesDemo() { - const [searchWord, setSearchWord] = useState('홍길동'); - const [userInput, setUserInput] = useState('ㅎㄱㄷ'); - - const result = choseongIncludes(searchWord, userInput); - - return ( -
-
- - setSearchWord(e.target.value)} - className="w-full p-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-300" - /> -
-
- - setUserInput(e.target.value)} - className="w-full p-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-300" - /> -
- {result !== null && ( -

- Result: {result ? 'Match found' : 'No match'} -

- )} -
- ); -} From 6bcd40e29c867fd020056d37cab8a0cfd793b4bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=B0=AC=ED=98=81?= Date: Tue, 6 Aug 2024 02:20:16 +0900 Subject: [PATCH 15/21] Update README.md Co-authored-by: Jonghyeon Ko --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index faf7b845..003f6dd5 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ ## 사용 예시 -문자열 초성화 , 조사 붙이기와 같은 한글 작업을 간단히 할 수 있습니다. +문자열 초성화, 조사 붙이기와 같은 한글 작업을 간단히 할 수 있습니다. ```tsx import { getChoseong } from 'es-hangul'; From 3c5299d86b55c8b2fc4d805b2eaec80cba9a4080 Mon Sep 17 00:00:00 2001 From: chanhyuk-park Date: Tue, 6 Aug 2024 02:25:54 +0900 Subject: [PATCH 16/21] remove removeHangulCharacter --- src/removeLastHangulCharacter.ts | 49 -------------------------------- 1 file changed, 49 deletions(-) delete mode 100644 src/removeLastHangulCharacter.ts diff --git a/src/removeLastHangulCharacter.ts b/src/removeLastHangulCharacter.ts deleted file mode 100644 index 0aed34fe..00000000 --- a/src/removeLastHangulCharacter.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { combineCharacter } from './combineCharacter'; -import { excludeLastElement } from './_internal'; -import { canBeJungseong } from './canBe'; -import { disassembleToGroups } from './disassemble'; - -/** - * @name removeLastCharacter - * @description - * 인자로 주어진 한글 문자열에서 가장 마지막 문자 하나를 제거하여 반환합니다. - * ```typescript - * removeLastCharacter( - * // 한글 문자열 - * words: string - * ): string - * ``` - * @example - * removeLastCharacter('안녕하세요 값') // 안녕하세요 갑 - * removeLastCharacter('프론트엔드') // 프론트엔ㄷ - * removeLastCharacter('일요일') // 일요이 - * removeLastCharacter('전화') // 전호 - * removeLastCharacter('신세계') // 신세ㄱ - */ -export function removeLastCharacter(words: string) { - const lastCharacter = words[words.length - 1]; - if (lastCharacter == null) { - return ''; - } - - const result = (() => { - const disassembleLastCharacter = disassembleToGroups(lastCharacter); - const [lastCharacterWithoutLastAlphabet] = excludeLastElement(disassembleLastCharacter[0]); - if (lastCharacterWithoutLastAlphabet.length <= 3) { - const [first, middle, last] = lastCharacterWithoutLastAlphabet; - if (middle != null) { - return canBeJungseong(last) - ? combineCharacter(first, `${middle}${last}`) - : combineCharacter(first, middle, last); - } - - return first; - } else { - const [first, firstJungsung, secondJungsung, firstJongsung] = lastCharacterWithoutLastAlphabet; - - return combineCharacter(first, `${firstJungsung}${secondJungsung}`, firstJongsung); - } - })(); - - return [words.substring(0, words.length - 1), result].join(''); -} From c62c1db5adcabefbf1892123ecad9a66c0636fd8 Mon Sep 17 00:00:00 2001 From: chanhyuk-park Date: Tue, 6 Aug 2024 03:06:00 +0900 Subject: [PATCH 17/21] change hasbatchim interface --- docs/src/pages/docs/api/hasBatchim.en.mdx | 10 +-- docs/src/pages/docs/api/hasBatchim.ko.mdx | 9 +- src/hasBatchim.spec.ts | 101 +++++++++++++++++++--- src/hasBatchim.ts | 19 ++-- 4 files changed, 108 insertions(+), 31 deletions(-) diff --git a/docs/src/pages/docs/api/hasBatchim.en.mdx b/docs/src/pages/docs/api/hasBatchim.en.mdx index b5fe9e55..c546d623 100644 --- a/docs/src/pages/docs/api/hasBatchim.en.mdx +++ b/docs/src/pages/docs/api/hasBatchim.en.mdx @@ -9,15 +9,15 @@ Checks if the last character of a Korean string has a batchim (jongseong). ````typescript hasBatchim( str: string, - // checking for single batchim - options?: { single?: boolean } + options?: { only?: "single" | "double" } ): boolean ```typescript hasBatchim('값') // true hasBatchim('토') // false - hasBatchim('갑', { single: true }) // true - hasBatchim('값', { single: true }) // false - hasBatchim('토', { single: true }) // false + hasBatchim('갑', { only : "single" }) // true + hasBatchim('값', { only : "single" }) // false + hasBatchim('토', { only : "double" }) // false ```` + diff --git a/docs/src/pages/docs/api/hasBatchim.ko.mdx b/docs/src/pages/docs/api/hasBatchim.ko.mdx index 73eac438..b5e6c20a 100644 --- a/docs/src/pages/docs/api/hasBatchim.ko.mdx +++ b/docs/src/pages/docs/api/hasBatchim.ko.mdx @@ -9,15 +9,14 @@ title: hasBatchim ````typescript hasBatchim( str: string, - // 홑받침 여부를 확인할지 여부 - options?: { single?: boolean } + options?: { only?: "single" | "double" } ): boolean ```typescript hasBatchim('값') // true hasBatchim('토') // false - hasBatchim('갑', { single: true }) // true - hasBatchim('값', { single: true }) // false - hasBatchim('토', { single: true }) // false + hasBatchim('갑', { only : "single" }) // true + hasBatchim('값', { only : "single" }) // false + hasBatchim('토', { only : "double" }) // false ```` diff --git a/src/hasBatchim.spec.ts b/src/hasBatchim.spec.ts index 02de88dc..ef9c58db 100644 --- a/src/hasBatchim.spec.ts +++ b/src/hasBatchim.spec.ts @@ -1,3 +1,4 @@ +import { deserialize } from 'v8'; import { hasBatchim } from './hasBatchim'; describe('hasBatchim', () => { @@ -42,31 +43,31 @@ describe('홑받침', () => { it('홑받침을 받으면 true를 반환한다.', () => { expect( hasBatchim('공', { - single: true, + only: 'single', }) ).toBe(true); expect( hasBatchim('핫', { - single: true, + only: 'single', }) ).toBe(true); expect( hasBatchim('양', { - single: true, + only: 'single', }) ).toBe(true); expect( hasBatchim('신', { - single: true, + only: 'single', }) ).toBe(true); expect( hasBatchim('확', { - single: true, + only: 'single', }) ).toBe(true); }); @@ -75,25 +76,97 @@ describe('홑받침', () => { it('겹받침을 받으면 false를 반환한다.', () => { expect( hasBatchim('값', { - single: true, + only: 'single', }) ).toBe(false); - expect(hasBatchim('읊', { single: true })).toBe(false); + expect( + hasBatchim('읊', { + only: 'single', + }) + ).toBe(false); - expect(hasBatchim('웱', { single: true })).toBe(false); + expect(hasBatchim('웱', { only: 'single' })).toBe(false); }); it('받침이 없는 문자를 받으면 false를 반환한다.', () => { - expect(hasBatchim('토', { single: true })).toBe(false); - expect(hasBatchim('서', { single: true })).toBe(false); - expect(hasBatchim('와', { single: true })).toBe(false); + expect(hasBatchim('토', { only: 'single' })).toBe(false); + expect(hasBatchim('서', { only: 'single' })).toBe(false); + expect(hasBatchim('와', { only: 'single' })).toBe(false); }); it('한글 외의 문자를 입력하면 false를 반환한다.', () => { - expect(hasBatchim('cat', { single: true })).toBe(false); - expect(hasBatchim('', { single: true })).toBe(false); - expect(hasBatchim('?', { single: true })).toBe(false); + expect(hasBatchim('cat', { only: 'single' })).toBe(false); + expect(hasBatchim('', { only: 'single' })).toBe(false); + expect(hasBatchim('?', { only: 'single' })).toBe(false); + }); + }); + + describe('겹받침', () => { + it('겹받침을 받으면 true를 반환한다.', () => { + expect( + hasBatchim('값', { + only: 'double', + }) + ).toBe(true); + + expect( + hasBatchim('읊', { + only: 'double', + }) + ).toBe(true); + + expect( + hasBatchim('웱', { + only: 'double', + }) + ).toBe(true); + }); + + describe('겹받침이 아니라고 판단되는 경우', () => { + it('홑받침을 받으면 false를 반환한다.', () => { + expect( + hasBatchim('공', { + only: 'double', + }) + ).toBe(false); + + expect( + hasBatchim('핫', { + only: 'double', + }) + ).toBe(false); + + expect( + hasBatchim('양', { + only: 'double', + }) + ).toBe(false); + + expect( + hasBatchim('신', { + only: 'double', + }) + ).toBe(false); + + expect( + hasBatchim('확', { + only: 'double', + }) + ).toBe(false); + }); + + it('받침이 없는 문자를 받으면 false를 반환한다.', () => { + expect(hasBatchim('토', { only: 'double' })).toBe(false); + expect(hasBatchim('서', { only: 'double' })).toBe(false); + expect(hasBatchim('와', { only: 'double' })).toBe(false); + }); + + it('한글 외의 문자를 입력하면 false를 반환한다.', () => { + expect(hasBatchim('cat', { only: 'double' })).toBe(false); + expect(hasBatchim('', { only: 'double' })).toBe(false); + expect(hasBatchim('?', { only: 'double' })).toBe(false); + }); }); }); }); diff --git a/src/hasBatchim.ts b/src/hasBatchim.ts index 6ad7a287..8311e0aa 100644 --- a/src/hasBatchim.ts +++ b/src/hasBatchim.ts @@ -13,18 +13,19 @@ import { * hasBatchim( * // 글자에 받침이 있는지 확인하고 싶은 문자열 * str: string, - * // 옵션 객체로 홑받침 여부를 확인 - * options?: { single?: boolean } + * // 옵션 객체로 only 속성을 받을 수 있습니다. + * options?: { only?: "single" | "double" } * ): boolean * ``` * @example * hasBatchim('값') // true * hasBatchim('토') // false - * hasBatchim('갑', { single: true }) // true - * hasBatchim('값', { single: true }) // false - * hasBatchim('토', { single: true }) // false + * hasBatchim('갑', { only: "single" }) // true + * hasBatchim('값', { only: "single" }) // false + * hasBatchim('값', { only: "double" }) // true + * hasBatchim('토', { only: "double" }) // false */ -export function hasBatchim(str: string, options?: { single?: boolean }) { +export function hasBatchim(str: string, options?: { only?: 'single' | 'double' }) { const lastChar = str[str.length - 1]; if (lastChar == null) { @@ -39,9 +40,13 @@ export function hasBatchim(str: string, options?: { single?: boolean }) { const batchimCode = (charCode - COMPLETE_HANGUL_START_CHARCODE) % NUMBER_OF_JONGSEONG; - if (options?.single) { + if (options?.only === 'single') { return HANGUL_CHARACTERS_BY_LAST_INDEX[batchimCode].length === 1; } + if (options?.only === 'double') { + return HANGUL_CHARACTERS_BY_LAST_INDEX[batchimCode].length === 2; + } + return batchimCode > 0; } From bfaa5683c03ca8ef6954dac5e6c5d1e7d137d266 Mon Sep 17 00:00:00 2001 From: chanhyuk-park Date: Tue, 6 Aug 2024 03:28:44 +0900 Subject: [PATCH 18/21] add jsdoc in hasBatchim --- src/_internal/hangul.ts | 2 +- src/hasBatchim.ts | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/_internal/hangul.ts b/src/_internal/hangul.ts index 00601a21..9155e838 100644 --- a/src/_internal/hangul.ts +++ b/src/_internal/hangul.ts @@ -151,7 +151,7 @@ export function binaryAssembleCharacters(source: string, nextCharacter: string) if ( hasBatchim(source, { - single: true, + only: 'single', }) && canBeJongseong(`${lastConsonant}${nextCharacter}`) ) { diff --git a/src/hasBatchim.ts b/src/hasBatchim.ts index 8311e0aa..9fcfc2a3 100644 --- a/src/hasBatchim.ts +++ b/src/hasBatchim.ts @@ -25,7 +25,16 @@ import { * hasBatchim('값', { only: "double" }) // true * hasBatchim('토', { only: "double" }) // false */ -export function hasBatchim(str: string, options?: { only?: 'single' | 'double' }) { +export function hasBatchim( + str: string, + options?: { + /** + * 체크할 받침의 종류 + * 사용하지 않으면 둘다 체크합니다. + */ + only?: 'single' | 'double'; + } +) { const lastChar = str[str.length - 1]; if (lastChar == null) { From d0599d2a0613b5d8c8f1a62be7002eef5d1aba62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=B0=AC=ED=98=81?= Date: Tue, 6 Aug 2024 03:33:03 +0900 Subject: [PATCH 19/21] Update docs/src/pages/docs/api/getChoseong.en.mdx Co-authored-by: Jonghyeon Ko --- docs/src/pages/docs/api/getChoseong.en.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/src/pages/docs/api/getChoseong.en.mdx b/docs/src/pages/docs/api/getChoseong.en.mdx index 9335dc86..3839acca 100644 --- a/docs/src/pages/docs/api/getChoseong.en.mdx +++ b/docs/src/pages/docs/api/getChoseong.en.mdx @@ -17,6 +17,5 @@ function getChoseong( ```tsx getChoseong('사과'); // 'ㅅㄱ' -getChoseong('리액트'); // 'ㄹㅇㅌ' getChoseong('띄어 쓰기'); // 'ㄸㅇ ㅆㄱ' ``` From d3d27e8dde4f705f74097d0ab3afdff8b452d29a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=B0=AC=ED=98=81?= Date: Tue, 6 Aug 2024 03:33:20 +0900 Subject: [PATCH 20/21] Update docs/src/pages/docs/api/disassembleToGroups.en.md Co-authored-by: Jonghyeon Ko --- docs/src/pages/docs/api/disassembleToGroups.en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/docs/api/disassembleToGroups.en.md b/docs/src/pages/docs/api/disassembleToGroups.en.md index c4213014..a52352e1 100644 --- a/docs/src/pages/docs/api/disassembleToGroups.en.md +++ b/docs/src/pages/docs/api/disassembleToGroups.en.md @@ -20,7 +20,7 @@ function disassembleToGroups( ## Examples ```typescript -disassembleToGroups('값'); // [['ㄱ', 'ㅏ', 'ㅂ', 'ㅅ']] +disassembleToGroups('사과'); // [['ㅅ', 'ㅏ'], ['ㄱ', 'ㅗ', 'ㅏ']] disassembleToGroups('ㅘ'); // [['ㅗ', 'ㅏ']] disassembleToGroups('ㄵ'); // [['ㄴ', 'ㅈ']] ``` From 4c3e9f97ae0b10d21c602b6495531b425185aa7b Mon Sep 17 00:00:00 2001 From: chanhyuk-park Date: Tue, 6 Aug 2024 03:35:29 +0900 Subject: [PATCH 21/21] add --- docs/src/pages/docs/api/disassembleToGroups.ko.md | 2 +- docs/src/pages/docs/api/getChoseong.ko.mdx | 1 - src/getChoseong.ts | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/src/pages/docs/api/disassembleToGroups.ko.md b/docs/src/pages/docs/api/disassembleToGroups.ko.md index 131bc1c6..3106879f 100644 --- a/docs/src/pages/docs/api/disassembleToGroups.ko.md +++ b/docs/src/pages/docs/api/disassembleToGroups.ko.md @@ -20,7 +20,7 @@ function disassembleToGroups( ## Examples ```typescript -disassembleToGroups('값'); // [['ㄱ', 'ㅏ', 'ㅂ', 'ㅅ']] +disassembleToGroups('사과'); // [['ㅅ', 'ㅏ'], ['ㄱ', 'ㅗ', 'ㅏ']] disassembleToGroups('ㅘ'); // [['ㅗ', 'ㅏ']] disassembleToGroups('ㄵ'); // [['ㄴ', 'ㅈ']] ``` diff --git a/docs/src/pages/docs/api/getChoseong.ko.mdx b/docs/src/pages/docs/api/getChoseong.ko.mdx index acab11d2..8f10d84d 100644 --- a/docs/src/pages/docs/api/getChoseong.ko.mdx +++ b/docs/src/pages/docs/api/getChoseong.ko.mdx @@ -19,6 +19,5 @@ function getChoseong( ```tsx getChoseong('사과'); // 'ㅅㄱ' -getChoseong('리액트'); // 'ㄹㅇㅌ' getChoseong('띄어 쓰기'); // 'ㄸㅇ ㅆㄱ' ``` diff --git a/src/getChoseong.ts b/src/getChoseong.ts index 2889733f..befd95f6 100644 --- a/src/getChoseong.ts +++ b/src/getChoseong.ts @@ -12,7 +12,6 @@ import { HANGUL_CHARACTERS_BY_FIRST_INDEX, JASO_HANGUL_NFD } from './constants'; * ``` * @example * getChoseong('사과') // 'ㅅㄱ' - * getChoseong('리액트') // 'ㄹㅇㅌ' * getChoseong('띄어 쓰기') // 'ㄸㅇ ㅆㄱ' */ export function getChoseong(word: string) {