--- /dev/null
+#!/usr/bin/python
+
+import cgi
+import cgitb
+import gv
+import re
+
+cgitb.enable()
+def add_quotes(s):
+ return '\"'+str(s)+'\"'
+
+def add_node(node,node_attr):
+ global dot
+ global nodes
+ node_attr = attr_string(node_attr)
+ if node not in nodes:
+ dot = dot + add_quotes(node) + node_attr + ";\n"
+ nodes.append(node)
+
+def has_node(node):
+ if node in nodes:
+ return 1
+ else:
+ return 0
+def has_edge(edge):
+ edge[0] = add_quotes(edge[0])
+ edge[1] = add_quotes(edge[1])
+ if edge in edges:
+ return 1
+ else:
+ return 0
+
+def add_edge(n1,n2,edge_attr):
+ global dot
+ global edges
+ edge = (add_quotes(n1),add_quotes(n2))
+ edge_attr = attr_string(edge_attr)
+ if edge not in edges:
+ dot = dot + edge[0] + ' -> ' + edge[1] + edge_attr + ";"
+ edges.append(edge)
+
+def add_arrow(n1,n2):
+ add_edge(n1,n2,edge_attr)
+
+def add_no_arrow(n1,n2):
+ add_edge(n1,n2,nodir_attr)
+
+def add_marriage(n1,n2,children,joinChildren):
+ global cNodes
+
+ jN = n1+n2
+ jNRev = n2+n1
+ if has_node(jNRev):
+ jN = jNRev
+ add_spot(jN)
+ add_person(n1)
+ add_person(n2)
+
+
+
+ if len(children)>0 and joinChildren==1:
+ cNode = jN + 'c'
+ e = [cNode,children[0]]
+ if has_node(cNode):
+ tcNode = cNode + children[0]
+ if len(cNodes[cNode])>0:
+ last = cNodes[cNode][-1]
+ else:
+ last = cNode
+ add_spot(tcNode)
+ cNodes[cNode].append(tcNode)
+ add_no_arrow(last,tcNode)
+ add_subgraph([tcNode,cNode])
+ else:
+ tcNode = cNode
+ add_spot(cNode)
+ cNodes[cNode] = []
+ add_no_arrow(jN,cNode)
+
+ elif len(children)>0:
+ tcNode = jN
+
+ for c in children:
+ add_person(c)
+ add_arrow(tcNode,c)
+ for n in [n1, n2]:
+ add_edge(n,jN,marriage_attr)
+ add_subgraph([n1,n2])
+
+
+def add_subgraph(myG):
+ global subgraphs
+ subgraphs.append(myG)
+
+def add_subgraphs():
+ global dot
+ for sg in subgraphs:
+ line = "\n{rank=same "
+
+ for n in sg:
+ line = line +add_quotes(n) + ' '
+
+ line = line +"}"
+
+ dot = dot + line
+
+def end_dot():
+ global dot
+ dot = dot + "}"
+
+def start_dot():
+ global dot
+ global nodes
+ global edges
+ global subgraphs
+ global cNodes
+ nodes=[]
+ edges=[]
+ cNodes={}
+ dot = "digraph G{\n"
+ dot = dot + "ranksep = 0.5 nodesep = 0\n"
+ subgraphs=[]
+ set_attr()
+
+def add_highlight(name):
+ add_node(name,highlight_attr)
+
+def add_person(name):
+ add_node(name,person_attr)
+
+def add_spot(name):
+ add_node(name,spot_attr)
+
+
+def set_attr():
+ global person_attr
+ global highlight_attr
+ global spot_attr
+ global edge_attr
+ global invis_attr
+ global ignored_attr
+ global nodir_attr
+ global marriage_attr
+ global debug_attr
+ global debug_edge_attr
+ zero_size = [('width','0'),('height','0')]
+ person_attr = [('fontsize','8'),('shape','plaintext')] + zero_size
+ highlight_attr = person_attr + \
+ [('fontcolor','red'),('shape','box'),('color','red')]
+ debug_attr = person_attr + [('fontcolor','green')]
+ spot_attr = [('shape','point')] + zero_size
+ edge_attr = [('len','0'),('arrowsize','0.5')]
+ debug_edge_attr = edge_attr + [('color','green')]
+ invis_attr = edge_attr + [('style','invis')]
+ nodir_attr = edge_attr + [('dir','none')]
+ marriage_attr = nodir_attr + [('weight','10'),('color','red')]
+ ignored_attr =edge_attr + [('constraint','false')] + nodir_attr
+
+def attr_string(attr):
+
+ attr_str = '['
+ for a in attr:
+ attr_str = attr_str + a[0] + '=' + a[1]
+ if a != attr[-1]:
+ attr_str = attr_str +','
+
+ attr_str = attr_str + ']'
+ return attr_str
+
+def render_dot():
+ gvv = gv.readstring(dot)
+ gv.layout(gvv,'dot')
+
+ format = 'png'
+
+ print "Content-type: image/" + format + "\n"
+ print gv.render(gvv,format)