Skip to content

Support block-specific style overrides #13611

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f541c9f
Working protype!
hmedina May 10, 2025
95ef08b
Media queries for light or dark style
hmedina May 13, 2025
39cc441
Merge branch 'sphinx-doc:master' into master
hmedina May 13, 2025
e2a6e04
Merge branch 'sphinx-doc:master' into master
hmedina May 29, 2025
b5c34d2
Unify pygments.css and pygments_dark.css
hmedina May 29, 2025
33a2183
Revert "Unify pygments.css and pygments_dark.css"
hmedina May 29, 2025
cac1808
Use separate style sheets; leave media queries out
hmedina May 29, 2025
a96870f
Fix `singlehtml` builder
hmedina May 30, 2025
3b2d3c9
Remove unnecessary parenthesis
hmedina May 30, 2025
6eebcf9
Add LaTeX builder
hmedina May 30, 2025
6aa37f4
Merge branch 'sphinx-doc:master' into master
hmedina Jun 2, 2025
5c2d244
Lint & style with Ruff
hmedina Jun 2, 2025
37a018f
Provide usage examples in docs for new directive options
hmedina Jun 2, 2025
a83b6af
Merge branch 'sphinx-doc:master' into master
hmedina Jun 2, 2025
a26d133
Add name to contributor list
hmedina Jun 2, 2025
957a5ee
Merge branch 'master' into master
hmedina Jun 3, 2025
349e051
Sphinx-lint; remove trailing whitespaces
hmedina Jun 3, 2025
e1a7929
Bugfix: fetcher of PygmentsBridge objects from string had wrong param…
hmedina Jun 3, 2025
5bc8dbf
Properly catch Nones; pass `mypy`
hmedina Jun 3, 2025
ae62908
Ruff, round 2
hmedina Jun 3, 2025
a8ac128
Ruff, formatting
hmedina Jun 3, 2025
0c3d5a7
Fix MyPy ?
hmedina Jun 3, 2025
b2b9c34
Merge remote-tracking branch 'upstream/master'
hmedina Jun 12, 2025
fa2a798
Fix docs-lint; line too long after adding PR number
hmedina Jun 12, 2025
35f782c
"sanitize" LaTeX command prefix from user-specified style
hmedina Jun 14, 2025
7fab81e
Fix ruff format?
hmedina Jun 14, 2025
4b09baa
LaTeX: fix style arg lacking, refactor to achieve full LaTeX support
jfbu Jun 15, 2025
3a7d4a6
Merge branch 'master' into multistyle
jfbu Jun 17, 2025
27b5239
Remove left-over curly brace pairs in LaTeX code in highlighting.py
jfbu Jun 17, 2025
901a5de
Merge branch 'sphinx-doc:master' into master
hmedina Jun 19, 2025
83932f7
Simplify LaTeX code
hmedina Jun 19, 2025
f5d5178
Simplify HTML code
hmedina Jun 19, 2025
37fabbe
LaTeX: implement support for custom background color
jfbu Jun 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
@@ -58,6 +58,7 @@ Contributors
* Filip Vavera -- napoleon todo directive
* Glenn Matthews -- python domain signature improvements
* Gregory Szorc -- performance improvements
* Héctor Medina Abarca -- per-code-block highlighting style overrides
* Henrique Bastos -- SVG support for graphviz extension
* Hernan Grecco -- search improvements
* Hong Xu -- svg support in imgmath extension and various bug fixes
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -54,6 +54,11 @@ Features added
Patch by Adam Turner.
* #13647: LaTeX: allow more cases of table nesting.
Patch by Jean-François B.
* #13611: Allow `Pygments style <https://pygments.org/styles/>`_ overriding on a
per-block basis via new options (:rst:dir:`code-block:style-light` and
:rst:dir:`code-block:style-dark`) for the :rst:dir:`code-block`,
:rst:dir:`sourcecode`, :rst:dir:`literalinclude` and :rst:dir:`code`.
Patch by Héctor Medina Abarca.

Bugs fixed
----------
55 changes: 51 additions & 4 deletions doc/usage/restructuredtext/directives.rst
Original file line number Diff line number Diff line change
@@ -728,13 +728,15 @@ values are supported:
* ... and any other `lexer alias that Pygments supports`__

