If you plan to make a YouTube video or other content using bootlegs downloaded from our site, although we can't and won't force you to do anything, we greatly appreciate attribution for the large amounts of time and effort we spend finding these bootlegs. Thank you!

Happy Pride Month, everyone!

Module:Infobox

Revision as of 02:52, 31 March 2023 by CHOCOLATEMAN (talk | contribs) (1 revision imported: FUCK MEDIAWIKI!!!!!!)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Documentation for this module may be created at Module:Infobox/doc

-- 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(args, prefix)
	local ret = { }
	for k in pairs(args) do
		local num = string.match(k, "^" .. prefix .. "(%d*)$")
		if num then
			table.insert(ret, tonumber(num))
		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(args, '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(args, 'image'), getArgNums(args, '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(args, 'header'), getArgNums(args, 'data'))
	table.sort(nums)
	
	local lastHeader
	
	for _, v in pairs(nums) do
		if args['header' .. v] then
			if lastHeader then
				args['header' .. lastHeader] = nil
			end
			lastHeader = v
		else
			lastHeader = nil
		end
	end

	if lastHeader then
		args['header' .. lastHeader] = nil
	end
end

function Infobox:setRows()
	local args = self.args
	
	local nums = { }
	nums = union(nums, getArgNums(args, 'header'))
	nums = union(nums, getArgNums(args, 'label'))
	nums = union(nums, getArgNums(args, '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
			if v.header ~= '_BLANK_' then 
				local header = root:tag('tr'):tag('th')
				header:attr('colspan', 2)
				header:addClass('ib-header')
				header:wikitext(v.header)
			end
		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

return p