模組:TemplateVariadicArgumentSingle
外观
local p = {}
local lib_arg = {}
local function checkParaExist(obj, para_list)
local result = false
for _, target_par_name in ipairs(para_list) do
result = result or (type(obj[target_par_name]) ~= type(nil))
end
return result
end
function p.build_template(frame)
local args, working_frame
local inner_args
if frame == mw.getCurrentFrame() then
-- We're being called via #invoke. The args are passed through to the module
-- from the template page, so use the args that were passed into the template.
if lib_arg.getArgs == nil then lib_arg = require('Module:Arguments') end
args = lib_arg.getArgs(frame, {parentFirst=true})
inner_args = frame.args
working_frame = frame
else
-- We're being called from another module or from the debug console, so assume
-- the args are passed in directly.
args = frame
working_frame = mw.getCurrentFrame()
if type(args) ~= type({}) then args = {frame} end
inner_args = args
end
--預設值暫且設定為 Template:US_county_navigation_box
local core_template_name = inner_args._core_template or "Template:US_county_navigation_box/core"
local core_insert_point = inner_args._core_insert_point or "__LUA_INSERT_CORE__"
local parent_start = tonumber(inner_args._parent_start or "1") or 1
local core_insert_code = inner_args._core_insert_code or "\n\n" ..
"|group$ = {{{title$|}}}\n".. --Template:US_county_navigation_box的不定參數語法
"|list$ = {{#if:{{{body$|}}}|<div>\n"..
"{{{body$}}}\n"..
"</div>}}"
core_insert_code = mw.text.decode(mw.text.unstripNoWiki(core_insert_code))
local core_args = mw.text.split(inner_args._core_args or "body,title",",") or {"arg"}
local ki = 1
for key, value in ipairs(core_args) do
local trimed_value = mw.text.trim(value)
if trimed_value ~= '' then
core_args[ki] = mw.ustring.lower(trimed_value)
ki = ki + 1
end
end
local template_obj = mw.title.new( core_template_name ) --載入模板樣板
if not template_obj then return '' end --如模板樣板載入失敗,返回空
local template_body = template_obj:getContent() --讀取模板樣板
if mw.text.trim(template_body or '') == '' then return '' end --如果讀取不到模板樣板,返回空
--摘除模板樣板中的noinclude
local noinclude = mw.ustring.find(template_body,"<%s*[Nn][Oo][Ii][Nn][Cc][Ll][Uu][Dd][Ee]%s*>")
while noinclude do --如果找到<noinclude>
--尋找</noinclude>
local _, noinclude_end = mw.ustring.find(template_body,"<%s*/%s*[Nn][Oo][Ii][Nn][Cc][Ll][Uu][Dd][Ee]%s*>")
--如無</noinclude>,視為noinclude到頁面結尾
noinclude_end = noinclude_end or -1
--去除掉<noinclude>...</noinclude>與其之間的內容
template_body = mw.ustring.sub(template_body, 1, noinclude-1) .. ((noinclude_end < 0) and '' or mw.ustring.sub(template_body, noinclude_end + 1, -1))
--尋找下一個<noinclude>
noinclude = mw.ustring.find(template_body,"<%s*[Nn][Oo][Ii][Nn][Cc][Ll][Uu][Dd][Ee]%s*>")
end
template_body = mw.ustring.gsub(template_body, "<%s*/?%s*[Nn][Oo][Ii][Nn][Cc][Ll][Uu][Dd][Ee]%s*/?%s*>", "")
template_body = mw.ustring.gsub(template_body, "<%s*/?%s*[Ii][Nn][Cc][Ll][Uu][Dd][Ee][Oo][Nn][Ll][Yy]%s*/?%s*>", "")
template_body = mw.ustring.gsub(template_body, "<%s*/?%s*[Oo][Nn][Ll][Yy][Ii][Nn][Cc][Ll][Uu][Dd][Ee]%s*/?%s*>", "")
local row_list = {} --用於儲存有多少組不定參數
local max_id = -1 --紀錄輸入參數中,最大的那一個
local min_id = tonumber("inf") --紀錄輸入參數中,最小的那一個
for key, value in pairs(args) do --查閱所有已輸入參數
local par_name_id, _ = mw.ustring.find(key,"%d+$") --參數字尾是否存在數字
local par_name = par_name_id and mw.ustring.sub(key, 1, par_name_id - 1) or nil --取得參數名稱
local par_id = par_name_id and mw.ustring.sub(key, par_name_id, -1) or nil --取得參數數字
local par_num = tonumber(par_id) --將參數數字轉換成數字
if par_name and par_id then --如果參數名稱和參數數字都存在,才嘗試匹配參數
local par_name_check = mw.ustring.lower(par_name) --統一以小寫匹配
local loaded_value = false --等一下檢查有無讀到有效的body或title參數
for __, target_par_name in ipairs(core_args) do
if par_name_check == target_par_name then --匹配到參數
loaded_value = true --有效的參數
--new row
if type(row_list[par_num]) == type(nil) then row_list[par_num] = {}end
row_list[par_num][target_par_name] = value --存入參數
end
end
if loaded_value then
if par_num > max_id then max_id = par_num end --如果是有效的參數組,嘗試紀錄參數值的最大值
if par_num < min_id then min_id = par_num end --如果是有效的參數組,嘗試紀錄參數值的最小值
end
end
end
if tostring(min_id) == "inf" then min_id = 1 end
local body = '' --準備生成不定參數語法
local j = parent_start
for i = min_id, max_id do --將所有不定參數組跑一遍
local para_obj = row_list[i]
if para_obj then --如果是有效的不定參數組
if checkParaExist(para_obj, core_args) then --如果該不定參數組有輸入其一參數
local body_unit = mw.ustring.sub(mw.ustring.gsub(' '..core_insert_code..' ', "([%$@])(.)", function(sym,txt)
if sym == "@" then
if txt ~= '@' then return j .. txt --生成這組參數的對應語法
elseif txt == '@' then return "@"
else return "@" .. txt end
elseif sym == "$" then
if txt ~= '$' then return i .. txt --生成這組參數的對應語法
elseif txt == '$' then return "$"
else return "$" .. txt end
else
return sym..txt
end
end),2,-2)
body = body .. body_unit
end
j = j + 1
end
end --不定參數語法生成完畢。
--尋找模板樣板中的不定參數組的插入點,並插入不定參數語法
template_body = mw.ustring.gsub(template_body, core_insert_point, body)
--解析要使用外層解析器 (才讀得到那些不定參數,內層是{{#invoke:}})
working_frame = working_frame:getParent() or working_frame
--將包含了不定參數的模板展開
template_body = working_frame:preprocess(template_body)
return template_body --回傳展開了不定參數的模板結果
end
return p