1
+ from urllib .parse import urlsplit , urlunsplit
2
+
1
3
from docutils import nodes
2
- from os . path import sep
4
+
3
5
from matplotlib import rcParamsDefault
4
6
5
7
6
- def rcparam_role (name , rawtext , text , lineno , inliner , options = {}, content = []):
7
- rendered = nodes .Text (f'rcParams["{ text } "]' )
8
+ class QueryReference (nodes .Inline , nodes .TextElement ):
9
+ """
10
+ Wraps a reference or pending reference to add a query string.
11
+
12
+ The query string is generated from the attributes added to this node.
13
+
14
+ Also equivalent to a `~docutils.nodes.literal` node.
15
+ """
16
+
17
+ def to_query_string (self ):
18
+ """Generate query string from node attributes."""
19
+ return '&' .join (f'{ name } ={ value } ' for name , value in self .attlist ())
20
+
21
+
22
+ def visit_query_reference_node (self , node ):
23
+ """
24
+ Resolve *node* into query strings on its ``reference`` children.
8
25
9
- source = inliner .document .attributes ['source' ].replace (sep , '/' )
10
- rel_source = source .split ('/doc/' , 1 )[1 ]
26
+ Then act as if this is a `~docutils.nodes.literal`.
27
+ """
28
+ query = node .to_query_string ()
29
+ for refnode in node .findall (nodes .reference ):
30
+ uri = urlsplit (refnode ['refuri' ])._replace (query = query )
31
+ refnode ['refuri' ] = urlunsplit (uri )
11
32
12
- levels = rel_source .count ('/' )
13
- refuri = ('../' * levels +
14
- 'tutorials/introductory/customizing.html' +
15
- f"?highlight={ text } #a-sample-matplotlibrc-file" )
33
+ self .visit_literal (node )
34
+
35
+
36
+ def depart_query_reference_node (self , node ):
37
+ """
38
+ Act as if this is a `~docutils.nodes.literal`.
39
+ """
40
+ self .depart_literal (node )
41
+
42
+
43
+ def rcparam_role (name , rawtext , text , lineno , inliner , options = {}, content = []):
44
+ # Generate a pending cross-reference so that Sphinx will ensure this link
45
+ # isn't broken at some point in the future.
46
+ title = f'rcParam["{ text } "]'
47
+ target = 'matplotlibrc-sample'
48
+ ref_nodes , messages = inliner .interpreted (title , f'{ title } <{ target } >' ,
49
+ 'ref' , lineno )
50
+
51
+ qr = QueryReference (rawtext , highlight = text )
52
+ qr += ref_nodes
53
+ node_list = [qr ]
16
54
17
- ref = nodes .reference (rawtext , rendered , refuri = refuri )
18
- node_list = [nodes .literal ('' , '' , ref )]
19
55
# The default backend would be printed as "agg", but that's not correct (as
20
56
# the default is actually determined by fallback).
21
57
if text in rcParamsDefault and text != "backend" :
@@ -24,9 +60,16 @@ def rcparam_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
24
60
nodes .literal ('' , repr (rcParamsDefault [text ])),
25
61
nodes .Text (')' ),
26
62
])
27
- return node_list , []
63
+
64
+ return node_list , messages
28
65
29
66
30
67
def setup (app ):
31
68
app .add_role ("rc" , rcparam_role )
69
+ app .add_node (
70
+ QueryReference ,
71
+ html = (visit_query_reference_node , depart_query_reference_node ),
72
+ latex = (visit_query_reference_node , depart_query_reference_node ),
73
+ text = (visit_query_reference_node , depart_query_reference_node ),
74
+ )
32
75
return {"parallel_read_safe" : True , "parallel_write_safe" : True }
0 commit comments