Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:CricketLeagueProgression/sandbox

From Wikipedia, the free encyclopedia
local p = {}

---------- Background colours for table cells ----------
local colours = {
    W = "#99FF99",
    L = "#FFDDDD",
    N = "#DFDFFF",
    D = "#F0E68C",
    T = "#DDFFDD",
    X = "#FFD"
}
local classes = {
    W = "yes table-yes2",
    L = "no table-no2",
    N = "noresult",
    X = "partial table-partial"
}
local elimColour = "#DCDCDC" -- Eliminated

function trim(s)
    if not s then
        return nil
    else
        return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))
    end
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.render = function(m, row, team, points)
	local cell = row:tag('td')
	local home = m.home == team

	local vs = home and m.away or m.home
	local venue = home and 'H' or 'A'
	cell:attr('title', string.format('vs. %s (%s)', vs.fullName, venue))

	local result = m.result
	local gained = 0
	if m.result == 'H' then
		result = home and 'W' or 'L'
		gained = home and 2 or 0
	elseif m.result == 'A' then
		result = home and 'L' or 'W'
		gained = home and 0 or 2
	elseif m.result == 'N' or m.result == 'T' then
		gained = 1
	else
		cell
			:css('background-color', colours.X)
			:attr('class', classes.X)
			:wikitext(string.format('[[#match%d|?]]', m.id))
		return points
	end

	points = points + gained
	cell
		:css('background-color', colours[result])
		:wikitext(string.format('[[#match%d|%d]]', m.id, points))
	if classes[cell] then cell:attr('class', classes[cell]) end
	return points
end

function createMatch(id, home, away, result, margin, dl)
    if not home or not away then
        return nil
    end
    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

--
--   Helper functions
--
function buildLegend(container, types)
    local key = container:tag('table')
        :addClass('wikitable')
        :css('float', 'right')
        :css('text-align', 'center')
        :css('font-size', '90%')
        :css('margin', '0 0 0 10px')
        :tag('td')
            :css('background-color', colours.W)
            :css('padding-left', '10px')
            :css('padding-right', '10px')
            :wikitext('Win')
        :done()
        :tag('td')
            :css('background-color', colours.L)
            :css('padding', '0 10px')
            :wikitext('Loss')
        :done()
        :tag('td')
            :css('background-color', colours.N)
            :css('padding', '0 10px')
            :wikitext('No result')
        :done()

    local list = container:tag('ul')
        :css('font-size', '90%')
        :tag('li')
            :wikitext("'''Note''': The total points " ..
                "at the end of each group match are listed.")
        :done()
        :tag('li')
            :wikitext("'''Note''': Click on the points (group matches) " ..
                "or W/L (playoffs) to see the match summary.")
        :done()
    return container
end

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

function renderTeam(tbl, count, team, matches, koStages, total)
    local row = tbl:tag('tr')
        :tag('th')
            :css('text-align', 'left')
            :css('padding-right', '10px')
            :css('border-right', 'black solid 2px')
            :css('min-width', '160px')
            :wikitext(string.format('[[%s|%s]]', team.pageName, team.fullName))
        :done()
    local points = 0
    for i = 1, count do
        if matches[i] then
            points = matches[i].render(row, team, points)
        else
            row:tag('td')
        end
    end
    local cell, koMatches, koMatch, result, colour, matchNo
    local eliminated = true
    for i = 1, #koStages do
        result = nil
        cell = row:tag('td')
        if i == 1 then cell:css('border-left', 'black solid 2px') end
        koMatches = koStages[i].matches
        for j = 1, #koMatches do
            total = total + 1
            koMatch = koMatches[j]
            if result then
            elseif not koMatch.winner then
                eliminated = false
            else
                if koMatch.winner == team.code then
                    result = 'W'
                    matchNo = total
                elseif koMatch.loser == team.code then
                    result = 'L'
                    matchNo = total
                end
            end
        end
        if result then
            cell:css('background-color', colours[result])
                :wikitext(string.format('[[#match%d|%s]]', matchNo, result))
        elseif eliminated then
            cell:css('background-color', elimColour)
        end
    end
end

p.create = function(args, teams, koName, koStages)
    local matches = getMatchData(args, teams)
    local wrapper = mw.html.create('div')

    local codes, results = {}, {}
    local count = 0
    for _, match in ipairs(matches) do
        local home = match.home.code
        local away = match.away.code
        if not results[home] then
            table.insert(codes, home)
            results[home] = {}
        end
        if not results[away] then
            table.insert(codes, away)
            results[away] = {}
        end
        table.insert(results[home], match)
        table.insert(results[away], match)
        count = math.max(count, #results[home], #results[away])
    end
    local teamsort = function(t1, t2)
        return teams[t1].fullName < teams[t2].fullName
    end
    table.sort(codes, teamsort)

    local container = wrapper:tag('div')
        :css('float', 'left')
        :css('max-width', '100%')
    local tbl = container:tag('table')
        :attr('class', 'wikitable')
        :css('width', '100%')
        :css('text-align', 'center')
        :css('display', 'block')
        :css('overflow', 'auto')
        :css('border', 'none')

    -- headers
    local row = tbl:tag('tr')
    row
        :tag('th')
            :attr('scope', 'col')
            :attr('rowspan', '2')
            :css('border-right', 'black solid 2px')
            :wikitext('Team')
        :done()
        :tag('th'):attr('colspan', count):wikitext('Group matches'):done()
    if koStages then
        row:tag('th')
            :attr('colspan', #koStages)
            :css('border-left', 'black solid 2px')
            :wikitext(koName or 'Knockout matches')
    end

    row = tbl:tag('tr')
    for i = 1, count do
        row:tag('th'):attr('scope', 'col'):css('min-width', '18px'):wikitext(i)
    end
    local cell
    for i = 1, #koStages do
        cell = row:tag('th')
            :attr('scope', 'col')
            :css('width', '18px')
            :tag('abbr')
                :attr('title', koStages[i].name)
                :wikitext(koStages[i].abbr)
            :done()
        if i == 1 then cell:css('border-left', 'black solid 2px') end
    end

    -- matches
    for _, code in ipairs(codes) do
        renderTeam(tbl, count, teams[code], results[code], koStages, #matches)
    end

    buildLegend(container)
    wrapper:tag('div'):css('clear', 'left')
    return tostring(wrapper)
end

p.IPL = function(frame)
    local args = getArgs(frame)
    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
    local playoffs = {
        { name = 'Qualifier 1 or Eliminator', abbr = 'Q1/E', matches = {
            { winner = args.P1W, loser = args.P1L },
            { winner = args.P2W, loser = args.P2L }
        }},
        { name = 'Qualifier 2', abbr = 'Q2', matches = {
            { winner = args.P3W, loser = args.P3L }
        }},
        { name = 'Final', abbr = 'F', matches = {
            { winner = args.P4W, loser = args.P4L }
        }}
    }
    return p.create(args, teamsAssoc, "Playoffs", playoffs)
end

p.IPL_SF = function(frame)
    local args = getArgs(frame)
    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
    local knockout = {
        { name = 'Semi-finals', abbr = 'SF', matches = {
            { winner = args.SF1W, loser = args.SF1L },
            { winner = args.SF2W, loser = args.SF2L }
        }},
        { name = 'Final', abbr = 'F', matches = {
            { winner = args.FW, loser = args.FL }
        }}
    }
    return p.create(args, teamsAssoc, "Knockout", knockout)
end

return p