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 _module = {}
---------- 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
---------- Html Builder ----------
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
local function buildLegend(isLimitedOvers)
local key = htmlBuilder.create('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').css('width', '50%')
addTableCell(row, tieColour, 'Match tied').css('width', '50%')
else
local row
row = addTableRow(key)
local width = '33.333333%'
addTableCell(row, homeWinColour, 'Home team won').css('width', width)
addTableCell(row, awayWinColour, 'Visitor team won').css('width', width)
addTableCell(row, noResultColour, 'Match drawn').css('width', width).attr('rowspan', '2')
row = addTableRow(key)
addTableCell(row, tieColour, 'Match abandoned').css('width', width)
addTableCell(row, drawColour, 'Match tied').css('width', width)
end
local list = htmlBuilder.create('ul').css('font-size', '90%')
list.tag('li').wikitext("'''Note''': Results listed are according to the home (horizontal) and visitor (vertical) teams.")
list.tag('li').wikitext("'''Note''': Click on a result to see a summary of the match.")
return tostring(key) .. tostring(list)
end
_module.create = function(frame, title, teams, isLimitedOvers, tableStyle, useWebSlice)
---------- Functions ----------
local strMatch = string.match
local strFind = string.find
local strFormat = string.format
local strSub = string.sub
local strRepeat = string.rep
local strUpper = string.upper
local yesno = require("Module:Yesno")
-- The table containing all the matches, looked up by home and away teams.
local matches = {}
-- Matches which have been defined have a 'true' value for their match number key in this table.
local matchIDs = {}
-- This is used to lookup team objects by name
local teamLookup = {}
-- The total number of teams
local teamCount = #teams
-- The output buffer. It contains all the strings to be output. The 'print' function adds a string to the output buffer
local output = {}
local outputIndex = 1
local print = function(s)
output[outputIndex] = s
outputIndex = outputIndex + 1
end
-- The error buffer. It contains all the errors accumulated when the table was generated. addError() adds an error to the buffer
local errors
local errorIndex = 1
local addError = function(msg, matchID)
errors = errors or {}
if matchID then
errors[errorIndex] = strFormat('* <span class="error" style="font-weight: normal">Error (match %s): %s</span>\n', matchID, msg)
else
errors[errorIndex] = strFormat('* <span class="error" style="font-weight: normal">Error: %s</span>\n', msg)
end
errorIndex = errorIndex + 1
end
-- Sort the teams and create the lookup table
local teamSorter = function(t1, t2)
return t1.fullName < t2.fullName
end
table.sort(teams, teamSorter)
for i = 1, teamCount do
local teamObj = teams[i]
teamLookup[teamObj.code] = teamObj
teamLookup[teamObj.shortName] = teamObj
teamLookup[teamObj.fullName] = teamObj
end
-- Parse the rows
for i, row in ipairs(frame.args) do
local match = {}
-- Key/value pairs for each row are separated by semicolons, and a colon separates the key from the value.
local semicolon = 0
repeat
local start = semicolon + 1
semicolon = strFind(row, ';', start, true) or 0
local colon = strFind(row, ':', start, true)
if colon and (colon < semicolon or semicolon == 0) then
match[strMatch(strSub(row, start, colon - 1), '^%s*(.-)%s*$')] = strMatch(strSub(row, colon + 1, semicolon - 1), '^%s*(.-)%s*$')
end
until semicolon == 0
local hasError = false
local id = match.match
if not id then
addError(strFormat("Parameter #%d does not have a match number.", i))
hasError = true
end
-- Get the home and away teams for the match.
local home, away, t
t = match.home
if t then
home = teamLookup[t]
if not home then addError("The team '" .. t .. "' does not exist.", id); hasError = true end
else addError("Missing parameter: 'home'."); hasError = true end
t = match.away
if t then
away = teamLookup[t]
if not away then addError("The team '" .. t .. "' does not exist.", id); hasError = true end
else addError("Missing parameter: 'away'."); hasError = true end
if home == away then -- Home and away teams cannot be the same.
addError("Invalid match (home and away teams are equal).", id); hasError = true
elseif matchIDs[id] then -- A match with the given match number is already defined
addError("A match with this match number has already been defined.", id); hasError = true
end
if not hasError then -- If there is no error, store the match in the matches table.
matchIDs[id] = true
if not matches[home] then matches[home] = {} end
matches[home][away] = match
end
end
-- Construct the header
print(strFormat([[
%s
<div style="float: left">
{| class="wikitable" style="%s"
! scope="row" | Visitor team →
]],
useWebSlice and frame:expandTemplate({ title = "WebSlice-begin", args = { id = "427", title = name } }) or "",
tableStyle or "text-align: center; white-space: nowrap; width: 100%"))
for i = 1, teamCount do
local team = teams[i]
print(strFormat('! rowspan="2" scope="col" style="padding: inherit 10px" | [[%s|%s]]\n', team.pageName, team.code))
end
print('|-\n! scope="col" | Home team ↓\n')
-- The wikitext fot the table cell where a match is not defined.
local noMatchCell = '| style="background-color: ' .. noMatchColour .. '" |\n'
-- The text appended to the margin string if the match's 'dl' parameter is true
local dlString = isDL and ' <span style="font-size: 85%">(D/L)</span>' or ""
--[[
Returns a margin string from the given parameters, or nil if an error occurs.
id: The match number (used in error messages).
margin: A number suffixed with 'R' (runs) or 'W' (wickets), or 'F' for a forfeited match.
isDL: If the result is decided by the D/L method, this should be true.
isSuperOver: If the result is decided by a super over, this should be true.
]]
local getMarginString = function(id, margin, isDL, isSuperOver)
if not margin then
addError("The result 'H' or 'A' requires a margin.", id)
elseif margin == 'F' then return "Forfeited"
elseif isSuperOver then return "Super Over"
else
local n, t = tonumber(strSub(margin, 1, -2)), strUpper(strSub(margin, -1, -1))
if not n then
addError("Margin must be a valid number suffixed with R or W.", id)
elseif t == 'R' then
return strFormat("%d runs%s", n, dlString)
elseif t == 'W' then
return strFormat("%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.", id)
else
return strFormat("inns & %d runs%s", n, dlString)
end
else
addError("Margin must be 'F', or a valid number suffixed with 'R', 'W' or 'I'.", id)
end
end
return nil -- Return nil in case of an error
end
-- Outputs an error cell for a given match number.
local printErrorCell = function(id)
print(strFormat('| style="background-color: %s; padding: 3px 5px; line-height: 300%%" |[[#match%s|Match %s]]\n', errorColour, id, id))
end
-- Output the main body of the table
for i = 1, teamCount do
-- Each row starts with a home team header
local home = teams[i]
local noHomeMatches = not matches[home]
print(strFormat('|-\n! scope="row" style="text-align: left; padding: 3px 5px; white-space: normal%s" | [[%s|%s]]\n', noHomeMatches and "; line-height: 275%" or "", home.pageName, home.fullName))
if noHomeMatches then -- No home matches played by the team
print(strRepeat(noMatchCell, teamCount))
else
for j = 1, teamCount do
local away = teams[j]
local match = matches[home][away]
if match then
local id, result, dl, superover = match.match, match.result, yesno(match.dl, false), yesno(match.superover, false)
if not result then -- Result not provided
addError("Missing parameter: 'result'.")
printErrorCell(id)
elseif result == 'H' then -- Home team wins
local m = getMarginString(id, match.margin, dl, superover)
if m then
print(strFormat('| style="background-color: %s; padding: 3px 5px" | %s<br />[[#match%s|%s]]\n', homeWinColour, home.shortName, id, m))
else printErrorCell(id) end
elseif result == 'A' then -- Away team wins
local m = getMarginString(id, match.margin, dl, superover)
if m then
print(strFormat('| style="background-color: %s; padding: 3px 5px" | %s<br />[[#match%s|%s]]\n', awayWinColour, home.shortName, id, m))
else printErrorCell(id) end
elseif result == 'X' then -- Match has not been played yet
print(strFormat('| style="background-color: %s; padding: 3px 5px; line-height: 300%%" | [[#match%s|Match %s]]\n', notPlayedColour, id, id))
elseif 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.", id)
printErrorCell(id)
else
print(strFormat('| style="background-color: %s; padding: 3px 5px; line-height: 300%%" | [[#match%s|Match drawn]]\n', drawColour, id))
end
elseif result == 'N' then -- Abandoned match
print(strFormat('| style="background-color: %s; padding: 3px 5px" | [[#match%s|Match<br />abandoned]]\n', noResultColour, id))
elseif result == 'T' then -- Tied match
print(strFormat('| style="background-color: %s; padding: 3px 5px;" | [[#match%s|Match tied]]\n', tieColour, id))
else -- Invalid result
addError("Invalid result: '" .. result .. "'. Expected: H, A, X, N, D or T.", id)
printErrorCell(id)
end
else
-- The match is not defined.
print(noMatchCell)
end
print('\n')
end
end
end
-- Legend and notes
print(strFormat('|}'))
print(buildLegend(isLimitedOvers))
print(strFormat([[
</div>
<div style="clear: both" />
%s]],
useWebSlice and frame:expandTemplate({ title = 'WebSlice-end', args = {} }) or ""))
if errorIndex ~= 1 then -- If there are errors, output them and insert a tracking category
return strFormat('<div class="plainlist">\n%s</div>[[Category:Pages with errors reported by Module:CricketLeagueGroupStageSummary]]\n%s', table.concat(errors), table.concat(output))
end
return table.concat(output)
end
return _module