Module:CricketLeagueGroupStageSummary/sandbox
Appearance
![]() | This is the module sandbox page for Module:CricketLeagueGroupStageSummary (diff). See also the companion subpage for test cases (run). |
Example
{{#invoke: CricketLeagueGroupStageSummary|IPL <!-- home | away | result | margin | DL --> | MI | KKR | A | 41R | N | KKR | MI | A | 2W | N | MI | CSK | T | | Y | CSK | MI | H | SO | N | KKR | CSK | N | | N | CSK | KKR | | | }}
Visitor team → | CSK | KKR | MI |
---|---|---|---|
Home team ↓ | |||
Chennai Super Kings | Match 6 | Chennai Super Over | |
Kolkata Knight Riders | Match abandoned | Mumbai 2 wickets | |
Mumbai Indians | Match tied | Kolkata 41 runs |
Home team won | Visitor team won |
- Note: Results listed are according to the home (horizontal) and visitor (vertical) teams.
- Note: Click on a result to see a summary of the match.
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.getMarginResult = function(m, row, isLimitedOvers)
local colour = m.result == 'H' and homeWinColour or awayWinColour
local marginText
if m.margin == 'F' then
marginText = "Forfeited"
elseif m.margin == 'SO' then
marginText = "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 t == 'R' then
marginText = string.format("%d runs%s", n, dlString)
elseif t == 'W' then
marginText = string.format("%d wickets%s", n, dlString)
elseif t == 'I' then
if isLimitedOvers then
return addErrorCell(row, m.id,
"A margin suffixed with 'I' cannot be used in limited-overs formats.")
else
marginText = string.format("Inns & %d runs%s", n, dlString)
end
end
end
if not marginText then
return addErrorCell(row, m.id, "Margin must be 'F', or a valid number suffixed with 'R', 'W' or 'I'.")
end
return addTableCell(row, colour,
string.format('%s<br />[[#match%s|%s]]', m.home.shortName, m.id, marginText))
.css('padding', '3px 5px')
end
cricmatch.getMargin = function(m, isLimitedOvers)
if not m.margin then
return nil
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
return nil
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 & %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, isLimitedOvers)
-- Result not provided
if not m.result then
return addErrorCell(row, m.id)
end
-- Match has not been played yet
if m.result == 'X' then
return 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
return addErrorCell(row, m.id, "The result 'D' cannot be used in limited-overs formats.")
else
return 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
return addTableCell(row, noResultColour,
string.format('[[#match%s|Match<br />abandoned]]', m.id))
.css('padding', '3px 5px')
elseif m.result == 'T' then
-- Tied match
return addTableCell(row, tieColour,
string.format('[[#match%s|Match tied]]', m.id))
.css('padding', '3px 5px')
elseif m.result == 'H' or m.result == 'A' then
return m.getMarginResult(row, isLimitedOvers)
end
-- Invalid result
return addErrorCell(row, m.id,
"Invalid result: '" .. m.result .. "'. Expected: H, A, X, N, D or T.")
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, error)
local text = string.format('Match %s', id)
local link = string.format('[[#match%s|<abbr title="%s">%s</abbr>]]', id, error, text)
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, 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
local teamsort = function(t1, t2)
return teams[t1].fullName < teams[t2].fullName
end
table.sort(codes, teamsort)
-- Construct the header
local container = htmlBuilder.create('div')
.css('float', 'left')
local tbl = container.tag('table')
.attr('class', 'wikitable')
if tableStyle then
tbl.cssText(tableStyle)
else
tbl.css('text-align', 'center')
.css('white-space', 'nowrap')
.css('width', '100%')
end
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, isLimitedOvers)
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.IPL = function(frame)
local args = getArgs(frame)
local teamsAssoc = {}
local i = 1
while teams[i] do
teamsAssoc[teams[i].code] = teams[i]
i = i + 1
end
return p.create(args, teamsAssoc, true)
end
return p