mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Close #7530: html: Support nested <kbd> elements
This commit is contained in:
parent
911a3b9809
commit
a148a8e7cb
1
CHANGES
1
CHANGES
@ -49,6 +49,7 @@ Features added
|
|||||||
to generate stub files recursively
|
to generate stub files recursively
|
||||||
* #4030: autosummary: Add :confval:`autosummary_context` to add template
|
* #4030: autosummary: Add :confval:`autosummary_context` to add template
|
||||||
variables for custom templates
|
variables for custom templates
|
||||||
|
* #7530: html: Support nested <kbd> elements
|
||||||
* #7481: html theme: Add right margin to footnote/citation labels
|
* #7481: html theme: Add right margin to footnote/citation labels
|
||||||
* #7482: html theme: CSS spacing for code blocks with captions and line numbers
|
* #7482: html theme: CSS spacing for code blocks with captions and line numbers
|
||||||
* #7443: html theme: Add new options :confval:`globaltoc_collapse` and
|
* #7443: html theme: Add new options :confval:`globaltoc_collapse` and
|
||||||
|
@ -1243,6 +1243,9 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
# load default math renderer
|
# load default math renderer
|
||||||
app.setup_extension('sphinx.ext.mathjax')
|
app.setup_extension('sphinx.ext.mathjax')
|
||||||
|
|
||||||
|
# load transforms for HTML builder
|
||||||
|
app.setup_extension('sphinx.builders.html.transforms')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'version': 'builtin',
|
'version': 'builtin',
|
||||||
'parallel_read_safe': True,
|
'parallel_read_safe': True,
|
||||||
|
69
sphinx/builders/html/transforms.py
Normal file
69
sphinx/builders/html/transforms.py
Normal file
@ -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,
|
||||||
|
}
|
@ -16,6 +16,7 @@ from docutils.parsers.rst import Parser as RstParser
|
|||||||
from docutils.transforms.universal import SmartQuotes
|
from docutils.transforms.universal import SmartQuotes
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
from sphinx.builders.html.transforms import KeyboardTransform
|
||||||
from sphinx.builders.latex import LaTeXBuilder
|
from sphinx.builders.latex import LaTeXBuilder
|
||||||
from sphinx.roles import XRefRole
|
from sphinx.roles import XRefRole
|
||||||
from sphinx.testing.util import Struct, assert_node
|
from sphinx.testing.util import Struct, assert_node
|
||||||
@ -94,6 +95,7 @@ class ForgivingLaTeXTranslator(LaTeXTranslator, ForgivingTranslator):
|
|||||||
def verify_re_html(app, parse):
|
def verify_re_html(app, parse):
|
||||||
def verify(rst, html_expected):
|
def verify(rst, html_expected):
|
||||||
document = parse(rst)
|
document = parse(rst)
|
||||||
|
KeyboardTransform(document).apply()
|
||||||
html_translator = ForgivingHTMLTranslator(document, app.builder)
|
html_translator = ForgivingHTMLTranslator(document, app.builder)
|
||||||
document.walkabout(html_translator)
|
document.walkabout(html_translator)
|
||||||
html_translated = ''.join(html_translator.fragment).strip()
|
html_translated = ''.join(html_translator.fragment).strip()
|
||||||
@ -237,6 +239,32 @@ def get_verifier(verify, verify_re):
|
|||||||
'<p><kbd class="kbd docutils literal notranslate">space</kbd></p>',
|
'<p><kbd class="kbd docutils literal notranslate">space</kbd></p>',
|
||||||
'\\sphinxkeyboard{\\sphinxupquote{space}}',
|
'\\sphinxkeyboard{\\sphinxupquote{space}}',
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
# kbd role
|
||||||
|
'verify',
|
||||||
|
':kbd:`Control+X`',
|
||||||
|
('<p><kbd class="kbd docutils literal notranslate">'
|
||||||
|
'<kbd class="kbd docutils literal notranslate">Control</kbd>'
|
||||||
|
'+'
|
||||||
|
'<kbd class="kbd docutils literal notranslate">X</kbd>'
|
||||||
|
'</kbd></p>'),
|
||||||
|
'\\sphinxkeyboard{\\sphinxupquote{Control+X}}',
|
||||||
|
),
|
||||||
|
(
|
||||||
|
# kbd role
|
||||||
|
'verify',
|
||||||
|
':kbd:`M-x M-s`',
|
||||||
|
('<p><kbd class="kbd docutils literal notranslate">'
|
||||||
|
'<kbd class="kbd docutils literal notranslate">M</kbd>'
|
||||||
|
'-'
|
||||||
|
'<kbd class="kbd docutils literal notranslate">x</kbd>'
|
||||||
|
' '
|
||||||
|
'<kbd class="kbd docutils literal notranslate">M</kbd>'
|
||||||
|
'-'
|
||||||
|
'<kbd class="kbd docutils literal notranslate">s</kbd>'
|
||||||
|
'</kbd></p>'),
|
||||||
|
'\\sphinxkeyboard{\\sphinxupquote{M\\sphinxhyphen{}x M\\sphinxhyphen{}s}}',
|
||||||
|
),
|
||||||
(
|
(
|
||||||
# non-interpolation of dashes in option role
|
# non-interpolation of dashes in option role
|
||||||
'verify_re',
|
'verify_re',
|
||||||
|
Loading…
Reference in New Issue
Block a user