GNU-Pascal in Beispielen: Internationalisierung

Aus Wikibooks

zurück zu GNU-Pascal in Beispielen

Internationalisierung[Bearbeiten]

Veröffentlichte Programme werden nicht selten von Menschen aus den unterschiedlichsten Nationen benutzt. Damit diese Programme auch benutzt werden können ist es oft erforderlich, sie zu internationalisieren. Die folgenden Kapitel geben einen Überblick über die Möglichkeiten von GNU-Gettext [1]. Für die folgenden Beispiele benötigen Sie ein Programm namens pas2po [2], welches Sie im Quelltext von http://www.gnu-pascal.de/contrib/eike/ herunterladen können.

Ein Programm Internationalisieren[Bearbeiten]

Quelltext vorbereiten[Bearbeiten]

Nehmen wir die englischsprachige Fassung des ersten Beispiels aus dem Kapitel Das erste Programm als Grundlage für die ersten Gehversuche mit GNU-Gettext:

Programm: Inter1[Bearbeiten]
program Inter1;

begin
  WriteLn ('Hello World!')
end.

Das Programm gibt bei der Ausführung den englischsprachigen Text "Hello World!" aus. Dieses Programm wollen wir nun internationalisieren. Wir fügen dem Programm die benötigten Informationen hinzu, damit ein "Sprachenkatalog" in der gewählten Landessprache gefunden werden kann und natürlich muss das Programm wissen, welche Sprache es gerade auszugeben hat:

Programm: Inter2[Bearbeiten]
program Inter2;

uses GPC, Intl;

const
  LocaleDir = '/usr/share/locale';

var
  Dummy: TString;

begin
  Dummy := SetLocale (LC_MESSAGES, '');
  Dummy := BindTextDomain ('inter2', LocaleDir);
  Dummy := TextDomain ('inter2');
  WriteLn (GetText ('Hello World!'))
end.
Erklärung[Bearbeiten]

Zuerst legen wir das Verzeichnis fest, in dem die so genannten "Locale-Informationen" abgelegt sind. Unter Linux und den meisten anderen Betriebssystem ist dies /usr/share/locale oder /usr/local/share/locale [3]. Innerhalb dieses Verzeichnisses sollten diverse Verzeichnisse liegen, die mit einer Länderkennung versehen sind. Schauen Sie sich dort ruhig einmal um, denn innerhalb von z.B. de befindet sich ein weiteres Verzeichnis mit dem Namen LC_MESSAGES. In diesem Verzeichnis liegen alle deutschsprachigen Kataloge von den verschiedensten Programmen.

Um die gegenwärtige verwendete Spracheinstellung zu benutzen ruft man SetLocale [4] auf. Wollen Sie eine bestimmte Sprache angeben, so können sie dies dort machen, wo die leere Zeichenkette steht. Eine französischsprachige Ausgabe erhalten Sie beispielsweise mit SetLocale (LC_MESSAGES, 'fr_FR');, sofern die entsprechenden Dateien auf ihrem System installiert sind.

Der Funktionsaufruf BindTextDomain sucht eine Datei mit dem angegebenen Namen im angegebenen Pfad. In unserem Fall würde BindTextDomain also im Pfad /usr/share/locale/de/LC_MESSAGES/ eine Datei suchen, die inter2.mo heißt. Diese Datei wird durch den Aufruf von TextDomain für alle weiteren Aufrufe von GetText benutzt. GetText sucht in der angegebenen Datei nach der Übersetzung des übergebenen Strings zur vorher gewählten Locale-Einstellung.

Sprachenkatalog erzeugen[Bearbeiten]

Da wir den Quelltext vorbereitet haben sind wir vom erstellen des Sprachenkataloges nur noch wenige Programmaufrufe entfernt. Mit pas2po -o inter2.po inter2.pas erzeugen wir eine Datei, welche alle zur Übersetzung vorbereiteten Strings enthält. Nur diejenigen Zeichenketten werden hier aufgeführt, die mit GetText vorbereitet wurden:

# This file was created by pas2po with 'inter2.pas'.
# Please change this file manually.
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Free Software Foundation, Inc.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2003-04-01 21:54+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"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#foo1.pas:15
msgid "Hello World!"
msgstr ""

Ab dem Zeitpunkt, wo diese Datei vorliegt gibt es keinen Grund mehr, den originalen Quelltext zu besitzen. Jedes beliebige entsprechend vorbereitete Programm lässt sich übersetzen, wenn diese Datei vorliegt.

Alle großgeschriebenen Einträge hinter den Doppelpunkten müssen entsprechend bearbeitet werden. Für die genaue Bedeutung dieser Einträge wird auf die Dokumentation von gettext verwiesen. Das wichtigste an dieser Datei ist die Übersetzung der angegebenen Zeichenkette. Im Folgenden wird die entsprechend bearbeitete Datei angegeben:

