Module:DartsRankings


Module to display ranking tables and individual rankings for ranked PDC darts players.

Module Data

Template:Div col

Template:Div col end

Rankings can be updated above and will display for all OOM instances and rankings on individual pages.

This can possibly later include WDF rankings when they have a new system in place.

Template for individual rankings

Rank & move w/date: {{Template:PDC Rankings}}

Usage

  • List ranking from start ranking to end ranking:

{{#invoke:DartsRankings|list|PDC Rankings|first|last}}

Examples:

Player examples Code Output
PDC OOM Ranking for Michael van Gerwen {{#invoke:DartsRankings|main |PDC Rankings|Michael van Gerwen}} Lua error: expandTemplate: template "refn" does not exist.
PDC OOM Ranking for Peter Wright from template {{PDC Rankings|Peter Wright}} Template:PDC Rankings
WDF Ranking for Larry Butler from template {{WDF Rankings|Larry Butler|mdy=mdy}} Template:WDF Rankings
WDF Ranking for Fallon Sherrock from template {{WDF Women's Rankings|Fallon Sherrock}} Template:WDF Women's Rankings
PDC Ranking only for Gary Anderson from template {{PDC Rankings|Gary Anderson|nochange=1|nodate=1}} Template:PDC Rankings
Flag & link for José de Sousa from template {{PDCFlag|Jose de Sousa}} Template:PDCFlag
PDC Ranking & flag for Simon Whitlock from template {{PDCFlag|Simon Whitlock}} {{PDC Rankings|Simon Whitlock|nochange=1|nodate=1|par=1}} Template:PDCFlag Template:PDC Rankings
PDC Rankings table (1-5) {{#invoke:DartsRankings|list |PDC Rankings |1 |5 }} Lua error: expandTemplate: template "refn" does not exist.
PDC Rankings table (16-20) {{#invoke:DartsRankings|list |PDC Rankings |16 |20 }} Lua error: expandTemplate: template "refn" does not exist.
PDC Pro Tour table (1-5) {{#invoke:DartsRankings|list |PDC Pro Tour Rankings |1 |5 }} Lua error: expandTemplate: template "refn" does not exist.

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

  local normalisedString = ''

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

  return normalisedString

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 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 
			   
		   	flag= u[2] -- Flag string from libarary
		   	if templateArgs['flag'] then
		   		flag = templateArgs['flag']
		   	end
		   	
		end
	end
	if side == 'right' then 
		outputString = link .. frame:expandTemplate{title= 'flagg', args ={ 'csxr', flag}}
	elseif side == 'none' then
		outputString = link
	else 
		outputString = frame:expandTemplate{title= 'flagg', args ={ '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

--[[  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