Skip to content

Commit

Permalink
feat: 한국어를 로마자로 변환해주는 함수와 한국어를 표준 발음법으로 변환해주는 함수를 만들고 문서화를 진행합니다 (#115)
Browse files Browse the repository at this point in the history
* test: 음성 표기법 테스트 코드 작성

* test: isNotUndefined 유틸 구현

* test: 단일자모 테스트 케이스 추가

* test: 단일 자모 테스트 케이스 수정

* feat: 음성 표기법 기능 구현

* feat: 음절분해 속 disassembleCompleteHangulCharacter 함수는 undefined일 수 없음

* feat: 다음 음절 변수 조건식 강화

* refactor: 16항 -1 인덱스 조건 처리

* refactor: 16항 조건문 상수화하여 축약

* refactor: 음의 동화 조건 상수화

* refactor: ㄴ,ㄹ이 덧나는 경우 조건 상수화

* refactor: 19항 조건문 상수화

* refactor: 18항 조건문 상수화

* refactor: 20항 유음화 조건문 순서 수정

* refactor: 12항 조건에 상수화 적용

* refactor: 13,14항 상수화 및 반환타입추론

* refactor: 9,10,11항 조건문 상수화

* refactor: internal 함수 사용

* docs: phoneticNotation 문서 작성

* test: covertToRoman 테스트 코드 작성

* test: convertToRoman 테스트 케이스 추가

* feat: convertToRoman 구현

* refactor: 음절분해 return type 명시

* test: 테스트 케이스 수정

* docs: romanize

* refactor: convertToRoman에서 romanize로 이름을 변경합니다.

* refactor: phoneticNotation에서standardPronunciation으로 이름을 변경합니다

* feat: type guard include 함수를 구현합니다

* test: 경음화를 적용합니다

* feat: 경음화 기능을 옵션으로 추가합니다

* refactor: 표준발음 함수에서 사용되는 상수를 상수파일로 이동

* docs: 함수 설명문 수정

* docs: 표준발음법 문서 수정

* docs: 표준 발음법 영문 문서의 주석을 변경합니다

* test: isIncludedInArray 테스트 코드를 작성합니다

* fix: 특정회사 언급 문자 제거

* fix: 보다 간결하게 isIncludedInArray > arrayIncludes로 이름 변경

* fix: standardPronunciation 상수와 관련하여 새파일을 만든다

* fix: map 메소드를 축약한다

* fix: arrayIncludes > isArrayIncludes로 이름을 변경

* fix: arrayIncludes 함수를 개선합니다

* fix: romanize 가독성을 개선합니다

* fix: romanize > romanizeHangul #121

* refactor: 경음화 로직 분리

* refactor: nextSyllabel 연산 로직 축약

* refactor: 16항 로직 분리

* refactor: 17,19항 로직을 분리합니다

* refactor: 18항 로직을 분리합니다.

* refactor: 불필요한 조건문 return 제거

* refactor: 12항 로직 분리

* refactor: 13,14 항 로직을 분리합니다

* refactor: 9,10,11항 로직 분리

* refactor: standardPronunciation 기능을 개별 폴더로 분리합니다

* refactor: ㄴ,ㄹ 동화작용 설명 추가

* refactor: standardPronunciation 조건문 중복 처리

* test: 경음화 등의 된소리를 적용하지 않는 테스트 케이스 추가

* refactor: 주요 로직 추상화

* fix: romanizeHangul에 일관된 변수명 적용 #131

* test: 한글과 영어가 혼합된 테스트 케이스를 추가합니다

* test: 테스트 케이스 예시를 변경합니다

* fix: ㄴ/ㄹ이 덧나는 경우에도 연음규칙 적용이 가능

* fix: 주석 변경

* fix: 이해하기 쉬운 용어로 주석 변경

* fix: 메서드 컨벤션을 적용합니다 #132

* fix: Received Object applyRules

* fix: SRP 원칙 적용 - 1

* refactor: replace받침ㅎ

* refactor: make pure function

* refactor: applyRules

* refactor: rule 별로 파일 분리

* refactor: rule naming 변경

* test: rules에 test case 추가

* fix: type import

* fix: update import case

* fix: isNotUndefined, defined, arrayIncludes를 internal로 이동합니다.

* test: romanize test case 수정

* Create hip-pianos-live.md

---------

Co-authored-by: 박찬혁 <[email protected]>
  • Loading branch information
po4tion and okinawaa authored Aug 4, 2024
1 parent c9c6302 commit 84584d4
Show file tree
Hide file tree
Showing 38 changed files with 2,142 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/hip-pianos-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"es-hangul": minor
---

feat: 한국어를 로마자로 변환해주는 함수와 한국어를 표준 발음법으로 변환해주는 함수를 만들고 문서화를 진행합니다
28 changes: 28 additions & 0 deletions docs/src/pages/docs/api/romanize.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
title: romanize
---

# romanize

Change the Hangul string to Roman.

For detailed examples, see below.

```typescript
function romanize(hangul: string): string;
```

## Examples

```tsx
romanize('백마'); // 'baengma'
romanize('학여울'); // 'hangnyeoul'
romanize('해돋이'); // 'haedoji'
romanize('좋고'); // 'joko'
romanize('압구정'); // 'apgujeong'
romanize('구미'); // 'gumi'
romanize('대관령'); // 'daegwallyeong'
romanize(''); // 'g'
romanize('한국어!'); // 'hangugeo!'
romanize('안녕하세요'); // 'annyeonghaseyo'
```
28 changes: 28 additions & 0 deletions docs/src/pages/docs/api/romanize.ko.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
title: romanize
---

# romanize

한글 문자열을 로마자로 변경합니다.

자세한 예시는 아래 Example을 참고하세요.

```typescript
function romanize(hangul: string): string;
```

## Examples

```tsx
romanize('백마'); // 'baengma'
romanize('학여울'); // 'hangnyeoul'
romanize('해돋이'); // 'haedoji'
romanize('좋고'); // 'joko'
romanize('압구정'); // 'apgujeong'
romanize('구미'); // 'gumi'
romanize('대관령'); // 'daegwallyeong'
romanize(''); // 'g'
romanize('한국어!'); // 'hangugeo!'
romanize('안녕하세요'); // 'annyeonghaseyo'
```
42 changes: 42 additions & 0 deletions docs/src/pages/docs/api/standardizePronunciation.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: standardizePronunciation
---

# standardizePronunciation

Change the Hangul string to standard pronunciation.

For detailed examples, see below.

```typescript
function standardizePronunciation(
// Input a Hangul string
hangul: string,
options: {
// Set whether to apply hard sounds. Default is true."
hardConversion: boolean;
} = { hardConversion: true }
): string;
```

## Examples

```tsx
standardizePronunciation('디귿이'); // '디그시'
standardizePronunciation('굳이'); // '구지'
standardizePronunciation('담요'); // '딤뇨'
standardizePronunciation('침략'); // '침냑'
standardizePronunciation('먹는'); // '멍는'
standardizePronunciation('신라'); // '실라'
standardizePronunciation('놓고'); // '노코'
standardizePronunciation('곧이듣다'); // '고지듣따'
standardizePronunciation('곧이듣다', { hardConversion: false }); // '고지듣다'
standardizePronunciation('닦다'); // '닥따'
standardizePronunciation('닦다', { hardConversion: false }); // '닥다'
standardizePronunciation('있다'); // '읻따'
standardizePronunciation('있다', { hardConversion: false }); // '읻다'
standardizePronunciation('핥다'); // '할따'
standardizePronunciation('핥다', { hardConversion: false }); // '할다'
standardizePronunciation('젊다'); // '점따'
standardizePronunciation('젊다', { hardConversion: false }); // '점다'
```
42 changes: 42 additions & 0 deletions docs/src/pages/docs/api/standardizePronunciation.ko.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: standardizePronunciation
---

# standardizePronunciation

한글 문자열을 표준 발음법으로 변경합니다.

자세한 예시는 아래 Example을 참고하세요.

```typescript
function standardizePronunciation(
// 한글 문자열을 입력합니다.
hangul: string,
options: {
// 경음화 등의 된소리를 적용할지 여부를 설정합니다. 기본값은 true입니다.
hardConversion: boolean;
} = { hardConversion: true }
): string;
```

## Examples

```tsx
standardizePronunciation('디귿이'); // '디그시'
standardizePronunciation('굳이'); // '구지'
standardizePronunciation('담요'); // '딤뇨'
standardizePronunciation('침략'); // '침냑'
standardizePronunciation('먹는'); // '멍는'
standardizePronunciation('신라'); // '실라'
standardizePronunciation('놓고'); // '노코'
standardizePronunciation('곧이듣다'); // '고지듣따'
standardizePronunciation('곧이듣다', { hardConversion: false }); // '고지듣다'
standardizePronunciation('닦다'); // '닥따'
standardizePronunciation('닦다', { hardConversion: false }); // '닥다'
standardizePronunciation('있다'); // '읻따'
standardizePronunciation('있다', { hardConversion: false }); // '읻다'
standardizePronunciation('핥다'); // '할따'
standardizePronunciation('핥다', { hardConversion: false }); // '할다'
standardizePronunciation('젊다'); // '점따'
standardizePronunciation('젊다', { hardConversion: false }); // '점다'
```
14 changes: 14 additions & 0 deletions src/_internal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,17 @@ export default function assert(condition: boolean, errorMessage?: string): asser
throw new Error(errorMessage ?? 'Invalid condition');
}
}

