Further fixes. All produced latex documents now run through pdflatex without errors.

This commit is contained in:
Georg Brandl 2007-12-16 23:14:24 +00:00
parent fe94305a20
commit e77b466281
5 changed files with 75 additions and 68 deletions

View File

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

View File

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

View File

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

View File

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

View File

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