From cf7da1843c45a4c2df7a749f7886a2d2ba0ee92a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 19:25:40 +0200 Subject: Adding upstream version 7.2.6. Signed-off-by: Daniel Baumann --- sphinx/builders/html/transforms.py | 86 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 sphinx/builders/html/transforms.py (limited to 'sphinx/builders/html/transforms.py') diff --git a/sphinx/builders/html/transforms.py b/sphinx/builders/html/transforms.py new file mode 100644 index 0000000..18a8d38 --- /dev/null +++ b/sphinx/builders/html/transforms.py @@ -0,0 +1,86 @@ +"""Transforms for HTML builder.""" + +from __future__ import annotations + +import re +from typing import TYPE_CHECKING, Any + +from docutils import nodes + +from sphinx.transforms.post_transforms import SphinxPostTransform +from sphinx.util.nodes import NodeMatcher + +if TYPE_CHECKING: + from sphinx.application import Sphinx + + +class KeyboardTransform(SphinxPostTransform): + """Transform :kbd: role to more detailed form. + + Before:: + + + Control-x + + After:: + + + + Control + - + + x + """ + default_priority = 400 + formats = ('html',) + pattern = re.compile(r'(?<=.)(-|\+|\^|\s+)(?=.)') + multiwords_keys = (('caps', 'lock'), + ('page', 'down'), + ('page', 'up'), + ('scroll', 'lock'), + ('num', 'lock'), + ('sys', 'rq'), + ('back', 'space')) + + def run(self, **kwargs: Any) -> None: + matcher = NodeMatcher(nodes.literal, classes=["kbd"]) + # this list must be pre-created as during iteration new nodes + # are added which match the condition in the NodeMatcher. + for node in list(self.document.findall(matcher)): # type: nodes.literal + parts = self.pattern.split(node[-1].astext()) + if len(parts) == 1 or self.is_multiwords_key(parts): + continue + + node['classes'].append('compound') + node.pop() + while parts: + if self.is_multiwords_key(parts): + key = ''.join(parts[:3]) + parts[:3] = [] + else: + key = parts.pop(0) + node += nodes.literal('', key, classes=["kbd"]) + + try: + # key separator (ex. -, +, ^) + sep = parts.pop(0) + node += nodes.Text(sep) + except IndexError: + pass + + def is_multiwords_key(self, parts: list[str]) -> bool: + if len(parts) >= 3 and parts[1].strip() == '': + name = parts[0].lower(), parts[2].lower() + return name in self.multiwords_keys + else: + return False + + +def setup(app: Sphinx) -> dict[str, Any]: + app.add_post_transform(KeyboardTransform) + + return { + 'version': 'builtin', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + } -- cgit v1.2.3