# This file was created by pas2po with 'inter2.pas'.
# Please change this file manually.
# Deutschsprachige Uebersetzung des Programms inter2
# Eike Lange <eike@gnu.de>, 2003.
#
msgid ""
msgstr ""
"Project-Id-Version: inter2 1.0\n"
"POT-Creation-Date: 2003-04-01 21:54+0200\n"
"PO-Revision-Date: 2003-04-01 22:30+0200\n"
"Last-Translator: Eike Lange <eike@gnu.de>\n"
"Language-Team: <>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"

#foo1.pas:15
msgid "Hello World!"
msgstr "Hallo Welt!"


Der Befehl msgfmt inter2.po -o inter2.mo erzeugt aus der bearbeiteten Datei inter2.po eine Datei namens inter2.mo. Diese Datei war das Ziel all unserer Bemühungen.

Mit dem Befehl cp inter2.mo /usr/share/locale/de/LC_MESSAGES/ wird diese Datei an die richtige Stelle im System installiert.

Wenn wir jetzt das Programm aufrufen, so erscheint der deutschsprachige übersetzte Text der im Quelltext weiterhin englischsprachig vorliegt. Es wird zur Laufzeit des Programms entschieden, welche Sprache zur Ausgabe benutzt wird.


Argumente Tauschen[Bearbeiten]

In vielen Sprachen ist die Reihenfolge von Argumenten wichtig. Betrachten wir dazu die folgenden Sätze:

Die Antwort ist 42.
42 ist die Antwort.
Die Antwort kann 42 sein.

Um dieser Reihenfolge in verschiedenen Sprachen Rechnung zu tragen wurde die Funktion FormatString entwickelt, die wir direkt in unseren Quelltext einbauen können:

Programm: Inter3[Bearbeiten]
program Inter3;

uses GPC, Intl;

const
  LocaleDir = '/usr/local/share/locale';

var
  Ignore, Answer, s: TString;

begin
  Ignore := SetLocale (LC_MESSAGES, '');
  Ignore := BindTextDomain ('inter3', LocaleDir);
  Ignore := TextDomain ('inter3');
  Write (GetText ('What is the answer of all questions? '));
  ReadLn (Answer);
  s := FormatString (GetText ('%@1a %@2a'), Answer,
    GetText (' is the answer.'));
  WriteLn (s)
end.
Erklärung[Bearbeiten]

Das erste Argument von FormatString ist eine Zeichenkette, die eine Nummerierung aller folgenden Argumente enthält. %@1a ist das Erste, %@2a das Zweite und %@100a das hundertste folgende Argument. Ohne eine Übersetzung würde das Programm etwa folgende Ausgabe liefern:

What is the answer of all questions? 42
42 is the answer.

Wir wollen nun das Programm internationalisieren, wobei wir die Argumente derart vertauschen, dass der eingegebene Text hinter den erklärenden Text platziert wird. Hierzu führen wir wieder das Programm pas2po -o inter3.po inter3.pas aus und erhalten, neben dem uns schon bekannten Kopfteil, folgende Ausgabe:

#inter3.pas:15
msgid "What is the answer of all questions? "
msgstr ""

#inter3.pas:17
msgid "%@1a %@2a"
msgstr ""

#inter3.pas:18
msgid "is the answer."
msgstr ""

Wenn wir diese Datei nun übersetzen, achten wir besonders darauf, die Formatreihenfolge zu vertauschen:

# Message File for Inter3
#
msgid ""
msgstr ""
"Project-Id-Version: inter3 1.0\n"
"POT-Creation-Date: 2003-04-02 15:34+0200\n"
"PO-Revision-Date: 2003-04-02 15:34+0200\n"
"Last-Translator: Eike Lange <eike@gnu.de>\n"
"Language-Team: German <de@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"

#inter3.pas:15
msgid "What is the answer of all questions? "
msgstr "Wie lautet die Antwort auf alle Fragen? "

#inter3.pas:17
msgid "%@1a %@2a"
msgstr "%@2a %@1a"

#inter3.pas:18
msgid "is the answer."
msgstr "Die Antwort lautet:"

Nach dem Erzeugen der .mo-Datei mit msgfmt inter3.po -o inter3.mo und dem Installieren nach /usr/local/share/locale/de/LC_MESSAGES/ lautet die Ausgabe unseres Programms wie folgt:

Wie lautet die Antwort auf alle Fragen? 42
Die Antwort lautet: 42

Anmerkungen[Bearbeiten]

  1. Wenn Sie mehr darüber erfahren wollen, so schauen sie sich bitte die Hilfen zu den Themen gettext, xgettext und msgfmt an.
  2. Dieses Programm ersetzt das bei C-Programmierern beliebte xgettext.
  3. Auf die betriebssystemspezifischen Details dieses Pfades gehen wir in Anhang Systemspezifische Details ein.
  4. Mit dem Befehl man setlocale bekommen Sie weitere Informationen zu diesem Systemaufruf.