Module:Infobox
来自滚动的天空Wiki
local p = {}
local others = require "module:others"
local newindex = others.newindex
local index = others.index
local addNewline = others.addNewLine
function p.process(args)
local data = {}
local function process(k,v)
if type(k) ~= 'string' then return end
-- 以下代码只检查字符串键
if k=="name" then
data[k] = v
end
for _, prefix in ipairs
{'title','label','data','body','header'}
do --对于以上前缀,检查其后缀(可以为空),默认为content
if k:find "%d" then break end -- include no number
local suffix = k:match("^" .. prefix .. "(%l*)$")
if suffix == "" then suffix = "content" end
if suffix then
newindex(data,v,prefix,suffix)
return
end
end
for _, prefix in ipairs {'header','data','label',"row"} do
if not k:find("%d") then break end
--检查带数字键,没有数字直接退出循环
local num, suffix = k:match('^' .. prefix .. '(%d+%.?%d*)(%l*)')
if suffix == ""then
suffix = "content"
end
if suffix then
num = tonumber(num)
newindex(data,v,"rows",num,prefix,suffix)
--这里单独存放在data.rows便于判断是否有任意一行
return
end
end
end
for k,v in pairs(args) do
process(k,v)
end
return data
end
function p.render(data)
local root = mw.html.create()
local content = root:tag "div"
:addClass("infobox")
-- 渲染标题,必须要有内容
if index(data,"title","content") then
content:tag "div":addClass("infobox-title-line"):tag "div"
:addClass "infobox-title"
:wikitext(data.title.content)
:addClass(data.title.class)
:cssText(data.title.style)
end
-- 渲染框
if data.rows then
--检测是否有框的需求
local rows = content:tag "div"
:addClass "infobox-rows"
:addClass(index(data,"body","class"))
:cssText(index(data,"body","style"))
local keys = {} --考虑到断层参数的排序以及小数,先进行人工排序再迭代
for k,v in pairs(data.rows) do
if index(v,'header','content') or index(v,'data','content') then
table.insert(keys,k)
end
end
table.sort(keys)
for i,k in ipairs(keys) do
local v = data.rows[k]
local header = v.header
local label = v.label
local d = v.data
local r = v.row
--渲染行
local row = rows:tag "div"
:addClass "infobox-row"
:addClass(index(r,"class"))
:cssText(index(r,"style"))
:addClass(index(data,"row","class"))
:cssText(index(data,"row","style"))
if index(header,"content") then
--如果有header
row:addClass "infobox-header-row"
:wikitext(header.content)
:cssText(header.style):cssText(index(data,"header","style"))
:addClass(header.class):addClass(index(data,"header","class"))
elseif index(d,"content") then
--如果没有,渲染带data的行
row:addClass "infobox-data-row"
if index(label,"content") then
--如果有标签内容
row:tag("div")
:addClass "infobox-label"
:addClass(label.class):addClass(index(data,"label","class"))
:cssText(label.style):cssText(index(data,"label","style"))
:wikitext(label.content)
end
--渲染data格
local c
if not index(label,"content") then c = "data-without-label" end
row:tag("div")
:addClass("infobox-data")
:addClass(c)
:cssText(d.style):cssText(index(data,"data","style"))
:addClass(d.class):addClass(index(data,"data","class"))
:newline()
:wikitext(d.content)
end
end
end
return tostring(root)
end
function p.infobox(frame)
local args = {}
for k, v in pairs(frame:getParent().args) do
if v and v ~= "" then
args[k] = v
end
end
return p.render(p.process(args))
end
return p