Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 826575f

Browse files
authored
Merge pull request #28472 from meeseeksmachine/auto-backport-of-pr-28289-on-v3.9.x
Backport PR #28289 on branch v3.9.x (Promote mpltype Sphinx role to a public extension)
2 parents cf6b1ca + 8709791 commit 826575f

File tree

8 files changed

+166
-92
lines changed

8 files changed

+166
-92
lines changed

doc/api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ Alphabetical list of modules:
126126
sphinxext_mathmpl_api.rst
127127
sphinxext_plot_directive_api.rst
128128
sphinxext_figmpl_directive_api.rst
129+
sphinxext_roles.rst
129130
spines_api.rst
130131
style_api.rst
131132
table_api.rst
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Documentation-specific custom Sphinx roles are now semi-public
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
For third-party packages that derive types from Matplotlib, our use of custom roles may
5+
prevent Sphinx from building their docs. These custom Sphinx roles are now public solely
6+
for the purposes of use within projects that derive from Matplotlib types. See
7+
:mod:`matplotlib.sphinxext.roles` for details.

doc/api/sphinxext_roles.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
==============================
2+
``matplotlib.sphinxext.roles``
3+
==============================
4+
5+
.. automodule:: matplotlib.sphinxext.roles
6+
:no-undoc-members:
7+
:private-members: _rcparam_role, _mpltype_role

doc/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ def _parse_skip_subdirs_file():
116116
'sphinx_gallery.gen_gallery',
117117
'matplotlib.sphinxext.mathmpl',
118118
'matplotlib.sphinxext.plot_directive',
119+
'matplotlib.sphinxext.roles',
119120
'matplotlib.sphinxext.figmpl_directive',
120121
'sphinxcontrib.inkscapeconverter',
121-
'sphinxext.custom_roles',
122122
'sphinxext.github',
123123
'sphinxext.math_symbol_table',
124124
'sphinxext.missing_references',

doc/sphinxext/custom_roles.py

Lines changed: 0 additions & 89 deletions
This file was deleted.

lib/matplotlib/sphinxext/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ python_sources = [
33
'figmpl_directive.py',
44
'mathmpl.py',
55
'plot_directive.py',
6+
'roles.py',
67
]
78

