Sprachunabhängige Meldungen in Auswerteprogrammen

(Michael Schröpl für Interzine '92.06', 1992-06-14)

Der folgende Artikel richtet sich primär an Programmierer von Auswerteprogrammen, die von mehreren Spielleitern verwendet werden sollen, aber auch an die Benutzer solcher Programme. Obwohl teilweise programmspezifische Details erwähnt werden müssen, sollten auch reine Benutzer diesen Artikel komplett lesen.

Ein großer Teil des Aufwands bei Auswerteprogrammen (die diesen Namen auch verdienen) steckt im Entwurf des Benutzerdialogs. Man möchte ja als Benutzer einerseits möglichst verstehen, was der Druck auf eine bestimmte Taste in einem bestimmten Zustand bewirken wird, und andererseits ein hohes Maß an Flexibilität haben ('gefährliche' Eingaben mit Bestätigungseingaben 'absichern', Menüstrukturen für Kommandos usw.).
Aber auch bei der Ausgabe von Ergebnissen auf Drucker oder (besser) Dateien liegen Texte vor, nicht nur Tabellenstrukturen und Zahlenwerte. Oft ist die Bestimmung der entsprechenden Texte teilweise abhängig von aktuellen Programmdaten. So fallen mit der Zeit erhebliche Mengen an Texten an, die mehr oder weniger tief in die Programmstruktur integriert sind.

Was tun, wenn nun jemand das Programm benutzen will, der mit den verwendeten Texten nicht zurechtkommt? Das kann an der konkreten Wortwahl liegen (dem Programmierer selbst ist natürlich alles, klar), aber auch - und das war der für mich konkret vorliegende Fall - an der verwendeten Landessprache.
Alan Parr verteilt in Großbritannien deutsche Versionen von UNITED/XY, Paul Stouthart hat mich angeschrieben und wollte eine in Holland verwendbare Version haben (da geht es u. a. auch um Regeldifferenzen), Borger Borgersen verwendet in Norwegen ebenfalls eine deutsche Version, weil nichts anderes da ist. Alle diese (und vielleicht noch viele andere) Benutzer wären glücklich, wenn es auch fremdsprachige Versionen dieses Programms (und anderer Programme) gäbe.

Was also tun? Ein Programm wie UNITED/XY mit 22000 Zeilen Quellcode läßt sich nicht in mehreren verschiedensprachigen Versionen warten. In jeder solchen Version dieselben Änderungen einbauen, ist viel zu fehleranfällig und zeitlich zudem nicht zu schaffen.
Was dagegen durchaus geht (auch wenn es erst einmal eine Riesenarbeit ist), ist eine komplette Umstellung des Programms auf sprachunabhängige Meldungen. Genau dies tue ich gerade. Das Prinzip möchte ich hier gerne erläutern, weil es sich für andere Programme auch verwenden läßt (für neue Programme sogar viel leichter, wenn man gleich beim Entwurf das Meldungssystem verwendet). Zudem gebe ich schon mal bekannt, daß ich den Quelltext meines Meldungsmoduls (in Turbo-Pascal) warten und an Interessenten weitergeben werde; der sollte in jeder höheren Programmiersprache verwendbar sein.

Meldung ist nicht gleich Meldung, und verschiedene Sprachen haben unterschiedliche Eigenarten bezüglich ihres Satzbaus. Auch tauchen in Meldungen nicht nur statisch definierte Texte auf, sondern auch datenabhängige Einfügungen (meist Zahlen oder Zeichenketten), und außerdem können einzelne Worte des Textes von den eingefügten Werten abhängen ("1 Sätze gelesen", man kennt das ja). Im Sinne meines Meldungssystems sieht eine Meldung z. B. folgendermaßen aus:

SPLIG001:'[&1] hat bisher [#1] [$Ligaspiel|Ligaspiele] absolviert!'

Eine Meldung besteht also aus

Innerhalb des Meldungstextes können die folgenden Strukturen verwendet werden:

Wie verwendet ein Programmierer eine solche Meldung? Für das obige Beispiel sähe das Programmstück etwa folgendermaßen aus:

      (* msg: '[&1] hat bisher [#1] [$Ligaspiel|Ligaspiele] absolviert!' *)
      msgGetText      ('SPLIG003');

      (* Wert von vereins_name für '[&1]' einsetzen *)
      msgInsertString (1, vereins_name);

      (* Wert von anzahl_spiele für '[#1]' einsetzen *)
      msgInsertNumber (1, anzahl_spiele);

      (* Falls anzahl_einsaetze = 1, dann Singular-, sonst Pluralform[-en] *)
      msgPlural       (anzahl_einsaetze);

      (* Fertigen Meldungstext verwenden *)
      write           (msgText);

