Moduł:Navbox
Zobacz podstrony tego modułu.
|
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,
ColSpan = function(frame)
local colspan = tonumber(frame.args[1]) or 0
local minimumIndex = tonumber(frame.args[minimumIndexArgName]) or 1
local maximumIndex = tonumber(frame.args[maximumIndexArgName]) or 30
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 ""
if #groupArg > 0 then
colspan = colspan + 1
break
end
end
end
return colspan > 1 and string.format('colspan="%d"', colspan) or ""
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,
}