9,298 bytes added
, 7 years ago
-- Lua port of [[Template:Infobox]]
-- by DennouNeko
local common = require("Module:Common")
local style = require("Module:Styles")
local colors = style.main_colors
-- == Helper functions ==
-- retrieve param list from arguments
-- builds a table of objects with 'header', 'label', 'data', 'class', 'rclass' fields
local function scan_data_rows(frame, ttype)
local idx = {}
local header = {}
local label = {}
local data = {}
local class = {}
local rclass = {}
local ret = {}
local s,e,t
for k,v in frame:argumentPairs() do
-- accept only parameters without leading zeros
s,e,t = string.find(k, '^header([1-9]%d*)$')
if s ~= nil then
header[tonumber(t)] = v
idx[#idx+1] = tonumber(t)
end
s,e,t = string.find(k, '^label([1-9]%d*)$')
if s ~= nil then
label[tonumber(t)] = v
end
s,e,t = string.find(k, '^data([1-9]%d*)$')
if s ~= nil then
data[tonumber(t)] = v
idx[#idx+1] = tonumber(t)
end
s,e,t = string.find(k, '^class([1-9]%d*)$')
if s ~= nil then
class[tonumber(t)] = v
end
s,e,t = string.find(k, '^rowclass([1-9]%d*)$')
if s ~= nil then
rclass[tonumber(t)] = v
end
end
common.trunkTable(idx)
for k,v in pairs(idx) do
local tmp = {}
tmp['index'] = v
if common.isset(header[v]) then tmp['header'] = header[v] end
if common.isset(label[v]) then tmp['label'] = label[v] end
if common.isset(data[v]) then tmp['data'] = data[v] end
if common.isset(class[v]) then tmp['class'] = class[v] end
if common.isset(rclass[v]) then tmp['rclass'] = rclass[v] end
ret[#ret+1] = tmp
end
return ret
end
-- builds a single header row for table
local function build_header_row(ttype, class, rclass, header, hstyle)
local ret = {''}
if common.isset(header) then
if common.isset(colors[ttype]) then
hstyle = 'background-color:' .. colors[ttype]['title'] .. ';' .. common.cv(common.isset(hstyle), hstyle, '')
end
ret[#ret+1] = '<tr><th colspan="2"'
if common.isset(class) then ret[#ret+1] = ' class="' .. class .. '"' end
ret[#ret+1] = ' style="text-align:center;'
style.add(ret, hstyle)
ret[#ret+1] = '">'
ret[#ret+1] = header
ret[#ret+1] = '</th></tr>'
end
return table.concat(ret)
end
-- builds a single regular row for table
local function build_row(ttype, class, rclass, label, lstyle, data, dstyle)
local ret = {''}
if common.isset(data) then
ret[#ret+1] = '<tr'
if common.isset(rclass) then ret[#ret+1] = ' class="' .. rclass .. '"' end
ret[#ret+1] = '>'
if common.isset(label) then
ret[#ret+1] = '<th scope="row"'
if common.isset(class) then ret[#ret+1] = ' class="' .. class .. '"' end
ret[#ret+1] = ' style="text-align:left;'
style.add(ret, lstyle)
ret[#ret+1] = '">'
ret[#ret+1] = label
ret[#ret+1] = '</th><td'
else
ret[#ret+1] = '<td colspan="2"'
dstyle = 'text-align:center;' .. common.cv(common.isset(dstyle), dstyle, '')
end
if common.isset(class) then ret[#ret+1] = ' class="' .. class .. '"' end
if common.isset(dstyle) then ret[#ret+1] = ' style="' .. dstyle .. '"' end
ret[#ret+1] = '>'
ret[#ret+1] = '\n' .. data
ret[#ret+1] = '\n</td></tr>'
end
return table.concat(ret)
end
-- == Functions generating the table body ==
-- starts the infobox
local function build_start(frame, ttype)
local ret = {}
if frame.args['child'] ~= 'yes' then
-- if it's not a child infobox, start a table
ret[#ret+1] = '<table'
ret[#ret+1] = ' class="infobox'
if common.isset(frame.args['bodyclass']) then ret[#ret+1] = ' ' .. frame.args['bodyclass'] end
ret[#ret+1] = '"'
ret[#ret+1] = ' cellspacing="5"'
ret[#ret+1] = ' style="width:22em; text-align:left; font-size:88%; line-height:1.5em;'
if common.isset(colors[ttype]) then
ret[#ret+1] = 'border-color:' .. colors[ttype]['border'] .. ';'
ret[#ret+1] = 'background-color:' .. colors[ttype]['background'] .. ';'
end
style.add(ret, frame.args['bodystyle'])
ret[#ret+1] = '"'
ret[#ret+1] = '>'
-- Caption
if common.isset(frame.args['title']) then
ret[#ret+1] = '<caption'
if common.isset(frame.args['titleclass']) then ret[#ret+1] = ' class="' .. frame.args['titleclass'] .. '"' end
ret[#ret+1] = ' style="font-size:125%; font-weight:bold;'
style.add(ret, frame.args['titlestyle'])
ret[#ret+1] = '"'
ret[#ret+1] = '>'
ret[#ret+1] = frame.args['title']
ret[#ret+1] = '</caption>'
end
-- Header
if common.isset(frame.args['above']) then
local class = frame.args['aboveclass']
local rclass = frame.args['aboverowclass']
local text = frame.args['above']
local style = 'text-align:center; font-size:125%; font-weight:bold;'
if common.isset(frame.args['abovestyle']) then style = style .. ' ' .. frame.args['abovestyle'] end
ret[#ret+1] = build_header_row(ttype, class, rclass, text, style)
end
else
-- for child infobox add simple header
if common.isset(frame.args['title']) then
ret[#ret+1] = "'''" .. frame.args['title'] .. "'''"
end
end
return table.concat(ret)
end
-- build the header part (subheaders and images)
local function build_headers(frame, ttype)
local ret = {}
-- Subheader1
if common.isset(frame.args['subheader']) or common.isset(frame.args['subheader1']) then
local text = common.cv(common.isset(frame.args['subheader']), frame.args['subheader'], frame.args['subheader1'])
local style = frame.args['subheaderstyle']
local class = frame.args['subheaderclass']
local rclass = common.cv(common.isset(frame.args['subheaderrowclass']), frame.args['subheaderrowclass'], frame.args['subheaderrowclass1'])
ret[#ret+1] = build_row(ttype, class, rclass, '', '', text, style)
end
-- Subheader2
if common.isset(frame.args['subheader2']) then
local text = frame.args['subheader2']
local style = frame.args['subheaderstyle']
local class = frame.args['subheaderclass']
local rclass = frame.args['subheaderrowclass2']
ret[#ret+1] = build_row(ttype, class, rclass, '', '', text, style)
end
-- Image1
if common.isset(frame.args['image']) or common.isset(frame.args['image1']) then
local text = {}
text[#text+1] = common.cv(common.isset(frame.args['image']), frame.args['image'], frame.args['image1'])
if common.isset(frame.args['caption']) or common.isset(frame.args['caption1']) then
text[#text+1] = '<br/><span'
if common.isset(frame.args['captionstyle']) then text[#text+1] = ' style="' .. frame.args['captionstyle'] .. '"' end
text[#text+1] = '>'
text[#text+1] = common.cv(common.isset(frame.args['caption']), frame.args['caption'], frame.args['caption1'])
text[#text+1] = '</span>'
end
text = table.concat(text)
local class = frame.args['imageclass']
local dstyle = frame.args['imagestyle']
local rclass = frame.args['imagerowclass1']
ret[#ret+1] = build_row(ttype, class, rclass, '', '', text, dstyle)
end
-- Image2
if common.isset(frame.args['image2']) then
local text = {}
text[#text+1] = frame.args['image2']
if common.isset(frame.args['caption2']) then
text[#text+1] = '<br/><span'
if common.isset(frame.args['captionstyle']) then text[#text+1] = ' style="' .. frame.args['captionstyle'] .. '"' end
text[#text+1] = '>'
text[#text+1] = frame.args['caption2']
text[#text+1] = '</span>'
end
text = table.concat(text)
local class = frame.args['imageclass']
local dstyle = frame.args['imagestyle']
local rclass = frame.args['imagerowclass2']
ret[#ret+1] = build_row(ttype, class, rclass, '', '', text, dstyle)
end
return table.concat(ret)
end
-- build the main part (all the headers and data rows below images)
local function build_body(frame, ttype, tbl)
local ret = {''}
local hstyle = frame.args['headerstyle']
local lstyle = frame.args['labelstyle']
local dstyle = frame.args['datastyle']
for k,v in pairs(tbl) do
-- not using common.cv, because both functions would be called
if common.isset(v['header']) then
ret[#ret+1] = build_header_row(ttype, v['class'], v['rclass'], v['header'], hstyle)
else
ret[#ret+1] = build_row(ttype, v['class'], v['rclass'], v['label'], lstyle, v['data'], dstyle)
end
end
return table.concat(ret)
end
-- finalize the infobox
local function build_end(frame, ttype)
local ret = {''}
if frame.args['child'] ~= 'yes' then
ret[#ret+1] = '</table>'
end
return table.concat(ret)
end
-- == Exported functions ==
-- the basic infobox
local function build_infobox(frame)
local ret = {}
-- prepare data
local drows = scan_data_rows(frame)
local ttype = frame.args['type']
if ttype == nil then ttype = '' end
-- build infobox
ret[#ret+1] = build_start(frame, ttype)
ret[#ret+1] = build_headers(frame, ttype)
ret[#ret+1] = build_body(frame, ttype, drows)
ret[#ret+1] = build_end(frame, ttype)
return table.concat(ret)
end
return {
['BuildInfobox'] = build_infobox,
['BuildInfoboxTemplate'] = function(frame) return build_infobox(frame:getParent()) end,
}