If highlighting with the selected language fails (i.e. Pygments emits an
"Error" token), the block is not highlighted in any way.
"Error" token), the block is not highlighted in any way. Per-block highlighting
styles can be specified for directives :rst:dir:`code-block`,
:rst:dir:`sourcecode`, :rst:dir:`literalinclude`, and :rst:dir:`code`.

.. important::

The list of lexer aliases supported is tied to the Pygment version. If you
want to ensure consistent highlighting, you should fix your version of
Pygments.
The list of lexer and style aliases supported is tied to the Pygment
version. If you want to ensure consistent highlighting, you should fix your
version of Pygments.

__ https://pygments.org/docs/lexers

@@ -903,6 +905,51 @@ __ https://pygments.org/docs/lexers
.. versionchanged:: 3.5
Support automatic dedent.
.. rst:directive:option:: style-light: style name
style-dark: style name
:type: the name of a style to use
Pygments includes `various highlighting styles
<https://pygments.org/styles/>`_, and supports `custom ones
<https://pygments.org/docs/styledevelopment/>`_ installed as
plugins. This option accepts any valid style name and will apply it to
this code block, overriding any default in :confval:`pygments_style`
config value. Some builder and theme configurations (e.g.
:ref:`HTML <builders>` & `Python Docs Theme <https://pypi.org/project/python-docs-theme/>`_) will
accept both `light` and `dark` options, and switch appropriately; others
may support only one style (e.g. PDF), in which case `style-light` takes
precedence. For example::
.. code-block:: python
print('Code with default styling')
Renders as:
.. code-block:: python
print('Code with default styling')
While this code::
.. code-block:: python
:style-light: tango
print('Code with a style override')
Renders as:
.. code-block:: python
:style-light: tango
print('Code with a style override')
.. versionadded:: 8.3
.. rst:directive:: .. literalinclude:: filename
Longer displays of verbatim text may be included by storing the example text
81 changes: 73 additions & 8 deletions sphinx/builders/html/__init__.py
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@

if TYPE_CHECKING:
from collections.abc import Iterator, Set
from typing import Any, TypeAlias
from typing import Any, TypeAlias, TypedDict

from docutils.nodes import Node
from docutils.readers import Reader
@@ -262,6 +262,19 @@ def init_highlighter(self) -> None:
else:
self.dark_highlighter = None

# Maps a code block's identifier to requested light and dark styles.
# This is populated by the writer / translator as it invokes
# the visit_literal_block method.
# The information is also used in the selectors of the CSS file(s).
if TYPE_CHECKING:

class spec_highlighter(TypedDict):
bridge: PygmentsBridge
ids: list[int]

self.specialized_dark_lighters: dict[str, spec_highlighter] = {}
self.specialized_light_lighters: dict[str, spec_highlighter] = {}

@property
def css_files(self) -> list[_CascadingStyleSheet]:
_deprecation_warning(
@@ -691,6 +704,7 @@ def write_doc_serialized(self, docname: str, doctree: nodes.document) -> None:
self.index_page(docname, doctree, title)

def finish(self) -> None:
self.finish_tasks.add_task(self.create_pygments_style_file)
self.finish_tasks.add_task(self.gen_indices)
self.finish_tasks.add_task(self.gen_pages_from_extensions)
self.finish_tasks.add_task(self.gen_additional_pages)
@@ -827,16 +841,68 @@ def to_relpath(f: str) -> str:
err,
)

def update_override_styles_dark(self, style: str, id: int) -> PygmentsBridge:
"""Update the tracker of highlighting styles with a possibly new dark-mode style;
return the PygmentsBridge object associated with said style.
"""
if style in self.specialized_dark_lighters:
self.specialized_dark_lighters[style]['ids'].append(id)
else:
pb = PygmentsBridge(dest='html', stylename=style)
self.specialized_dark_lighters[style] = {'bridge': pb, 'ids': [id]}
return self.specialized_dark_lighters[style]['bridge']

def update_override_styles_light(self, style: str, id: int) -> PygmentsBridge:
"""Update the tracker of highlighting styles with a possibly new light-mode style;
return the PygmentsBridge object associated with said style.
"""
if style in self.specialized_light_lighters:
self.specialized_light_lighters[style]['ids'].append(id)
else:
pb = PygmentsBridge(dest='html', stylename=style)
self.specialized_light_lighters[style] = {'bridge': pb, 'ids': [id]}
return self.specialized_light_lighters[style]['bridge']

