1818from sphinx .writers .html5 import HTML5Translator
1919from .css_and_javascript_bundles import add_global_css
2020from .inline_icons import load_svg_into_builder_env , get_custom_icons
21+ from . import html_translator_mixin
2122
2223logger = getLogger (__name__ )
2324
2627
2728_CUSTOM_ADMONITIONS_KEY = "sphinx_immaterial_custom_admonitions"
2829
30+ # defaults used for version directives re-styling
31+ VERSION_DIR_STYLE = {
32+ "versionadded" : {"icon" : "material/alert-circle" , "color" : (72 , 138 , 87 )},
33+ "versionchanged" : {"icon" : "material/alert-circle" , "color" : (238 , 144 , 64 )},
34+ "deprecated" : {"icon" : "material/delete" , "color" : (203 , 70 , 83 )},
35+ }
36+
2937
3038class CustomAdmonitionConfig (pydantic .BaseModel ):
3139 """This data class validates the user's configuration value(s) in
@@ -146,6 +154,22 @@ def depart_admonition(self: HTML5Translator, node: Optional[nodes.Element] = Non
146154 HTML5Translator .depart_admonition = depart_admonition # type: ignore[assignment]
147155
148156
157+ @html_translator_mixin .override
158+ def visit_versionmodified (
159+ self : html_translator_mixin .HTMLTranslatorMixin ,
160+ node : sphinx .addnodes .versionmodified ,
161+ super_func : html_translator_mixin .BaseVisitCallback [
162+ sphinx .addnodes .versionmodified
163+ ],
164+ ) -> None :
165+ # similar to what the OG visitor does but with an added admonition class
166+ self .body .append (self .starttag (node , "div" , CLASSES = [node ["type" ], "admonition" ]))
167+ # do compatibility check for changes in Sphinx
168+ assert len (node ) >= 1 and isinstance (node [0 ], nodes .paragraph )
169+ # add admonition-title class to first paragraph
170+ node [0 ]["classes" ].append ("admonition-title" )
171+
172+
149173patch_visit_admonition ()
150174patch_depart_admonition ()
151175
@@ -257,7 +281,20 @@ def on_builder_inited(app: Sphinx):
257281 custom_admonitions : List [CustomAdmonitionConfig ] = getattr (
258282 config , "sphinx_immaterial_custom_admonitions"
259283 )
284+ custom_admonition_names = []
260285 for admonition in custom_admonitions :
286+ custom_admonition_names .append (admonition .name )
287+ if admonition .name in VERSION_DIR_STYLE : # if specific to version directives
288+ admonition .icon = load_svg_into_builder_env (
289+ app .builder ,
290+ admonition .icon
291+ or cast (str , VERSION_DIR_STYLE [admonition .name ]["icon" ]),
292+ )
293+ if admonition .color is None :
294+ admonition .color = cast (
295+ Tuple [int , int , int ], VERSION_DIR_STYLE [admonition .name ]["color" ]
296+ )
297+ continue # don't override the version directives
261298 app .add_directive (
262299 name = admonition .name ,
263300 cls = get_directive_class (
@@ -270,6 +307,18 @@ def on_builder_inited(app: Sphinx):
270307 admonition .name = nodes .make_id (admonition .name )
271308 if admonition .icon is not None :
272309 admonition .icon = load_svg_into_builder_env (app .builder , admonition .icon )
310+
311+ # add styles for sphinx directives versionadded, versionchanged, and deprecated
312+ for name , style in VERSION_DIR_STYLE .items ():
313+ if name in custom_admonition_names :
314+ continue # already handled above
315+ # add entries for default style of version directives
316+ version_dir_style = CustomAdmonitionConfig (
317+ name = name ,
318+ icon = load_svg_into_builder_env (app .builder , cast (str , style ["icon" ])),
319+ color = style ["color" ],
320+ )
321+ custom_admonitions .append (version_dir_style )
273322 setattr (app .builder .env , "sphinx_immaterial_custom_admonitions" , custom_admonitions )
274323
275324
0 commit comments