Jump to content

Module:Card List

From The Petit Planet Wiki

Documentation for this module may be created at Module:Card List/doc

local p = {}
local lib = require('Module:Feature')
local Card = require('Module:Card')._main

function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame, {
		parentFirst = true,
		removeBlanks = false,
		wrapper = { 'Template:Card List' }
	})
	return p._main(args)
end

function p.splitNote(entry, notePattern)
	if notePattern then
		item, note = entry:match(notePattern)
		if item == nil then -- will be nil if note is not present
			return entry
		end
		return item, note
	end
	return entry
end

function p.splitParams(entry, paramDelim)
	if entry:find('{.-}') then
		local params = string.match(entry, '{(.-)}')
		entry = entry:gsub('{.-}', '')
		params = lib.split(params, paramDelim)
		local returns = {}
		for i, param in ipairs(params) do
			local name, val = string.match(param, '^%s*(.-)%s*=%s*(.-)%s*$')
			if name ~= nil and name ~= '' and val ~= nil then --named params
				returns[name] = val
			elseif param ~= nil and param ~= '' then --unnamed params
				table.insert(returns, param)
			end
		end
		return entry, returns
	end
	return entry, {}
end

-- all the non-boolean params except note_delim
local PARAMS_NOT_SUPPORTING_BLANKS = {"caption", "amount", "delim", "amount_delim", "type", "caption_width"}

function p._main(args)
	local input = args[1] or ''
	local itemDelim = args.delim or ','
	local countDelim = args.amount_delim or '*'
	local noteDelim = args.note_delim or '/'
	local paramDelim = args.param_delim or '$'
	
	--= handle blanks for non-boolean params
	for _, paramName in ipairs(PARAMS_NOT_SUPPORTING_BLANKS) do
		local value = args[paramName]
		if value == "" then
			args[paramName] = nil
		end
	end
	
	-- put all text after the first noteDelim into the second capture
	local notePattern
	if lib.isNotEmpty(noteDelim) then
		notePattern = "^(.-)" .. noteDelim .. "(.*)$"
	end
	
	local containerClass = "card-list-container "
	if args.mobile_list then
		containerClass = containerClass .. "card-mobile-list "
	end
	if lib.isNotEmpty(args.class) then
		containerClass = containerClass .. args.class
	end
	
	local result = mw.html.create():tag("span"):addClass(containerClass)
	local categories = mw.html.create()
	local splitSett = {
		noTrim      = args.trim and false or true,
		removeEmpty = args.removeEmpty and true or false
	}
	
	for entry in lib.gsplit(input, itemDelim, splitSett) do
		if not lib.isEmpty(entry) then
			local entry, cardArgs = p.splitParams(entry, paramDelim) --check for entry-specific params
			
			local item, note = p.splitNote(entry, notePattern) --check for entry-specific note
			
			local item_parts = lib.split(item, countDelim) --check for entry-specific amount
			local name = item_parts[1]
			local amount = item_parts[2]
			if args.ts and tonumber(amount) ~= nil then amount = lib.thousandsSeparator(amount) end
			
			--set card arguments without replacing those set by entry-specific params
			cardArgs = p.assignArgs(cardArgs, args, name, amount, note)
			-- mw.logObject(cardArgs)
			
			result:node(Card(cardArgs))
	
			if (args.category ~= nil) then
				if type(args.category) ~= 'table' then args.category = {args.category} end
				for _, catForm in ipairs(args.category) do
					categories:wikitext('[[Category:', catForm:gsub('{item}', cardArgs.name), ']]')
				end
			end
		end
	end
	
	if (args.category ~= nil) then
		result:node(require('Module:Namespace detect')._main({ main = categories }))
	end
	
	return result
end

