Mehrsprachige Programme mit INIs. _Translation.au3

  • Ich möchte euch meine UDFs für die Übersetzung von Strings in einem Skript vorstellen.
    Die Funktionsweise ist relativ simpel: Es werden Strings aus einer INI in ein Dicitionary-Objekt eingelesen, sodass später einfach darauf zugegriffen werden kann.
    Es gibt dabei Funktionen, die die Übersetzungen in einer Datei als unterschiedliche Sektionen erwarten. Es ist auch möglich, für jede Übersetzung eine eigene Datei zu verwenden. Immer entspricht dabei der ini-Sektionsname dem Namen der Sprache.

    Hier 2 Beispiele:

    Eine INI
    [autoit]

    #include "_Translate.au3"

    [/autoit] [autoit][/autoit] [autoit]

    $sPath = @ScriptDir & "\translations.ini"

    [/autoit] [autoit][/autoit] [autoit]

    ; hole Übersetzungen
    $aTranslations = _Translation_SI_ListAll($sPath)
    $sTranslation = _Translation_SI_Choose($aTranslations)
    ;~ If $sTranslation = '' Then $sTranslation = 'English'
    _Translation_SI_Load($sPath, $sTranslation)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $sName = InputBox(__("Your name"), __("Please enter your name!"))

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, '', StringFormat(__("Hi %s"), $sName))

    [/autoit]
    Mehrere INIs
    [autoit]

    #include "_Translate.au3"

    [/autoit] [autoit][/autoit] [autoit]

    $sPath = @ScriptDir & "\translations"

    [/autoit] [autoit][/autoit] [autoit]

    ; hole Übersetzungen
    $aTranslations = _Translation_MI_ListAll($sPath)
    $aTranslation = _Translation_MI_Choose($aTranslations)
    _Translation_MI_Load($sPath, $aTranslation)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $sName = InputBox(__("Your name"), __("Please enter your name"))

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, '', StringFormat(__("Hi %s"), $sName))

    [/autoit]


    Alle Dateien befinden sich im Anhang.

  • Kannst dus vll noch mal erklähren...
    Wie werden z.b. die strings aus dem Script in die Ini geschrieben?
    per hand?

  • Die Strigs werden ganz einfach als Stringpaare gespeichert.
    Links der String, der im String verwendet wird als Key
    Rechts die Übersetzung als Wert

    Im originalstring darf natürlich kein Gleichheitszeichen vorkommen, da das das Ini-Format zerstören würde. Wenn Zeilenumbrüche benötigt werden, sollte der String entweder mit Stringformat und den Metazeichen \r\n verwendet werden oder auf mehrere Strings aufgeteilst werden :) (StringFormat musst du aber selber im Skript einbauen, das wird nicht automatisch gemacht. Ich habe das ja auch ins Beispiel integriert

    Und noch ein Beispiel für eine Ini:

    Code
    [Sprache]
    String=Übersetzung ;)
    Anderer String=Stringformatstring \r\n %s

    Ja, de Strings werden per Hand in die Ini geschrieben. Ich kann aber auch ein Include erstellen, das eine leere Ini erstellt.

  • Es währe besser , weil meine Ini sieht so aus,

    INI

    [DE]
    basserror=Sound konnte nichtInitialisiertwerden!
    lizenz1=Mit dem ausführen dieses Programms stimmen sie der aktuellen lizenz zu.
    lizenz2=Wollen sie dieses Programm starten?
    close=Schließen
    playpause=Play|Pause
    stop=Stop
    andereDatei=Andere Datei
    neueBib=Neue Bibliothek
    Lautstärke=Lautstärke
    listtabs=Dateiname|Pfad
    vorwärts=Vorwärts
    playlistespeichern=Playliste speichern
    playlisteladen=Playliste laden
    JSoundöffnen=JSound öffnen
    RCVL=Lautsprecher Rechts
    LCVL=Lautsprecher Links
    statbar1=INR-Multimediacenter gestartet
    gespielt=Gerade gespielt:
    urlangeben?!=Internetadresse angeben
    urlinput=Bitte URL angeben
    laden=Laden
    senderHinzufügen=Sender Hinzufügen
    opt=Optionen
    statbar2= Konnte ID3-Tags nicht Lesen!
    statbar3=Playliste gestartet
    FOD1=MP3-Datei öffnen...
    FOD2=Ordner wählen
    FSD=Playliste Speichern...
    FSD1.2=Playlisten (*.INRP)
    FOD3=Playliste laden...
    FOD3.2=Playlisten (*.INRP)
    radioerror=Sie haben kein Radio ausgewählt!
    input1=BitteSendernamen angeben
    input1.2=Sendername
    input2=Bitte Adresseangeben
    input2.2=Adresse
    senderaddfinisch=Sendername:
    senderaddfinisch2=Senderadresse:"
    senderaddfinisch3=Ist das Richtig?
    senderaddanswer=Hinzugefügt
    tagoutputerror=Konnte ID3-Tags nicht Lesen!


    und das ist nichtmal die hälfte :pinch:

  • So, anstelle der _Translate,au3 kannst du folgenden Code includen (_TranslateCreate.au3):
    Dann werden alle abgerufenen Strings beim Skriptende in eine Datei geschrieben (EMPTY_TRANSLATION.ini im @ScriptDir)

    Spoiler anzeigen
    [autoit]

    Global $__goTranslationObject = ObjCreate("Scripting.Dictionary")
    $__goTranslationObject.CompareMode = 1 ; Text
    OnAutoItExitRegister("__Translate_Write")

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func __Translate_Write()
    ; Author: ProgAndy
    Local $keys = $__goTranslationObject.Keys
    Local $hTranslation = FileOpen(@ScriptDir & "\EMPTY_TRANSLATION.ini", 2)
    FileWrite($hTranslation, "[LANGUAGE]" & @CRLF)
    For $i = 0 To UBound($keys)-1
    FileWrite($hTranslation, $keys[$i] & "=" & @CRLF)
    Next
    FileClose($hTranslation)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Translation_Translate(Const $s)
    ; Author: ProgAndy
    $__goTranslationObject.Add($s, 0)
    Return $s
    EndFunc
    Func __(Const $s)
    ; Author: ProgAndy
    $__goTranslationObject.Add($s, 0)
    Return $s
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Translation_SI_Load()
    Return SetError(1,0,0)
    EndFunc
    Func _Translation_SI_ListAll(Const $sIniPath)
    Return SetError(1,0,0)
    EndFunc
    Func _Translation_SI_Choose(ByRef Const $aTranslations, $iStart=1)
    Return SetError(1,0,0)
    EndFunc
    Func _Translation_MI_ListAll(Const $sTransPath, $sExtension='ini')
    Return SetError(1,0,0)
    EndFunc
    Func _Translation_MI_Load(Const $sTransPath, $sIni, $sLanguage='')
    Return SetError(1,0,0)
    EndFunc
    Func _Translation_MI_Choose(ByRef Const $aTranslations, $iStart=1)
    Return SetError(1,0,0)
    EndFunc

    [/autoit]
  • was verstehst du unetr abgerufene strings?


    Ein abgerufener String ist einer, für den die Übersetzen-Funktion aufgerufen wurde ;) Also ein String, für den bereits die Übersetzung abgerufen/ausgelesen/angezeigt/abgefragt/angefordert/... wurde.