Difference between revisions of "Module:Bar box"

From blackwiki
Jump to navigation Jump to search
blackwiki>Ahecht
(Write my own table.maxn, since the built-in one doesn't work (and it deprecated in newer versions of Lua anyway))
blackwiki>Ahecht
(Better missing width handling, add is() function)
Line 1: Line 1:
 
local getArgs = require('Module:Arguments').getArgs
 
local getArgs = require('Module:Arguments').getArgs
 
local yesno = require('Module:Yesno')
 
local yesno = require('Module:Yesno')
 +
 +
local function is(v)
 +
return (v or '') ~= ''
 +
end
 +
 +
local function widths(w,d)
 +
local width = is(w) and w or d
 +
if tonumber(width) then width = width .. 'px' end
 +
return width
 +
end
  
 
local p = {}
 
local p = {}
  
 
function p._box(args)
 
function p._box(args)
local width = args.width or 'auto'
+
local width = widths(args.width,'auto')
 
 
 
local class = 'barbox'
 
local class = 'barbox'
Line 16: Line 26:
 
local output = {}
 
local output = {}
 
 
output[1] = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = {src=( ((args.css or '') ~= '') and args.css or 'Template:Bar box/styles.css' )} }
+
output[1] = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = {src=( is(args.css) and args.css or 'Template:Bar box/styles.css' )} }
 
 
 
if (args.float == 'left') or (args.float == 'right') then
 
if (args.float == 'left') or (args.float == 'right') then
Line 35: Line 45:
 
'<div style="border:' .. (args.border_width or '1') .. 'px solid silver; font-size:88%; padding:0.4em; width:' .. width .. '; background: ' .. (args['background-color'] or 'white') .. ';">\n' ..
 
'<div style="border:' .. (args.border_width or '1') .. 'px solid silver; font-size:88%; padding:0.4em; width:' .. width .. '; background: ' .. (args['background-color'] or 'white') .. ';">\n' ..
 
'<table style="text-align:left; border-collapse:collapse; width:100%;">\n'
 
