Module:Sports series: Difference between revisions

Content deleted Content added
allow for simplified anchor links
improve link rewriting
 
(26 intermediate revisions by 4 users not shown)
Line 9:
end
 
-- Function to check the existence of template passed via |flag=flagTemplate
local function templateExists(templateName)
local title = mw.title.new('Template:' .. templateName)
Line 15:
end
 
-- Function to process country codes and variants OR youth team flag templates and age level, dividing parameters by the "+" sign
local function processIcon(iconString)
if not iconString or iconString:match("^%s*$") then
Line 41:
else
return n .. 'th'
end
end
 
-- Function to replace wiki links with their display text or link text
local function replaceLink(match)
local pipePos = match:find("|")
if pipePos then
return match:sub(pipePos + 1, -3) -- Return text after the '|'
else
return match:sub(3, -3) -- Return text without the brackets
end
end
Line 49 ⟶ 59:
if not score or score:match("^%s*$") then
return ''
end
 
-- Function to replace wiki links with their display text or link text
local function replaceLink(match)
local pipePos = match:find("|")
if pipePos then
return match:sub(pipePos + 1, -3) -- Return text after the '|'
else
return match:sub(3, -3) -- Return text without the brackets
end
end
 
Line 65:
 
-- Remove MediaWiki's unique placeholder sequences for references
score = score:gsub('\127%\'"`UNIQ.-QINU`"%\'\127', '')
 
-- Remove superscript tags and their contents
Line 71:
 
-- Convert dashes to a standard format
score = score:gsub('[–—―‒−]+', '-')
 
-- Strip all characters except numbers, dashes and parentheses
Line 78:
 
-- Function to determine the winner based on scores within parentheses (first) or regular format (second)
local function determineWinner(cleanAggregate, matchType, team1, team2, boldWinner, colorWinner, aggregate, isFBRStyle, legs, leg1Score, leg2Score, disableAwayGoals, skipAutoWinner, aggFormat)
local team1Winner, team2Winner = false, false
local score1, score2
Line 114:
end
if aggregate then
if aggregate:find("aggFormat == 'bold' or aggFormat == 'both'") then
aggregate = aggregate:gsub("'''<b>", .. aggregate .. "</b>")
aggregate = "<strong>" .. aggregate .. "</strong>"
end
manualColorDraw = aggregate:find("aggFormat == 'italic'") andor notaggFormat == (aggregate:gsub("'both'", ""):match("^%s*$"))
aggregate = aggregate:gsub("''", "")
end
 
Line 140 ⟶ 138:
 
-- Regular winner determination logic if manual bolding or coloring is not conclusive
if not team1Winner and not team2Winner and not isDraw and not skipAutoWinner and (boldWinner or colorWinner or isFBRStyle) then
local parenthetical = cleanAggregate:match('%((%d+%-+%d+)%)')
local outsideParenthetical = cleanAggregate:match('^(%d+%-+%d+)')
Line 152 ⟶ 150:
score1 = tonumber(score1)
score2 = tonumber(score2)
 
if score1 > score2 then
team1Winner = true
Line 166 ⟶ 164:
if team1AwayGoals and team2AwayGoals then
team1AwayGoals, team2AwayGoals = tonumber(team1AwayGoals), tonumber(team2AwayGoals)
 
if team1AwayGoals > team2AwayGoals then
team1Winner = true
Line 174 ⟶ 172:
end
end
 
if (colorWinner or isFBRStyle) and legs == 0 then
isDraw = not team1Winner and not team2Winner
Line 182 ⟶ 180:
 
return team1, team2, team1Winner, team2Winner, manualBold, manualColor, isDraw, aggregate
end
 
-- Function to process score bold/italic formatting
function processScore(s)
if not s or s == "" then
return "", false
end
 
local scoreFormat = false
 
-- Check for 5+ apostrophes (both bold and italic)
if s:match("'''''+") then
scoreFormat = "both"
s = s:gsub("''+", "")
return s, scoreFormat
end
 
-- Check for 3+ apostrophes (bold)
if s:match("'''+") then
scoreFormat = "bold"
s = s:gsub("''+", "")
return s, scoreFormat
end
 
-- Check for 2 apostrophes (italic)
if s:match("''") then
scoreFormat = "italic"
s = s:gsub("''+", "")
return s, scoreFormat
end
 
-- If no matches found, return original string and false
return s, scoreFormat
end
 
-- Function to check if any parameter in a given row is non-nil and non-empty
local function anyParameterPresent(startIndex, step, args)
-- Check regular parameters
for index = startIndex, startIndex + step - 1 do
if args[index] and args[index]:match("^%s*(.-)%s*$") ~= "" then
Line 191 ⟶ 223:
end
end
 
-- Check aggregate note
local rowIndex = math.floor((startIndex - 1) / step) + 1
local aggNote = args['note_agg_' .. rowIndex]
if aggNote and aggNote:match("^%s*(.-)%s*$") ~= "" then
return true
end
 
-- Check leg notes
local numLegs = step - (noFlagIcons and 3 or 5) -- Calculate number of legs
for leg = 1, numLegs do
local legNote = args['note_leg' .. leg .. '_' .. rowIndex]
if legNote and legNote:match("^%s*(.-)%s*$") ~= "" then
return true
end
end
 
return false
end
 
