Moduł:Navbox: Różnice pomiędzy wersjami

Z Czarnobyl Wiki
Skocz do: nawigacja, szukaj
m (1 wersja)
m (1 wersja)
 
(Nie pokazano 1 wersji utworzonej przez jednego użytkownika)
Linia 1: Linia 1:
--
+
local navboxFramePrefixStart = '<table class="navbox '
-- This module implements {{Navbox}}
+
local navboxFramePrefixEnd = '><tr><td>'
--
+
local navboxFrameSuffix = '</td></tr></table>'
  
local p = {}
+
local nameTemplateArg = "nazwa"
 +
local classesTemplateArg = "klasa"
 +
local widthTemplateArg = "szerokość"
 +
local parityTemplateArg = "parzystość"
 +
local listTemplateArg = "spis"
 +
local groupTemplateArg = "opis"
 +
local indexTemplateArg = "n"
  
local navbar = require('Module:Navbar')._navbar
+
local minimumIndexArgName = "min"
local getArgs -- lazily initialized
+
local maximumIndexArgName = "max"
 +
local listOnlyTemplateArgName = "spis"
 +
local listGroupTemplateArgName = "opis"
  
local args
+
local genericCategory = "Kategoria:Szablony nawigacyjne"
local border
 
local listnums = {}
 
local ODD_EVEN_MARKER = '\127_ODDEVEN_\127'
 
local RESTART_MARKER = '\127_ODDEVEN0_\127'
 
local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127'
 
  
local function striped(wikitext)
+
local listArgFormat = "spis%d"
-- Return wikitext with markers replaced for odd/even striping.
+
local groupArgFormat = "opis%d"
-- Child (subgroup) navboxes are flagged with a category that is removed
+
 
-- by parent navboxes. The result is that the category shows all pages
+
local classNavboxInner = "navbox-inner"
-- where a child navbox is not contained in a parent navbox.
+
local classNavbox = "navbox"
local orphanCat = '[[Category:Navbox orphans]]'
+
local classNavboxSubGroup = "navbox-subgroup"
if border == 'subgroup' and args.orphan ~= 'yes' then
+
local classColumnsTable = "navbox-columns-table"
-- No change; striping occurs in outermost navbox.
+
local classNavboxList = "navbox-list"
return wikitext .. orphanCat
+
local classNavboxGroup = "navbox-group"
end
+
local classNavboxColumn = "navbox-column"
local first, second = 'odd', 'even'
+
local classNavboxOdd = "navbox-odd"
if args.evenodd then
+
local classNavboxEven = "navbox-even"
if args.evenodd == 'swap' then
+
local classNavboxAboveBelow = "navbox-abovebelow"
first, second = second, first
+
local classFixedParity = "fixed-parity"
else
+
local classHList = "hlist"
first = args.evenodd
+
 
second = first
+
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 changer
+
if first == second then
+
return classes
changer = first
+
end
else
+
 
local index = 0
+
function adjustHList(classes)
changer = function (code)
+
local lists = {}
if code == '0' then
+
for i = 1, #classes do
-- Current occurrence is for a group before a nested table.
+
if classes[i].list then
-- Set it to first as a valid although pointless class.
+
local needsParity = i >= #classes or classes[i + 1].list
-- The next occurrence will be the first row after a title
+
-- in a subgroup and will also be first.
+
-- copy all classes except hlist
index = 0
+
local cc = {}
return first
+
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
index = index + 1
+
return index % 2 == 1 and first or second
+
local class = 'class="'..table.concat(cc, ' ')..'"'
 +
table.insert(lists, { s = classes[i].s, e = classes[i].e, c = class })
 
end
 
end
 
end
 
end
local regex = orphanCat:gsub('([%[%]])', '%%%1')
+
return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer))  -- () omits gsub count
+
return lists
 
end
 
end
  
local function processItem(item, nowrapitems)
+
function adjustHListAndParity(classes, oddParity, navboxOdd, navboxEven)
if item:sub(1, 2) == '{|' then
+
local lists = {}
-- Applying nowrap to lines in a table does not make sense.
+
for i = 1, #classes do
-- Add newlines to compensate for trim of x in |parm=x in a template.
+
if classes[i].list then
return '\n' .. item ..'\n'
+
local needsParity = i >= #classes or classes[i + 1].list
end
+
if nowrapitems == 'yes' then
+
-- copy all classes except navbox parity markers
local lines = {}
+
local cc = {}
for line in (item .. '\n'):gmatch('([^\n]*)\n') do
+
local vlist = false
local prefix, content = line:match('^([*:;#]+)%s*(.*)')
+
local fixed = false
if prefix and not content:match('^<span class="nowrap">') then
+
for _, v in ipairs(classes[i].c) do
line = prefix .. '<span class="nowrap">' .. content .. '</span>'
+
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(lines, line)
+
 +
