1+ from urllib .parse import urlsplit , urlunsplit
2+
13from docutils import nodes
2- from os . path import sep
4+
35from matplotlib import rcParamsDefault
46
57
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.
825
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 )
1132
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 ]
1654
17- ref = nodes .reference (rawtext , rendered , refuri = refuri )
18- node_list = [nodes .literal ('' , '' , ref )]
1955 # The default backend would be printed as "agg", but that's not correct (as
2056 # the default is actually determined by fallback).
2157 if text in rcParamsDefault and text != "backend" :
@@ -24,9 +60,16 @@ def rcparam_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
2460 nodes .literal ('' , repr (rcParamsDefault [text ])),
2561 nodes .Text (')' ),
2662 ])
27- return node_list , []
63+
64+ return node_list , messages
2865
2966
3067def setup (app ):
3168 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+ )
3275 return {"parallel_read_safe" : True , "parallel_write_safe" : True }
0 commit comments