Module:Sandbox/B2project/NHL Standings
-- This module copies content from Template:MLB_standings; see the history of that page
-- for attribution. 6/15/16
local me = { }
local nhlData
-- if mw.loadData() not supported, use require() instead
if mw.loadData then
nhlData = mw.loadData('Module:Sandbox/B2project/NHL Standings/data')
else
nhlData = 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',
current = 'current',
winsloss = 'winsloss',
WLT = 'WLT',
}
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])),
row = tonumber(mw.text.trim(args[currentIdx+5])),
gf = tonumber(mw.text.trim(args[currentIdx+6])),
ga = tonumber(mw.text.trim(args[currentIdx+7])),
winpoints = 2,
tiepoints = 1,
otlpoints = 1,
points = '',
gamesplayed = '',
}
returnData.cIndicesRead = 8
teamInfo.gamesplayed = teamInfo.wins + teamInfo.losses + teamInfo.ties + teamInfo.otlosses
teamInfo.points = (teamInfo.winpoints*teamInfo.wins)+(teamInfo.tiepoints*teamInfo.ties)+(teamInfo.otlpoints*teamInfo.otlosses)
return teamInfo
end, -- function readTeamInfo.default()
current = 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 ) 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])),
otlosses = tonumber(mw.text.trim(args[currentIdx+3])),
row = tonumber(mw.text.trim(args[currentIdx+4])),
gf = tonumber(mw.text.trim(args[currentIdx+5])),
ga = tonumber(mw.text.trim(args[currentIdx+6])),
winpoints = 2,
otlpoints = 1,
points = '',
gamesplayed = '',
}
returnData.cIndicesRead = 7
teamInfo.gamesplayed = teamInfo.wins + teamInfo.losses + teamInfo.otlosses
teamInfo.points = (teamInfo.winpoints*teamInfo.wins)+(teamInfo.otlpoints*teamInfo.otlosses)
return teamInfo
end, -- function readTeamInfo.default()
winsloss = 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 ) 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])),
gf = tonumber(mw.text.trim(args[currentIdx+3])),
ga = tonumber(mw.text.trim(args[currentIdx+4])),
winpoints = 2,
points = '',
gamesplayed = '',
}
returnData.cIndicesRead = 5
teamInfo.gamesplayed = teamInfo.wins + teamInfo.losses
teamInfo.points = (teamInfo.winpoints*teamInfo.wins)
return teamInfo
end, -- function readTeamInfo.default()
WLT = 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 ) 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])),
gf = tonumber(mw.text.trim(args[currentIdx+4])),
ga = tonumber(mw.text.trim(args[currentIdx+5])),
winpoints = 2,
tiepoints = 1,
points = '',
gamesplayed = '',
}
returnData.cIndicesRead = 6
teamInfo.gamesplayed = teamInfo.wins + teamInfo.losses + teamInfo.ties
teamInfo.points = (teamInfo.winpoints*teamInfo.wins) + (teamInfo.tiepoints*teamInfo.ties)
return teamInfo
end, -- function readTeamInfo.default()
} -- readTeamInfo object
local generateTableHeader = {
default = function(tableHeaderInfo)
return
'
class="wikitable sortable" width="" style="text-align:center;"\
|+ ' .. tableHeaderInfo.division .. '' ..tableHeaderInfo.source.. '\ ! width=32 | Pos\ ! width=190 | Team ' .. tableHeaderInfo.navbarText .. '\ ! width=32 | GP\ ! width=32 | W\ ! width=32 | L\ ! width=32 | T\ ! width=32 | OTL\ ! width=32 | ROW\ ! width=32 | GF\ ! width=32 | GA\ ! width=32 | GD\ ! width=32 | Pts\ ' end, -- function generateTableHeader.default() current = function(tableHeaderInfo) return '{| class="wikitable sortable" width="" style="text-align:center;"\ |+ ' .. tableHeaderInfo.division .. '\ ! width=32 | Pos\ ! width=190 | Team ' .. tableHeaderInfo.navbarText .. '\ ! width=32 | GP\ ! width=32 | W\ ! width=32 | L\ ! width=32 | OTL\ ! width=32 | ROW\ ! width=32 | GF\ ! width=32 | GA\ ! width=32 | GD\ ! width=32 | Pts\ ' end, winsloss = function(tableHeaderInfo) return '{| class="wikitable sortable" width="" style="text-align:center;"\ |+ ' .. tableHeaderInfo.division .. '\ ! width=32 | Pos\ ! width=190 | Team ' .. tableHeaderInfo.navbarText .. '\ ! width=32 | GP\ ! width=32 | W\ ! width=32 | L\ ! width=32 | GF\ ! width=32 | GA\ ! width=32 | GD\ ! width=32 | Pts\ ' end, -- function generateTableHeader.winloss() WLT = function(tableHeaderInfo) return '{| class="wikitable sortable" width="" style="text-align:center;"\ |+ ' .. tableHeaderInfo.division .. '\ ! width=32 | Pos\ ! width=190 | Team ' .. tableHeaderInfo.navbarText .. '\ ! width=32 | GP\ ! width=32 | W\ ! width=32 | L\ ! width=32 | T\ ! width=32 | GF\ ! width=32 | GA\ ! width=32 | GD\ ! width=32 | Pts\ ' end, -- function generateTableHeader.WLT() } -- generateTableHeader object local generateTeamRow = { default = function(teamRowInfo, teamInfo) return ' | ||||||||||
' .. teamRowInfo.rowStyle .. '\ | ' .. teamRowInfo.position ..'\
| style="text-align:left;" | ' .. teamRowInfo.statusText .. '' .. teamInfo.name .. '\ | ' .. teamInfo.gamesplayed .. '\ | ' .. teamInfo.wins .. '\ | ' .. teamInfo.losses .. '\ | ' .. teamInfo.ties ..'\ | ' .. teamInfo.otlosses ..'\ | ' .. teamInfo.row ..'\ | ' .. teamInfo.gf .. '\ | ' .. teamInfo.ga .. '\ | ' .. teamRowInfo.goaldiff ..'\
| style="font-weight:bold;" | ' .. teamInfo.points ..'\n' end, -- function generateTeamRow.default() current = function(teamRowInfo, teamInfo) return ' |
' .. teamRowInfo.rowStyle .. '\ | ' .. teamRowInfo.position ..'\
| style="text-align:left;" | ' .. teamRowInfo.statusText .. '' .. teamInfo.name .. '\ | ' .. teamInfo.gamesplayed .. '\ | ' .. teamInfo.wins .. '\ | ' .. teamInfo.losses .. '\ | ' .. teamInfo.otlosses ..'\ | ' .. teamInfo.row ..'\ | ' .. teamInfo.gf .. '\ | ' .. teamInfo.ga .. '\ | ' .. teamRowInfo.goaldiff ..'\
| style="font-weight:bold;" | ' .. teamInfo.points ..'\n' end, winsloss = function(teamRowInfo, teamInfo) return ' | |
' .. teamRowInfo.rowStyle .. '\ | ' .. teamRowInfo.position ..'\
| style="text-align:left;" | ' .. teamRowInfo.statusText .. '' .. teamInfo.name .. '\ | ' .. teamInfo.gamesplayed .. '\ | ' .. teamInfo.wins .. '\ | ' .. teamInfo.losses .. '\ | ' .. teamInfo.gf .. '\ | ' .. teamInfo.ga .. '\ | ' .. teamRowInfo.goaldiff ..'\
| style="font-weight:bold;" | ' .. teamInfo.points ..'\n' end, -- function generateTeamRow.default() WLT = function(teamRowInfo, teamInfo) return ' | |||
' .. teamRowInfo.rowStyle .. '\ | ' .. teamRowInfo.position ..'\
| style="text-align:left;" | ' .. teamRowInfo.statusText .. '' .. teamInfo.name .. '\ | ' .. teamInfo.gamesplayed .. '\ | ' .. teamInfo.wins .. '\ | ' .. teamInfo.losses .. '\ | ' .. teamInfo.ties .. '\ | ' .. teamInfo.gf .. '\ | ' .. teamInfo.ga .. '\ | ' .. teamRowInfo.goaldiff ..'\
| style="font-weight:bold;" | ' .. teamInfo.points ..'\n' end, -- function generateTeamRow.default() } -- generateTeamRow object local function parsestatus_list(status_listArg, status_list) local statusList = mw.text.split(status_listArg, '%s*,%s*') if (#statusList == 0) then return end for idx, status in ipairs(statusList) do local statusData = mw.text.split(status, '%s*:%s*') if (#statusData >= 2) then local statusNumber = mw.text.trim(statusData[1]) local team = mw.text.trim(statusData[2]) status_list[statusNumber] = team status_list[team] = statusNumber end end end -- function parsestatus_list() 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 == 'current') then inputFormat = 'current' end if (inputArg == 'winsloss') then inputFormat = 'winsloss' end if (inputArg == 'WLT') then inputFormat = 'WLT' 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 fDisplayTies = true if (frame.args.output ~= nil) then local outputArg = mw.text.trim(frame.args.output) if (outputArg == 'current') then outputFormat = 'current' fDisplayTies = false end if (outputArg == 'winsloss') then outputFormat = 'winsloss' end if (outputArg == 'WLT') then outputFormat = 'WLT' 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 source = mw.text.trim(frame.args.source or '') local statusInfo = {} if (frame.args.status_list ~= nil) then parsestatus_list(frame.args.status_list, statusInfo) 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 t_footer = { } local tableHeaderInfo = { division = division, divisionLink = divisionLink, source = source, } if (fDisplayNavbar) then local divisionForNavbox = division if (nhlData.abbreviationForDivision[division] ~= nil) then divisionForNavbox = nhlData.abbreviationForDivision[division] end local standingsPage if (templateName ~= nil) then standingsPage = templateName else standingsPage = year .. ' ' .. divisionForNavbox .. ' standings' end tableHeaderInfo.navbarText = Navbar.navbar({ standingsPage, mini = 1, style = 'float:right;', }) end table.insert(outputBuffer, generateTableHeader[outputFormat](tableHeaderInfo) ) local leadingHalfGames = nil; for idx, teamInfo in ipairs(listOfTeams) do local teamRowInfo = { teamSeasonPage = year .. ' ' .. teamInfo.teamLink .. ' season', statusText = '', rowStyle = '', position = idx, goaldiff = '', winpoints = 2, tiepoints = 1, otlpoints = 1, } teamRowInfo.goaldiff = teamInfo.gf - teamInfo.ga if teamRowInfo.goaldiff>0 then teamRowInfo.goaldiff='+'..teamRowInfo.goaldiff..'' elseif teamRowInfo.goaldiff<0 then teamRowInfo.goaldiff=teamRowInfo.goaldiff*-1 teamRowInfo.goaldiff='−'..teamRowInfo.goaldiff..'' end if (statusInfo[teamInfo.name] ~= nil) then teamRowInfo.statusText = '' .. string.lower(statusInfo[teamInfo.name]) .. ' – ' --teamRowInfo.rowStyle = ' style="background:#CCFFCC"' end if (teamsToHighlight[teamInfo.name]) then teamRowInfo.rowStyle = ' style="background:#CCFFCC;font-weight:bold;"' end table.insert(outputBuffer, generateTeamRow[outputFormat](teamRowInfo, teamInfo) ) end -- end of looping over listOfTeams table.insert(outputBuffer, ' |
local update = mw.text.trim(frame.args.update or 'unknown')
local start_date = mw.text.trim(frame.args.start_date or 'unknown')
--local source = mw.text.trim(frame.args.source or '')
if (source ~= nil) then
source = source
else
source = ''
end
local matches_text = mw.text.trim(frame.args.matches_text or 'games')
if string.lower(update)=='complete' then
table.insert(t_footer,'Final standings.'..tableHeaderInfo.source..'')
elseif update=='' then
-- Empty
table.insert(t_footer,'Source'..tableHeaderInfo.source..'')
elseif update=='future' then
-- Future start date
table.insert(t_footer,'First '..matches_text..' will be played on '..start_date..'. ')
else
table.insert(t_footer,'Updated to '..matches_text..' played on '..update..'.'..tableHeaderInfo.source..'')
end
return table.concat(outputBuffer), table.concat(t_footer)
end -- function me.generateStandingsTable()
function me.generateStandingsTable_fromTemplate(frame)
return me.generateStandingsTable(frame:getParent())
end -- function me.generateStandingsTable_fromTemplate()
return me