Ez a modul az olyan egyenes kieséses rendszerű tornák ágrajzainak vizuális megjelenítését valósítja meg, amelyeket a Modul:TeamBracket segítségével nem mindig lehet elkészíteni. Például egyesével kihagyott mérkőzések, vagy kettőnél több szereplő van egy mérkőzésen. Jellemzője, hogy a mérkőzésekhez tartozik egy szöveges rész is (például dátumhoz, helyszínhez).
{{Build bracket
| RD1 =
| RD1-seed1 =
| RD1-team1 =
| RD1-score1 =
...
}}
Paraméter
Leírás
Alapértelmezés
maxround
A megjelenített fordulók száma. A paramétert nem veszi figyelembe, ha az értéke kisebb, mint a rounds
paraméterben beállított érték.
minround
Az elsőnek megjelenített forduló száma.
1
height
Az ágrajz láthatósága függőlegesen. Ha nem fér el a magasságban az ágrajz, akkor gördítősáv jelenik meg. A számot egységben kell megadni (pl., 30em
or 480px
).
autocol
yes
érték esetén a megjelenítendő maximális fordulók számának automatikus beállítása a bejegyzések alapján.
no
col-spacing
A fordulók közötti távolság. Egyszerű számot kell használni (pl.: 10
for 10px).
5
nowrap
A yes
érték megadásával a hosszú nevek azonos sorba kerülnek, nem lesz sortörés.
no
seed-width
A kiemelések (seed) cellák szélessége. Az egyszerű számokat pixelben kell megadni (pl.: 25
a 25px értékhez vagy 2em
a 2em értékhez vagy auto
az automatikus mérethez.
25
team-width
A csapatnevek (team) cellák szélessége. Az egyszerű számokat pixelben kell megadni (pl.: 200
a 200px értékhez vagy 15em
a 15em értékhez vagy auto
az automatikus mérethez.
150
score-width
Az eredmény (score) cellák szélessége. Az egyszerű számokat pixelben kell megadni (pl.: 25
a 25px értékhez vagy 2em
a 2em értékhez vagy auto
az automatikus mérethez.
25
agg-width
Az összesített eredmény (aggregate) cellák szélessége. Az egyszerű számokat pixelben kell megadni (pl.: 25
a 25px értékhez vagy 2em
a 2em értékhez vagy auto
az automatikus mérethez.
25
seeds
A no
érték megadásával a kiemelés cellái nem jelennek meg, a yes
megadásával a kiemelés cellái mindig megjelennek.
legs
A párosításokhoz tartozó mérkőzések száma az összes fordulóban. Az RDm -legs
paraméterrel az m -edik fordulót állítja be. Az RDm -legsk
paraméterrel az m -edik fordulóban a k csapathoz tartozó mérkőzések számát lehet egyedileg megadni.
1
autolegs
set to yes
to automatically generate score cells per team. If legs
or RDm -legs
is used, autolegs
will be set to no
.
no
byes
A yes
érték használatával elrejti az összes üres cellát. Az RDm -byes
paraméterrel az m -edik oszlopban lévőeket rejti el. Az RDmh -byes
paraméterrel a h fejléc alattiak az m -edik oszlopban lévőeket rejti el.
no
show-bye-paths
set to yes
to replace any team cells that that are hidden byes
with a path.
no
aggregate
A yes
érték esetén minden mérkőzéshez egy összesítésként használható cella jelenik meg. Csak a kettő vagy több mérkőzéses párosításoknál jelenik meg.
no
boldwinner
A yes
érték használatával a győztes csapat neve – a zárójelbe tett szövegek kivételével – és az eredménye automatikusan vastagbetűvel jelenik meg. A kiemelés alapértelmezésben nem lesz vastagbetűs.
no
boldseed
A boldwinner
alkalmazása esetén a yes
érték beállításával a győztes kiemelése is vastagbetűs lesz.
yes
shift
függőlegesen eltolja az összes cellát a megadott értékkel. Az RDm -shift
paraméterrel csak az m -edik oszlop celláit tolja el.
0
RDm
, RDmh
A h -adik fejléc szövege az m -edik oszlopban. (pl.: az RD1
vagy RD1a
az első fejléc, az RD1b
a második fejléc szöveg az 1. oszlopban)
RDm -seedk
A k -adik csapat kiemelése az m -edik oszlopban. Alternatívaként használható az RDmh -seedk
paraméter, amely a k -adik csapatot jelenti az mh fejléc alatt.
RDm -teamk
A k -adik csapat neve az m -edik oszlopban. Alternatívaként használható az RDmh -teamk
paraméter, amely a k -adik csapatot jelenti az mh fejléc alatt.
RDm -scorek
A k -adik csapat eredménye az m -edik oszlopban. Alternatívaként használható az RDmh -scorek
, amely a k -adik csapatot jelenti az mh fejléc alatt. A -l
utótag használata az l -edik mérkőzést vagy az -agg
használata az összesített eredményt jelenti.
RDm -textk
A k -adik mérkőzés felett az m -edik oszlopban megjelenő szöveges rész. Alternatívaként használható az RDmh -textk
paraméter, amely a k -adik mérkőzést jelenti az mh fejléc alatt.
RDm -groupk
Az k -adik csoport megnevezése az m -edik oszlopban. A csoport szövege a két ág találkozásának bal oldalán jelenik meg.
RD-shade
the background color (in hex format, e.g. #ABCDEF
) of all headers. Use RDm -shade
or RDmh -shade
for individual headers.
#F2F2F2
RDm -RD(m +1)-path
set to no
or 0
to omit the paths from round m to round m +1. Note: Does not currently work for paths under subheaders .
yes
paramstyle
[ a 1]
A numbered
értékkel az RDm -textk
, RDm -seedk
, RDm -teamk
, és az RDm -scorek
paramétereket folytatólagosan számozott paraméternevekre állítja át (|1=
,|2=
...). A |seeds=yes
beállítással a kiemelések mindenhol megjelennek.
indexed
↑ Lehet, hogy nem kompatibilis bizonyos más funkciókkal.
Megjegyzés : Ezek csak példák a paraméterek illusztrálására. A sztenderd sablonok jobban kezelhetőek a Modul:Team bracket modullal.
Standard 4-csapatos ág
{{#invoke:Build bracket|main
| rounds=2
| col1-headers = 1
| col2-headers = 1
| col1-matches = 3,7
| col2-matches = 5
| col1-col2-paths = (3,7)-5
<!-- Defaults -->
| RD2 = Döntő
| RD1-seed1 = 1
| RD1-seed3 = 2
}}
3 szereplős ág
{{#invoke:Build bracket|main
| rounds=2
| teams-per-match = 3
| col1-headers = 1
| col2-headers = 1
| col1-matches = 3,7,11
| col2-matches = 7
| col1-col2-paths = (3,7,11)-7
}}
Vigaszágas rendszer
{{#invoke:Build bracket|main
| rounds=4
| col1-headers = 1,7
| col2-headers = 1,7
| col3-headers = 7
| col4-headers = 1
| col1-matches = 4,11
| col2-matches = 3,10
| col3-matches = 9
| col4-matches = 6
| col1-col2-paths = 4-3, 11-10
| col2-col3-paths = 3-3, 10-9
| col3-col4-paths = (3,9)-6
<!-- Defaults -->
| RD1 = Felső ág, 1. forduló
| RD2 = Felső döntő
| RD1b = Alsó ág, 1. forduló
| RD2b = Alsó ág, 2. forduló
| RD3b = Alsó döntő
}}
Felső ág, 1. forduló Felső döntő Döntő Alsó ág, 1. forduló Alsó ág, 2. forduló Alsó döntő
Keresztező ágak
{{#invoke:Build bracket|main
| rounds=2
| col1-matches = 3,7
| col2-matches = 3,7
| col1-col2-paths = 3-7, 7-3
| col1-col2-cross = 5
}}
{{#invoke:Build bracket|main
| rounds=2
| seeds=no
| col1-matches = 3,7
| col2-matches = 5
| col1-col2-paths = (3,7)-5
}}
{{#invoke:Build bracket|main
| rounds=2
| col1-matches = 3,6
| col2-matches = 4.5
| col1-col2-paths = (3,6)-4.5
| RD1-text1 = Szöveg 1
| RD1-text2 = Szöveg 2
| RD2-text1 = Szöveg 3
}}
Elődöntők Döntő Szöveg 1 Szöveg 3 Szöveg 2
{{#invoke:Build bracket|main
| rounds=3
| col1-matches = 3,6,9,12
| col2-matches = 4.5,10.5
| col3-matches = 7.5
| col1-col2-paths = (3,6)-4.5, (9,12)-10.5
| col2-col3-paths = (4.5,10.5)-7.5
| RD1-group1 = Csoport 1
| RD1-group2 = Csoport 2
| RD2-group1 = Csoport 3
}}
Negyeddöntők Elődöntők Döntő Csoport 1 Csoport 3 Csoport 2
{{#invoke:Build bracket|main
| rounds=3
| legs = 2
| RD1-legs = 3
| col1-matches = 3,6,9,12
| col2-matches = 4.5,10.5
| col3-matches = 7.5
| col1-col2-paths = (3,6)-4.5, (9,12)-10.5
| col2-col3-paths = (4.5,10.5)-7.5
}}
Negyeddöntők Elődöntők Döntő
{{#invoke:Build bracket|main
| rounds=3
| legs=2
| aggregate=y
| col1-matches = 3,6,9,12
| col2-matches = 4.5,10.5
| col3-matches = 7.5
| col1-col2-paths = (3,6)-4.5, (9,12)-10.5
| col2-col3-paths = (4.5,10.5)-7.5
}}
Negyeddöntők Elődöntők Döntő
{{#invoke:Build bracket|main
| rounds=3
| RD1-byes = y
| col1-matches = 3,6,9,12
| col2-matches = 4.5,10.5
| col3-matches = 7.5
| col1-col2-paths = (3,6)-4.5, (9,12)-10.5
| col2-col3-paths = (4.5,10.5)-7.5
| RD1-team1 = Csapat 1
| RD1-team2 = Csapat 2
}}
Negyeddöntők Elődöntők Döntő Csapat 1 Csapat 2
{{#invoke:Build bracket|main
| rounds=2
| col1-matches = 3,7
| col2-matches = 5
| col1-col2-paths = (3,7)-5
| paramstyle = numbered
| seeds = yes
| Szöveg 1 | 1 | Csapat 1 | 5 | 4 | Csapat 2 | 11
| Szöveg 2 | 2 | Csapat 3 | 6 | 3 | Csapat 4 | 3
| Szöveg 3 | 4 | Csapat 2 | 2 | 2 | Csapat 3 | 1
}}
Elődöntők Döntő Szöveg 1 1 Csapat 1 5 4 Csapat 2 11
Szöveg 3 4 Csapat 2 2 Szöveg 2 2 Csapat 3 1
2 Csapat 3 6 3 Csapat 4 3
A győztes vastagbetűvel
{{#invoke:Build bracket|main
| rounds=2
| legs = 3
| boldwinner=y
| col1-matches = 3,7
| col2-matches = 5
| col1-col2-paths = (3,7)-5
| RD1-seed1 = 1 | RD1-team1 = Csapat 1 | RD1-score1-1 = 5 | RD1-score1-2 = 12 | RD1-score1-3 = 15
| RD1-seed2 = 4 | RD1-team2 = Csapat 2 | RD1-score2-1 = 11 | RD1-score2-2 = 10 | RD1-score2-3 = 4
| RD1-seed3 = 2 | RD1-team3 = Csapat 3 | RD1-score3-1 = 6 | RD1-score3-2 = 13 | RD1-score3-3 = {{ndash}}
| RD1-seed4 = 3 | RD1-team4 = Csapat 4 | RD1-score4-1 = 3 | RD1-score4-2 = 2 | RD1-score4-3 = {{ndash}}
| RD2-seed1 = 4 | RD2-team1 = Csapat 2 | RD2-score1-1 = 2 | RD2-score1-2 = 2 | RD2-score1-3 = 5
| RD2-seed2 = 2 | RD2-team2 = Csapat 3 | RD2-score2-1 = 1 | RD2-score2-2 = 7 | RD2-score2-3 = 2
}}
Elődöntők Döntő 1 Csapat 1 5 12 15 4 Csapat 2 11 10 4 4 Csapat 2 2 2 5 2 Csapat 3 1 7 2 2 Csapat 3 6 13 – 3 Csapat 4 3 2 –
local p = {}
local entries = {}
local pathCell = {}
local crossCell = {}
local skipPath = {}
local shift = {}
local hascross = {}
local teams_per_match = {}
local rlegs = {}
local maxlegs = {}
local autolegs
local byes = {}
local hide = {}
local matchgroup = {}
local nowrap
local autocol
local seeds
local forceseeds
local boldwinner
local boldseed
local aggregate
local boldlegs
local boldagg
local paramstyle
local masterindex
local function isempty ( s )
return s == nil or s == ''
end
local function notempty ( s )
return s ~= nil and s ~= ''
end
local function bargs ( s )
return pargs [ s ] or fargs [ s ]
end
local function toChar ( num )
return string.char ( string.byte ( "a" ) + num - 1 )
end
local function unboldParenthetical ( text )
-- Replace wikilinks with unique placeholders
local counter = 0
local placeholders = {}
text = text : gsub ( '%[%[(.-)%]%]' , function ( link )
counter = counter + 1
local placeholder = '__WIKILINK__' .. counter .. '__'
placeholders [ placeholder ] = link
return placeholder
end )
-- Apply <span style="font-weight:normal"></span> to parenthetical and bracketed text
text = text : gsub ( '(%b())' , '<span style="font-weight:normal">%1</span>' )
: gsub ( '(%b[])' , '<span style="font-weight:normal">%1</span>' )
-- Restore the original wikilinks
for placeholder , link in pairs ( placeholders ) do
text = text : gsub ( placeholder , '[[' .. link .. ']]' )
end
return text
end
local function split ( str , delim , tonum )
result = {};
local a = "[^" .. table.concat ( delim ) .. "]+"
for w in str : gmatch ( a ) do
if tonum == true then
table.insert ( result , tonumber ( w ));
else
table.insert ( result , w );
end
end
return result ;
end
local function getWidth ( ctype , default )
local result = bargs ( ctype .. '-width' )
if isempty ( result ) then return default end
if tonumber ( result ) ~= nil then return result .. 'px' end
return result
end
local function matchGroups ()
for j = minc , c do
matchgroup [ j ] = {}
for i = 1 , r do
if entries [ j ][ i ] ~= nil and entries [ j ][ i ][ 'ctype' ] == 'team' then
matchgroup [ j ][ i ] = math.ceil ( entries [ j ][ i ][ 'index' ] / teams_per_match [ j ])
entries [ j ][ i ][ 'group' ] = math.ceil ( entries [ j ][ i ][ 'index' ] / teams_per_match [ j ])
end
end
end
end
local function teamLegs ( j , i )
local legs = rlegs [ j ]
if notempty ( entries [ j ][ i ][ 'legs' ]) then
legs = tonumber ( entries [ j ][ i ][ 'legs' ])
end
if autolegs then
local l = 1
repeat l = l + 1
until isempty ( entries [ j ][ i ][ 'score' ][ l ])
legs = l - 1
end
return legs
end
local function boldWinner ()
local function boldScore ( j , i , l )
if entries [ j ][ i ] ~= nil and entries [ j ][ i ][ 'ctype' ] == 'team' then
local myscore = entries [ j ][ i ][ 'score' ][ l ]: gsub ( '%W' , '' )
if myscore == "" or myscore : find ( "%D" ) then return 'normal'
else myscore = tonumber ( myscore ) end
local compscore = {}
for k , v in pairs ( matchgroup [ j ]) do
if matchgroup [ j ][ i ] == v and k ~= i then
local theirscore = entries [ j ][ k ][ 'score' ][ l ] or ''
theirscore = theirscore : gsub ( '%W' , '' )
if theirscore == "" or theirscore : find ( "%D" ) then return 'normal'
else table.insert ( compscore , tonumber ( theirscore )) end
end
end
for k , v in pairs ( compscore ) do
if myscore <= v then return 'normal' end
end
if l ~= 'agg' then
entries [ j ][ i ][ 'wins' ] = entries [ j ][ i ][ 'wins' ] + 1
else
entries [ j ][ i ][ 'aggwins' ] = 1
end
return 'bold'
end
end
local function boldTeam ( j , i , agg )
local wins
local legs = teamLegs ( j , i )
if agg ~= true then
wins = 'wins'
if entries [ j ][ i ][ wins ] > legs / 2 then
return 'bold'
end
if autolegs then
for l = 1 , legs do
if notempty ( entries [ j ][ i ][ 'score' ][ l ]) and string.find ( entries [ j ][ i ][ 'score' ][ l ], "nbsp" ) then
return 'normal'
end
end
else
for l = 1 , legs do
if isempty ( entries [ j ][ i ][ 'score' ][ l ]) or string.find ( entries [ j ][ i ][ 'score' ][ l ], "nbsp" ) then
return 'normal'
end
end
end
else
wins = 'aggwins'
end
local compteam = {}
for k , v in pairs ( matchgroup [ j ]) do
if matchgroup [ j ][ i ] == v and k ~= i then
table.insert ( compteam , tonumber ( entries [ j ][ k ][ wins ]))
end
end
for k , v in pairs ( compteam ) do
if entries [ j ][ i ][ wins ] <= v then
return 'normal'
end
end
return 'bold'
end
for j = minc , c do
for i = 1 , r do
if entries [ j ][ i ] ~= nil and entries [ j ][ i ][ 'ctype' ] == 'team' then
entries [ j ][ i ][ 'wins' ] = 0
entries [ j ][ i ][ 'aggwins' ] = 0
end
end
for i = 1 , r do
if entries [ j ][ i ] ~= nil and entries [ j ][ i ][ 'ctype' ] == 'team' then
local legs = teamLegs ( j , i )
for l = 1 , legs do
entries [ j ][ i ][ 'score' ][ 'weight' ][ l ] = boldScore ( j , i , l )
end
if aggregate and legs > 1 then
--boldlegs = bargs('boldlegs') or 'yes'
--if boldlegs == 'yes' then
-- entries[j][i]['score']['weight'][l] = boldScore(j,i,l)
-- else
-- entries[j][i]['score']['weight'][l] = 'normal'
--end
boldagg = bargs ( 'boldagg' ) or 'no'
if boldagg == 'yes' then
entries [ j ][ i ][ 'score' ][ 'weight' ][ 'agg' ] = 'bold'
else
entries [ j ][ i ][ 'score' ][ 'weight' ][ 'agg' ] = boldScore ( j , i , 'agg' )
end
end
end
end
for i = 1 , r do
if entries [ j ][ i ] ~= nil and entries [ j ][ i ][ 'ctype' ] == 'team' then
local agg
local legs = teamLegs ( j , i )
if aggregate and legs > 1 then agg = true end
entries [ j ][ i ][ 'weight' ] = boldTeam ( j , i , agg )
end
end
end
end
local function isBlankEntry ( col , row , ctype )
if isempty ( entries [ col ][ row ]) then return true end
if isempty ( entries [ col ][ row ][ 'team' ]) and isempty ( entries [ col ][ row ][ 'text' ]) then return true end
return false
end
local function showSeeds ( j , i )
local showseed = false
if forceseeds or notempty ( entries [ j ][ i ][ 'seed' ]) then
showseed = true
else
for k = 1 , teams_per_match [ j ] - 1 do
if notempty ( entries [ j ][ i + 2 * k ]) and entries [ j ][ i ][ 'group' ] == entries [ j ][ i + 2 * k ][ 'group' ] and notempty ( entries [ j ][ i + 2 * k ][ 'seed' ]) then
showseed = true
end
if notempty ( entries [ j ][ i - 2 * k ]) and entries [ j ][ i ][ 'group' ] == entries [ j ][ i - 2 * k ][ 'group' ] and notempty ( entries [ j ][ i - 2 * k ][ 'seed' ]) then
showseed = true
end
end
end
return showseed
end
local function cellBorder ( b )
return b [ 1 ] .. 'px ' .. b [ 2 ] .. 'px ' .. b [ 3 ] .. 'px ' .. b [ 4 ] .. 'px'
end
local function Cell ( tbl , j , i , rowspan , colspan , text , align , border , border_width , bg , padding , weight , nwrap )
local cell = tbl : tag ( 'td' )
if colspan ~= 1 then
cell : attr ( 'colspan' , colspan )
end
if rowspan ~= 1 then
cell : attr ( 'rowspan' , rowspan )
end
if notempty ( border ) then
cell : css ( 'border' , border )
end
if notempty ( border_width ) then
cell : css ( 'border-width' , cellBorder ( border_width ))
end
if notempty ( bg ) then
cell : css ( 'background-color' , bg )
end
if notempty ( align ) then
cell : css ( 'text-align' , align )
end
cell : css ( 'padding' , '0em 0.3em' )
if weight == 'bold' then
cell : css ( 'font-weight' , weight )
end
if notempty ( text ) then
cell : wikitext ( text )
end
return cell
end
local function teamCell ( tbl , k , j , i , l , colspan )
boldseed = bargs ( 'boldseed' ) or 'no'
local bg = '#F2F2F2'
local align
local padding
local weight
local text
local nwrap
local b = { 0 , 0 , 1 , 1 }
if k == 'seed' or k == 'score' then
align = 'center'
end
if k ~= 'seed' then
bg = '#F9F9F9'
end
if k == 'team' then
padding = '0.3em'
if teamLegs ( j , i ) == 0 then
b [ 2 ] = 1
end
end
if entries [ j ][ i ][ 'position' ] == 'top' then
b [ 1 ] = 1
end
if l == teamLegs ( j , i ) or l == 'agg' or k == 'seed' then
b [ 2 ] = 1
end
if ( l == nil and entries [ j ][ i ][ 'weight' ] == 'bold' ) or entries [ j ][ i ][ 'score' ][ 'weight' ][ l ] == 'bold' then
weight = 'bold'
end
if l == nil then
text = unboldParenthetical ( entries [ j ][ i ][ k ])
else
text = tostring ( entries [ j ][ i ][ k ][ l ])
end
if k == 'seed' and boldseed == 'no' then
weight = 'normal'
end
return Cell ( tbl , j , i , 2 , colspan , text , align , 'solid #aaa' , b , bg , padding , weight , nwrap )
end
local function insertEntry ( tbl , j , i )
local entry_colspan = maxlegs [ j ] + 2
if not seeds then entry_colspan = entry_colspan - 1 end
if ( aggregate and maxlegs [ j ] > 1 ) or maxlegs [ j ] == 0 then
entry_colspan = entry_colspan + 1
end
if entries [ j ][ i ] ~= nil and entries [ j ][ i ][ 'ctype' ] == 'blank' then
return
end
if entries [ j ][ i ] == nil then
if entries [ j ][ i - 1 ] ~= nil or i == 1 then
local rowspan = 0
local row = i
repeat
rowspan = rowspan + 1
row = row + 1
until entries [ j ][ row ] ~= nil or row > r
return Cell ( tbl , j , i , rowspan , entry_colspan )
else
return
end
end
if entries [ j ][ i ][ 'ctype' ] == 'header' then
if byes [ j ][ entries [ j ][ i ][ 'headerindex' ]] then
local emptyround = true
local row = i + 1
repeat
if not isBlankEntry ( j , row ) then
emptyround = false
end
row = row + 1
until ( entries [ j ][ row ] ~= nil and entries [ j ][ row ][ 'ctype' ] == 'header' ) or row > r
if emptyround == true then
return Cell ( tbl , j , i , 2 , entry_colspan )
end
end
if hide [ j ][ entries [ j ][ i ][ 'headerindex' ]] then
return Cell ( tbl , j , i , 2 , entry_colspan )
end
if isempty ( entries [ j ][ i ][ 'header' ]) then
if entries [ j ][ i ][ 'headerindex' ] == 1 then
if j == c then entries [ j ][ i ][ 'header' ] = 'Döntő'
elseif j == c - 1 then entries [ j ][ i ][ 'header' ] = 'Elődöntők'
elseif j == c - 2 then entries [ j ][ i ][ 'header' ] = 'Negyeddöntők'
else entries [ j ][ i ][ 'header' ] = j .. '. forduló'
end
else
entries [ j ][ i ][ 'header' ] = 'Lower round ' .. j
end
end
return Cell ( tbl , j , i , 2 , entry_colspan , entries [ j ][ i ][ 'header' ], 'center' , '1px solid #aaa' , nil , entries [ j ][ i ][ 'shade' ])
end
if entries [ j ][ i ][ 'ctype' ] == 'team' then
if ( byes [ j ][ entries [ j ][ i ][ 'headerindex' ]] and isBlankEntry ( j , i )) or hide [ j ][ entries [ j ][ i ][ 'headerindex' ]] then
return Cell ( tbl , j , i , 2 , entry_colspan )
end
local legs = teamLegs ( j , i )
local team_colspan = maxlegs [ j ] - legs + 1
if aggregate and legs == 1 and maxlegs [ j ] > 1 then
team_colspan = team_colspan + 1
end
if maxlegs [ j ] == 0 then
team_colspan = team_colspan + 1
end
if seeds then
if showSeeds ( j , i ) == true then
teamCell ( tbl , 'seed' , j , i )
else
team_colspan = team_colspan + 1
end
end
teamCell ( tbl , 'team' , j , i , nil , team_colspan )
for l = 1 , legs do
teamCell ( tbl , 'score' , j , i , l )
end
if aggregate and legs > 1 then
teamCell ( tbl , 'score' , j , i , 'agg' )
end
end
if entries [ j ][ i ][ 'ctype' ] == 'text' then
Cell ( tbl , j , i , 2 , entry_colspan , entries [ j ][ i ][ 'text' ], nil , nil , nil , nil , '0.3em' )
end
if entries [ j ][ i ][ 'ctype' ] == 'group' then
local colspan = 0
for m = j , entries [ j ][ i ][ 'colspan' ] + j - 1 do
colspan = colspan + maxlegs [ m ] + 2
if not seeds then colspan = colspan - 1 end
if ( aggregate and maxlegs [ m ] > 1 ) or maxlegs [ m ] == 0 then
colspan = colspan + 1
end
end
colspan = colspan + 2 * ( entries [ j ][ i ][ 'colspan' ] - 1 )
return Cell ( tbl , j , i , 2 , colspan , entries [ j ][ i ][ 'group' ], 'center' )
end
if entries [ j ][ i ][ 'ctype' ] == 'line' then
local b = { 0 , 0 , 0 , 0 }
b [ 3 ] = 2 * pathCell [ j - 1 ][ i + 1 ][ 3 ][ 3 ]
return Cell ( tbl , j , i , 2 , entry_colspan , entries [ j ][ i ][ 'text' ], nil , 'solid black' , b )
end
if entries [ j ][ i ][ 'ctype' ] == 'line2' then
local b = { 0 , 0 , 0 , 0 }
b [ 1 ] = 2 * pathCell [ j - 1 ][ i ][ 3 ][ 1 ]
return Cell ( tbl , j , i , 2 , entry_colspan , entries [ j ][ i ][ 'text' ], nil , 'solid black' , b )
end
end
local function isRoundHidden ( j , i , headerindex )
if notempty ( entries [ j ][ i ][ 'pheader' ]) then
hide [ j ][ entries [ j ][ i ][ 'headerindex' ]] = false
end
local row = i + 1
repeat
if not isBlankEntry ( j , row ) then
hide [ j ][ entries [ j ][ i ][ 'headerindex' ]] = false
end
row = row + 1
until ( entries [ j ][ row ] ~= nil and entries [ j ][ row ][ 'ctype' ] == 'header' ) or row > r
end
local function paramNames ( cname , j , i , l )
local rname = {
{ 'RD' .. j , bargs ( 'RD' .. j .. '-altname' ) or 'RD' .. j },
{ 'RD' .. j .. toChar ( entries [ j ][ i ][ 'headerindex' ]), bargs ( 'RD' .. j .. toChar ( entries [ j ][ i ][ 'headerindex' ]) .. '-altname' ) or 'RD' .. j .. toChar ( entries [ j ][ i ][ 'headerindex' ])}
}
local name = { cname , bargs ( cname .. '-altname' ) or cname }
local index = { entries [ j ][ i ][ 'index' ], entries [ j ][ i ][ 'altindex' ]}
local result = {}
if cname == 'header' then
if entries [ j ][ i ][ 'headerindex' ] == 1 then
for k = 1 , 2 do
table.insert ( result , bargs ( rname [ 1 ][ 3 - k ]) or '' )
table.insert ( result , bargs ( rname [ 2 ][ 3 - k ]) or '' )
end
else
for k = 1 , 2 do
table.insert ( result , bargs ( rname [ 2 ][ 3 - k ]) or '' )
end
end
elseif cname == 'pheader' then
if entries [ j ][ i ][ 'headerindex' ] == 1 then
for k = 1 , 2 do
table.insert ( result , pargs [ rname [ 1 ][ 3 - k ]] or '' )
table.insert ( result , pargs [ rname [ 2 ][ 3 - k ]] or '' )
end
else
for k = 1 , 2 do
table.insert ( result , pargs [ rname [ 2 ][ 3 - k ]] or '' )
end
end
elseif cname == 'score' then
for m = 1 , 2 do for k = 1 , 2 do
if l == 1 then
table.insert ( result , bargs ( rname [ 3 - m ][ 3 - k ] .. '-' .. name [ 1 ] .. index [ 3 - m ]) or bargs ( rname [ 3 - m ][ 3 - k ] .. '-' .. name [ 1 ] .. '0' .. index [ 3 - m ]) or '' )
end
table.insert ( result , bargs ( rname [ 3 - m ][ 3 - k ] .. '-' .. name [ 1 ] .. index [ 3 - m ] .. '-' .. l ) or bargs ( rname [ 3 - m ][ 3 - k ] .. '-' .. name [ 1 ] .. '0' .. index [ 3 - m ] .. '-' .. l ) or '' )
end end
elseif cname == 'shade' then
for k = 1 , 2 do
if entries [ j ][ i ][ 'headerindex' ] == 1 then
table.insert ( result , bargs ( rname [ 1 ][ 3 - k ] .. '-' .. name [ 1 ]) or '' )
else
table.insert ( result , bargs ( rname [ 2 ][ 3 - k ] .. '-' .. name [ 1 ]) or '' )
end
end
table.insert ( result , bargs ( 'RD-shade' ))
table.insert ( result , '#F2F2F2' )
elseif cname == 'text' then
for n = 1 , 2 do for m = 1 , 2 do for k = 1 , 2 do
table.insert ( result , bargs ( rname [ 3 - m ][ 3 - k ] .. '-' .. name [ 3 - n ] .. index [ 3 - m ]) or bargs ( rname [ 3 - m ][ 3 - k ] .. '-' .. name [ 3 - n ] .. '0' .. index [ 3 - m ]) or '' )
end end end
else
for m = 1 , 2 do for k = 1 , 2 do
table.insert ( result , bargs ( rname [ 3 - m ][ 3 - k ] .. '-' .. name [ 1 ] .. index [ 3 - m ]) or bargs ( rname [ 3 - m ][ 3 - k ] .. '-' .. name [ 1 ] .. '0' .. index [ 3 - m ]) or '' )
end end
end
for k = 1 , # result do
if notempty ( result [ k ]) then
return result [ k ]
end
end
return ''
end
local function indexedParams ( j )
for i = 1 , r do
if entries [ j ][ i ] ~= nil then
if entries [ j ][ i ][ 'ctype' ] == 'team' then
local legs = rlegs [ j ]
if forceseeds then
entries [ j ][ i ][ 'seed' ] = bargs ( masterindex ) or ''
masterindex = masterindex + 1
end
entries [ j ][ i ][ 'team' ] = bargs ( tostring ( masterindex )) or ''
masterindex = masterindex + 1
entries [ j ][ i ][ 'legs' ] = paramNames ( 'legs' , j , i )
entries [ j ][ i ][ 'score' ] = {}
entries [ j ][ i ][ 'weight' ] = 'normal'
entries [ j ][ i ][ 'score' ][ 'weight' ] = {}
if notempty ( entries [ j ][ i ][ 'legs' ]) then
legs = tonumber ( entries [ j ][ i ][ 'legs' ])
end
for l = 1 , legs do
entries [ j ][ i ][ 'score' ][ l ] = bargs ( tostring ( masterindex )) or ''
masterindex = masterindex + 1
entries [ j ][ i ][ 'score' ][ 'weight' ][ l ] = 'normal'
end
if aggregate and legs > 1 then
entries [ j ][ i ][ 'score' ][ 'agg' ] = bargs ( masterindex ) or ''
masterindex = masterindex + 1
entries [ j ][ i ][ 'score' ][ 'weight' ][ 'agg' ] = 'normal'
end
end
if entries [ j ][ i ][ 'ctype' ] == 'header' then
entries [ j ][ i ][ 'header' ] = paramNames ( 'header' , j , i )
entries [ j ][ i ][ 'pheader' ] = paramNames ( 'pheader' , j , i )
entries [ j ][ i ][ 'shade' ] = paramNames ( 'shade' , j , i )
end
if entries [ j ][ i ][ 'ctype' ] == 'text' then
entries [ j ][ i ][ 'text' ] = bargs ( tostring ( masterindex )) or ''
masterindex = masterindex + 1
end
if entries [ j ][ i ][ 'ctype' ] == 'group' then
entries [ j ][ i ][ 'group' ] = bargs ( tostring ( masterindex )) or ''
masterindex = masterindex + 1
end
if entries [ j ][ i ][ 'ctype' ] == 'line' and entries [ j ][ i ][ 'hastext' ] == true then
entries [ j ][ i ][ 'text' ] = bargs ( masterindex ) or ''
masterindex = masterindex + 1
end
end
end
end
local function assignParams ()
masterindex = 1
local maxcol = 1
local byerows = 1
local hiderows = 1
for j = minc , c do
rlegs [ j ] = tonumber ( bargs ( 'RD' .. j .. '-legs' )) or tonumber ( bargs ( 'legs' )) or 1
if notempty ( bargs ( 'RD' .. j .. '-legs' )) or bargs ( 'legs' ) then autolegs = false end
if paramstyle == 'numbered' then
indexedParams ( j )
else
for i = 1 , r do
if entries [ j ][ i ] ~= nil then
if entries [ j ][ i ][ 'ctype' ] == 'team' then
local legs = rlegs [ j ]
entries [ j ][ i ][ 'seed' ] = paramNames ( 'seed' , j , i )
entries [ j ][ i ][ 'team' ] = paramNames ( 'team' , j , i )
entries [ j ][ i ][ 'legs' ] = paramNames ( 'legs' , j , i )
entries [ j ][ i ][ 'score' ] = {}
entries [ j ][ i ][ 'weight' ] = 'normal'
entries [ j ][ i ][ 'score' ][ 'weight' ] = {}
if notempty ( entries [ j ][ i ][ 'legs' ]) then
legs = tonumber ( entries [ j ][ i ][ 'legs' ])
end
if autolegs then
local l = 1
repeat
entries [ j ][ i ][ 'score' ][ l ] = paramNames ( 'score' , j , i , l )
entries [ j ][ i ][ 'score' ][ 'weight' ][ l ] = 'normal'
l = l + 1
until isempty ( paramNames ( 'score' , j , i , l ))
legs = l - 1
else
for l = 1 , legs do
entries [ j ][ i ][ 'score' ][ l ] = paramNames ( 'score' , j , i , l )
entries [ j ][ i ][ 'score' ][ 'weight' ][ l ] = 'normal'
end
end
if aggregate and legs > 1 then
entries [ j ][ i ][ 'score' ][ 'agg' ] = paramNames ( 'score' , j , i , 'agg' )
entries [ j ][ i ][ 'score' ][ 'weight' ][ 'agg' ] = 'normal'
end
end
if entries [ j ][ i ][ 'ctype' ] == 'header' then
entries [ j ][ i ][ 'header' ] = paramNames ( 'header' , j , i )
entries [ j ][ i ][ 'pheader' ] = paramNames ( 'pheader' , j , i )
entries [ j ][ i ][ 'shade' ] = paramNames ( 'shade' , j , i )
end
if entries [ j ][ i ][ 'ctype' ] == 'text' then
entries [ j ][ i ][ 'text' ] = paramNames ( 'text' , j , i )
end
if entries [ j ][ i ][ 'ctype' ] == 'group' then
entries [ j ][ i ][ 'group' ] = paramNames ( 'group' , j , i )
end
if entries [ j ][ i ][ 'ctype' ] == 'line' and entries [ j ][ i ][ 'hastext' ] == true then
entries [ j ][ i ][ 'text' ] = paramNames ( 'text' , j , i )
end
end
if autocol and not isBlankEntry ( j , i ) then
maxcol = math.max ( maxcol , j )
end
end
end
for i = 1 , r do
if entries [ j ][ i ] ~= nil and entries [ j ][ i ][ 'ctype' ] == 'header' then
isRoundHidden ( j , i )
end
if entries [ j ][ i ] ~= nil and not hide [ j ][ entries [ j ][ i ][ 'headerindex' ]] then
if not byes [ j ][ entries [ j ][ i ][ 'headerindex' ]] or ( byes [ j ][ entries [ j ][ i ][ 'headerindex' ]] and not isBlankEntry ( j , i )) then
byerows = math.max ( byerows , i )
end
end
end
end
for j = minc , c do
for k = 1 , headerindex [ j ] do
if byes [ j ][ k ] or hide [ j ][ k ] then
r = byerows + 1
end
end
end
if autocol then
c = maxcol
end
end
local function getHide ( j , headerindex )
hide [ j ] = {}
for k = 1 , headerindex [ j ] do
if bargs ( 'RD' .. j .. toChar ( k ) .. '-hide' ) == 'yes' or bargs ( 'RD' .. j .. toChar ( k ) .. '-hide' ) == 'y' then
hide [ j ][ k ] = true
end
end
end
local function getByes ( j , headerindex )
byes [ j ] = {}
for k = 1 , headerindex [ j ] do
if bargs ( 'byes' ) == 'yes' or bargs ( 'byes' ) == 'y' then
byes [ j ][ k ] = true
elseif tonumber ( bargs ( 'byes' )) then
if j <= tonumber ( bargs ( 'byes' )) then
byes [ j ][ k ] = true
end
else
byes [ j ][ k ] = false
end
if bargs ( 'RD' .. j .. '-byes' ) == 'yes' or bargs ( 'RD' .. j .. '-byes' ) == 'y' then
byes [ j ][ k ] = true
elseif bargs ( 'RD' .. j .. '-byes' ) == 'no' or bargs ( 'RD' .. j .. '-byes' ) == 'n' then
byes [ j ][ k ] = false
end
if bargs ( 'RD' .. j .. toChar ( k ) .. '-byes' ) == 'yes' or bargs ( 'RD' .. j .. toChar ( k ) .. '-byes' ) == 'y' then
byes [ j ][ k ] = true
elseif bargs ( 'RD' .. j .. '-byes' ) == 'no' or bargs ( 'RD' .. j .. '-byes' ) == 'n' then
byes [ j ][ k ] = false
end
end
end
local function getAltIndices ()
local teamindex = 1
local textindex = 1
local groupindex = 1
for j = minc , c do
headerindex [ j ] = 0
for i = 1 , r do
if entries [ j ][ i ] == nil and i == 1 then
headerindex [ j ] = headerindex [ j ] + 1
end
if entries [ j ][ i ] ~= nil then
if entries [ j ][ i ][ 'ctype' ] == 'header' then
entries [ j ][ i ][ 'altindex' ] = headerindex [ j ]
teamindex = 1
textindex = 1
headerindex [ j ] = headerindex [ j ] + 1
elseif entries [ j ][ i ][ 'ctype' ] == 'team' then
entries [ j ][ i ][ 'altindex' ] = teamindex
teamindex = teamindex + 1
elseif entries [ j ][ i ][ 'ctype' ] == 'text' then
entries [ j ][ i ][ 'altindex' ] = textindex
textindex = textindex + 1
elseif entries [ j ][ i ][ 'ctype' ] == 'group' then
entries [ j ][ i ][ 'altindex' ] = groupindex
groupindex = groupindex + 1
elseif entries [ j ][ i ][ 'ctype' ] == 'line' and entries [ j ][ i ][ 'hastext' ] == true then
entries [ j ][ i ][ 'altindex' ] = textindex
textindex = textindex + 1
end
entries [ j ][ i ][ 'headerindex' ] = headerindex [ j ]
end
end
getByes ( j , headerindex )
getHide ( j , headerindex )
end
end
local function noPaths ( j , i )
local result = true
local cols = 2
if hascross [ j ] == true then
cols = 3
end
for k = 1 , cols do
for n = 1 , 4 do
if pathCell [ j ][ i ][ k ][ n ] ~= 0 then
result = false
return result
end
end
end
if hascross [ j ] == true and ( crossCell [ j ][ i ][ 'left' ][ 1 ] == 1 or crossCell [ j ][ i ][ 'right' ][ 1 ] == 1 ) then
result = false
return result
end
return result
end
local function generatePathCell ( tbl , j , i , k , color , bg , rowspan )
if not hascross [ j ] and k == 2 then
return
end
local cell = tbl : tag ( 'td' )
local a = pathCell [ j ][ i ]
if rowspan ~= 1 then
cell : attr ( 'rowspan' , rowspan )
end
if notempty ( bg ) and k == 2 then
cell : css ( 'background' , bg )
: css ( 'transform' , 'translate(-1px)' )
end
if a [ k ][ 1 ] ~= 0 or a [ k ][ 2 ] ~= 0 or a [ k ][ 3 ] ~= 0 or a [ k ][ 4 ] ~= 0 then
cell : css ( 'border' , 'solid ' .. color )
: css ( 'border-width' , 2 * a [ k ][ 1 ] .. 'px ' .. 2 * a [ k ][ 2 ] .. 'px ' .. 2 * a [ k ][ 3 ] .. 'px ' .. 2 * a [ k ][ 4 ] .. 'px' )
end
return cell
end
local function insertPath ( tbl , j , i )
if skipPath [ j ][ i ] then
return
end
local colspan = 2
local rowspan = 1
local angle = 58.2
local pathcolor = pathCell [ j ][ i ][ 'color' ] or 'black'
local bg = ''
local cross = { '' , '' }
if i < r then
local function repeatedPath ( a )
if a > r - 1 or skipPath [ j ][ a ] then
return false
end
for k = 1 , 3 do
for n = 1 , 4 do
if pathCell [ j ][ i ][ k ][ n ] ~= pathCell [ j ][ a ][ k ][ n ] then
return false
end
end
end
return true
end
if repeatedPath ( i ) then
local row = i
repeat
if row ~= i and repeatedPath ( row ) then
skipPath [ j ][ row ] = true
end
rowspan = rowspan + 1
row = row + 1
until row > r or not repeatedPath ( row )
rowspan = rowspan - 1
end
end
if i > 1 and ( crossCell [ j ][ i - 1 ][ 'left' ][ 1 ] == 1 or crossCell [ j ][ i - 1 ][ 'right' ][ 1 ] == 1 ) then
return
end
if hascross [ j ] then
colspan = 3
if crossCell [ j ][ i ][ 'left' ][ 1 ] == 1 or crossCell [ j ][ i ][ 'right' ][ 1 ] == 1 then
rowspan = 2
if crossCell [ j ][ i ][ 'left' ][ 1 ] == 1 then
cross [ 1 ] = 'linear-gradient(to top right, transparent calc(50% - 1px),' .. crossCell [ j ][ i ][ 'left' ][ 2 ] .. ' calc(50% - 1px),' .. crossCell [ j ][ i ][ 'left' ][ 2 ] .. ' calc(50% + 1px), transparent calc(50% + 1px))'
end
if crossCell [ j ][ i ][ 'right' ][ 1 ] == 1 then
cross [ 2 ] = 'linear-gradient(to bottom right, transparent calc(50% - 1px),' .. crossCell [ j ][ i ][ 'right' ][ 2 ] .. ' calc(50% - 1px),' .. crossCell [ j ][ i ][ 'right' ][ 2 ] .. ' calc(50% + 1px), transparent calc(50% + 1px))'
end
end
if notempty ( cross [ 1 ]) and notempty ( cross [ 2 ]) then
cross [ 1 ] = cross [ 1 ] .. ','
end
bg = cross [ 1 ] .. cross [ 2 ]
end
for k = 1 , 3 do
generatePathCell ( tbl , j , i , k , pathcolor , bg , rowspan )
end
end
local function parsePaths ( j )
local result = {}
local str = fargs [ 'col' .. j .. '-col' .. ( j + 1 ) .. '-paths' ] or ''
for val in str : gsub ( "%s+" , "" )
: gsub ( "," , ", " )
: gsub ( "%S+" , " \0 %0 \0 " )
: gsub ( "%b()" , function ( s ) return s : gsub ( "%z" , "" ) end )
: gmatch ( "%z(.-)%z" ) do
local array = split ( val : gsub ( "%s+" , "" ): gsub ( "%)" , "" ): gsub ( "%(" , "" ),{ "-" })
for k , _ in pairs ( array ) do
array [ k ] = split ( array [ k ],{ "," })
end
if notempty ( array [ 2 ]) then
for m = 1 , # array [ 2 ] do
array [ 3 ] = {}
array [ 2 ][ m ] = split ( array [ 2 ][ m ],{ ":" })
array [ 3 ][ m ] = array [ 2 ][ m ][ 2 ]
array [ 2 ][ m ] = array [ 2 ][ m ][ 1 ]
end
for n = 1 , # array [ 1 ] do
for m = 1 , # array [ 2 ] do
table.insert ( result ,{ tonumber ( array [ 1 ][ n ]), tonumber ( array [ 2 ][ m ]),[ 'color' ] = array [ 3 ][ m ]})
end
end
end
end
return result
end
local function isPathHidden ( j , i , start , stop )
local result = false
if notempty ( entries [ j ][ start - 1 ]) and ( byes [ j ][ entries [ j ][ start - 1 ][ 'headerindex' ]] and isBlankEntry ( j , start - 1 ) and isBlankEntry ( j , start + 1 ) or hide [ j ][ entries [ j ][ start - 1 ][ 'headerindex' ]]) then
if bargs ( 'show-bye-paths' ) ~= 'y' and bargs ( 'show-bye-paths' ) ~= 'yes' then
result = true
end
end
if notempty ( entries [ j + 1 ][ stop - 1 ]) and ( byes [ j + 1 ][ entries [ j + 1 ][ stop - 1 ][ 'headerindex' ]] and isBlankEntry ( j + 1 , stop - 1 ) and isBlankEntry ( j + 1 , stop + 1 ) or hide [ j + 1 ][ entries [ j + 1 ][ stop - 1 ][ 'headerindex' ]]) then
if bargs ( 'show-bye-paths' ) ~= 'y' and bargs ( 'show-bye-paths' ) ~= 'yes' then
result = true
end
end
if bargs ( 'RD' .. j .. '-RD' .. ( j + 1 ) .. '-path' ) == 'n' or bargs ( 'RD' .. j .. '-RD' .. ( j + 1 ) .. '-path' ) == 'no' or bargs ( 'RD' .. j .. '-RD' .. ( j + 1 ) .. '-path' ) == '0' then
if notempty ( entries [ j ][ start - 1 ]) and entries [ j ][ start - 1 ][ 'headerindex' ] == 1 then
result = true
end
end
return result
end
local function getPaths ()
local paths = {}
for j = minc , c - 1 do
hascross [ j ] = false
if notempty ( fargs [ 'col' .. j .. '-col' .. ( j + 1 ) .. '-cross' ]) then
hascross [ j ] = true
end
end
for j = minc , c - 1 do
local straightpaths = {}
local outpaths = {}
local inpaths = {}
paths [ j ] = parsePaths ( j )
pathCell [ j ] = {}
crossCell [ j ] = {}
skipPath [ j ] = {}
for i = 1 , r do
pathCell [ j ][ i ] = {}
crossCell [ j ][ i ] = {[ 'left' ] = { 0 , 'black' },[ 'right' ] = { 0 , 'black' }}
for k = 1 , 3 do
pathCell [ j ][ i ][ k ] = { 0 , 0 , 0 , 0 }
end
skipPath [ j ][ i ] = false
end
local crossloc = split (( fargs [ 'col' .. j .. '-col' .. ( j + 1 ) .. '-cross' ] or '' ): gsub ( "%s+" , "" ),{ "," }, true )
if shift [ j ] ~= 0 and notempty ( crossloc [ 1 ]) then
for n = 1 , # crossloc do
crossloc [ n ] = crossloc [ n ] + shift [ j ]
end
end
for k , v in ipairs ( paths [ j ]) do
local start = 2 * ( paths [ j ][ k ][ 1 ] + shift [ j ]) + ( teams_per_match [ j ] - 2 )
local stop = 2 * ( paths [ j ][ k ][ 2 ] + shift [ j + 1 ]) + ( teams_per_match [ j + 1 ] - 2 )
local mid = {}
local cross = 0
if notempty ( crossloc [ 1 ]) then
for n = 1 , # crossloc do
mid [ n ] = 2 * crossloc [ n ] + ( teams_per_match [ j ] - 2 )
end
else
mid [ 1 ] = 0
end
for n = 1 , # mid do
if ( start < stop and mid [ n ] < stop and mid [ n ] > start ) or ( start > stop and mid [ n ] > stop and mid [ n ] < start ) then
cross = mid [ n ]
end
end
paths [ j ][ k ][ 'color' ] = paths [ j ][ k ][ 'color' ] or 'black'
table.insert ( outpaths ,{ start , paths [ j ][ k ][ 'color' ]})
table.insert ( inpaths ,{ stop , paths [ j ][ k ][ 'color' ]})
if not isPathHidden ( j , i , start , stop ) then
if start == stop then
table.insert ( straightpaths ,{ start , paths [ j ][ k ][ 'color' ]})
elseif start < stop then
if stop > r then break end
for i = start + 1 , stop do
pathCell [ j ][ i ][ 'color' ] = paths [ j ][ k ][ 'color' ]
end
pathCell [ j ][ start + 1 ][ 1 ][ 1 ] = 1
if cross == 0 then
if hascross [ j ] then
pathCell [ j ][ start + 1 ][ 2 ][ 1 ] = 1
for i = start + 1 , stop do
pathCell [ j ][ i ][ 2 ][ 2 ] = 1
end
else
for i = start + 1 , stop do
pathCell [ j ][ i ][ 1 ][ 2 ] = 1
end
end
else
crossCell [ j ][ cross ][ 'left' ] = { 1 , paths [ j ][ k ][ 'color' ]}
for i = start + 1 , cross - 1 do pathCell [ j ][ i ][ 1 ][ 2 ] = 1 end
for i = cross + 2 , stop do pathCell [ j ][ i ][ 2 ][ 2 ] = 1 end
end
pathCell [ j ][ stop ][ 3 ][ 3 ] = 1
elseif start > stop then
if start > r then break end
for i = stop + 1 , start do
pathCell [ j ][ i ][ 'color' ] = paths [ j ][ k ][ 'color' ]
end
pathCell [ j ][ stop + 1 ][ 3 ][ 1 ] = 1
if cross == 0 then
if hascross [ j ] then
for i = stop + 1 , start do
pathCell [ j ][ i ][ 2 ][ 2 ] = 1
end
pathCell [ j ][ start ][ 2 ][ 3 ] = 1
else
for i = stop + 1 , start do
pathCell [ j ][ i ][ 1 ][ 2 ] = 1
end
end
else
crossCell [ j ][ cross ][ 'right' ] = { 1 , paths [ j ][ k ][ 'color' ]}
for i = stop + 1 , cross - 1 do pathCell [ j ][ i ][ 2 ][ 2 ] = 1 end
for i = cross + 2 , start do pathCell [ j ][ i ][ 1 ][ 2 ] = 1 end
end
pathCell [ j ][ start ][ 1 ][ 3 ] = 1
end
end
end
-- Thicken start==stop paths
for n = 1 , # straightpaths do
local i = straightpaths [ n ][ 1 ]
local color = straightpaths [ n ][ 2 ]
if i > r then break end
if pathCell [ j ][ i ][ 1 ][ 3 ] == 0 then
pathCell [ j ][ i ][ 'color' ] = color
pathCell [ j ][ i ][ 1 ][ 3 ] = 1
pathCell [ j ][ i ][ 2 ][ 3 ] = 1
pathCell [ j ][ i ][ 3 ][ 3 ] = 1
if pathCell [ j ][ i + 1 ][ 1 ][ 1 ] == 0 then
pathCell [ j ][ i + 1 ][ 'color' ] = color
pathCell [ j ][ i + 1 ][ 1 ][ 1 ] = 0.5
pathCell [ j ][ i + 1 ][ 2 ][ 1 ] = 0.5
pathCell [ j ][ i + 1 ][ 3 ][ 1 ] = 0.5
end
elseif pathCell [ j ][ i + 1 ][ 1 ][ 1 ] == 0 then
pathCell [ j ][ i + 1 ][ 'color' ] = color
pathCell [ j ][ i + 1 ][ 1 ][ 1 ] = 1
if hascross [ j ] then
pathCell [ j ][ i + 1 ][ 2 ][ 1 ] = 1
end
pathCell [ j ][ i + 1 ][ 3 ][ 1 ] = 1
end
end
-- Thicken/Thin out paths
for n = 1 , # outpaths do
local i = outpaths [ n ][ 1 ]
local color = outpaths [ n ][ 2 ]
if i < r and pathCell [ j ][ i ][ 1 ][ 3 ] == 1 and pathCell [ j ][ i + 1 ][ 1 ][ 1 ] == 0 then
pathCell [ j ][ i + 1 ][ 'color' ] = color
pathCell [ j ][ i + 1 ][ 1 ][ 1 ] = 0.5 * pathCell [ j ][ i ][ 1 ][ 3 ]
pathCell [ j ][ i + 1 ][ 2 ][ 1 ] = 0.5 * pathCell [ j ][ i ][ 2 ][ 3 ]
elseif i < r and pathCell [ j ][ i ][ 1 ][ 3 ] == 0 and pathCell [ j ][ i + 1 ][ 1 ][ 1 ] == 1 then
pathCell [ j ][ i ][ 'color' ] = color
pathCell [ j ][ i ][ 1 ][ 3 ] = pathCell [ j ][ i + 1 ][ 1 ][ 1 ]
pathCell [ j ][ i ][ 2 ][ 3 ] = pathCell [ j ][ i + 1 ][ 2 ][ 1 ]
pathCell [ j ][ i + 1 ][ 1 ][ 1 ] = 0.5 * pathCell [ j ][ i ][ 1 ][ 3 ]
pathCell [ j ][ i + 1 ][ 2 ][ 1 ] = 0.5 * pathCell [ j ][ i ][ 2 ][ 3 ]
end
end
-- Thin double-in paths
for n = 1 , # inpaths do
local i = inpaths [ n ][ 1 ]
local color = inpaths [ n ][ 2 ]
if i < r and pathCell [ j ][ i ][ 3 ][ 3 ] == 1 and pathCell [ j ][ i + 1 ][ 3 ][ 1 ] == 1 and pathCell [ j ][ i ][ 'color' ] == pathCell [ j ][ i + 1 ][ 'color' ] then
pathCell [ j ][ i + 1 ][ 3 ][ 1 ] = 0.5 * pathCell [ j ][ i ][ 3 ][ 3 ]
end
end
end
for j = minc , c - 1 do
for i = 1 , r - 1 do
local straightpath = false
if ( entries [ j + 1 ][ i - 1 ] == nil or ( byes [ j + 1 ][ entries [ j + 1 ][ i - 1 ][ 'headerindex' ]]) and isBlankEntry ( j + 1 , i - 1 )) then
if ( pathCell [ j ][ i ][ 3 ][ 3 ] ~= 0 and pathCell [ j + 1 ][ i ][ 1 ][ 3 ] ~= 0 ) or ( pathCell [ j ][ i + 1 ][ 3 ][ 1 ] ~= 0 and pathCell [ j + 1 ][ i + 1 ][ 1 ][ 1 ] ~= 0 ) then
if pathCell [ j + 1 ][ i ][ 1 ][ 3 ] == pathCell [ j + 1 ][ i ][ 3 ][ 3 ] and pathCell [ j + 1 ][ i + 1 ][ 1 ][ 1 ] == pathCell [ j + 1 ][ i + 1 ][ 3 ][ 1 ] then
straightpath = true
end
pathCell [ j + 1 ][ i ][ 1 ][ 3 ] = pathCell [ j ][ i ][ 3 ][ 3 ]
pathCell [ j + 1 ][ i + 1 ][ 1 ][ 1 ] = pathCell [ j ][ i + 1 ][ 3 ][ 1 ]
pathCell [ j + 1 ][ i ][ 2 ][ 3 ] = pathCell [ j ][ i ][ 3 ][ 3 ]
pathCell [ j + 1 ][ i + 1 ][ 2 ][ 1 ] = pathCell [ j ][ i + 1 ][ 3 ][ 1 ]
entries [ j + 1 ][ i - 1 ] = {[ 'ctype' ] = 'line' }
entries [ j + 1 ][ i ] = {[ 'ctype' ] = 'blank' }
if notempty ( entries [ j + 1 ][ i + 1 ]) then
entries [ j + 1 ][ i + 1 ][ 'ctype' ] = 'line2'
else
entries [ j + 1 ][ i + 1 ] = {[ 'ctype' ] = 'line2' }
end
entries [ j + 1 ][ i + 2 ] = {[ 'ctype' ] = 'blank' }
if straightpath then
pathCell [ j + 1 ][ i ][ 3 ][ 3 ] = pathCell [ j + 1 ][ i ][ 1 ][ 3 ]
pathCell [ j + 1 ][ i + 1 ][ 3 ][ 1 ] = pathCell [ j + 1 ][ i + 1 ][ 1 ][ 1 ]
end
end
end
end
end
end
local function getGroups ()
local function check ( j , i )
local result = false
if entries [ j ][ i ] == nil then
if entries [ j ][ i + 1 ] == nil then
result = true
elseif entries [ j ][ i + 1 ][ 'ctype' ] == 'text' and isBlankEntry ( j , i + 1 ) then
result = true
end
elseif entries [ j ][ i ][ 'ctype' ] == 'text' and isBlankEntry ( j , i ) then
result = true
end
return result
end
for j = minc , c - 1 do
if teams_per_match [ j ] == 2 then
local n = 0
for i = 1 , r - 1 do
if pathCell [ j ][ i ][ 3 ][ 3 ] == 1 or pathCell [ j ][ i + 1 ][ 3 ][ 1 ] == 1 then
n = n + 1
if check ( j , i ) then
local k = minc - 1
repeat
if entries [ j - k ][ i + 1 ] ~= nil and entries [ j - k ][ i + 1 ][ 'ctype' ] == 'text' and isBlankEntry ( j - k , i + 1 ) then
entries [ j - k ][ i + 2 ] = nil
end
entries [ j - k ][ i ] = {[ 'ctype' ] = 'blank' }
entries [ j - k ][ i + 1 ] = {[ 'ctype' ] = 'blank' }
if k > 0 and noPaths ( j - k , i ) then
skipPath [ j - k ][ i ] = true
skipPath [ j - k ][ i + 1 ] = true
end
k = k + 1
until k > j - 1 or not check ( j - k , i ) or not noPaths ( j - k , i )
k = k - 1
entries [ j - k ][ i ] = {[ 'ctype' ] = 'group' ,[ 'index' ] = n ,[ 'colspan' ] = k + 1 }
entries [ j - k ][ i + 1 ] = {[ 'ctype' ] = 'blank' }
entries [ j - k ][ i ][ 'group' ] = bargs ( 'RD' .. j .. '-group' .. n )
end
end
end
end
end
end
local function getCells ()
local maxrow = 1
local colentry = {}
local bool = true
for j = minc , c do
if notempty ( fargs [ 'col' .. j .. '-headers' ]) then bool = false end
teams_per_match [ j ] = tonumber ( fargs [ 'RD' .. j .. '-teams-per-match' ]) or tonumber ( fargs [ 'col' .. j .. '-teams-per-match' ]) or tonumber ( fargs [ 'teams-per-match' ]) or 2
maxtpm = math.max ( maxtpm , teams_per_match [ j ])
end
for j = minc , c do
entries [ j ] = {}
shift [ j ] = tonumber ( bargs ( 'RD' .. j .. '-shift' )) or tonumber ( bargs ( 'shift' )) or 0
colentry [ j ] = {
split (( fargs [ 'col' .. j .. '-headers' ] or '' ): gsub ( "%s+" , "" ),{ "," }, true ),
split (( fargs [ 'col' .. j .. '-matches' ] or '' ): gsub ( "%s+" , "" ),{ "," }, true ),
split (( fargs [ 'col' .. j .. '-lines' ] or '' ): gsub ( "%s+" , "" ),{ "," }, true ),
split (( fargs [ 'col' .. j .. '-text' ] or '' ): gsub ( "%s+" , "" ),{ "," }, true ),
}
if bool == true and fargs [ 'noheaders' ] ~= 'y' and fargs [ 'noheaders' ] ~= 'yes' then
table.insert ( colentry [ j ][ 1 ], 1 )
end
end
for j = minc , c do
local textindex = 0
for k , v in ipairs ( colentry [ j ]) do
table.sort ( colentry [ j ][ k ])
local ctype
if k == 1 then ctype = 'header'
elseif k == 2 then ctype = 'team'
elseif k == 3 then ctype = 'line'
elseif k == 4 then ctype = 'text'
elseif k == 5 then ctype = 'group'
end
for n = 1 , # colentry [ j ][ k ] do
if shift [ j ] ~= 0 and colentry [ j ][ k ][ n ] > 1 then
colentry [ j ][ k ][ n ] = colentry [ j ][ k ][ n ] + shift [ j ]
end
local i = 2 * colentry [ j ][ k ][ n ] - 1
maxrow = math.max ( i + 2 * teams_per_match [ j ] - 1 , maxrow )
if ctype == 'team' then
if entries [ j ][ i - 1 ] == nil and entries [ j ][ i - 2 ] == nil then
entries [ j ][ i - 2 ] = {[ 'ctype' ] = 'text' ,[ 'index' ] = n }
entries [ j ][ i - 1 ] = {[ 'ctype' ] = 'blank' }
textindex = n
end
entries [ j ][ i ] = {[ 'ctype' ] = ctype ,[ 'index' ] = teams_per_match [ j ] * n - ( teams_per_match [ j ] - 1 ),[ 'position' ] = 'top' }
entries [ j ][ i + 1 ] = {[ 'ctype' ] = 'blank' }
for m = 2 , teams_per_match [ j ] do
entries [ j ][ i + 2 * ( m - 1 )] = {[ 'ctype' ] = ctype ,[ 'index' ] = teams_per_match [ j ] * n - ( teams_per_match [ j ] - m )}
entries [ j ][ i + 2 * ( m - 1 ) + 1 ] = {[ 'ctype' ] = 'blank' }
end
elseif ctype == 'text' then
entries [ j ][ i ] = {[ 'ctype' ] = ctype ,[ 'index' ] = textindex + n }
entries [ j ][ i + 1 ] = {[ 'ctype' ] = 'blank' }
elseif ctype == 'line' then
entries [ j ][ i ] = {[ 'ctype' ] = ctype }
entries [ j ][ i + 1 ] = {[ 'ctype' ] = 'blank' }
entries [ j ][ i + 2 ] = {[ 'ctype' ] = 'line2' }
entries [ j ][ i + 3 ] = {[ 'ctype' ] = 'blank' }
elseif ctype == 'group' then
entries [ j ][ i ] = {[ 'ctype' ] = ctype ,[ 'index' ] = n }
entries [ j ][ i + 1 ] = {[ 'ctype' ] = 'blank' }
else
entries [ j ][ i ] = {[ 'ctype' ] = ctype ,[ 'index' ] = n ,[ 'position' ] = 'top' }
entries [ j ][ i + 1 ] = {[ 'ctype' ] = 'blank' }
end
end
end
end
if isempty ( r ) then
r = maxrow
end
end
function p . main ( frame )
fargs = frame . args
pargs = frame : getParent (). args ;
r = tonumber ( fargs . rows ) or ''
c = tonumber ( fargs . rounds ) or 1
maxc = tonumber ( pargs . maxrounds ) or tonumber ( pargs . maxround ) or ''
minc = tonumber ( pargs . minround ) or 1
headerindex = {}
if notempty ( maxc ) then c = maxc end
if fargs . autocol == 'yes' or fargs . autocol == 'y' then autocol = true end
local colspacing = tonumber ( fargs [ 'col-spacing' ]) or 5
local height = bargs ( 'height' ) or 0
maxtpm = 1
seeds = true
nowrap = true
forceseeds = false
boldwinner = bargs ( 'boldwinner' ) or ''
if bargs ( 'seeds' ) == 'y' or bargs ( 'seeds' ) == 'yes' then forceseeds = true end
if bargs ( 'seeds' ) == 'n' or bargs ( 'seeds' ) == 'no' then seeds = false end
if bargs ( 'aggregate' ) == 'y' or bargs ( 'aggregate' ) == 'yes' then aggregate = true end
if bargs ( 'autolegs' ) == 'y' or bargs ( 'autolegs' ) == 'yes' then autolegs = true end
if bargs ( 'paramstyle' ) == 'numbered' then
paramstyle = 'numbered'
else
paramstyle = 'indexed'
end
if pargs . nowrap == 'n' or pargs . nowrap == 'no' then nowrap = false end
getCells ()
getAltIndices ()
assignParams ()
matchGroups ()
if ( boldwinner == 'yes' or boldwinner == 'y' or boldwinner == 'high' ) then boldWinner () end
getPaths ()
if minc == 1 then
getGroups ()
end
for j = minc , c do
maxlegs [ j ] = rlegs [ j ]
for i = 1 , r do
if notempty ( entries [ j ][ i ]) then
if notempty ( entries [ j ][ i ][ 'legs' ]) then
maxlegs [ j ] = math.max ( rlegs [ j ], entries [ j ][ i ][ 'legs' ])
end
if autolegs then
local l = 1
repeat l = l + 1
until isempty ( entries [ j ][ i ][ 'score' ]) or isempty ( entries [ j ][ i ][ 'score' ][ l ])
maxlegs [ j ] = math.max ( maxlegs [ j ], l - 1 )
end
end
end
end
local div = mw . html . create ( 'div' )
: css ( 'overflow' , 'auto' )
if height ~= 0 then
div : css ( 'height' , height )
end
local tbl = mw . html . create ( 'table' )
: attr ( 'cellpadding' , '0' )
: attr ( 'cellspacing' , '0' )
: css ( 'font-size' , '90%' )
: css ( 'border-collapse' , 'separate' )
: css ( 'margin' , '1em 2em 1em 1em' )
if nowrap then
tbl : css ( 'white-space' , 'nowrap' )
end
tbl : tag ( 'tr' ): css ( 'visibility' , 'collapse' )
tbl : tag ( 'td' ): css ( 'width' , '1px' )
for j = minc , c do
if seeds then
tbl : tag ( 'td' ): css ( 'width' , getWidth ( 'seed' , '25px' ))
end
tbl : tag ( 'td' ): css ( 'width' , getWidth ( 'team' , '150px' ))
if maxlegs [ j ] == 0 then
tbl : tag ( 'td' ): css ( 'width' , getWidth ( 'score' , '25px' ))
else
for l = 1 , maxlegs [ j ] do
tbl : tag ( 'td' ): css ( 'width' , getWidth ( 'score' , '25px' ))
end
end
if aggregate and maxlegs [ j ] > 1 then
tbl : tag ( 'td' ): css ( 'width' , getWidth ( 'agg' , getWidth ( 'score' , '25px' )))
end
if j ~= c then
if hascross [ j ] then
tbl : tag ( 'td' ): css ( 'width' , colspacing + 1 - 4 .. 'px' )
: css ( 'padding-left' , '4px' )
tbl : tag ( 'td' ): css ( 'padding-left' , '5px' )
: css ( 'width' , '5px' )
tbl : tag ( 'td' ): css ( 'width' , colspacing - 1 - 2 .. 'px' )
: css ( 'padding-right' , '2px' )
else
tbl : tag ( 'td' ): css ( 'width' , colspacing + 1 - 4 .. 'px' )
: css ( 'padding-left' , '4px' )
tbl : tag ( 'td' ): css ( 'width' , colspacing - 1 - 2 .. 'px' )
: css ( 'padding-right' , '2px' )
end
end
end
for i = 1 , r do
local row = tbl : tag ( 'tr' )
row : tag ( 'td' ): css ( 'height' , '11px' )
for j = minc , c do
insertEntry ( row , j , i )
if j ~= c then
insertPath ( row , j , i )
end
end
end
div : wikitext ( tostring ( tbl ))
return tostring ( div )
end
return p