diff --git a/doc/source/_static/numpy.css b/doc/source/_static/numpy.css index bc84d02dbeea..4a489474d9d7 100644 --- a/doc/source/_static/numpy.css +++ b/doc/source/_static/numpy.css @@ -136,3 +136,22 @@ html[data-theme=dark] h1 { html[data-theme=dark] h3 { color: #0a6774; } + +/* Legacy admonition */ + +div.admonition-legacy { + border-color: var(--pst-color-warning); +} + +.admonition-legacy.admonition>.admonition-title::before, +div.admonition>.admonition-title::before { + color: var(--pst-color-warning); + content: var(--pst-icon-admonition-attention); + background-color: var(--pst-color-warning); +} + +.admonition-legacy.admonition>.admonition-title::after, +div.admonition>.admonition-title::after { + color: var(--pst-color-warning); + content: var(--pst-icon-admonition-default); +} \ No newline at end of file diff --git a/doc/source/conf.py b/doc/source/conf.py index cde67f4b0bb1..3214bbb548c8 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -2,6 +2,8 @@ import re import sys import importlib +from docutils import nodes +from docutils.parsers.rst import Directive # Minimum version, enforced by sphinx needs_sphinx = '4.3' @@ -152,10 +154,64 @@ class PyTypeObject(ctypes.Structure): # output. They are ignored by default. #show_authors = False +class LegacyDirective(Directive): + """ + Adapted from docutils/parsers/rst/directives/admonitions.py + + Uses a default text if the directive does not have contents. If it does, + the default text is concatenated to the contents. + + See also the same implementation in SciPy's conf.py. + """ + has_content = True + node_class = nodes.admonition + optional_arguments = 1 + + def run(self): + try: + obj = self.arguments[0] + except IndexError: + # Argument is empty; use default text + obj = "submodule" + text = (f"This {obj} is considered legacy and will no longer receive " + "updates. This could also mean it will be removed in future " + "NumPy versions.") + + try: + self.content[0] = text+" "+self.content[0] + except IndexError: + # Content is empty; use the default text + source, lineno = self.state_machine.get_source_and_line( + self.lineno + ) + self.content.append( + text, + source=source, + offset=lineno + ) + text = '\n'.join(self.content) + # Create the admonition node, to be populated by `nested_parse` + admonition_node = self.node_class(rawsource=text) + # Set custom title + title_text = "Legacy" + textnodes, _ = self.state.inline_text(title_text, self.lineno) + title = nodes.title(title_text, '', *textnodes) + # Set up admonition node + admonition_node += title + # Select custom class for CSS styling + admonition_node['classes'] = ['admonition-legacy'] + # Parse the directive contents + self.state.nested_parse(self.content, self.content_offset, + admonition_node) + return [admonition_node] + + def setup(app): # add a config value for `ifconfig` directives app.add_config_value('python_version_major', str(sys.version_info.major), 'env') app.add_lexer('NumPyC', NumPyLexer) + app.add_directive("legacy", LegacyDirective) + # While these objects do have type `module`, the names are aliases for modules # elsewhere. Sphinx does not support referring to modules by an aliases name, diff --git a/doc/source/dev/howto-docs.rst b/doc/source/dev/howto-docs.rst index 8e1d957a8bf3..c07724e70f0a 100644 --- a/doc/source/dev/howto-docs.rst +++ b/doc/source/dev/howto-docs.rst @@ -429,6 +429,42 @@ for more details and to see it in action. .. _`Breathe`: https://breathe.readthedocs.io/en/latest/ +Legacy directive +================ + +If a function, module or API is in *legacy* mode, meaning that it is kept around +for backwards compatibility reasons, but is not recommended to use in new code, +you can use the ``.. legacy::`` directive. + +By default, if used with no arguments, the legacy directive will generate the +following output: + +.. legacy:: + + +We strongly recommend that you also add a custom message, such as a new API to +replace the old one:: + + .. legacy:: + + For more details, see :ref:`distutils-status-migration`. + +This message will be appended to the default message and will create the +following output: + +.. legacy:: + + For more details, see :ref:`distutils-status-migration`. + +Finally, if you want to mention a function, method (or any custom object) +instead of a *submodule*, you can use an optional argument:: + + .. legacy:: function + +This will create the following output: + +.. legacy:: function + ********************* Documentation reading *********************