def create_pygments_style_file(self) -> None:
"""Create a style file for pygments."""
"""Create style file(s) for Pygments."""
pyg_path = self._static_dir / 'pygments.css'
with open(pyg_path, 'w', encoding='utf-8') as f:
f.write(self.highlighter.get_stylesheet())
light_style = self.highlighter.formatter_args.get('style')
if light_style is None:
logger.warning(__('Default highlighter has no set style'))
else:
with open(pyg_path, 'w', encoding='utf-8') as f:
light_style_name = light_style.name
light_style_sheet = '/* CSS for style: {} */\n'.format(light_style_name)
light_style_sheet += self.highlighter.get_stylesheet()
if self.specialized_light_lighters:
for s_name, item in self.specialized_light_lighters.items():
light_style_sheet += '\n\n/* CSS for style: {} */\n'.format(
s_name
)
light_style_sheet += item['bridge'].get_stylesheet(item['ids'])
f.write(light_style_sheet)

if self.dark_highlighter:
dark_path = self._static_dir / 'pygments_dark.css'
with open(dark_path, 'w', encoding='utf-8') as f:
f.write(self.dark_highlighter.get_stylesheet())
dark_style = self.dark_highlighter.formatter_args.get('style')
if dark_style is None:
logger.warning(__('Default dark highlighter has no set style'))
else:
dark_path = self._static_dir / 'pygments_dark.css'
with open(dark_path, 'w', encoding='utf-8') as f:
dark_style_name = dark_style.name
dark_style_sheet = '/* CSS for style: {} */\n'.format(
dark_style_name
)
dark_style_sheet += self.dark_highlighter.get_stylesheet()
if self.specialized_dark_lighters:
for s_name, item in self.specialized_dark_lighters.items():
dark_style_sheet += '\n\n/* CSS for style: {} */\n'.format(
s_name
)
dark_style_sheet += item['bridge'].get_stylesheet(
item['ids']
)
f.write(dark_style_sheet)

def copy_translation_js(self) -> None:
"""Copy a JavaScript file for translations."""
@@ -930,7 +996,6 @@ def copy_static_files(self) -> None:
if self.indexer is not None:
context.update(self.indexer.context_for_searchtool())

self.create_pygments_style_file()
self.copy_translation_js()
self.copy_stemmer_js()
self.copy_theme_static_files(context)
26 changes: 23 additions & 3 deletions sphinx/builders/latex/__init__.py
Original file line number Diff line number Diff line change
@@ -130,6 +130,7 @@ def init(self) -> None:
self.docnames: Iterable[str] = {}
self.document_data: list[tuple[str, str, str, str, str, bool]] = []
self.themes = ThemeFactory(srcdir=self.srcdir, config=self.config)
self.specialized_highlighters: dict[str, highlighting.PygmentsBridge] = {}
texescape.init()

self.init_context()
@@ -272,23 +273,41 @@ def init_multilingual(self) -> None:

self.context['multilingual'] = f'{self.context["polyglossia"]}\n{language}'

def update_override_styles(self, style: str) -> highlighting.PygmentsBridge:
"""Update the tracker of highlighting styles with a possibly new style;
return the PygmentsBridge object associated with said style.
"""
if style in self.specialized_highlighters:
return self.specialized_highlighters[style]
else:
pb = highlighting.PygmentsBridge(dest='latex', stylename=style)
self.specialized_highlighters[style] = pb
return pb

def write_stylesheet(self) -> None:
highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style)
stylesheet = self.outdir / 'sphinxhighlight.sty'
with open(stylesheet, 'w', encoding='utf-8') as f:
f.write('\\NeedsTeXFormat{LaTeX2e}[1995/12/01]\n')
f.write(
'\\ProvidesPackage{sphinxhighlight}'
'[2022/06/30 stylesheet for highlighting with pygments]\n'
'[2025/06/15 stylesheet for highlighting with pygments]\n'
)
f.write(
'% Its contents depend on pygments_style configuration variable.\n\n'
'% Its contents depend on pygments_style configuration variable.\n'
'% And also on encountered code-blocks :style-light: options.\n\n'
)
f.write(highlighter.get_stylesheet())
if self.specialized_highlighters:
specialized_styles = []
for style_name, pyg_bridge in self.specialized_highlighters.items():
specialized_style = '\n% Stylesheet for style {}'.format(style_name)
specialized_style += pyg_bridge.get_stylesheet(style_name)
specialized_styles.append(specialized_style)
f.write('\n'.join(specialized_styles))

