Module:Sports series: Difference between revisions

Content deleted Content added
add class
improve logic, use Module:Yesno
Line 78:
 
-- Function to determine the winner based on scores within parentheses (first) or regular format (second)
local function determineWinner(cleanAggregate, 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 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
 
Line 262 ⟶ 293:
 
-- 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, noWrap, disableNoWrapaddSpan)
if not s then return '', '' end -- Return empty strings if input is nil
 
Line 277 ⟶ 308:
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%.]+)')
 
-- Format winning notes in brackets
local has_multiple_parentheses = s:match("%(.*%(")
local add_span = (disableNoWrap or (not noWrap and not disableNoWrap and has_multiple_parentheses))
 
if add_span then
s = mw.ustring.gsub(s, '(%(%d+%s*–%s*%d+)%s+[Pp]%.?[EeSs]?%.?[NnOo]?%.?%)', '<span class="nowrap">%1 [[Penalty shoot-out (association football)|p]])</span>')
s = mw.ustring.gsub(s, '%([Aa]%.?[Ee]%.?[Tt]%.?%)', '<span class="nowrap">([[Overtime (sports)#Association football|a.e.t.]])</span>')
else
s = mw.ustring.gsub(s, '(%(%d+%s*–%s*%d+)%s+[Pp]%.?[EeSs]?%.?[NnOo]?%.?%)', '%1 [[Penalty shoot-out (association football)|p]])')
s = mw.ustring.gsub(s, '%([Aa]%.?[Ee]%.?[Tt]%.?%)', '([[Overtime (sports)#Association football|a.e.t.]])')
end
s = mw.ustring.gsub(s, '%([Aa]%.?[Gg]?%.?[Rr]?%.?%)', '([[Away goals rule|a]])')
 
-- Extract end text
-- Pattern to match superscript
local supStart = s:find('<sup')
-- Pattern to match the unique placeholder
local placeholderStart = s:find('\127%\'"`UNIQ')
 
Line 303 ⟶ 319:
pos = s:find('%(', pos)
if not pos then break end
 
