ماڊيول:Ahnentafel
ڏيک
Documentation for this module may be created at ماڊيول:Ahnentafel/doc
-- Module:Ahnentafel (dependency-free)
local p = {}
local rows = {}
local rowbegin, rowend = -1,-1
local tcats = ''
-- simple yes/no (replacement for Module:Yesno)
local function yesno(v)
if v == nil then return false end
if type(v) == 'boolean' then return v end
v = tostring(v):lower():gsub('^%s+', ''):gsub('%s+$', '')
if v == '' then return false end
if v == 'no' or v == 'n' or v == '0' or v == 'false' then return false end
return true
end
-- simple getArgs (replacement for Module:Arguments)
local function getArgs(frame)
local args = {}
local function add(t)
if not t then return end
for k, v in pairs(t) do
if v ~= nil then args[k] = v end
end
end
add(frame.args)
local parent = frame:getParent()
if parent then add(parent.args) end
return args
end
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 == '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('^border_[1-8]$') 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)
if ((r + rspan - 1) < rowbegin) or (r > rowend) then
return
elseif r < rowbegin then
rspan = rspan - (rowbegin - r)
r = rowbegin
elseif (r + rspan - 1) > rowend then
rspan = rowend + 1 - r
end
if rspan > 0 then
rows[r]:tag('td')
:attr('rowspan', (rspan > 1) and rspan or nil)
:attr('colspan', (cspan > 1) and cspan or nil)
:cssText(s)
:wikitext(t)
end
end
function p.chart(frame)
local args = getArgs(frame)
local align = (args['align'] or ''):lower()
local style = args['style'] or ''
local topbranch = 'border-top:#000 solid 1px; border-left:#000 solid 1px;'
local botbranch = 'border-bottom:#000 solid 1px; border-left:#000 solid 1px;'
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 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
local maxnum = 0
for k, v in pairs(args) do
if (type(k) == 'number') or (type(k) == 'string' and tonumber(k)) then
local nk = tonumber(k)
if nk and nk > maxnum then maxnum = nk end
else
if type(k) == 'string' then checkparameters(k) end
end
end
maxnum = (maxnum > 511) and 511 or maxnum
local levels = math.ceil(math.log(maxnum + 1) / math.log(2))
local cells = math.pow(2, levels) - 1
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] = ' '
end
end
end
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
local res = mw.html.create() -- IMPORTANT: no empty string
local innercell = res
local innerfs = '88%'
if yesno(args['collapsible'] or 'no') then
local r = res:tag('table')
local t = args['title'] or ('Forebears 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 '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 .. (args['ref'] or ''))
innercell = r:tag('tr'):tag('td'):css('text-align', args['text-align'] or 'center')
innerfs = nil
args['ref'] = nil
end
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
local root = innercell:tag('table')
root:css('border-collapse', 'separate')
:css('border-spacing', '0')
:css('line-height', '130%')
:css('font-size', innerfs)
:cssText(style)
for k = rowbegin, (rowend + 1) do
rows[k] = root:tag('tr'):css('text-align', 'center')
rows[k]:tag('td'):wikitext(' ')
end
for k = 1, (3 * levels + 1) do
rows[rowend + 1]:tag('td'):wikitext(' ')
end
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
addcell(offset, 2*(math.pow(2,levels-l+1)-1), (l < levels) and 2 or 4, ' ', nil)
if l < levels then
addcell(offset, math.pow(2,levels-l+1)-1, 1, ' ', nil)
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)
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), ' ', nil)
end
offset = offset + 2
addcell(offset, 2*(math.pow(2,levels-l+1)-1), (l < levels) and 2 or 4, ' ', nil)
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, ' ', nil)
end
offset = offset + 2*(math.pow(2,levels-l+1)-1) + 2
end
end
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'] or '')
innercell:wikitext(args['footnotes'] or '')
end
end
return tostring(res) .. tcats
end
return p