Merge pull request #6129 from tk0miya/refactor_util.nodes

Refactor util.nodes
This commit is contained in:
Takeshi KOMIYA 2019-03-07 01:20:06 +09:00 committed by GitHub
commit 4ca5924d49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 43 additions and 21 deletions

View File

@ -18,6 +18,7 @@ Deprecated
* ``sphinx.ext.autodoc.importer.MockLoader`` * ``sphinx.ext.autodoc.importer.MockLoader``
* ``sphinx.ext.autodoc.importer.mock()`` * ``sphinx.ext.autodoc.importer.mock()``
* ``sphinx.ext.autosummary.autolink_role()`` * ``sphinx.ext.autosummary.autolink_role()``
* ``sphinx.util.node.find_source_node()``
* ``sphinx.util.i18n.find_catalog()`` * ``sphinx.util.i18n.find_catalog()``
* ``sphinx.util.i18n.find_catalog_files()`` * ``sphinx.util.i18n.find_catalog_files()``
* ``sphinx.util.i18n.find_catalog_source_files()`` * ``sphinx.util.i18n.find_catalog_source_files()``
@ -27,6 +28,8 @@ For more details, see :ref:`deprecation APIs list <dev-deprecated-apis>`.
Features added Features added
-------------- --------------
* Add a helper method ``SphinxDirective.set_source_info()``
Bugs fixed Bugs fixed
---------- ----------

View File

@ -259,6 +259,11 @@ The following is a list of deprecated interfaces.
- 4.0 - 4.0
- ``sphinx.ext.autosummary.AutoLink`` - ``sphinx.ext.autosummary.AutoLink``
* - ``sphinx.util.node.find_source_node()``
- 2.1
- 4.0
- ``sphinx.util.node.get_node_source()``
* - ``sphinx.util.i18n.find_catalog()`` * - ``sphinx.util.i18n.find_catalog()``
- 2.1 - 2.1
- 4.0 - 4.0

View File

@ -20,7 +20,6 @@ from sphinx.locale import __
from sphinx.util import logging from sphinx.util import logging
from sphinx.util import parselinenos from sphinx.util import parselinenos
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import set_source_info
if False: if False:
# For type annotation # For type annotation
@ -173,7 +172,7 @@ class CodeBlock(SphinxDirective):
extra_args['hl_lines'] = hl_lines extra_args['hl_lines'] = hl_lines
if 'lineno-start' in self.options: if 'lineno-start' in self.options:
extra_args['linenostart'] = self.options['lineno-start'] extra_args['linenostart'] = self.options['lineno-start']
set_source_info(self, literal) self.set_source_info(literal)
caption = self.options.get('caption') caption = self.options.get('caption')
if caption: if caption:
@ -446,7 +445,7 @@ class LiteralInclude(SphinxDirective):
text, lines = reader.read(location=location) text, lines = reader.read(location=location)
retnode = nodes.literal_block(text, text, source=filename) # type: nodes.Element retnode = nodes.literal_block(text, text, source=filename) # type: nodes.Element
set_source_info(self, retnode) self.set_source_info(retnode)
if self.options.get('diff'): # if diff is set, set udiff if self.options.get('diff'): # if diff is set, set udiff
retnode['language'] = 'udiff' retnode['language'] = 'udiff'
elif 'language' in self.options: elif 'language' in self.options:

View File

