Merge pull request #6025 from tk0miya/refactor_roles2

Introduce SphinxRole class as a base class of roles
This commit is contained in:
Takeshi KOMIYA 2019-02-14 01:09:28 +09:00 committed by GitHub
commit 549a763195
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 3 deletions

View File

@ -114,6 +114,7 @@ Deprecated
* ``sphinx.io.SphinxFileInput.supported`` * ``sphinx.io.SphinxFileInput.supported``
* ``sphinx.io.SphinxRSTFileInput`` * ``sphinx.io.SphinxRSTFileInput``
* ``sphinx.registry.SphinxComponentRegistry.add_source_input()`` * ``sphinx.registry.SphinxComponentRegistry.add_source_input()``
* ``sphinx.roles.abbr_role()``
* ``sphinx.testing.util.remove_unicode_literal()`` * ``sphinx.testing.util.remove_unicode_literal()``
* ``sphinx.util.attrdict`` * ``sphinx.util.attrdict``
* ``sphinx.util.force_decode()`` * ``sphinx.util.force_decode()``

View File

@ -370,6 +370,11 @@ The following is a list of deprecated interfaces.
- 4.0 - 4.0
- ``sphinxcontrib.jsmath`` - ``sphinxcontrib.jsmath``
* - ``sphinx.roles.abbr_role()``
- 2.0
- 4.0
- ``sphinx.roles.Abbreviation``
* - ``sphinx.testing.util.remove_unicode_literal()`` * - ``sphinx.testing.util.remove_unicode_literal()``
- 2.0 - 2.0
- 4.0 - 4.0

View File

@ -9,13 +9,16 @@
""" """
import re import re
import warnings
from docutils import nodes, utils from docutils import nodes, utils
from sphinx import addnodes from sphinx import addnodes
from sphinx.deprecation import RemovedInSphinx40Warning
from sphinx.errors import SphinxError from sphinx.errors import SphinxError
from sphinx.locale import _ from sphinx.locale import _
from sphinx.util import ws_re from sphinx.util import ws_re
from sphinx.util.docutils import SphinxRole
from sphinx.util.nodes import split_explicit_title, process_index_entry, \ from sphinx.util.nodes import split_explicit_title, process_index_entry, \
set_role_source_info set_role_source_info
@ -338,6 +341,8 @@ _abbr_re = re.compile(r'\((.*)\)$', re.S)
def abbr_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): def abbr_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
# type: (str, str, str, int, Inliner, Dict, List[str]) -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA # type: (str, str, str, int, Inliner, Dict, List[str]) -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA
warnings.warn('abbr_role() is deprecated. Please use Abbrevation class instead.',
RemovedInSphinx40Warning, stacklevel=2)
text = utils.unescape(text) text = utils.unescape(text)
m = _abbr_re.search(text) m = _abbr_re.search(text)
if m is None: if m is None:
@ -349,6 +354,21 @@ def abbr_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
return [nodes.abbreviation(abbr, abbr, **options)], [] return [nodes.abbreviation(abbr, abbr, **options)], []
class Abbreviation(SphinxRole):
abbr_re = re.compile(r'\((.*)\)$', re.S)
def run(self):
# type: () -> Tuple[List[nodes.Node], List[nodes.system_message]]
matched = self.abbr_re.search(self.text)
if matched:
text = self.text[:matched.start()].strip()
self.options['explanation'] = matched.group(1)
else:
text = self.text
return [nodes.abbreviation(self.rawtext, text, **self.options)], []
def index_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): def index_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
# type: (str, str, str, int, Inliner, Dict, List[str]) -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA # type: (str, str, str, int, Inliner, Dict, List[str]) -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA
# create new reference target # create new reference target
@ -390,7 +410,7 @@ specific_docroles = {
'menuselection': menusel_role, 'menuselection': menusel_role,
'file': emph_literal_role, 'file': emph_literal_role,
'samp': emph_literal_role, 'samp': emph_literal_role,
'abbr': abbr_role, 'abbr': Abbreviation(),
'index': index_role, 'index': index_role,
} # type: Dict[str, RoleFunction] } # type: Dict[str, RoleFunction]

View File

@ -23,7 +23,7 @@ from docutils import nodes
from docutils.io import FileOutput from docutils.io import FileOutput
from docutils.parsers.rst import Directive, directives, roles, convert_directive_function from docutils.parsers.rst import Directive, directives, roles, convert_directive_function
from docutils.statemachine import StateMachine from docutils.statemachine import StateMachine
from docutils.utils import Reporter from docutils.utils import Reporter, unescape
from sphinx.deprecation import RemovedInSphinx30Warning from sphinx.deprecation import RemovedInSphinx30Warning
from sphinx.errors import ExtensionError from sphinx.errors import ExtensionError
@ -36,7 +36,8 @@ report_re = re.compile('^(.+?:(?:\\d+)?): \\((DEBUG|INFO|WARNING|ERROR|SEVERE)/(
if False: if False:
# For type annotation # For type annotation
from types import ModuleType # NOQA from types import ModuleType # NOQA
from typing import Any, Callable, Generator, List, Set, Tuple, Type # NOQA from typing import Any, Callable, Dict, Generator, List, Set, Tuple, Type # NOQA
from docutils.parsers.rst.states import Inliner # NOQA
from docutils.statemachine import State, StringList # NOQA from docutils.statemachine import State, StringList # NOQA
from sphinx.builders import Builder # NOQA from sphinx.builders import Builder # NOQA
from sphinx.config import Config # NOQA from sphinx.config import Config # NOQA
@ -383,6 +384,44 @@ class SphinxDirective(Directive):
return self.env.config return self.env.config
class SphinxRole:
"""A base class for Sphinx roles.
This class provides helper methods for Sphinx roles.
.. note:: The subclasses of this class might not work with docutils.
This class is strongly coupled with Sphinx.
"""
def __call__(self, typ, rawtext, text, lineno, inliner, options={}, content=[]):
# type: (str, str, str, int, Inliner, Dict, List[str]) -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA
self.type = typ
self.rawtext = rawtext
self.text = unescape(text)
self.lineno = lineno
self.inliner = inliner
self.options = options
self.content = content
return self.run()
def run(self):
# type: () -> Tuple[List[nodes.Node], List[nodes.system_message]]
raise NotImplementedError
@property
def env(self):
# type: () -> BuildEnvironment
"""Reference to the :class:`.BuildEnvironment` object."""
return self.inliner.document.settings.env
@property
def config(self):
# type: () -> Config
"""Reference to the :class:`.Config` object."""
return self.env.config
class SphinxTranslator(nodes.NodeVisitor): class SphinxTranslator(nodes.NodeVisitor):
"""A base class for Sphinx translators. """A base class for Sphinx translators.