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
612f381e
Commit
612f381e
authored
Aug 02, 2012
by
Mike Chen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
GeneralResponse in Wiki syntax and formularesponse rendering
parent
d256b929
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
237 additions
and
32 deletions
+237
-32
cms/static/grammars/main.jspeg
+187
-21
common/lib/xmodule/xmodule/js/src/capa/edit.coffee
+50
-11
No files found.
cms/static/grammars/main.jspeg
View file @
612f381e
/* null_ is used in JSON parser */
{
null_ = new Object();
}
start
start
= sections:(Image /
= sections:(Image /
GeneralResponse /
NumericalOrStringResponse /
NumericalOrStringResponse /
NumericalResponse /
NumericalResponse /
MultipleChoice /
MultipleChoice /
Paragraph /
Paragraph
PreservedLinebreaks)+
)+
/* GeneralResponse */
KeyValueString
= QuotedString
/ chars:[^: \n]+
{
return chars.join("");
}
KeyValuePair
= key:KeyValueString _ ':' _ value:KeyValueString
{
return {'key': key, 'value': value};
}
InlineGeneralResponse
= CorrectAnswerIdentifier pairs:(' '+ KeyValuePair)+ Linebreak
{
ret = {};
pairs = pairs.map(function (x) { return x[1]; });
for (var i = 0; i < pairs.length; i++) {
console.log(pairs);
if (ret[pairs[i].key] == undefined)
ret[pairs[i].key] = pairs[i].value;
else
throw new SyntaxError("Key " + pairs[i].key + " was used more than once. " );
}
return ret;
}
GeneralResponseValue
= InlineGeneralResponse / JSONDictionary
GeneralResponse
= dic:GeneralResponseValue
{
if (dic.type == undefined) {
throw new SyntaxError("Please define 'type' in response. ")
}
return dic;
}
/* Image */
/* Image */
ImageLink
ImageLink
=
Double
QuotedString
= QuotedString
/ chars:( (!')' [^\n])+)
/ chars:( (!')' [^\n])+)
{
{
return $.trim(chars.map(function(element) { return element[1]; }).join(""));
return $.trim(chars.map(function(element) { return element[1]; }).join(""));
...
@@ -22,7 +70,7 @@ ImageTitle
...
@@ -22,7 +70,7 @@ ImageTitle
}
}
Image
Image
= ImageIdentifier title:ImageTitle?
OptionalSpaces '(' OptionalSpaces url:ImageLink ')' OptionalSpaces
Linebreak
= ImageIdentifier title:ImageTitle?
_ '(' _ url:ImageLink ')' ' '*
Linebreak
{
{
return {'type': 'image', 'url': url, 'title': title};
return {'type': 'image', 'url': url, 'title': title};
}
}
...
@@ -38,19 +86,19 @@ ChoiceIdentifier
...
@@ -38,19 +86,19 @@ ChoiceIdentifier
ImageIdentifier
ImageIdentifier
= '!'
= '!'
StudentProducedResponse
Identifier
CorrectAnswer
Identifier
= '='
= '='
/* StringResponse */
/* StringResponse */
StringResponse
StringResponse
=
StudentProducedResponseIdentifier OptionalSpaces !'(' value:Text
Linebreak
=
CorrectAnswerIdentifier _ !'(' value:(QuotedString / Text)
Linebreak
{
{
return {'type': 'string', 'answer': $.trim(value)};
return {'type': 'string', 'answer': $.trim(value)};
}
}
NumericalOrStringResponse
NumericalOrStringResponse
=
StudentProducedResponseIdentifier OptionalSpaces value:NumericalValue OptionalSpaces tolerance:NumericalTolerance? OptionalSpaces
Linebreak
=
CorrectAnswerIdentifier _ value:NumericalValue _ tolerance:NumericalTolerance? _
Linebreak
{
{
if (tolerance == "")
if (tolerance == "")
tolerance = "5%"
tolerance = "5%"
...
@@ -79,9 +127,11 @@ MultipleChoice
...
@@ -79,9 +127,11 @@ MultipleChoice
}
}
/* Paragraph */
/* Paragraph */
LineOrLinebreak
= Line / Linebreak
ParagraphTextLine
ParagraphTextLine
= !
ImageIdentifier !ChoiceIdentifier !StudentProducedResponseIdentifier line:Line
= !
JSONDictionary !ImageIdentifier !ChoiceIdentifier !CorrectAnswerIdentifier line:LineOrLinebreak
{
{
return line;
return line;
}
}
...
@@ -89,7 +139,7 @@ ParagraphTextLine
...
@@ -89,7 +139,7 @@ ParagraphTextLine
Paragraph
Paragraph
= lines:ParagraphTextLine+
= lines:ParagraphTextLine+
{
{
return {'type': '
paragraph
', 'text': lines.join("")};
return {'type': '
text
', 'text': lines.join("")};
}
}
/* Base symbols */
/* Base symbols */
...
@@ -106,49 +156,165 @@ Text
...
@@ -106,49 +156,165 @@ Text
return chars.join("");
return chars.join("");
}
}
OptionalSpaces
AndLines
_
AndLines
= (' ' / '\n' / '\t')*
= (' ' / '\n' / '\t')*
OptionalSpaces
_
= (' ' / '\t')*
= (' ' / '\t')*
PreservedLinebreaks
= terminators:('\n')+
{
return {'type': 'linebreaks', 'count': terminators.length}
}
Linebreak
Linebreak
= ('\n')
= ('\n')
QuotedString
= DoubleQuotedString / SingleQuotedString
DoubleQuotedString
DoubleQuotedString
= "\"\"" { return ""; }
= "\"\"" { return ""; }
/ "\"" str:(!Unescaped
Quote .)* last:Unescaped
Quote {
/ "\"" str:(!Unescaped
DoubleQuote .)* last:UnescapedDouble
Quote {
return str.map(function(element) { return element[1]; }).join("") + last;
return str.map(function(element) { return element[1]; }).join("") + last;
}
}
UnescapedQuote
Unescaped
Double
Quote
= last:[^\\] "\"" {return last;}
= last:[^\\] "\"" {return last;}
SingleQuotedString
= "''" { return ""; }
/ "'" str:(!UnescapedSingleQuote .)* last:UnescapedSingleQuote {
return str.map(function(element) { return element[1]; }).join("") + last;
}
UnescapedSingleQuote
= last:[^\\] "'" {return last;}
AlphanumericalText
AlphanumericalText
= chars:[a-zA-Z0-9]+
= chars:[a-zA-Z0-9]+
{
{
return chars.join("");
return chars.join("");
}
}
/* JSON */
/* JSON parser based on the grammar described at http://json.org/. */
JSONDictionary
= _ o:object { return o; }
object
= "{" _ "}" _ { return {}; }
/ "{" _ members:members "}" _ { return members; }
members
= head:pair tail:("," _ pair)* {
var result = {};
result[head[0]] = (head[1] === null_ ? null : head[1]);
for (var i = 0; i < tail.length; i++) {
result[tail[i][2][0]] = (tail[i][2][1] === null_ ? null : tail[i][2][1]);
}
return result;
}
pair
= name:string ":" _ value:value { return [name, value]; }
array
= "[" _ "]" _ { return []; }
/ "[" _ elements:elements "]" _ { return elements; }
elements
= head:value tail:("," _ value)* {
var result = [head === null_ ? null : head];
for (var i = 0; i < tail.length; i++) {
result.push(tail[i][2] === null_ ? null : tail[i][2]);
}
return result;
}
value
= string
/ number
/ object
/ array
/ "true" _ { return true; }
/ "false" _ { return false; }
/ "null" _ { return null_; }
string "string"
= '"' '"' _ { return ""; }
/ '"' chars:chars '"' _ { return chars; }
chars
= chars:char+ { return chars.join(""); }
char
// In the original JSON grammar: "any-Unicode-character-except-"-or-\-or-control-character"
= [^"\\\0-\x1F\x7f]
/ '\\"' { return '"'; }
/ "\\\\" { return "\\"; }
/ "\\/" { return "/"; }
/ "\\b" { return "\b"; }
/ "\\f" { return "\f"; }
/ "\\n" { return "\n"; }
/ "\\r" { return "\r"; }
/ "\\t" { return "\t"; }
/ "\\u" h1:hexDigit h2:hexDigit h3:hexDigit h4:hexDigit {
return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4));
}
number "number"
= int_:int frac:frac exp:exp _ { return parseFloat(int_ + frac + exp); }
/ int_:int frac:frac _ { return parseFloat(int_ + frac); }
/ int_:int exp:exp _ { return parseFloat(int_ + exp); }
/ int_:int _ { return parseFloat(int_); }
int
= digit19:digit19 digits:digits { return digit19 + digits; }
/ digit:digit
/ "-" digit19:digit19 digits:digits { return "-" + digit19 + digits; }
/ "-" digit:digit { return "-" + digit; }
frac
= "." digits:digits { return "." + digits; }
exp
= e:e digits:digits { return e + digits; }
digits
= digits:digit+ { return digits.join(""); }
e
= e:[eE] sign:[+-]? { return e + sign; }
digit
= [0-9]
digit19
= [1-9]
hexDigit
= [0-9a-fA-F]
_ "whitespace"
= whitespace*
// Whitespace is undefined in the original JSON grammar, so I assume a simple
// conventional definition consistent with ECMA-262, 5th ed.
whitespace
= [ \t\n\r]
/* NumericalResponse */
/* NumericalResponse */
NumericalToleranceValueType
NumericalToleranceValueType
= decimal / percentage / integer
= decimal / percentage / integer
NumericalTolerance
NumericalTolerance
= '+-'
OptionalSpaces value:NumericalToleranceValueType OptionalSpaces
= '+-'
_ value:NumericalToleranceValueType _
{
{
return value;
return value;
}
}
NumericalResponse
NumericalResponse
=
StudentProducedResponseIdentifier OptionalSpaces '(' OptionalSpaces value:NumericalValue OptionalSpaces tolerance:NumericalTolerance? ')' OptionalSpaces
Linebreak
=
CorrectAnswerIdentifier _ '(' _ value:NumericalValue _ tolerance:NumericalTolerance? ')' _
Linebreak
{
{
if (tolerance == "")
if (tolerance == "")
tolerance = "5%"
tolerance = "5%"
...
...
common/lib/xmodule/xmodule/js/src/capa/edit.coffee
View file @
612f381e
class
@
CapaDescriptor
class
@
CapaDescriptor
constructor
:
(
@
element
)
->
constructor
:
(
@
element
)
->
@
problem_text
=
""
@
edit_box
=
$
(
".edit-box.capa-box"
,
@
element
)
@
edit_box
=
$
(
".edit-box.capa-box"
,
@
element
)
@
source_box
=
$
(
".edit-box.source-box"
,
@
element
)
@
source_box
=
$
(
".edit-box.source-box"
,
@
element
)
@
message_box
=
$
(
".parser-message-box"
,
@
element
)
@
message_box
=
$
(
".parser-message-box"
,
@
element
)
@
buildParser
()
@
buildParser
()
@
throttledAutoSave
=
_
.
throttle
(
@
autoSave
,
0
);
@
source_box
.
keyup
=>
@
source_box
.
keyup
=>
@
parse
()
@
parse
()
...
@@ -20,6 +22,19 @@ class @CapaDescriptor
...
@@ -20,6 +22,19 @@ class @CapaDescriptor
"Line "
+
e
.
line
+
", column "
+
e
.
column
+
": "
+
e
.
message
"Line "
+
e
.
line
+
", column "
+
e
.
column
+
": "
+
e
.
message
else
e
.
message
else
e
.
message
checkAutoSaveTimeout
:
->
@
auto_save_timer
=
null
@
throttledAutoSave
()
checkAutoSave
:
->
callback
=
_
.
bind
(
@
checkAutoSaveTimeout
,
this
)
if
@
auto_save_timer
@
auto_save_timer
=
window
.
clearTimeout
(
@
auto_save_timer
)
@
auto_save_timer
=
window
.
setTimeout
(
callback
,
1000
)
autoSave
:
(
event
)
->
$
(
".save-update"
).
click
();
parse
:
->
parse
:
->
try
try
source
=
@
source_box
.
val
()
+
"
\n
"
source
=
@
source_box
.
val
()
+
"
\n
"
...
@@ -34,25 +49,27 @@ class @CapaDescriptor
...
@@ -34,25 +49,27 @@ class @CapaDescriptor
outputXML
:
(
parsed
)
->
outputXML
:
(
parsed
)
->
@
edit_box
.
val
@
buildXML
(
parsed
)
@
edit_box
.
val
@
buildXML
(
parsed
)
@
checkAutoSave
()
dom2capa
:
(
node
)
->
dom2capa
:
(
node
)
->
capa
=
new
XMLSerializer
().
serializeToString
(
node
)
serializer
=
new
XMLSerializer
()
capa
=
capa
+
""
capa
=
serializer
.
serializeToString
(
node
)
return
capa
.
replace
(
/<startouttext>/g
,
'<startouttext />'
)
.
replace
(
/<\/startouttext>/g
,
'<endouttext />'
)
buildXML
:
(
parsed
)
->
buildXML
:
(
parsed
)
->
dom_parser
=
new
DOMParser
()
dom_parser
=
new
DOMParser
()
doc
=
dom_parser
.
parseFromString
(
"<problem
></problem
>"
,
"text/xml"
);
doc
=
dom_parser
.
parseFromString
(
"<problem
/
>"
,
"text/xml"
);
problem
=
$
(
doc
.
getElementsByTagName
(
'problem'
)[
0
]
)
problem
=
$
(
doc
).
find
(
'problem'
)
create_text_element
=
(
content
)
->
create_text_element
=
(
content
)
->
el
=
$
(
doc
.
createElement
(
'startouttext'
))
el
=
$
(
doc
.
createElement
(
'text'
))
el
.
text
content
for
line
in
content
.
split
(
'
\n
'
)
el
.
append
doc
.
createTextNode
(
line
)
el
.
append
doc
.
createElement
(
'br'
)
el
.
children
().
last
().
remove
()
return
el
return
el
for
section
in
parsed
for
section
in
parsed
if
section
.
type
==
'
paragraph
'
if
section
.
type
==
'
text
'
newel
=
create_text_element
(
section
.
text
)
newel
=
create_text_element
(
section
.
text
)
problem
.
append
(
newel
)
problem
.
append
(
newel
)
...
@@ -103,6 +120,8 @@ class @CapaDescriptor
...
@@ -103,6 +120,8 @@ class @CapaDescriptor
tolerance
=
$
(
doc
.
createElement
(
'responseparam'
))
tolerance
=
$
(
doc
.
createElement
(
'responseparam'
))
tolerance
.
attr
'type'
,
'tolerance'
tolerance
.
attr
'type'
,
'tolerance'
if
section
.
tolerance
==
undefined
section
.
tolerance
=
"5%"
tolerance
.
attr
'default'
,
section
.
tolerance
tolerance
.
attr
'default'
,
section
.
tolerance
tolerance
.
attr
'name'
,
'tol'
tolerance
.
attr
'name'
,
'tol'
tolerance
.
attr
'description'
,
'Numerical Tolerance'
tolerance
.
attr
'description'
,
'Numerical Tolerance'
...
@@ -117,6 +136,27 @@ class @CapaDescriptor
...
@@ -117,6 +136,27 @@ class @CapaDescriptor
newel
.
append
doc
.
createElement
(
'textline'
)
newel
.
append
doc
.
createElement
(
'textline'
)
problem
.
append
(
newel
)
problem
.
append
(
newel
)
else
if
section
.
type
==
'formula'
formularesponse
=
$
(
doc
.
createElement
(
"formularesponse"
))
formularesponse
.
attr
'samples'
,
section
.
samples
formularesponse
.
attr
'answer'
,
section
.
answer
formularesponse
.
attr
'type'
,
'cs'
tolerance
=
$
(
doc
.
createElement
(
'responseparam'
))
tolerance
.
attr
'type'
,
'tolerance'
if
section
.
tolerance
==
undefined
section
.
tolerance
=
"5%"
tolerance
.
attr
'default'
,
section
.
tolerance
tolerance
.
attr
'name'
,
'tol'
tolerance
.
attr
'description'
,
'Numerical Tolerance'
formularesponse
.
append
tolerance
formularesponse
.
append
doc
.
createElement
(
'textline'
)
problem
.
append
(
formularesponse
)
else
throw
new
SyntaxError
(
"unexpected section type "
+
section
.
type
)
capa
=
@
dom2capa
(
doc
)
capa
=
@
dom2capa
(
doc
)
console
.
log
capa
return
capa
return
capa
\ No newline at end of file
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