'<table style="text-align:left; border-collapse:collapse; width:100%;">\n'
output[4] = ( ((args.title or '') ~= '') and (
+
output[4] = ( is(args.title) and (
 
'<tr style="background:' .. (args.titlebar or 'none') .. '">' ..
 
'<tr style="background:' .. (args.titlebar or 'none') .. '">' ..
 
'<th style="text-align:center;" colspan="5">' .. args.title .. '</th>' ..
 
'<th style="text-align:center;" colspan="5">' .. args.title .. '</th>' ..
Line 45: Line 55:
 
(args.left1 or '') ..  
 
(args.left1 or '') ..  
 
'</td>\n'
 
'</td>\n'
output[7] = ( ((args.left2 or '') ~= '') and (
+
output[7] = ( is(args.left2) and (
 
'<td style="padding:0 4px; text-align:right;">' .. args.left2 .. '</td>\n') or '')
 
'<td style="padding:0 4px; text-align:right;">' .. args.left2 .. '</td>\n') or '')
 
output[8] =
 
output[8] =
'<td style="width:' .. (args.barwidth or '100px') .. '; text-align:left;"></td>\n' ..
+
'<td style="width:' .. widths(args.barwidth,'100px') .. '; text-align:left;"></td>\n' ..
 
'<td ' .. (args.right2 and '' or 'colspan="2"') .. ' style="padding:0 4px; width:1em; text-align:right;">' ..  
 
'<td ' .. (args.right2 and '' or 'colspan="2"') .. ' style="padding:0 4px; width:1em; text-align:right;">' ..  
 
(args.right1 or '') ..  
 
(args.right1 or '') ..  
 
'</td>\n'
 
'</td>\n'
output[9] = ( ((args.right2 or '') ~= '') and (
+
output[9] = ( is(args.right2) and (
 
'<td style="padding:0 4px; text-align:right;">' .. args.right2 .. '</td>\n') or '')
 
'<td style="padding:0 4px; text-align:right;">' .. args.right2 .. '</td>\n') or '')
 
output[10] =
 
output[10] =
Line 58: Line 68:
 
output[11] =
 
output[11] =
 
args.bars or ''
 
args.bars or ''
output[12] = ( ((args.caption or '') ~= '') and (
+
output[12] = ( is(args.caption) and (
 
'<tr><td colspan="5" style="padding:5px; text-align:left;">' ..  
 
'<tr><td colspan="5" style="padding:5px; text-align:left;">' ..  
 
args.caption ..  
 
args.caption ..  
Line 71: Line 81:
 
function p._percent(args)
 
function p._percent(args)
 
local output = {}
 
local output = {}
local background = ( ((args.bg or '') ~= '') and ('background:' .. args.bg .. ';') or '' )
+
local background = ( is(args.bg) and ('background:' .. args.bg .. ';') or '' )
local percentage = ( ((args[3] or '') ~= '') and args[3] or '0' ) .. '%'
+
local percentage = ( is(args[3]) and args[3] or '0' ) .. '%'
 
 
 
output[1] = '<tr>\n'
 
output[1] = '<tr>\n'
 
output[2] = '<td colspan="2" class="bb-4em" style="min-width:8em;' .. background .. '">' .. (args[1] or '') .. '</td>\n'
 
output[2] = '<td colspan="2" class="bb-4em" style="min-width:8em;' .. background .. '">' .. (args[1] or '') .. '</td>\n'
output[3] = '<td class="bb-lr" style="width:' .. ( ((args.barwidth or '') ~= '') and args.barwidth or '100px' ) .. ';' .. background .. '">'
+
output[3] = '<td class="bb-lr" style="width:' .. widths(args.barwidth,'100px') .. ';' .. background .. '">'
output[4] = '<div style="background:' .. ( ((args[2] or '') ~= '') and args[2] or 'gray' ) .. ';width:' .. percentage .. ';overflow:hidden;">&thinsp;</div>'
+
output[4] = '<div style="background:' .. ( is(args[2]) and args[2] or 'gray' ) .. ';width:' .. percentage .. ';overflow:hidden;">&thinsp;</div>'
 
output[5] = '</td>\n'
 
output[5] = '</td>\n'
output[6] = '<td colspan="' .. ( ((args.note or '') ~= '') and '1' or '2' ) .. '" class="bb-4emr" style="' .. background .. '">' .. ( ((args[4] or '') ~= '') and args[4] or percentage ) .. '</td>\n'
+
output[6] = '<td colspan="' .. ( is(args.note) and '1' or '2' ) .. '" class="bb-4emr" style="' .. background .. '">' .. ( is(args[4]) and args[4] or percentage ) .. '</td>\n'
output[7] = ( ((args.note or '') ~= '') and ('<td class=bb-4emr" style="' .. background .. '">' .. args.note .. '</td>\n') or '' )
+
output[7] = ( is(args.note) and ('<td class=bb-4emr" style="' .. background .. '">' .. args.note .. '</td>\n') or '' )
 
output[8] = '</tr>'
 
output[8] = '</tr>'
 
 
Line 88: Line 98:
 
function p._pixel(args)
 
function p._pixel(args)
 
local output = {}
 
local output = {}
local background = ( ((args[2] or '') ~= '') and args[2] or 'gray' )
+
local background = ( is(args[2]) and args[2] or 'gray' )
local width = ( ((args[3] or '') ~= '') and args[3] or '0' )
+
local width = ( is(args[3]) and args[3] or '0' )
local note = ( ((args.note or '') ~= '') and '1' or '2' )
+
local note = ( is(args.note) and '1' or '2' )
 
 
 
output[1] =
 
output[1] =
Line 103: Line 113:
 
'</td>\n'
 
'</td>\n'
 
output[4] =
 
output[4] =
'<td colspan="' .. ( ((args.note or '') ~= '') and '1' or '2' ) .. '" class="bb-min3">' ..
+
'<td colspan="' .. note .. '" class="bb-min3">' ..
( ((args[5] or '') ~= '') and args[5] or (width .. (args[4] or '')) ) ..
+
( is(args[5]) and args[5] or (width .. (args[4] or '')) ) ..
 
'</td>\n'
 
'</td>\n'
output[5] = ( ((args.note or '') ~= '')  and (
+
output[5] = ( is(args.note)  and (
 
'<td class="bb-4emr">' ..
 
'<td class="bb-4emr">' ..
 
args.note ..
 
args.note ..
Line 136: Line 146:
 
local output = {}
 
local output = {}
 
 
output[1] = ( ((args.id or '') ~= '') and (
+
output[1] = ( is(args.id) and (
 
'<tr class="mw-collapsible' .. ( yesno(args.collapsed) and ' mw-collapsed' or '') ..
 
'<tr class="mw-collapsible' .. ( yesno(args.collapsed) and ' mw-collapsed' or '') ..
 
'" id="mw-customcollapsible-' .. args.id .. '"}}>\n') or '<tr>\n')
 
'" id="mw-customcollapsible-' .. args.id .. '"}}>\n') or '<tr>\n')
Line 144: Line 154:
 
mw.text.trim(args[1] or '') ..  
 
mw.text.trim(args[1] or '') ..  
 
'</td>\n'
 
'</td>\n'
output[3] = ( ((args.note1 or '') ~= '') and (
+
output[3] = ( is(args.note1) and (
 
'<td style="text-align:' .. _align(2,'right') .. '" class="bb-04em">' ..  
 
'<td style="text-align:' .. _align(2,'right') .. '" class="bb-04em">' ..  
 
args.note1 ..  
 
args.note1 ..  
Line 159: Line 169:
 
for i=1,(( maxn - 2 )/2),1 do
 
for i=1,(( maxn - 2 )/2),1 do
 
local width = ( mw.text.trim(args[(2*i) + 2] or 0) )
 
local width = ( mw.text.trim(args[(2*i) + 2] or 0) )
 +
width = (is(width) and width or 0)
 
width = tonumber( mw.ustring.format("%.2f", width) )
 
width = tonumber( mw.ustring.format("%.2f", width) )
 
if width == 0 then
 
if width == 0 then
Line 180: Line 191:
 
mw.text.trim(args[2] or '') ..  
 
mw.text.trim(args[2] or '') ..  
 
'</td>\n'
 
'</td>\n'
output[#output+1] = ( ((args.note2 or '') ~= '') and (
+
output[#output+1] = ( is(args.note2) and (
 
'<td style="text-align:' .. _align(4,'right') .. '" class="bb-04em">' ..  
 
'<td style="text-align:' .. _align(4,'right') .. '" class="bb-04em">' ..  
 
args.note2 ..
 
args.note2 ..

Revision as of 14:51, 15 April 2020

Script error: No such module "Uses TemplateStyles".

This 'Bar box' template documentation is transcluded for all Bar box/doc including templates [edit].Masterpage

 

{{Bar box}}, {{bar percent}}, {{bar pixel}}, {{bar stacked}} and {{bar gap}} are a family of templates for construction of horizontal bar charts.

Usage

{{Bar box
|width   =  width of the graph         (optional)
|barwidth=  width of the bararea       (optional, defaults to 100px)
|float   =  (left|right|none)          (optional, defaults to none)
|title   =  title of the chart         (optional)
|titlebar=  title bar colour           (optional, defaults to none)
|left1   =  first left column header   (optional)
|left2   =  second left column header  (optional)
|right1  =  first right column header  (optional)
|right2  =  second right column header (optional)
|bars    =  chart contents             (see below)
|caption =  caption under the chart    (optional)
}}

Chart contents

Bar box can contain any number of bars. There are four types of bars:

  • Percentage bar:
{{bar percent|row label|colour|value (width in percents)|optional value label}}

If value label is not provided, it is constructed from the percentage and "%". This bar type also has the {{bar percent 2}} and {{bar percent 3}} variations which display more bars for the same row label.

  • Pixel bar:
{{bar pixel|row label|colour|value (width in pixels)|value suffix|optional value label}}

If value label is provided, value suffix is ignored. Otherwise, the value label is constructed from the value and the value suffix. This is used as shorthand. Both following examples give identical results:

{{bar pixel|foo|red|12||12,345}}
{{bar pixel|foo|red|12|,345}}

This bar type also has the {{bar pixel 2}} variation which displays two bars for the same row label.

  • Stacked bars:
{{bar stacked|1st left label|1st right label|color 1|width 1 (in pixels)|...|color 5|width 5 (in pixels)|note1=2nd left label|note2=2nd right label|title1="tooltip" 1|...|title5="tooltip" 5|align=xxxx(l|c|r|d)|collapsed=(yes|y|1)|id=collapsible id}}

titlex sets the "tooltip" of the respective bar and is viewed when hovered over. align sets the text-alignment (left, center, right or default) for each column based on the respective initials. All parameters are optional, but if id is not supplied, collapsed has no effect. Use a custom toggle as the default toggle will distort the chart (see the last example).

  • Gap bar:
{{bar gap|optional separator|height=any valid length (omitting unit defaults to px, default is 10px)}}

Ommiting the separator generates a blank row. Another useful separator is <hr> which produces a horizontal line.

Examples

{{Bar box
|float=right
|caption=distribution of stuff
|width=200px
|bars=
{{bar percent|foo|red|30}}
{{bar percent|bar|green|40}}
{{bar percent|baz|blue|20}}
{{bar percent|bla|orange|8}}
{{bar percent|bla1|teal|2|1/50}}
}}
foo
30%
bar
40%
baz
20%
bla
8%
bla1
1/50
distribution of stuff
{{Bar box
|title=Quantity of stuff
|titlebar=#DDD
|left1=kinds of stuff
|right2=pcs.
|width=400px
|bars=
{{bar pixel|Foobar|red|33|,213}}
{{bar pixel|Barfoo|green|123|,123}}
{{bar pixel|Bazbar|blue|210|,121}}
{{bar pixel|Barfoobaz|orange|13||12,854}}
|caption=Some stuff displayed by quantity.
}}
Quantity of stuff
kinds of stuff pcs.
Foobar
33,213
Barfoo
123,123
Bazbar
210,121
Barfoobaz
12,854
Some stuff displayed by quantity.
{{Bar box
|float=right
|title=Election results
|titlebar=#AAF
|left1=party
|left2=year
|right1=votes
|right2=change
|width=300px
|bars=
{{bar percent 2|Left|1898|silver|33|1902|red|42|+9%}}
{{bar percent 2|Right|1898|silver|40|1902|black|35|-5%}}
{{bar percent 2|Middle|1898|silver|17|1902|blue|10|-7%}}
{{bar percent 2|Other|1898|silver|10|1902|gray|13|+3%}}
|caption=1902 and 1898 election results in Freedonia compared.
}}
Election results
party year votes change
Left 1898
  
33% +9%
1902
  
42%
Right 1898
  
40% -5%
1902
  
35%
Middle 1898
  
17% -7%
1902
  
10%
Other 1898
  
10% +3%
1902
  
13%
1902 and 1898 election results in Freedonia compared.
{{Bar box
|width=250px
|title=
<div class="mw-customtoggle-a mw-customtoggle-b">Toggle all</div>
<div class="mw-customtoggle-b">Toggle last</div>
|bars=
{{bar stacked|January|(---)|red|3|blue|22|align=ddcd|id=a}}
{{bar stacked|February|+60.3%|red|8|blue|26|green|6|id=a}}
{{bar stacked|March|99|red|11|blue|18|green|8|orange|11|magenta|20|note2=+25%|align=cdrl|id=a}}
{{bar stacked|April|142|red|15|blue|24|green|8|orange|13|magenta|26|note1=foo|note2=+11%|collapsed=yes|id=b}}
}}
Toggle all
Toggle last
January
(---)
February
+60.3%
March
99 +25%
April foo
142 +11%

Tracking category

See also


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

local function is(v)
	return (v or '') ~= ''
end

local function widths(w,d)
	local width = is(w) and w or d
	if tonumber(width) then width = width .. 'px' end
	return width
end

local p = {}

function p._box(args)
	local width = widths(args.width,'auto')
	
	local class = 'barbox'
	if args.float == 'left' or args.float == 'right' or args.float == 'none' then
		class = 'barbox t' .. args.float
	elseif args.float == 'center' then
		class = 'barbox tnone'
	end
	
	local output = {}
	
	output[1] = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = {src=( is(args.css) and args.css or 'Template:Bar box/styles.css' )} }
	
	if (args.float == 'left') or (args.float == 'right') then
		output[2], output[14] = '', ''
	else
		output[2] =
			'<table style="margin:' .. ( (args.float == 'center') and '0 auto' or '0' ) .. '; border:none;">' .. 
				'<tr>' .. 
					'<td style="border:none; padding:0;">'
		output[14] = '</td>' ..
				'</tr>' .. 
			'</table>' .. 
			'[[Category:Pages using bar box without float left or float right|' .. ( (width == 'auto') and 'Ω' or '' ) .. mw.title.getCurrentTitle().text .. ']]'
	end
	
	output[3] = 
		'<div class="' .. class .. '" style="overflow-x: auto;' .. (args.style or '') .. '">\n' ..
		'<div style="border:' .. (args.border_width or '1') .. 'px solid silver; font-size:88%; padding:0.4em; width:' .. width .. '; background: ' .. (args['background-color'] or 'white') .. ';">\n' ..
		'<table style="text-align:left; border-collapse:collapse; width:100%;">\n'
		output[4] = ( is(args.title) and (
			'<tr style="background:' .. (args.titlebar or 'none') .. '">' ..
				'<th style="text-align:center;" colspan="5">' .. args.title .. '</th>' ..
			'</tr>\n') or '')
		output[5] =
			'<tr style="font-size:88%; height:4px;">\n'
			output[6] =
				'<td ' .. (args.left2 and '' or 'colspan="2"') .. ' style="padding:0 4px; text-align:left;">' .. 
					(args.left1 or '') .. 
				'</td>\n'
			output[7] = ( is(args.left2) and (
				'<td style="padding:0 4px; text-align:right;">' .. args.left2 .. '</td>\n') or '')
			output[8] =
				'<td style="width:' ..  widths(args.barwidth,'100px') .. '; text-align:left;"></td>\n' ..
				'<td ' .. (args.right2 and '' or 'colspan="2"') .. ' style="padding:0 4px; width:1em; text-align:right;">' .. 
					(args.right1 or '') .. 
				'</td>\n'
			output[9] = ( is(args.right2) and (
				'<td style="padding:0 4px; text-align:right;">' .. args.right2 .. '</td>\n') or '')
		output[10] =
			'</tr>\n'
		output[11] =
			args.bars or ''
		output[12] = ( is(args.caption) and (
			'<tr><td colspan="5" style="padding:5px; text-align:left;">' .. 
				args.caption .. 
			'</td></tr>\n') or '')
	output[13] =
		'</table>\n</div>\n</div>\n'
	-- output[14] defined above
	
	return table.concat(output)
end

function p._percent(args)
	local output = {}
	local background = ( is(args.bg) and ('background:' .. args.bg .. ';') or '' )
	local percentage = ( is(args[3]) and args[3] or '0' ) .. '%'
	
	output[1] = '<tr>\n'
		output[2] = '<td colspan="2" class="bb-4em" style="min-width:8em;' .. background .. '">' .. (args[1] or '') .. '</td>\n'
		output[3] = '<td class="bb-lr" style="width:' .. widths(args.barwidth,'100px') .. ';' .. background .. '">'
			output[4] = '<div style="background:' .. ( is(args[2]) and args[2] or 'gray' ) .. ';width:' .. percentage .. ';overflow:hidden;">&thinsp;</div>'
		output[5] = '</td>\n'
		output[6] = '<td colspan="' .. ( is(args.note) and '1' or '2' ) .. '" class="bb-4emr" style="' .. background .. '">' .. ( is(args[4]) and args[4] or percentage ) .. '</td>\n'
		output[7] = ( is(args.note) and ('<td class=bb-4emr" style="' .. background .. '">' .. args.note .. '</td>\n') or '' )
	output[8] = '</tr>'
	
	return table.concat(output)
end

function p._pixel(args)
	local output = {}
	local background = ( is(args[2]) and args[2] or 'gray' )
	local width = ( is(args[3]) and args[3] or '0' )
	local note = ( is(args.note) and '1' or '2' )
	
	output[1] =
		'<tr>\n'
		output[2] =
			'<td colspan="2" class="bb-4em">' .. (args[1] or '') .. '</td>\n'
		output[3] =
			'<td class-"bb-lr">' ..
				'<div style="background:' .. background .. '; width:' .. width .. 'px; overflow:hidden">' .. 
					'&emsp;' ..
				'</div>' ..
			'</td>\n'
		output[4] =
			'<td colspan="' .. note .. '" class="bb-min3">' ..
				( is(args[5]) and args[5] or (width .. (args[4] or '')) ) ..
			'</td>\n'
		output[5] = ( is(args.note)  and (
			'<td class="bb-4emr">' ..
				args.note ..
			'</td>\n') or '' )
	output[6] =
		'</tr>'
	
	return table.concat(output)
end

function p._stacked(args)
	local function _align(n, default)
		if (args.align or '') ~= '' then
			local a = mw.ustring.sub(args.align,n,n)
			if a == 'l' then
				return 'left'
			elseif a == 'c' then
				return 'center'
			elseif a == 'r' then
				return 'right'
			elseif a == 'd' then
				return default
			end
		end
		
		return default
	end

	local output = {}
	
	output[1] = ( is(args.id) and (
		'<tr class="mw-collapsible' .. ( yesno(args.collapsed) and ' mw-collapsed' or '') ..
		'" id="mw-customcollapsible-' .. args.id .. '"}}>\n') or '<tr>\n')
		output[2] =
			'<td ' .. (args.note1 and '' or 'colspan="2" ') .. 
			'style="text-align:' .. _align(1,'left') .. '" class="bb-04em">' .. 
				mw.text.trim(args[1] or '') .. 
			'</td>\n'
		output[3] = ( is(args.note1) and (
			'<td style="text-align:' .. _align(2,'right') .. '" class="bb-04em">' .. 
				args.note1 .. 
			'</td>\n') or '')
		output[4] =
			'<td class="bb-lr">\n'
			
			local maxn = 4
			for k in pairs(args) do
				local kn = tonumber(k) or 0
				if kn > maxn then maxn = kn end
			end
			
			for i=1,(( maxn - 2 )/2),1 do
				local width = ( mw.text.trim(args[(2*i) + 2] or 0) )
				width = (is(width) and width or 0)
				width = tonumber( mw.ustring.format("%.2f", width) )
				if width == 0 then
					output[i+4] = ''
				else
					local title = ( (args['title' .. i] or '') ~= '' ) and ( ' title=' .. args['title' .. i] ) or ''
					local background = ( (args[(2*i) + 1] or '') ~= '' ) and args[(2*i) + 1] or 'gray'
					
					output[i+4] =
						'<div' .. title .. ' style="background:' .. background .. ';width:' .. width .. 'px" class="bb-fl">' ..
							'&#8203;' ..
						'</div>\n'
				end
			end
	
		output[#output+1] =
			'</td>\n'
		output[#output+1] = 
			'<td ' .. (args.note2 and '' or 'colspan="2" ') .. 
			'style="text-align:' .. _align(3,'left') .. '" class="bb-04em">' .. 
				mw.text.trim(args[2] or '') .. 
			'</td>\n'
		output[#output+1] = ( is(args.note2) and (
			'<td style="text-align:' .. _align(4,'right') .. '" class="bb-04em">' .. 
				args.note2 ..
			'</td>\n') or '')
	output[#output+1] =
		'</tr>\n'
	
	return table.concat(output)
end

function p._gap(args)
	local output = {}
	
	local height = '10px'
	if (args.height or '') ~= '' then
		height = (tonumber(args.height) and (args.height .. 'px') or args.height)
	end
			
	output[1] =
		'<tr>\n'
		output[2] = 
			'<td colspan="5" style="height:'.. height .. '">' .. (args[1] or '') .. '</td>\n'
	output[3] =
		'</tr>\n'

	return table.concat(output)
end

function p.box(frame)
	local args = getArgs(frame, {
		valueFunc = function (key, value)
			if value then
				value = mw.text.trim(value)
				if (key == 'width') or (key == 'float') then
					value = mw.ustring.lower(value)
				end
				if value ~= '' then
					return value
				end
			end
			return nil
		end
	})
	return p._box(args)
end

function p.percent(frame)
	local args = getArgs(frame, {
		valueFunc = function (key, value)
			if value then
				value = mw.text.trim(value)
				if value ~= '' then
					return value
				end
			end
			return nil
		end
	})
	return p._percent(args)
end

function p.pixel(frame)
	local args = getArgs(frame, {
		valueFunc = function (key, value)
			if value then
				value = mw.text.trim(value)
				if value ~= '' then
					return value
				end
			end
			return nil
		end
	})
	return p._pixel(args)
end

function p.gap(frame)
	local args = getArgs(frame, {
		valueFunc = function (key, value)
			if value then
				value = mw.text.trim(value)
				if value ~= '' then
					return value
				end
			end
			return nil
		end
	})
	return p._gap(args)
end

function p.stacked(frame)
	local args = getArgs(frame, {
		valueFunc = function (key, value)
			if value then
				value = mw.text.trim(value)
				if (key == 'collapsed') or (key == 'align') then
					value = mw.ustring.lower(value)
				end
				if value ~= '' then
					return value
				end
			end
			return nil
		end
	})
	return p._stacked(args)
end

return p