배틀넷 런처.. 새로운 UI로 바뀌었네요.

오랜만에 업데이트했는데, 초기화면에서 바로 L10N 이슈를 찾았습니다.

 

# 맥락없이 번역했을 때 발생할 수 있는 일들

메인화면에서 게임을 즐겨찾기하거나 즐겨찾기에서 게임을 뺄 수 있는데요.

아래 두 화면에서 툴팁을 보시면 바로 L10N(Localization)중 번역 문자열 이슈가 보입니다.

 

 

정황상 소셜 패널에 영문으로 "Add To Favorites"라는 문자열이 두군데 모두 사용되었고, 번역대상 문자열을 뽑다가 어떤 맥락에서 사용된 것인지 모르는 채로 번역팀에 "Add To Favorites"가 전달되어 두 곳 모두  "친한 친구에 추가"로 모두 처리한 것이 아닌가 싶습니다.

이 문제가 번역 과정만의 문제인가? 사실 그렇지는 않습니다.

번역팀(혹은 외부 전문 업체)에서는 소스코드에 접근하는 것이 아니므로 어떤 맥락(상황)에서 해당 문장이 사용되었는지의 정보가 함께 있을 때 정확한 번역이 이루어질 수 있습니다. 

 

예를 들어 크로스 플랫폼 UI를 제공하는 Qt Framework에서 L10N을 지원하기 위해 코드에서는 tr함수를 이용합니다.

QPushButton hello(QPushButton::tr("Hello world!"));

lupdate명령을 통해 소스에서 tr로 된 문자열을 뽑아내죠. 이 과정은 C계열 오픈소스 프로젝트에서 사용하는  po에서도 비슷합니다.

 

보통은 위와 같이 코드에서 다국어 지원을 표시하는데, 번역대상인 문장만으로는 오해의 가능성이 존재합니다.

 

송수신자의 이름을 입력받는 대화창을 생각해 봅시다.

Qt를 이용한다면 다음과 같은 코드가 작성되겠죠.

    QLabel *senderLabel = new QLabel(tr("Name:"));
    QLabel *recipientLabel = new QLabel(tr("Name:"));

lupdate를 하면 dialog.cpp에서 사용되는 L10N대상 문자열은 "Name:"이 추출될 것입니다. 번역팀은 이 정보만 있으니 "이름:"으로 번역해서 업데이트가 되겠죠. 이 번역파일이 적용되면 송수신자 대화상자에 "이름:"이라고만 표시되는 레이블이 2개가 있을 겁니다.

 

이러한 모호성을 없애기 위하여 두번째 인자로 맥락 정보를 제공해 주는 것이 좋습니다.

    QLabel *senderLabel = new QLabel(tr("Name:", "sender"));
    QLabel *recipientLabel = new QLabel(tr("Name:", "recipient"));

즉, "Name:" 이라고 사용되었지만 recipient라는 맥락이 있으니 '이름:'이라는 일반적인 번역 대신 첫번째는 '발송인', 두번째는 '수취인'으로 번역될 수 있겠죠. 정보는 더 많아지지만, 코드는 조금  지저분한 느낌이 드는 것은 사실입니다.

 

비슷한 사례로 인쇄 옵션이 생각나네요. 영어로 가로 출력과 세로 출력이 'Landscape'와 'Portrait'인데, 단어 자체의 뜻은 각각 '조경'과 '초상화'라는 뜻이죠. 그래서 단어만 보고 번역되었을 경우 인쇄 옵션에 생뚱맞게 조경과 초상화가 등장하기도 합니다.

 

개발자분들에게 팁을 드리자면 L10N처리는 문장 단위가 되어야 합니다.

제가 배틀넷 런처 개발당시 겪었던 일을 대략적으로만 소개하겠습니다.(시간은 좀 지났으나..그래도 자세하게 했던 일을 공유하는 것을 피하는것이 제 원칙이라..)

사용자에게 어떤 메시지를 날짜/시간 정보와 함께 표시해야 하는 기능이었는데, 전 포맷팅 문자열을 국가별로 다른 부분만 tr처리를 해서 문장의 일부 부분을 바꾸었습니다. 그랬더니 보스가 절 부르더니 (예가 정확히 기억나지 않는데..) 국가별로 문장 방식이 다를 수 있으니 바뀔 수 있는 부분 말고 문장 단위로 바꾸게끔 것을 가이드하더군요. 그때부터 L10N은 문장 단위로 끊어서 코드에 작성했습니다.

 

 

#L10N, 문장 번역을 넘어서

L10N은 단순히 번역 문제만 말하는 것은 아니고 복잡한 주제들이 있습니다. 대표적으로 표시 형식과 특정 언어만 가지는 문제들이 있죠.

우리가 다루는 데이터에는 날짜, 시간, 숫자(특히 화폐..) 등이 있죠. 날짜만 봐도 2021/03/06, 03/06/2021, 06/03/2021, Mar/06/2021, 2021-03-06 등등 많은 표시형식들이 각 나라별로 있습니다. 화폐단위만 봐도 달러는 센트단위가 있어서 123.45 달러라 표시하면 123달러 45센트가 됩니다만, 원화에서는 소숫점 아래 자리가 없죠. (전이라는 단위가 있긴 합니다만 사용하지 않습니다.)

 

