Internationalisierung

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Internationalisierung

Beitrag 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
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag 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:
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Little John

Re: Internationalisierung

Beitrag 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
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Beitrag 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?
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Antworten