-- Check if there are unclosed [[ before this position
local beforeParen = s:sub(1, pos - 1)
local openLinks = 0select(2, beforeParen:gsub('%[%[', '')) - select(2, beforeParen:gsub('%]%]', ''))
for linkStart in beforeParen:gmatch('%[%[') do
openLinks = openLinks + 1
end
for linkEnd in beforeParen:gmatch('%]%]') do
openLinks = openLinks - 1
end
 
-- If there are no unclosed links, this is a valid parenthesis
if openLinks == 0 then
return pos
end
 
pos = pos + 1
end
Line 324 ⟶ 332:
end
 
-- Find the first parenthesis outside of wikilinks
local parenStart = find_paren_outside_wikilinks(s)
 
-- Store all start positions in a table
local startPositions = {}
if supStart then table.insert(startPositions, supStart) end
Line 333 ⟶ 339:
if parenStart then table.insert(startPositions, parenStart) end
 
local startPosscoreMatch, endText
if #startPositions > 0 then
local startPos = math.min(unpack(startPositions))
-- Find the minimum start position
-- Find the last non-whitespace character before startPos
end
local scoreEnd = s:sub(1, startPos - 1):match(".*%S") or ""
 
scoreEnd = #scoreEnd
if startPos then
-- Find the preceding whitespace
local wsStart = s:find("%s*$", 1, startPos)
 
-- Extract the score and endText
local scoreMatch = s:sub(1, wsStart and wsStart - 1 or startPos - 1scoreEnd)
local endText = s:sub(wsStartscoreEnd or+ startPos1)
 
return scoreMatch, endText
else
-- If no match found, return the entire score
returnscoreMatch s,= ""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
 
Line 491 ⟶ 509:
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {trim = true})
local yesno = require('Module:Yesno')
 
-- Check for section transclusion
Line 499 ⟶ 518:
return '' -- Return an empty string if sections don't match
end
end
 
-- Helper function for boolean checks
local function isTrue(value)
if not value then return false end
local lowerValue = value:lower()
return lowerValue == 'y' or lowerValue == 'yes' or lowerValue == '1' or lowerValue == 'true'
end
 
-- Helper function for negative boolean checks
local function isFalse(value)
if not value then return false end
local lowerValue = value:lower()
return lowerValue == 'n' or lowerValue == 'no' or lowerValue == '0' or lowerValue == 'false' or lowerValue == 'null' or lowerValue == 'none'
end
 
Line 522 ⟶ 527:
root:wikitext(templatestyles)
 
local noFlagIconsflagYesno = falseyesno(args.flag)
local fillBlanksshowFlags = isTrue(args.fill_blanks)flagYesno ~= false
local generateLinksnoFlagIcons = isTrue(args.generate_links)not showFlags
local fillBlanks = yesno(args.fill_blanks)
local solidCell = isTrue(args.solid_cell) or args.solid_cell == 'grey' or args.solid_cell == 'gray'
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()
local currentPageTitle = mw.title.getCurrentTitle().fullText
Line 531 ⟶ 538:
local notes = {}
local noteGroup = args.note_group or 'lower-alpha'
local displayNotesnoteListValue = isTrueyesno(args.note_list)
local externalNotesdisplayNotes = isFalse(args.note_list)noteListValue == true
local externalNotes = noteListValue == false
math.randomseed(os.clock() * 10^8) -- Initialize random number generator
local rand_val = math.random()
Line 547 ⟶ 555:
 
-- Process flag parameter to determine flag template and variant
local flagTemplate = args.flag or 'fbaicon' -- Default to {{fbaicon}}
local noFlagIcons = isFalse(args.flag)
local flagSize = args.flag_size
if flagSize and not flagSize:match('px$')showFlags then
if args.flag and args.flag ~= '' and not flagYesno then
flagSize = flagSize .. 'px'
flagTemplate = args.flag:gsub('^Template:', '')
end
if not templateExists(flagTemplate) then
flagTemplate = 'flag icon'
end
end
 
if flagSize and not flagSize:match('px$') then
-- Check if flagTemplate exists and adjust if necessary
flagSize = flagSize .. 'px'
if not noFlagIcons and flagTemplate ~= 'fbaicon' then
if not templateExists(flagTemplate) then
flagTemplate = 'flagicon'
end
end
Line 570 ⟶ 579:
end
 
local legs = 2
local legs = (isFalse(args.legs) or args.legs == '1') 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 = notargs.bold_winner isFalse== nil or yesno(args.bold_winner, true)
local colorWinner = isTrueyesno(args.color_winner)
local matchesStyle = args.matches_style
local isFBRStyle = matchesStyle and matchesStyle:upper() == "FBR"
local isHA = isTrueyesno(args.h_a) or (isFBRStyle and legs == 0)
local disableAwayGoals = isFalseyesno(args.away_goals) == false
local disableSmallText = isFalseyesno(args.small_text) == false
local noWrapnoWrapValue = isTrueyesno(args.nowrap)
local disableNoWrapnoWrap = isFalse(args.nowrap)noWrapValue == true
local disableNoWrap = noWrapValue == false
local aggFormat
 
local tableClass = 'wikitable sports-series'
iflocal isTruedoCollapsed = yesno(args.collapsed) then
if doCollapsed then
tableClass = tableClass .. ' mw-collapsible mw-collapsed'
end
if isTrueyesno(args.center_table) and not doCollapsed then
tableClass = tableClass .. ' center-table'
end
Line 643 ⟶ 659:
if not legHeading then
if args.leg_prefix then
legHeading = isTrueyesno(args.leg_prefix) and ('Leg ' .. leg) or (args.leg_prefix .. ' ' .. leg)
elseif args.leg_suffix and not isTrueyesno(args.leg_suffix) then
legHeading = ordinal(leg) .. ' ' .. args.leg_suffix
else
Line 703 ⟶ 719:
-- Clean the aggregate score
local cleanAggregate = cleanScore(aggregateScore)
aggregateScore, aggFormat = processScore(aggregateScore)
-- Format anchor links for aggregate score
local aggParen = cleanAggregate:match("%(.*%(")
aggregateScore, aggregateEndText = format_and_extract_score(aggregateScore, noWrap, disableNoWrap)
local aggSpan = (disableNoWrap or (not noWrap and not disableNoWrap and aggParen))
aggregateScore, aggregateEndText = format_and_extract_score(aggregateScore, aggSpan)
aggregateEndText, notes = processNote(frame, notes, 'agg', aggNote, aggregateEndText, rowIndex, rand_val, noteGroup)
if generateLinks and legs == 0 then
Line 713 ⟶ 732:
 
-- Determine the winning team on aggregate
team1, team2, team1Winner, team2Winner, manualBold, manualColor, isDraw, aggregateScore = determineWinner(cleanAggregate, team1, team2, boldWinner, colorWinner, aggregateScore, isFBRStyle, legs, leg1Score, leg2Score, disableAwayGoals, skipAutoWinner, aggFormat)
 
-- Function to create flag template parameters
Line 729 ⟶ 748:
 
-- When set by user, adds blank flag placeholder next to team names
if fillBlanks and not noFlagIconsshowFlags 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;<span' class="flagicon">[[File:Flag placeholder.svg|25x17px|link=]]</span>'. placeholderFlag
end
if not team2Icon or team2Icon == "" then
team2Text = '<spanplaceholderFlag class="flagicon">[[File:Flag placeholder.svg|25x17px|link=]]</span>. '&nbsp;' .. team2Text
end
end
Line 758 ⟶ 779:
aggregateClass = 'draw'
end
if not disableNoWrap and (not noWrap and (cleanAggregate:match("%(.*%("))aggParen) then
aggregateClass = (aggregateClass ~= '' and aggregateClass .. ' ' or '') .. 'allow-wrap'
end
 
Line 785 ⟶ 806:
-- Format anchor links for leg scores
local cleanLeg = cleanScore(legScore)
legScore,local legEndText = format_and_extract_score(legScore, noWrap, disableNoWrap)legFormat
legScore, legFormat = processScore(legScore)
local legParen = cleanLeg:match("%(.*%(")
local legSpan = (disableNoWrap or (not noWrap and not disableNoWrap and legParen))
legScore, legEndText = format_and_extract_score(legScore, legSpan)
legEndText, notes = processNote(frame, notes, 'leg' .. leg, legNote, legEndText, rowIndex, rand_val, noteGroup)
if generateLinks and not aggregateContent:lower():find("bye") then
Line 794 ⟶ 819:
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
Line 801 ⟶ 828:
end
local legClass = ''
if not disableNoWrap and (not noWrap and (cleanLeg:match("%(.*%("))legParen) then
legClass = 'allow-wrap'
end