File: custom_roles.py

package info (click to toggle)
matplotlib 3.6.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 76,280 kB
  • sloc: python: 133,763; cpp: 66,599; objc: 1,699; ansic: 1,367; javascript: 765; makefile: 153; sh: 48
file content (75 lines) | stat: -rw-r--r-- 2,394 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
from urllib.parse import urlsplit, urlunsplit

from docutils import nodes

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={}, content=[]):
    # 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 setup(app):
    app.add_role("rc", rcparam_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 {"parallel_read_safe": True, "parallel_write_safe": True}