Language preprocessor

This is a cheap preprocessor for a one-level conditional compilation of Inform files. This could be used for a single source file containing the data for different languages.

Usage:

perl inf-tags.pl [inf-compiler] {inf-options} -L[language-tag] [src] {game}

or possibly:

./inf-tags.pl [inf-compiler] {inf-options} -L[language-tag] [src] {game}

[Square brackets] denote mandatory, {curly braces} optional items.

[inf-compiler] is the Inform compiler to use, perhaps with a full path name prepended. [src] is the source file and {game} the game file to be written which defaults the the source’s base name with a z-Code suffix.

{inf-options} are the usual options of the Inform compiler. The language tag must be specified. This can be any continous string of non-whitespace characters like EN, EN-UK or ENGLISH. The tag is case-sensitive. There is no default value.

Inside the source code, the text must be structured like this:

...
description
:EN  "It is about two feet long.",
:ES  "Mide aproximadamente sesenta centímetros.",
:DE  "Es ist ungefähr einen halben Meter lang.",
:

That is, the text looks a bit like a switch statement. There is a line for every tag, the whole block is terminated with a single colon. With the -W option activated, a warning is issued when the block does not contain a definition for the requested language as for example would be the case if the above example hat be compiles with the tag IT. If the -W switch is set the compilation will not be started if there are empty blocks for that language tag.

It is important to close all tag blocks!

The tagging follows Inform Include statements, but it skips system files. This means that in any library file, the System_file; directive must be the first non-comment.

The script creates temporary source and output files. By default, these files are deleted after the script completes. With the -K option which must be on its own, the file is only converted and written to stdout so that it can be redirected with >.

The option -V (verbose) reports inclusion of files.

inf-tags.pl

Inform 6 preprocessor
Download zip archive with example

This is a Perl script and requires Perl 5. No special packages are required.

Known issues

The script assumes that the standard error style is -E0 (Acorn style messages). Since the script scans the output and replaces the temporary line numbers with line numbers in the tagged source, the correct error style must be known. You can wor around this by always specifying the error style with -E or by setting the defult error style in the script to something diffenent: just change the following line

my $errorstyle = 0;

Discussion

The method described here uses the “everything in one file” approach. This might be useful if one person writes all the text in several languages. The example below illustrates that it is easy to lose track of the game itself by adding too many languages. I would favour an approach that uses a game skeleton that can be filled with translations.

The method used in inf-tags.pl might be useful for small teams, though. (In fact, I am told it is currently being used for a bilingual project involving several authors.)

An example

Roberto Grassi from Italy, Urbatain from Spain and Eric Forgeot from France have reworked my original Jade example so that it includes an English, a German, an Italian, a Spanish and a French version in a single file:

Here it is, highlighted by language:

!==========================================================
!    Multilingual Inform Game
!    Version  Nov. 2006
!==========================================================

Constant Story

:DE      "DIE JADESTATUE";
:EN      "THE JADE STATUETTE";
:IT      "LA STATUETTA DI GIADA";
:SP      "LA ESTATUILLA DE JADE";
:FR      "LA STATUETTE DE JADE";
:

Constant Headline

:DE
 "^^Ein interaktives Beispiel^
    Viersprachige Version 2006 von
    Eric Forgeot, Roberto Grassi, Urbatain
    und Martin Oehm^^";
:EN
 "^^An interactive example^
    Multilingual version 2006 by Martin Oehm,
    Eric Forgeot, Roberto Grassi and
    El Clérigo Urbatain.^^";
:IT
 "^^Un esempio interattivo^
    Versione quattrilingue 2006 di Martin Oehm,
    El Clérigo Urbatain, Eric Forgeot
    e Roberto Grassi.^^";
:SP
 "^^Un ejemplo interactivo^
    Version cuatrilingue 2006 por Martin Oehm,
    Eric Forgeot, Roberto Grassi and
    El Clérigo Urbatain.^^";
:FR
 "^^Un exemple interactif^
    Version 2006 multilingue par Martin Oehm,
    Roberto Grassi, El Clérigo Urbatain
    et Eric Forgeot.^^";
:


Constant NO_PUNCTUATION;

Release 1;

Serial "030215"; !JJMMTT

Include "Parser";

