| 第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 |
| | | | |