summaryrefslogtreecommitdiff
path: root/sphinx/builders/html/transforms.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/builders/html/transforms.py')
-rw-r--r--sphinx/builders/html/transforms.py69
1 files changed, 69 insertions, 0 deletions
diff --git a/sphinx/builders/html/transforms.py b/sphinx/builders/html/transforms.py
new file mode 100644
index 000000000..c91da57e9
--- /dev/null
+++ b/sphinx/builders/html/transforms.py
@@ -0,0 +1,69 @@
+"""
+ sphinx.builders.html.transforms
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Transforms for HTML builder.
+
+ :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import re
+from typing import Any, Dict
+
+from docutils import nodes
+
+from sphinx.application import Sphinx
+from sphinx.transforms.post_transforms import SphinxPostTransform
+from sphinx.util.nodes import NodeMatcher
+
+
+class KeyboardTransform(SphinxPostTransform):
+ """Transform :kbd: role to more detailed form.
+
+ Before::
+
+ <literal class="kbd">
+ Control-x
+
+ After::
+
+ <literal class="kbd">
+ <literal class="kbd">
+ Control
+ -
+ <literal class="kbd">
+ x
+ """
+ default_priority = 400
+ builders = ('html',)
+ pattern = re.compile(r'(-|\+|\^|\s+)')
+
+ def run(self, **kwargs: Any) -> None:
+ matcher = NodeMatcher(nodes.literal, classes=["kbd"])
+ for node in self.document.traverse(matcher): # type: nodes.literal
+ parts = self.pattern.split(node[-1].astext())
+ if len(parts) == 1:
+ continue
+
+ node.pop()
+ while parts:
+ 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 setup(app: Sphinx) -> Dict[str, Any]:
+ app.add_post_transform(KeyboardTransform)
+
+ return {
+ 'version': 'builtin',
+ 'parallel_read_safe': True,
+ 'parallel_write_safe': True,
+ }