Module:Arguments: Difference between revisions

m>Mr. Stradivarius
(fix undefined next() behaviour bug by checking for metatable.donePairs in the __index metamethod; also, format the module so it fits into 80 characters)
m (3 revisions imported from templatewiki:Module:Arguments: see Topic:Vtixlm0q28eo6jtf)
 
(29 intermediate revisions by 24 users not shown)
Line 7: Line 7:


local arguments = {}
local arguments = {}
local nilArg = {} -- Used for memoizing nil arguments in metaArgs.


-- Generate four different tidyVal functions, so that we don't have to check the
-- Generate four different tidyVal functions, so that we don't have to check the
Line 49: Line 47:
return val
return val
end
end
local function matchesTitle(given, title)
local tp = type( given )
return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title
end
local translate_mt = { __index = function(t, k) return k end }


function arguments.getArgs(frame, options)
function arguments.getArgs(frame, options)
Line 57: Line 62:


--[[
--[[
-- Get the arguments from the frame object if available. If the frame object
-- Set up argument translation.
-- is not available, we are being called from another Lua module or from the
--]]
-- debug console, so assign the args to a new variable so we can
options.translate = options.translate or {}
-- differentiate them.
if getmetatable(options.translate) == nil then
setmetatable(options.translate, translate_mt)
end
if options.backtranslate == nil then
options.backtranslate = {}
for k,v in pairs(options.translate) do
options.backtranslate[v] = k
end
end
if options.backtranslate and getmetatable(options.backtranslate) == nil then
setmetatable(options.backtranslate, {
__index = function(t, k)
if options.translate[k] ~= k then
return nil
else
return k
end
end
})
end
 
--[[
-- Get the argument tables. If we were passed a valid frame object, get the
-- frame arguments (fargs) and the parent frame arguments (pargs), depending
-- on the options set and on the parent frame's availability. If we weren't
-- passed a valid frame object, we are being called from another Lua module
-- or from the debug console, so assume that we were passed a table of args
-- directly, and assign it to a new variable (luaArgs).
--]]
--]]
local fargs, pargs, luaArgs
local fargs, pargs, luaArgs
if type(frame.args) == 'table' and type(frame.getParent) == 'function' then
if type(frame.args) == 'table' and type(frame.getParent) == 'function' then
if not options.parentOnly then
if options.wrappers then
fargs = frame.args
--[[
end
-- The wrappers option makes Module:Arguments look up arguments in
if not options.frameOnly then
-- either the frame argument table or the parent argument table, but
pargs = frame:getParent().args
-- not both. This means that users can use either the #invoke syntax
-- or a wrapper template without the loss of performance associated
-- with looking arguments up in both the frame and the parent frame.
-- Module:Arguments will look up arguments in the parent frame
-- if it finds the parent frame's title in options.wrapper;
-- otherwise it will look up arguments in the frame object passed
-- to getArgs.
--]]
local parent = frame:getParent()
if not parent then
fargs = frame.args
else
local title = parent:getTitle():gsub('/sandbox$', '')
local found = false
if matchesTitle(options.wrappers, title) then
found = true
elseif type(options.wrappers) == 'table' then
for _,v in pairs(options.wrappers) do
if matchesTitle(v, title) then
found = true
break
end
end
end
 
-- We test for false specifically here so that nil (the default) acts like true.
if found or options.frameOnly == false then
pargs = parent.args
end
if not found or options.parentOnly == false then
fargs = frame.args
end
end
else
-- options.wrapper isn't set, so check the other options.
if not options.parentOnly then
fargs = frame.args
end
if not options.frameOnly then
local parent = frame:getParent()
pargs = parent and parent.args or nil
end
end
end
if options.parentFirst then
if options.parentFirst then
Line 77: Line 150:
end
end


-- Set up the args and metaArgs tables. args will be the one accessed from
-- Set the order of precedence of the argument tables. If the variables are
-- functions, and metaArgs will hold the actual arguments. The metatable
-- nil, nothing will be added to the table, which is how we avoid clashes
-- connects the two together.
-- between the frame/parent args and the Lua args.
local args, metaArgs, metatable = {}, {}, {}
local argTables = {fargs}
setmetatable(args, metatable)
argTables[#argTables + 1] = pargs
argTables[#argTables + 1] = luaArgs


--[[