Skip to content

Commit

Permalink
Fix #8714: html: kbd role with "Caps Lock" rendered incorrectly
Browse files Browse the repository at this point in the history
`:kbd:` role has to support keys in consist of multiple words (ex. caps
lock, num lock, etc.)
  • Loading branch information
tk0miya committed Jan 22, 2021
1 parent d5d072b commit d6f4122
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Bugs fixed
* #8618: html: kbd role produces incorrect HTML when compound-key separators (-,
+ or ^) are used as keystrokes
* #8629: html: A type warning for html_use_opensearch is shown twice
* #8714: html: kbd role with "Caps Lock" rendered incorrectly
* #8665: html theme: Could not override globaltoc_maxdepth in theme.conf
* #4304: linkcheck: Fix race condition that could lead to checking the
availability of the same URL twice
Expand Down
27 changes: 24 additions & 3 deletions sphinx/builders/html/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"""

import re
from typing import Any, Dict
from typing import Any, Dict, List

from docutils import nodes

Expand Down Expand Up @@ -38,18 +38,29 @@ class KeyboardTransform(SphinxPostTransform):
default_priority = 400
builders = ('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"])
for node in self.document.traverse(matcher): # type: nodes.literal
parts = self.pattern.split(node[-1].astext())
if len(parts) == 1:
if len(parts) == 1 or self.is_multiwords_key(parts):
continue

node['classes'].append('compound')
node.pop()
while parts:
key = parts.pop(0)
if self.is_multiwords_key(parts):
key = ''.join(parts[:3])
parts[:3] = []
else:
key = parts.pop(0)
node += nodes.literal('', key, classes=["kbd"])

try:
Expand All @@ -59,6 +70,16 @@ def run(self, **kwargs: Any) -> None:
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()
if name in self.multiwords_keys:
return True
else:
return False
else:
return False


def setup(app: Sphinx) -> Dict[str, Any]:
app.add_post_transform(KeyboardTransform)
Expand Down
7 changes: 7 additions & 0 deletions tests/test_markup.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,13 @@ def get(name):
'<p><kbd class="kbd docutils literal notranslate">-</kbd></p>',
'\\sphinxkeyboard{\\sphinxupquote{\\sphinxhyphen{}}}',
),
(
# kbd role
'verify',
':kbd:`Caps Lock`',
'<p><kbd class="kbd docutils literal notranslate">Caps Lock</kbd></p>',
'\\sphinxkeyboard{\\sphinxupquote{Caps Lock}}',
),
(
# non-interpolation of dashes in option role
'verify_re',
Expand Down

0 comments on commit d6f4122

Please sign in to comment.