Update intllib, add `core.get_translator_auto()` wrapper
parent
318a67d168
commit
b2dc09ad3a
|
@ -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 escapes = { n="\n", r="\r", t="\t" }
|
||||||
|
|
||||||
local function unescape(str)
|
local function unescape(str)
|
||||||
return (strgsub(str, "(\\+)([nrt]?)", function(bs, c)
|
return (str:gsub("(\\+)([nrt]?)", function(bs, c)
|
||||||
local bsl = #bs
|
local bsl = #bs
|
||||||
local realbs = strrep("\\", bsl/2)
|
local realbs = ("\\"):rep(bsl/2)
|
||||||
if bsl%2 == 1 then
|
if bsl%2 == 1 then
|
||||||
c = escapes[c] or c
|
c = escapes[c] or c
|
||||||
end
|
end
|
||||||
|
@ -27,14 +20,14 @@ local function parse_po(str)
|
||||||
end
|
end
|
||||||
for _, line in ipairs(str:split("\n")) do repeat
|
for _, line in ipairs(str:split("\n")) do repeat
|
||||||
lineno = lineno + 1
|
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
|
state, msgid, msgid_plural = nil, nil, nil
|
||||||
break -- continue
|
break -- continue
|
||||||
end
|
end
|
||||||
|
|
||||||
local mid = strmatch(line, "^%s*msgid%s*\"(.*)\"%s*$")
|
local mid = line:match("^%s*msgid%s*\"(.*)\"%s*$")
|
||||||
if mid then
|
if mid then
|
||||||
if state == "id" then
|
if state == "id" then
|
||||||
return perror("unexpected msgid")
|
return perror("unexpected msgid")
|
||||||
|
@ -43,7 +36,7 @@ local function parse_po(str)
|
||||||
break -- continue
|
break -- continue
|
||||||
end
|
end
|
||||||
|
|
||||||
mid = strmatch(line, "^%s*msgid_plural%s*\"(.*)\"%s*$")
|
mid = line:match("^%s*msgid_plural%s*\"(.*)\"%s*$")
|
||||||
if mid then
|
if mid then
|
||||||
if state ~= "id" then
|
if state ~= "id" then
|
||||||
return perror("unexpected msgid_plural")
|
return perror("unexpected msgid_plural")
|
||||||
|
@ -52,15 +45,14 @@ local function parse_po(str)
|
||||||
break -- continue
|
break -- continue
|
||||||
end
|
end
|
||||||
|
|
||||||
local ind, mstr = strmatch(line,
|
local ind, mstr = line:match("^%s*msgstr([0-9%[%]]*)%s*\"(.*)\"%s*$")
|
||||||
"^%s*msgstr([0-9%[%]]*)%s*\"(.*)\"%s*$")
|
|
||||||
if ind then
|
if ind then
|
||||||
if not msgid then
|
if not msgid then
|
||||||
return perror("missing msgid")
|
return perror("missing msgid")
|
||||||
elseif ind == "" then
|
elseif ind == "" then
|
||||||
msgstrind = 0
|
msgstrind = 0
|
||||||
elseif strmatch(ind, "%[[0-9]+%]") then
|
elseif ind:match("%[[0-9]+%]") then
|
||||||
msgstrind = tonumber(strsub(ind, 2, -2))
|
msgstrind = tonumber(ind:sub(2, -2))
|
||||||
else
|
else
|
||||||
return perror("malformed msgstr")
|
return perror("malformed msgstr")
|
||||||
end
|
end
|
||||||
|
@ -73,7 +65,7 @@ local function parse_po(str)
|
||||||
break -- continue
|
break -- continue
|
||||||
end
|
end
|
||||||
|
|
||||||
mstr = strmatch(line, "^%s*\"(.*)\"%s*$")
|
mstr = line:match("^%s*\"(.*)\"%s*$")
|
||||||
if mstr then
|
if mstr then
|
||||||
if state == "id" then
|
if state == "id" then
|
||||||
msgid = msgid..unescape(mstr)
|
msgid = msgid..unescape(mstr)
|
||||||
|
@ -107,9 +99,9 @@ end
|
||||||
-- It handles enough stuff to parse the `Plural-Forms` header correctly.
|
-- It handles enough stuff to parse the `Plural-Forms` header correctly.
|
||||||
-- Note that it assumes the C expression is valid to begin with.
|
-- Note that it assumes the C expression is valid to begin with.
|
||||||
local function compile_plural_forms(str)
|
local function compile_plural_forms(str)
|
||||||
local plural = strmatch(str, "plural=([^;]+);?$")
|
local plural = str:match("plural=([^;]+);?$")
|
||||||
local function replace_ternary(s)
|
local function replace_ternary(s)
|
||||||
local c, t, f = strmatch(s, "^(.-)%?(.-):(.*)")
|
local c, t, f = s:match(s"^(.-)%?(.-):(.*)")
|
||||||
if c then
|
if c then
|
||||||
return ("__if("
|
return ("__if("
|
||||||
..replace_ternary(c)
|
..replace_ternary(c)
|
||||||
|
@ -120,10 +112,10 @@ local function compile_plural_forms(str)
|
||||||
return s
|
return s
|
||||||
end
|
end
|
||||||
plural = replace_ternary(plural)
|
plural = replace_ternary(plural)
|
||||||
plural = strgsub(plural, "&&", " and ")
|
plural = plural:gsub("&&", " and ")
|
||||||
plural = strgsub(plural, "||", " or ")
|
plural = plural:gsub("||", " or ")
|
||||||
plural = strgsub(plural, "!=", "~=")
|
plural = plural:gsub("!=", "~=")
|
||||||
plural = strgsub(plural, "!", " not ")
|
plural = plural:gsub("!", " not ")
|
||||||
local f, err = loadstring([[
|
local f, err = loadstring([[
|
||||||
local function __if(c, t, f)
|
local function __if(c, t, f)
|
||||||
if c and c~=0 then return t else return f end
|
if c and c~=0 then return t else return f end
|
||||||
|
@ -150,7 +142,7 @@ end
|
||||||
local function parse_headers(str)
|
local function parse_headers(str)
|
||||||
local headers = { }
|
local headers = { }
|
||||||
for _, line in ipairs(str:split("\n")) do
|
for _, line in ipairs(str:split("\n")) do
|
||||||
local k, v = strmatch(line, "^([^:]+):%s*(.*)")
|
local k, v = line:match("^([^:]+):%s*(.*)")
|
||||||
if k then
|
if k then
|
||||||
headers[k] = v
|
headers[k] = v
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@ intllib = {
|
||||||
strings = {},
|
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")
|
dofile(path .. "lib.lua")
|
||||||
|
|
||||||
local LANG = core.settings:get("language")
|
local LANG = core.settings:get("language")
|
||||||
|
@ -67,15 +67,14 @@ function intllib.Getter(modname)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local strfind, strsub = string.find, string.sub
|
|
||||||
local langs
|
local langs
|
||||||
|
|
||||||
local function split(str, sep)
|
local function split(str, sep)
|
||||||
local pos, endp = 1, #str+1
|
local pos, endp = 1, #str+1
|
||||||
return function()
|
return function()
|
||||||
if (not pos) or pos > endp then return end
|
if (not pos) or pos > endp then return end
|
||||||
local s, e = strfind(str, sep, pos, true)
|
local s, e = str:find(sep, pos, true)
|
||||||
local part = strsub(str, pos, s and s-1)
|
local part = str:sub(pos, s and s-1)
|
||||||
pos = e and e + 1
|
pos = e and e + 1
|
||||||
return part
|
return part
|
||||||
end
|
end
|
||||||
|
@ -89,14 +88,14 @@ function intllib.get_detected_languages()
|
||||||
local function addlang(l)
|
local function addlang(l)
|
||||||
local sep
|
local sep
|
||||||
langs[#langs+1] = l
|
langs[#langs+1] = l
|
||||||
sep = strfind(l, ".", 1, true)
|
sep = l:find(".", 1, true)
|
||||||
if sep then
|
if sep then
|
||||||
l = strsub(l, 1, sep-1)
|
l = l:sub(1, sep-1)
|
||||||
langs[#langs+1] = l
|
langs[#langs+1] = l
|
||||||
end
|
end
|
||||||
sep = strfind(l, "_", 1, true)
|
sep = l:find("_", 1, true)
|
||||||
if sep then
|
if sep then
|
||||||
langs[#langs+1] = strsub(l, 1, sep-1)
|
langs[#langs+1] = l:sub(1, sep-1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -138,8 +137,9 @@ local function catgettext(catalogs, msgid)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local floor = math.floor
|
||||||
local function catngettext(catalogs, msgid, msgid_plural, n)
|
local function catngettext(catalogs, msgid, msgid_plural, n)
|
||||||
n = math.floor(n)
|
n = floor(n)
|
||||||
for _, cat in ipairs(catalogs) do
|
for _, cat in ipairs(catalogs) do
|
||||||
local msgstr = cat and cat[msgid]
|
local msgstr = cat and cat[msgid]
|
||||||
if msgstr then
|
if msgstr then
|
||||||
|
@ -158,7 +158,7 @@ function intllib.make_gettext_pair(modname)
|
||||||
if gettext_getters[modname] then
|
if gettext_getters[modname] then
|
||||||
return unpack(gettext_getters[modname])
|
return unpack(gettext_getters[modname])
|
||||||
end
|
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 localedir = modpath and modpath.."/locale"
|
||||||
local catalogs = localedir and gettext.load_catalogs(localedir) or {}
|
local catalogs = localedir and gettext.load_catalogs(localedir) or {}
|
||||||
local getter = Getter(modname)
|
local getter = Getter(modname)
|
||||||
|
@ -192,18 +192,24 @@ function intllib.get_strings(modname, langcode)
|
||||||
modname = modname or core.get_current_modname()
|
modname = modname or core.get_current_modname()
|
||||||
local msgstr = intllib.strings[modname]
|
local msgstr = intllib.strings[modname]
|
||||||
if not msgstr then
|
if not msgstr then
|
||||||
local modpath = core.get_modpath(modname) and core.get_modpath(modname)
|
local modpath = core.get_modpath(modname)
|
||||||
msgstr = { }
|
msgstr = { }
|
||||||
if modpath then
|
if modpath then
|
||||||
for _, l in ipairs(get_locales(langcode)) do
|
for _, l in ipairs(get_locales(langcode)) do
|
||||||
local t = intllib.load_strings(modpath.."/locale/"..modname.."."..l..".tr")
|
local t = intllib.load_strings(modpath.."/locale/"..modname.."."..l..".tr")
|
||||||
or intllib.load_strings(modpath.."/locale/"..l..".txt") or { }
|
or intllib.load_strings(modpath.."/locale/"..l..".txt") or { }
|
||||||
for k, v in pairs(t) do
|
for k, v in pairs(t) do
|
||||||
msgstr[k] = msgstr[k] or v
|
msgstr[k] = msgstr[k] or v
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
intllib.strings[modname] = msgstr
|
||||||
intllib.strings[modname] = msgstr
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return msgstr
|
return msgstr
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function core.get_translator_auto()
|
||||||
|
-- Surrounded in brackets so there's only one return value
|
||||||
|
return (intllib.make_gettext_pair())
|
||||||
|
end
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
intllib = intllib or {}
|
|
||||||
|
|
||||||
local INS_CHAR = "@"
|
local INS_CHAR = "@"
|
||||||
intllib.INSERTION_CHAR = INS_CHAR
|
intllib.INSERTION_CHAR = INS_CHAR
|
||||||
|
|
||||||
|
@ -10,7 +8,7 @@ local escapes = {
|
||||||
["t"] = "\t",
|
["t"] = "\t",
|
||||||
["r"] = "\r",
|
["r"] = "\r",
|
||||||
["f"] = "\f",
|
["f"] = "\f",
|
||||||
[INS_CHAR] = INS_CHAR..INS_CHAR,
|
[INS_CHAR] = INS_CHAR..INS_CHAR,
|
||||||
}
|
}
|
||||||
|
|
||||||
local function unescape(str)
|
local function unescape(str)
|
||||||
|
@ -23,7 +21,7 @@ local function unescape(str)
|
||||||
|
|
||||||
local start = 1
|
local start = 1
|
||||||
while true do
|
while true do
|
||||||
local pos = str:find("\\", start, true)
|
local pos = str:find("[\\@]", start)
|
||||||
if pos then
|
if pos then
|
||||||
add(str:sub(start, pos - 1))
|
add(str:sub(start, pos - 1))
|
||||||
else
|
else
|
||||||
|
@ -31,7 +29,13 @@ local function unescape(str)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
local c = str:sub(pos + 1, pos + 1)
|
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
|
start = pos + 2
|
||||||
end
|
end
|
||||||
return table.concat(parts)
|
return table.concat(parts)
|
||||||
|
|
Loading…
Reference in New Issue