Package logilab-common-0 :: Package 39 :: Package 0 :: Module vcgutils
[frames] | no frames]

Source Code for Module logilab-common-0.39.0.vcgutils

  1  """Functions to generate files readable with Georg Sander's vcg 
  2  (Visualization of Compiler Graphs). 
  3   
  4  You can download vcg at http://rw4.cs.uni-sb.de/~sander/html/gshome.html 
  5  Note that vcg exists as a debian package. 
  6   
  7  See vcg's documentation for explanation about the different values that 
  8  maybe used for the functions parameters. 
  9   
 10  :copyright: 2000-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 
 11  :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr 
 12  :license: General Public License version 2 - http://www.gnu.org/licenses 
 13  """ 
 14  __docformat__ = "restructuredtext en" 
 15   
 16  import string 
 17   
 18  ATTRS_VAL = { 
 19      'algos':       ('dfs', 'tree', 'minbackward', 
 20                      'left_to_right','right_to_left', 
 21                      'top_to_bottom','bottom_to_top', 
 22                      'maxdepth', 'maxdepthslow', 'mindepth', 'mindepthslow', 
 23                      'mindegree', 'minindegree', 'minoutdegree', 
 24                      'maxdegree','maxindegree', 'maxoutdegree'), 
 25      'booleans':    ('yes', 'no'), 
 26      'colors':      ('black', 'white', 'blue', 'red', 'green', 'yellow', 
 27                      'magenta', 'lightgrey', 
 28                      'cyan', 'darkgrey', 'darkblue', 'darkred', 'darkgreen', 
 29                      'darkyellow', 'darkmagenta', 'darkcyan', 'gold', 
 30                      'lightblue', 'lightred', 'lightgreen', 'lightyellow', 
 31                      'lightmagenta', 'lightcyan', 'lilac', 'turquoise', 
 32                      'aquamarine', 'khaki', 'purple', 'yellowgreen', 'pink', 
 33                      'orange', 'orchid'), 
 34      'shapes':      ('box', 'ellipse', 'rhomb', 'triangle'), 
 35      'textmodes':   ('center', 'left_justify', 'right_justify'), 
 36      'arrowstyles': ('solid', 'line', 'none'), 
 37      'linestyles':  ('continuous', 'dashed', 'dotted', 'invisible'), 
 38      } 
 39   
 40  # meaning of possible values: 
 41  #   O    -> string 
 42  #   1    -> int  
 43  #   list -> value in list 
 44  GRAPH_ATTRS = { 
 45      'title' :              0, 
 46      'label' :              0, 
 47      'color':               ATTRS_VAL['colors'], 
 48      'textcolor':           ATTRS_VAL['colors'], 
 49      'bordercolor':         ATTRS_VAL['colors'], 
 50      'width':               1, 
 51      'height':              1, 
 52      'borderwidth':         1, 
 53      'textmode':            ATTRS_VAL['textmodes'], 
 54      'shape':               ATTRS_VAL['shapes'], 
 55      'shrink':              1, 
 56      'stretch':             1, 
 57      'orientation':         ATTRS_VAL['algos'], 
 58      'vertical_order':      1, 
 59      'horizontal_order':    1, 
 60      'xspace':              1, 
 61      'yspace':              1, 
 62      'layoutalgorithm' :    ATTRS_VAL['algos'], 
 63      'late_edge_labels' :   ATTRS_VAL['booleans'], 
 64      'display_edge_labels': ATTRS_VAL['booleans'], 
 65      'dirty_edge_labels' :  ATTRS_VAL['booleans'], 
 66      'finetuning':          ATTRS_VAL['booleans'], 
 67      'manhattan_edges':     ATTRS_VAL['booleans'], 
 68      'smanhattan_edges':    ATTRS_VAL['booleans'], 
 69      'port_sharing':        ATTRS_VAL['booleans'], 
 70      'edges':               ATTRS_VAL['booleans'], 
 71      'nodes':               ATTRS_VAL['booleans'], 
 72      'splines':             ATTRS_VAL['booleans'], 
 73      } 
 74  NODE_ATTRS = { 
 75      'title' :              0, 
 76      'label' :              0, 
 77      'color':               ATTRS_VAL['colors'], 
 78      'textcolor':           ATTRS_VAL['colors'], 
 79      'bordercolor':         ATTRS_VAL['colors'], 
 80      'width':               1, 
 81      'height':              1, 
 82      'borderwidth':         1, 
 83      'textmode':            ATTRS_VAL['textmodes'], 
 84      'shape':               ATTRS_VAL['shapes'], 
 85      'shrink':              1, 
 86      'stretch':             1, 
 87      'vertical_order':      1, 
 88      'horizontal_order':    1, 
 89      } 
 90  EDGE_ATTRS = { 
 91      'sourcename' :         0, 
 92      'targetname' :         0, 
 93      'label' :              0, 
 94      'linestyle' :          ATTRS_VAL['linestyles'], 
 95      'class' :              1, 
 96      'thickness' :          0, 
 97      'color':               ATTRS_VAL['colors'], 
 98      'textcolor':           ATTRS_VAL['colors'], 
 99      'arrowcolor':          ATTRS_VAL['colors'], 
100      'backarrowcolor':      ATTRS_VAL['colors'], 
101      'arrowsize':           1, 
102      'backarrowsize':       1, 
103      'arrowstyle':          ATTRS_VAL['arrowstyles'], 
104      'backarrowstyle':      ATTRS_VAL['arrowstyles'], 
105      'textmode':            ATTRS_VAL['textmodes'], 
106      'priority':            1, 
107      'anchor':              1, 
108      'horizontal_order':    1, 
109      } 
110   
111   
112  # Misc utilities ############################################################### 
113   
114 -def latin_to_vcg(st):
115 """Convert latin characters using vcg escape sequence. 116 """ 117 for char in st: 118 if char not in string.ascii_letters: 119 try: 120 num = ord(char) 121 if num >= 192: 122 st = st.replace(char, r'\fi%d'%ord(char)) 123 except: 124 pass 125 return st
126 127
128 -class VCGPrinter:
129 """A vcg graph writer. 130 """ 131
132 - def __init__(self, output_stream):
133 self._stream = output_stream 134 self._indent = ''
135
136 - def open_graph(self, **args):
137 """open a vcg graph 138 """ 139 self._stream.write('%sgraph:{\n'%self._indent) 140 self._inc_indent() 141 self._write_attributes(GRAPH_ATTRS, **args)
142
143 - def close_graph(self):
144 """close a vcg graph 145 """ 146 self._dec_indent() 147 self._stream.write('%s}\n'%self._indent)
148 149
150 - def node(self, title, **args):
151 """draw a node 152 """ 153 self._stream.write('%snode: {title:"%s"' % (self._indent, title)) 154 self._write_attributes(NODE_ATTRS, **args) 155 self._stream.write('}\n')
156 157
158 - def edge(self, from_node, to_node, edge_type='', **args):
159 """draw an edge from a node to another. 160 """ 161 self._stream.write( 162 '%s%sedge: {sourcename:"%s" targetname:"%s"' % ( 163 self._indent, edge_type, from_node, to_node)) 164 self._write_attributes(EDGE_ATTRS, **args) 165 self._stream.write('}\n')
166 167 168 # private ################################################################## 169
170 - def _write_attributes(self, attributes_dict, **args):
171 """write graph, node or edge attributes 172 """ 173 for key, value in args.items(): 174 try: 175 _type = attributes_dict[key] 176 except KeyError: 177 raise Exception('''no such attribute %s 178 possible attributes are %s''' % (key, attributes_dict.keys())) 179 180 if not _type: 181 self._stream.write('%s%s:"%s"\n' % (self._indent, key, value)) 182 elif _type == 1: 183 self._stream.write('%s%s:%s\n' % (self._indent, key, 184 int(value))) 185 elif value in _type: 186 self._stream.write('%s%s:%s\n' % (self._indent, key, value)) 187 else: 188 raise Exception('''value %s isn\'t correct for attribute %s 189 correct values are %s''' % (value, key, _type))
190
191 - def _inc_indent(self):
192 """increment indentation 193 """ 194 self._indent = ' %s' % self._indent
195
196 - def _dec_indent(self):
197 """decrement indentation 198 """ 199 self._indent = self._indent[:-2]
200