Modul:Sports series: Perbedaan antara revisi
Konten dihapus Konten ditambahkan
opsi pewarnaan agregat untuk leg=0 |
penambahan fitur catatan pada agregat dan skor |
||
(8 revisi perantara oleh pengguna yang sama tidak ditampilkan) | |||
Baris 8:
return frame:expandTemplate{ title = templateName, args = params }
end
-- Function to check the existence of flagTemplate
local function templateExists(templateName)
local title = mw.title.new('Templat:' .. templateName)
Baris 14:
end
-- Function to process country codes and variants
local function processIcon(iconString)
if not iconString or iconString:match("^%s*$") then
Baris 39:
end
-- Function to
local function replaceLink(match)
local pipePos = match:find("|")
Baris 56 ⟶ 49:
end
-- Function to clean and process the aggregate score for comparison
local function cleanScore(score)
-- Return an empty string if score is nil or empty to avoid errors
if not score or score:match("^%s*$") then
return ''
end
-- Replace wiki links
score = score:gsub("%[%[.-%]%]", replaceLink)
-- Remove MediaWiki's unique placeholder sequences for references
score = score:gsub('\127%\'"`UNIQ.-QINU`"
-- Remove superscript tags and their contents
Baris 66:
-- Convert dashes to a standard format
score = score:gsub('[–—―‒−]+', '-')
-- Strip all characters except numbers, dashes and parentheses
Baris 73:
-- Function to determine the winner based on scores within parentheses (first) or regular format (second)
local function determineWinner(
local team1Winner, team2Winner = false, false
local score1, score2
Baris 99:
end
-- Handling for manual coloring of team or aggregate cells
if team1 and type(team1) == 'string' then
manualColor1 = team1:find("''") and not (team1:gsub("''", ""):match("^%s*$"))
Baris 110:
if aggregate then
if aggregate:find("'''") then
aggregate = aggregate:gsub("'''", "")
aggregate = "<strong>" .. aggregate .. "</strong>"
end
manualColorDraw = aggregate:find("''") and not (aggregate:gsub("''", ""):match("^%s*$"))
aggregate = aggregate:gsub("''", "")
Baris 132 ⟶ 136:
-- Regular winner determination logic if manual bolding or coloring is not conclusive
if not team1Winner and not team2Winner and not isDraw and (boldWinner or colorWinner) then
local parenthetical =
local outsideParenthetical =
if parenthetical then -- Prioritize checking score inside parenthetical
score1, score2 = parenthetical:match('(%d+)%-+(%d+)')
elseif outsideParenthetical then
Baris 141 ⟶ 145:
if score1 and score2 then
team1Winner = true
team2Winner = true
elseif score1 == score2 and legs == 2 and not disableAwayGoals then
-- Apply away goals rule
local cleanLeg1 = cleanScore(leg1Score):gsub('[()]', '')
local cleanLeg2 = cleanScore(leg2Score):gsub('[()]', '')
local _, team2AwayGoals = cleanLeg1:match('(%d+)%-+(%d+)')
local team1AwayGoals = cleanLeg2:match('(%d+)%-+(%d+)')
if team1AwayGoals and team2AwayGoals then
team1AwayGoals, team2AwayGoals = tonumber(team1AwayGoals), tonumber(team2AwayGoals)
if team1AwayGoals > team2AwayGoals then
team1Winner = true
elseif team2AwayGoals > team1AwayGoals then
team2Winner = true
end
end
end
if (colorWinner or isFBRStyle) and legs == 0 then
isDraw = not team1Winner and not team2Winner
end
end
end
Baris 154 ⟶ 181:
-- 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
Baris 159 ⟶ 187:
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 check whether to reduce font size for upcoming matches
local function checkSmallText(str)
-- Check for font size or small/big HTML tags
if str:match("font%s?%-?size") or str:match("<small>") or str:match("<big>") then
return false
end
-- 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") 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 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 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, doWrap)
if not s then return '', '' end -- Return empty strings if input is nil
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%.]+)')
-- Format winning notes in brackets
if doWrap and not (s:match("%(.*%(")) then
s = mw.ustring.gsub(s, '(%(%d+%s*–%s*%d+)%s+[Pp]%.?[EeSs]?%.?[NnOo]?%.?%)', '%1 [[Adu penalti|a.p]])')
s = mw.ustring.gsub(s, '%([Aa]%.?[Ee]%.?[Tt]%.?%)', '([[Perpanjangan waktu (sepak bola)|p.w.]])')
else
s = mw.ustring.gsub(s, '(%(%d+%s*–%s*%d+)%s+[Pp]%.?[EeSs]?%.?[NnOo]?%.?%)', '<span class="nowrap">%1 [[Adu penalti|a.p]])</span>')
s = mw.ustring.gsub(s, '%([Aa]%.?[Ee]%.?[Tt]%.?%)', '<span class="nowrap">([[Perpanjangan waktu (sepak bola)|p.w.]])</span>')
end
s = mw.ustring.gsub(s, '%([Aa]%.?[Gg]?%.?[Rr]?%.?%)', '([[Peraturan gol tandang|p.g.t]])')
-- Extract end text
-- Pattern to match superscript
local supStart = s:find('<sup')
-- Pattern to match the unique placeholder
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
-- Check if there are unclosed [[ before this position
local beforeParen = s:sub(1, pos - 1)
local openLinks = 0
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
return nil
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
if placeholderStart then table.insert(startPositions, placeholderStart) end
if parenStart then table.insert(startPositions, parenStart) end
local startPos
if #startPositions > 0 then
startPos = math.min(unpack(startPositions)) -- Find the minimum start position
end
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 - 1)
local endText = s:sub(wsStart or startPos)
return scoreMatch, endText
else
-- If no match found, return the entire score
return s, ""
end
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("%[%[[Bb]erkas:[^%]]+%]%]", "")
str = str:gsub("%[%[[Ii]mage:[^%]]+%]%]", "")
str = str:gsub("%[%[.-%]%]", replaceLink)
str = str:gsub("%s* %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)
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
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')
:css('font-size', '90%')
:css('margin-bottom', '0.5em')
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')
:css('display', 'none')
: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('Modul:Arguments').getArgs(frame, {trim = true})
-- Check for section transclusion
Baris 182 ⟶ 492:
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
local root = mw.html.create()
local noFlagIcons = false
local fillBlanks =
local generateLinks = isTrue(args.generate_links)
local solidCell = isTrue(args.solid_cell) or args.solid_cell == 'grey' or args.solid_cell == 'gray' or args.solid_cell == 'abu-abu'
local baselink = frame:getParent():getTitle()
if mw.title.getCurrentTitle().text == baselink then baselink = '' end
local notes = {}
local noteGroup = args.note_group or 'lower-alpha'
local displayNotes = isTrue(args.note_list)
local externalNotes = isFalse(args.note_list)
math.randomseed(os.clock() * 10^8) -- Initialize random number generator
local rand_val = math.random()
-- Process the font size parameter
local
if args.
-- Remove trailing '%' if present and convert to number
if
end
end
-- Process flag parameter to determine flag template and variant
local noFlagIcons = isFalse(args.flag)
local flagSize = args.flag_size
if flagSize and not
flagSize = flagSize ..
end
-- Check if flagTemplate exists and adjust if necessary
if not noFlagIcons and flagTemplate ~= 'fbaicon' then
if
flagTemplate = 'flagicon'
end
end
-- Determine whether line should be displayed
local showCountry = args.show_country
local function shouldShowRow(team1Icon, team2Icon)
if not showCountry or noFlagIcons then
return true
end
return team1Icon == showCountry or team2Icon == showCountry
end
local legs = (isFalse(args.legs
if legs and legs < 0 then
legs = 2
Baris 239 ⟶ 560:
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 = isTrue(args.h_a
local disableAwayGoals = isFalse(args.away_goals)
local disableSmallText = isFalse(args.small_text)
local noWrap = isTrue(args.nowrap)
local disableNoWrap = isFalse(args.nowrap)
local doWrap = not noWrap and not disableNoWrap
local tableClass = 'wikitable'
local tableStyle = 'text-align: center;'
if
tableClass = 'wikitable mw-collapsible mw-collapsed'
tableStyle = tableStyle .. ' width: 100%
end
if isTrue(args.center_table) then
tableStyle = tableStyle .. ' margin-left: auto; margin-right: auto; border: none;'
end
if noWrap then
tableStyle = tableStyle .. ' white-space: nowrap;'
end
if
tableStyle = tableStyle .. ' font-size: ' ..
end
Baris 264 ⟶ 593:
if args.id then
table:attr('id', args.id) -- Optional id parameter to allow anchor to table
end
Baris 286 ⟶ 609:
:attr('colspan', colCount)
:attr('scope', 'colgroup')
:wikitext(args.title)
end
Baris 292 ⟶ 614:
-- Create the header row with team and score columns
local header = table:tag('tr')
if doWrap then
header:css('white-space', 'nowrap')
end
local defaultTeam1 = isHA and 'Tim kandang' or 'Tim 1'
local defaultTeam2 = isHA and 'Tim tandang' or 'Tim 2'
Baris 312 ⟶ 637:
if legs > 0 then
for leg = 1, legs do
local legHeading = args['leg' .. leg]
-- Check if "legN" parameter is present
if
if args.leg_prefix then
legHeading = args.leg_suffix .. ' ' .. ordinal(leg)
else
Baris 341 ⟶ 657:
end
local step =
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]
local team1, team2, aggregateScore, aggregateEndText, legEndText, team1Icon, team2Icon, team1Variant, team2Variant
local team1Winner, team2Winner, manualBold, manualColor, isDraw = false, false, false, false, false
local
-- Process rows
if noFlagIcons then
aggregateScore = args[i+1]
team2 = args[i+2]
else
team1Icon,
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')
headingRow:tag('td')
:attr('colspan', colCount)
:css('background', 'whitesmoke')
:wikitext('<strong>' .. headingParam .. '</strong>')
end
local row = table:tag('tr')
-- Name the 1st/2nd leg scores for two-legged ties
if legs == 2 then
if noFlagIcons then
leg1Score = args[i+3]
leg2Score = args[i+4]
else
leg1Score = args[i+5]
leg2Score = args[i+6]
end
end
-- Clean the aggregate score
local cleanAggregate = cleanScore(aggregateScore)
-- Format and rewrite anchor links for aggregate score
aggregateScore, aggregateEndText = format_and_extract_score(aggregateScore, doWrap)
aggregateEndText, notes = processNote(frame, notes, 'agg', aggNote, aggregateEndText, rowIndex, rand_val, noteGroup)
if generateLinks and legs == 0 then
aggregateScore = cleanAndGenerateLinks(team1, team2, aggregateScore, false)
end
-- Determine the winning team on aggregate
if not skipDetermineWinner then
team1, team2, team1Winner, team2Winner, manualBold, manualColor, isDraw, aggregateScore = determineWinner(cleanAggregate, team1, team2, boldWinner, colorWinner, aggregateScore, isFBRStyle, legs, leg1Score, leg2Score, disableAwayGoals)
end
-- Add background-color for winning team if set by user
local team1Style =
local team2Style =
team1Style = team1Style .. ' background-color: #CCFFCC;'
end
if team2Winner and (colorWinner or manualColor) then
team2Style = team2Style .. ' background-color: #CCFFCC;'
-- Function to create flag template parameters
local function getFlagParams(icon, variant)
local params = {icon, variant = variant}
if flagSize then
params.size = flagSize
end
end
-- Generate text to display for each team
local team1Text = noFlagIcons and (team1 or '') or ((team1Icon ~= "" and team1Icon ~= nil) and ((team1 or '') .. ' ' .. 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)) .. ' ' .. (team2 or '')) or (team2 or ''))
-- When set by user, adds blank flag placeholder next to team names
if fillBlanks and 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
aggregateContent = '<span style="font-size:85%;">' .. aggregateScore .. '</span>' .. aggregateEndText
else
end
-- Create aggregate score cell with conditional styling
local aggregateStyle = '
if
end
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 ~= '' and aggregateStyle or nil):wikitext(
row:tag('td'):cssText(team2Style):wikitext((team2Winner and (boldWinner or manualBold) and team2Text ~= '') and ('<strong>' .. team2Text .. '</strong>') or team2Text)
-- Add columns for each leg score if applicable
if legs > 0 then
for leg = 1, legs do
local legIndex = i + 4 + leg +
local legScore = args[legIndex]
if legScore == "null" then
if solidCell then
row:tag('td'):css('background', '#BBBBBB')
else
legScore = '—'
end
end
if legScore ~= "null" then
-- Format and rewrite anchor links for leg scores
local cleanLeg = cleanScore(legScore)
legScore, legEndText = format_and_extract_score(legScore, doWrap)
legEndText, notes = processNote(frame, notes, 'leg' .. leg, legNote, legEndText, rowIndex, rand_val, noteGroup)
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
local legContent
if not disableSmallText and legScore ~= '' and checkSmallText(legScore) then
legContent = '<span style="font-size:85%;">' .. legScore .. '</span>' .. legEndText
else
legContent = legScore .. legEndText
end
local legStyle = ''
if doWrap and not (cleanLeg:match("%(.*%(")) then
legStyle = 'white-space: nowrap;'
end
-- Write cells for legs
row:tag('td'):cssText(legStyle ~= '' and legStyle or nil):wikitext(legContent)
end
end
end
end
Baris 490 ⟶ 827:
i = i + step
end
-- Generate footer text
local footerText = createFooter(frame, notes, noteGroup, isFBRStyle, displayNotes, externalNotes, legs)
root:wikitext(footerText)
local tableCode = tostring(root)
-- Rewrite anchor links for the entire table
if baselink ~= '' then
tableCode = mw.ustring.gsub(tableCode, '(%[%[)(#[^%[%]]*%|)', '%1' .. baselink .. '%2')
end
return
end
|