From 0067c8f29e2e2c0e015a682ae50811342cbfe2ff Mon Sep 17 00:00:00 2001 From: Frans de Jonge Date: Wed, 21 Aug 2019 19:40:15 +0200 Subject: [PATCH] [i18n, feat] Add basic context (msgctxt) support (#5234) References https://github.com/koreader/koreader/issues/5232 Given an entry in the PO file like the following: ``` msgctxt "systemstat" msgid " Total" msgstr "Totaal" ``` It can be addressed using: ```lua local _ = require("gettext") local C_ = _.pgettext C_("systemstat", " Total") ``` This allows to distinguish between separate instances of the same string, for example "Pages" meaning "Number of pages" and "Pages" meaning "Display of pages". Extraction of this code pattern is not yet implemented by nightswatcher. xgettext didn't yet support Lua back in 2013 when all this was first added to the program, but now it does. Therefore it might make the most sense to replace the current Python extraction script with xgettext itself. By default it only understands gettext.pgettext(), but that can be addressed by passing some extra command line arguments, for example: ``` xgettext -l lua -c --keyword=C_:1c,2 *.lua ``` --- frontend/gettext.lua | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/frontend/gettext.lua b/frontend/gettext.lua index e22ecd71a..ec4ec6620 100644 --- a/frontend/gettext.lua +++ b/frontend/gettext.lua @@ -12,8 +12,8 @@ local GetText_mt = { __index = {} } -function GetText_mt.__call(gettext, string) - return gettext.translation[string] or string +function GetText_mt.__call(gettext, msgstr) + return gettext.translation[msgstr] or msgstr end local function c_escape(what) @@ -36,6 +36,7 @@ end -- we only implement a sane subset for now function GetText_mt.__index.changeLang(new_lang) + GetText.context = {} GetText.translation = {} GetText.current_lang = "C" @@ -61,7 +62,15 @@ function GetText_mt.__index.changeLang(new_lang) 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) + local unescaped_string = string.gsub(data.msgstr, "\\(.)", c_escape) + if data.msgctxt and data.msgctxt ~= "" then + if not GetText.context[data.msgctxt] then + GetText.context[data.msgctxt] = {} + end + GetText.context[data.msgctxt][data.msgid] = unescaped_string + else + GetText.translation[data.msgid] = unescaped_string + end end -- stop at EOF: if line == nil then break end @@ -91,6 +100,10 @@ function GetText_mt.__index.changeLang(new_lang) GetText.current_lang = new_lang end +function GetText_mt.__index.pgettext(msgctxt, msgstr) + return GetText.context[msgctxt] and GetText.context[msgctxt][msgstr] or msgstr +end + setmetatable(GetText, GetText_mt) if os.getenv("LANGUAGE") then