Jump to content

Module:CricketLeagueGroupStageSummary/sandbox

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by SocietyBox (talk | contribs) at 04:02, 14 April 2014 (remove teams without matches). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
local p = {}

---------- Background colours for table cells ----------
local noMatchColour = "#C0C0C0"     -- No match defined
local homeWinColour = "#CCCCFF"     -- Home team wins
local awayWinColour = "#FFCCCC"     -- Away team wins
local noResultColour = "#FFDEAD"    -- Match abandoned
local drawColour = "#F0E68C"        -- Match drawn
local tieColour = "#DDFFDD"         -- Match tied
local notPlayedColour = "inherit"   -- Not played yet
local errorColour = "#FF7777"       -- Error
    
function trim(s)
    return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))
end

function getArgs(frame)
    local parent = frame:getParent();
    local args = {}
    for k,v in pairs(parent.args) do
        args[k] = trim(v)
    end
    for k,v in pairs(frame.args) do 
        args[k] = trim(v)
    end
    return args;
end

--
--   Match class
--
local cricmatch = {}

cricmatch.__index = function(t, key)
    local ret = rawget(t, key)
    if ret then
        return ret
    end
    ret = cricmatch[key]
    if type(ret) == 'function' then
        return function(...) 
            return ret(t, ...) 
        end 
    else
        return ret
    end
end

cricmatch.getMargin = function(m)
    if not m.margin then
        addError("The result 'H' or 'A' requires a margin.", id)
    elseif m.margin == 'F' then return "Forfeited"
    elseif m.margin == 'SO' then return "Super Over"
    else
        local dlString = m.dl and ' <span style="font-size: 85%">(D/L)</span>' or ""
        local n = tonumber(string.sub(m.margin, 1, -2))
        local t = string.upper(string.sub(m.margin, -1, -1))
        if not n then
            error("margin = \"" .. m.margin .. "\", match = " .. m.id)
        elseif t == 'R' then
            return string.format("%d runs%s", n, dlString)
        elseif t == 'W' then
            return string.format("%d wickets%s", n, dlString)
        elseif t == 'I' then
            if isLimitedOvers then
                addError("A margin suffixed with 'I' cannot be used in limited-overs formats.", m.id)
            else
                return string.format("Inns &amp; %d runs%s", n, dlString)
            end
        else
            addError("Margin must be 'F', or a valid number suffixed with 'R', 'W' or 'I'.", m.id)
        end
    end
    
    return nil   -- Return nil in case of an error
end

cricmatch.getResult = function(m, row)
    -- Result not provided
    if not m.result then
        addError("Missing parameter: 'result'.")
        addErrorCell(row, m.id)
        return
    end
    
    -- Match has not been played yet
    if m.result == 'X' then
        addTableCell(row, notPlayedColour,
        		string.format('[[#match%s|Match %s]]', m.id, m.id))
            .css('padding', '3px 5px')
            .css('line-height', '300%')
    elseif m.result == 'D' then
        -- Drawn match
        if isLimitedOvers then
            -- No draws in limited-overs matches
            addError("The result 'D' cannot be used in limited-overs formats.", m.id)
            addErrorCell(row, m.id)
        else
	        addTableCell(row, drawColour,
	        		string.format('[[#match%s|Match drawn]]', m.id))
	            .css('padding', '3px 5px')
	            .css('line-height', '300%')
        end
    elseif m.result == 'N' then
        -- Abandoned match
        addTableCell(row, noResultColour,
        		string.format('[[#match%s|Match<br />abandoned]]', m.id))
            .css('padding', '3px 5px')
    elseif m.result == 'T' then
        -- Tied match
        addTableCell(row, tieColour,
        		string.format('[[#match%s|Match tied]]', m.id))
            .css('padding', '3px 5px')
    elseif m.result == 'H' then
        -- Home team wins
        local margin = m.getMargin()
        if margin then
            addTableCell(row, homeWinColour, string.format('%s<br />[[#match%s|%s]]', m.home.shortName, m.id, margin))
                .css('padding', '3px 5px')
        else addErrorCell(row, m.id) end
    elseif m.result == 'A' then
        -- Away team wins
        local margin = m.getMargin()
        if margin then
            addTableCell(row, awayWinColour, string.format('%s<br />[[#match%s|%s]]', m.home.shortName, m.id, margin))
                .css('padding', '3px 5px')
        else addErrorCell(row, m.id) end
    else  -- Invalid result
        addError("Invalid result: '" .. m.result .. "'. Expected: H, A, X, N, D or T.", m.id)
        addErrorCell(row, m.id)
    end
end

function createMatch(id, home, away, result, margin, dl)
    local match = {}
    setmetatable(match, cricmatch)
    match.id = id
    match.home = home
    match.away = away
    match.result = result
    match.margin = margin
    match.dl = dl
    return match
end

--
--   Html Builder helpers
--
local htmlBuilder = require('Module:HtmlBuilder')
function addTableRow(tbl)
    return tbl.tag('tr')
