Jump to content

Module:Bar/sandbox: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
Fixed subclass constructor
Upgraded module to the new Lua class framework
Line 1: Line 1:
local getArgs = require('Module:Arguments').getArgs
require('Module:Lua class')


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


local function __call(cls, args)
__init = function (self, args)
self.css = args.css
local self = mw.clone(args) or {}
self.float = args.float or 'none'
cls.__call = __call
self.backgroundcolor = args.backgroundcolor or 'white'
cls.__index = cls
self.borderwidth = args.borderwidth or '1'
setmetatable(self, cls)
self.style = args.style
return self
self.width = args.width-- or 'auto'
end
self.barwidth = args.barwidth or '100px'
setmetatable(BarBox, {__call=__call})
self.lineheight = args.lineheight-- or '1.6'
self.title = args.title
self.titlebar = args.titlebar-- or 'none'
self.left1 = args.left1
self.left2 = args.left2
self.right1 = args.right1
self.right2 = args.right2
self.bars = args.bars
self.caption = args.caption -- deprecated
self.footer = args.footer or args.caption
end,


function BarBox.create(args)
create = function (cls, args)
args = mw.clone(args)
return BarBox{
args.float = args.float and args.float:lower()
css = args.css,
float = args.float and args.float:lower(),
args.width = tonumber(args.width) and args.width .. 'px' or args.width and args.width:lower()
args.barwidth = tonumber(args.barwidth) and args.barwidth .. 'px' or args.barwidth and args.barwidth:lower()
backgroundcolor = args.backgroundcolor,
return cls(args)
borderwidth = args.borderwidth,
end,
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'
_sDefaultAlign = 'lrlr',
local tDefaultAlign = {false, 'r', false, 'r'}
_tDefaultAlign = {false, 'r', false, 'r'},
local alignClasses


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


function BarBox:html()
html = function (self)
local output = {}
local output = {}


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


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


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


output[4] = self.title and
output[4] = self.title and
'|+ class=bb-default' .. (self.titlebar and ' style="background:' .. self.titlebar .. '"' or '') .. ' |\n' .. self.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 self._alignClasses then -- same as self.__class._alignClasses
if not alignClasses then
self._alignClasses = self._alignClasses
setAlign(sDefaultAlign)
self.__class._alignClasses = nil
end
else
output[6] = '!' .. (self.left2 and '' or 'colspan=2') .. alignClasses[1] .. (self.left1 or ' ')
self._setAlign(self, self._sDefaultAlign)
output[7] = self.left2 and '!!' .. alignClasses[2] .. self.left2 or ''
end
output[8] = '!!style="width:' .. self.barwidth .. '"| '
output[9] = '!!' .. (self.right2 and alignClasses[3] or 'colspan=2' .. alignClasses[4]) .. (self.right1 or ' ')
output[6] = '!' .. (self.left2 and '' or 'colspan=2') .. self._alignClasses[1] .. (self.left1 or ' ')
output[10] = self.right2 and '!!' .. alignClasses[4] .. self.right2 or ''
output[7] = self.left2 and '!!' .. self._alignClasses[2] .. self.left2 or ''
output[8] = '!!style="width:' .. self.barwidth .. '"| '
alignClasses = nil
output[9] = '!!' .. (self.right2 and self._alignClasses[3] or 'colspan=2' .. self._alignClasses[4]) .. (self.right1 or ' ')
output[11] = '\n'
output[10] = self.right2 and '!!' .. self._alignClasses[4] .. self.right2 or ''
output[11] = '\n'


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


if self.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]]'
else
else
output[15] = ''
output[15] = ''
end
end
output[13] = self.footer and
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
'|- 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'


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


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


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


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


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


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


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


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


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


