From d32bd22ae78cf14622476b41b238df7ccff25064 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 2 Jan 2010 21:38:27 +0100 Subject: [PATCH] #309: The ``graphviz`` extension can now output SVG instead of PNG images, controlled by the ``graphviz_output_format`` config value. Patch by Henrique Bastos. --- AUTHORS | 1 + CHANGES | 3 ++ doc/ext/graphviz.rst | 13 +++++-- sphinx/ext/graphviz.py | 79 ++++++++++++++++++++++++++++++++---------- 4 files changed, 76 insertions(+), 20 deletions(-) diff --git a/AUTHORS b/AUTHORS index ebda43077..54f53db2d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -5,6 +5,7 @@ Substantial parts of the templates were written by Armin Ronacher Other contributors, listed alphabetically, are: +* Henrique Bastos -- SVG support for graphviz extension * Daniel Bültmann -- todo extension * Michael Droettboom -- inheritance_diagram extension * Charles Duffy -- original graphviz extension diff --git a/CHANGES b/CHANGES index 3c03e89b2..b56b62945 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,9 @@ Release 1.0 (in development) * Added Epub builder. +* #309: The ``graphviz`` extension can now output SVG instead of PNG + images, controlled by the ``graphviz_output_format`` config value. + * #284: All docinfo metadata is now put into the document metadata, not just the author. diff --git a/doc/ext/graphviz.rst b/doc/ext/graphviz.rst index d007bf258..64d2023b9 100644 --- a/doc/ext/graphviz.rst +++ b/doc/ext/graphviz.rst @@ -25,8 +25,9 @@ It adds these directives: "bar" -> "baz"; } - In HTML output, the code will be rendered to a PNG image. In LaTeX output, - the code will be rendered to an embeddable PDF file. + In HTML output, the code will be rendered to a PNG or SVG image (see + :confval:`graphviz_output_format`). In LaTeX output, the code will be + rendered to an embeddable PDF file. .. directive:: graph @@ -75,3 +76,11 @@ There are also these new config values: Additional command-line arguments to give to dot, as a list. The default is an empty list. This is the right place to set global graph, node or edge attributes via dot's ``-G``, ``-N`` and ``-E`` options. + +.. confval:: graphviz_output_format + + The output format for Graphviz when building HTML files. This must be either + ``'png'`` or ``'svg'``; the default is ``'png'``. + + .. versionadded:: 1.0 + Previously, output always was PNG. diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py index 05ec4ec11..509ea64a4 100644 --- a/sphinx/ext/graphviz.py +++ b/sphinx/ext/graphviz.py @@ -13,6 +13,7 @@ import re import posixpath from os import path +from math import ceil from subprocess import Popen, PIPE try: from hashlib import sha1 as sha @@ -27,6 +28,7 @@ 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): + 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 @@ -139,23 +176,28 @@ def render_dot_html(self, node, code, options, prefix='graphviz', imgcls=None): if fname is None: self.body.append(self.encode(code)) 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, self.encode(code).strip(), imgcss)) + if format == 'svg': + svgtag = get_svg_tag(fname, outfn, imgcls) + self.body.append(svgtag) 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, self.encode(code).strip(), - mapname, imgcss)) - self.body.extend(imgmap) + 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, self.encode(code).strip(), 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, self.encode(code).strip(), + mapname, imgcss)) + self.body.extend(imgmap) + self.body.append('

\n') raise nodes.SkipNode @@ -188,3 +230,4 @@ def setup(app): 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')