Include "VerbLib";


[ Initialise;

    location = Lichtung;
    print

:DE
    "Endlich! Nach tagelangem Suchen im Dschungel
        stößt du auf eine Lichtung. Und auf etwas mehr.
        Vielleicht ist dies der Ort, an dem sich die
        Jadestatue befindet?^^";
:EN
    "At last! After days of restless searching through
        the nearby jungle, you have come across a
        clearing. And something more. Maybe this is
        where you can find the fabled jade statuette?^^";
:IT
    "Finalmente! Dopo giorni di ricerca senza sosta
        nella vicina giungla sei giunto in una radura.
        E c'e' anche dell'altro. Forse sei vicino a
        trovare la famosa statuetta di giada?^^";
:SP
    "¡Al fin! Después de días de búsqueda sin descanso
        a través de la jungla cercana, has llegado a un
        claro. Y algo más. ¿Quizás es aqui donde podrás
        encontrar la legendaria estatuilla de jade?^^";
:FR
    "Enfin ! Après des jours d'exploration sans repos
        à travers la jungle, vous êtes arrivé à une
        clairière. Et bien plus. Peut-être est-ce ici
        que vous pourrez trouver la fabuleuse
        statuette de jade ?^^";
:

];



Object Lichtung

:DE    "Lichtung im Dschungel"
:EN    "Jungle Clearing"
:IT    "Radura nella giungla"
:SP    "Claro en la Jungla"
:FR    "Clairière dans la jungle"
:

with
 cant_go

:DE
    "Dort ist der Dschungel zu dicht, es gibt
        keinen Pfad in diese Richtung.",
:EN
    "In this direction, the jungle is too dense;
        There's no path in that direction.",
:IT
    "La giungla e' troppo densa in quella direzione;
        non ci sono sentieri percorribili.",
:SP
    "En esa dirección, la jungla es demasiado densa;
        No hay camino en esa dirección.",
:FR
    "Dans cette direction la jungle est trop fournie,
        il n'y a aucun chemin dans cette direction.",
:
 n_to Im_Schrein,
 in_to Lichtung,
 s_to [;

    if (Jadestatue notin player)

:DE "Nicht ohne die Statue!";
:EN "Not without the statuette!";
:IT "Non senza la statuetta!";
:SP "¡No sin la estátua!";
:FR "Pas sans la statuette !";
:
    deadflag = 2;


:DE
    "Du schaffst es, mit der Statue wieder zurück
    in die Zivilisation zu gelangen.";
:EN
    "You make it back to civilisation, and you got
    that statuette, too.";
:IT
    "Torni alla civilta'... con la statuetta.";
:SP
    "Vuelves a la civilización, y llevas la
    estatuilla además.";
:FR
    "Vous retournez à la civilisation, et vous
    avez avec vous la statuette.";
:
 ],
description

:DE
    "Du stehst auf einer Lichtung im
        dichten Dschungel. Im Norden steht ein alter,
        von Ranken überzogener Schrein. Im Süden führt
        ein schmaler Pfad zurück in die Zivilisation.",
:EN
    "You are standing on a clearing in a dense jungle.
        To the north there is an old shrine, overgrown
        with vines. A narrow track leads to the south
        and back to civilisation.",
:IT
    "Sei in una radura di una densa giungla. A nord vedi
        un vecchio tempio, coperto quasi interamente
        dalle radici. Un sentiero conduce a sud, verso
        la civilta'.",
:SP
    "Estás en un claro en la densa jungla.
        Al norte hay un santuario antiguo, envuelto
        en enredaderas. Un sendero estrecho conduce
        hacia el sur de vuelta a la civilización.",
:FR
    "Vous vous trouvez dans une clairière d'une jungle
        dense. Au nord se trouve un ancien tombeau,
        recouvert de lierre. Un petit sentier conduit
        au sud, vers la civilisation.",
:
has light;


Object -> Stein

:DE    "Stein"
:EN    "stone the size of your fist"
:IT    "una pietra grande quanto il tuo pugno"
:SP    "una piedra del tamaño de tu puño"
:FR    "une pierre grosse comme le poing"
:

with
 name

:DE
    'faustgross' 'gross' 'rund' 'glatt' 'stein',
    dekl 3,
    adj "faustgroß",