export function isNotUndefined<T>(value: T | undefined): value is T {
return value !== undefined;
}

export function defined<T>(value: T | undefined): T {
assert(value !== undefined);

return value as T;
}

export function arrayIncludes<Type>(array: Type[] | readonly Type[], item: unknown, fromIndex?: number): item is Type {
return array.includes(item as Type, fromIndex);
}
69 changes: 69 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,75 @@ export const QWERTY_KEYBOARD_MAP = {
M: 'ㅡ',
} as const;

export const 중성_알파벳_발음 = {
// ------- 단모음
: 'a',
: 'eo',
: 'o',
: 'u',
: 'eu',
: 'i',
: 'ae',
: 'e',
: 'oe',
: 'wi',
// -------
// ------- 이중모음
: 'ya',
: 'yeo',
: 'yo',
: 'yu',
: 'yae',
: 'ye',
: 'wa',
: 'wae',
: 'wo',
: 'we',
: 'ui',
} as const;

export const 초성_알파벳_발음 = {
// ------- 파열음
: 'g',
: 'kk',
: 'k',
: 'd',
: 'tt',
: 't',
: 'b',
: 'pp',
: 'p',
// -------
// ------- 파찰음
: 'j',
: 'jj',
: 'ch',
// -------
// ------- 마찰음
: 's',
: 'ss',
: 'h',
// -------
// ------- 비음
: 'n',
: 'm',
: '',
// -------
// ------- 유음
: 'r',
} as const;

