From b2dc09ad3a3b15b32648000830ed4c4ddd499d7a Mon Sep 17 00:00:00 2001 From: Maksim Date: Sun, 26 Dec 2021 20:51:26 +0100 Subject: [PATCH] Update intllib, add `core.get_translator_auto()` wrapper --- builtin/intllib/gettext.lua | 42 +++++++++++++++---------------------- builtin/intllib/init.lua | 42 +++++++++++++++++++++---------------- builtin/intllib/lib.lua | 14 ++++++++----- 3 files changed, 50 insertions(+), 48 deletions(-) diff --git a/builtin/intllib/gettext.lua b/builtin/intllib/gettext.lua index 6c82ceae..4b131d1c 100644 --- a/builtin/intllib/gettext.lua +++ b/builtin/intllib/gettext.lua @@ -1,16 +1,9 @@ -local strsub, strrep = string.sub, string.rep -local strmatch, strgsub = string.match, string.gsub - -local function trim(str) - return strmatch(str, "^%s*(.-)%s*$") -end - local escapes = { n="\n", r="\r", t="\t" } local function unescape(str) - return (strgsub(str, "(\\+)([nrt]?)", function(bs, c) + return (str:gsub("(\\+)([nrt]?)", function(bs, c) local bsl = #bs - local realbs = strrep("\\", bsl/2) + local realbs = ("\\"):rep(bsl/2) if bsl%2 == 1 then c = escapes[c] or c end @@ -27,14 +20,14 @@ local function parse_po(str) end for _, line in ipairs(str:split("\n")) do repeat lineno = lineno + 1 - line = trim(line) + line = line:trim() - if line == "" or strmatch(line, "^#") then + if line == "" or line:match("^#") then state, msgid, msgid_plural = nil, nil, nil break -- continue end - local mid = strmatch(line, "^%s*msgid%s*\"(.*)\"%s*$") + local mid = line:match("^%s*msgid%s*\"(.*)\"%s*$") if mid then if state == "id" then return perror("unexpected msgid") @@ -43,7 +36,7 @@ local function parse_po(str) break -- continue end - mid = strmatch(line, "^%s*msgid_plural%s*\"(.*)\"%s*$") + mid = line:match("^%s*msgid_plural%s*\"(.*)\"%s*$") if mid then if state ~= "id" then return perror("unexpected msgid_plural") @@ -52,15 +45,14 @@ local function parse_po(str) break -- continue end - local ind, mstr = strmatch(line, - "^%s*msgstr([0-9%[%]]*)%s*\"(.*)\"%s*$") + local ind, mstr = line:match("^%s*msgstr([0-9%[%]]*)%s*\"(.*)\"%s*$") if ind then if not msgid then return perror("missing msgid") elseif ind == "" then msgstrind = 0 - elseif strmatch(ind, "%[[0-9]+%]") then - msgstrind = tonumber(strsub(ind, 2, -2)) + elseif ind:match("%[[0-9]+%]") then + msgstrind = tonumber(ind:sub(2, -2)) else return perror("malformed msgstr") end @@ -73,7 +65,7 @@ local function parse_po(str) break -- continue end - mstr = strmatch(line, "^%s*\"(.*)\"%s*$") + mstr = line:match("^%s*\"(.*)\"%s*$") if mstr then if state == "id" then msgid = msgid..unescape(mstr) @@ -107,9 +99,9 @@ end -- It handles enough stuff to parse the `Plural-Forms` header correctly. -- Note that it assumes the C expression is valid to begin with. local function compile_plural_forms(str) - local plural = strmatch(str, "plural=([^;]+);?$") + local plural = str:match("plural=([^;]+);?$") local function replace_ternary(s) - local c, t, f = strmatch(s, "^(.-)%?(.-):(.*)") + local c, t, f = s:match(s"^(.-)%?(.-):(.*)") if c then return ("__if(" ..replace_ternary(c) @@ -120,10 +112,10 @@ local function compile_plural_forms(str) return s end plural = replace_ternary(plural) - plural = strgsub(plural, "&&", " and ") - plural = strgsub(plural, "||", " or ") - plural = strgsub(plural, "!=", "~=") - plural = strgsub(plural, "!", " not ") + plural = plural:gsub("&&", " and ") + plural = plural:gsub("||", " or ") + plural = plural:gsub("!=", "~=") + plural = plural:gsub("!", " not ") local f, err = loadstring([[ local function __if(c, t, f) if c and c~=0 then return t else return f end @@ -150,7 +142,7 @@ end local function parse_headers(str) local headers = { } for _, line in ipairs(str:split("\n")) do - local k, v = strmatch(line, "^([^:]+):%s*(.*)") + local k, v = line:match("^([^:]+):%s*(.*)") if k then headers[k] = v end diff --git a/builtin/intllib/init.lua b/builtin/intllib/init.lua index 248c4220..e60cea31 100644 --- a/builtin/intllib/init.lua +++ b/builtin/intllib/init.lua @@ -3,7 +3,7 @@ intllib = { strings = {}, } -local path = core.get_builtin_path() .. DIR_DELIM .. "intllib" .. DIR_DELIM +local path = core.get_builtin_path() .. "intllib" .. DIR_DELIM dofile(path .. "lib.lua") local LANG = core.settings:get("language") @@ -67,15 +67,14 @@ function intllib.Getter(modname) end -local strfind, strsub = string.find, string.sub local langs local function split(str, sep) local pos, endp = 1, #str+1 return function() if (not pos) or pos > endp then return end - local s, e = strfind(str, sep, pos, true) - local part = strsub(str, pos, s and s-1) + local s, e = str:find(sep, pos, true) + local part = str:sub(pos, s and s-1) pos = e and e + 1 return part end @@ -89,14 +88,14 @@ function intllib.get_detected_languages() local function addlang(l) local sep langs[#langs+1] = l - sep = strfind(l, ".", 1, true) + sep = l:find(".", 1, true) if sep then - l = strsub(l, 1, sep-1) + l = l:sub(1, sep-1) langs[#langs+1] = l end - sep = strfind(l, "_", 1, true) + sep = l:find("_", 1, true) if sep then - langs[#langs+1] = strsub(l, 1, sep-1) + langs[#langs+1] = l:sub(1, sep-1) end end @@ -138,8 +137,9 @@ local function catgettext(catalogs, msgid) end end +local floor = math.floor local function catngettext(catalogs, msgid, msgid_plural, n) - n = math.floor(n) + n = floor(n) for _, cat in ipairs(catalogs) do local msgstr = cat and cat[msgid] if msgstr then @@ -158,7 +158,7 @@ function intllib.make_gettext_pair(modname) if gettext_getters[modname] then return unpack(gettext_getters[modname]) end - local modpath = core.get_modpath(modname) and core.get_modpath(modname) + local modpath = core.get_modpath(modname) local localedir = modpath and modpath.."/locale" local catalogs = localedir and gettext.load_catalogs(localedir) or {} local getter = Getter(modname) @@ -192,18 +192,24 @@ function intllib.get_strings(modname, langcode) modname = modname or core.get_current_modname() local msgstr = intllib.strings[modname] if not msgstr then - local modpath = core.get_modpath(modname) and core.get_modpath(modname) + local modpath = core.get_modpath(modname) msgstr = { } if modpath then - for _, l in ipairs(get_locales(langcode)) do - local t = intllib.load_strings(modpath.."/locale/"..modname.."."..l..".tr") - or intllib.load_strings(modpath.."/locale/"..l..".txt") or { } - for k, v in pairs(t) do - msgstr[k] = msgstr[k] or v + for _, l in ipairs(get_locales(langcode)) do + local t = intllib.load_strings(modpath.."/locale/"..modname.."."..l..".tr") + or intllib.load_strings(modpath.."/locale/"..l..".txt") or { } + for k, v in pairs(t) do + msgstr[k] = msgstr[k] or v + end end - end - intllib.strings[modname] = msgstr + intllib.strings[modname] = msgstr end end return msgstr end + + +function core.get_translator_auto() + -- Surrounded in brackets so there's only one return value + return (intllib.make_gettext_pair()) +end diff --git a/builtin/intllib/lib.lua b/builtin/intllib/lib.lua index 8ea299c8..da649336 100644 --- a/builtin/intllib/lib.lua +++ b/builtin/intllib/lib.lua @@ -1,5 +1,3 @@ -intllib = intllib or {} - local INS_CHAR = "@" intllib.INSERTION_CHAR = INS_CHAR @@ -10,7 +8,7 @@ local escapes = { ["t"] = "\t", ["r"] = "\r", ["f"] = "\f", - [INS_CHAR] = INS_CHAR..INS_CHAR, + [INS_CHAR] = INS_CHAR..INS_CHAR, } local function unescape(str) @@ -23,7 +21,7 @@ local function unescape(str) local start = 1 while true do - local pos = str:find("\\", start, true) + local pos = str:find("[\\@]", start) if pos then add(str:sub(start, pos - 1)) else @@ -31,7 +29,13 @@ local function unescape(str) break end local c = str:sub(pos + 1, pos + 1) - add(escapes[c] or c) + if escapes[c] then + add(escapes[c]) + elseif str:sub(pos, pos) == "@" then + add("@" .. c) + else + add(c) + end start = pos + 2 end return table.concat(parts)