Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit e124be1

Browse files
committed
reverted changes to activecode.py
1 parent c5ea33a commit e124be1

File tree

1 file changed

+270
-49
lines changed

1 file changed

+270
-49
lines changed

runestone/activecode/activecode.py

Lines changed: 270 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,87 +14,239 @@
1414
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1515
#
1616

17-
__author__ = 'isaiahmayerchak'
17+
__author__ = 'bmiller'
1818

1919
from docutils import nodes
2020
from docutils.parsers.rst import directives
2121
from docutils.parsers.rst import Directive
22-
from .textfield import *
2322

2423

2524
def setup(app):
2625
app.add_directive('activecode', ActiveCode)
26+
app.add_directive('actex', ActiveExercise)
27+
app.add_stylesheet('codemirror.css')
2728
app.add_stylesheet('activecode.css')
2829

29-
app.add_javascript('skulpt.min.js')
30-
app.add_javascript('skulpt-stdlib.js')
30+
app.add_javascript('jquery.highlight.js')
31+
app.add_javascript('bookfuncs.js')
3132
app.add_javascript('codemirror.js')
33+
app.add_javascript('xml.js')
34+
app.add_javascript('css.js')
35+
app.add_javascript('htmlmixed.js')
3236
app.add_javascript('python.js')
37+
app.add_javascript('javascript.js')
3338
app.add_javascript('activecode.js')
34-
35-
app.add_role('textfield', textfield_role)
39+
app.add_javascript('skulpt.min.js')
40+
app.add_javascript('skulpt-stdlib.js')
3641

3742
app.add_node(ActivcodeNode, html=(visit_ac_node, depart_ac_node))
3843

3944
app.connect('doctree-resolved', process_activcode_nodes)
4045
app.connect('env-purge-doc', purge_activecodes)
4146

4247

43-
TEMPLATE = """
44-
<pre data-component="activecode" id=%(divid)s data-lang="%(language)s" %(autorun)s %(hidecode)s %(include)s %(timelimit)s %(coach)s %(codelens)s>
45-
%(initialcode)s
46-
</pre>
47-
"""
48+
START = '''
49+
<div id="cont"></div>
50+
<div id="%(divid)s" lang="%(language)s" time="%(timelimit)s" class="ac_section alert alert-warning" >
51+
'''
52+
53+
EDIT1 = '''
54+
</div>
55+
<br/>
56+
<div id="%(divid)s_code_div" style="display: %(hidecode)s" class="ac_code_div">
57+
<textarea cols="50" rows="12" id="%(divid)s_code" class="active_code" prefixcode="%(include)s" lang="%(language)s">
58+
%(initialcode)s
59+
</textarea>
60+
</div>
61+
'''
62+
63+
CAPTION = '''
64+
<div class="clearfix"></div>
65+
<p class="ac_caption"><span class="ac_caption_text">%(caption)s (%(divid)s)</span> </p>
66+
'''
67+
68+
UNHIDE = '''
69+
<span class="ac_sep"></span>
70+
<button class='btn btn-default' id="%(divid)s_showb" onclick="$('#%(divid)s_code_div').toggle();cm_editors['%(divid)s_code'].refresh();$('#%(divid)s_saveb').toggle();$('#%(divid)s_loadb').toggle()">Show/Hide Code</button>
71+
'''
72+
73+
GRADES = '''
74+
<span class="ac_sep"></span>
75+
<input type="button" class='btn btn-default ' id="gradeb" name="Show Feedback" value="Show Feedback" onclick="createGradeSummary('%(divid)s')"/>
76+
'''
77+
78+
AUDIO = '''
79+
<span class="ac_sep"></span>
80+
<input type="button" class='btn btn-default ' id="audiob" name="Play Audio" value="Start Audio Tour" onclick="createAudioTourHTML('%(divid)s','%(argu)s','%(no_of_buttons)s','%(ctext)s')"/>
81+
'''
82+
83+
EDIT2 = '''
84+
<div class="ac_actions">
85+
<button class='btn btn-success' id="%(divid)s_runb">Run</button>
86+
<button class="ac_opt btn btn-default" style="display: inline-block" id="%(divid)s_saveb" onclick="saveEditor('%(divid)s');">Save</button>
87+
<button class="ac_opt btn btn-default" style="display: inline-block" id="%(divid)s_loadb" onclick="requestCode('%(divid)s');">Load</button>
88+
'''
89+
90+
VIZB = '''<button class='btn btn-default' id="%(divid)s_vizb" onclick="injectCodelens(this,'%(divid)s');">Show in Codelens</button>
91+
'''
92+
93+
COACHB = '''<button class='ac_opt btn btn-default' id="%(divid)s_coach_b" onclick="injectCodeCoach('%(divid)s');">Code Coach</button>
94+
'''
95+
96+
SCRIPT = '''
97+
<script>
98+
if ('%(hidecode)s' == 'none') {
99+
// a hack to preserve the inline-block display style. Toggle() will use display: block
100+
// (instead of inline-block) if the previous display style was 'none'
101+
$('#%(divid)s_saveb').toggle();
102+
$('#%(divid)s_loadb').toggle();
103+
}
104+
if ($("#%(divid)s").attr("lang") !== "html" && $("#%(divid)s_code_div").parents(".admonition").length == 0 && $("#%(divid)s_code_div").parents("#exercises").length == 0){
105+
if ($(window).width() > 975){
106+
$("#%(divid)s_code_div").offset({
107+
left: $("#%(divid)s .clearfix").offset().left
108+
});
109+
}
110+
$("#%(divid)s_runb").one("click", function(){
111+
$({})
112+
.queue(function (next) {
113+
if ($(window).width() > 975){
114+
$("#%(divid)s_code_div").animate({
115+
left: 40
116+
}, 500, next);
117+
if (! Sk.TurtleGraphics ) {
118+
Sk.TurtleGraphics = {};
119+
}
120+
Sk.TurtleGraphics.height = 320;
121+
Sk.TurtleGraphics.width = 320;
122+
}
123+
else{
124+
next();
125+
}
126+
})
127+
.queue(function (next) {
128+
$("#%(divid)s_runb").parent().siblings(".ac_output").show();
129+
runit('%(divid)s',this, %(include)s);
130+
$("#%(divid)s_runb").on("click", function(){
131+
runit('%(divid)s',this, %(include)s);
132+
});
133+
})
134+
135+
});
136+
}
137+
else{
138+
$("#%(divid)s_code_div").css({float : "none", marginLeft : "auto", marginRight : "auto"});
139+
$("#%(divid)s_runb").parent().siblings(".ac_output").show().css({float : "none", right : "0px"});
140+
$("#%(divid)s_runb").on("click", function(){
141+
runit('%(divid)s',this, %(include)s);
142+
});
143+
}
144+
</script>
145+
'''
146+
OUTPUT_START = '''
147+
<div class="ac_output">'''
148+
149+
CANVAS = '''
150+
<div style="text-align: center">
151+
<div id="%(divid)s_canvas" class="ac-canvas" style="border-style: solid; text-align: center"></div>
152+
</div>
153+
'''
154+
155+
SUFF = '''<pre id="%(divid)s_suffix" style="display:none">%(suffix)s</pre>'''
156+
157+
PRE = '''<pre id="%(divid)s_pre" class="active_out"></pre>
158+
'''
159+
OUTPUT_END = '''
160+
</div> <!-- end output -->'''
161+
162+
VIZ = '''<div id="%(divid)s_codelens_div" style="display:none"></div>'''
163+
164+
# <iframe id="%(divid)s_codelens" width="800" height="500" style="display:block"src="#">
165+
# </iframe>
166+
167+
COACH = '''<div id="%(divid)s_coach_div" style="display:none;"></div>'''
168+
169+
HTMLOUT = '''<div id="%(divid)s_htmlout" style="display:none;" class="ac_htmlout"></div>'''
170+
171+
END = '''
172+
</div>
173+
174+
'''
175+
176+
AUTO = '''
177+
<script type="text/javascript">
178+
$(document).ready(function() {
179+
$(window).load(function() {
180+
var runb = document.getElementById("%(divid)s_runb");
181+
runit('%(divid)s',runb, %(include)s);
182+
});
183+
});
184+
</script>
185+
'''
186+
48187

49188
class ActivcodeNode(nodes.General, nodes.Element):
50189
def __init__(self, content):
51190
"""
191+
52192
Arguments:
53193
- `self`:
54194
- `content`:
55195
"""
56196
super(ActivcodeNode, self).__init__()
57-
self.ac_options = content
197+
self.ac_components = content
58198

