# PyDia DOT Renderer # Copyright (c) 2005 Hans Breuer # A Dia export filter based on the object export interface. # Generating output in the DOT language. That can be processed # with the dot tool from http://www.graphviz.org # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. import sys, dia class DotRenderer : def __init__ (self) : self.nodes = {} self.edges = {} def GetName (self, o) : "A small helper to turn a dia object into a name" s = "" if o.properties.has_key("name") : s = o.properties["name"].value elif o.properties.has_key("text") : s = o.properties["text"].value.text if s is None or s == "" : s = str(o) return s def GetColor (self, o) : if o.properties.has_key("fill_colour") : rgb = o.properties["fill_colour"].value return "#%02x%02x%02x" % (rgb.red * 255, rgb.green * 255, rgb.blue * 255) return None def begin_render (self, data, filename) : self.f = open(filename, "w") self.f.write ("# %s\n" % (filename,)) self.f.write ("# generated by (dia)dot.py\n") self.f.write ("digraph test {\n") # preserve the ratio as given by the bounding box rect = data.extents ratio = (rect.bottom - rect.top) / (rect.right - rect.left) self.f.write ("ratio=%.3f\n" % (ratio,)) # extract some attributes as well as grouping self.f.write("node [style=filled]\n") # otherwise fillcolor is ignored for layer in data.layers : for o in layer.objects : if len(o.connections) < 1 : continue # no node if o.type.name == "Group" : continue # FIXME : iterate these, but we seem them below, too sColor = self.GetColor (o) if sColor and sColor != "#ffffff" : # dont write the default self.f.write('"%s" [fillcolor="%s"];\n' % (self.GetName(o), self.GetColor (o))) for layer in data.layers : for o in layer.objects : for c in o.connections : # these are the connection points of the objects. We will have e.g. "UML - Dependency" for n in c.connected : # we see the connecting lines multiple times, just process once if self.edges.has_key(str(n)) : continue self.edges[str(n)] = 1 if not (n.handles[0].connected_to and n.handles[1].connected_to) : continue # the right handles give us the direction a = n.handles[0].connected_to.object b = n.handles[1].connected_to.object try : self.f.write('"%s" -> "%s"\n' % (self.GetName(a), self.GetName(b))) #self.f.write('"%s" -> "%s"\n' % (str(a.properties["text"].value.text), str(b.properties["text"].value.text))) except : print a, b, " writing connection failed." else : pass self.f.write('}\n') def end_render (self) : self.f.close() # dia-python keeps a reference to the renderer class and uses it on demand dia.register_export ("PyDia DOT Export", "dot", DotRenderer())