Module:Ranking movements
Appearance
This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected. |
This module depends on the following other modules: |
This module uses TemplateStyles: |
This module implements {{Ranking movements}}.
Usage
{{#invoke:Ranking movements|main}}
-- This module implements [[Template:Ranking movements]]
local p = {}
local templatestyles = 'Module:Ranking movements/styles.css'
local colors = {
['+'] = '#D8FFEB',
['-'] = '#FFE6E6',
['not released'] = '#999999'
}
local labels = {
['title'] = 'Ranking movements',
['legend'] = 'Legend',
['week'] = 'Week',
['poll'] = 'Poll',
['pre'] = 'Pre',
['final'] = 'Final',
['not released'] = 'Not released',
['+'] = 'Increase in ranking',
['-'] = 'Decrease in ranking',
['—'] = 'Not ranked',
['RV'] = 'Received votes',
['т'] = 'Tied with team above or below',
['( )'] = 'First-place votes'
}
local legend = {
['+'] = false,
['-'] = false,
['—'] = false,
['RV'] = false,
['т'] = false,
['( )'] = false
}
local function format_cell_text(s)
if s then
if s:match('^[Nn][Rr]') or s:match('^—') then
legend['—'] = true
end
if s:match('^[Rr][Vv]') then
legend['RV'] = true
end
if s:match('%d[%-%s]*[Tt]') or s:match('[Tт]') then
legend['т'] = true
end
if s:match('[%(%)]') then
legend['( )'] = true
end
s = mw.ustring.gsub(s, '^NR', '—')
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 == '') or (lastweek == '')
or (lastweek == 'N/A') or (thisweek == 'N/A') 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' or lastweek == '—') then
legend['+'] = true
return colors['+']
end
-- If last week was RV
if (lastweek == 'RV') then
-- If this week is NR then rank has decreased, otherwise increased
if (thisweek == 'NR' or thisweek == '—') then
legend['-'] = true
return colors['-']
else
legend['+'] = true
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
legend['+'] = true
return colors['+']
end
if (thisweek > lastweek) then
legend['-'] = true
return colors['-']
end
return nil
end
local tracking, preview = {}, {}
local function checkargs(args)
for k, v in pairs(args) do
if v ~= '' then
if k and type(k) == 'string' then
if k:match('^poll[1-6]firstweek$') or k:match('^poll[1-6]lastweek$')
or k:match('^poll[1-6]title$') or k:match('^poll[1-6]_final$') or k == 'title' or k == 'nocat'
or k:match('^wk1?%d$') or k:match('^wk2[01]') then
-- valid
elseif k:match('^poll[1-6]_1?%d$') or k:match('^poll[1-6]_2[01]$') then
-- valid
local i = mw.ustring.gsub(k, '^poll([1-6])_%d+$', '%1')
local j = mw.ustring.gsub(k, '^poll[1-6]_(%d+)$', '%1')
local maxweeks = tonumber(args['poll' .. i .. 'lastweek']) or 20
if tonumber(j) > maxweeks then
table.insert(tracking, '[[Category:Pages using ranking movements with poll after last week|' .. i .. ']]')
end
else
-- invalid
local vlen = mw.ustring.len(k)
k = mw.ustring.sub(k, 1, (vlen < 25) and vlen or 25)
k = mw.ustring.gsub(k, '[^%w\-_ ]', '?')
table.insert(tracking, '[[Category:Pages using ranking movements with unknown parameters|' .. k .. ']]')
table.insert(preview, '"' .. k .. '"')
end
end
end
end
end
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame)
local maxpolls = 6
-- Compute the maximum number of columns
local minweeks = 20
local maxweeks = 0
for k = 1,maxpolls do
local n = tonumber(args['poll' .. k .. 'lastweek']) or (args['poll' .. k .. 'title'] and 20 or 0)
maxweeks = (n > maxweeks) and n or maxweeks
local n = tonumber(args['poll' .. k .. 'firstweek']) or (args['poll' .. k .. 'title'] and 0 or 20)
minweeks = (n < minweeks) and n or minweeks
end
-- Start table
local root = mw.html.create('table')
:addClass('wikitable ranking-movements')
-- Table caption title
local caption = root:tag('caption'):wikitext(args['title'] or labels['title'])
-- Week header row
local row = root:tag('tr')
row:tag('th') -- Blank space in corner
row:tag('th'):attr('colspan', maxweeks - minweeks + 1):wikitext(labels['week'])
-- Poll header row
row = root:tag('tr')
row:tag('th')
:wikitext(labels['poll'])
for k = minweeks,maxweeks do
local text = args['wk' .. k] or k
if (k == 0) then
text = args['wk' .. k] or labels['pre']
elseif (k == maxweeks) then
text = args['wk' .. k] or labels['final']
end
row:tag('th')
: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 20
if ptitle ~= '' then
row = root:tag('tr')
row:tag('th')
:wikitext(ptitle)
-- Before the first poll
if pfirstweek > minweeks then
row:tag('td')
:attr('colspan', pfirstweek - minweeks)
:css('background', colors['not released'])
:wikitext(labels['not released'])
end
-- Results
local lastweek = 'first week'
for k = pfirstweek,plastweek do
local rank = args['poll' .. i .. '_' .. k]
if rank then
rank = mw.ustring.gsub(rank, '^&[MNmn][Dd][Aa][Ss][Hh];', '—')
rank = mw.ustring.gsub(rank, '^[–%-]', '—')
end
local thisweek = get_rank(rank)
row:tag('td')
:css('background', get_color(lastweek, thisweek))
:wikitext(format_cell_text(rank))
lastweek = thisweek
end
-- After the last poll
if plastweek < maxweeks then
rank = args['poll' .. i .. '_final']
local colspan = (maxweeks - plastweek) - (rank and 1 or 0)
row:tag('td')
:attr('colspan', (colspan > 1) and colspan or nil)
:css('background', colors['not released'])
:wikitext(labels['not released'])
if rank and colspan > 0 then
rank = mw.ustring.gsub(rank, '^&[MNmn][Dd][Aa][Ss][Hh];', '—')
rank = mw.ustring.gsub(rank, '^[–%-]', '—')
local thisweek = get_rank(rank)
row:tag('td')
:css('background', get_color(lastweek, thisweek))
:wikitext(format_cell_text(rank))
end
end
end
end
-- Add legend
local line1, line2 = '', ''
if legend['+'] or legend['-'] then
for k,v in ipairs({'+', '-'}) do
line1 = line1 .. ' <span style="color:' .. colors[v] .. '">██</span>'
line1 = line1 .. ' ' .. labels[v]
end
end
for k,v in ipairs({'—', 'RV', 'т', '( )'}) do
if legend[v] then line2 = line2 .. ' ' .. v .. ' = ' .. labels[v] end
end
if line1 ~= '' or line2 ~= '' then
caption:wikitext('<br /><small>\'\'\'' .. labels['legend'] .. ':\'\'\'' .. line1)
if line1 ~= '' and line2 ~= '' then
caption:wikitext('<br />')
end
caption:wikitext(line2 .. '</small>')
end
checkargs(args)
local trackstr = (#tracking > 0) and table.concat(tracking, '') or ''
if #preview > 0 then
trackstr = require('Module:If preview')._warning({
'Unknown parameters ' .. table.concat(preview, '; ') .. '.'
}) .. trackstr
end
return frame:extensionTag{ name = 'templatestyles', args = { src = templatestyles} }
.. tostring(root) .. trackstr
end
return p