Szoftverfordítás GNU gettext segítségével

A GNU gettext az egyik legszélesebb körben használt eszköz a szabad szoftverek nemzetközivé tételére. Egyszerű, de rugalmas megoldást kínál a szoftver lokalizálására. Kiválóan kezeli a többes számokat, lehetőséget ad extra kontextus megadására a fordítandó szöveghez, és rengeteg kiegészítő eszköz áll rendelkezésre hozzá. Természetesen a Weblate is teljes körűen támogatja (lásd: GNU gettext PO (Portable Object) fájlformátum-leírás).

Megjegyzés

Ha zárt forráskódú szoftverben szeretné használni, először tájékozódjon a licencfeltételekről, mivel lehet, hogy nem alkalmas az Ön számára.

A GNU gettext számos nyelvből elérhető (pl. C, Python, PHP, Ruby, JavaScript és mások), általában a felhasználói felülethez használt keretrendszerek már beépített támogatással rendelkeznek hozzá. Az alapvető használata a gettext() függvényhíváson keresztül történik, amelyet gyakran _() rövidítéssel használnak, hogy a kód olvashatóbb legyen.

Emellett elérhető a pgettext() hívás is, amely lehetővé teszi, hogy a fordítók számára további kontextust adjunk meg, valamint az ngettext() hívás, amely képes a célnyelvre jellemző többes számú alakok kezelésére.

Mivel széles körben használt eszköz, számos segédfelület (wrapper) létezik hozzá, amelyek egyszerűsítik a használatát — így nem kell manuálisan használni az alább leírt gettext parancsokat. Például érdemes kipróbálni az intltool eszközt.

Munkafolyamat áttekintése

A GNU gettext több fájlt használ a lokalizáció kezelésére:

  • PACKAGE.pot – A forráskódból kinyert szövegeket tartalmazza, tipikusan xgettext vagy magasabb szintű eszközök (pl. intltool) segítségével jön létre.

  • LANGUAGE.po – Egy adott nyelvre lefordított szövegeket tartalmaz. A PACKAGE.pot frissítése után a msgmerge eszközzel kell naprakésszé tenni. Új nyelvi fájlokat msginit segítségével vagy a Weblate-ben is létre lehet hozni.

  • LANGUAGE.mo – a LANGUAGE.po bináris formátumú megfelelője, és az alkalmazás futása során kerül felhasználásra. Általában nem kerül verziókezelés alá, hanem fordításkor automatikusan generálódik a msgfmt segítségével. Amennyiben mégis szeretné verziókezelésben tárolni, a Weblate-ben létrehozhatja az MO-fájlok generálása kiegészítő segítségével.

Összességében a GNU gettext munkafolyamata így néz ki:

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 "]; }

Példaprogram

Egy egyszerű C nyelvű program gettext használatával így nézhet ki:

#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);
}

Fordítható szövegek kinyerése

Miután a kód már használja a gettext hívásokat, az xgettext eszközzel kinyerheti belőle az üzeneteket, és egy .pot fájlba mentheti őket:

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

Megjegyzés

Léteznek alternatív eszközök is a szövegek kinyerésére, például a pybabel.

Ez létrehoz egy sablonfájlt, amely új fordítások indításához használható (ehhez a msginit parancsot alkalmazhatja) vagy meglévő fordítások frissítéséhez kódbeli változás után (ehhez a msgmerge való). Az eredményül kapott fájl egyszerű, strukturált szövegfájl:

# 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 ""

Minden egyes msgid sor egy lefordítandó szöveget jelöl. A fájl elején szereplő speciális üres sztring a fájl fejlécét adja, amely a fordításhoz tartozó metaadatokat tartalmazza.

Új fordítás indítása

Ha a sablon már rendelkezésre áll, megkezdhetjük az első fordítást:

$ msginit -i po/hello.pot -l cs --no-translator -o po/cs.po
Created cs.po.

A most létrehozott cs.po fájl már tartalmaz néhány előre kitöltött információt. A legfontosabb, hogy a kiválasztott nyelvhez megfelelő többes szám definíció kerül bele, ennek megfelelően a többes számú alakok száma is megváltozik:

# 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 ""

Ez a fájl egy optimalizált bináris formátumba fordul le, amely a .mo fájl – ezt használják a GNU gettext függvények futásidőben.

Szövegek frissítése

Amikor új szövegeket ad hozzá programjához vagy meglévő szövegeket módosít, ismét futtassa a xgettext parancsot, amely újragenerálja a sablonfájlt:

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

Ezután frissítheti az egyes nyelvi fájlokat, hogy azok megfeleljenek az új sablonnak (ez magában foglalja a szövegek sorrendjének igazítását is az új sablonhoz):

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

Megjegyzés

When using Weblate, you typically don’t need to run msgmerge manually. Weblate can handle this automatically through the PO-fájlok frissítése a POT-fájlhoz igazítva (msgmerge) add-on, or you can upload the updated POT file using the Update source strings upload method. See Célnyelvi fájlok frissítése for details.

Importálás Weblate-be

Egy ilyen fordítás Weblate-be való importálásához csak az alábbi mezőket kell megadnia új összetevő létrehozásakor (lásd: Összetevőkonfiguráció a mezők részletes leírásához):

Mező

Érték

Forráskód tároló

A projekt VCS tárolójának URL-je

Fájlmaszk

po/*.po

Sablon az új fordításokhoz

po/hello.pot

Fájlformátum

Válassza a gettext PO-fájl formátumot

Új nyelv

Válassza az Új nyelvi fájl létrehozása lehetőséget

És ennyi – már készen is áll szoftvere fordítására!

Lásd még

Többnyelvű gettext példát a Weblate Hello projektben talál a GitHubon: <https://github.com/WeblateOrg/hello>.