Module:Bar box and Module:Bar box/sandbox: Difference between pages
Appearance
(Difference between pages)
Content deleted Content added
Ahecht moved page Module:Bar box to Module:Bar: Simplify name (so {{bar box}} can be replaced by {{#invoke:bar|box}}, {{bar percent}} by {{#invoke:bar|percent}}, etc.) Tag: New redirect |
Tag: Removed redirect |
||
Line 1: | Line 1: | ||
require('Module:Lua class') |
|||
require('strict') |
|||
local BarBox = class('BarBox', { |
|||
_css = 'Module:Bar/sandbox/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] = |
|||
'<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 |
|||
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[[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" | ' .. -- <p> is created if \n precedes the footer |
|||
self.footer .. '\n' |
|||
or '' |
|||
output[14] = '|}\n</div>' |
|||
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 .. '">​</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">​</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 |
|||
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#Known limitations]] |
|||
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] = |
|||
'<div' .. title .. ' class=' .. args.bkgclasses[i] .. ' style=width:' .. width .. 'px></div>' |
|||
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] = |
|||
'<div' .. title .. ' style="background:' .. background .. ';width:' .. width .. 'px"></div>' |
|||
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.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 |