first import book
This commit is contained in:
parent
6be2701fd8
commit
dfd9c869d5
233 changed files with 47797 additions and 0 deletions
290
book/modules/luther/sphinx/activecode/activecode.py
Normal file
290
book/modules/luther/sphinx/activecode/activecode.py
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
# Copyright (C) 2011 Bradley N. Miller
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
__author__ = 'bmiller'
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
from docutils.parsers.rst import Directive
|
||||
import json
|
||||
import os
|
||||
|
||||
# try:
|
||||
# import conf
|
||||
# version = conf.version
|
||||
# staticserver = conf.staticserver
|
||||
# except:
|
||||
# version = '2.1.0'
|
||||
# staticserver = 'runestonestatic.appspot.com'
|
||||
|
||||
def setup(app):
|
||||
app.add_directive('activecode',ActiveCode)
|
||||
app.add_directive('actex',ActiveExercise)
|
||||
app.add_stylesheet('codemirror.css')
|
||||
app.add_stylesheet('activecode.css')
|
||||
|
||||
app.add_javascript('jquery.highlight.js' )
|
||||
app.add_javascript('bookfuncs.js' )
|
||||
app.add_javascript('codemirror.js' )
|
||||
app.add_javascript('python.js' )
|
||||
app.add_javascript('javascript.js' )
|
||||
app.add_javascript('activecode.js')
|
||||
app.add_javascript('skulpt.min.js' )
|
||||
app.add_javascript('skulpt-stdlib.js')
|
||||
|
||||
app.add_node(ActivcodeNode, html=(visit_ac_node, depart_ac_node))
|
||||
|
||||
app.connect('doctree-resolved',process_activcode_nodes)
|
||||
app.connect('env-purge-doc', purge_activecodes)
|
||||
|
||||
|
||||
|
||||
START = '''
|
||||
<div id="%(divid)s" lang="%(language)s" >
|
||||
'''
|
||||
|
||||
|
||||
EDIT1 = '''
|
||||
<br/>
|
||||
<div id="%(divid)s_code_div" style="display: %(hidecode)s">
|
||||
<textarea cols="50" rows="12" id="%(divid)s_code" class="active_code", prefixcode="%(include)s" lang="%(language)s">
|
||||
%(initialcode)s
|
||||
</textarea>
|
||||
</div>
|
||||
<p class="ac_caption"><span class="ac_caption_text">%(caption)s (%(divid)s)</span> </p>
|
||||
|
||||
<button class='btn btn-success' id="%(divid)s_runb" onclick="runit('%(divid)s',this, %(include)s);">Run</button>
|
||||
'''
|
||||
|
||||
UNHIDE='''
|
||||
<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>
|
||||
'''
|
||||
|
||||
GRADES = '''
|
||||
<input type="button" class='btn btn-default ' id="gradeb" name="Show Feedback" value="Show Feedback" onclick="createGradeSummary('%(divid)s')"/>
|
||||
'''
|
||||
|
||||
AUDIO = '''
|
||||
<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')"/>
|
||||
'''
|
||||
|
||||
EDIT2 = '''
|
||||
<div id="cont"></div>
|
||||
|
||||
<button class="ac_opt btn btn-default" style="display: inline-block" id="%(divid)s_saveb" onclick="saveEditor('%(divid)s');">Save</button>
|
||||
<button class="ac_opt btn btn-default" style="display: inline-block" id="%(divid)s_loadb" onclick="requestCode('%(divid)s');">Load</button>
|
||||
|
||||
<script>
|
||||
if ('%(hidecode)s' == 'none') {
|
||||
// a hack to preserve the inline-block display style. Toggle() will use display: block
|
||||
// (instead of inline-block) if the previous display style was 'none'
|
||||
$('#%(divid)s_saveb').toggle();
|
||||
$('#%(divid)s_loadb').toggle();
|
||||
}
|
||||
</script>
|
||||
|
||||
'''
|
||||
|
||||
CANVAS = '''
|
||||
<div style="text-align: center">
|
||||
<canvas id="%(divid)s_canvas" class="ac-canvas" height="400" width="400" style="border-style: solid; display: none; text-align: center"></canvas>
|
||||
</div>
|
||||
'''
|
||||
|
||||
SUFF = '''<pre id="%(divid)s_suffix" style="display:none">%(suffix)s</pre>'''
|
||||
|
||||
PRE = '''
|
||||
<pre id="%(divid)s_pre" class="active_out">
|
||||
|
||||
</pre>
|
||||
|
||||
'''
|
||||
|
||||
END = '''
|
||||
</div>
|
||||
|
||||
'''
|
||||
|
||||
AUTO = '''
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$(window).load(function() {
|
||||
var runb = document.getElementById("%(divid)s_runb");
|
||||
runit('%(divid)s',runb, %(include)s);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
'''
|
||||
|
||||
#'
|
||||
class ActivcodeNode(nodes.General, nodes.Element):
|
||||
def __init__(self,content):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
- `content`:
|
||||
"""
|
||||
super(ActivcodeNode,self).__init__()
|
||||
self.ac_components = content
|
||||
|
||||
# self for these functions is an instance of the writer class. For example
|
||||
# in html, self is sphinx.writers.html.SmartyPantsHTMLTranslator
|
||||
# The node that is passed as a parameter is an instance of our node class.
|
||||
def visit_ac_node(self,node):
|
||||
#print self.settings.env.activecodecounter
|
||||
res = START
|
||||
if 'above' in node.ac_components:
|
||||
res += CANVAS
|
||||
res += EDIT1
|
||||
if 'tour_1' not in node.ac_components:
|
||||
res += EDIT2
|
||||
else:
|
||||
res += AUDIO + EDIT2
|
||||
if 'above' not in node.ac_components:
|
||||
if 'nocanvas' not in node.ac_components:
|
||||
res += CANVAS
|
||||
if 'hidecode' not in node.ac_components:
|
||||
node.ac_components['hidecode'] = 'block'
|
||||
if node.ac_components['hidecode'] == 'none':
|
||||
res += UNHIDE
|
||||
if 'gradebutton' in node.ac_components:
|
||||
res += GRADES
|
||||
if 'suffix' in node.ac_components:
|
||||
res += SUFF
|
||||
if 'nopre' not in node.ac_components:
|
||||
res += PRE
|
||||
if 'autorun' in node.ac_components:
|
||||
res += AUTO
|
||||
res += END
|
||||
res = res % node.ac_components
|
||||
res = res.replace("u'","'") # hack: there must be a better way to include the list and avoid unicode strings
|
||||
|
||||
self.body.append(res)
|
||||
|
||||
def depart_ac_node(self,node):
|
||||
''' This is called at the start of processing an activecode node. If activecode had recursive nodes
|
||||
etc and did not want to do all of the processing in visit_ac_node any finishing touches could be
|
||||
added here.
|
||||
'''
|
||||
pass
|
||||
|
||||
|
||||
def process_activcode_nodes(app,env,docname):
|
||||
pass
|
||||
|
||||
|
||||
def purge_activecodes(app,env,docname):
|
||||
pass
|
||||
|
||||
|
||||
class ActiveCode(Directive):
|
||||
required_arguments = 1
|
||||
optional_arguments = 1
|
||||
has_content = True
|
||||
option_spec = {
|
||||
'nocanvas':directives.flag,
|
||||
'nopre':directives.flag,
|
||||
'above':directives.flag, # put the canvas above the code
|
||||
'autorun':directives.flag,
|
||||
'caption':directives.unchanged,
|
||||
'include':directives.unchanged,
|
||||
'hidecode':directives.flag,
|
||||
'language':directives.unchanged,
|
||||
'tour_1':directives.unchanged,
|
||||
'tour_2':directives.unchanged,
|
||||
'tour_3':directives.unchanged,
|
||||
'tour_4':directives.unchanged,
|
||||
'tour_5':directives.unchanged
|
||||
}
|
||||
|
||||
def run(self):
|
||||
env = self.state.document.settings.env
|
||||
# keep track of how many activecodes we have.... could be used to automatically make a unique id for them.
|
||||
if not hasattr(env,'activecodecounter'):
|
||||
env.activecodecounter = 0
|
||||
env.activecodecounter += 1
|
||||
|
||||
self.options['divid'] = self.arguments[0]
|
||||
|
||||
if self.content:
|
||||
if '====' in self.content:
|
||||
idx = self.content.index('====')
|
||||
source = "\n".join(self.content[:idx])
|
||||
suffix = "\n".join(self.content[idx+1:])
|
||||
else:
|
||||
source = "\n".join(self.content)
|
||||
suffix = "\n"
|
||||
else:
|
||||
source = '\n'
|
||||
suffix = '\n'
|
||||
|
||||
self.options['initialcode'] = source
|
||||
self.options['suffix'] = suffix
|
||||
str=source.replace("\n","*nline*")
|
||||
str0=str.replace("\"","*doubleq*")
|
||||
str1=str0.replace("(","*open*")
|
||||
str2=str1.replace(")","*close*")
|
||||
str3=str2.replace("'","*singleq*")
|
||||
self.options['argu']=str3
|
||||
|
||||
complete=""
|
||||
no_of_buttons=0
|
||||
okeys = self.options.keys()
|
||||
for k in okeys:
|
||||
if '_' in k:
|
||||
x,label = k.split('_')
|
||||
no_of_buttons=no_of_buttons+1
|
||||
complete=complete+self.options[k]+"*atype*"
|
||||
|
||||
newcomplete=complete.replace("\"","*doubleq*")
|
||||
self.options['ctext'] = newcomplete
|
||||
self.options['no_of_buttons'] = no_of_buttons
|
||||
|
||||
if 'caption' not in self.options:
|
||||
self.options['caption'] = ''
|
||||
|
||||
if 'include' not in self.options:
|
||||
self.options['include'] = 'undefined'
|
||||
else:
|
||||
lst = self.options['include'].split(',')
|
||||
lst = [x.strip() for x in lst]
|
||||
self.options['include'] = lst
|
||||
|
||||
if 'hidecode' in self.options:
|
||||
self.options['hidecode'] = 'none'
|
||||
else:
|
||||
self.options['hidecode'] = 'block'
|
||||
|
||||
if 'language' not in self.options:
|
||||
self.options['language'] = 'python'
|
||||
|
||||
return [ActivcodeNode(self.options)]
|
||||
|
||||
|
||||
class ActiveExercise(ActiveCode):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
has_content = True
|
||||
|
||||
def run(self):
|
||||
self.options['hidecode'] = True
|
||||
self.options['gradebutton'] = True
|
||||
return super(ActiveExercise,self).run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
a = ActiveCode()
|
||||
Loading…
Add table
Add a link
Reference in a new issue