function p.list(args)
	args = args or {}
	
	--= handle blanks for non-boolean params
	for _, paramName in ipairs(PARAMS_NOT_SUPPORTING_BLANKS) do
		local value = args[paramName]
		if value == "" then
			args[paramName] = nil
		end
	end

	local containerClass = "card-list-container"
	if args.mobile_list then
		containerClass = containerClass .. " card-mobile-list"
	end
	
	local result = mw.html.create():tag("span"):addClass(containerClass)
	local categories = mw.html.create()
	
	for i, cardArgs in ipairs(args) do
		if not lib.isEmpty(cardArgs) then
			if type(cardArgs) == 'string' then cardArgs = {cardArgs} end
			cardArgs = p.assignArgs(cardArgs, args)
			
			if (args.category ~= nil) then
				if type(args.category) ~= 'table' then args.category = {args.category} end
				for _, catForm in ipairs(args.category) do
					categories:wikitext('[[Category:', catForm:gsub('{item}', cardArgs.name), ']]')
				end
			end
			
			result:node(Card(cardArgs))
		end
	end
	
	if (args.category ~= nil) then
		result:node(require('Module:Namespace detect')._main({ main = categories }))
	end
	
	return result
end

function p.assignArgs(cardArgs, args, name, amount, note)
	local finalArgs = cardArgs or {}
	local assignVals = { -- 1 = cardArgs; 2 = args; 0 = param name
		['name']						= { {1, '1'}, name },
		['text']						= { {1, '2'}, amount, {2, 0}, {2, 'amount'} },
		['caption']						= { {2, 0} },
		['show_caption']				= { {2, 0} },
		['caption_width']				= { {2, 0} },
		['note']						= { note },
		['stars']						= { {2, 0} },
		['type']						= { {2, 0} },
		['suffix']						= { {2, 0} },
		['set']							= { {2, 0} },
		['mini']						= { {2, 0} },
		['mobile_list']					= { {2, 0} },
		['link']						= { pref = args.link_prefix, suff = args.link_suffix },
		['nolink']						= { {2, 0} },
		
		--icon
		['icon']						= { {2, 0} },
		['icon_type']					= { {2, 0} },
		['icon_size']					= { {2, 0} },
		['icon_suffix']					= { {2, 0} },
		['icon_link']					= { pref = args.icon_link_prefix, suff = args.icon_link_suffix },
		
		--icon_right
		['icon_right']					= { {2, 0} },
		['icon_right_type']				= { {2, 0} },
		['icon_right_size']				= { {2, 0} },
		['icon_right_suffix']			= { {2, 0} },
		['icon_right_link']				= { pref = args.icon_right_link_prefix, suff = args.icon_right_link_suffix },
		
		--icon_bottom_left
		['icon_bottom_left']			= { {2, 0} },
		['icon_bottom_left_type']		= { {2, 0} },
		['icon_bottom_left_size']		= { {2, 0} },
		['icon_bottom_left_suffix']		= { {2, 0} },
		['icon_bottom_left_link']		= { pref = args.icon_bottom_left_link_prefix, suff = args.icon_bottom_left_link_suffix },
		
		--icon_bottom_right
		['icon_bottom_right']			= { {2, 0} },
		['icon_bottom_right_type']		= { {2, 0} },
		['icon_bottom_right_size']		= { {2, 0} },
		['icon_bottom_right_suffix']	= { {2, 0} },
		['icon_bottom_right_link']		= { pref = args.icon_bottom_right_link_prefix, suff = args.icon_bottom_right_link_suffix },
	}
	local st = {cardArgs, args}
	
	for param, list in pairs(assignVals) do
		if lib.isNotEmpty(list) and type(list) == 'table' then
			local paramF
			if lib.isNotEmpty(cardArgs[param]) then
				paramF = cardArgs[param]
			elseif #list > 0 then
				local i = 0
				while i < #list do
					i = i+1
					local val = list[i]
					if type(val) == 'string' and lib.isNotEmpty(val) then
						paramF = val
						break
					elseif type(val) == 'table' and lib.isNotEmpty(st[val[1]][(val[2]==0 and param or val[2])]) then
						paramF = st[val[1]][(val[2]==0 and param or val[2])]
						break
					end
				end
			end
			if paramF then
				finalArgs[param] = table.concat({
					lib.ternary(lib.isNotEmpty(list.pref) and type(list.pref) == 'string', list.pref, ''),
					paramF,
					lib.ternary(lib.isNotEmpty(list.suff) and type(list.suff) == 'string', list.suff, '')
				}, '')
			end
		end
	end
	
	return finalArgs
end	
return p