Alte Revision
Spielplatz place02
#! /usr/bin/env ruby # encoding: UTF-8 # iolate.rb: # # Version 2.03.12 # # Extract the translateable text from # the dokwiki-file cpage.dkw to the Textfile # transfertext.utf8 and after translation # reinsert it # # Copyright 25.02.2022 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. # # == syntax # # iolate.rb [-i inputfilename] # [-o throughputfilename] # [-c separation character] # [-k] # [-v] # [-h] # # -i # name of the file in dokuwiki-syntax. If none is given, # cpage.dkw is assumed # # -o # Name of the text file which contains the text in dokuwiki-syntax. # If none is given transfertext.utf8 is assumed # # -c # Character to seperate languages in transfertext.utf8 # from oneanother. The default is ~. You may need this option, # if a ~ is naturally occuring in the text # # -k # Keep tags in the outputfile transfertext.utf8 # # -e # ignore empty lines # # -v # verbose # # -h # show help # # == file formats # # cpage.dkw # has to be formated according to https://comicslate.org/en/wiki/12balloons # Only the text in text boxes between the the first tag pair # {{cotan>...}} ... {{<cotan}} is extractet into transfertext.utf8, # text boxes before or after this are left unchanged # The first ... here represents a Filename which must not contain }} # The second ... represents the string which is searched for translateable text # which must not itself contain {{<cotan}}. # Only text in textboxs is extraxted i.e. the line before the text must # start with an @ wich is followed by at least four # comma seperated integeres, e.g. @37,25,419,112 # After the text there has to be a line containing exactly one ~ character # at the start of the line, marking the end of the texbox # The following holds true für the translated file cpage.dkw # All <...> tags are removed from the result of the second run # All [...] tags which are not at the start of the first line, # are removed from the result of the second run # All -. are removed # All linefeeds and carriage returns are removed # The removing of <...> and [...] tags can be suppressed with -k # This file is than also used as output to store the data # between passes in yaml format. # # cpages.yaml # stores all the data of the file cpages.dkw except for the text which # has to be translated # # transfertext.utf8 # In the extracted text all text from one textbox is concatenatet into # one line, seperated by a space. The text of all textboxes # is concatenated seperated by one LF character per box. # This output file is used as input in the second pass. # The translated text has to concur to the same specification # in order to be used for the construction of cpages1.dkw # # cpages1.dkw # The recreated file containing the markup from cpage.dkw and the text # from transfertext.utf8 # == usage in context # # 0. It is assumed that you have the curent version of # the ruby interpreter installed as well as the gems # listed under "dependecies". Copy this script into # a directory on your computer. All further file handling # is assumed to take place there # # 1. copy the content of the strip you want to translate # or at least {{cotan>...}}, {{<cotan}} and what is between them # into the file called cpage.dkw in the directory where # the executable file iolate.rb is located # # 2. execute, e.g call ruby iolate.rb # # 3. open the file transfertext.utf8 and copy its contense # into the input field of a translation service or programm # like Deepl.com or lingvanex.com # # 4. translate # # 5. overcopy the text in transfertext.utf8 with # the translation and save the file # # 5. execute iolate.rb again # # 6. cpages1.dkw should now contain the translation # # == todo # # 1. add a loop and REST-api combatibility # to this script, to translate whole comics at once # # == constants # NEWLINECHAR = "\n" # EOL standard char to indicate end of line SYSLIMITFILENAME = 255 # maximal length of a file name for ext4 # one of these letters after a ~ gives an outputfilename with the corresponding language name COUNTRYLETTERS = [ ["b", "Brazilian"], ["l", "Bulgarian"], ["c", "Chinese"], ["d", "Danish"], ["f", "French"], ["g", "German"], ["h", "Hungarian"], ["p", "Portuguese"], ["j", "Japanese"], ["r", "Russian"], ["s", "Spanish"], ["t", "Turkish"], ["u", "Finnish"] ] DEFAULTLANGUAGELETTER = "g" # translations without an indicating letter are considered German # == dependecies # class for handling filenames, pathnames, etc. begin require 'pathname' rescue Exception STDERR.puts "warnung: require of pathname failed." end # class for parsing commandline options begin require 'optparse' rescue Exception STDERR.puts "warnung: require of optparse failed." # exit 1 # nonfatal if no options are given, so cross your fingers end # class for serialization begin require 'yaml' rescue Exception STDERR.puts "warnung: require of yaml failed." exit 1 end # == methods # # to keep in line with a functional approch which might be easier # to port to javascript with opal, we make no use of oo, # but use the methods of this object as functions # remove everything between sBeginChar # und sEndChar including those characters # allover sStr and return sStr def removebetween(sStr, sBeginChar="<", sEndChar=">") iBegin = sStr.index(sBeginChar) while not iBegin.nil? iEnd = sStr.index(sEndChar, iBegin + 1) if iEnd.nil? return sStr else sStr.slice!(iBegin, iEnd - iBegin + 1) iBegin = sStr.index(sBeginChar) end end return sStr end # returns true if a string represents an integer def is_i?(sMayBeInteger) /\A[-+]?\d+\z/ === sMayBeInteger end def is_number? string true if Float(string) rescue false end # returns true, if the string sLine is the first line of a text or mask box def isBoxStart(sLine) unless sLine.start_with? "@" # has to start with @ return false end asLine = sLine[1...-1].rstrip.split "," # get rid of the @ and slit the rest of the line into coordinates, if it is a box unless asLine.length > 3 # al leas four coordinates return false end unless is_number?(asLine[0]) # each coordinate has to be a float, testing the first return false end unless is_number?(asLine[1]) # each coordinate has to be a float, testing the second return false end unless is_number?(asLine[2]) # each coordinate has to be a float, testing the third return false end unless is_number?(asLine[3][0]) # TODO not a complete test jet, some non textboxes might fulfill this and slip through return false end return true end # returns true, if the string sLine is the first line of a text box def isTextBoxStart(sLine, sNextLine) unless sNextLine.nil? # there is something ahead, i.e. a second line if isBoxStart(sLine) unless sNextLine.chr == "#" # no mask return true end end end return false end # splits a filename into extension and the part before # unlike File.extname the dot is returned as part of the extension def splitbasename(sFilename) iDotPos = sFilename.rindex(".") aF = Array.new if iDotPos.nil? aF << sFilename aF << "" else aF << sFilename[0...iDotPos] aF << sFilename[iDotPos..-1] end return aF end # shortens the basename, until it is of legal length def shortentolegallength(sFilename) if SYSLIMITFILENAME < 3 exit 1 # not your usual file system end aFilename = File.split(sFilename) # il = aFilename[1].length aB = splitbasename(aFilename[1]) # field of two elements for the extension and the stuff before it if il > SYSLIMITFILENAME # to long iDif = il - SYSLIMITFILENAME if aB[0].length > iDif # we want to keep at least one letter, to avoid producing dot files aB[0] = aB[0...-iDif] else iresttocut = iDif - aB[0].length + 1 aB[0] = aB[0].chr # keep one letter aB[1] = aB[0...-iresttocut] # additionally shorten the extension end end return aFilename[0] + File::SEPARATOR + aB[0] + aB[1] end # gives the name of a language given by a letter def languagefromletter(slchar) ael = COUNTRYLETTERS.select {|schar| schar[0] == slchar } if ael.nil? return nil else return ael[0][1] end end # gives the phrase memory of a language given by the language's letter def phrasememoryfromletter(slchar, asPhrasesTT) slanguage = languagefromletter(slchar) if slanguage.nil? return nill else return phrasememoryfromname(slanguage, asPhrasesTT) end end # gives the phrase memory of a language given by the language's name in english def phrasememoryfromname(slanguage, asPhrasesTT) slPhrases = asPhrasesTT.select { |slPhr| slanguage == slPhr[0] } return slPhrases[0] end # remove the last lines if they are empty # if the rest of the string contains an empty line, remove it and everything before it def removebeforeemptyline(stranslation) iemptylinepos = stranslation.rindex("\n\n") if ! iemptylinepos.nil? while iemptylinepos == stranslation.length - 2 #letzte Zeile ist leer stranslation.slice!(stranslation.length - 2, stranslation.length) # TODO why does stranslation.slice!(-2, -1) not work # stranslation.slice! (-2) , -1 # TODO (-2) instead of -2 in order to avoid the warnung of ambigous syntax, but still does not work iemptylinepos = stranslation.rindex("\n\n") end end stranslation.slice! 0, iemptylinepos + 2 unless iemptylinepos.nil? # TODO warum muss hier 2 statt 1 stehen? return stranslation end # == main # # For phrases wich are always translated, eg. headers # the translation can be provided in the DATA-section at the end of this file asPhrasesToTranslate = COUNTRYLETTERS.map { |sla| [ sla[1] ] } # an array with an array for each language, containing as its only element the name of the lamguage sOrig = "" # outside of the loop to be persistent between runs DATA.each_line do |sDATAline| #read those phrases fro, the DATA sLangChar = sDATAline.chr if sLangChar == "=" # origin's language, englisch sOrig = sDATAline[2..-2] # skip firt two characters and the last else ap = phrasememoryfromletter(sLangChar, asPhrasesToTranslate) #puts ap.inspect if not ap.nil? ap << [sOrig, sDATAline[2..-2]] end end end # options = {:verbose => nil, :dokuinfilename => "cpage.dkw", :textoutputfilename => "transfertext.utf8", :sepcharacter => "~", :fkeep => false, :fkeepempty => false} # default values go here opt_parser = OptionParser.new do |opts| opts.banner = "Usage: ocr-latest-png.rb [-i dokuinfilename] [-o textoutputfilename] [-c separationcharacter] [-k] [-v] [-h]" opts.on("-i filename", "--inputfile", "name of the dokuwiki file from which to extract translateable text. The default is cpages.dkw.") do |anopt| options[:dokuinfilename] = anopt end opts.on("-o filename", "--outputtext", "name of the text file to which translateable text is written. The default istransfertext.utf8.") do |anopt| options[:textoutputfilename] = anopt end opts.on("-c separationcharacter", "--separationcharacter", "the charcter used to seperate different languages in transfertext.utf8. The default is ~.") do |anopt| options[:sepcharacter] = anopt end opts.on("-k filename", "--keeptags", "do not atempt to delete all tags. Default is .") do |anopt| options[:fkeep] = anopt end opts.on("-e keepemty", "--keepemtyline", "do not delete empty lines at the end and do not delete the first empty line and everything before it. Default is do delete") do |anopt| options[:fkeepempty] = anopt end opts.on("-v", "--[no-]verbose", "show comments") do |anopt| options[:verbose] = anopt end opts.on("-h", "--help", "show this help.") do puts opts exit end end begin opt_parser.parse! rescue OptionParser::InvalidOption puts "\nunknown option" puts "in line" + __LINE__ # the current line number in the source file. puts $! # error message puts $@ # error position raise end # set verbosity flag if ! options[:verbose].nil? $ivc = 0 else $ivc = 1 end sDokuwikifile = "cpage.dkw" # default name if options[:dokuinfilename].nil? # should be impossible, but well ... puts "after the -i option there needs to be a filename" if $ivc > 0 exit 1 else sDokuwikifile = options[:dokuinfilename] end sTransferfile = "transfertext.utf8" if options[:textoutputfilename].nil? # also impossible puts "after the -o option there needs to be a filename" if $ivc > 0 exit 1 else sTransferfile = options[:textoutputfilename] end sSepChar = "~" if options[:sepcharacter].nil? # also impossible puts "after the -c option there needs to be a separation character for the different languages" if $ivc > 0 exit 1 else sSepChar = options[:sepcharacter] end fkeep = options[:fkeep] fkeepempty = options[:fkeepemty] bInCotan = false # flag bInTextbox = false # flag iNrTextboxes = 0 # the total number of textboxes which were red asPageAsLines = Array.new # the markup pieces of the file are collected here aiTextLineNumbersInPage = Array.new # the line numbers of the text box lines in the page asTextLines = Array.new # the text lines from the text boxes, one element per textbox contains all the lines from this textbox asTextboxTags = Array.new # the tags at the start of a text line unless File.exists? sTransferfile # if true, we are pre translation, otherwise post translation if File.exists? sDokuwikifile file = File.open(sDokuwikifile, "r") else STDERR.puts "Dokuwiki file " + sDokuwikifile + " could not be found. Maybe you have to use the option -i to make the correct name known." exit 1 end aText = file.read.split "\n" file.close sTextBoxText = String.new # string to collect all the text from a textbox in aText.each_index { |iline| sline = aText[iline] if bInCotan # starting to search for textboxes if sline.include? "{{<cotan}}" # stop searching for textboxes, if you're out of the cotan block bInCotan = false asPageAsLines << sline unless bInCotan # hand cotan block's tail through else if bInTextbox if sline.strip == "~".chr # this is the way a textbox ends, not with a !, but with a ~ asTextLines << sTextBoxText # all the txt from the text box has been collected and can now be stored as one line sTextBoxText = String.new # reset to empty asPageAsLines << "" # store an empty line, because the text goes to asTextLine asPageAsLines << sline #lines before and after a textbox, including the textbox's head and tail are just handed through bInTextbox = false else sline.strip! if sTextBoxText.empty? # this is the first non empty text box line if sline.chr == "[" # text line starts with a tag while sline.chr == "[" # a tag is still at the start of the line iClose = sline.index "]" if iClose == -1 # no closing parenthesis found break # the rest of the line is supposed to contain the text else asTextboxTags[iNrTextboxes - 1] += sline[0..iClose] # save the tag by appending it to previous tags in the same line sline = sline[iClose + 1 .. -1] # remove the tag from the line end end # next tag end # all starting tags removed end # the starting tags in non first text box lines in textboxes are not saved unless fkeep # remove other tags unless blocked removebetween sline removebetween sline, "[", "]" end if ! sTextBoxText.empty? # if the text has various lines concatenate them all sepereted by a blank sTextBoxText += " " end sTextBoxText += sline + "\n" end else # not in a Textbox asPageAsLines << sline #lines before and after a textbox, including the textbox's head and tail are just handed through if isTextBoxStart(sline, aText[iline + 1]) # a textbox starts with this line, but also a mask aiTextLineNumbersInPage << asPageAsLines.length - 1 # the line number in the output file where the text belongs. asTextboxTags << "" # initialize tag memory for this textbox iNrTextboxes += 1 # keep, count of the textboxes bInTextbox = true end end end else asPageAsLines << sline # lines before and after the cotan block, including the cotan block's head and tail are just handed through bInCotan = sline[0..7] == "{{cotan>" end } # next line of the dokuwiki file # collect all information for the second pass in an array oSerializedData = Array.new oSerializedData << fkeep oSerializedData << iNrTextboxes oSerializedData << asPageAsLines oSerializedData << aiTextLineNumbersInPage oSerializedData << asTextboxTags # oSerializedData << asTextLines # write intermediate file for second pass, using the original dokuwiki file name with a yaml extension iDotPos = sDokuwikifile.rindex "." iDotPos = sDokuwikifile.length if iDotPos.nil? sYamlFile = Pathname.new(sDokuwikifile).sub_ext(".yaml") File.open(sYamlFile, "w") do |file| file.puts YAML::dump(oSerializedData) end # write textfile to be translated File.open(sTransferfile, "w") { |file| asTextLines.each { |s| file.write s } } else # post translation sYamlFile = Pathname.new(sDokuwikifile).sub_ext(".yaml") # name of the yaml file reconstructed oSerializedData = Array.new oSerializedData = YAML.load_file(sYamlFile) # fkeep = oSerializedData[0] # Flag indicating if HTML-mark up is to be kept iNrTextboxes = oSerializedData[1] # the number of txtboxes should equal the lines of translated text asPageAsLines = oSerializedData[2] aiTextLineNumbersInPage = oSerializedData[3] asTextboxTags = oSerializedData[4] # [...]-style mark up at the beginning of a textbox, if there is one stranslation = String.new # load translated text if File.exists? sTransferfile file = File.open(sTransferfile, "r") # load all translations stranslation = file.read file.close else STDERR.puts "Transfer file " + sTransferfile + " could not be found. Maybe you have to use the option -o to make the correct name known." exit 1 end if ! fkeepempty # if not wanted otherwise remove the first empty line and everything before it removebeforeemptyline stranslation end asAllTranslatedText = stranslation.split sSepChar # various languages are seperated by a sSepChar wich by default is a ~ and optionally an additional letter to indicate the language sLanguage = String.new # holds the language of the second and following translations asAllTranslatedText.each_index { |iOneLanguage| # one language at a time, by number asTranslatedText = Array.new # contains one translation as an Array sOneLanguage = asAllTranslatedText[iOneLanguage] # the translated text of this language in one string wih linebraks asTranslatedText = sOneLanguage.split "\n" # get the lines for this languge if iOneLanguage > 0 # more than one language according to the number of subfiles. Starting with the second language there's the possibilty that there is a letter indicating a language after the ~ sFirstLine = asTranslatedText[0][0] # the separation character e.g. ~, was already removed, so this is second character in the original line if sFirstLine.empty? # no language identifying letter or language given # sLanguage = "" # stays empty else # an additional character can indicate a languge allLangs = COUNTRYLETTERS.select { |sl| # search through all letters indicating countries fReturn = false sFirstLine.each_char { |sChar| # search through all chars in the string, which should be one if sl[0].upcase == sChar.upcase fReturn = true end } fReturn # returns tue if the corresponding language indicating letter was found in the first line } allLangs.each_index { |iL| if iL == 0 sLanguage = allLangs[0][1] else sLanguage = sLanguage + "-" + allLangs[iL][1] end } end # we now have a language string which contains all languages of the translation, which was overly complicated, because we restricted the line to one charcter indicating a language and therefore to one language asTranslatedText.shift # remove the first line of this languge's block, as it does not contain translated text end # end of the search for the name of the language if asTranslatedText.length != iNrTextboxes # regardless of language every translation has to have the same number of lines if $ivc > 0 if sLanguage == "" STDERR.puts "warning for default language " else STDERR.puts "warning for language " + sLanguage end STDERR.puts "warning: the number of textboxes " + iNrTextboxes.to_s + " does not equal the number of translated strings " + asTranslatedText.length.to_s + "." end end # get the translateable phrases for this language if sLanguage.empty? sdefLang = languagefromletter(DEFAULTLANGUAGELETTER) # use the default language if non given if sdefLang.nil? asPhrasesForLanguage = Array.new # empty array else asPhrasesForLanguage = asPhrasesToTranslate.select { |asa| asa[0] == sdefLang } end else # use the language indicated in the seperator line asPhrasesForLanguage = asPhrasesToTranslate.select { |asa| asa[0] == sLanguage } # make translation end asPhrasesForLanguage = asPhrasesForLanguage[0] unless asPhrasesForLanguage.empty? # TODO why is this a three times array? sOutputtext = String.new # collect the new dokuwiki-file to be written in ths variable # iTextBoxCur = 0 asPageAsLines.each_index { |iline| # go through all the lines of the dokuwiki source page by their number iTextBoxCur = aiTextLineNumbersInPage.find_index(iline - 1) # do a lookup, whether this line's number is in the table of translateable lines if iTextBoxCur.nil? # do we have no translation for this line? sPL = asPageAsLines[iline] # no translation, so take the line as handed down from the original unless asPhrasesForLanguage.empty? # but if we have phrases for this language .,. asPhrasesForLanguage.each { |colmem| # ... go through all the phrases to see, if part of this line can be translated this way if colmem.class.to_s == "Array" # there has to be an original and a translated text in this element of the phrases collection, i.e. it has to be an array sPL = sPL.gsub(colmem[0],colmem[1]) # translate end } end sOutputtext = sOutputtext + sPL + "\n" # this line gets handed through unchanged else # there is a translation for this line which we take from the sTransferfile if asTranslatedText[iTextBoxCur].nil? # catch out of array error, if there are too few lines of translated text unless sLanguage == "" STDERR.puts "warning for language " + sLanguage end STDERR.puts " no textbox found for " + iTextBoxCur.to_s + " Too few lines of translated text" exit 1 else sOutputtext = sOutputtext + asTextboxTags[iTextBoxCur] + asTranslatedText[iTextBoxCur] + "\n" end # iTextBoxCur += 1 end } # remove trailing empty lines while sOutputtext[sOutputtext.length - 1] == "\n" sOutputtext.chomp! end # construct a name for the output file by inserting the number of the translation and the language before the extension dot iDotPos = sDokuwikifile.rindex "." iDotPos = sDokuwikifile.length if iDotPos.nil? if iDotPos != sDokuwikifile.length # insert language name before dot sOutputfile = shortentolegallength( sDokuwikifile[0..iDotPos-1] + "-" + iOneLanguage.to_s + "-" + sLanguage + sDokuwikifile[iDotPos..-1] ) else # add shortend language name, because if the file is without extension, we assume that length is expansive sOutputfile = shortentolegallength( sDokuwikifile + iOneLanguage.to_s + sLanguage[0..2] ) end # write final output File.open(sOutputfile, "w") do |file| file.puts sOutputtext end } # this translation is finished, go to the next File.delete sTransferfile # cleaning up # File.delete sYamlFile # cleaning up end # # The following DATA-section provides how # to translate certain phrases. A = denotes # the phrase in the original language, # which is english in the following examples __END__ = Color by George Peterson b Cor por George Peterson c 乔治-彼得森的色彩 d Farve af George Peterson f Couleur par George Peterson g Farbe von George Peterson h Színezd George Peterson j カラー:ジョージ・ピーターソン l Цвят от George Peterson p Cor por George Peterson r Цвет по Джорджу Петерсону s Color de George Peterson t u Väri George Peterson = Cameo by b Cameo por c 伪装者 d Cameo af f Cameo par g Cameo von h Cameo a j カメラマン l Камео от p Cameo por r В ролях s Cameo de t u Cameo = Provisional Title: Return to the Station b Título provisório: Retorno à Estação Espacial c 临时标题。返回空间站 d Foreløbig titel: Tilbage til rumstationen f Titre provisoire : Retour à la station g Vorläufiger Titel: Rückkehr zur Station h Ideiglenes cím: Visszatérés az állomásra j 仮のタイトル 宇宙ステーションへの帰還 l Временно заглавие: Завръщане на гарата p Título provisório: Regresso à Estação r Предварительное название: Возвращение на станцию s Título provisional: Regreso a la estación t u Väliaikainen nimi: Avaruusasemalle paluu = How to catch a deer. Sort of b Caçador de cervos, por assim dizer c 可以这么说,猎鹿人 d Hjortejæger, så at sige f Cerbère pour ainsi dire g Hirschfängerin sozusagen h Szarvasvadász, hogy úgy mondjam j ディアハンター l Ловец на елени, така да се каже p Caçador de veados, por assim dizer r «Как поймать оленя» в картинках s Cazador de ciervos, por así decirlo t u Hirvenmetsästäjä, niin sanoakseni = Florence gets the sticky notes of doom b Florença recebe as notas pegajosas da desgraça c 佛罗伦萨得到厄运的贴纸 d Florence får de uheldige sedler f Florence obtient les notes autocollantes de la malédiction g Florence bekommt die Klebezettel der Vernichtung h Florence megkapja a végzet öntapadós jegyzeteit j 運命の付箋を手にするフローレンス l Флоренция получава самозалепващите се бележки на съдбата p Florença recebe as notas pegajosas da desgraça r Флоренция получает липкие записки судьбы s Florence recibe las notas adhesivas de la destrucción t u Florence saa tuomion muistilaput = Day of the dead b Dia dos mortos c 死者之日 d De dødes dag f Le jour des morts g Totentag h A halottak napja j デイ・オブ・ザ・デッド l Ден на мъртвите p Dia dos mortos r s Día de los muertos t u Kuolleiden päivä = Off to see Mr. Raibert b Fora para ver o Sr. Raibert c 去见Raibert先生 d På vej til hr. Raibert f Je vais voir M. Raibert g Unterwegs zum Treffen mit Herrn Raibert h Elmegyek Raibert úrhoz j ライバート氏に会いに行く l Отивам при г-н Райберт p Fora para ver o Sr. Raibert r Пошел к мистеру Райберту s Vamos a ver al Sr. Raibert t u Menossa tapaamaan herra Raibertia = Dumpster diving for wolves b Mergulho em lixeiras para lobos c 垃圾箱中的狼群 d Dumpster diving for ulve f Plonger dans les poubelles pour trouver des loups g Containernde Wölfe h Szemétbúvárkodás farkasokért j オオカミのダンプカー・ダイビング l Търсене на вълци в кофите за боклук p Mergulho em contentores de lixo para lobos r Погружение в мусорный контейнер в поисках волков s Búsqueda de lobos en el contenedor t u Roskasukellus susien löytämiseksi = Off to see the Mayor b Vamos até o prefeito c 让我们去找市长 d Lad os gå til borgmesteren f En route pour la mairesse g Auf zur Bürgermeisterin h Menjünk a polgármesterhez j 市長のところへ行こう l На посещение при кмета p Vamos até ao presidente da câmara r Давайте обратимся к мэру s Vamos a ver a la alcaldesa t u Mennään pormestarin luo = Breaking and entering for fun and profit b Arrombamento e entrada para diversão e lucro c 为了乐趣和利益而破门而入 d Indbrud og indbrud for sjov og profit f Effraction pour le plaisir et le profit g Einbruch und Raubzüge bringen Spaß und Geld h Betörés és behatolás szórakozásból és haszonszerzés céljából j 遊び心と利益のための不法侵入 l Влизане с взлом за забавление и печалба p Arrombamento e entrada por diversão e lucro r Проникновение с приколом s Los robos y asaltos aportan diversión y dinero t u Murtautuminen huvin ja voiton tavoittelemiseksi = A secret meeting and Sawtooth's birthday b Uma reunião secreta e o aniversário de Sawtooth c 秘密会议和Sawtooth的生日 d Et hemmeligt møde og Sawtooths fødselsdag f Une réunion secrète et l'anniversaire de Sawtooth g Ein geheimes Treffen und Sawtooths Geburtstag h Egy titkos találkozó és Fűrészfog születésnapja j 秘密会議とノコギリソウの誕生日 l Тайна среща и рожден ден на Sawtooth p Uma reunião secreta e o aniversário de Sawtooth r Секретная встреча на дне рождения Пилозуба s Una reunión secreta y el cumpleaños de Sawtooth t u Salainen kokous ja Sahanhampaan syntymäpäivä = Spiking the servers b Espicaçando os servidores c 加注服务器 d Spiking af serverne f Piquez les serveurs g Die Server spicken h A szerverek felturbózása j サーバーへのスパイク l Спийкване на сървърите p Espicaçar os servidores r «Прокалывание» серверов s Pegar a los servidores t u Palvelimien piikittäminen = Edge reactivates Blunt b Edge reativa o Blunt c 边缘重新激活钝器 d Edge genaktiverer Blunt f Edge réactive Blunt g Edge reaktiviert Blunt h Edge újra aktiválja Blunt j エッジがブラントを再活性化 l Edge активира отново Blunt p Edge reactiva o Blunt r Эдж перезапускает Железяку s Edge reactiva Blunt t u Edge aktivoi Bluntin uudelleen = Robot chases wolf b robô persegue lobo c 机器人追赶狼 d robot jagter ulv f un robot chasse le loup g Roboter jagt Wolf h robot üldözi a farkast j ロボットが狼を追う l Робот преследва вълк p robô persegue lobo r Робот гонится за волком s el robot persigue al lobo t u robotti jahtaa sutta = Into the Ecosystems Unlimited compound b Dentro do composto Ecosystems Unlimited c 进入生态系统的无限复合 d Ind i Ecosystems Unlimited-forbindelsen f Dans l'enceinte d'Ecosystems Unlimited g Aufs Ecosystems Unlimited Firmengelände h Az Ecosystems Unlimited vegyületbe j エコシステムズ・アンリミテッドの化合物の中へ l В състава на Ecosystems Unlimited p Dentro do composto Ecosystems Unlimited r Внутри «Экосистемс Анлимитед» s En el recinto de Ecosystems Unlimited t u Ecosystems Unlimited -yhdisteeseen = Clippy discovers his plan has failed b Clippy descobre que seu plano falhou c Clippy发现他的计划失败了 d Clippy opdager, at hans plan er mislykkedes f Clippy découvre que son plan a échoué g Clippy erkennt, dass sein Plan in die Hose gegangen ist h Clippy rájön, hogy terve kudarcot vallott l Клипи открива, че планът му се е провалил p Clippy descobre que o seu plano falhou j クリッピーの計画が失敗したことを知る r Клиппи обнаруживает провал плана s Clippy descubre que su plan ha fracasado t u Clippy huomaa suunnitelmansa epäonnistuneen = Midnight and movement is restored b A meia-noite e o movimento são restaurados c 午夜和运动恢复了 d Midnat og bevægelse er genoprettet f Minuit et le mouvement est restauré g Die Geisterstunde bringt wieder Bewegung ins Spiel h Éjfél és a mozgás helyreáll j 真夜中、動きが回復する l Полунощ и движението е възстановено p A meia-noite e o movimento são restaurados r Полуночное оживление s La medianoche y el movimiento se restablecen t u Keskiyö ja liikkuminen palautuu = What's it take to get arrested in this town? b O que é preciso para ser preso nesta cidade? c 在这个城市,要怎样才能被逮捕呢? d Hvad skal der til for at blive arresteret i denne by? f Qu'est-ce qu'il faut pour se faire arrêter dans cette ville ? g Gnn! Was genau in aller Welt Namen muss man hier eigentlich anstellen, um verhaftet zu werden? h Mi kell ahhoz, hogy letartóztassanak ebben a városban? j この街で逮捕されるにはどうしたらいいんだ? l Какво е нужно, за да те арестуват в този град? p O que é preciso para ser detido nesta cidade? r Как арестоваться в этом городе? s ¿Qué hace falta para que te arresten en esta ciudad? t u Mitä vaaditaan, että sinut pidätetään tässä kaupungissa? = Jailbreak b Fuga da prisão c 越狱 d Fængselsflugt f Évasion de prison g Der Ausbruch h Börtönszökés j プリズンブレイク l Бягство от затвора p Pausa na prisão r Взлом тюрьмы s Fuga de la prisión t u Vankilapako = Good morning, Mr. Kornada b Bom dia, Sr. Kornada. c 早上好,科纳达先生。 d Godmorgen, hr. Kornada. f Bonjour, M. Kornada. g Guten Morgen, Herr Kornada. h Jó reggelt, Kornada úr. j 角田さん、おはようございます。 l Добро утро, г-н Корнада. p Bom dia, Sr. Kornada. r Доброе утро, мистер Корнада s Buenos días, Sr. Kornada. t u Huomenta, herra Kornada. = Chaos in the streets, a good day for Sam. b Caos nas ruas, um bom dia para Sam. c 街道上一片混乱,对山姆来说是个好日子。 d Kaos i gaderne, en god dag for Sam. f Chaos dans les rues, un bon jour pour Sam. g Chaos auf den Straßen, Sam im Glück h Káosz az utcákon, egy jó nap Sam számára. j 街はカオス、サムにとっては良い日だ。 l Хаос по улиците - добър ден за Сам. p Caos nas ruas, um bom dia para Sam. r Хаос на улицах – хороший знак для Сэма s Kaos på gatorna, en bra dag för Sam. t u Kaaos kaduilla, hyvä päivä Samille. = Max Post talks with the Mayor. b Max Post em conversa com o prefeito. c 马克斯-波斯特在与市长谈话。 d Max Post i samtale med borgmesteren. f Max Post s'entretient avec le maire. g Die Aussprache zwishen der Bürgermeisterin und Max Post. h Max Post beszélget a polgármesterrel. j 市長と話すマックス・ポスト氏。 l Макс Пост разговаря с кмета. p Max Post fala com o Presidente da Câmara. r Макс Пост разговаривает с мэром s Max Post habla con el alcalde. t u Max Post keskustelee pormestarin kanssa. = Meanwhile, down at the south pole. b Enquanto isso, no pólo sul. c 与此同时,在南极的下面。 d I mellemtiden, nede på sydpolen. f Pendant ce temps, au pôle Sud. g Zwischenzeitlich am Südpol h Eközben lent a déli póluson. j 一方、南極では l Междувременно на южния полюс. p Entretanto, no pólo sul. r В это время на южном полюсе s Mientras tanto, en el polo sur. t u Samaan aikaan etelänavalla. = Sam figures it out. b A Sam descobre isso. c 萨姆搞清楚了。 d Sam regner det ud. f Sam a compris. g Sam kommt dahinter. h Sam rájön. j サムはそれを理解する。 l Сам го разбира. p Sam descobre isso. r Сэм понял s Sam se da cuenta. t u Sam keksii sen. = Florence gets out for a walk. b Florence sai para um passeio. c 弗洛伦斯出去散步了。 d Florence går en tur. f Florence sort pour une promenade. g Gassigehen, -stehen und -flüchten. h Florence kimegy sétálni. j フローレンスは散歩に出る。 l Флорънс излиза на разходка. p Florença sai para dar um passeio. r Флоренс выходит на прогулку s Florence sale a dar un paseo. t u Florence lähtee kävelylle. = Doctor Bowman, I presume? b Doutor Bowman, eu presumo? c 鲍曼医生,我想是吧? d Doktor Bowman, går jeg ud fra? f Docteur Bowman, je présume ? g Dr. Bowman, nehme ich an? h Dr. Bowman, gondolom? j ボウマン博士ですね? l Доктор Боумън, предполагам? p Doutor Bowman, presumo? r Доктор Боуман, я полагаю? s ¿El doctor Bowman, supongo? t u Tohtori Bowman, oletan? = A meeting of the mechanical minds. b Uma reunião das mentes mecânicas. c 一个机械思维的会议。 d Et møde mellem de mekaniske hjerner. f Une réunion des esprits mécaniques. g Ein Treffen der mechanischen Denker h A mechanikus elmék találkozója. j メカニカルマインドの出会い。 l Среща на механичните умове. p Uma reunião das mentes mecânicas. r Собрание механических разумов s Una reunión de las mentes mecánicas. t u Mekaanisten mielten tapaaminen. = Chaos in the streets, a good day for Sam b Caos nas ruas, um bom dia para Sam c 街头的混乱,山姆的好日子 d Kaos i gaderne, en god dag for Sam f Chaos dans les rues, une bonne journée pour Sam g Chaos regiert die Stadt. Ein Traum für Sam h Káosz az utcákon, egy jó nap Sam számára j 街はカオス、サムにとっては良い日 l Хаос по улиците, добър ден за Сам p Caos nas ruas, um bom dia para Sam r Хаос на улицах – хороший знак для Сэма s Caos en las calles, un buen día para Sam t u Kaaos kaduilla, hyvä päivä Samille = Max Post talks with the Mayor b Max Post conversa com o prefeito c Max Post与市长对话 d Max Post taler med borgmesteren f Max Post s'entretient avec le maire g Max Post spricht mit der Bürgermeisterin h Max Post beszél a polgármesterrel j マックスポストが市長に聞く l Max Post разговаря с кмета p Max Post fala com o presidente da câmara r Макс Пост разговаривает с мэром s Max Post habla con el alcalde t u Max Post puhuu pormestarin kanssa = Meanwhile, down at the south pole b Enquanto isso, no pólo sul c 同时,在南极的下面 d I mellemtiden, nede på sydpolen f Pendant ce temps, au pôle sud g Währenddessen am Südpol j 一方、南極では h Eközben lent a déli póluson l Междувременно на южния полюс p Entretanto, no pólo sul r В это время на южном полюсе s Mientras tanto, en el polo sur t u Samaan aikaan etelänavalla = Sam figures it out b A Sam descobre isso c 萨姆搞清楚了 d Sam regner det ud f Sam a compris g Sam findet's raus h Sam rájön j サムはそれを理解する l Сам го разбира p Sam descobre isso r Сэм понял s Sam se da cuenta t u Sam keksii sen. = Florence gets out for a walk. b Florence sai para um passeio. c 弗洛伦斯出去散步了。 d Florence går en tur. f Florence sort pour une promenade. g Florence kommt für einen kurzen Spaziergang raus an die frische Luft h Florence kimegy sétálni. l Флорънс излиза на разходка. p Florença sai para dar um passeio. r Флоренс выходит на прогулку s Florence sale a dar un paseo. t u Florence lähtee kävelylle. = Doctor Bowman, I presume? b Doutor Bowman, eu presumo? c 鲍曼医生,我想是吧? d Doktor Bowman, går jeg ud fra? f Docteur Bowman, je présume ? g Doktor Bowman, vermute ich? h Dr. Bowman, gondolom? j フローレンスは散歩に出る。 l Доктор Боумън, предполагам? p Doutor Bowman, presumo? j ボウマン博士ですね? r Доктор Боуман, я полагаю? s ¿El doctor Bowman, supongo? t u Tohtori Bowman, oletan? = A meeting of the mehanical minds b Uma reunião das mentes mehânicas. c 医学界的思想交流会。 d Et møde mellem de mehaniske hjerner. f Une rencontre entre les esprits méhariens. g Ein Treffen der mechanischen Denker h Une rencontre entre les esprits méhariens. j メディカルマインドとの出会い。 l Среща на механичните умове. p Um encontro de mentes mehânicas. r Собрание механических разумов s Una reunión de las mentes mehánicas. t u Mehaanisten mielten tapaaminen. = Sam leads the way b Sam lidera o caminho c 萨姆引领潮流 d Sam viser vejen f Sam ouvre la voie g Sam führt h Sam vezeti az utat j サムが先導する l Сам е начело p Sam lidera o caminho r s Sam lidera el camino t u Sam näyttää tietä = Robots have memories b Os robôs têm lembranças c 机器人有记忆 d Robotter har hukommelse f Les robots ont des souvenirs g Robotererinnerungen h A robotoknak van memóriájuk j ロボットには記憶がある l Роботите имат спомени p Os robôs têm memórias r s Los robots tienen memoria t u Roboteilla on muisti = The Debate b O Debate c 辩论会 d Debatten f Le débat g Das Roboterduell h A vita j 討論会 l Дебатът p O Debate r s El debate t u Keskustelu = Mr. Raibert, You've Got Mail b Sr. Raibert, o senhor tem correio c 雷贝特先生,你有邮件了 d Hr. Raibert, du har fået post f M. Raibert, vous avez un message. g Hr. Raibert, sie haben E-Mail h Mr. Raibert, levelet kaptál! j ミスター・ライベルト、ユー・ガット・メール l Г-н Райберт, имате поща p Sr. Raibert, Recebeu Correio r s Sr. Raibert, tiene correo t u Herra Raibert, teillä on postia! = Socks, Spoons and Neural Nets b Meias, Colheres e Redes Neurais c 袜子、勺子和神经网路 d Sokker, skeer og neurale net f Chaussettes, cuillères et réseaux neuronaux g Socken, Löffel und neuronale Netze h Zoknik, kanalak és neurális hálók j 靴下、スプーン、ニューラルネット l Чорапи, лъжици и невронни мрежи p Meias, Colheres e Redes Neurais r s Calcetines, cucharas y redes neuronales t u Sukat, lusikat ja neuroverkot = A chat with the commander b Uma conversa com o comandante c 与指挥官的谈话 d En snak med den øverstbefalende f Une discussion avec le commandant g Ein Gespräch mit dem Kommandanten h Beszélgetés a parancsnokkal j 指揮官との雑談 l Разговор с командира p Uma conversa com o comandante r s Una charla con el comandante t u Keskustelu komentajan kanssa = The police always call while I'm adjusting my wolf b A polícia sempre liga enquanto eu estou ajustando meu lobo c 警察总是在我调整狼性的时候打电话来 d Politiet ringer altid, mens jeg justerer min ulv f La police appelle toujours pendant que j'ajuste mon loup. g Die Polizei ruft immer an, wenn ich gerade meinen Wolf einstelle h A rendőrség mindig akkor hív, amikor épp a farkasomat igazgatom. j 狼の調整中にいつも警察から電話がかかってくる。 l Полицията винаги се обажда, докато си оправям вълка p A polícia telefona sempre enquanto eu estou a ajustar o meu lobo r s La policía siempre llama mientras estoy ajustando mi lobo t u Poliisi soittaa aina, kun olen säätämässä sutta. = Free puppies, inquire within b Filhotes de cachorro livres, pergunte dentro de c 免费幼犬,内部咨询 d Gratis hvalpe, henvendelse indenfor f Chiots libres, se renseigner à l'intérieur g Kostenlos Welpen, bitte drinnen fragen h Ingyenes kölykök, érdeklődjön belül j 子犬の無料配布、お問い合わせはこちら l Безплатни кученца, попитайте в рамките на p Cachorros grátis, informe-se dentro de r s Cachorros gratis, consultar dentro t u Vapaat pennut, tiedustele sisällä = Exit procedure b Procedimento de saída c 退出程序 d Procedure ved afslutning f Procédure de sortie g Eine Strategie um hier rauszukommen h Kilépési eljárás j 終了手順 l Процедура за излизане p Procedimento de saída r s Procedimiento de salida t u Poistumismenettely = Now I really feel contaminated b Agora eu realmente me sinto contaminado c 现在我真的感到被污染了 d Nu føler jeg mig virkelig forurenet f Maintenant je me sens vraiment contaminé g Jetzt fühl ich erst recht schmutzig h Most már tényleg fertőzöttnek érzem magam j 今、私は本当に汚染されていると感じています。 l Сега наистина се чувствам заразена p Agora sinto-me realmente contaminado r s Ahora me siento realmente contaminado t u Nyt tunnen itseni todella saastuneeksi = Absolute Power b Potência Absoluta c 绝对权力 d Absolut magt f Le pouvoir absolu g Totale Macht h Abszolút hatalom j 絶対的な力 l Абсолютна власт p Potência Absoluta r s Poder absoluto t u Absoluuttinen valta = Year 2015: Wake up, we found her b Ano 2015: Acorda, nós a encontramos c 2015年。醒醒吧,我们找到她了 d År 2015: Vågn op, vi har fundet hende f Année 2015 : Réveillez-vous, nous l'avons trouvée g Jahr 2015: Aufwachen! Wir haben Sie gefunden h 2015-ös év: Ébredj, megtaláltuk őt j 2015年の年号です。目覚めよ、彼女を見つけた l 2015 г: Събуди се, намерихме я p Ano 2015: Acorda, encontrámo-la r s Año 2015: Despierta, la hemos encontrado t u Vuosi 2015: Herää, me löysimme hänet = Plots and plans b Lotes e planos c 地块和计划 d Parceller og planer f Parcelles et plans g Abläufe und Pläne h Telkek és tervek j プロット・プラン l Парцели и планове p Lotes e planos r s Parcelas y planos t u Tontit ja suunnitelmat = Orders and disclosures b Ordens e divulgações c 命令和披露 d Bekendtgørelser og offentliggørelser f Ordonnances et divulgations g Befehle und Geheimnisse aufdecken h Rendeletek és közlések j 注文と開示 l Поръчки и оповестявания p Encomendas e divulgações r s Órdenes y divulgaciones t u Määräykset ja ilmoitukset = Cold arctic logic b Lógica ártica fria c 寒冷的北极逻辑 d Kold arktisk logik f Logique du froid arctique g Kalte arktische Logik h Hideg sarkvidéki logika j 冷たい北極の論理 l Студена арктическа логика p Lógica árctica fria r s La lógica del frío ártico t u Kylmä arktinen logiikka = Doctor M consults with Doctor B b Лекар М се консултира с лекар В c 医生M与医生B进行协商 d Læge M rådfører sig med læge B f Le Docteur M consulte le Docteur B g Dr. M. berät sich mit Dr. B. h M orvos konzultál B orvossal j 医師Mが医師Bに相談する l Лекар М се консултира с лекар В p O Doutor M consulta o Doutor B j 医師Mが医師Bに相談する r s El doctor M consulta con el doctor B t u Lääkäri M konsultoi lääkäriä B = Out of control group b Grupo fora de controle c 失控组 d Uden for kontrolgruppen f Groupe hors contrôle g Außerkontrollgruppe h Kontrollcsoporton kívüli csoport j 制御不能群 l Извън контролната група p Grupo fora de controlo r s Grupo fuera de control t u Valvontaryhmän ulkopuolella = Hang on, There's someone at the door b Espere, tem alguém na porta c 等一下,有人在门外。 d Vent lidt, der er nogen ved døren f Attendez, il y a quelqu'un à la porte. g Sekunde, da ist jemand an der Tür h Várj, valaki van az ajtónál! j 待てよ、誰か来たぞ。 まてよ だれか きたぞ l Чакайте, Има някой на вратата p Espera, está alguém à porta r s Espera, hay alguien en la puerta t u Odota, joku on ovella. = Pizza, we have liftoff b Pizza, nós temos liftoff c 披萨,我们有升空 d Pizza, vi har afgang f Pizza, nous avons le décollage g Zur Pizza einen Flugzeugstart h Pizza, felszálltunk. j ピッツァ、リフトオフ l Пица, имаме старт p Pizza, temos liftoff r s Pizza, tenemos el despegue t u Pizza, meillä on lähtö = Delete this text b c d f g h j l p r s t u
An Example from 1911.
After the first run of iolate.rb, the file transfertext.utf8 should look like this
Those were… **MY** notes. I think I know what's going on. The majority of robots on this planet are approaching neural pruning age. Rather than scrap robots using Dr. Bowman's mental design, they may be planning to use an aggressive neural pruning program. Aggressive? I've seen this program in action! Saying this thing is aggressive is like saying a great white shark likes to nibble on things! I'm more than a little disturbed by how much you know about this program.
Translate it into various languaes and seperate the languages by a line with an ~ otionally followed by a letter to indicate the language, to make it look like this example
Das waren... **Meine** Notizen. Ich glaube, ich weiß, was hier los ist. Die meisten Roboter auf diesem Planeten erreichen das Alter der neuronalen Beschneidung. Anstatt die Roboter mit Dr. Bowmans mentalem Design zu verschrotten, planen sie vielleicht ein aggressives neurales Beschneidungsprogramm zu verwenden. Aggressiv? Ich habe dieses Programm in Aktion gesehen! Es als aggressiv zu bezeichnen, ist so, als würde man sagen, dass ein weißer Hai gerne an Dingen knabbert! Ich bin mehr als nur ein wenig beunruhigt darüber, wie viel Sie über dieses Programm wissen. ~f C'était... mes notes. Je pense que je sais ce qui se passe. La majorité des robots sur cette planète approchent de l'âge de l'élagage neural. Plutôt que de détruire les robots en utilisant le design mental du Dr. Bowman, ils peuvent prévoir d'utiliser un programme agressif d'élagage neuronal. Agressif ? J'ai vu ce programme en action ! Dire que cette chose est agressive c'est comme dire qu'un grand requin blanc aime grignoter des choses ! Je suis plus que troublé par ce que tu sais de ce programme. ~d Det var... **MINE** noter. Jeg tror, jeg ved, hvad der foregår. De fleste robotter på denne planet nærmer sig den neurale beskæringsalder. I stedet for at skrotte robotter ved hjælp af Dr. Bowmans mentale design, planlægger de måske at bruge et aggressivt neuralt beskæringsprogram. Aggressivt? Jeg har set dette program i aktion! At sige, at denne tingest er aggressiv er som at sige, at en stor hvid haj kan lide at gnaske på ting! Jeg er mere end en smule foruroliget over, hvor meget du ved om dette program. ~s Esas eran... mis notas. Creo que sé lo que está pasando. La mayoría de los robots de este planeta se acercan a la edad de poda neural. En lugar de desechar los robots usando el diseño mental del Dr. Bowman, pueden estar planeando usar un programa de poda neural agresivo. ¿Agresivo? ¡He visto este programa en acción! Decir que esta cosa es agresiva es como decir que a un gran tiburón blanco le gusta mordisquear cosas. Estoy más que perturbado por lo mucho que sabes sobre este programa. ~u Ne olivat... **MINUN** muistiinpanojani. Luulen tietäväni mistä on kyse. Suurin osa tämän planeetan roboteista lähestyy hermojen karsintaikää. Sen sijaan, että he romuttaisivat robotteja tohtori Bowmanin mentaalisen mallin mukaan, he saattavat suunnitella aggressiivista hermojen karsintaohjelmaa. Aggressiivinen? Olen nähnyt tämän ohjelman toiminnassa! Tämän sanominen aggressiiviseksi on kuin sanoisi, että valkohai tykkää nakertaa asioita! Minua häiritsee, miten paljon tiedät tästä ohjelmasta. ~h Ezek... **az én jegyzeteim** voltak. Azt hiszem, tudom, mi folyik itt. A robotok többsége ezen a bolygón közelít az idegrendszeri metszési korhoz. Ahelyett, hogy a robotokat Dr. Bowman mentális tervezésével selejteznék, talán egy agresszív neurális metszési programot terveznek. Agresszív? Láttam ezt a programot működés közben! Azt mondani, hogy ez a dolog agresszív, olyan, mintha azt mondanánk, hogy egy nagy fehér cápa szeret rágcsálni dolgokat! Egy kicsit zavar, hogy mennyit tudsz erről a programról.
Note that DeepL honors the bold formating here only for German, Danish, Finnish and Hungarian, but not for French or Spanish. Your mileage may vary on this.
The second run of iolate.rb should than give you translated files for all the languages, which here are
cpage-0-.dkw cpage-1-French.dkw cpage-2-Dansk.dkw cpage-3-Spanish.dkw cpage-4-Finnish.dkw cpage-5-Hungarian.dkw
You still have to translate what is outside the cotan tags manually.