Jump to content

Module:Bar/sandbox

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Alexiscoutinho (talk | contribs) at 01:17, 18 February 2021 (Optimized align handling. Divided table into caption, thead, tbody and tfoot. Substituted rowstyle with bodystyle. Rewrote classes to minimize wikitext (expanded template) length. Cleaned up code.). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
local getArgs = require('Module:Arguments').getArgs

local p = {}

p.sDefaultAlign = 'lrlr'
p.tDefaultAlign = {nil, 'r', nil, 'r'}

function p._setAlign(align)
	p.alignClasses = {}
	for i, d in ipairs(p.tDefaultAlign) do
		local a = align:sub(i, i)
		if a == 'l' then
			a = nil
		elseif a == 'd' then
			a = d
		elseif a ~= 'c' and a ~= 'r' then
			error('unrecognized align[' .. i .. ']')
		end
		p.alignClasses[i] = (a and ' class=bb-' .. a or '') .. '>'
	end
end

function p._box(args)
	for key, value in pairs(args) do
		if ({float=1, width=1, barwidth=1})[key] then -- if key in {...}
			args[key] = value:lower()
		end
	end

	local output = {}

	output[1] = '<templatestyles src="Module:Bar box/styles.css" />\n'
	output[2] = args.css and '<templatestyles src="' .. args.css .. '" />\n' or ''

	local function _width(width, default)
		local w = width or default
		if tonumber(w) then w = w .. 'px' end
		return w
	end
	local width = _width(args.width, 'auto')

	if args.float == 'left' or args.float == 'right' then
		output[3], output[16] = '', ''
	else
		output[3] =
			'<table style="border:none; margin:' .. (args.float == 'center' and '0 auto' or '0') .. '">\n' ..
				'<tr>\n' ..
					'<td style="border:none; padding:0">\n'
		output[16] =
					'</td>\n' ..
				'</tr>\n' ..
			'</table>\n' ..
			'\n[[Category:Pages using bar box without float left or float right|' .. (width == 'auto' and 'Ω' or '') ..
			mw.title.getCurrentTitle().text .. ']]'
	end

	local class = 'barbox'
	if ({left=1, right=1, none=1})[args.float] then
		class = class .. ' t' .. args.float
	elseif args.float == 'center' then
		class = class .. ' tnone'
	end

	output[4] =
		'<div class="' .. class .. '" style="overflow-x:auto' .. (args.style and '; ' .. args.style or '') .. '">\n' ..
			'<div style="background:' .. (args.backgroundcolor or 'white') ..
			'; border:' .. (args.borderwidth or '1') .. 'px solid silver' ..
			'; font-size:88%' ..
			'; padding:0.4em' ..
			'; width:' .. width .. '">\n' ..
				'<table style="border-collapse:collapse; width:100%">\n'

		output[5] = args.title and
			'<caption style="background:' .. (args.titlebar or 'none') .. '; padding:5px">\n' .. args.title .. '\n</caption>\n'
		or ''

		output[6] = '<thead style="font-size:88%">\n<tr>'
			if not p.alignClasses then
				p._setAlign(p.sDefaultAlign)
			end
			output[7] = '<td' .. (args.left2 and '' or ' colspan=2') .. p.alignClasses[1] .. (args.left1 or '') .. '</td>'
			output[8] = args.left2 and '<td' .. p.alignClasses[2] .. args.left2 .. '</td>' or ''
			output[9] = '<td style="width:' .. _width(args.barwidth, '100px') .. '"></td>'
			output[10] = '<td' .. (args.right2 and p.alignClasses[3] or ' colspan=2' .. p.alignClasses[4]) .. (args.right1 or '') .. '</td>'
			output[11] = args.right2 and '<td' .. p.alignClasses[4] .. args.right2 .. '</td>' or ''
		output[12] = '</tr>\n</thead>\n'

		output[13] =
			'<tbody' .. (args.bodystyle and ' style="' .. args.bodystyle .. '"' or '') .. '>\n' .. (args.bars or '') .. '\n</tbody>\n'

		if args.caption then
			output[17] = '\n[[Category:Pages using bar box with deprecated caption parameter]]'
			args.footer = args.caption
		else
			output[17] = ''
		end
		output[14] = args.footer and
			'<tfoot>\n<tr>\n<td colspan=5 style="padding:5px">\n' .. args.footer .. '\n</td>\n</tr>\n</tfoot>\n'
		or ''
	output[15] = '</table>\n</div>\n</div>\n'
	-- output[16] defined above

	return table.concat(output)
