mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #7009 from tk0miya/refactor_SphinxTranslator2
SphinxTranslator calls visitor/departure method for super node class
This commit is contained in:
commit
4cecd700e0
2
CHANGES
2
CHANGES
@ -35,6 +35,8 @@ Features added
|
||||
images (imagesize-1.2.0 or above is required)
|
||||
* #6994: imgconverter: Support illustrator file (.ai) to .png conversion
|
||||
* autodoc: Support Positional-Only Argument separator (PEP-570 compliant)
|
||||
* SphinxTranslator now calls visitor/departure method for super node class if
|
||||
visitor/departure method for original node class not found
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
@ -452,7 +452,10 @@ class ReferenceRole(SphinxRole):
|
||||
class SphinxTranslator(nodes.NodeVisitor):
|
||||
"""A base class for Sphinx translators.
|
||||
|
||||
This class provides helper methods for Sphinx translators.
|
||||
This class adds a support for visitor/departure method for super node class
|
||||
if visitor/departure method for node class is not found.
|
||||
|
||||
It also provides helper methods for Sphinx translators.
|
||||
|
||||
.. note:: The subclasses of this class might not work with docutils.
|
||||
This class is strongly coupled with Sphinx.
|
||||
@ -464,6 +467,42 @@ class SphinxTranslator(nodes.NodeVisitor):
|
||||
self.config = builder.config
|
||||
self.settings = document.settings
|
||||
|
||||
def dispatch_visit(self, node):
|
||||
"""
|
||||
Dispatch node to appropriate visitor method.
|
||||
The priority of visitor method is:
|
||||
|
||||
1. ``self.visit_{node_class}()``
|
||||
2. ``self.visit_{supre_node_class}()``
|
||||
3. ``self.unknown_visit()``
|
||||
"""
|
||||
for node_class in node.__class__.__mro__:
|
||||
method = getattr(self, 'visit_%s' % (node_class.__name__), None)
|
||||
if method:
|
||||
logger.debug('SphinxTranslator.dispatch_visit calling %s for %s' %
|
||||
(method.__name__, node))
|
||||
return method(node)
|
||||
else:
|
||||
super().dispatch_visit(node)
|
||||
|
||||
def dispatch_departure(self, node):
|
||||
"""
|
||||
Dispatch node to appropriate departure method.
|
||||
The priority of departure method is:
|
||||
|
||||
1. ``self.depart_{node_class}()``
|
||||
2. ``self.depart_{super_node_class}()``
|
||||
3. ``self.unknown_departure()``
|
||||
"""
|
||||
for node_class in node.__class__.__mro__:
|
||||
method = getattr(self, 'depart_%s' % (node_class.__name__), None)
|
||||
if method:
|
||||
logger.debug('SphinxTranslator.dispatch_departure calling %s for %s' %
|
||||
(method.__name__, node))
|
||||
return method(node)
|
||||
else:
|
||||
super().dispatch_departure(node)
|
||||
|
||||
|
||||
# cache a vanilla instance of nodes.document
|
||||
# Used in new_document() function
|
||||
|
@ -12,7 +12,9 @@ import os
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx.util.docutils import SphinxFileOutput, docutils_namespace, register_node
|
||||
from sphinx.util.docutils import (
|
||||
SphinxFileOutput, SphinxTranslator, docutils_namespace, new_document, register_node
|
||||
)
|
||||
|
||||
|
||||
def test_register_node():
|
||||
@ -61,3 +63,34 @@ def test_SphinxFileOutput(tmpdir):
|
||||
# overrite it again (content changed)
|
||||
output.write(content + "; content change")
|
||||
assert os.stat(filename).st_mtime != 0 # updated
|
||||
|
||||
|
||||
def test_SphinxTranslator(app):
|
||||
class CustomNode(nodes.inline):
|
||||
pass
|
||||
|
||||
class MyTranslator(SphinxTranslator):
|
||||
def __init__(self, *args):
|
||||
self.called = []
|
||||
super().__init__(*args)
|
||||
|
||||
def visit_document(self, node):
|
||||
pass
|
||||
|
||||
def depart_document(self, node):
|
||||
pass
|
||||
|
||||
def visit_inline(self, node):
|
||||
self.called.append('visit_inline')
|
||||
|
||||
def depart_inline(self, node):
|
||||
self.called.append('depart_inline')
|
||||
|
||||
document = new_document('')
|
||||
document += CustomNode()
|
||||
|
||||
translator = MyTranslator(document, app.builder)
|
||||
document.walkabout(translator)
|
||||
|
||||
# MyTranslator does not have visit_CustomNode. But it calls visit_inline instead.
|
||||
assert translator.called == ['visit_inline', 'depart_inline']
|
||||
|
Loading…
Reference in New Issue
Block a user