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