mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
merge with 0.6
This commit is contained in:
commit
8bb4d4320d
5
CHANGES
5
CHANGES
@ -79,6 +79,11 @@ Release 1.0 (in development)
|
|||||||
Release 0.6.4 (in development)
|
Release 0.6.4 (in development)
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
|
* Improve the handling of non-Unicode strings in the configuration.
|
||||||
|
|
||||||
|
* #316: Catch OSErrors occurring when calling graphviz with
|
||||||
|
arguments it doesn't understand.
|
||||||
|
|
||||||
* Restore compatibility with Pygments >= 1.2.
|
* Restore compatibility with Pygments >= 1.2.
|
||||||
|
|
||||||
* #295: Fix escaping of hyperref targets in LaTeX output.
|
* #295: Fix escaping of hyperref targets in LaTeX output.
|
||||||
|
33
doc/faq.rst
33
doc/faq.rst
@ -53,6 +53,39 @@ github pages
|
|||||||
<http://github.com/michaeljones/sphinx-to-github/tree/master>`_ to prepare
|
<http://github.com/michaeljones/sphinx-to-github/tree/master>`_ to prepare
|
||||||
Sphinx HTML output.
|
Sphinx HTML output.
|
||||||
|
|
||||||
|
Google Analytics
|
||||||
|
You can use a custom ``layout.html`` template, like this:
|
||||||
|
|
||||||
|
.. code-block:: html+django
|
||||||
|
|
||||||
|
{% extends "!layout.html" %}
|
||||||
|
|
||||||
|
{%- block extrahead %}
|
||||||
|
{{ super() }}
|
||||||
|
<script type="text/javascript">
|
||||||
|
var _gaq = _gaq || [];
|
||||||
|
_gaq.push(['_setAccount', 'XXX account number XXX']);
|
||||||
|
_gaq.push(['_trackPageview']);
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block footer %}
|
||||||
|
{{ super() }}
|
||||||
|
<div class="footer">This page uses <a href="http://analytics.google.com/">
|
||||||
|
Google Analytics</a> to collect statistics. You can disable it by blocking
|
||||||
|
the JavaScript coming from www.google-analytics.com.
|
||||||
|
<script type="text/javascript">
|
||||||
|
(function() {
|
||||||
|
var ga = document.createElement('script');
|
||||||
|
ga.src = ('https:' == document.location.protocol ?
|
||||||
|
'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||||
|
ga.setAttribute('async', 'true');
|
||||||
|
document.documentElement.firstChild.appendChild(ga);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
.. _api role: http://git.savannah.gnu.org/cgit/kenozooid.git/tree/doc/extapi.py
|
.. _api role: http://git.savannah.gnu.org/cgit/kenozooid.git/tree/doc/extapi.py
|
||||||
.. _xhtml to reST: http://docutils.sourceforge.net/sandbox/xhtml2rest/xhtml2rest.py
|
.. _xhtml to reST: http://docutils.sourceforge.net/sandbox/xhtml2rest/xhtml2rest.py
|
||||||
|
@ -92,6 +92,7 @@ class Sphinx(object):
|
|||||||
# read config
|
# read config
|
||||||
self.tags = Tags(tags)
|
self.tags = Tags(tags)
|
||||||
self.config = Config(confdir, CONFIG_FILENAME, confoverrides, self.tags)
|
self.config = Config(confdir, CONFIG_FILENAME, confoverrides, self.tags)
|
||||||
|
self.config.check_unicode(self.warn)
|
||||||
|
|
||||||
# load all extension modules
|
# load all extension modules
|
||||||
for extension in self.config.extensions:
|
for extension in self.config.extensions:
|
||||||
|
@ -723,7 +723,14 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
self.app.emit('html-page-context', pagename, templatename,
|
self.app.emit('html-page-context', pagename, templatename,
|
||||||
ctx, event_arg)
|
ctx, event_arg)
|
||||||
|
|
||||||
output = self.templates.render(templatename, ctx)
|
try:
|
||||||
|
output = self.templates.render(templatename, ctx)
|
||||||
|
except UnicodeError:
|
||||||
|
self.warn("a Unicode error occurred when rendering the page %s. "
|
||||||
|
"Please make sure all config values that contain "
|
||||||
|
"non-ASCII content are Unicode strings." % pagename)
|
||||||
|
return
|
||||||
|
|
||||||
if not outfilename:
|
if not outfilename:
|
||||||
outfilename = self.get_outfilename(pagename)
|
outfilename = self.get_outfilename(pagename)
|
||||||
# outfilename's path is in general different from self.outdir
|
# outfilename's path is in general different from self.outdir
|
||||||
|
@ -102,7 +102,13 @@ class LaTeXBuilder(Builder):
|
|||||||
doctree.settings.title = title
|
doctree.settings.title = title
|
||||||
doctree.settings.docname = docname
|
doctree.settings.docname = docname
|
||||||
doctree.settings.docclass = docclass
|
doctree.settings.docclass = docclass
|
||||||
docwriter.write(doctree, destination)
|
try:
|
||||||
|
docwriter.write(doctree, destination)
|
||||||
|
except UnicodeError:
|
||||||
|
self.warn("a Unicode error occurred when writing the output. "
|
||||||
|
"Please make sure all config values that contain "
|
||||||
|
"non-ASCII content are Unicode strings." % pagename)
|
||||||
|
return
|
||||||
self.info("done")
|
self.info("done")
|
||||||
|
|
||||||
def assemble_doctree(self, indexfile, toctree_only, appendices):
|
def assemble_doctree(self, indexfile, toctree_only, appendices):
|
||||||
|
@ -198,10 +198,13 @@ def main(argv):
|
|||||||
tbpath = save_traceback()
|
tbpath = save_traceback()
|
||||||
print >>error, red('The full traceback has been saved '
|
print >>error, red('The full traceback has been saved '
|
||||||
'in %s, if you want to report the '
|
'in %s, if you want to report the '
|
||||||
'issue to the author.' % tbpath)
|
'issue to the developers.' % tbpath)
|
||||||
print >>error, ('Please also report this if it was a user '
|
print >>error, ('Please also report this if it was a user '
|
||||||
'error, so that a better error message '
|
'error, so that a better error message '
|
||||||
'can be provided next time.')
|
'can be provided next time.')
|
||||||
print >>error, ('Send reports to sphinx-dev@googlegroups.com. '
|
print >>error, (
|
||||||
'Thanks!')
|
'Either send bugs to the mailing list at '
|
||||||
|
'<http://groups.google.com/group/sphinx-dev/>,\n'
|
||||||
|
'or report them in the tracker at '
|
||||||
|
'<http://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!')
|
||||||
return 1
|
return 1
|
||||||
|
@ -10,9 +10,13 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
from sphinx.util import make_filename
|
from sphinx.util import make_filename
|
||||||
|
from sphinx.errors import ConfigError
|
||||||
|
|
||||||
|
nonascii_re = re.compile(r'[\x80-\xff]')
|
||||||
|
|
||||||
|
|
||||||
class Config(object):
|
class Config(object):
|
||||||
@ -135,20 +139,34 @@ class Config(object):
|
|||||||
self.values = Config.config_values.copy()
|
self.values = Config.config_values.copy()
|
||||||
config = {}
|
config = {}
|
||||||
if dirname is not None:
|
if dirname is not None:
|
||||||
config['__file__'] = path.join(dirname, filename)
|
config_file = path.join(dirname, filename)
|
||||||
|
config['__file__'] = config_file
|
||||||
config['tags'] = tags
|
config['tags'] = tags
|
||||||
olddir = os.getcwd()
|
olddir = os.getcwd()
|
||||||
try:
|
try:
|
||||||
os.chdir(dirname)
|
os.chdir(dirname)
|
||||||
execfile(config['__file__'], config)
|
execfile(config['__file__'], config)
|
||||||
|
except SyntaxError, err:
|
||||||
|
raise ConfigError('There is a syntax error in your '
|
||||||
|
'configuration file: ' + str(err))
|
||||||
finally:
|
finally:
|
||||||
os.chdir(olddir)
|
os.chdir(olddir)
|
||||||
|
|
||||||
self._raw_config = config
|
self._raw_config = config
|
||||||
# these two must be preinitialized because extensions can add their
|
# these two must be preinitialized because extensions can add their
|
||||||
# own config values
|
# own config values
|
||||||
self.setup = config.get('setup', None)
|
self.setup = config.get('setup', None)
|
||||||
self.extensions = config.get('extensions', [])
|
self.extensions = config.get('extensions', [])
|
||||||
|
|
||||||
|
def check_unicode(self, warn):
|
||||||
|
# check all string values for non-ASCII characters in
|
||||||
|
# bytestrings, since that can
|
||||||
|
for name, value in self._raw_config.iteritems():
|
||||||
|
if isinstance(value, str) and nonascii_re.search(value):
|
||||||
|
warn('the config value %r is set to a string with non-ASCII '
|
||||||
|
'characters; this can lead to Unicode errors occurring. '
|
||||||
|
'Please use Unicode strings, e.g. u"Content".' % name)
|
||||||
|
|
||||||
def init_values(self):
|
def init_values(self):
|
||||||
config = self._raw_config
|
config = self._raw_config
|
||||||
for valname, value in self.overrides.iteritems():
|
for valname, value in self.overrides.iteritems():
|
||||||
|
@ -44,5 +44,9 @@ class ExtensionError(SphinxError):
|
|||||||
return parent_str
|
return parent_str
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigError(SphinxError):
|
||||||
|
category = 'Configuration error'
|
||||||
|
|
||||||
|
|
||||||
class ThemeError(SphinxError):
|
class ThemeError(SphinxError):
|
||||||
category = 'Theme error'
|
category = 'Theme error'
|
||||||
|
@ -24,7 +24,7 @@ from docutils import nodes
|
|||||||
from docutils.parsers.rst import directives
|
from docutils.parsers.rst import directives
|
||||||
|
|
||||||
from sphinx.errors import SphinxError
|
from sphinx.errors import SphinxError
|
||||||
from sphinx.util import ensuredir, ENOENT
|
from sphinx.util import ensuredir, ENOENT, EPIPE
|
||||||
from sphinx.util.compat import Directive
|
from sphinx.util.compat import Directive
|
||||||
|
|
||||||
|
|
||||||
@ -113,6 +113,10 @@ def render_dot(self, code, options, format, prefix='graphviz'):
|
|||||||
|
|
||||||
ensuredir(path.dirname(outfn))
|
ensuredir(path.dirname(outfn))
|
||||||
|
|
||||||
|
# graphviz expects UTF-8 by default
|
||||||
|
if isinstance(code, unicode):
|
||||||
|
code = code.encode('utf-8')
|
||||||
|
|
||||||
dot_args = [self.builder.config.graphviz_dot]
|
dot_args = [self.builder.config.graphviz_dot]
|
||||||
dot_args.extend(self.builder.config.graphviz_dot_args)
|
dot_args.extend(self.builder.config.graphviz_dot_args)
|
||||||
dot_args.extend(options)
|
dot_args.extend(options)
|
||||||
@ -129,10 +133,17 @@ def render_dot(self, code, options, format, prefix='graphviz'):
|
|||||||
self.builder.config.graphviz_dot)
|
self.builder.config.graphviz_dot)
|
||||||
self.builder._graphviz_warned_dot = True
|
self.builder._graphviz_warned_dot = True
|
||||||
return None, None
|
return None, None
|
||||||
# graphviz expects UTF-8 by default
|
try:
|
||||||
if isinstance(code, unicode):
|
# Graphviz may close standard input when an error occurs,
|
||||||
code = code.encode('utf-8')
|
# resulting in a broken pipe on communicate()
|
||||||
stdout, stderr = p.communicate(code)
|
stdout, stderr = p.communicate(code)
|
||||||
|
except OSError, err:
|
||||||
|
if err.errno != EPIPE:
|
||||||
|
raise
|
||||||
|
# in this case, read the standard output and standard error streams
|
||||||
|
# directly, to get the error message(s)
|
||||||
|
stdout, stderr = p.stdout.read(), p.stderr.read()
|
||||||
|
p.wait()
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise GraphvizError('dot exited with error:\n[stderr]\n%s\n'
|
raise GraphvizError('dot exited with error:\n[stderr]\n%s\n'
|
||||||
'[stdout]\n%s' % (stderr, stdout))
|
'[stdout]\n%s' % (stderr, stdout))
|
||||||
|
@ -32,6 +32,7 @@ import sphinx
|
|||||||
# Errnos that we need.
|
# Errnos that we need.
|
||||||
EEXIST = getattr(errno, 'EEXIST', 0)
|
EEXIST = getattr(errno, 'EEXIST', 0)
|
||||||
ENOENT = getattr(errno, 'ENOENT', 0)
|
ENOENT = getattr(errno, 'ENOENT', 0)
|
||||||
|
EPIPE = getattr(errno, 'EPIPE', 0)
|
||||||
|
|
||||||
# Generally useful regular expressions.
|
# Generally useful regular expressions.
|
||||||
ws_re = re.compile(r'\s+')
|
ws_re = re.compile(r'\s+')
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
from util import *
|
from util import *
|
||||||
|
|
||||||
from sphinx.application import ExtensionError
|
from sphinx.config import Config
|
||||||
|
from sphinx.errors import ExtensionError, ConfigError
|
||||||
|
|
||||||
|
|
||||||
@with_app(confoverrides={'master_doc': 'master', 'nonexisting_value': 'True',
|
@with_app(confoverrides={'master_doc': 'master', 'nonexisting_value': 'True',
|
||||||
@ -77,3 +78,19 @@ def test_extension_values(app):
|
|||||||
'html_title', 'x', True)
|
'html_title', 'x', True)
|
||||||
raises_msg(ExtensionError, 'already present', app.add_config_value,
|
raises_msg(ExtensionError, 'already present', app.add_config_value,
|
||||||
'value_from_ext', 'x', True)
|
'value_from_ext', 'x', True)
|
||||||
|
|
||||||
|
|
||||||
|
@with_tempdir
|
||||||
|
def test_errors_warnings(dir):
|
||||||
|
# test the error for syntax errors in the config file
|
||||||
|
write_file(dir / 'conf.py', 'project = \n')
|
||||||
|
raises_msg(ConfigError, 'conf.py', Config, dir, 'conf.py', {}, None)
|
||||||
|
|
||||||
|
# test the warning for bytestrings with non-ascii content
|
||||||
|
write_file(dir / 'conf.py', '# -*- coding: latin-1\nproject = "foo\xe4"\n')
|
||||||
|
cfg = Config(dir, 'conf.py', {}, None)
|
||||||
|
warned = [False]
|
||||||
|
def warn(msg):
|
||||||
|
warned[0] = True
|
||||||
|
cfg.check_unicode(warn)
|
||||||
|
assert warned[0]
|
||||||
|
Loading…
Reference in New Issue
Block a user