| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 | // 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"));  else if (typeof define == "function" && define.amd) // AMD    define(["../../lib/codemirror"], mod);  else // Plain browser env    mod(CodeMirror);})(function(CodeMirror) {"use strict";CodeMirror.defineMode("r", function(config) {  function wordObj(str) {    var words = str.split(" "), res = {};    for (var i = 0; i < words.length; ++i) res[words[i]] = true;    return res;  }  var atoms = wordObj("NULL NA Inf NaN NA_integer_ NA_real_ NA_complex_ NA_character_");  var builtins = wordObj("list quote bquote eval return call parse deparse");  var keywords = wordObj("if else repeat while function for in next break");  var blockkeywords = wordObj("if else repeat while function for");  var opChars = /[+\-*\/^<>=!&|~$:]/;  var curPunc;  function tokenBase(stream, state) {    curPunc = null;    var ch = stream.next();    if (ch == "#") {      stream.skipToEnd();      return "comment";    } else if (ch == "0" && stream.eat("x")) {      stream.eatWhile(/[\da-f]/i);      return "number";    } else if (ch == "." && stream.eat(/\d/)) {      stream.match(/\d*(?:e[+\-]?\d+)?/);      return "number";    } else if (/\d/.test(ch)) {      stream.match(/\d*(?:\.\d+)?(?:e[+\-]\d+)?L?/);      return "number";    } else if (ch == "'" || ch == '"') {      state.tokenize = tokenString(ch);      return "string";    } else if (ch == "." && stream.match(/.[.\d]+/)) {      return "keyword";    } else if (/[\w\.]/.test(ch) && ch != "_") {      stream.eatWhile(/[\w\.]/);      var word = stream.current();      if (atoms.propertyIsEnumerable(word)) return "atom";      if (keywords.propertyIsEnumerable(word)) {        // Block keywords start new blocks, except 'else if', which only starts        // one new block for the 'if', no block for the 'else'.        if (blockkeywords.propertyIsEnumerable(word) &&            !stream.match(/\s*if(\s+|$)/, false))          curPunc = "block";        return "keyword";      }      if (builtins.propertyIsEnumerable(word)) return "builtin";      return "variable";    } else if (ch == "%") {      if (stream.skipTo("%")) stream.next();      return "variable-2";    } else if (ch == "<" && stream.eat("-")) {      return "arrow";    } else if (ch == "=" && state.ctx.argList) {      return "arg-is";    } else if (opChars.test(ch)) {      if (ch == "$") return "dollar";      stream.eatWhile(opChars);      return "operator";    } else if (/[\(\){}\[\];]/.test(ch)) {      curPunc = ch;      if (ch == ";") return "semi";      return null;    } else {      return null;    }  }  function tokenString(quote) {    return function(stream, state) {      if (stream.eat("\\")) {        var ch = stream.next();        if (ch == "x") stream.match(/^[a-f0-9]{2}/i);        else if ((ch == "u" || ch == "U") && stream.eat("{") && stream.skipTo("}")) stream.next();        else if (ch == "u") stream.match(/^[a-f0-9]{4}/i);        else if (ch == "U") stream.match(/^[a-f0-9]{8}/i);        else if (/[0-7]/.test(ch)) stream.match(/^[0-7]{1,2}/);        return "string-2";      } else {        var next;        while ((next = stream.next()) != null) {          if (next == quote) { state.tokenize = tokenBase; break; }          if (next == "\\") { stream.backUp(1); break; }        }        return "string";      }    };  }  function push(state, type, stream) {    state.ctx = {type: type,                 indent: state.indent,                 align: null,                 column: stream.column(),                 prev: state.ctx};  }  function pop(state) {    state.indent = state.ctx.indent;    state.ctx = state.ctx.prev;  }  return {    startState: function() {      return {tokenize: tokenBase,              ctx: {type: "top",                    indent: -config.indentUnit,                    align: false},              indent: 0,              afterIdent: false};    },    token: function(stream, state) {      if (stream.sol()) {        if (state.ctx.align == null) state.ctx.align = false;        state.indent = stream.indentation();      }      if (stream.eatSpace()) return null;      var style = state.tokenize(stream, state);      if (style != "comment" && state.ctx.align == null) state.ctx.align = true;      var ctype = state.ctx.type;      if ((curPunc == ";" || curPunc == "{" || curPunc == "}") && ctype == "block") pop(state);      if (curPunc == "{") push(state, "}", stream);      else if (curPunc == "(") {        push(state, ")", stream);        if (state.afterIdent) state.ctx.argList = true;      }      else if (curPunc == "[") push(state, "]", stream);      else if (curPunc == "block") push(state, "block", stream);      else if (curPunc == ctype) pop(state);      state.afterIdent = style == "variable" || style == "keyword";      return style;    },    indent: function(state, textAfter) {      if (state.tokenize != tokenBase) return 0;      var firstChar = textAfter && textAfter.charAt(0), ctx = state.ctx,          closing = firstChar == ctx.type;      if (ctx.type == "block") return ctx.indent + (firstChar == "{" ? 0 : config.indentUnit);      else if (ctx.align) return ctx.column + (closing ? 0 : 1);      else return ctx.indent + (closing ? 0 : config.indentUnit);    },    lineComment: "#"  };});CodeMirror.defineMIME("text/x-rsrc", "r");});
 |