Изменения

Перейти к навигации Перейти к поиску
5686 байт убрано ,  2 года назад
Содержимое страницы заменено на «{{#invoke:Message box|fmbox}}<noinclude> {{documentation}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </...»
Строка 1: Строка 1: −
-- This module provides easy processing of arguments passed to Scribunto from #invoke.
+
{{#invoke:Message box|fmbox}}<noinclude>
-- It is intended for use by other Lua modules, and should not be called from #invoke directly.
+
{{documentation}}
 
+
<!-- Add categories and interwikis to the /doc subpage, not here! -->
local libraryUtil = require('libraryUtil')
+
</noinclude>
local checkType = libraryUtil.checkType
  −
 
  −
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 options every time we call it.
  −
 
  −
local function tidyValDefault(key, val)
  −
if type(val) == 'string' then
  −
val = val:match('^%s*(.-)%s*$')
  −
if val == '' then
  −
return nil
  −
else
  −
return val
  −
end
  −
else
  −
return val
  −
end
  −
end
  −
 
  −
local function tidyValTrimOnly(key, val)
  −
if type(val) == 'string' then
  −
return val:match('^%s*(.-)%s*$')
  −
else
  −
return val
  −
end
  −
end
  −
 
  −
local function tidyValRemoveBlanksOnly(key, val)
  −
if type(val) == 'string' then
  −
if val:find('%S') then
  −
return val
  −
else
  −
return nil
  −
end
  −
else
  −
return val
  −
end
  −
end
  −
 
  −
local function tidyValNoChange(key, val)
  −
return val
  −
end
  −
 
  −
function arguments.getArgs(frame, options)
  −
checkType('getArgs', 1, frame, 'table', true)
  −
checkType('getArgs', 2, options, 'table', true)
  −
frame = frame or {}
  −
options = 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 assign the args to a new variable so we can differentiate them.
  −
local fargs, pargs, luaArgs
  −
if type(frame.args) == 'table' and type(frame.getParent) == 'function' then
  −
if not options.parentOnly then
  −
fargs = frame.args
  −
end
  −
if not options.frameOnly then
  −
pargs = frame:getParent().args
  −
end
  −
if options.parentFirst then
  −
fargs, pargs = pargs, fargs
  −
end
  −
else
  −
luaArgs = frame
  −
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)
  −
 
  −
-- Generate the tidyVal function. If it has been specified by the user, we use that; if not, we choose one of four functions
  −
-- depending on the options chosen. This is so that we don't have to call the options table every time the function is called.
  −
local tidyVal = options.valueFunc
  −
if tidyVal then
  −
if type(tidyVal) ~= 'function' then
  −
error("bad value assigned to option 'valueFunc' (function expected, got " .. type(tidyVal) .. ')', 2)
  −
end
  −
elseif options.trim ~= false then
  −
if options.removeBlanks ~= false then
  −
tidyVal = tidyValDefault
  −
else
  −
tidyVal = tidyValTrimOnly
  −
end
  −
else
  −
if options.removeBlanks ~= false then
  −
tidyVal = tidyValRemoveBlanksOnly
  −
else
  −
tidyVal = tidyValNoChange
  −
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 precedence.
  −
-- We are also memoizing nil values, but those values can be overwritten.
  −
for _, t in ipairs(tables) do
  −
for key, val in iterator(t) do
  −
local metaArgsVal = metaArgs[key]
  −
if metaArgsVal == nil or metaArgsVal == nilArg then
  −
local tidiedVal = tidyVal(key, val)
  −
if tidiedVal == nil then
  −
metaArgs[key] = nilArg
  −
else
  −
metaArgs[key] = tidiedVal
  −
end
  −
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 = {fargs}
  −
argTables[#argTables + 1] = pargs
  −
argTables[#argTables + 1] = luaArgs
  −
 
  −
--[[
  −
-- Define metatable behaviour. Arguments are memoized in the metaArgs table, and are only fetched from the
  −
-- argument tables once. Nil arguments are also memoized using the nilArg variable in order to increase
  −
-- performance. 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
  −
if val == nilArg then
  −
return nil
  −
else
  −
return val
  −
end
  −
end
  −
for _, argTable in ipairs(argTables) do
  −
local argTableVal = tidyVal(key, argTable[key])
  −
if argTableVal == nil then
  −
metaArgs[key] = nilArg
  −
else
  −
metaArgs[key] = argTableVal
  −
return argTableVal
  −
end
  −
end
  −
return nil
  −
end
  −
 
  −
metatable.__newindex = function (t, key, val)
  −
if options.readOnly then
  −
error('could not write to argument table key "' .. tostring(key) .. '"; the table is read-only', 2)
  −
elseif options.noOverwrite and args[key] ~= nil then
  −
error('could not write to argument table key "' .. tostring(key) .. '"; overwriting existing arguments is not permitted', 2)
  −
elseif val == nil then
  −
metaArgs[key] = nilArg -- Memoize nils.
  −
else
  −
metaArgs[key] = val
  −
end
  −
end
  −
 
  −
metatable.__pairs = function ()
  −
if not metatable.donePairs then
  −
mergeArgs(pairs, argTables)
  −
metatable.donePairs = true
  −
metatable.doneIpairs = true
  −
end
  −
return function (t, k)
  −
local nk, val = next(metaArgs, k)
  −
if val == nilArg then
  −
val = nil
  −
end
  −
return nk, val
  −
end
  −
end
  −
 
  −
metatable.__ipairs = function ()
  −
if not metatable.doneIpairs then
  −
mergeArgs(ipairs, argTables)
  −
metatable.doneIpairs = true
  −
end
  −
return function (t, i)
  −
local val = metaArgs[i + 1]
  −
if val == nil then
  −
return nil
  −
elseif val == nilArg then
  −
val = nil
  −
end
  −
return i + 1, val
  −
end, nil, 0
  −
end
  −
 
  −
return args
  −
end
  −
 
  −
return arguments
 

Реклама:

Навигация