Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
ed3f0817
Commit
ed3f0817
authored
May 21, 2012
by
Calen Pennington
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into asset-pipeline
parents
fe4f7bb2
4fe22be5
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
325 additions
and
52 deletions
+325
-52
djangoapps/courseware/capa/capa_problem.py
+14
-5
djangoapps/courseware/capa/inputtypes.py
+121
-2
djangoapps/courseware/capa/responsetypes.py
+13
-13
djangoapps/courseware/capa/util.py
+1
-0
djangoapps/courseware/module_render.py
+6
-4
djangoapps/courseware/views.py
+13
-16
djangoapps/multicourse/multicourse_settings.py
+5
-0
djangoapps/multicourse/views.py
+24
-1
lib/util/views.py
+0
-6
templates/mathjax_include.html
+89
-0
templates/mitxhome.html
+4
-4
templates/optioninput.html
+25
-0
templates/problem.html
+9
-0
urls.py
+1
-1
No files found.
djangoapps/courseware/capa/capa_problem.py
View file @
ed3f0817
...
...
@@ -25,6 +25,7 @@ from mako.template import Template
from
util
import
contextualize_text
import
inputtypes
from
responsetypes
import
NumericalResponse
,
FormulaResponse
,
CustomResponse
,
SchematicResponse
,
MultipleChoiceResponse
,
StudentInputError
,
TrueFalseResponse
,
ExternalResponse
,
ImageResponse
,
OptionResponse
import
calc
...
...
@@ -166,7 +167,7 @@ class LoncapaProblem(object):
problems_simple
=
self
.
extract_problems
(
self
.
tree
)
for
response
in
problems_simple
:
grader
=
response_types
[
response
.
tag
](
response
,
self
.
context
,
self
.
system
)
results
=
grader
.
g
rad
e
(
answers
)
# call the responsetype instance to do the actual grading
results
=
grader
.
g
et_scor
e
(
answers
)
# call the responsetype instance to do the actual grading
self
.
correct_map
.
update
(
results
)
return
self
.
correct_map
...
...
@@ -239,7 +240,7 @@ class LoncapaProblem(object):
# used to be
# if problemtree.tag in html_special_response:
if
hasattr
(
inputtypes
,
problemtree
.
tag
):
if
problemtree
.
tag
in
inputtypes
.
get_input_xml_tags
(
):
# status is currently the answer for the problem ID for the input element,
# but it will turn into a dict containing both the answer and any associated message
# for the problem ID for the input element.
...
...
@@ -266,9 +267,17 @@ class LoncapaProblem(object):
# print "[courseware.capa.capa_problem.extract_html] msg = ",msg
# do the rendering
#render_function = html_special_response[problemtree.tag]
render_function
=
getattr
(
inputtypes
,
problemtree
.
tag
)
return
render_function
(
problemtree
,
value
,
status
,
msg
)
# render the special response (textline, schematic,...)
# This should be broken out into a helper function
# that handles all input objects
render_object
=
inputtypes
.
SimpleInput
(
system
=
self
.
system
,
xml
=
problemtree
,
state
=
{
'value'
:
value
,
'status'
:
status
,
'id'
:
problemtree
.
get
(
'id'
),
'feedback'
:{
'message'
:
msg
}
},
use
=
'capa_input'
)
return
render_object
.
get_html
()
#function(problemtree, value, status, msg) # render the special response (textline, schematic,...)
tree
=
Element
(
problemtree
.
tag
)
for
item
in
problemtree
:
...
...
djangoapps/courseware/capa/inputtypes.py
View file @
ed3f0817
...
...
@@ -32,8 +32,121 @@ from lxml import etree
from
mitxmako.shortcuts
import
render_to_string
def
get_input_xml_tags
():
''' Eventually, this will be for all registered input types '''
return
SimpleInput
.
get_xml_tags
()
class
SimpleInput
():
# XModule
''' Type for simple inputs -- plain HTML with a form element
State is a dictionary with optional keys:
* Value
* ID
* Status (answered, unanswered, unsubmitted)
* Feedback (dictionary containing keys for hints, errors, or other
feedback from previous attempt)
'''
xml_tags
=
{}
## Maps tags to functions
@classmethod
def
get_xml_tags
(
c
):
return
c
.
xml_tags
.
keys
()
@classmethod
def
get_uses
(
c
):
return
[
'capa_input'
,
'capa_transform'
]
def
get_html
(
self
):
return
self
.
xml_tags
[
self
.
tag
](
self
.
xml
,
self
.
value
,
self
.
status
,
self
.
msg
)
def
__init__
(
self
,
system
,
xml
,
item_id
=
None
,
track_url
=
None
,
state
=
None
,
use
=
'capa_input'
):
self
.
xml
=
xml
self
.
tag
=
xml
.
tag
if
not
state
:
state
=
{}
## ID should only come from one place.
## If it comes from multiple, we use state first, XML second, and parameter
## third. Since we don't make this guarantee, we can swap this around in
## the future if there's a more logical order.
if
item_id
:
self
.
id
=
item_id
if
xml
.
get
(
'id'
):
self
.
id
=
xml
.
get
(
'id'
)
if
'id'
in
state
:
self
.
id
=
state
[
'id'
]
self
.
system
=
system
self
.
value
=
''
if
'value'
in
state
:
self
.
value
=
state
[
'value'
]
self
.
msg
=
''
if
'feedback'
in
state
and
'message'
in
state
[
'feedback'
]:
self
.
msg
=
state
[
'feedback'
][
'message'
]
self
.
status
=
'unanswered'
if
'status'
in
state
:
self
.
status
=
state
[
'status'
]
## TODO
# class SimpleTransform():
# ''' Type for simple XML to HTML transforms. Examples:
# * Math tags, which go from LON-CAPA-style m-tags to MathJAX
# '''
# xml_tags = {} ## Maps tags to functions
# @classmethod
# def get_xml_tags(c):
# return c.xml_tags.keys()
# @classmethod
# def get_uses(c):
# return ['capa_transform']
# def get_html(self):
# return self.xml_tags[self.tag](self.xml, self.value, self.status, self.msg)
# def __init__(self, system, xml, item_id = None, track_url=None, state=None, use = 'capa_input'):
# self.xml = xml
# self.tag = xml.tag
# if not state:
# state = {}
# if item_id:
# self.id = item_id
# if xml.get('id'):
# self.id = xml.get('id')
# if 'id' in state:
# self.id = state['id']
# self.system = system
# self.value = ''
# if 'value' in state:
# self.value = state['value']
# self.msg = ''
# if 'feedback' in state and 'message' in state['feedback']:
# self.msg = state['feedback']['message']
# self.status = 'unanswered'
# if 'status' in state:
# self.status = state['status']
def
register_render_function
(
fn
,
names
=
None
,
cls
=
SimpleInput
):
if
names
==
None
:
SimpleInput
.
xml_tags
[
fn
.
__name__
]
=
fn
else
:
raise
NotImplementedError
def
wrapped
():
return
fn
return
wrapped
#-----------------------------------------------------------------------------
@register_render_function
def
optioninput
(
element
,
value
,
status
,
msg
=
''
):
'''
Select option input type.
...
...
@@ -67,7 +180,7 @@ def optioninput(element, value, status, msg=''):
return
etree
.
XML
(
html
)
#-----------------------------------------------------------------------------
@register_render_function
def
choicegroup
(
element
,
value
,
status
,
msg
=
''
):
'''
Radio button inputs: multiple choice or true/false
...
...
@@ -90,6 +203,7 @@ def choicegroup(element, value, status, msg=''):
html
=
render_to_string
(
"choicegroup.html"
,
context
)
return
etree
.
XML
(
html
)
@register_render_function
def
textline
(
element
,
value
,
state
,
msg
=
""
):
eid
=
element
.
get
(
'id'
)
count
=
int
(
eid
.
split
(
'_'
)[
-
2
])
-
1
# HACK
...
...
@@ -100,6 +214,7 @@ def textline(element, value, state, msg=""):
#-----------------------------------------------------------------------------
@register_render_function
def
js_textline
(
element
,
value
,
status
,
msg
=
''
):
'''
Plan: We will inspect element to figure out type
...
...
@@ -125,6 +240,7 @@ def js_textline(element, value, status, msg=''):
#-----------------------------------------------------------------------------
## TODO: Make a wrapper for <codeinput>
@register_render_function
def
textbox
(
element
,
value
,
status
,
msg
=
''
):
'''
The textbox is used for code input. The message is the return HTML string from
...
...
@@ -140,6 +256,7 @@ def textbox(element, value, status, msg=''):
return
etree
.
XML
(
html
)
#-----------------------------------------------------------------------------
@register_render_function
def
schematic
(
element
,
value
,
status
,
msg
=
''
):
eid
=
element
.
get
(
'id'
)
height
=
element
.
get
(
'height'
)
...
...
@@ -164,6 +281,7 @@ def schematic(element, value, status, msg=''):
#-----------------------------------------------------------------------------
### TODO: Move out of inputtypes
@register_render_function
def
math
(
element
,
value
,
status
,
msg
=
''
):
'''
This is not really an input type. It is a convention from Lon-CAPA, used for
...
...
@@ -198,6 +316,7 @@ def math(element, value, status, msg=''):
#-----------------------------------------------------------------------------
@register_render_function
def
solution
(
element
,
value
,
status
,
msg
=
''
):
'''
This is not really an input type. It is just a <span>...</span> which is given an ID,
...
...
@@ -218,6 +337,7 @@ def solution(element, value, status, msg=''):
#-----------------------------------------------------------------------------
@register_render_function
def
imageinput
(
element
,
value
,
status
,
msg
=
''
):
'''
Clickable image as an input field. Element should specify the image source, height, and width, eg
...
...
@@ -253,4 +373,3 @@ def imageinput(element, value, status, msg=''):
print
'[courseware.capa.inputtypes.imageinput] context='
,
context
html
=
render_to_string
(
"imageinput.html"
,
context
)
return
etree
.
XML
(
html
)
djangoapps/courseware/capa/responsetypes.py
View file @
ed3f0817
...
...
@@ -47,10 +47,10 @@ def compare_with_tolerance(v1, v2, tol):
return
abs
(
v1
-
v2
)
<=
tolerance
class
GenericResponse
(
object
):
__metaclass__
=
abc
.
ABCMeta
__metaclass__
=
abc
.
ABCMeta
# abc = Abstract Base Class
@abc.abstractmethod
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
pass
@abc.abstractmethod
...
...
@@ -61,7 +61,7 @@ class GenericResponse(object):
def
preprocess_response
(
self
):
pass
#Every response type needs methods "g
rad
e" and "get_answers"
#Every response type needs methods "g
et_scor
e" and "get_answers"
#-----------------------------------------------------------------------------
...
...
@@ -95,7 +95,7 @@ class MultipleChoiceResponse(GenericResponse):
raise
Exception
(
"should have exactly one choice group per multiplechoicceresponse"
)
self
.
answer_id
=
self
.
answer_id
[
0
]
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
if
self
.
answer_id
in
student_answers
and
student_answers
[
self
.
answer_id
]
in
self
.
correct_choices
:
return
{
self
.
answer_id
:
'correct'
}
else
:
...
...
@@ -132,7 +132,7 @@ class TrueFalseResponse(MultipleChoiceResponse):
else
:
choice
.
set
(
"name"
,
"choice_"
+
choice
.
get
(
"name"
))
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
correct
=
set
(
self
.
correct_choices
)
answers
=
set
(
student_answers
.
get
(
self
.
answer_id
,
[]))
...
...
@@ -162,7 +162,7 @@ class OptionResponse(GenericResponse):
print
'[courseware.capa.responsetypes.OR.init] answer_fields=
%
s'
%
(
self
.
answer_fields
)
self
.
context
=
context
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
cmap
=
{}
amap
=
self
.
get_answers
()
for
aid
in
amap
:
...
...
@@ -194,7 +194,7 @@ class NumericalResponse(GenericResponse):
except
Exception
,
err
:
self
.
answer_id
=
None
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
''' Display HTML for a numeric response '''
student_answer
=
student_answers
[
self
.
answer_id
]
try
:
...
...
@@ -300,7 +300,7 @@ def sympy_check2():
else
:
self
.
code
=
answer
.
text
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
'''
student_answers is a dict with everything from request.POST, but with the first part
of each key removed (the string before the first "_").
...
...
@@ -363,7 +363,7 @@ def sympy_check2():
print
"oops in customresponse (cfn) error
%
s"
%
err
# print "context = ",self.context
print
traceback
.
format_exc
()
if
settings
.
DEBUG
:
print
"[courseware.capa.responsetypes.customresponse.g
rad
e] ret = "
,
ret
if
settings
.
DEBUG
:
print
"[courseware.capa.responsetypes.customresponse.g
et_scor
e] ret = "
,
ret
if
type
(
ret
)
==
dict
:
correct
[
0
]
=
'correct'
if
ret
[
'ok'
]
else
'incorrect'
msg
=
ret
[
'msg'
]
...
...
@@ -428,7 +428,7 @@ class ExternalResponse(GenericResponse):
self
.
tests
=
xml
.
get
(
'answer'
)
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
submission
=
[
student_answers
[
k
]
for
k
in
sorted
(
self
.
answer_ids
)]
self
.
context
.
update
({
'submission'
:
submission
})
...
...
@@ -504,7 +504,7 @@ class FormulaResponse(GenericResponse):
self
.
case_sensitive
=
False
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
variables
=
self
.
samples
.
split
(
'@'
)[
0
]
.
split
(
','
)
numsamples
=
int
(
self
.
samples
.
split
(
'@'
)[
1
]
.
split
(
'#'
)[
1
])
sranges
=
zip
(
*
map
(
lambda
x
:
map
(
float
,
x
.
split
(
","
)),
...
...
@@ -566,7 +566,7 @@ class SchematicResponse(GenericResponse):
else
:
self
.
code
=
answer
.
text
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
from
capa_problem
import
global_context
submission
=
[
json
.
loads
(
student_answers
[
k
])
for
k
in
sorted
(
self
.
answer_ids
)]
self
.
context
.
update
({
'submission'
:
submission
})
...
...
@@ -605,7 +605,7 @@ class ImageResponse(GenericResponse):
self
.
ielements
=
xml
.
findall
(
'imageinput'
)
self
.
answer_ids
=
[
ie
.
get
(
'id'
)
for
ie
in
self
.
ielements
]
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
correct_map
=
{}
expectedset
=
self
.
get_answers
()
...
...
djangoapps/courseware/capa/util.py
View file @
ed3f0817
def
contextualize_text
(
text
,
context
):
# private
''' Takes a string with variables. E.g. $a+$b.
Does a substitution of those variables from the context '''
if
not
text
:
return
text
for
key
in
sorted
(
context
,
lambda
x
,
y
:
cmp
(
len
(
y
),
len
(
x
))):
text
=
text
.
replace
(
'$'
+
key
,
str
(
context
[
key
]))
return
text
djangoapps/courseware/module_render.py
View file @
ed3f0817
...
...
@@ -13,8 +13,8 @@ from fs.osfs import OSFS
from
django.conf
import
settings
from
mitxmako.shortcuts
import
render_to_string
from
models
import
StudentModule
from
multicourse
import
multicourse_settings
import
courseware.modules
...
...
@@ -31,6 +31,8 @@ class I4xSystem(object):
self
.
track_function
=
track_function
if
not
filestore
:
self
.
filestore
=
OSFS
(
settings
.
DATA_DIR
)
else
:
self
.
filestore
=
filestore
self
.
render_function
=
render_function
self
.
exception404
=
Http404
def
__repr__
(
self
):
...
...
@@ -95,15 +97,15 @@ def render_x_module(user, request, xml_module, module_object_preload):
state
=
smod
.
state
# get coursename if stored
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
else
:
coursename
=
Non
e
coursename
=
multicourse_settings
.
get_coursename_from_request
(
request
)
xp
=
multicourse_settings
.
get_course_xmlpath
(
coursename
)
# path to XML for the cours
e
# Create a new instance
ajax_url
=
settings
.
MITX_ROOT_URL
+
'/modx/'
+
module_type
+
'/'
+
module_id
+
'/'
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
render_function
=
lambda
x
:
render_module
(
user
,
request
,
x
,
module_object_preload
),
ajax_url
=
ajax_url
,
filestore
=
None
filestore
=
OSFS
(
settings
.
DATA_DIR
+
xp
),
)
instance
=
module_class
(
system
,
etree
.
tostring
(
xml_module
),
...
...
djangoapps/courseware/views.py
View file @
ed3f0817
...
...
@@ -2,6 +2,8 @@ import logging
import
urllib
import
json
from
fs.osfs
import
OSFS
from
django.conf
import
settings
from
django.core.context_processors
import
csrf
from
django.contrib.auth.models
import
User
...
...
@@ -38,9 +40,7 @@ def gradebook(request):
if
'course_admin'
not
in
content_parser
.
user_groups
(
request
.
user
):
raise
Http404
# TODO: This should be abstracted out. We repeat this logic many times.
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
else
:
coursename
=
None
coursename
=
multicourse_settings
.
get_coursename_from_request
(
request
)
student_objects
=
User
.
objects
.
all
()[:
100
]
student_info
=
[{
'username'
:
s
.
username
,
...
...
@@ -68,8 +68,7 @@ def profile(request, student_id = None):
user_info
=
UserProfile
.
objects
.
get
(
user
=
student
)
# request.user.profile_cache #
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
else
:
coursename
=
None
coursename
=
multicourse_settings
.
get_coursename_from_request
(
request
)
context
=
{
'name'
:
user_info
.
name
,
'username'
:
student
.
username
,
...
...
@@ -110,8 +109,7 @@ def render_section(request, section):
if
not
settings
.
COURSEWARE_ENABLED
:
return
redirect
(
'/'
)
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
else
:
coursename
=
None
coursename
=
multicourse_settings
.
get_coursename_from_request
(
request
)
try
:
dom
=
content_parser
.
section_file
(
user
,
section
,
coursename
)
...
...
@@ -251,8 +249,8 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
ajax_url
=
settings
.
MITX_ROOT_URL
+
'/modx/'
+
module
+
'/'
+
id
+
'/'
# get coursename if stored
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
else
:
coursename
=
Non
e
coursename
=
multicourse_settings
.
get_coursename_from_request
(
request
)
xp
=
multicourse_settings
.
get_course_xmlpath
(
coursename
)
# path to XML for the cours
e
# Grab the XML corresponding to the request from course.xml
try
:
...
...
@@ -269,7 +267,7 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
render_function
=
None
,
ajax_url
=
ajax_url
,
filestore
=
None
filestore
=
OSFS
(
settings
.
DATA_DIR
+
xp
),
)
try
:
...
...
@@ -307,12 +305,12 @@ def quickedit(request, id=None):
print
"In deployed use, this will only edit on one server"
print
"We need a setting to disable for production where there is"
print
"a load balanacer"
if
not
request
.
user
.
is_staff
()
:
if
not
request
.
user
.
is_staff
:
return
redirect
(
'/'
)
# get coursename if stored
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
else
:
coursename
=
Non
e
coursename
=
multicourse_settings
.
get_coursename_from_request
(
request
)
xp
=
multicourse_settings
.
get_course_xmlpath
(
coursename
)
# path to XML for the cours
e
def
get_lcp
(
coursename
,
id
):
# Grab the XML corresponding to the request from course.xml
...
...
@@ -325,9 +323,8 @@ def quickedit(request, id=None):
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
render_function
=
None
,
ajax_url
=
ajax_url
,
filestore
=
None
,
coursename
=
coursename
,
role
=
'staff'
if
request
.
user
.
is_staff
else
'student'
,
# TODO: generalize this
filestore
=
OSFS
(
settings
.
DATA_DIR
+
xp
),
#role = 'staff' if request.user.is_staff else 'student', # TODO: generalize this
)
instance
=
courseware
.
modules
.
get_module_class
(
module
)(
system
,
xml
,
...
...
djangoapps/multicourse/multicourse_settings.py
View file @
ed3f0817
...
...
@@ -42,6 +42,11 @@ else: # default to 6.002_Spring_2012
#-----------------------------------------------------------------------------
# wrapper functions around course settings
def
get_coursename_from_request
(
request
):
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
else
:
coursename
=
None
return
coursename
def
get_course_settings
(
coursename
):
if
not
coursename
:
if
hasattr
(
settings
,
'COURSE_DEFAULT'
):
...
...
djangoapps/multicourse/views.py
View file @
ed3f0817
# multicourse/views.py
import
datetime
import
json
import
sys
from
django.conf
import
settings
from
django.contrib.auth.models
import
User
from
django.core.context_processors
import
csrf
from
django.core.mail
import
send_mail
from
django.http
import
Http404
from
django.http
import
HttpResponse
from
django.shortcuts
import
redirect
from
mitxmako.shortcuts
import
render_to_response
,
render_to_string
import
courseware.capa.calc
import
track.views
from
multicourse
import
multicourse_settings
def
mitxhome
(
request
):
''' Home page (link from main header). List of courses. '''
if
settings
.
ENABLE_MULTICOURSE
:
context
=
{
'courseinfo'
:
multicourse_settings
.
COURSE_SETTINGS
}
return
render_to_response
(
"mitxhome.html"
,
context
)
return
info
(
request
)
lib/util/views.py
View file @
ed3f0817
...
...
@@ -61,12 +61,6 @@ def info(request):
''' Info page (link from main header) '''
return
render_to_response
(
"info.html"
,
{})
def
mitxhome
(
request
):
''' Home page (link from main header). List of courses. '''
if
settings
.
ENABLE_MULTICOURSE
:
return
render_to_response
(
"mitxhome.html"
,
{})
return
info
(
request
)
# From http://djangosnippets.org/snippets/1042/
def
parse_accept_header
(
accept
):
"""Parse the Accept header *accept*, returning a list with pairs of
...
...
templates/mathjax_include.html
0 → 100644
View file @
ed3f0817
##
## File: templates/mathjax_include.html
##
## Advanced mathjax using 2.0-latest CDN for Dynamic Math
##
## This enables ASCIIMathJAX, and is used by js_textbox
<script
type=
"text/x-mathjax-config"
>
// (function () {
var
QUEUE
=
MathJax
.
Hub
.
queue
;
// shorthand for the queue
var
math
=
null
;
var
jaxset
=
{};
// associative array of the element jaxs for the math output.
var
mmlset
=
{};
// associative array of mathml from each jax
// constructs mathML of the specified jax element
function
toMathML
(
jax
,
callback
)
{
var
mml
;
try
{
mml
=
jax
.
root
.
toMathML
(
""
);
}
catch
(
err
)
{
if
(
!
err
.
restart
)
{
throw
err
}
// an actual error
return
MathJax
.
Callback
.
After
([
toMathML
,
jax
,
callback
],
err
.
restart
);
}
MathJax
.
Callback
(
callback
)(
mml
);
}
// function to queue in MathJax to get put the MathML expression in in the right document element
function
UpdateMathML
(
jax
,
id
)
{
toMathML
(
jax
,
function
(
mml
)
{
// document.getElementById(id+'_fromjs').value=math.originalText+ "\n\n=>\n\n"+ mml;
delem
=
document
.
getElementById
(
"input_"
+
id
+
"_fromjs"
);
if
(
delem
)
{
delem
.
value
=
mml
;
};
mmlset
[
id
]
=
mml
;
})
}
MathJax
.
Hub
.
Config
({
tex2jax
:
{
inlineMath
:
[
[
"
\\
("
,
"
\\
)"
],
[
'[mathjaxinline]'
,
'[/mathjaxinline]'
]
],
displayMath
:
[
[
"
\\
["
,
"
\\
]"
],
[
'[mathjax]'
,
'[/mathjax]'
]
]
}
});
//
// The onchange event handler that typesets the
// math entered by the user
//
window
.
UpdateMath
=
function
(
Am
,
id
)
{
QUEUE
.
Push
([
"Text"
,
jaxset
[
id
],
Am
]);
QUEUE
.
Push
(
UpdateMathML
(
jaxset
[
id
],
id
));
}
// })();
function
DoUpdateMath
(
inputId
)
{
var
str
=
document
.
getElementById
(
"input_"
+
inputId
).
value
;
// make sure the input field is in the jaxset
if
(
$
.
inArray
(
inputId
,
jaxset
)
==
-
1
){
//alert('missing '+inputId);
if
(
document
.
getElementById
(
"display_"
+
inputId
)){
MathJax
.
Hub
.
queue
.
Push
(
function
()
{
math
=
MathJax
.
Hub
.
getAllJax
(
"display_"
+
inputId
)[
0
];
if
(
math
){
jaxset
[
inputId
]
=
math
;
}
});
};
}
UpdateMath
(
str
,
inputId
)
}
</script>
<
%
block
name=
"headextra"
/>
<!-- This must appear after all mathjax-config blocks, so it is after the imports from the other templates -->
<!-- TODO: move to settings -->
<script
type=
"text/javascript"
src=
"http://cdn.mathjax.org/mathjax/2.0-latest/MathJax.js?config=TeX-MML-AM_HTMLorMML-full"
>
</script>
templates/mitxhome.html
View file @
ed3f0817
...
...
@@ -28,10 +28,10 @@ $(document).ready(function(){
<hr
width=
"100%"
>
<h3>
Courses available:
</h3>
<ul>
<li><a
href=
${
MITX_ROOT_URL
}/
courseware
/
6
.
002_Spring_2012
/>
6.002 (Spring 2012)
</a></li>
<li><a
href=
${
MITX_ROOT_URL
}/
courseware
/
8
.
02_Spring_2013
/>
8.02 (Spring 2013
)
</a></li>
<li><a
href=
${
MITX_ROOT_URL
}/
courseware
/
8
.
01_Spring_2013
/>
8.01 (Spring 201x)
</a></li>
</ul>
% for coursename, info in courseinfo.items():
<li><a
href=
${
MITX_ROOT_URL
}/
courseware
/${
coursename
}
/>
${info['title']} (${coursename}
)
</a></li>
% endfor
</ul>
</section>
</div>
</section>
templates/optioninput.html
0 → 100644
View file @
ed3f0817
<form
class=
"option-input"
>
<select
name=
"input_${id}"
id=
"input_${id}"
>
<option
value=
"option_${id}_dummy_default"
>
</option>
% for option_id, option_description in options.items():
<option
value=
"${option_id}"
%
if
(
option_id=
=value):
selected=
"true"
%
endif
>
${option_description}
</option>
% endfor
</select>
<span
id=
"answer_${id}"
></span>
% if state == 'unsubmitted':
<span
class=
"unanswered"
style=
"display:inline-block;"
id=
"status_${id}"
></span>
% elif state == 'correct':
<span
class=
"correct"
id=
"status_${id}"
></span>
% elif state == 'incorrect':
<span
class=
"incorrect"
id=
"status_${id}"
></span>
% elif state == 'incomplete':
<span
class=
"incorrect"
id=
"status_${id}"
></span>
% endif
</form>
templates/problem.html
View file @
ed3f0817
...
...
@@ -3,6 +3,15 @@
% if problem['weight']:
: ${ problem['weight'] } points
% endif
% if settings.QUICKEDIT:
<span
class=
"staff"
>
<br/>
<br/>
<br/>
<br/>
<font
size=
-2
><a
href=
${MITX_ROOT_URL}/quickedit/${id}
>
Quick
Edit Problem
</a></font></span>
% endif
</h2>
<section
class=
"problem"
>
...
...
urls.py
View file @
ed3f0817
...
...
@@ -70,7 +70,7 @@ if settings.COURSEWARE_ENABLED:
)
if
settings
.
ENABLE_MULTICOURSE
:
urlpatterns
+=
(
url
(
r'^mitxhome$'
,
'
util
.views.mitxhome'
),)
urlpatterns
+=
(
url
(
r'^mitxhome$'
,
'
multicourse
.views.mitxhome'
),)
if
settings
.
QUICKEDIT
:
urlpatterns
+=
(
url
(
r'^quickedit/(?P<id>[^/]*)$'
,
'courseware.views.quickedit'
),)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment