| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590 | // CodeMirror, copyright (c) by Marijn Haverbeke and others// Distributed under an MIT license: http://codemirror.net/LICENSE(function(mod) {  if (typeof exports == "object" && typeof module == "object") // CommonJS    mod(require("../../lib/codemirror"), require("../javascript/javascript"), require("../css/css"), require("../htmlmixed/htmlmixed"));  else if (typeof define == "function" && define.amd) // AMD    define(["../../lib/codemirror", "../javascript/javascript", "../css/css", "../htmlmixed/htmlmixed"], mod);  else // Plain browser env    mod(CodeMirror);})(function(CodeMirror) {"use strict";CodeMirror.defineMode('jade', function (config) {  // token types  var KEYWORD = 'keyword';  var DOCTYPE = 'meta';  var ID = 'builtin';  var CLASS = 'qualifier';  var ATTRS_NEST = {    '{': '}',    '(': ')',    '[': ']'  };  var jsMode = CodeMirror.getMode(config, 'javascript');  function State() {    this.javaScriptLine = false;    this.javaScriptLineExcludesColon = false;    this.javaScriptArguments = false;    this.javaScriptArgumentsDepth = 0;    this.isInterpolating = false;    this.interpolationNesting = 0;    this.jsState = CodeMirror.startState(jsMode);    this.restOfLine = '';    this.isIncludeFiltered = false;    this.isEach = false;    this.lastTag = '';    this.scriptType = '';    // Attributes Mode    this.isAttrs = false;    this.attrsNest = [];    this.inAttributeName = true;    this.attributeIsType = false;    this.attrValue = '';    // Indented Mode    this.indentOf = Infinity;    this.indentToken = '';    this.innerMode = null;    this.innerState = null;    this.innerModeForLine = false;  }  /**   * Safely copy a state   *   * @return {State}   */  State.prototype.copy = function () {    var res = new State();    res.javaScriptLine = this.javaScriptLine;    res.javaScriptLineExcludesColon = this.javaScriptLineExcludesColon;    res.javaScriptArguments = this.javaScriptArguments;    res.javaScriptArgumentsDepth = this.javaScriptArgumentsDepth;    res.isInterpolating = this.isInterpolating;    res.interpolationNesting = this.interpolationNesting;    res.jsState = CodeMirror.copyState(jsMode, this.jsState);    res.innerMode = this.innerMode;    if (this.innerMode && this.innerState) {      res.innerState = CodeMirror.copyState(this.innerMode, this.innerState);    }    res.restOfLine = this.restOfLine;    res.isIncludeFiltered = this.isIncludeFiltered;    res.isEach = this.isEach;    res.lastTag = this.lastTag;    res.scriptType = this.scriptType;    res.isAttrs = this.isAttrs;    res.attrsNest = this.attrsNest.slice();    res.inAttributeName = this.inAttributeName;    res.attributeIsType = this.attributeIsType;    res.attrValue = this.attrValue;    res.indentOf = this.indentOf;    res.indentToken = this.indentToken;    res.innerModeForLine = this.innerModeForLine;    return res;  };  function javaScript(stream, state) {    if (stream.sol()) {      // if javaScriptLine was set at end of line, ignore it      state.javaScriptLine = false;      state.javaScriptLineExcludesColon = false;    }    if (state.javaScriptLine) {      if (state.javaScriptLineExcludesColon && stream.peek() === ':') {        state.javaScriptLine = false;        state.javaScriptLineExcludesColon = false;        return;      }      var tok = jsMode.token(stream, state.jsState);      if (stream.eol()) state.javaScriptLine = false;      return tok || true;    }  }  function javaScriptArguments(stream, state) {    if (state.javaScriptArguments) {      if (state.javaScriptArgumentsDepth === 0 && stream.peek() !== '(') {        state.javaScriptArguments = false;        return;      }      if (stream.peek() === '(') {        state.javaScriptArgumentsDepth++;      } else if (stream.peek() === ')') {        state.javaScriptArgumentsDepth--;      }      if (state.javaScriptArgumentsDepth === 0) {        state.javaScriptArguments = false;        return;      }      var tok = jsMode.token(stream, state.jsState);      return tok || true;    }  }  function yieldStatement(stream) {    if (stream.match(/^yield\b/)) {        return 'keyword';    }  }  function doctype(stream) {    if (stream.match(/^(?:doctype) *([^\n]+)?/)) {        return DOCTYPE;    }  }  function interpolation(stream, state) {    if (stream.match('#{')) {      state.isInterpolating = true;      state.interpolationNesting = 0;      return 'punctuation';    }  }  function interpolationContinued(stream, state) {    if (state.isInterpolating) {      if (stream.peek() === '}') {        state.interpolationNesting--;        if (state.interpolationNesting < 0) {          stream.next();          state.isInterpolating = false;          return 'punctuation';        }      } else if (stream.peek() === '{') {        state.interpolationNesting++;      }      return jsMode.token(stream, state.jsState) || true;    }  }  function caseStatement(stream, state) {    if (stream.match(/^case\b/)) {      state.javaScriptLine = true;      return KEYWORD;    }  }  function when(stream, state) {    if (stream.match(/^when\b/)) {      state.javaScriptLine = true;      state.javaScriptLineExcludesColon = true;      return KEYWORD;    }  }  function defaultStatement(stream) {    if (stream.match(/^default\b/)) {      return KEYWORD;    }  }  function extendsStatement(stream, state) {    if (stream.match(/^extends?\b/)) {      state.restOfLine = 'string';      return KEYWORD;    }  }  function append(stream, state) {    if (stream.match(/^append\b/)) {      state.restOfLine = 'variable';      return KEYWORD;    }  }  function prepend(stream, state) {    if (stream.match(/^prepend\b/)) {      state.restOfLine = 'variable';      return KEYWORD;    }  }  function block(stream, state) {    if (stream.match(/^block\b *(?:(prepend|append)\b)?/)) {      state.restOfLine = 'variable';      return KEYWORD;    }  }  function include(stream, state) {    if (stream.match(/^include\b/)) {      state.restOfLine = 'string';      return KEYWORD;    }  }  function includeFiltered(stream, state) {    if (stream.match(/^include:([a-zA-Z0-9\-]+)/, false) && stream.match('include')) {      state.isIncludeFiltered = true;      return KEYWORD;    }  }  function includeFilteredContinued(stream, state) {    if (state.isIncludeFiltered) {      var tok = filter(stream, state);      state.isIncludeFiltered = false;      state.restOfLine = 'string';      return tok;    }  }  function mixin(stream, state) {    if (stream.match(/^mixin\b/)) {      state.javaScriptLine = true;      return KEYWORD;    }  }  function call(stream, state) {    if (stream.match(/^\+([-\w]+)/)) {      if (!stream.match(/^\( *[-\w]+ *=/, false)) {        state.javaScriptArguments = true;        state.javaScriptArgumentsDepth = 0;      }      return 'variable';    }    if (stream.match(/^\+#{/, false)) {      stream.next();      state.mixinCallAfter = true;      return interpolation(stream, state);    }  }  function callArguments(stream, state) {    if (state.mixinCallAfter) {      state.mixinCallAfter = false;      if (!stream.match(/^\( *[-\w]+ *=/, false)) {        state.javaScriptArguments = true;        state.javaScriptArgumentsDepth = 0;      }      return true;    }  }  function conditional(stream, state) {    if (stream.match(/^(if|unless|else if|else)\b/)) {      state.javaScriptLine = true;      return KEYWORD;    }  }  function each(stream, state) {    if (stream.match(/^(- *)?(each|for)\b/)) {      state.isEach = true;      return KEYWORD;    }  }  function eachContinued(stream, state) {    if (state.isEach) {      if (stream.match(/^ in\b/)) {        state.javaScriptLine = true;        state.isEach = false;        return KEYWORD;      } else if (stream.sol() || stream.eol()) {        state.isEach = false;      } else if (stream.next()) {        while (!stream.match(/^ in\b/, false) && stream.next());        return 'variable';      }    }  }  function whileStatement(stream, state) {    if (stream.match(/^while\b/)) {      state.javaScriptLine = true;      return KEYWORD;    }  }  function tag(stream, state) {    var captures;    if (captures = stream.match(/^(\w(?:[-:\w]*\w)?)\/?/)) {      state.lastTag = captures[1].toLowerCase();      if (state.lastTag === 'script') {        state.scriptType = 'application/javascript';      }      return 'tag';    }  }  function filter(stream, state) {    if (stream.match(/^:([\w\-]+)/)) {      var innerMode;      if (config && config.innerModes) {        innerMode = config.innerModes(stream.current().substring(1));      }      if (!innerMode) {        innerMode = stream.current().substring(1);      }      if (typeof innerMode === 'string') {        innerMode = CodeMirror.getMode(config, innerMode);      }      setInnerMode(stream, state, innerMode);      return 'atom';    }  }  function code(stream, state) {    if (stream.match(/^(!?=|-)/)) {      state.javaScriptLine = true;      return 'punctuation';    }  }  function id(stream) {    if (stream.match(/^#([\w-]+)/)) {      return ID;    }  }  function className(stream) {    if (stream.match(/^\.([\w-]+)/)) {      return CLASS;    }  }  function attrs(stream, state) {    if (stream.peek() == '(') {      stream.next();      state.isAttrs = true;      state.attrsNest = [];      state.inAttributeName = true;      state.attrValue = '';      state.attributeIsType = false;      return 'punctuation';    }  }  function attrsContinued(stream, state) {    if (state.isAttrs) {      if (ATTRS_NEST[stream.peek()]) {        state.attrsNest.push(ATTRS_NEST[stream.peek()]);      }      if (state.attrsNest[state.attrsNest.length - 1] === stream.peek()) {        state.attrsNest.pop();      } else  if (stream.eat(')')) {        state.isAttrs = false;        return 'punctuation';      }      if (state.inAttributeName && stream.match(/^[^=,\)!]+/)) {        if (stream.peek() === '=' || stream.peek() === '!') {          state.inAttributeName = false;          state.jsState = CodeMirror.startState(jsMode);          if (state.lastTag === 'script' && stream.current().trim().toLowerCase() === 'type') {            state.attributeIsType = true;          } else {            state.attributeIsType = false;          }        }        return 'attribute';      }      var tok = jsMode.token(stream, state.jsState);      if (state.attributeIsType && tok === 'string') {        state.scriptType = stream.current().toString();      }      if (state.attrsNest.length === 0 && (tok === 'string' || tok === 'variable' || tok === 'keyword')) {        try {          Function('', 'var x ' + state.attrValue.replace(/,\s*$/, '').replace(/^!/, ''));          state.inAttributeName = true;          state.attrValue = '';          stream.backUp(stream.current().length);          return attrsContinued(stream, state);        } catch (ex) {          //not the end of an attribute        }      }      state.attrValue += stream.current();      return tok || true;    }  }  function attributesBlock(stream, state) {    if (stream.match(/^&attributes\b/)) {      state.javaScriptArguments = true;      state.javaScriptArgumentsDepth = 0;      return 'keyword';    }  }  function indent(stream) {    if (stream.sol() && stream.eatSpace()) {      return 'indent';    }  }  function comment(stream, state) {    if (stream.match(/^ *\/\/(-)?([^\n]*)/)) {      state.indentOf = stream.indentation();      state.indentToken = 'comment';      return 'comment';    }  }  function colon(stream) {    if (stream.match(/^: */)) {      return 'colon';    }  }  function text(stream, state) {    if (stream.match(/^(?:\| ?| )([^\n]+)/)) {      return 'string';    }    if (stream.match(/^(<[^\n]*)/, false)) {      // html string      setInnerMode(stream, state, 'htmlmixed');      state.innerModeForLine = true;      return innerMode(stream, state, true);    }  }  function dot(stream, state) {    if (stream.eat('.')) {      var innerMode = null;      if (state.lastTag === 'script' && state.scriptType.toLowerCase().indexOf('javascript') != -1) {        innerMode = state.scriptType.toLowerCase().replace(/"|'/g, '');      } else if (state.lastTag === 'style') {        innerMode = 'css';      }      setInnerMode(stream, state, innerMode);      return 'dot';    }  }  function fail(stream) {    stream.next();    return null;  }  function setInnerMode(stream, state, mode) {    mode = CodeMirror.mimeModes[mode] || mode;    mode = config.innerModes ? config.innerModes(mode) || mode : mode;    mode = CodeMirror.mimeModes[mode] || mode;    mode = CodeMirror.getMode(config, mode);    state.indentOf = stream.indentation();    if (mode && mode.name !== 'null') {      state.innerMode = mode;    } else {      state.indentToken = 'string';    }  }  function innerMode(stream, state, force) {    if (stream.indentation() > state.indentOf || (state.innerModeForLine && !stream.sol()) || force) {      if (state.innerMode) {        if (!state.innerState) {          state.innerState = state.innerMode.startState ? CodeMirror.startState(state.innerMode, stream.indentation()) : {};        }        return stream.hideFirstChars(state.indentOf + 2, function () {          return state.innerMode.token(stream, state.innerState) || true;        });      } else {        stream.skipToEnd();        return state.indentToken;      }    } else if (stream.sol()) {      state.indentOf = Infinity;      state.indentToken = null;      state.innerMode = null;      state.innerState = null;    }  }  function restOfLine(stream, state) {    if (stream.sol()) {      // if restOfLine was set at end of line, ignore it      state.restOfLine = '';    }    if (state.restOfLine) {      stream.skipToEnd();      var tok = state.restOfLine;      state.restOfLine = '';      return tok;    }  }  function startState() {    return new State();  }  function copyState(state) {    return state.copy();  }  /**   * Get the next token in the stream   *   * @param {Stream} stream   * @param {State} state   */  function nextToken(stream, state) {    var tok = innerMode(stream, state)      || restOfLine(stream, state)      || interpolationContinued(stream, state)      || includeFilteredContinued(stream, state)      || eachContinued(stream, state)      || attrsContinued(stream, state)      || javaScript(stream, state)      || javaScriptArguments(stream, state)      || callArguments(stream, state)      || yieldStatement(stream, state)      || doctype(stream, state)      || interpolation(stream, state)      || caseStatement(stream, state)      || when(stream, state)      || defaultStatement(stream, state)      || extendsStatement(stream, state)      || append(stream, state)      || prepend(stream, state)      || block(stream, state)      || include(stream, state)      || includeFiltered(stream, state)      || mixin(stream, state)      || call(stream, state)      || conditional(stream, state)      || each(stream, state)      || whileStatement(stream, state)      || tag(stream, state)      || filter(stream, state)      || code(stream, state)      || id(stream, state)      || className(stream, state)      || attrs(stream, state)      || attributesBlock(stream, state)      || indent(stream, state)      || text(stream, state)      || comment(stream, state)      || colon(stream, state)      || dot(stream, state)      || fail(stream, state);    return tok === true ? null : tok;  }  return {    startState: startState,    copyState: copyState,    token: nextToken  };}, 'javascript', 'css', 'htmlmixed');CodeMirror.defineMIME('text/x-jade', 'jade');});
 |