Software mit GNU gettext übersetzen

GNU gettext ist eines der am weitesten verbreiteten Tools zur Internationalisierung von Freier Software. Es bietet eine einfache und doch flexible Möglichkeit, die Software zu lokalisieren. Es hat eine großartige Unterstützung für Pluralformen, es kann der übersetzten Zeichenkette weiteren Kontext hinzufügen und es gibt eine ganze Reihe von Tools, die darauf aufbauen. Natürlich wird es in Weblate hervorragend unterstützt (siehe Dateiformatbeschreibung von GNU gettext PO (Portable Object)).

Bemerkung

Wenn Sie es in proprietärer Software verwenden wollen, konsultieren Sie bitte zuerst die Lizenzbestimmungen, da es möglicherweise nicht für Sie geeignet ist.

GNU gettext kann aus einer Vielzahl von Sprachen verwendet werden (C, Python, PHP, Ruby, JavaScript und viele mehr) und normalerweise bieten die UI-Frameworks bereits eine gewisse Unterstützung dafür. Die Standardverwendung erfolgt über den Funktionsaufruf gettext(), der oft als Alias _() verwendet wird, um den Code einfacher und leichter lesbar zu machen.

Zusätzlich bietet es den Aufruf pgettext(), um Übersetzern zusätzlichen Kontext zu liefern und ngettext(), das Pluraltypen wie in der Zielsprache definiert behandeln kann.

Als weit verbreitetes Tool hat es viele Wrapper, die seine Benutzung sehr einfach machen. Anstelle des unten beschriebenen manuellen Aufrufs von gettext sollten Sie vielleicht einen von ihnen ausprobieren, zum Beispiel intltool.

Übersicht über den Arbeitsablauf

GNU gettext verwendet mehrere Dateien, um die Lokalisierung zu verwalten:

  • PACKAGE.pot enthält Zeichenketten, die aus Ihrem Quellcode extrahiert wurden, typischerweise unter Verwendung von xgettext oder einigen High-Level-Wrappern wie intltool.

  • LANGUAGE.po enthält Zeichenketten mit einer Übersetzung in eine einzelne Sprache. Sie muss mit msgmerge aktualisiert werden, sobald PACKAGE.pot aktualisiert wird. Sie können neue Sprachdateien mit msginit oder in Weblate erstellen.

  • LANGUAGE.mo enthält die binäre Darstellung von LANGUAGE.po und wird zur Laufzeit der Anwendung verwendet. Normalerweise wird sie nicht unter Versionsverwaltung gehalten, sondern zur Kompilierungszeit mit msgfmt erzeugt. Wenn Sie sie in der Versionsverwaltung haben wollen, können Sie sie in Weblate mit der Erweiterung MO-Dateien erzeugen erzeugen.

Insgesamt sieht der GNU-gettext-Arbeitsablauf wie folgt aus:

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

Beispielprogramm

Das einfache Programm in C, das gettext verwendet, könnte wie folgt aussehen:

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

Extrahieren übersetzbarer Zeichenketten

Sobald Sie Code haben, der die gettext-Aufrufe verwendet, können Sie xgettext verwenden, um Nachrichten daraus zu extrahieren und sie in eine .pot zu speichern:

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

Bemerkung

Es gibt alternative Programme, um Zeichenketten aus dem Code zu extrahieren, zum Beispiel pybabel.

Dadurch wird eine Vorlagendatei erstellt, die Sie zum Starten neuer Übersetzungen (mit msginit) oder zum Aktualisieren bestehender Übersetzungen nach einer Codeänderung verwenden können (dafür würden Sie msgmerge verwenden). Die resultierende Datei ist einfach eine strukturierte Textdatei:

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

Jede msgid-Zeile definiert eine zu übersetzende Zeichenkette, die spezielle leere Zeichenkette am Anfang ist der Dateiheader, der Metadaten über die Übersetzung enthält.

Eine neue Übersetzung beginnen

Mit der Vorlage können wir mit unserer ersten Übersetzung beginnen:

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

Die soeben erstellte cs.po enthält bereits einige Informationen. Am wichtigsten ist, dass sie die richtige Definition der Pluralformen für die gewählte Sprache erhalten hat, und Sie können sehen, dass sich die Anzahl der Pluralformen dementsprechend geändert hat:

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

Diese Datei wird in eine optimierte Binärform kompiliert, die .mo-Datei, die von den GNU gettext-Funktionen zur Laufzeit verwendet wird.

Aktualisieren von Zeichenketten

Sobald Sie weitere Zeichenketten hinzufügen oder einige Zeichenketten in Ihrem Programm ändern, führen Sie erneut xgettext aus, wodurch die Vorlagendatei neu generiert wird:

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

Dann können Sie die einzelnen Übersetzungsdateien aktualisieren, damit sie mit den neu erstellten Vorlagen übereinstimmen (dazu gehört auch das Neuordnen der Zeichenketten, damit sie mit der neuen Vorlage übereinstimmen):

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

Importieren in Weblate

Um eine solche Übersetzung in Weblate zu importieren, müssen Sie nur die folgenden Felder beim Erstellen der Komponente definieren (siehe Komponentenkonfiguration für eine detaillierte Beschreibung der Felder):

Feld

Wert

Quellcode-Repository

URL des VCS-Repositorys mit Ihrem Projekt

Dateimaske

po/*.po

Vorlage für neue Übersetzungen

po/hello.pot

Dateiformat

gettext PO-Datei auswählen

Neue Sprache

Neue Sprachdatei erstellen auswählen

Und das war’s, jetzt können Sie mit der Übersetzung Ihrer Software beginnen!

Siehe auch

Ein gettext-Beispiel mit vielen Sprachen finden Sie im Weblate Hello-Projekt auf GitHub: <https://github.com/WeblateOrg/hello>.