Fix #5002: graphviz: SVGs do not adapt to the column width

This commit is contained in:
Takeshi KOMIYA 2018-08-04 18:38:39 +09:00
parent e5a3f67cf7
commit f591cba27f
5 changed files with 50 additions and 15 deletions

View File

@ -200,6 +200,7 @@ Bugs fixed
* #5114: sphinx-build: Handle errors on scanning documents * #5114: sphinx-build: Handle errors on scanning documents
* epub: spine has been broken when "self" is listed on toctree (refs: #4611) * epub: spine has been broken when "self" is listed on toctree (refs: #4611)
* #344: autosummary does not understand docstring of module level attributes * #344: autosummary does not understand docstring of module level attributes
* #5002: graphviz: SVGs do not adapt to the column width
Testing Testing
-------- --------

View File

@ -27,6 +27,7 @@ from sphinx.errors import SphinxError
from sphinx.locale import _, __ from sphinx.locale import _, __
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.fileutil import copy_asset_file
from sphinx.util.i18n import search_image_for_language from sphinx.util.i18n import search_image_for_language
from sphinx.util.osutil import ensuredir, ENOENT, EPIPE, EINVAL from sphinx.util.osutil import ensuredir, ENOENT, EPIPE, EINVAL
@ -281,19 +282,23 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
logger.warning(__('dot code %r: %s'), code, text_type(exc)) logger.warning(__('dot code %r: %s'), code, text_type(exc))
raise nodes.SkipNode raise nodes.SkipNode
if imgcls:
imgcls += " graphviz"
else:
imgcls = "graphviz"
if fname is None: if fname is None:
self.body.append(self.encode(code)) self.body.append(self.encode(code))
else: else:
if alt is None: if alt is None:
alt = node.get('alt', self.encode(code).strip()) alt = node.get('alt', self.encode(code).strip())
imgcss = imgcls and 'class="%s"' % imgcls or ''
if 'align' in node: if 'align' in node:
self.body.append('<div align="%s" class="align-%s">' % self.body.append('<div align="%s" class="align-%s">' %
(node['align'], node['align'])) (node['align'], node['align']))
if format == 'svg': if format == 'svg':
self.body.append('<div class="graphviz">') self.body.append('<div class="graphviz">')
self.body.append('<object data="%s" type="image/svg+xml" %s>\n' % self.body.append('<object data="%s" type="image/svg+xml" class="%s">\n' %
(fname, imgcss)) (fname, imgcls))
self.body.append('<p class="warning">%s</p>' % alt) self.body.append('<p class="warning">%s</p>' % alt)
self.body.append('</object></div>\n') self.body.append('</object></div>\n')
else: else:
@ -302,15 +307,15 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
if imgmap.clickable: if imgmap.clickable:
# has a map # has a map
self.body.append('<div class="graphviz">') self.body.append('<div class="graphviz">')
self.body.append('<img src="%s" alt="%s" usemap="#%s" %s/>' % self.body.append('<img src="%s" alt="%s" usemap="#%s" class="%s" />' %
(fname, alt, imgmap.id, imgcss)) (fname, alt, imgmap.id, imgcls))
self.body.append('</div>\n') self.body.append('</div>\n')
self.body.append(imgmap.generate_clickable_map()) self.body.append(imgmap.generate_clickable_map())
else: else:
# nothing in image map # nothing in image map
self.body.append('<div class="graphviz">') self.body.append('<div class="graphviz">')
self.body.append('<img src="%s" alt="%s" %s/>' % self.body.append('<img src="%s" alt="%s" class="%s" />' %
(fname, alt, imgcss)) (fname, alt, imgcls))
self.body.append('</div>\n') self.body.append('</div>\n')
if 'align' in node: if 'align' in node:
self.body.append('</div>\n') self.body.append('</div>\n')
@ -396,6 +401,14 @@ def man_visit_graphviz(self, node):
raise nodes.SkipNode raise nodes.SkipNode
def on_build_finished(app, exc):
# type: (Sphinx, Exception) -> None
if exc is None:
src = path.join(sphinx.package_dir, 'templates', 'graphviz', 'graphviz.css')
dst = path.join(app.outdir, '_static')
copy_asset_file(src, dst)
def setup(app): def setup(app):
# type: (Sphinx) -> Dict[unicode, Any] # type: (Sphinx) -> Dict[unicode, Any]
app.add_node(graphviz, app.add_node(graphviz,
@ -410,4 +423,6 @@ def setup(app):
app.add_config_value('graphviz_dot', 'dot', 'html') app.add_config_value('graphviz_dot', 'dot', 'html')
app.add_config_value('graphviz_dot_args', [], 'html') app.add_config_value('graphviz_dot_args', [], 'html')
app.add_config_value('graphviz_output_format', 'png', 'html') app.add_config_value('graphviz_output_format', 'png', 'html')
app.add_css_file('graphviz.css')
app.connect('build-finished', on_build_finished)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True} return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -0,0 +1,19 @@
/*
* graphviz.css
* ~~~~~~~~~~~~
*
* Sphinx stylesheet -- graphviz extension.
*
* :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
img.graphviz {
border: 0;
max-width: 100%;
}
object.graphviz {
max-width: 100%;
}

View File

@ -30,7 +30,7 @@ def test_graphviz_png_html(app, status, warning):
html = 'Hello <div class="graphviz"><img .*?/></div>\n graphviz world' html = 'Hello <div class="graphviz"><img .*?/></div>\n graphviz world'
assert re.search(html, content, re.S) assert re.search(html, content, re.S)
html = '<img src=".*?" alt="digraph {\n bar -&gt; baz\n}" />' html = '<img src=".*?" alt="digraph {\n bar -&gt; baz\n}" class="graphviz" />'
assert re.search(html, content, re.M) assert re.search(html, content, re.M)
html = (r'<div class="figure align-right" .*?>\s*' html = (r'<div class="figure align-right" .*?>\s*'
@ -41,7 +41,7 @@ def test_graphviz_png_html(app, status, warning):
html = (r'<div align=\"center\" class=\"align-center\">' html = (r'<div align=\"center\" class=\"align-center\">'
r'<div class="graphviz"><img src=\".*\.png\" alt=\"digraph foo {\n' r'<div class="graphviz"><img src=\".*\.png\" alt=\"digraph foo {\n'
r'centered\n' r'centered\n'
r'}\" /></div>\n</div>') r'}\" class="graphviz" /></div>\n</div>')
assert re.search(html, content, re.S) assert re.search(html, content, re.S)
@ -117,7 +117,7 @@ def test_graphviz_i18n(app, status, warning):
app.builder.build_all() app.builder.build_all()
content = (app.outdir / 'index.html').text() content = (app.outdir / 'index.html').text()
html = '<img src=".*?" alt="digraph {\n BAR -&gt; BAZ\n}" />' html = '<img src=".*?" alt="digraph {\n BAR -&gt; BAZ\n}" class="graphviz" />'
assert re.search(html, content, re.M) assert re.search(html, content, re.M)

View File

@ -27,8 +27,8 @@ def test_inheritance_diagram_png_html(app, status, warning):
pattern = ('<div class="figure" id="id1">\n' pattern = ('<div class="figure" id="id1">\n'
'<div class="graphviz">' '<div class="graphviz">'
'<img src="_images/inheritance-\\w+.png" alt="Inheritance diagram of test.Foo" ' '<img src="_images/inheritance-\\w+.png" alt="Inheritance diagram of test.Foo" '
'class="inheritance"/></div>\n<p class="caption"><span class="caption-text">' 'class="inheritance graphviz" /></div>\n<p class="caption">'
'Test Foo!</span><a class="headerlink" href="#id1" ' '<span class="caption-text">Test Foo!</span><a class="headerlink" href="#id1" '
'title="Permalink to this image">\xb6</a></p>') 'title="Permalink to this image">\xb6</a></p>')
assert re.search(pattern, content, re.M) assert re.search(pattern, content, re.M)
@ -44,7 +44,7 @@ def test_inheritance_diagram_svg_html(app, status, warning):
pattern = ('<div class="figure" id="id1">\n' pattern = ('<div class="figure" id="id1">\n'
'<div class="graphviz">' '<div class="graphviz">'
'<object data="_images/inheritance-\\w+.svg" ' '<object data="_images/inheritance-\\w+.svg" '
'type="image/svg\\+xml" class="inheritance">\n' 'type="image/svg\\+xml" class="inheritance graphviz">\n'
'<p class=\"warning\">Inheritance diagram of test.Foo</p>' '<p class=\"warning\">Inheritance diagram of test.Foo</p>'
'</object></div>\n<p class="caption"><span class="caption-text">' '</object></div>\n<p class="caption"><span class="caption-text">'
'Test Foo!</span><a class="headerlink" href="#id1" ' 'Test Foo!</span><a class="headerlink" href="#id1" '
@ -84,8 +84,8 @@ def test_inheritance_diagram_latex_alias(app, status, warning):
pattern = ('<div class="figure" id="id1">\n' pattern = ('<div class="figure" id="id1">\n'
'<div class="graphviz">' '<div class="graphviz">'
'<img src="_images/inheritance-\\w+.png" alt="Inheritance diagram of test.Foo" ' '<img src="_images/inheritance-\\w+.png" alt="Inheritance diagram of test.Foo" '
'class="inheritance"/></div>\n<p class="caption"><span class="caption-text">' 'class="inheritance graphviz" /></div>\n<p class="caption">'
'Test Foo!</span><a class="headerlink" href="#id1" ' '<span class="caption-text">Test Foo!</span><a class="headerlink" href="#id1" '
'title="Permalink to this image">\xb6</a></p>') 'title="Permalink to this image">\xb6</a></p>')
assert re.search(pattern, content, re.M) assert re.search(pattern, content, re.M)