export const 종성_알파벳_발음 = {
: 'k',
: 'n',
: 't',
: 'l',
: 'm',
: 'p',
: 'ng',
'': '',
} as const;

export const SUSA_MAP = {
1: '하나',
2: '둘',
Expand Down
10 changes: 6 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
export { acronymizeHangul } from './acronymizeHangul';
export { assembleHangul } from './assemble';
export { chosungIncludes } from './chosungIncludes';
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 { extractHangul } from './extractHangul';
export { hangulIncludes } from './hangulIncludes';
export { josa } from './josa';
export { removeLastHangulCharacter } from './removeLastHangulCharacter';
export { romanize } from './romanize';
export { standardizePronunciation } from './standardizePronunciation';
export { susa } from './susa';
export {
canBeChosung,
canBeJongsung,
Expand All @@ -18,6 +23,3 @@ export {
hasSingleBatchim,
hasValueInReadOnlyStringList,
} from './utils';
export { extractHangul } from './extractHangul';
export { acronymizeHangul } from './acronymizeHangul';
export { susa } from './susa';
81 changes: 81 additions & 0 deletions src/romanize.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { romanize } from './romanize';

describe('romanize', () => {
it('자음 사이에서 동화 작용이 일어나는 경우', () => {
expect(romanize('백마')).toBe('baengma');
expect(romanize('종로')).toBe('jongno');
expect(romanize('왕십리')).toBe('wangsimni');
expect(romanize('별래')).toBe('byeollae');
expect(romanize('신라')).toBe('silla');
});

it('ㄴ, ㄹ’이 덧나는 경우', () => {
expect(romanize('학여울')).toBe('hangnyeoul');
expect(romanize('알약')).toBe('allyak');
});

it('구개음화가 되는 경우', () => {
expect(romanize('해돋이')).toBe('haedoji');
expect(romanize('같이')).toBe('gachi');
expect(romanize('굳히다')).toBe('guchida');
});

it('"ㄱ, ㄷ, ㅂ, ㅈ"이 "ㅎ"과 합하여 거센소리로 소리 나는 경우', () => {
expect(romanize('좋고')).toBe('joko');
expect(romanize('놓다')).toBe('nota');
expect(romanize('잡혀')).toBe('japyeo');
expect(romanize('낳지')).toBe('nachi');
});

it('된소리되기는 표기에 반영하지 않는다', () => {
expect(romanize('압구정')).toBe('apgujeong');
expect(romanize('낙동강')).toBe('nakdonggang');
expect(romanize('죽변')).toBe('jukbyeon');
expect(romanize('낙성대')).toBe('nakseongdae');
expect(romanize('합정')).toBe('hapjeong');
expect(romanize('팔당')).toBe('paldang');
expect(romanize('샛별')).toBe('saetbyeol');
expect(romanize('울산')).toBe('ulsan');
});

it('"ㄱ, ㄷ, ㅂ"은 모음 앞에서는 "g, d, b"로, 자음 앞이나 어말에서는 "k, t, p"로 적는다', () => {
expect(romanize('구미')).toBe('gumi');
expect(romanize('영동')).toBe('yeongdong');
expect(romanize('백암')).toBe('baegam');
expect(romanize('옥천')).toBe('okcheon');
expect(romanize('합덕')).toBe('hapdeok');
expect(romanize('호법')).toBe('hobeop');
expect(romanize('월곶')).toBe('wolgot');
expect(romanize('벚꽃')).toBe('beotkkot');
expect(romanize('한밭')).toBe('hanbat');
});

it('"ㄹ"은 모음 앞에서는 "r"로, 자음 앞이나 어말에서는 "l"로 적는다. 단, "ㄹㄹ"은 "ll"로 적는다', () => {
expect(romanize('구리')).toBe('guri');
expect(romanize('설악')).toBe('seorak');
expect(romanize('칠곡')).toBe('chilgok');
expect(romanize('임실')).toBe('imsil');
expect(romanize('울릉')).toBe('ulleung');
expect(romanize('대관령')).toBe('daegwallyeong');
});

it('완성된 음절이 아닌 경우에는 그대로 반환한다', () => {
expect(romanize('ㄱ')).toBe('g');
expect(romanize('가나다라ㅁㅂㅅㅇ')).toBe('ganadarambs');
expect(romanize('ㅏ')).toBe('a');
expect(romanize('ㅘ')).toBe('wa');
});

it('특수문자는 로마자 표기로 변경하지 않는다', () => {
expect(romanize('안녕하세요.')).toBe('annyeonghaseyo.');
expect(romanize('한국어!')).toBe('hangugeo!');
expect(romanize('')).toBe('');
expect(romanize('!?/')).toBe('!?/');
});

it('한글과 영어가 혼합된 경우에는 영어는 그대로 반환된다', () => {
expect(romanize('안녕하세요 es-hangul')).toBe('annyeonghaseyo es-hangul');
expect(romanize('한국은korea')).toBe('hangugeunkorea');
expect(romanize('고양이는cat')).toBe('goyangineuncat');
});
});
Loading

0 comments on commit 84584d4

Please sign in to comment.