Jump to content

Module:Ranking movements

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Frietjes (talk | contribs) at 19:25, 25 February 2022. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

-- This module implements [[Template:Ranking movements]]
local p = {}

local colors = {
	['+'] = '#D8FFEB',
	['-'] = '#FFE6E6',
	['not released'] = '#999999'
}
local labels = {
	['title'] = 'Ranking movements',
	['legend'] = 'Legend',
	['week'] = 'Week',
	['pre'] = 'Pre',
	['final'] = 'Final',
	['not released'] = 'Not released',
	['+'] = 'Increase in ranking.',
	['-'] = 'Decrease in ranking.',
	['NR'] = 'Not ranked',
	['RV'] = 'Received votes.',
	['т'] = 'Tied with team above or below.',
	['( )'] = 'First place votes.'
}

local function format_cell_text(s)
	if s and s == 'NR' then
		return '—'
	end
	return s
end

local function get_rank(s)
	-- This is intended to remove any extra stuff after the ranking
	local result = mw.ustring.match(s or '', '^%d*') or '' -- Is it numbers?
	if result == '' then
		result = mw.ustring.match(s or '', '^%a*') or '' -- Is it letters?
	end
	return result
end

local function get_color(lastweek, thisweek)
	-- No coloring if first week or this week is blank
	if (lastweek == 'first week') or (thisweek == '') then
		return nil
	end
	-- No coloring if the rank has not changes
	if (lastweek == thisweek) then
		return nil
	end
	-- If last week was NR then rank has increased
	if (lastweek == 'NR') then
		return colors['+']
	end
	-- If last week was RV
	if (lastweek == 'NR') then
		-- If this week is NR then rank has decreased, otherwise increased
		if (thisweek == 'NR') then
			return colors['-']
		else
			return colors['+']
		end
	end
	-- In all other cases, just compare the numbers
	lastweek = tonumber(lastweek) or 999999
	thisweek = tonumber(thisweek) or 999999
	if (lastweek > thisweek) then
		return colors['-']
	end
	if (thisweek > lastweek) then
		return colors['+']
	end
	return nil
end

function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame)
	
	local maxpolls = 5
	-- Compute the maximum number of columns
	local maxweeks = 0
	for k = 1,maxpolls do
		local n = tonumber(args['poll' .. k .. 'lastweek']) or 0
		maxweeks = (n > maxweeks) and n or maxweeks
	end

	-- Start table
	local root = mw.html.create('table')
		:addClass('wikitable')
		:css('white-space', 'nowrap')
		:css('text-align', 'center')

	-- Table caption (title and legend)
	local caption = labels['title']
	caption = caption .. '<br /><small>\'\'\'' .. labels['legend'] .. ':\'\'\''
	for k,v in ipairs({'+', '-'}) do
		caption = caption .. ' <span style="color:#' .. colors[v] .. '">██</span>'
		caption = caption .. ' ' .. labels[v]
	end
	caption = caption .. '<br />'
	for k,v in ipairs({'NR', 'RV', 'т', '( )'}) do
		caption = caption .. ' ' .. v .. ' = ' .. labels[v]
	end
	caption = caption .. '</small>'
	root:tag('caption'):wikitext(caption)
	
	-- Week header row
	local row = root:tag('tr')
	row:tag('th') -- Blank space in corner
	row:tag('th'):attr('colspan', maxweeks + 1):wikitext(labels['week'])

	-- Poll header row
	row = root:tag('tr')
	for k = 0,maxweeks do
		local text = k
		if (k == 0) then
			text = labels['pre']
		elseif (k == maxweeks) then
			text = labels['final']
		end
		row:tag('th')
			:css('padding-left', '5px')
			:css('padding-right','5px')	
			:wikitext(text)
	end
	
	-- Poll data rows
	for i = 1,maxpolls do
		local ptitle = args['poll' .. i .. 'title'] or ''
		local pfirstweek = tonumber(args['poll' .. i .. 'firstweek']) or 0
		local plastweek = tonumber(args['poll' .. i .. 'lastweek']) or 0
		if ptitle ~= '' then
			row = root:tag('tr')
			-- Before the first poll
			if pfirstweek > 0 then
				row:tag('td')
					:attr('colspan', pfirstweek)
					:css('background', '#' .. colors['not released'])
					:css('padding-left', '5px')
					:css('padding-right', '5px')
					:wikitext(labels['not released'])
			end
			-- Results
			local lastweek = 'first week'
			for k = pfirstweek,plastweek do
				local thisweek = get_rank(args['poll' .. i .. '_' .. k])
				row:tag('td')
					:css('background', get_color(lastweek, thisweek))
					:css('padding-left', '5px')
					:css('padding-right', '5px')
					:wikitable(format_cell_text(args['poll' .. i .. '_' .. k]))
			end
			-- After the last poll
			if plastweek < maxweeks then
				row:tag('td')
					:attr('colspan', maxweeks - plastweek)
					:css('background', '#' .. colors['not released'])
					:css('padding-left', '5px')
					:css('padding-right', '5px')
					:wikitext(labels['not released'])
			end
		end
	end
	return tostring(root)
end

return p