| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 | // CodeMirror, copyright (c) by Marijn Haverbeke and others// Distributed under an MIT license: http://codemirror.net/LICENSE// Mathematica mode copyright (c) 2015 by Calin Barbat// Based on code by Patrick Scheibe (halirutan)// See: https://github.com/halirutan/Mathematica-Source-Highlighting/tree/master/src/lang-mma.js(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('mathematica', function(_config, _parserConfig) {  // used pattern building blocks  var Identifier = '[a-zA-Z\\$][a-zA-Z0-9\\$]*';  var pBase      = "(?:\\d+)";  var pFloat     = "(?:\\.\\d+|\\d+\\.\\d*|\\d+)";  var pFloatBase = "(?:\\.\\w+|\\w+\\.\\w*|\\w+)";  var pPrecision = "(?:`(?:`?"+pFloat+")?)";  // regular expressions  var reBaseForm        = new RegExp('(?:'+pBase+'(?:\\^\\^'+pFloatBase+pPrecision+'?(?:\\*\\^[+-]?\\d+)?))');  var reFloatForm       = new RegExp('(?:' + pFloat + pPrecision + '?(?:\\*\\^[+-]?\\d+)?)');  var reIdInContext     = new RegExp('(?:`?)(?:' + Identifier + ')(?:`(?:' + Identifier + '))*(?:`?)');  function tokenBase(stream, state) {    var ch;    // get next character    ch = stream.next();    // string    if (ch === '"') {      state.tokenize = tokenString;      return state.tokenize(stream, state);    }    // comment    if (ch === '(') {      if (stream.eat('*')) {        state.commentLevel++;        state.tokenize = tokenComment;        return state.tokenize(stream, state);      }    }    // go back one character    stream.backUp(1);    // look for numbers    // Numbers in a baseform    if (stream.match(reBaseForm, true, false)) {      return 'number';    }    // Mathematica numbers. Floats (1.2, .2, 1.) can have optionally a precision (`float) or an accuracy definition    // (``float). Note: while 1.2` is possible 1.2`` is not. At the end an exponent (float*^+12) can follow.    if (stream.match(reFloatForm, true, false)) {      return 'number';    }    /* In[23] and Out[34] */    if (stream.match(/(?:In|Out)\[[0-9]*\]/, true, false)) {      return 'atom';    }    // usage    if (stream.match(/([a-zA-Z\$]+(?:`?[a-zA-Z0-9\$])*::usage)/, true, false)) {      return 'meta';    }    // message    if (stream.match(/([a-zA-Z\$]+(?:`?[a-zA-Z0-9\$])*::[a-zA-Z\$][a-zA-Z0-9\$]*):?/, true, false)) {      return 'string-2';    }    // this makes a look-ahead match for something like variable:{_Integer}    // the match is then forwarded to the mma-patterns tokenizer.    if (stream.match(/([a-zA-Z\$][a-zA-Z0-9\$]*\s*:)(?:(?:[a-zA-Z\$][a-zA-Z0-9\$]*)|(?:[^:=>~@\^\&\*\)\[\]'\?,\|])).*/, true, false)) {      return 'variable-2';    }    // catch variables which are used together with Blank (_), BlankSequence (__) or BlankNullSequence (___)    // Cannot start with a number, but can have numbers at any other position. Examples    // blub__Integer, a1_, b34_Integer32    if (stream.match(/[a-zA-Z\$][a-zA-Z0-9\$]*_+[a-zA-Z\$][a-zA-Z0-9\$]*/, true, false)) {      return 'variable-2';    }    if (stream.match(/[a-zA-Z\$][a-zA-Z0-9\$]*_+/, true, false)) {      return 'variable-2';    }    if (stream.match(/_+[a-zA-Z\$][a-zA-Z0-9\$]*/, true, false)) {      return 'variable-2';    }    // Named characters in Mathematica, like \[Gamma].    if (stream.match(/\\\[[a-zA-Z\$][a-zA-Z0-9\$]*\]/, true, false)) {      return 'variable-3';    }    // Match all braces separately    if (stream.match(/(?:\[|\]|{|}|\(|\))/, true, false)) {      return 'bracket';    }    // Catch Slots (#, ##, #3, ##9 and the V10 named slots #name). I have never seen someone using more than one digit after #, so we match    // only one.    if (stream.match(/(?:#[a-zA-Z\$][a-zA-Z0-9\$]*|#+[0-9]?)/, true, false)) {      return 'variable-2';    }    // Literals like variables, keywords, functions    if (stream.match(reIdInContext, true, false)) {      return 'keyword';    }    // operators. Note that operators like @@ or /; are matched separately for each symbol.    if (stream.match(/(?:\\|\+|\-|\*|\/|,|;|\.|:|@|~|=|>|<|&|\||_|`|'|\^|\?|!|%)/, true, false)) {      return 'operator';    }    // everything else is an error    stream.next(); // advance the stream.    return 'error';  }  function tokenString(stream, state) {    var next, end = false, escaped = false;    while ((next = stream.next()) != null) {      if (next === '"' && !escaped) {        end = true;        break;      }      escaped = !escaped && next === '\\';    }    if (end && !escaped) {      state.tokenize = tokenBase;    }    return 'string';  };  function tokenComment(stream, state) {    var prev, next;    while(state.commentLevel > 0 && (next = stream.next()) != null) {      if (prev === '(' && next === '*') state.commentLevel++;      if (prev === '*' && next === ')') state.commentLevel--;      prev = next;    }    if (state.commentLevel <= 0) {      state.tokenize = tokenBase;    }    return 'comment';  }  return {    startState: function() {return {tokenize: tokenBase, commentLevel: 0};},    token: function(stream, state) {      if (stream.eatSpace()) return null;      return state.tokenize(stream, state);    },    blockCommentStart: "(*",    blockCommentEnd: "*)"  };});CodeMirror.defineMIME('text/x-mathematica', {  name: 'mathematica'});});
 |