input mp-tool ; input boxes ; % for generic_declare input marctool ; numeric nrtrees_ ; picture node_[] ; numeric depth_[] ; numeric width_[] ; numeric nrbranches_[] ; numeric branch_[][] ; nrtrees_ := 0; vardef tree@#( expr pic ) = _n_ := str @#; generic_declare(numeric) _n.number, _n.distx, _n.disty; @#distx := 1cm; @#disty := 1cm; @#number := nrtrees_ + 1; numerictree( @#number, pic ); enddef; def numerictree( expr nr, pic ) = nrtrees_ := nr; node_[ nr ] := pic; depth_[ nr ] := 0; width_[ nr ] := 0; nrbranches_[ nr ] := 0; enddef; vardef branches@#( text ns_ ) = forsuffixes $$ = ns_: numericbranch( @#number, $$.number ); endfor; enddef; def numericbranch( expr nr, nrnr ) = begingroup save d, w; nrbranches_[ nr ] := nrbranches_[ nr ] + 1; branch_[ nr ][ nrbranches_[ nr ] ] := nrnr; d := 0; w := 0; for b = 1 upto nrbranches_[ nr ]: d := max( d, depth_[ branch_[ nr ][ b ] ] ); w := w + width_[ branch_[ nr ][ b ] ]; endfor; depth_[ nr ] := 1 + d; width_[ nr ] := w; endgroup; enddef; def treeit( suffix $ ) = treeitpicture( $.number, (0,0), $.distx, $.disty ) enddef; vardef treeitpicture( expr nr, pos, distx, disty ) = save bp, ts, pic, w; picture pic, ts[]; pic := node_[ nr ] shifted (pos - centreofbox( node_[ nr ] )); w := -distx; for b = 1 upto nrbranches_[ nr ]: ts[ b ] = treeitpicture( branch_[ nr ][ b ], (0,0), distx, disty ); w := w + widthofbox( ts[ b ] ) + distx; endfor; w := -0.5*w; for b = 1 upto nrbranches_[ nr ]: addto pic also (ts[ b ] shifted (w+0.5*widthofbox( ts[ b ] ),disty)); addto pic doublepath (pos + (0,0.5*heightofbox( node_[ nr ] ) + 1mm)-- ( w+0.5*widthofbox( ts[ b ] ) , disty - 0.5heightofbox( node_[ branch_[ nr ][ b ] ] ) - 1mm) ); w := w + widthofbox( ts[ b ] ) + distx; endfor; pic enddef; vardef leaf@#( expr pic ) = tree.@#( pic ) enddef; vardef node@# = tree.@#( nullpicture ) enddef; vardef branch@#( text bs_ ) = branches@#( bs_ ) enddef;