:EN
    'stone' 'big' 'fist' 'size' 'sized' 'fist-sized',
:IT
    'pietra' 'grande' 'pugno',
:SP
    'piedra' 'grande' 'puño' 'tamaño',
:FR
    'pierre' 'grande' 'grosse' 'comme' 'taille' 'poing',
:

 description

:DE
    "Der Stein ist so groß wie eine Faust
        und außergewöhnlich glatt und rund.",
:EN
    "The stone is about as big as your fist
        and it is incredibly smooth and perfectly
        round.",
:IT
    "La pietra è grande quanto il tuo pugno. E'
        incredibilmente levigata e perfettamente
        sferica.",
:SP
    "La piedra es tan grande como tu puño
        y es increiblemente suave y perfectamente
        redonda.",
:FR
    "La pierre est environ grande comme votre poing,
        incroyablement lisse et parfaitement ronde.",
:

 initial

:DE
    "^In der Nähe des Schreins liegt ein
        glatter, runder Stein im Gras.",
:EN
    "^A smooth, round stone is lying in the grass
        by the shrine.",
:IT
    "^Una pietra levigata e circolare giace tra l'erba
        intorno al tempio.",
:SP
    "^Una piedra redonda y suave está tirada en la
        hierba al lado del santuario.",
:FR
    "^Une pierre ronde et lisse se trouve sur l'herbe
        dans les environs du tombeau.",
:
has
:DE male
:IT female
:SP female
:FR female
:
;

Object -> Schrein

:DE    "Schrein"
:EN    "shrine"
:IT    "tempio"
:SP    "santuario"
:FR    "tombeau"
:

with
 name

:DE  'alt' 'toltekisch' 'schrein' 'efeu' 'ranken',
     dekl 1,
     adj "alt",
:EN  'old' 'toltec' 'shrine' 'temple' 'vines' 'weeds',
:IT  'vecchio' 'tolteco' 'tempio' 'costruzione'
     'radici',
:SP  'antiguo' 'toltec' 'santuario' 'templo'
     'enrredaderas',
:FR  'vieux' 'tolteque' 'tombeau' 'sanctuaire' 'lierre',
:

 description

:DE
    "Der alte Toltekenschrein ist fast
        komplett mit Efeu überwuchert.",
:EN
    "The old Toltec shrine is completely
        overgrown with vines.",
:IT
    "Il vecchio tempio tolteco e' quasi completamente
        avvolto dalle radici.",
:SP
    "El antiguo santuario de Toltec está completamente
        lleno de enrredaderas.",
:FR
    "L'ancien tombeau toltèque est complètement
        recouvert de lierre.",
:

 before [;
            Enter: <>;
    ],
has 
:DE male
:IT male
:SP male
:FR male
:
scenery;


Object Im_Schrein

:DE
   "Im Schrein"
:EN
   "In the Shrine"
:IT
   "Nel tempio"
:SP
   "En el Santuario"
:FR
   "Dans le sanctuaire"
:
with
 description

:DE
    "In dem kleinen Schrein ist es
        dunkel, nur wenig Licht fällt durch das halb
        verfallene Dach. Ein großer Lichtstrahl fällt
        auf eine Steinsäule in der Mitte des Schreins.
        ^^Die Lichtung liegt im Süden.",
:EN
    "It is dark inside the small shrine,
        only little light pours in through the broken
        roof. A wide beam of light illuminates a stone
        pedestal in the centre of the room, however.^^
        The clearing is to the south.",
:IT
    "Nel piccolo tempio regna l'oscurita', tuttavia
        una luce fioca filtra dal tetto danneggiato.
        Un raggio di luce illumina un piedistallo al
        centro della stanza.^^
        L'uscita e' a sud.",
:SP
    "Está oscuro dentro del pequeño santuario,
        sólo un poco de luz cae a través del tejado
        roto. Sin embargo, un ancho haz de luz
        ilumina un pedestal de piedra en el centro
        de la habitación.^^
        El claro está hacia el sur.",
:FR
    "Il fait sombre dans le petit tombeau, juste un peu
        de lumière passe à travers la toiture cassée.
        Un large rayon de lumière illumine un piédestal
        de pierre dans le centre de la pièce.^^
        La clairière est vers le sud.",
