Created
January 14, 2014 15:04
-
-
Save gecko0307/8419717 to your computer and use it in GitHub Desktop.
Internationalization module for D programs.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module i18n; | |
import std.stdio; | |
import std.conv; | |
import std.format; | |
import std.array; | |
import std.process; | |
import std.path; | |
import std.file; | |
import std.string; | |
version(Windows) | |
{ | |
extern(Windows) int GetLocaleInfoW( | |
in uint Locale, | |
in uint LCType, | |
wchar* lpLCData, | |
in int cchData | |
); | |
extern(Windows) int GetLocaleInfoA( | |
in uint Locale, | |
in uint LCType, | |
char* lpLCData, | |
in int cchData | |
); | |
enum uint LOCALE_USER_DEFAULT = 0x0400; | |
enum uint LOCALE_SISO639LANGNAME = 0x59; | |
enum uint LOCALE_SISO3166CTRYNAME = 0x5a; | |
} | |
string formatString(A...)(string f, A args) | |
{ | |
auto writer = appender!string(); | |
formattedWrite(writer, f, args); | |
return writer.data; | |
} | |
private string syslocale; | |
static this() | |
{ | |
version(Windows) | |
{ | |
string getLanguage() | |
{ | |
char[16] str; | |
GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, str.ptr, str.length); | |
return str.ptr.to!string; | |
} | |
string getCountry() | |
{ | |
char[16] str; | |
GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, str.ptr, str.length); | |
return str.ptr.to!string; | |
} | |
string lang = getLanguage(); | |
string country = getCountry(); | |
syslocale = formatString("%s_%s", lang, country); | |
} | |
else version(Posix) | |
{ | |
string lang = environment.get("LANG", "en_US.utf8"); | |
string locale, encoding; | |
formattedRead(lang, "%s.%s", &locale, &encoding); | |
syslocale = locale; | |
} | |
else | |
{ | |
static assert(0, "This OS is unsupported by i18n.d"); | |
} | |
} | |
string systemLocale() | |
{ | |
return syslocale; | |
} | |
class Locale | |
{ | |
static string[string] translation; | |
static void readLang(string dir, string ext = ".lang") | |
{ | |
if (exists(dir) && isDir(dir)) | |
{ | |
string loc = buildNormalizedPath(dir, syslocale ~ ext); | |
if (exists(loc)) | |
readLangFile(loc); | |
} | |
} | |
static void readLangFile(string filename) | |
{ | |
foreach(line; filename.readText.splitLines) | |
if (line) | |
{ | |
string key, value; | |
try | |
formattedRead(line, "\"%s\" = \"%s\" ", &key, &value); | |
catch(Exception) {} | |
finally | |
translation[key] = value; | |
} | |
} | |
} | |
string _(string s) | |
{ | |
if (s in Locale.translation) | |
return Locale.translation[s]; | |
else | |
return s; | |
} | |
/* | |
// Usage: | |
import std.stdio; | |
import i18n; | |
void main() | |
{ | |
Locale.readLang("locale", ".lang"); | |
writeln("Hello, world!"._); | |
} | |
// locale/ru_RU.lang: | |
"Hello, world!" = "Привет, мир!" | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment