[Python-checkins] r65486 - in doctools/trunk: CHANGES TODO doc/ext/appapi.rst sphinx/application.py sphinx/builder.py sphinx/environment.py sphinx/ext/autodoc.py
georg.brandl
python-checkins at python.org
Mon Aug 4 11:54:45 CEST 2008
Author: georg.brandl
Date: Mon Aug 4 11:54:45 2008
New Revision: 65486
Log:
Add "env-updated" and "missing-reference" events.
Write inventory file as part of the HTML build.
Modified:
doctools/trunk/CHANGES
doctools/trunk/TODO
doctools/trunk/doc/ext/appapi.rst
doctools/trunk/sphinx/application.py
doctools/trunk/sphinx/builder.py
doctools/trunk/sphinx/environment.py
doctools/trunk/sphinx/ext/autodoc.py
Modified: doctools/trunk/CHANGES
==============================================================================
--- doctools/trunk/CHANGES (original)
+++ doctools/trunk/CHANGES Mon Aug 4 11:54:45 2008
@@ -27,6 +27,8 @@
* sphinx.doc.autodoc has a new event ``autodoc-process-signature`` that
allows tuning function signature introspection.
+* Added new events: ``env-updated`` and ``missing-reference``.
+
Release 0.4.2 (Jul 29, 2008)
============================
Modified: doctools/trunk/TODO
==============================================================================
--- doctools/trunk/TODO (original)
+++ doctools/trunk/TODO Mon Aug 4 11:54:45 2008
@@ -1,14 +1,16 @@
Sphinx TODO
===========
-- literal search mode
+- RSS generation
+- files for downloading
- specify node visit functions when adding nodes to app
- allow extensions to add static files
- decide which static files to include
- verbose option
- remove redundant <ul>s in tocs
- autoattribute in autodoc
-- range and object options for literalinclude
+- section, range and object options for literalinclude
+- literal search mode
- option for compact module index
- HTML section numbers?
- "seealso" links to external examples, see http://svn.python.org/projects/sandbox/trunk/seealso/ and http://effbot.org/zone/idea-seealso.htm
Modified: doctools/trunk/doc/ext/appapi.rst
==============================================================================
--- doctools/trunk/doc/ext/appapi.rst (original)
+++ doctools/trunk/doc/ext/appapi.rst Mon Aug 4 11:54:45 2008
@@ -144,8 +144,17 @@
.. method:: Sphinx.emit(event, *arguments)
- Emit *event* and pass *arguments* to the callback functions. Do not emit
- core Sphinx events in extensions!
+ Emit *event* and pass *arguments* to the callback functions. Return the
+ return values of all callbacks as a list. Do not emit core Sphinx events
+ in extensions!
+
+.. method:: Sphinx.emit_firstresult(event, *arguments)
+
+ Emit *event* and pass *arguments* to the callback functions. Return the
+ result of the first callback that doesn't return ``None`` (and don't call
+ the rest of the callbacks).
+
+ .. versionadded:: 0.5
.. exception:: ExtensionError
@@ -167,18 +176,43 @@
.. event:: builder-inited (app)
- Emitted the builder object has been created.
+ Emitted when the builder object has been created. It is available as
+ ``app.builder``.
.. event:: doctree-read (app, doctree)
Emitted when a doctree has been parsed and read by the environment, and is
- about to be pickled.
+ about to be pickled. The *doctree* can be modified in-place.
+
+.. event:: missing-reference (app, env, node, contnode)
+ Emitted when a cross-reference to a Python module or object cannot be
+ resolved. If the event handler can resolve the reference, it should return a
+ new docutils node to be inserted in the document tree in place of the node
+ *node*. Usually this node is a :class:`reference` node containing *contnode*
+ as a child.
+
+ :param env: The build environment (``app.builder.env``).
+ :param node: The :class:`pending_xref` node to be resolved. Its attributes
+ ``reftype``, ``reftarget``, ``modname`` and ``classname`` attributes
+ determine the type and target of the reference.
+ :param contnode: The node that carries the text and formatting inside the
+ future reference and should be a child of the returned reference node.
+
+ .. versionadded:: 0.5
+
.. event:: doctree-resolved (app, doctree, docname)
Emitted when a doctree has been "resolved" by the environment, that is, all
- references and TOCs have been inserted.
+ references have been resolved and TOCs have been inserted.
+
+.. event:: env-updated (app, env)
+
+ Emitted when the :meth:`update` method of the build environment has
+ completed, that is, the environment and all doctrees are now up-to-date.
+ .. versionadded:: 0.5
+
.. event:: page-context (app, pagename, templatename, context, doctree)
Emitted when the HTML builder has created a context dictionary to render a
Modified: doctools/trunk/sphinx/application.py
==============================================================================
--- doctools/trunk/sphinx/application.py (original)
+++ doctools/trunk/sphinx/application.py Mon Aug 4 11:54:45 2008
@@ -167,6 +167,12 @@
result.append(callback(self, *args))
return result
+ def emit_firstresult(self, event, *args):
+ for result in self.emit(event, *args):
+ if result is not None:
+ return result
+ return None
+
# registering addon parts
def add_builder(self, builder):
Modified: doctools/trunk/sphinx/builder.py
==============================================================================
--- doctools/trunk/sphinx/builder.py (original)
+++ doctools/trunk/sphinx/builder.py Mon Aug 4 11:54:45 2008
@@ -11,6 +11,7 @@
import os
import time
+import gzip
import codecs
import shutil
import cPickle as pickle
@@ -40,6 +41,8 @@
ENV_PICKLE_FILENAME = 'environment.pickle'
LAST_BUILD_FILENAME = 'last_build'
+INVENTORY_FILENAME = 'inventory.txt.gz'
+
class Builder(object):
"""
@@ -153,7 +156,7 @@
return
if not self.freshenv:
try:
- self.info(bold('trying to load pickled env... '), nonl=True)
+ self.info(bold('loading pickled environment... '), nonl=True)
self.env = BuildEnvironment.frompickle(self.config,
path.join(self.doctreedir, ENV_PICKLE_FILENAME))
self.info('done')
@@ -214,7 +217,7 @@
iterator = self.env.update(self.config, self.srcdir, self.doctreedir, self.app)
# the first item in the iterator is a summary message
self.info(iterator.next())
- for docname in self.status_iterator(iterator, 'reading... ', purple):
+ for docname in self.status_iterator(iterator, 'reading sources... ', purple):
updated_docnames.append(docname)
# nothing further to do, the environment has already done the reading
for warning in warnings:
@@ -224,13 +227,14 @@
if updated_docnames:
# save the environment
- self.info(bold('pickling the env... '), nonl=True)
+ self.info(bold('pickling environment... '), nonl=True)
self.env.topickle(path.join(self.doctreedir, ENV_PICKLE_FILENAME))
self.info('done')
# global actions
- self.info(bold('checking consistency...'))
+ self.info(bold('checking consistency... '), nonl=True)
self.env.check_consistency()
+ self.info('done')
else:
if method == 'update' and not docnames:
self.info(bold('no targets are out of date.'))
@@ -241,7 +245,6 @@
self.write(docnames, updated_docnames, method)
# finish (write static files etc.)
- self.info(bold('finishing... '))
self.finish()
if self.app._warncount:
self.info(bold('build succeeded, %s warning%s.' %
@@ -266,7 +269,9 @@
docnames.add(tocdocname)
docnames.add(self.config.master_doc)
+ self.info(bold('preparing documents... '), nonl=True)
self.prepare_writing(docnames)
+ self.info('done')
# write target files
warnings = []
@@ -571,7 +576,7 @@
# copy image files
if self.images:
- self.info(bold('copying images...'), nonl=1)
+ self.info(bold('copying images...'), nonl=True)
ensuredir(path.join(self.outdir, '_images'))
for src, dest in self.images.iteritems():
self.info(' '+src, nonl=1)
@@ -580,7 +585,7 @@
self.info()
# copy static files
- self.info(bold('copying static files...'))
+ self.info(bold('copying static files... '), nonl=True)
ensuredir(path.join(self.outdir, '_static'))
staticdirnames = [path.join(path.dirname(__file__), 'static')] + \
[path.join(self.confdir, spath)
@@ -605,6 +610,7 @@
f = open(path.join(self.outdir, '_static', 'pygments.css'), 'w')
f.write(PygmentsBridge('html', self.config.pygments_style).get_stylesheet())
f.close()
+ self.info('done')
# dump the search index
self.handle_finish()
@@ -693,13 +699,25 @@
shutil.copyfile(self.env.doc2path(pagename), source_name)
def handle_finish(self):
- self.info(bold('dumping search index...'))
+ self.info(bold('dumping search index... '), nonl=True)
self.indexer.prune(self.env.all_docs)
f = open(path.join(self.outdir, self.searchindex_filename), 'wb')
try:
self.indexer.dump(f, self.indexer_format)
finally:
f.close()
+ self.info('done')
+
+ self.info(bold('dumping object inventory... '), nonl=True)
+ f = gzip.open(path.join(self.outdir, INVENTORY_FILENAME), 'w')
+ try:
+ for modname, info in self.env.modules.iteritems():
+ f.write('%s mod %s\n' % (modname, self.get_target_uri(info[0])))
+ for refname, (docname, desctype) in self.env.descrefs.iteritems():
+ f.write('%s %s %s\n' % (refname, desctype, self.get_target_uri(docname)))
+ finally:
+ f.close()
+ self.info('done')
class SerializingHTMLBuilder(StandaloneHTMLBuilder):
@@ -974,12 +992,13 @@
shutil.copyfile(path.join(self.confdir, self.config.latex_logo),
path.join(self.outdir, logobase))
- self.info(bold('copying TeX support files...'))
+ self.info(bold('copying TeX support files... '), nonl=True)
staticdirname = path.join(path.dirname(__file__), 'texinputs')
for filename in os.listdir(staticdirname):
if not filename.startswith('.'):
shutil.copyfile(path.join(staticdirname, filename),
path.join(self.outdir, filename))
+ self.info('done')
class ChangesBuilder(Builder):
Modified: doctools/trunk/sphinx/environment.py
==============================================================================
--- doctools/trunk/sphinx/environment.py (original)
+++ doctools/trunk/sphinx/environment.py Mon Aug 4 11:54:45 2008
@@ -457,6 +457,9 @@
if not os.access(path.join(self.srcdir, imgsrc), os.R_OK):
del self.images[imgsrc]
+ if app:
+ app.emit('env-updated', self)
+
# --------- SINGLE FILE READING --------------------------------------------
@@ -880,6 +883,10 @@
'meth', 'cfunc', 'cdata', 'ctype', 'cmacro', 'obj'))
def resolve_references(self, doctree, fromdocname, builder):
+ reftarget_roles = set(('token', 'term', 'option'))
+ # add all custom xref types too
+ reftarget_roles.update(i[0] for i in additional_xref_types.values())
+
for node in doctree.traverse(addnodes.pending_xref):
contnode = node[0].deepcopy()
newnode = None
@@ -887,10 +894,6 @@
typ = node['reftype']
target = node['reftarget']
- reftarget_roles = set(('token', 'term', 'option'))
- # add all custom xref types too
- reftarget_roles.update(i[0] for i in additional_xref_types.values())
-
try:
if typ == 'ref':
if node['refcaption']:
@@ -962,7 +965,12 @@
# because the anchor is generally below the heading which is ugly
# but can't be helped easily
anchor = ''
- if not docname or docname == fromdocname:
+ if not docname:
+ newnode = builder.app.emit_firstresult('missing-reference',
+ self, node, contnode)
+ if not newnode:
+ newnode = contnode
+ elif docname == fromdocname:
# don't link to self
newnode = contnode
else:
@@ -983,7 +991,10 @@
name, desc = self.find_desc(modname, clsname,
target, typ, searchorder)
if not desc:
- newnode = contnode
+ newnode = builder.app.emit_firstresult('missing-reference',
+ self, node, contnode)
+ if not newnode:
+ newnode = contnode
else:
newnode = nodes.reference('', '')
if desc[0] == fromdocname:
Modified: doctools/trunk/sphinx/ext/autodoc.py
==============================================================================
--- doctools/trunk/sphinx/ext/autodoc.py (original)
+++ doctools/trunk/sphinx/ext/autodoc.py Mon Aug 4 11:54:45 2008
@@ -350,11 +350,10 @@
args = None
err = e
- results = self.env.app.emit('autodoc-process-signature',
- what, name, obj, self.options, args, retann)
- for result in results:
- if result:
- args, retann = result
+ result = self.env.app.emit_firstresult('autodoc-process-signature', what,
+ name, obj, self.options, args, retann)
+ if result:
+ args, retann = result
if args is not None:
return '%s%s' % (args, retann or '')
More information about the Python-checkins
mailing list