수치표현도 복잡해 집니다. 우리나라를 비롯한 아시아권에서는 주로 만단위의 숫자를 표시하지만 영미권은 천단위로 숫자를 읽습니다. '123,456'의 의미는 뭘까요? 대부분 우리나라사람들은 '12만 3천4백5십6'으로 읽을 겁니다. 하지만 프랑스에서는 '1백2십3 쩜 사오육(소숫점)'으로 이해됩니다. 와우~. 궁금하신분은 Decimal Separator를 읽어보세요. 

 

복수형표시문제, 단어의 성별...

표시형식 문제에 복수형도 복잡하죠.  Qt 문서사이트에 소개된 예를 들어봅시다.

우리나라만 대상으로 하는 소프트웨어를 개발한다고 하면 다음과 같이 코드를 작성하겠죠.

  QString *receivedMessageNotificationFormatter = tr("%d개의 메시지가 도착하였습니다.");

우리나라에서는 몇개의 메시지가 도착하든 상관없이 저 문장 하나로 처리됩니다.

그런데 다음 표를 보세요.

 

프랑스에서는 0개 또는 1개일때는 s가 붙지 않고, 2개 이상에는 s가 붙습니다. (메시지에도 s가 붙고 저장되었다는 동사에도 s가 붙습니다.)

영어에서는 0개또는 2개 이상일 때 s가 붙습니다.(메시지에만 s가 붙고, 동사에는 s가 붙지 않습니다.) 1개일 경우 s가 붙지 않습니다. 

즉, 복수형의 기준 잣대가 언어별로 다르다는 이야기입니다. 특정 국가에서는 단어의 성별에 따라 이어지는 단어의 형태가 바뀌어야 하는 경우도 있습니다.

 

라틴어계열만 그런 것은 아닙니다. 우리말에도 '은는이가'가 있죠.

'닭은 동물이다'와 '고양이는 동물이다'라는 문장이 있죠. '%s은(는) 동물이다'로 표현하는데, 좀 더 매끄러운 문장을 만들려면 %s에 해당하는 단어의 끝 받침에 따라서 '은' 또는 '는'이 선택되어야 하죠.

 

코드에서 L10N을 고려하기 시작하면 챙겨야 할 것들이 많이 있습니다. 하지만 너무 걱정하지 않으셔도 됩니다. 많이 사용되는 L10N 이슈들은 대부분 프레임워크나 운영체제 레벨에서 제공하는 API 또는 정보를 활용하면 됩니다.

 

 

배틀넷 번역때문에 L10N을 문자열 중심으로만 소개했는데, 이미지도 L10N 대상입니다.

우리가 흔히 접하는 이미지(기호)가 국가에 따라 다른 의미를 가질 수도 있기 때문입니다. 널리 알려진 예가 미키마우스 손가락 갯수입니다. 자세히 보신 분들이 있으실 것 같은데 미키마우스는 손가락이 4개입니다. 미키마우스가 일본에서 처음 방영되었을 때 일본 시청자들은 심리적으로 이상한 감정을 느꼈다고 합니다. 지금도 그런지 확인해봐야 합니다만,  일본에서 4손가락은 야쿠자(조폭)이미지를 떠올린다고 합니다. 일본 영화에 가끔 단지 장면이 나오잖아요. "귀여운 미키가 야쿠자라니"라는 무의식이 동작했었다고 하네요. 그래서 L10N에는 번역만 있는 것이 아니라 특정 국가에서 다른 의미나 뉘앙스를 가지는 기호체계를 현지화하는 것이 포함됩니다.

개발에서는 이 문제를 쉽게 resource overriding으로 해결할 수 있습니다.

예를 들어 symbol1.png 이미지가 특정 국가에서는 다르게 바뀌어야 한다면 리소스를 처리하는 부분에서 다음과 같은 방식으로 변경하면 되겠죠? 코드를 아래와 같이 사용하려면 소프트웨어 리소스의 위치 구조도 처음부터 잘 고려해야 합니다.

if (file_exist("{current_locale}/symbol1.png")) {
 return {current_locale}/symbol1.png;
} else {
  return general/symbol1.png;
}

 

배틀넷 런처에서 찾은 번역 오류 이야기하다가 코드 이야기로 빠져서 L10N까지 슬쩍 이야기해보았습니다.

글로벌용 소프트웨어/서비스를 만드는데 작은 도움이 되길 바랍니다.

 

사족

설치/업데이트가 끝나면 "완료하는 중"으로 표시되는데, "마무리 중"이 더 우리글 스럽지 않나 생각되네요.

 

'2. 개발 > 2.0 General' 카테고리의 다른 글

네트워크 연결 테스트와 ping?  (0) 2021.04.03
배틀넷 런처에서 찾은 L10N 이슈  (0) 2021.03.05

+ Recent posts