https://de.wikipedia.org/w/index.php?action=history&feed=atom&title=Modul%3ARoundN
Modul:RoundN - Versionsgeschichte
2025-06-27T04:07:03Z
Versionsgeschichte dieser Seite in Wikipedia
MediaWiki 1.45.0-wmf.7
https://de.wikipedia.org/w/index.php?title=Modul:RoundN&diff=218569770&oldid=prev
Florentyna am 28. Dezember 2021 um 15:04 Uhr
2021-12-28T15:04:26Z
<p></p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="de">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Nächstältere Version</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Version vom 28. Dezember 2021, 17:04 Uhr</td>
</tr><tr>
<td colspan="2" class="diff-lineno">Zeile 1:</td>
<td colspan="2" class="diff-lineno">Zeile 1:</td>
</tr>
<tr>
<td class="diff-marker"></td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>local p = {</div></td>
<td class="diff-marker"></td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>local p = {</div></td>
</tr>
<tr>
<td class="diff-marker"></td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> RD = {</div></td>
<td class="diff-marker"></td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> RD = {</div></td>
</tr>
<tr>
<td class="diff-marker" data-marker="−"></td>
<td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div> '<del style="font-weight: bold; text-decoration: none;">Quarter-finals</del>',</div></td>
<td class="diff-marker" data-marker="+"></td>
<td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> '<ins style="font-weight: bold; text-decoration: none;">Viertelfinale</ins>',</div></td>
</tr>
<tr>
<td class="diff-marker" data-marker="−"></td>
<td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div> '<del style="font-weight: bold; text-decoration: none;">Semi-finals</del>',</div></td>
<td class="diff-marker" data-marker="+"></td>
<td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> '<ins style="font-weight: bold; text-decoration: none;">Halbfinale</ins>',</div></td>
</tr>
<tr>
<td class="diff-marker" data-marker="−"></td>
<td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div> '<del style="font-weight: bold; text-decoration: none;">Final</del>',</div></td>
<td class="diff-marker" data-marker="+"></td>
<td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> '<ins style="font-weight: bold; text-decoration: none;">Finale</ins>',</div></td>
</tr>
<tr>
<td class="diff-marker" data-marker="−"></td>
<td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div> '<del style="font-weight: bold; text-decoration: none;">Third</del> <del style="font-weight: bold; text-decoration: none;">place</del>'</div></td>
<td class="diff-marker" data-marker="+"></td>
<td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> '<ins style="font-weight: bold; text-decoration: none;">3.</ins> <ins style="font-weight: bold; text-decoration: none;">Platz</ins>'</div></td>
</tr>
<tr>
<td class="diff-marker"></td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> },</div></td>
<td class="diff-marker"></td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> },</div></td>
</tr>
<tr>
<td class="diff-marker"></td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> bgColor = {head = '#f2f2f2', 'gold', 'silver', '#C96', '#f9f9f9'},</div></td>
<td class="diff-marker"></td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> bgColor = {head = '#f2f2f2', 'gold', 'silver', '#C96', '#f9f9f9'},</div></td>
</tr>
</table>
Florentyna
https://de.wikipedia.org/w/index.php?title=Modul:RoundN&diff=202698638&oldid=prev
Marcus Cyron: AZ: Die Seite wurde neu angelegt: local p = { RD = { 'Quarter-finals', 'Semi-finals', 'Final', 'Third place' }, bgColor = {he…
2020-08-11T20:40:47Z
<p><a href="/wiki/Hilfe:Zusammenfassung_und_Quellen#Auto-Zusammenfassung" title="Hilfe:Zusammenfassung und Quellen">AZ</a>: Die Seite wurde neu angelegt: local p = { RD = { 'Quarter-finals', 'Semi-finals', 'Final', 'Third place' }, bgColor = {he…</p>
<p><b>Neue Seite</b></p><div>local p = {<br />
RD = {<br />
'Quarter-finals',<br />
'Semi-finals',<br />
'Final',<br />
'Third place'<br />
},<br />
bgColor = {head = '#f2f2f2', 'gold', 'silver', '#C96', '#f9f9f9'},<br />
reuseStr = {},<br />
saveStr = function(self, name, ...)<br />
if not self.reuseStr[name] then<br />
self.reuseStr[name] = table.concat{...}<br />
end<br />
return self.reuseStr[name]<br />
end<br />
}<br />
<br />
--Provides a convenient naming shortcut up to {{#invoke:RoundN|N512}} = {{invoke:RoundN|main|columns = 9}}<br />
for columns = 1, 9 do<br />
local N = math.pow(2, columns)<br />
p['N' .. N] = function(frame)<br />
return p.main(frame.args, columns)<br />
end<br />
p['n' .. N] = p['N' .. N]--to make case insensitive<br />
end<br />
<br />
--saves memory and avoids errors when using a nil as a table by providing a temporary table; if using nil as false; use 'table(k)' to look up table[k]<br />
p.nilAsTab = {<br />
__index = function(t, i)<br />
return setmetatable({}, setmetatable(p.nilAsTab, {__index = {t = t, i = i}}))<br />
end,<br />
__newindex = function (pt, pi, v) --store new values in actual table rather than temporary<br />
rawset(p.nilAsTab.t, p.nilAsTab.i, {})[p.nilAsTab.i][pi] = v<br />
setmetatable(p.nilAsTab.t[p.nilAsTab.i], {__call = p.nilAsTab.__call})<br />
end,<br />
__call = function(t, i)<br />
return t and rawget(t, i)<br />
end<br />
}<br />
--never assign a value to these or they will stop being empty<br />
local infiniteEmpty = setmetatable({}, {__index = setmetatable({}, p.nilAsTab), p.nilAsTab}) -- infiniteEmpty[1][2][3]...[infinity] = {}<br />
local callableEmpty = setmetatable({}, p.nilAsTab)<br />
<br />
local rowNum, head, m, col, tab, esc = {}, {}, {num = 1, phase = 0, bold = infiniteEmpty}, {}, mw.html.create'table', {<br />
bs = require'Module:Escape',--backslash<br />
comma = {['(%([^,]*),([^%)]*%))'] = '%1|@!#|%2'},--escape commas in ()<br />
}<br />
local nodeFunc = {<br />
scanPattern = function(self, args, step)<br />
self.pattern = nil<br />
if args[step] then<br />
self.pattern, self.nonFunc = string.match(esc.bs:text(args[step]), '^node_function{(.-)}(.*)')<br />
end<br />
if self.pattern then<br />
for k, v in pairs(esc.comma) do<br />
self.pattern = self.pattern:gsub(k, v)<br />
end<br />
self.nonFunc = self.nonFunc and esc.bs:undo(self.nonFunc)<br />
self.pattern = mw.text.split(self.pattern, '%s*,%s*')<br />
for k, v in ipairs(self.pattern) do<br />
local func, arg = string.match(v, '^(%w+)%(?([^%)]*)')<br />
if func and self[func] and self[func].main then<br />
self.pattern[k] = func<br />
if arg then<br />
for x, y in pairs(esc.comma) do<br />
arg = esc.bs:undo(arg):gsub(y:gsub('%%%d', ''), x:match('%)([^%(])%(') or x:gsub('\\', ''))<br />
end<br />
self[func].arg = self[func].arg or {}<br />
self[func].arg[m.num] = arg<br />
end<br />
end<br />
end<br />
end<br />
return self.pattern<br />
end,<br />
helper = {<br />
topBranch = function()--node is top of fork if top is 0<br />
return (m.num - col.top) % 2<br />
end,<br />
addText = function(text)<br />
if text and text ~= '' then<br />
tab.r:wikitext(text)<br />
end<br />
end<br />
},<br />
line = {--this node is omitted and replaced with a line<br />
main = function(x)<br />
local h = p.getNodeFunc()<br />
if m.available then<br />
local text, topId, isTop, notTop = h.line.arg[m.num] or '', h.topBranch()<br />
isTop = topId == 0<br />
notTop = {[isTop and 1 or 0] = p.reuseStr.solid}<br />
for k = 0, 1 do<br />
tab.r = rowNum[m.r + k * 4]:tag'td'<br />
:css(notTop[k] and<br />
{[isTop and 'border-top' or 'border-bottom'] = notTop[k]}<br />
or {}<br />
)<br />
:attr{<br />
rowspan = ({[0] = 4, 2})[k],<br />
colspan = p.colspan<br />
}<br />
h.addText(text or h.nonFunc)<br />
text = nil<br />
end<br />
m.available = false<br />
else<br />
return nil<br />
end<br />
return x<br />
end<br />
},<br />
bridge = {--Draw a line to the neighboring node in the same column that is not connected to the current node<br />
main = function(x)<br />
local h = p.getNodeFunc()<br />
h.bridge.lay[col.c][m.num - col.top + 1 + (h.topBranch() == 1 and 1 or -1)] = true<br />
h.addText(nonFunc)<br />
return x<br />
end,<br />
lay = setmetatable({}, p.nilAsTab)<br />
},<br />
canvas = {--Merges all cells in node. Content will be the next parameter.<br />
main = function(x)<br />
local h = p.getNodeFunc()<br />
if m.available then<br />
tab.r = rowNum[m.r]:tag'td'<br />
:attr{<br />
rowspan = 6,<br />
colspan = p.colspan<br />
}<br />
h.addText(h.nonFunc)<br />
m.available = false<br />
return x<br />
else<br />
return nil<br />
end<br />
end<br />
},<br />
orphan = {--sets a flag for skipMatch to be set by p._main<br />
main = function(x)<br />
p.getNodeFunc().orphan.num = m.num<br />
return x<br />
end<br />
},<br />
skipAllowed = {--table of supported node functions when node is skipped (i.e. by skipmatch)<br />
bridge = true,<br />
canvas = true<br />
}<br />
}<br />
<br />
setmetatable(nodeFunc.helper, {__index = nodeFunc})<br />
function p.getNodeFunc()<br />
return nodeFunc.helper<br />
end<br />
<br />
local function newRow(bodyRow)<br />
local first = p.flex_tree.merge and mw.clone(p.flex_tree.cell) or p.flex_tree.cell<br />
tab.r = tab:tag'tr'<br />
:node(first)<br />
if bodyRow then<br />
table.insert(rowNum, bodyRow, tab.r)<br />
if p.flex_tree.merge then<br />
rowNum[bodyRow].first = first<br />
rowNum[bodyRow].first.unchanged = true<br />
end<br />
end<br />
end<br />
<br />
local function drawHead(text, row3rd)<br />
local td = (row3rd and rowNum[row3rd]:tag'td':attr{rowspan = 2}<br />
or head.row:tag'td')<br />
:attr{colspan = p.colspan}<br />
if text ~= 'omit_label' then<br />
td:wikitext(text):css{<br />
['text-align'] = 'center',<br />
border = '1px solid #aaa',<br />
background = p.bgColor.head<br />
}<br />
end<br />
end<br />
<br />
local function spacer(width)<br />
tab.r:tag'td'<br />
:attr{width = width}<br />
:wikitext(p.no_column_head and '' or '&nbsp;')<br />
end<br />
<br />
local function dpBox(v, r)<br />
p.dpBoxBase = p.dpBoxBase or mw.html.create'td':attr{rowspan = 2, colspan = p.colspan}<br />
if not v then<br />
p.dpBoxEmpty = p.previewnumbers and mw.clone(p.dpBoxBase) or p.dpBoxEmpty or mw.clone(p.dpBoxBase):wikitext(p.flex_tree.wt)<br />
rowNum[r]:node(p.dpBoxEmpty)<br />
else<br />
rowNum[r]:node(mw.clone(p.dpBoxBase):wikitext(v))<br />
end<br />
end<br />
<br />
p.scoreWasher = {<br />
numberFormat = '%-?%d+%.?%d*',<br />
main = function (self, s)<br />
if s then<br />
for _, cycle in ipairs(self.cycles) do<br />
s = s:gsub(unpack(cycle))<br />
end<br />
if p.scoreSumBox and self.plus then<br />
local t = 0<br />
for _, part in ipairs(mw.text.split(s, self.plus)) do<br />
t = t + (tonumber(part:match('%-?%d+%.?%d*')) or 0)<br />
end<br />
return t<br />
end<br />
return tonumber(s:match(self.numberFormat)) or math.huge<br />
end<br />
return 0<br />
end,<br />
spin = function(self, v)<br />
table.insert(self, v)<br />
return self<br />
end,<br />
load = function (self, cycle)<br />
local wash, rinse = 0, {spin = self.spin}<br />
for v in cycle:gfind('%(([^%(%)]-)%)') do<br />
if v == '_plus_' then<br />
self.plus = v<br />
rinse:spin(v)<br />
cycle = cycle:gsub('%(_plus_%)', '', 1)<br />
else<br />
wash = wash + 1<br />
rinse:spin('%'):spin(wash)<br />
end<br />
end<br />
table.insert(self.cycles, {esc.bs:undo(cycle, '%%'), table.concat(rinse)})<br />
end,<br />
init = function(self, setting)<br />
self.cycles = {original = setting}<br />
for cycle in (setting and esc.bs:text(setting) or '{<.->} {[^%d]*}'):gfind('{(.-)}') do<br />
self:load(cycle)<br />
end<br />
end,<br />
sum = function (clean)<br />
local sum = {0, 0}<br />
for _, box in ipairs(clean) do<br />
for team, score in ipairs(box) do<br />
sum[team] = sum[team] + score<br />
end<br />
end<br />
return unpack(math.max(unpack(sum)) == math.huge and {'&mdash;', '&mdash;'} or sum)<br />
end<br />
}<br />
<br />
local function boldWin(s1, s2)<br />
return setmetatable(<br />
p.bold and s1 ~= s2 and (math[({'min', 'max'})[p.bold]](s1, s2) == s1 and {true} or {[2] = true}) or callableEmpty,<br />
p.nilAsTab<br />
)<br />
end<br />
<br />
local function maxSpan(span, start, rows)<br />
return math.min(span, math.max(0, rows - start + 1))<br />
end<br />
<br />
--in case of templates like RDseed need padding value<br />
p.teamBoxPadding = function()<br />
return '.6ex'<br />
end<br />
p.teamBoxPadTab = {padding = '0 ' .. p.teamBoxPadding()}<br />
p.teamBoxNormal = {border = '1px solid #aaa', background = p.bgColor[4]}<br />
local function teamBox(v, r, f)<br />
if p.flex_tree.merge and not v and f.phase == 2 then<br />
for i = -2, 0 do<br />
if rowNum[r + i].first.unchanged then<br />
rowNum[r + i].first.unchanged = nil<br />
rowNum[r + i].first:node(p.unflex_div)<br />
end<br />
end<br />
tab.r:attr{rowspan = 4}:css{['vertical-align'] = 'center'}<br />
else<br />
if not p.bold then<br />
--backwards compatability (wikitemplates bold each arg individually)<br />
local hasBold, b = tostring(v):gsub("([^']*)'''([^']*)", '%1<b>%2</b>')<br />
if b == 1 then<br />
v = hasBold<br />
end<br />
end<br />
local cell<br />
if f[1] then<br />
cell = f.sumBox and f.sumBox[1] and<br />
{padding = f.sumBox[1]}<br />
or {['border-left'] = f.borderLeft}<br />
cell['text-align'] = v and f[1]<br />
else<br />
cell = p.teamBoxPadTab<br />
end<br />
tab.r = rowNum[r]:tag'td'<br />
:css(p.teamBoxCSS)<br />
:css(cell)<br />
:attr{rowspan = 2}<br />
:node(mw.html.create(f.bold and 'b'):wikitext(v or f[1] and '' or '&nbsp;'))<br />
end<br />
end<br />
<br />
function p._main(args)<br />
function args:clean(key, params)--prevent html comments from breaking named args and reduces repeat concatenation<br />
params = params or {}<br />
local clean = args[key] or params.ifNil<br />
if clean then<br />
params.append = params.append or ''<br />
clean = mw.text.decode(clean):gsub('<!%-.-%->', ''):gsub(params.pattern or '[^%w-;%.]', '') .. params.append<br />
clean = clean ~= params.append and clean or params.ifNil<br />
end<br />
args[key] = params.keepOld and args[key] or clean<br />
return clean<br />
end<br />
p.cols = tonumber(args:clean('columns', {pattern = '%D'}))<br />
p.tCols = (tonumber(args:clean('final_RDs_excluded', {pattern = '%D'})) or 0) + p.cols<br />
local matchPer = {<br />
pattern = '%d*per%d+[%-x]%d+',<br />
vals = '(%d*)per(%d+)([%-x])(%d+)'<br />
}<br />
local skipMatch, unBold = {}, {}--(skip|manualbold)match# to boolean<br />
for k, _ in pairs(args) do<br />
local mType, mNum = string.match(k, '^(%l+)match(%d*)$')<br />
mType, mNum = ({skip = skipMatch, manualbold = unBold})[mType], tonumber(mNum)<br />
if mType then<br />
if mNum then<br />
mType[mNum] = args:clean(k) == 'yes' or args[k] == 'true'<br />
else<br />
for pattern in args:clean(k, {ifNil = ''}):gfind(matchPer.pattern) do<br />
local d1, period, op, d2 = pattern:match(matchPer.vals)<br />
d1 = tonumber(d1) or 1<br />
d2 = op == '-' and d2 or (d1 + period * (d2 - 1))<br />
for y = d1, d2, period do<br />
mType[y] = true<br />
end<br />
end<br />
for _, x in ipairs(mw.text.split(args[k]:gsub(matchPer.pattern, ''):gsub('[;%-%a][;%-%a]+', ';'):match('^;*(.-)[;%-]*$'), ';')) do<br />
x = mw.text.split(x, '-')<br />
for y = tonumber(x[1]) or 1, tonumber(x[2] or x[1]) or 0 do<br />
mType[y] = true<br />
end<br />
end<br />
end<br />
end<br />
end<br />
for _, v in ipairs({--more args to boolean<br />
'widescore',<br />
'template',<br />
'article_include',<br />
'color',<br />
'3rdplace',<br />
'omit_blanks',<br />
'scroll_head_unlock',<br />
'previewnumbers',<br />
'flex_tree',<br />
'no_column_head',<br />
'short_brackets',<br />
'branch_upwards'<br />
}) do<br />
if args[v] and (p[v] == nil or type(p[v]) == 'boolean') then<br />
p[v] = args:clean(v) == 'yes' or args[v] == 'true'<br />
end<br />
end<br />
p.namespace = mw.title.getCurrentTitle().namespace<br />
p.previewnumbers = p.namespace ~= 0 and p.previewnumbers<br />
p.scoreWasher:init(args['score-clean'])<br />
p.scoreWasher.demo = args.demoWash and tonumber(args:clean('demoWash', {pattern = '%D'}), 10)<br />
p.scoreSumBox = args['score-boxes'] and args['score-boxes']:match('%d ?%+ ?sum')<br />
p.bold = ({low = 1, high = 2})[args:clean('bold_winner')] or p.scoreSumBox and 2<br />
local sumBox = p.scoreSumBox and 1 or 0<br />
p.scoreBoxes = (tonumber(args:clean('score-boxes', {pattern = '%D'})) or 1) + sumBox<br />
p.scoreSumBox = p.scoreBoxes > 0 and p.scoreSumBox or nil<br />
local boxStyle = p.scoreBoxes > 1 and<br />
(p.scoreSumBox and<br />
setmetatable(<br />
{{}, [p.scoreBoxes] = {'0 1ex'}},<br />
{__call = function(t, i) if t[i] then return nil end return 0 end}<br />
)<br />
or setmetatable(<br />
{},<br />
{__call = function() return 0 end}<br />
)<br />
)<br />
or setmetatable({}, {__call = function() return nil end})<br />
p.colspan = p.scoreBoxes > 0 and (p.scoreBoxes + 1) or nil<br />
local nodeArgs = {<br />
score = p.scoreBoxes - sumBox,<br />
team = {offset = 1 + p.scoreBoxes - sumBox}<br />
}<br />
nodeArgs.all = 1 + nodeArgs.team.offset * 2<br />
nodeArgs.tableSum = {<br />
__add = function(v, t)<br />
if #t == 3 then<br />
return v + nodeArgs.all<br />
end<br />
local s = v<br />
for i, n in ipairs(t) do<br />
s = s + n<br />
end<br />
return s--[[ + (p.scoreSumBox and #t == 3 and -2 or 0) --merging disabled with score boxes, uncomment if enable]]<br />
end<br />
}<br />
nodeArgs.team[1] = 1--constant to be replaced later by new param<br />
nodeArgs.team[2] = nodeArgs.team[1] + nodeArgs.team.offset<br />
nodeArgs.blank = setmetatable({}, nodeArgs.tableSum)<br />
p.unflex_div = mw.html.create'div'<br />
:css{overflow = 'hidden', height = '1ex'}<br />
:wikitext'&nbsp;'<br />
p.flex_tree = setmetatable({},{__index = {<br />
merge = p.flex_tree and p.scoreBoxes == 0,<br />
wt = p.flex_tree and '' or '&nbsp;',<br />
cell = mw.html.create'td'<br />
:node(not p.flex_tree and p.unflex_div or nil)<br />
}})<br />
if args:clean'scroll_height' then<br />
local fontSize, fontUnit = args.style and args.style:match('font%-size *: *(%d+)([^ ]+)')<br />
if fontSize then<br />
local units = {<br />
em = 1,<br />
ex = 2,<br />
['%'] = 0.01<br />
}<br />
fontSize, fontUnit = {fontSize * fontUnit}<br />
end<br />
end<br />
tab<br />
:cssText(table.concat{args.scroll_height and 'padding' or 'margin', ':', fontSize and (math.ceil(fontSize * 10) / 10) or '.9', 'em 2em 1em 1em;border:0;', fontSize and '' or 'font-size:90%;border-collapse:separate;', args.style})<br />
:attr{cellpadding = 0, cellspacing = 0}<br />
if not p.no_column_head then--headings row<br />
newRow()<br />
head.row = tab.r<br />
:css{['white-space'] = args.scroll_height and 'nowrap'}<br />
newRow()<br />
else<br />
tab.r = tab:tag'tr'<br />
tab.r:tag'td'<br />
end<br />
local sp = {--set column widths<br />
args['team-width'] or 170,<br />
p.widescore and 40 or 30,<br />
p.short_brackets and 6 or 15,<br />
p.short_brackets and 4 or 20<br />
}<br />
local scoreWidth = args:clean('score-width', {pattern = '[^%d;]'}) and mw.text.split(args['score-width'], ';') or {}<br />
scoreWidth[1] = tonumber(scoreWidth[1], 10)<br />
if p.scoreSumBox and #scoreWidth ~= 1 then<br />
local _scoreWidth = {}<br />
for k = 1, p.scoreBoxes - 1 do<br />
_scoreWidth[k] = tonumber(scoreWidth[k], 10) or math.ceil(sp[2] * 0.75)<br />
end<br />
setmetatable(scoreWidth, _scoreWidth)<br />
end<br />
if p.template or p.article_include then<br />
p.template = mw.title.new(args.name)<br />
p.templateFixedName = (p.template.namespace == 0 and not p.article_include and 'Template:' or '') .. p.template.fullText<br />
end<br />
p.template = p.template and mw.title.new(args:clean('name', {pattern = ''}))<br />
local head_br = {<br />
count = 0,<br />
compare = function (self, text)<br />
if text and args.scroll_height then<br />
local _, count = text:gsub('<br[ >/]', '%1')<br />
self.count = math.max(self.count, count)<br />
end<br />
return text<br />
end<br />
}<br />
p.branch_upwards = p.branch_upwards and 0<br />
for k = 1, p.cols do<br />
if k > 1 then<br />
spacer(sp[3])<br />
spacer(sp[4])<br />
if not p.no_column_head then<br />
head.row:tag'td':attr{colspan = 2}<br />
end<br />
end<br />
spacer(sp[1])<br />
for s = 1, p.scoreBoxes do<br />
spacer(#scoreWidth == 1 and scoreWidth[1] or scoreWidth[s] or sp[2])<br />
end<br />
if not p.no_column_head then<br />
head.wt = head_br:compare(args:clean('RD' .. k, {pattern = ''}))<br />
or p.RD[#p.RD + k - p.tCols - 1]<br />
or ('Round of ' .. math.pow(2, p.tCols - k + 1))<br />
drawHead(<br />
k == 1 and p.template and mw.getCurrentFrame():expandTemplate{<br />
title = 'navbar-header',<br />
args = {head.wt, p.templateFixedName}<br />
} or head.wt<br />
)<br />
end<br />
end<br />
sp.row = tab.r<br />
col.tot = math.pow(2, p.tCols - 1)<br />
local step, bump, bumpBase, rows = 1, 0, mw.html.create'td':attr{colspan = p.colspan}, col.tot * 6--Begin body row output<br />
args.line_px = table.concat{args:clean('line_px') or 3, args.line_px ~= '0' and 'px' or nil}<br />
tab.line = {--reduces concats and 'or' statements<br />
{<br />
[true] = args.line_px,<br />
[false] = 0<br />
},<br />
args.line_px:rep(2):gsub('(%a)(%d)', '%1 %2', 1)<br />
}<br />
p['3rdplace'] = p.tCols == p.cols and (p['3rdplace'] or p.cols > 3 and nil == p['3rdplace'] and not p.no_column_head)<br />
if p['3rdplace'] then<br />
p.textThird = args.Consol or args['RD' .. (p.cols + 1)] or p.RD[4]<br />
local no3rdText = p.no_column_head or p.textThird and p.textThird:match('omit_label')<br />
rowNum.third = math.max(math.pow(2, p.branch_upwards and -3 or p.cols - 2) * 9 + (no3rdText and 4 or 9), no3rdText and 12 or 17, rows)<br />
end<br />
for r = 1, rowNum.third or rows do<br />
newRow(r)<br />
end<br />
p:saveStr('solid', tab.line[1][true], ' solid')<br />
p.cornerDiv = mw.html.create'div':css{height = tab.line[1][true], ['border-right'] = p.reuseStr.solid}<br />
for c = 1, p.cols do<br />
col.c = c<br />
local bumps = bump<br />
if c > 1 then<br />
col.tot = col.tot + math.pow(2, p.tCols - c)<br />
if p.branch_upwards then<br />
bumps = 0<br />
rowNum[1]:tag'td':attr{rowspan = 4}<br />
else<br />
rowNum[1]:node(c < p.cols and<br />
mw.clone(bumpBase):attr{rowspan = bump}<br />
or p.no_column_head and p.template and<br />
mw.html.create'td':wikitext(mw.getCurrentFrame():expandTemplate{<br />
title = 'navbar-header',<br />
args = {'', p.templateFixedName}<br />
})<br />
)<br />
end<br />
end<br />
col.top = m.num<br />
p.span = p.tCols > c and bump * 2 or p.branch_upwards or math.max((bump - 1) / 2, 2)<br />
col.show3rd = p['3rdplace'] and c == p.tCols and rowNum.third<br />
local colorFinal, bumpMid = p.color and c == p.tCols, p.span > 0 and mw.clone(bumpBase):attr{rowspan = p.span} or nil<br />
for r = 1, col.show3rd or rows, 2 do<br />
m.r = r + bumps<br />
if col.show3rd or rowNum[m.r] and m.num <= col.tot then<br />
if m.phase == 0 then<br />
m.showBox = setmetatable({1, nodeArgs.team.offset, nodeArgs.team.offset}, nodeArgs.tableSum)<br />
if nodeFunc:scanPattern(args, step) then<br />
nodeFunc.called = {}<br />
m.available = true<br />
else<br />
m.available = nil<br />
end<br />
end<br />
if skipMatch[m.num] then<br />
if m.phase == 0 then<br />
if nodeFunc.pattern then<br />
for x, y in ipairs(nodeFunc.pattern) do<br />
if nodeFunc.skipAllowed[y] then<br />
nodeFunc.called[y] = nodeFunc[y].main(x)<br />
end<br />
end<br />
end<br />
local canvas = nodeFunc.pattern and nodeFunc.called.canvas and 6<br />
rowNum[m.r + (canvas or 0)]:tag'td':attr{rowspan = maxSpan((canvas and 0 or 6) + bump * 2, m.r + (canvas or 0), rows), colspan = p.colspan}<br />
elseif m.phase == 2 then<br />
if nodeFunc.pattern and (nodeFunc.called.bridge or nodeFunc.called.canvas) then<br />
step = step + 1<br />
end<br />
m.num = m.num + 1<br />
step = step + (p.omit_blanks and 0 or m.showBox)<br />
bumps = bumps + (col.show3rd and 0 or maxSpan(p.span, m.r, rows))<br />
end<br />
elseif m.phase == 0 then<br />
if nodeFunc.pattern then<br />
for x, y in ipairs(nodeFunc.pattern) do<br />
if nodeFunc[y] and nodeFunc[y].main then<br />
nodeFunc.called[y] = nodeFunc[y].main(x)<br />
end<br />
end<br />
if m.available == false then<br />
m.showBox = nodeArgs.blank<br />
step = step + 1<br />
end<br />
end<br />
if m.showBox[1] then<br />
if col.show3rd then<br />
col.show3rd = (m.num - col.top) * 2<br />
if col.show3rd == 2 then<br />
if p.textThird:match('omit_label') then<br />
p.textThird = nil<br />
end<br />
if rowNum[rows + 1] and p.cols > 1 then --if 3rd place extends below bottom cell<br />
rowNum[rows + 1]:tag'td':attr{<br />
rowspan = m.r + 9 - rows - (text and 0 or 2),<br />
colspan = (p.cols - 1) * (3 + p.scoreBoxes)<br />
}<br />
end<br />
if p.tCols == 1 then<br />
bumps = p.textThird and 3 or 0<br />
elseif p.branch_upwards then<br />
r = 7<br />
bumps = p.textThird and 2 or 0<br />
end<br />
m.r = r + bumps<br />
if p.textThird then<br />
drawHead(p.textThird, m.r)<br />
bumps = bumps + 2<br />
m.r = r + bumps<br />
end<br />
end<br />
end<br />
dpBox(nodeFunc.pattern and nodeFunc.nonFunc or args[step], m.r)<br />
if p.previewnumbers then <br />
rowNum[m.r].nodes[#rowNum[m.r].nodes]<br />
:tag'div'<br />
:css{<br />
float = 'left',<br />
border = '1px solid red',<br />
padding = '0 .5ex',<br />
['color'] = 'red'<br />
}<br />
:wikitext(m.num)<br />
:attr{title = 'Number only visible outside article space (e.g. template) when |numberpreview=yes'}<br />
end<br />
end<br />
if p.colspan then<br />
m.nonEmpty = {}<br />
for s = step + 2, step + nodeArgs.team.offset do<br />
local i = {s, s + nodeArgs.team.offset}<br />
if args[i[1]] or args[i[2]] then<br />
table.insert(m.nonEmpty, i)<br />
end<br />
end<br />
if p.bold and m.showBox[2] and m.showBox[3] and not unBold[m.num] then<br />
m.bold = {<br />
box = {},<br />
clean = {}<br />
}<br />
local notSummed = not p.scoreSumBox or #m.nonEmpty < 2<br />
for s, i in ipairs(m.nonEmpty) do<br />
m.bold.clean[s] = {p.scoreWasher:main(args[i[1]]), p.scoreWasher:main(args[i[2]])}<br />
m.bold.box[s] = notSummed and boldWin(m.bold.clean[s][1], m.bold.clean[s][2]) or callableEmpty<br />
end<br />
if p.scoreSumBox and m.nonEmpty[2] then<br />
local i = {-step, -step - 1}<br />
table.insert(m.nonEmpty, i)<br />
args[i[1]], args[i[2]] = p.scoreWasher.sum(m.bold.clean)<br />
m.bold.box[p.scoreBoxes] = boldWin(args[i[1]], args[i[2]])<br />
end<br />
getmetatable(boxStyle).__index = p.scoreSumBoxes and {[#m.nonEmpty] = boxStyle[p.scoreBoxes]}<br />
m.bold.win = m.bold.box[#m.nonEmpty] or callableEmpty<br />
else<br />
m.bold = infiniteEmpty<br />
end<br />
end<br />
else<br />
if m.showBox[m.phase] then<br />
p.teamBoxCSS = colorFinal and<br />
{border = p.teamBoxNormal.border, background = p.bgColor[m.phase + (col.show3rd or 0)]}<br />
or p.teamBoxNormal<br />
local f = {phase = m.phase, bold = m.bold.win(m.phase)}<br />
teamBox(args[step + nodeArgs.team[m.phase]], m.r, f)<br />
f[1] = 'center'<br />
if p.colspan then<br />
if m.nonEmpty[1] then<br />
local loneSum<br />
if #m.nonEmpty < p.scoreBoxes then<br />
loneSum = #m.nonEmpty == 1 and boxStyle[p.scoreBoxes]<br />
tab.r:attr{colspan = 1 + p.scoreBoxes - #m.nonEmpty}<br />
end<br />
for s, i in ipairs(m.nonEmpty) do<br />
f.borderLeft = boxStyle(s)<br />
f.sumBox = loneSum or boxStyle[s]<br />
f.bold = m.bold.box[s](m.phase)<br />
teamBox(args[i[m.phase]], m.r, f)<br />
end<br />
else<br />
for s = 1, p.scoreBoxes do<br />
f.borderLeft = boxStyle(s)<br />
teamBox(nil, m.r, f)<br />
end<br />
end<br />
end<br />
end<br />
if m.phase == 2 then<br />
col.show3rd = col.show3rd ~= 2 and col.show3rd or nil<br />
if p.scoreWasher.demo and p.scoreWasher.demo == m.num and p.namespace ~= 0 then<br />
table.insert(m.bold.clean, 1, {args[step + nodeArgs.team[1]], args[step + nodeArgs.team[2]]})<br />
return table.concat{<br />
'Score data for match specified by <code>|demoWash=</code>:<br>',<br />
mw.dumpObject{scores = m.bold.clean, cycles = p.scoreWasher.cycles, sum = p.scoreSumBox and {m.nonEmpty[#m.nonEmpty][1], m.nonEmpty[#m.nonEmpty][1]}},<br />
'<table>',<br />
tostring(sp.row), '<tr>',<br />
tostring(rowNum[m.r - 4]), '<tr>',<br />
tostring(rowNum[m.r - 2]), '<tr>',<br />
tostring(rowNum[m.r]), '</table>',<br />
}<br />
end<br />
if nodeFunc.orphan.num == m.num then<br />
skipMatch[m.num] = 'orphan'<br />
end<br />
step = step + m.showBox<br />
m.num = m.num + 1<br />
if bump > 0 and rowNum[m.r + 2] and not (nodeFunc.pattern and nodeFunc.called.canvas) then<br />
bumps = bumps + p.span<br />
rowNum[m.r + 2]:node(bumpMid)<br />
end<br />
r = r + (col.show3rd or bump)<br />
end<br />
end<br />
m.phase = (m.phase + 1) % 3<br />
end<br />
end<br />
if p.cols > c then--draw lines to next round<br />
p.unit = bump + 3<br />
bump = 3 * math.pow(2, c) - 3<br />
bumps = p.branch_upwards and 4 or (p.unit + 1)<br />
rowNum[1]<br />
:tag'td':attr{rowspan = bumps}<br />
if not p.branch_upwards then<br />
rowNum[1]:tag'td'<br />
:attr{rowspan = (p.branch_upwards or bump) + 4}<br />
:css(nodeFunc.bridge.lay[c](0) and<br />
{['border-right'] = p.reuseStr.solid}<br />
or {}<br />
)<br />
end<br />
col.n = 0<br />
for r = bumps + 1, rows, p.unit * 2 do<br />
tab.r = rowNum[r]:tag'td'<br />
local interval = ((r - bumps - 1) / (p.unit * 2)) % 4<br />
if interval % 2 == 0 then<br />
--col.t and col.t2 control whether lines are drawn<br />
col.t = col.t2 or skipMatch[col.tot + col.n / 2 + 1] and 3 or ((skipMatch[col.top] and 1 or 0) + (skipMatch[col.top + 1] and 2 or 0))<br />
col.n = col.n + 2<br />
col.t2 = skipMatch[col.tot + col.n / 2 + 1] and 3 or ((skipMatch[col.top + col.n] and 1 or 0) + (skipMatch[col.top + col.n + 1] and 2 or 0))<br />
if col.t == 0 then<br />
tab.r<br />
:attr{rowspan = maxSpan(p.unit * 2, r, rows)}<br />
:css(skipMatch[col.tot + col.n / 2] and {} or {<br />
border = p.reuseStr.solid,<br />
['border-left'] = 0<br />
})<br />
else<br />
tab.r<br />
:attr{rowspan = maxSpan(p.unit, r, rows)}<br />
:cssText(col.t == 2 and<br />
p:saveStr('topRight', 'border-width:', tab.line[2], ' 0 0;border-style:solid')<br />
or col.t == 1 and (nodeFunc.bridge.lay[c](col.n - 2) and<br />
p:saveStr('right', ';border-right:', p.reuseStr.solid)<br />
or 'vertical-align:bottom'<br />
)<br />
or nil<br />
)<br />
:node(col.t == 1 and interval > 0 and not nodeFunc.bridge.lay[c](col.n - 2) and p.cornerDiv)<br />
rowNum[r + (p.branch_upwards and (4 - bump) or p.unit)]:tag'td'<br />
:attr{rowspan = maxSpan(p.unit, r + p.unit, rows)}<br />
:cssText(col.t == 1 and<br />
p:saveStr('bttmRght', 'border-width:0 ', tab.line[2], ' 0;border-style:solid')<br />
or col.t == 2 and (nodeFunc.bridge.lay[c](col.n + 2) and<br />
p:saveStr('right', ';border-right:', p.reuseStr.solid)<br />
or 'vertical-align:top'<br />
)<br />
or nil<br />
)<br />
:node(col.t == 2 and interval ~= 2 and not nodeFunc.bridge.lay[c](col.n + 2) and p.cornerDiv)<br />
end<br />
col.t = {<br />
col.t < 3,<br />
rowNum[r + p.unit * 5] and col.t2 < 3 or false<br />
}<br />
rowNum[r + (p.branch_upwards or p.unit)]:tag'td'<br />
:attr{rowspan = maxSpan(p.unit * 4, r + (p.branch_upwards and (4 - bump) or p.unit), rows)}<br />
:css(interval == 0 and (col.t[1] or col.t[2]) and {<br />
['border-width'] = table.concat{tab.line[1][col.t[1]], ' 0 ', tab.line[1][col.t[2]]},<br />
['border-style'] = 'solid'<br />
} or {})<br />
else<br />
tab.r<br />
:attr{rowspan = maxSpan(p.unit * 2, r, rows)}<br />
:css(nodeFunc.bridge.lay[c](col.n) and<br />
{['border-right'] = p.reuseStr.solid}<br />
or {}<br />
)<br />
end<br />
end<br />
end<br />
end<br />
local lock_height = (head_br.count or 0) + 1<br />
return args.scroll_height and<br />
mw.html.create'div'<br />
:cssText'border-bottom:1px solid #eee;display:inline-block'<br />
:node(not (p.scroll_head_unlock or p.no_column_head) and mw.html.create'div'<br />
:css{<br />
overflow = 'hidden',<br />
height = lock_height * 1.4 + 1.6 .. 'em',<br />
['border-bottom'] = 'inherit',<br />
['margin-right'] = '17px'<br />
}<br />
:node(mw.clone(tab))<br />
)<br />
:tag'div'<br />
:css{<br />
['overflow-y'] = 'scroll',<br />
['max-height'] = tonumber(args.scroll_height, 10) and args.scroll_height .. 'px' or args.scroll_height<br />
}<br />
:node(not (p.scroll_head_unlock or p.no_column_head) and<br />
tab:css{['margin-top'] = math.floor(-10 * (lock_height * 1.4 + 1.6)/(fontSize or .9)) / 10 .. 'em', ['padding-top'] = '-3px'}<br />
or tab<br />
)<br />
:done()<br />
or tab<br />
end<br />
<br />
--[[local standard = {<br />
'beta' = {<br />
bold_winner = 'high',<br />
omit_blanks = 'yes',<br />
auto_3rd = 'yes'<br />
}<br />
}--]]<br />
function p.main(frame, columns)<br />
local args = require'Module:Arguments'.getArgs(frame, {trim = false})<br />
args.columns = args.columns or columns<br />
return p._main(args)<br />
end<br />
<br />
function p.seed(frame)<br />
local parent = frame:getParent() or frame<br />
local function arg(k, alt)<br />
return parent.args[k] or frame.args[k] or alt<br />
end<br />
local padding, width = arg(2, p.teamBoxPadding()), arg(3, arg('widescore') and 40 or 30)<br />
padding = tonumber(padding) and tonumber(padding) .. 'px' or padding<br />
width = tonumber(width) and tonumber(width) .. 'px' or width<br />
return mw.html.create'div'<br />
:css{<br />
margin = ('-1px %s -1px -%s'):format(padding, padding),<br />
float = 'left',<br />
['background-color'] = p.bgColor.head,<br />
border = '1px solid #aaa',<br />
['text-align'] = 'center',<br />
width = width<br />
}<br />
:wikitext(arg(1, '&nbsp;'))<br />
end<br />
<br />
return p</div>
Marcus Cyron