Module:Navbox with columns: Difference between revisions
Jump to navigation
Jump to search
w>Ahecht (Remove code that omitted colspan in the final column (the browser can deal with it). Fix column sorting) |
m (1 revision imported) |
Latest revision as of 08:46, 22 November 2024
Documentation for this module may be created at Module:Navbox with columns/doc
require('strict') local p = {} local parentCfg = mw.loadData('Module:Navbox/configuration') local thisCfg = mw.loadData('Module:Navbox with columns/configuration') local cfg = {} for k, v in pairs(thisCfg) do if type(v) == 'table' then cfg[k] = {} if type(parentCfg[k]) == 'table' then for kk, vv in pairs(parentCfg[k]) do cfg[k][kk] = vv end end for kk, vv in pairs(v) do cfg[k][kk] = vv end end end local inArray = require("Module:TableTools").inArray local getArgs -- lazily initialized -- helper functions local andnum = function(s, n) return string.format(cfg.arg[s..'_and_num'], n) end local isblank = function(v) return (v or '') == '' end local function concatstrings(s) local r = table.concat(s, '') if r:match('^%s*$') then return nil end return r end local function concatstyles(s) local r = '' for _, v in ipairs(s) do v = mw.text.trim(v, "%s;") if not isblank(v) then r = r .. v .. ';' end end if isblank(r) then return nil end return r end local function getSubgroup(args, listnum, listText, prefix) local subArgs = { [cfg.arg.border] = cfg.keyword.border_subgroup, [cfg.arg.navbar] = cfg.keyword.navbar_plain } local hasSubArgs = false local subgroups = prefix and {prefix} or cfg.keyword.subgroups for k, v in pairs(args) do k = tostring(k) for _, w in ipairs(subgroups) do w = w .. listnum .. "_" if (#k > #w) and (k:sub(1, #w) == w) then subArgs[k:sub(#w + 1)] = v hasSubArgs = true end end end return hasSubArgs and p._navbox(subArgs) or listText end -- Main functions p._navbox = require('Module:Navbox')._navbox function p._withColumns(pargs) -- table for args passed to navbox local targs = {} -- tables of column numbers local colheadernums = {} local colnums = {} local colfooternums = {} -- process args local passthrough = { [cfg.arg.above]=true,[cfg.arg.aboveclass]=true,[cfg.arg.abovestyle]=true, [cfg.arg.basestyle]=true, [cfg.arg.below]=true,[cfg.arg.belowclass]=true,[cfg.arg.belowstyle]=true, [cfg.arg.bodyclass]=true, [cfg.arg.evenstyle]=true, [cfg.arg.groupclass]=true,[cfg.arg.groupstyle]=true, [cfg.arg.image]=true,[cfg.arg.imageclass]=true,[cfg.arg.imagestyle]=true, [cfg.arg.imageleft]=true,[cfg.arg.imageleftstyle]=true, [cfg.arg.listclass]=true,[cfg.arg.liststyle]=true, [cfg.arg.name]=true, [cfg.arg.navbar]=true, [cfg.arg.oddstyle]=true, [cfg.arg.state]=true, [cfg.arg.title]=true,[cfg.arg.titleclass]=true,[cfg.arg.titlestyle]=true, } for k,v in pairs(pargs) do if passthrough[k] then targs[k] = v elseif type(k) == 'string' then if k:match(cfg.pattern.listnum) then local n = k:match(cfg.pattern.listnum) targs[andnum('liststyle', n + 2)] = pargs[andnum('liststyle', n)] targs[andnum('group', n + 2)] = pargs[andnum('group', n)] targs[andnum('groupstyle', n + 2)] = pargs[andnum('groupstyle', n)] if v and inArray(cfg.keyword.subgroups, v) then targs[andnum('list', n + 2)] = getSubgroup(pargs, n, v) else targs[andnum('list', n + 2)] = v end elseif (k:match(cfg.pattern.colheadernum) and v ~= '') then table.insert(colheadernums, tonumber(k:match(cfg.pattern.colheadernum))) elseif (k:match(cfg.pattern.colnum) and v ~= '') then table.insert(colnums, tonumber(k:match(cfg.pattern.colnum))) elseif (k:match(cfg.pattern.colfooternum) and v ~= '') then table.insert(colfooternums, tonumber(k:match(cfg.pattern.colfooternum))) end end end table.sort(colheadernums) table.sort(colnums) table.sort(colfooternums) -- HTML table for list1 local coltable = mw.html.create( 'table' ):attr('class', 'navbox-columns-table') local row, col local tablestyle = ( (#colheadernums > 0) or (not isblank(pargs[cfg.arg.fullwidth])) ) and 'width:100%' or 'width:auto; margin-left:auto; margin-right:auto' coltable:attr('style', concatstyles({ 'border-spacing: 0px; text-align:left', tablestyle, pargs[cfg.arg.coltablestyle] or '' })) --- Header row --- if (#colheadernums > 0) then row = coltable:tag('tr') for k, n in ipairs(colheadernums) do col = row:tag('td'):attr('class', 'navbox-abovebelow') col:attr('style', concatstyles({ (k > 1) and 'border-left:2px solid #fdfdfd' or '', 'font-weight:bold', pargs[cfg.arg.colheaderstyle] or '', pargs[andnum('colheaderstyle', n)] or '' })) if tonumber(pargs[andnum('colheadercolspan', n)]) then col:attr('colspan', pargs[andnum('colheadercolspan', n)]) end col:wikitext(pargs[andnum('colheader', n)]) end end --- Main columns --- row = coltable:tag('tr'):attr('style', 'vertical-align:top') for k, n in ipairs(colnums) do if k == 1 and isblank(pargs[andnum('colheader', 1)]) and isblank(pargs[andnum('colfooter', 1)]) and isblank(pargs[cfg.arg.fullwidth]) then local nopad = inArray( {'off', '0', '0em', '0px'}, mw.ustring.gsub(pargs[cfg.arg.padding] or '', '[;%%]', '')) if not nopad then row:tag('td'):wikitext(' ') :attr('style', 'width:'..(pargs[cfg.arg.padding] or '5em')..';') end end col = row:tag('td'):attr('class', 'navbox-list') col:attr('style', concatstyles({ (k > 1) and 'border-left:2px solid #fdfdfd' or '', 'padding:0px', pargs[cfg.arg.colstyle] or '', ((n%2 == 0) and pargs[cfg.arg.evencolstyle] or pargs[cfg.arg.oddcolstyle]) or '', pargs[andnum('colstyle', n)] or '', 'width:' .. (pargs[andnum('colwidth', n)] or pargs[cfg.arg.colwidth] or '10em') })) local wt = pargs[andnum('col', n)] if wt and inArray(cfg.keyword.subgroups, wt) then local prefix = mw.ustring.gsub(cfg.arg.col_and_num,"%%d","") wt = getSubgroup(pargs, n, wt, prefix) end col:tag('div'):newline():wikitext(wt):newline() end --- Footer row --- if (#colfooternums > 0) then row = coltable:tag('tr') for k, n in ipairs(colfooternums) do col = row:tag('td'):attr('class', 'navbox-abovebelow') col:attr('style', concatstyles({ (k > 1) and 'border-left:2px solid #fdfdfd' or '', 'font-weight:bold', pargs[cfg.arg.colfooterstyle] or '', pargs[andnum('colfooterstyle', n)] or '' })) if tonumber(pargs[andnum('colfootercolspan', n)]) then col:attr('colspan', pargs[andnum('colfootercolspan', n)]) end col:wikitext(pargs[andnum('colfooter', n)]) end end -- assign table to list1 targs[andnum('list', 1)] = tostring(coltable) if isblank(pargs[andnum('colheader', 1)]) and isblank(pargs[andnum('col', 1)]) and isblank(pargs[andnum('colfooter', 1)]) then targs[andnum('list', 1)] = targs[andnum('list', 1)] .. '[[' .. cfg.pattern.without_first_col .. ']]' end -- Other parameters targs[cfg.arg.border] = pargs[cfg.arg.border] or pargs[1] targs[cfg.arg.evenodd] = (not isblank(pargs[cfg.arg.evenodd])) and pargs[cfg.arg.evenodd] or nil targs[cfg.arg.list1padding] = '0px' targs[andnum('liststyle', 1)] = 'background:transparent;color:inherit;' targs[cfg.arg.style] = concatstyles({pargs[cfg.arg.style], pargs[cfg.arg.bodystyle]}) targs[cfg.arg.tracking] = 'no' return p._navbox(targs) end -- Template entry points function p.navbox (frame, boxtype) local function readArgs(args, prefix) -- Read the arguments in the order they'll be output in, to make references -- number in the right order. local _ _ = args[prefix .. cfg.arg.title] _ = args[prefix .. cfg.arg.above] -- Limit this to 20 as covering 'most' cases (that's a SWAG) and because -- iterator approach won't work here for i = 1, 20 do _ = args[prefix .. andnum('group', i)] if inArray(cfg.keyword.subgroups, args[prefix .. andnum('list', i)]) then for _, v in ipairs(cfg.keyword.subgroups) do readArgs(args, prefix .. v .. i .. "_") end end end _ = args[prefix .. cfg.arg.below] end if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = {cfg.pattern[boxtype or 'navbox']}}) readArgs(args, "") return p['_'..(boxtype or 'navbox')](args) end p['with columns'] = function (frame) return p.navbox(frame, 'withColumns') end local q = {} q._navbox = p._withColumns q.navbox = p['with columns'] return q