Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Want your own wiki page on WikiGenius? Create one today or request a page.

Module:Navbox with collapsible groups

From WikiGenius

Documentation for this module may be created at Module:Navbox with collapsible groups/doc

-- This module implements {{Navbox with collapsible groups}}

require('strict')
local p = {}
local parentCfg = mw.loadData('Module:Navbox/configuration')
local thisCfg = mw.loadData('Module:Navbox with collapsible groups/configuration')
local cfg = {}
for k, v in pairs(thisCfg) do
	if type(v) == 'table' then
		cfg[k] = {}
		if type(parentCfg[k]) == 'table' then
			for kk, vv in pairs(parentCfg[k]) do cfg[k][kk] = vv end
		end
		for kk, vv in pairs(v) do cfg[k][kk] = vv end
	end
end
local inArray = require("Module:TableTools").inArray
local getArgs -- lazily initialized

-- helper functions
local andnum = function(s, n) return string.format(cfg.arg[s..'_and_num'], n) end
	
local isblank = function(v) return (v or '') == '' end

local function concatstrings(s)
	local r = table.concat(s, '')
	if r:match('^%s*$') then return nil end
	return r
end
	
local function concatstyles(s)
	local r = ''
	for _, v in ipairs(s) do
		v = mw.text.trim(v, "%s;")
		if not isblank(v) then r = r .. v .. ';' end
	end
	if isblank(r) then return nil end
	return r
end
	
