Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

vcgutils.py 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. # -*- coding: utf-8 -*-
  2. # Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com>
  3. # Copyright (c) 2015 Florian Bruhin <me@the-compiler.org>
  4. # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  5. # For details: https://github.com/PyCQA/pylint/blob/master/COPYING
  6. """Functions to generate files readable with Georg Sander's vcg
  7. (Visualization of Compiler Graphs).
  8. You can download vcg at http://rw4.cs.uni-sb.de/~sander/html/gshome.html
  9. Note that vcg exists as a debian package.
  10. See vcg's documentation for explanation about the different values that
  11. maybe used for the functions parameters.
  12. """
  13. ATTRS_VAL = {
  14. 'algos': ('dfs', 'tree', 'minbackward',
  15. 'left_to_right', 'right_to_left',
  16. 'top_to_bottom', 'bottom_to_top',
  17. 'maxdepth', 'maxdepthslow', 'mindepth', 'mindepthslow',
  18. 'mindegree', 'minindegree', 'minoutdegree',
  19. 'maxdegree', 'maxindegree', 'maxoutdegree'),
  20. 'booleans': ('yes', 'no'),
  21. 'colors': ('black', 'white', 'blue', 'red', 'green', 'yellow',
  22. 'magenta', 'lightgrey',
  23. 'cyan', 'darkgrey', 'darkblue', 'darkred', 'darkgreen',
  24. 'darkyellow', 'darkmagenta', 'darkcyan', 'gold',
  25. 'lightblue', 'lightred', 'lightgreen', 'lightyellow',
  26. 'lightmagenta', 'lightcyan', 'lilac', 'turquoise',
  27. 'aquamarine', 'khaki', 'purple', 'yellowgreen', 'pink',
  28. 'orange', 'orchid'),
  29. 'shapes': ('box', 'ellipse', 'rhomb', 'triangle'),
  30. 'textmodes': ('center', 'left_justify', 'right_justify'),
  31. 'arrowstyles': ('solid', 'line', 'none'),
  32. 'linestyles': ('continuous', 'dashed', 'dotted', 'invisible'),
  33. }
  34. # meaning of possible values:
  35. # O -> string
  36. # 1 -> int
  37. # list -> value in list
  38. GRAPH_ATTRS = {
  39. 'title': 0,
  40. 'label': 0,
  41. 'color': ATTRS_VAL['colors'],
  42. 'textcolor': ATTRS_VAL['colors'],
  43. 'bordercolor': ATTRS_VAL['colors'],
  44. 'width': 1,
  45. 'height': 1,
  46. 'borderwidth': 1,
  47. 'textmode': ATTRS_VAL['textmodes'],
  48. 'shape': ATTRS_VAL['shapes'],
  49. 'shrink': 1,
  50. 'stretch': 1,
  51. 'orientation': ATTRS_VAL['algos'],
  52. 'vertical_order': 1,
  53. 'horizontal_order': 1,
  54. 'xspace': 1,
  55. 'yspace': 1,
  56. 'layoutalgorithm': ATTRS_VAL['algos'],
  57. 'late_edge_labels': ATTRS_VAL['booleans'],
  58. 'display_edge_labels': ATTRS_VAL['booleans'],
  59. 'dirty_edge_labels': ATTRS_VAL['booleans'],
  60. 'finetuning': ATTRS_VAL['booleans'],
  61. 'manhattan_edges': ATTRS_VAL['booleans'],
  62. 'smanhattan_edges': ATTRS_VAL['booleans'],
  63. 'port_sharing': ATTRS_VAL['booleans'],
  64. 'edges': ATTRS_VAL['booleans'],
  65. 'nodes': ATTRS_VAL['booleans'],
  66. 'splines': ATTRS_VAL['booleans'],
  67. }
  68. NODE_ATTRS = {
  69. 'title': 0,
  70. 'label': 0,
  71. 'color': ATTRS_VAL['colors'],
  72. 'textcolor': ATTRS_VAL['colors'],
  73. 'bordercolor': ATTRS_VAL['colors'],
  74. 'width': 1,
  75. 'height': 1,
  76. 'borderwidth': 1,
  77. 'textmode': ATTRS_VAL['textmodes'],
  78. 'shape': ATTRS_VAL['shapes'],
  79. 'shrink': 1,
  80. 'stretch': 1,
  81. 'vertical_order': 1,
  82. 'horizontal_order': 1,
  83. }
  84. EDGE_ATTRS = {
  85. 'sourcename': 0,
  86. 'targetname': 0,
  87. 'label': 0,
  88. 'linestyle': ATTRS_VAL['linestyles'],
  89. 'class': 1,
  90. 'thickness': 0,
  91. 'color': ATTRS_VAL['colors'],
  92. 'textcolor': ATTRS_VAL['colors'],
  93. 'arrowcolor': ATTRS_VAL['colors'],
  94. 'backarrowcolor': ATTRS_VAL['colors'],
  95. 'arrowsize': 1,
  96. 'backarrowsize': 1,
  97. 'arrowstyle': ATTRS_VAL['arrowstyles'],
  98. 'backarrowstyle': ATTRS_VAL['arrowstyles'],
  99. 'textmode': ATTRS_VAL['textmodes'],
  100. 'priority': 1,
  101. 'anchor': 1,
  102. 'horizontal_order': 1,
  103. }
  104. # Misc utilities ###############################################################
  105. class VCGPrinter(object):
  106. """A vcg graph writer.
  107. """
  108. def __init__(self, output_stream):
  109. self._stream = output_stream
  110. self._indent = ''
  111. def open_graph(self, **args):
  112. """open a vcg graph
  113. """
  114. self._stream.write('%sgraph:{\n'%self._indent)
  115. self._inc_indent()
  116. self._write_attributes(GRAPH_ATTRS, **args)
  117. def close_graph(self):
  118. """close a vcg graph
  119. """
  120. self._dec_indent()
  121. self._stream.write('%s}\n'%self._indent)
  122. def node(self, title, **args):
  123. """draw a node
  124. """
  125. self._stream.write('%snode: {title:"%s"' % (self._indent, title))
  126. self._write_attributes(NODE_ATTRS, **args)
  127. self._stream.write('}\n')
  128. def edge(self, from_node, to_node, edge_type='', **args):
  129. """draw an edge from a node to another.
  130. """
  131. self._stream.write(
  132. '%s%sedge: {sourcename:"%s" targetname:"%s"' % (
  133. self._indent, edge_type, from_node, to_node))
  134. self._write_attributes(EDGE_ATTRS, **args)
  135. self._stream.write('}\n')
  136. # private ##################################################################
  137. def _write_attributes(self, attributes_dict, **args):
  138. """write graph, node or edge attributes
  139. """
  140. for key, value in args.items():
  141. try:
  142. _type = attributes_dict[key]
  143. except KeyError:
  144. raise Exception('''no such attribute %s
  145. possible attributes are %s''' % (key, attributes_dict.keys()))
  146. if not _type:
  147. self._stream.write('%s%s:"%s"\n' % (self._indent, key, value))
  148. elif _type == 1:
  149. self._stream.write('%s%s:%s\n' % (self._indent, key,
  150. int(value)))
  151. elif value in _type:
  152. self._stream.write('%s%s:%s\n' % (self._indent, key, value))
  153. else:
  154. raise Exception('''value %s isn\'t correct for attribute %s
  155. correct values are %s''' % (value, key, _type))
  156. def _inc_indent(self):
  157. """increment indentation
  158. """
  159. self._indent = ' %s' % self._indent
  160. def _dec_indent(self):
  161. """decrement indentation
  162. """
  163. self._indent = self._indent[:-2]