Moduł:Navbox: Różnice pomiędzy wersjami
Z Czarnobyl Wiki
m (1 wersja) |
m (1 wersja) |
||
| (Nie pokazano 1 wersji utworzonej przez jednego użytkownika) | |||
| Linia 1: | Linia 1: | ||
| − | + | local navboxFramePrefixStart = '<table class="navbox ' | |
| − | + | local navboxFramePrefixEnd = '><tr><td>' | |
| − | + | local navboxFrameSuffix = '</td></tr></table>' | |
| − | local | + | local nameTemplateArg = "nazwa" |
| + | local classesTemplateArg = "klasa" | ||
| + | local widthTemplateArg = "szerokość" | ||
| + | local parityTemplateArg = "parzystość" | ||
| + | local listTemplateArg = "spis" | ||
| + | local groupTemplateArg = "opis" | ||
| + | local indexTemplateArg = "n" | ||
| − | local | + | local minimumIndexArgName = "min" |
| − | local | + | local maximumIndexArgName = "max" |
| + | local listOnlyTemplateArgName = "spis" | ||
| + | local listGroupTemplateArgName = "opis" | ||
| − | local | + | local genericCategory = "Kategoria:Szablony nawigacyjne" |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | local | + | local listArgFormat = "spis%d" |
| − | + | local groupArgFormat = "opis%d" | |
| − | -- | + | |
| − | -- | + | local classNavboxInner = "navbox-inner" |
| − | -- | + | local classNavbox = "navbox" |
| − | local | + | local classNavboxSubGroup = "navbox-subgroup" |
| − | + | local classColumnsTable = "navbox-columns-table" | |
| − | + | local classNavboxList = "navbox-list" | |
| − | + | local classNavboxGroup = "navbox-group" | |
| − | + | local classNavboxColumn = "navbox-column" | |
| − | + | local classNavboxOdd = "navbox-odd" | |
| − | + | local classNavboxEven = "navbox-even" | |
| − | + | local classNavboxAboveBelow = "navbox-abovebelow" | |
| − | + | local classFixedParity = "fixed-parity" | |
| − | + | local classHList = "hlist" | |
| − | + | ||
| − | + | local paritySwapped = "zamień" | |
| + | local parityEven = "parzyste" | ||
| + | local parityOdd = "nieparzyste" | ||
| + | local parityOff = "brak" | ||
| + | |||
| + | local tableHeaderGroupArgName = "nagłówek opisu" | ||
| + | local tableHeaderGroupWidthArgName = "szerokość opisu" | ||
| + | local tableHeaderArgFormat = "nagłówek%d" | ||
| + | local tableContentArgName = "zawartość" | ||
| + | local tableContentGroupName = "opis" | ||
| + | local tableHeaderClassGroup = "opis" | ||
| + | local tableRowClassGroupFormat = "opis%d" | ||
| + | local tableHeaderClassListFormat = "spis%d" | ||
| + | local tableRowClassListFormat = "wpis-%d-%d" | ||
| + | |||
| + | local tableParityHorizontal = "poziomo" | ||
| + | local tableParityVertical = "pionowo" | ||
| + | |||
| + | local tableHeaderDefaultGroupWidth = "10em" | ||
| + | |||
| + | local validExtraClasses = { | ||
| + | "ll-script", | ||
| + | "ll-script-dl-hlist", | ||
| + | "kz-linia", | ||
| + | "nav-teams", | ||
| + | "hnowrap-ul-ul" | ||
| + | } | ||
| + | |||
| + | function findNavboxClasses(text) | ||
| + | local classes = {} | ||
| + | local i = 1 | ||
| + | while true do | ||
| + | local s, e, c = mw.ustring.find(text, "class%s*=%s*\"([^\"]-%f[%a]navbox%f[^%a][^\"]*)\"", i) | ||
| + | if not c then | ||
| + | break | ||
| + | end | ||
| + | |||
| + | local cc = mw.text.split(c,"%s+") | ||
| + | for _, v in ipairs(cc) do | ||
| + | if (v == classNavbox) or (v == classNavboxSubGroup) or (v == classColumnsTable) then | ||
| + | table.insert(classes, { list=false }) | ||
| + | break | ||
| + | elseif (v == classNavboxList) or (v == classNavboxColumn) then | ||
| + | table.insert(classes, { list=true, c=cc, s=s, e=e }) | ||
| + | break | ||
| + | end | ||
end | end | ||
| + | |||
| + | i = e + 1 | ||
end | end | ||
| − | local | + | |
| − | if | + | return classes |
| − | + | end | |
| − | + | ||
| − | + | function adjustHList(classes) | |
| − | + | local lists = {} | |
| − | + | for i = 1, #classes do | |
| − | + | if classes[i].list then | |
| − | + | local needsParity = i >= #classes or classes[i + 1].list | |
| − | + | ||
| − | -- | + | -- copy all classes except hlist |
| − | + | local cc = {} | |
| − | + | local vlist = false | |
| + | for _, v in ipairs(classes[i].c) do | ||
| + | if v == classNavboxColumn then | ||
| + | vlist = true | ||
| + | table.insert(cc, v) | ||
| + | elseif (v ~= classHList) then | ||
| + | table.insert(cc, v) | ||
| + | end | ||
| + | end | ||
| + | |||
| + | if needsParity and not vlist then | ||
| + | -- restore or update missing hlist | ||
| + | table.insert(cc, classHList) | ||
end | end | ||
| − | + | ||
| − | + | local class = 'class="'..table.concat(cc, ' ')..'"' | |
| + | table.insert(lists, { s = classes[i].s, e = classes[i].e, c = class }) | ||
end | end | ||
end | end | ||
| − | + | ||
| − | return | + | return lists |
end | end | ||
| − | + | function adjustHListAndParity(classes, oddParity, navboxOdd, navboxEven) | |
| − | + | local lists = {} | |
| − | + | for i = 1, #classes do | |
| − | + | if classes[i].list then | |
| − | + | local needsParity = i >= #classes or classes[i + 1].list | |
| − | + | ||
| − | + | -- copy all classes except navbox parity markers | |
| − | + | local cc = {} | |
| − | + | local vlist = false | |
| − | + | local fixed = false | |
| − | if | + | for _, v in ipairs(classes[i].c) do |
| − | + | if v == classFixedParity then | |
| + | fixed = true | ||
| + | break | ||
| + | end | ||
| + | end | ||
| + | |||
| + | for _, v in ipairs(classes[i].c) do | ||
| + | if v == classHList then | ||
| + | -- remove | ||
| + | elseif v == classNavboxColumn then | ||
| + | vlist = true | ||
| + | table.insert(cc, v) | ||
| + | elseif fixed or (v ~= classNavboxOdd) and (v ~= classNavboxEven) then | ||
| + | table.insert(cc, v) | ||
| + | end | ||
| + | end | ||
| + | |||
| + | if needsParity then | ||
| + | if not vlist then | ||
| + | table.insert(cc, classHList) | ||
| + | end | ||
| + | |||
| + | if not fixed then | ||
| + | table.insert(cc, oddParity and navboxOdd or navboxEven) | ||
| + | if navboxOdd == navboxEven then | ||
| + | table.insert(cc, classFixedParity) | ||
| + | end | ||
| + | |||
| + | oddParity = not oddParity | ||
| + | end | ||
end | end | ||
| − | table.insert( | + | |
| + | local class = 'class="'..table.concat(cc, ' ')..'"' | ||
| + | table.insert(lists, { s = classes[i].s, e = classes[i].e, c = class }) | ||
end | end | ||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| − | return | + | |
| + | return lists | ||
end | end | ||
| − | + | function apply(text, lists) | |
| − | + | local fragments = {} | |
| − | + | local start = 1 | |
| − | + | for _, l in ipairs(lists) do | |
| − | + | table.insert(fragments, mw.ustring.sub(text, start, l.s-1)) | |
| − | + | table.insert(fragments, l.c) | |
| − | + | start = l.e + 1 | |
| − | |||
end | end | ||
| − | + | ||
| + | table.insert(fragments, mw.ustring.sub(text, start, #text)) | ||
| + | return table.concat(fragments, "") | ||
end | end | ||
| − | + | function makeClasses(classes, name) | |
| − | + | local valid = {} | |
| − | + | for _, v in ipairs(validExtraClasses) do | |
| − | local | + | valid[v] = true |
| − | + | end | |
| + | |||
| + | local added = {} | ||
| + | local result = { | ||
| + | "v2", | ||
| + | "do-not-make-smaller" | ||
| + | } | ||
| − | + | for c in string.gmatch(classes, "%S+") do | |
| − | + | if valid[c] and not added[c] then | |
| − | + | table.insert(result, c) | |
| − | + | added[c] = true | |
| − | + | end | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| − | + | ||
| − | + | if #name > 0 then | |
| − | + | table.insert(result, mw.uri.anchorEncode("navbox-name-"..mw.getContentLanguage():lcfirst(name))) | |
| − | if | ||
| − | |||
| − | |||
| − | |||
end | end | ||
| − | + | ||
| − | + | return table.concat(result, " ") | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| − | + | function unwrap(text, makeChild) | |
| − | + | if not text or (#text < (#navboxFramePrefixStart + #navboxFramePrefixEnd + #navboxFrameSuffix)) then | |
| − | + | -- za krótki text | |
| − | + | return text | |
| − | + | end | |
| − | + | ||
| − | if | + | if string.sub(text, 1, #navboxFramePrefixStart) ~= navboxFramePrefixStart then |
| − | + | -- brak początku prefiksu | |
| − | + | return text | |
| − | + | end | |
| − | + | ||
| − | + | local ps, pe = string.find(text, navboxFramePrefixEnd, #navboxFramePrefixStart, true) | |
| − | + | if not pe then | |
| − | + | -- brak końca prefiksu | |
| − | + | return text | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | end | ||
| − | |||
| − | |||
| − | if | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | -- | ||
| − | |||
| − | |||
| − | |||
| − | local | ||
| − | |||
| − | if | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| − | + | ||
| − | + | local gs, ge = string.find(text, classNavboxInner, pe, true) | |
| − | + | if not gs then | |
| − | + | -- brak klasy wnętrza navboksu | |
| − | + | return text | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| − | local | + | local ss, se = string.find(text, navboxFrameSuffix, ge, true) |
| − | + | if not se then | |
| − | if | + | -- brak sufiksu |
| − | + | return text | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| − | + | ||
| − | if not | + | while true do |
| − | + | local s, e = string.find(text, navboxFrameSuffix, se, true) | |
| + | if not s then | ||
| + | -- brak następnego sufixu | ||
| + | break | ||
| + | end | ||
| + | |||
| + | -- znalazłem kolejny sufix | ||
| + | ss = s | ||
| + | se = e | ||
end | end | ||
| − | + | ||
| − | local | + | local result = {} |
| − | if | + | if makeChild then |
| − | + | table.insert(result, string.sub(text, pe+1, gs-1)) | |
| + | table.insert(result, classNavboxSubGroup) | ||
| + | table.insert(result, string.sub(text, ge+1, ss-1)) | ||
else | else | ||
| − | + | table.insert(result, string.sub(text, pe+1, ss-1)) | |
| + | end | ||
| + | |||
| + | table.insert(result, string.sub(text, se+1, #text)) | ||
| + | local innerText = table.concat(result, "") | ||
| + | if makeChild then | ||
| + | -- trim generic category | ||
| + | innerText = mw.ustring.gsub(innerText, "%[%[ *"..genericCategory.." *|.-%]%]", "") | ||
| + | innerText = mw.ustring.gsub(innerText, "%[%[ *"..genericCategory.." *%]%]", "") | ||
end | end | ||
| + | |||
| + | return innerText | ||
| + | end | ||
| − | + | function wrap(text, classes, name, width) | |
| − | + | if not text then | |
| − | if | + | return text |
| − | |||
| − | |||
end | end | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | + | local result = {} | |
| − | + | table.insert(result, navboxFramePrefixStart) | |
| − | + | table.insert(result, makeClasses(classes, name)) | |
| − | + | table.insert(result, '"') | |
| − | + | if #width > 0 then | |
| − | + | table.insert(result, ' style="width: ') | |
| − | + | table.insert(result, width) | |
| − | + | table.insert(result, ';"') | |
| − | |||
| − | |||
| − | |||
end | end | ||
| + | |||
| + | table.insert(result, navboxFramePrefixEnd) | ||
| + | table.insert(result, text) | ||
| + | table.insert(result, navboxFrameSuffix) | ||
| + | return table.concat(result, "") | ||
end | end | ||
| − | + | return { | |
| − | + | ||
| − | + | Finish = function(frame) | |
| − | + | local parity = frame:getParent().args[parityTemplateArg] | |
| − | + | local text = wrap( | |
| − | local | + | unwrap(frame.args and frame.args[1] or frame[1], false), |
| − | + | frame:getParent().args[classesTemplateArg] or "", | |
| − | return | + | frame:getParent().args[nameTemplateArg] or "", |
| + | frame:getParent().args[widthTemplateArg] or "" | ||
| + | ) | ||
| + | if not text then | ||
| + | return text | ||
| + | end | ||
| + | |||
| + | local classes = findNavboxClasses(text) | ||
| + | if #classes <= 0 then | ||
| + | return text | ||
end | end | ||
| − | local | + | |
| − | + | local oddParity = parity ~= paritySwapped | |
| − | + | local navboxOdd = parity == parityEven and classNavboxEven or classNavboxOdd | |
| − | + | local navboxEven = parity == parityOdd and classNavboxOdd or classNavboxEven | |
| − | |||
| − | |||
| − | |||
| − | local | + | local lists = parity == parityOff |
| − | + | and adjustHList(classes) | |
| − | + | or adjustHListAndParity(classes, oddParity, navboxOdd, navboxEven) | |
| − | + | if #lists <= 0 then | |
| − | + | return text | |
end | end | ||
| − | end | + | |
| + | return apply(text, lists) | ||
| + | end, | ||
| − | + | Iterate = function(frame) | |
| − | for | + | local minimumIndex = tonumber(frame.args[minimumIndexArgName]) or 1 |
| − | if | + | local maximumIndex = tonumber(frame.args[maximumIndexArgName]) or 30 |
| − | + | local listOnlyTemplate = frame.args[listOnlyTemplateArgName] | |
| + | local listGroupTemplate = frame.args[listGroupTemplateArgName] or listOnlyTemplate | ||
| + | local result = {} | ||
| + | for i = minimumIndex, maximumIndex do | ||
| + | local listArgName = string.format(listArgFormat, i) | ||
| + | local groupArgName = string.format(groupArgFormat, i) | ||
| + | local listArg = frame:getParent().args[listArgName] or "" | ||
| + | if #listArg > 0 then | ||
| + | local groupArg = frame:getParent().args[groupArgName] or "" | ||
| + | local template = #groupArg > 0 and listGroupTemplate or listOnlyTemplate | ||
| + | local repl = { | ||
| + | [listTemplateArg] = unwrap(listArg, true), | ||
| + | [groupTemplateArg] = groupArg, | ||
| + | [indexTemplateArg] = tostring(i), | ||
| + | } | ||
| + | local text, _ = mw.ustring.gsub(template, "{{{(%w+)}}}", repl) | ||
| + | table.insert(result, text) | ||
end | end | ||
end | end | ||
| − | end | + | |
| + | return table.concat(result, "") | ||
| + | end, | ||
| − | + | TableRow = function(frame) | |
| − | local | + | local args = frame:getParent().args |
| + | return mw.text.jsonEncode({ | ||
| + | [tableContentGroupName] = args[tableContentGroupName], | ||
| + | [1] = args[1], | ||
| + | [2] = args[2], | ||
| + | [3] = args[3], | ||
| + | [4] = args[4], | ||
| + | [5] = args[5], | ||
| + | [6] = args[6], | ||
| + | [7] = args[7], | ||
| + | [8] = args[8], | ||
| + | [9] = args[9], | ||
| + | }) | ||
| + | end, | ||
| − | + | Table = function(frame) | |
| − | + | ||
| − | + | local args = frame:getParent().args | |
| − | + | ||
| − | + | function getNonEmpty(name) | |
| − | + | local result = args[name] | |
| + | return (result and (#result > 0)) and result or false | ||
end | end | ||
| − | + | ||
| − | + | local header = { | |
| − | + | h = getNonEmpty(tableHeaderGroupArgName), | |
| − | + | s = getNonEmpty(tableHeaderGroupWidthArgName) or tableHeaderDefaultGroupWidth, | |
| − | local | + | } |
| − | + | ||
| − | + | function fakeParity(row, col) | |
| − | + | return nil | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| − | + | ||
| − | + | function horizontalParity(row, col) | |
| − | + | return (row % 2) == 0 and classNavboxEven or classNavboxOdd | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| − | + | ||
| − | + | function verticalParity(row, col) | |
| − | + | return (col % 2) == 0 and classNavboxEven or classNavboxOdd | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| − | + | ||
| − | + | local parity = getNonEmpty(parityTemplateArg) | |
| − | + | local selectParity | |
| − | + | if parity == tableParityHorizontal then | |
| − | + | selectParity = horizontalParity | |
| − | + | elseif parity == tableParityVertical then | |
| + | selectParity = verticalParity | ||
| + | else | ||
| + | selectParity = fakeParity | ||
end | end | ||
| − | + | ||
| − | + | for i = 1, 9 do | |
| − | + | local name = string.format(tableHeaderArgFormat, i) | |
| − | + | local columnTitle = getNonEmpty(name) | |
| − | + | if not columnTitle and (i == 1) then | |
| − | + | return nil | |
| − | + | elseif not columnTitle then | |
| − | + | break | |
| − | |||
| − | if | ||
| − | |||
| − | |||
end | end | ||
| + | |||
| + | header[i] = columnTitle | ||
end | end | ||
| − | + | ||
| − | + | local content = getNonEmpty(tableContentArgName) | |
| − | + | if not content then | |
| − | if | + | return nil |
| − | |||
end | end | ||
| − | + | ||
| − | + | local data = mw.text.jsonDecode("["..content.."false]") | |
| − | + | if not data or not data[1] then | |
| − | + | return nil | |
| − | |||
| − | local | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| − | + | ||
| − | + | local buffer = mw.html.create("table") | |
| − | + | :addClass(classColumnsTable) | |
| − | + | :addClass('v2') -- to jest tylko tymczasowo | |
| − | + | local headerRow = buffer:tag("tr") | |
| − | + | if header.h then | |
| − | + | headerRow:tag("th") | |
| − | if | + | :addClass(classNavboxAboveBelow) |
| − | + | :addClass(tableHeaderClassGroup) | |
| + | :attr('scope','col') | ||
| + | :css('width',header.s):wikitext(header.h) | ||
end | end | ||
| − | + | for i, columnTitle in ipairs(header) do | |
| − | + | headerRow:tag("th") | |
| − | + | :addClass(classNavboxAboveBelow) | |
| − | + | :addClass(string.format(tableHeaderClassListFormat, i)) | |
| + | :attr('scope','col') | ||
| + | :wikitext(columnTitle) | ||
end | end | ||
| − | + | for i, values in ipairs(data) do | |
| − | + | if not values then | |
| − | + | break | |
| − | + | end | |
| − | + | ||
| − | + | local dataRow = buffer:tag("tr") | |
| − | + | if header.h then | |
| − | + | dataRow:tag("th") | |
| + | :addClass(classNavboxGroup) | ||
| + | :addClass(string.format(tableRowClassGroupFormat, i)) | ||
| + | :attr('scope','row') | ||
| + | :wikitext(values[tableContentGroupName] or string.format("%d. {{{%s}}}", i, tableContentGroupName)) | ||
| + | end | ||
| + | |||
| + | for j, columnTitle in ipairs(header) do | ||
| + | local cell = dataRow:tag("td") | ||
| + | :addClass(classNavboxColumn) | ||
| + | :addClass(string.format(tableRowClassListFormat, i, j)) | ||
| + | :wikitext(values[j] or string.format("%d. {{{%d}}}", i, j)) | ||
| + | local parity = selectParity(i, j) | ||
| + | if parity then | ||
| + | cell | ||
| + | :addClass(classFixedParity) | ||
| + | :addClass(parity) | ||
| + | end | ||
| + | end | ||
end | end | ||
| − | + | ||
| − | + | return tostring(buffer) | |
| − | return | + | end, |
| − | end | ||
| − | + | } | |
Aktualna wersja na dzień 18:12, 9 lut 2019
Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:Navbox/opis
Błąd skryptu: Błąd Lua: Błąd wewnętrzny: Proces interpretera został zakończony z sygnałem "-129".
local navboxFramePrefixStart = '<table class="navbox '
local navboxFramePrefixEnd = '><tr><td>'
local navboxFrameSuffix = '</td></tr></table>'
local nameTemplateArg = "nazwa"
local classesTemplateArg = "klasa"
local widthTemplateArg = "szerokość"
local parityTemplateArg = "parzystość"
local listTemplateArg = "spis"
local groupTemplateArg = "opis"
local indexTemplateArg = "n"
local minimumIndexArgName = "min"
local maximumIndexArgName = "max"
local listOnlyTemplateArgName = "spis"
local listGroupTemplateArgName = "opis"
local genericCategory = "Kategoria:Szablony nawigacyjne"
local listArgFormat = "spis%d"
local groupArgFormat = "opis%d"
local classNavboxInner = "navbox-inner"
local classNavbox = "navbox"
local classNavboxSubGroup = "navbox-subgroup"
local classColumnsTable = "navbox-columns-table"
local classNavboxList = "navbox-list"
local classNavboxGroup = "navbox-group"
local classNavboxColumn = "navbox-column"
local classNavboxOdd = "navbox-odd"
local classNavboxEven = "navbox-even"
local classNavboxAboveBelow = "navbox-abovebelow"
local classFixedParity = "fixed-parity"
local classHList = "hlist"
local paritySwapped = "zamień"
local parityEven = "parzyste"
local parityOdd = "nieparzyste"
local parityOff = "brak"
local tableHeaderGroupArgName = "nagłówek opisu"
local tableHeaderGroupWidthArgName = "szerokość opisu"
local tableHeaderArgFormat = "nagłówek%d"
local tableContentArgName = "zawartość"
local tableContentGroupName = "opis"
local tableHeaderClassGroup = "opis"
local tableRowClassGroupFormat = "opis%d"
local tableHeaderClassListFormat = "spis%d"
local tableRowClassListFormat = "wpis-%d-%d"
local tableParityHorizontal = "poziomo"
local tableParityVertical = "pionowo"
local tableHeaderDefaultGroupWidth = "10em"
local validExtraClasses = {
"ll-script",
"ll-script-dl-hlist",
"kz-linia",
"nav-teams",
"hnowrap-ul-ul"
}
function findNavboxClasses(text)
local classes = {}
local i = 1
while true do
local s, e, c = mw.ustring.find(text, "class%s*=%s*\"([^\"]-%f[%a]navbox%f[^%a][^\"]*)\"", i)
if not c then
break
end
local cc = mw.text.split(c,"%s+")
for _, v in ipairs(cc) do
if (v == classNavbox) or (v == classNavboxSubGroup) or (v == classColumnsTable) then
table.insert(classes, { list=false })
break
elseif (v == classNavboxList) or (v == classNavboxColumn) then
table.insert(classes, { list=true, c=cc, s=s, e=e })
break
end
end
i = e + 1
end
return classes
end
function adjustHList(classes)
local lists = {}
for i = 1, #classes do
if classes[i].list then
local needsParity = i >= #classes or classes[i + 1].list
-- copy all classes except hlist
local cc = {}
local vlist = false
for _, v in ipairs(classes[i].c) do
if v == classNavboxColumn then
vlist = true
table.insert(cc, v)
elseif (v ~= classHList) then
table.insert(cc, v)
end
end
if needsParity and not vlist then
-- restore or update missing hlist
table.insert(cc, classHList)
end
local class = 'class="'..table.concat(cc, ' ')..'"'
table.insert(lists, { s = classes[i].s, e = classes[i].e, c = class })
end
end
return lists
end
function adjustHListAndParity(classes, oddParity, navboxOdd, navboxEven)
local lists = {}
for i = 1, #classes do
if classes[i].list then
local needsParity = i >= #classes or classes[i + 1].list
-- copy all classes except navbox parity markers
local cc = {}
local vlist = false
local fixed = false
for _, v in ipairs(classes[i].c) do
if v == classFixedParity then
fixed = true
break
end
end
for _, v in ipairs(classes[i].c) do
if v == classHList then
-- remove
elseif v == classNavboxColumn then
vlist = true
table.insert(cc, v)
elseif fixed or (v ~= classNavboxOdd) and (v ~= classNavboxEven) then
table.insert(cc, v)
end
end
if needsParity then
if not vlist then
table.insert(cc, classHList)
end
if not fixed then
table.insert(cc, oddParity and navboxOdd or navboxEven)
if navboxOdd == navboxEven then
table.insert(cc, classFixedParity)
end
oddParity = not oddParity
end
end
local class = 'class="'..table.concat(cc, ' ')..'"'
table.insert(lists, { s = classes[i].s, e = classes[i].e, c = class })
end
end
return lists
end
function apply(text, lists)
local fragments = {}
local start = 1
for _, l in ipairs(lists) do
table.insert(fragments, mw.ustring.sub(text, start, l.s-1))
table.insert(fragments, l.c)
start = l.e + 1
end
table.insert(fragments, mw.ustring.sub(text, start, #text))
return table.concat(fragments, "")
end
function makeClasses(classes, name)
local valid = {}
for _, v in ipairs(validExtraClasses) do
valid[v] = true
end
local added = {}
local result = {
"v2",
"do-not-make-smaller"
}
for c in string.gmatch(classes, "%S+") do
if valid[c] and not added[c] then
table.insert(result, c)
added[c] = true
end
end
if #name > 0 then
table.insert(result, mw.uri.anchorEncode("navbox-name-"..mw.getContentLanguage():lcfirst(name)))
end
return table.concat(result, " ")
end
function unwrap(text, makeChild)
if not text or (#text < (#navboxFramePrefixStart + #navboxFramePrefixEnd + #navboxFrameSuffix)) then
-- za krótki text
return text
end
if string.sub(text, 1, #navboxFramePrefixStart) ~= navboxFramePrefixStart then
-- brak początku prefiksu
return text
end
local ps, pe = string.find(text, navboxFramePrefixEnd, #navboxFramePrefixStart, true)
if not pe then
-- brak końca prefiksu
return text
end
local gs, ge = string.find(text, classNavboxInner, pe, true)
if not gs then
-- brak klasy wnętrza navboksu
return text
end
local ss, se = string.find(text, navboxFrameSuffix, ge, true)
if not se then
-- brak sufiksu
return text
end
while true do
local s, e = string.find(text, navboxFrameSuffix, se, true)
if not s then
-- brak następnego sufixu
break
end
-- znalazłem kolejny sufix
ss = s
se = e
end
local result = {}
if makeChild then
table.insert(result, string.sub(text, pe+1, gs-1))
table.insert(result, classNavboxSubGroup)
table.insert(result, string.sub(text, ge+1, ss-1))
else
table.insert(result, string.sub(text, pe+1, ss-1))
end
table.insert(result, string.sub(text, se+1, #text))
local innerText = table.concat(result, "")
if makeChild then
-- trim generic category
innerText = mw.ustring.gsub(innerText, "%[%[ *"..genericCategory.." *|.-%]%]", "")
innerText = mw.ustring.gsub(innerText, "%[%[ *"..genericCategory.." *%]%]", "")
end
return innerText
end
function wrap(text, classes, name, width)
if not text then
return text
end
local result = {}
table.insert(result, navboxFramePrefixStart)
table.insert(result, makeClasses(classes, name))
table.insert(result, '"')
if #width > 0 then
table.insert(result, ' style="width: ')
table.insert(result, width)
table.insert(result, ';"')
end
table.insert(result, navboxFramePrefixEnd)
table.insert(result, text)
table.insert(result, navboxFrameSuffix)
return table.concat(result, "")
end
return {
Finish = function(frame)
local parity = frame:getParent().args[parityTemplateArg]
local text = wrap(
unwrap(frame.args and frame.args[1] or frame[1], false),
frame:getParent().args[classesTemplateArg] or "",
frame:getParent().args[nameTemplateArg] or "",
frame:getParent().args[widthTemplateArg] or ""
)
if not text then
return text
end
local classes = findNavboxClasses(text)
if #classes <= 0 then
return text
end
local oddParity = parity ~= paritySwapped
local navboxOdd = parity == parityEven and classNavboxEven or classNavboxOdd
local navboxEven = parity == parityOdd and classNavboxOdd or classNavboxEven
local lists = parity == parityOff
and adjustHList(classes)
or adjustHListAndParity(classes, oddParity, navboxOdd, navboxEven)
if #lists <= 0 then
return text
end
return apply(text, lists)
end,
Iterate = function(frame)
local minimumIndex = tonumber(frame.args[minimumIndexArgName]) or 1
local maximumIndex = tonumber(frame.args[maximumIndexArgName]) or 30
local listOnlyTemplate = frame.args[listOnlyTemplateArgName]
local listGroupTemplate = frame.args[listGroupTemplateArgName] or listOnlyTemplate
local result = {}
for i = minimumIndex, maximumIndex do
local listArgName = string.format(listArgFormat, i)
local groupArgName = string.format(groupArgFormat, i)
local listArg = frame:getParent().args[listArgName] or ""
if #listArg > 0 then
local groupArg = frame:getParent().args[groupArgName] or ""
local template = #groupArg > 0 and listGroupTemplate or listOnlyTemplate
local repl = {
[listTemplateArg] = unwrap(listArg, true),
[groupTemplateArg] = groupArg,
[indexTemplateArg] = tostring(i),
}
local text, _ = mw.ustring.gsub(template, "{{{(%w+)}}}", repl)
table.insert(result, text)
end
end
return table.concat(result, "")
end,
TableRow = function(frame)
local args = frame:getParent().args
return mw.text.jsonEncode({
[tableContentGroupName] = args[tableContentGroupName],
[1] = args[1],
[2] = args[2],
[3] = args[3],
[4] = args[4],
[5] = args[5],
[6] = args[6],
[7] = args[7],
[8] = args[8],
[9] = args[9],
})
end,
Table = function(frame)
local args = frame:getParent().args
function getNonEmpty(name)
local result = args[name]
return (result and (#result > 0)) and result or false
end
local header = {
h = getNonEmpty(tableHeaderGroupArgName),
s = getNonEmpty(tableHeaderGroupWidthArgName) or tableHeaderDefaultGroupWidth,
}
function fakeParity(row, col)
return nil
end
function horizontalParity(row, col)
return (row % 2) == 0 and classNavboxEven or classNavboxOdd
end
function verticalParity(row, col)
return (col % 2) == 0 and classNavboxEven or classNavboxOdd
end
local parity = getNonEmpty(parityTemplateArg)
local selectParity
if parity == tableParityHorizontal then
selectParity = horizontalParity
elseif parity == tableParityVertical then
selectParity = verticalParity
else
selectParity = fakeParity
end
for i = 1, 9 do
local name = string.format(tableHeaderArgFormat, i)
local columnTitle = getNonEmpty(name)
if not columnTitle and (i == 1) then
return nil
elseif not columnTitle then
break
end
header[i] = columnTitle
end
local content = getNonEmpty(tableContentArgName)
if not content then
return nil
end
local data = mw.text.jsonDecode("["..content.."false]")
if not data or not data[1] then
return nil
end
local buffer = mw.html.create("table")
:addClass(classColumnsTable)
:addClass('v2') -- to jest tylko tymczasowo
local headerRow = buffer:tag("tr")
if header.h then
headerRow:tag("th")
:addClass(classNavboxAboveBelow)
:addClass(tableHeaderClassGroup)
:attr('scope','col')
:css('width',header.s):wikitext(header.h)
end
for i, columnTitle in ipairs(header) do
headerRow:tag("th")
:addClass(classNavboxAboveBelow)
:addClass(string.format(tableHeaderClassListFormat, i))
:attr('scope','col')
:wikitext(columnTitle)
end
for i, values in ipairs(data) do
if not values then
break
end
local dataRow = buffer:tag("tr")
if header.h then
dataRow:tag("th")
:addClass(classNavboxGroup)
:addClass(string.format(tableRowClassGroupFormat, i))
:attr('scope','row')
:wikitext(values[tableContentGroupName] or string.format("%d. {{{%s}}}", i, tableContentGroupName))
end
for j, columnTitle in ipairs(header) do
local cell = dataRow:tag("td")
:addClass(classNavboxColumn)
:addClass(string.format(tableRowClassListFormat, i, j))
:wikitext(values[j] or string.format("%d. {{{%d}}}", i, j))
local parity = selectParity(i, j)
if parity then
cell
:addClass(classFixedParity)
:addClass(parity)
end
end
end
return tostring(buffer)
end,
}