1 minute read

레트로 게임을 하다보면 을/를, 이/가 와 같은 조사들을 괄호를 통해 (을)를, (이)가 식으로 함께 표기해둔것을 흔히 볼수 있다. 예상하기로는 외국어를 한글로 현지화하는 과정에서 {name}(이)가 승부를 걸어왔다! 식으로 문자열 탬플릿을 작성해두고 name 변수를 조합하는 방식을 차용하여 아래와 같은 괄호 표기가 나온것이 아닐까 한다.

pokemon gold game screenshot

탬플릿 문자열은 i18next 등으로 다국어를 지원할때에 흔히 사용하는 방식이다. 명사/대명사 등을 동적으로 변수를 통해 적용할때에 json 형식으로 문자열을 선언해두고, 사용부에서 매개변수에 값을 넘기는 식으로 동적으로 변경되어야하는 문장의 현지화를 지원하고는 한다.

  • {fieldName}(을)를 입력하세요.
  • {a}(와)과 {b}(을)를 선택해주세요.
  • {userName}(이)가 메시지를 보냈습니다.

i18next 형식으로 나타내보자면 아래와 같다.

const translation = {
  wild_pokemon_appeared: "야생의 {pokemon}(이)가 튀어나왔다!"
}
t('wild_pokemon_appeared', {pokemon: '리자몽'}) // 야생의 리자몽(이)가 튀어나왔다! 

을/를, 이/가 중 무엇을 붙힐지 계산하는 방법은 검색을 통해 쉽게 찾을 수 있는데, String.prototype.charCodeAt 을 통해 변수로 들어올 명사의 마지막 글자의 유니코드를 확인하는 방법을 사용할 수 있다. (참고)

/**
 * 마지막 글자가 받침을 가지는지 확인
 */
function checkBatchimEnding(word: string): boolean {
  const lastLetter = word[word.length - 1];
  const uni = lastLetter.charCodeAt(0);

  // 한글 범위 밖일 경우 false
  if (uni < 44032 || uni > 55203) return false;

  // 받침이 있을 경우 true
  return (uni - 44032) % 28 !== 0;
}

checkBatchimEnding('리자몽') // true
checkBatchimEnding('피카츄') // false

다음으로 checkBatchimEnding 을 이용하여 i18next 로 변수에 따라 조사를 달아주는 포멧팅 함수를 정의해보자. i18next 의 i18next.services.formatter.add 을 이용하여 정의할 수 있다. (참고)

i18next.services.formatter.add('이가', value => {
  return value + (checkBatchimEnding(value) ? '' : '');
});

i18next.services.formatter.add('을를', value => {
  return value + (checkBatchimEnding(value) ? '' : '');
});

함수명이 이가, 을를 인 받침이 있느냐 없느냐에 따라 조사를 붙혀주는 포멧 함수를 만들었다. 이 함수는 i18n 다국어 탬플릿내에 다음과 같이 사용할 수 있다. 함수명을 이례적으로 한글로 명명한 이유는 다국어 탬플릿만 보아도 자연스럽게 의미가 설명 될 수 있게하기 위함이다.

const translation = {
  wild_pokemon_appeared: "야생의 {pokemon, 이가} 튀어나왔다!",
  caught_a_pokemon: "신난다! {pokemon, 을를} 잡았다!"
}
t('wild_pokemon_appeared', {pokemon: '리자몽'}) // 야생의 리자몽이 튀어나왔다!
t('caught_a_pokemon', {pokemon: '피카츄'}) // 신난다! 피카츄를 잡았다!

i18next 는 위와 같은 formatting 이외에도 많은 유틸리티 기능을 제공한다. 이와 같이 값에 따라 동적으로 문자열을 변경해야할때에 찾아보면 썩 도움이 될만한 기능들이 많은것같다.

예시로 작성한 실행 가능한 코드를 github 에 올려두었다.

https://github.com/kjkandrea/i18next-josa/blob/main/src/main.ts

Categories:

Updated: