Module:CricketLeagueProgression

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.title = function(m, home) local opponent = home and m.away or m.home local venue = home and 'H' or 'A'   local title = string.format('vs. %s (%s)', opponent.fullName, venue) if m.result ~= 'H' and m.result ~= 'A' then return title end

local marginText = (m.result == 'H' and home or       m.result == 'A' and not home) and 'Won by ' or 'Lost by ' if m.margin == 'F' then marginText = marginText .. "forfeit" elseif m.margin == 'SO' then marginText = marginText .. "Super Over" else local n = tonumber(string.sub(m.margin, 1, -2)) local t = string.upper(string.sub(m.margin, -1, -1)) if t == 'R' then marginText = marginText .. "%d run" elseif t == 'W' then marginText = marginText .. "%d wicket" elseif t == 'I' then marginText = marginText .. "an innings and %d run" end if marginText and n then marginText = string.format(marginText, n)           if n > 1 then marginText = marginText .. "s" end end if m.dl then marginText = marginText .. ' (' .. m.dl .. ')' end end return marginText .. ' ' .. title end

cricmatch.render = function(m, row, team, points) local cell = row:tag('td') local home = m.home == team local span = cell:tag('span'):attr('title', m.title(home))

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)        span:wikitext(string.format('?', m.id)) return points end

points = points + gained cell:css('background-color', colours[result]) span:wikitext(string.format('%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   local dlText = args.dls == 'Y' and 'DLS' or 'D/L' 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 and dlText or nil) 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', 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('%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.ICC = function(frame) local args = getArgs(frame) local teams = mw.loadData("Module:ICC teams") local teamsAssoc = {} local i = 1 while teams[i] do       teamsAssoc[teams[i].code] = teams[i] i = i + 1 end return p.create(args, teamsAssoc) end

p.IPL = function(frame) local args = getArgs(frame) local teams = mw.loadData("Module:Indian Premier League 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:Indian Premier League 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

p.WPL = function(frame) local args = getArgs(frame) local teams = mw.loadData("Module:Women's Premier League teams") local teamsAssoc = {} local i = 1 while teams[i] do       teamsAssoc[teams[i].code] = teams[i] i = i + 1 end local playoffs = { { name = 'Eliminator', abbr = 'E', matches = { { winner = args.P1W, loser = args.P1L } }},       { name = 'Final', abbr = 'F', matches = { { winner = args.P2W, loser = args.P2L } }}   }    return p.create(args, teamsAssoc, "Playoffs", playoffs) end

p.PSL = function(frame) local args = getArgs(frame) local teams = mw.loadData("Module:PakistanSuperLeagueTeams") local teamsAssoc = {} local i = 1 while teams[i] do       teamsAssoc[teams[i].code] = teams[i] i = i + 1 end local playoffs = { { name = 'Eliminator 1 or Qualifier', abbr = 'E1/Q', matches = { { winner = args.P1W, loser = args.P1L }, { winner = args.P2W, loser = args.P2L } }},       { name = 'Eliminator 2', abbr = 'E2', 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.PSL_SF = function(frame) local args = getArgs(frame) local teams = mw.loadData("Module:PakistanSuperLeagueTeams") 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