Module:BSicon catalogue

Lua

CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules

For using BSicon catalogue, please refer to the documentation at Template:BSicon catalogue.

Code

local p = {}

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

p.sets = { "u", "f", "g", "maroon", "red", "orange", "saffron", "yellow",
	"golden", "olive", "lime", "green", "jade", "teal", "cyan", "deepsky",
	"azure", "sky", "cerulean", "blue", "denim", "lavender", "purple", "violet",
	"fuchsia", "ruby", "pink", "carrot", "ochre", "brown", "steel", "grey",
	"black" } -- also update Template:BSicon catalogue/styles.css on change

p.presets_generators = {
	['.'] = function (x) return p.presets[x] end,
	['/'] = function (x, p, r) -- skip gsub '%' interpretation for simple p
		return p=='^' and r..x or (p=='$' and x..r or (x:gsub(p, r)))
	end,
	['~'] = function (x, n, r)
		x=','..x
		x=x:gsub(('('..(',[^,]*'):rep(n)..')'):rep(#(x:gsub('[^,]','')) / n), r)
		return x:sub(2)
	end,
	['+clrs'] = function(x, skip)
		local t={ x }
		x=','..x
		for _, c in ipairs(p.sets) do
			if skip and skip > 0 then skip = skip - 1 else
				if #c > 1 then table.insert(t, (x:gsub(',[^,]*', '%0 '..c)))
				else table.insert(t, (x:gsub(',', ','..c)))
				end
			end
		end
		return table.concat(t)
	end,
	['+u'] = function (x) return x..',u'..x:gsub(',', ',u') end,
	['+x'] = function (x) return x..(','..x):gsub(',[ufge]?','%0x') end,
	['+m'] = function (x) return x..(','..x):gsub(',[^,%%htv]*', '%0m') end,
	['+t'] = function (x) return x..(','..x):gsub(',[^,%%v]*', '%0t') end,
	['+th'] = function (x) return x..(','..x):gsub(',[^,%%v]*', '%0t')..(','..x):gsub(',[^,%%v]*', '%0h') end,
	['p'] = function (x) return '%1'..x:gsub('%%([0-9])', function (x) return '%'..(x+1) end):gsub('[!,]','%0%%1') end,
	['s'] = function (x) local s=0 repeat s=s+1 until not x:match('%%'..s) return x:gsub('[!,]','%%'..s..'%0')..'%'..s end,
	['xm'] = function (x) return x..','..x:gsub('m','xm')..','..x:gsub('([^m])(%%[24])','%1x%2')..',ex'..x:gsub(',',',ex') end,
	['xxe'] = function (x, a, b)
		a=a or '%%2'
		b=b or '%%4'
		local sw=b..'[^,]*'..a
		local t=function (x) return x:gsub(b, 'x%1')..x:gsub(a, 'x%1') end
		local s=function (x) return x..t(x)..x:gsub(',', ',e') end
		a='([^%%0-9]*'..a..')'
		b='([^%%0-9]*'..b..')'
		if x:match(sw) then t=function (x)
			return x:match(sw)
				and x:gsub(a, 'x%1')..x:gsub(b..'(.-)'..a, '%3%2x%1')
				or x:gsub(b, 'x%1')..x:gsub(a..'(.-)'..b, '%3%2x%1')
			end
		end
		x=(','..x):gsub(',[^,]*', s)
		return x:sub(2)
	end,
	['imp'] = function (x)
		local p=x:match('%%') and ',[^,]-%%.' or ',[^,]*'
		local t={}
		x=','..x
		for _, v in ipairs({ 'INT', 'ACC', 'HSTACC', 'INTACC'}) do
			table.insert(t, (x:gsub(p, '%0'..v)))
		end
		return table.concat(t):sub(2)
	end,
	['v'] = function (x, lr, shift)
		x=','..x
		shift=shift or 1
		local s=function (x) return shift==0 and x or x:gsub('%%([0-9])', function (x) return '%'..(x+shift) end) end
		local y=x
		if lr
		then x=x:gsub(',[^,]*', function (x) return (not x:match('[ex]') or x:match('ex')) and x or '' end)
		else lr='r'
		end
		if lr=='l' then lr=function(x,y) return x..'-'..s(y) end end
		if lr=='r' then lr=function(x,y) return y..'-'..s(x) end end
		if lr=='e' then x=',y-sx,x-sy,y-sy' local _x
			lr=function(x,y)
				if _x~=y then
					_x=_x or y
					return x:gsub('s?[xy]', { y=y, sy=s(y), x=_x, sx=s(_x) })
				end
			end
		end
		x=x:gsub(',([^,]*)', function (x)
			return y:gsub(',([^,]*)', function (y) y=lr(x,y) return y and ',v'..y or '' end)
		end)
		return x:sub(2)
	end,
	['exv'] = function (x) return x:gsub('([^,]*)vex([^,]*-)ex','ex%1v%2') end,
	['exv0'] = function (x) return x:gsub('([^,]*)v((e?x?)([^-]-))-%2','%3%1v%4') end,
}

p.presets_recipes = {
	['1']		= { '' }, -- was BSa1
	['1c']		= { '+clrs', '%1' }, -- new
	['2']		= { ',ex' }, -- was BSa
	['2c']		= { '+clrs', '%1,ex%1' }, -- new
	--['2i_old']= { { '/', '^', '%1…%2!' }, { '~', 2, '%1%3%4%5%6%7' }, 'imp', '%1%2,ex%1%2,%1x%2,ex%1x%2' },
	['2i']		= { { '/', '^', '%1…%2!' }, 'imp', '%1%2,ex%1%2,%1x%2,ex%1x%2' }, --new
	['2i-']		= { { '/', '^', '%1…%2!' }, 'imp', '%1%2,ex%1%2' }, --new
	['2p']		= { 'p', '%1,ex%1' }, -- was BSa
	['3']		= { ',e,x,ex' }, -- was BSa6x
	['3v']		= { 'exv', 'v', '.', '3' }, -- new
	['3ve']		= { 'exv', { 'v', 'e' }, '.', '3' }, -- new
	['3vl']		= { 'exv', { 'v', 'l' }, '.', '3' }, -- 3v with e and x variations for the right track omitted
	['3vr']		= { 'exv', { 'v', 'r' }, '.', '3' }, -- 3v with e and x variations for the left track omitted
	['3v0']		= { 'exv0', { 'v', nil, 0 }, '%1,e%1,x%1,ex%1' }, -- new
	['3v0s']	= { 's', '.', '3v0' }, -- new, 3v0 with suffix option
	['3x']		= { '%1%2%3%4,%1%2x%3%4,%1x%2%3%4,%1%3x%2%4,ex%1%2%3%4' }, -- cp. 6x, 7x, 7xc
	['3x1']		= { '%1%2%3,%1%2x%3,%1x%2%3,ex%1%2%3' }, -- cp. 6x1, 7x1, 7x1c
	['3x2']		= { '%1%2%3%4,%1%2x%3%4,%1%3x%2%4,ex%1%2%3%4' }, -- cp. 6x2, 7x2, 7x2c
	['3x1x']	= { '%1%2%3,%1%2x%3,%1x%2%3,e%1%2%3,x%1%2%3,x%1%2x%3,x%1x%2%3,ex%1%2%3' }, -- cp. 6x1x
	['3x2e']	= { '%1%2%3%4,%1%2x%3%4,%1%3x%2%4,e%1%2%3%4,e%1%2x%3%4,e%1%3x%2%4,x%1%2%3%4,ex%1%2%3%4' }, -- cp. 6x2e
	['3x2x']	= { '%1%2%3%4,%1%2x%3%4,%1%3x%2%4,e%1%2%3%4,x%1%2%3%4,x%1%2x%3%4,x%1%3x%2%4,ex%1%2%3%4' }, -- cp. 6x2x
	['3p']		= { 'p', '%1,e%1,x%1,ex%1' }, -- was BSa6x
	['3xp']		= { 'p', '.', '3x' },
	['3x1p']	= { 'p', '.', '3x1' },
	['3x2p']	= { 'p', '.', '3x2' },
	['3m']		= { '+m', '.', '3' }, -- new
	['3mm']		= { { '/', '^', '%1%2%3%4!' }, { '~', 4, '%1%2%3%6%5%4' }, '+x', 'xxe', 'm%1%2%3%4,%1%2%3m%4,%1m%2%3%4' }, -- new
	['3mm~']	= { { '/', '^', '%1%2%3%4!' }, { '~', 4, '%1%2%3%6%5%4' }, '+x', 'xxe', 'm%1%2%3%4,%1%2%3m%4,%1%4%3m%2' }, -- new
	['3mmp']	= { 'p', '.', '3mm' }, -- new
	['3mmp~']	= { 'p', '.', '3mm~' }, -- new
	['4']		= { '+u', ',ex' }, -- was BSa4
	['4e']		= { '+u', ',e,ex' }, -- was BSa4e
	['4x']		= { '+u', ',x,ex' }, -- was BSa4x
	['4v']		= { '+u', 'exv', { 'v', 'l' }, ',ex' }, -- was BSa4x2
	['4vp']		= { '+u', 'exv', 'p', { 'v', 'l' }, '%1,ex%1' }, -- new
	['4m']		= { { '~', 2, '%1%2%4%3' }, '+u', '+m', ',ex' }, -- new
	['4mv']		= { { '~', 4, '%1%2%4%3' }, '+u', 'exv', '+m', { 'v', 'l' }, ',ex' }, -- new
	['4mvp']	= { { '~', 4, '%1%2%4%3' }, '+u', 'exv', '+m', 'p', { 'v', 'l' }, '%1,ex%1' }, -- new
	['5']		= { '+u', '+t', ',ex' }, -- was BSa5
	['5v']		= { '+u', 'exv', '+t', { 'v', 'l' }, ',ex' }, -- was BSa5x2
	['5m']		= { { '~', 4, '%1%2%4%3' }, '+u', '+m', '+t', ',ex' }, -- new
	['5mv']		= { { '~', 4, '%1%2%3%4%8%7%6%5' }, '+u', 'exv', '+m', '+t', { 'v', 'l' }, ',ex' }, -- new
	['6']		= { '+u', '.', '3' }, -- was BSa6
	['6v']		= { '+u', '.', '3v' }, -- new
	['6ve']		= { '+u', '.', '3ve' }, -- was BSa6x2
	['6vl']		= { '+u', '.', '3vl' }, -- 6v with e and x variations for the right track omitted
	['6vr']		= { '+u', '.', '3vr' }, -- 6v with e and x variations for the left track omitted
	['6v0']		= { '+u', '.', '3v0' }, -- new
	['6v0s']    = { 's', '.', '6v0' }, -- new, 6v0 with suffix option
	['6vp']		= { '+u', 'exv', 'p', 'v', '%1,e%1,x%1,ex%1' }, -- new
	['6vpe']	= { '+u', 'exv', 'p', { 'v', 'e' }, '%1,e%1,x%1,ex%1' }, -- new
	['6vpl']	= { '+u', 'exv', 'p', { 'v', 'l' }, '%1,e%1,x%1,ex%1' }, -- new
	['6vpr']	= { '+u', 'exv', 'p', { 'v', 'r' }, '%1,e%1,x%1,ex%1' }, -- new
	['6vp0']	= { '+u', 'exv0', 'p', { 'v', nil, 0 }, '%1,e%1,x%1,ex%1' }, -- new
	['6x']		= { '+u', '.', '3x', }, -- was BSa7x2
	['6x1']		= { '+u', '.', '3x1', }, -- was BSa7x2
	['6x2']		= { '+u', '.', '3x2', }, -- was BSa7x2
	['6x1x']	= { '+u', '.', '3x1x', }, -- new
	['6x2e']	= { '+u', '.', '3x2e', }, -- new
	['6x2x']	= { '+u', '.', '3x2x', }, -- new
	['6m']		= { { '~', 4, '%1%2%4%3' }, '+u', '.', '3m' }, -- new
	['6xm4']	= { { '/', '^', '%1%2%3%4!' }, '+u', 'xm', '%1m%2%3%4,%1%2%3m%4,%1%4%3m%2,%1m%4%3%2' },
	['6xm2']	= { { '/', '^', '%1%2%3%4!' }, '+u', 'xm', '%1m%2%3%4,%1%2%3m%4' },
	['6xm2f']	= { { '/', '^', '%1%2%3%4!' }, '+u', 'xm', '%1%4%3m%2,%1m%4%3%2' },
	['6xm1']	= { { '/', '^', '%1%2%3%4!' }, '+u', 'xm', '%1m%2%3%4' },
	['6xm1b']	= { { '/', '^', '%1%2%3%4!' }, '+u', 'xm', '%1%2%3m%4' },
	['6xm1c']	= { { '/', '^', '%1%2%3%4!' }, '+u', 'xm', '%1%4%3m%2' },
	['6xm1d']	= { { '/', '^', '%1%2%3%4!' }, '+u', 'xm', '%1m%4%3%2' },
	['6xm1r']	= { { '/', '^', '%1%2%3%4!' }, '+u', '%1m%2%3%4,%1m%2%3x%4,%1x%2%3m%4,ex%1m%2%3%4' }, -- 6xm2 with specific eight columns omitted
	['6xm4p']	= { 'p', '.', '6xm4' },
	['6xm2p']	= { 'p', '.', '6xm2' },
	['6xm_4']	= { '.', '6xm4p' }, -- slight change in column order cp. to legacy 6xm_4
	['6xm_2']	= { '.', '6xm2p' },
	['6xm']		= { '.', '6xm2' },
	['6xm2sf']	= { { '/', '(m)(f)(ex)' ,'%3%1%2' }, { '/', '([!,])([^f])', '%1mf%2' }, { '/', ',u', ',f' }, '.', '6xm2' }, -- as 6xm2, but mix set f instead of set u
	['6xm2sfu']	= { { '/', '([uf])([uf])(ex)' ,'%1%3%2' }, { '/', '([!,])([^f])', '%1uf%2' }, { '/', ',u', ',fu' }, '.', '6xm2' }, -- .. mix sets f and u (experimental)
	['7c']		= { '+th', '.', '3', }, -- for BSicon/Catalogue/railway/other colors
	['7xc']		= { '+th', '.', '3x' },
	['7x1c']	= { '+th', '.', '3x1' },
	['7x2c']	= { '+th', '.', '3x2' },
	['7x1xc']	= { '+th', '.', '3x1x' },
	['7x2ec']	= { '+th', '.', '3x2e' },
	['7x2xc']	= { '+th', '.', '3x2x' },
	['7']		= { '+u', '.', '7c', }, -- was BSa7
	['7x']		= { '+u', '.', '7xc', }, -- was BSa7x
	['7x1']		= { '+u', '.', '7x1c', }, -- was BSa7x
	['7x2']		= { '+u', '.', '7x2c', }, -- was BSa7x
	['7x1x']	= { '+u', '.', '7x1xc' },
	['7x2e']	= { '+u', '.', '7x2ec' },
	['7x2x']	= { '+u', '.', '7x2xc' },
	['7pc']		= { 'p', '+th', '%1,e%1,x%1,ex%1' }, -- for BSicon/Catalogue/railway/other colors, with prefix option
	['7xpc']	= { 'p', '.', '7xc' },
	['7x1pc']	= { 'p', '.', '7x1c' },
	['7x2pc']	= { 'p', '.', '7x2c' },
	['7x1xpc']	= { 'p', '.', '7x1xc' },
	['7x2epc']	= { 'p', '.', '7x2ec' },
	['7x2xpc']	= { 'p', '.', '7x2xc' },
	['8c']		= { '+th', '.', '2' }, -- for BSicon/Catalogue/railway/other colors
	['8pc']		= { 'p', '+th', '%1,ex%1' }, -- for BSicon/Catalogue/railway/other colors
	['8']		= { '+u', '.', '8c', }, -- was BSa8
	['8v']		= { '+u', 'exv', '+th', { 'v', 'l' }, '.', '2' }, -- new
	['8m']		= { { '~', 6, '%1%2%4%3' }, '+u', '+m', '+th', '.', '2' }, -- new
	['9c']		= { '+t', '.', '3' }, -- for BSicon/Catalogue/railway/other colors
	['9pc']		= { 'p', '+t', '%1,e%1,x%1,ex%1' }, -- for BSicon/Catalogue/railway/other colors
	['9']		= { '+u', '.', '9c', }, -- was BSaV
	['9x']		= { '+u', '+t', '.', '3x', }, -- new
	['9x1']		= { '+u', '+t', '.', '3x1', }, -- new
	['9x2']		= { '+u', '+t', '.', '3x2', }, -- new
	['9m']		= { { '~', 4, '%1%3%4%8%7%5'}, '+u', '+m', '.', '9c' }, -- new
	['9mo']		= { { '/', '^', '!' }, { '~', 4, '%2%3%4%5'}, '.', '9m' }, -- new, 9m 'mixed only'
	['6t']		= { '%1%2,e%1%2,%1x%2,e%1x%2,x%1%2,ex%1%2,x%1x%2,ex%1x%2,u%1%2,ue%1%2,u%1x%2,ue%1x%2,ux%1%2,uex%1%2,ux%1x%2,uex%1x%2' }, -- new
	['10']		= { 't,ext,h,exh,ht,exht,ut,uext,uh,uexh,uht,uexht' }, -- new
	['11']		= { 't,et,xt,ext,h,eh,xh,exh,ht,eht,xht,exht,ut,uet,uxt,uext,uh,ueh,uxh,uexh,uht,ueht,uxht,uexht' }, -- new
	['12']		= { 'C,exC,D,exD,uC,uexC,uD,uexD' }, -- new
	['13']		= { 'C,eC,xC,exC,D,eD,xD,exD,uC,ueC,uxC,uexC,uD,ueD,uxD,uexD' }, -- new
	['14']		= { ',ex,t,ext,h,exh,C,exC,D,exD,u,uex,ut,uext,uh,uexh,uC,uexC,uD,uexD' }, -- new
	['51']		= { '%1…%2!%1RD1%2,%1RP1%2,%1RP2%2,%1RP4%2,%1vRP2%2,%1RA%2,%1RM%2,%1RB%2,%1RR%2,%1RG%2,%1RY%2,%1RE%2' }, -- new
	['51f']		= { '%1…%2!%1RA%2,%1RM%2,%1RB%2,%1RR%2,%1RG%2,%1RY%2,%1RE%2' }, -- was BSaR
	['51g']		= { '%1…%2!%1RD1%2,%1RP1%2,%1RP2%2,%1RP4%2,%1vRP2%2' }, -- was RPa
	['51k']		= { '%1…%2!%1SKRZ-GD%2,%1SKRZ-G1%2,%1SKRZ-G2%2,%1SKRZ-G4%2,%1SKRZ-A%2,%1SKRZ-M%2,%1SKRZ-B%2,%1SKRZ-R%2,%1SKRZ-G%2,%1SKRZ-Y%2,%1SKRZ-E%2' }, -- new
	['51kf']	= { '%1…%2!%1SKRZ-A%2,%1SKRZ-M%2,%1SKRZ-B%2,%1SKRZ-R%2,%1SKRZ-G%2,%1SKRZ-Y%2,%1SKRZ-E%2' }, -- was RPaS
	['51kg']	= { '%1…%2!%1SKRZ-GD%2,%1SKRZ-G1%2,%1SKRZ-G2%2,%1SKRZ-G4%2' }, -- was RPaN
}

p.presets = setmetatable({}, {
	__index = function (_, x)
		local t=p.presets_recipes[x]
		local g=p.presets_generators
		local r, v
		if t then r=t[#t]
			for i=#t-1, 1, -1 do v=t[i]
				if r then
					if type(v)=='string' then r=g[v] and g[v](r)
					elseif type(v)=='table' then r=g[v[1]] and g[v[1]](r, v[2], v[3])
					end
				end
			end
			--if not r then error('error in preset definition '..x) end
		end
		return r --or error('preset '..x..' not defined') -- caller does fallback
	end
})

function p._main(args)
	local match = mw.ustring.match
	local ret = { '{|' }
	ret.insert = table.insert

	local i = 1 
	while args[i] do
		local id_format = args['format'..(i>1 and i or '')]
		id_format = id_format or args['prefixes'..(i>1 and i or '')]
		local preset = ((not id_format) and (args['preset'..(i>1 and i or '')] or '4'))
		id_format = p.presets[preset] or id_format or ',ex,u,uex'
		if not (i>1) then
			ret:insert('class="wikitable BSicon-catalogue ')
			if not args.header then
				if match(id_format, '%%[2-9]') or match(id_format, '%%1[^,]+') or match(id_format, '-') then
					ret:insert('vertical-headers ')
				end
			end
			ret:insert(preset and 'BSc-p-'..preset..' ' or '')
			ret:insert(args.class and args.class..' ' or '')
			ret:insert('"\n')
		end
		for _, row in ipairs(p.tablechunk(args, id_format, i)) do
			ret:insert(row)
		end
		i = i + 1
	end

	ret:insert('|}')
	return table.concat(ret)
end

function p.tablechunk(args, id_format, chunk)
	-- Define often-used functions
	local gsub = mw.ustring.gsub
	local format = string.format
	local match = mw.ustring.match
	local trim = mw.text.trim
	local split = mw.text.split
	local insert = table.insert
	local header, header1, parallel, row, rows
	local multi = match(gsub(args[chunk], '~~[^\n]*', ''), '\\')
	if not args[chunk] then -- for those who don't escape equals signs
		return error('<code>1=</code> missing')
	end

	local id1_format
	if match(id_format, '!') then
		id1_format = gsub(id_format, '^(.*)![^!]*$', '%1')
		id_format = gsub(id_format, '^.*!([^!]*)$', '%1')
	end

	if not match(id_format, '%%') then -- to check if conversion is needed
		if match(id_format, '-') then
			id_format = gsub(','..id_format, ',([^,]*)-([^,]*)', ',%1%%1-%2%%2')
			if id1_format then
				id1_format = gsub(id1_format, '^([^,]*)-([^,]*)$', '%1%%1-%2%%2') or id1_format
			end
		else
			id_format = gsub(','..id_format, ',([^,]*)', ',%1%%1')
			if id1_format then
				id1_format = gsub(id1_format, '^([^,]*)$', '%1%%1') or id1_format
			end
		end
		id_format = gsub(id_format, '^,', '')
	end

	local function icon_format(var)
		local t={}
		local c=string.byte(':', 1)
		local j=1
		local k
		for i=1, 9 do
			k=j
			while k<#var+1 and string.byte(var, k)~=c do k=k+1 end
			t['%'..i]=var:sub(j, k-1) --also assigns '' to remove unused markers
			j=k+1
		end
		local str = ','..id_format
		str = gsub(str, '%%[1-9]', t)
		str = gsub(str, ',([^,]*)', function (x)
			return x:match('/') and '\n|' or '\n|[[File:BSicon '..x..'.svg|x20px|border| ]]'
		end)
		return str
	end

	local t = split(mw.text.trim(args[chunk]), '\n') -- columns based on first row
	local row_format
	id1_format = id1_format or gsub(id_format, '^([^,]*).*$', '%1')
	local bsc = not match(id_format, '%%[2-9]') and 'c'
	local row_h = function (v)
		local m = v and string.gmatch(v..':', '([^:]*):?')
		return id1_format:gsub('%%([1-9])', function (i)
			local r = not m and i or m() or ''
			i = bsc or i
			if r=='/' then i='x' r='' end
			return '<span class="BSc-'..i..'">'..r..'</span>'
		end)
	end
	if not multi then
		row_format = function(var)
			insert(rows, '\n|-\n| ' .. row_h(var))
			insert(rows, (icon_format(var)))
		end
	else
		row_format = function(var)
			insert(rows, '\n|-')
			var = split(var, '\\')
			if #var > multi then multi = #var end
			for i, v in ipairs(var) do
				if match(v, '%*') then
					if i%2 == 0 then
						insert(rows, '\n|class="BSc-t BSc-e" colspan="'.. (#split(id_format, ',') + 1) ..'"|' .. gsub(v, '%*(.*)$', '%1'))
					else
						insert(rows, '\n|class="BSc-t" colspan="'.. (#split(id_format, ',') + 1) ..'"|' .. gsub(v, '%*(.*)$', '%1'))
					end
				else
					if i%2 == 0 then
						insert(rows, '\n|class="BSc-n BSc-e"|' .. row_h(v))
						insert(rows, (gsub((icon_format(v)), '\n|', '\n|class="BSc-e"|')))
					else
						insert(rows, '\n|class="BSc-n"|' .. row_h(v))
						insert(rows, (icon_format(v)))
					end
				end
			end
		end
		local n, tmp, tmp2 = 1
		while not tmp do
			if not match(t[n], '^!') then
				tmp2 = split(t[n], '~~')
				if tmp2[2] or (tmp2[1] ~= '') then
					tmp = #split(tmp2[1], '\\')
				end
			end
			n = n + 1
		end
		multi = tmp
	end

	local ispercenthdr = match(id_format, '%%[2-9]') or match(id_format, '%%1[^,]+')
	if args['header'..(chunk>1 and chunk or '')] then
		header = args['header'..(chunk>1 and chunk or '')]
	else
		local tmp = ''
		if tonumber(args.width) then tmp = 'style="width:' .. args.width .. 'px" ' end
		header = mw.clone(id_format)
		if ispercenthdr then
			header1 = gsub(row_h(), '<(/?)span', '<%1var')
			local c = args.preset and match('1c 2c', args.preset)
			local v = match(id_format, '%%[2-9]') and '<var class="BSc-%1">%1</var>' or '<var class="BSc-c">1</var>'
			header = (','..header):gsub(',([^,]*)', function (x)
				if x:match('/') then return '\n!' end
				local _c = '>'
				if c then
					_c = x:find(' ', 1, true)
					_c = _c and x:sub(_c + 1) or (x:gsub('%%[1-9]',''):match('^[ufg]') or '')
					_c = (x:match('ex') or '').._c
					_c = ' class="BScc-'.._c..'">'
				end
				return '\n!<div'.._c..x:gsub('%%([1-9])', v)..'</div>'
			end)
			tmp = tmp..'class="BSc-h"|'..header1..header..'\n!'
			header = '!'..tmp..(multi and mw.ustring.rep(tmp, (multi - 1)) or '')
		else
			header = gsub(header, '%%1', '')
			header = header..(multi and mw.ustring.rep(','..tmp..'class="BSc-h"| ,'..header, (multi - 1)) or '')
			header = '!'..tmp..'class="BSc-h"| \n!'..gsub(header, ',', '\n!')..'\n!'
		end
	end
	if args.note then header = header .. args.note end
	rows = {'|-\n', header}
	local colspan
	for i, v in ipairs(t) do
		if match(v, '^!') then
			colspan = colspan or (#split(id_format, ',') + 1) * (multi or 1) + 1
			insert(rows, (gsub(gsub(v, '^!=', '!\n='), '^!', '\n|-\n!colspan="'.. colspan ..'"|')))
		else
			v = split(v, '~~')
			if v[2] or (v[1] ~= '') then
				row_format(v[1])
				insert(rows, '\n| ' .. (v[2] or '') .. (v[3] and ' <span class="BSc-s">' .. v[3] .. '</span>' or ''))
				if v[4] then insert(rows, ' – ' .. (v[4] or '') .. (v[5] and ' <span class="BSc-s">' .. v[5] .. '</span>' or '')) end
			end
		end
	end
	if args.footer ~= 'no' and (#t>4 or not ispercenthdr) then
		insert(rows, '\n|-\n')
		insert(rows, header)
	end
	insert(rows, '\n')
	
	return rows
end

function p.main(frame)
	local args = getArgs(frame, {parentFirst = true})
	return p._main(args)
end

return p