en>Mr. Stradivarius |
en>MZMcBride |
Line 1: |
Line 1: |
| -- This module provides easy processing of arguments passed to Scribunto from #invoke. | | <div class="messagebox" id="template_doc_page_viewed_directly" style="text-align: center"> |
| -- It is intended for use by other Lua modules, and should not be called from #invoke directly.
| | This is the [[Wikipedia:Template documentation|documentation]] page {{{1|for [[{{NAMESPACE}}:{{BASEPAGENAME}}]].}}} <div style="font-size: 90%">When it is viewed directly, links using [[Help:Variable|variables]] may appear broken; do not replace these with [[hard coding|hardcoded]] page names or URLs.</div> |
| | | </div><includeonly>{{#if: {{{inhib|{{{inhibit|}}}}}} |<!-- skip -->|[[Category:Template documentation|{{PAGENAME}}]]}}</includeonly><noinclude> |
| local arguments = {}
| | {{pp-semi-protected|small=yes}} |
| | | {{template doc}} |
| function arguments.getArgs(frame, options)
| | <!-- Add categories and interwikis to the /doc subpage, not here! --> |
| options = type(options) == 'table' and options or {}
| | </noinclude> |
| | |
| -- 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 frame == mw.getCurrentFrame() 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
| |