Das Programm muß also wissen, wie eine konkrete Meldung strukturiert ist, kann die entsprechenden Operationen wie Einfügung usw. aber über ein abstraktes Prozedur-Interface ansprechen.
Ansonsten ist im Programm kein Wissen mehr darüber verankert, daß es sich um eine Meldung der deutschen Sprache handelte!

Um nun ein Programm auf eine andere Sprache umzustellen, müssen also lediglich die Meldungen übersetzt werden. Da Einfügungen an beliebigen Stellen innerhalb der Meldung stehen dürfen, kann der Übersetzer dabei den Satzbau der Zielsprache ohne Einschränkung berücksichtigen. Hat die Zielsprache identische Singular-/Plural-Formen, dann darf eine [$...]-Konstruktion auch durch konstanten Text ersetzt werden (es stört den msgPlural-Aufruf nicht, wenn er keinen Treffer findet).

Alle Meldungen könnten z. B. in einem eigenen Meldungsmodul des Programms statisch definiert sein. Dieser Modul wäre dann vom Programmierer bei einer neuen Version des Programms entsprechend anzupassen.
Noch flexibler aber ist es, sämtliche Meldungen in einer eigenen Datei zu halten und diese beim Start des Programms einlesen zu lassen. In diesem Falle nämlich könnte sich der Benutzer des Programms selbst eine eigene, ihm genehme Meldungsdatei erstellen. Dafür muß er nicht selbst programmieren können und hat keinen Zugriff auf den Programmtext selbst (kann also z. B. nicht regelrelevante Mechanismen ändern). Dies werde ich für UNITED/XY so vorsehen; die Erstellung einer englischen, niederländischen, norwegischen Version ist dann nicht mehr mein Problem (meine norwegischen Sprachkenntnisse sind eher bescheiden ...), aber die Interessenten selbst haben alle dazu erforderlichen Voraussetzungen.

Einfügungen in Meldungen dürfen übrigens zusätzlich eine Ausrichtungsangabe enthalten. In die Einfügung [#1<05] wird eine Zahl rechtsbündig in der Länge von 5 Zeichen eingefügt (und links ggf. mit Leerzeichen aufgefüllt), > ist analog die rechtsbündige Ausrichtung.
Durch solche Formatierungsanweisungen spart sich der Programmierer, immer wieder dieselben Anweisungen in seinem Programm angeben zu müssen. Der Benutzer hingegen kann durch Änderung von konstanten Texten und/oder Formatierungsanweisungen das Layout der Dialoge wie auch der erzeugten Auswertungsdateien in seinem Sinne beeinflussen.

Potenzielle Benutzer eines solchen Programms müssen sich allerdings darüber im Klaren sien, daß ein Eingriff in eine Meldungsdefinition durchaus einem Eingriff in den Programmtext ähnelt (denn durch die Strukturlogik der Meldungen steckt ein Teil des Programmablaufs in dieser verschlüsselten Form in dieser Meldung selbst). Wenn man dabei Einfügungen löscht, die das Programm erwartet, dann wird das Meldungssystem - gutmütigerweise - eine Warnung ausgeben. Diese Warnung ist allerdings selbst keine 'Meldung' (denn wie sollte das Programm dem Benutzer dann mitteilen, daß es die Meldungsdatei nicht gefunden hat?), sondern eine im Meldungssystem fest eingebrannte Ausgabe. Und die ist natürlich in Englisch (wenn sich jemals eine Weltsprache etablieren sollte, dann hat Englisch derzeit die besten Chancen dafür). Wer sich seine Meldungsdatei vermurkst, der ist selber schuld. Also: Kopien aufbewahren und voooorsichtig ändern!

Wenn ich mit der Sisyphus-Arbeit, UNITED/XY-international (V1.70) zu basteln (derzeit bin ich bei Meldung 561), fertig bin, dann werde ich vermutlich meine anderen 'in Wartung stehenden' Auswerteprogramme auch entsprechend umbauen. Das kann dann ja nicht mehr so schlimm sein.
In jedem Falle hoffe ich, daß bei einer solchen Programmkonzeption dem internationalen Austausch von Auswerteprogrammen ein Stein weniger im Wege liegt. Leser des Europa2000 könnten von englischen Versionen allfälliger Auswerteprogramme vielleich als erste profitieren? Und das aktuelle Diplomacy-Auswertesystem, das ebenfalls in Turbo-Pascal gebaut wird, könnte man auch gleich damit verseuchen ...