Package logilab :: Package common :: Module vcgutils
[frames] | no frames]

Source Code for Module logilab.common.vcgutils

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