local table = table
local string = string
local ipairs = ipairs
local unpack = unpack
local p = {}
local parentArgs = {}
local processedArgs = {}
-- 从父框架中接收一个或所有以某个前缀开头的前缀
-- @param {string} pref - 参数名的前缀
-- @param {string} desiredIdx - 欲接收参数的序号,`-1`代表接收所有参数
local function getPrefixArgsFromParent(pref, desiredIdx)
desiredIdx = tonumber(desiredIdx) or -1
local prefLen = #pref
local currIdx = 0
for i, arg in ipairs(parentArgs) do
local key, val = unpack(arg)
if string.sub(key, 1, prefLen) == pref then
-- 接收所有参数
if desiredIdx == -1 then
table.insert(processedArgs, string.sub(key, prefLen+1) .. '::' .. val)
-- 只接收特定序号的参数
else
currIdx = currIdx + 1
if currIdx == desiredIdx then
table.insert(processedArgs, string.sub(key, prefLen+1) .. '::' .. val)
return
end
end
end
end
if currIdx < desiredIdx then
mw.log('[Infobox3] 第' .. desiredIdx .. '个' .. pref .. '前缀参数不存在!')
end
end
local function _main(frame, calleeTemplate)
-- 预先将传给父框架的、以 `::` 分割的键值对筛选出来存好
-- 为了保持顺序而借用匿名参数,须注意这绕过了 Scribunto 的设计哲学
for i, arg in ipairs(frame:getParent().args) do
local key, val = string.match(arg, '^%s*(.-)%s*::%s*(.-)%s*$')
if key ~= nil and val ~= '' then
table.insert(parentArgs, {key, val})
end
end
-- 加工传给此模块的参数
for argKey, argVal in pairs(frame.args) do
if type(argKey) ~= 'number' then
processedArgs[argKey] = argVal
end
end
for _, argVal in ipairs(frame.args) do
local prefix = string.sub(argVal, 1, 1)
local key, val = string.match(string.sub(argVal, 2), '^%s*(.-)%s*::%s*(.-)%s*$')
if prefix == '*' then
getPrefixArgsFromParent(key, val)
else
table.insert(processedArgs, argVal)
end
end
-- 将加工后的参数传给 Infobox3 或 Infobox3/legacy
return frame:expandTemplate{
title = calleeTemplate,
args = processedArgs
}
end
function p.main(frame)
return _main(frame, 'Infobox3')
end
function p.legacy(frame)
return _main(frame, 'Infobox3/legacy')
end
return p