Commit f846f4c2 by ichuang

add import filter capability to html & problem editing; provides latex2edx interface

parent 73477ec1
# dev environment for ichuang/mit
from .common import *
from logsettings import get_logger_config
from .dev import *
import socket
#MITX_FEATURES['USE_DJANGO_PIPELINE']=False # don't recompile scss
% if metadata: % if metadata:
<%
import hashlib
hlskey = hashlib.md5(module.location.url()).hexdigest()
%>
<section class="metadata_edit"> <section class="metadata_edit">
<h3>Metadata</h3> <h3>Metadata</h3>
<ul> <ul>
% for keyname in editable_metadata_fields: % for keyname in editable_metadata_fields:
<li><label>${keyname}:</label> <input type='text' data-metadata-name='${keyname}' value='${metadata[keyname]}' size='60' /></li> <li>
% if keyname=='source_code':
<a href="#hls-modal-${hlskey}" style="color:yellow;" id="hls-trig-${hlskey}" >Edit High Level Source</a>
% else:
<label>${keyname}:</label>
<input type='text' data-metadata-name='${keyname}' value='${metadata[keyname]}' size='60' />
% endif
</li>
% endfor % endfor
</ul> </ul>
% if 'source_code' in editable_metadata_fields:
<%include file="source-edit.html" />
% endif
</section> </section>
% endif % endif
<%
import hashlib
hlskey = hashlib.md5(module.location.url()).hexdigest()
%>
<section id="hls-modal-${hlskey}" class="upload-modal modal" style="width:80%!important; left:30%!important; height:90%; overflow:auto; background:#ECF7D3;" >
<a href="#" class="close-button"><span class="close-icon"></span></a>
<div id="hls-div">
<header>
<h2>High Level Source Editing</h2>
</header>
<form id="hls-form">
<section class="source-edit">
<textarea name="" data-metadata-name="source_code" class="source-edit-box hls-data" rows="8" cols="40">${metadata['source_code']|h}</textarea>
</section>
<div class="submit">
<button type="reset" class="hls-compile">Save &amp; Compile to edX XML</button>
<button type="reset" class="hls-save">Save</button>
<button type="reset" class="hls-refresh">Refresh</button>
</div>
</form>
</div>
</section>
<script type="text/javascript" src="/static/js/vendor/CodeMirror/stex.js"></script>
<script type="text/javascript">
$('#hls-trig-${hlskey}').leanModal({ top:40, overlay:0.8, closeButton: ".close-button"});
$('#hls-modal-${hlskey}').data('editor',CodeMirror.fromTextArea($('#hls-modal-${hlskey}').find('.hls-data')[0], {lineNumbers: true, mode: 'stex'}));
$('#hls-trig-${hlskey}').click(function(){slow_refresh_hls($('#hls-modal-${hlskey}'))})
// refresh button
$('#hls-modal-${hlskey}').find('.hls-refresh').click(function(){refresh_hls($('#hls-modal-${hlskey}'))});
function refresh_hls(el){
el.data('editor').refresh();
}
function slow_refresh_hls(el){
el.delay(200).queue(function(){
refresh_hls(el);
$(this).dequeue();
});
}
// compile & save button
$('#hls-modal-${hlskey}').find('.hls-compile').click(compile_hls_${hlskey});
function compile_hls_${hlskey}(){
editor = $('#hls-modal-${hlskey}').data('editor')
var myquery = { latexin: editor.getValue() };
$.ajax({
url: '${metadata.get('source_processor_url','https://qisx.mit.edu:5443/latex2edx')}',
type: 'GET',
contentType: 'application/json',
data: escape(JSON.stringify(myquery)),
crossDomain: true,
dataType: 'jsonp',
jsonpCallback: 'process_return_${hlskey}',
beforeSend: function (xhr) { xhr.setRequestHeader ("Authorization", "Basic eHFhOmFnYXJ3YWw="); },
timeout : 7000,
success: function(result) {
console.log(result);
},
error: function() {
alert('Error: cannot connect to latex2edx server');
console.log('error!');
}
});
// $('#hls-modal-${hlskey}').hide();
}
function process_return_${hlskey}(datadict){
// datadict is json of array with "xml" and "message"
// if "xml" value is '' then the conversion failed
xml = datadict.xml;
console.log('xml:');
console.log(xml);
if (xml.length==0){
alert('Conversion failed! error:'+ datadict.message);
}else{
set_raw_edit_box(xml,'${hlskey}');
save_hls($('#hls-modal-${hlskey}'));
}
}
function set_raw_edit_box(data,key){
// get the codemirror editor for the raw-edit-box
// it's a CodeMirror-wrap class element
$('#hls-modal-'+key).closest('.component').find('.CodeMirror-wrap')[0].CodeMirror.setValue(data);
}
// save button
$('#hls-modal-${hlskey}').find('.hls-save').click(function(){save_hls($('#hls-modal-${hlskey}'))});
function save_hls(el){
el.find('.hls-data').val(el.data('editor').getValue());
el.closest('.component').find('.save-button').click();
}
</script>
---
metadata:
display_name: E-text Written in LaTeX
source_processor_url: https://qisx.mit.edu:5443/latex2edx
source_code: |
\subsection{Example of E-text in LaTeX}
It is very convenient to write complex equations in LaTeX.
\begin{equation}
x = \frac{-b\pm\sqrt{b^2-4*a*c}}{2a}
\end{equation}
Seize the moment.
data: |
<html>
<h2>Example: E-text page</h2>
<p>
It is very convenient to write complex equations in LaTeX.
</p>
</html>
children: []
---
metadata:
display_name: Problem Written in LaTeX
source_processor_url: https://qisx.mit.edu:5443/latex2edx
source_code: |
\subsection{Example: Option Response Problem in Latex}
Where is the earth?
\edXabox{options='up','down' expect='down'}
data: |
<problem>
<text>
<h2>Example: Option Response Problem</h2>
<p>
An option response problem presents option boxes for students to select from. Correctness of input is evaluated based
on which option is defined as correct in the optioninput statement.
</p>
<p>Select the correct options:</p>
<optionresponse direction="vertical" randomize="yes">
<p><text class="inline">The location of the sky is: </text><optioninput inline="1" options="('Up','Down')" correct="Up"></optioninput></p>
<p><text>The location of the earth is: </text><optioninput options="('Up','Down')" correct="Down"></optioninput></p>
</optionresponse>
</text>
</problem>
children: []
/*
* Author: Constantin Jucovschi (c.jucovschi@jacobs-university.de)
* Licence: MIT
*/
CodeMirror.defineMode("stex", function(cmCfg, modeCfg)
{
function pushCommand(state, command) {
state.cmdState.push(command);
}
function peekCommand(state) {
if (state.cmdState.length>0)
return state.cmdState[state.cmdState.length-1];
else
return null;
}
function popCommand(state) {
if (state.cmdState.length>0) {
var plug = state.cmdState.pop();
plug.closeBracket();
}
}
function applyMostPowerful(state) {
var context = state.cmdState;
for (var i = context.length - 1; i >= 0; i--) {
var plug = context[i];
if (plug.name=="DEFAULT")
continue;
return plug.styleIdentifier();
}
return null;
}
function addPluginPattern(pluginName, cmdStyle, brackets, styles) {
return function () {
this.name=pluginName;
this.bracketNo = 0;
this.style=cmdStyle;
this.styles = styles;
this.brackets = brackets;
this.styleIdentifier = function(content) {
if (this.bracketNo<=this.styles.length)
return this.styles[this.bracketNo-1];
else
return null;
};
this.openBracket = function(content) {
this.bracketNo++;
return "bracket";
};
this.closeBracket = function(content) {
};
};
}
var plugins = new Array();
plugins["importmodule"] = addPluginPattern("importmodule", "tag", "{[", ["string", "builtin"]);
plugins["documentclass"] = addPluginPattern("documentclass", "tag", "{[", ["", "atom"]);
plugins["usepackage"] = addPluginPattern("documentclass", "tag", "[", ["atom"]);
plugins["begin"] = addPluginPattern("documentclass", "tag", "[", ["atom"]);
plugins["end"] = addPluginPattern("documentclass", "tag", "[", ["atom"]);
plugins["DEFAULT"] = function () {
this.name="DEFAULT";
this.style="tag";
this.styleIdentifier = function(content) {
};
this.openBracket = function(content) {
};
this.closeBracket = function(content) {
};
};
function setState(state, f) {
state.f = f;
}
function normal(source, state) {
if (source.match(/^\\[a-zA-Z@]+/)) {
var cmdName = source.current();
cmdName = cmdName.substr(1, cmdName.length-1);
var plug;
if (plugins.hasOwnProperty(cmdName)) {
plug = plugins[cmdName];
} else {
plug = plugins["DEFAULT"];
}
plug = new plug();
pushCommand(state, plug);
setState(state, beginParams);
return plug.style;
}
// escape characters
if (source.match(/^\\[$&%#{}_]/)) {
return "tag";
}
// white space control characters
if (source.match(/^\\[,;!\/]/)) {
return "tag";
}
var ch = source.next();
if (ch == "%") {
// special case: % at end of its own line; stay in same state
if (!source.eol()) {
setState(state, inCComment);
}
return "comment";
}
else if (ch=='}' || ch==']') {
plug = peekCommand(state);
if (plug) {
plug.closeBracket(ch);
setState(state, beginParams);
} else
return "error";
return "bracket";
} else if (ch=='{' || ch=='[') {
plug = plugins["DEFAULT"];
plug = new plug();
pushCommand(state, plug);
return "bracket";
}
else if (/\d/.test(ch)) {
source.eatWhile(/[\w.%]/);
return "atom";
}
else {
source.eatWhile(/[\w-_]/);
return applyMostPowerful(state);
}
}
function inCComment(source, state) {
source.skipToEnd();
setState(state, normal);
return "comment";
}
function beginParams(source, state) {
var ch = source.peek();
if (ch == '{' || ch == '[') {
var lastPlug = peekCommand(state);
var style = lastPlug.openBracket(ch);
source.eat(ch);
setState(state, normal);
return "bracket";
}
if (/[ \t\r]/.test(ch)) {
source.eat(ch);
return null;
}
setState(state, normal);
lastPlug = peekCommand(state);
if (lastPlug) {
popCommand(state);
}
return normal(source, state);
}
return {
startState: function() { return { f:normal, cmdState:[] }; },
copyState: function(s) { return { f: s.f, cmdState: s.cmdState.slice(0, s.cmdState.length) }; },
token: function(stream, state) {
var t = state.f(stream, state);
var w = stream.current();
return t;
}
};
});
CodeMirror.defineMIME("text/x-stex", "stex");
CodeMirror.defineMIME("text/x-latex", "stex");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment