Skip to content

Commit

Permalink
Add desc_sig_element and inherited nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
tk0miya committed Feb 29, 2020
1 parent bac5192 commit 675e7e5
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
30 changes: 29 additions & 1 deletion sphinx/addnodes.py
Expand Up @@ -12,7 +12,7 @@
from typing import Any, Dict, List, Sequence

from docutils import nodes
from docutils.nodes import Node
from docutils.nodes import Element, Node

from sphinx.deprecation import RemovedInSphinx40Warning

Expand Down Expand Up @@ -174,6 +174,31 @@ class desc_content(nodes.General, nodes.Element):
"""


class desc_sig_element(nodes.inline):
"""Common parent class of nodes for inline text of a signature."""
classes = [] # type: List[str]

def __init__(self, rawsource: str = '', text: str = '',
*children: Element, **attributes: Any) -> None:
super().__init__(rawsource, text, *children, **attributes)
self['classes'].extend(self.classes)


class desc_sig_name(desc_sig_element):
"""Node for a name in a signature."""
classes = ["n"]


class desc_sig_operator(desc_sig_element):
"""Node for an operator in a signature."""
classes = ["o"]


class desc_sig_punctuation(desc_sig_element):
"""Node for a punctuation in a signature."""
classes = ["p"]


# new admonition-like constructs

class versionmodified(nodes.Admonition, nodes.TextElement):
Expand Down Expand Up @@ -332,6 +357,9 @@ def setup(app: "Sphinx") -> Dict[str, Any]:
app.add_node(desc_optional)
app.add_node(desc_annotation)
app.add_node(desc_content)
app.add_node(desc_sig_name)
app.add_node(desc_sig_operator)
app.add_node(desc_sig_punctuation)
app.add_node(versionmodified)
app.add_node(seealso)
app.add_node(productionlist)
Expand Down
35 changes: 34 additions & 1 deletion sphinx/transforms/post_transforms/__init__.py
Expand Up @@ -8,7 +8,7 @@
:license: BSD, see LICENSE for details.
"""

from typing import Any, Dict, List, Tuple
from typing import Any, Dict, List, Tuple, Type
from typing import cast

from docutils import nodes
Expand All @@ -22,6 +22,7 @@
from sphinx.locale import __
from sphinx.transforms import SphinxTransform
from sphinx.util import logging
from sphinx.util.docutils import SphinxTranslator
from sphinx.util.nodes import process_only_nodes


Expand Down Expand Up @@ -186,9 +187,41 @@ def run(self, **kwargs: Any) -> None:
process_only_nodes(self.document, self.app.builder.tags)


class SigElementFallbackTransform(SphinxPostTransform):
"""Fallback desc_sig_element nodes to inline if translator does not supported them."""
default_priority = 200

SIG_ELEMENTS = [addnodes.desc_sig_name,
addnodes.desc_sig_operator,
addnodes.desc_sig_punctuation]

def run(self, **kwargs: Any) -> None:
def has_visitor(translator: Type[nodes.NodeVisitor], node: Type[Element]) -> bool:
return hasattr(translator, "visit_%s" % node.__name__)

translator = self.app.builder.get_translator_class()
if isinstance(translator, SphinxTranslator):
# subclass of SphinxTranslator supports desc_sig_element nodes automatically.
return

if all(has_visitor(translator, node) for node in self.SIG_ELEMENTS):
# the translator supports all desc_sig_element nodes
return
else:
self.fallback()

def fallback(self):
for node in self.document.traverse(addnodes.desc_sig_element):
newnode = nodes.inline()
newnode.update_all_atts(node)
newnode.extend(node)
node.replace_self(newnode)


def setup(app: Sphinx) -> Dict[str, Any]:
app.add_post_transform(ReferencesResolver)
app.add_post_transform(OnlyNodeTransform)
app.add_post_transform(SigElementFallbackTransform)

return {
'version': 'builtin',
Expand Down

0 comments on commit 675e7e5

Please sign in to comment.