Jump to content

Module:Bar/sandbox: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
Fixed left/right spacing of caption and footer
Made module Object-Oriented with a bit of Python flavor
Line 1: Line 1:
local getArgs = require('Module:Arguments').getArgs
local getArgs = require('Module:Arguments').getArgs


local p = {}
local BarBox = {
_css = 'Module:Bar box/styles.css',
float = 'none',
backgroundcolor = 'white',
borderwidth = '1',
-- width = 'auto',
barwidth = '100px',
-- lineheight = '1.6',
-- titlebar = 'none'
}


BarBox.__index = BarBox
p.sDefaultAlign = 'lrlr'
BarBox.__tostring = function (self)
p.tDefaultAlign = {false, 'r', false, 'r'}
return self:html()
end

local metatable = {
__call = function (cls, args)
local self = mw.clone(args) or {}
setmetatable(self, cls)
return self
end
}
setmetatable(BarBox, metatable)

function BarBox.create(args)
return BarBox{
css = args.css,
float = args.float and args.float:lower(),
backgroundcolor = args.backgroundcolor,
borderwidth = args.borderwidth,
style = args.style,
width = tonumber(args.width) and args.width .. 'px' or args.width and args.width:lower(),
barwidth = tonumber(args.barwidth) and args.barwidth .. 'px' or args.barwidth and args.barwidth:lower(),
lineheight = args.lineheight,
title = args.title,
titlebar = args.titlebar,
left1 = args.left1,
left2 = args.left2,
right1 = args.right1,
right2 = args.right2,
bars = args.bars,
caption = args.caption, -- deprecated
footer = args.footer or args.caption
}
end

local sDefaultAlign = 'lrlr'
local tDefaultAlign = {false, 'r', false, 'r'}
local alignClasses


function p._setAlign(align)
local function setAlign(align)
p.alignClasses = {}
alignClasses = {}
for i, d in ipairs(p.tDefaultAlign) do
for i, d in ipairs(tDefaultAlign) do
local a = align:sub(i, i)
local a = align:sub(i, i)
if a == 'l' then
if a == 'l' then
Line 17: Line 63:
error('unrecognized align[' .. i .. ']')
error('unrecognized align[' .. i .. ']')
end
end
p.alignClasses[i] = (a and ' class=bb-' .. a or '') .. '|'
alignClasses[i] = (a and ' class=bb-' .. a or '') .. '|'
end
end
end
end


function p._box(args)
function BarBox:html()
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 = {}
local output = {}


local frame = mw.getCurrentFrame()
local frame = mw.getCurrentFrame()
output[1] = frame:extensionTag('templatestyles', '', {src='Module:Bar box/styles.css'}) .. '\n'
output[1] = frame:extensionTag('templatestyles', '', {src=self._css}) .. '\n'
output[2] = args.css and frame:extensionTag('templatestyles', '', {src=args.css}) .. '\n' or ''
output[2] = self.css and frame:extensionTag('templatestyles', '', {src=self.css}) .. '\n' or ''


local class = 'barbox'
local class = 'barbox'
if args.float == 'left' or args.float == 'right' then
if self.float == 'left' or self.float == 'right' then
class = class .. ' t' .. args.float
class = class .. ' t' .. self.float
end

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


output[3] =
output[3] =
'<div class="' .. class .. '" style="background:' .. (args.backgroundcolor or 'white') ..
'<div class="' .. class .. '" style="background:' .. self.backgroundcolor ..
'; border:' .. (args.borderwidth or '1') .. 'px solid silver' ..
'; border:' .. self.borderwidth .. 'px solid silver' ..
(args.float == 'center' and '; margin:0 auto' or '') ..
(self.float == 'center' and '; margin:0 auto' or '') ..
'; width:' .. _width(args.width, 'auto') ..
(self.width and '; width:' .. self.width or '') ..
(args.style and '; ' .. args.style or '') .. '">\n' ..
(self.style and '; ' .. self.style or '') .. '">\n' ..
'{|' .. (args.lineheight and ' style="line-height:' .. args.lineheight .. '"' or '') .. '\n'
'{|' .. (self.lineheight and ' style="line-height:' .. self.lineheight .. '"' or '') .. '\n'


output[4] = args.title and
output[4] = self.title and
'|+ class=bb-default' .. (args.titlebar and ' style="background:' .. args.titlebar .. '"' or '') .. ' |\n' .. args.title .. '\n'
'|+ class=bb-default' .. (self.titlebar and ' style="background:' .. self.titlebar .. '"' or '') .. ' |\n' .. self.title .. '\n'
or ''
or ''


