Jump to content

Module:DartsRankings: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
m Protected "Module:DartsRankings": High-risk template or module: 345 transclusions (more info) ([Edit=Require autoconfirmed or confirmed access] (indefinite))
Update from sandbox (format code and optimize by using Module:Flagg directly
Line 1: Line 1:
require('Module:No globals');
require('Module:No globals');


local p = {}

local p = {}


local error_msg = '<span style=\"font-size:100%\" class=\"error\"><code style=\"color:inherit; border:inherit; padding:inherit;\">&#124;_template=</code> missing or empty</span>';
local error_msg = '<span style=\"font-size:100%\" class=\"error\"><code style=\"color:inherit; border:inherit; padding:inherit;\">&#124;_template=</code> missing or empty</span>';
Line 8: Line 7:
-- data for various rankings held in module subpages, e.g. "Module:SportsRankings/data/FIFA World Rankings"
-- data for various rankings held in module subpages, e.g. "Module:SportsRankings/data/FIFA World Rankings"
local data = {} --[[ parameters containing data help in three tables
local data = {} --[[ parameters containing data help in three tables
data.source = {} -- parameters for using in cite web (title, url, website)
data.source = {} -- parameters for using in cite web (title, url, website)
data.updated = {} -- date of latest update (month, day, year)
data.updated = {} -- date of latest update (month, day, year)
data.rankings = {} -- the rankings list (country code, ranking, movement)
data.rankings = {} -- the rankings list (country code, ranking, movement)
data.alias = {} -- player list (player, country code [=key], wiki link, proper display)
data.alias = {} -- player list (player, country code [=key], wiki link, proper display)
--]]
local tcats= ''
local tcatsp=''
local templateArgs = {} -- contains arguments from template involking module


--]]
local tcats = ''
local tcatsp = ''
local templateArgs = {} -- contains arguments from template involking module


local function getArgs(frame)
local function getArgs(frame)
local parents = mw.getCurrentFrame():getParent()
local parents = mw.getCurrentFrame():getParent()

for k,v in pairs(parents.args) do
for k,v in pairs(parents.args) do
--check content
--check content
if v and v ~= "" then
if v and v ~= "" then
templateArgs[k]=v --parents.args[k]
templateArgs[k] = v --parents.args[k]
end
end
end
end
for k,v in pairs(frame.args) do
for k,v in pairs(frame.args) do
--check content
--check content
if v and v ~= "" then
if v and v ~= "" then
templateArgs[k]=v --parents.args[k]
templateArgs[k] = v --parents.args[k]
end
end
end
end
-- allow empty caption to blank default
-- allow empty caption to blank default
if parents.args['caption'] then templateArgs['caption'] = parents.args['caption'] end
if parents.args['caption'] then templateArgs['caption'] = parents.args['caption'] end
end
end


local function loadData(frame)
local function loadData(frame)
local source = frame.args[1] -- source of rankings e.g. PDC Rankings
local source = frame.args[1] -- source of rankings e.g. PDC Rankings
data = require('Module:DartsRankings/data/'.. source);
data = require('Module:DartsRankings/data/'.. source);
if templateArgs['org'] then
if templateArgs['org'] then
data = require('Module:DartsRankings/data/' .. templateArgs['org'] .. ' Rankings');
data = require('Module:DartsRankings/data/' .. templateArgs['org'] .. ' Rankings');
end
end
end
end


local function getDate(option)
local function getDate(option)
local dateTable = data.updated -- there must be date table (data.updated)
-- TODO add a warning and/or category
local dateTable = data.updated -- there must be date table (data.updated)
if option == "LAST" then
-- TODO add a warning and/or category
local lastDateTable = data.previous
if option == "LAST" then
local lastDateTable = data.previous
if lastDateTable then -- there might not be a previous data table (data.previous)
dateTable = lastDateTable
if lastDateTable then -- there might not be a previous data table (data.previous)
else
dateTable = lastDateTable
return "No previous date available (data.updated missing)"
else
end
return "No previous date available (data.updated missing)"
end
end

end
if templateArgs['mdy'] and templateArgs['mdy'] ~= "" then
if templateArgs['mdy'] and templateArgs['mdy'] ~= "" then
return dateTable['month'] .. " " .. dateTable['day'] .. ", " .. dateTable['year']
else
return dateTable['month'] .. " " .. dateTable['day'] .. ", " .. dateTable['year']
return dateTable['day'] .. " " .. dateTable['month'] .. " " .. dateTable['year']
else
end
return dateTable['day'] .. " " .. dateTable['month'] .. " " .. dateTable['year']
end
end
end


local function addCiteWeb(frame) -- use cite web template
local function addCiteWeb(frame) -- use cite web template
return frame:expandTemplate{ title = 'cite web' , args = {
url = data.source['url'], --"https://www.fifa.com/fifa-world-ranking/ranking-table/men/index.html",
return frame:expandTemplate{ title = 'cite web' , args = {
url = data.source['url'], --"https://www.fifa.com/fifa-world-ranking/ranking-table/men/index.html",
title = data.source['title'], -- "The FIFA/Coca-Cola World Ranking",
title = data.source['title'], -- "The FIFA/Coca-Cola World Ranking",
website = data.source['website'], --"FIFA",
['date'] = getDate(),
website = data.source['website'], --"FIFA",
['date'] = getDate(),
['access-date'] = getDate()
}}
['access-date'] = getDate()
}}
end
end

local function addReference(frame)
local function addReference(frame)
local text = ""
if data.source['text'] then text = data.source['text'] end
local text = ""
if data.source['text'] then text = data.source['text'] end
return frame:expandTemplate{ title = 'refn' , args = {
name=frame.args[1], --ranking used, e.g. "PDC Rankings",
text .. addCiteWeb(frame)
}}


return frame:expandTemplate{ title = 'refn', args = {
name=frame.args[1], --ranking used, e.g. "PDC Rankings",
text .. addCiteWeb(frame)
}}
end
end


local function noAc(str)
local function noAc(str)
local tableAccents = {}
local tableAccents = {
tableAccents["À"] = "A"
["À"] = "A",
tableAccents["Á"] = "A"
["Á"] = "A",
tableAccents["Â"] = "A"
["Â"] = "A",
tableAccents["Ã"] = "A"
["Ã"] = "A",
tableAccents["Ä"] = "A"
["Ä"] = "A",
tableAccents["Å"] = "A"
["Å"] = "A",
tableAccents["Æ"] = "AE"
["Æ"] = "AE",
tableAccents["Ç"] = "C"
["Ç"] = "C",
tableAccents["È"] = "E"
["È"] = "E",
tableAccents["É"] = "E"
["É"] = "E",
tableAccents["Ê"] = "E"
["Ê"] = "E",
tableAccents["Ë"] = "E"
["Ë"] = "E",
tableAccents["Ì"] = "I"
["Ì"] = "I",
tableAccents["Í"] = "I"
["Í"] = "I",
tableAccents["Î"] = "I"
["Î"] = "I",
tableAccents["Ï"] = "I"
["Ï"] = "I",
tableAccents["Ð"] = "D"
["Ð"] = "D",
tableAccents["Ñ"] = "N"
["Ñ"] = "N",
tableAccents["Ò"] = "O"
["Ò"] = "O",
tableAccents["Ó"] = "O"
["Ó"] = "O",
tableAccents["Ô"] = "O"
["Ô"] = "O",
tableAccents["Õ"] = "O"
["Õ"] = "O",
tableAccents["Ö"] = "O"
["Ö"] = "O",
tableAccents["ő"] = "O"
["ő"] = "O",
tableAccents["Ø"] = "O"
["Ø"] = "O",
tableAccents["Ù"] = "U"
["Ù"] = "U",
tableAccents["Ú"] = "U"
["Ú"] = "U",
tableAccents["Û"] = "U"
["Û"] = "U",
tableAccents["Ü"] = "U"
["Ü"] = "U",
tableAccents["Ý"] = "Y"
["Ý"] = "Y",
tableAccents["Þ"] = "P"
["Þ"] = "P",
tableAccents["ß"] = "s"
["ß"] = "s",
tableAccents["à"] = "a"
["à"] = "a",
tableAccents["á"] = "a"
["á"] = "a",
tableAccents["â"] = "a"
["â"] = "a",
tableAccents["ã"] = "a"
["ã"] = "a",
tableAccents["ä"] = "a"
["ä"] = "a",
tableAccents["å"] = "a"
["å"] = "a",
tableAccents["æ"] = "ae"
["æ"] = "ae",
tableAccents["ç"] = "c"
["ç"] = "c",
tableAccents["č"] = "c"
["č"] = "c",
tableAccents["ć"] = "c"
["ć"] = "c",
tableAccents["è"] = "e"
["è"] = "e",
tableAccents["é"] = "e"
["é"] = "e",
tableAccents["ê"] = "e"
["ê"] = "e",
tableAccents["ë"] = "e"
["ë"] = "e",
tableAccents["ì"] = "i"
["ì"] = "i",
tableAccents["í"] = "i"
["í"] = "i",
tableAccents["î"] = "i"
["î"] = "i",
tableAccents["ï"] = "i"
["ï"] = "i",
tableAccents["ł"] = "l"
["ł"] = "l",
tableAccents["ð"] = "eth"
["ð"] = "eth",
tableAccents["ñ"] = "n"
["ñ"] = "n",
tableAccents["ò"] = "o"
["ò"] = "o",
tableAccents["ó"] = "o"
["ó"] = "o",
tableAccents["ô"] = "o"
["ô"] = "o",
tableAccents["õ"] = "o"
["õ"] = "o",
tableAccents["ö"] = "o"
["ö"] = "o",
tableAccents["ø"] = "o"
["ø"] = "o",
tableAccents["ù"] = "u"
["ù"] = "u",
tableAccents["ú"] = "u"
["ú"] = "u",
tableAccents["û"] = "u"
["û"] = "u",
tableAccents["ü"] = "u"
["ü"] = "u",
tableAccents["ý"] = "y"
["ý"] = "y",
tableAccents["þ"] = "p"
["þ"] = "p",
tableAccents["ÿ"] = "y"
["ÿ"] = "y"
}

local normalisedString = ''

local normalisedString = str: gsub("[%z\1-\127\194-\244][\128-\191]*", tableAccents)

return normalisedString


return str:gsub("[%z\1-\127\194-\244][\128-\191]*", tableAccents)
end
end


local function nameEqual(str1, str2)
local function nameEqual(str1, str2)
return string.lower(noAc(str1)):gsub( "%W", "")==string.lower(noAc(str2)):gsub( "%W", "")
return string.lower(noAc(str1)):gsub("%W", "") == string.lower(noAc(str2)):gsub("%W", "")
end
end


function p.dates(frame)
function p.dates(frame)
getArgs(frame) -- returns args table having checked for content
getArgs(frame) -- returns args table having checked for content
loadData(frame)
loadData(frame)

-- if templateArgs[1]==1 then
-- if templateArgs[1]==1 then
return getDate(templateArgs[2])
return getDate(templateArgs[2])
-- else
-- else
-- return getDate()
-- return getDate()
-- end
-- end
end
end


local function flagPlayer(frame, player, side)
local function flagPlayer(frame, player, side)

local outputString = ""
local outputString = ""
local flag, link = '', ''
local flag, link = '', ''
if player and player ~= '' then link = '[[' .. player .. ']]'
if player and player ~= '' then link = '[[' .. player .. ']]'
tcatsp='[[Category:Pages using DartsRankings with missing player data|' .. player .. ']]'
tcatsp='[[Category:Pages using DartsRankings with missing player data|' .. player .. ']]'
end
end
for _,u in pairs(data.alias) do -- get country code from name
for _,u in pairs(data.alias) do -- get country code from name
if nameEqual(u[1], player) then
if nameEqual(u[1], player) then
tcatsp=''
tcatsp=''
local nlink = ""
local nlink = ""
if u[5] == 0 then nlink = 1 end
if u[5] == 0 then nlink = 1 end
if templateArgs['nolink'] == '1' then nlink = 1 end
if templateArgs['nolink'] == '1' then nlink = 1 end
if templateArgs['nolink'] == '0' then nlink = "" end
if templateArgs['nolink'] == '0' then nlink = "" end
if templateArgs['surname'] =='1' then
if u[6] and u[6]~="" then
link = '[[' .. u[3] .. ' ' .. u[4] .. ' (' ..u[6] .. ')' .. '|' .. u[4] ..']]'
else
link = '[[' .. u[3] .. ' ' .. u[4] .. '|' .. u[4] ..']]'
end
elseif templateArgs['surname'] then
if u[6] and u[6]~="" then
link = '[[' .. u[3] .. ' ' .. u[4] .. ' (' ..u[6] .. ')' .. '|' .. templateArgs['surname'] ..']]'
else
link = '[[' .. u[3] .. ' ' .. u[4] .. '|' .. templateArgs['surname'] ..']]'
end
else
if u[6] and u[6]~="" then
link = frame:expandTemplate{title= 'sortname', args ={ u[3], u[4] , dab = u[6] , nolink = nlink } }
else
link = frame:expandTemplate{title= 'sortname', args ={ u[3], u[4], nolink = nlink } }
end
end
flag= u[2] -- Flag string from libarary


if templateArgs['surname'] =='1' then
if u[6] and u[6]~="" then
end
link = '[[' .. u[3] .. ' ' .. u[4] .. ' (' ..u[6] .. ')' .. '|' .. u[4] ..']]'
if templateArgs['flag'] then
else
flag = templateArgs['flag']
link = '[[' .. u[3] .. ' ' .. u[4] .. '|' .. u[4] ..']]'
end
end
end
elseif templateArgs['surname'] then
if side == 'right' then
if u[6] and u[6]~="" then
outputString = link .. frame:expandTemplate{title= 'flagg', args ={ 'csxr', flag}}
link = '[[' .. u[3] .. ' ' .. u[4] .. ' (' ..u[6] .. ')' .. '|' .. templateArgs['surname'] ..']]'
elseif side == 'none' then
else
outputString = link
link = '[[' .. u[3] .. ' ' .. u[4] .. '|' .. templateArgs['surname'] ..']]'
else
end
outputString = frame:expandTemplate{title= 'flagg', args ={ 'csx', flag}} .. link
else
end
if u[6] and u[6]~="" then
tcats = tcats .. tcatsp
link = frame:expandTemplate{title= 'sortname', args ={ u[3], u[4] , dab = u[6] , nolink = nlink } }
else
link = frame:expandTemplate{title= 'sortname', args ={ u[3], u[4], nolink = nlink } }
end

end
flag= u[2] -- Flag string from libarary
end
if templateArgs['flag'] then
flag = templateArgs['flag']
end
end
if side == 'right' then
outputString = link .. require('Module:Flagg').luaMain(frame, {'csxr', flag})
elseif side == 'none' then
outputString = link
else
outputString = require('Module:Flagg').luaMain(frame, {'csx', flag}) .. link
end
tcats = tcats .. tcatsp
return outputString .. tcats
return outputString .. tcats
end
end


Line 240: Line 225:
getArgs(frame) -- returns args table having checked for content
getArgs(frame) -- returns args table having checked for content
loadData(frame)
loadData(frame)
return flagPlayer(frame, frame.args[2], 'left')
return flagPlayer(frame, frame.args[2], 'left')
end
end


Line 246: Line 231:
getArgs(frame) -- returns args table having checked for content
getArgs(frame) -- returns args table having checked for content
loadData(frame)
loadData(frame)
return flagPlayer(frame, frame.args[2], 'right')
return flagPlayer(frame, frame.args[2], 'right')
end
end


Line 252: Line 237:
getArgs(frame) -- returns args table having checked for content
getArgs(frame) -- returns args table having checked for content
loadData(frame)
loadData(frame)
return flagPlayer(frame, frame.args[2], 'none')
return flagPlayer(frame, frame.args[2], 'none')
end
end


function p.main(frame)
function p.main(frame)
getArgs(frame) -- returns args table having checked for content
getArgs(frame) -- returns args table having checked for content
loadData(frame)
loadData(frame)
Line 263: Line 247:
local player = templateArgs[2] -- player name passed as parameter
local player = templateArgs[2] -- player name passed as parameter
local rank, move
local rank, move

for _,u in pairs(data.alias) do -- run through the list
for _,u in pairs(data.alias) do -- run through the list
if nameEqual(u[1], player) then -- if code = passed parameter
if nameEqual(u[1], player) then -- if code = passed parameter
validCode = true
validCode = true
break
break
end
end
end
end
-- if no match of code to country name, set category
-- if no match of code to country name, set category


for _,v in pairs(data.rankings) do
for _,v in pairs(data.rankings) do
if nameEqual(v[1], player) then
if nameEqual(v[1], player) then
rank = v[2] -- get rank
rank = v[2] -- get rank
break
break
end
end
end
end

if rank then -- no ranking found
if rank then -- no ranking found


for _,v in pairs(data.rankingsold) do
for _,v in pairs(data.rankingsold) do
if nameEqual(v[1], player) then
if nameEqual(v[1], player) then
move = v[2] - rank -- get move from last ranking
move = v[2] - rank -- get move from last ranking
break
break
else
else
move = 0 - rank
move = 0 - rank
end
end
end
end
else
else
rank = 'NR'
rank = 'NR'
end
end


local changeString = ""
local changeString = ""

if rank ~= 'NR' then
if rank ~= 'NR' then
outputString = rank
outputString = rank
if move < 0 and math.abs( move ) == math.abs( rank ) then -- new teams in ranking: move = -ranking
if move < 0 and math.abs( move ) == math.abs( rank ) then -- new teams in ranking: move = -ranking
changeString = frame:expandTemplate{ title = 'new entry' }
changeString = frame:expandTemplate{ title = 'new entry' }
elseif move == 0 then -- if no change in ranking
elseif move == 0 then -- if no change in ranking
changeString = frame:expandTemplate{ title = 'steady' }
changeString = frame:expandTemplate{ title = 'steady' }
elseif move < 0 then -- if ranking down
elseif move < 0 then -- if ranking down
changeString = frame:expandTemplate{ title = 'decrease' } .. ' ' .. math.abs(move)
changeString = frame:expandTemplate{ title = 'decrease' } .. ' ' .. math.abs(move)
elseif move > 0 then -- if ranking up
elseif move > 0 then -- if ranking up
changeString = frame:expandTemplate{ title = 'increase' } .. ' ' .. move
changeString = frame:expandTemplate{ title = 'increase' } .. ' ' .. move
end
end
if not templateArgs['nochange'] or templateArgs['nochange'] == "" then
if not templateArgs['nochange'] or templateArgs['nochange'] == "" then
outputString = outputString .. ' ' .. changeString
outputString = outputString .. ' ' .. changeString
end
end
else
else
outputString = outputString .. frame:expandTemplate{ title = 'Abbr', args = { "NR", "Not ranked"} }
outputString = outputString .. frame:expandTemplate{ title = 'Abbr', args = { "NR", "Not ranked"} }
-- {{Abbr|NR|Not ranked}}
-- {{Abbr|NR|Not ranked}}
end
end

if not templateArgs['nodate'] or templateArgs['nodate'] == "" then
outputString = outputString .. ' <small>(' .. getDate() .. ')</small>'
end
if templateArgs['par'] and templateArgs['par'] ~= '' then
outputString = '(' .. outputString .. ')'
end
if not templateArgs['noref'] or templateArgs['noref'] == "" then
outputString = outputString .. addReference(frame)
end


if not templateArgs['nodate'] or templateArgs['nodate'] == "" then
outputString = outputString .. ' <small>(' .. getDate() .. ')</small>'
end
if templateArgs['par'] and templateArgs['par'] ~= '' then
outputString = '(' .. outputString .. ')'
end
if not templateArgs['noref'] or templateArgs['noref'] == "" then
outputString = outputString .. addReference(frame)
end
return outputString
return outputString
end
end


function p.rankOnly(frame)
function p.rankOnly(frame)
getArgs(frame) -- returns args table having checked for content
getArgs(frame) -- returns args table having checked for content
loadData(frame)
loadData(frame)
Line 337: Line 319:
local rank ='NR'
local rank ='NR'
local move
local move

for _,u in pairs(data.alias) do -- run through the list
for _,u in pairs(data.alias) do -- run through the list
if nameEqual(u[1], player) then -- if code = passed parameter
if nameEqual(u[1], player) then -- if code = passed parameter
validCode = true
validCode = true
break
break
end
end
end
-- if no match of code to country name, set category
end
-- if no match of code to country name, set category


for _,v in pairs(data.rankings) do
for _,v in pairs(data.rankings) do
if nameEqual(v[1], player) then
if nameEqual(v[1], player) then
rank = v[2] -- get rank
rank = v[2] -- get rank
break
break
end
end
end
end

return rank
return rank
end
end


--[[ outputs a table of the rankings
--[[ outputs a table of the rankings
called by list() or list2()
called by list() or list2()
positional parameters - |ranking|first|last the ranking to use, fist and last in table
positional parameters - |ranking|first|last the ranking to use, fist and last in table
other parameters: |style= -- CSS styling
other parameters: |style= -- CSS styling
|headerN= footerN= -- displays header and footer rows with additional information
|headerN= footerN= -- displays header and footer rows with additional information
|caption= -- value of caption to display
|caption= -- value of caption to display
-- by default it generates a caption
-- by default it generates a caption
-- this can be suppressed with empty |caption=
-- this can be suppressed with empty |caption=
]]
]]
local function table(frame, ranking, first,last)
local function table(frame, ranking, first,last)
Line 371: Line 351:
local styleString = ""
local styleString = ""
if templateArgs['style'] and templateArgs['style'] ~= "" then styleString = templateArgs['style'] end
if templateArgs['style'] and templateArgs['style'] ~= "" then styleString = templateArgs['style'] end

local lastRank = 0
local lastRank = 0
local selectCount = 0
local selectCount = 0
Line 377: Line 357:
local selectList = nil
local selectList = nil



-- column header customisation
-- column header customisation
local rankHeader = templateArgs['rank_header'] or "Rank"
local rankHeader = templateArgs['rank_header'] or "Rank"
Line 385: Line 365:
local changeHeader = templateArgs['change_header'] or "Change"
local changeHeader = templateArgs['change_header'] or "Change"
local noChange = templateArgs['change_col'] or 1
local noChange = templateArgs['change_col'] or 1

--start table
--start table
local outputString = '{| class="wikitable" style="text-align:center;' .. styleString .. '"'
local outputString = '{| class="wikitable" style="text-align:center;' .. styleString .. '"'

local tabletitle = data.labels['title']
local tabletitle = data.labels['title']
-- add default or custom caption
-- add default or custom caption
local caption = tabletitle .. ' as of ' .. getDate() .. '.'
local caption = tabletitle .. ' as of ' .. getDate() .. '.'
if templateArgs['caption'] and templateArgs['caption'] ~= "" then
if templateArgs['caption'] and templateArgs['caption'] ~= "" then
caption = templateArgs['caption']
caption = templateArgs['caption']
caption = p.replaceKeywords(caption)
caption = p.replaceKeywords(caption)
end
end
outputString = outputString .. '\n|+' .. caption .. addReference(frame)
outputString = outputString .. '\n|+' .. caption .. addReference(frame)

-- add header rows (logo, date of update etc)
-- add header rows (logo, date of update etc)
local count = 0
local count = 0
Line 404: Line 384:
if selectList then tableWidth = 5 end
if selectList then tableWidth = 5 end
while count < 5 do
while count < 5 do
count = count + 1
count = count + 1
if templateArgs['header'..count] then
if templateArgs['header'..count] then
header[count] = templateArgs['header'..count]
header[count] = templateArgs['header'..count]
header[count] = p.replaceKeywords( header[count])
header[count] = p.replaceKeywords( header[count])
outputString = outputString .. '\n|-\n| colspan="'.. tableWidth .. '" |' .. header[count]
outputString = outputString .. '\n|-\n| colspan="'.. tableWidth .. '" |' .. header[count]
end
end
end
end

-- add the add part of the table
-- add the add part of the table
local optionalColumn = ""
local optionalColumn = ""
if selectList then
if selectList then
optionalColumn = '\n!' .. selectionHeader
optionalColumn = '\n!' .. selectionHeader
end
end
outputString = outputString .. '\n|-' .. optionalColumn
outputString = outputString .. '\n|-' .. optionalColumn .. '\n!' .. rankHeader
if noChange == 1 then
.. '\n!' .. rankHeader
outputString = outputString .. '\n!' .. changeHeader
if noChange == 1 then
end
outputString = outputString .. '\n!' .. changeHeader
outputString = outputString .. '\n!' .. teamHeader .. '\n!' .. pointsHeader
end

outputString = outputString .. '\n!' .. teamHeader .. '\n!' .. pointsHeader
local change,player,plink = '', '', ''
local change,player,plink = '', '', ''
--while i<last do
--while i<last do
for k,v in pairs(data.rankings) do
for k,v in pairs(data.rankings) do
--v[2] = tonumber(v[2])
--v[2] = tonumber(v[2])
if v[2] >= first and v[2] <= last then
if v[2] >= first and v[2] <= last then


plink = flagPlayer(frame, v[1], 'left')
plink = flagPlayer(frame, v[1], 'left')
local continue = true
if continue ==true then
local rowString = '\n|-'
if selectList then
local selectRank = selectCount
if v[2]==lastRank then selectRank = selectCount -1 end -- only handles two at same rank
rowString = rowString .. '\n|' .. selectRank
selectCount = selectCount + 1
end
rowString = rowString .. '\n|' .. v[2] -- rank
lastRank = v[2]
local move = nil
for _,w in pairs(data.rankingsold) do
if nameEqual(w[1], v[1]) then
move = w[2] - lastRank -- get move from last ranking
break
else
move = 0 - lastRank
end
end
if move < 0 and math.abs( move ) == math.abs( v[2] ) then -- new teams in ranking: move = -ranking
change = frame:expandTemplate{ title = 'new entry' }
elseif move == 0 then -- if no change in ranking
change = frame:expandTemplate{ title = 'steady' }
elseif move < 0 then -- if ranking down
change = frame:expandTemplate{ title = 'decrease' } .. ' ' .. math.abs(move)
elseif move > 0 then -- if ranking up
change = frame:expandTemplate{ title = 'increase' } .. ' ' .. move
end
if noChange == 1 then


local continue = true
rowString = rowString .. '||' .. change
end


if continue ==true then

local rowString = '\n|-'
if selectList then
local selectRank = selectCount
if v[2]==lastRank then selectRank = selectCount -1 end -- only handles two at same rank
rowString = rowString .. '\n|' .. selectRank
selectCount = selectCount + 1
end
rowString = rowString .. '\n|' .. v[2] -- rank
lastRank = v[2]

local move = nil

for _,w in pairs(data.rankingsold) do
if nameEqual(w[1], v[1]) then
move = w[2] - lastRank -- get move from last ranking
break
else
move = 0 - lastRank
end
end

if move < 0 and math.abs( move ) == math.abs( v[2] ) then -- new teams in ranking: move = -ranking
change = frame:expandTemplate{ title = 'new entry' }
elseif move == 0 then -- if no change in ranking
change = frame:expandTemplate{ title = 'steady' }
elseif move < 0 then -- if ranking down
change = frame:expandTemplate{ title = 'decrease' } .. ' ' .. math.abs(move)
elseif move > 0 then -- if ranking up
change = frame:expandTemplate{ title = 'increase' } .. ' ' .. move
end
if noChange == 1 then

rowString = rowString .. '||' .. change
end


rowString = rowString .. '\n|style="text-align:left"|' .. plink

local points = ""
if v[3] then points = v[3] end
rowString = rowString .. '||' .. points -- country for now, later points
outputString = outputString .. rowString
end
end
end


rowString = rowString .. '\n|style="text-align:left"|' .. plink
local points = ""
if v[3] then points = v[3] end
rowString = rowString .. '||' .. points -- country for now, later points
outputString = outputString .. rowString
end
end
end
-- add footer rows
-- add footer rows
count = 0
count = 0
local footer = {}
local footer = {}
while count < 5 do
while count < 5 do
count = count + 1
count = count + 1
if templateArgs['footer'..count] then
if templateArgs['footer'..count] then
footer[count] = templateArgs['footer'..count]
footer[count] = templateArgs['footer'..count]
footer[count] = p.replaceKeywords(footer[count])
footer[count] = p.replaceKeywords(footer[count])
outputString = outputString .. '\n|-\n| colspan="'.. tableWidth .. '" |' .. footer[count]
outputString = outputString .. '\n|-\n| colspan="'.. tableWidth .. '" |' .. footer[count]
end
end
end
end


Line 497: Line 476:


return outputString
return outputString
end
end

function p.replaceKeywords(keyword)
function p.replaceKeywords(keyword)
keyword = string.gsub( keyword, "INSERT_UPDATE_DATE", getDate())
keyword = string.gsub( keyword, "INSERT_UPDATE_DATE", getDate())
keyword = string.gsub( keyword, "INSERT_LAST_DATE", getDate("LAST"))
keyword = string.gsub( keyword, "INSERT_LAST_DATE", getDate("LAST"))
keyword = string.gsub( keyword, "INSERT_REFERENCE", addReference(mw.getCurrentFrame()))
keyword = string.gsub( keyword, "INSERT_REFERENCE", addReference(mw.getCurrentFrame()))
return keyword
return keyword
end
end


--[[ create a table of rankings
--[[ create a table of rankings
parameters: |ranking= -- ranking to display (e.g. FIFA World Rankings)
parameters: |ranking= -- ranking to display (e.g. FIFA World Rankings)
|first= |last= -- first and last ranking to display (defaults 1-10)
|first= |last= -- first and last ranking to display (defaults 1-10)
]]
]]
function p.list(frame)
function p.list(frame)


getArgs(frame) -- returns args table having checked for content
getArgs(frame) -- returns args table having checked for content
loadData(frame)
loadData(frame)
local ranking = frame.args[1]
local ranking = frame.args[1]
local first, last = 1,10
local first, last = 1,10
first = tonumber(frame.args['2'])
first = tonumber(frame.args['2'])
last = tonumber(frame.args['3'])
last = tonumber(frame.args['3'])

return table(frame, ranking, first, last)
return table(frame, ranking, first, last)
end
end
Line 528: Line 507:
local selectData = nil
local selectData = nil
local selectList = nil
local selectList = nil

--start list
--start list
local outputString = '<ol start="' .. first .. '">'
local outputString = '<ol start="' .. first .. '">'

local change,player,plink = '', '', ''
local change,player,plink = '', '', ''
for k,v in pairs(data.rankings) do
for k,v in pairs(data.rankings) do
if v[2] >= first and v[2] <= last then
if v[2] >= first and v[2] <= last then
plink = flagPlayer(frame, v[1], 'left')
plink = flagPlayer(frame, v[1], 'left')
local rowString = '<li>' -- rank
local rowString = '<li>' -- rank
lastRank = v[2]
lastRank = v[2]
rowString = rowString .. plink
rowString = rowString .. plink

if not templateArgs['nochange'] or templateArgs['nochange'] == "" then

local move = nil
for _,w in pairs(data.rankingsold) do
if nameEqual(w[1], v[1]) then
move = w[2] - lastRank -- get move from last ranking
break
else
move = 0 - lastRank
end
end

if move < 0 and math.abs( move ) == math.abs( v[2] ) then -- new teams in ranking: move = -ranking
change = frame:expandTemplate{ title = 'new entry' }
elseif move == 0 then -- if no change in ranking
change = frame:expandTemplate{ title = 'steady' }
elseif move < 0 then -- if ranking down
change = frame:expandTemplate{ title = 'decrease' }
elseif move > 0 then -- if ranking up
change = frame:expandTemplate{ title = 'increase' }
end
rowString = rowString .. ' ' .. change .. '</li>'
end

outputString = outputString .. '\n'.. rowString
end
end
outputString = outputString .. '</ol>'


if not templateArgs['nochange'] or templateArgs['nochange'] == "" then
local move = nil
for _,w in pairs(data.rankingsold) do
if nameEqual(w[1], v[1]) then
move = w[2] - lastRank -- get move from last ranking
break
else
move = 0 - lastRank
end
end
if move < 0 and math.abs( move ) == math.abs( v[2] ) then -- new teams in ranking: move = -ranking
change = frame:expandTemplate{ title = 'new entry' }
elseif move == 0 then -- if no change in ranking
change = frame:expandTemplate{ title = 'steady' }
elseif move < 0 then -- if ranking down
change = frame:expandTemplate{ title = 'decrease' }
elseif move > 0 then -- if ranking up
change = frame:expandTemplate{ title = 'increase' }
end
rowString = rowString .. ' ' .. change .. '</li>'
end
outputString = outputString .. '\n'.. rowString
end
end
outputString = outputString .. '</ol>'
return outputString
return outputString
end
end


Line 576: Line 554:
--- Returns text list for players first,last for PDC top 20 navbox
--- Returns text list for players first,last for PDC top 20 navbox
function p.nav(frame)
function p.nav(frame)

getArgs(frame) -- returns args table having checked for content
getArgs(frame) -- returns args table having checked for content
loadData(frame)
loadData(frame)
local ranking = frame.args[1]
local ranking = frame.args[1]
local first, last = 1,10
local first, last = 1,10
first = tonumber(frame.args['2'])
first = tonumber(frame.args['2'])
last = tonumber(frame.args['3'])
last = tonumber(frame.args['3'])

return navlist(frame, ranking, first, last)
return navlist(frame, ranking, first, last)
end
end



return p
return p

Revision as of 20:06, 2 January 2022

require('Module:No globals');

local p = {}

local error_msg = '<span style=\"font-size:100%\" class=\"error\"><code style=\"color:inherit; border:inherit; padding:inherit;\">&#124;_template=</code> missing or empty</span>';

-- data for various rankings held in module subpages, e.g. "Module:SportsRankings/data/FIFA World Rankings"
local data = {}      --[[ parameters containing data help in three tables
data.source = {}     -- parameters for using in cite web (title, url, website)
data.updated = {}    -- date of latest update (month, day, year)
data.rankings = {}   -- the rankings list (country code, ranking, movement)
data.alias = {}      -- player list (player, country code [=key], wiki link, proper display)

--]]
local tcats = ''
local tcatsp = ''
local templateArgs = {} -- contains arguments from template involking module

local function getArgs(frame)
    local parents = mw.getCurrentFrame():getParent()

    for k,v in pairs(parents.args) do
        --check content
        if v and v ~= "" then
            templateArgs[k] = v --parents.args[k]
        end
    end
    for k,v in pairs(frame.args) do
        --check content
        if v and v ~= "" then
            templateArgs[k] = v --parents.args[k]
        end
    end
    -- allow empty caption to blank default
    if parents.args['caption'] then templateArgs['caption'] = parents.args['caption'] end
end

local function loadData(frame)
    local source = frame.args[1] -- source of rankings e.g. PDC Rankings
    data = require('Module:DartsRankings/data/'.. source);
    if templateArgs['org'] then
        data = require('Module:DartsRankings/data/' .. templateArgs['org'] .. ' Rankings');
    end
end

local function getDate(option)
    local dateTable = data.updated         -- there must be date table (data.updated)
    -- TODO add a warning and/or category
    if option == "LAST" then
        local lastDateTable = data.previous
        if lastDateTable then             -- there might not be a previous data table (data.previous)
            dateTable = lastDateTable
        else
            return "No previous date available (data.updated missing)"
        end
    end

    if templateArgs['mdy'] and templateArgs['mdy'] ~= "" then
        return dateTable['month'] .. " " .. dateTable['day'] .. ", " .. dateTable['year']
    else
        return dateTable['day'] .. " " .. dateTable['month'] .. " " .. dateTable['year']
    end
end

local function addCiteWeb(frame)  -- use cite web template
    return frame:expandTemplate{ title = 'cite web' , args = {
        url = data.source['url'],            --"https://www.fifa.com/fifa-world-ranking/ranking-table/men/index.html",
        title = data.source['title'],        -- "The FIFA/Coca-Cola World Ranking",
        website = data.source['website'],    --"FIFA",
        ['date'] = getDate(),
        ['access-date'] = getDate()
    }}
end

local function addReference(frame)
    local text = ""
    if data.source['text'] then text = data.source['text'] end

    return frame:expandTemplate{ title = 'refn', args = {
        name=frame.args[1],                   --ranking used, e.g. "PDC Rankings",
        text .. addCiteWeb(frame)
    }}
end

local function noAc(str)
    local tableAccents = {
        ["À"] = "A",
        ["Á"] = "A",
        ["Â"] = "A",
        ["Ã"] = "A",
        ["Ä"] = "A",
        ["Å"] = "A",
        ["Æ"] = "AE",
        ["Ç"] = "C",
        ["È"] = "E",
        ["É"] = "E",
        ["Ê"] = "E",
        ["Ë"] = "E",
        ["Ì"] = "I",
        ["Í"] = "I",
        ["Î"] = "I",
        ["Ï"] = "I",
        ["Ð"] = "D",
        ["Ñ"] = "N",
        ["Ò"] = "O",
        ["Ó"] = "O",
        ["Ô"] = "O",
        ["Õ"] = "O",
        ["Ö"] = "O",
        ["ő"] = "O",
        ["Ø"] = "O",
        ["Ù"] = "U",
        ["Ú"] = "U",
        ["Û"] = "U",
        ["Ü"] = "U",
        ["Ý"] = "Y",
        ["Þ"] = "P",
        ["ß"] = "s",
        ["à"] = "a",
        ["á"] = "a",
        ["â"] = "a",
        ["ã"] = "a",
        ["ä"] = "a",
        ["å"] = "a",
        ["æ"] = "ae",
        ["ç"] = "c",
        ["č"] = "c",
        ["ć"] = "c",
        ["è"] = "e",
        ["é"] = "e",
        ["ê"] = "e",
        ["ë"] = "e",
        ["ì"] = "i",
        ["í"] = "i",
        ["î"] = "i",
        ["ï"] = "i",
        ["ł"] = "l",
        ["ð"] = "eth",
        ["ñ"] = "n",
        ["ò"] = "o",
        ["ó"] = "o",
        ["ô"] = "o",
        ["õ"] = "o",
        ["ö"] = "o",
        ["ø"] = "o",
        ["ù"] = "u",
        ["ú"] = "u",
        ["û"] = "u",
        ["ü"] = "u",
        ["ý"] = "y",
        ["þ"] = "p",
        ["ÿ"] = "y"
    }

    return str:gsub("[%z\1-\127\194-\244][\128-\191]*", tableAccents)
end

local function nameEqual(str1, str2)
    return string.lower(noAc(str1)):gsub("%W", "") == string.lower(noAc(str2)):gsub("%W", "")
end

function p.dates(frame)
    getArgs(frame) -- returns args table having checked for content
    loadData(frame)

    --	if templateArgs[1]==1 then
    return getDate(templateArgs[2])
    --	else
    --		return getDate()
    --	end
end

local function flagPlayer(frame, player, side)
    local outputString = ""
    local flag, link = '', ''
    if player and player ~= '' then link = '[[' .. player .. ']]'
        tcatsp='[[Category:Pages using DartsRankings with missing player data|' .. player .. ']]'
    end
    for _,u in pairs(data.alias) do  -- get country code from name
        if nameEqual(u[1], player) then
            tcatsp=''
            local nlink = ""
            if u[5] == 0 then nlink = 1 end
            if templateArgs['nolink'] == '1' then nlink = 1 end
            if templateArgs['nolink'] == '0' then nlink = "" end

            if templateArgs['surname'] =='1' then
                if u[6] and u[6]~="" then
                    link = '[[' .. u[3] .. ' ' .. u[4] .. ' (' ..u[6] .. ')' .. '|' .. u[4] ..']]'
                else
                    link = '[[' .. u[3] .. ' ' ..  u[4] .. '|' .. u[4] ..']]'
                end
            elseif templateArgs['surname'] then
                if u[6] and u[6]~="" then
                    link = '[[' .. u[3] .. ' ' .. u[4] .. ' (' ..u[6] .. ')' .. '|' .. templateArgs['surname'] ..']]'
                else
                    link = '[[' .. u[3] .. ' ' .. u[4] .. '|' .. templateArgs['surname'] ..']]'
                end
            else
                if u[6] and u[6]~="" then
                    link = frame:expandTemplate{title= 'sortname', args ={ u[3], u[4] , dab = u[6] , nolink = nlink } }
                else
                    link = frame:expandTemplate{title= 'sortname', args ={ u[3], u[4], nolink = nlink } }
                end

            end
            flag= u[2] -- Flag string from libarary
        end
        if templateArgs['flag'] then
            flag = templateArgs['flag']
        end
    end
    if side == 'right' then
        outputString = link .. require('Module:Flagg').luaMain(frame, {'csxr', flag})
    elseif side == 'none' then
        outputString = link
    else
        outputString = require('Module:Flagg').luaMain(frame, {'csx', flag}) .. link
    end
    tcats = tcats .. tcatsp
    return outputString .. tcats
end

function p.playerLink(frame)
    getArgs(frame) -- returns args table having checked for content
    loadData(frame)
    return flagPlayer(frame, frame.args[2], 'left')
end

function p.playerLinkRight(frame)
    getArgs(frame) -- returns args table having checked for content
    loadData(frame)
    return flagPlayer(frame, frame.args[2], 'right')
end

function p.playerLinkNoFlag(frame)
    getArgs(frame) -- returns args table having checked for content
    loadData(frame)
    return flagPlayer(frame, frame.args[2], 'none')
end

function p.main(frame)
    getArgs(frame) -- returns args table having checked for content
    loadData(frame)
    local outputString = ""
    local validCode = false
    local player = templateArgs[2] -- player name passed as parameter
    local rank, move

    for _,u in pairs(data.alias) do  -- run through the list
        if nameEqual(u[1], player) then        -- if code = passed parameter
            validCode = true
            break
        end
    end
    -- if no match of code to country name, set category

    for _,v in pairs(data.rankings) do
        if nameEqual(v[1], player) then
            rank = v[2]    -- get rank
            break
        end
    end

    if rank then -- no ranking found

        for _,v in pairs(data.rankingsold) do
            if nameEqual(v[1], player) then
                move = v[2] - rank    -- get move from last ranking
                break
            else
                move = 0 - rank
            end
        end
    else
        rank = 'NR'
    end

    local changeString = ""

    if rank ~= 'NR' then
        outputString = rank
        if move < 0 and math.abs( move ) == math.abs( rank ) then -- new teams in ranking: move = -ranking
            changeString = frame:expandTemplate{ title = 'new entry' }
        elseif move == 0 then                                    -- if no change in ranking
            changeString = frame:expandTemplate{ title = 'steady' }
        elseif move < 0 then                                 --  if ranking down
            changeString = frame:expandTemplate{ title = 'decrease' } .. ' ' .. math.abs(move)
        elseif move > 0 then                                 -- if ranking up
            changeString = frame:expandTemplate{ title = 'increase' } .. ' ' .. move
        end
        if not templateArgs['nochange'] or templateArgs['nochange'] == "" then
            outputString = outputString .. ' ' .. changeString
        end
    else
        outputString = outputString .. frame:expandTemplate{ title = 'Abbr', args = { "NR", "Not ranked"}  }
        --	{{Abbr|NR|Not ranked}}
    end

    if not templateArgs['nodate'] or templateArgs['nodate'] == "" then
        outputString = outputString .. ' <small>(' .. getDate() .. ')</small>'
    end
    if templateArgs['par'] and templateArgs['par'] ~= '' then
        outputString = '(' .. outputString .. ')'
    end
    if not templateArgs['noref'] or templateArgs['noref'] == "" then
        outputString = outputString .. addReference(frame)
    end

    return outputString
end

function p.rankOnly(frame)
    getArgs(frame) -- returns args table having checked for content
    loadData(frame)
    local outputString = ""
    local validCode = false
    local player = templateArgs[2] -- player name passed as parameter
    local rank ='NR'
    local move

    for _,u in pairs(data.alias) do  -- run through the list
        if nameEqual(u[1], player) then        -- if code = passed parameter
            validCode = true
            break
        end
    end
    -- if no match of code to country name, set category

    for _,v in pairs(data.rankings) do
        if nameEqual(v[1], player) then
            rank = v[2]    -- get rank
            break
        end
    end

    return rank
end

--[[  outputs a table of the rankings
called by list() or list2()
positional parameters - |ranking|first|last the ranking to use, fist and last in table
other parameters: |style=               -- CSS styling
|headerN= footerN=    -- displays header and footer rows with additional information
|caption=             -- value of caption to display
-- by default it generates a caption
-- this can be suppressed with empty |caption=
]]
local function table(frame, ranking, first,last)

    local styleString = ""
    if templateArgs['style'] and templateArgs['style'] ~= "" then styleString = templateArgs['style'] end

    local lastRank = 0
    local selectCount = 0
    local selectData = nil
    local selectList = nil


    -- column header customisation
    local rankHeader = templateArgs['rank_header'] or "Rank"
    local selectionHeader = templateArgs['selection_header'] or selectList or "Rank"
    local teamHeader = templateArgs['team_header'] or "Player"
    local pointsHeader = templateArgs['points_header'] or "Earnings"
    local changeHeader = templateArgs['change_header'] or "Change"
    local noChange = templateArgs['change_col'] or 1

    --start table
    local outputString = '{| class="wikitable" style="text-align:center;' .. styleString .. '"'

    local tabletitle = data.labels['title']
    -- add default or custom caption
    local caption = tabletitle .. ' as of ' .. getDate() .. '.'
    if templateArgs['caption'] and templateArgs['caption']  ~= "" then
        caption = templateArgs['caption']
        caption = p.replaceKeywords(caption)
    end
    outputString = outputString ..	'\n|+' .. caption .. addReference(frame)

    -- add header rows (logo, date of update etc)
    local count = 0
    local header = {}
    local tableWidth = 4
    if selectList then tableWidth = 5 end
    while count < 5 do
        count = count + 1
        if templateArgs['header'..count] then
            header[count] = templateArgs['header'..count]
            header[count] = p.replaceKeywords( header[count])
            outputString = outputString ..	'\n|-\n| colspan="'.. tableWidth .. '" |' .. header[count]
        end
    end

    -- add the add part of the table
    local optionalColumn = ""
    if selectList then
        optionalColumn = '\n!' .. selectionHeader
    end
    outputString = outputString .. '\n|-' .. optionalColumn .. '\n!' .. rankHeader
    if noChange == 1 then
        outputString = outputString .. '\n!' .. changeHeader
    end
    outputString = outputString .. '\n!' .. teamHeader .. '\n!' .. pointsHeader

    local change,player,plink = '', '', ''
    --while i<last do
    for k,v in pairs(data.rankings) do
        --v[2] = tonumber(v[2])
        if v[2] >= first and v[2] <= last then

            plink = flagPlayer(frame, v[1], 'left')

            local continue = true

            if continue ==true  then

                local rowString = '\n|-'
                if selectList then
                    local selectRank = selectCount
                    if v[2]==lastRank then selectRank = selectCount -1 end -- only handles two at same rank
                    rowString = rowString ..  '\n|' .. selectRank
                    selectCount = selectCount + 1
                end
                rowString = rowString .. '\n|' .. v[2]  -- rank
                lastRank = v[2]

                local move = nil

                for _,w in pairs(data.rankingsold) do
                    if nameEqual(w[1], v[1]) then
                        move = w[2] - lastRank    -- get move from last ranking
                        break
                    else
                        move = 0 - lastRank
                    end
                end

                if move < 0 and math.abs( move ) == math.abs( v[2] ) then -- new teams in ranking: move = -ranking
                    change = frame:expandTemplate{ title = 'new entry' }
                elseif move == 0 then                                    -- if no change in ranking
                    change = frame:expandTemplate{ title = 'steady' }
                elseif move < 0 then                                 --  if ranking down
                    change = frame:expandTemplate{ title = 'decrease' } .. ' ' .. math.abs(move)
                elseif move > 0 then                                 -- if ranking up
                    change = frame:expandTemplate{ title = 'increase' } .. ' ' .. move
                end
                if noChange == 1 then

                    rowString = rowString .. '||' .. change
                end


                rowString = rowString .. '\n|style="text-align:left"|' .. plink

                local points = ""
                if v[3] then points = v[3] end
                rowString = rowString ..  '||' .. points       -- country for now, later points
                outputString = outputString .. rowString
            end
        end
    end

    -- add footer rows
    count = 0
    local footer = {}
    while count < 5 do
        count = count + 1
        if templateArgs['footer'..count] then
            footer[count] = templateArgs['footer'..count]
            footer[count] = p.replaceKeywords(footer[count])
            outputString = outputString ..	'\n|-\n| colspan="'.. tableWidth .. '" |' .. footer[count]
        end
    end

    outputString = outputString .. "\n|}"

    return outputString
end

function p.replaceKeywords(keyword)
    keyword =  string.gsub( keyword, "INSERT_UPDATE_DATE", getDate())
    keyword =  string.gsub( keyword, "INSERT_LAST_DATE", getDate("LAST"))
    keyword =  string.gsub( keyword, "INSERT_REFERENCE", addReference(mw.getCurrentFrame()))
    return keyword
end

--[[ create a table of rankings
parameters:  |ranking=        -- ranking to display (e.g. FIFA World Rankings)
|first= |last=   -- first and last ranking to display (defaults 1-10)
]]
function p.list(frame)

    getArgs(frame) -- returns args table having checked for content
    loadData(frame)
    local ranking = frame.args[1]
    local first, last = 1,10
    first = tonumber(frame.args['2'])
    last = tonumber(frame.args['3'])

    return table(frame, ranking, first, last)
end

local function navlist(frame, ranking, first,last)

    local lastRank = 0
    local selectCount = 0
    local selectData = nil
    local selectList = nil

    --start list
    local outputString = '<ol start="' .. first .. '">'

    local change,player,plink = '', '', ''
    for k,v in pairs(data.rankings) do
        if v[2] >= first and v[2] <= last then
            plink = flagPlayer(frame, v[1], 'left')
            local rowString = '<li>'  -- rank
            lastRank = v[2]
            rowString = rowString .. plink

            if not templateArgs['nochange'] or templateArgs['nochange'] == "" then

                local move = nil
                for _,w in pairs(data.rankingsold) do
                    if nameEqual(w[1], v[1]) then
                        move = w[2] - lastRank    -- get move from last ranking
                        break
                    else
                        move = 0 - lastRank
                    end
                end

                if move < 0 and math.abs( move ) == math.abs( v[2] ) then -- new teams in ranking: move = -ranking
                    change = frame:expandTemplate{ title = 'new entry' }
                elseif move == 0 then                                    -- if no change in ranking
                    change = frame:expandTemplate{ title = 'steady' }
                elseif move < 0 then                                 --  if ranking down
                    change = frame:expandTemplate{ title = 'decrease' }
                elseif move > 0 then                                 -- if ranking up
                    change = frame:expandTemplate{ title = 'increase' }
                end
                rowString = rowString .. ' ' .. change .. '</li>'
            end

            outputString = outputString .. '\n'.. rowString
        end
    end
    outputString = outputString .. '</ol>'

    return outputString
end

---
--- Returns text list for players first,last for PDC top 20 navbox
function p.nav(frame)
    getArgs(frame) -- returns args table having checked for content
    loadData(frame)
    local ranking = frame.args[1]
    local first, last = 1,10
    first = tonumber(frame.args['2'])
    last = tonumber(frame.args['3'])

    return navlist(frame, ranking, first, last)
end

return p