i18n
A multilingual program: translating messages, placing values into them and choosing singular or plural.
import i18n
If your program has to speak several languages, do not write the messages into the code. Put them in a translation catalog under a key, and ask for the user's language when you display one.
Every catalog has a fallback language. When a message has no translation in the user's language, the fallback is shown, and when that is missing too, the key itself; so the program never shows an empty message.
Types
Catalog
struct CatalogNew and release it with Free.| Name | Type | Description |
|---|---|---|
keys | Vector | The stored keys, in the form "language:key". |
vals | Vector | The translations, in the same order as the keys. |
fallback | str = "en" | The fallback language. |
import i18n
func main:
mut c := i18n.New("en")
defer i18n.Free(c)
i18n.Set(c, "en", "hello", "Hello")
i18n.Set(c, "fa", "hello", "سلام")
i18n.Set(c, "en", "bye", "Goodbye")
println i18n.T(c, "fa", "hello"), i18n.T(c, "fa", "bye"), i18n.T(c, "fa", "missing")
println i18n.Has(c, "fa", "bye"), i18n.RawGet(c, "fa", "bye") == ""
println c.fallback
endFunctions
New
func New(default_locale: str): CatalogThe example for this item is shown with the ones above: i18n-Catalog.salam
Set
func Set(c &: Catalog, locale: str, key: str, val: str)The example for this item is shown with the ones above: i18n-Catalog.salam
Has
func Has(c &: Catalog, locale: str, key: str): boolThe example for this item is shown with the ones above: i18n-Catalog.salam
RawGet
func RawGet(c &: Catalog, locale: str, key: str): strThe example for this item is shown with the ones above: i18n-Catalog.salam
T
func T(c &: Catalog, locale: str, key: str): strThe example for this item is shown with the ones above: i18n-Catalog.salam
Interpolate
func Interpolate(msg: str, param_names: Vector<str>, param_vals: Vector<str>): str{name} in the message with the value of that name. The names and the values are given in two vectors in the same order.import i18n
func main:
mut c := i18n.New("en")
defer i18n.Free(c)
i18n.Set(c, "en", "greet", "Hello {name}, you have {n} new messages")
mut names := Vector {} as Vector<str>
mut values := Vector {} as Vector<str>
defer names.free()
defer values.free()
names.push("name")
names.push("n")
values.push("Maryam")
values.push("3")
println i18n.Tf(c, "en", "greet", names, values)
println i18n.Interpolate("{name} and {name} again", names, values)
endTf
func Tf(c &: Catalog, locale: str, key: str, param_names: Vector<str>, param_vals: Vector<str>): strThe example for this item is shown with the ones above: i18n-Tf.salam
Plural
func Plural(c &: Catalog, locale: str, key: str, n: i64): strn: the key .one for one and .other for the rest. It does not place the number in the message itself; use Interpolate for that. Languages that need only one form can define .other alone.import i18n
import io
func main:
mut c := i18n.New("en")
defer i18n.Free(c)
io.WriteFile("en.txt", "apple.one = one apple\napple.other = {n} apples\n")
println i18n.LoadLocale(c, "en", "en.txt")
mut names := Vector {} as Vector<str>
defer names.free()
names.push("n")
each n in [1, 5]:
mut values := Vector {} as Vector<str>
values.push("" + n)
println i18n.Interpolate(i18n.Plural(c, "en", "apple", n), names, values)
values.free()
end
println i18n.DetectLocale().len() > 0
endLoadLocale
func LoadLocale(c &: Catalog, locale: str, path: str): intkey = value lines and returns how many keys were read.The example for this item is shown with the ones above: i18n-Plural.salam
DetectLocale
func DetectLocale(): strSALAM_LOCALE first, then LANG and LC_ALL. When none is set it returns en.The example for this item is shown with the ones above: i18n-Plural.salam
Free
func Free(c &: Catalog)The example for this item is shown with the ones above: i18n-Catalog.salam