Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
sputnik/sputnik/lua/sputnik/i18n.lua
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
75 lines (67 sloc)
2.75 KB
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
| ------------------------------------------------------------------------------- | |
| -- Provides method for replacing translatable strings with the right | |
| -- translations, using a fallback mechanism. | |
| ------------------------------------------------------------------------------- | |
| module(..., package.seeall) | |
| ------------------------------------------------------------------------------- | |
| -- Generates a list of fallback language codes for a given language. E.g., for | |
| -- pt_PT we might get back {"pt_PT", "pt_BR", "en_US"}, meaning: use pt_PT | |
| -- translation if defined, if not try pt_BR, if that isn't defined either use | |
| -- en_US. The list of fallbacks depends on the fallback_table, though, which | |
| -- defines a set of fallbacks for any specific language prefix. | |
| -- For instance, if we have | |
| -- | |
| -- fallback_table = { | |
| -- en = "en_US", | |
| -- pt = "pt_BR", | |
| -- _all = "en_US", | |
| -- } | |
| -- | |
| -- This means that any "pt" language has "pt_BR" as fallback, and _any_ language | |
| -- falls back on en_US. | |
| ------------------------------------------------------------------------------- | |
| function make_language_fallback_chain(fallback_table, lang) | |
| local fallback_chain = {} | |
| if lang then | |
| fallback_chain[1] = lang | |
| local prefix = lang | |
| while prefix do | |
| if prefix and fallback_table[prefix] then | |
| table.insert(fallback_chain, fallback_table[prefix]) | |
| end | |
| prefix, _ = prefix:match("(.+)_([^_]*)") | |
| end | |
| end | |
| table.insert(fallback_chain, fallback_table._all or "en_US") | |
| return fallback_chain | |
| end | |
| ------------------------------------------------------------------------------- | |
| -- Generates a closure with two functions: translate_key() which looks up the | |
| -- translation for a specific key, and translate() which replaces all keys in | |
| -- the text with their translations. | |
| ------------------------------------------------------------------------------- | |
| function make_translator(translations, language, fallback_table) | |
| if not fallback_table then | |
| fallback_table = translations.FALLBACKS or {} | |
| end | |
| local fallback_chain = make_language_fallback_chain(fallback_table, language) | |
| local function translate_key(key) | |
| if not translations[key] then -- simply no entry for this key | |
| return "_("..key..")" | |
| else | |
| for i, lang in ipairs(fallback_chain) do -- down the fallback chain | |
| if translations[key][lang] then | |
| return translations[key][lang] -- return a match | |
| end | |
| end | |
| return "%("..key..")" -- didn't find anything - shouldn't happen | |
| end | |
| end | |
| local function translate(text) | |
| return string.gsub(text, "_%(([%w_%d]+)([^%)]*)%)", translate_key) | |
| end | |
| return { | |
| translate = translate, | |
| translate_key = translate_key | |
| } | |
| end | |