Module:Infobox

-- Load necessary modules. require('Module:No globals') local getArgs local yesno = require('Module:Yesno')

local p = { }

-- Helper functions

local function union(t1, t2) local temp = {} for _, v in pairs(t1) do		temp[v] = true end for _, v in pairs(t2) do		temp[v] = true end local ret = {} for k in pairs(temp) do		table.insert(ret, k)	end table.sort(ret) return ret end

local function getArgNums(prefix) local ret = { } for k in pairs(mw.getCurrentFrame:getParent.args) do if string.match(k, "^" .. prefix .. "[0-9]%d*$") then table.insert(ret, tonumber(string.sub(k, string.len(prefix) + 1))) end end table.sort(ret) return ret end

-- Box class definition

local Infobox = {} Infobox.__index = Infobox

function Infobox.new(args) args = args or {} local obj = {}

-- Set the arguments obj.args = args mw.logObject(obj)

return setmetatable(obj, Infobox) end

function Infobox:setParameters local args = self.args self.title = args.title self.above = args.above self.autoheaders = yesno(args.autoheaders) if self.autoheaders then self:removeLoneHeaders end self.subheaders = self:setSubheaders self.images = self:setImages self.rows = self:setRows self.below = args.below end

function Infobox:setSubheaders local args = self.args local nums = getArgNums('subheader') local t = { } if args.subheader then table.insert(t, args.subheader) end for _,v in pairs(nums) do table.insert(t, args['subheader' .. v]) end return t end

function Infobox:setImages local args = self.args local nums = union(getArgNums('image'), getArgNums('caption')) local t = { } if args.image or args.caption then table.insert(t, 			{				image = args.image,				caption = args.caption			}) end for _,v in pairs(nums) do		table.insert(t, 			{				image = args['image' .. v], 				caption = args['caption' .. v]			}) end return t end

function Infobox:removeLoneHeaders local args = self.args local nums = union(getArgNums('header'), getArgNums('data')) table.sort(nums) local lastHeader for _, v in nums do if args['header' .. v] then if lastHeader then args['header' .. lastHeader] = nil end lastHeader = v		else lastHeader = nil end end end

function Infobox:setRows local args = self.args local nums = { } nums = union(nums, getArgNums('header')) nums = union(nums, getArgNums('label')) nums = union(nums, getArgNums('data')) local t = { } for _,v in pairs(nums) do		table.insert(t, 			{				header = args['header' .. v],				label = args['label' .. v],				data = args['data' .. v]			}) end return t end

function Infobox:export local root = mw.html.create:tag('table') root:addClass('infobox') if self.title then local title = root:tag('caption') title :addClass('ib-title') :wikitext(self.title) end if self.above then local above = root:tag('tr'):tag('td') above :attr('colspan', 2) :addClass('ib-above') :wikitext(self.above) end for _,v in ipairs(self.subheaders) do		local subheader = root:tag('tr'):tag('td') subheader :attr('colspan', 2) :addClass('ib-subheader') :wikitext(v) end for _,v in ipairs(self.images) do		if v.image then local cell = root:tag('tr'):tag('td') :attr('colspan', 2) :addClass('ib-image') :wikitext(v.image) if v.caption then cell :tag('div') :addClass('ib-image-caption') :wikitext(v.caption) end end end for _,v in ipairs(self.rows) do		if v.header then local header = root:tag('tr'):tag('th') header:attr('colspan', 2) header:addClass('ib-header') header:wikitext(v.header) else if v.label and v.data then local row = root:tag('tr') local label = row:tag('th') label:addClass('ib-label') label:wikitext(v.label) local data = row:tag('td') data:addClass('ib-data') data:wikitext(v.data) end if v.data and not v.label then local data = root:tag('tr'):tag('td') data:attr('colspan', 2) data:addClass('ib-data') data:wikitext(v.data) end end end if self.below then local below = root:tag('tr'):tag('td') below :attr('colspan', 2) :addClass('ib-below') :wikitext(self.below) end local templateStyle = mw.getCurrentFrame:extensionTag( 'templatestyles', '', { src = 'Template:Infobox/styles.css' } );

return templateStyle .. tostring(root) end

-- Exports

function p.infobox(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local box = Infobox.new(getArgs(frame)) box:setParameters return box:export end

if mw.site.siteName:byte == 66 then return p end