Fandom Developers Wiki
Documentation icon Module documentation

The documentation for this module is missing. Click here to create it.

-- Useful utilit for editing lists
-- Perfectly combines with Variables, Arrays, and DPL3 ({{#dplvar}}) extensions
-- TODO: 
---- * Add documentation and comments for all functions
---- * Probably refactor some nested loops

trim = mw.text.trim

p = {}

local function morphList(list, separator)
	local result = {}
	local text = mw.text.split(list, separator)
	
	for i = 1, #text, 1 do
		text[i] = trim(text[i])
		if not (text[i] == "" or not text[i]) then
			result[#result + 1] = text[i]
		end
	end
	
	return result
end

function p.lstSeparator(frame)
	local list = morphList(frame.args[1], frame.args[2])
	local output_separator = frame.args[3]
	
	return table.concat(list, output_separator)
end

function p.lstCount(frame)
	local list = morphList(frame.args[1], frame.args[2])
	
	return #list
end

function p.lstIndex(frame)
	local list = morphList(frame.args[1], frame.args[2])
	local index = tonumber(frame.args[3])
	
	if index > #list then
		return ""
	end
	
	if index <= 0 then
		index = (#list + 1) + index 
	end
	
	return list[index]
end

function p.lstSub(frame)
	local list = morphList(frame.args[1], frame.args[2])
	local output_separator = frame.args[3]
	local start_index = tonumber(frame.args[4])
	local length = tonumber(frame.args[5])
	
	local result_table = {}
	
	if start_index <= 0 then
		start_index = (#list + 1) + start_index
	end
	if length > 0 then
		length = start_index + length - 1
	else
		length = #list + length
	end
	
	for i = start_index, length, 1 do
		result_table[#result_table + 1] = list[i]
	end
	
	return table.concat(result_table, output_separator)
end

function p.lstFind(frame)
	local item = frame.args[1]
	local list = morphList(frame.args[2], frame.args[3])
	local lowerCase = frame.args[4]
	
	if lowerCase == "cs" then
		lowerCase = false
	else
		lowerCase = true
	end
	
	if lowerCase then
		for i = 1, #list, 1 do
			if string.lower(list[i]) == string.lower(item) then
				return list[i]
			end
		end
	else
		for i = 1, #list, 1 do
			if list[i] == item then
				return list[i]
			end
		end
	end
	
	return ""
end

function p.lstApp(frame)
	local separator = frame.args[2]
	local list = morphList(frame.args[1], separator)
	local item = trim(frame.args[3])

	if item ~= "" then
		list[#list+1] = item
	end
	return table.concat(list, separator)
end

function p.lstPrep(frame)
	local separator = frame.args[2]
	local list = morphList(frame.args[3], separator)
	local item = trim(frame.args[1])
	local new_list = {}
	
	if item ~= "" then
		new_list[1] = item
	end
	
	if new_list[1] then
		for i = 1, #list, 1 do
			new_list[i+1] = list[i]
		end
	else
		new_list = list
	end
	
	return table.concat(new_list, separator)
end

function p.lstJoin(frame)
	local first_list = morphList(frame.args[1], frame.args[2])
	local second_list = morphList(frame.args[3], frame.args[4])
	local separator = frame.args[5]
	
	for i = 1, #second_list, 1 do
		first_list[#first_list + 1] = second_list[i]
	end
	
	return table.concat(first_list, separator)
end

function p.lstUniq(frame)
	local mode = frame.args[1]
	local list = morphList(frame.args[2], frame.args[3])
	local separator = frame.args[4]
	local lowerCase = frame.args[5]
	local seen = {}
	
	if lowerCase == "cs" then
		lowerCase = false
	else
		lowerCase = true
	end
	
	for index,item in ipairs(list) do
		if lowerCase then
			if seen[string.lower(item)] then
				table.remove(list, index)
			else
				seen[string.lower(item)] = true
			end
		else
			if seen[item] then
				table.remove(list, index)
			else
				seen[item] = true
			end
		end
	end
	
	if mode == "cnt" then
		return #list
	end
	return table.concat(list, separator)
end

function p.lstSrt(frame)
	local list = morphList(frame.args[1], frame.args[2])
	local separator = frame.args[3]
	local numeric = frame.args[4]
	local reversed = frame.args[5]
	
	if numeric == "y" then
		for i = 1, #list, 1 do
			list[i] = tonumber(list[i])
		end
	end
	table.sort(list)
	if reversed == "y" then
		temp_list = list
		list = {}
		for i = #temp_list, 1, -1 do
			list[#list + 1] = temp_list[i]
		end
	end
	
	return table.concat(list, separator)
end

function p.lstMap(frame)
	local list = morphList(frame.args[1], frame.args[2])
	local token = frame.args[3]
	local pattern = frame.args[4]
	local separator = frame.args[5]
	local mode = frame.args[6]
	local result = {}
	
	for i = 1, #list, 1 do
		result[i] = string.gsub(pattern, token, list[i])
	end
	
	if mode == "np" then
		return table.concat(result, separator)
	else
		return frame:preprocess(table.concat(result, separator))
	end
end

function p.lstFltr(frame)
	local items = morphList(frame.args[1], frame.args[2])
	local list = morphList(frame.args[3], frame.args[4])
	local separator = frame.args[5]
	local lowerCase = frame.args[6]
	local result = {}
	
	if lowerCase == "cs" then
		lowerCase = false
	else
		lowerCase = true
	end
	
	if lowerCase then
		for i = 1, #items, 1 do
			for j = 1, #list, 1 do
				if string.lower(items[i]) == string.lower(list[j]) then
					result[#result+1] = list[j]
				end
			end
		end
	else
		for i = 1, #items, 1 do
			for j = 1, #list, 1 do
				if items[i] == list[j] then
					result[#result+1] = list[j]
				end
			end
		end
	end
	
	return table.concat(result, separator)
end

function p.lstTrm(frame)
	local item = trim(frame.args[1]) or ""
	local list = morphList(frame.args[2], frame.args[3])
	local separator = frame.args[4]
	local lowerCase = frame.args[5]
	local result = {}
	
	if lowerCase == "cs" then
		lowerCase = false
	else
		lowerCase = true
	end
	
	if lowerCase then
		for i = 1, #list, 1 do
			if string.lower(item) ~= string.lower(list[i]) then
				result[#result+1] = list[i]
			end
		end
	else
		for i = 1, #list, 1 do
			if item ~= list[i] then
				result[#result+1] = list[i]
			end
		end
	end
	
	return table.concat(result, separator)
end

return p