summaryrefslogtreecommitdiff
path: root/sphinx/directives/other.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/directives/other.py')
-rw-r--r--sphinx/directives/other.py96
1 files changed, 64 insertions, 32 deletions
diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py
index e9a3864ab..41b21f917 100644
--- a/sphinx/directives/other.py
+++ b/sphinx/directives/other.py
@@ -8,17 +8,20 @@
"""
import re
+from contextlib import contextmanager
from docutils import nodes
-from docutils.parsers.rst import Directive, directives
+from docutils.parsers.rst import directives
from docutils.parsers.rst.directives.admonitions import BaseAdmonition
from docutils.parsers.rst.directives.misc import Class
from docutils.parsers.rst.directives.misc import Include as BaseInclude
from six.moves import range
-from sphinx import addnodes
-from sphinx.locale import versionlabels, _
+from sphinx import addnodes, locale
+from sphinx.deprecation import DeprecatedDict, RemovedInSphinx30Warning
+from sphinx.locale import _
from sphinx.util import url_re, docname_join
+from sphinx.util.docutils import SphinxDirective
from sphinx.util.matching import patfilter
from sphinx.util.nodes import explicit_title_re, set_source_info, \
process_index_entry
@@ -29,6 +32,19 @@ if False:
from sphinx.application import Sphinx # NOQA
+versionlabels = {
+ 'versionadded': _('New in version %s'),
+ 'versionchanged': _('Changed in version %s'),
+ 'deprecated': _('Deprecated since version %s'),
+} # type: Dict[unicode, unicode]
+
+locale.versionlabels = DeprecatedDict(
+ versionlabels,
+ 'sphinx.locale.versionlabels is deprecated. '
+ 'Please use sphinx.directives.other.versionlabels instead.',
+ RemovedInSphinx30Warning
+)
+
glob_re = re.compile('.*[*?\[].*')
@@ -39,7 +55,7 @@ def int_or_nothing(argument):
return int(argument)
-class TocTree(Directive):
+class TocTree(SphinxDirective):
"""
Directive to notify Sphinx about the hierarchical structure of the docs,
and to include a table-of-contents like tree in the current document.
@@ -63,7 +79,7 @@ class TocTree(Directive):
def run(self):
# type: () -> List[nodes.Node]
subnode = addnodes.toctree()
- subnode['parent'] = self.state.document.settings.env.docname
+ subnode['parent'] = self.env.docname
# (title, ref) pairs, where ref may be a document, or an external link,
# and title may be None if the document's title is to be used
@@ -86,12 +102,11 @@ class TocTree(Directive):
return ret
def parse_content(self, toctree):
- env = self.state.document.settings.env
- suffixes = env.config.source_suffix
+ suffixes = self.config.source_suffix
# glob target documents
- all_docnames = env.found_docs.copy()
- all_docnames.remove(env.docname) # remove current document
+ all_docnames = self.env.found_docs.copy()
+ all_docnames.remove(self.env.docname) # remove current document
ret = []
for entry in self.content:
@@ -101,7 +116,7 @@ class TocTree(Directive):
explicit = explicit_title_re.match(entry)
if (toctree['glob'] and glob_re.match(entry) and
not explicit and not url_re.match(entry)):
- patname = docname_join(env.docname, entry)
+ patname = docname_join(self.env.docname, entry)
docnames = sorted(patfilter(all_docnames, patname))
for docname in docnames:
all_docnames.remove(docname) # don't include it again
@@ -125,14 +140,14 @@ class TocTree(Directive):
docname = docname[:-len(suffix)]
break
# absolutize filenames
- docname = docname_join(env.docname, docname)
+ docname = docname_join(self.env.docname, docname)
if url_re.match(ref) or ref == 'self':
toctree['entries'].append((title, ref))
- elif docname not in env.found_docs:
+ elif docname not in self.env.found_docs:
ret.append(self.state.document.reporter.warning(
'toctree contains reference to nonexisting '
'document %r' % docname, line=self.lineno))
- env.note_reread()
+ self.env.note_reread()
else:
all_docnames.discard(docname)
toctree['entries'].append((title, docname))
@@ -145,7 +160,7 @@ class TocTree(Directive):
return ret
-class Author(Directive):
+class Author(SphinxDirective):
"""
Directive to give the name of the author of the current document
or section. Shown in the output only if the show_authors option is on.
@@ -158,8 +173,7 @@ class Author(Directive):
def run(self):
# type: () -> List[nodes.Node]
- env = self.state.document.settings.env
- if not env.config.show_authors:
+ if not self.config.show_authors:
return []
para = nodes.paragraph(translatable=False)
emph = nodes.emphasis()
@@ -179,7 +193,7 @@ class Author(Directive):
return [para] + messages
-class Index(Directive):
+class Index(SphinxDirective):
"""
Directive to add entries to the index.
"""
@@ -192,8 +206,7 @@ class Index(Directive):
def run(self):
# type: () -> List[nodes.Node]
arguments = self.arguments[0].split('\n')
- env = self.state.document.settings.env
- targetid = 'index-%s' % env.new_serialno('index')
+ targetid = 'index-%s' % self.env.new_serialno('index')
targetnode = nodes.target('', '', ids=[targetid])
self.state.document.note_explicit_target(targetnode)
indexnode = addnodes.index()
@@ -205,7 +218,7 @@ class Index(Directive):
return [indexnode, targetnode]
-class VersionChange(Directive):
+class VersionChange(SphinxDirective):
"""
Directive to describe a change/addition/deprecation in a specific version.
"""
@@ -248,9 +261,8 @@ class VersionChange(Directive):
classes=['versionmodified']),
translatable=False)
node.append(para)
- env = self.state.document.settings.env
# XXX should record node.source as well
- env.note_versionchange(node['type'], node['version'], node, node.line)
+ self.env.note_versionchange(node['type'], node['version'], node, node.line)
return [node] + messages
@@ -261,7 +273,7 @@ class SeeAlso(BaseAdmonition):
node_class = addnodes.seealso
-class TabularColumns(Directive):
+class TabularColumns(SphinxDirective):
"""
Directive to give an explicit tabulary column definition to LaTeX.
"""
@@ -279,7 +291,7 @@ class TabularColumns(Directive):
return [node]
-class Centered(Directive):
+class Centered(SphinxDirective):
"""
Directive to create a centered line of bold text.
"""
@@ -300,7 +312,7 @@ class Centered(Directive):
return [subnode] + messages
-class Acks(Directive):
+class Acks(SphinxDirective):
"""
Directive for a list of names.
"""
@@ -322,7 +334,7 @@ class Acks(Directive):
return [node]
-class HList(Directive):
+class HList(SphinxDirective):
"""
Directive for a list that gets compacted horizontally.
"""
@@ -359,7 +371,7 @@ class HList(Directive):
return [newnode]
-class Only(Directive):
+class Only(SphinxDirective):
"""
Directive to only include text if the given tag(s) are enabled.
"""
@@ -417,7 +429,7 @@ class Only(Directive):
self.state.memo.section_level = surrounding_section_level
-class Include(BaseInclude):
+class Include(BaseInclude, SphinxDirective):
"""
Like the standard "Include" directive, but interprets absolute paths
"correctly", i.e. relative to source directory.
@@ -425,15 +437,35 @@ class Include(BaseInclude):
def run(self):
# type: () -> List[nodes.Node]
- env = self.state.document.settings.env
+ current_filename = self.env.doc2path(self.env.docname)
if self.arguments[0].startswith('<') and \
self.arguments[0].endswith('>'):
# docutils "standard" includes, do not do path processing
return BaseInclude.run(self)
- rel_filename, filename = env.relfn2path(self.arguments[0])
+ rel_filename, filename = self.env.relfn2path(self.arguments[0])
self.arguments[0] = filename
- env.note_included(filename)
- return BaseInclude.run(self)
+ self.env.note_included(filename)
+ with patched_warnings(self, current_filename):
+ return BaseInclude.run(self)
+
+
+@contextmanager
+def patched_warnings(directive, parent_filename):
+ # type: (BaseInclude, unicode) -> Generator[None, None, None]
+ """Add includee filename to the warnings during inclusion."""
+ try:
+ original = directive.state_machine.insert_input
+
+ def insert_input(input_lines, source):
+ # type: (Any, unicode) -> None
+ source += ' <included from %s>' % parent_filename
+ original(input_lines, source)
+
+ # patch insert_input() temporarily
+ directive.state_machine.insert_input = insert_input
+ yield
+ finally:
+ directive.state_machine.insert_input = original
def setup(app):