def prepare_writing(self, docnames: Set[str]) -> None:
self.init_document_data()
self.write_stylesheet()

def copy_assets(self) -> None:
self.copy_support_files()
@@ -413,6 +432,7 @@ def assemble_doctree(
return largetree

def finish(self) -> None:
self.write_stylesheet()
self.copy_image_files()
self.write_message_catalog()

1 change: 1 addition & 0 deletions sphinx/builders/singlehtml.py
Original file line number Diff line number Diff line change
@@ -182,6 +182,7 @@ def finish(self) -> None:
self.copy_image_files()
self.copy_download_files()
self.copy_static_files()
self.create_pygments_style_file()
self.copy_extra_files()
self.write_buildinfo()
self.dump_inventory()
8 changes: 8 additions & 0 deletions sphinx/directives/code.py
Original file line number Diff line number Diff line change
@@ -114,6 +114,8 @@ class CodeBlock(SphinxDirective):
'caption': directives.unchanged_required,
'class': directives.class_option,
'name': directives.unchanged,
'style-light': directives.unchanged,
'style-dark': directives.unchanged,
}

def run(self) -> list[Node]:
@@ -162,6 +164,8 @@ def run(self) -> list[Node]:
self.env.current_document.highlight_language
or self.config.highlight_language
)
literal['style-light'] = self.options.get('style-light')
literal['style-dark'] = self.options.get('style-dark')
extra_args = literal['highlight_args'] = {}
if hl_lines is not None:
extra_args['hl_lines'] = hl_lines
@@ -425,6 +429,8 @@ class LiteralInclude(SphinxDirective):
'lineno-match': directives.flag,
'tab-width': int,
'language': directives.unchanged_required,
'style-light': directives.unchanged,
'style-dark': directives.unchanged,
'force': directives.flag,
'encoding': directives.encoding,
'pyobject': directives.unchanged_required,
@@ -468,6 +474,8 @@ def run(self) -> list[Node]:
retnode['language'] = 'udiff'
elif 'language' in self.options:
retnode['language'] = self.options['language']
retnode['style-light'] = self.options.get('style-light')
retnode['style-dark'] = self.options.get('style-dark')
if (
'linenos' in self.options
or 'lineno-start' in self.options
5 changes: 5 additions & 0 deletions sphinx/directives/patches.py
Original file line number Diff line number Diff line change
@@ -93,6 +93,8 @@ class Code(SphinxDirective):
'class': directives.class_option,
'force': directives.flag,
'name': directives.unchanged,
'style-light': directives.unchanged,
'style-dark': directives.unchanged,
'number-lines': optional_int,
}
has_content = True
@@ -124,6 +126,9 @@ def run(self) -> list[Node]:
or self.config.highlight_language
)

node['style-light'] = self.options.get('style-light')
node['style-dark'] = self.options.get('style-dark')

if 'number-lines' in self.options:
node['linenos'] = True

101 changes: 96 additions & 5 deletions sphinx/highlighting.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,9 @@

from __future__ import annotations

import re
from functools import partial
from hashlib import md5
from importlib import import_module
from typing import TYPE_CHECKING

@@ -20,6 +22,7 @@
guess_lexer,
)
from pygments.styles import get_style_by_name
from pygments.token import Token
from pygments.util import ClassNotFound