89
typing_sources = [

lib/matplotlib/sphinxext/roles.py

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
"""
2+
Custom roles for the Matplotlib documentation.
3+
4+
.. warning::
5+
6+
These roles are considered semi-public. They are only intended to be used in
7+
the Matplotlib documentation.
8+
9+
However, it can happen that downstream packages end up pulling these roles into
10+
their documentation, which will result in documentation build errors. The following
11+
describes the exact mechanism and how to fix the errors.
12+
13+
There are two ways, Matplotlib docstrings can end up in downstream documentation.
14+
You have to subclass a Matplotlib class and either use the ``:inherited-members:``
15+
option in your autodoc configuration, or you have to override a method without
16+
specifying a new docstring; the new method will inherit the original docstring and
17+
still render in your autodoc. If the docstring contains one of the custom sphinx
18+
roles, you'll see one of the following error messages:
19+
20+
.. code-block:: none
21+
22+
Unknown interpreted text role "mpltype".
23+
Unknown interpreted text role "rc".
24+
25+
To fix this, you can add this module as extension to your sphinx :file:`conf.py`::
26+
27+
extensions = [
28+
'matplotlib.sphinxext.roles',
29+
# Other extensions.
30+
]
31+
32+
.. warning::
33+
34+
Direct use of these roles in other packages is not officially supported. We
35+
reserve the right to modify or remove these roles without prior notification.
36+
"""
37+
38+
from urllib.parse import urlsplit, urlunsplit
39+
40+
from docutils import nodes
41+
42+
import matplotlib
43+
from matplotlib import rcParamsDefault
44+
45+
46+
class _QueryReference(nodes.Inline, nodes.TextElement):
47+
"""
48+
Wraps a reference or pending reference to add a query string.
49+
50+
The query string is generated from the attributes added to this node.
51+
52+
Also equivalent to a `~docutils.nodes.literal` node.
53+
"""
54+
55+
def to_query_string(self):
56+
"""Generate query string from node attributes."""
57+
return '&'.join(f'{name}={value}' for name, value in self.attlist())
58+
59+
60+
def _visit_query_reference_node(self, node):
61+
"""
62+
Resolve *node* into query strings on its ``reference`` children.
63+
64+
Then act as if this is a `~docutils.nodes.literal`.
65+
"""
66+
query = node.to_query_string()
67+
for refnode in node.findall(nodes.reference):
68+
uri = urlsplit(refnode['refuri'])._replace(query=query)
69+
refnode['refuri'] = urlunsplit(uri)
70+
71+
self.visit_literal(node)
72+
73+
74+
def _depart_query_reference_node(self, node):
75+
"""
76+
Act as if this is a `~docutils.nodes.literal`.
77+
"""
78+
self.depart_literal(node)
79+
80+
81+
def _rcparam_role(name, rawtext, text, lineno, inliner, options=None, content=None):
82+
"""
83+
Sphinx role ``:rc:`` to highlight and link ``rcParams`` entries.
84+
85+
Usage: Give the desired ``rcParams`` key as parameter.
86+
87+
:code:`:rc:`figure.dpi`` will render as: :rc:`figure.dpi`
88+
"""
89+
# Generate a pending cross-reference so that Sphinx will ensure this link
90+
# isn't broken at some point in the future.
91+
title = f'rcParams["{text}"]'
92+
target = 'matplotlibrc-sample'
93+
ref_nodes, messages = inliner.interpreted(title, f'{title} <{target}>',
94+
'ref', lineno)
95+
96+
qr = _QueryReference(rawtext, highlight=text)
97+
qr += ref_nodes
98+
node_list = [qr]
99+
100+
# The default backend would be printed as "agg", but that's not correct (as
101+
# the default is actually determined by fallback).
102+
if text in rcParamsDefault and text != "backend":
103+
node_list.extend([
104+
nodes.Text(' (default: '),
105+
nodes.literal('', repr(rcParamsDefault[text])),
106+
nodes.Text(')'),
107+
])
108+
109+
return node_list, messages
110+
111+
112+
def _mpltype_role(name, rawtext, text, lineno, inliner, options=None, content=None):
113+
"""
114+
Sphinx role ``:mpltype:`` for custom matplotlib types.
115+
116+
In Matplotlib, there are a number of type-like concepts that do not have a
117+
direct type representation; example: color. This role allows to properly
118+
highlight them in the docs and link to their definition.
119+
120+
Currently supported values:
121+
122+
- :code:`:mpltype:`color`` will render as: :mpltype:`color`
123+
124+
"""
125+
mpltype = text
126+
type_to_link_target = {
127+
'color': 'colors_def',
128+
}
129+
if mpltype not in type_to_link_target:
130+
raise ValueError(f"Unknown mpltype: {mpltype!r}")
131+
132+
node_list, messages = inliner.interpreted(
133+
mpltype, f'{mpltype} <{type_to_link_target[mpltype]}>', 'ref', lineno)
134+
return node_list, messages
135+
136+
137+
def setup(app):
138+
app.add_role("rc", _rcparam_role)
139+
app.add_role("mpltype", _mpltype_role)
140+
app.add_node(
141+
_QueryReference,
142+
html=(_visit_query_reference_node, _depart_query_reference_node),
143+
latex=(_visit_query_reference_node, _depart_query_reference_node),
144+
text=(_visit_query_reference_node, _depart_query_reference_node),
145+
)
146+
return {"version": matplotlib.__version__,
147+
"parallel_read_safe": True, "parallel_write_safe": True}

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,11 @@ ignore_directives = [
283283
"include"
284284
]
285285
ignore_roles = [
286-
# sphinxext.custom_roles
287-
"rc",
288286
# matplotlib.sphinxext.mathmpl
289287
"mathmpl",
290288
"math-stix",
289+
# matplotlib.sphinxext.roles
290+
"rc",
291291
# sphinxext.github
292292
"ghissue",
293293
"ghpull",

0 commit comments

Comments
 (0)