1111from sphinx .util import logging
1212from docutils import nodes as docutil_nodes
1313from sphinx .writers .latex import LaTeXTranslator
14- from .utils import get_node_number , find_parent
14+ from .utils import get_node_number , find_parent , list_rindex
1515
1616logger = logging .getLogger (__name__ )
1717
@@ -32,51 +32,67 @@ class exercise_unenumerable_node(docutil_nodes.Admonition, docutil_nodes.Element
3232 pass
3333
3434
35+ def _visit_nodes_latex (self , node , find_parent ):
36+ """ Function to handle visit_node for latex. """
37+ docname = find_parent (self .builder .env , node , "section" )
38+ self .body .append (
39+ "\\ phantomsection \\ label{" + f"{ docname } :{ node .attributes ['label' ]} " + "}"
40+ )
41+ self .body .append (latex_admonition_start )
42+
43+
44+ def _depart_nodes_latex (self , node , title , pop_index = False ):
45+ """ Function to handle depart_node for latex. """
46+ idx = list_rindex (self .body , latex_admonition_start ) + 2
47+ if pop_index :
48+ self .body .pop (idx )
49+ self .body .insert (idx , title )
50+ self .body .append (latex_admonition_end )
51+
52+
53+ def _remove_placeholder_title_exercise (typ , node ):
54+ """ Removing the exercise placeholder we put in title earlier."""
55+ for title in node .traverse (docutil_nodes .title ):
56+ if typ .title () in title .astext ():
57+ title [0 ] = docutil_nodes .Text ("" )
58+
59+
3560def visit_enumerable_node (self , node : Node ) -> None :
61+ typ = node .attributes .get ("type" , "" )
3662 if isinstance (self , LaTeXTranslator ):
37- docname = find_parent (self .builder .env , node , "section" )
38- self .body .append ("\\ label{" + f"{ docname } :{ node .attributes ['label' ]} " + "}" )
39- self .body .append (latex_admonition_start )
63+ _remove_placeholder_title_exercise (typ , node )
64+ _visit_nodes_latex (self , node , find_parent )
4065 else :
41- for title in node .traverse (docutil_nodes .title ):
42- if "Exercise" in title .astext ():
43- title [0 ] = docutil_nodes .Text ("" )
66+ _remove_placeholder_title_exercise (typ , node )
4467 self .body .append (self .starttag (node , "div" , CLASS = "admonition" ))
4568
4669
4770def depart_enumerable_node (self , node : Node ) -> None :
4871 typ = node .attributes .get ("type" , "" )
4972 if isinstance (self , LaTeXTranslator ):
5073 number = get_node_number (self , node , typ )
51- idx = list_rindex (self .body , latex_admonition_start ) + 2
52- self .body .insert (idx , f"{ typ .title ()} { number } " )
53- self .body .append (latex_admonition_end )
74+ _depart_nodes_latex (self , node , f"{ typ .title ()} { number } " )
5475 else :
5576 number = get_node_number (self , node , typ )
56- if number :
57- idx = self .body .index (f"{ typ .title ()} { number } " )
58- self .body [idx ] = f"{ typ .title ()} { number } "
77+ idx = list_rindex (self .body , f"{ typ .title ()} { number } " )
78+ self .body [idx ] = f"{ typ .title ()} { number } "
5979 self .body .append ("</div>" )
6080
6181
6282def visit_exercise_unenumerable_node (self , node : Node ) -> None :
83+ typ = node .attributes .get ("type" , "" )
6384 if isinstance (self , LaTeXTranslator ):
64- docname = find_parent (self .builder .env , node , "section" )
65- self .body .append ("\\ label{" + f"{ docname } :{ node .attributes ['label' ]} " + "}" )
66- self .body .append (latex_admonition_start )
85+ _remove_placeholder_title_exercise (typ , node )
86+ _visit_nodes_latex (self , node , find_parent )
6787 else :
68- for title in node .traverse (docutil_nodes .title ):
69- if "Exercise" in title .astext ():
70- title [0 ] = docutil_nodes .Text ("" )
88+ _remove_placeholder_title_exercise (typ , node )
7189 self .body .append (self .starttag (node , "div" , CLASS = "admonition" ))
7290
7391
7492def depart_exercise_unenumerable_node (self , node : Node ) -> None :
7593 typ = node .attributes .get ("type" , "" )
7694 if isinstance (self , LaTeXTranslator ):
77- idx = list_rindex (self .body , latex_admonition_start ) + 2
78- self .body .insert (idx , f"{ typ .title ()} " )
79- self .body .append (latex_admonition_end )
95+ _depart_nodes_latex (self , node , f"{ typ .title ()} " )
8096 else :
8197 idx = list_rindex (self .body , '<p class="admonition-title">' ) + 1
8298 element = f"<span>{ typ .title ()} </span>"
@@ -86,23 +102,18 @@ def depart_exercise_unenumerable_node(self, node: Node) -> None:
86102
87103def visit_solution_node (self , node : Node ) -> None :
88104 if isinstance (self , LaTeXTranslator ):
89- docname = find_parent (self .builder .env , node , "section" )
90- self .body .append ("\\ label{" + f"{ docname } :{ node .attributes ['label' ]} " + "}" )
91- self .body .append (latex_admonition_start )
105+ _visit_nodes_latex (self , node , find_parent )
92106 else :
93107 self .body .append (self .starttag (node , "div" , CLASS = "admonition" ))
94108
95109
96110def depart_solution_node (self , node : Node ) -> None :
97111 typ = node .attributes .get ("type" , "" )
98112 if isinstance (self , LaTeXTranslator ):
99- idx = list_rindex (self .body , latex_admonition_start ) + 2
100- self .body .pop (idx )
101- self .body .insert (idx , f"{ typ .title ()} " )
102- self .body .append (latex_admonition_end )
113+ _depart_nodes_latex (self , node , f"{ typ .title ()} to " , True )
103114 else :
104115 number = get_node_number (self , node , typ )
105- idx = self .body . index ( f"{ typ .title ()} { number } " )
116+ idx = list_rindex ( self .body , f"{ typ .title ()} { number } " )
106117 self .body .pop (idx )
107118 self .body .append ("</div>" )
108119
@@ -111,7 +122,7 @@ def is_exercise_node(node):
111122 return isinstance (node , exercise_node )
112123
113124
114- def is_unenumerable_node (node ):
125+ def is_exercise_unenumerable_node (node ):
115126 return isinstance (node , exercise_unenumerable_node )
116127
117128
@@ -121,7 +132,9 @@ def is_solution_node(node):
121132
122133def is_extension_node (node ):
123134 return (
124- is_exercise_node (node ) or is_unenumerable_node (node ) or is_solution_node (node )
135+ is_exercise_node (node )
136+ or is_exercise_unenumerable_node (node )
137+ or is_solution_node (node )
125138 )
126139
127140
@@ -131,14 +144,6 @@ def rreplace(s, old, new, occurrence):
131144 return new .join (li )
132145
133146
134- def list_rindex (li , x ) -> int :
135- """Getting the last occurence of an item in a list."""
136- for i in reversed (range (len (li ))):
137- if li [i ] == x :
138- return i
139- raise ValueError ("{} is not in list" .format (x ))
140-
141-
142147NODE_TYPES = {
143148 "exercise" : {"node" : exercise_node , "type" : "exercise" },
144149 "solution" : {"node" : solution_node , "type" : "solution" },
0 commit comments