Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:Translate/opis
local T, A, translate, back, arguments = {}, {}, {}, {}, {}
local getArgs = require('Dev:Arguments').getArgs
local checkType = require('libraryUtil').checkType
local MD, MD_list, MD_count = {}, {}, 0
function MD.new(key, parent)
local obj = setmetatable({_v={}}, MD)
if parent then
key = tonumber(key)
rawset(obj, 'key', key)
rawset(obj, 'parent', parent)
rawset(obj, 'translate', parent:param(key))
else
key = tostring(key)
if mw.ustring.find(translate[key], '##') then
error(mw.ustring.format('Bad pattern: \'%s\' for \'%s\' key (#\'s have to be separated)', translate[key], key), 3)
end
rawset(obj, 'key', key)
rawset(obj, 'translate', translate[key])
end
local pattern, depth = mw.ustring.gsub(obj.translate, '#', '(%%-?%%d-)')
rawset(obj, 'pattern', '^' .. pattern .. '$')
rawset(obj, 'depth', tonumber(depth))
return obj
end
function MD.__index(self, key)
if MD[key] then return MD[key] end
local i = tonumber(key)
if not i then error('Bad key given to ' .. MD.tostring(self) .. ' parameter (number expected, got ' .. type(key) .. ')', 2) end
local param = self:param(i)
if self._v[i] then
if self._v[i] == true then return arguments[param] end
return self._v[i]
end
if mw.ustring.find(param, '#') then
self._v[i] = MD.new(i, self)
return self._v[i]
end
self._v[i] = not not arguments[param]
return arguments[param]
end
function MD.__newindex(self, key, val)
local i = tonumber(key)
if not i then error('Bad key given to ' .. MD.tostring(self) .. ' parameter (number expected, got ' .. type(key) .. ')', 2) end
local param = self:param(i)
if mw.ustring.find(param, '#') then
error('Only top level keys can be set', 2)
end
arguments[param] = val
self._v[i] = not not arguments[param]
end
local function md_next(invariant)
local key = table.remove(invariant.order, 1)
if key then return key, invariant.tab[key] end
return nil
end
function MD.__pairs(self)
return md_next, {tab=self, order=self:keys(true)}
end
local function mdi_next(self, i)
i = i+1
if self._v[i] then return i, self[i] end
return nil
end
function MD.__ipairs(self)
return mdi_next, self, 0
end
function MD:len(full)
if not not full then return #self:keys() end
local c = 1
while self._v[c] do c = c+1 end
return c-1
end
function MD.__len(self)
return self:len(false)
end
function MD.tostring(obj)
if type(obj) ~= 'table' then return tostring(obj) end
if rawget(obj, 'parent') == nil then return 'table[\'' .. tostring(obj.key) .. '\']' end
return MD.tostring(rawget(obj, 'parent')) .. '[' .. tostring(obj.key) .. ']'
end
function MD:param(...)
local p = self.translate
for i,v in ipairs(arg) do
checkType(':param', i, v, 'number', false)
p = mw.ustring.gsub(p, '#', tostring(v), 1)
end
return p
end
local function getKeys(tab, sorted)
local list = {}
local k = next(tab)
while k do
list[#list+1] = k
k = next(tab, k)
end
if sorted then table.sort(list) end
return list
end
function MD:keys(sorted)
return getKeys(self._v, sorted)
end
function T.getArgs(frame, options)
options = options or {}
translate = options.translate or {}
for key,val in pairs(translate) do
if mw.ustring.find(tostring(val), '#') then
MD_list[key] = MD.new(key)
MD_count = MD_count + 1
else
back[val] = key
end
end
if MD_count == 0 then
mw.log('No multi-dimensional parameters found. Returning regular Module:Arguments output. Consider using it instead.')
return getArgs(frame, options)
end
options.translate = nil
options.backtranslate = nil
arguments = getArgs(frame, options)
local meta = {}
local A = setmetatable({}, meta)
function meta.__index(self, key)
if meta[key] then return meta[key] end
if MD_list[key] then return MD_list[key] end
if translate[key] then key = translate[key] end
return arguments[key]
end
function meta.__newindex(self, key, val)
if MD_list[key] then MD_list[key] = val end
if translate[key] then key = translate[key] end
arguments[key] = val
end
local rawArgs = select(2, pairs(arguments)).t
local function t_next(invariant)
local key, val = invariant.k or true, nil
while key do
key, val = next(invariant.t, invariant.k)
invariant.k = key
if key == nil then
meta.scanDone = true
invariant.n = invariant.n or {}
if #invariant.n > 0 then
invariant.t = table.remove(invariant.n, 1)
invariant.k = nil
key = true
else
return nil
end
elseif type(key) ~= 'string' or MD_count == 0 then
return key, val
else
if back[key] and key == translate[back[key]] then
return back[key], val
end
for k,v in pairs(invariant.check or MD_list) do
local m = {mw.ustring.match(key, v.pattern)}
if #m > 0 then
local dummy, i = v, table.remove(m, 1)
while i do
dummy = dummy[i]
i = table.remove(m, 1)
end
val = nil
break
end
end
if val then return key, val end
end
end
end
function meta.__pairs()
return t_next, {t=rawArgs,n={MD_list}}
end
local function i_next(self, i)
local v = self[i+1]
if v ~= nil then return i+1, v end
end
function meta.__ipairs(self) return i_next, self, 0 end
function meta:scan(...)
if not meta.scanDone then
for k,v in pairs(self) do end
meta.scanDone = true
end
return self
end
local function merge(first, second, overwrite)
overwrite = not not overwrite
for k,v in pairs(second) do
if type(first[k]) == 'table' and type(v) == 'table' then
first[k] = merge(first[k], v, overwrite)
elseif overwrite or first[k] == nil then
first[k] = v
end
end
return first
end
local function flip(md, key, depth)
local res = {}
for k,v in pairs(md) do
if depth > 1 and type(v) == 'table' then
res[k] = flip(v, key, depth-1)
else
res[k] = res[k] or {}
res[k][key] = v
end
end
return res
end
local function tConcat(t1, ...)
for _,tab in ipairs(arg) do
for i,v in ipairs(tab) do
t1[#t1+1] = v
end
end
return t1
end
local function optionals(tab, opt, depth, keys)
keys = keys or {}
for k,v in pairs(tab) do
local keys = tConcat({}, keys, {k})
if depth > 1 then
optionals(v, opt, depth-1, keys)
else
for _,k in ipairs(opt) do
local val, i = MD_list[k], 1
while keys[i] do
val = val[keys[i]]
i = i+1
end
v[k] = val
end
end
end
end
function meta:group(req, opt, depth)
self:scan()
if type(req) ~= 'table' then req = {req} end
if type(opt) ~= 'table' then opt = {opt} end
depth = tonumber(depth)
local reqMDs, optMDs = {}, {}
for i,key in ipairs(req) do
if MD_list[key] then
reqMDs[#reqMDs+1] = key
if not depth then
depth = MD_list[key].depth
elseif MD_list[key].depth < depth then
depth = MD_list[key].depth
end
end
end
for i,key in ipairs(opt) do
if MD_list[key] then
optMDs[#optMDs+1] = key
if not depth then
depth = MD_list[key].depth
elseif MD_list[key].depth < depth then
depth = MD_list[key].depth
end
end
end
local res = {}
for i,key in ipairs(reqMDs) do
merge(res, flip(self[key], key, depth))
end
optionals(res, opt, depth)
return res
end
return A, MD_list
end
return T
-- [[Kategoria:Moduły]]