mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Further fixes. All produced latex documents now run through pdflatex without errors.
This commit is contained in:
parent
fe94305a20
commit
e77b466281
@ -59,14 +59,13 @@ class relpath_to(object):
|
||||
class collect_env_warnings(object):
|
||||
def __init__(self, builder):
|
||||
self.builder = builder
|
||||
self.warnings = []
|
||||
def __enter__(self):
|
||||
self.stream = StringIO.StringIO()
|
||||
self.builder.env.set_warning_stream(self.stream)
|
||||
self.builder.env.set_warnfunc(self.warnings.append)
|
||||
def __exit__(self, *args):
|
||||
self.builder.env.set_warning_stream(self.builder.warning_stream)
|
||||
warnings = self.stream.getvalue()
|
||||
if warnings:
|
||||
print >>self.builder.warning_stream, warnings
|
||||
self.builder.env.set_warnfunc(self.builder.warn)
|
||||
for warning in self.warnings:
|
||||
self.builder.warn(warning)
|
||||
|
||||
|
||||
class Builder(object):
|
||||
@ -90,6 +89,9 @@ class Builder(object):
|
||||
self.options = attrdict(options)
|
||||
self.validate_options()
|
||||
|
||||
self.status_stream = status_stream or sys.stdout
|
||||
self.warning_stream = warning_stream or sys.stderr
|
||||
|
||||
# probably set in load_env()
|
||||
self.env = env
|
||||
|
||||
@ -108,17 +110,13 @@ class Builder(object):
|
||||
version, release = get_version_info(srcdirname)
|
||||
except (IOError, OSError):
|
||||
version, release = get_sys_version_info()
|
||||
print >>warning_stream, 'WARNING: Can\'t get version info from ' \
|
||||
'Include/patchlevel.h, using version of this ' \
|
||||
'interpreter (%s).' % release
|
||||
self.warn('Can\'t get version info from Include/patchlevel.h, '
|
||||
'using version of this interpreter (%s).' % release)
|
||||
if self.config['version'] == 'auto':
|
||||
self.config['version'] = version
|
||||
if self.config['release'] == 'auto':
|
||||
self.config['release'] = release
|
||||
|
||||
self.status_stream = status_stream or sys.stdout
|
||||
self.warning_stream = warning_stream or sys.stderr
|
||||
|
||||
self.init()
|
||||
|
||||
# helper methods
|
||||
@ -139,6 +137,9 @@ class Builder(object):
|
||||
print >>self.status_stream, message
|
||||
self.status_stream.flush()
|
||||
|
||||
def warn(self, message):
|
||||
print >>self.warning_stream, 'WARNING:', message
|
||||
|
||||
def init(self):
|
||||
"""Load necessary templates and perform initialization."""
|
||||
raise NotImplementedError
|
||||
@ -527,7 +528,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
with codecs.open(outfilename, 'w', 'utf-8') as fp:
|
||||
fp.write(output)
|
||||
except (IOError, OSError), err:
|
||||
print >>self.warning_stream, "Error writing file %s: %s" % (outfilename, err)
|
||||
self.warn("Error writing file %s: %s" % (outfilename, err))
|
||||
if self.copysource and context.get('sourcename'):
|
||||
# copy the source file for the "show source" link
|
||||
shutil.copyfile(path.join(self.srcdir, os_path(filename)),
|
||||
@ -707,7 +708,7 @@ class LaTeXBuilder(Builder):
|
||||
self.filenames = set([indexfile, 'glossary.rst', 'about.rst',
|
||||
'license.rst', 'copyright.rst'])
|
||||
print green(indexfile),
|
||||
def process_tree(tree):
|
||||
def process_tree(filename, tree):
|
||||
#tree = tree.deepcopy() XXX
|
||||
for toctreenode in tree.traverse(addnodes.toctree):
|
||||
newnodes = []
|
||||
@ -715,16 +716,17 @@ class LaTeXBuilder(Builder):
|
||||
for includefile in includefiles:
|
||||
try:
|
||||
print green(includefile),
|
||||
subtree = process_tree(self.env.get_doctree(includefile))
|
||||
subtree = process_tree(includefile,
|
||||
self.env.get_doctree(includefile))
|
||||
self.filenames.add(includefile)
|
||||
except:
|
||||
print >>self.warning_stream, 'WARNING: %s: toctree contains ' \
|
||||
'ref to nonexisting file %r' % (filename, includefile)
|
||||
self.warn('%s: toctree contains ref to nonexisting file %r' %
|
||||
(filename, includefile))
|
||||
else:
|
||||
newnodes.extend(subtree.children)
|
||||
toctreenode.parent.replace(toctreenode, newnodes)
|
||||
return tree
|
||||
largetree = process_tree(self.env.get_doctree(indexfile))
|
||||
largetree = process_tree(indexfile, self.env.get_doctree(indexfile))
|
||||
largetree.extend(specials)
|
||||
print
|
||||
print "resolving references..."
|
||||
|
@ -74,6 +74,11 @@ default_substitutions = set([
|
||||
])
|
||||
|
||||
|
||||
class RedirStream(object):
|
||||
def __init__(self, write):
|
||||
self.write = write
|
||||
|
||||
|
||||
class NoUri(Exception):
|
||||
"""Raised by get_relative_uri if there is no URI available."""
|
||||
pass
|
||||
@ -159,12 +164,12 @@ class BuildEnvironment:
|
||||
|
||||
def topickle(self, filename):
|
||||
# remove unpicklable attributes
|
||||
wstream = self.warning_stream
|
||||
self.set_warning_stream(None)
|
||||
warnfunc = self._warnfunc
|
||||
self.set_warnfunc(None)
|
||||
with open(filename, 'wb') as picklefile:
|
||||
pickle.dump(self, picklefile, pickle.HIGHEST_PROTOCOL)
|
||||
# reset stream
|
||||
self.set_warning_stream(wstream)
|
||||
self.set_warnfunc(warnfunc)
|
||||
|
||||
# --------- ENVIRONMENT INITIALIZATION -------------------------------------
|
||||
|
||||
@ -181,8 +186,8 @@ class BuildEnvironment:
|
||||
self.settings = default_settings.copy()
|
||||
self.settings['env'] = self
|
||||
|
||||
# the stream to write warning messages to
|
||||
self.warning_stream = None
|
||||
# the function to write warning messages with
|
||||
self._warnfunc = None
|
||||
|
||||
# this is to invalidate old pickles
|
||||
self.version = ENV_VERSION
|
||||
@ -227,9 +232,9 @@ class BuildEnvironment:
|
||||
self.index_num = 0 # autonumber for index targets
|
||||
self.gloss_entries = set() # existing definition labels
|
||||
|
||||
def set_warning_stream(self, stream):
|
||||
self.warning_stream = stream
|
||||
self.settings['warning_stream'] = stream
|
||||
def set_warnfunc(self, func):
|
||||
self._warnfunc = func
|
||||
self.settings['warnfunc'] = func
|
||||
|
||||
def clear_file(self, filename):
|
||||
"""Remove all traces of a source file in the inventory."""
|
||||
@ -367,7 +372,7 @@ class BuildEnvironment:
|
||||
doctree.reporter = None
|
||||
doctree.transformer = None
|
||||
doctree.settings.env = None
|
||||
doctree.settings.warning_stream = None
|
||||
doctree.settings.warnfunc = None
|
||||
|
||||
# cleanup
|
||||
self.filename = None
|
||||
@ -429,9 +434,8 @@ class BuildEnvironment:
|
||||
continue
|
||||
sectname = node[0].astext() # node[0] == title node
|
||||
if name in self.labels:
|
||||
print >>self.warning_stream, \
|
||||
('WARNING: duplicate label %s, ' % name +
|
||||
'in %s and %s' % (self.labels[name][0], filename))
|
||||
self._warnfunc('duplicate label %s, ' % name +
|
||||
'in %s and %s' % (self.labels[name][0], filename))
|
||||
self.labels[name] = filename, labelid, sectname
|
||||
|
||||
def note_toctree(self, filename, toctreenode):
|
||||
@ -509,9 +513,8 @@ class BuildEnvironment:
|
||||
#
|
||||
def note_descref(self, fullname, desctype):
|
||||
if fullname in self.descrefs:
|
||||
print >>self.warning_stream, \
|
||||
('WARNING: duplicate canonical description name %s, ' % fullname +
|
||||
'in %s and %s' % (self.descrefs[fullname][0], self.filename))
|
||||
self._warnfunc('duplicate canonical description name %s, ' % fullname +
|
||||
'in %s and %s' % (self.descrefs[fullname][0], self.filename))
|
||||
self.descrefs[fullname] = (self.filename, desctype)
|
||||
|
||||
def note_module(self, modname, synopsis, platform, deprecated):
|
||||
@ -537,7 +540,7 @@ class BuildEnvironment:
|
||||
doctree_filename = path.join(self.doctreedir, os_path(filename)[:-3] + 'doctree')
|
||||
with file(doctree_filename, 'rb') as f:
|
||||
doctree = pickle.load(f)
|
||||
doctree.reporter = Reporter(filename, 2, 4, stream=self.warning_stream)
|
||||
doctree.reporter = Reporter(filename, 2, 4, stream=RedirStream(self._warnfunc))
|
||||
return doctree
|
||||
|
||||
def get_and_resolve_doctree(self, filename, builder, doctree=None):
|
||||
@ -560,8 +563,8 @@ class BuildEnvironment:
|
||||
toc = self.tocs[includefile].deepcopy()
|
||||
except KeyError, err:
|
||||
# this is raised if the included file does not exist
|
||||
print >>self.warning_stream, 'WARNING: %s: toctree contains ' \
|
||||
'ref to nonexisting file %r' % (filename, includefile)
|
||||
self._warnfunc('%s: toctree contains ref to nonexisting '
|
||||
'file %r' % (filename, includefile))
|
||||
else:
|
||||
for toctreenode in toc.traverse(addnodes.toctree):
|
||||
toctreenode.parent.replace_self(
|
||||
@ -604,8 +607,7 @@ class BuildEnvironment:
|
||||
if not filename:
|
||||
newnode = doctree.reporter.system_message(
|
||||
2, 'undefined label: %s' % target)
|
||||
print >>self.warning_stream, \
|
||||
'%s: undefined label: %s' % (docfilename, target)
|
||||
self._warnfunc('%s: undefined label: %s' % (docfilename, target))
|
||||
else:
|
||||
newnode = nodes.reference('', '')
|
||||
innernode = nodes.emphasis(sectname, sectname)
|
||||
@ -622,8 +624,8 @@ class BuildEnvironment:
|
||||
filename, labelid = self.reftargets.get((typ, target), ('', ''))
|
||||
if not filename:
|
||||
if typ == 'term':
|
||||
print >>self.warning_stream, \
|
||||
'%s: term not in glossary: %s' % (docfilename, target)
|
||||
self._warnfunc('%s: term not in glossary: %s' %
|
||||
(docfilename, target))
|
||||
newnode = contnode
|
||||
else:
|
||||
newnode = nodes.reference('', '')
|
||||
@ -714,8 +716,7 @@ class BuildEnvironment:
|
||||
add_entry(string, 'built-in function')
|
||||
add_entry('built-in function', string)
|
||||
else:
|
||||
print >>self.warning_stream, \
|
||||
"unknown index entry type %r in %s" % (type, fn)
|
||||
self._warnfunc("unknown index entry type %r in %s" % (type, fn))
|
||||
|
||||
newlist = new.items()
|
||||
newlist.sort(key=lambda t: t[0].lower())
|
||||
@ -769,8 +770,7 @@ class BuildEnvironment:
|
||||
if filename == 'contents.rst':
|
||||
# the master file is not included anywhere ;)
|
||||
continue
|
||||
self.warning_stream.write(
|
||||
'WARNING: %s isn\'t included in any toctree\n' % filename)
|
||||
self._warnfunc('%s isn\'t included in any toctree' % filename)
|
||||
|
||||
# --------- QUERYING -------------------------------------------------------
|
||||
|
||||
|
@ -25,7 +25,7 @@ from . import highlighting
|
||||
HEADER = r'''%% Generated by Sphinx.
|
||||
\documentclass[%(papersize)s,%(pointsize)s]{%(docclass)s}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[colorlinks]{hyperref}
|
||||
\usepackage[colorlinks,breaklinks]{hyperref}
|
||||
\title{%(title)s}
|
||||
\date{%(date)s}
|
||||
\release{%(release)s}
|
||||
@ -200,8 +200,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
raise nodes.SkipNode
|
||||
elif self.this_is_the_title:
|
||||
if len(node.children) != 1 and not isinstance(node.children[0], Text):
|
||||
print >>self.builder.warning_stream, 'WARNING: document title ' \
|
||||
'is not a single Text node'
|
||||
self.builder.warn('document title is not a single Text node')
|
||||
self.options['title'] = node.astext()
|
||||
self.this_is_the_title = 0
|
||||
raise nodes.SkipNode
|
||||
@ -212,8 +211,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.body.append(r'\textbf{')
|
||||
self.context.append('}\n\n\medskip\n\n')
|
||||
else:
|
||||
print >>self.builder.warning_stream, 'WARNING: encountered title node ' \
|
||||
'not in section, topic or sidebar'
|
||||
self.builder.warn('encountered title node not in section, topic or sidebar')
|
||||
self.body.append('\\textbf{')
|
||||
self.context.append('}')
|
||||
self.in_title = 1
|
||||
@ -323,8 +321,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
def visit_rubric(self, node):
|
||||
if len(node.children) == 1 and node.children[0].astext() == 'Footnotes':
|
||||
raise nodes.SkipNode
|
||||
print >>self.builder.warning_stream, 'WARNING: encountered rubric node' \
|
||||
'not used for footnotes, content will be lost'
|
||||
self.builder.warn('encountered rubric node not used for footnotes, '
|
||||
'content will be lost')
|
||||
|
||||
def visit_footnote(self, node):
|
||||
# XXX not optimal, footnotes are at section end
|
||||
@ -358,8 +356,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
elif columnCount == 5:
|
||||
self.body.append('\\begin{tablev}{l|l|l|l|l}{textrm}')
|
||||
else:
|
||||
print >>self.builder.warning_stream, 'WARNING: table with too ' \
|
||||
'many columns, ignoring'
|
||||
self.builder.warn('table with too many columns, ignoring')
|
||||
raise nodes.SkipNode
|
||||
def depart_tgroup(self, node):
|
||||
if self.tableSpec.columnCount == 2:
|
||||
@ -548,6 +545,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.body.append(self.context.pop())
|
||||
|
||||
indextype_map = {
|
||||
'module': 'refmodindex',
|
||||
'keyword': 'kwindex',
|
||||
'operator': 'opindex',
|
||||
'object': 'obindex',
|
||||
@ -567,15 +565,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
elif type == 'triple':
|
||||
parts = tuple(self.encode(x.strip()) for x in string.split(';', 2))
|
||||
self.body.append(r'\indexiii{%s}{%s}{%s}' % parts)
|
||||
elif type == 'module':
|
||||
self.body.append(r'\refmodindex[%s]{%s}' % (string.replace('_', ''),
|
||||
self.encode(string)))
|
||||
elif type in self.indextype_map:
|
||||
self.body.append(r'\%s{%s}' % (self.indextype_map[type],
|
||||
self.encode(string)))
|
||||
else:
|
||||
print >>self.builder.warning_stream, 'WARNING: unknown index entry ' \
|
||||
'type %s found' % type
|
||||
self.builder.warn('unknown index entry type %s found' % type)
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_reference(self, node):
|
||||
@ -595,8 +589,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.body.append('\\grammartoken{')
|
||||
self.context.append('}')
|
||||
else:
|
||||
print self.builder.warning_stream, 'WARNING: malformed reference ' \
|
||||
'target found: %s' % uri
|
||||
self.builder.warn('malformed reference target found: %s' % uri)
|
||||
self.context.append('')
|
||||
def depart_reference(self, node):
|
||||
self.body.append(self.context.pop())
|
||||
@ -645,6 +638,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
def depart_literal_block(self, node):
|
||||
hlcode = highlighting.highlight_block(self.verbatim.rstrip('\n'),
|
||||
self.highlightlang, 'latex')
|
||||
# workaround for Unicode issue
|
||||
hlcode = hlcode.replace(u'€', u'@texteuro[]')
|
||||
# workaround for Pygments bug
|
||||
hlcode = hlcode.replace('\n\\end{Verbatim}', '\\end{Verbatim}')
|
||||
self.body.append('\n' + hlcode)
|
||||
|
@ -42,22 +42,26 @@ def indexmarkup_role(typ, rawtext, text, lineno, inliner, options={}, content=[]
|
||||
text = utils.unescape(text)
|
||||
targetid = 'index-%s' % env.index_num
|
||||
env.index_num += 1
|
||||
indexnode = addnodes.index()
|
||||
targetnode = nodes.target('', '', ids=[targetid])
|
||||
inliner.document.note_explicit_target(targetnode)
|
||||
if typ == 'envvar':
|
||||
env.note_index_entry('single', '%s' % text,
|
||||
targetid, text)
|
||||
env.note_index_entry('single', text, targetid, text)
|
||||
env.note_index_entry('single', 'environment variable; %s' % text,
|
||||
targetid, text)
|
||||
#textnode = nodes.strong(text, text)
|
||||
indexnode['entries'] = [('single', text, targetid, text),
|
||||
('single', 'environment variable; %s' % text,
|
||||
targetid, text)]
|
||||
pnode = addnodes.pending_xref(rawtext)
|
||||
pnode['reftype'] = 'envvar'
|
||||
pnode['reftarget'] = text
|
||||
pnode += nodes.strong(text, text, classes=['xref'])
|
||||
return [targetnode, pnode], []
|
||||
return [indexnode, targetnode, pnode], []
|
||||
elif typ == 'pep':
|
||||
env.note_index_entry('single', 'Python Enhancement Proposals!PEP %s' % text,
|
||||
targetid, 'PEP %s' % text)
|
||||
indexnode['entries'] = [('single', 'Python Enhancement Proposals!PEP %s' % text,
|
||||
targetid, 'PEP %s' % text)]
|
||||
try:
|
||||
pepnum = int(text)
|
||||
except ValueError:
|
||||
@ -68,10 +72,12 @@ def indexmarkup_role(typ, rawtext, text, lineno, inliner, options={}, content=[]
|
||||
sn = nodes.strong('PEP '+text, 'PEP '+text)
|
||||
rn = nodes.reference('', '', refuri=ref)
|
||||
rn += sn
|
||||
return [targetnode, rn], []
|
||||
return [indexnode, targetnode, rn], []
|
||||
elif typ == 'rfc':
|
||||
env.note_index_entry('single', 'RFC!RFC %s' % text,
|
||||
env.note_index_entry('single', 'RFC; RFC %s' % text,
|
||||
targetid, 'RFC %s' % text)
|
||||
indexnode['entries'] = [('single', 'RFC; RFC %s' % text,
|
||||
targetid, 'RFC %s' % text)]
|
||||
try:
|
||||
rfcnum = int(text)
|
||||
except ValueError:
|
||||
@ -82,7 +88,7 @@ def indexmarkup_role(typ, rawtext, text, lineno, inliner, options={}, content=[]
|
||||
sn = nodes.strong('RFC '+text, 'RFC '+text)
|
||||
rn = nodes.reference('', '', refuri=ref)
|
||||
rn += sn
|
||||
return [targetnode, rn], []
|
||||
return [indexnode, targetnode, rn], []
|
||||
|
||||
roles.register_canonical_role('envvar', indexmarkup_role)
|
||||
roles.register_local_role('pep', indexmarkup_role)
|
||||
|
@ -6,6 +6,7 @@
|
||||
\ProvidesPackage{python}
|
||||
[1998/01/11 LaTeX package (Python markup)]
|
||||
|
||||
\RequirePackage{textcomp}
|
||||
\RequirePackage{longtable}
|
||||
\RequirePackage{times}
|
||||
\RequirePackage{fancyvrb}
|
||||
@ -808,9 +809,12 @@
|
||||
}{\end{fulllineitems}}
|
||||
|
||||
% generic description ----------------------------------------------------
|
||||
\newcommand{\descline}[1]{%
|
||||
\item[\bfcode{#1}]\nopagebreak%
|
||||
}
|
||||
\newenvironment{describe}[1]{
|
||||
\begin{fulllineitems}
|
||||
\item[\bfcode{#1}]\nopagebreak
|
||||
\descline{#1}
|
||||
}{\end{fulllineitems}}
|
||||
|
||||
\newcommand{\nodename}[1]{\label{#1}}
|
||||
|
Loading…
Reference in New Issue
Block a user