Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 664b457

Browse filesBrowse files
authored
Merge pull request #28289 from QuLogic/public-roles
Promote mpltype Sphinx role to a public extension
2 parents 7c86942 + 3fe382d commit 664b457
Copy full SHA for 664b457

File tree

8 files changed

+166
-92
lines changed
Filter options

8 files changed

+166
-92
lines changed

‎doc/api/index.rst

Copy file name to clipboardExpand all lines: doc/api/index.rst
+1Lines 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
+7Lines 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

Copy file name to clipboard
+7Lines 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

Copy file name to clipboardExpand all lines: doc/conf.py
+1-1Lines 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

Copy file name to clipboardExpand all lines: doc/sphinxext/custom_roles.py
-89Lines changed: 0 additions & 89 deletions
This file was deleted.

‎lib/matplotlib/sphinxext/meson.build

Copy file name to clipboardExpand all lines: lib/matplotlib/sphinxext/meson.build
+1Lines 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

Copy file name to clipboard
+147Lines 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

Copy file name to clipboardExpand all lines: pyproject.toml
+2-2Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.