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 = { &#039;Quarter-finals&#039;, &#039;Semi-finals&#039;, &#039;Final&#039;, &#039;Third place&#039; }, bgColor = {he…</p> <p><b>Neue Seite</b></p><div>local p = {<br /> RD = {<br /> &#039;Quarter-finals&#039;,<br /> &#039;Semi-finals&#039;,<br /> &#039;Final&#039;,<br /> &#039;Third place&#039;<br /> },<br /> bgColor = {head = &#039;#f2f2f2&#039;, &#039;gold&#039;, &#039;silver&#039;, &#039;#C96&#039;, &#039;#f9f9f9&#039;},<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[&#039;N&#039; .. N] = function(frame)<br /> return p.main(frame.args, columns)<br /> end<br /> p[&#039;n&#039; .. N] = p[&#039;N&#039; .. 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 &#039;table(k)&#039; 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&#039;table&#039;, {<br /> bs = require&#039;Module:Escape&#039;,--backslash<br /> comma = {[&#039;(%([^,]*),([^%)]*%))&#039;] = &#039;%1|@!#|%2&#039;},--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]), &#039;^node_function{(.-)}(.*)&#039;)<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, &#039;%s*,%s*&#039;)<br /> for k, v in ipairs(self.pattern) do<br /> local func, arg = string.match(v, &#039;^(%w+)%(?([^%)]*)&#039;)<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(&#039;%%%d&#039;, &#039;&#039;), x:match(&#039;%)([^%(])%(&#039;) or x:gsub(&#039;\\&#039;, &#039;&#039;))<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 ~= &#039;&#039; 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 &#039;&#039;, 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&#039;td&#039;<br /> :css(notTop[k] and<br /> {[isTop and &#039;border-top&#039; or &#039;border-bottom&#039;] = 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&#039;td&#039;<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&#039;tr&#039;<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&#039;td&#039;:attr{rowspan = 2}<br /> or head.row:tag&#039;td&#039;)<br /> :attr{colspan = p.colspan}<br /> if text ~= &#039;omit_label&#039; then<br /> td:wikitext(text):css{<br /> [&#039;text-align&#039;] = &#039;center&#039;,<br /> border = &#039;1px solid #aaa&#039;,<br /> background = p.bgColor.head<br /> }<br /> end<br /> end<br /> <br /> local function spacer(width)<br /> tab.r:tag&#039;td&#039;<br /> :attr{width = width}<br /> :wikitext(p.no_column_head and &#039;&#039; or &#039;&amp;nbsp;&#039;)<br /> end<br /> <br /> local function dpBox(v, r)<br /> p.dpBoxBase = p.dpBoxBase or mw.html.create&#039;td&#039;: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 = &#039;%-?%d+%.?%d*&#039;,<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(&#039;%-?%d+%.?%d*&#039;)) 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(&#039;%(([^%(%)]-)%)&#039;) do<br /> if v == &#039;_plus_&#039; then<br /> self.plus = v<br /> rinse:spin(v)<br /> cycle = cycle:gsub(&#039;%(_plus_%)&#039;, &#039;&#039;, 1)<br /> else<br /> wash = wash + 1<br /> rinse:spin(&#039;%&#039;):spin(wash)<br /> end<br /> end<br /> table.insert(self.cycles, {esc.bs:undo(cycle, &#039;%%&#039;), 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 &#039;{&lt;.-&gt;} {[^%d]*}&#039;):gfind(&#039;{(.-)}&#039;) 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 {&#039;&amp;mdash;&#039;, &#039;&amp;mdash;&#039;} or sum)<br /> end<br /> }<br /> <br /> local function boldWin(s1, s2)<br /> return setmetatable(<br /> p.bold and s1 ~= s2 and (math[({&#039;min&#039;, &#039;max&#039;})[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 &#039;.6ex&#039;<br /> end<br /> p.teamBoxPadTab = {padding = &#039;0 &#039; .. p.teamBoxPadding()}<br /> p.teamBoxNormal = {border = &#039;1px solid #aaa&#039;, 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{[&#039;vertical-align&#039;] = &#039;center&#039;}<br /> else<br /> if not p.bold then<br /> --backwards compatability (wikitemplates bold each arg individually)<br /> local hasBold, b = tostring(v):gsub(&quot;([^&#039;]*)&#039;&#039;&#039;([^&#039;]*)&quot;, &#039;%1&lt;b&gt;%2&lt;/b&gt;&#039;)<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 {[&#039;border-left&#039;] = f.borderLeft}<br /> cell[&#039;text-align&#039;] = v and f[1]<br /> else<br /> cell = p.teamBoxPadTab<br /> end<br /> tab.r = rowNum[r]:tag&#039;td&#039;<br /> :css(p.teamBoxCSS)<br /> :css(cell)<br /> :attr{rowspan = 2}<br /> :node(mw.html.create(f.bold and &#039;b&#039;):wikitext(v or f[1] and &#039;&#039; or &#039;&amp;nbsp;&#039;))<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 &#039;&#039;<br /> clean = mw.text.decode(clean):gsub(&#039;&lt;!%-.-%-&gt;&#039;, &#039;&#039;):gsub(params.pattern or &#039;[^%w-;%.]&#039;, &#039;&#039;) .. 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(&#039;columns&#039;, {pattern = &#039;%D&#039;}))<br /> p.tCols = (tonumber(args:clean(&#039;final_RDs_excluded&#039;, {pattern = &#039;%D&#039;})) or 0) + p.cols<br /> local matchPer = {<br /> pattern = &#039;%d*per%d+[%-x]%d+&#039;,<br /> vals = &#039;(%d*)per(%d+)([%-x])(%d+)&#039;<br /> }<br /> local skipMatch, unBold = {}, {}--(skip|manualbold)match# to boolean<br /> for k, _ in pairs(args) do<br /> local mType, mNum = string.match(k, &#039;^(%l+)match(%d*)$&#039;)<br /> mType, mNum = ({skip = skipMatch, manualbold = unBold})[mType], tonumber(mNum)<br /> if mType then<br /> if mNum then<br /> mType[mNum] = args:clean(k) == &#039;yes&#039; or args[k] == &#039;true&#039;<br /> else<br /> for pattern in args:clean(k, {ifNil = &#039;&#039;}):gfind(matchPer.pattern) do<br /> local d1, period, op, d2 = pattern:match(matchPer.vals)<br /> d1 = tonumber(d1) or 1<br /> d2 = op == &#039;-&#039; 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, &#039;&#039;):gsub(&#039;[;%-%a][;%-%a]+&#039;, &#039;;&#039;):match(&#039;^;*(.-)[;%-]*$&#039;), &#039;;&#039;)) do<br /> x = mw.text.split(x, &#039;-&#039;)<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 /> &#039;widescore&#039;,<br /> &#039;template&#039;,<br /> &#039;article_include&#039;,<br /> &#039;color&#039;,<br /> &#039;3rdplace&#039;,<br /> &#039;omit_blanks&#039;,<br /> &#039;scroll_head_unlock&#039;,<br /> &#039;previewnumbers&#039;,<br /> &#039;flex_tree&#039;,<br /> &#039;no_column_head&#039;,<br /> &#039;short_brackets&#039;,<br /> &#039;branch_upwards&#039;<br /> }) do<br /> if args[v] and (p[v] == nil or type(p[v]) == &#039;boolean&#039;) then<br /> p[v] = args:clean(v) == &#039;yes&#039; or args[v] == &#039;true&#039;<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[&#039;score-clean&#039;])<br /> p.scoreWasher.demo = args.demoWash and tonumber(args:clean(&#039;demoWash&#039;, {pattern = &#039;%D&#039;}), 10)<br /> p.scoreSumBox = args[&#039;score-boxes&#039;] and args[&#039;score-boxes&#039;]:match(&#039;%d ?%+ ?sum&#039;)<br /> p.bold = ({low = 1, high = 2})[args:clean(&#039;bold_winner&#039;)] or p.scoreSumBox and 2<br /> local sumBox = p.scoreSumBox and 1 or 0<br /> p.scoreBoxes = (tonumber(args:clean(&#039;score-boxes&#039;, {pattern = &#039;%D&#039;})) or 1) + sumBox<br /> p.scoreSumBox = p.scoreBoxes &gt; 0 and p.scoreSumBox or nil<br /> local boxStyle = p.scoreBoxes &gt; 1 and<br /> (p.scoreSumBox and<br /> setmetatable(<br /> {{}, [p.scoreBoxes] = {&#039;0 1ex&#039;}},<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 &gt; 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&#039;div&#039;<br /> :css{overflow = &#039;hidden&#039;, height = &#039;1ex&#039;}<br /> :wikitext&#039;&amp;nbsp;&#039;<br /> p.flex_tree = setmetatable({},{__index = {<br /> merge = p.flex_tree and p.scoreBoxes == 0,<br /> wt = p.flex_tree and &#039;&#039; or &#039;&amp;nbsp;&#039;,<br /> cell = mw.html.create&#039;td&#039;<br /> :node(not p.flex_tree and p.unflex_div or nil)<br /> }})<br /> if args:clean&#039;scroll_height&#039; then<br /> local fontSize, fontUnit = args.style and args.style:match(&#039;font%-size *: *(%d+)([^ ]+)&#039;)<br /> if fontSize then<br /> local units = {<br /> em = 1,<br /> ex = 2,<br /> [&#039;%&#039;] = 0.01<br /> }<br /> fontSize, fontUnit = {fontSize * fontUnit}<br /> end<br /> end<br /> tab<br /> :cssText(table.concat{args.scroll_height and &#039;padding&#039; or &#039;margin&#039;, &#039;:&#039;, fontSize and (math.ceil(fontSize * 10) / 10) or &#039;.9&#039;, &#039;em 2em 1em 1em;border:0;&#039;, fontSize and &#039;&#039; or &#039;font-size:90%;border-collapse:separate;&#039;, 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{[&#039;white-space&#039;] = args.scroll_height and &#039;nowrap&#039;}<br /> newRow()<br /> else<br /> tab.r = tab:tag&#039;tr&#039;<br /> tab.r:tag&#039;td&#039;<br /> end<br /> local sp = {--set column widths<br /> args[&#039;team-width&#039;] 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(&#039;score-width&#039;, {pattern = &#039;[^%d;]&#039;}) and mw.text.split(args[&#039;score-width&#039;], &#039;;&#039;) 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 &#039;Template:&#039; or &#039;&#039;) .. p.template.fullText<br /> end<br /> p.template = p.template and mw.title.new(args:clean(&#039;name&#039;, {pattern = &#039;&#039;}))<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(&#039;&lt;br[ &gt;/]&#039;, &#039;%1&#039;)<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 &gt; 1 then<br /> spacer(sp[3])<br /> spacer(sp[4])<br /> if not p.no_column_head then<br /> head.row:tag&#039;td&#039;: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(&#039;RD&#039; .. k, {pattern = &#039;&#039;}))<br /> or p.RD[#p.RD + k - p.tCols - 1]<br /> or (&#039;Round of &#039; .. math.pow(2, p.tCols - k + 1))<br /> drawHead(<br /> k == 1 and p.template and mw.getCurrentFrame():expandTemplate{<br /> title = &#039;navbar-header&#039;,<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&#039;td&#039;:attr{colspan = p.colspan}, col.tot * 6--Begin body row output<br /> args.line_px = table.concat{args:clean(&#039;line_px&#039;) or 3, args.line_px ~= &#039;0&#039; and &#039;px&#039; or nil}<br /> tab.line = {--reduces concats and &#039;or&#039; statements<br /> {<br /> [true] = args.line_px,<br /> [false] = 0<br /> },<br /> args.line_px:rep(2):gsub(&#039;(%a)(%d)&#039;, &#039;%1 %2&#039;, 1)<br /> }<br /> p[&#039;3rdplace&#039;] = p.tCols == p.cols and (p[&#039;3rdplace&#039;] or p.cols &gt; 3 and nil == p[&#039;3rdplace&#039;] and not p.no_column_head)<br /> if p[&#039;3rdplace&#039;] then<br /> p.textThird = args.Consol or args[&#039;RD&#039; .. (p.cols + 1)] or p.RD[4]<br /> local no3rdText = p.no_column_head or p.textThird and p.textThird:match(&#039;omit_label&#039;)<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(&#039;solid&#039;, tab.line[1][true], &#039; solid&#039;)<br /> p.cornerDiv = mw.html.create&#039;div&#039;:css{height = tab.line[1][true], [&#039;border-right&#039;] = p.reuseStr.solid}<br /> for c = 1, p.cols do<br /> col.c = c<br /> local bumps = bump<br /> if c &gt; 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&#039;td&#039;:attr{rowspan = 4}<br /> else<br /> rowNum[1]:node(c &lt; p.cols and<br /> mw.clone(bumpBase):attr{rowspan = bump}<br /> or p.no_column_head and p.template and<br /> mw.html.create&#039;td&#039;:wikitext(mw.getCurrentFrame():expandTemplate{<br /> title = &#039;navbar-header&#039;,<br /> args = {&#039;&#039;, p.templateFixedName}<br /> })<br /> )<br /> end<br /> end<br /> col.top = m.num<br /> p.span = p.tCols &gt; c and bump * 2 or p.branch_upwards or math.max((bump - 1) / 2, 2)<br /> col.show3rd = p[&#039;3rdplace&#039;] and c == p.tCols and rowNum.third<br /> local colorFinal, bumpMid = p.color and c == p.tCols, p.span &gt; 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 &lt;= 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&#039;td&#039;: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(&#039;omit_label&#039;) then<br /> p.textThird = nil<br /> end<br /> if rowNum[rows + 1] and p.cols &gt; 1 then --if 3rd place extends below bottom cell<br /> rowNum[rows + 1]:tag&#039;td&#039;: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&#039;div&#039;<br /> :css{<br /> float = &#039;left&#039;,<br /> border = &#039;1px solid red&#039;,<br /> padding = &#039;0 .5ex&#039;,<br /> [&#039;color&#039;] = &#039;red&#039;<br /> }<br /> :wikitext(m.num)<br /> :attr{title = &#039;Number only visible outside article space (e.g. template) when |numberpreview=yes&#039;}<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 &lt; 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] = &#039;center&#039;<br /> if p.colspan then<br /> if m.nonEmpty[1] then<br /> local loneSum<br /> if #m.nonEmpty &lt; 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 /> &#039;Score data for match specified by &lt;code&gt;|demoWash=&lt;/code&gt;:&lt;br&gt;&#039;,<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 /> &#039;&lt;table&gt;&#039;,<br /> tostring(sp.row), &#039;&lt;tr&gt;&#039;,<br /> tostring(rowNum[m.r - 4]), &#039;&lt;tr&gt;&#039;,<br /> tostring(rowNum[m.r - 2]), &#039;&lt;tr&gt;&#039;,<br /> tostring(rowNum[m.r]), &#039;&lt;/table&gt;&#039;,<br /> }<br /> end<br /> if nodeFunc.orphan.num == m.num then<br /> skipMatch[m.num] = &#039;orphan&#039;<br /> end<br /> step = step + m.showBox<br /> m.num = m.num + 1<br /> if bump &gt; 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 &gt; 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&#039;td&#039;:attr{rowspan = bumps}<br /> if not p.branch_upwards then<br /> rowNum[1]:tag&#039;td&#039;<br /> :attr{rowspan = (p.branch_upwards or bump) + 4}<br /> :css(nodeFunc.bridge.lay[c](0) and<br /> {[&#039;border-right&#039;] = 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&#039;td&#039;<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 /> [&#039;border-left&#039;] = 0<br /> })<br /> else<br /> tab.r<br /> :attr{rowspan = maxSpan(p.unit, r, rows)}<br /> :cssText(col.t == 2 and<br /> p:saveStr(&#039;topRight&#039;, &#039;border-width:&#039;, tab.line[2], &#039; 0 0;border-style:solid&#039;)<br /> or col.t == 1 and (nodeFunc.bridge.lay[c](col.n - 2) and<br /> p:saveStr(&#039;right&#039;, &#039;;border-right:&#039;, p.reuseStr.solid)<br /> or &#039;vertical-align:bottom&#039;<br /> )<br /> or nil<br /> )<br /> :node(col.t == 1 and interval &gt; 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&#039;td&#039;<br /> :attr{rowspan = maxSpan(p.unit, r + p.unit, rows)}<br /> :cssText(col.t == 1 and<br /> p:saveStr(&#039;bttmRght&#039;, &#039;border-width:0 &#039;, tab.line[2], &#039; 0;border-style:solid&#039;)<br /> or col.t == 2 and (nodeFunc.bridge.lay[c](col.n + 2) and<br /> p:saveStr(&#039;right&#039;, &#039;;border-right:&#039;, p.reuseStr.solid)<br /> or &#039;vertical-align:top&#039;<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 &lt; 3,<br /> rowNum[r + p.unit * 5] and col.t2 &lt; 3 or false<br /> }<br /> rowNum[r + (p.branch_upwards or p.unit)]:tag&#039;td&#039;<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 /> [&#039;border-width&#039;] = table.concat{tab.line[1][col.t[1]], &#039; 0 &#039;, tab.line[1][col.t[2]]},<br /> [&#039;border-style&#039;] = &#039;solid&#039;<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 /> {[&#039;border-right&#039;] = 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&#039;div&#039;<br /> :cssText&#039;border-bottom:1px solid #eee;display:inline-block&#039;<br /> :node(not (p.scroll_head_unlock or p.no_column_head) and mw.html.create&#039;div&#039;<br /> :css{<br /> overflow = &#039;hidden&#039;,<br /> height = lock_height * 1.4 + 1.6 .. &#039;em&#039;,<br /> [&#039;border-bottom&#039;] = &#039;inherit&#039;,<br /> [&#039;margin-right&#039;] = &#039;17px&#039;<br /> }<br /> :node(mw.clone(tab))<br /> )<br /> :tag&#039;div&#039;<br /> :css{<br /> [&#039;overflow-y&#039;] = &#039;scroll&#039;,<br /> [&#039;max-height&#039;] = tonumber(args.scroll_height, 10) and args.scroll_height .. &#039;px&#039; or args.scroll_height<br /> }<br /> :node(not (p.scroll_head_unlock or p.no_column_head) and<br /> tab:css{[&#039;margin-top&#039;] = math.floor(-10 * (lock_height * 1.4 + 1.6)/(fontSize or .9)) / 10 .. &#039;em&#039;, [&#039;padding-top&#039;] = &#039;-3px&#039;}<br /> or tab<br /> )<br /> :done()<br /> or tab<br /> end<br /> <br /> --[[local standard = {<br /> &#039;beta&#039; = {<br /> bold_winner = &#039;high&#039;,<br /> omit_blanks = &#039;yes&#039;,<br /> auto_3rd = &#039;yes&#039;<br /> }<br /> }--]]<br /> function p.main(frame, columns)<br /> local args = require&#039;Module:Arguments&#039;.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(&#039;widescore&#039;) and 40 or 30)<br /> padding = tonumber(padding) and tonumber(padding) .. &#039;px&#039; or padding<br /> width = tonumber(width) and tonumber(width) .. &#039;px&#039; or width<br /> return mw.html.create&#039;div&#039;<br /> :css{<br /> margin = (&#039;-1px %s -1px -%s&#039;):format(padding, padding),<br /> float = &#039;left&#039;,<br /> [&#039;background-color&#039;] = p.bgColor.head,<br /> border = &#039;1px solid #aaa&#039;,<br /> [&#039;text-align&#039;] = &#039;center&#039;,<br /> width = width<br /> }<br /> :wikitext(arg(1, &#039;&amp;nbsp;&#039;))<br /> end<br /> <br /> return p</div> Marcus Cyron