@ -21,8 +21,7 @@ from sphinx.locale import _
from sphinx.util import url_re, docname_join from sphinx.util import url_re, docname_join
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.matching import Matcher, patfilter from sphinx.util.matching import Matcher, patfilter
from sphinx.util.nodes import explicit_title_re, set_source_info, \ from sphinx.util.nodes import explicit_title_re, process_index_entry
process_index_entry
if False: if False:
# For type annotation # For type annotation
@ -77,7 +76,7 @@ class TocTree(SphinxDirective):
subnode['includehidden'] = 'includehidden' in self.options subnode['includehidden'] = 'includehidden' in self.options
subnode['numbered'] = self.options.get('numbered', 0) subnode['numbered'] = self.options.get('numbered', 0)
subnode['titlesonly'] = 'titlesonly' in self.options subnode['titlesonly'] = 'titlesonly' in self.options
set_source_info(self, subnode) self.set_source_info(subnode)
wrappernode = nodes.compound(classes=['toctree-wrapper']) wrappernode = nodes.compound(classes=['toctree-wrapper'])
wrappernode.append(subnode) wrappernode.append(subnode)
self.add_name(wrappernode) self.add_name(wrappernode)
@ -204,7 +203,7 @@ class Index(SphinxDirective):
indexnode = addnodes.index() indexnode = addnodes.index()
indexnode['entries'] = [] indexnode['entries'] = []
indexnode['inline'] = False indexnode['inline'] = False
set_source_info(self, indexnode) self.set_source_info(indexnode)
for entry in arguments: for entry in arguments:
indexnode['entries'].extend(process_index_entry(entry, targetid)) indexnode['entries'].extend(process_index_entry(entry, targetid))
return [indexnode, targetnode] return [indexnode, targetnode]
@ -231,7 +230,7 @@ class TabularColumns(SphinxDirective):
# type: () -> List[nodes.Node] # type: () -> List[nodes.Node]
node = addnodes.tabular_col_spec() node = addnodes.tabular_col_spec()
node['spec'] = self.arguments[0] node['spec'] = self.arguments[0]
set_source_info(self, node) self.set_source_info(node)
return [node] return [node]
@ -330,7 +329,7 @@ class Only(SphinxDirective):
# type: () -> List[nodes.Node] # type: () -> List[nodes.Node]
node = addnodes.only() node = addnodes.only()
node.document = self.state.document node.document = self.state.document
set_source_info(self, node) self.set_source_info(node)
node['expr'] = self.arguments[0] node['expr'] = self.arguments[0]
# Same as util.nested_parse_with_titles but try to handle nested # Same as util.nested_parse_with_titles but try to handle nested

View File

@ -132,7 +132,7 @@ class MathDirective(SphinxDirective):
label=self.options.get('label'), label=self.options.get('label'),
nowrap='nowrap' in self.options) nowrap='nowrap' in self.options)
ret = [node] # type: List[nodes.Node] ret = [node] # type: List[nodes.Node]
set_source_info(self, node) self.set_source_info(node)
self.add_target(ret) self.add_target(ret)
return ret return ret

View File

@ -19,7 +19,6 @@ from sphinx.deprecation import DeprecatedDict, RemovedInSphinx30Warning
from sphinx.domains import Domain from sphinx.domains import Domain
from sphinx.locale import _ from sphinx.locale import _
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import set_source_info
if False: if False:
@ -68,7 +67,7 @@ class VersionChange(SphinxDirective):
# type: () -> List[nodes.Node] # type: () -> List[nodes.Node]
node = addnodes.versionmodified() node = addnodes.versionmodified()
node.document = self.state.document node.document = self.state.document
set_source_info(self, node) self.set_source_info(node)
node['type'] = self.name node['type'] = self.name
node['version'] = self.arguments[0] node['version'] = self.arguments[0]
text = versionlabels[self.name] % self.arguments[0] text = versionlabels[self.name] % self.arguments[0]
@ -76,7 +75,7 @@ class VersionChange(SphinxDirective):
inodes, messages = self.state.inline_text(self.arguments[1], inodes, messages = self.state.inline_text(self.arguments[1],
self.lineno + 1) self.lineno + 1)
para = nodes.paragraph(self.arguments[1], '', *inodes, translatable=False) para = nodes.paragraph(self.arguments[1], '', *inodes, translatable=False)
set_source_info(self, para) self.set_source_info(para)
node.append(para) node.append(para)
else: else:
messages = [] messages = []

View File

@ -29,7 +29,6 @@ from sphinx.locale import __
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.console import bold # type: ignore from sphinx.util.console import bold # type: ignore
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import set_source_info
from sphinx.util.osutil import relpath from sphinx.util.osutil import relpath
if False: if False:
@ -104,7 +103,7 @@ class TestDirective(SphinxDirective):
else: else:
groups = ['default'] groups = ['default']
node = nodetype(code, code, testnodetype=self.name, groups=groups) node = nodetype(code, code, testnodetype=self.name, groups=groups)
set_source_info(self, node) self.set_source_info(node)
if test is not None: if test is not None:
# only save if it differs from code # only save if it differs from code
node['test'] = test node['test'] = test

View File

