44from docutils import nodes
55from docutils .parsers .rst import Directive , directives
66import sphinx
7+ from sphinx .errors import ConfigError , ExtensionError
78
89import matplotlib as mpl
910from matplotlib import _api , mathtext
@@ -52,11 +53,11 @@ def run(self):
5253
5354
5455# This uses mathtext to render the expression
55- def latex2png (latex , filename , fontset = 'cm' , fontsize = 10 ):
56+ def latex2png (latex , filename , fontset = 'cm' , fontsize = 10 , dpi = 100 ):
5657 with mpl .rc_context ({'mathtext.fontset' : fontset , 'font.size' : fontsize }):
5758 try :
5859 depth = mathtext .math_to_image (
59- f"${ latex } $" , filename , dpi = 100 , format = "png" )
60+ f"${ latex } $" , filename , dpi = dpi , format = "png" )
6061 except Exception :
6162 _api .warn_external (f"Could not render math expression { latex } " )
6263 depth = 0
@@ -74,10 +75,21 @@ def latex2html(node, source):
7475
7576 destdir = Path (setup .app .builder .outdir , '_images' , 'mathmpl' )
7677 destdir .mkdir (parents = True , exist_ok = True )
77- dest = destdir / f'{ name } .png'
7878
79+ dest = destdir / f'{ name } .png'
7980 depth = latex2png (latex , dest , fontset , fontsize = fontsize )
8081
82+ srcset = []
83+ for size in setup .app .config .mathmpl_srcset :
84+ filename = f'{ name } -{ size .replace ("." , "_" )} .png'
85+ latex2png (latex , destdir / filename , fontset , fontsize = fontsize ,
86+ dpi = 100 * float (size [:- 1 ]))
87+ srcset .append (
88+ f'{ setup .app .builder .imgpath } /mathmpl/{ filename } { size } ' )
89+ if srcset :
90+ srcset = (f'srcset="{ setup .app .builder .imgpath } /mathmpl/{ name } .png, ' +
91+ ', ' .join (srcset ) + '" ' )
92+
8193 if inline :
8294 cls = ''
8395 else :
@@ -88,12 +100,35 @@ def latex2html(node, source):
88100 style = ''
89101
90102 return (f'<img src="{ setup .app .builder .imgpath } /mathmpl/{ name } .png"'
91- f' { cls } { style } />' )
103+ f' { srcset } { cls } { style } />' )
104+
105+
106+ def _config_inited (app , config ):
107+ # Check for srcset hidpi images
108+ for i , size in enumerate (app .config .mathmpl_srcset ):
109+ if size [- 1 ] == 'x' : # "2x" = "2.0"
110+ try :
111+ float (size [:- 1 ])
112+ except ValueError :
113+ raise ConfigError (
114+ f'Invalid value for mathmpl_srcset parameter: { size !r} . '
115+ 'Must be a list of strings with the multiplicative '
116+ 'factor followed by an "x". e.g. ["2.0x", "1.5x"]' )
117+ else :
118+ raise ConfigError (
119+ f'Invalid value for mathmpl_srcset parameter: { size !r} . '
120+ 'Must be a list of strings with the multiplicative '
121+ 'factor followed by an "x". e.g. ["2.0x", "1.5x"]' )
92122
93123
94124def setup (app ):
95125 setup .app = app
96126 app .add_config_value ('mathmpl_fontsize' , 10.0 , True )
127+ app .add_config_value ('mathmpl_srcset' , [], True )
128+ try :
129+ app .connect ('config-inited' , _config_inited ) # Sphinx 1.8+
130+ except ExtensionError :
131+ app .connect ('env-updated' , lambda app , env : _config_inited (app , None ))
97132
98133 # Add visit/depart methods to HTML-Translator:
99134 def visit_latex_math_html (self , node ):
0 commit comments