Module:Ahnentafel/sandbox
MyWikiBiz, Author Your Legacy — Friday November 15, 2024
Jump to navigationJump to searchDocumentation for this module may be created at Module:Ahnentafel/sandbox/doc
-- -- implements [[Template:ahnentafel]] -- local p = {} -- templatestyles local templatestyles = 'Ahnentafel/styles.css' -- table of row pointers local rows = {} -- first and last indices in rows table local rowbegin, rowend = -1,-1 -- tracking local tcats = '' -- args local args = {} -- inner cell local innerfs = '88%' local innercell = nil -- right to left? local rtl = false local function checkparameters(k) if (k == 'align' or k == 'collapsed' or k == 'collapsible' or k == 'title' or k == 'float' or k == 'clear' or k == 'ref' or k == 'headnotes' or k == 'headnotes_align' or k == 'rtl' or k == 'footnotes' or k == 'footnotes_align' or k == 'width' or k == 'min-width' or k == 'text-align') then return end if (k == 'boxstyle' or k == 'style' or k == 'border') then tcats = tcats .. '[[Category:Pages using ahnentafel with ' .. k .. ']]' return end if k:find('^boxstyle_[1-8]$') then return end if k:find('^color_[1-8]$') then return end if k:find('^border_[1-8]$') then return end if k:find('^r_[1-9][0-9]*$') then return end k = mw.ustring.gsub(k, '[^%w\-_ ]', '?') tcats = tcats .. '[[Category:Pages using ahnentafel with unknown parameters|' .. k .. ' ]]' end local function addcell(r, rspan, cspan, t, s, c) if ((r + rspan - 1) < rowbegin) or (r > rowend) then -- completely out of range; do nothing return elseif r < rowbegin then -- partially out of range, adjust rspan = rspan - (rowbegin - r) r = rowbegin elseif (r + rspan - 1) > rowend then -- partially out of range, adjust rspan = rowend + 1 - r end if rspan > 0 then local c = mw.html.create('td') :attr('rowspan', (rspan > 1) and rspan or nil) :attr('colspan', (cspan > 1) and cspan or nil) :css('background', 'cornsilk') :cssText(s) :addClass(c) :wikitext(t) if rtl then table.insert(rows[r], 1, tostring(c)) else table.insert(rows[r], tostring(c)) end end end local function float_style() -- style for floating local align = (args['align'] or ''):lower() if (align == 'right') then return 'float:right;' elseif (align == 'left') then return 'float:left;' elseif (align == 'center') then return 'margin-left:auto; margin-right:auto;' else return '' end end local function add_outer_container(res) -- inner = outer (default) innercell = res local yesno = require('Module:Yesno') if args['collapsed'] and args['collapsed'] ~= '' then args['collapsible'] = 'yes' end if args['title'] and args['title'] ~= '' then args['collapsible'] = 'yes' if yesno(args['collapsed'] or 'no') then args['collapsed'] = 'yes' else args['collapsed'] = 'no' end end if yesno(args['collapsible'] or 'no') then local r = res:tag('table') local t = args['title'] or ('Ancestors of ' .. mw.title.getCurrentTitle().text) r:addClass('collapsible') if yesno(args['collapsed'] or 'yes') then r:addClass('collapsed') end local f = args['float'] or '' if f == 'left' then r:css('margin', '0.3em 1em 0.3em 0') 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 0 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') elseif f == 'none' then r:css('margin', '0.3em 0') r:css('min-width', args['min-width'] or args['width'] or '60em') else r:css('margin', '0.3em auto') r:css('clear', args['clear'] or 'none') r:css('min-width', args['min-width'] or args['width'] or '60em') 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 .. (args['ref'] or '')) innercell = r:tag('tr'):tag('td') :css('text-align', args['text-align'] or 'center') innerfs = nil args['ref'] = nil end end local function add_headnotes() if args['headnotes'] then if args['headnotes_align'] then innercell:tag('div') :css('width','100%') :css('text-align',args['headnotes_align']) :wikitext(args['headnotes']) else innercell:wikitext(args['headnotes']) end end end local function add_footnotes() if args['footnotes'] or args['ref'] then if args['footnotes_align'] then innercell:tag('div') :css('width','100%') :css('text-align',args['footnotes_align']) :wikitext(args['footnotes']) else innercell:wikitext(args['ref']) innercell:wikitext(args['footnotes']) end end end local function process_args() -- compute the number of levels and track unsupported parameters local maxnum = 0 newargs = {} 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 elseif (k and type(k) == 'string') then if k:find('^r_[1-9][0-9]*$') then args[k] = nil k = mw.ustring.gsub(k, '^r_([1-9][0-9]*)$', '%1') k = tonumber(k) if k > maxnum then maxnum = k end newargs[k] = v else checkparameters(k) end end end for k,v in pairs(newargs) do args[k] = v end -- limit the number of levels maxnum = (maxnum > 1023) and 1023 or maxnum local levels = math.ceil(math.log(maxnum+1)/math.log(2)) local cells = math.pow(2, levels) - 1 -- "fill in" missing boxes for k=cells,2,-1 do local j = math.floor(k/2) if args[k] and args[k] ~= '' then if args[j] == nil or args[j] == '' then args[j] = ' ' -- single space end end end return cells, levels end function p.list( frame ) local colors = {'#fcc', 'silver', '#ffc', '#bfc', '#9fe', '#ffc', '#bfc', '#9fe'} local getArgs = require('Module:Arguments').getArgs args = getArgs(frame) -- inner style local style = float_style() .. (args['style'] or '') -- compute number of levels and cells and add empty cells local cells, levels = process_args() -- add a collapsing outer container if required local res = mw.html.create('') add_outer_container(res) -- add content before the table if required add_headnotes() -- build the inner div local root = innercell:tag('div') root:addClass('treeview') :css('font-size', innerfs) :css('text-align', 'left') :cssText(style) rows[1] = root:tag('ul'):tag('li') crows = {} 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 local cellsk = math.pow(2,l-1) local offset = 1 for k = 1,cellsk do cellnum = cellnum + 1 -- cell if args[cellnum] then rows[k] :tag('span') :css('background-color', colors[l]) :cssText(levelstyle) :wikitext(cellnum .. '. ' .. args[cellnum]) local ul if args[2*cellnum] or args[2*cellnum + 1] then ul = rows[k]:tag('ul') end if args[2*cellnum] then crows[2*(k-1) + 1] = ul:tag('li') end if args[2*cellnum + 1] then crows[2*(k-1) + 2] = ul:tag('li'):addClass('lastline') end end end rows = crows crows = {} end -- add content after the table if required add_footnotes() return tostring(res) .. tcats end function p.chart( frame ) local getArgs = require('Module:Arguments').getArgs args = getArgs(frame) -- right to left? rtl = (args['rtl'] and args['rtl'] ~= '') and true or false -- inner style local style = float_style() .. (args['style'] or '') -- compute number of levels and cells and add empty cells local cells, levels = process_args() -- add a collapsing outer container if required local res = mw.html.create('') add_outer_container(res) -- add content before the table if required add_headnotes() local topbranch = 'border-top:#000 solid 1px; border-' .. (rtl and 'right' or 'left') .. ':#000 solid 1px;' local botbranch = 'border-bottom:#000 solid 1px; border-' .. (rtl and 'right' or 'left') .. ':#000 solid 1px;' -- compute the first and last row number rowbegin = 2*cells+1 rowend = 2*cells+2 local cellnum = 0 for l = 1,levels do local cellsk = math.pow(2,l-1) local offset = 1 for k = 1,cellsk do cellnum = cellnum + 1 offset = offset + 2*(math.pow(2,levels-l+1)-1) if args[cellnum] and args[cellnum] ~= '' then rowbegin = (offset < rowbegin) and offset or rowbegin rowend = ((offset+1) > rowend) and (offset+1) or rowend end if args[cellnum] and args[cellnum] == '' then args[cellnum] = nil end offset = offset + 2*(math.pow(2,levels-l+1)-1) + 4 end end -- build the inner table local root = innercell:tag('table') root:css('border-collapse', 'separate') :css('border-spacing', '0') :css('line-height', '130%') :css('font-size', innerfs) :cssText(style) -- initialize the rows with 1 by 1 blank cells for k = rowbegin, (rowend+1) do rows[k] = {} table.insert(rows[k], tostring(mw.html.create('td'):wikitext(' '))) end -- add a blank row of cells to assist with alignment for k = 1,(3*levels + 1) do table.insert(rows[rowend+1], tostring(mw.html.create('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 = 'height:0.5em; padding:0 0.2em;' .. levelstyle levelstyle = 'border:' .. (args['border_' .. l] or args['border'] or '1') .. 'px solid black;' .. levelstyle local cellsk = math.pow(2,l-1) local offset = 1 for k = 1,cellsk do cellnum = cellnum + 1 -- top padding addcell(offset, math.pow(2,levels-l+1)-1, (l < levels) and 2 or 4, ' ', 'background-color:silver') addcell(offset + math.pow(2,levels-l+1)-1, math.pow(2,levels-l+1)-1, (l < levels) and 2 or 4, ' ', 'background-color:pink') -- top branch if l < levels then addcell(offset, math.pow(2,levels-l+1)-2, 1, ' ', 'background-color:lightblue') addcell(offset + math.pow(2,levels-l+1)-2, 1, 1, ' ', 'background-color:lightblue') addcell(offset + math.pow(2,levels-l+1)-1, math.pow(2,levels-l+1)-1, 1, ' ', args[2*cellnum] and topbranch or nil) end offset = offset + 2*(math.pow(2,levels-l+1)-1) -- cell addcell(offset, 2, 4, args[cellnum] or ' ', args[cellnum] and levelstyle or nil) if l < levels then addcell(offset, 2, 3 + 4*(levels - l - 1), ' ', 'background-color:yellow') end offset = offset + 2 -- bottom padding addcell(offset + math.pow(2,levels-l+1)-1, math.pow(2,levels-l+1)-1, (l < levels) and 2 or 4, ' ', 'background-color:lime') addcell(offset, math.pow(2,levels-l+1)-1, (l < levels) and 2 or 4, ' ', 'background-color:magenta') -- bottom branch if l < levels then addcell(offset, math.pow(2,levels-l+1)-1, 1, ' ', args[2*cellnum+1] and botbranch or nil) addcell(offset + math.pow(2,levels-l+1)-1, math.pow(2,levels-l+1)-1, 1, ' ', 'background-color:steelblue') end offset = offset + 2*(math.pow(2,levels-l+1)-1) + 2 end end -- finalize the inner table for k = rowbegin, (rowend+1) do root:tag('tr'):css('text-align', 'center'):wikitext(table.concat(rows[k], '')) end -- add content after the table if required add_footnotes() return tostring(res) .. tcats end return p