-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Promote mpltype Sphinx role to a public extension #28289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+166
−92
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Documentation-specific custom Sphinx roles are now semi-public | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
For third-party packages that derive types from Matplotlib, our use of custom roles may | ||
prevent Sphinx from building their docs. These custom Sphinx roles are now public solely | ||
for the purposes of use within projects that derive from Matplotlib types. See | ||
:mod:`matplotlib.sphinxext.roles` for details. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
============================== | ||
``matplotlib.sphinxext.roles`` | ||
============================== | ||
|
||
.. automodule:: matplotlib.sphinxext.roles | ||
:no-undoc-members: | ||
:private-members: _rcparam_role, _mpltype_role |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
""" | ||
Custom roles for the Matplotlib documentation. | ||
|
||
.. warning:: | ||
|
||
These roles are considered semi-public. They are only intended to be used in | ||
the Matplotlib documentation. | ||
|
||
However, it can happen that downstream packages end up pulling these roles into | ||
their documentation, which will result in documentation build errors. The following | ||
describes the exact mechanism and how to fix the errors. | ||
|
||
There are two ways, Matplotlib docstrings can end up in downstream documentation. | ||
You have to subclass a Matplotlib class and either use the ``:inherited-members:`` | ||
option in your autodoc configuration, or you have to override a method without | ||
specifying a new docstring; the new method will inherit the original docstring and | ||
still render in your autodoc. If the docstring contains one of the custom sphinx | ||
roles, you'll see one of the following error messages: | ||
|
||
.. code-block:: none | ||
|
||
Unknown interpreted text role "mpltype". | ||
Unknown interpreted text role "rc". | ||
|
||
To fix this, you can add this module as extension to your sphinx :file:`conf.py`:: | ||
|
||
extensions = [ | ||
'matplotlib.sphinxext.roles', | ||
# Other extensions. | ||
] | ||
|
||
.. warning:: | ||
|
||
Direct use of these roles in other packages is not officially supported. We | ||
reserve the right to modify or remove these roles without prior notification. | ||
""" | ||
|
||
from urllib.parse import urlsplit, urlunsplit | ||
|
||
from docutils import nodes | ||
|
||
import matplotlib | ||
from matplotlib import rcParamsDefault | ||
|
||
|
||
class _QueryReference(nodes.Inline, nodes.TextElement): | ||
""" | ||
Wraps a reference or pending reference to add a query string. | ||
|
||
The query string is generated from the attributes added to this node. | ||
|
||
Also equivalent to a `~docutils.nodes.literal` node. | ||
""" | ||
|
||
def to_query_string(self): | ||
"""Generate query string from node attributes.""" | ||
return '&'.join(f'{name}={value}' for name, value in self.attlist()) | ||
|
||
|
||
def _visit_query_reference_node(self, node): | ||
""" | ||
Resolve *node* into query strings on its ``reference`` children. | ||
|
||
Then act as if this is a `~docutils.nodes.literal`. | ||
""" | ||
query = node.to_query_string() | ||
for refnode in node.findall(nodes.reference): | ||
uri = urlsplit(refnode['refuri'])._replace(query=query) | ||
refnode['refuri'] = urlunsplit(uri) | ||
|
||
self.visit_literal(node) | ||
|
||
|
||
def _depart_query_reference_node(self, node): | ||
""" | ||
Act as if this is a `~docutils.nodes.literal`. | ||
""" | ||
self.depart_literal(node) | ||
|
||
|
||
def _rcparam_role(name, rawtext, text, lineno, inliner, options=None, content=None): | ||
""" | ||
Sphinx role ``:rc:`` to highlight and link ``rcParams`` entries. | ||
|
||
Usage: Give the desired ``rcParams`` key as parameter. | ||
|
||
:code:`:rc:`figure.dpi`` will render as: :rc:`figure.dpi` | ||
""" | ||
# Generate a pending cross-reference so that Sphinx will ensure this link | ||
# isn't broken at some point in the future. | ||
title = f'rcParams["{text}"]' | ||
target = 'matplotlibrc-sample' | ||
ref_nodes, messages = inliner.interpreted(title, f'{title} <{target}>', | ||
'ref', lineno) | ||
|
||
qr = _QueryReference(rawtext, highlight=text) | ||
qr += ref_nodes | ||
node_list = [qr] | ||
|
||
# The default backend would be printed as "agg", but that's not correct (as | ||
# the default is actually determined by fallback). | ||
if text in rcParamsDefault and text != "backend": | ||
node_list.extend([ | ||
nodes.Text(' (default: '), | ||
nodes.literal('', repr(rcParamsDefault[text])), | ||
nodes.Text(')'), | ||
]) | ||
|
||
return node_list, messages | ||
|
||
|
||
def _mpltype_role(name, rawtext, text, lineno, inliner, options=None, content=None): | ||
""" | ||
Sphinx role ``:mpltype:`` for custom matplotlib types. | ||
|
||
In Matplotlib, there are a number of type-like concepts that do not have a | ||
direct type representation; example: color. This role allows to properly | ||
highlight them in the docs and link to their definition. | ||
|
||
Currently supported values: | ||
|
||
- :code:`:mpltype:`color`` will render as: :mpltype:`color` | ||
|
||
""" | ||
mpltype = text | ||
type_to_link_target = { | ||
'color': 'colors_def', | ||
} | ||
if mpltype not in type_to_link_target: | ||
raise ValueError(f"Unknown mpltype: {mpltype!r}") | ||
|
||
node_list, messages = inliner.interpreted( | ||
mpltype, f'{mpltype} <{type_to_link_target[mpltype]}>', 'ref', lineno) | ||
return node_list, messages | ||
|
||
|
||
def setup(app): | ||
app.add_role("rc", _rcparam_role) | ||
app.add_role("mpltype", _mpltype_role) | ||
app.add_node( | ||
_QueryReference, | ||
html=(_visit_query_reference_node, _depart_query_reference_node), | ||
latex=(_visit_query_reference_node, _depart_query_reference_node), | ||
text=(_visit_query_reference_node, _depart_query_reference_node), | ||
) | ||
return {"version": matplotlib.__version__, | ||
"parallel_read_safe": True, "parallel_write_safe": True} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can be more explicit here:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe move the bulk of the explanation to the roles module docstring and give only a very brief summary here, linking to the module docs. That way, it’s easier to update the docs later.