# -*- coding: utf-8 -*- """ sphinx.ext.graphviz ~~~~~~~~~~~~~~~~~~~ Allow graphviz-formatted graphs to be included in Sphinx-generated documents inline. :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import re import posixpath from os import path from math import ceil from subprocess import Popen, PIPE try: from hashlib import sha1 as sha except ImportError: from sha import sha from docutils import nodes from docutils.parsers.rst import directives from sphinx.errors import SphinxError from sphinx.util.osutil import ensuredir, ENOENT, EPIPE from sphinx.util.compat import Directive mapname_re = re.compile(r'\n' % \ (svgref, imgcss, style) def render_dot_html(self, node, code, options, prefix='graphviz', imgcls=None, alt=None): format = self.builder.config.graphviz_output_format try: if format not in ('png', 'svg'): raise GraphvizError("graphviz_output_format must be one of 'png', " "'svg', but is %r" % format) fname, outfn = render_dot(self, code, options, format, prefix) except GraphvizError, exc: self.builder.warn('dot code %r: ' % code + str(exc)) raise nodes.SkipNode self.body.append(self.starttag(node, 'p', CLASS='graphviz')) if fname is None: self.body.append(self.encode(code)) else: if alt is None: alt = node.get('alt', self.encode(code).strip()) if format == 'svg': svgtag = get_svg_tag(fname, outfn, imgcls) self.body.append(svgtag) else: mapfile = open(outfn + '.map', 'rb') try: imgmap = mapfile.readlines() finally: mapfile.close() imgcss = imgcls and 'class="%s"' % imgcls or '' if len(imgmap) == 2: # nothing in image map (the lines are and ) self.body.append('%s\n' % (fname, alt, imgcss)) else: # has a map: get the name of the map and connect the parts mapname = mapname_re.match(imgmap[0]).group(1) self.body.append('%s\n' % (fname, alt, mapname, imgcss)) self.body.extend(imgmap) self.body.append('

\n') raise nodes.SkipNode def html_visit_graphviz(self, node): render_dot_html(self, node, node['code'], node['options']) def render_dot_latex(self, node, code, options, prefix='graphviz'): try: fname, outfn = render_dot(self, code, options, 'pdf', prefix) except GraphvizError, exc: self.builder.warn('dot code %r: ' % code + str(exc)) raise nodes.SkipNode if fname is not None: self.body.append('\\includegraphics{%s}' % fname) raise nodes.SkipNode def latex_visit_graphviz(self, node): render_dot_latex(self, node, node['code'], node['options']) def setup(app): app.add_node(graphviz, html=(html_visit_graphviz, None), latex=(latex_visit_graphviz, None)) app.add_directive('graphviz', Graphviz) app.add_directive('graph', GraphvizSimple) app.add_directive('digraph', GraphvizSimple) app.add_config_value('graphviz_dot', 'dot', 'html') app.add_config_value('graphviz_dot_args', [], 'html') app.add_config_value('graphviz_output_format', 'png', 'html')