Module:Table list

From the RuneScape Wiki, the wiki for all things RuneScape
Jump to navigation Jump to search
Module documentation
This documentation is transcluded from Module:Table list/doc. [edit] [history] [purge]
This module does not have any documentation. Please consider adding documentation at Module:Table list/doc. [edit]
Module:Table list's function main is invoked by Template:Table list.
Module:Table list requires Module:Achievement description.
Module:Table list requires Module:Mw.html extension.
Module:Table list requires Module:Paramtest.
Module:Table list requires Module:Yesno.
Module:Table list requires strict.
Module:Table list is required by Module:AnimalNames.
Function list
L 13 — parse_delim
L 38 — importpage
L 49 — verticalize
L 71 — sorter
L 76 — string_formatter
L 116 — p.main
L 122 — p._main

require("strict");
require('Module:Mw.html extension');
local yn = require("Module:Yesno");
local def = require('Module:Paramtest');

local alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ#'

local p = {}

-- Parses a string to be used as formatting function args
-- Splits on semicolons and then again on key/value pairs in the form
-- <key>:<value> such that we get a table of text entries and key/value pairs
local function parse_delim(t)
	setmetatable(t,{__index={delim=nil}})
    local input, delim =
      t[1] or t.input, 
      t[2] or t.delim
	
	if delim == nil then return {input} end
	
	local u = {}
	for str in string.gmatch(input, "([^"..delim.."]+)") do
		if str:find(":") then
			local v = {}
			for str_ in string.gmatch(str, "([^%:]+)") do
				table.insert(v, str_)
			end
			u[v[1]] = v[2]
		else
			table.insert(u, str)
		end
	end
	return u
end

-- Import entries from existing wikipage
-- NOTE: Functionality is currently undocumented and unused (and broken)
local function importpage(tbl, pageimport)
	local _t = mw.title.new(pageimport)
 	if _t.exists then
		local tsplit = mw.text.split(_t:getContent(),'\n')
 		for _, v in ipairs(tsplit) do
			table.insert(tbl,v)
 		end
 	end
 	return tbl
end
	
local function verticalize(tbl, columns)
	local listsize = #tbl
	local colsize = math.ceil(listsize / columns)
	local leftover = listsize % columns
	if leftover == 0 then leftover = columns end
	-- If this table is not a perfect rectangle, there will be
	-- "leftover" columns of size "colsize" and "columns-leftover"
	-- columns of size "colsize-1" (last row will have "leftover" items)
	local pivoted = {}
	for row = 0, colsize - 1 do
		local thiscolumns = columns
		if row == colsize - 1 then
			thiscolumns = leftover
		end
		for col = 0, thiscolumns - 1 do
			local targetindex = 1 + math.min(leftover, col) * colsize + math.max(0, col-leftover) * (colsize-1) + row
			table.insert(pivoted, tbl[targetindex])
		end
	end
	return pivoted
end

local function sorter(list)
	table.sort(list, function (a,b) return a:lower() < b:lower() end)
	return list
end

local function string_formatter(value, links, delimiter)
	local achivoTableCell = require("Module:Achievement description")._tableCell;
	if links == 'achievements' then
		return achivoTableCell(value) or ("[[" .. value .. "]]");
	end
	
	local parsed = parse_delim{value, delim=delimiter}
	local default = def.default_to(parsed[1], value)
	local pic = def.default_to(parsed.pic, default)
	local plink = def.default_to(parsed.plink, pic)
	local tlink = def.default_to(parsed.tlink, plink)
	local text = def.default_to(parsed.text, tlink)
	local ref = def.default_to(parsed.ref, '')
	
	local _format, _args;
	local base_link = '[[%s|%s]]'
	local base_ref = '%s'
	local base_space = '&nbsp;'
	local base_pic = '[[File:%s.png|link=%s]]'

	if links == 'yes' then
		_format = base_link
		_args = {tlink,text}
	elseif links == 'plink' then
		_format = base_pic..base_space..base_link
		_args = {pic,plink,tlink,text}
	elseif links == 'plinkp' then
		_format = base_pic
		_args = {pic,plink}
	elseif delimiter then
		_format = base_pic..base_space..base_link..base_ref
		_args = {pic, plink, tlink, text, ref}
	else
		_format = base_ref
		_args = {default}
	end
	mw.log(unpack(_args))
	return string.format(_format, unpack(_args))
