diff --git a/cms/envs/dev_ike.py b/cms/envs/dev_ike.py
new file mode 100644
index 0000000000..ec769ff6ab
--- /dev/null
+++ b/cms/envs/dev_ike.py
@@ -0,0 +1,8 @@
+# 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
diff --git a/cms/templates/widgets/metadata-edit.html b/cms/templates/widgets/metadata-edit.html
index f960ecfebd..069db424da 100644
--- a/cms/templates/widgets/metadata-edit.html
+++ b/cms/templates/widgets/metadata-edit.html
@@ -1,10 +1,26 @@
% if metadata:
+<%
+ import hashlib
+ hlskey = hashlib.md5(module.location.url()).hexdigest()
+%>
% endif
diff --git a/cms/templates/widgets/source-edit.html b/cms/templates/widgets/source-edit.html
new file mode 100644
index 0000000000..42b85ded8b
--- /dev/null
+++ b/cms/templates/widgets/source-edit.html
@@ -0,0 +1,109 @@
+<%
+ import hashlib
+ hlskey = hashlib.md5(module.location.url()).hexdigest()
+%>
+
+
+
+
+
+ High Level Source Editing
+
+
+
+
+
+
+
+
+
diff --git a/common/lib/xmodule/xmodule/templates/html/latex_html.yaml b/common/lib/xmodule/xmodule/templates/html/latex_html.yaml
new file mode 100644
index 0000000000..439565c16e
--- /dev/null
+++ b/common/lib/xmodule/xmodule/templates/html/latex_html.yaml
@@ -0,0 +1,23 @@
+---
+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: |
+
+
Example: E-text page
+
+ It is very convenient to write complex equations in LaTeX.
+
+
+children: []
diff --git a/common/lib/xmodule/xmodule/templates/problem/latex_problem.yaml b/common/lib/xmodule/xmodule/templates/problem/latex_problem.yaml
new file mode 100644
index 0000000000..fc9cae254d
--- /dev/null
+++ b/common/lib/xmodule/xmodule/templates/problem/latex_problem.yaml
@@ -0,0 +1,27 @@
+---
+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: |
+
+
+ Example: Option Response Problem
+
+ 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.
+
+ Select the correct options:
+
+ The location of the sky is:
+ The location of the earth is:
+
+
+
+children: []
diff --git a/common/static/js/vendor/CodeMirror/stex.js b/common/static/js/vendor/CodeMirror/stex.js
new file mode 100644
index 0000000000..7d9495f9f7
--- /dev/null
+++ b/common/static/js/vendor/CodeMirror/stex.js
@@ -0,0 +1,182 @@
+/*
+ * 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");