199+
200+
# self for these functions is an instance of the writer class. For example
201+
# in html, self is sphinx.writers.html.SmartyPantsHTMLTranslator
202+
# The node that is passed as a parameter is an instance of our node class.
59203
def visit_ac_node(self, node):
60204
# print self.settings.env.activecodecounter
61-
res = ""
62-
63-
if 'language' not in node.ac_options:
64-
node.ac_options['language'] = 'python'
65-
66-
if 'autorun' in node.ac_options:
67-
node.ac_options['autorun'] = 'data-autorun'
68-
else:
69-
node.ac_options['autorun'] = ''
70-
71-
if 'hidecode' in node.ac_options:
72-
node.ac_options['hidecode'] = 'data-hidecode'
73-
else:
74-
node.ac_options['hidecode'] = ''
75-
76-
if 'include' in node.ac_options:
77-
node.ac_options['include'] = 'data-include=' + str(node.ac_options['include'])
205+
res = START
206+
if 'above' in node.ac_components:
207+
res += CANVAS
208+
if 'tour_1' not in node.ac_components:
209+
res += EDIT2
78210
else:
79-
node.ac_options['include'] = ''
80-
81-
if 'timelimit' in node.ac_options:
82-
node.ac_options['timelimit'] = 'data-timelimit=' + str(node.ac_options['timelimit'])
83-
else:
84-
node.ac_options['timelimit'] = ''
85-
86-
if 'coach' in node.ac_options:
87-
node.ac_options['coach'] = 'data-coach'
88-
else:
89-
node.ac_options['coach'] = ''
90-
91-
if 'codelens' in node.ac_options:
92-
node.ac_options['codelens'] = 'data-codelens'
93-
else:
94-
node.ac_options['codelens'] = ''
95-
96-
res += TEMPLATE % node.ac_options
97-
211+
res += EDIT2 + AUDIO
212+
if node.ac_components['codelens']:
213+
res += VIZB
214+
215+
if 'coach' in node.ac_components:
216+
res += COACHB
217+
218+
if 'hidecode' not in node.ac_components:
219+
node.ac_components['hidecode'] = 'block'
220+
if node.ac_components['hidecode'] == 'none':
221+
res += UNHIDE
222+
if 'gradebutton' in node.ac_components:
223+
res += GRADES
224+
res += EDIT1
225+
res += OUTPUT_START
226+
if 'above' not in node.ac_components:
227+
if 'nocanvas' not in node.ac_components:
228+
res += CANVAS
229+
if 'suffix' in node.ac_components:
230+
res += SUFF
231+
if 'nopre' not in node.ac_components:
232+
res += PRE
233+
if 'autorun' in node.ac_components:
234+
res += AUTO
235+
res += OUTPUT_END
236+
res += CAPTION
237+
238+
if node.ac_components['codelens']:
239+
res += VIZ
240+
241+
if 'coach' in node.ac_components:
242+
res += COACH
243+
244+
if node.ac_components['language'] == 'html':
245+
res += HTMLOUT
246+
247+
res += SCRIPT
248+
res += END
249+
res = res % node.ac_components
98250
res = res.replace("u'", "'") # hack: there must be a better way to include the list and avoid unicode strings
99251

100252
self.body.append(res)
@@ -148,11 +300,80 @@ def run(self):
148300

149301
self.options['divid'] = self.arguments[0]
150302

151-
source = "\n".join(self.content)
303+
if self.content:
304+
if '====' in self.content:
305+
idx = self.content.index('====')
306+
source = "\n".join(self.content[:idx])
307+
suffix = "\n".join(self.content[idx + 1:])
308+
else:
309+
source = "\n".join(self.content)
310+
suffix = "\n"
311+
else:
312+
source = '\n'
313+
suffix = '\n'
314+
152315
self.options['initialcode'] = source
316+
self.options['suffix'] = suffix
317+
str = source.replace("\n", "*nline*")
318+
str0 = str.replace("\"", "*doubleq*")
319+
str1 = str0.replace("(", "*open*")
320+
str2 = str1.replace(")", "*close*")
321+
str3 = str2.replace("'", "*singleq*")
322+
self.options['argu'] = str3
323+
324+
complete = ""
325+
no_of_buttons = 0
326+
okeys = list(self.options.keys())
327+
for k in okeys:
328+
if '_' in k:
329+
x, label = k.split('_')
330+
no_of_buttons = no_of_buttons + 1
331+
complete = complete + self.options[k] + "*atype*"
332+
333+
newcomplete = complete.replace("\"", "*doubleq*")
334+
self.options['ctext'] = newcomplete
335+
self.options['no_of_buttons'] = no_of_buttons
336+
337+
if 'caption' not in self.options:
338+
self.options['caption'] = ''
339+
340+
if 'include' not in self.options:
341+
self.options['include'] = 'undefined'
342+
else:
343+
lst = self.options['include'].split(',')
344+
lst = [x.strip() for x in lst]
345+
self.options['include'] = lst
346+
347+
if 'hidecode' in self.options:
348+
self.options['hidecode'] = 'none'
349+
else:
350+
self.options['hidecode'] = 'block'
351+
352+
if 'language' not in self.options:
353+
self.options['language'] = 'python'
354+
355+
if 'nocodelens' in self.options or self.options['language'] != 'python':
356+
self.options['codelens'] = False
357+
else:
358+
self.options['codelens'] = True
359+
360+
if 'timelimit' not in self.options:
361+
self.options['timelimit'] = ''
153362

154363
return [ActivcodeNode(self.options)]
155364

156365

366+
class ActiveExercise(ActiveCode):
367+
required_arguments = 1
368+
optional_arguments = 0
369+
has_content = True
370+
371+
def run(self):
372+
self.options['hidecode'] = True
373+
self.options['gradebutton'] = True
374+
self.options['coach'] = True
375+
return super(ActiveExercise, self).run()
376+
377+
157378
if __name__ == '__main__':
158379
a = ActiveCode()

0 commit comments

Comments
 (0)