2
2
3
3
from __future__ import annotations
4
4
5
+ import re
5
6
from functools import partial
6
7
from hashlib import md5
7
8
from importlib import import_module
21
22
guess_lexer ,
22
23
)
23
24
from pygments .styles import get_style_by_name
25
+ from pygments .token import Token
24
26
from pygments .util import ClassNotFound
25
27
26
28
from sphinx .locale import __
@@ -247,22 +249,7 @@ def get_stylesheet(self, selectors: list[int] | str | None = None) -> str:
247
249
return formatter .get_style_defs ('.highlight' ) # type: ignore [no-untyped-call]
248
250
else :
249
251
if selectors :
250
- if isinstance (selectors , str ):
251
- _tex_name = md5 (selectors .encode ()).hexdigest ()[:6 ] # noqa: S324
252
- for d , l in [
253
- ('0' , 'G' ),
254
- ('1' , 'H' ),
255
- ('2' , 'I' ),
256
- ('3' , 'J' ),
257
- ('4' , 'K' ),
258
- ('5' , 'L' ),
259
- ('6' , 'M' ),
260
- ('7' , 'N' ),
261
- ('8' , 'O' ),
262
- ('9' , 'P' ),
263
- ]:
264
- _tex_name = _tex_name .replace (d , l )
265
- else :
252
+ if not isinstance (selectors , str ):
266
253
logger .error (
267
254
__ (
268
255
'Encountered %s in selectors field; expected a string '
@@ -274,10 +261,67 @@ def get_stylesheet(self, selectors: list[int] | str | None = None) -> str:
274
261
)
275
262
# not using '' as we don't want \PYG being overwritten.
276
263
_tex_name = 'INVALID'
264
+ selectors = 'default' # TODO: make more informed choice?
265
+ _tex_name = md5 (selectors .encode ()).hexdigest ()[:6 ] # noqa: S324
266
+ for d , l in [
267
+ ('0' , 'G' ),
268
+ ('1' , 'H' ),
269
+ ('2' , 'I' ),
270
+ ('3' , 'J' ),
271
+ ('4' , 'K' ),
272
+ ('5' , 'L' ),
273
+ ('6' , 'M' ),
274
+ ('7' , 'N' ),
275
+ ('8' , 'O' ),
276
+ ('9' , 'P' ),
277
+ ]:
278
+ _tex_name = _tex_name .replace (d , l )
277
279
stylesheet = self .formatter (
278
280
style = selectors , commandprefix = 'PYG' + _tex_name
279
281
).get_style_defs ()
280
282
sphinx_redefs = ''
283
+ bc = self .get_style (selectors ).background_color
284
+ if bc is not None :
285
+ bc = bc .lstrip ('#' ).lower ()
286
+ # The xcolor LaTeX package requires 6 hexadecimal digits
287
+ if len (bc ) == 3 :
288
+ bc = bc [0 ] * 2 + bc [1 ] * 2 + bc [2 ] * 2
289
+ # We intercept a purely white background, so that PDF will use Sphinx
290
+ # light gray default, rather, or the user VerbatimColor global choice.
291
+ # TODO: argue pros and cons.
292
+ if bc != 'ffffff' :
293
+ sphinx_redefs = (
294
+ '% background color for above style, "HTML" syntax\n '
295
+ f'\\ def\\ sphinxPYG{ _tex_name } bc{{{ bc } }}\n '
296
+ )
297
+ # TODO: THIS MAY NOT BE THE RIGHT THING TO DO.
298
+ # TODO: REMOVE NEXT COMMENTS.
299
+ # I wanted to try with
300
+ # solarized-light which will use #657b83 but my sample code-block
301
+ # has no token not using a color so I could not confirm it does work.
302
+ # (indeed solarized-light uses \textcolor everywhere in its stylesheet,
303
+ # so I modified manually LaTeX output to confirm the whole thing
304
+ # actually worked as expected).
305
+ # I have not for lack of time searched for a pygments style defining
306
+ # such a color and not using \textcolor everywhere.
307
+ # The idea is to avoid invisible text on dark background which I believe
308
+ # I have experienced in the past when using dark background via injection
309
+ # of \sphinxsetup using raw:: latex directive.
310
+ base_style = self .get_style (selectors ).styles [Token ]
311
+ if base_style : # could look like 'italic #000 bg:#ffffff'
312
+ match = re .match (
313
+ r'#([0-9a-fA-F]{3,6})(?:\s+bg:#([0-9a-fA-F]{3,6}))?' , base_style
314
+ )
315
+ if match is not None :
316
+ tc = match .group (1 )
317
+ if len (tc ) == 3 :
318
+ tc = tc [0 ] * 2 + tc [1 ] * 2 + tc [2 ] * 2
319
+ sphinx_redefs += (
320
+ '% text default color for above style, "HTML" syntax\n '
321
+ f'\\ def\\ sphinxPYG{ _tex_name } tc{{{ tc } }}\n '
322
+ )
323
+ # TODO: what should we do for the color used to emphasize lines?
324
+ # It is VerbatimHightlightColor.
281
325
else :
282
326
stylesheet = formatter .get_style_defs ()
283
327
sphinx_redefs = _LATEX_ADD_STYLES
0 commit comments