Module:Ahnentafel

-- -- implements Template:ahnentafel -- local p = {}

function p.chart( frame ) local args = frame.args[1] and frame.args or frame:getParent.args local align = (args['align'] or ''):lower local style = args['style'] or '' -- style for floating if (align == 'right') then style = 'float:right;' .. style elseif (align == 'left') then style = 'float:left;' .. style elseif (align == 'center') then style = 'margin-left:auto; margin-right:auto;' .. style end -- compute the number of levels local maxnum = 0 for k, v in pairs( args ) do		if k and type(k) == 'number' or (type(k) == 'string' and (tonumber(k) or 0) > 0) then if tonumber(k) > maxnum then maxnum = k			end end end local levels = math.ceil(math.log(maxnum+1)/math.log(2)) local cells = math.pow(2, levels) - 1 -- add a collapsing outer container if required local res = mw.html.create('') local innercell = res if args['collapsed'] or args['title'] then local r = res:tag('table') local t = args['title'] or ('Ancestors of ' .. frame:getParent:getTitle) r:addClass('collapsible') if args['collapsed'] and args['collapsed'] == 'no' then r:addClass('expanded') else r:addClass('collapsed') end local f = args['float'] or '' if f == 'left' then r:css('margin', '0.3em 0 0.3em 1em') r:css('float', 'left') r:css('clear', args['clear'] or 'left') r:css('min-width', args['min-width'] or args['width'] or '33em') elseif f == 'right' then r:css('margin', '0.3em 1em 0.3em 1em') r:css('float', 'right') r:css('clear', args['clear'] or 'right') r:css('min-width', args['min-width'] or args['width'] or '33em') else r:css('margin', '0.3em auto auto') r:css('clear', args['clear'] or 'none') r:css('min-width', args['min-width'] or args['width'] or '70em') end r:css('width', args['width'] or 'auto') r:css('font-size', '88%') r:css('border', '1px solid #aaa') r:tag('tr'):tag('th') :css('padding', '0.2em 0.3em 0.2em 4.3em') :css('background', 'none') :css('width', args['width'] or 'auto') :wikitext(t) innercell = r:tag('tr'):tag('td') :css('text-align', args['text-align'] or 'center') end

-- add content before the table if required if args['headnotes'] then innercell:wikitext(args['headnotes']) end

-- build the inner table local root = innercell:tag('table') root:css('border-spacing', '0') :cssText(style) local rows = {} for k = 1,2*(2*cells+1) do		rows[k] = root:tag('tr'):css('text-align', 'center') rows[k]:tag('td'):wikitext(' ') end local cellnum = 0 for l = 1,levels do local levelstyle = args['boxstyle_' .. l] or '' if args['boxstyle'] and args['boxstyle'] ~= '' then levelstyle = args['boxstyle'] .. ';' .. levelstyle end levelstyle = 'padding:0 0.2em;' .. levelstyle levelstyle = 'border:' .. (args['border_' .. l] or args['border'] or '2') .. 'px solid black;' .. levelstyle local cellsk = math.pow(2,l-1) local offset = 1 for k = 1,cellsk do			cellnum = cellnum + 1 -- top padding rows[offset] :tag('td') :attr('colspan', (l < levels) and 2 or 4) :attr('rowspan', 2*(math.pow(2,levels-l+1)-1)) :wikitext(' ') -- top branch if l < levels then rows[offset] :tag('td') :attr('rowspan', math.pow(2,levels-l+1)-1) :wikitext(' ') rows[offset + math.pow(2,levels-l+1)-1] :tag('td') :attr('rowspan', math.pow(2,levels-l+1)-1) :css('border-top', args[2*cellnum] and '#000 solid 1px') :css('border-left', args[2*cellnum] and '#000 solid 1px') :wikitext(' ') end offset = offset + 2*(math.pow(2,levels-l+1)-1) -- cell rows[offset] :tag('td') :attr('colspan',4) :attr('rowspan',2) :cssText(args[cellnum] and levelstyle) :wikitext(args[cellnum] or ' ') if l < levels then rows[offset] :tag('td') :attr('rowspan', 2) :attr('colspan', 3) :wikitext(' ') end offset = offset + 2 -- bottom padding rows[offset] :tag('td') :attr('colspan', (l < levels) and 2 or 4) :attr('rowspan', 2*(math.pow(2,levels-l+1)-1)) :wikitext(' ') -- bottom branch if l < levels then rows[offset] :tag('td') :attr('rowspan', math.pow(2,levels-l+1)-1) :css('border-bottom', args[2*cellnum+1] and '#000 solid 1px') :css('border-left', args[2*cellnum+1] and '#000 solid 1px') :wikitext(' ') rows[offset + math.pow(2,levels-l+1)-1] :tag('td') :attr('rowspan', math.pow(2,levels-l+1)-1) :wikitext(' ') end offset = offset + 2*(math.pow(2,levels-l+1)-1) offset = offset + 2 end end -- add content after the table if required if args['footnotes'] then innercell:wikitext(args['footnotes']) end return tostring(res) end

return p