GNU gettext를 사용한 소프트웨어 번역¶
GNU gettext 는 자유 소프트웨어 국제화에 가장 널리 사용되는 도구 중 하나입니다. 간단하면서도 유연한 방식으로 소프트웨어를 현지화할 수 있습니다. 복수형에 대한 훌륭한 지원을 제공하고 번역 문자열에 추가 컨텍스트를 추가할 수 있으며 이를 기반으로 구축된 도구가 많습니다. 물론 Weblate에서도 훌륭하게 지원됩니다 ( GNU gettext PO (Portable Object) 파일 형식 설명 참조).
참고
독점 소프트웨어에서 사용하려는 경우 먼저 라이선스를 확인하세요. 적합하지 않을 수 있습니다.
GNU gettext는 다양한 언어 (C, Python, PHP, Ruby, JavaScript 등)에서 사용할 수 있으며 일반적으로 UI 프레임워크에서 이미 일부 지원을 제공합니다. 표준 사용법은 gettext() 함수 호출을 통해서이며, 코드를 더 간단하고 읽기 쉽게 하기 위해 종종 _() 로 별칭이 지정됩니다.
또한 번역자에게 추가 컨텍스트를 제공하는 pgettext() 호출과 대상 언어에 정의된 대로 복수형을 처리할 수 있는 ngettext() 를 제공합니다.
널리 사용되는 도구로서 사용을 매우 간단하게 만드는 많은 래퍼가 있습니다. 아래에 설명된 gettext의 수동 호출 대신 예를 들어 intltool 같은 것을 시도해 볼 수 있습니다.
워크플로 개요¶
GNU gettext는 현지화를 관리하기 위해 여러 파일을 사용함:
PACKAGE.pot에는 소스 코드에서 추출된 문자열이 포함되어 있습니다. 일반적으로 xgettext 또는 intltool 과 같은 일부 상위 래퍼를 사용합니다.LANGUAGE.po에는 단일 언어로의 번역이 포함된 문자열이 있습니다.PACKAGE.pot이 업데이트되면 msgmerge 로 업데이트해야 합니다. msginit 또는 Weblate 내에서 새 언어 파일을 만들 수 있습니다.LANGUAGE.mo는LANGUAGE.po의 이진 표현을 포함하며 애플리케이션 런타임에 사용됩니다. 일반적으로 버전 관리에 보관되지 않으며 msgfmt 를 사용하여 컴파일 시 생성됩니다. 버전 관리에 포함하려면 MO 파일 생성 애드온을 사용하여 Weblate에서 생성할 수 있습니다.
전체적으로 GNU gettext 워크플로는 다음과 같음:
더 보기
샘플 프로그램¶
gettext를 사용하는 간단한 C 프로그램은 다음과 같음:
#include <libintl.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int count = 1;
setlocale(LC_ALL, "");
bindtextdomain("hello", "/usr/share/locale");
textdomain("hello");
printf(
ngettext(
"Orangutan has %d banana.\n",
"Orangutan has %d bananas.\n",
count
),
count
);
printf("%s\n", gettext("Thank you for using Weblate."));
exit(0);
}
번역 가능한 문자열 추출¶
gettext 호출을 사용하는 코드가 있으면 xgettext 를 사용하여 메시지를 추출하고 .pot 에 저장할 수 있음:
$ xgettext main.c -o po/hello.pot
참고
코드에서 문자열을 추출하는 대체 프로그램도 있습니다. 예를 들어 pybabel.
이렇게 하면 새 번역을 시작하거나 (msginit 사용) 코드 변경 후 기존 번역을 업데이트하는 데 (msgmerge 사용) 사용할 수 있는 템플릿 파일이 생성됩니다. 결과 파일은 단순한 구조화된 텍스트 파일임:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-10-23 11:02+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
#: main.c:14
#, c-format
msgid "Orangutan has %d banana.\n"
msgid_plural "Orangutan has %d bananas.\n"
msgstr[0] ""
msgstr[1] ""
#: main.c:20
msgid "Thank you for using Weblate."
msgstr ""
각 msgid 행은 번역할 문자열을 정의하며, 시작 부분의 특별한 빈 문자열은 번역에 대한 메타데이터를 포함하는 파일 헤더입니다.
새 번역 시작¶
템플릿이 준비되면 첫 번째 번역을 시작할 수 있음:
$ msginit -i po/hello.pot -l cs --no-translator -o po/cs.po
Created cs.po.
방금 생성된 cs.po 에는 이미 일부 정보가 채워져 있습니다. 가장 중요한 것은 선택한 언어에 대한 적절한 복수형 정의가 포함되어 있어 복수형 수가 그에 따라 변경된 것을 확인할 수 있음:
# Czech translations for PACKAGE package.
# Copyright (C) 2015 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# Automatically generated, 2015.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-10-23 11:02+0200\n"
"PO-Revision-Date: 2015-10-23 11:02+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
#: main.c:14
#, c-format
msgid "Orangutan has %d banana.\n"
msgid_plural "Orangutan has %d bananas.\n"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
#: main.c:20
msgid "Thank you for using Weblate."
msgstr ""
이 파일은 최적화된 이진 형태로 컴파일되며, 런타임에 GNU gettext 함수가 사용하는 .mo 파일입니다.
문자열 업데이트¶
프로그램에 더 많은 문자열을 추가하거나 일부 문자열을 변경하면 xgettext 를 다시 실행하여 템플릿 파일을 다시 생성함:
$ xgettext main.c -o po/hello.pot
그런 다음 새로 생성된 템플릿에 맞게 개별 번역 파일을 업데이트할 수 있습니다 (새 템플릿에 맞게 문자열 순서를 다시 지정하는 것이 포함됩니다):
$ msgmerge --previous --update po/cs.po po/hello.pot
참고
Weblate를 사용할 때 일반적으로 msgmerge를 수동으로 실행할 필요가 없습니다. Weblate는 PO 파일을 POT에 맞게 업데이트 (msgmerge) 애드온을 통해 이를 자동으로 처리하거나 원문 문자열 업데이트 업로드 방법을 사용하여 업데이트된 POT 파일을 업로드할 수 있습니다. 자세한 내용은 대상 언어 파일 업데이트 를 참조하세요.
Weblate로 가져오기¶
이러한 번역을 Weblate로 가져오려면 구성요소를 만들 때 다음 필드를 정의하기만 하면 됩니다 (필드에 대한 자세한 설명은 구성요소 설정 참조):
필드 |
값 |
|---|---|
소스 코드 저장소 |
프로젝트가 있는 VCS 저장소의 URL |
파일 마스크 |
|
신규 번역의 템플릿 |
|
파일 형식 |
gettext PO 파일 선택 |
새 언어 |
새 언어 파일 만들기 선택 |
이것으로 끝입니다. 이제 소프트웨어 번역을 시작할 준비가 되었습니다!
더 보기
GitHub의 Weblate Hello 프로젝트에서 다양한 언어의 gettext 예제를 찾을 수 있습니다: <https://github.com/WeblateOrg/hello>.