2424 maybeAddToAssignment ,
2525)
2626from runestone .common .runestonedirective import RunestoneIdDirective , RunestoneIdNode
27+ from runestone .common .xmlcommon import write_substitute , substitute_visitor , substitute_departure
2728
2829
2930def setup (app ):
3031 app .add_directive ("clickablearea" , ClickableArea )
3132
32- app .add_node (ClickableAreaNode , html = (visit_ca_html , depart_ca_html ))
33+ app .add_node (ClickableAreaNode , html = (visit_ca_html , depart_ca_html ),
34+ xml = (visit_ca_xml , depart_ca_xml ))
3335
34- app .add_config_value ("clickable_div_class" , "runestone alert alert-warning " , "html" )
36+ app .add_config_value ("clickable_div_class" , "" , "html" )
3537
3638
3739TEMPLATE = """
@@ -44,6 +46,11 @@ def setup(app):
4446</div>
4547"""
4648
49+ XML_START = """
50+ <exercise xml:id="{divid}">
51+ <statement><p>{question}</p></statement>
52+ """
53+
4754
4855class ClickableAreaNode (nodes .General , nodes .Element , RunestoneIdNode ):
4956 pass
@@ -95,6 +102,29 @@ def depart_ca_html(self, node):
95102 self .body .remove (node ["delimiter" ])
96103
97104
105+ def visit_ca_xml (self , node ):
106+ res = XML_START .format (** node ["runestone_options" ])
107+ if node ["runestone_options" ].get ("feedback" , None ):
108+ res += "<feedback><p>{feedback}</p></feedback>\n " .format (
109+ ** node ["runestone_options" ])
110+ res += "<areas>\n "
111+ if "iscode" in node ["runestone_options" ]:
112+ # The case where iscode is not in options makes no sense and probably does not exist in
113+ # any runestone books
114+ for row in node ["runestone_options" ]["raw_source" ]:
115+ row = row .replace ("\n " , "" )
116+ row = row .replace (":click-correct:" , "<area correct='yes'>" )
117+ row = row .replace (":click-incorrect:" , "<area>" )
118+ row = row .replace (":endclick" , "</area>" )
119+ row = "<cline>" + row + "</cline>\n "
120+ res += row
121+ self .output .append (res )
122+
123+
124+ def depart_ca_xml (self , node ):
125+ self .output .append ("</areas></exercise>" )
126+
127+
98128class ClickableArea (RunestoneIdDirective ):
99129 """
100130.. clickablearea:: identifier
@@ -157,6 +187,7 @@ def run(self):
157187 source = source .replace (":endclick:" , "</span>" )
158188 source = "<pre>" + source + "</pre>"
159189 self .options ["clickcode" ] = source
190+ self .options ["raw_source" ] = self .content
160191 else :
161192 self .options ["clickcode" ] = ""
162193 clickNode = ClickableAreaNode ()
0 commit comments