output[5] = '|- class=bb-default style="font-size:88%; min-height:4px"\n'
output[5] = '|- class=bb-default style="font-size:88%; min-height:4px"\n'
if not p.alignClasses then
if not alignClasses then
p._setAlign(p.sDefaultAlign)
setAlign(sDefaultAlign)
end
end
output[6] = '!' .. (args.left2 and '' or 'colspan=2') .. p.alignClasses[1] .. (args.left1 or ' ')
output[6] = '!' .. (self.left2 and '' or 'colspan=2') .. alignClasses[1] .. (self.left1 or ' ')
output[7] = args.left2 and '!!' .. p.alignClasses[2] .. args.left2 or ''
output[7] = self.left2 and '!!' .. alignClasses[2] .. self.left2 or ''
output[8] = '!!style="width:' .. _width(args.barwidth, '100px') .. '"| '
output[8] = '!!style="width:' .. self.barwidth .. '"| '
output[9] = '!!' .. (args.right2 and p.alignClasses[3] or 'colspan=2' .. p.alignClasses[4]) .. (args.right1 or ' ')
output[9] = '!!' .. (self.right2 and alignClasses[3] or 'colspan=2' .. alignClasses[4]) .. (self.right1 or ' ')
output[10] = args.right2 and '!!' .. p.alignClasses[4] .. args.right2 or ''
output[10] = self.right2 and '!!' .. alignClasses[4] .. self.right2 or ''
alignClasses = nil
output[11] = '\n'
output[11] = '\n'


output[12] = args.bars and args.bars .. '\n' or ''
output[12] = self.bars and self.bars .. '\n' or ''


if args.caption then
if self.caption then
output[15] = '\n[[Category:Pages using bar box with deprecated caption parameter]]'
output[15] = '\n[[Category:Pages using bar box with deprecated caption parameter]]'
args.footer = args.caption
else
else
output[15] = ''
output[15] = ''
end
end
output[13] = args.footer and
output[13] = self.footer and
'|- class=bb-default\n| colspan=5 style="padding:5px 0" | ' .. args.footer .. '\n' -- <p> created with \n before the footer
'|- class=bb-default\n| colspan=5 style="padding:5px 0" | ' .. self.footer .. '\n' -- <p> is created if \n precedes the footer
or ''
or ''
output[14] = '|}\n</div>\n'
output[14] = '|}\n</div>\n'
Line 84: Line 118:
end
end


function p._percent(args)
function BarBox._percent(args)
local output = {}
local output = {}
local percentage = (args[3] or '0') .. '%'
local percentage = (args[3] or '0') .. '%'
Line 98: Line 132:
end
end


function p._pixel(args)
function BarBox._pixel(args)
local output = {}
local output = {}
local pixels = args[3] or '0'
local pixels = args[3] or '0'
Line 112: Line 146:
end
end


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

local output = {}
local output = {}


Line 120: Line 152:
'|-class="mw-collapsible' .. (args.collapsed and ' mw-collapsed' or '') .. '" id=mw-customcollapsible-' .. args.id .. '\n'
'|-class="mw-collapsible' .. (args.collapsed and ' mw-collapsed' or '') .. '" id=mw-customcollapsible-' .. args.id .. '\n'
or '|-\n'
or '|-\n'
if not p.alignClasses then
if not alignClasses then
p._setAlign(args.align or p.sDefaultAlign)
setAlign(args.align and args.align:lower() or sDefaultAlign)
end
end
output[2] = '|' .. (args.note1 and '' or 'colspan=2') .. p.alignClasses[1] .. (args[1] or ' ')
output[2] = '|' .. (args.note1 and '' or 'colspan=2') .. alignClasses[1] .. (args[1] or ' ')
output[3] = args.note1 and '||' .. p.alignClasses[2] .. args.note1 or ''
output[3] = args.note1 and '||' .. alignClasses[2] .. args.note1 or ''
output[4] = '||class=bb-b|'
output[4] = '||class=bb-b|'


Line 133: Line 165:
end
end


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