output[1] = args.id and
output[1] = args.id and
'|-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 alignClasses then
if not cls._alignClasses then
setAlign(args.align and args.align:lower() or sDefaultAlign)
cls._setAlign(cls, args.align and args.align:lower() or cls._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
end
output[2] = '|' .. (args.note1 and '' or 'colspan=2') .. cls._alignClasses[1] .. (args[1] or ' ')
output[3] = args.note1 and '||' .. cls._alignClasses[2] .. args.note1 or ''
output[4] = '||class=bb-b|'


local len = 4 -- can't use #args because of [[Module:Arguments#Known limitations]]
for i = 1, (len-2) / 2 do
for k in pairs(args) do
local width, title, background
width = args[2*i + 2] or 0
local idx = tonumber(k) or 0
if idx > len then len = idx end
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
end


for i = 1, (len-2) / 2 do
output[#output+1] = '||' .. (args.note2 and alignClasses[3] or 'colspan=2' .. alignClasses[4]) .. (args[2] or ' ')
local width, title, background
output[#output+1] = args.note2 and '||' .. alignClasses[4] .. args.note2 or ''
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 cls._alignClasses[3] or 'colspan=2' .. cls._alignClasses[4]) .. (args[2] or ' ')
return table.concat(output)
output[#output+1] = args.note2 and '||' .. cls._alignClasses[4] .. args.note2 or ''
end

return table.concat(output)
end,


function BarBox._gap(args)
gap = function (args)
local output = {}
local output = {}
local height = tonumber(args.height) and args.height .. 'px' or args.height and args.height:lower() 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'
output[2] = '|colspan=5 style="height:' .. height .. '"|' .. (args[1] or '')
output[2] = '|colspan=5 style="height:' .. height .. '"|' .. (args[1] or '')


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

__classmethods = {'create', 'stacked'},
__staticmethods = {'_setAlign', 'percent', 'pixel', 'gap'},
__slots = {'_alignClasses'}
})


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

local p = {BarBox=BarBox}


function BarBox.box(frame)
function p.box(frame)
local args = getArgs(frame)
local args = getArgs(frame)
local box = BarBox.create(args)
local box = BarBox.create(args)
Line 199: Line 201:
end
end


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


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


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


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


return BarBox
return p

Revision as of 15:43, 12 June 2021

require('Module:Lua class')

local BarBox = class('BarBox', {
	_css = 'Module:Bar box/styles.css',

	__init = function (self, args)
		self.css			 = args.css
		self.float			 = args.float or 'none'
		self.backgroundcolor = args.backgroundcolor or 'white'
		self.borderwidth	 = args.borderwidth or '1'
		self.style			 = args.style
		self.width			 = args.width-- or 'auto'
		self.barwidth		 = args.barwidth or '100px'
		self.lineheight		 = args.lineheight-- or '1.6'
		self.title			 = args.title
		self.titlebar		 = args.titlebar-- or 'none'
		self.left1			 = args.left1
		self.left2			 = args.left2
		self.right1			 = args.right1
		self.right2			 = args.right2
		self.bars			 = args.bars
		self.caption		 = args.caption -- deprecated
		self.footer			 = args.footer or args.caption
	end,

	create = function (cls, args)
		args = mw.clone(args)
		args.float	  = args.float and args.float:lower()
		args.width	  = tonumber(args.width) and args.width .. 'px' or args.width and args.width:lower()
		args.barwidth = tonumber(args.barwidth) and args.barwidth .. 'px' or args.barwidth and args.barwidth:lower()
		return cls(args)
	end,

	_sDefaultAlign = 'lrlr',
	_tDefaultAlign = {false, 'r', false, 'r'},

	_setAlign = function (obj, align)
		obj._alignClasses = {}
		for i, d in ipairs(obj._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
			obj._alignClasses[i] = (a and ' class=bb-' .. a or '') .. '|'
		end
	end,

	html = function (self)
		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 self._alignClasses then -- same as self.__class._alignClasses
					self._alignClasses = self._alignClasses
					self.__class._alignClasses = nil
				else
					self._setAlign(self, self._sDefaultAlign)
				end
				output[6] = '!' .. (self.left2 and '' or 'colspan=2') .. self._alignClasses[1] .. (self.left1 or ' ')
				output[7] = self.left2 and '!!' .. self._alignClasses[2] .. self.left2 or ''
				output[8] = '!!style="width:' .. self.barwidth .. '"| '
				output[9] = '!!' .. (self.right2 and self._alignClasses[3] or 'colspan=2' .. self._alignClasses[4]) .. (self.right1 or ' ')
				output[10] = self.right2 and '!!' .. self._alignClasses[4] .. self.right2 or ''
			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,

	__tostring = function (self)
		return self.html()
	end,

	percent = function (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,

	pixel = function (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,

	stacked = function (cls, 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 cls._alignClasses then
				cls._setAlign(cls, args.align and args.align:lower() or cls._sDefaultAlign)
			end
			output[2] = '|' .. (args.note1 and '' or 'colspan=2') .. cls._alignClasses[1] .. (args[1] or ' ')
			output[3] = args.note1 and '||' .. cls._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 cls._alignClasses[3] or 'colspan=2' .. cls._alignClasses[4]) .. (args[2] or ' ')
			output[#output+1] = args.note2 and '||' .. cls._alignClasses[4] .. args.note2 or ''

		return table.concat(output)
	end,

	gap = function (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,

	__classmethods = {'create', 'stacked'},
	__staticmethods = {'_setAlign', 'percent', 'pixel', 'gap'},
	__slots = {'_alignClasses'}
})


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

local p = {BarBox=BarBox}

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

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

function p.pixel(frame)
	local args = getArgs(frame)
	return BarBox.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 BarBox.stacked(args)
end

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

return p