merge with trunk

This commit is contained in:
Georg Brandl
2010-01-17 14:24:24 +01:00
22 changed files with 190 additions and 40 deletions

13
CHANGES
View File

@@ -94,9 +94,20 @@ Release 1.0 (in development)
* Added ``htmltitle`` block in layout template.
Release 0.6.4 (in development)
Release 0.6.5 (in development)
==============================
* #321: Fix link generation in the LaTeX builder.
Release 0.6.4 (Jan 12, 2010)
============================
* 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.
* #295: Fix escaping of hyperref targets in LaTeX output.

View File

@@ -46,8 +46,10 @@
<p>
The <a href="http://docs.python.org/dev/">Python documentation</a> and
this page are different examples of Sphinx in use.
You can also download a <a href="http://sphinx.pocoo.org/sphinx.pdf">PDF version</a>
of the Sphinx documentation, generated from the LaTeX Sphinx produces.
You can also download PDF versions of the Sphinx documentation:
a <a href="http://sphinx.pocoo.org/sphinx.pdf">version</a> generated from
the LaTeX Sphinx produces, and a
<a href="http://sphinx.pocoo.org/sphinx-rst2pdf.pdf">version</a> generated by rst2pdf.
</p>
<p>
For examples of how Sphinx source files look, use the &#8220;Show source&#8221;

View File

@@ -63,6 +63,39 @@ github pages
<http://github.com/michaeljones/sphinx-to-github/tree/master>`_ to prepare
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
.. _xhtml to reST: http://docutils.sourceforge.net/sandbox/xhtml2rest/xhtml2rest.py

View File

@@ -21,19 +21,20 @@ Sphinx uses reStructuredText as its markup language, and many of its strengths
come from the power and straightforwardness of reStructuredText and its
parsing and translating suite, the Docutils.
Although it is still under constant development, the following features
are already present, work fine and can be seen "in action" in the Python docs:
Among its features are the following:
* Output formats: HTML (including Windows HTML Help), plain text and LaTeX,
for printable PDF versions
* Output formats: HTML (including derivative formats such as HTML Help, Epub
and Qt Help), plain text and LaTeX or direct PDF output using rst2pdf
* Extensive cross-references: semantic markup and automatic links
for functions, classes, glossary terms and similar pieces of information
* Hierarchical structure: easy definition of a document tree, with automatic
links to siblings, parents and children
* Automatic indices: general index as well as a module index
* Code handling: automatic highlighting using the Pygments highlighter
* Flexible HTML output using the Jinja 2 templating engine
* Various extensions are available, e.g. for automatic testing of snippets
and inclusion of appropriately formatted docstrings.
and inclusion of appropriately formatted docstrings
* Setuptools integration
A development egg can be found `here
<http://bitbucket.org/birkenfeld/sphinx/get/tip.gz#egg=Sphinx-dev>`_.

View File

@@ -98,6 +98,7 @@ class Sphinx(object):
# read config
self.tags = Tags(tags)
self.config = Config(confdir, CONFIG_FILENAME, confoverrides, self.tags)
self.config.check_unicode(self.warn)
# load all extension modules
for extension in self.config.extensions:

View File

@@ -72,7 +72,8 @@ class StandaloneHTMLBuilder(Builder):
embedded = False # for things like HTML help or Qt help: suppresses sidebar
# This is a class attribute because it is mutated by Sphinx.add_javascript.
script_files = ['_static/jquery.js', '_static/doctools.js']
script_files = ['_static/jquery.js', '_static/underscore.js',
'_static/doctools.js']
# Dito for this one.
css_files = []
@@ -731,7 +732,14 @@ class StandaloneHTMLBuilder(Builder):
self.app.emit('html-page-context', pagename, templatename,
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:
outfilename = self.get_outfilename(pagename)
# outfilename's path is in general different from self.outdir

View File

@@ -102,7 +102,13 @@ class LaTeXBuilder(Builder):
doctree.settings.title = title
doctree.settings.docname = docname
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.")
return
self.info("done")
def assemble_doctree(self, indexfile, toctree_only, appendices):

View File

@@ -198,10 +198,13 @@ def main(argv):
tbpath = save_traceback()
print >>error, red('The full traceback has been saved '
'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 '
'error, so that a better error message '
'can be provided next time.')
print >>error, ('Send reports to sphinx-dev@googlegroups.com. '
'Thanks!')
print >>error, (
'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

View File

@@ -10,9 +10,13 @@
"""
import os
import re
from os import path
from sphinx.util import make_filename
from sphinx.errors import ConfigError
nonascii_re = re.compile(r'[\x80-\xff]')
class Config(object):
@@ -140,20 +144,35 @@ class Config(object):
self.values = Config.config_values.copy()
config = {}
if dirname is not None:
config['__file__'] = path.join(dirname, filename)
config_file = path.join(dirname, filename)
config['__file__'] = config_file
config['tags'] = tags
olddir = os.getcwd()
try:
os.chdir(dirname)
execfile(config['__file__'], config)
try:
os.chdir(dirname)
execfile(config['__file__'], config)
except SyntaxError, err:
raise ConfigError('There is a syntax error in your '
'configuration file: ' + str(err))
finally:
os.chdir(olddir)
self._raw_config = config
# these two must be preinitialized because extensions can add their
# own config values
self.setup = config.get('setup', None)
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):
config = self._raw_config
for valname, value in self.overrides.iteritems():

View File

@@ -369,7 +369,7 @@ class StandardDomain(Domain):
docname, labelid = self.data['objects'].get((typ, target), ('', ''))
if not docname:
if typ == 'term':
env.warn(node['refdoc'],
env.warn(node.get('refdoc', fromdocname),
'term not in glossary: %s' % target, node.line)
return None
else:

View File

@@ -1222,6 +1222,7 @@ class BuildEnvironment:
typ = node['reftype']
target = node['reftarget']
refdoc = node.get('refdoc', fromdocname)
try:
if node.has_key('refdomain') and node['refdomain']:
@@ -1240,7 +1241,7 @@ class BuildEnvironment:
docname, labelid = self.anonlabels.get(target, ('',''))
sectname = node.astext()
if not docname:
self.warn(node['refdoc'], 'undefined label: %s' %
self.warn(refdoc, 'undefined label: %s' %
target, node.line)
else:
# reference to named label; the final node will
@@ -1248,8 +1249,7 @@ class BuildEnvironment:
docname, labelid, sectname = self.labels.get(target,
('','',''))
if not docname:
self.warn(
node['refdoc'],
self.warn(refdoc,
'undefined label: %s' % target + ' -- if you '
'don\'t give a link caption the label must '
'precede a section header.', node.line)
@@ -1273,9 +1273,9 @@ class BuildEnvironment:
elif typ == 'doc':
# directly reference to document by source name;
# can be absolute or relative
docname = docname_join(node['refdoc'], target)
docname = docname_join(refdoc, target)
if docname not in self.all_docs:
self.warn(node['refdoc'],
self.warn(refdoc,
'unknown document: %s' % docname, node.line)
else:
if node['refexplicit']:
@@ -1300,8 +1300,7 @@ class BuildEnvironment:
# keywords are oddballs: they are referenced by named labels
docname, labelid, _ = self.labels.get(target, ('','',''))
if not docname:
#self.warn(node['refdoc'],
# 'unknown keyword: %s' % target)
#self.warn(refdoc, 'unknown keyword: %s' % target)
pass
else:
newnode = make_refnode(builder, fromdocname, docname,

View File

@@ -44,6 +44,10 @@ class ExtensionError(SphinxError):
return parent_str
class ConfigError(SphinxError):
category = 'Configuration error'
class ThemeError(SphinxError):
category = 'Theme error'

View File

@@ -30,7 +30,7 @@
.. rubric:: Exceptions
.. autosummary::
{% for item in classes %}
{% for item in exceptions %}
{{ item }}
{%- endfor %}
{% endif %}

View File

@@ -24,7 +24,7 @@ from docutils import nodes
from docutils.parsers.rst import directives
from sphinx.errors import SphinxError
from sphinx.util import ensuredir, ENOENT
from sphinx.util import ensuredir, ENOENT, EPIPE
from sphinx.util.compat import Directive
@@ -113,6 +113,10 @@ def render_dot(self, code, options, format, prefix='graphviz'):
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.extend(self.builder.config.graphviz_dot_args)
dot_args.extend(options)
@@ -129,10 +133,17 @@ def render_dot(self, code, options, format, prefix='graphviz'):
self.builder.config.graphviz_dot)
self.builder._graphviz_warned_dot = True
return None, None
# graphviz expects UTF-8 by default
if isinstance(code, unicode):
code = code.encode('utf-8')
stdout, stderr = p.communicate(code)
try:
# Graphviz may close standard input when an error occurs,
# resulting in a broken pipe on communicate()
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:
raise GraphvizError('dot exited with error:\n[stderr]\n%s\n'
'[stdout]\n%s' % (stderr, stdout))

View File

@@ -9,6 +9,11 @@
*
*/
/**
* select a different prefix for underscore
*/
$u = _.noConflict();
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
@@ -54,7 +59,7 @@ jQuery.getQueryParameters = function(s) {
result[key] = [value];
}
return result;
}
};
/**
* small function to check if an array contains
@@ -66,7 +71,7 @@ jQuery.contains = function(arr, item) {
return true;
}
return false;
}
};
/**
* highlight a given string on a jquery object by wrapping it in
@@ -96,7 +101,7 @@ jQuery.fn.highlightText = function(text, className) {
return this.each(function() {
highlight(this);
});
}
};
/**
* Small JavaScript module for the documentation.

View File

@@ -312,7 +312,7 @@ var Search = {
var tmp = query.split(/\s+/);
var object = (tmp.length == 1) ? tmp[0].toLowerCase() : null;
for (var i = 0; i < tmp.length; i++) {
if (stopwords.indexOf(tmp[i]) != -1 || tmp[i].match(/^\d+$/)) {
if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/)) {
// skip this word
continue;
}

View File

@@ -0,0 +1,16 @@
(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e<f;e++)c.call(d,
a[e],e,a);else{var g=b.keys(a);f=g.length;for(e=0;e<f;e++)c.call(d,a[g[e]],g[e],a)}}catch(h){if(h!=m)throw h;}return a};b.map=function(a,c,d){if(a&&b.isFunction(a.map))return a.map(c,d);var e=[];b.each(a,function(f,g,h){e.push(c.call(d,f,g,h))});return e};b.reduce=function(a,c,d,e){if(a&&b.isFunction(a.reduce))return a.reduce(b.bind(d,e),c);b.each(a,function(f,g,h){c=d.call(e,c,f,g,h)});return c};b.reduceRight=function(a,c,d,e){if(a&&b.isFunction(a.reduceRight))return a.reduceRight(b.bind(d,e),c);
var f=b.clone(b.toArray(a)).reverse();b.each(f,function(g,h){c=d.call(e,c,g,h,a)});return c};b.detect=function(a,c,d){var e;b.each(a,function(f,g,h){if(c.call(d,f,g,h)){e=f;b.breakLoop()}});return e};b.select=function(a,c,d){if(a&&b.isFunction(a.filter))return a.filter(c,d);var e=[];b.each(a,function(f,g,h){c.call(d,f,g,h)&&e.push(f)});return e};b.reject=function(a,c,d){var e=[];b.each(a,function(f,g,h){!c.call(d,f,g,h)&&e.push(f)});return e};b.all=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.every))return a.every(c,
d);var e=true;b.each(a,function(f,g,h){(e=e&&c.call(d,f,g,h))||b.breakLoop()});return e};b.any=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.some))return a.some(c,d);var e=false;b.each(a,function(f,g,h){if(e=c.call(d,f,g,h))b.breakLoop()});return e};b.include=function(a,c){if(b.isArray(a))return b.indexOf(a,c)!=-1;var d=false;b.each(a,function(e){if(d=e===c)b.breakLoop()});return d};b.invoke=function(a,c){var d=b.rest(arguments,2);return b.map(a,function(e){return(c?e[c]:e).apply(e,d)})};b.pluck=
function(a,c){return b.map(a,function(d){return d[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g>=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g<e.computed&&(e={value:f,computed:g})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,
function(e,f,g){return{value:e,criteria:c.call(d,e,f,g)}}).sort(function(e,f){e=e.criteria;f=f.criteria;return e<f?-1:e>f?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?(e=g+1):(f=g)}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return k.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=function(a,c,d){return c&&!d?k.call(a,
0,c):a[0]};b.rest=function(a,c,d){return k.call(a,b.isUndefined(c)||d?1:c)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.select(a,function(c){return!!c})};b.flatten=function(a){return b.reduce(a,[],function(c,d){if(b.isArray(d))return c.concat(b.flatten(d));c.push(d);return c})};b.without=function(a){var c=b.rest(arguments);return b.select(a,function(d){return!b.include(c,d)})};b.uniq=function(a,c){return b.reduce(a,[],function(d,e,f){if(0==f||(c===true?b.last(d)!=e:!b.include(d,
e)))d.push(e);return d})};b.intersect=function(a){var c=b.rest(arguments);return b.select(b.uniq(a),function(d){return b.all(c,function(e){return b.indexOf(e,d)>=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e<c;e++)d[e]=b.pluck(a,String(e));return d};b.indexOf=function(a,c){if(a.indexOf)return a.indexOf(c);for(var d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,c){if(a.lastIndexOf)return a.lastIndexOf(c);for(var d=
a.length;d--;)if(a[d]===c)return d;return-1};b.range=function(a,c,d){var e=b.toArray(arguments),f=e.length<=1;a=f?0:e[0];c=f?e[0]:e[1];d=e[2]||1;e=Math.ceil((c-a)/d);if(e<=0)return[];e=new Array(e);f=a;for(var g=0;1;f+=d){if((d>0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)});
return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length);
var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false;
if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length==
0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&&
a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g,
" ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments);
o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})();

View File

@@ -210,6 +210,18 @@ div.admonition p.admonition-title + p {
display: inline;
}
div.admonition p {
margin-bottom: 5px;
}
div.admonition pre {
margin-bottom: 5px;
}
div.admonition ul, div.admonition ol {
margin-bottom: 5px;
}
div.note {
background-color: #eee;
border: 1px solid #ccc;

View File

@@ -34,6 +34,7 @@ from sphinx.errors import PycodeError
# Errnos that we need.
EEXIST = getattr(errno, 'EEXIST', 0)
ENOENT = getattr(errno, 'ENOENT', 0)
EPIPE = getattr(errno, 'EPIPE', 0)
# Generally useful regular expressions.
ws_re = re.compile(r'\s+')

View File

@@ -1046,13 +1046,15 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.body.append('\\href{%s}{' % self.encode_uri(uri))
self.context.append('}')
elif uri.startswith('#'):
self.body.append('\\hyperlink{%s}{' % uri[1:])
# references to labels
self.body.append('\\hyperlink{%s}{' % self.idescape(uri[1:]))
self.context.append('}')
elif uri.startswith('%'):
# references to documents or labels inside documents
hashindex = uri.find('#')
targetname = (hashindex == -1) and '--doc-' + uri[1:] \
or uri[hashindex+1:]
self.body.append('\\hyperlink{%s}{' % targetname)
self.body.append('\\hyperlink{%s}{' % self.idescape(targetname))
self.context.append('}')
elif uri.startswith('@token'):
if self.in_production_list:

View File

@@ -12,7 +12,8 @@
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',
@@ -77,3 +78,19 @@ def test_extension_values(app):
'html_title', 'x', True)
raises_msg(ExtensionError, 'already present', app.add_config_value,
'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]

View File

@@ -154,8 +154,7 @@ def check_whitespace_and_spelling(fn, lines):
yield lno+1, '"%s" used' % word
bad_tags = ('<u>', '<s>', '<strike>'
'<center>', '<big>', '<small>', '<font')
bad_tags = ('<u>', '<s>', '<strike>', '<center>', '<font')
@checker('.html')
def check_xhtml(fn, lines):