Jump to content

Module:Ahnentafel/sandbox

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Frietjes (talk | contribs) at 15:51, 26 March 2018 (Created page with '-- -- implements Template:ahnentafel -- local p = {} function p.chart( frame ) local args = frame.args[1] and frame.args or frame:getParent().args local a...'). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
--
-- 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 ' .. mw.title.getCurrentTitle().text)
		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