AutoIt-Skripte multilingual machen

  • Hi,

    Ich hatte mich damit schonmal vor einiger Zeit beschäftigt:
    Wie macht man ein Skript schnell multilingual.

    Damals hab ich das mit RegEx gemacht, war aber dumm, weil er verschachtelte Strings nicht konnte... Also heute mit Schleifen und Zeile-für-Zeile abarbeiten.
    Es ist noch ziemlich Beta, aber funktioniert in den meisten Fällen.
    Probleme:

    • Kommentare werden einfach verschluckt.
    • Strings in Funktionsdefinitionen werden auch ersetzt, das muss man also von Hand korrigieren
    • Man muss nach der Umwandlung per Hand an den Beginn des Skriptes $lang="de" (bzw. die gewünschte Sprache) stellen
    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    $file=Fileopen("dummy.au3")
    $newfile=Fileopen("dummy_multilang.au3",1)
    Global $iniID=0
    $chars=""
    For $i=1 To 9999999999
    $chars = FileReadLine($file, $i)
    If @error = -1 Then ExitLoop
    $array = StringSplit($chars,"")
    $result=_renderline($array)
    FileWriteLine($newfile,$result)
    Next

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

    Func _renderline($array)
    Local $state=0 ; 0=nix, 1=", 2='
    Local $returnArray[1],$stringpos=0
    For $i=1 To $array[0]
    Switch $state
    Case 0
    ;wir schauen nach allem
    Switch $array[$i]
    Case ";"
    ;Kommentar, nächste Zeile (vorerst auffressen)
    ExitLoop
    Case "'"
    $state=2
    $stringpos=$i
    Case '"'
    $state=1
    $stringpos=$i
    Case Else
    _ArrayAdd($returnArray,$array[$i])
    EndSwitch
    Case 1
    ;wir schauen nach "
    Switch $array[$i]
    Case '"'
    $state=0
    $string=StringFromArray($array,$stringpos,$i)
    $iniID +=1
    IniWrite("multilang.ini","de",$iniID,$string)
    _ArrayAdd($returnArray,"IniRead('multilang.ini',$lang," & $iniID & "," & $string & ")")
    Case Else
    ContinueLoop
    EndSwitch
    Case 2
    ;wir schauen nach '
    Switch $array[$i]
    Case "'"
    $state=0
    ;~ $string="STRB" & StringFromArray($array,$stringpos,$i) & "SRTE"
    $string=StringFromArray($array,$stringpos,$i)
    $iniID +=1
    IniWrite("multilang.ini","de",$iniID,$string)
    _ArrayAdd($returnArray,"IniRead('multilang.ini',$lang," & $iniID & "," & $string & ")")
    Case Else
    ContinueLoop
    EndSwitch
    EndSwitch
    Next
    Return StringFromArray($returnArray)
    EndFunc

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

    Func StringFromArray($array,$stringpos="def",$i="def")
    If not IsArray($array) Then MsgBox(0,"Error","Not an array inside StringFromArray")
    If $stringpos="def" Then
    $stringpos=0
    $i= UBound($array)-1
    EndIf
    $ret=""
    For $j=$stringpos To $i
    $ret &= $array[$j]
    Next
    Return $ret
    EndFunc

    [/autoit]

    Twitter: @L3viathan2142
    Benutze AutoIt persönlich nicht mehr, da ich keinen Windows-Rechner mehr besitze.

  • Wenn ichs richtig verstanden habe, Erställt es aus einem "Basisscript" ein neues Script in dem sämmtliche Funktionsparameter auf Iniread bezogen werden und erstellt eine Ini nach dem Muster: 1(1. Parameter im Script)=Parameter Wert.

    Vorteil: man kann im nachhinein noch das Programm verändern auch wenn es schon Compiled ist, richtig verstanden? =)


    Edit: nochmal überflogen habs schätzungsweise falsche verstanden....

  • @Bloodykill: Richtig verstanden, außer den Verwendungszweck (auch wenn das natürlich auch geht)

    Der Hauptzweck ist es aber, dass man ganz einfach zum Beispiel Programme schreiben kann, die in unterschiedlichen Sprachen (Englisch, Deutsch, Französisch bspw.) verfügbar sind. Die Implementierung eines Sprachauswahldialogs o.ä. habe ich bewusst weggelassen, das kann der jeweilige Entwickler dann selbst machen.

    Twitter: @L3viathan2142
    Benutze AutoIt persönlich nicht mehr, da ich keinen Windows-Rechner mehr besitze.

  • Zitat von Das Help-File

    From a performance standpoint it is a bad idea to read line by line specifying "line" parameter whose value is incrementing by one. This forces AutoIt to reread the file from the beginning until it reach the specified line.

  • ich include per fileinclude eine deutsche und eine englische sprachdatei, hier könnten noch beliebig weitere zugeführt werden. lasse dann per @oslang den ersten dialog nach programmstart in der systemsprache anzeigen, in dem aber gleichzeitig auch ein sprachwechsel möglich ist.

    [autoit]


    FileInstall("dvbs-de.lng", @TempDir & "\dvbs-de.lng", 1)
    FileInstall("dvbs-en.lng", @TempDir & "\dvbs-en.lng", 1)
    if StringInStr("0409 0809 0c09 1009 1409 1809 1c09 2009 2409 2809 2c09 3009 3409", @OSLang) then
    $language = "english"
    $langcfg = "en"
    Dim $interface
    _FileReadToArray(@TempDir & "\dvbs-"&StringLeft($language, 2)&".lng",$interface)
    else
    $language = "deutsch"
    $langcfg = ""
    Dim $interface
    _FileReadToArray(@TempDir & "\dvbs-"&StringLeft($language, 2)&".lng",$interface)
    endif

    [/autoit]


    [Blockierte Grafik: http://img822.imageshack.us/img822/3764/tempsnap64t.jpg][Blockierte Grafik: http://img822.imageshack.us/img822/1061/tempsnap64j.jpg]
    alle weiteren gui's und dialoge werden dann in der gewählten sprache angezeigt.
    z.b.:

    [autoit]


    MsgBox(16, $interface[18], $interface[28])

    [/autoit]
  • Dein Code ersetzt doch alle Strings automatisch mit dem IniRead. Ich hätte jetzt vorgeschlagen, dass du stattdessen den Text mit der Funktion __() umgibst ;)

  • Ah klar, kein Problem:

    Progandy-Variante
    [autoit]

    #include <Array.au3>
    $file=Fileopen("dummy.au3")
    $newfile=Fileopen("dummy_multilang.au3",1)
    Global $iniID=0
    $chars=""
    While 1
    $chars = FileReadLine($file)
    If @error = -1 Then ExitLoop
    $array = StringSplit($chars,"")
    $result=_renderline($array)
    FileWriteLine($newfile,$result)
    WEnd

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

    Func _renderline($array)
    Local $state=0 ; 0=nix, 1=", 2='
    Local $returnArray[1],$stringpos=0
    For $i=1 To $array[0]
    Switch $state
    Case 0
    ;wir schauen nach allem
    Switch $array[$i]
    Case ";"
    ;Kommentar, nächste Zeile (vorerst auffressen)
    ExitLoop
    Case "'"
    $state=2
    $stringpos=$i
    Case '"'
    $state=1
    $stringpos=$i
    Case Else
    _ArrayAdd($returnArray,$array[$i])
    EndSwitch
    Case 1
    ;wir schauen nach "
    Switch $array[$i]
    Case '"'
    $state=0
    $string=StringFromArray($array,$stringpos,$i)
    _ArrayAdd($returnArray,"__(" & $string & "," & $string & ")")
    Case Else
    ContinueLoop
    EndSwitch
    Case 2
    ;wir schauen nach '
    Switch $array[$i]
    Case "'"
    $state=0
    ;~ $string="STRB" & StringFromArray($array,$stringpos,$i) & "SRTE"
    $string=StringFromArray($array,$stringpos,$i)
    _ArrayAdd($returnArray,"__(" & $string & "," & $string & ")")
    Case Else
    ContinueLoop
    EndSwitch
    EndSwitch
    Next
    Return StringFromArray($returnArray)
    EndFunc

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

    Func StringFromArray($array,$stringpos="def",$i="def")
    If not IsArray($array) Then MsgBox(0,"Error","Not an array inside StringFromArray")
    If $stringpos="def" Then
    $stringpos=0
    $i= UBound($array)-1
    EndIf
    $ret=""
    For $j=$stringpos To $i
    $ret &= $array[$j]
    Next
    Return $ret
    EndFunc

    [/autoit]

    Twitter: @L3viathan2142
    Benutze AutoIt persönlich nicht mehr, da ich keinen Windows-Rechner mehr besitze.