diff options
Diffstat (limited to 'script-beta/language.lua')
-rw-r--r-- | script-beta/language.lua | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/script-beta/language.lua b/script-beta/language.lua new file mode 100644 index 00000000..d1a4b4cf --- /dev/null +++ b/script-beta/language.lua @@ -0,0 +1,137 @@ +local fs = require 'bee.filesystem' +local lni = require 'lni' +local util = require 'utility' + +local function supportLanguage() + local list = {} + for path in (ROOT / 'locale'):list_directory() do + if fs.is_directory(path) then + list[#list+1] = path:filename():string():lower() + end + end + return list +end + +local function osLanguage() + return LANG:lower() +end + +local function getLanguage(id) + local support = supportLanguage() + -- 检查是否支持语言 + if support[id] then + return id + end + -- 根据语言的前2个字母来找近似语言 + for _, lang in ipairs(support) do + if lang:sub(1, 2) == id:sub(1, 2) then + return lang + end + end + -- 使用英文 + return 'enUS' +end + +local function loadFileByLanguage(name, language) + local path = ROOT / 'locale' / language / (name .. '.lni') + local buf = util.loadFile(path:string()) + if not buf then + return {} + end + local suc, tbl = xpcall(lni, log.error, buf, path:string()) + if not suc then + return {} + end + return tbl +end + +local function formatAsArray(str, ...) + local index = 0 + local args = {...} + return str:gsub('%{(.-)%}', function (pat) + local id, fmt + local pos = pat:find(':', 1, true) + if pos then + id = pat:sub(1, pos-1) + fmt = pat:sub(pos+1) + else + id = pat + fmt = 's' + end + id = tonumber(id) + if not id then + index = index + 1 + id = index + end + return ('%'..fmt):format(args[id]) + end) +end + +local function formatAsTable(str, ...) + local args = ... + return str:gsub('%{(.-)%}', function (pat) + local id, fmt + local pos = pat:find(':', 1, true) + if pos then + id = pat:sub(1, pos-1) + fmt = pat:sub(pos+1) + else + id = pat + fmt = 's' + end + if not id then + return + end + return ('%'..fmt):format(args[id]) + end) +end + +local function loadLang(name, language) + local tbl = loadFileByLanguage(name, 'en-US') + if language ~= 'en-US' then + local other = loadFileByLanguage(name, language) + for k, v in pairs(other) do + tbl[k] = v + end + end + return setmetatable(tbl, { + __index = function (self, key) + self[key] = key + return key + end, + __call = function (self, key, ...) + local str = self[key] + local suc, res + if type(...) == 'table' then + suc, res = pcall(formatAsTable, str, ...) + else + suc, res = pcall(formatAsArray, str, ...) + end + if suc then + return res + else + -- 这里不能使用翻译,以免死循环 + log.warn(('[%s][%s-%s] formated error: %s'):format( + language, name, key, str + )) + return str + end + end, + }) +end + +local function init() + local id = osLanguage() + local language = getLanguage(id) + log.info(('VSC language: %s'):format(id)) + log.info(('LS language: %s'):format(language)) + return setmetatable({ id = language }, { + __index = function (self, name) + local tbl = loadLang(name, language) + self[name] = tbl + return tbl + end, + }) +end + +return init() |