local function getSubgroup(args, listnum, listText)
	local subArgs = {
		[cfg.arg.border] = cfg.keyword.border_subgroup,
		[cfg.arg.navbar] = cfg.keyword.navbar_plain
	}
	local hasSubArgs = false
	for k, v in pairs(args) do
		k = tostring(k)
		for _, w in ipairs(cfg.keyword.subgroups) do
			w = w .. listnum .. "_"
			if (#k > #w) and (k:sub(1, #w) == w) then
				subArgs[k:sub(#w + 1)] = v
				hasSubArgs = true
			end
		end
	end
	return hasSubArgs and p._navbox(subArgs) or listText
end

-- Main functions
p._navbox = require('Module:Navbox')._navbox

function p._withCollapsibleGroups(pargs)
	-- table for args passed to navbox
	local targs = {}

	-- process args
	local passthrough = {
		[cfg.arg.above]=true,[cfg.arg.aboveclass]=true,[cfg.arg.abovestyle]=true,
		[cfg.arg.basestyle]=true,
		[cfg.arg.below]=true,[cfg.arg.belowclass]=true,[cfg.arg.belowstyle]=true,
		[cfg.arg.bodyclass]=true,[cfg.arg.bodystyle]=true,
		[cfg.arg.border]=true,
		[cfg.arg.groupclass]=true,
		[cfg.arg.image]=true,[cfg.arg.imageclass]=true,[cfg.arg.imagestyle]=true,
		[cfg.arg.imageleft]=true,[cfg.arg.imageleftstyle]=true,
		[cfg.arg.listclass]=true,
		[cfg.arg.name]=true,
		[cfg.arg.navbar]=true,
		[cfg.arg.state]=true,
		[cfg.arg.style]=true,
		[cfg.arg.title]=true,[cfg.arg.titleclass]=true,[cfg.arg.titlestyle]=true
	}
	for k,v in pairs(pargs) do
		if k and type(k) == 'string' then
			if passthrough[k] then
				targs[k] = v
			elseif (k:match(cfg.pattern.num)) then
				local n = k:match(cfg.pattern.num)
				local list_and_num = andnum('list', n)
				if ((k:match(cfg.pattern.listnum) or k:match(cfg.pattern.contentnum))
						and targs[list_and_num] == nil
						and pargs[andnum('group', n)] == nil
						and pargs[andnum('sect', n)] == nil
						and pargs[andnum('section', n)] == nil) then
					targs[list_and_num] = concatstrings({
						pargs[list_and_num] or '',
						pargs[andnum('content', n)] or ''
					})
					if (targs[list_and_num] and inArray(cfg.keyword.subgroups, targs[list_and_num])) then
						targs[list_and_num] = getSubgroup(pargs, n, targs[list_and_num])
					end
				elseif ((k:match(cfg.pattern.groupnum) or k:match(cfg.pattern.sectnum) or k:match(cfg.pattern.sectionnum))
						and targs[list_and_num] == nil) then
					local titlestyle = concatstyles({
						pargs[cfg.arg.groupstyle] or '',
						pargs[cfg.arg.secttitlestyle] or '', 
						pargs[andnum('groupstyle', n)] or '', 
						pargs[andnum('sectiontitlestyle', n)] or ''
					})
					local liststyle = concatstyles({
						pargs[cfg.arg.liststyle] or '',
						pargs[cfg.arg.contentstyle] or '', 
						pargs[andnum('liststyle', n)] or '', 
						pargs[andnum('contentstyle', n)] or ''
					})
					local title = concatstrings({
						pargs[andnum('group', n)] or '',
						pargs[andnum('sect', n)] or '',
						pargs[andnum('section', n)] or ''
					})
					local list = concatstrings({
						pargs[list_and_num] or '', 
						pargs[andnum('content', n)] or ''
					})
					if list and inArray(cfg.keyword.subgroups, list) then
						list = getSubgroup(pargs, n, list)
					end
					local abbr_and_num = andnum('abbr', n)
					local state = (pargs[abbr_and_num] and pargs[abbr_and_num] == pargs[cfg.arg.selected]) 
						and cfg.keyword.state_uncollapsed
						or (pargs[andnum('state', n)] or cfg.keyword.state_collapsed)
					
					targs[list_and_num] =p._navbox({
						cfg.keyword.border_child,
						[cfg.arg.navbar] = cfg.keyword.navbar_plain,
						[cfg.arg.state] = state,
						[cfg.arg.basestyle] = pargs[cfg.arg.basestyle],
						[cfg.arg.title] = title,
						[cfg.arg.titlestyle] = titlestyle,
						[andnum('list', 1)] = list,
						[cfg.arg.liststyle] = liststyle,
						[cfg.arg.listclass] = pargs[andnum('listclass', n)],
						[cfg.arg.image] = pargs[andnum('image', n)],
						[cfg.arg.imageleft] = pargs[andnum('imageleft', n)],
						[cfg.arg.listpadding] = pargs[cfg.arg.listpadding]
					})
				end
			end
		end
	end
	-- ordering of style and bodystyle
	targs[cfg.arg.style] = concatstyles({targs[cfg.arg.style] or '', targs[cfg.arg.bodystyle] or ''})
	targs[cfg.arg.bodystyle] = nil
	
	-- child or subgroup
	if targs[cfg.arg.border] == nil then targs[cfg.arg.border] = pargs[1] end

	return p._navbox(targs)
end

-- Template entry points
function p.navbox (frame, boxtype)
	local function readArgs(args, prefix)
		-- Read the arguments in the order they'll be output in, to make references
		-- number in the right order.
		local _
		_ = args[prefix .. cfg.arg.title]
		_ = args[prefix .. cfg.arg.above]
		-- Limit this to 20 as covering 'most' cases (that's a SWAG) and because
		-- iterator approach won't work here
		for i = 1, 20 do
			_ = args[prefix .. andnum('group', i)]
			if inArray(cfg.keyword.subgroups, args[prefix .. andnum('list', i)]) then
				for _, v in ipairs(cfg.keyword.subgroups) do
					readArgs(args, prefix .. v .. i .. "_")
				end
			end
		end
		_ = args[prefix .. cfg.arg.below]
	end

	if not getArgs then
		getArgs = require('Module:Arguments').getArgs
	end
	local args = getArgs(frame, {wrappers = {cfg.pattern[boxtype or 'navbox']}})
	readArgs(args, "")
	return p['_'..(boxtype or 'navbox')](args)
end

p['with collapsible groups'] = function (frame)
	return p.navbox(frame, 'withCollapsibleGroups')
end

local q = {}
q._navbox = p._withCollapsibleGroups
q.navbox = p['with collapsible groups']
return q