মডিউল:Wrapper
অবয়ব
-- Localize an enwiki module by wrapping its returned p table.
-- The intention is that only minimal changes to the enwiki module will be needed.
-- Before the module is called, local text is converted to en.
-- After the module finishes, en text is converted to local.
--
-- The enwiki module might look like this:
-- local p = {}
-- ...
-- return p
--
-- Replace that with:
-- local p = {}
-- local modwrap = require('Module:Wrapper').getWrapper()
-- ...
-- -- Use modwrap.text2en(...) if more translations are needed.
-- ...
-- return modwrap.wrapper(p)
--
-- If needed, use the following to replace the above getWrapper line.
-- local modwrap = require('Module:Wrapper').getWrapper('Module:Example/translate')
-- where Module:Example/translate contains optional functions
-- (text2en, text2local) to convert text other than digits.
--
-- Simplifying assumptions:
-- Page has {{example|one|two|name=three}}
-- Template:Example is {{#invoke|example|anyname}}
-- Module:Example returns p where p is a table including
-- function p.anyname(frame)
-- ...
-- end
-- The wrapper translates "|one|two|name=three" from the local language
-- before calling anyname, and translates the result to the local language.
local convert = require('Module:সংখ্যা রূপান্তরকারী')
local digits2en = convert._translate2en
local digits2local = convert._translate2bn
local text2en, text2local -- forward declarations
local function makeWrapper(f)
local function table2en(args)
local result = {}
for k, v in pairs(args) do
result[k] = text2en(v)
end
return result
end
return function (...)
local args = {...}
local first = args[1]
if type(first) == 'table' and type(first.getParent) == 'function' then
local xargs = table2en(first:getParent().args)
args = { first:newChild({ args = xargs }):newChild({ args = first.args }) }
end
return text2local(f(unpack(args)))
end
end
local function wrapper(p)
return setmetatable({}, {
__index = function (self, key)
local f = p[key]
if type(f) == 'function' then
f = makeWrapper(f)
end
rawset(self, key, f)
return f
end
})
end
local function exclude(translator)
-- Return a function that translates while excluding some html such as
-- '*' and the span in '<span style="color:#888">1995</span>'.
local tEncode = {} -- encode digits as letters to avoid translation
for i = 0, 9 do
tEncode[tostring(i)] = string.char(i + 65) -- 65 is 'A'
end
local nid = 0
local text2id = {} -- [removed_text] = replacement_id
local id2text = {} -- inverse
local function marker(s)
local sid = text2id[s]
if not sid then
nid = nid + 1
sid = tostring(nid):gsub('%d', tEncode)
text2id[s] = sid
id2text[sid] = s
end
return '«÷REMOVED' .. sid .. '÷»'
end
local function hider(s)
return (s
:gsub('&#[Xx]?%x+;', marker)
:gsub('<div%s[^>]*%d[^>]*>', marker)
:gsub('<span%s[^>]*%d[^>]*>', marker)
)
end
local function unhider(s)
return (s:gsub('«÷REMOVED(%u+)÷»', id2text))
end
return function (s) return unhider(translator(hider(s))) end
end
local function getWrapper(modName)
local year2decade
if modName then
local xlate = require(modName)
year2decade = xlate.year2decade
if xlate.text2en then
text2en = function (text)
return xlate.text2en(digits2en(text))
end
end
if xlate.text2local then
text2local = function (text)
return digits2local(xlate.text2local(text))
end
end
end
text2local = exclude(text2local or digits2local)
return {
text2en = text2en or digits2en,
text2local = text2local,
wrapper = wrapper,
year2decade = year2decade,
}
end
return {
getWrapper = getWrapper,
}