Перевод программ с помощью GNU Gettext¶
GNU Gettext является одним из наиболее широко используемых инструментов интернационализации свободного программного обеспечения. Он предоставляет простой, но гибкий способ локализации программного обеспечения. Он имеет отличную поддержку форм множественного числа, может добавлять к переводимым строкам дополнительный контекст и на его основе построено довольно большое количество инструментов. И конечно, он имеет отличную поддержку в Weblate (смотрите описание формата файла GNU gettext).
Примечание
Если вы собираетесь использовать его в несвободном программном обеспечении, пожалуйста, сначала ознакомьтесь с его лицензией, она может оказаться для вас непригодной.
GNU Gettext можно использовать со множеством различных языков (C, Python, PHP, Ruby, JavaScript и со многими другими), и обычно во фреймворках пользовательского интерфейса уже есть некоторая его поддержка. Стандартным его использованием является вызов функции gettext(), которая часто сокращается до своего псевдонима _(), чтобы сделать код более простым и лёгким для чтения.
Дополнительно он предоставляет вызовы pgettext(), позволяющий предоставлять дополнительный контекст для переводчиков, и ngettext(), который умеет обрабатывать формы множественного числа по правилам целевого языка.
Как широко распространённый инструмент, для него существует множество обёрток, значительно упрощающих его использование; вместо описанного ниже ручного вызова Gettext, вы, возможно, захотите попробовать одну из них, например, intltool.
Workflow overview¶
The GNU Gettext uses several files to manage the localization:
PACKAGE.pot
contains strings extracted from your source code, typically using xgettext or some high level wrappers such as intltool.LANGUAGE.po
contains strings with a translation to single language. It has to be updated by msgmerge once thePACKAGE.pot
is updated. You can create new language files using msginit or within Weblate.LANGUAGE.mo
contains binary representation ofLANGUAGE.po
and is used at application runtime. Typically it is not kept under version control, but generated at compilation time using msgfmt. In case you want to have it in the version control, you can generate it in Weblate using Генерирование MO-файлов addon.
Overall the GNU Gettext workflow looks like this:
См.также
Пример программы¶
Простая программа на C, использующая Gettext, может выглядеть следующим образом:
#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);
}
Извлечение строк для перевода¶
Once you have code using the gettext calls, you can use xgettext to extract messages from it and store them into a .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 ""
Этот файл компилируется в оптимизированную двоичную форму — файл .mo, используемый функциями GNU Gettext времени выполнения.
Обновление строк¶
Once you add more strings or change some strings in your program, you execute again xgettext which regenerates the template file:
$ xgettext main.c -o po/hello.pot
Затем вы можете обновить отдельные файлы перевода, чтобы они соответствовали вновь созданным шаблонам (обновление, в том числе, переупорядочивает строки для соответствия их новому шаблону):
$ msgmerge --previous --update po/cs.po po/hello.pot
Импорт в Weblate¶
Для импорта такого перевода в Weblate, всё, что вам нужно — это определить следующие поля при создании компонента (подробное описание полей смотрите в разделе в Конфигурация компонента):
Поле |
Значение |
---|---|
Репозиторий исходного кода |
URL-адрес репозитория системы контроля версий с вашим проектом |
Маска файла |
|
Шаблон для новых переводов |
|
Формат файла |
Выберите gettext PO-файл |
Новый язык |
Выберите Создать новый язык |
Вот и всё, теперь вы готовы начать переводить свою программу!
См.также
Пример использования Gettext со многими языками можно найти в проекте Weblate Hello на GitHub’е: <https://github.com/WeblateOrg/hello>.