2
0
mirror of https://github.com/koreader/koreader synced 2024-11-10 01:10:34 +00:00
koreader/frontend/gettext.lua

119 lines
3.5 KiB
Lua
Raw Normal View History

2014-06-08 13:32:45 +00:00
local isAndroid, android = pcall(require, "android")
local logger = require("logger")
2013-04-07 08:09:33 +00:00
local GetText = {
translation = {},
current_lang = "C",
dirname = "l10n",
textdomain = "koreader"
}
local GetText_mt = {
__index = {}
}
2013-04-07 08:09:33 +00:00
2013-10-18 20:38:07 +00:00
function GetText_mt.__call(gettext, string)
return gettext.translation[string] or string
end
local function c_escape(what)
if what == "\n" then return ""
elseif what == "a" then return "\a"
elseif what == "b" then return "\b"
elseif what == "f" then return "\f"
elseif what == "n" then return "\n"
elseif what == "r" then return "\r"
elseif what == "t" then return "\t"
elseif what == "v" then return "\v"
elseif what == "0" then return "\0" -- shouldn't happen, though
else
return what
end
2013-04-07 08:09:33 +00:00
end
-- for PO file syntax, see
-- https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html
-- we only implement a sane subset for now
function GetText_mt.__index.changeLang(new_lang)
GetText.translation = {}
GetText.current_lang = "C"
2017-10-11 12:22:11 +00:00
-- the "C" locale disables localization altogether
-- can be various things such as `en_US` or `en_US:en`
if new_lang == "C" or new_lang == nil or new_lang == ""
or new_lang:match("^en_US") == "en_US" then return end
-- strip encoding suffix in locale like "zh_CN.utf8"
new_lang = new_lang:sub(1, new_lang:find(".%."))
local file = GetText.dirname .. "/" .. new_lang .. "/" .. GetText.textdomain .. ".po"
local po = io.open(file, "r")
if not po then
logger.dbg("cannot open translation file:", file)
2017-10-11 12:22:11 +00:00
return false
end
local data = {}
local what = nil
while true do
local line = po:read("*l")
if line == nil or line == "" then
if data.msgid and data.msgstr and data.msgstr ~= "" then
GetText.translation[data.msgid] = string.gsub(data.msgstr, "\\(.)", c_escape)
end
-- stop at EOF:
if line == nil then break end
data = {}
what = nil
else
-- comment
if not line:match("^#") then
-- new data item (msgid, msgstr, ...
local w, s = line:match("^%s*(%a+)%s+\"(.*)\"%s*$")
if w then
what = w
else
-- string continuation
s = line:match("^%s*\"(.*)\"%s*$")
end
if what and s then
-- unescape \n or msgid won't match
s = s:gsub("\\n", "\n")
-- unescape " or msgid won't match
s = s:gsub('\\"', '"')
data[what] = (data[what] or "") .. s
end
end
end
end
GetText.current_lang = new_lang
2013-04-07 08:09:33 +00:00
end
2013-10-18 20:38:07 +00:00
setmetatable(GetText, GetText_mt)
if os.getenv("LANGUAGE") then
GetText.changeLang(os.getenv("LANGUAGE"))
elseif os.getenv("LC_ALL") then
GetText.changeLang(os.getenv("LC_ALL"))
elseif os.getenv("LC_MESSAGES") then
GetText.changeLang(os.getenv("LC_MESSAGES"))
elseif os.getenv("LANG") then
GetText.changeLang(os.getenv("LANG"))
end
2014-06-08 13:32:45 +00:00
if isAndroid then
local ffi = require("ffi")
local buf = ffi.new("char[?]", 16)
android.lib.AConfiguration_getLanguage(android.app.config, buf)
2014-06-08 13:32:45 +00:00
local lang = ffi.string(buf)
android.lib.AConfiguration_getCountry(android.app.config, buf)
2014-06-08 13:32:45 +00:00
local country = ffi.string(buf)
if lang and country then
GetText.changeLang(lang.."_"..country)
end
end
2013-10-18 20:38:07 +00:00
return GetText