Переклад програмного забезпечення за допомогою GNU gettext

GNU gettext є одним із найпоширеніших інструментів перекладу вільного програмного забезпечення. Він надає простий, але гнучкий спосіб локалізації програмного забезпечення. У ньому передбачено чудову підтримку форм множини, у ньому можна додавати контекст до перекладеного рядка, на його основі побудовано доволі багато інших інструментів. Звичайно ж, його підтримку реалізовано у Weblate на найвищому рівні (див. опис формату файлів GNU gettext PO (портативний об’єкт)).

Примітка

Якщо ви хочете скористатися цим форматом у закритому програмному забезпеченні, будь ласка, спочатку ознайомтеся із умовами ліцензування — може так статися, що ці умови видадуться вам непридатними.

GNU gettext можна скористатися у коді широким спектром мов (C, Python, PHP, Ruby, JavaScript тощо) і, зазвичай, в оболонках інтерфейсу користувача передбачено певну його підтримку. Стандарт полягає у використанні виклику функції gettext(), альтернативним варіантом якої є _(), що спрощує код і робить його придатнішим для читання.

Крім того, інструмент надає у ваше розпорядження виклик pgettext(), за допомогою якого можна надати додатковий контекст перекладачам, і виклик ngettext(), який може обробляти типи форм множини, які визначено для мови перекладу.

Як широко розповсюджений інструмент, він має багато обгорток, які роблять користування ним дуже простим. Замість виклику gettext вручну, який описано нижче, ви можете скористатися однією з обгорток, наприклад intltool.

Огляд робочого процесу

Для керування локалізацією у GNU gettext використовують декілька файлів:

  • ПАКУНОК.pot містить рядки, які було видобуто з початкового коду, типово, за допомогою xgettext або якихось обгорток вищого рівня, зокрема intltool.

  • МОВА.po містить рядки із перекладами окремою мовою. Оновлення цього файла відбувається за допомогою msgmerge після оновлення файла ПАКУНОК.pot. Створити файл для нової мови можна за допомогою msginit або самого Weblate.

  • МОВА.mo містить двійкове представлення вмісту файлу МОВА.po і використовується під час роботи застосунку. Типово, такі файли не розміщуються у системі керування версіями, а створюються під час збирання пакунка за допомогою msgfmt. Якщо ви хочете зберігати ці файли у системі керування версіями, ви можете створити їх за допомогою додатку Weblate Генерувати mo-файли.

Загалом робочий процес GNU gettext виглядає так:

digraph translations { graph [fontname = "sans-serif", fontsize=10]; node [fontname = "sans-serif", fontsize=10, shape=note, margin=0.1, height=0]; edge [fontname = "monospace", fontsize=10]; "Source code" -> "PACKAGE.pot" [label=" xgettext "]; "PACKAGE.pot" -> "LANGUAGE.po" [label=" msgmerge "]; "LANGUAGE.po" -> "LANGUAGE.mo" [label=" msgfmt "]; }

Дивись також

Огляд GNU gettext

Зразок програми

Проста програма мовою 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);
}

Видобування рядків для перекладу

Щойно у вас буде код, де використовуються виклики 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 ""

Цей файл компілюється у оптимізовану двійкову форму — файл .mo, який використовується GNU gettext функціями під час роботи.

Оновлення рядків

Після додавання рядків або зміни рядків у вашій програм, ви можете запустити xgettext знову і повторно створити файл шаблона:

$ xgettext main.c -o po/hello.pot

Далі, ви можете оновити окремі файли перекладів, щоб вони відповідали новоствореному шаблону (це стосується і перевпорядковування рядків відповідно до нового шаблона):

$ msgmerge --previous --update po/cs.po po/hello.pot

Імпортування до Weblate

Щоб імпортувати такий переклад до Weblate, вам достатньо визначити вказані нижче поля при створенні складника (див. Налаштовування складників для докладного опису полів):

Поле

Значення

Сховище з джерелами

Адреса сховища VCS із вашим проєктом

Маска файлів

po/*.po

Шаблон для нових перекладів

po/hello.pot

Формат файлу

Виберіть файл PO gettext

Нова мова

Виберіть Створити новий мовний файл

Ось і все — можна починати переклад вашого програмного забезпечення!

Дивись також

Ви можете знайти приклад gettext із багатьма мовами у проєкті Weblate Hello на GitHub: <https://github.com/WeblateOrg/hello>.