« Module:Tournoi » : différence entre les versions
Aller à la navigation
Aller à la recherche
Aucun résumé des modifications |
Aucun résumé des modifications |
||
Ligne 10 : | Ligne 10 : | ||
local showSeeds | local showSeeds | ||
local tracking = '' | local tracking = '' | ||
local WIDTH_NAME = 'largeur' | |||
local ROUND_NAME = 'manche' | |||
local ROUNDS_NAME = 'manches' | |||
local COMPACT_NAME = 'compact' | |||
local AUTOSEEDS_NAME = 'autograines' | |||
local SEEDS_NAME = 'graines' | |||
local SEED_NAME = 'graine' | |||
local TEAM_NAME = 'équipe' | |||
local SCORE_NAME = 'score' | |||
local YES_VALUE = 'oui' | |||
local Y_VALUE = 'o' | |||
local NO_VALUE = 'non' | |||
local N_VALUE = 'n' | |||
local FINALS_LABEL = 'Finale' | |||
local SEMIFINALS_LABEL = 'Demi-finales' | |||
local QUARTERFINALS_LABEL = 'Quarts de finale' | |||
local ROUNDOF_LABEL = '%d<sup>ème</sup> de finale' | |||
function getSeeds() | function getSeeds() | ||
Ligne 77 : | Ligne 95 : | ||
function getWidth(param, default) | function getWidth(param, default) | ||
local arg = args[param .. '- | local arg = args[param .. '-' .. WIDTH_NAME] | ||
if not arg or string.len(arg) == 0 then | if not arg or string.len(arg) == 0 then | ||
arg = default | arg = default | ||
Ligne 92 : | Ligne 110 : | ||
function getTeamArgName(round, type, team) | function getTeamArgName(round, type, team) | ||
return string.format(' | return string.format(ROUND_NAME .. '%d-%s' .. padding, round, type, team) | ||
end | end | ||
function getRoundName(round) | function getRoundName(round) | ||
local name = args[ | local name = args[ROUND_NAME .. round] | ||
if name and string.len(name) > 0 then | if name and string.len(name) > 0 then | ||
return name | return name | ||
Ligne 102 : | Ligne 120 : | ||
local roundFromLast = rounds - round + 1 | local roundFromLast = rounds - round + 1 | ||
if roundFromLast == 1 then | if roundFromLast == 1 then | ||
return | return FINALS_LABEL | ||
elseif roundFromLast == 2 then | elseif roundFromLast == 2 then | ||
return | return SEMIFINALS_LABEL | ||
elseif roundFromLast == 3 then | elseif roundFromLast == 3 then | ||
return | return QUARTERFINALS_LABEL | ||
else | else | ||
return | return string.format(ROUNDOF_LABEL, math.pow(2, roundFromLast)) | ||
end | end | ||
end | end | ||
Ligne 114 : | Ligne 132 : | ||
function renderTeam(row, round, team, top, compact) | function renderTeam(row, round, team, top, compact) | ||
local seedCell | local seedCell | ||
local seedArg = getTeamArg(round, | local seedArg = getTeamArg(round, SEED_NAME, team) | ||
-- seed value for the paired team | -- seed value for the paired team | ||
local pairSeedArg = getTeamArg(round, | local pairSeedArg = getTeamArg(round, SEED_NAME, | ||
team % 2 == 0 and team - 1 or team + 1) | team % 2 == 0 and team - 1 or team + 1) | ||
-- show seed if seed is defined for either or both | -- show seed if seed is defined for either or both | ||
Ligne 136 : | Ligne 154 : | ||
end | end | ||
local teamArg = getTeamArg(round, | local teamArg = getTeamArg(round, TEAM_NAME, team) | ||
if not teamArg or string.len(teamArg) == 0 then | if not teamArg or string.len(teamArg) == 0 then | ||
teamArg = ' ' | teamArg = ' ' | ||
Ligne 164 : | Ligne 182 : | ||
:css('border-bottom-width', '0') | :css('border-bottom-width', '0') | ||
:css('background-color', '#f9f9f9') | :css('background-color', '#f9f9f9') | ||
:wikitext(getTeamArg(round, | :wikitext(getTeamArg(round, SCORE_NAME, team)) | ||
:newline() | :newline() | ||
Ligne 271 : | Ligne 289 : | ||
local group = 1 | local group = 1 | ||
for i = step / 2, count, step do | for i = step / 2, count, step do | ||
local name = | local name = ROUND_NAME .. round .. '-groupe' .. group | ||
addBlank(rows[i]):css('height', '7px') | addBlank(rows[i]):css('height', '7px') | ||
addBlank(rows[i + 1]):css('height', '7px') | addBlank(rows[i + 1]):css('height', '7px') | ||
Ligne 325 : | Ligne 343 : | ||
local seedCell | local seedCell | ||
if not hideSeeds then | if not hideSeeds then | ||
seedCell = addBlank(widthRow, getWidth( | seedCell = addBlank(widthRow, getWidth(SEED_NAME, '25px')) | ||
end | end | ||
local teamCell = addBlank(widthRow, getWidth( | local teamCell = addBlank(widthRow, getWidth(TEAM_NAME, '150px')) | ||
local scoreCell = addBlank(widthRow, getWidth( | local scoreCell = addBlank(widthRow, getWidth(SCORE_NAME, '25px')) | ||
addBlank(titleRow) | addBlank(titleRow) | ||
addBlank(widthRow, r < rounds and '5px' or nil) | addBlank(widthRow, r < rounds and '5px' or nil) | ||
Ligne 353 : | Ligne 371 : | ||
end | end | ||
rounds = tonumber(args | rounds = tonumber(args[ROUNDS_NAME]) or 2 | ||
local teams = math.pow(2, rounds) | local teams = math.pow(2, rounds) | ||
padding = '%0' .. (teams < 10 and 1 or 2) .. 'd' | padding = '%0' .. (teams < 10 and 1 or 2) .. 'd' | ||
local compact = (args[ | local compact = (args[COMPACT_NAME] and (args[COMPACT_NAME] == YES_VALUE or args[COMPACT_NAME] == Y_VALUE)) | ||
local autoSeeds = (args[ | local autoSeeds = (args[AUTOSEEDS_NAME] and (args[AUTOSEEDS_NAME] == YES_VALUE or args[AUTOSEEDS_NAME] == Y_VALUE)) | ||
hideSeeds = (args[ | hideSeeds = (args[SEEDS_NAME] and (args[SEEDS_NAME] == NO_VALUE or args[SEEDS_NAME] == N_VALUE)) | ||
showSeeds = (args[ | showSeeds = (args[SEEDS_NAME] and (args[SEEDS_NAME] == YES_VALUE or args[SEEDS_NAME] == Y_VALUE)) | ||
if autoSeeds then | if autoSeeds then | ||
Ligne 379 : | Ligne 397 : | ||
:css('border-spacing', '0') | :css('border-spacing', '0') | ||
if (args['nowrap'] and (args['nowrap'] == | if (args['nowrap'] and (args['nowrap'] == YES_VALUE or args['nowrap'] == Y_VALUE)) then | ||
tbl:css('white-space', 'nowrap') | tbl:css('white-space', 'nowrap') | ||
end | end |
Version du 14 septembre 2020 à 01:29
Ce modèle permet de représenter un tournoi à élimination simple. Il est copié du module TeamBracket de Wikipédia.
Usage
{{#invoke: Tournoi | tournoi | manches = | graine-largeur = | equipe-largeur = | score-largeur = | manche1 = | manche1-groupe1 = | manche1-graine1 = | manche1-équipe1 = | manche1-score1 = ... }}
Liste des paramètres
Les paramètres sont les suivants:
graine-largeur –
la largeur des cellules pour les graines.équipe-largeur –
la largeur des cellules pour les noms d'équipes.score-largeur –
la largeur des cellules pour les scores.graines –
mettre ànon
pour masquer toutes les graines.compact –
mettre àoui
pour un tournoi compact et la désactivation des groupes.
manchen –
Le nom de la manche n.manchen-groupem –
Le nom du groupe m à la manche n.manchen-grainem –
La graine de l'équipe m à la manche n.manchen-équipem –
Le nom de l'équipe m à la manche n.manchen-scorem –
Le score de l'équipe m à la manche n.
Descriptions des paramètres
- graine-largeur
- La largeur des cellules de graines en CSS. Exemples :
N [em/%/px]
auto
- équipe-largeur
- La largeur des cellules de noms d'équipes en CSS.
- score-largeur
- La largeur des cellules de score en CSS.
- manchen
- Le nom de la manche n. Par défaut "mèmes de finale", ..., "Quarts de finale", "Demi-finales", et "Finale", où m est le nombre d'équipes dans la manche.
- manchen-groupem
- Le nom du groupe m à la manche n. Pour chaque manche, chaque ensemble de quatre équipes est classifiée comme un groupe.
- manchen-grainem
- La graine de l'équipe m à la manche n. À la manche 1, cette valeur vaut par défaut l'allocation de graine conventionnelle pour les tournois. Si omis, la cellule est masquée. Pour masquer une cellule à la manche 1, la valeur doit explicitement être vide. m est la position comblée de 0.
- manchen-équipem
- Le nom de l'équipe m à la manche n. m est la position comblée de 0.
- manchen-scorem
- Le score de l'équipe m à la manche n. m est la position comblée de 0.
Exemples
Sans graine
{{#invoke: Tournoi | tournoi | manches = 2 | manche1-graine1 = | manche1-graine2 = | manche1-graine3 = | manche1-graine4 = }}
Demi-finales | Finale | ||||||||
Groupes
{{#invoke: Tournoi | tournoi | autograines = oui | manches = 4 | scores = non | manche1-groupe1 = Pacific | manche1-groupe2 = Mountain | manche2-groupe1 = West }}
16ème de finale | Quarts de finale | Demi-finales | Finale | ||||||||||||||||
Pacific | |||||||||||||||||||
West | |||||||||||||||||||
Mountain | |||||||||||||||||||
-- -- This module will implement {{Tournoi}} -- local p = {} local args local rounds local padding local hideSeeds local showSeeds local tracking = '' local WIDTH_NAME = 'largeur' local ROUND_NAME = 'manche' local ROUNDS_NAME = 'manches' local COMPACT_NAME = 'compact' local AUTOSEEDS_NAME = 'autograines' local SEEDS_NAME = 'graines' local SEED_NAME = 'graine' local TEAM_NAME = 'équipe' local SCORE_NAME = 'score' local YES_VALUE = 'oui' local Y_VALUE = 'o' local NO_VALUE = 'non' local N_VALUE = 'n' local FINALS_LABEL = 'Finale' local SEMIFINALS_LABEL = 'Demi-finales' local QUARTERFINALS_LABEL = 'Quarts de finale' local ROUNDOF_LABEL = '%d<sup>ème</sup> de finale' function getSeeds() local seeds = {1, 2} local count = 2 local before = false for r = 2, rounds do local max = math.pow(2, r) for i = 1, count do local pos = i * 2 if before then pos = pos - 1 end table.insert(seeds, pos, max - seeds[i * 2 - 1] + 1) before = not before end count = count * 2 end return seeds end function addTableRow(tbl) return tbl:tag('tr') end function addBlank(row, width) local cell = row:tag('td') if width then cell:css('width', width) end return cell end function addPath(rows, index, round, top, left) local prop = top and 'border-bottom-width' or 'border-top-width' if left and round == 1 then addBlank(rows[index]):css('height', '7px') addBlank(rows[index + 1]):css('height', '7px') return nil else local cell = addBlank(rows[index]) :attr('rowspan', '2') :css('border-width', '0') :css('border-style', 'solid') :css('border-color', 'black') if left or round < rounds and not left then cell:css(prop, '2px') end return cell end end function addCompactPath(rows, index, round, top, left) local prop = top and 'border-bottom-width' or 'border-top-width' if left and round == 1 then addBlank(rows[index]) return nil else local cell = addBlank(rows[index]) :css('border-width', '0') :css('border-style', 'solid') :css('border-color', 'black') if left or round < rounds and not left then cell:css(prop, '2px') end return cell end end function getWidth(param, default) local arg = args[param .. '-' .. WIDTH_NAME] if not arg or string.len(arg) == 0 then arg = default end if tonumber(arg) ~= nil then arg = arg .. 'px' end return arg end function getTeamArg(round, type, team) return args[getTeamArgName(round, type, team)] end function getTeamArgName(round, type, team) return string.format(ROUND_NAME .. '%d-%s' .. padding, round, type, team) end function getRoundName(round) local name = args[ROUND_NAME .. round] if name and string.len(name) > 0 then return name end local roundFromLast = rounds - round + 1 if roundFromLast == 1 then return FINALS_LABEL elseif roundFromLast == 2 then return SEMIFINALS_LABEL elseif roundFromLast == 3 then return QUARTERFINALS_LABEL else return string.format(ROUNDOF_LABEL, math.pow(2, roundFromLast)) end end function renderTeam(row, round, team, top, compact) local seedCell local seedArg = getTeamArg(round, SEED_NAME, team) -- seed value for the paired team local pairSeedArg = getTeamArg(round, SEED_NAME, team % 2 == 0 and team - 1 or team + 1) -- show seed if seed is defined for either or both local showSeed = showSeeds or (seedArg and string.len(seedArg) > 0) or (pairSeedArg and string.len(pairSeedArg) > 0) if showSeed and (not hideSeeds) then seedCell = row:tag('td') :css('text-align', 'center') :css('background-color', '#f2f2f2') :css('border-color', '#aaa') :css('border-style', 'solid') :css('border-top-width', '1px') :css('border-left-width', '1px') :css('border-right-width', '1px') :css('border-bottom-width', '0') :wikitext(seedArg) :newline() end local teamArg = getTeamArg(round, TEAM_NAME, team) if not teamArg or string.len(teamArg) == 0 then teamArg = ' ' end local teamCell = row:tag('td') :css('background-color', '#f9f9f9') :css('border-color', '#aaa') :css('border-style', 'solid') :css('border-top-width', '1px') :css('border-left-width', '1px') :css('border-right-width', '0') :css('border-bottom-width', '0') :css('padding', '0 2px') :wikitext(teamArg) :newline() if not showSeed and (not hideSeeds) then teamCell:attr('colspan', '2') end local scoreCell = row:tag('td') :css('text-align', 'center') :css('border-color', '#aaa') :css('border-style', 'solid') :css('border-top-width', '1px') :css('border-left-width', '1px') :css('border-right-width', '1px') :css('border-bottom-width', '0') :css('background-color', '#f9f9f9') :wikitext(getTeamArg(round, SCORE_NAME, team)) :newline() if not compact then if seedCell then seedCell:attr('rowspan', '2') :css('border-bottom-width', '1px') end scoreCell:attr('rowspan', '2') :css('border-bottom-width', '1px') teamCell:attr('rowspan', '2') :css('border-right-width', '1px') :css('border-bottom-width', '1px') else if not top then if seedCell then seedCell:css('border-bottom-width', '1px') end teamCell:css('border-bottom-width', '1px') scoreCell:css('border-bottom-width', '1px') end end end function renderRound(rows, count, r) local teams = math.pow(2, rounds - r + 1) local step = count / teams local topTeam = true -- is top row in match-up local topPair = true -- is top match-up in pair of match local team = 1 for i = 1, count, step do local offset, height, blank -- leave room for groups for teams other than first and last if team == 1 or team == teams then offset = topTeam and i or i + 2 height = step - 2 else offset = topTeam and i + 1 or i + 2 height = step - 3 end if height > 0 then blank = addBlank(rows[offset]) :attr('colspan', hideSeeds and '4' or '5') :attr('rowspan', height) :css('border-color', 'black') :css('border-style', 'solid') :css('border-width', '0') end -- add bracket local j = topTeam and i + step - 2 or i -- add left path addPath(rows, j, r, topTeam, true) renderTeam(rows[j], r, team, topTeam, false) local rightPath = addPath(rows, j, r, topTeam, false) if not topTeam then topPair = not topPair end if not topPair and r < rounds then if blank then blank:css('border-right-width', '2px') end rightPath:css('border-right-width', '2px') end team = team + 1 topTeam = not topTeam end end function renderCompactRound(rows, count, r) local teams = math.pow(2, rounds - r + 1) local step = count / teams local topTeam = true -- is top row in match-up local topPair = true -- is top match-up in pair of match local team = 1 for i = 1, count, step do local offset, height, blank -- empty space above or below local offset = topTeam and i or i + 1 local height = step - 1 if height > 0 then blank = addBlank(rows[offset]) :attr('colspan', hideSeeds and '4' or '5') :css('border-color', 'black') :css('border-style', 'solid') :css('border-width', '0') :attr('rowspan', height) end -- add bracket local j = topTeam and i + step - 1 or i -- add left path addCompactPath(rows, j, r, topTeam, true) renderTeam(rows[j], r, team, topTeam, true) local rightPath = addCompactPath(rows, j, r, topTeam, false) if not topTeam then topPair = not topPair end if not topPair and r < rounds then if blank then blank:css('border-right-width', '2px') end rightPath:css('border-right-width', '2px') end team = team + 1 topTeam = not topTeam end end function renderGroups(rows, count, round) local roundFromLast = rounds - round + 1 local groups = math.pow(2, roundFromLast - 2) local step = count / groups local group = 1 for i = step / 2, count, step do local name = ROUND_NAME .. round .. '-groupe' .. group addBlank(rows[i]):css('height', '7px') addBlank(rows[i + 1]):css('height', '7px') addBlank(rows[i]) :attr('rowspan', '2') :attr('colspan', (hideSeeds and 4 or 5) * round - 1) :css('text-align', 'center') :css('border-color', 'black') :css('border-style', 'solid') :css('border-width', '0 2px 0 0') :wikitext(args[name]) :newline() group = group + 1 end end function renderTree(tbl, compact) -- create 3 or 1 rows for every team local count = math.pow(2, rounds) * (compact and 1 or 3) local rows = {} for i = 1, count do rows[i] = addTableRow(tbl) end if not compact then -- fill rows with groups for r = 1, rounds - 1 do renderGroups(rows, count, r) end end -- fill rows with bracket for r = 1, rounds do if compact then renderCompactRound(rows, count, r) else renderRound(rows, count, r) end end end function renderHeading(tbl, compact) local titleRow = addTableRow(tbl) local widthRow = addTableRow(tbl) for r = 1, rounds do addBlank(titleRow) addBlank(widthRow, r > 1 and '5px' or nil) titleRow:tag('td') :attr('colspan', hideSeeds and '2' or '3') :css('text-align', 'center') :css('border', '1px solid #aaa') :css('background-color', '#f2f2f2') :wikitext(getRoundName(r)) :newline() local seedCell if not hideSeeds then seedCell = addBlank(widthRow, getWidth(SEED_NAME, '25px')) end local teamCell = addBlank(widthRow, getWidth(TEAM_NAME, '150px')) local scoreCell = addBlank(widthRow, getWidth(SCORE_NAME, '25px')) addBlank(titleRow) addBlank(widthRow, r < rounds and '5px' or nil) if compact then teamCell:css('height', '7px') else if seedCell then seedCell:wikitext(' ') end teamCell:wikitext(' ') scoreCell:wikitext(' ') end end end function p.tournoi(frame) local getArgs = require('Module:Arguments').getArgs args = getArgs(frame, {trim = false, removeBlanks = false}) -- exit early if this section is not to be transcluded if args['section'] and args['transcludesection'] and args['section'] ~= args['transcludesection'] then return '' end rounds = tonumber(args[ROUNDS_NAME]) or 2 local teams = math.pow(2, rounds) padding = '%0' .. (teams < 10 and 1 or 2) .. 'd' local compact = (args[COMPACT_NAME] and (args[COMPACT_NAME] == YES_VALUE or args[COMPACT_NAME] == Y_VALUE)) local autoSeeds = (args[AUTOSEEDS_NAME] and (args[AUTOSEEDS_NAME] == YES_VALUE or args[AUTOSEEDS_NAME] == Y_VALUE)) hideSeeds = (args[SEEDS_NAME] and (args[SEEDS_NAME] == NO_VALUE or args[SEEDS_NAME] == N_VALUE)) showSeeds = (args[SEEDS_NAME] and (args[SEEDS_NAME] == YES_VALUE or args[SEEDS_NAME] == Y_VALUE)) if autoSeeds then -- set default seeds for round 1 local seeds = getSeeds() for i = 1, table.getn(seeds) do local argname = getTeamArgName(1, 'seed', i) if not args[argname] then args[argname] = seeds[i] end end end local tbl = mw.html.create('table') :css('border-style', 'none') :css('font-size', '90%') :css('margin', '1em 2em 1em 1em') :css('border-collapse', 'separate') :css('border-spacing', '0') if (args['nowrap'] and (args['nowrap'] == YES_VALUE or args['nowrap'] == Y_VALUE)) then tbl:css('white-space', 'nowrap') end if compact then tbl:css('font-size', '90%'):attr('cellpadding', '0') end renderHeading(tbl, compact) renderTree(tbl, compact) return tostring(tbl) .. tracking end return p