Jump to content

Module:Item List

From The Petit Planet Wiki

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

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

function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame, {
		parentFirst = true,
		removeBlanks = false,
		wrapper = { 'Template:Item 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", "text", "amount", "delim", "amount_delim", "type", "size"}

function p._main(args)
	local input = args[1] or ''
	local mode = args.mode or 'bullet'
	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 result = mw.html.create()
	local categories = mw.html.create()
	local items = {}
	
	for i, entry in ipairs(lib.split(input, itemDelim, {noTrim=true})) do
		if lib.isNotEmpty(entry) then
			local entry, itemArgs = 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]

			itemArgs.name		= itemArgs[1]			or itemArgs.name	or name
			itemArgs.size		= itemArgs[2]			or itemArgs.size	or args[2]			or args.size or '20'
			itemArgs.count		= amount				or itemArgs.x		or itemArgs.amount	or args.x	or args.amount
			itemArgs.type		= itemArgs.type			or args.type
			itemArgs.text		= itemArgs.text			or args.text
			itemArgs.link		= itemArgs.link			or args.link
			itemArgs.note		= itemArgs.note			or args.note
			itemArgs.ref		= itemArgs.ref			or args.ref
			itemArgs.blueprint	= itemArgs.blueprint	or args.blueprint
			itemArgs.newline	= itemArgs.newline		or args.newline
			itemArgs.notext		= itemArgs.notext		or args.notext
			itemArgs.white		= itemArgs.white		or args.white
			-- mw.logObject(itemArgs)
			
			table.insert(items, Item(itemArgs))
	
			if (args.category ~= nil) then
				categories:wikitext('[[Category:', args.category:gsub('{item}', name), ']]')
			end
		end
	end
	if #items>0 then
		if mode == 'bullet' then
			local ul = result:tag('ul')
			for ord, item in ipairs(items) do
				ul:tag('li'):node(item)
			end
		elseif mode == 'br' then
			for ord, item in ipairs(items) do
				if ord ~= 1 then
					result:tag('br')
				end
				result:node(item)
			end
		elseif mode == 'sent' then
			for ord, item in ipairs(items) do
				if ord == 1 then
				elseif ord == #items then
					result:wikitext(#items == 2 and ' ' or ', ', 'and ')
				else
					result:wikitext(', ')
				end
				result:node(item)
			end
		else
			error('Invalid list format specified. Please revise [[Template:Item List]].')
		end
		if (args.category ~= nil) then
			result:node(require('Module:Namespace detect')._main({ main = categories }))
		end
	end
	
	return result
end

return p