@ -23,7 +23,6 @@ from docutils import nodes
import sphinx import sphinx
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import set_source_info
if False: if False:
# For type annotation # For type annotation
@ -47,7 +46,7 @@ class IfConfig(SphinxDirective):
# type: () -> List[nodes.Node] # type: () -> List[nodes.Node]
node = ifconfig() node = ifconfig()
node.document = self.state.document node.document = self.state.document
set_source_info(self, node) self.set_source_info(node)
node['expr'] = self.arguments[0] node['expr'] = self.arguments[0]
self.state.nested_parse(self.content, self.content_offset, self.state.nested_parse(self.content, self.content_offset,
node, match_titles=True) node, match_titles=True)

View File

@ -22,7 +22,6 @@ from sphinx.errors import NoUri
from sphinx.locale import _, __ from sphinx.locale import _, __
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import set_source_info
from sphinx.util.texescape import tex_escape_map from sphinx.util.texescape import tex_escape_map
if False: if False:
@ -68,7 +67,7 @@ class Todo(BaseAdmonition, SphinxDirective):
return [todo] return [todo]
elif isinstance(todo, todo_node): elif isinstance(todo, todo_node):
todo.insert(0, nodes.title(text=_('Todo'))) todo.insert(0, nodes.title(text=_('Todo')))
set_source_info(self, todo) self.set_source_info(todo)
targetid = 'index-%s' % self.env.new_serialno('index') targetid = 'index-%s' % self.env.new_serialno('index')
# Stash the target to be retrieved later in latex_visit_todo_node. # Stash the target to be retrieved later in latex_visit_todo_node.

View File

@ -383,6 +383,11 @@ class SphinxDirective(Directive):
"""Reference to the :class:`.Config` object.""" """Reference to the :class:`.Config` object."""
return self.env.config return self.env.config
def set_source_info(self, node):
# type: (nodes.Node) -> None
"""Set source and line number to the node."""
node.source, node.line = self.state_machine.get_source_and_line(self.lineno)
class SphinxRole: class SphinxRole:
"""A base class for Sphinx roles. """A base class for Sphinx roles.

View File

@ -9,11 +9,13 @@
""" """
import re import re
import warnings
from typing import Any, cast from typing import Any, cast
from docutils import nodes from docutils import nodes
from sphinx import addnodes from sphinx import addnodes
from sphinx.deprecation import RemovedInSphinx40Warning
from sphinx.locale import __ from sphinx.locale import __
from sphinx.util import logging from sphinx.util import logging
@ -152,7 +154,7 @@ def apply_source_workaround(node):
# workaround: literal_block under bullet list (#4913) # workaround: literal_block under bullet list (#4913)
if isinstance(node, nodes.literal_block) and node.source is None: if isinstance(node, nodes.literal_block) and node.source is None:
node.source = find_source_node(node) node.source = get_node_source(node)
# workaround: recommonmark-0.2.0 doesn't set rawsource attribute # workaround: recommonmark-0.2.0 doesn't set rawsource attribute
if not node.rawsource: if not node.rawsource:
@ -170,7 +172,7 @@ def apply_source_workaround(node):
))): ))):
logger.debug('[i18n] PATCH: %r to have source and line: %s', logger.debug('[i18n] PATCH: %r to have source and line: %s',
get_full_module_name(node), repr_domxml(node)) get_full_module_name(node), repr_domxml(node))
node.source = find_source_node(node) node.source = get_node_source(node)
node.line = 0 # need fix docutils to get `node.line` node.line = 0 # need fix docutils to get `node.line`
return return
@ -278,6 +280,13 @@ def extract_messages(doctree):
def find_source_node(node): def find_source_node(node):
# type: (nodes.Element) -> str
warnings.warn('find_source_node() is deprecated.',
RemovedInSphinx40Warning)
return get_node_source(node)
def get_node_source(node):
# type: (nodes.Element) -> str # type: (nodes.Element) -> str
for pnode in traverse_parent(node): for pnode in traverse_parent(node):
if pnode.source: if pnode.source:
@ -467,6 +476,12 @@ def set_role_source_info(inliner, lineno, node):
node.source, node.line = inliner.reporter.get_source_and_line(lineno) # type: ignore node.source, node.line = inliner.reporter.get_source_and_line(lineno) # type: ignore
def copy_source_info(src, dst):
# type: (nodes.Element, nodes.Element) -> None
dst.source = get_node_source(src)
dst.line = get_node_line(src)
NON_SMARTQUOTABLE_PARENT_NODES = ( NON_SMARTQUOTABLE_PARENT_NODES = (
nodes.FixedTextElement, nodes.FixedTextElement,
nodes.literal, nodes.literal,