How to use Codemirror in LON-CAPA

A variable $CodemirrorMime has to be set within the LON-CAPA problem file before the import line of the Footer library. The choices are (It should be emphasised that most of these choices are only useful for manually assessed code, because automated marking is not provided for most of these languages.)

Where to find the libraries

Codemirror can be used to provide better editing support for textareas for example for the LON-CAPA problem types "external response" and "essay response". It has modes for different programming languages. Libraries are provided in the following LON-CAPA location "/res/fhwf/ecult/lib/SyntaxHighlighter" by the eCULT project. Alternatively, such files can be installed from http://codemirror.net/doc/compress.html and then be configured for use in LON-CAPA. The current eCULT configuration includes: codemirror.js, clike.js, javascript.js, php.js, python.js, sql.js, xml.js, active-line.js, closebrackets.js, matchbrackets.js, matchtags.js.

How to use the libraries

The eCULT Codemirror libraries can be used by any LON-CAPA author. In order to use the libraries, the following two lines of code need to be included in the problem file. The first line should be at the beginning of the problem file, the second one at the end. A variable $CodemirrorMime has to be set within the LON-CAPA problem file before the import line of the Footer library.
<import id="91">/res/fhwf/ecult/lib/SyntaxHighlighter/CodeMirror_Header.library</import>
<import id="92">/res/fhwf/ecult/lib/SyntaxHighlighter/CodeMirror_Footer.library</import>

The eCULT CodeMirror_Header.library

An "<allow>" tag in LON-CAPA ensures that the resource has permission to be viewed. The codemirror-compressed.js file was downloaded from the Codemirror website, but the codemirror_3_16.css requires some modifications after downloading (in particular, it requires something like ".CodeMirror div { margin: 0; padding-bottom: 0; }".
<library>
<link rel="stylesheet" index="11" href="/res/fhwf/ecult/lib/SyntaxHighlighter/codemirror_3_16.css" type="text/css" />
<script src="/res/fhwf/ecult/lib/SyntaxHighlighter/codemirror-compressed.js" type="text/javascript"></script>
<allow src="/res/fhwf/ecult/lib/SyntaxHighlighter/codemirror-compressed.js" />
<allow src="/res/fhwf/ecult/lib/SyntaxHighlighter/codemirror_3_16.css" />
</library>

The eCULT CodeMirror_Footer.library

The eCULT library currently provides the following:
<library>
<script type="loncapa/perl">

$CodeMirText = "var editor = CodeMirror.fromTextArea(document.getElementsByTagName('textarea')[0],{";
if ($CodemirrorMime eq "x-python") {
    $CodeMirText .= "mode: {name:'python',version: 2,singleLineStringErrors: false},
    indentUnit: 4,
    lineNumbers: true,
    matchBrackets: true,
    tabMode : 'shift',
    styleActiveLine: true,
    viewportMargin: Infinity,
    autoCloseBrackets: true,
    extraKeys: {'Tab': function(){editor.replaceSelection('    ' , 'end');}}
});";
}  elsif ($CodemirrorMime eq "xml" or $CodemirrorMime eq "json" or $CodemirrorMime eq "x-httpd-php" ) {
    $CodeMirText .= "mode:  'application/$CodemirrorMime',
    indentUnit: 4,
    lineNumbers: true,
    matchBrackets: true,
    tabMode : 'shift',
    styleActiveLine: true,
    viewportMargin: Infinity,
    autoCloseBrackets: true,
    extraKeys: {'Tab': function(){editor.replaceSelection('    ' , 'end');}}
});";
}  elsif ($CodemirrorMime eq "x-java") {
    $CodeMirText .= "mode:  'text/x-java',
    theme: 'eclipse',
    indentUnit: 4,
    lineNumbers: true,
    matchBrackets: true,
    tabMode : 'shift',
    styleActiveLine: true,
    viewportMargin: Infinity,
    autoCloseBrackets: true,
    extraKeys: {'Tab': function(){editor.replaceSelection('    ' , 'end');}}
});";
}  elsif ($CodemirrorMime =~  /x-/ or $CodemirrorMime eq "javascript") {
    $CodeMirText .= "mode:  'text/$CodemirrorMime',
    indentUnit: 4,
    lineNumbers: true,
    matchBrackets: true,
    tabMode : 'shift',
    styleActiveLine: true,
    viewportMargin: Infinity,
    autoCloseBrackets: true,
    extraKeys: {'Tab': function(){editor.replaceSelection('    ' , 'end');}}
});";
} else {
    $CodeMirText .= "mode:  '',
    lineNumbers: true,
    matchBrackets: true,
    tabMode : 'shift',
    styleActiveLine: true,
    viewportMargin: Infinity});";
}


</script>

<startouttext />
<script type="text/javascript">
$CodeMirText
</script>
<endouttext />
</library>

Instead of using this library, one can also use the configuration for a single programming language. For example:

<startouttext />
<script type="text/javascript">
var editor = CodeMirror.fromTextArea(document.getElementsByTagName('textarea')[0],{
    mode:  'text/x-java',
    theme: 'eclipse',
    indentUnit: 4,
    lineNumbers: true,
    matchBrackets: true,
    tabMode : 'shift',
    styleActiveLine: true,
    viewportMargin: Infinity,
    autoCloseBrackets: true});
</script>
<endouttext />
Hint: when making changes to the footer library, it may be necessary to empty the browser cache to see the changes.