local class = 'class="'..table.concat(cc, ' ')..'"'
 +
table.insert(lists, { s = classes[i].s, e = classes[i].e, c = class })
 
end
 
end
item = table.concat(lines, '\n')
 
end
 
if item:match('^[*:;#]') then
 
return '\n' .. item ..'\n'
 
 
end
 
end
return item
+
 +
return lists
 
end
 
end
  
local function renderNavBar(titleCell)
+
function apply(text, lists)
 
+
local fragments = {}
if args.navbar ~= 'off' and args.navbar ~= 'plain' and not (not args.name and mw.getCurrentFrame():getParent():getTitle():gsub('/sandbox$', '') == 'Template:Navbox') then
+
local start = 1
titleCell:wikitext(navbar{
+
for _, l in ipairs(lists) do
args.name,
+
table.insert(fragments, mw.ustring.sub(text, start, l.s-1))
mini = 1,
+
table.insert(fragments, l.c)
fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none;'
+
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)
--  Title row
+
local valid = {}
--
+
for _, v in ipairs(validExtraClasses) do
local function renderTitleRow(tbl)
+
valid[v] = true
if not args.title then return end
+
end
 +
 +
local added = {}
 +
local result = {
 +
"v2",
 +
"do-not-make-smaller"
 +
}
  
local titleRow = tbl:tag('tr')
+
for c in string.gmatch(classes, "%S+") do
 
+
if valid[c] and not added[c] then
if args.titlegroup then
+
table.insert(result, c)
titleRow
+
added[c] = true
:tag('th')
+
end
:attr('scope', 'row')
 
:addClass('navbox-group')
 
:addClass(args.titlegroupclass)
 
:cssText(args.basestyle)
 
:cssText(args.groupstyle)
 
:cssText(args.titlegroupstyle)
 
:wikitext(args.titlegroup)
 
 
end
 
end
 
+
local titleCell = titleRow:tag('th'):attr('scope', 'col')
+
if #name > 0 then
 
+
table.insert(result, mw.uri.anchorEncode("navbox-name-"..mw.getContentLanguage():lcfirst(name)))
if args.titlegroup then
 
titleCell
 
:css('border-left', '2px solid #fdfdfd')
 
:css('width', '100%')
 
 
end
 
end
 
+
local titleColspan = 2
+
return table.concat(result, " ")
if args.imageleft then titleColspan = titleColspan + 1 end
 
if args.image then titleColspan = titleColspan + 1 end
 
if args.titlegroup then titleColspan = titleColspan - 1 end
 
 
 
titleCell
 
:cssText(args.basestyle)
 
:cssText(args.titlestyle)
 
:addClass('navbox-title')
 
:attr('colspan', titleColspan)
 
 
 
renderNavBar(titleCell)
 
 
 
titleCell
 
:tag('div')
 
:attr('id', mw.uri.anchorEncode(args.title))
 
:addClass(args.titleclass)
 
:css('font-size', '114%')
 
:css('margin', '0 4em')
 
:wikitext(processItem(args.title))
 
 
end
 
end
  
--
+
function unwrap(text, makeChild)
--  Above/Below rows
+
if not text or (#text < (#navboxFramePrefixStart + #navboxFramePrefixEnd + #navboxFrameSuffix)) then
--
+
-- za krótki text
 
+
return text
local function getAboveBelowColspan()
+
end
local ret = 2
+
if args.imageleft then ret = ret + 1 end
+
if string.sub(text, 1, #navboxFramePrefixStart) ~= navboxFramePrefixStart then
if args.image then ret = ret + 1 end
+
-- brak początku prefiksu
return ret
+
return text
end
+
end
 
+
local function renderAboveRow(tbl)
+
local ps, pe = string.find(text, navboxFramePrefixEnd, #navboxFramePrefixStart, true)
if not args.above then return end
+
if not pe then
 
+
-- brak końca prefiksu
tbl:tag('tr')
+
return text
:tag('td')
 
:addClass('navbox-abovebelow')
 
:addClass(args.aboveclass)
 
:cssText(args.basestyle)
 
:cssText(args.abovestyle)
 
:attr('colspan', getAboveBelowColspan())
 
:tag('div')
 
:wikitext(processItem(args.above, args.nowrapitems))
 
end
 
 
 
local function renderBelowRow(tbl)
 
if not args.below then return end
 
 
 
tbl:tag('tr')
 
:tag('td')
 
:addClass('navbox-abovebelow')
 
:addClass(args.belowclass)
 
:cssText(args.basestyle)
 
:cssText(args.belowstyle)
 
:attr('colspan', getAboveBelowColspan())
 
:tag('div')
 
:wikitext(processItem(args.below, args.nowrapitems))
 
end
 
 
 
--
 
--  List rows
 
--
 
local function renderListRow(tbl, index, listnum)
 
local row = tbl:tag('tr')
 
 
 
if index == 1 and args.imageleft then
 
row
 
:tag('td')
 
:addClass('navbox-image')
 
:addClass(args.imageclass)
 
:css('width', '1px')              -- Minimize width
 
:css('padding', '0px 2px 0px 0px')
 
:cssText(args.imageleftstyle)
 
:attr('rowspan', #listnums)
 
:tag('div')
 
:wikitext(processItem(args.imageleft))
 
 
end
 
end
 
+
if args['group' .. listnum] then
+
local gs, ge = string.find(text, classNavboxInner, pe, true)
local groupCell = row:tag('th')
+
if not gs then
 
+
-- brak klasy wnętrza navboksu
groupCell
+
return text
:attr('scope', 'row')
 
:addClass('navbox-group')
 
:addClass(args.groupclass)
 
:cssText(args.basestyle)
 
            :css('width', args.groupwidth or '1%') -- If groupwidth not specified, minimize width
 
 
 
groupCell
 
:cssText(args.groupstyle)
 
:cssText(args['group' .. listnum .. 'style'])
 
:wikitext(args['group' .. listnum])
 
 
end
 
end
  
local listCell = row:tag('td')
+
local ss, se = string.find(text, navboxFrameSuffix, ge, true)
 
+
if not se then
if args['group' .. listnum] then
+
-- brak sufiksu
listCell
+
return text
:css('text-align', 'left')
 
:css('border-left-width', '2px')
 
:css('border-left-style', 'solid')
 
else
 
listCell:attr('colspan', 2)
 
 
end
 
end
 
+
if not args.groupwidth then
+
while true do
listCell:css('width', '100%')
+
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 rowstyle  -- usually nil so cssText(rowstyle) usually adds nothing
+
local result = {}
if index % 2 == 1 then
+
if makeChild then
rowstyle = args.oddstyle
+
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
rowstyle = args.evenstyle
+
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
  
local listText = args['list' .. listnum]
+
function wrap(text, classes, name, width)
local oddEven = ODD_EVEN_MARKER
+
if not text then
if listText:sub(1, 12) == '</div><table' then
+
return text
-- Assume list text is for a subgroup navbox so no automatic striping for this row.
 
oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd'
 
 
end
 
end
listCell
 
:css('padding', '0px')
 
:cssText(args.liststyle)
 
:cssText(rowstyle)
 
:cssText(args['list' .. listnum .. 'style'])
 
:addClass('navbox-list')
 
:addClass('navbox-' .. oddEven)
 
:addClass(args.listclass)
 
:tag('div')
 
:css('padding', (index == 1 and args.list1padding) or args.listpadding or '0em 0.25em')
 
:wikitext(processItem(listText, args.nowrapitems))
 
  
if index == 1 and args.image then
+
local result = {}
row
+
table.insert(result, navboxFramePrefixStart)
:tag('td')
+
table.insert(result, makeClasses(classes, name))
:addClass('navbox-image')
+
table.insert(result, '"')
:addClass(args.imageclass)
+
if #width > 0 then
:css('width', '1px')               -- Minimize width
+
table.insert(result, ' style="width: ')
:css('padding', '0px 0px 0px 2px')
+
table.insert(result, width)
:cssText(args.imagestyle)
+
table.insert(result, ';"')
:attr('rowspan', #listnums)
 
:tag('div')
 
:wikitext(processItem(args.image))
 
 
end
 
end
 +
 +
table.insert(result, navboxFramePrefixEnd)
 +
table.insert(result, text)
 +
table.insert(result, navboxFrameSuffix)
 +
return table.concat(result, "")
 
end
 
end
  
 
+
return {
--
+
--  Tracking categories
+
Finish = function(frame)
--
+
local parity = frame:getParent().args[parityTemplateArg]
 
+
local text = wrap(
local function needsHorizontalLists()
+
unwrap(frame.args and frame.args[1] or frame[1], false),
if border == 'subgroup' or args.tracking == 'no' then
+
frame:getParent().args[classesTemplateArg] or "",
return false
+
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 listClasses = {
+
['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true,
+
local oddParity = parity ~= paritySwapped
['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true,
+
local navboxOdd = parity == parityEven and classNavboxEven or classNavboxOdd
['hlist vevent'] = true,
+
local navboxEven = parity == parityOdd and classNavboxOdd or classNavboxEven
}
 
return not (listClasses[args.listclass] or listClasses[args.bodyclass])
 
end
 
  
local function hasBackgroundColors()
+
local lists = parity == parityOff
for _, key in ipairs({'titlestyle', 'groupstyle', 'basestyle', 'abovestyle', 'belowstyle'}) do
+
and adjustHList(classes)
if tostring(args[key]):find('background', 1, true) then
+
or adjustHListAndParity(classes, oddParity, navboxOdd, navboxEven)
return true
+
if #lists <= 0 then
end
+
return text
 
end
 
end
end
+
 +
return apply(text, lists)
 +
end,
  
local function hasBorders()
+
Iterate = function(frame)
for _, key in ipairs({'groupstyle', 'basestyle', 'abovestyle', 'belowstyle'}) do
+
local minimumIndex = tonumber(frame.args[minimumIndexArgName]) or 1
if tostring(args[key]):find('border', 1, true) then
+
local maximumIndex = tonumber(frame.args[maximumIndexArgName]) or 30
return true
+
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,
  
local function isIllegible()
+
TableRow = function(frame)
local styleratio = require('Module:Color contrast')._styleratio
+
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,
  
for key, style in pairs(args) do
+
Table = function(frame)
if tostring(key):match("style$") then
+
if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then
+
local args = frame:getParent().args
return true
+
end
+
function getNonEmpty(name)
end
+
local result = args[name]
 +
return (result and (#result > 0)) and result or false
 
end
 
end
return false
+
end
+
local header = {
 
+
h = getNonEmpty(tableHeaderGroupArgName),
local function getTrackingCategories()
+
s = getNonEmpty(tableHeaderGroupWidthArgName) or tableHeaderDefaultGroupWidth,
local cats = {}
+
}
if needsHorizontalLists() then table.insert(cats, 'Navigational boxes without horizontal lists') end
+
if hasBackgroundColors() then table.insert(cats, 'Navboxes using background colours') end
+
function fakeParity(row, col)
if isIllegible() then table.insert(cats, 'Potentially illegible navboxes') end
+
return nil
if hasBorders() then table.insert(cats, 'Navboxes using borders') end
 
return cats
 
end
 
 
 
local function renderTrackingCategories(builder)
 
local title = mw.title.getCurrentTitle()
 
if title.namespace ~= 10 then return end -- not in template space
 
local subpage = title.subpageText
 
if subpage == 'doc' or subpage == 'sandbox' or subpage == 'testcases' then return end
 
 
 
for _, cat in ipairs(getTrackingCategories()) do
 
builder:wikitext('[[Category:' .. cat .. ']]')
 
 
end
 
end
end
+
 
+
function horizontalParity(row, col)
--
+
return (row % 2) == 0 and classNavboxEven or classNavboxOdd
--  Main navbox tables
 
--
 
local function renderMainTable()
 
local tbl = mw.html.create('table')
 
:addClass('nowraplinks')
 
:addClass(args.bodyclass)
 
 
 
if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
 
tbl
 
:addClass('collapsible')
 
:addClass(args.state or 'autocollapse')
 
 
end
 
end
 
+
tbl:css('border-spacing', 0)
+
function verticalParity(row, col)
if border == 'subgroup' or border == 'none' then
+
return (col % 2) == 0 and classNavboxEven or classNavboxOdd
tbl
 
:addClass('navbox-subgroup')
 
:cssText(args.bodystyle)
 
:cssText(args.style)
 
else  -- regular navbox - bodystyle and style will be applied to the wrapper table
 
tbl
 
:addClass('navbox-inner')
 
:css('background', 'transparent')
 
:css('color', 'inherit')
 
 
end
 
end
tbl:cssText(args.innerstyle)
+
 
+
local parity = getNonEmpty(parityTemplateArg)
renderTitleRow(tbl)
+
local selectParity
renderAboveRow(tbl)
+
if parity == tableParityHorizontal then
for i, listnum in ipairs(listnums) do
+
selectParity = horizontalParity
renderListRow(tbl, i, listnum)
+
elseif parity == tableParityVertical then
 +
selectParity = verticalParity
 +
else
 +
selectParity = fakeParity
 
end
 
end
renderBelowRow(tbl)
+
 
+
for i = 1, 9 do
return tbl
+
local name = string.format(tableHeaderArgFormat, i)
end
+
local columnTitle = getNonEmpty(name)
 
+
if not columnTitle and (i == 1) then
function p._navbox(navboxArgs)
+
return nil
args = navboxArgs
+
elseif not columnTitle then
 
+
break
for k, _ in pairs(args) do
 
if type(k) == 'string' then
 
local listnum = k:match('^list(%d+)$')
 
if listnum then table.insert(listnums, tonumber(listnum)) end
 
 
end
 
end
 +
 +
header[i] = columnTitle
 
end
 
end
table.sort(listnums)
+
 
+
local content = getNonEmpty(tableContentArgName)
border = mw.text.trim(args.border or args[1] or '')
+
if not content then
if border == 'child' then
+
return nil
border = 'subgroup'
 
 
end
 
end
 
+
-- render the main body of the navbox
+
local data = mw.text.jsonDecode("["..content.."false]")
local tbl = renderMainTable()
+
if not data or not data[1] then
 
+
return nil
-- render the appropriate wrapper around the navbox, depending on the border param
 
local res = mw.html.create()
 
if border == 'none' then
 
local nav = res:tag('div')
 
:attr('role', 'navigation')
 
:node(tbl)
 
if args.title then
 
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title))
 
else
 
nav:attr('aria-label', 'Navbox')
 
end
 
elseif border == 'subgroup' then
 
-- We assume that this navbox is being rendered in a list cell of a parent navbox, and is
 
-- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the
 
-- padding being applied, and at the end add a <div> to balance out the parent's </div>
 
res
 
:wikitext('</div>')
 
:node(tbl)
 
:wikitext('<div>')
 
else
 
local nav = res:tag('div')
 
:attr('role', 'navigation')
 
:addClass('navbox')
 
:cssText(args.bodystyle)
 
:cssText(args.style)
 
:css('padding', '3px')
 
:node(tbl)
 
if args.title then
 
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title))
 
else
 
nav:attr('aria-label', 'Navbox')
 
end
 
 
end
 
end
 
+
renderTrackingCategories(res)
+
local buffer = mw.html.create("table")
 
+
:addClass(classColumnsTable)
return striped(tostring(res))
+
:addClass('v2') -- to jest tylko tymczasowo
end
+
local headerRow = buffer:tag("tr")
 
+
if header.h then
function p.navbox(frame)
+
headerRow:tag("th")
if not getArgs then
+
:addClass(classNavboxAboveBelow)
getArgs = require('Module:Arguments').getArgs
+
:addClass(tableHeaderClassGroup)
 +
:attr('scope','col')
 +
:css('width',header.s):wikitext(header.h)
 
end
 
end
args = getArgs(frame, {wrappers = {'Template:Navbox', 'Template:Navbox subgroup'}})
+
for i, columnTitle in ipairs(header) do
if frame.args.border then
+
headerRow:tag("th")
-- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}.
+
:addClass(classNavboxAboveBelow)
args.border = frame.args.border
+
:addClass(string.format(tableHeaderClassListFormat, i))
 +
:attr('scope','col')
 +
:wikitext(columnTitle)
 
end
 
end
 
+
for i, values in ipairs(data) do
-- Read the arguments in the order they'll be output in, to make references number in the right order.
+
if not values then
local _
+
break
_ = args.title
+
end
_ = args.above
+
for i = 1, 20 do
+
local dataRow = buffer:tag("tr")
_ = args["group" .. tostring(i)]
+
if header.h then
_ = args["list" .. tostring(i)]
+
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
_ = args.below
+
 
+
return tostring(buffer)
return p._navbox(args)
+
end,
end
 
  
return p
+
}

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,

}