# pretty printing graphs

John Hunter jdhunter at ace.bsd.uchicago.edu
Mon Jul 28 19:13:10 CEST 2003

```I have a tree structure (directed acyclic graph), where each node can
represent itself as a multi-line string that is not very wide (eg, 10
chars per line).  I would like to print the graph like

C
C1        C2
C1a  C1b   C2a   C2b

Where C, C1, etc.. are the multiline string blocks referred to above.
Does anybody know of a tool that can do this.  Here is an example,
somewhat long because I have to create the multiline strings.

from __future__ import division, generators

def enumerate(seq):
"Waiting for python 2.3"
for i in range(len(seq)):
yield i, seq[i]

class O:

def __init__(self, text):
self.text = text
def __str__(self):
return self.text

class Node:
def __init__(self, o):
self.node = o
self.children = []

def __str__(self):
s = ''
#s += str(self.node) + '\n\n'
if len(self.children)==0: return s
childStrs = [str(child.node) for child in self.children]

lines = [[] for tmp in childStrs]
for lineNum, t in enumerate(childStrs):
lines[lineNum].extend(t.split('\n'))

maxLines = max([len(l) for l in lines])
sep = '      '
for lineNum in range(maxLines):
row = ''
for childNum in range(len(childStrs)):
row += lines[childNum][lineNum] + sep
s += row + '\n'
s += '\n\n'
for l in self.children:
s += str(l)
return s

n0 = Node(O("""1  2  3  0
1  2  3  4
1  2  1  5
1  2  1  1
4  3  2  2
4  3  2  7
2  3  2  3
2  3  2  9"""))

n1 = Node(O("""1  2  3  0
1  2  3  4
1  2  1  5
1  2  1  1
----------
1  1  0  0"""))

n2 = Node(O("""4  3  2  2
4  3  2  7
2  3  2  3
2  3  2  9
----------
0  1  1  0"""))

n1a = Node(O("""1  2  1  5
1  2  1  1
----------
1  1  1  0"""))

n1b = Node(O("""1  2  3  0
1  2  3  4
----------
1  1  1  0"""))

n2a = Node(O("""2  3  2  3
2  3  2  9
----------
1  1  1  0"""))

n2b = Node(O("""4  3  2  2
4  3  2  7
----------
1  1  1  0"""))

n0.children.extend([n1, n2])
n1.children.extend([n1a, n1b])
n2.children.extend([n2a, n2b])
print n0

Which prints:

1  2  3  0      4  3  2  2
1  2  3  4      4  3  2  7
1  2  1  5      2  3  2  3
1  2  1  1      2  3  2  9
----------      ----------
1  1  0  0      0  1  1  0

1  2  1  5      1  2  3  0
1  2  1  1      1  2  3  4
----------      ----------
1  1  1  0      1  1  1  0

2  3  2  3      4  3  2  2
2  3  2  9      4  3  2  7
----------      ----------
1  1  1  0      1  1  1  0

This does part of the work, printing the child nodes on the same rows,
but doesn't the hierarchical part very well.  What I would like is
something like this:

1  2  3  0
1  2  3  4
1  2  1  5
1  2  1  1
4  3  2  2
4  3  2  7
2  3  2  3
2  3  2  9

1  2  3  0        4  3  2  2
1  2  3  4        4  3  2  7
1  2  1  5        2  3  2  3
1  2  1  1        2  3  2  9
----------        ----------
1  1  0  0        0  1  1  0

1  2  1  5    1  2  3  0          2  3  2  3      4  3  2  2
1  2  1  1    1  2  3  4          2  3  2  9      4  3  2  7
----------    ----------          ----------      ----------
1  1  1  0    1  1  1  0          1  1  1  0      1  1  1  0

Thanks,
John Hunter

```