codemirror
Version: 
In-browser code editing made bearable
56 lines (51 loc) • 1.76 kB
JavaScript
(function(CodeMirror) {
  "use strict";
  CodeMirror.defineMode("django:inner", function() {
    var keywords = ["block", "endblock", "for", "endfor", "in", "true", "false",
                    "loop", "none", "self", "super", "if", "endif", "as", "not", "and",
                    "else", "import", "with", "endwith", "without", "context", "ifequal", "endifequal",
                    "ifnotequal", "endifnotequal", "extends", "include", "load", "length", "comment",
                    "endcomment", "empty"];
    keywords = new RegExp("^((" + keywords.join(")|(") + "))\\b");
    function tokenBase (stream, state) {
      stream.eatWhile(/[^\{]/);
      var ch = stream.next();
      if (ch == "{") {
        if (ch = stream.eat(/\{|%|#/)) {
          state.tokenize = inTag(ch);
          return "tag";
        }
      }
    }
    function inTag (close) {
      if (close == "{") {
        close = "}";
      }
      return function (stream, state) {
        var ch = stream.next();
        if ((ch == close) && stream.eat("}")) {
          state.tokenize = tokenBase;
          return "tag";
        }
        if (stream.match(keywords)) {
          return "keyword";
        }
        return close == "#" ? "comment" : "string";
      };
    }
    return {
      startState: function () {
        return {tokenize: tokenBase};
      },
      token: function (stream, state) {
        return state.tokenize(stream, state);
      }
    };
  });
  CodeMirror.defineMode("django", function(config) {
    var htmlBase = CodeMirror.getMode(config, "text/html");
    var djangoInner = CodeMirror.getMode(config, "django:inner");
    return CodeMirror.overlayMode(htmlBase, djangoInner);
  });
  CodeMirror.defineMIME("text/x-django", "django");
})(CodeMirror);