openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

r.js (6396B)


      1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
      2 // Distributed under an MIT license: http://codemirror.net/LICENSE
      3 
      4 (function(mod) {
      5   if (typeof exports == "object" && typeof module == "object") // CommonJS
      6     mod(require("../../lib/codemirror"));
      7   else if (typeof define == "function" && define.amd) // AMD
      8     define(["../../lib/codemirror"], mod);
      9   else // Plain browser env
     10     mod(CodeMirror);
     11 })(function(CodeMirror) {
     12 "use strict";
     13 
     14 CodeMirror.registerHelper("wordChars", "r", /[\w.]/);
     15 
     16 CodeMirror.defineMode("r", function(config) {
     17   function wordObj(str) {
     18     var words = str.split(" "), res = {};
     19     for (var i = 0; i < words.length; ++i) res[words[i]] = true;
     20     return res;
     21   }
     22   var atoms = wordObj("NULL NA Inf NaN NA_integer_ NA_real_ NA_complex_ NA_character_");
     23   var builtins = wordObj("list quote bquote eval return call parse deparse");
     24   var keywords = wordObj("if else repeat while function for in next break");
     25   var blockkeywords = wordObj("if else repeat while function for");
     26   var opChars = /[+\-*\/^<>=!&|~$:]/;
     27   var curPunc;
     28 
     29   function tokenBase(stream, state) {
     30     curPunc = null;
     31     var ch = stream.next();
     32     if (ch == "#") {
     33       stream.skipToEnd();
     34       return "comment";
     35     } else if (ch == "0" && stream.eat("x")) {
     36       stream.eatWhile(/[\da-f]/i);
     37       return "number";
     38     } else if (ch == "." && stream.eat(/\d/)) {
     39       stream.match(/\d*(?:e[+\-]?\d+)?/);
     40       return "number";
     41     } else if (/\d/.test(ch)) {
     42       stream.match(/\d*(?:\.\d+)?(?:e[+\-]\d+)?L?/);
     43       return "number";
     44     } else if (ch == "'" || ch == '"') {
     45       state.tokenize = tokenString(ch);
     46       return "string";
     47     } else if (ch == "`") {
     48       stream.match(/[^`]+`/);
     49       return "variable-3";
     50     } else if (ch == "." && stream.match(/.[.\d]+/)) {
     51       return "keyword";
     52     } else if (/[\w\.]/.test(ch) && ch != "_") {
     53       stream.eatWhile(/[\w\.]/);
     54       var word = stream.current();
     55       if (atoms.propertyIsEnumerable(word)) return "atom";
     56       if (keywords.propertyIsEnumerable(word)) {
     57         // Block keywords start new blocks, except 'else if', which only starts
     58         // one new block for the 'if', no block for the 'else'.
     59         if (blockkeywords.propertyIsEnumerable(word) &&
     60             !stream.match(/\s*if(\s+|$)/, false))
     61           curPunc = "block";
     62         return "keyword";
     63       }
     64       if (builtins.propertyIsEnumerable(word)) return "builtin";
     65       return "variable";
     66     } else if (ch == "%") {
     67       if (stream.skipTo("%")) stream.next();
     68       return "operator variable-2";
     69     } else if (
     70         (ch == "<" && stream.eat("-")) ||
     71         (ch == "<" && stream.match("<-")) ||
     72         (ch == "-" && stream.match(/>>?/))
     73       ) {
     74       return "operator arrow";
     75     } else if (ch == "=" && state.ctx.argList) {
     76       return "arg-is";
     77     } else if (opChars.test(ch)) {
     78       if (ch == "$") return "operator dollar";
     79       stream.eatWhile(opChars);
     80       return "operator";
     81     } else if (/[\(\){}\[\];]/.test(ch)) {
     82       curPunc = ch;
     83       if (ch == ";") return "semi";
     84       return null;
     85     } else {
     86       return null;
     87     }
     88   }
     89 
     90   function tokenString(quote) {
     91     return function(stream, state) {
     92       if (stream.eat("\\")) {
     93         var ch = stream.next();
     94         if (ch == "x") stream.match(/^[a-f0-9]{2}/i);
     95         else if ((ch == "u" || ch == "U") && stream.eat("{") && stream.skipTo("}")) stream.next();
     96         else if (ch == "u") stream.match(/^[a-f0-9]{4}/i);
     97         else if (ch == "U") stream.match(/^[a-f0-9]{8}/i);
     98         else if (/[0-7]/.test(ch)) stream.match(/^[0-7]{1,2}/);
     99         return "string-2";
    100       } else {
    101         var next;
    102         while ((next = stream.next()) != null) {
    103           if (next == quote) { state.tokenize = tokenBase; break; }
    104           if (next == "\\") { stream.backUp(1); break; }
    105         }
    106         return "string";
    107       }
    108     };
    109   }
    110 
    111   var ALIGN_YES = 1, ALIGN_NO = 2, BRACELESS = 4
    112 
    113   function push(state, type, stream) {
    114     state.ctx = {type: type,
    115                  indent: state.indent,
    116                  flags: 0,
    117                  column: stream.column(),
    118                  prev: state.ctx};
    119   }
    120   function setFlag(state, flag) {
    121     var ctx = state.ctx
    122     state.ctx = {type: ctx.type,
    123                  indent: ctx.indent,
    124                  flags: ctx.flags | flag,
    125                  column: ctx.column,
    126                  prev: ctx.prev}
    127   }
    128   function pop(state) {
    129     state.indent = state.ctx.indent;
    130     state.ctx = state.ctx.prev;
    131   }
    132 
    133   return {
    134     startState: function() {
    135       return {tokenize: tokenBase,
    136               ctx: {type: "top",
    137                     indent: -config.indentUnit,
    138                     flags: ALIGN_NO},
    139               indent: 0,
    140               afterIdent: false};
    141     },
    142 
    143     token: function(stream, state) {
    144       if (stream.sol()) {
    145         if ((state.ctx.flags & 3) == 0) state.ctx.flags |= ALIGN_NO
    146         if (state.ctx.flags & BRACELESS) pop(state)
    147         state.indent = stream.indentation();
    148       }
    149       if (stream.eatSpace()) return null;
    150       var style = state.tokenize(stream, state);
    151       if (style != "comment" && (state.ctx.flags & ALIGN_NO) == 0) setFlag(state, ALIGN_YES)
    152 
    153       if ((curPunc == ";" || curPunc == "{" || curPunc == "}") && state.ctx.type == "block") pop(state);
    154       if (curPunc == "{") push(state, "}", stream);
    155       else if (curPunc == "(") {
    156         push(state, ")", stream);
    157         if (state.afterIdent) state.ctx.argList = true;
    158       }
    159       else if (curPunc == "[") push(state, "]", stream);
    160       else if (curPunc == "block") push(state, "block", stream);
    161       else if (curPunc == state.ctx.type) pop(state);
    162       else if (state.ctx.type == "block" && style != "comment") setFlag(state, BRACELESS)
    163       state.afterIdent = style == "variable" || style == "keyword";
    164       return style;
    165     },
    166 
    167     indent: function(state, textAfter) {
    168       if (state.tokenize != tokenBase) return 0;
    169       var firstChar = textAfter && textAfter.charAt(0), ctx = state.ctx,
    170           closing = firstChar == ctx.type;
    171       if (ctx.flags & BRACELESS) ctx = ctx.prev
    172       if (ctx.type == "block") return ctx.indent + (firstChar == "{" ? 0 : config.indentUnit);
    173       else if (ctx.flags & ALIGN_YES) return ctx.column + (closing ? 0 : 1);
    174       else return ctx.indent + (closing ? 0 : config.indentUnit);
    175     },
    176 
    177     lineComment: "#"
    178   };
    179 });
    180 
    181 CodeMirror.defineMIME("text/x-rsrc", "r");
    182 
    183 });