merge with trunk

This commit is contained in:
Georg Brandl 2010-01-07 19:07:50 +01:00
commit a43738e47a
14 changed files with 119 additions and 30 deletions

View File

@ -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

View File

@ -9,6 +9,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.
@ -60,6 +63,10 @@ Release 1.0 (in development)
Release 0.6.4 (in development)
==============================
* The ``alt`` text of inheritance diagrams is now much cleaner.
* Ignore images in section titles when generating link captions.
* #310: support exception messages in the ``testoutput`` blocks of
the ``doctest`` extension.

View File

@ -8,7 +8,7 @@ all: clean-pyc check test
check:
@$(PYTHON) utils/check_sources.py -i build -i dist -i sphinx/style/jquery.js \
-i sphinx/pycode/pgen2 -i sphinx/util/smartypants.py \
-i sphinx/pycode/pgen2 -i sphinx/util/smartypants.py -i .ropeproject \
-i doc/_build -i ez_setup.py -i tests/path.py -i tests/coverage.py -i env .
clean: clean-pyc clean-patchfiles

View File

@ -47,3 +47,8 @@ The extension adds one new config value:
You can also use the usual "explicit title" syntax supported by other roles
that generate links, i.e. ``:issue:`this issue <123>```. In this case, the
*prefix* is not relevant.
.. note::
Since links are generated from the role in the reading stage, they appear as
ordinary links to e.g. the ``linkcheck`` builder.

View File

@ -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.

View File

@ -128,7 +128,7 @@ These themes are:
on the right side. There are currently no options beyond *nosidebar*.
* **scrolls** -- A more lightweight theme, based on `the Jinja documentation
<http://jinja.pocoo.org/documentation/2>`_. The following color options are
<http://jinja.pocoo.org/2/documentation/>`_. The following color options are
available:
- **headerbordercolor**

View File

@ -443,6 +443,10 @@ class StandaloneHTMLBuilder(Builder):
else:
stripped = ''
# we stripped the whole module name
if not mn:
continue
if fl != mn[0].lower() and mn[0] != '_':
# heading
letter = mn[0].upper()

View File

@ -70,6 +70,8 @@ class CheckExternalLinksBuilder(Builder):
lineno = node.line
if uri[0:5] == 'http:' or uri[0:6] == 'https:':
if lineno:
self.info('(line %3d) ' % lineno, nonl=1)
self.info(uri, nonl=1)
if uri in self.broken:

View File

@ -35,7 +35,7 @@ from docutils.transforms.parts import ContentsFilter
from sphinx import addnodes
from sphinx.util import movefile, get_matching_docs, SEP, ustrftime, \
docname_join, FilenameUniqDict, url_re, make_refnode
docname_join, FilenameUniqDict, url_re, make_refnode, clean_astext
from sphinx.errors import SphinxError, ExtensionError
@ -898,11 +898,11 @@ class BuildEnvironment:
node.line)
self.anonlabels[name] = docname, labelid
if node.tagname == 'section':
sectname = node[0].astext() # node[0] == title node
sectname = clean_astext(node[0]) # node[0] == title node
elif node.tagname == 'figure':
for n in node:
if n.tagname == 'caption':
sectname = n.astext()
sectname = clean_astext(n)
break
else:
continue
@ -1130,7 +1130,7 @@ class BuildEnvironment:
# toctree originates
ref = toctreenode['parent']
if not title:
title = self.titles[ref].astext()
title = clean_astext(self.titles[ref])
reference = nodes.reference('', '',
refuri=ref,
anchorname='',
@ -1281,7 +1281,7 @@ class BuildEnvironment:
# reference with explicit title
caption = node.astext()
else:
caption = self.titles[docname].astext()
caption = clean_astext(self.titles[docname])
innernode = nodes.emphasis(caption, caption)
newnode = nodes.reference('', '')
newnode['refuri'] = builder.get_relative_uri(

View File

@ -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'<map id="(.*?)"')
svg_dim_re = re.compile(r'<svg\swidth="(\d+)pt"\sheight="(\d+)pt"', re.M)
class GraphvizError(SphinxError):
@ -128,9 +130,45 @@ def render_dot(self, code, options, format, prefix='graphviz'):
return relfn, outfn
def render_dot_html(self, node, code, options, prefix='graphviz', imgcls=None):
def get_svg_tag(svgref, svgfile, imgcls=None):
# Webkit can't figure out svg dimensions when using object tag
# so we need to get it from the svg file
fp = open(svgfile, 'r')
try:
fname, outfn = render_dot(self, code, options, 'png', prefix)
for line in fp:
match = svg_dim_re.match(line)
if match:
dimensions = match.groups()
break
else:
dimensions = None
finally:
fp.close()
# We need this hack to make WebKit show our object tag properly
def pt2px(x):
return int(ceil((96.0/72.0) * float(x)))
if dimensions:
style = ' width="%s" height="%s"' % tuple(map(pt2px, dimensions))
else:
style = ''
# The object tag works fine on Firefox and WebKit
# Besides it's a hack, this strategy does not mess with templates.
imgcss = imgcls and ' class="%s"' % imgcls or ''
return '<object type="image/svg+xml" data="%s"%s%s/>\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
@ -139,23 +177,29 @@ 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 <map> and </map>)
self.body.append('<img src="%s" alt="%s" %s/>\n' %
(fname, self.encode(code).strip(), imgcss))
if alt is None:
alt = self.encode(code).strip()
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('<img src="%s" alt="%s" usemap="#%s" %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 <map> and </map>)
self.body.append('<img src="%s" alt="%s" %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('<img src="%s" alt="%s" usemap="#%s" %s/>\n' %
(fname, alt, mapname, imgcss))
self.body.extend(imgmap)
self.body.append('</p>\n')
raise nodes.SkipNode
@ -188,3 +232,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')

View File

@ -302,7 +302,7 @@ class InheritanceDiagram(Directive):
node['graph'] = graph
# Store the original content for use as a hash
node['parts'] = self.options.get('parts', 0)
node['content'] = ' '.join(class_names)
node['content'] = ', '.join(class_names)
return [node]
@ -330,7 +330,8 @@ def html_visit_inheritance_diagram(self, node):
urls[child['reftitle']] = '#' + child.get('refid')
dotcode = graph.generate_dot(name, parts, urls, env=self.builder.env)
render_dot_html(self, node, dotcode, [], 'inheritance', 'inheritance')
render_dot_html(self, node, dotcode, [], 'inheritance', 'inheritance',
alt='Inheritance diagram of ' + node['content'])
raise nodes.SkipNode

View File

@ -250,3 +250,11 @@ tt {
th {
background-color: #ede;
}
.warning tt {
background: #efc2c2;
}
.note tt {
background: #d6d6d6;
}

View File

@ -445,6 +445,13 @@ def copy_static_entry(source, target, builder, context={}):
shutil.copytree(source, target)
def clean_astext(node):
"""Like node.astext(), but ignore images."""
node = node.deepcopy()
for img in node.traverse(docutils.nodes.image):
img['alt'] = ''
return node.astext()
def split_explicit_title(text):
"""Split role content into title and target, if given."""

View File

@ -30,7 +30,7 @@ def checker(*suffixes, **kwds):
name_mail_re = r'[\w ]+(<.*?>)?'
copyright_re = re.compile(r'^ :copyright: Copyright 200\d(-200\d)? '
copyright_re = re.compile(r'^ :copyright: Copyright 200\d(-20\d\d)? '
r'by %s(, %s)*[,.]$' %
(name_mail_re, name_mail_re))
license_re = re.compile(r" :license: (.*?).\n")