Prekladanie softvéru pomocou GNU gettext

GNU gettext je jedným z najpoužívanejších nástrojov pre internacionalizáciu slobodného softvéru. Poskytuje jednoduchý, no flexibilný spôsob lokalizácie softvéru. Má skvelú podporu pre množné čísla, môže pridať ďalší kontext preloženému reťazcu a existuje pomerne veľa nástrojov postavených okolo neho. Samozrejme, má skvelú podporu vo Weblate (pozri popis formátu súboru GNU gettext PO (Portable Object)).

Poznámka

Ak ho plánujete použiť v proprietárnom softvéri, prosím, najprv sa poraďte ohľadom licencovania, nemusí byť pre vás vhodný.

GNU gettext môže byť použitý z rôznych jazykov (C, Python, PHP, Ruby, JavaScript a mnohé ďalšie) a zvyčajne UI frameworky už prichádzajú s nejakou podporou preň. Štandardné použitie je prostredníctvom volania funkcie gettext(), ktorá je často aliasovaná na _(), aby bol kód jednoduchší a ľahšie čitateľný.

Okrem toho poskytuje volanie pgettext() na poskytnutie dodatočného kontextu prekladateľom a ngettext(), ktoré dokáže spracovať typy množných čísel, ako sú definované pre cieľový jazyk.

Ako široko rozšírený nástroj má mnoho wrapperov, ktoré robia jeho použitie naozaj jednoduchým, namiesto manuálneho vyvolávania gettext popísaného nižšie, môžete chcieť vyskúšať jeden z nich, napríklad intltool.

Prehľad workflow

GNU gettext používa niekoľko súborov na správu lokalizácie:

  • PACKAGE.pot obsahuje reťazce extrahované z vášho zdrojového kódu, zvyčajne pomocou xgettext alebo niektorých vysokourovňových wrapperov, ako je intltool.

  • LANGUAGE.po obsahuje reťazce s prekladom do jedného jazyka. Musí byť aktualizovaný pomocou msgmerge, akonáhle je PACKAGE.pot aktualizovaný. Nové jazykové súbory môžete vytvoriť pomocou msginit alebo vo Weblate.

  • LANGUAGE.mo obsahuje binárnu reprezentáciu LANGUAGE.po a používa sa počas behu aplikácie. Zvyčajne nie je uchovávaný pod správou verzií, ale generovaný v čase kompilácie pomocou msgfmt. V prípade, že ho chcete mať v správe verzií, môžete ho generovať vo Weblate pomocou doplnku Generovať súbory MO.

Celkovo workflow GNU gettext vyzerá takto:

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

Ukážkový program

Jednoduchý program v C používajúci gettext môže vyzerať nasledovne:

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

Extrakcia preložiteľných reťazcov

Akonáhle máte kód používajúci volania gettext, môžete použiť xgettext na extrakciu správ z neho a uloženie do .pot:

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

Poznámka

Existujú alternatívne programy na extrakciu reťazcov z kódu, napríklad pybabel.

Toto vytvorí šablónový súbor, ktorý môžete použiť na začatie nových prekladov (pomocou msginit) alebo aktualizáciu existujúcich po zmene kódu (na to by ste použili msgmerge). Výsledný súbor je jednoducho štruktúrovaný textový súbor:

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

Každý riadok msgid definuje reťazec na preklad, špeciálny prázdny reťazec na začiatku je hlavička súboru obsahujúca metadáta o preklade.

Začatie nového prekladu

So šablónou na mieste môžeme začať náš prvý preklad:

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

Práve vytvorený cs.po už má vyplnené niektoré informácie. Najdôležitejšie je, že dostal správnu definíciu tvarov množného čísla pre zvolený jazyk a môžete vidieť, že počet množných čísel sa podľa toho zmenil:

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

Tento súbor je skompilovaný do optimalizovanej binárnej formy, súbor .mo používaný funkciami GNU gettext počas behu.

Aktualizácia reťazcov

Akonáhle pridáte viac reťazcov alebo zmeníte niektoré reťazce vo vašom programe, znovu vykonáte xgettext, ktorý regeneruje šablónový súbor:

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

Potom môžete aktualizovať jednotlivé prekladové súbory, aby zodpovedali novo vytvoreným šablónam (zahŕňa to aj preusporiadanie reťazcov tak, aby zodpovedali novej šablóne):

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

Poznámka

Pri používaní Weblate zvyčajne nepotrebujete spúšťať msgmerge manuálne. Weblate to môže spracovať automaticky prostredníctvom doplnku Aktualizovať súbory PO tak, aby zodpovedali POT (msgmerge), alebo môžete nahrať aktualizovaný súbor POT pomocou metódy nahrávania Aktualizovať zdrojové reťazce. Podrobnosti nájdete v Aktualizácia súborov cieľového jazyka.

Import do Weblate

Na import takéhoto prekladu do Weblate stačí definovať nasledujúce polia pri vytváraní súčasti (podrobný popis polí nájdete v Konfigurácia komponentu):

Pole

Hodnota

Repozitár zdrojového kódu

URL repozitára VCS s vaším projektom

Maska súboru

po/*.po

Šablóna pre nové preklady

po/hello.pot

Formát súboru

Vyberte gettext PO súbor

Nový jazyk

Vyberte Vytvoriť nový jazykový súbor

A to je všetko, teraz ste pripravení začať prekladať váš softvér!

Viď aj

Príklad gettextu s mnohými jazykmi nájdete v projekte Weblate Hello na GitHube: <https://github.com/WeblateOrg/hello>.