第47行: |
第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) |
第60行: |
第53行: |
| frame = frame or {} | | frame = frame or {} |
| options = options or {} | | options = options or {} |
− |
| |
− | --[[
| |
− | -- Set up argument translation.
| |
− | --]]
| |
− | options.translate = options.translate or {}
| |
− | 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
| |
| | | |
| --[[ | | --[[ |
第114行: |
第82行: |
| local title = parent:getTitle():gsub('/sandbox$', '') | | local title = parent:getTitle():gsub('/sandbox$', '') |
| local found = false | | local found = false |
− | if matchesTitle(options.wrappers, title) then | + | if type(options.wrappers) == 'table' then |
− | found = true
| |
− | elseif type(options.wrappers) == 'table' then
| |
| for _,v in pairs(options.wrappers) do | | for _,v in pairs(options.wrappers) do |
− | if matchesTitle(v, title) then | + | if v == title then |
| found = true | | found = true |
| break | | break |
| end | | end |
| end | | end |
| + | elseif options.wrappers == title then |
| + | found = true |
| end | | end |
− | | + | |
| -- We test for false specifically here so that nil (the default) acts like true. | | -- We test for false specifically here so that nil (the default) acts like true. |
| if found or options.frameOnly == false then | | if found or options.frameOnly == false then |
第149行: |
第117行: |
| luaArgs = frame | | luaArgs = frame |
| end | | end |
− | | + | |
| -- Set the order of precedence of the argument tables. If the variables are | | -- 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 | | -- nil, nothing will be added to the table, which is how we avoid clashes |
− | -- between the frame/parent args and the Lua args. | + | -- between the frame/parent args and the Lua args. |
| local argTables = {fargs} | | local argTables = {fargs} |
| argTables[#argTables + 1] = pargs | | argTables[#argTables + 1] = pargs |
第197行: |
第165行: |
| setmetatable(args, metatable) | | setmetatable(args, metatable) |
| | | |
− | local function mergeArgs(tables) | + | local function mergeArgs(iterator, tables) |
| --[[ | | --[[ |
| -- Accepts multiple tables as input and merges their keys and values | | -- Accepts multiple tables as input and merges their keys and values |
− | -- into one table. If a value is already present it is not overwritten; | + | -- into one table using the specified iterator. If a value is already |
− | -- tables listed earlier have precedence. We are also memoizing nil
| + | -- present it is not overwritten; tables listed earlier have precedence. |
− | -- values, which can be overwritten if they are 's' (soft). | + | -- We are also memoizing nil values, but those values can be |
| + | -- overwritten. |
| --]] | | --]] |
| for _, t in ipairs(tables) do | | for _, t in ipairs(tables) do |
− | for key, val in pairs(t) do | + | for key, val in iterator(t) do |
− | if metaArgs[key] == nil and nilArgs[key] ~= 'h' then | + | if metaArgs[key] == nil then |
| local tidiedVal = tidyVal(key, val) | | local tidiedVal = tidyVal(key, val) |
| if tidiedVal == nil then | | if tidiedVal == nil then |
− | nilArgs[key] = 's' | + | nilArgs[key] = true |
| else | | else |
| metaArgs[key] = tidiedVal | | metaArgs[key] = tidiedVal |
第242行: |
第211行: |
| -- must be nil. | | -- must be nil. |
| --]] | | --]] |
− | if type(key) == 'string' then
| |
− | key = options.translate[key]
| |
− | end
| |
| local val = metaArgs[key] | | local val = metaArgs[key] |
| if val ~= nil then | | if val ~= nil then |
第253行: |
第219行: |
| for _, argTable in ipairs(argTables) do | | for _, argTable in ipairs(argTables) do |
| local argTableVal = tidyVal(key, argTable[key]) | | local argTableVal = tidyVal(key, argTable[key]) |
− | if argTableVal ~= nil then | + | if argTableVal == nil then |
| + | nilArgs[key] = true |
| + | else |
| metaArgs[key] = argTableVal | | metaArgs[key] = argTableVal |
| return argTableVal | | return argTableVal |
| end | | end |
| end | | end |
− | nilArgs[key] = 'h'
| |
| return nil | | return nil |
| end | | end |
第265行: |
第232行: |
| -- This function is called when a module tries to add a new value to the | | -- This function is called when a module tries to add a new value to the |
| -- args table, or tries to change an existing value. | | -- args table, or tries to change an existing value. |
− | if type(key) == 'string' then
| |
− | key = options.translate[key]
| |
− | end
| |
| if options.readOnly then | | if options.readOnly then |
| error( | | error( |
第291行: |
第255行: |
| --]] | | --]] |
| metaArgs[key] = nil | | metaArgs[key] = nil |
− | nilArgs[key] = 'h' | + | nilArgs[key] = true |
| else | | else |
| metaArgs[key] = val | | metaArgs[key] = val |
− | end
| |
− | end
| |
− |
| |
− | local function translatenext(invariant)
| |
− | local k, v = next(invariant.t, invariant.k)
| |
− | invariant.k = k
| |
− | if k == nil then
| |
− | return nil
| |
− | elseif type(k) ~= 'string' or not options.backtranslate then
| |
− | return k, v
| |
− | else
| |
− | local backtranslate = options.backtranslate[k]
| |
− | if backtranslate == nil then
| |
− | -- Skip this one. This is a tail call, so this won't cause stack overflow
| |
− | return translatenext(invariant)
| |
− | else
| |
− | return backtranslate, v
| |
− | end
| |
| end | | end |
| end | | end |
第318行: |
第264行: |
| -- Called when pairs is run on the args table. | | -- Called when pairs is run on the args table. |
| if not metatable.donePairs then | | if not metatable.donePairs then |
− | mergeArgs(argTables) | + | mergeArgs(pairs, argTables) |
| metatable.donePairs = true | | metatable.donePairs = true |
| + | metatable.doneIpairs = true |
| end | | end |
− | return translatenext, { t = metaArgs } | + | return pairs(metaArgs) |
| end | | end |
| | | |
− | local function inext(t, i) | + | metatable.__ipairs = function () |
− | -- This uses our __index metamethod | + | -- Called when ipairs is run on the args table. |
− | local v = t[i + 1]
| + | if not metatable.doneIpairs then |
− | if v ~= nil then | + | mergeArgs(ipairs, argTables) |
− | return i + 1, v | + | metatable.doneIpairs = true |
| end | | end |
− | end
| + | return ipairs(metaArgs) |
− | | |
− | metatable.__ipairs = function (t)
| |
− | -- Called when ipairs is run on the args table.
| |
− | return inext, t, 0
| |
| end | | end |
| | | |