태국어 조합 원리

자음·모음·성조 조합, 단어 공백 없음·단어 경계, 그래핀·커서·삭제 단위

태국어는 자음·모음(위/아래/좌우 결합)·성조가 한 음절 안에서 겹쳐 쓰인다. 유니코드에는 자음 + 결합 모음 + 결합 성조여러 코드 포인트로 저장될 수 있어, “한 글자”가 그래핀 클러스터 단위가 된다. 또한 단어 사이에 공백을 두지 않는 경우가 많아 단어 경계 계산이 별도로 필요하다.


1. 문자 구성

1.1 자음·모음·성조

  • 자음: 초기 자음 44자, 종성 자음 등. 유니코드 블록 Thai (U+0E00~U+0E7F).
  • 모음: 위·아래·좌우에 붙는 결합 문자(combining character) 또는 독립 모음. 같은 음절이 한 코드 포인트(precomposed) 또는 자음 + 결합 모음(decomposed)로 저장될 수 있다.
  • 성조: 결합 문자로 표기. 음절 전체가 여러 코드 포인트로 이뤄질 수 있다.

1.2 유니코드·그래핀 클러스터

  • 한 음절이 사용자 눈에는 “한 글자”지만, 내부적으로는 자음(U+0E01~) + 결합 모음(U+0E34 등) + 결합 성조여러 코드 포인트 시퀀스다.
  • 그래핀 클러스터(UAX #29)가 “사용자 인식 문자” 단위에 해당한다. 커서 이동·한 글자 삭제·선택 시 코드 유닛/코드 포인트가 아니라 그래핀 클러스터 경계를 써야 한다.

2. 단어 공백 없음·단어 경계

  • 태국어는 단어와 단어 사이에 공백을 두지 않는 경우가 많다. 따라서 “단어” 경계는 공백이 아니라 유니코드 텍스트 세그멘테이션(UAX #29 word boundary) 또는 사전·언어 모델에 의존해야 한다.
  • Intl.Segmenter (granularity: 'word', locale: 'th')로 단어 경계를 얻을 수 있다. 지원 환경에서는 이 API를 사용하면 된다. UAX #29(Unicode Text Segmentation)에 단어 경계 규칙이 정의되어 있다.

3. 그래핀·커서·삭제 단위

3.1 커서 이동

  • 한 글자 단위 이동 시 그래핀 클러스터 경계를 사용한다. 코드 포인트 단위로만 이동하면 한 음절 중간에 커서가 서거나, 결합 문자가 쪼개질 수 있다.
  • Intl.Segmenter (granularity: 'grapheme', locale: 'th')로 그래핀 경계를 얻을 수 있다.

3.2 한 글자 삭제

  • Backspace/Delete 시 삭제할 범위를 그래핀 클러스터(또는 최소한 코드 포인트) 단위로 정한다. 코드 유닛 1개만 지우면 UTF-16에서 서로게이트가 깨질 수 있고, 코드 포인트 1개만 지우면 결합 문자가 분리될 수 있다.

3.3 선택

  • 드래그로 “한 글자” 선택 시 그래핀 클러스터 단위로 선택 범위를 맞추면, 음절이 반만 선택되는 일을 줄일 수 있다.

4. IME·composition

  • OS 태국어 키보드가 자음 + 모음 + 성조 조합을 처리한다. compositionstartcompositionupdatecompositionend가 발생할 수 있고, 환경에 따라 insertText만 올 수도 있다.
  • 에디터는 composition 시나리오별 처리 규칙에 따라, composition이 오면 조합 구간으로, 오지 않으면 insertText로 처리하면 된다.

5. 참고

  • 유니코드 기본 — 코드 포인트, 서로게이트, 그래핀 클러스터 개념.
  • 이모지 — 여러 코드 포인트가 한 “글자”가 되는 경우, Intl.Segmenter 사용.
  • UAX #29 (Unicode Text Segmentation): 그래핀·단어·문장 경계 정의.