mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
merge with 1.0
This commit is contained in:
17
CHANGES
17
CHANGES
@@ -78,6 +78,23 @@ Release 1.1 (in development)
|
|||||||
Release 1.0.7 (in development)
|
Release 1.0.7 (in development)
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
|
* Fix general index links for C++ domain objects.
|
||||||
|
|
||||||
|
* #332: Make admonition boundaries in LaTeX output visible.
|
||||||
|
|
||||||
|
* #573: Fix KeyErrors occurring on rebuild after removing a file.
|
||||||
|
|
||||||
|
* Fix a traceback when removing files with globbed toctrees.
|
||||||
|
|
||||||
|
* If an autodoc object cannot be imported, always re-read the
|
||||||
|
document containing the directive on next build.
|
||||||
|
|
||||||
|
* If an autodoc object cannot be imported, show the full traceback
|
||||||
|
of the import error.
|
||||||
|
|
||||||
|
* Fix a bug where the removal of download files and images wasn't
|
||||||
|
noticed.
|
||||||
|
|
||||||
* #571: Implement ``~`` cross-reference prefix for the C domain.
|
* #571: Implement ``~`` cross-reference prefix for the C domain.
|
||||||
|
|
||||||
* Fix regression of LaTeX output with the fix of #556.
|
* Fix regression of LaTeX output with the fix of #556.
|
||||||
|
|||||||
1
EXAMPLES
1
EXAMPLES
@@ -20,6 +20,7 @@ Documentation using the default theme
|
|||||||
* Cython: http://docs.cython.org/
|
* Cython: http://docs.cython.org/
|
||||||
* C\\C++ Python language binding project: http://language-binding.net/index.html
|
* C\\C++ Python language binding project: http://language-binding.net/index.html
|
||||||
* Director: http://packages.python.org/director/
|
* Director: http://packages.python.org/director/
|
||||||
|
* Dirigible: http://www.projectdirigible.com/documentation/
|
||||||
* F2py: http://f2py.sourceforge.net/docs/
|
* F2py: http://f2py.sourceforge.net/docs/
|
||||||
* GeoDjango: http://geodjango.org/docs/
|
* GeoDjango: http://geodjango.org/docs/
|
||||||
* gevent: http://www.gevent.org/
|
* gevent: http://www.gevent.org/
|
||||||
|
|||||||
12
doc/conf.py
12
doc/conf.py
@@ -99,8 +99,12 @@ def parse_event(env, sig, signode):
|
|||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
from sphinx.ext.autodoc import cut_lines
|
from sphinx.ext.autodoc import cut_lines
|
||||||
|
from sphinx.util.docfields import GroupedField
|
||||||
app.connect('autodoc-process-docstring', cut_lines(4, what=['module']))
|
app.connect('autodoc-process-docstring', cut_lines(4, what=['module']))
|
||||||
app.add_description_unit('confval', 'confval',
|
app.add_object_type('confval', 'confval',
|
||||||
objname='configuration value',
|
objname='configuration value',
|
||||||
indextemplate='pair: %s; configuration value')
|
indextemplate='pair: %s; configuration value')
|
||||||
app.add_description_unit('event', 'event', 'pair: %s; event', parse_event)
|
fdesc = GroupedField('parameter', label='Parameters',
|
||||||
|
names=['param'], can_collapse=True)
|
||||||
|
app.add_object_type('event', 'event', 'pair: %s; event', parse_event,
|
||||||
|
doc_field_types=[fdesc])
|
||||||
|
|||||||
@@ -163,7 +163,8 @@ the following public API:
|
|||||||
|
|
||||||
.. versionadded:: 0.6
|
.. versionadded:: 0.6
|
||||||
|
|
||||||
.. method:: Sphinx.add_object_type(directivename, rolename, indextemplate='', parse_node=None, ref_nodeclass=None, objname='')
|
.. method:: Sphinx.add_object_type(directivename, rolename, indextemplate='', parse_node=None, \
|
||||||
|
ref_nodeclass=None, objname='', doc_field_types=[])
|
||||||
|
|
||||||
This method is a very convenient way to add a new :term:`object` type that
|
This method is a very convenient way to add a new :term:`object` type that
|
||||||
can be cross-referenced. It will do this:
|
can be cross-referenced. It will do this:
|
||||||
|
|||||||
@@ -432,13 +432,15 @@ class Sphinx(object):
|
|||||||
setattr(self.domains[domain], 'get_%s_index' % name, func)
|
setattr(self.domains[domain], 'get_%s_index' % name, func)
|
||||||
|
|
||||||
def add_object_type(self, directivename, rolename, indextemplate='',
|
def add_object_type(self, directivename, rolename, indextemplate='',
|
||||||
parse_node=None, ref_nodeclass=None, objname=''):
|
parse_node=None, ref_nodeclass=None, objname='',
|
||||||
|
doc_field_types=[]):
|
||||||
StandardDomain.object_types[directivename] = \
|
StandardDomain.object_types[directivename] = \
|
||||||
ObjType(objname or directivename, rolename)
|
ObjType(objname or directivename, rolename)
|
||||||
# create a subclass of GenericObject as the new directive
|
# create a subclass of GenericObject as the new directive
|
||||||
new_directive = type(directivename, (GenericObject, object),
|
new_directive = type(directivename, (GenericObject, object),
|
||||||
{'indextemplate': indextemplate,
|
{'indextemplate': indextemplate,
|
||||||
'parse_node': staticmethod(parse_node)})
|
'parse_node': staticmethod(parse_node),
|
||||||
|
'doc_field_types': doc_field_types})
|
||||||
StandardDomain.directives[directivename] = new_directive
|
StandardDomain.directives[directivename] = new_directive
|
||||||
# XXX support more options?
|
# XXX support more options?
|
||||||
StandardDomain.roles[rolename] = XRefRole(innernodeclass=ref_nodeclass)
|
StandardDomain.roles[rolename] = XRefRole(innernodeclass=ref_nodeclass)
|
||||||
|
|||||||
@@ -272,7 +272,8 @@ class Builder(object):
|
|||||||
# add all toctree-containing files that may have changed
|
# add all toctree-containing files that may have changed
|
||||||
for docname in list(docnames):
|
for docname in list(docnames):
|
||||||
for tocdocname in self.env.files_to_rebuild.get(docname, []):
|
for tocdocname in self.env.files_to_rebuild.get(docname, []):
|
||||||
docnames.add(tocdocname)
|
if tocdocname in self.env.found_docs:
|
||||||
|
docnames.add(tocdocname)
|
||||||
docnames.add(self.config.master_doc)
|
docnames.add(self.config.master_doc)
|
||||||
|
|
||||||
self.info(bold('preparing documents... '), nonl=True)
|
self.info(bold('preparing documents... '), nonl=True)
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ class CodeBlock(Directive):
|
|||||||
literal = nodes.literal_block(code, code)
|
literal = nodes.literal_block(code, code)
|
||||||
literal['language'] = self.arguments[0]
|
literal['language'] = self.arguments[0]
|
||||||
literal['linenos'] = 'linenos' in self.options
|
literal['linenos'] = 'linenos' in self.options
|
||||||
|
literal.line = self.lineno
|
||||||
return [literal]
|
return [literal]
|
||||||
|
|
||||||
|
|
||||||
@@ -166,6 +167,7 @@ class LiteralInclude(Directive):
|
|||||||
text = text.expandtabs(self.options['tab-width'])
|
text = text.expandtabs(self.options['tab-width'])
|
||||||
retnode = nodes.literal_block(text, text, source=filename)
|
retnode = nodes.literal_block(text, text, source=filename)
|
||||||
retnode.line = 1
|
retnode.line = 1
|
||||||
|
retnode.attributes['line_number'] = self.lineno
|
||||||
if self.options.get('language', ''):
|
if self.options.get('language', ''):
|
||||||
retnode['language'] = self.options['language']
|
retnode['language'] = self.options['language']
|
||||||
if 'linenos' in self.options:
|
if 'linenos' in self.options:
|
||||||
|
|||||||
@@ -80,8 +80,9 @@ class TocTree(Directive):
|
|||||||
entries.append((title, ref))
|
entries.append((title, ref))
|
||||||
elif docname not in env.found_docs:
|
elif docname not in env.found_docs:
|
||||||
ret.append(self.state.document.reporter.warning(
|
ret.append(self.state.document.reporter.warning(
|
||||||
'toctree references unknown document %r' % docname,
|
'toctree contains reference to nonexisting '
|
||||||
line=self.lineno))
|
'document %r' % docname, line=self.lineno))
|
||||||
|
env.note_reread()
|
||||||
else:
|
else:
|
||||||
entries.append((title, docname))
|
entries.append((title, docname))
|
||||||
includefiles.append(docname)
|
includefiles.append(docname)
|
||||||
@@ -237,6 +238,7 @@ class TabularColumns(Directive):
|
|||||||
def run(self):
|
def run(self):
|
||||||
node = addnodes.tabular_col_spec()
|
node = addnodes.tabular_col_spec()
|
||||||
node['spec'] = self.arguments[0]
|
node['spec'] = self.arguments[0]
|
||||||
|
node.line = self.lineno
|
||||||
return [node]
|
return [node]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ default_settings = {
|
|||||||
|
|
||||||
# This is increased every time an environment attribute is added
|
# This is increased every time an environment attribute is added
|
||||||
# or changed to properly invalidate pickle files.
|
# or changed to properly invalidate pickle files.
|
||||||
ENV_VERSION = 38
|
ENV_VERSION = 39
|
||||||
|
|
||||||
|
|
||||||
default_substitutions = set([
|
default_substitutions = set([
|
||||||
@@ -336,6 +336,8 @@ class BuildEnvironment:
|
|||||||
# contains all built docnames
|
# contains all built docnames
|
||||||
self.dependencies = {} # docname -> set of dependent file
|
self.dependencies = {} # docname -> set of dependent file
|
||||||
# names, relative to documentation root
|
# names, relative to documentation root
|
||||||
|
self.reread_always = set() # docnames to re-read unconditionally on
|
||||||
|
# next build
|
||||||
|
|
||||||
# File metadata
|
# File metadata
|
||||||
self.metadata = {} # docname -> dict of metadata items
|
self.metadata = {} # docname -> dict of metadata items
|
||||||
@@ -385,6 +387,7 @@ class BuildEnvironment:
|
|||||||
"""Remove all traces of a source file in the inventory."""
|
"""Remove all traces of a source file in the inventory."""
|
||||||
if docname in self.all_docs:
|
if docname in self.all_docs:
|
||||||
self.all_docs.pop(docname, None)
|
self.all_docs.pop(docname, None)
|
||||||
|
self.reread_always.discard(docname)
|
||||||
self.metadata.pop(docname, None)
|
self.metadata.pop(docname, None)
|
||||||
self.dependencies.pop(docname, None)
|
self.dependencies.pop(docname, None)
|
||||||
self.titles.pop(docname, None)
|
self.titles.pop(docname, None)
|
||||||
@@ -486,6 +489,10 @@ class BuildEnvironment:
|
|||||||
'.doctree')):
|
'.doctree')):
|
||||||
changed.add(docname)
|
changed.add(docname)
|
||||||
continue
|
continue
|
||||||
|
# check the "reread always" list
|
||||||
|
if docname in self.reread_always:
|
||||||
|
changed.add(docname)
|
||||||
|
continue
|
||||||
# check the mtime of the document
|
# check the mtime of the document
|
||||||
mtime = self.all_docs[docname]
|
mtime = self.all_docs[docname]
|
||||||
newmtime = path.getmtime(self.doc2path(docname))
|
newmtime = path.getmtime(self.doc2path(docname))
|
||||||
@@ -555,7 +562,8 @@ class BuildEnvironment:
|
|||||||
# if files were added or removed, all documents with globbed toctrees
|
# if files were added or removed, all documents with globbed toctrees
|
||||||
# must be reread
|
# must be reread
|
||||||
if added or removed:
|
if added or removed:
|
||||||
changed.update(self.glob_toctrees)
|
# ... but not those that already were removed
|
||||||
|
changed.update(self.glob_toctrees & self.found_docs)
|
||||||
|
|
||||||
msg += '%s added, %s changed, %s removed' % (len(added), len(changed),
|
msg += '%s added, %s changed, %s removed' % (len(added), len(changed),
|
||||||
len(removed))
|
len(removed))
|
||||||
@@ -687,6 +695,11 @@ class BuildEnvironment:
|
|||||||
codecs.register_error('sphinx', self.warn_and_replace)
|
codecs.register_error('sphinx', self.warn_and_replace)
|
||||||
|
|
||||||
class SphinxSourceClass(FileInput):
|
class SphinxSourceClass(FileInput):
|
||||||
|
def __init__(self_, *args, **kwds):
|
||||||
|
# don't call sys.exit() on IOErrors
|
||||||
|
kwds['handle_io_errors'] = False
|
||||||
|
FileInput.__init__(self_, *args, **kwds)
|
||||||
|
|
||||||
def decode(self_, data):
|
def decode(self_, data):
|
||||||
if isinstance(data, unicode):
|
if isinstance(data, unicode):
|
||||||
return data
|
return data
|
||||||
@@ -795,6 +808,9 @@ class BuildEnvironment:
|
|||||||
def note_dependency(self, filename):
|
def note_dependency(self, filename):
|
||||||
self.dependencies.setdefault(self.docname, set()).add(filename)
|
self.dependencies.setdefault(self.docname, set()).add(filename)
|
||||||
|
|
||||||
|
def note_reread(self):
|
||||||
|
self.reread_always.add(self.docname)
|
||||||
|
|
||||||
def note_versionchange(self, type, version, node, lineno):
|
def note_versionchange(self, type, version, node, lineno):
|
||||||
self.versionchanges.setdefault(version, []).append(
|
self.versionchanges.setdefault(version, []).append(
|
||||||
(type, self.temp_data['docname'], lineno,
|
(type, self.temp_data['docname'], lineno,
|
||||||
@@ -1280,11 +1296,12 @@ class BuildEnvironment:
|
|||||||
self.warn(docname,
|
self.warn(docname,
|
||||||
'toctree contains reference to document '
|
'toctree contains reference to document '
|
||||||
'%r that doesn\'t have a title: no link '
|
'%r that doesn\'t have a title: no link '
|
||||||
'will be generated' % ref)
|
'will be generated' % ref, toctreenode.line)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# this is raised if the included file does not exist
|
# this is raised if the included file does not exist
|
||||||
self.warn(docname, 'toctree contains reference to '
|
self.warn(docname, 'toctree contains reference to '
|
||||||
'nonexisting document %r' % ref)
|
'nonexisting document %r' % ref,
|
||||||
|
toctreenode.line)
|
||||||
else:
|
else:
|
||||||
# if titles_only is given, only keep the main title and
|
# if titles_only is given, only keep the main title and
|
||||||
# sub-toctrees
|
# sub-toctrees
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import inspect
|
import inspect
|
||||||
|
import traceback
|
||||||
from types import FunctionType, BuiltinFunctionType, MethodType
|
from types import FunctionType, BuiltinFunctionType, MethodType
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
@@ -216,6 +217,8 @@ class Documenter(object):
|
|||||||
priority = 0
|
priority = 0
|
||||||
#: order if autodoc_member_order is set to 'groupwise'
|
#: order if autodoc_member_order is set to 'groupwise'
|
||||||
member_order = 0
|
member_order = 0
|
||||||
|
#: true if the generated content may contain titles
|
||||||
|
titles_allowed = False
|
||||||
|
|
||||||
option_spec = {'noindex': bool_option}
|
option_spec = {'noindex': bool_option}
|
||||||
|
|
||||||
@@ -327,10 +330,13 @@ class Documenter(object):
|
|||||||
# this used to only catch SyntaxError, ImportError and AttributeError,
|
# this used to only catch SyntaxError, ImportError and AttributeError,
|
||||||
# but importing modules with side effects can raise all kinds of errors
|
# but importing modules with side effects can raise all kinds of errors
|
||||||
except Exception, err:
|
except Exception, err:
|
||||||
|
if self.env.app and not self.env.app.quiet:
|
||||||
|
self.env.app.info(traceback.format_exc().rstrip())
|
||||||
self.directive.warn(
|
self.directive.warn(
|
||||||
'autodoc can\'t import/find %s %r, it reported error: '
|
'autodoc can\'t import/find %s %r, it reported error: '
|
||||||
'"%s", please check your spelling and sys.path' %
|
'"%s", please check your spelling and sys.path' %
|
||||||
(self.objtype, str(self.fullname), err))
|
(self.objtype, str(self.fullname), err))
|
||||||
|
self.env.note_reread()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_real_modname(self):
|
def get_real_modname(self):
|
||||||
@@ -718,6 +724,7 @@ class ModuleDocumenter(Documenter):
|
|||||||
"""
|
"""
|
||||||
objtype = 'module'
|
objtype = 'module'
|
||||||
content_indent = u''
|
content_indent = u''
|
||||||
|
titles_allowed = True
|
||||||
|
|
||||||
option_spec = {
|
option_spec = {
|
||||||
'members': members_option, 'undoc-members': bool_option,
|
'members': members_option, 'undoc-members': bool_option,
|
||||||
@@ -1252,7 +1259,7 @@ class AutoDirective(Directive):
|
|||||||
self.state.memo.reporter = AutodocReporter(self.result,
|
self.state.memo.reporter = AutodocReporter(self.result,
|
||||||
self.state.memo.reporter)
|
self.state.memo.reporter)
|
||||||
|
|
||||||
if self.name == 'automodule':
|
if documenter.titles_allowed:
|
||||||
node = nodes.section()
|
node = nodes.section()
|
||||||
# necessary so that the child nodes get the right source/line set
|
# necessary so that the child nodes get the right source/line set
|
||||||
node.document = self.state.document
|
node.document = self.state.document
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ class MathDirective(Directive):
|
|||||||
node['nowrap'] = 'nowrap' in self.options
|
node['nowrap'] = 'nowrap' in self.options
|
||||||
node['docname'] = self.state.document.settings.env.docname
|
node['docname'] = self.state.document.settings.env.docname
|
||||||
ret = [node]
|
ret = [node]
|
||||||
|
node.line = self.lineno
|
||||||
|
node.source = self.src
|
||||||
if node['label']:
|
if node['label']:
|
||||||
tnode = nodes.target('', '', ids=['equation-' + node['label']])
|
tnode = nodes.target('', '', ids=['equation-' + node['label']])
|
||||||
self.state.document.note_explicit_target(tnode)
|
self.state.document.note_explicit_target(tnode)
|
||||||
|
|||||||
@@ -248,11 +248,11 @@
|
|||||||
|
|
||||||
\newcommand{\py@heavybox}{
|
\newcommand{\py@heavybox}{
|
||||||
\setlength{\fboxrule}{1pt}
|
\setlength{\fboxrule}{1pt}
|
||||||
\setlength{\fboxsep}{7pt}
|
\setlength{\fboxsep}{6pt}
|
||||||
\setlength{\py@noticelength}{\linewidth}
|
\setlength{\py@noticelength}{\linewidth}
|
||||||
\addtolength{\py@noticelength}{-2\fboxsep}
|
\addtolength{\py@noticelength}{-2\fboxsep}
|
||||||
\addtolength{\py@noticelength}{-2\fboxrule}
|
\addtolength{\py@noticelength}{-2\fboxrule}
|
||||||
\setlength{\shadowsize}{3pt}
|
%\setlength{\shadowsize}{3pt}
|
||||||
\Sbox
|
\Sbox
|
||||||
\minipage{\py@noticelength}
|
\minipage{\py@noticelength}
|
||||||
}
|
}
|
||||||
@@ -262,15 +262,26 @@
|
|||||||
\fbox{\TheSbox}
|
\fbox{\TheSbox}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
\newcommand{\py@lightbox}{{%
|
||||||
|
\setlength\parskip{0pt}\par
|
||||||
|
\rule[0ex]{\linewidth}{0.5pt}%
|
||||||
|
\par\vspace{-0.5ex}%
|
||||||
|
}}
|
||||||
|
\newcommand{\py@endlightbox}{{%
|
||||||
|
\setlength{\parskip}{0pt}%
|
||||||
|
\par\rule[0.5ex]{\linewidth}{0.5pt}%
|
||||||
|
\par\vspace{-0.5ex}%
|
||||||
|
}}
|
||||||
|
|
||||||
% Some are quite plain:
|
% Some are quite plain:
|
||||||
\newcommand{\py@noticestart@note}{}
|
\newcommand{\py@noticestart@note}{\py@lightbox}
|
||||||
\newcommand{\py@noticeend@note}{}
|
\newcommand{\py@noticeend@note}{\py@endlightbox}
|
||||||
\newcommand{\py@noticestart@hint}{}
|
\newcommand{\py@noticestart@hint}{\py@lightbox}
|
||||||
\newcommand{\py@noticeend@hint}{}
|
\newcommand{\py@noticeend@hint}{\py@endlightbox}
|
||||||
\newcommand{\py@noticestart@important}{}
|
\newcommand{\py@noticestart@important}{\py@lightbox}
|
||||||
\newcommand{\py@noticeend@important}{}
|
\newcommand{\py@noticeend@important}{\py@endlightbox}
|
||||||
\newcommand{\py@noticestart@tip}{}
|
\newcommand{\py@noticestart@tip}{\py@lightbox}
|
||||||
\newcommand{\py@noticeend@tip}{}
|
\newcommand{\py@noticeend@tip}{\py@endlightbox}
|
||||||
|
|
||||||
% Others gets more visible distinction:
|
% Others gets more visible distinction:
|
||||||
\newcommand{\py@noticestart@warning}{\py@heavybox}
|
\newcommand{\py@noticestart@warning}{\py@heavybox}
|
||||||
@@ -287,7 +298,7 @@
|
|||||||
\newenvironment{notice}[2]{
|
\newenvironment{notice}[2]{
|
||||||
\def\py@noticetype{#1}
|
\def\py@noticetype{#1}
|
||||||
\csname py@noticestart@#1\endcsname
|
\csname py@noticestart@#1\endcsname
|
||||||
\par\strong{#2}
|
\strong{#2}
|
||||||
}{\csname py@noticeend@\py@noticetype\endcsname}
|
}{\csname py@noticeend@\py@noticetype\endcsname}
|
||||||
|
|
||||||
% Allow the release number to be specified independently of the
|
% Allow the release number to be specified independently of the
|
||||||
|
|||||||
@@ -114,9 +114,9 @@ class FilenameUniqDict(dict):
|
|||||||
def purge_doc(self, docname):
|
def purge_doc(self, docname):
|
||||||
for filename, (docs, _) in self.items():
|
for filename, (docs, _) in self.items():
|
||||||
docs.discard(docname)
|
docs.discard(docname)
|
||||||
#if not docs:
|
if not docs:
|
||||||
# del self[filename]
|
del self[filename]
|
||||||
# self._existing.discard(filename)
|
self._existing.discard(filename)
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
return self._existing
|
return self._existing
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ def setup_module():
|
|||||||
|
|
||||||
app = TestApp()
|
app = TestApp()
|
||||||
app.builder.env.app = app
|
app.builder.env.app = app
|
||||||
|
app.builder.env.temp_data['docname'] = 'dummy'
|
||||||
app.connect('autodoc-process-docstring', process_docstring)
|
app.connect('autodoc-process-docstring', process_docstring)
|
||||||
app.connect('autodoc-process-signature', process_signature)
|
app.connect('autodoc-process-signature', process_signature)
|
||||||
app.connect('autodoc-skip-member', skip_member)
|
app.connect('autodoc-skip-member', skip_member)
|
||||||
|
|||||||
Reference in New Issue
Block a user