Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Humanipedia
Search
Search
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Module:Lineage
Module
Discussion
English
Read
Edit source
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit source
View history
General
What links here
Related changes
Special pages
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
require('strict') local getArgs = require('Module:Arguments').getArgs local errorCategory = '[[Categoria:Errors reported by Module Lineage]]' local mwHtml = getmetatable( mw.html.create() ).__index function mwHtml:attrIf( cond, name, value ) if cond then return self:attr( name, value ) else return self end end function mwHtml:cssIf( cond, name, value ) if cond then return self:css( name, value ) else return self end end function mwHtml:wikitextIf( cond, value1, value2 ) if cond then return self:wikitext( value1 ) elseif value2 ~= nil then return self:wikitext( value2 ) else return self end end local p = {} local pers = {} local tabella = {} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<span class="error">%s</span>%s', msg, cat) end 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] = { padre = px, testo = dati[m-1], nota = dati[m], id = -1, x = -1, y = -1, sp = 0, figli = {} } 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)) end end 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 nn end 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 dt end 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 dt end 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 vrf end 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) == 1) then verifica(pid) end sposta = 0 end end end local function calcolaX1(pid) for _, v in pairs(pers[pid].figli) do calcolaX1(v) end local tt = #pers[pid].figli if (tt == 0) then if (pers[pid].padre == -1 or pers[pid].id == 1) then pers[pid].x = 0 else pers[pid].x = pers[pers[pers[pid].padre].figli[pers[pid].id - 1]].x + 2 end elseif (tt == 1) then if (pers[pid].padre == -1 or pers[pid].id == 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 or pers[pid].id == 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 end end 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 end end 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) end end 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 t end local function mostraX(pid,allinea,largo,dida) local posx = {} local n1 local stx local riga = {} local xx, xp local stileDiv = { ['width'] = largo..'px', ['padding'] = '3px', ['background'] = '#FFF', ['border'] = '1px solid #C8CCD1' } local stileTabella = { ['border-collapse'] = 'separate', ['text-align'] = 'center', ['font-size'] = '95%', ['line-height'] = '105%', ['margin'] = '10px auto !important', } local xy = massimoXY(pid, {0, 0}) local lg = math.floor(100/(xy[1]+2)) if (lg == 0) then lg = 1 end local bDiv = mw.html.create('div') if (allinea == 'right') then bDiv:css(stileDiv):addClass('floatright') stileTabella['margin'] = '0px auto !important' end local bTabella = mw.html.create('table') :css(stileTabella) :attr({['cellpadding']='1',['cellspacing']='0',['border']='0'}) for n=1,xy[2] do local riga1 = mw.html.create('tr') local riga2 = mw.html.create('tr') local riga3 = mw.html.create('tr') posx[1] = 0; posx[2] = 0; posx[3] = 0 n1 = 0 if (n > 1) then riga1:css('line-height','8px') end if (n < xy[2]) then riga3:css('line-height','8px') end for _, v in pairs(tabella[n]) do xx = pers[v].x xp = pers[v].padre if n == 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 == xp,'border-top','1px solid #000') :attrIf(xx-posx[1]>0,'colspan',xx+1-posx[1]) :wikitext(' ') ) n1 = xp posx[1] = xx + 1 end 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=='-', pers[v].testo, string.format('%s<br/><span style="font-size:90%%"><i>%s</i></span>',pers[v].testo,pers[v].nota)) ) posx[2] = xx + 2 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 == 'right' and dida ~= '') then bDiv:node(mw.html.create('p') :css({['font-size'] = '87%', ['font-style'] = 'normal', ['border-top'] = '1px solid #c8ccd1', ['margin'] = '8px 2px 3px'}) :wikitext(dida) ) end return tostring(bDiv) end 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 t end local function mostraY(pid) local bTabella = mw.html.create('table') :attr({['cellpadding']='0',['cellspacing']='0',['border']='0'}) :css({['border-collapse']='separate',['text-align']='left',['margin']='10px 0 10px 16px'}) 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 == 1 and pers[pers[pid].padre].padre > -1) then riga1:node(mw.html.create('td') :attr('rowspan',2*spd)) riga1:node(mw.html.create('td') :attr('rowspan',2*spd) :cssIf(pers[pers[pid].padre].id < #pers[pers[pers[pid].padre].padre].figli,'border-left','1px solid #666') ) end riga1 :node(mw.html.create('td') :css('width','6px')) :node(mw.html.create('td') :css({['border-left']='1px solid #666',['border-bottom']='1px solid #666',['width']='10px',['line-height']='3px',['height']='12px'})) :node(mw.html.create('td') :attr({['colspan']=2*a-1, ['rowspan']=2}) :css('padding', '0px 3px 2px 1px') :wikitextIf(pers[pid].nota=='', pers[pid].testo, pers[pid].testo..' - '..pers[pid].nota)) riga2 :node(mw.html.create('td')) :node(mw.html.create('td') :css({['line-height']='8px',['line-height']='3px',['height']='12px'}) :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=='',pers[pid].testo,pers[pid].testo..' - '..pers[pid].nota) ) ) end if (pers[pid].sp > 0) then for _, v in pairs(pers[pid].figli) do mostraY2(v,a-1) end end end 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 if (capo == -1) then capo = i else error(string.format('Duplicated progenitor (id = %d, %d)',capo,i)) end else if (v.padre == i) then error(string.format('%d is parent of himself', i)) elseif (pers[v.padre]) then table.insert(pers[v.padre].figli,i) else error(string.format('Erroneous parent id %d for row with id %d',v.padre,i)) end end end if (capo == -1) then error('Progenitor not found') else n2 = organizza(capo, 1) if (n1 == n2) then if (tipo == 'v') then return mostraY(capo) elseif (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 end end function p.lineage(frame) local args = getArgs(frame, { valueFunc = function (key, value) if type(key) == "number" then if value == nil then return nil else value = mw.text.trim(value) end else if value == '' then return nil end end return value end }) return p._lineage(args) end return p
Summary:
Please note that all contributions to Humanipedia may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Humanipedia:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Template used on this page:
Module:Lineage/doc
(
edit
)