require('strict')local getArgs = require('Module:Arguments').getArgslocal errorCategory = ''local mwHtml = getmetatable(mw.html.create).__index
function mwHtml:attrIf(cond, name, value) if cond then return self:attr(name, value) else return self endend
function mwHtml:cssIf(cond, name, value) if cond then return self:css(name, value) else return self endend
function mwHtml:wikitextIf(cond, value1, value2) if cond then return self:wikitext(value1) elseif value2 ~= nil then return self:wikitext(value2) else return self endend
local p = local pers = local tabella =
local function errhandler(msg) local cat = mw.title.getCurrentTitle.namespace
local function dividi(dati) local n = 1 local resto = 0 local nx,px while (dati[n]) do n = n + 1 end n = n-1 for m = 4, n, 4 do nx = tonumber(dati[m-3]) px = tonumber(dati[m-2]) if nx then if px then if pers[nx] then error(string.format('Duplicated id %d',nx)) else pers[nx] = end else error(string.format('Erroneous parent id %s for id %d',dati[m-2],nx)) end else error(string.format('Erroneous id %s',dati[m-3])) end resto = n-m end if resto > 0 then error(string.format('Erroneous number of data %d (elementi in piĆ¹: %d)',n)) endend
local function organizza(pid, y) local nn = 1 pers[pid].y = y if (not tabella[y]) then tabella[y] = end table.insert(tabella[y], pid) for i, v in pairs(pers[pid].figli) do pers[v].id = i nn = nn + organizza(v, y+1) end return nnend
local function limSx(pid, delta, dt) if (dt[pers[pid].y]) then dt[pers[pid].y] = math.min(dt[pers[pid].y], pers[pid].x+delta) else dt[pers[pid].y] = pers[pid].x + delta end for _, v in pairs(pers[pid].figli) do dt = limSx(v, delta+pers[pid].sp, dt) end return dtend
local function limDx(pid, delta, dt) if (dt[pers[pid].y]) then dt[pers[pid].y] = math.max(dt[pers[pid].y], pers[pid].x+delta) else dt[pers[pid].y] = pers[pid].x + delta end for _, v in pairs(pers[pid].figli) do dt = limDx(v, delta+pers[pid].sp, dt) end return dtend
local function riallinea(pid2, n1, n2) local distanza = n2 - n1 local vrf = 0 local pos, inizio, passo if (distanza > 1) then inizio = pers[pers[pid2].figli[n1]].x passo = (pers[pers[pid2].figli[n2]].x - inizio)/distanza for cc=1, (distanza-1) do pos = inizio + math.floor(cc*passo) if (pos - pers[pers[pid2].figli[n1+cc]].x > 0) then pers[pers[pid2].figli[n1+cc]].x = pos pers[pers[pid2].figli[n1+cc]].sp = pos end end vrf = 1 end return vrfend
local function verifica(pid) local tSx local tDx local sposta = 0
local fine = pers[pid].id local frt2, n for frt=1, (fine-1) do frt2 = pers[pers[pid].padre].figli[frt] tDx = limDx(frt2, 0,) tSx = limSx(pid, 0,) n = pers[pid].y while tSx[n] and tDx[n] do if (tSx[n] - tDx[n] + sposta < 2) then sposta = 2 + tDx[n] - tSx[n] end n = n + 1 end if (sposta > 0) then pers[pid].x = pers[pid].x + sposta pers[pid].sp = pers[pid].sp + sposta if (riallinea(pers[pid].padre, frt, fine)
local function calcolaX1(pid) for _, v in pairs(pers[pid].figli) do calcolaX1(v) end local tt = #pers[pid].figli if (tt
-1 or pers[pid].id
1) then if (pers[pid].padre
1) then pers[pid].x = pers[pers[pid].figli[1]].x else pers[pid].x = pers[pers[pers[pid].padre].figli[pers[pid].id - 1]].x + 2 pers[pid].sp = pers[pid].x - pers[pers[pid].figli[1]].x verifica(pid) end else local media = math.floor((pers[pers[pid].figli[1]].x + pers[pers[pid].figli[tt]].x)/2) if (pers[pid].padre
1) then pers[pid].x = media else pers[pid].x = pers[pers[pers[pid].padre].figli[pers[pid].id - 1]].x + 2 pers[pid].sp = pers[pid].x - media verifica(pid) end endend
local function calcolaX2(pid) local sposta = 0 local tt = limSx(pid, 0,) for _, v in pairs(tt) do if (v+sposta<0) then sposta = -v end end if (sposta > 0) then pers[pid].x = pers[pid].x + sposta pers[pid].sp = pers[pid].sp + sposta endend
local function calcolaX3(pid, sposta) pers[pid].x = pers[pid].x + sposta for _, v in pairs(pers[pid].figli) do calcolaX3(v, sposta + pers[pid].sp) endend
local function massimoXY(pid, t) if (pers[pid].x > t[1]) then t[1] = pers[pid].x end if (pers[pid].y > t[2]) then t[2] = pers[pid].y end for _, v in pairs(pers[pid].figli) do t = massimoXY(v,t) end return tend
local function mostraX(pid,allinea,largo,dida) local posx = local n1 local stx local riga = local xx, xp local stileDiv = local stileTabella = local xy = massimoXY(pid,) local lg = math.floor(100/(xy[1]+2)) if (lg
local bDiv = mw.html.create('div') if (allinea
1 then for m=1,(xy[1]+2) do riga1:node(mw.html.create('td'):css('width',lg..'%')) end else riga1:node(mw.html.create('td') :css('border-right','1px solid #000') :cssIf(n1
if xx-posx[2] > 0 then riga2:node(mw.html.create('td') :attrIf(xx-posx[2]>1,'colspan',xx-posx[2]) :wikitext(' ') ) end riga2:node(mw.html.create('td') :attr('colspan','2') :wikitextIf(pers[v].nota
if n < xy[2] and #pers[v].figli > 0 then riga3:node(mw.html.create('td') :css('border-right','1px solid #000') :attrIf(xx-posx[3]>0,'colspan',xx+1-posx[3]) :wikitext(' ') ) posx[3] = xx + 1 end end
bTabella:node(riga1):node(riga2):node(riga3) end
bDiv:node(bTabella) if (allinea
local function calcolaY(pid, t) if (pers[pid].y > t) then t = pers[pid].y end for _, v in pairs(pers[pid].figli) do t = calcolaY(v,t) pers[pid].sp = pers[pid].sp + 1 + pers[v].sp end return tend
local function mostraY(pid) local bTabella = mw.html.create('table') :attr :css
local function mostraY2(pid, a) if (pers[pid].padre > -1) then local riga1 = mw.html.create('tr') local riga2 = mw.html.create('tr') local spd = pers[pers[pid].padre].sp if (pers[pid].id
, pers[pid].testo, pers[pid].testo..' - '..pers[pid].nota)) riga2 :node(mw.html.create('td')) :node(mw.html.create('td') :css :cssIf(pers[pid].id < #pers[pers[pid].padre].figli,'border-left','1px solid #666')) bTabella:node(riga1):node(riga2) else bTabella:node(mw.html.create('tr') :node(mw.html.create('td') :attr('colspan',2*a-1) :css('padding','0px 0px 2px 2px') :wikitextIf(pers[pid].nota
mostraY2(pid,calcolaY(pid,0)) return tostring(bTabella)end
function p._lineage(args) local capo = -1 local n1, n2 local lato = args['align'] or 'center' local larg = args['width'] or '300' local tipo = args['show'] or 'h' local dida = args['caption'] or dividi(args) n1 = 0 for i, v in pairs(pers) do n1 = n1+1 if (v.padre
-1) then capo = i else error(string.format('Duplicated progenitor (id = %d, %d)',capo,i)) end else if (v.padre
if (capo
n2) then if (tipo
'h') then calcolaX1(capo) calcolaX2(capo) calcolaX3(capo, 0) return mostraX(capo, lato, larg, dida) end else error('Some elements are not linked to the progenitor') end endend
function p.lineage(frame) local args = getArgs(frame,) return p._lineage(args)end
return p