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, '

\n')

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