end
function addTableCell(row, bg, text)
    return row.tag('td').css('background-color', bg).wikitext(text)
end
function addNoMatch(row)
    addTableCell(row, noMatchColour)
    return row
end
function addErrorCell(row, id)
	local link = string.format('[[#match%s|Match %s]]', id, id)
    addTableCell(row, errorColour, link)
        .css('padding', '3px 5px')
        .css('line-height', '300%')
    return row
end

--
--   Helper functions
-- 
function buildLegend(container, isLimitedOvers)
    local key = container.tag('table')
        .addClass('wikitable')
        .css('float', 'right')
        .css('text-align', 'center')
        .css('font-size', '90%')

    if isLimitedOvers then
        key.css('width', '30%')
        local row
        row = addTableRow(key)
        addTableCell(row, homeWinColour, 'Home team won').css('width', '50%')
        addTableCell(row, awayWinColour, 'Visitor team won').css('width', '50%')
        row = addTableRow(key)
        addTableCell(row, noResultColour, 'Match abandoned')
        addTableCell(row, tieColour, 'Match tied')
    else
        local row
        row = addTableRow(key)
        addTableCell(row, homeWinColour, 'Home team won').css('width', '33%')
        addTableCell(row, awayWinColour, 'Visitor team won').css('width', '34%')
        addTableCell(row, noResultColour, 'Match drawn')
            .css('width', '33%')
            .attr('rowspan', '2')
        row = addTableRow(key)
        addTableCell(row, tieColour, 'Match abandoned')
        addTableCell(row, drawColour, 'Match tied')
    end

    local list = container.tag('ul')
        .css('font-size', '90%')
        .tag('li')
            .wikitext("'''Note''': Results listed are according to the home (horizontal) and visitor (vertical) teams.")
        .done()
        .tag('li')
            .wikitext("'''Note''': Click on a result to see a summary of the match.")
        .done()
    return container
end

function getMatchData(args, teams)
    local m = 0
    local matches = {}
    local home, away, result, margin, dl
    while args[m * 5 + 5] do
        home = teams[trim(args[m * 5 + 1])]
        away = teams[args[m * 5 + 2]]
        result = args[m * 5 + 3]
        margin = args[m * 5 + 4]
        dl = args[m * 5 + 5] == "Y"
        table.insert(matches, createMatch(m + 1, home, away, result, margin, dl))
        m = m + 1
    end
    return matches
end

p.create = function(args, title, teams, isLimitedOvers, tableStyle)
    local matches = getMatchData(args, teams)

	-- organise by team
    local codes = {}
    local results = {}
    for i, match in ipairs(matches) do
    	local home = match.home.code
    	if not results[home] then
	        table.insert(codes, home)
	        results[home] = {}
		end
        results[home][match.away.code] = match
    end
    table.sort(codes)

    -- Construct the header
    local container = htmlBuilder.create('div')
        .css('float', 'left')
    local tbl = container.tag('table')
        .attr('class', 'wikitable')
        .cssText(tableStyle or "text-align: center; white-space: nowrap; width: 100%")
    local header = addTableRow(tbl)
        .tag('th')
            .attr('scope', 'row')
            .wikitext('Visitor team →')
        .done()
    for i, code in ipairs(codes) do
        local team = teams[code]
        header.tag('th')
            .attr('rowspan', '2')
            .attr('scope', 'col')
            .css('padding', 'inherit 10px')
            .wikitext(string.format('[[%s|%s]]', team.pageName, team.code))
            .newline()
    end
    tbl.tag('tr')
        .tag('th')
            .attr('scope', 'col')
            .wikitext('Home team ↓')

    -- Output the main body of the table
    for i, homecode in ipairs(codes) do
        local home = teams[homecode]
        local noHomeMatches = false
        local row = addTableRow(tbl)
        local teamcell = row.tag('th')
            .attr('scope', 'row')
            .css('text-align', 'left')
            .css('padding', '3px 5px')
            .css('white-space', 'normal')
            .wikitext(string.format('[[%s|%s]]', home.pageName, home.fullName))
        if noHomeMatches then
            teamcell.css('line-height', '275%')
            for j, away in ipairs(codes) do
                addNoMatch(row)
            end
        else    
            for j, awaycode in ipairs(codes) do
                local match = results[homecode][awaycode]
                if match then
                    match.getResult(row)
                else
                    addNoMatch(row)
                end
            end
        end
    end

    -- Legend and notes
    buildLegend(container, isLimitedOvers)
    local output = tostring(container) .. '<div style="clear: both"></div>'
    return output
end

p.test = function(frame)
    local args = getArgs(frame)
    local title = "1999 IPL Group Stage Match Summary"
    local teams = mw.loadData("Module:IndianPremierLeague/Teams")
    local teamsAssoc = {}
    local i = 1
    while teams[i] do
        teamsAssoc[teams[i].code] = teams[i]
        i = i + 1
    end
    return p.create(args, title, teamsAssoc, true)
end

return p