-- This module copies content from Template:MLB_standings; see the history of that page
-- for attribution.
local me = { }
local mlbData
-- if mw.loadData() not supported, use require() instead
if mw.loadData then
mlbData = mw.loadData('Module:Sandbox/B2project/NHL Standings/data')
else
mlbData = require('Module:Sandbox/B2project/NHL Standings/data')
end
local Navbar = require('Module:Navbar')
-- Temporary workaround for missing mw.text utility functions
mw.text = mw.text or {}
if (mw.text.trim == nil) then
mw.text.trim = function(s)
if (s == nil) then
return ''
end
return mw.ustring.match(s, "^%s*(.-)%s*$")
end
end
if (mw.text.gsplit == nil) then
mw.text.gsplit = function( text, pattern, plain )
local s, l = 1, mw.ustring.len( text )
return function ()
if s then
local e, n = mw.ustring.find( text, pattern, s, plain )
local ret
if not e then
ret = mw.ustring.sub( text, s )
s = nil
elseif n < e then
-- Empty separator!
ret = mw.ustring.sub( text, s, e )
if e < l then
s = e + 1
else
s = nil
end
else
ret = e > s and mw.ustring.sub( text, s, e - 1 ) or ''
s = n + 1
end
return ret
end
end, nil, nil
end
end
if (mw.text.split == nil) then
mw.text.split = function ( text, pattern, plain )
local ret = {}
for m in mw.text.gsplit( text, pattern, plain ) do
ret[#ret+1] = m
end
return ret
end
end
local defaultOutputForInput = {
default = 'default',
overallWinLoss = 'winLossOnly',
}
local readTeamInfo = {
default = function(args, currentIdx, returnData)
if (args[currentIdx] == nil or
args[currentIdx+1] == nil or
args[currentIdx+2] == nil or
args[currentIdx+3] == nil or
args[currentIdx+4] == nil or
args[currentIdx+5] == nil or
args[currentIdx+6] == nil or
args[currentIdx+7] == nil ) then
return nil
end
teamInfo = {
name = mw.text.trim(args[currentIdx]),
wins = tonumber(mw.text.trim(args[currentIdx+1])),
losses = tonumber(mw.text.trim(args[currentIdx+2])),
ties = tonumber(mw.text.trim(args[currentIdx+3])),
OTlosses = tonumber(mw.text.trim(args[currentIdx+4])),
tiebr = tonumber(mw.text.trim(args[currentIdx+5])),
goalsfor = tonumber(mw.text.trim(args[currentIdx+6])),
goalsag = tonumber(mw.text.trim(args[currentIdx+7])),
}
returnData.cIndicesRead = 5
teamInfo.wins = teamInfo.wins
teamInfo.losses = teamInfo.losses
teamInfo.ties = teamInfo.ties
teamInfo.OTlosses = teamInfo.OTlosses
teamInfo.tiebr = teamInfo.tiebr
teamInfo.goalsfor = teamInfo.goalsfor
teamInfo.goalsag = teamInfo.goalsag
return teamInfo
end, -- function readTeamInfo.default()
overallWinLoss = function(args, currentIdx, returnData)
if (args[currentIdx] == nil or
args[currentIdx+1] == nil or
args[currentIdx+2] == nil ) then
return nil
end
teamInfo = {
name = mw.text.trim(args[currentIdx]),
wins = tonumber(mw.text.trim(args[currentIdx+1])),
losses = tonumber(mw.text.trim(args[currentIdx+2])),
}
returnData.cIndicesRead = 3
return teamInfo
end, -- function readTeamInfo.default()
} -- readTeamInfo object
local pp = {}
function pp.header(t,Args,p_sub,pos_label,group_col,VTE_text,full_table,results_header_txt)
-- Load relevant modules
local yesno = require('Module:Yesno')
-- Create table header
-- Pre stuff
local team_width = Args['teamwidth'] or '190'
local sort_text = ''
local sort_table_val = Args['sortable_table'] or 'no'
if yesno(sort_table_val) then sort_text = 'sortable' end
table.insert(t,'{|class="wikitable '..sort_text..'" style="text-align:center;"\n') -- Open table
-- Custom header options
-- Table header
local table_header = Args['table_header']
if table_header then
table.insert(t,'|+'..table_header..'\n')
end
--Column headers
local pld_head_text = Args['pld_header'] or '<abbr title="Played">Pld</abbr>'
local OTloss_head_text = Args['OTloss_header'] or '<abbr title="Lost in overtime">OTL</abbr>'
local tiebr_head_text = Args['tiebr_header'] or '<abbr title="Tiebreaker">TBR</abbr>'
local group_head_text = Args['group_header'] or '<abbr title="Group">Grp</abbr>'
-- Use points instead of goals for/against
local for_against_style = Args['for_against_style'] or 'goals'
local fa_letter, fa_word_sing, fa_word_plur
-- First convert to lower case if it is a string
for_against_style = string.lower(for_against_style)
if for_against_style=='g' or for_against_style=='goal' or for_against_style=='goals' then
fa_letter = 'G'
fa_word_sing = 'Goal'
fa_word_plur = 'Goals'
elseif for_against_style=='p' or for_against_style=='point' or for_against_style=='points' then
fa_letter = 'P'
fa_word_sing = 'Point'
fa_word_plur = 'Points'
else
fa_letter = 'G'
fa_word_sing = 'Goal'
fa_word_plur = 'Goals'
end
-- Whether to use goal ratio (goal average) instead
local use_ratio_val = Args['use_goal_ratio'] or 'no'
local do_ratio = false
-- True if exist, false otherwise
if yesno(use_ratio_val) then do_ratio = true end
-- Whether to use tiebreak
local use_tiebr_val = Args['use_tiebreak'] or 'yes'
local do_tiebr = false
if yesno(use_tiebr_val) then do_tiebr = true end
-- Ties and OTL
local use_tieOTL_val = Args['use_ties'] or 'no'
local do_ties = false
if yesno(use_tieOTL_val) then do_ties = true end
-- Initialize
local tt = {}
tt.count = 0 -- Up by one after every call
tt.tab_text = t -- Actual text
-- Actual headers
tt = p_sub.colhead(tt,32,pos_label) -- Position col
-- Add group header
if full_table and group_col then
tt = p_sub.colhead(tt,32,group_head_text) -- Group/division col
end
tt = p_sub.colhead(tt,team_width,'Team'..VTE_text) -- Team col
tt = p_sub.colhead(tt,32,pld_head_text) -- Matches played col
if full_table then
tt = p_sub.colhead(tt,32,'<abbr title="Won">W</abbr>') -- Win col
tt = p_sub.colhead(tt,32,'<abbr title="Lost">L</abbr>') -- Loss col
if do_ties then
tt = p_sub.colhead(tt,32,'<abbr title="Ties">T</abbr>') -- Ties
end
tt = p_sub.colhead(tt,32,OTloss_head_text)
if do_tiebr then
tt = p_sub.colhead(tt,32,tiebr_head_text)
end
tt = p_sub.colhead(tt,32,'<abbr title="'..fa_word_plur..' for">'..fa_letter..'F</abbr>') -- For col
tt = p_sub.colhead(tt,32,'<abbr title="'..fa_word_plur..' against">'..fa_letter..'A</abbr>') -- Against col
if not do_ratio then
tt = p_sub.colhead(tt,32,'<abbr title="'..fa_word_sing..' difference">'..fa_letter..'D</abbr>') -- Difference col
else
tt = p_sub.colhead(tt,36,'<abbr title="'..fa_word_sing..' ratio">'..fa_letter..'R</abbr>') -- Ratio col
end
end
tt = p_sub.colhead(tt,32,'<abbr title="Points">Pts</abbr>') -- Points col
if full_table then
tt.count = tt.count+1
table.insert(tt.tab_text,results_header_txt)
end
return tt
end
local generateTeamRow = {
default = function(teamRowInfo, teamInfo)
return
'|-' .. teamRowInfo.rowStyle .. '\
|| ' .. teamRowInfo.seedText .. '[[' .. teamRowInfo.teamSeasonPage .. '|' .. teamInfo.name .. ']]\
|| ' .. (teamInfo.wins+teamInfo.losses+teamInfo.ties+teamInfo.OTlosses) ..'\
|| ' .. teamInfo.wins .. ' || ' .. teamInfo.losses .. '\n'
end, -- function generateTeamRow.default()
winLossOnly = function(teamRowInfo, teamInfo)
return
'|-' .. teamRowInfo.rowStyle .. '\
|| ' .. teamRowInfo.seedText .. '[[' .. teamRowInfo.teamSeasonPage .. '|' .. teamInfo.name .. ']]\
|| ' .. teamInfo.wins .. ' || ' .. teamInfo.losses .. '\
|| ' .. teamRowInfo.winningPercentage .. '\n'
end, -- function generateTeamRow.winLossOnly
wildCard2012 = function(teamRowInfo, teamInfo)
return
'|-' .. teamRowInfo.rowStyle .. '\
|| ' .. teamRowInfo.seedText .. '[[' .. teamRowInfo.teamSeasonPage .. '|' .. teamInfo.name .. ']]\
|| ' .. teamInfo.wins .. ' || ' .. teamInfo.losses .. '\
|| ' .. teamRowInfo.winningPercentage .. '\
|| ' .. teamRowInfo.gamesBehind .. '\n'
end, -- function generateTeamRow.wildCard2012
} -- generateTeamRow object
local function parseSeeds(seedsArg, seeds)
local seedList = mw.text.split(seedsArg, '%s*,%s*')
if (#seedList == 0) then
return
end
for idx, seed in ipairs(seedList) do
local seedData = mw.text.split(seed, '%s*:%s*')
if (#seedData >= 2) then
local seedNumber = tonumber(mw.text.trim(seedData[1]))
local team = mw.text.trim(seedData[2])
seeds[seedNumber] = team
seeds[team] = seedNumber
end
end
end -- function parseSeeds()
local function parseHighlightArg(highlightArg, teamsToHighlight)
local teamList = mw.text.split(highlightArg, '%s*,%s*')
if (#teamList == 0) then
return
end
for idx, team in ipairs(teamList) do
teamsToHighlight[mw.text.trim(team)] = true
end
end -- function parseHighlightArg
local function parseTeamLinks(teamLinksArg, linkForTeam)
local teamList = mw.text.split(teamLinksArg, '%s*,%s*')
if (#teamList == 0) then
return
end
for idx, teamLinkInfo in ipairs(teamList) do
local teamData = mw.text.split(teamLinkInfo, '%s*:%s*')
if (#teamData >= 2) then
local team = mw.text.trim(teamData[1])
local teamLink = mw.text.trim(teamData[2])
linkForTeam[team] = teamLink
end
end
end -- function parseTeamLinks
function me.generateStandingsTable(frame)
local inputFormat = 'default'
if (frame.args.input ~= nil) then
local inputArg = mw.text.trim(frame.args.input)
if (inputArg == 'overallWinLoss') then
inputFormat = 'overallWinLoss'
end
end
local templateName = nil
if (frame.args.template_name ~= nil) then
templateName = frame.args.template_name
end
local outputFormat = defaultOutputForInput[inputFormat]
local fDisplayNavbar = true
local fDisplayGamesBehind = true
if (frame.args.output ~= nil) then
local outputArg = mw.text.trim(frame.args.output)
if (outputArg == 'winLossOnly') then
outputFormat = 'winLossOnly'
fDisplayGamesBehind = false
end
if (outputArg == 'wildCard2012') then
outputFormat = 'wildCard2012'
end
end
local year = mw.text.trim(frame.args.year or '')
local division = mw.text.trim(frame.args.division or '')
local divisionLink = mw.text.trim(frame.args.division_link or division)
local seedInfo = {}
if (frame.args.seeds ~= nil) then
parseSeeds(frame.args.seeds, seedInfo)
end
local teamsToHighlight = {}
if (frame.args.highlight ~= nil) then
parseHighlightArg(frame.args.highlight, teamsToHighlight)
end
local linkForTeam = {}
if (frame.args.team_links ~= nil) then
parseTeamLinks(frame.args.team_links, linkForTeam)
end
local listOfTeams = {};
local currentArgIdx = 1;
while (frame.args[currentArgIdx] ~= nil) do
local returnData = { }
local teamInfo = readTeamInfo[inputFormat](frame.args, currentArgIdx, returnData);
if (teamInfo == nil) then
break
end
if (linkForTeam[teamInfo.name] ~= nil) then
teamInfo.teamLink = linkForTeam[teamInfo.name]
else
teamInfo.teamLink = teamInfo.name
end
table.insert(listOfTeams, teamInfo)
currentArgIdx = currentArgIdx + returnData.cIndicesRead
end
if (#listOfTeams == 0) then
return ''
end
local outputBuffer = { }
local tableHeaderInfo = {
division = division,
divisionLink = divisionLink,
}
if (fDisplayNavbar) then
local divisionForNavbox = division
if (mlbData.abbreviationForDivision[division] ~= nil) then
divisionForNavbox = mlbData.abbreviationForDivision[division]
end
local standingsPage
if templateName ~= nil then
standingsPage = templateName
else
standingsPage = year .. ' NHL ' .. divisionForNavbox .. ' standings'
end
tableHeaderInfo.navbarText =
Navbar.navbar({
standingsPage,
mini = 1,
style = 'float:left;width:0;',
})
end
table.insert(outputBuffer,
generateTableHeader[outputFormat](tableHeaderInfo)
)
local leadingHalfGames = nil;
if (fDisplayGamesBehind) then
local standingsLeaderIdx = 1;
if (outputFormat == 'wildCard2012' and #listOfTeams > 1) then
standingsLeaderIdx = 2;
end
local teamInfo = listOfTeams[standingsLeaderIdx]
leadingHalfGames = (teamInfo.wins - teamInfo.losses)
end
for idx, teamInfo in ipairs(listOfTeams) do
local teamRowInfo = {
teamSeasonPage = year .. ' ' .. teamInfo.teamLink .. ' season',
winningPercentage = string.format(
'%.3f', teamInfo.wins / ( teamInfo.wins + teamInfo.losses )
),
gamesBehind = '',
seedText = '',
rowStyle = '',
}
if (teamsToHighlight[teamInfo.name]) then
teamRowInfo.rowStyle = ' style="background:#CCFFCC"'
end
table.insert(outputBuffer,
generateTeamRow[outputFormat](teamRowInfo, teamInfo)
)
end -- end of looping over listOfTeams
table.insert(outputBuffer, '|}\n')
return table.concat(outputBuffer)
end -- function me.generateStandingsTable()
function me.generateStandingsTable_fromTemplate(frame)
return me.generateStandingsTable(frame:getParent())
end -- function me.generateStandingsTable_fromTemplate()
return me