end

function p._percent(args)
	local output = {}
	local percentage = (args[3] or '0') .. '%'

	output[1] = '<tr' .. (args.bg and ' style="background:' .. args.bg .. '"' or '') .. '>'
		output[2] = '<td colspan=2 class=bb-min8>' .. (args[1] or '') .. '</td>'
		output[3] = '<td class=bb-b><div>'
			output[4] = '<div style="background:' .. (args[2] or 'gray') .. '; overflow:hidden; width:' .. percentage .. '">&#8203;</div>'
		output[5] = '</div></td>'
		output[6] = '<td' .. (args.note and '' or ' colspan=2 class=bb-r') .. '>' .. (args[4] or percentage) .. '</td>'
		output[7] = args.note and '<td class=bb-r>' .. args.note .. '</td>' or ''
	output[8] = '</tr>'

	return table.concat(output)
end

function p._pixel(args)
	local output = {}
	local pixels = args[3] or '0'

	output[1] = '<tr' .. (args.bg and ' style="background:' .. args.bg .. '"' or '') .. '>'
		output[2] = '<td colspan=2>' .. (args[1] or '') .. '</td>'
		output[3] = '<td class=bb-b><div>'
			output[4] = '<div style="background:' .. (args[2] or 'gray') .. '; overflow:hidden; width:' .. pixels .. 'px">&#8203;</div>'
		output[5] = '</div></td>'
		output[6] = '<td class="bb-min3' .. (args.note and '"' or ' bb-r" colspan=2') .. '>' .. (args[5] or pixels .. (args[4] or '')) .. '</td>'
		output[7] = args.note and '<td class=bb-r>' .. args.note .. '</td>' or ''
	output[8] = '</tr>'

	return table.concat(output)
end

function p._stacked(args)
	if args.align then args.align:lower() end

	local output = {}

	output[1] = args.id and
		'<tr class="mw-collapsible' .. (args.collapsed and ' mw-collapsed' or '') .. '" id=mw-customcollapsible-' .. args.id .. '>'
	or '<tr>'
		if not p.alignClasses then
			p._setAlign(args.align or p.sDefaultAlign)
		end
		output[2] = '<td' .. (args.note1 and '' or ' colspan=2') .. p.alignClasses[1] .. (args[1] or '') .. '</td>'
		output[3] = args.note1 and '<td' .. p.alignClasses[2] .. args.note1 .. '</td>' or ''
		output[4] = '<td class=bb-b><div>'

			local width, title, background
			for i = 1, (#args-2) / 2 do
				width = args[2*i + 2] or 0
				width = tonumber(('%.2f'):format(width))
				if width == 0 then
					output[i+4] = ''
				else
					title = args['title' .. i] and ' title="' .. args['title' .. i] .. '"' or ''
					background = args[2*i + 1] or 'gray'
					output[i+4] =
						'<div' .. title .. ' class=bb-l style="background:' .. background .. '; width:' .. width .. 'px">&#8203;</div>'
				end
			end

		output[#output+1] = '</div></td>'
		output[#output+1] = '<td' .. (args.note2 and p.alignClasses[3] or ' colspan=2' .. p.alignClasses[4]) .. (args[2] or '') .. '</td>'
		output[#output+1] = args.note2 and '<td' .. p.alignClasses[4] .. args.note2 .. '</td>' or ''
	output[#output+1] = '</tr>'

	return table.concat(output)
end

function p._gap(args)
	local output = {}
	local height = tonumber(args.height) and args.height .. 'px' or args.height or '10px'

	output[1] = '<tr>'
		output[2] = '<td colspan=5 style="height:' .. height .. '">' .. (args[1] or '') .. '</td>'
	output[3] = '</tr>'

	return table.concat(output)
end

function p.box(frame)
	local args = getArgs(frame)
	return p._box(args)
end

function p.percent(frame)
	local args = getArgs(frame)
	return p._percent(args)
end

function p.pixel(frame)
	local args = getArgs(frame)
	return p._pixel(args)
end

function p.stacked(frame)
	local yesno = require('Module:Yesno')
	local args = getArgs(frame, {
		valueFunc = function (key, value)
			if value then
				if key == 'collapsed' then
					return yesno(value)
				end
				value = mw.text.trim(value)
				if value ~= '' then
					return value
				end
			end
			return nil
		end
	})
	return p._stacked(args)
end

function p.gap(frame)
	local args = getArgs(frame)
	return p._gap(args)
end

return p