2626
2727from sphinx .writers .html import HTMLTranslator
2828from docutils .transforms import Transform
29+ from docutils .parsers .rst import Directive
2930import docutils .nodes as nodes
3031
3132import numpy as np
@@ -215,7 +216,6 @@ def autodoc_process_docstring(app, what, name, obj, options, lines):
215216 docs = {
216217 "abbreviation" : MM_QUALIFIERS_DOCUMENTATION ["abbreviation" ],
217218 "conjugate" : MM_QUALIFIERS_DOCUMENTATION ["conjugate" ],
218- "transpose" : MM_QUALIFIERS_DOCUMENTATION ["transpose" ],
219219 "uplo" : MM_QUALIFIERS_DOCUMENTATION ["uplo" ],
220220 "diag" : MM_QUALIFIERS_DOCUMENTATION ["diag" ],
221221 "incx" : MM_QUALIFIERS_DOCUMENTATION ["incx" ],
@@ -312,6 +312,72 @@ def default_departure(self, node):
312312 default_priority = 800
313313
314314
315+ class ExperimentalDirective (Directive ):
316+ """
317+ Custom admonition for marking experimental APIs.
318+
319+ Usage in docstrings:
320+ .. experimental:: method # specify the API type
321+ .. experimental:: function
322+ .. experimental:: class
323+ .. experimental:: parameter
324+
325+ This creates a warning admonition with the standard experimental text.
326+ Note: this admonition is automatically detected by the mark_experimental_apis function,
327+ which adds the 'experimental' CSS class to the method/function/class.
328+ """
329+
330+ # Directive does not expect indented content below it (e.g., no text block)
331+ has_content = False
332+ # Requires exactly one argument: the API type (see above)
333+ required_arguments = 1
334+ # No optional arguments allowed
335+ optional_arguments = 0
336+
337+ def run (self ):
338+ # Get the API type from argument or default to "method"
339+ api_type = self .arguments [0 ]
340+ assert api_type in ["method" , "function" , "class" , "parameter" ], "Invalid API type"
341+
342+ text = f"This { api_type } is experimental and potentially subject to future changes."
343+ # Create a simple container div to inline the experimental text
344+ container = nodes .container ()
345+ container += nodes .paragraph ("" , text )
346+ container ["classes" ].append ("experimental-marker" )
347+ return [container ]
348+
349+
350+ def mark_experimental_apis (app , doctree , docname ):
351+ """
352+ Add 'experimental' CSS class to any method/function/class that contains
353+ the .. experimental:: directive.
354+
355+ This runs on the 'doctree-resolved' event, after the doctree is fully built.
356+ """
357+ from sphinx import addnodes
358+
359+ for desc_node in doctree .traverse (addnodes .desc ):
360+ # Get the desc_content child (the docstring content)
361+ desc_content_nodes = [n for n in desc_node .children if isinstance (n , addnodes .desc_content )]
362+
363+ if not desc_content_nodes :
364+ continue
365+
366+ content_node = desc_content_nodes [0 ]
367+
368+ # Check only direct child nodes of desc_content, skipping nested desc nodes
369+ for child in content_node .children :
370+ # Skip nested desc nodes entirely
371+ if isinstance (child , addnodes .desc ):
372+ continue
373+
374+ # Check if this child has the experimental-marker class
375+ # (from .. experimental:: directive)
376+ if "experimental-marker" in child .get ("classes" , []):
377+ desc_node ["classes" ].append ("experimental" )
378+ break
379+
380+
315381class NotebookHandler :
316382 def __init__ (self ):
317383 self .tmpdir = tempfile .mkdtemp ()
@@ -347,8 +413,18 @@ def remove_notebook_copyright(self, app, docname, content):
347413def setup (app ):
348414 fixup_internal_alias ()
349415 app .add_css_file ("nvmath_override.css" )
416+ app .add_directive ("experimental" , ExperimentalDirective )
350417 app .connect ("autodoc-process-docstring" , autodoc_process_docstring )
351418 app .connect ("source-read" , lambda * args , ** kwargs : notebook_handler .remove_notebook_copyright (* args , ** kwargs ))
419+
420+ # Connect the experimental API marker to the doctree-resolved event.
421+ # doctree-resolved fires after the doc tree is fully built and
422+ # cross-references are resolved, allowing us to safely traverse and
423+ # modify nodes before HTML generation.
424+ # This detects methods/functions/classes with the "experimental-marker"
425+ # and adds the 'experimental' CSS class for styling (orange border).
426+ app .connect ("doctree-resolved" , mark_experimental_apis )
427+
352428 app .set_translator ("html" , DotBreakHtmlTranslator )
353429 app .add_autodocumenter (PatchedEnumDocumenter , override = True )
354430 app .add_post_transform (UnqualifiedTitlesTransform )
@@ -374,7 +450,7 @@ def fixup_internal_alias():
374450 "nvmath.device.FFT" : "nvmath.device.FFT-class" ,
375451 "nvmath.device.Matmul" : "nvmath.device.Matmul-class" ,
376452 "nvmath.linalg.advanced.Matmul" : "nvmath.linalg.advanced.Matmul-class" ,
377- "nvmath.linalg.generic. Matmul" : "nvmath.linalg.generic .Matmul-class" ,
453+ "nvmath.linalg.Matmul" : "nvmath.linalg.Matmul-class" ,
378454 "nvmath.distributed.linalg.advanced.Matmul" : "nvmath.distributed.linalg.advanced.Matmul-class" ,
379455 "nvmath.distributed.fft.FFT" : "nvmath.distributed.fft.FFT-class" ,
380456 "nvmath.distributed.reshape.Reshape" : "nvmath.distributed.reshape.Reshape-class" ,
0 commit comments