output[#output+1] = '||' .. (args.note2 and p.alignClasses[3] or 'colspan=2' .. p.alignClasses[4]) .. (args[2] or ' ')
output[#output+1] = '||' .. (args.note2 and alignClasses[3] or 'colspan=2' .. alignClasses[4]) .. (args[2] or ' ')
output[#output+1] = args.note2 and '||' .. p.alignClasses[4] .. args.note2 or ''
output[#output+1] = args.note2 and '||' .. alignClasses[4] .. args.note2 or ''


return table.concat(output)
return table.concat(output)
end
end


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


output[1] = '|-\n'
output[1] = '|-\n'
Line 163: Line 194:
end
end


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


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


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


function p.stacked(frame)
function BarBox.stacked(frame)
local yesno = require('Module:Yesno')
local yesno = require('Module:Yesno')
local args = getArgs(frame, {
local args = getArgs(frame, {
Line 194: Line 226:
end
end
})
})
return p._stacked(args)
return BarBox._stacked(args)
end
end


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


return p
return BarBox

Revision as of 00:16, 2 March 2021

local getArgs = require('Module:Arguments').getArgs

local BarBox = {
	_css			= 'Module:Bar box/styles.css',
	float			= 'none',
	backgroundcolor	= 'white',
	borderwidth		= '1',
--	width			= 'auto',
	barwidth		= '100px',
--	lineheight		= '1.6',
--	titlebar		= 'none'
}

BarBox.__index = BarBox
BarBox.__tostring = function (self)
	return self:html()
end

local metatable = {
	__call = function (cls, args)
		local self = mw.clone(args) or {}
		setmetatable(self, cls)
		return self
	end
}
setmetatable(BarBox, metatable)

function BarBox.create(args)
	return BarBox{
		css				= args.css,
		float			= args.float and args.float:lower(),
		backgroundcolor	= args.backgroundcolor,
		borderwidth		= args.borderwidth,
		style			= args.style,
		width			= tonumber(args.width) and args.width .. 'px' or args.width and args.width:lower(),
		barwidth		= tonumber(args.barwidth) and args.barwidth .. 'px' or args.barwidth and args.barwidth:lower(),
		lineheight		= args.lineheight,
		title			= args.title,
		titlebar		= args.titlebar,
		left1			= args.left1,
		left2			= args.left2,
		right1			= args.right1,
		right2			= args.right2,
		bars			= args.bars,
		caption			= args.caption, -- deprecated
		footer			= args.footer or args.caption
	}
end

local sDefaultAlign = 'lrlr'
local tDefaultAlign = {false, 'r', false, 'r'}
local alignClasses

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

function BarBox:html()
	local output = {}

	local frame = mw.getCurrentFrame()
	output[1] = frame:extensionTag('templatestyles', '', {src=self._css}) .. '\n'
	output[2] = self.css and frame:extensionTag('templatestyles', '', {src=self.css}) .. '\n' or ''

	local class = 'barbox'
	if self.float == 'left' or self.float == 'right' then
		class = class .. ' t' .. self.float
	end

	output[3] =
		'<div class="' .. class .. '" style="background:' .. self.backgroundcolor ..
		'; border:' .. self.borderwidth .. 'px solid silver' ..
		(self.float == 'center' and '; margin:0 auto' or '') ..
		(self.width and '; width:' .. self.width or '') ..
		(self.style and '; ' .. self.style or '') .. '">\n' ..
			'{|' .. (self.lineheight and ' style="line-height:' .. self.lineheight .. '"' or '') .. '\n'

		output[4] = self.title and
			'|+ class=bb-default' .. (self.titlebar and ' style="background:' .. self.titlebar .. '"' or '') .. ' |\n' .. self.title .. '\n'
		or ''

		output[5] = '|- class=bb-default style="font-size:88%; min-height:4px"\n'
			if not alignClasses then
				setAlign(sDefaultAlign)
			end
			output[6] = '!' .. (self.left2 and '' or 'colspan=2') .. alignClasses[1] .. (self.left1 or ' ')
			output[7] = self.left2 and '!!' .. alignClasses[2] .. self.left2 or ''
			output[8] = '!!style="width:' .. self.barwidth .. '"| '
			output[9] = '!!' .. (self.right2 and alignClasses[3] or 'colspan=2' .. alignClasses[4]) .. (self.right1 or ' ')
			output[10] = self.right2 and '!!' .. alignClasses[4] .. self.right2 or ''
			alignClasses = nil
		output[11] = '\n'

		output[12] = self.bars and self.bars .. '\n' or ''

		if self.caption then
			output[15] = '\n[[Category:Pages using bar box with deprecated caption parameter]]'
		else
			output[15] = ''
		end
		output[13] = self.footer and
			'|- class=bb-default\n| colspan=5 style="padding:5px 0" | ' .. self.footer .. '\n' -- <p> is created if \n precedes the footer
		or ''
	output[14] = '|}\n</div>\n'

	return table.concat(output)
end

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

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

	return table.concat(output)
end

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

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

	return table.concat(output)
end

function BarBox._stacked(args)
	local output = {}

	output[1] = args.id and
		'|-class="mw-collapsible' .. (args.collapsed and ' mw-collapsed' or '') .. '" id=mw-customcollapsible-' .. args.id .. '\n'
	or '|-\n'
		if not alignClasses then
			setAlign(args.align and args.align:lower() or sDefaultAlign)
		end
		output[2] = '|' .. (args.note1 and '' or 'colspan=2') .. alignClasses[1] .. (args[1] or ' ')
		output[3] = args.note1 and '||' .. alignClasses[2] .. args.note1 or ''
		output[4] = '||class=bb-b|'

			local len = 4 -- can't use #args because of [[Module:Arguments#Known limitations]]
			for k in pairs(args) do
				local idx = tonumber(k) or 0
				if idx > len then len = idx end
			end

			for i = 1, (len-2) / 2 do
				local width, title, background
				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 .. ' style="background:' .. background .. '; width:' .. width .. 'px">&#8203;</div>'
				end
			end

		output[#output+1] = '||' .. (args.note2 and alignClasses[3] or 'colspan=2' .. alignClasses[4]) .. (args[2] or ' ')
		output[#output+1] = args.note2 and '||' .. alignClasses[4] .. args.note2 or ''

	return table.concat(output)
end

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

	output[1] = '|-\n'
		output[2] = '|colspan=5 style="height:' .. height .. '"|' .. (args[1] or '')

	return table.concat(output)
end

function BarBox.box(frame)
	local args = getArgs(frame)
	local box = BarBox.create(args)
	return tostring(box)
end

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

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

function BarBox.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 BarBox._stacked(args)
end

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

return BarBox