Content deleted Content added
S.A. Julio (talk | contribs) improve logic |
S.A. Julio (talk | contribs) improve link rewriting |
||
(10 intermediate revisions by 3 users not shown) | |||
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 =
end
manualColorDraw =
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 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 226 ⟶ 257:
-- 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
Line 246 ⟶ 277:
-- Remove opening and closing HTML tags
str = str:gsub("</?%w+[^>]*>", "")
-- Remove apostrophes
str = str:gsub("''+", "")
-- Remove all whitespace
Line 256 ⟶ 290:
return true
end
end
-- Function to rewrite anchor links in a string
local function rewriteAnchorLinks(str, baselink, currentPageTitle)
if not str or str == "" then
return str
end
-- 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,
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)
Line 274 ⟶ 334:
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')
Line 297 ⟶ 345:
pos = s:find('%(', pos)
if not pos then break end
local beforeParen = s:sub(1, pos - 1)
local openLinks =
if openLinks == 0 then
return pos
end
pos = pos + 1
end
Line 318 ⟶ 358:
end
local parenStart = find_paren_outside_wikilinks(s)
local startPositions = {}
if supStart then table.insert(startPositions, supStart) end
Line 327 ⟶ 365:
if parenStart then table.insert(startPositions, parenStart) end
local
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
else
-- If no match found, return the entire score
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 351 ⟶ 401:
local function cleanTeam(str, defaultName)
if str and str ~= "" then
str = str:gsub("</?%w+[^>]*>", "")
str = str:gsub('\127%\'"`UNIQ.-QINU`"%\'\127', '')
Line 383 ⟶ 433:
link = "[[#" .. team1 .. " v " .. team2 .. "|" .. linkScore .. "]]"
end
return link .. score:sub(#linkScore + 1)
end
Line 391 ⟶ 442:
-- 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
Line 412 ⟶ 463:
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
Line 431 ⟶ 487:
local divContent = mw.html.create('div')
:
if isFBRStyle and legs == 0 then
Line 461 ⟶ 516:
if externalNotes then
local hiddenRefs = mw.html.create('span')
:
:wikitext(table.concat(noteDefinitions))
if isFBRStyle and legs == 0 then
Line 486 ⟶ 541:
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {trim = true})
local yesno = require('Module:Yesno')
-- Check for section transclusion
Line 494 ⟶ 550:
return '' -- Return an empty string if sections don't match
end
end
local root = mw.html.create()
local
name = 'templatestyles',
args = { src = 'Screen reader-only/styles.css' }
} .. frame:extensionTag{
name = 'templatestyles',
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()
if currentPageTitle == baselink then baselink = '' end
local notes = {}
local noteGroup = args.note_group or 'lower-alpha'
local
local
local externalNotes = noteListValue == false
math.randomseed(os.clock() * 10^8) -- Initialize random number generator
local rand_val = math.random()
Line 535 ⟶ 590:
-- Process flag parameter to determine flag template and variant
local flagTemplate =
local flagSize = args.flag_size
if
if args.flag and args.flag ~= '' and not flagYesno then
flagTemplate = args.flag:gsub('^Template:', '')
if not templateExists(flagTemplate) then
flagTemplate = 'flag icon'
end
end
if flagSize and not flagSize:match('px$') then
flagSize = flagSize .. 'px'
end
end
Line 558 ⟶ 614:
end
local legs = 2
if args.legs
if yesno(args.legs) == false or args.legs == '1'
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 =
local colorWinner =
local matchesStyle = args.matches_style
local isFBRStyle = matchesStyle and matchesStyle:upper() == "FBR"
local isHA =
local disableAwayGoals =
local disableSmallText =
local
local
local
local aggFormat
local tableClass = 'wikitable sports-series'
local
if
tableClass = tableClass .. '
end
if
end
if fontSize then
end
Line 597 ⟶ 654:
if args.id then
table:attr('id', args.id) -- Optional id parameter to allow anchor to table
end
if noWrap then
table:attr('data-nowrap', 'y')
elseif not disableNoWrap then
table:attr('data-nowrap', 'n')
end
Line 609 ⟶ 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)
Line 618 ⟶ 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'):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>')
header:tag('th'):attr('scope', 'col'):css('width', teamWidth):wikitext(args['team2'] or defaultTeam2)
-- Add columns for each leg if applicable
Line 646 ⟶ 694:
if not legHeading then
if args.leg_prefix then
legHeading =
elseif args.leg_suffix and not
legHeading = ordinal(leg) .. ' ' .. args.leg_suffix
else
Line 654 ⟶ 702:
end
header:tag('th'):attr('scope', 'col'):css('width', scoreWidth):wikitext(legHeading)
end
end
Line 688 ⟶ 733:
-- 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
Line 710 ⟶ 754:
-- 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, team1, team2, boldWinner, colorWinner, aggregateScore, isFBRStyle, legs, leg1Score, leg2Score, disableAwayGoals, skipAutoWinner, aggFormat)
-- Function to create flag template parameters
Line 748 ⟶ 788:
-- When set by user, adds blank flag placeholder next to team names
if fillBlanks and
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 .. '
end
if not team2Icon or team2Icon == "" then
team2Text =
end
end
local aggregateContent
if not disableSmallText and
aggregateContent = '<span
else
aggregateContent = aggregateScore .. aggregateEndText
Line 765 ⟶ 807:
-- Create aggregate score cell with conditional styling
local
if isFBRStyle and legs == 0 then
if team1Winner then
elseif team2Winner then
elseif isDraw then
end
elseif isDraw then
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'):
row:tag('td'):
row:tag('td'):
-- Add columns for each leg score if applicable
Line 795 ⟶ 837:
if legScore == "null" then
if solidCell then
row:tag('td'):
else
legScore = '—'
Line 802 ⟶ 844:
if legScore ~= "null" then
-- Format
local cleanLeg = cleanScore(legScore)
local legParen = cleanLeg:match("%(.*%(")
local legSpan = (disableNoWrap or (not noWrap and not disableNoWrap and legParen))
legScore, legEndText = format_and_extract_score(legScore, legSpan)
-- 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
Line 813 ⟶ 860:
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
else
legContent = legScore .. legEndText
end
local
if
end
-- Write cells for legs
row:tag('td'):
end
end
Line 840 ⟶ 889:
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
|