You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			148 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			148 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Python
		
	
"""
 | 
						|
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}
 |