summaryrefslogtreecommitdiff
path: root/sphinx/util/nodes.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/util/nodes.py')
-rw-r--r--sphinx/util/nodes.py59
1 files changed, 32 insertions, 27 deletions
diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py
index d5e43e716..44eb5d303 100644
--- a/sphinx/util/nodes.py
+++ b/sphinx/util/nodes.py
@@ -10,8 +10,7 @@
import re
import unicodedata
-import warnings
-from typing import Any, Callable, Iterable, List, Set, Tuple, cast
+from typing import TYPE_CHECKING, Any, Callable, Iterable, List, Set, Tuple, Type, Union, cast
from docutils import nodes
from docutils.nodes import Element, Node
@@ -20,14 +19,10 @@ from docutils.parsers.rst.states import Inliner
from docutils.statemachine import StringList
from sphinx import addnodes
-from sphinx.deprecation import RemovedInSphinx40Warning
from sphinx.locale import __
from sphinx.util import logging
-if False:
- # For type annotation
- from typing import Type # for python3.5.1
-
+if TYPE_CHECKING:
from sphinx.builders import Builder
from sphinx.domain import IndexEntry
from sphinx.environment import BuildEnvironment
@@ -63,7 +58,7 @@ class NodeMatcher:
# => [<reference ...>, <reference ...>, ...]
"""
- def __init__(self, *node_classes: "Type[Node]", **attrs: Any) -> None:
+ def __init__(self, *node_classes: Type[Node], **attrs: Any) -> None:
self.classes = node_classes
self.attrs = attrs
@@ -201,6 +196,10 @@ def is_translatable(node: Node) -> bool:
if isinstance(node, addnodes.translatable):
return True
+ # image node marked as translatable or having alt text
+ if isinstance(node, nodes.image) and (node.get('translatable') or node.get('alt')):
+ return True
+
if isinstance(node, nodes.Inline) and 'translatable' not in node: # type: ignore
# inline node must not be translated if 'translatable' is not set
return False
@@ -228,9 +227,6 @@ def is_translatable(node: Node) -> bool:
return False
return True
- if isinstance(node, nodes.image) and node.get('translatable'):
- return True
-
if isinstance(node, addnodes.meta):
return True
if is_pending_meta(node):
@@ -255,7 +251,7 @@ META_TYPE_NODES = (
def extract_messages(doctree: Element) -> Iterable[Tuple[Element, str]]:
"""Extract translatable messages from a document tree."""
- for node in doctree.traverse(is_translatable): # type: nodes.Element
+ for node in doctree.traverse(is_translatable): # type: Element
if isinstance(node, addnodes.translatable):
for msg in node.extract_original_messages():
yield node, msg
@@ -264,10 +260,13 @@ def extract_messages(doctree: Element) -> Iterable[Tuple[Element, str]]:
msg = node.rawsource
if not msg:
msg = node.astext()
- elif isinstance(node, IMAGE_TYPE_NODES):
- msg = '.. image:: %s' % node['uri']
+ elif isinstance(node, nodes.image):
if node.get('alt'):
- msg += '\n :alt: %s' % node['alt']
+ yield node, node['alt']
+ if node.get('translatable'):
+ msg = '.. image:: %s' % node['uri']
+ else:
+ msg = None
elif isinstance(node, META_TYPE_NODES):
msg = node.rawcontent
elif isinstance(node, nodes.pending) and is_pending_meta(node):
@@ -280,12 +279,6 @@ def extract_messages(doctree: Element) -> Iterable[Tuple[Element, str]]:
yield node, msg
-def find_source_node(node: Element) -> str:
- warnings.warn('find_source_node() is deprecated.',
- RemovedInSphinx40Warning, stacklevel=2)
- return get_node_source(node)
-
-
def get_node_source(node: Element) -> str:
for pnode in traverse_parent(node):
if pnode.source:
@@ -370,7 +363,7 @@ indextypes = [
def process_index_entry(entry: str, targetid: str) -> List[Tuple[str, str, str, str, str]]:
from sphinx.domains.python import pairindextypes
- indexentries = [] # type: List[Tuple[str, str, str, str, str]]
+ indexentries: List[Tuple[str, str, str, str, str]] = []
entry = entry.strip()
oentry = entry
main = ''
@@ -538,8 +531,18 @@ def make_id(env: "BuildEnvironment", document: nodes.document,
return node_id
+def find_pending_xref_condition(node: addnodes.pending_xref, condition: str) -> Element:
+ """Pick matched pending_xref_condition node up from the pending_xref."""
+ for subnode in node:
+ if (isinstance(subnode, addnodes.pending_xref_condition) and
+ subnode.get('condition') == condition):
+ return subnode
+ else:
+ return None
+
+
def make_refnode(builder: "Builder", fromdocname: str, todocname: str, targetid: str,
- child: Node, title: str = None) -> nodes.reference:
+ child: Union[Node, List[Node]], title: str = None) -> nodes.reference:
"""Shortcut to create a reference node."""
node = nodes.reference('', '', internal=True)
if fromdocname == todocname and targetid:
@@ -552,7 +555,7 @@ def make_refnode(builder: "Builder", fromdocname: str, todocname: str, targetid:
node['refuri'] = builder.get_relative_uri(fromdocname, todocname)
if title:
node['reftitle'] = title
- node.append(child)
+ node += child
return node
@@ -613,10 +616,12 @@ def process_only_nodes(document: Node, tags: "Tags") -> None:
node.replace_self(nodes.comment())
-# monkey-patch Element.copy to copy the rawsource and line
-# for docutils-0.14 or older versions.
-
def _new_copy(self: Element) -> Element:
+ """monkey-patch Element.copy to copy the rawsource and line
+ for docutils-0.16 or older versions.
+
+ refs: https://sourceforge.net/p/docutils/patches/165/
+ """
newnode = self.__class__(self.rawsource, **self.attributes)
if isinstance(self, nodes.Element):
newnode.source = self.source