end

function p.main( frame )
    local invokeArgs = frame.args
    local args = frame:getParent().args
    return p._main( args, invokeArgs )
end

function p._main( args, invokeArgs )
	local columns = def.default_to(tonumber(args.columns), 4)
	local header = def.default_to(args.header, '')
	local pageimport = def.default_to(args.pageimport, '')
	local links = string.lower(def.default_to(args.links, ''))
	local delimiter = args.delimiter
	local sort, highlight, collapsed, vertical, alphaheaders =
		yn(args.sort), yn(args.highlight), yn(args.collapsed), yn(args.vertical), yn(args.alphaheaders)

	local isAchievements = links == 'achievements'
	
	local ret = mw.html.create('table')
		:addClass('wikitable')
		:addClassIf(collapsed, 'mw-collapsed mw-collapsible')
		:addClassIf(highlight, 'lighttable individual')
		:addClass(args.class)
		:cssText(args.style)
		:IF(header ~= '')
			:tr():th{header, attr={'colspan', columns}}:allDone()
		:END()

	local list = {}
	for _, v in ipairs(args) do
		if v:find('%S') then
			table.insert(list, mw.text.trim(v))
		end
	end
	
	if pageimport ~= '' then 
		list = importpage(list, pageimport) 
	end
	
	if sort ~= false then
		list = sorter(list)
	end

	if vertical then 
		list = verticalize(list, columns) 
	end
	
	if isAchievements then
		ret = ret:attr("data-tableid", "Achievements list")
	end

		
	-- Sort entries into subheaders based on the first letter and add a ToC at the top of the table
	-- NOTE: Functionality is currently undocumented and unused
	if alphaheaders then
		local alphalist = {}
		local alphatable = mw.text.split(alphabet,'')
		local toc = {}
			
		for _, v in pairs(alphatable) do
			alphalist[v] = {}
			table.insert(toc,string.format('[[#tl-%s|%s]]',v,v))
		end

		toc = table.concat(toc,' <b>•</b> ')

		for _, v in ipairs(list) do
			local firstletter = mw.text.split(v:upper(),'')[1]
			if alphalist[firstletter] then
				table.insert(alphalist[firstletter],v)
			else
				table.insert(alphalist['#'],v)
			end
		end

		ret:newline():tr():td{toc, attr={'colspan', columns}}

		for _, v in ipairs(alphatable) do
			local letterused = false
			ret:newline():tr():th{v, attr={colspan=columns, id='tl-'..v}}
			
			local newrow
			local i = 0
			for _, value in ipairs(alphalist[v]) do
				letterused = true
				if (i % columns == 0) then
					newrow = ret:newline():tr()
				end
				i = i + 1
				newrow:td(string_formatter(value, links, false))
			end

			local j = i % columns
			if j ~= 0 then
				while j < columns do
					newrow:td{ class = "table-na nohighlight" };
					j = j + 1;
				end
			elseif not letterused then
				ret:newline():tr():td{
					"&nbsp;",
					class = "table-na nohighlight",
					attr = { "colspan", columns },
				};
			end
		end
	else
		for ind, value in ipairs(list) do
			if ((ind-1) % columns == 0) then
				ret:tr()
			end
			ret:td(string_formatter(value, links, delimiter))
		end
		if (#list % columns) ~= 0 then
			for j=(#list%columns)+1,columns do
				ret:td{ class = "table-na nohighlight" }
			end
		end
	end
return ret:allDone()
end
	
return p