Module:Bar

require('Module:Lua class') require('strict')

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

__init = function (self, args) self.css			 = args[1] or args.css self.float			 = args[2] or args.float or 'none' self.backgroundcolor = args[3] or args.backgroundcolor or 'white' self.borderwidth	 = args[4] or args.borderwidth or '1' self.style			 = args[5] or args.style self.width			 = args[6] or args.width-- or 'auto' self.barwidth		 = args[7] or args.barwidth or '100px' self.lineheight		 = args[8] or args.lineheight-- or '1.6' self.title			 = args[9] or args.title self.titlebar		 = args[10] or args.titlebar-- or 'none' self.left1			 = args[11] or args.left1 self.left2			 = args[12] or args.left2 self.right1			 = args[13] or args.right1 self.right2			 = args[14] or args.right2 self.bars			 = args[15] or args.bars self.caption		 = args[16] or args.caption -- deprecated self.footer			 = args[17] or args.footer or args[16] 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		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] = '\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

local attributes = not self.left2 and 'colspan=2' .. (self._alignClasses[1] and ' ' .. self._alignClasses[1] or '') or self._alignClasses[1] output[6] = '!' .. (attributes and attributes .. '|' or '') .. (self.left1 or ' ') output[7] = self.left2 and '!!' .. (self._alignClasses[2] and self._alignClasses[2] .. '|' or '') .. self.left2 or '' output[8] = '!!style="width:' .. self.barwidth .. '"| ' attributes = not self.right2 and 'colspan=2' .. (self._alignClasses[4] and ' ' .. self._alignClasses[4] or '') or self._alignClasses[3] output[9] = '!!' .. (attributes and attributes .. '|' or '') .. (self.right1 or self.right2 and ' ' or '') output[10] = self.right2 and '!!' .. (self._alignClasses[4] and self._alignClasses[4] .. '|' or '') .. self.right2 or '' output[11] = '\n'

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

if self.caption then output[15] = '\n' else output[15] = '' end output[13] = self.footer and '|- class=bb-default\n| colspan=5 style="padding:5px 0" | ' .. -- is created if \n precedes the footer self.footer .. '\n' or '' output[14] = '|}\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] = '&#8203; ' 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] = '&#8203; ' 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

local attributes = not args.note1 and 'colspan=2' .. (cls._alignClasses[1] and ' ' .. cls._alignClasses[1] or '') or cls._alignClasses[1] output[2] = '|' .. (attributes and attributes .. '|' or '') .. (args[1] or ' ') output[3] = args.note1 and '||' .. (cls._alignClasses[2] and cls._alignClasses[2] .. '|' or '') .. args.note1 or '' output[4] = '||class=bb-b|'

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

if args.bkgclasses then -- used when wikitext minimization is essential for i = 1, len-2 do local width, delim, title --is delim reset every cycle? width = args[i+2] or 0 width = tonumber(('%.2f'):format(width)) if width > 0 then if not delim then -- assuming title types are consistent delim = tonumber(args['title' .. i]) and  or '"'							end							title = args['title' .. i] and ' title=' .. delim .. args['title' .. i] .. delim or 							output[#output+1] =								' '						end					end				else					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							title = args['title' .. i] and ' title="' .. args['title' .. i] .. '"' or ''							background = args[2*i + 1] or 'gray'							output[#output+1] =								' '						end					end				end

if #output == 4 then output[5] = ' ' end

attributes = not args.note2 and 'colspan=2' .. (cls._alignClasses[4] and ' ' .. cls._alignClasses[4] or '') or cls._alignClasses[3] output[#output+1] = '||' .. (attributes and attributes .. '|' or '') .. (args[2] or args.note2 and ' ' or '') output[#output+1] = args.note2 and '||' .. (cls._alignClasses[4] and cls._alignClasses[4] .. '|' or '') .. 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}

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.log(frame) local args = getArgs(frame) local outArgs = {[1] = args[2], [2] = args[3]} outArgs[3] = math.log((tonumber(args[4]) ~= nil) and (args[4] + 1) or 100)/ math.log((tonumber(args[1]) ~= nil) and args[1] or 2)*30 outArgs[5] = ((args[6] or ) ~= ) and args[6] or ((args[4] or ) .. (args[5] or )) return BarBox.pixel(outArgs) 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)				elseif key == 'bkgclasses' then					return mw.text.jsonDecode(value) -- string to table				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