:
 s_to Lichtung,
 out_to Lichtung,
has light;


Object -> Saeule

:DE    "Steinsäule"
:EN    "stone pedestal"
:IT    "piedistallo di pietra"
:SP    "pedestal de piedra"
:FR    "piédestal en pierre"
:

with


:DE
 dekl 9,
:

 name

:DE  'steinsaeule' 'saeule' 'steinpodest' 'podest',
:EN  'stone' 'pedestal' 'pillar',
:IT  'pietra' 'piedistallo',
:SP  'piedra' 'pedestal' 'pilar',
:FR  'pied' 'piedestal' 'pilier' 'roche',
:

 description


:DE
    "Die Säule ist aus glattem Stein
        gehauen, etwas mehr als einen Meter hoch und
        oben flach, wie ein Podest.",
:EN
    "The pedestal is carved from smooth
        stone. It is about one metre high and has a
        flat top.",
:IT
    "Il piedistallo e' scolpito nella roccia.
        E' alto un metro ed ha una base piatta.",
:SP
    "El pedestal está formado por suaves labrados.
        Es como un metro de alto y la parte alta está
        plana.",
:FR
    "Le piédestal est taillé dans une roche lisse.
        Il fait environ un mètre de haut et a sa
        partie supérieure plane.",
:
has 
:DE female
:IT male
:SP male
:FR male
:
supporter static concealed;


Object -> -> Jadestatue

:DE    "Jadestatue"
:EN    "jade statuette"
:IT    "statuetta di giada"
:SP    "estatuilla de jade"
:FR    "statuette de jade"
:

with

 name

:DE 'gruen' 'klein' 'statue' 'figur' 'jadestatue'
    'jadefigur',
     dekl 9,
:EN 'green' 'small' 'jade' 'figurine' 'statue'
    'statuette' 'idol',
:IT 'verde' 'piccola' 'giada' 'figurina' 'statua'
    'statuetta' 'idolo',
:SP 'verde' 'pequena' 'jade' 'figura' 'estatua'
    'estatuilla' 'idolo',
:FR 'verte' 'petite' 'jade' 'figurine' 'statue'
    'statuette' 'idole',
:

 description

:DE
    "Es ist die Statue einer toltekischen
        Gottheit, komplett aus grüner Jade geschnitzt.
        Sie glänzt und sieht sehr wertvoll aus.",
:EN
    "It is the statue of a Toltec deity,
        crafted from green jade. It reflects the light
        beautifully and looks quite valuable.",
:IT
    "E' la statua di una divinita' tolteca, intagliata da
        una giada verde. Riflette la luce
        meravigiosamente e sembra di grande valore.",
:SP
    "Es una estatua de la deidad Toltec,
        tallada en jade verde. Refleja la luz
        de una manera hermosa y parece muy valiosa.",
:FR
    "C'est la statuette d'une divinité toltèque, taillée
        dans du jade vert. Elle reflète merveilleusement
        la lumière et semble avoir beaucoup de valeur.",
:
 before [;
    Take:
    if (self in Saeule && ~~(Stein in Saeule))
    {
        deadflag = true;

    :DE
        "Als du das Gewicht der Statue von der
        Säule nimmst, hörst Du ein klickendes
        Geräusch. Kurz darauf wirst du von
        Giftpfeilen durchbohrt.";
    :EN
        "As you lift the stauette's weight off
        the pedestal, you hear a klicking sound.
        A second later, you are pierced by poison
        darts.";
    :IT
        "Appena sollevi la statuetta dal piedistallo,
        senti uno scatto. Un momento dopo, sei colpito
        da dardi avvelenati.";
    :SP
        "En cuanto levantas la estatuilla del pedestal,
        escuchas un click. Un segundo después, tienes
        clavado un dardo envenenado.";
    :FR
        "Tandis que vous soulevez le poids de la
        statuette hors du piédestal, vous entendez un
        cliquetis. Une seconde plus tard, vous êtes
        transpercé par une fléchette empoisonnée.";
    :
    }
   ],
has female;



:DE Include "GermanG";
:EN Include "Grammar";
:IT Include "ItalianG";
:SP Include "SpanishG";
:FR Include "FrenchG";
:

end;