from sphinx.locale import __
@@ -90,7 +93,9 @@
\def\PYGZti{\text\textasciitilde}
\makeatletter
% use \protected to allow syntax highlighting in captions
\protected\def\PYG#1#2{\PYG@reset\PYG@toks#1+\relax+{\PYG@do{#2}}}
\def\PYG@#1#2{{\PYG@reset\PYG@toks#1+\relax+{{\PYG@do{{#2}}}}}}
\protected\def\PYG{\csname PYG\ifdefined\sphinxpygmentsstylename
\sphinxpygmentsstylename\else @\fi\endcsname}
\makeatother
"""

@@ -229,9 +234,95 @@ def highlight_block(
# MEMO: this is done to escape Unicode chars with non-Unicode engines
return texescape.hlescape(hlsource, self.latex_engine)

def get_stylesheet(self) -> str:
def get_stylesheet(self, selectors: list[int] | str | None = None) -> str:
"""Return a string with the specification for the tokens yielded by the language
lexer, appropriate for the output formatter, using the style defined at
initialization. In an HTML context, `selectors` is a list of CSS class selectors. In a
LaTeX context, it modifies the command prefix used for macro definitions; see also
LaTeXBuilder.add_block_style()
"""
formatter = self.get_formatter()
if self.dest == 'html':
return formatter.get_style_defs('.highlight')
if isinstance(formatter, HtmlFormatter):
if selectors:
return formatter.get_style_defs(['.c{}'.format(s) for s in selectors]) # type: ignore [no-untyped-call]
else:
return formatter.get_style_defs('.highlight') # type: ignore [no-untyped-call]
else:
return formatter.get_style_defs() + _LATEX_ADD_STYLES
if selectors:
if not isinstance(selectors, str):
logger.error(
__(
'Encountered %s in selectors field; expected a string '
'for the LaTeX formatter. Please report this error.'
),
type(selectors),
type='misc',
subtype='highlighting_failure',
)
# not using '' as we don't want \PYG being overwritten.
_tex_name = 'INVALID'
selectors = 'default' # TODO: make more informed choice?
_tex_name = md5(selectors.encode()).hexdigest()[:6] # noqa: S324
for d, l in [
('0', 'G'),
('1', 'H'),
('2', 'I'),
('3', 'J'),
('4', 'K'),
('5', 'L'),
('6', 'M'),
('7', 'N'),
('8', 'O'),
('9', 'P'),
]:
_tex_name = _tex_name.replace(d, l)
stylesheet = self.formatter(
style=selectors, commandprefix='PYG' + _tex_name
).get_style_defs()
sphinx_redefs = ''
bc = self.get_style(selectors).background_color
if bc is not None:
bc = bc.lstrip('#').lower()
# The xcolor LaTeX package requires 6 hexadecimal digits
if len(bc) == 3:
bc = bc[0] * 2 + bc[1] * 2 + bc[2] * 2
# We intercept a purely white background, so that PDF will use Sphinx
# light gray default, rather, or the user VerbatimColor global choice.
# TODO: argue pros and cons.
if bc != 'ffffff':
sphinx_redefs = (
'% background color for above style, "HTML" syntax\n'
f'\\def\\sphinxPYG{_tex_name}bc{{{bc}}}\n'
)
# TODO: THIS MAY NOT BE THE RIGHT THING TO DO.
# TODO: REMOVE NEXT COMMENTS.
# I wanted to try with
# solarized-light which will use #657b83 but my sample code-block
# has no token not using a color so I could not confirm it does work.
# (indeed solarized-light uses \textcolor everywhere in its stylesheet,
# so I modified manually LaTeX output to confirm the whole thing
# actually worked as expected).
# I have not for lack of time searched for a pygments style defining
# such a color and not using \textcolor everywhere.
# The idea is to avoid invisible text on dark background which I believe
# I have experienced in the past when using dark background via injection
# of \sphinxsetup using raw:: latex directive.
base_style = self.get_style(selectors).styles[Token]
if base_style: # could look like 'italic #000 bg:#ffffff'
match = re.match(
r'#([0-9a-fA-F]{3,6})(?:\s+bg:#([0-9a-fA-F]{3,6}))?', base_style
)
if match is not None:
tc = match.group(1)
if len(tc) == 3:
tc = tc[0] * 2 + tc[1] * 2 + tc[2] * 2
sphinx_redefs += (
'% text default color for above style, "HTML" syntax\n'
f'\\def\\sphinxPYG{_tex_name}tc{{{tc}}}\n'
)
# TODO: what should we do for the color used to emphasize lines?
# It is VerbatimHightlightColor.
else:
stylesheet = formatter.get_style_defs()
sphinx_redefs = _LATEX_ADD_STYLES
return stylesheet + sphinx_redefs
45 changes: 37 additions & 8 deletions sphinx/writers/html5.py
Original file line number Diff line number Diff line change
@@ -600,14 +600,43 @@ def visit_literal_block(self, node: nodes.literal_block) -> None:
if linenos and self.config.html_codeblock_linenos_style:
linenos = self.config.html_codeblock_linenos_style

highlighted = self.highlighter.highlight_block(
node.rawsource,
lang,
opts=opts,
linenos=linenos,
location=node,
**highlight_args,
)
# As blocks are processed, we discover specified styles.
# If either dark or style were requested, use their specialized
# highlighter. If neither, use the default highlighter.
block_id = hash(node)
dark_style = node.get('style-dark', None)
light_style = node.get('style-light', None)
if dark_style:
pb = self.builder.update_override_styles_dark(dark_style, block_id)
highlighted = pb.highlight_block(
node.rawsource,
lang,
opts=opts,
linenos=linenos,
location=node,
cssclass='highlight c{}'.format(block_id),
**highlight_args,
)
if light_style:
pb = self.builder.update_override_styles_light(light_style, block_id)
highlighted = pb.highlight_block(
node.rawsource,
lang,
opts=opts,
linenos=linenos,
location=node,
cssclass='highlight c{}'.format(block_id),
**highlight_args,
)
if not (dark_style or light_style):
highlighted = self.highlighter.highlight_block(
node.rawsource,
lang,
opts=opts,
linenos=linenos,
location=node,
**highlight_args,
)
starttag = self.starttag(
node, 'div', suffix='', CLASS='highlight-%s notranslate' % lang
)
62 changes: 54 additions & 8 deletions sphinx/writers/latex.py
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@

import re
from collections import defaultdict
from hashlib import md5
from pathlib import Path
from typing import TYPE_CHECKING, cast

@@ -2257,14 +2258,57 @@ def visit_literal_block(self, node: Element) -> None:
highlight_args['force'] = node.get('force', False)
opts = self.config.highlight_options.get(lang, {})

hlcode = self.highlighter.highlight_block(
node.rawsource,
lang,
opts=opts,
linenos=linenos,
location=node,
**highlight_args,
)
# As blocks are processed, we discover specified styles.
_texstylename = ''
if node.get('style-light'):
code_style = node.get('style-light')
pb = self.builder.update_override_styles(style=code_style)
hlcode = pb.highlight_block(
node.rawsource,
lang,
opts=opts,
linenos=linenos,
location=node,
**highlight_args,
)
_texstylename = md5(code_style.encode()).hexdigest()[:6] # noqa: S324
for d, l in [
('0', 'G'),
('1', 'H'),
('2', 'I'),
('3', 'J'),
('4', 'K'),
('5', 'L'),
('6', 'M'),
('7', 'N'),
('8', 'O'),
('9', 'P'),
]:
_texstylename = _texstylename.replace(d, l)
else:
hlcode = self.highlighter.highlight_block(
node.rawsource,
lang,
opts=opts,
linenos=linenos,
location=node,
**highlight_args,
)
if _texstylename:
# There is no a priori "VerbatimTextColor" set, except is user employed
# the sphinxsetup with pre_TeXcolor. We could query the TeX boolean
# ifspx@opt@pre@withtextcolor but the @ letter is annoying here. So
# let's simply add a group level and not worry about testing if this
# or other things pre-exist so we don't have to reset.
self.body.append(
f'{CR}\\begingroup\\def\\sphinxpygmentsstylename{{{_texstylename}}}%'
f'{CR}\\ifdefined\\sphinxPYG{_texstylename}bc'
f'{CR} \\sphinxsetup{{VerbatimColor={{HTML}}'
f'{{\\sphinxPYG{_texstylename}bc}}}}%{CR}\\fi'
f'{CR}\\ifdefined\\sphinxPYG{_texstylename}tc'
f'{CR} \\sphinxsetup{{pre_TeXcolor={{HTML}}'
f'{{\\sphinxPYG{_texstylename}tc}}}}%{CR}\\fi'
)
if self.in_footnote:
self.body.append(CR + r'\sphinxSetupCodeBlockInFootnote')
hlcode = hlcode.replace(r'\begin{Verbatim}', r'\begin{sphinxVerbatim}')
@@ -2291,6 +2335,8 @@ def visit_literal_block(self, node: Element) -> None:
self.body.append(CR + hlcode + CR)
if hllines:
self.body.append(r'\sphinxresetverbatimhllines' + CR)
if _texstylename:
self.body.append(r'\endgroup' + CR)
raise nodes.SkipNode

def depart_literal_block(self, node: Element) -> None: