summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sphinx/io.py10
-rw-r--r--sphinx/transforms/__init__.py223
-rw-r--r--sphinx/transforms/i18n.py (renamed from sphinx/transforms.py)218
3 files changed, 235 insertions, 216 deletions
diff --git a/sphinx/io.py b/sphinx/io.py
index 2b965b805..7f6ea2c59 100644
--- a/sphinx/io.py
+++ b/sphinx/io.py
@@ -14,10 +14,12 @@ from docutils.writers import UnfilteredWriter
from six import string_types, text_type
from sphinx.transforms import (
- ApplySourceWorkaround, ExtraTranslatableNodes, PreserveTranslatableMessages, Locale,
- CitationReferences, DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks,
- AutoNumbering, AutoIndexUpgrader, SortIds, RemoveTranslatableInline,
- FilterSystemMessages
+ ApplySourceWorkaround, ExtraTranslatableNodes, CitationReferences,
+ DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks, SortIds,
+ AutoNumbering, AutoIndexUpgrader, FilterSystemMessages,
+)
+from sphinx.transforms.i18n import (
+ PreserveTranslatableMessages, Locale, RemoveTranslatableInline,
)
from sphinx.util import import_object, split_docinfo
diff --git a/sphinx/transforms/__init__.py b/sphinx/transforms/__init__.py
new file mode 100644
index 000000000..79ac99c9f
--- /dev/null
+++ b/sphinx/transforms/__init__.py
@@ -0,0 +1,223 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.transforms
+ ~~~~~~~~~~~~~~~~~
+
+ Docutils transforms used by Sphinx when reading documents.
+
+ :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+from docutils import nodes
+from docutils.transforms import Transform
+from docutils.transforms.parts import ContentsFilter
+
+from sphinx import addnodes
+from sphinx.locale import _
+from sphinx.util.i18n import format_date
+from sphinx.util.nodes import apply_source_workaround
+
+default_substitutions = set([
+ 'version',
+ 'release',
+ 'today',
+])
+
+
+class DefaultSubstitutions(Transform):
+ """
+ Replace some substitutions if they aren't defined in the document.
+ """
+ # run before the default Substitutions
+ default_priority = 210
+
+ def apply(self):
+ env = self.document.settings.env
+ config = self.document.settings.env.config
+ # only handle those not otherwise defined in the document
+ to_handle = default_substitutions - set(self.document.substitution_defs)
+ for ref in self.document.traverse(nodes.substitution_reference):
+ refname = ref['refname']
+ if refname in to_handle:
+ text = config[refname]
+ if refname == 'today' and not text:
+ # special handling: can also specify a strftime format
+ text = format_date(config.today_fmt or _('%b %d, %Y'),
+ language=config.language, warn=env.warn)
+ ref.replace_self(nodes.Text(text, text))
+
+
+class MoveModuleTargets(Transform):
+ """
+ Move module targets that are the first thing in a section to the section
+ title.
+
+ XXX Python specific
+ """
+ default_priority = 210
+
+ def apply(self):
+ for node in self.document.traverse(nodes.target):
+ if not node['ids']:
+ continue
+ if ('ismod' in node and
+ node.parent.__class__ is nodes.section and
+ # index 0 is the section title node
+ node.parent.index(node) == 1):
+ node.parent['ids'][0:0] = node['ids']
+ node.parent.remove(node)
+
+
+class HandleCodeBlocks(Transform):
+ """
+ Several code block related transformations.
+ """
+ default_priority = 210
+
+ def apply(self):
+ # move doctest blocks out of blockquotes
+ for node in self.document.traverse(nodes.block_quote):
+ if all(isinstance(child, nodes.doctest_block) for child
+ in node.children):
+ node.replace_self(node.children)
+ # combine successive doctest blocks
+ # for node in self.document.traverse(nodes.doctest_block):
+ # if node not in node.parent.children:
+ # continue
+ # parindex = node.parent.index(node)
+ # while len(node.parent) > parindex+1 and \
+ # isinstance(node.parent[parindex+1], nodes.doctest_block):
+ # node[0] = nodes.Text(node[0] + '\n\n' +
+ # node.parent[parindex+1][0])
+ # del node.parent[parindex+1]
+
+
+class AutoNumbering(Transform):
+ """
+ Register IDs of tables, figures and literal_blocks to assign numbers.
+ """
+ default_priority = 210
+
+ def apply(self):
+ domain = self.document.settings.env.domains['std']
+
+ for node in self.document.traverse(nodes.Element):
+ if domain.is_enumerable_node(node) and domain.get_numfig_title(node) is not None:
+ self.document.note_implicit_target(node)
+
+
+class SortIds(Transform):
+ """
+ Sort secion IDs so that the "id[0-9]+" one comes last.
+ """
+ default_priority = 261
+
+ def apply(self):
+ for node in self.document.traverse(nodes.section):
+ if len(node['ids']) > 1 and node['ids'][0].startswith('id'):
+ node['ids'] = node['ids'][1:] + [node['ids'][0]]
+
+
+class CitationReferences(Transform):
+ """
+ Replace citation references by pending_xref nodes before the default
+ docutils transform tries to resolve them.
+ """
+ default_priority = 619
+
+ def apply(self):
+ for citnode in self.document.traverse(nodes.citation_reference):
+ cittext = citnode.astext()
+ refnode = addnodes.pending_xref(cittext, refdomain='std', reftype='citation',
+ reftarget=cittext, refwarn=True,
+ ids=citnode["ids"])
+ refnode.source = citnode.source or citnode.parent.source
+ refnode.line = citnode.line or citnode.parent.line
+ refnode += nodes.Text('[' + cittext + ']')
+ citnode.parent.replace(citnode, refnode)
+
+
+TRANSLATABLE_NODES = {
+ 'literal-block': nodes.literal_block,
+ 'doctest-block': nodes.doctest_block,
+ 'raw': nodes.raw,
+ 'index': addnodes.index,
+ 'image': nodes.image,
+}
+
+
+class ApplySourceWorkaround(Transform):
+ """
+ update source and rawsource attributes
+ """
+ default_priority = 10
+
+ def apply(self):
+ for n in self.document.traverse():
+ if isinstance(n, nodes.TextElement):
+ apply_source_workaround(n)
+
+
+class AutoIndexUpgrader(Transform):
+ """
+ Detect old style; 4 column based indices and automatically upgrade to new style.
+ """
+ default_priority = 210
+
+ def apply(self):
+ env = self.document.settings.env
+ for node in self.document.traverse(addnodes.index):
+ if 'entries' in node and any(len(entry) == 4 for entry in node['entries']):
+ msg = ('4 column based index found. '
+ 'It might be a bug of extensions you use: %r' % node['entries'])
+ env.warn_node(msg, node)
+ for i, entry in enumerate(node['entries']):
+ if len(entry) == 4:
+ node['entries'][i] = entry + (None,)
+
+
+class ExtraTranslatableNodes(Transform):
+ """
+ make nodes translatable
+ """
+ default_priority = 10
+
+ def apply(self):
+ targets = self.document.settings.env.config.gettext_additional_targets
+ target_nodes = [v for k, v in TRANSLATABLE_NODES.items() if k in targets]
+ if not target_nodes:
+ return
+
+ def is_translatable_node(node):
+ return isinstance(node, tuple(target_nodes))
+
+ for node in self.document.traverse(is_translatable_node):
+ node['translatable'] = True
+
+
+class FilterSystemMessages(Transform):
+ """Filter system messages from a doctree."""
+ default_priority = 999
+
+ def apply(self):
+ env = self.document.settings.env
+ filterlevel = env.config.keep_warnings and 2 or 5
+ for node in self.document.traverse(nodes.system_message):
+ if node['level'] < filterlevel:
+ env.app.debug('%s [filtered system message]', node.astext())
+ node.parent.remove(node)
+
+
+class SphinxContentsFilter(ContentsFilter):
+ """
+ Used with BuildEnvironment.add_toc_from() to discard cross-file links
+ within table-of-contents link nodes.
+ """
+ def visit_pending_xref(self, node):
+ text = node.astext()
+ self.parent.append(nodes.literal(text, text))
+ raise nodes.SkipNode
+
+ def visit_image(self, node):
+ raise nodes.SkipNode
diff --git a/sphinx/transforms.py b/sphinx/transforms/i18n.py
index 516b22843..38c5aef25 100644
--- a/sphinx/transforms.py
+++ b/sphinx/transforms/i18n.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
- sphinx.transforms
- ~~~~~~~~~~~~~~~~~
+ sphinx.transforms.i18n
+ ~~~~~~~~~~~~~~~~~~~~~~
Docutils transforms used by Sphinx when reading documents.
@@ -15,198 +15,19 @@ from docutils import nodes
from docutils.io import StringInput
from docutils.utils import relative_path
from docutils.transforms import Transform
-from docutils.transforms.parts import ContentsFilter
from sphinx import addnodes
-from sphinx.locale import _, init as init_locale
from sphinx.util import split_index_msg
+from sphinx.util.i18n import find_catalog
from sphinx.util.nodes import (
- traverse_translatable_index, extract_messages, LITERAL_TYPE_NODES, IMAGE_TYPE_NODES,
- apply_source_workaround, is_pending_meta,
+ LITERAL_TYPE_NODES, IMAGE_TYPE_NODES,
+ extract_messages, is_pending_meta, traverse_translatable_index,
)
-from sphinx.util.i18n import find_catalog, format_date
from sphinx.util.pycompat import indent
+from sphinx.locale import init as init_locale
from sphinx.domains.std import make_glossary_term, split_term_classifiers
-default_substitutions = set([
- 'version',
- 'release',
- 'today',
-])
-
-
-class DefaultSubstitutions(Transform):
- """
- Replace some substitutions if they aren't defined in the document.
- """
- # run before the default Substitutions
- default_priority = 210
-
- def apply(self):
- env = self.document.settings.env
- config = self.document.settings.env.config
- # only handle those not otherwise defined in the document
- to_handle = default_substitutions - set(self.document.substitution_defs)
- for ref in self.document.traverse(nodes.substitution_reference):
- refname = ref['refname']
- if refname in to_handle:
- text = config[refname]
- if refname == 'today' and not text:
- # special handling: can also specify a strftime format
- text = format_date(config.today_fmt or _('%b %d, %Y'),
- language=config.language, warn=env.warn)
- ref.replace_self(nodes.Text(text, text))
-
-
-class MoveModuleTargets(Transform):
- """
- Move module targets that are the first thing in a section to the section
- title.
-
- XXX Python specific
- """
- default_priority = 210
-
- def apply(self):
- for node in self.document.traverse(nodes.target):
- if not node['ids']:
- continue
- if ('ismod' in node and
- node.parent.__class__ is nodes.section and
- # index 0 is the section title node
- node.parent.index(node) == 1):
- node.parent['ids'][0:0] = node['ids']
- node.parent.remove(node)
-
-
-class HandleCodeBlocks(Transform):
- """
- Several code block related transformations.
- """
- default_priority = 210
-
- def apply(self):
- # move doctest blocks out of blockquotes
- for node in self.document.traverse(nodes.block_quote):
- if all(isinstance(child, nodes.doctest_block) for child
- in node.children):
- node.replace_self(node.children)
- # combine successive doctest blocks
- # for node in self.document.traverse(nodes.doctest_block):
- # if node not in node.parent.children:
- # continue
- # parindex = node.parent.index(node)
- # while len(node.parent) > parindex+1 and \
- # isinstance(node.parent[parindex+1], nodes.doctest_block):
- # node[0] = nodes.Text(node[0] + '\n\n' +
- # node.parent[parindex+1][0])
- # del node.parent[parindex+1]
-
-
-class AutoNumbering(Transform):
- """
- Register IDs of tables, figures and literal_blocks to assign numbers.
- """
- default_priority = 210
-
- def apply(self):
- domain = self.document.settings.env.domains['std']
-
- for node in self.document.traverse(nodes.Element):
- if domain.is_enumerable_node(node) and domain.get_numfig_title(node) is not None:
- self.document.note_implicit_target(node)
-
-
-class SortIds(Transform):
- """
- Sort secion IDs so that the "id[0-9]+" one comes last.
- """
- default_priority = 261
-
- def apply(self):
- for node in self.document.traverse(nodes.section):
- if len(node['ids']) > 1 and node['ids'][0].startswith('id'):
- node['ids'] = node['ids'][1:] + [node['ids'][0]]
-
-
-class CitationReferences(Transform):
- """
- Replace citation references by pending_xref nodes before the default
- docutils transform tries to resolve them.
- """
- default_priority = 619
-
- def apply(self):
- for citnode in self.document.traverse(nodes.citation_reference):
- cittext = citnode.astext()
- refnode = addnodes.pending_xref(cittext, refdomain='std', reftype='citation',
- reftarget=cittext, refwarn=True,
- ids=citnode["ids"])
- refnode.source = citnode.source or citnode.parent.source
- refnode.line = citnode.line or citnode.parent.line
- refnode += nodes.Text('[' + cittext + ']')
- citnode.parent.replace(citnode, refnode)
-
-
-TRANSLATABLE_NODES = {
- 'literal-block': nodes.literal_block,
- 'doctest-block': nodes.doctest_block,
- 'raw': nodes.raw,
- 'index': addnodes.index,
- 'image': nodes.image,
-}
-
-
-class ApplySourceWorkaround(Transform):
- """
- update source and rawsource attributes
- """
- default_priority = 10
-
- def apply(self):
- for n in self.document.traverse():
- if isinstance(n, nodes.TextElement):
- apply_source_workaround(n)
-
-
-class AutoIndexUpgrader(Transform):
- """
- Detect old style; 4 column based indices and automatically upgrade to new style.
- """
- default_priority = 210
-
- def apply(self):
- env = self.document.settings.env
- for node in self.document.traverse(addnodes.index):
- if 'entries' in node and any(len(entry) == 4 for entry in node['entries']):
- msg = ('4 column based index found. '
- 'It might be a bug of extensions you use: %r' % node['entries'])
- env.warn_node(msg, node)
- for i, entry in enumerate(node['entries']):
- if len(entry) == 4:
- node['entries'][i] = entry + (None,)
-
-
-class ExtraTranslatableNodes(Transform):
- """
- make nodes translatable
- """
- default_priority = 10
-
- def apply(self):
- targets = self.document.settings.env.config.gettext_additional_targets
- target_nodes = [v for k, v in TRANSLATABLE_NODES.items() if k in targets]
- if not target_nodes:
- return
-
- def is_translatable_node(node):
- return isinstance(node, tuple(target_nodes))
-
- for node in self.document.traverse(is_translatable_node):
- node['translatable'] = True
-
-
def publish_msgstr(app, source, source_path, source_line, config, settings):
"""Publish msgstr (single line) into docutils document
@@ -249,19 +70,6 @@ class PreserveTranslatableMessages(Transform):
node.preserve_original_messages()
-class FilterSystemMessages(Transform):
- """Filter system messages from a doctree."""
- default_priority = 999
-
- def apply(self):
- env = self.document.settings.env
- filterlevel = env.config.keep_warnings and 2 or 5
- for node in self.document.traverse(nodes.system_message):
- if node['level'] < filterlevel:
- env.app.debug('%s [filtered system message]', node.astext())
- node.parent.remove(node)
-
-
class Locale(Transform):
"""
Replace translatable nodes with their translated doctree.
@@ -608,17 +416,3 @@ class RemoveTranslatableInline(Transform):
if 'translatable' in inline:
inline.parent.remove(inline)
inline.parent += inline.children
-
-
-class SphinxContentsFilter(ContentsFilter):
- """
- Used with BuildEnvironment.add_toc_from() to discard cross-file links
- within table-of-contents link nodes.
- """
- def visit_pending_xref(self, node):
- text = node.astext()
- self.parent.append(nodes.literal(text, text))
- raise nodes.SkipNode
-
- def visit_image(self, node):
- raise nodes.SkipNode