Module:Navbox: Difference between revisions

    From Nonbinary Wiki
    m>Toohool
    (fix for lists in image and imageleft)
    m>Toohool
    (rewrite with htmlbuilder)
    Line 2: Line 2:
    -- This module will implement {{Navbox}}
    -- This module will implement {{Navbox}}
    --
    --
     
    local p = {}
    local p = {}
    local HtmlBuilder = require('Module:Sandbox/Toohool/HtmlBuilder')


    local gutterRow = '<tr style="height:2px;"><td></td></tr>'
    local args
    local tableRowAdded = false
    local border
    local border
    local listnums = {}
    local listnums = {}
    local ret = {}
     
    function add(...)
        local args = {...}
        for i = 1, #args do
            if args[i] then
                table.insert(ret, args[i])
            end
        end
    end
     
    function trim(s)
    function trim(s)
         return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))
         return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))
    end
    function addTableRow(tbl)
        -- If any other rows have already been added, then we add a 2px gutter row.
        if tableRowAdded then
    tbl
    .tag('tr')
    .css('height', '2px')
    .tag('td')
    end
    tableRowAdded = true
    return tbl.tag('tr')
    end
    end


    function renderTitleRow(args)
     
    --
    --  Title row
    --
    function renderTitleRow(tbl)
         if not args.title then return end
         if not args.title then return end
    local titleRow = addTableRow(tbl)
        if args.titlegroup then
        titleRow
        .tag('th')
        .attr('scope', 'row')
        .addClass('navbox-group')
        .addClass(args.titlegroupclass)
        .cssText(args.basestyle)
        .cssText(args.groupstyle)
        .cssText(args.titlegroupstyle)
        .wikitext(args.titlegroup)
        end
          
          
         add('<tr>')
         local titleCell = titleRow.tag('th').attr('scope', 'col')
       
         if args.titlegroup then
         if args.titlegroup then
            add('<th scope="row" class="navbox-group ', args.titlegroupclass, '" style="', args.basestyle, ';', args.groupstyle, ';', args.titlegroupstyle, '">', args.titlegroup, '</th><th scope="col" style="border-left:2px solid #fdfdfd;width:100%;')
        titleCell
        else
        .css('border-left', '2px solid #fdfdfd')
            add('<th scope="col" style="')
        .css('width', '100%')
         end
         end
         local colspan = 2
       
         if args.imageleft then colspan = colspan + 1 end
         local titleColspan = 2
         if args.image then colspan = colspan + 1 end
         if args.imageleft then titleColspan = titleColspan + 1 end
         if args.titlegroup then colspan = colspan - 1 end
         if args.image then titleColspan = titleColspan + 1 end
         add(args.basestyle, ';', args.titlestyle, '" class="navbox-title" colspan=', colspan, '>')
         if args.titlegroup then titleColspan = titleColspan - 1 end
     
          
        local stateLinkPlaceholder = '<span style="float:right;width:6em;">&nbsp;</span>'
        titleCell
        .cssText(args.basestyle)
        .cssText(args.titlestyle)
        .addClass('navbox-title')
        .attr('colspan', titleColspan)
    renderNavBar(titleCell)
    titleCell
    .tag('div')
    .addClass(args.titleclass)
    .css('font-size', '110%')
    .newline()
    .wikitext(args.title)
    end
    function renderNavBar(titleCell)
    local addStateLinkPlaceholder = false
         if args.navbar == 'plain' or args.navbar == 'off' or (not args.name and (border == 'subgroup' or border == 'child' or border == 'none')) then
         if args.navbar == 'plain' or args.navbar == 'off' or (not args.name and (border == 'subgroup' or border == 'child' or border == 'none')) then
             if args.navbar == 'off' then
             if args.navbar == 'off' then
                if args.state == 'plain' then add(stateLinkPlaceholder) end
            addStateLinkPlaceholder = (args.state == 'plain')
             else
             else
                if args.state ~= 'plain' then add(stateLinkPlaceholder) end
            addStateLinkPlaceholder = (args.state ~= 'plain')
             end
             end
         else
         else
             if args.name then
             if args.name then
                 add(mw.getCurrentFrame():expandTemplate{ title = 'navbar', args = {  
                 titleCell.wikitext(mw.getCurrentFrame():expandTemplate{ title = 'navbar', args = {  
                     args.name,  
                     args.name,  
                     mini = 1,  
                     mini = 1,  
    Line 53: Line 96:
                 }})
                 }})
             else
             else
                add('<span class="error" style="float:left;white-space:nowrap;">Error: No name provided</span>')
            titleCell
                 if args.state == 'plain' then add(stateLinkPlaceholder) end
            .tag('span')
            .addClass('error')
            .css('float', 'left')
            .css('white-space', 'nowrap')
            .wikitext('Error: No name provided')
                 addStateLinkPlaceholder = (args.state == 'plain')
             end
             end
         end
         end
       
        if addStateLinkPlaceholder then
        titleCell
        .tag('span')
        .css('float', 'right')
        .css('width', '6em')
        .wikitext('&nbsp;')
        end
    end


        add('<div class="', args.titleclass, '" style="font-size:110%;">')
        add(args.title)
        add('</div></th></tr>')
    end


    function renderAboveRow(args)
    --
    --  Above/Below rows
    --
    function renderAboveRow(tbl)
         if not args.above then return end
         if not args.above then return end
       
        if args.title then add(gutterRow) end
    addTableRow(tbl)
        add('<tr><td class="navbox-abovebelow ', args.aboveclass, '" style="', args.basestyle, ';', args.abovestyle, '" colspan="', getAboveBelowColspan(args), '">')
    .tag('td')
        add('<div>\n', args.above, '</div></td></tr>')
    .addClass('navbox-abovebelow')
    .addClass(args.aboveclass)
    .cssText(args.basestyle)
    .cssText(args.abovestyle)
    .attr('colspan', getAboveBelowColspan())
    .tag('div')
    .newline()
    .wikitext(args.above)
    end
    end
    function renderBelowRow(args)
     
        if args.below then
    function renderBelowRow(tbl)
            if args.title or args.above or #listnums > 0 then add(gutterRow) end
    if not args.below then return end
            add('<tr><td class="navbox-abovebelow ', args.belowclass, '" style="', args.basestyle, ';', args.belowstyle, 'colspan="', getAboveBelowColspan(args), '">')
            add('<div>\n', args.below, '</div></td></tr>')
    addTableRow(tbl)
        end
    .tag('td')
    .addClass('navbox-abovebelow')
    .addClass(args.belowclass)
    .cssText(args.basestyle)
    .cssText(args.belowstyle)
    .attr('colspan', getAboveBelowColspan())
    .tag('div')
    .newline()
    .wikitext(args.below)
    end
    end
    function getAboveBelowColspan(args)
     
    function getAboveBelowColspan()
         local ret = 2
         local ret = 2
         if args.imageleft then ret = ret + 1 end
         if args.imageleft then ret = ret + 1 end
    Line 83: Line 155:
         return ret
         return ret
    end
    end
     
    function renderFirstListRow(args)
    --
    --  List rows
    --
    function renderFirstListRow(tbl)
         if not args.list1 then return end
         if not args.list1 then return end
       
        if args.title or args.above then add(gutterRow) end
    local row = addTableRow(tbl)
        add('<tr>')
         if args.imageleft then
         if args.imageleft then
            add('<td class="navbox-image ', args.imageclass, '" style="width:0%;padding:0px 2px 0px 0px;', args.imageleftstyle, '"')
        row
            add(' rowspan=', (2 * #listnums - 1), '><div>\n', args.imageleft, '</div></td>')
        .tag('td')
        .addClass('navbox-image')
        .addClass(args.imageclass)
        .css('width', '0%')
        .css('padding', '0px 2px 0px 0px')
        .cssText(args.imageleftstyle)
        .attr('rowspan', 2 * #listnums - 1)
        .tag('div')
        .newline()
        .wikitext(args.imageleft)
         end
         end
        if args.group1 then
        local groupCell = row.tag('th')
       
        groupCell
      .attr('scope', 'row')
      .addClass('navbox-group')
      .addClass(args.groupclass)
      .cssText(args.basestyle)
     
      if args.groupwidth then
      groupCell.css('width', args.groupwidth)
      end


    groupCell
    .cssText(args.groupstyle)
    .cssText(args.group1style)
    .wikitext(args.group1)
        end
       
        local listCell = row.tag('td')
       
         if args.group1 then
         if args.group1 then
            add('<th scope="row" class="navbox-group ', args.groupclass, '" style="', args.basestyle, ';')
        listCell
            if args.groupwidth then add('width:', args.groupwidth, ';') end
        .css('text-align', 'left')
            add(args.groupstyle, ';', args.group1style, '">')
        .css('border-left-width', '2px')
            add(args.group1, '</th>')
        .css('border-left-style', 'solid')
            add('<td style="text-align:left;border-left-width:2px;border-left-style:solid;')
         else
         else
            add('<td colspan=2 style="')
        listCell.attr('colspan', 2)
         end
         end
         if not args.groupwidth then add('width:100%;') end
       
        add('padding:0px;', args.liststyle, ';', args.oddstyle, ';', args.list1style, '" class="navbox-list navbox-')
         if not args.groupwidth then  
        if args.evenodd == 'swap' then
        listCell.css('width', '100%')
            add('even')
        else
            add(args.evenodd or 'odd')
         end
         end
         add(' ', args.listclass, '">')
     
        add('<div style="padding:', args.list1padding or args.listpadding or '0em 0.25em', '">\n')
        local evenOdd = args.evenodd or 'odd'
        add(args.list1)
         if args.evenodd == 'swap' then evenOdd = 'even' end
        add('</div></td>')
       
        listCell
        .css('padding', '0px')
        .cssText(args.liststyle)
        .cssText(args.oddstyle)
        .cssText(args.list1style)
        .addClass('navbox-list')
        .addClass('navbox-' .. evenOdd)
        .addClass(args.listclass)
        .tag('div')
        .css('padding', args.list1padding or args.listpadding or '0em 0.25em')
        .newline()
        .wikitext(args.list1)


         if args.image then
         if args.image then
            add('<td class="navbox-image ', args.imageclass, '" style="width:0%;padding:0px 0px 0px 2px;', args.imagestyle, '" ')
        row
            add(' rowspan=', (2 * #listnums - 1), '>')
        .tag('td')
            add('<div>\n', args.image, '</div></td>')
        .addClass('navbox-image')
        .addClass(args.imageclass)
        .css('width', '0%')
        .css('padding', '0px 0px 0px 2px')
        .cssText(args.imagestyle)
        .attr('rowspan', 2 * #listnums - 1)
        .tag('div')
        .newline()
        .wikitext(args.image)
        end
    end
    function renderNthListRow(tbl, listnum)
    local row = addTableRow(tbl)
        if args['group' .. listnum] then
        local groupCell = row.tag('th')
       
        groupCell
      .attr('scope', 'row')
      .addClass('navbox-group')
      .addClass(args.groupclass)
      .cssText(args.basestyle)
     
      if args.groupwidth then
      groupCell.css('width', args.groupwidth)
      end
     
      groupCell
      .cssText(args.groupstyle)
      .cssText(args['group' .. listnum .. 'style'])
      .wikitext(args['group' .. listnum])
         end
         end
          
          
         add('</tr>')
         local listCell = row.tag('td')
    end


    function renderNthListRow(args, listnum)
        if args.title or args.above or args.list1 then
            add(gutterRow)
        end
        add('<tr>')
         if args['group' .. listnum] then
         if args['group' .. listnum] then
            add('<th scope="row" class="navbox-group ', args.groupclass, '" style="', args.basestyle, ';')
        listCell
            if args.groupwidth then add('width:', args.groupwidth, ';') end
        .css('text-align', 'left')
            add(args.groupstyle, ';', args['group' .. listnum .. 'style'], '">')
        .css('border-left-width', '2px')
            add(args['group' .. listnum])
        .css('border-left-style', 'solid')
            add('</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;')
         else
         else
            add('<td colspan=2 style="')
        listCell.attr('colspan', 2)
        end
       
        if not args.groupwidth then
        listCell.css('width', '100%')
         end
         end
        if not args.groupwidth then add('width:100%;') end
          
          
         local isOdd = (listnum % 2) == 1
         local isOdd = (listnum % 2) == 1
         local rowstyle = args.evenstyle
         local rowstyle = args.evenstyle
         if isOdd then rowstyle = args.oddstyle end
         if isOdd then rowstyle = args.oddstyle end
           
        add('padding:0px;', args.liststyle, ';', rowstyle, ';', args['list' .. listnum .. 'style'], '" ')
    local evenOdd
        add('class="navbox-list navbox-')
    if args.evenodd == 'swap' then
        if args.evenodd == 'swap' then
    if isOdd then evenOdd = 'even' else evenOdd = 'odd' end
            if isOdd then add('even') else add('odd') end
    else
        else
    if isOdd then evenOdd = args.evenodd or 'odd' else evenOdd = args.evenodd or 'even' end
            if isOdd then add(args.evenodd or 'odd') else add(args.evenodd or 'even') end
    end
        end
         add(' ', args.listclass, '">')
         listCell
       
        .css('padding', '0px')
        add('<div style="padding:', args.listpadding or '0em 0.25em', '">\n', args['list' .. listnum], '</div></td></tr>')
        .cssText(args.liststyle)
        .cssText(rowstyle)
        .cssText(args['list' .. listnum .. 'style'])
        .addClass('navbox-list')
        .addClass('navbox-' .. evenOdd)
        .addClass(args.listclass)
        .tag('div')
        .css('padding', args.listpadding or '0em 0.25em')
        .newline()
        .wikitext(args['list' .. listnum])
    end
    end


    function p._navbox(args)
     
        for k, v in pairs(args) do
    --
            local listnum = ('' .. k):match('^list(%d+)$')
    --  Main navbox tables
            if listnum then table.insert(listnums, tonumber(listnum)) end
    --
        end
    function renderMainTable()
        table.sort(listnums)
    local tbl = HtmlBuilder.create('table')
       
    .attr('cellspacing', 0)
        border = trim(args.border or args[1] or '')
    .addClass('nowraplinks')
        if border == 'subgroup' or border == 'child' then
    .addClass(args.bodyclass)
            add('</div>')
        elseif border ~= 'none' then
            add('<table cellspacing="0" class="navbox" style="border-spacing:0;', args.bodystyle, ';', args.style, '"><tr><td style="padding:2px;">')
        end
       
        add('<table cellspacing="0" class="nowraplinks ', args.bodyclass, ' ')
       
         if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
         if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
            add('collapsible ', args.state or 'autocollapse', ' ')
        tbl
        .addClass('collapsible')
        .addClass(args.state or 'autocollapse')
         end
         end
       
    tbl.css('border-spacing', 0)
         if border == 'subgroup' or border == 'child' or border == 'none' then
         if border == 'subgroup' or border == 'child' or border == 'none' then
            add('navbox-subgroup" style="border-spacing:0;', args.bodystyle, ';', args.style)
        tbl
         else
        .addClass('navbox-subgroup')
            add('navbox-inner" style="border-spacing:0;background:transparent;color:inherit')
        .cssText(args.bodyStyle)
        .cssText(args.style)
         else -- regular navobx - bodyStyle and style will be applied to the wrapper table
        tbl
        .addClass('navbox-inner')
        .css('background', 'transparent')
        .css('color', 'inherit')
         end
         end
         add(';', args.innerstyle, ';">')
         tbl.cssText(args.innerstyle)
       
         renderTitleRow(args)
         renderTitleRow(tbl)
         renderAboveRow(args)
         renderAboveRow(tbl)
         renderFirstListRow(args)
         renderFirstListRow(tbl)
     
         -- render lists 2 through N
         -- render lists 2 through N
         for i, listnum in ipairs(listnums) do
         for i, listnum in ipairs(listnums) do
             if listnum > 1 then
             if listnum > 1 then
                 renderNthListRow(args, listnum)  
                 renderNthListRow(tbl, listnum)  
             end
             end
         end
         end
        renderBelowRow(tbl)
       
        return tbl
    end
    function p._navbox(navboxArgs)
    args = navboxArgs
        for k, v in pairs(args) do
            local listnum = ('' .. k):match('^list(%d+)$')
            if listnum then table.insert(listnums, tonumber(listnum)) end
        end
        table.sort(listnums)
        border = trim(args.border or args[1] or '')


        renderBelowRow(args)
    -- render the main body of the navbox
    local tbl = renderMainTable()


        add('</table>')
    -- render the appropriate wrapper around the navbox, depending on the border param
       
    local res = HtmlBuilder.create()
         if border == 'subgroup' or border == 'child' then
         if border == 'subgroup' or border == 'child' then
             add('<div>')
             res
          .tag('/div', {unclosed = true})
          .done()
          .node(tbl)
          .tag('div', {unclosed = true})
         elseif border ~= 'none' then
         elseif border ~= 'none' then
            add('</td></tr></table>')
        res
        .tag('table')
      .attr('cellspacing', 0)
        .addClass('navbox')
        .css('border-spacing', 0)
        .cssText(args.bodystyle)
        .cssText(args.style)
        .tag('tr')
        .tag('td')
        .css('padding', '2px')
        .node(tbl)
         end
         end
     
         -- TODO: add tracking categories
         -- TODO: add tracking categories
       
         return table.concat(ret, '')
         return tostring(res)
    end
    end
     
    function p.navbox(frame)
    function p.navbox(frame)
         return p._navbox(frame:getParent().args)
         return p._navbox(frame:getParent().args)
    end
    end
     
    return p
    return p

    Revision as of 04:36, 1 March 2013

    Documentation for this module may be created at Module:Navbox/doc

    --
    -- This module will implement {{Navbox}}
    --
     
    local p = {}
     
    local HtmlBuilder = require('Module:Sandbox/Toohool/HtmlBuilder')
    
    local args
    local tableRowAdded = false
    local border
    local listnums = {}
     
    function trim(s)
        return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))
    end
     
    function addTableRow(tbl)
        -- If any other rows have already been added, then we add a 2px gutter row.
        if tableRowAdded then
    		tbl
    			.tag('tr')
    				.css('height', '2px')
    				.tag('td')
    	end
    	
    	tableRowAdded = true
    	
    	return tbl.tag('tr')
    end
    
    
    --
    --   Title row
    --
    function renderTitleRow(tbl)
        if not args.title then return end
     
     	local titleRow = addTableRow(tbl)
     	
        if args.titlegroup then
        	titleRow
        		.tag('th')
        			.attr('scope', 'row')
        			.addClass('navbox-group')
        			.addClass(args.titlegroupclass)
        			.cssText(args.basestyle)
        			.cssText(args.groupstyle)
        			.cssText(args.titlegroupstyle)
        			.wikitext(args.titlegroup)
        end
        
        local titleCell = titleRow.tag('th').attr('scope', 'col')
        		
        if args.titlegroup then
        	titleCell
        		.css('border-left', '2px solid #fdfdfd')
        		.css('width', '100%')
        end
        
        local titleColspan = 2
        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')
     			.addClass(args.titleclass)
     			.css('font-size', '110%')
     			.newline()
     			.wikitext(args.title)
    end
     
    function renderNavBar(titleCell)
     	local addStateLinkPlaceholder = false
        if args.navbar == 'plain' or args.navbar == 'off' or (not args.name and (border == 'subgroup' or border == 'child' or border == 'none')) then
            if args.navbar == 'off' then
            	addStateLinkPlaceholder = (args.state == 'plain')
            else
            	addStateLinkPlaceholder = (args.state ~= 'plain')
            end
        else
            if args.name then
                titleCell.wikitext(mw.getCurrentFrame():expandTemplate{ title = 'navbar', args = { 
                    args.name, 
                    mini = 1, 
                    fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') ..  ';background:none transparent;border:none;'
                }})
            else
            	titleCell
            		.tag('span')
            			.addClass('error')
            			.css('float', 'left')
            			.css('white-space', 'nowrap')
            			.wikitext('Error: No name provided')
                addStateLinkPlaceholder = (args.state == 'plain')
            end
        end
        
        if addStateLinkPlaceholder then
        	titleCell
        		.tag('span')
        			.css('float', 'right')
        			.css('width', '6em')
        			.wikitext('&nbsp;')
        end
    end
    
    
    --
    --   Above/Below rows
    --
    function renderAboveRow(tbl)
        if not args.above then return end
     
     	addTableRow(tbl)
    		.tag('td')
    			.addClass('navbox-abovebelow')
    			.addClass(args.aboveclass)
    			.cssText(args.basestyle)
    			.cssText(args.abovestyle)
     			.attr('colspan', getAboveBelowColspan())
     			.tag('div')
     				.newline()
     				.wikitext(args.above)
    end
    
    function renderBelowRow(tbl)
    	if not args.below then return end
    	
    	addTableRow(tbl)
    		.tag('td')
    			.addClass('navbox-abovebelow')
    			.addClass(args.belowclass)
    			.cssText(args.basestyle)
    			.cssText(args.belowstyle)
    			.attr('colspan', getAboveBelowColspan())
    			.tag('div')
    				.newline()
    				.wikitext(args.below)
    end
    
    function getAboveBelowColspan()
        local ret = 2
        if args.imageleft then ret = ret + 1 end
        if args.image then ret = ret + 1 end
        return ret
    end
     
     
    --
    --   List rows
    --
    function renderFirstListRow(tbl)
        if not args.list1 then return end
     
     	local row = addTableRow(tbl)
     	
        if args.imageleft then
        	row
        		.tag('td')
        			.addClass('navbox-image')
        			.addClass(args.imageclass)
        			.css('width', '0%')
        			.css('padding', '0px 2px 0px 0px')
        			.cssText(args.imageleftstyle)
        			.attr('rowspan', 2 * #listnums - 1)
        			.tag('div')
        				.newline()
        				.wikitext(args.imageleft)
        end
     
        if args.group1 then
        	local groupCell = row.tag('th')
        	
        	groupCell
       			.attr('scope', 'row')
       			.addClass('navbox-group')
       			.addClass(args.groupclass)
       			.cssText(args.basestyle)
       			
       		if args.groupwidth then
       			groupCell.css('width', args.groupwidth)
       		end
    
    		groupCell
    			.cssText(args.groupstyle)
    			.cssText(args.group1style)
    			.wikitext(args.group1)
        end
        
        local listCell = row.tag('td')
        
        if args.group1 then
        	listCell
        		.css('text-align', 'left')
        		.css('border-left-width', '2px')
        		.css('border-left-style', 'solid')
        else
        	listCell.attr('colspan', 2)
        end
        
        if not args.groupwidth then 
        	listCell.css('width', '100%')
        end
    
        local evenOdd = args.evenodd or 'odd'
        if args.evenodd == 'swap' then evenOdd = 'even' end
        
        listCell
        	.css('padding', '0px')
        	.cssText(args.liststyle)
        	.cssText(args.oddstyle)
        	.cssText(args.list1style)
        	.addClass('navbox-list')
        	.addClass('navbox-' .. evenOdd)
        	.addClass(args.listclass)
        	.tag('div')
        		.css('padding', args.list1padding or args.listpadding or '0em 0.25em')
        		.newline()
        		.wikitext(args.list1)
    
        if args.image then
        	row
        		.tag('td')
        			.addClass('navbox-image')
        			.addClass(args.imageclass)
        			.css('width', '0%')
        			.css('padding', '0px 0px 0px 2px')
        			.cssText(args.imagestyle)
        			.attr('rowspan', 2 * #listnums - 1)
        			.tag('div')
        				.newline()
        				.wikitext(args.image)
        end
    end
     
    function renderNthListRow(tbl, listnum)
    	local row = addTableRow(tbl)
    	
        if args['group' .. listnum] then
        	local groupCell = row.tag('th')
        	
        	groupCell
       			.attr('scope', 'row')
       			.addClass('navbox-group')
       			.addClass(args.groupclass)
       			.cssText(args.basestyle)
       			
       		if args.groupwidth then
       			groupCell.css('width', args.groupwidth)
       		end
       		
       		groupCell
       			.cssText(args.groupstyle)
       			.cssText(args['group' .. listnum .. 'style'])
       			.wikitext(args['group' .. listnum])
        end
        
        local listCell = row.tag('td')
    
        if args['group' .. listnum] then
        	listCell
        		.css('text-align', 'left')
        		.css('border-left-width', '2px')
        		.css('border-left-style', 'solid')
        else
        	listCell.attr('colspan', 2)
        end
        
        if not args.groupwidth then 
        	listCell.css('width', '100%')
        end
        
        local isOdd = (listnum % 2) == 1
        local rowstyle = args.evenstyle
        if isOdd then rowstyle = args.oddstyle end
     
     	local evenOdd
     	if args.evenodd == 'swap' then
     		if isOdd then evenOdd = 'even' else evenOdd = 'odd' end
     	else
    		if isOdd then evenOdd = args.evenodd or 'odd' else evenOdd = args.evenodd or 'even' end
    	end
    	
        listCell
        	.css('padding', '0px')
        	.cssText(args.liststyle)
        	.cssText(rowstyle)
        	.cssText(args['list' .. listnum .. 'style'])
        	.addClass('navbox-list')
        	.addClass('navbox-' .. evenOdd)
        	.addClass(args.listclass)
        	.tag('div')
        		.css('padding', args.listpadding or '0em 0.25em')
        		.newline()
        		.wikitext(args['list' .. listnum])
    end
    
    
    --
    --   Main navbox tables
    --
    function renderMainTable()
     	local tbl = HtmlBuilder.create('table')
     		.attr('cellspacing', 0)
     		.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
     
     	tbl.css('border-spacing', 0)
        if border == 'subgroup' or border == 'child' or border == 'none' then
        	tbl
        		.addClass('navbox-subgroup')
        		.cssText(args.bodyStyle)
        		.cssText(args.style)
        else -- regular navobx - bodyStyle and style will be applied to the wrapper table
        	tbl
        		.addClass('navbox-inner')
        		.css('background', 'transparent')
        		.css('color', 'inherit')
        end
        tbl.cssText(args.innerstyle)
     
        renderTitleRow(tbl)
        renderAboveRow(tbl)
        renderFirstListRow(tbl)
     
        -- render lists 2 through N
        for i, listnum in ipairs(listnums) do
            if listnum > 1 then
                renderNthListRow(tbl, listnum) 
            end
        end
     
        renderBelowRow(tbl)
        
        return tbl
    end
    
    function p._navbox(navboxArgs)
    	args = navboxArgs
    	
        for k, v in pairs(args) do
            local listnum = ('' .. k):match('^list(%d+)$')
            if listnum then table.insert(listnums, tonumber(listnum)) end
        end
        table.sort(listnums)
     
        border = trim(args.border or args[1] or '')
    
    	-- render the main body of the navbox
     	local tbl = renderMainTable()
    
    	-- render the appropriate wrapper around the navbox, depending on the border param
    	local res = HtmlBuilder.create()
        if border == 'subgroup' or border == 'child' then
            res
           		.tag('/div', {unclosed = true})
           		.done()
           		.node(tbl)
           		.tag('div', {unclosed = true})
        elseif border ~= 'none' then
        	res
        		.tag('table')
       				.attr('cellspacing', 0)
        			.addClass('navbox')
        			.css('border-spacing', 0)
        			.cssText(args.bodystyle)
        			.cssText(args.style)
        			.tag('tr')
        				.tag('td')
        					.css('padding', '2px')
        					.node(tbl)
        end
     
        -- TODO: add tracking categories
     
        return tostring(res)
    end
     
    function p.navbox(frame)
        return p._navbox(frame:getParent().args)
    end
     
    return p