Seite 1 von 1

Internationalisierung

Verfasst: 27.02.2009 00:31
von Blackskyliner
Ich habe mal eine kleine Internationalisierung geschrieben, da ich bisher keine für Purebasic geschriebene gesehen habe.
Ist aber wirklich nur eine Kleine und auch nicht allzu Große ;)

Code: Alles auswählen

EnableExplicit

Structure internationalisation_struct
	original.s
	translation.s
EndStructure

Global NewList LanguageDatabase.internationalisation_struct()
Global languageDirectory.s

Procedure createLanguageFile(language.s)
	Define.s filePath
	
	filePath = languageDirectory + "/" + language + ".lng"
	
	If CreateFile(0, filePath)
		ForEach LanguageDatabase()
			WriteStringN(0, "message "+Chr(34)+LanguageDatabase()\original+Chr(34))
			WriteStringN(0, "translation "+Chr(34)+LanguageDatabase()\translation+Chr(34))
			WriteStringN(0, "")
		Next
		CloseFile(0)
	EndIf
EndProcedure

Procedure readLanguageFile(language.s)
	Define.s filePath, temp, message, translation
	
	filePath = languageDirectory + "/" + language + ".lng"
	ClearList(LanguageDatabase())

	If OpenFile(0, filePath)
		While Eof(0) = 0         
			temp = ReadString(0)      
			If Trim(temp) = "" Or Mid(Trim(temp),1,1) = "#"
				Continue
			EndIf
			
			If Trim(Mid(temp, 1, Len("message"))) = "message"
				message = temp
				translation = ReadString(0)
				
				; Dirty way to read the format...
				message = Mid(message, 10, Len(message)-10)
				translation = Mid(translation, 14, Len(translation)-14)
				
				AddElement(LanguageDatabase())
				LanguageDatabase()\original = message
				LanguageDatabase()\translation = translation
			EndIf
			
	    Wend

		CloseFile(0)
	EndIf
EndProcedure

Procedure setLanguageFileDir(dir$)
	languageDirectory = dir$
EndProcedure

Procedure.s __e(f_original.s, replacer.s = "")
	Define.i i, countTo
	Define.s toReplace
	Define.s text
	Define.b isInThere
	
	isInThere = #False
	ForEach LanguageDatabase()
		If LanguageDatabase()\original = f_original
			isInThere = #True
			If Trim(LanguageDatabase()\translation) <> ""
				text = LanguageDatabase()\translation
			Else
				text = LanguageDatabase()\original
			EndIf
		EndIf
	Next
	If isInThere = #False
		AddElement(LanguageDatabase())
		LanguageDatabase()\original = f_original
		LanguageDatabase()\translation = ""
		
		text = f_original
	EndIf
	
	If replacer <> ""
		countTo = CountString(replacer, "|")
		For i=0 To countTo
			toReplace.s = StringField(replacer, i+1, "|")
			text = ReplaceString(text, "{"+Str(i)+"}", toReplace)
		Next
	EndIf
	
	ProcedureReturn text
EndProcedure

setLanguageFileDir("language")
readLanguageFile("german")


Debug __e("First Test")
Debug __e("Second Test with unknown vars: {0}", "1234")
Debug __e("Hello {0}!", "Karl Heinz")
Debug __e("You have {0} of {1} jobs done.", "10|100")


; Its good to save, becaus new messages could be added
createLanguageFile("german")
Hier noch die german.lng

Code: Alles auswählen

message "First Test"
translation "Erster Test"

message "Second Test with unknown vars: {0}"
translation "Zweiter Test mit unbekannten: {0}"

message "Hello {0}!"
translation "Hallo {0}!"

message "You have {0} of {1} jobs done."
translation "Du hast {0} von {1} Aufgaben erledigt."

Meherere Unbekannte werden via | abgetrennt, da Purebasic ja keinen Support für unbekannte Variablen bei Procedures hat.. (zumindestnicht das ich wüsste)

Viel Spaß damit. Hoffentlich kanns jemand gebrauchen oder gar verbessern und verschnellern.

EDIT: Bei readLanguageFile noch eine kleine Anpassung gemacht, dass die LanguageDatabase() auch immer gelöscht wird, da sonst beim Sprachenwechsel alte Daten erhalten bleiben würden...

MFG
Blackskyliner

Verfasst: 27.02.2009 01:24
von STARGÅTE
hmm, das mag bei 1bis 10 oder sogar 30 "Texten" funktionieren, aber wenn man eine "vieltextige" Oberfläche hat, und dann bei ca 100 Texten immer wieder die LinkedList (LanguageDatabase()) durchlaufen wird um den passenden Text zu finden, dann wird das zimlich Zeit intensiv...

Trotzdem danke das du den Code zur Verfügung stellst...

PS: bezüglich der "Meherere Unbekannte Variable" habe ich mal was geschrieben was du verwenden kannst:

DimP - Viele ProcedurParameter (max 16) als Array verwenden

Bei Hilfe einfach nachfragen :allright:

Re: Internationalisierung

Verfasst: 28.02.2009 11:47
von Little John
Blackskyliner hat geschrieben:da ich bisher keine für Purebasic geschriebene gesehen habe.
Ich möchte nur anmerken, dass es sowas von freak im englischen Forum gibt.

Gruß, Little John

Verfasst: 28.02.2009 13:48
von Blackskyliner
Danke. Wusst ich nicht.
Werd mir die Libary mal ansehen, sieht sehr zusprechend aus <)

EDIT:
Scheint aber leider nichts für mich zu sein, da halt das ersetzen direkter Platzhalter entfällt... Mal sehn ob ich meins noch bisschen umschreibe. Aber eigentlich ist mein Ansatz ja am gettext von C, nur das Problem was ich persönlich mit gettext habe, dass ich es über externe Libary einbinden müsste... Fände es eigenlich schön, wenn es in Purebasic eine eingebaute Internationalisierungsfunktion gibt, die dann mir .mo dateien Arbeiten würde... Aber man kann ja Träumen <)

Was meinst du, wäre das mal ein Feature Request wert?