From Wikipedia, the free encyclopedia

-- 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 (argscurrentIdx   == nil or

            argscurrentIdx+1 == nil or

            argscurrentIdx+2 == nil or

            argscurrentIdx+3 == nil or

            argscurrentIdx+4 == nil or

            argscurrentIdx+5 == nil or

            argscurrentIdx+6 == nil or

            argscurrentIdx+7 == nil ) then

            return nil

        end

        teamInfo = {

            name = mw.text.trim(argscurrentIdx]),

            wins = tonumber(mw.text.trim(argscurrentIdx+1])),

            losses = tonumber(mw.text.trim(argscurrentIdx+2])),

            ties = tonumber(mw.text.trim(argscurrentIdx+3])),

            otlosses = tonumber(mw.text.trim(argscurrentIdx+4])),

            row = tonumber(mw.text.trim(argscurrentIdx+5])),

            gf = tonumber(mw.text.trim(argscurrentIdx+6])),

            ga = tonumber(mw.text.trim(argscurrentIdx+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 (argscurrentIdx   == nil or

            argscurrentIdx+1 == nil or

            argscurrentIdx+2 == nil or

            argscurrentIdx+3 == nil or

            argscurrentIdx+4 == nil or

            argscurrentIdx+5 == nil or

            argscurrentIdx+6 == nil ) then

            return nil

        end

        teamInfo = {

            name = mw.text.trim(argscurrentIdx]),

            wins = tonumber(mw.text.trim(argscurrentIdx+1])),

            losses = tonumber(mw.text.trim(argscurrentIdx+2])),

            otlosses = tonumber(mw.text.trim(argscurrentIdx+3])),

            row = tonumber(mw.text.trim(argscurrentIdx+4])),

            gf = tonumber(mw.text.trim(argscurrentIdx+5])),

            ga = tonumber(mw.text.trim(argscurrentIdx+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 (argscurrentIdx   == nil or

            argscurrentIdx+1 == nil or

            argscurrentIdx+2 == nil or

            argscurrentIdx+3 == nil or

            argscurrentIdx+4 == nil ) then

            return nil

        end

        teamInfo = {

            name = mw.text.trim(argscurrentIdx]),

            wins = tonumber(mw.text.trim(argscurrentIdx+1])),

            losses = tonumber(mw.text.trim(argscurrentIdx+2])),

            gf = tonumber(mw.text.trim(argscurrentIdx+3])),

            ga = tonumber(mw.text.trim(argscurrentIdx+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 (argscurrentIdx   == nil or

            argscurrentIdx+1 == nil or

            argscurrentIdx+2 == nil or

            argscurrentIdx+3 == nil or

            argscurrentIdx+4 == nil or

            argscurrentIdx+5 == nil ) then

            return nil

        end

        teamInfo = {

            name = mw.text.trim(argscurrentIdx]),

            wins = tonumber(mw.text.trim(argscurrentIdx+1])),

            losses = tonumber(mw.text.trim(argscurrentIdx+2])),

            ties = tonumber(mw.text.trim(argscurrentIdx+3])),

            gf = tonumber(mw.text.trim(argscurrentIdx+4])),

            ga = tonumber(mw.text.trim(argscurrentIdx+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.divisionLink.. '|' .. tableHeaderInfo.division .. ']]' ..tableHeaderInfo.source.. '\

! width=32 | <abbr title="Position">Pos</abbr>\

! width=190 | Team ' .. tableHeaderInfo.navbarText .. '\

! width=32 | <abbr title="Games played">GP</abbr>\

! width=32 | <abbr title="Won">W</abbr>\

! width=32 | <abbr title="Lost">L</abbr>\

! width=32 | <abbr title="Ties">T</abbr>\

! width=32 | <abbr title="Lost in overtime">OTL</abbr>\

! width=32 | <abbr title="Regulation + Overtime wins">ROW</abbr>\

! width=32 | <abbr title="Goals for">GF</abbr>\

! width=32 | <abbr title="Goals for">GA</abbr>\

! width=32 | <abbr title="Goal difference">GD</abbr>\

! width=32 | <abbr title="Points">Pts</abbr>\

'

end,  -- function generateTableHeader.default()



	current = function(tableHeaderInfo)

        return

'{| class="wikitable sortable" width="" style="text-align:center;"\

|+ [[' .. tableHeaderInfo.divisionLink.. '|' .. tableHeaderInfo.division .. ']]\

! width=32 | <abbr title="Position">Pos</abbr>\

! width=190 | Team ' .. tableHeaderInfo.navbarText .. '\

! width=32 | <abbr title="Games played">GP</abbr>\

! width=32 | <abbr title="Won">W</abbr>\

! width=32 | <abbr title="Lost">L</abbr>\

! width=32 | <abbr title="Lost in overtime">OTL</abbr>\

! width=32 | <abbr title="Regulation + Overtime wins">ROW</abbr>\

! width=32 | <abbr title="Goals for">GF</abbr>\

! width=32 | <abbr title="Goals for">GA</abbr>\

! width=32 | <abbr title="Goal difference">GD</abbr>\

! width=32 | <abbr title="Points">Pts</abbr>\

'

end,



    winsloss = function(tableHeaderInfo)

        return

'{| class="wikitable sortable" width="" style="text-align:center;"\

|+ [[' .. tableHeaderInfo.divisionLink.. '|' .. tableHeaderInfo.division .. ']]\

! width=32 | <abbr title="Position">Pos</abbr>\

! width=190 | Team ' .. tableHeaderInfo.navbarText .. '\

! width=32 | <abbr title="Games played">GP</abbr>\

! width=32 | <abbr title="Won">W</abbr>\

! width=32 | <abbr title="Lost">L</abbr>\

! width=32 | <abbr title="Goals for">GF</abbr>\

! width=32 | <abbr title="Goals for">GA</abbr>\

! width=32 | <abbr title="Goal difference">GD</abbr>\

! width=32 | <abbr title="Points">Pts</abbr>\

'

end,  -- function generateTableHeader.winloss()



    WLT = function(tableHeaderInfo)

        return

'{| class="wikitable sortable" width="" style="text-align:center;"\

|+ [[' .. tableHeaderInfo.divisionLink.. '|' .. tableHeaderInfo.division .. ']]\

! width=32 | <abbr title="Position">Pos</abbr>\

! width=190 | Team ' .. tableHeaderInfo.navbarText .. '\

! width=32 | <abbr title="Games played">GP</abbr>\

! width=32 | <abbr title="Won">W</abbr>\

! width=32 | <abbr title="Lost">L</abbr>\

! width=32 | <abbr title="Ties">T</abbr>\

! width=32 | <abbr title="Goals for">GF</abbr>\

! width=32 | <abbr title="Goals for">GA</abbr>\

! width=32 | <abbr title="Goal difference">GD</abbr>\

! width=32 | <abbr title="Points">Pts</abbr>\

'

end,  -- function generateTableHeader.WLT()

	

}  -- generateTableHeader object



local generateTeamRow = {

    default = function(teamRowInfo, teamInfo)

        return

'|-' .. teamRowInfo.rowStyle .. '\

|| ' .. teamRowInfo.position ..'\

| style="text-align:left;" | ' .. teamRowInfo.statusText .. '[[' .. teamRowInfo.teamSeasonPage .. '|' .. 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 .. '[[' .. teamRowInfo.teamSeasonPage .. '|' .. 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 .. '[[' .. teamRowInfo.teamSeasonPage .. '|' .. 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 .. '[[' .. teamRowInfo.teamSeasonPage .. '|' .. 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(statusData1])

            local team = mw.text.trim(statusData2])

            status_liststatusNumber = team

            status_listteam = 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

        teamsToHighlightmw.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(teamData1])

            local teamLink = mw.text.trim(teamData2])

            linkForTeamteam = 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 = defaultOutputForInputinputFormat

    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.argscurrentArgIdx ~= nil) do

        local returnData = { }

        local teamInfo = readTeamInfoinputFormat](frame.args, currentArgIdx, returnData);

        if (teamInfo == nil) then

            break

        end

        if (linkForTeamteamInfo.name ~= nil) then

            teamInfo.teamLink = linkForTeamteamInfo.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.abbreviationForDivisiondivision ~= nil) then

            divisionForNavbox = nhlData.abbreviationForDivisiondivision

        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,

        generateTableHeaderoutputFormat](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='<span style="color:green">+'..teamRowInfo.goaldiff..'</span>'

    	elseif teamRowInfo.goaldiff<0 then

    		teamRowInfo.goaldiff=teamRowInfo.goaldiff*-1

    		teamRowInfo.goaldiff='<span style="color:red">&minus;'..teamRowInfo.goaldiff..'</span>'

		end

		

        if (statusInfoteamInfo.name ~= nil) then

            teamRowInfo.statusText = '<span style="font-weight:bold">' .. string.lower(statusInfoteamInfo.name]) .. ' –</span> '

            --teamRowInfo.rowStyle = ' style="background:#CCFFCC"'

        end



        if (teamsToHighlightteamInfo.name]) then

            teamRowInfo.rowStyle =  ' style="background:#CCFFCC;font-weight:bold;"'

        end



        table.insert(outputBuffer,

            generateTeamRowoutputFormat](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