Module:Arguments: Difference between revisions
Jump to navigation
Jump to search
en>Mr. Stradivarius m (Protected Module:Arguments: High-risk Lua module ([Edit=Allow only autoconfirmed users] (indefinite) [Move=Allow only autoconfirmed users] (indefinite))) |
en>Mr. Stradivarius (don't use "if frame == mw.getCurrentFrame()") |
||
Line 10: | Line 10: | ||
-- from another Lua module or from the debug console, so put the args in a special table so we can differentiate them. | -- from another Lua module or from the debug console, so put the args in a special table so we can differentiate them. | ||
local fargs, pargs, luaArgs | local fargs, pargs, luaArgs | ||
if frame == | if type(frame) == 'table' and type(frame.args) == 'table' and type(frame.getParent) == 'function' then | ||
fargs = frame.args | fargs = frame.args | ||
pargs = frame:getParent().args | pargs = frame:getParent().args |
Revision as of 21:50, 10 December 2013
This is a meta module.
This module is meant to be used only by other modules. It should not be invoked in wikitext.
This module was adapted from Module:Arguments on Wikipedia.
Adaptation is noted for reference and attribution only. This module may differ from the original in function or in usage. The documentation on Wikipedia may be helpful in understanding this module.
Adaptation is noted for reference and attribution only. This module may differ from the original in function or in usage. The documentation on Wikipedia may be helpful in understanding this module.
The above documentation is transcluded from Module:Arguments/doc.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
-- This module provides easy processing of arguments passed to Scribunto from #invoke.
-- It is intended for use by other Lua modules, and should not be called from #invoke directly.
local arguments = {}
function arguments.getArgs(frame, options)
options = type(options) == 'table' and options or {}
-- Get the arguments from the frame object if available. If the frame object is not available, we are being called
-- from another Lua module or from the debug console, so put the args in a special table so we can differentiate them.
local fargs, pargs, luaArgs
if type(frame) == 'table' and type(frame.args) == 'table' and type(frame.getParent) == 'function' then
fargs = frame.args
pargs = frame:getParent().args
else
luaArgs = type(frame) == 'table' and frame or {}
end
-- Set up the args and metaArgs tables. args will be the one accessed from functions, and metaArgs will hold the actual arguments.
-- The metatable connects the two together.
local args, metaArgs, metatable = {}, {}, {}
setmetatable(args, metatable)
local function tidyVal(key, val)
-- Processes a value according to the options given to getArguments. Can trim whitespace and remove blanks.
-- Keys are not used here, but they can be used by user-generated functions, so defining it here to avoid breakage.
if type(val) == 'string' then
if options.trim ~= false then
val = mw.text.trim(val)
end
if options.removeBlanks == false or mw.ustring.find(val, '%S') then
return val
end
else
return val
end
end
-- Use a user-generated function to tidy the values if specified.
local valueFunc = options.valueFunc
if valueFunc then
local valueFuncType = type(valueFunc)
if valueFuncType == 'function' then
tidyVal = valueFunc
else
error('type error in option "valueFunc": expected function, got ' .. valueFuncType, 2)
end
end
local function mergeArgs(iterator, tables)
-- Accepts multiple tables as input and merges their keys and values into one table using the specified iterator.
-- If a value is already present it is not overwritten; tables listed earlier have precendence.
for _, t in ipairs(tables) do
for key, val in iterator(t) do
if metaArgs[key] == nil then
metaArgs[key] = tidyVal(key, val)
end
end
end
end
-- Set the order of precedence of the argument tables. If the variables are nil, nothing will be added to the table,
-- which is how we avoid clashes between the frame/parent args and the Lua args.
local argTables = {}
if options.frameOnly then
table.insert(argTables, fargs)
elseif options.parentOnly then
table.insert(argTables, pargs)
elseif options.parentFirst then
table.insert(argTables, pargs)
table.insert(argTables, fargs)
else
table.insert(argTables, fargs)
table.insert(argTables, pargs)
end
table.insert(argTables, luaArgs)
--[[
-- Define metatable behaviour. Arguments are stored in the metaArgs table, and are only fetched from the
-- argument tables once. Also, we keep a record in the metatable of when pairs and ipairs have been called,
-- so we do not run pairs and ipairs on fargs and pargs more than once. We also do not run ipairs on fargs
-- and pargs if pairs has already been run, as all the arguments will already have been copied over.
--]]
metatable.__index = function (t, key)
local val = metaArgs[key]
if val ~= nil then
return val
else
for i, argTable in ipairs(argTables) do
local argTableVal = tidyVal(key, argTable[key])
if argTableVal ~= nil then
metaArgs[key] = argTableVal
return argTableVal
end
end
end
end
metatable.__newindex = function (t, key, val)
if not options.readOnly and (not options.noOverwrite or args[key] == nil) then
metaArgs[key] = val
end
end
metatable.__pairs = function ()
if not metatable.donePairs then
mergeArgs(pairs, argTables)
metatable.donePairs = true
metatable.doneIpairs = true
end
return pairs(metaArgs)
end
metatable.__ipairs = function ()
if not metatable.doneIpairs then
mergeArgs(ipairs, argTables)
metatable.doneIpairs = true
end
return ipairs(metaArgs)
end
return args
end
return arguments