Module:EUT20LeagueGroupStageSummary

.mw-parser-output .documentation,.mw-parser-output .documentation-metadata{border:1px solid var(--border-color-base,#a2a9b1);background-color:#ecfcf4;color:inhe

Module:EUT20LeagueGroupStageSummary
local p = {}

---------- Background colours for table cells ----------
local colours = {
    H = "#CCCCFF", -- Home team wins
    A = "#FFCCCC", -- Away team wins
    N = "#FFDEAD", -- Match abandoned (Cross-matrix)
    D = "#F0E68C", -- Match drawn
    T = "#DDFFDD"  -- Match tied
}

local noMatchColour = "#C0C0C0"     -- Grey for same team diagonal and blank areas

local function trim(s)
    return s and (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1")) or nil
end

local 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

-- To render result text with anchor links safely
local function appendResultLink(cell, matchId, text)
    if not cell then return end
    cell:tag('span')
        :attr('title', string.format('Match %d', matchId))
        :wikitext(string.format('[[#match%d|%s]]', matchId, text))
end

local function renderMarginResult(row, match, matchNo)
    local team = match.result == 'H' and match.home or match.away
    local marginText = matchNo
    
    if match.margin == 'F' then 
        marginText = "Forfeited"
    elseif match.margin == 'SO' then 
        marginText = "Super Over"
    elseif match.margin == 'N' then
        marginText = "Match<br />abandoned"
    elseif match.margin and match.margin ~= "" then
        local n = tonumber(string.sub(match.margin, 1, -2))
        local t = string.upper(string.sub(match.margin, -1, -1))
        if t == 'R' then 
            marginText = n == 1 and "1 run" or string.format("%d runs", n)
        elseif t == 'W' then 
            marginText = n == 1 and "1 wicket" or string.format("%d wickets", n)
        else
            marginText = match.margin
        end
    end
    
    if match.dl then 
        marginText = marginText .. ' <span style="font-size: 85%">(' .. match.dl .. ')</span>' 
    end
    
    local cell = row:tag('td'):css('background-color', colours[match.result]):css('padding', '3px 5px')
    if match.margin == 'N' then
        appendResultLink(cell, match.id, marginText)
    else
        cell:tag('span'):wikitext(team.shortName):done():tag('br')
        appendResultLink(cell, match.id, marginText)
    end
end

local function processCellOutput(row, match)
    local matchNo = string.format('Match %d', match.id)
    if match.result == 'D' then
        local cell = row:tag('td'):css('background-color', colours.D):css('padding', '3px 5px')
        appendResultLink(cell, match.id, 'Match drawn')
    elseif match.result == 'N' then
        local cell = row:tag('td'):css('background-color', colours.N):css('padding', '3px 5px')
        appendResultLink(cell, match.id, 'Match<br />abandoned')
    elseif match.result == 'T' then
        local cell = row:tag('td'):css('background-color', colours.T):css('padding', '3px 5px')
        appendResultLink(cell, match.id, 'Match tied')
    elseif match.result == 'H' or match.result == 'A' then
        renderMarginResult(row, match, matchNo)
    else
        -- Match is defined but not played yet
        local cell = row:tag('td'):css('background-color', '#F2F2F2'):css('padding', '3px 5px')
        appendResultLink(cell, match.id, matchNo)
    end
end

-- To render the local progression table with notes below it
local function renderProgression(codes, teams, orderedMatches, args, formatMode, eliminated)
    local container = mw.html.create('div'):css('margin-bottom', '25px'):css('overflow', 'hidden')
    local tbl = container:tag('table'):addClass('wikitable'):css('text-align', 'center')
    
    -- Dynamic Round Count & Parameter tracking based on format parameters
    local isPlayoff = (formatMode == 'playoff_league')
    local maxRounds = isPlayoff and 3 or 4
    local stageLabel = isPlayoff and 'Playoff league' or 'Group matches'
    local playoffLabel = isPlayoff and 'F' or 'POQ'
    local playoffTooltip = isPlayoff and 'Final' or 'Playoff league qualifier'
    
    -- Switch parameters conditionally: FW/FL for playoff league, POW/POL for group stage
    local winnerCode = isPlayoff and (args.FW or "") or (args.POW or "")
    local loserCode = isPlayoff and (args.FL or "") or (args.POL or "")
    local hasPlayoffData = (winnerCode ~= "" or loserCode ~= "")
    
    local header = tbl:tag('tr')
    header:tag('th'):attr('rowspan', '2'):wikitext('Team')
    header:tag('th'):attr('colspan', tostring(maxRounds)):wikitext(stageLabel)
    
    -- Square structured playoff column header with explicit Wikipedia-style explain tooltip styling
    header:tag('th'):attr('rowspan', '2')
          :css('width', '32px')
          :css('min-width', '32px')
          :css('max-width', '32px')
          :tag('abbr')
              :addClass('explain')
              :attr('title', playoffTooltip)
              :css('cursor', 'help')
              :css('border-bottom', '1px dotted')
              :css('text-decoration', 'none')
              :wikitext(playoffLabel)
          :done()
    
    local subHeader = tbl:tag('tr')
    for r = 1, maxRounds do subHeader:tag('th'):wikitext(tostring(r)) end
    
    for _, code in ipairs(codes) do
        if code ~= eliminated then
            local row = tbl:tag('tr')
            row:tag('td'):css('text-align', 'left'):wikitext(string.format('[[%s|%s]]', teams[code].pageName, teams[code].fullName))
            
            local teamPoints = 0
            local playedCount = 0
            
            for _, m in ipairs(orderedMatches) do
                if m.home.code == code or m.away.code == code then
                    playedCount = playedCount + 1
                    if playedCount <= maxRounds then
                        local cell = row:tag('td')
                        if not m.result or m.result == '' then
                            cell:wikitext('?')
                        elseif m.result == 'N' then
                            teamPoints = teamPoints + 1
                            cell:css('background-color', '#DFDFFF'):wikitext(string.format('[[#match%d|%d]]', m.id, teamPoints))
                        elseif m.result == 'D' or m.result == 'T' then
                            teamPoints = teamPoints + 1
                            cell:css('background-color', '#F0E68C'):wikitext(string.format('[[#match%d|%d]]', m.id, teamPoints))
                        elseif (m.result == 'H' and m.home.code == code) or (m.result == 'A' and m.away.code == code) then
                            teamPoints = teamPoints + 2
                            cell:css('background-color', '#99FF99'):wikitext(string.format('[[#match%d|%d]]', m.id, teamPoints))
                        else
                            cell:css('background-color', '#FFDDDD'):wikitext(string.format('[[#match%d|%d]]', m.id, teamPoints))
                        end
                    end
                end
            end
            
            for r = playedCount + 1, maxRounds do
                row:tag('td'):wikitext('?')
            end
            
            -- Final or S4Q status indicator grid cell
            local s4qCell = row:tag('td')
                :css('width', '32px')
                :css('min-width', '32px')
                :css('max-width', '32px')
                :css('height', '32px')
                :css('line-height', '32px')
                :css('padding', '0')
                
            if code == winnerCode then
                s4qCell:css('background-color', '#99FF99'):wikitext('W')
            elseif code == loserCode then
                s4qCell:css('background-color', '#FFDDDD'):wikitext('L')
            else
                if hasPlayoffData then
                    s4qCell:css('background-color', '#DCDCDC'):wikitext('&nbsp;') -- Gray filler tile
                else
                    s4qCell:wikitext('&nbsp;')
                end
            end
        end
    end
    
    -- Inline Win/Loss/No Result Box Legend
    local legendTbl = container:tag('table')
        :css('margin-top', '5px')
        :css('border-collapse', 'collapse')
        :css('font-size', '90%')
        :css('text-align', 'center')
    local lRow = legendTbl:tag('tr')
    lRow:tag('td'):css('border', '1px solid #aaa'):css('background-color', '#99FF99'):css('padding', '2px 10px'):wikitext('Win')
    lRow:tag('td'):css('border', '1px solid #aaa'):css('background-color', '#FFDDDD'):css('padding', '2px 10px'):wikitext('Loss')
    lRow:tag('td'):css('border', '1px solid #aaa'):css('background-color', '#DFDFFF'):css('padding', '2px 10px'):wikitext('No result')

    -- Footnotes for Progression Layout
    local notes = container:tag('ul'):css('font-size', '90%'):css('margin-top', '8px'):css('list-style-type', 'disc'):css('overflow', 'hidden')
    notes:tag('li'):wikitext("'''Note:''' The total points at the end of each stage match are listed.")
    notes:tag('li'):wikitext("'''Note:''' Click on the points or W/L indicators to see the match summary.")
    
    return container
end

-- To renders the local cross matrix table with notes below it
local function renderSummaryMatrix(codes, teams, results, types, eliminated)
    local container = mw.html.create('div'):css('margin-bottom', '25px'):css('overflow', 'hidden')
    local tbl = container:tag('table'):addClass('wikitable'):css('text-align', 'center'):css('white-space', 'nowrap')
    
    local header = tbl:tag('tr')
    
    -- Corner cell structured with a solid, bold horizontal divider that touches both borders perfectly
    local cornerCell = header:tag('th')
        :css('padding', '0')
        :css('font-weight', 'bold')
        :css('min-width', '110px')
    
    cornerCell:tag('div')
        :css('text-align', 'center')
        :css('padding', '5px 5px 4px 5px')
        :css('border-bottom', '2px solid #aaa')
        :wikitext('Visitor team →')
        
    cornerCell:tag('div')
        :css('text-align', 'center')
        :css('padding', '4px 5px 5px 5px')
        :wikitext('Home team ↓')
    
    for _, code in ipairs(codes) do
        if code ~= eliminated then
            header:tag('th'):attr('scope', 'col')
                  :css('min-width', '90px')
                  :wikitext(string.format('[[%s|%s]]', teams[code].pageName, teams[code].code))
        end
    end
    
    for _, hCode in ipairs(codes) do
        if hCode ~= eliminated then
            local row = tbl:tag('tr')
            row:tag('th'):attr('scope', 'row'):css('text-align', 'left'):wikitext(string.format('[[%s|%s]]', teams[hCode].pageName, teams[hCode].fullName))
            for _, vCode in ipairs(codes) do
                if vCode ~= eliminated then
                    if hCode == vCode then
                        row:tag('td'):css('background-color', noMatchColour):css('padding', '3px 5px'):wikitext('&nbsp;<br />&nbsp;')
                    else
                        local match = results[hCode] and results[hCode][vCode]
                        if match then 
                            processCellOutput(row, match)
                        else 
                            row:tag('td'):css('background-color', noMatchColour):css('padding', '3px 5px'):wikitext('&nbsp;<br />&nbsp;') 
                        end
                    end
                end
            end
        end
    end
    
    local legendTbl = container:tag('table')
        :css('margin-top', '5px')
        :css('border-collapse', 'collapse')
        :css('font-size', '90%')
        :css('text-align', 'center')
    local lRow = legendTbl:tag('tr')
    lRow:tag('td'):css('border', '1px solid #aaa'):css('background-color', colours.H):css('padding', '4px 10px'):wikitext('Home team won')
    lRow:tag('td'):css('border', '1px solid #aaa'):css('background-color', colours.A):css('padding', '4px 10px'):wikitext('Visitor team won')

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

p.main = function(frame)
    local args = getArgs(frame)
    local mode = args.mode or 'summary'
    local engine = args.engine or ''
    local formatParam = args.format or ''
    local eliminated = args.eliminated_team or ''
    
    -- Extract match starting ID base (Default to 1 if missing or invalid)
    local startMatch = tonumber(args.start_match) or 1
    
    -- Rule validation guards
    if engine ~= 'custom' and (formatParam == 'group_only' or formatParam == 'playoff_league') then
        return '<span class="error" style="font-weight:bold;">Error: engine=custom is mandatory to use format=group_only or format=playoff_league.</span>'
    end
    
    if engine == 'custom' and formatParam ~= 'group_only' and formatParam ~= 'playoff_league' then
        return '<span class="error" style="font-weight:bold;">Error: Invalid custom format parameter configuration. Use group_only or playoff_league.</span>'
    end
    
    local teamsRaw = mw.loadData("Module:EUT20 Belgium teams")
    local teams = {}
    local codes = {}
    
    for _, t in ipairs(teamsRaw) do 
        teams[t.code] = t 
        table.insert(codes, t.code)
    end
    table.sort(codes, function(a, b) return teams[a].fullName < teams[b].fullName end)
    
    local matches, results, types = {}, {}, {}
    local i = 0
    local currentMatchId = startMatch
    local dlText = args.dls == 'Y' and 'DLS' or 'D/L'
    
    while true do
        local baseIndex = i * 5
        if not args[baseIndex + 1] and not args[baseIndex + 6] and not args[baseIndex + 11] then
            break
        end
        
        local homeCode = args[baseIndex + 1]
        local awayCode = args[baseIndex + 2]
        
        if homeCode and awayCode then
            local home = teams[homeCode]
            local away = teams[awayCode]
            local result = args[baseIndex + 3] or ""
            local margin = args[baseIndex + 4] or ""
            local dl = args[baseIndex + 5] == "Y"
            
            if home and away then
                local match = {
                    id = currentMatchId,
                    home = home,
                    away = away,
                    result = result,
                    margin = margin,
                    dl = dl and dlText or nil
                }
                table.insert(matches, match)
                results[home.code] = results[home.code] or {}
                results[home.code][away.code] = match
                if result ~= "" then types[result] = true end
                currentMatchId = currentMatchId + 1
            end
        end
        i = i + 1
    end
    
    local out = mw.html.create('div')
    
    if mode == 'summary/progression' or mode == 'progression/summary' or mode == 'progression' then
        out:node(renderProgression(codes, teams, matches, args, formatParam, eliminated))
    end
    
    if mode == 'summary/progression' or mode == 'progression/summary' or mode == 'summary' then
        out:node(renderSummaryMatrix(codes, teams, results, types, eliminated))
    end
    
    return tostring(out)
end

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.