148 lines
4.4 KiB
D
148 lines
4.4 KiB
D
/++
|
|
Module singlang - Lightweight internationalization (i18n) support for D programs.
|
|
|
|
Description:
|
|
This module integrates GNU Gettext for translations in D applications, using a singleton
|
|
`Singlang` class and a convenient `_()` function for message translation. Errors are
|
|
reported to stderr for proper error handling.
|
|
+/
|
|
module singlang;
|
|
|
|
import core.stdc.locale : setlocale, LC_ALL;
|
|
import std.string : toStringz;
|
|
import std.conv : to;
|
|
import std.stdio : writeln, stderr;
|
|
|
|
extern(C) {
|
|
char* bindtextdomain(const char* domainname, const char* dirname);
|
|
char* textdomain(const char* domainname);
|
|
char* gettext(const char* msgid);
|
|
}
|
|
|
|
/++
|
|
Class Singlang - Singleton manager for translation configuration.
|
|
|
|
Description:
|
|
The `Singlang` class encapsulates the setup and management of the GNU Gettext-based
|
|
translation system. It ensures that the translation environment is initialized only once
|
|
and provides a centralized configuration point for the domain and translation directory.
|
|
|
|
Usage Example:
|
|
---
|
|
import singlang;
|
|
|
|
void main() {
|
|
if (Singlang.set("myapp", "/usr/share/locale")) {
|
|
writeln("Translation system ready!");
|
|
}
|
|
}
|
|
---
|
|
+/
|
|
class Singlang {
|
|
private:
|
|
/++ Translation domain name used by GNU Gettext +/
|
|
string domain;
|
|
|
|
/++ Directory path containing translation files (.mo) +/
|
|
string localeDir;
|
|
|
|
/++ Singleton instance of the Singlang class +/
|
|
static Singlang instance;
|
|
|
|
/++
|
|
Private constructor for initializing a Singlang instance.
|
|
|
|
Params:
|
|
domain = The translation domain name
|
|
localeDir = Path to the directory with translation files
|
|
|
|
Note:
|
|
Accessible only internally; use `set` to create an instance.
|
|
+/
|
|
this(string domain, string localeDir) {
|
|
this.domain = domain;
|
|
this.localeDir = localeDir;
|
|
}
|
|
|
|
public:
|
|
/++
|
|
Initializes the translation system with a domain and directory.
|
|
|
|
Description:
|
|
Configures the GNU Gettext environment by setting the translation directory and domain.
|
|
This method must be called before using the `_()` function for translations. Errors
|
|
are reported to stderr.
|
|
|
|
Params:
|
|
domain = Name of the translation domain (e.g., application name)
|
|
localeDir = Path to the directory with translation files (.mo)
|
|
|
|
Returns:
|
|
`true` on successful initialization, `false` if an error occurs
|
|
|
|
Notes:
|
|
- Attempting to initialize an already initialized instance will fail with an error message to stderr.
|
|
- Errors during directory or domain setup will reset the instance to null and log messages to stderr.
|
|
|
|
Example:
|
|
---
|
|
if (Singlang.set("myapp", "/path/to/translations")) {
|
|
writeln("Ready to translate!");
|
|
} else {
|
|
writeln("Setup failed, check stderr for details!");
|
|
}
|
|
---
|
|
+/
|
|
static bool set(string domain, string localeDir) {
|
|
if (instance !is null) {
|
|
stderr.writeln("Error: Singlang is already initialized");
|
|
return false;
|
|
}
|
|
|
|
setlocale(LC_ALL, "");
|
|
|
|
instance = new Singlang(domain, localeDir);
|
|
|
|
if (bindtextdomain(domain.toStringz, localeDir.toStringz) is null) {
|
|
stderr.writeln("Error: Failed to set translations directory");
|
|
instance = null;
|
|
return false;
|
|
}
|
|
|
|
if (textdomain(domain.toStringz) is null) {
|
|
stderr.writeln("Error: Failed to set translations domain");
|
|
instance = null;
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/++
|
|
Retrieves the translated version of a given message.
|
|
|
|
Description:
|
|
Translates a message using the configured `Singlang` instance. If the system is not
|
|
initialized, it returns the original message and logs an error to stderr.
|
|
|
|
Params:
|
|
msg = The message to translate (UTF-8 encoded)
|
|
|
|
Returns:
|
|
The translated string, or the original message if translation fails or system is uninitialized
|
|
|
|
Example:
|
|
---
|
|
writeln(_("Error: File not found")); // Outputs translated text or original if unavailable
|
|
---
|
|
+/
|
|
string _(string msg) {
|
|
if (Singlang.instance is null) {
|
|
stderr.writeln("Error: Singlang module is not initialized");
|
|
return msg;
|
|
}
|
|
auto result = gettext(msg.toStringz);
|
|
return result !is null ? result.to!string : msg;
|
|
}
|