-- Function to addcheck a legendwhether to belowreduce font thesize tablefor whenupcoming |matches_style=FBRmatches
local function createFBRLegendcheckSmallText(str)
-- Check for font size or small/big HTML tags
return mw.html.create('div')
if str:cssmatch('"font%s?%-?size',") '90%'or str:match("<small>") or str:match("<big>") then
:css('margin-bottom',return '0.5em')false
end
:wikitext("Legend: Blue = home team win; Yellow = draw; Red = away team win.")
 
-- Remove MediaWiki's unique placeholder sequences for references
str = str:gsub('\127%\'"`UNIQ.-QINU`"%\'\127', '')
 
-- Remove superscript tags and their contents
str = str:gsub('<sup.->.-</sup>', '')
 
-- Check for walkover-related strings (never shown in small text)
if str:lower():match("walkover") or str:lower():match("w%.o%.") or str:lower():match("w/o") or str:lower():match("bye") then
return false
end
 
-- Replace wiki links with their display text or link text
str = str:gsub("%[%[.-%]%]", replaceLink)
 
-- Remove all text inside parentheses
str = str:gsub("%b()", "")
 
-- Exit if string contains only en/em dash
if str == "—" or str == "–" then
return false
end
 
-- Convert dashes to a standard format
str = str:gsub('[–—―‒−]+', '-')
 
-- Remove opening and closing HTML tags
str = str:gsub("</?%w+[^>]*>", "")
 
-- Remove apostrophes
str = str:gsub("''+", "")
 
-- Remove all whitespace
str = str:gsub("%s+", "")
 
-- Check if the string matches only a scoreline
if str:match("^%d+-%d+$") then
return false
else
return true
end
end
 
-- Function to rewrite anchor links ofin matcha scoresstring
local function rewriteAnchorLinks(textstr, baselink, currentPageTitle)
if not textstr or str == "" then
return textstr
end
return text:gsub('(%[%[)(#[^%[%]]*%|)', '%1' .. baselink .. '%2')
-- Add the base link to anchor links when the module is transcluded on another page
if baselink ~= '' then
str = mw.ustring.gsub(str, '(%[%[)(#[^%[%]]*%|)', '%1' .. baselink .. '%2')
end
-- Remove redundant page references when viewing anchors on the current page
if currentPageTitle and currentPageTitle ~= "" then
local escapedTitle = currentPageTitle:gsub("([%(%)%.%%%+%-%*%?%[%^%$])", "%%%1")
local titlePattern = '%[%[' .. escapedTitle .. '(#[^%[%]]*%|)'
str = mw.ustring.gsub(str, titlePattern, '[[%1')
end
return str
end
 
-- Function to format the dashes and winning notes for aggregate/leg score parameters, and divide the score from references/notes/superscripts
local function format_and_extract_score(s, addSpan)
if not s then return '', '' end -- Return empty strings if input is nil
 
-- Handle walkovers
if s:match("^%s*[Ww]%s*[/.]%s*[Oo]%s*%.?%s*$") then
return "[[Walkover|w/o]]", ""
end
 
local function format_dash(pattern)
s = mw.ustring.gsub(s, '^' .. pattern, '%1–%2')
s = mw.ustring.gsub(s, '%(' .. pattern, '(%1–%2')
end
 
-- Format dashes
format_dash('%s*([%d%.]+)%s*[–—―‒−%-]%s*([%d%.]+)')
format_dash('%s*([%d%.]+)%s*&[MmNn][Dd][Aa][Ss][Hh];%s*([%d%.]+)')
format_dash('%s*(%[%[[^%[%]]*%|[%d%.]+)%s*[–—―‒−%-]%s*([%d%.]+)')
format_dash('%s*(%[[^%[%]%s]*%s+[%d%.]+)%s*[–—―‒−%-]%s*([%d%.]+)')
format_dash('%s*(%[%[[^%[%]]*%|[%d%.]+)%s*&[MmNn][Dd][Aa][Ss][Hh];%s*([%d%.]+)')
format_dash('%s*(%[[^%[%]%s]*%s+[%d%.]+)%s*&[MmNn][Dd][Aa][Ss][Hh];%s*([%d%.]+)')
 
-- Extract end text
local supStart = s:find('<sup')
local placeholderStart = s:find('\127%\'"`UNIQ')
 
-- Function to find the first parenthesis outside of wikilinks
local function find_paren_outside_wikilinks(s)
local pos = 1
while true do
pos = s:find('%(', pos)
if not pos then break end
local beforeParen = s:sub(1, pos - 1)
local openLinks = select(2, beforeParen:gsub('%[%[', '')) - select(2, beforeParen:gsub('%]%]', ''))
if openLinks == 0 then
return pos
end
pos = pos + 1
end
return nil
end
 
local parenStart = find_paren_outside_wikilinks(s)
 
local startPositions = {}
if supStart then table.insert(startPositions, supStart) end
if placeholderStart then table.insert(startPositions, placeholderStart) end
if parenStart then table.insert(startPositions, parenStart) end
 
local scoreMatch, endText
if #startPositions > 0 then
local startPos = math.min(unpack(startPositions))
-- Find the last non-whitespace character before startPos
local scoreEnd = s:sub(1, startPos - 1):match(".*%S") or ""
scoreEnd = #scoreEnd
 
-- Extract the score and endText
scoreMatch = s:sub(1, scoreEnd)
endText = s:sub(scoreEnd + 1)
else
-- If no match found, return the entire score
scoreMatch = s
endText = ""
end
 
-- Format winning notes in brackets (only if endText is not empty)
if endText ~= "" then
if addSpan then
endText = mw.ustring.gsub(endText, '(%(%d+%s*–%s*%d+)%s*[Pp]%.?[EeSs]?%.?[NnOo]?%.?%)', '<span class="nowrap">%1 [[Penalty shoot-out (association football)|p]])</span>')
endText = mw.ustring.gsub(endText, '%([Aa]%.?[Ee]%.?[Tt]%.?%)', '<span class="nowrap">([[Overtime (sports)#Association football|a.e.t.]])</span>')
else
endText = mw.ustring.gsub(endText, '(%(%d+%s*–%s*%d+)%s*[Pp]%.?[EeSs]?%.?[NnOo]?%.?%)', '%1 [[Penalty shoot-out (association football)|p]])')
endText = mw.ustring.gsub(endText, '%([Aa]%.?[Ee]%.?[Tt]%.?%)', '([[Overtime (sports)#Association football|a.e.t.]])')
end
endText = mw.ustring.gsub(endText, '%([Aa]%.?[Gg]?%.?[Rr]?%.?%)', '([[Away goals rule|a]])')
end
 
return scoreMatch, endText
end
 
-- Function to clean team names and generate links
local function cleanAndGenerateLinks(team1, team2, score, isSecondLeg)
local function cleanTeam(str, defaultName)
if str and str ~= "" then
str = str:gsub('<sup.->.-</sup>', '')
str = str:gsub("</?%w+[^>]*>", "")
str = str:gsub('\127%\'"`UNIQ.-QINU`"%\'\127', '')
str = str:gsub("%[%[[Ff]ile:[^%]]+%]%]", "")
str = str:gsub("%[%[[Ii]mage:[^%]]+%]%]", "")
str = str:gsub("%[%[.-%]%]", replaceLink)
str = str:gsub("%s*&nbsp;%s*", "")
str = str:match("^%s*(.-)%s*$") -- Remove leading and trailing whitespace
return str ~= "" and str or defaultName
end
return defaultName
end
 
team1 = cleanTeam(team1, "Team 1")
team2 = cleanTeam(team2, "Team 2")
 
if score and score:match("%S") then
local linkScore = score
if score:find('%[') then
linkScore = score:match('^([%d%.]+–[%d%.]+)')
if not linkScore then
return score
end
end
 
if linkScore then
local link
if isSecondLeg then
link = "[[#" .. team2 .. " v " .. team1 .. "|" .. linkScore .. "]]"
else
link = "[[#" .. team1 .. " v " .. team2 .. "|" .. linkScore .. "]]"
end
return link .. score:sub(#linkScore + 1)
end
end
 
return score
end
 
-- Function to process notes for aggregate and leg scores
local function processNote(frame, notes, noteKey, noteText, endText, rowIndex, rand_val, noteGroup, baselink, currentPageTitle)
if not noteText then return endText, notes end
if noteText:match("^%s*<sup") or noteText:match("^\127%\'%\"`UNIQ") then
return noteText .. endText, notes
end
 
local function createInlineNote(name)
return frame:extensionTag{
name = 'ref',
args = {
name = name,
group = noteGroup
}
}
end
 
-- Check if noteText is a reference to another note
local referenced_note = noteText:match("^(agg_%d+)$") or noteText:match("^(leg%d+_%d+)$")
if referenced_note then
local referenced_note_id = '"table_note_' .. referenced_note .. '_' .. rand_val .. '"'
return endText .. createInlineNote(referenced_note_id), notes
end
 
-- Process anchor links in noteText before storing
if noteText:find("%[%[") then
noteText = rewriteAnchorLinks(noteText, baselink, currentPageTitle)
end
 
local note_id = '"table_note_' .. noteKey .. '_' .. rowIndex .. '_' .. rand_val .. '"'
if not notes[note_id] then
notes[note_id] = noteText
end
 
return endText .. createInlineNote(note_id), notes
end
 
-- Function to generate the footer if necessary
local function createFooter(frame, notes, noteGroup, isFBRStyle, displayNotes, externalNotes, legs)
local needFooter = (isFBRStyle and legs == 0) or displayNotes or (next(notes) ~= nil)
 
if not needFooter then
return '' -- Return an empty string if no footer is needed
end
 
local divContent = mw.html.create('div')
:addClass('sports-series-notes')
 
if isFBRStyle and legs == 0 then
divContent:wikitext("Legend: Blue = home team win; Yellow = draw; Red = away team win.")
end
 
if (next(notes) ~= nil and not externalNotes) or displayNotes then
divContent:wikitext((isFBRStyle and legs == 0) and "<br>Notes:" or "Notes:")
end
 
local footer = tostring(divContent)
 
if next(notes) ~= nil or displayNotes then
local noteDefinitions = {}
for noteId, noteText in pairs(notes) do
if type(noteId) == 'string' and noteId:match('^"table_note') then
table.insert(noteDefinitions, frame:extensionTag{
name = 'ref',
args = {
name = noteId,
group = noteGroup
},
content = noteText
})
end
end
 
if externalNotes then
local hiddenRefs = mw.html.create('span')
:addClass('sports-series-hidden')
:wikitext(table.concat(noteDefinitions))
if isFBRStyle and legs == 0 then
footer = footer .. tostring(hiddenRefs)
else
footer = tostring(hiddenRefs)
end
else
local reflistArgs = {
refs = table.concat(noteDefinitions),
group = noteGroup
}
footer = footer .. frame:expandTemplate{
title = 'reflist',
args = reflistArgs
}
end
end
 
return footer
end
 
-- Main function that processes input and returns the wikitable
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {trim = true})
local yesno = require('Module:Yesno')
 
-- Check for section transclusion
Line 224 ⟶ 553:
 
local root = mw.html.create()
local templatestyles = frame:extensionTag{
local matchType = (args.type == 'WNT' or args.type == 'MNT') and 'NT' or (args.type or 'club') -- Set default match type to 'club'
name = 'templatestyles',
local isWNT = args.type == 'WNT' -- Track if WNT was set
args = { src = 'Screen reader-only/styles.css' }
local flagTemplate, flagParam1
} .. frame:extensionTag{
local noFlagIcons = false
name = 'templatestyles',
local fillBlanks = args.fill_blanks and (args.fill_blanks == 'y' or args.fill_blanks == 'yes' or args.fill_blanks == '1' or args.fill_blanks == 'true')
args = { src = 'Module:Sports series/styles.css' }
}
root:wikitext(templatestyles)
 
local flagYesno = yesno(args.flag)
local showFlags = flagYesno ~= false
local noFlagIcons = not showFlags
local fillBlanks = yesno(args.fill_blanks)
local generateLinks = yesno(args.generate_links)
local solidCell = yesno(args.solid_cell) or args.solid_cell == 'grey' or args.solid_cell == 'gray'
local baselink = frame:getParent():getTitle()
iflocal currentPageTitle = mw.title.getCurrentTitle().text == baselink then baselink = '' endfullText
if currentPageTitle == baselink then baselink = '' end
local notes = {}
local noteGroup = args.note_group or 'lower-alpha'
local noteListValue = yesno(args.note_list)
local displayNotes = noteListValue == true
local externalNotes = noteListValue == false
math.randomseed(os.clock() * 10^8) -- Initialize random number generator
local rand_val = math.random()
 
-- Process the font size parameter
local sizefontSize
if args.font_size then
-- Remove trailing '%' if present and convert to number
sizefontSize = tonumber((args.font_size:gsub('%s*%%$', '')))
if sizefontSize then
sizefontSize = math.max(sizefontSize, 85) -- Ensure font size is at least 85
end
end
 
-- Process flag parameter to determine flag template and variant
local flagTemplate = 'fbaicon'
if args.flag and args.flag:find('+') then
local flagSize = args.flag_size
flagTemplate, flagParam1 = processIcon(args.flag) -- Process flag icons with variants
if showFlags then
else
if args.flag and args.flag ~= '' and not flagYesno then
flagTemplate = args.flag:gsub('^Template:', '')
elseif isWNT if not templateExists(flagTemplate) then
flagTemplate = 'fbw' --flagTemplate Default= to'flag {{fbw}} for WNT matchesicon'
elseif matchType == 'NT' thenend
flagTemplate = 'fb' -- Default to {{fb}} for NT/MNT matches
else
flagTemplate = 'fbaicon' -- Default to {{fbaicon}} for club matches
end
end
 
if flagSize and not flagSize:match('px$') then
if args.flag and (flagTemplate == 'n' or flagTemplate == 'no' or flagTemplate == '0' or flagTemplate == 'false' or flagTemplate == 'null' or flagTemplate == 'none' or flagTemplate == 'noflag') then
noFlagIcons = true --flagSize Hide flag icons= forflagSize club.. matches'px'
if matchType == 'NT' then
flagTemplate = isWNT and 'fbw' or 'fb' -- Set flagTemplate to "fbw"/"fb", as disabling flags is not allowed for NT
flagParam1 = false
end
end
 
-- Determine whether line should be displayed
-- Check if flagTemplate exists and adjust if necessary
local showCountry = args.show_country
if matchType == 'NT' and (flagTemplate ~= 'fb' and flagTemplate ~= 'fbw') then
local function shouldShowRow(team1Icon, team2Icon)
if not templateExists(flagTemplate) or not templateExists(flagTemplate .. '-rt') then
if not showCountry or noFlagIcons then
flagTemplate = isWNT and 'fbw' or 'fb'
end return true
elseif not noFlagIcons and flagTemplate ~= 'fbaicon' then
if not templateExists(flagTemplate) then
flagTemplate = 'fbaicon'
end
return team1Icon == showCountry or team2Icon == showCountry
end
 
local legs = 2
local legs = (args.legs == '1' or args.legs == 'n' or args.legs == 'no' or args.legs == 'false' or args.legs == 'null' or args.legs == 'none' or args.legs == 'single' or args.legs == 'one') and 0 or tonumber(args.legs) or 2
if args.legs and legs < 0 then
if yesno(args.legs) == false or args.legs == '1' 2then
legs = 0
else
legs = tonumber(args.legs) and math.max(tonumber(args.legs), 2) or 2
end
end
local teamWidth = (tonumber(args['team_width']) and args['team_width'] .. 'px') or '250px'
local scoreWidth = (tonumber(args['score_width']) and args['score_width'] .. 'px') or '80px'
local boldWinner = not (args.bold_winner == 'n'nil or yesno(args.bold_winner, == 'no' or args.bold_winner == '0' or args.bold_winner == 'false' or args.bold_winner == 'null'true)
local colorWinner = args.color_winner and yesno(args.color_winner == 'y' or args.color_winner == 'yes' or args.color_winner == '1' or args.color_winner == 'true')
local matchesStyle = args.matches_style
local isFBRStyle = matchesStyle and matchesStyle:upper() == "FBR"
local isHA = yesno(args.h_a == 'y') or args.h_a(isFBRStyle ==and 'yes' or args.h_a == '1' or args.h_alegs == 'true'0)
local disableAwayGoals = yesno(args.away_goals) == 'n' or args.away_goals == 'no' or args.away_goals == '0' or args.away_goals == 'false' or args.away_goals == 'null'
local disableSmallText = yesno(args.small_text) == false
local noWrapValue = yesno(args.nowrap)
local noWrap = noWrapValue == true
local disableNoWrap = noWrapValue == false
local aggFormat
 
local tableClass = 'wikitable sports-series'
local tableStyledoCollapsed = 'text-align: center;'yesno(args.collapsed)
if doCollapsed then
if args.collapsed and (args.collapsed == 'y' or args.collapsed == 'yes' or args.collapsed == '1' or args.collapsed == 'true') then
tableClass = tableClass .. 'wikitable mw-collapsible mw-collapsed'
tableStyle = 'width: 100%; text-align: center;'
end
if yesno(args.center_table) and not doCollapsed then
if args.nowrap and (args.nowrap == 'y' or args.nowrap == 'yes' or args.nowrap == '1' or args.nowrap == 'true') then
tableStyletableClass = tableStyletableClass .. ' whitecenter-space: nowrap;table'
end
if sizefontSize then
tableStyle = tableStyle .. table:css(' font-size: ', .. sizefontSize .. '%;')
end
 
Line 309 ⟶ 655:
table:attr('id', args.id) -- Optional id parameter to allow anchor to table
end
if noWrap then
 
table:attr('data-nowrap', 'y')
-- Add FBR legend if isFBRStyle is true
ifelseif isFBRStylenot and legs == 0disableNoWrap then
roottable:nodeattr(createFBRLegend()'data-nowrap', 'n')
isHA = true
end
 
Line 326 ⟶ 671:
-- Add a title row above column headings if the "title" parameter is passed
if args.title then
local titleRow = table:tag('tr'):addClass('title-row')
titleRow:tag('th')
:attr('colspan', colCount)
:attr('scope', 'colgroup')
:css('text-align', 'center')
:wikitext(args.title)
end
Line 336 ⟶ 680:
-- Create the header row with team and score columns
local header = table:tag('tr')
local defaultTeam1 = isHA and 'Home team' or 'Team 1'
local defaultTeam2 = isHA and 'Away team' or 'Team 2'
header:tag('th'):attr('scope', 'col'):css('width', teamWidth):wikitext(args['team1'] or defaultTeam1)
header:tag('th')
header:tag('th'):attr('scope', 'col'):css('width', scoreWidth):wikitext(args['aggregate'] or legs == 0 and 'Score' or '[[Aggregate score|<abbr title="Aggregate score">Agg.</abbr>]]<span class="sr-only"> Tooltip Aggregate score</span>')
:attr('scope', 'col')
header:tag('th'):attr('scope', 'col'):css('width', teamWidth):wikitext(args['team2'] or defaultTeam2)
:css('text-align', 'right')
:css('width', teamWidth)
:wikitext(args['team1'] or defaultTeam1)
header:tag('th')
:attr('scope', 'col')
:css('width', scoreWidth)
:wikitext(args['aggregate'] or legs == 0 and 'Score' or expandTemplate(frame, 'Abbrlink', {'Agg.', 'Aggregate score'}))
header:tag('th')
:attr('scope', 'col')
:css('text-align', 'left')
:css('width', teamWidth)
:wikitext(args['team2'] or defaultTeam2)
 
-- Add columns for each leg if applicable
if legs > 0 then
for leg = 1, legs do
local legHeading = args['leg' .. leg]
 
-- Check if "legN" parameter is present
if args['leg'not .. leg]legHeading then
legHeading = args['leg' .. leg]
else
-- Check if "leg_prefix" parameter is present
if args.leg_prefix then
--legHeading Check if= yesno(args.leg_prefix) isand y,('Leg yes,' 1,.. leg) or true(args.leg_prefix .. ' ' .. leg)
ifelseif args.leg_prefixleg_suffix ==and 'y' ornot yesno(args.leg_prefix == 'yes' or args.leg_prefix == '1' or args.leg_prefix == 'true'leg_suffix) then
legHeading = 'Leg ' .. leg
else
legHeading = args.leg_prefix .. ' ' .. leg
end
-- Check if "leg_suffix" parameter is present and does not equal y, yes, 1, or true
elseif args.leg_suffix and args.leg_suffix ~= 'y' and args.leg_suffix ~= 'yes' and args.leg_suffix ~= '1' and args.leg_suffix ~= 'true' then
legHeading = ordinal(leg) .. ' ' .. args.leg_suffix
else
Line 378 ⟶ 702:
end
 
header:tag('th'):attr('scope', 'col'):css('width', scoreWidth):wikitext(legHeading)
:attr('scope', 'col')
:css('width', scoreWidth)
:wikitext(legHeading)
end
end
 
local step = (matchType == 'NT' and 3 or (noFlagIcons and 3 or 5)) + legs -- Determine the step size based on the match type and presence of flag icons
local i = 1
while anyParameterPresent(i, step, args) do
local rowIndex = math.floor((i - 1) / step) + 1
local aggNote = args['note_agg_' .. rowIndex]
local headingParam = args['heading' .. rowIndex]
-- Add a heading above a given row in the table
if headingParam then
local headingRow = table:tag('tr')
headingRow:tag('td')
:attr('colspan', colCount)
:css('text-align', 'center')
:css('background', 'whitesmoke')
:wikitext('<strong>' .. headingParam .. '</strong>')
end
 
local team1, team2, aggregateScore, aggregateEndText, legEndText, team1Icon, team2Icon, team1Variant, team2Variant
local row = table:tag('tr')
local team1, aggregateScore, team2
local team1Winner, team2Winner, manualBold, manualColor, isDraw = false, false, false, false, false
local leg1Score, leg2Score = false, false
local team1Asterick, team2Asterick = false, false
 
-- Process rows forfrom national team matchesinput
if matchTypeteam1 == 'NT' thenargs[i]
if noFlagIcons then
-- Check if team parameter beings with an asterick instead of a country code, indicating a string will be displayed instead of national team flag
team1 = args[i]
if team1 and team1:match("^%s*%*") then
team1 = team1:gsub("^%s*%*", "")
team1Asterick = true
else
team1, team1Variant = processIcon(args[i])
end
aggregateScore = args[i+1]
team2 = args[i+2]
else
if team2 and team2:match("^%s*%*") then
team1Icon, team2team1Variant = team2:gsubprocessIcon("^%s*%*", ""args[i+1])
team2AsterickaggregateScore = trueargs[i+2]
elseteam2 = args[i+3]
team2team2Icon, team2Variant = processIcon(args[i+24])
end
 
-- Check if the line should be shown based on both teams
if shouldShowRow(team1Icon, team2Icon) then
-- Add a heading above a given row in the table
if headingParam and not showCountry then
local headingRow = table:tag('tr'):addClass('heading-row')
headingRow:tag('td')
:attr('colspan', colCount)
:wikitext('<strong>' .. headingParam .. '</strong>')
end
 
--local Cleanrow the= aggregate scoretable:tag('tr')
 
local cleanAggregate = cleanScore(aggregateScore)
-- RewriteName anchorthe links1st/2nd leg scores for two-legged ties
if baselink ~= '' then
aggregateScore = rewriteAnchorLinks(aggregateScore, baselink)
end
-- Name the 1st/2nd leg scores for two-legged ties for possibly determining the winner on away goals
if legs == 2 then
leg1Scoreif =noFlagIcons args[i+3]then
leg2Score = args[i+4]
end
-- Determine the winning team on aggregate
team1, team2, team1Winner, team2Winner, manualBold, manualColor, isDraw, aggregateScore = determineWinner(cleanAggregate, matchType, team1, team2, boldWinner, colorWinner, aggregateScore, isFBRStyle, legs, leg1Score, leg2Score, disableAwayGoals)
-- Add background-color for winning team if set by user
local team1Style = team1Winner and ((colorWinner or manualColor) and 'background-color: #CCFFCC;' or '') .. 'text-align: right;' or 'text-align: right;'
local team2Style = team2Winner and ((colorWinner or manualColor) and 'background-color: #CCFFCC;' or '') .. 'text-align: left;' or 'text-align: left;'
-- Generate text to display for each team
local team1Text, team2Text
if flagParam1 then -- Check whether youth team flag template with age level is used
team1Text = (not team1Asterick and team1 ~= "" and team1 ~= nil) and (expandTemplate(frame, flagTemplate .. '-rt', {flagParam1, team1, variant = team1Variant})) or (team1 ~= nil and team1 or "")
team2Text = (not team2Asterick and team2 ~= "" and team2 ~= nil) and (expandTemplate(frame, flagTemplate, {flagParam1, team2, variant = team2Variant})) or (team2 ~= nil and team2 or "")
else -- Use standard national team flag template without age level
team1Text = (not team1Asterick and team1 ~= "" and team1 ~= nil) and (expandTemplate(frame, flagTemplate .. '-rt', {team1, variant = team1Variant})) or (team1 ~= nil and team1 or "")
team2Text = (not team2Asterick and team2 ~= "" and team2 ~= nil) and (expandTemplate(frame, flagTemplate, {team2, variant = team2Variant})) or (team2 ~= nil and team2 or "")
end
-- When set by user, adds blank flags when string is used for a team instead of national team flag template
if fillBlanks then
if team1Asterick then
team1Text = team1Text .. ' <span class="flagicon">[[File:Flag placeholder.svg|25x17px|link=]]</span>'
end
if team2Asterick then
team2Text = '<span class="flagicon">[[File:Flag placeholder.svg|25x17px|link=]]</span> ' .. team2Text
end
end
-- Create aggregate score cell with conditional styling
local aggregateStyle = 'text-align: center;'
if isFBRStyle and legs == 0 then
if team1Winner then
aggregateStyle = aggregateStyle .. '; background-color: #BBF3FF;'
elseif team2Winner then
aggregateStyle = aggregateStyle .. '; background-color: #FFBBBB;'
elseif isDraw then
aggregateStyle = aggregateStyle .. '; background-color: #FFFFBB;'
end
elseif isDraw then
aggregateStyle = aggregateStyle .. '; background-color: #FFFFBB;'
end
-- Create rows for aggregate score and team names, bolded if set by user
row:tag('td'):cssText(team1Style):wikitext((team1Winner and (boldWinner or manualBold) and team1Text ~= '') and ('<strong>' .. team1Text .. '</strong>') or team1Text)
row:tag('td'):cssText(aggregateStyle):wikitext(aggregateScore)
row:tag('td'):cssText(team2Style):wikitext((team2Winner and (boldWinner or manualBold) and team2Text ~= '') and ('<strong>' .. team2Text .. '</strong>') or team2Text)
else
-- Process rows for club matches
team1 = args[i]
if noFlagIcons then -- Remove use of flag icons if set by user
aggregateScore = args[i+1]
team2 = args[i+2]
else
team1Icon, team1Variant = processIcon(args[i+1])
aggregateScore = args[i+2]
team2 = args[i+3]
team2Icon, team2Variant = processIcon(args[i+4])
end
-- Clean the aggregate score
local cleanAggregate = cleanScore(aggregateScore)
-- Rewrite anchor links
if baselink ~= '' then
aggregateScore = rewriteAnchorLinks(aggregateScore, baselink)
end
-- Name the 1st/2nd leg scores for two-legged ties for possibly determining the winner on away goals
if legs == 2 then
if noFlagIcons then
leg1Score = args[i+3]
leg2Score = args[i+4]
Line 504 ⟶ 751:
end
end
 
-- Clean the aggregate score
local cleanAggregate = cleanScore(aggregateScore)
aggregateScore, aggFormat = processScore(aggregateScore)
-- Format anchor links for aggregate score
local aggParen = cleanAggregate:match("%(.*%(")
local aggSpan = (disableNoWrap or (not noWrap and not disableNoWrap and aggParen))
aggregateScore, aggregateEndText = format_and_extract_score(aggregateScore, aggSpan)
-- Apply link rewriting to note text before creating the note
aggregateEndText, notes = processNote(frame, notes, 'agg', aggNote, aggregateEndText, rowIndex, rand_val, noteGroup, baselink, currentPageTitle)
if generateLinks and legs == 0 then
-- Skip link generation for "Bye" entries
local isBye = aggregateScore:match("^%s*[Bb][Yy][Ee]%s*$") or aggregateScore:match("|[Bb][Yy][Ee]%]%]")
if not isBye then
aggregateScore = cleanAndGenerateLinks(team1, team2, aggregateScore, false)
end
end
 
local skipAutoWinner = legs == 0 and aggregateScore ~= '' and checkSmallText(aggregateScore)
 
-- Determine the winning team on aggregate
team1, team2, team1Winner, team2Winner, manualBold, manualColor, isDraw, aggregateScore = determineWinner(cleanAggregate, matchType, team1, team2, boldWinner, colorWinner, aggregateScore, isFBRStyle, legs, leg1Score, leg2Score, disableAwayGoals, skipAutoWinner, aggFormat)
 
-- Add background-color for winning team if set by user
-- Function to create flag template parameters
local team1Style = team1Winner and ((colorWinner or manualColor) and 'background-color: #CCFFCC;' or '') .. 'text-align: right;' or 'text-align: right;'
local function getFlagParams(icon, variant)
local team2Style = team2Winner and ((colorWinner or manualColor) and 'background-color: #CCFFCC;' or '') .. 'text-align: left;' or 'text-align: left;'
-- Generate text, and flagslocal (ifparams not= disabled){icon, to display forvariant each= teamvariant}
if flagSize then
local team1Text = noFlagIcons and (team1 or '') or ((team1Icon ~= "" and team1Icon ~= nil) and ((team1 or '') .. ' ' .. expandTemplate(frame, flagTemplate, {team1Icon, variant = team1Variant})) or (team1 or ''))
params.size = flagSize
local team2Text = noFlagIcons and (team2 or '') or ((team2Icon ~= "" and team2Icon ~= nil) and (expandTemplate(frame, flagTemplate, {team2Icon, variant = team2Variant}) .. ' ' .. (team2 or '')) or (team2 or ''))
-- When set by user, adds blank flags when country code parameter is left blank
if fillBlanks then
if not noFlagIcons then
if not team1Icon or team1Icon == "" then
team1Text = team1Text .. ' <span class="flagicon">[[File:Flag placeholder.svg|25x17px|link=]]</span>'
end
if not team2Icon or team2Icon == "" then
team2Text = '<span class="flagicon">[[File:Flag placeholder.svg|25x17px|link=]]</span> ' .. team2Text
end
end
return params
end
 
-- Generate text to display for each team
local team1Text = noFlagIcons and (team1 or '') or ((team1Icon ~= "" and team1Icon ~= nil) and ((team1 or '') .. '&nbsp;' .. expandTemplate(frame, flagTemplate, getFlagParams(team1Icon, team1Variant))) or (team1 or ''))
local team2Text = noFlagIcons and (team2 or '') or ((team2Icon ~= "" and team2Icon ~= nil) and (expandTemplate(frame, flagTemplate, getFlagParams(team2Icon, team2Variant)) .. '&nbsp;' .. (team2 or '')) or (team2 or ''))
 
-- When set by user, adds blank flag placeholder next to team names
if fillBlanks and showFlags then
local flagDimensions = flagSize or "25x17px"
local placeholderFlag = string.format('<span class="flagicon">[[File:Flag placeholder.svg|%s|link=]]</span>', flagDimensions)
if not team1Icon or team1Icon == "" then
team1Text = team1Text .. '&nbsp;' .. placeholderFlag
end
if not team2Icon or team2Icon == "" then
team2Text = placeholderFlag .. '&nbsp;' .. team2Text
end
end
 
local aggregateContent
if not disableSmallText and skipAutoWinner then
aggregateContent = '<span class="sports-series-small">' .. aggregateScore .. '</span>' .. aggregateEndText
else
aggregateContent = aggregateScore .. aggregateEndText
end
 
-- Create aggregate score cell with conditional styling
local aggregateStyleaggregateClass = 'text-align: center;'
if isFBRStyle and legs == 0 then
if team1Winner then
aggregateStyleaggregateClass = aggregateStyle .. '; backgroundfbr-color: #BBF3FF;home-win'
elseif team2Winner then
aggregateStyleaggregateClass = aggregateStyle .. '; backgroundfbr-color: #FFBBBB;away-win'
elseif isDraw then
aggregateStyleaggregateClass = aggregateStyle .. '; background-color: #FFFFBB;draw'
end
elseif isDraw then
aggregateStyleaggregateClass = aggregateStyle .. '; background-color: #FFFFBB;draw'
end
if not disableNoWrap and (not noWrap and aggParen) then
aggregateClass = (aggregateClass ~= '' and aggregateClass .. ' ' or '') .. 'allow-wrap'
end
 
-- Create rows for aggregate score and team names, bolded if set by user
row:tag('td'):cssTextaddClass(team1Styleteam1Winner and (colorWinner or manualColor) and 'winner' or nil):wikitext((team1Winner and (boldWinner or manualBold) and team1Text ~= '') and ('<strong>' .. team1Text .. '</strong>') or team1Text)
row:tag('td'):cssTextaddClass(aggregateStyleaggregateClass ~= '' and aggregateClass or nil):wikitext(aggregateScoreaggregateContent)
row:tag('td'):cssTextaddClass(team2Styleteam2Winner and (colorWinner or manualColor) and 'winner' or nil):wikitext((team2Winner and (boldWinner or manualBold) and team2Text ~= '') and ('<strong>' .. team2Text .. '</strong>') or team2Text)
 
end
-- Add columns for each leg score if applicable
if legs > 0 then
for leg = 1, legs do
local legIndex = i + 4 + leg + (noFlagIcons and -2 or 0)
local legScore = args[legIndex]
local legNote = args['note_leg' .. leg .. '_' .. rowIndex]
if legScore ~= "nil" then
if legScore == "null" then
if solidCell then
row:tag('td'):addClass('solid-cell')
else
legScore = '—'
end
end
 
-- Add columns for each leg score if applicablelegScore ~= "null" then
-- Format anchor links for leg scores
if legs > 0 then
for leg = 1, legs do local cleanLeg = cleanScore(legScore)
local legIndex = i + 4 + leg + (matchType == 'NT' and -2 or (noFlagIcons and -2 orlocal 0))legFormat
local legScore, legFormat = args[legIndex]processScore(legScore)
if legScore ~ local legParen = cleanLeg:match("null%(.*%(" then)
if baselink ~ local legSpan = ''(disableNoWrap or (not noWrap and not disableNoWrap and thenlegParen))
legScore, legEndText = rewriteAnchorLinksformat_and_extract_score(legScore, baselinklegSpan)
-- Apply link rewriting to note text before creating the note
legEndText, notes = processNote(frame, notes, 'leg' .. leg, legNote, legEndText, rowIndex, rand_val, noteGroup, baselink, currentPageTitle)
if generateLinks and not aggregateContent:lower():find("bye") then
if leg == 1 then
legScore = cleanAndGenerateLinks(team1, team2, legScore, false)
elseif leg == 2 then
legScore = cleanAndGenerateLinks(team1, team2, legScore, true)
end
end
if legFormat == 'bold' or legFormat == 'both' then legScore = '<b>' .. legScore .. '</b>' end
if legFormat == 'italic' or legFormat == 'both' then legScore = '<i>' .. legScore .. '</i>' end
local legContent
if not disableSmallText and legScore ~= '' and checkSmallText(legScore) then
legContent = '<span class="sports-series-small">' .. legScore .. '</span>' .. legEndText
else
legContent = legScore .. legEndText
end
local legClass = ''
if not disableNoWrap and (not noWrap and legParen) then
legClass = 'allow-wrap'
end
-- Write cells for legs
row:tag('td'):addClass(legClass ~= '' and legClass or nil):wikitext(legContent)
end
end
row:tag('td'):css('text-align', 'center'):wikitext(legScore)
end
end
Line 559 ⟶ 883:
end
 
-- Generate footer text
return tostring(root)
local footerText = createFooter(frame, notes, noteGroup, isFBRStyle, displayNotes, externalNotes, legs)
root:wikitext(footerText)
 
local tableCode = tostring(root)
 
-- Rewrite anchor links for the entire table (except for notes which were handled separately)
tableCode = rewriteAnchorLinks(tableCode, baselink, currentPageTitle)
 
-- Return the completed table with rewritten links
return tableCode
end