chiark / gitweb /
9c9e20b157cf9d218c7e453116bbf5993aa25bd5
[familyTree.git] / cgiFiles / make_dot.py
1 #!/usr/bin/python
2
3 import cgi
4 import cgitb
5 import gv
6 import re
7
8 cgitb.enable()
9 def add_quotes(s):
10         return '\"'+str(s)+'\"'
11
12 def add_node(node,node_attr):
13         global dot
14         global nodes
15         node_attr = attr_string(node_attr)
16         if node not in nodes:
17                 dot = dot + add_quotes(node) + node_attr + ";\n"
18                 nodes.append(node)
19
20 def has_node(node):
21         if node in nodes:
22                 return 1
23         else:
24                 return 0
25 def has_edge(edge):
26         edge[0] = add_quotes(edge[0])
27         edge[1] = add_quotes(edge[1])
28         if edge in edges:
29                 return 1
30         else:
31                 return 0
32
33 def add_edge(n1,n2,edge_attr):
34         global dot
35         global edges
36         edge = (add_quotes(n1),add_quotes(n2))
37         edge_attr = attr_string(edge_attr)
38         if edge not in edges:
39                 dot = dot + edge[0] + ' -> ' + edge[1] + edge_attr + ";"
40                 edges.append(edge)
41
42 def add_arrow(n1,n2):
43         add_edge(n1,n2,edge_attr)
44
45 def add_no_arrow(n1,n2):
46         add_edge(n1,n2,nodir_attr)
47
48 def add_marriage(n1,n2,children,joinChildren):
49         global cNodes
50         
51         jN = n1+n2
52         jNRev = n2+n1
53         if has_node(jNRev):
54                 jN = jNRev
55         add_spot(jN)
56         add_person(n1)
57         add_person(n2)
58
59         
60
61         if len(children)>0 and joinChildren==1:
62                 cNode = jN + 'c'
63                 e = [cNode,children[0]]
64                 if has_node(cNode):
65                         tcNode = cNode + children[0]
66                         if len(cNodes[cNode])>0:
67                                 last = cNodes[cNode][-1]
68                         else:
69                                 last = cNode
70                         add_spot(tcNode)
71                         cNodes[cNode].append(tcNode)
72                         add_no_arrow(last,tcNode)
73                         add_subgraph([tcNode,cNode])
74                 else:
75                         tcNode = cNode
76                         add_spot(cNode)
77                         cNodes[cNode] = []
78                         add_no_arrow(jN,cNode)
79
80         elif len(children)>0:
81                 tcNode = jN
82
83         for c in children:
84                 add_person(c)
85                 add_arrow(tcNode,c)
86         for n in [n1, n2]:
87                 add_edge(n,jN,marriage_attr)
88         add_subgraph([n1,n2])
89
90
91 def add_subgraph(myG):
92         global subgraphs
93         subgraphs.append(myG)
94         
95 def add_subgraphs():
96         global dot
97         for sg in subgraphs:
98                 line = "\n{rank=same "
99
100                 for n in sg:
101                         line = line +add_quotes(n) + ' '
102
103                 line = line +"}"
104
105                 dot = dot + line
106
107 def end_dot():
108         global dot
109         dot = dot + "}"
110
111 def start_dot():
112         global dot
113         global nodes
114         global edges
115         global subgraphs
116         global cNodes
117         nodes=[]
118         edges=[]
119         cNodes={}
120         dot = "digraph G{\n"
121         dot = dot + "ranksep = 0.5 nodesep = 0\n"
122         subgraphs=[]
123         set_attr()
124
125 def add_highlight(name):
126         add_node(name,highlight_attr)
127
128 def add_person(name):
129         add_node(name,person_attr)
130
131 def add_spot(name):
132         add_node(name,spot_attr)
133
134
135 def set_attr():
136         global person_attr
137         global highlight_attr
138         global spot_attr
139         global edge_attr
140         global invis_attr
141         global ignored_attr
142         global nodir_attr
143         global marriage_attr
144         global debug_attr
145         global debug_edge_attr
146         zero_size = [('width','0'),('height','0')]
147         person_attr = [('fontsize','8'),('shape','plaintext')] + zero_size
148         highlight_attr = person_attr + \
149                 [('fontcolor','red'),('shape','box'),('color','red')]
150         debug_attr = person_attr + [('fontcolor','green')]
151         spot_attr = [('shape','point')] + zero_size
152         edge_attr = [('len','0'),('arrowsize','0.5')]
153         debug_edge_attr = edge_attr + [('color','green')]
154         invis_attr = edge_attr + [('style','invis')]
155         nodir_attr = edge_attr + [('dir','none')]
156         marriage_attr = nodir_attr + [('weight','10'),('color','red')]
157         ignored_attr =edge_attr + [('constraint','false')] + nodir_attr
158
159 def attr_string(attr):
160         
161         attr_str = '['
162         for a in attr:
163                 attr_str = attr_str + a[0] + '=' + a[1]
164                 if a != attr[-1]:
165                         attr_str = attr_str +','
166
167         attr_str = attr_str + ']'
168         return attr_str
169
170 def render_dot():
171         gvv = gv.readstring(dot)
172         gv.layout(gvv,'dot')
173
174         format = 'png'
175
176         print "Content-type: image/" + format + "\n"
177         print gv.render(gvv,format)