GPQAPP

Форк
0
176 строк · 5.5 Кб
1
// CodeMirror, copyright (c) by Marijn Haverbeke and others
2
// Distributed under an MIT license: https://codemirror.net/LICENSE
3

4
// Mathematica mode copyright (c) 2015 by Calin Barbat
5
// Based on code by Patrick Scheibe (halirutan)
6
// See: https://github.com/halirutan/Mathematica-Source-Highlighting/tree/master/src/lang-mma.js
7

8
(function(mod) {
9
  if (typeof exports == "object" && typeof module == "object") // CommonJS
10
    mod(require("../../lib/codemirror"));
11
  else if (typeof define == "function" && define.amd) // AMD
12
    define(["../../lib/codemirror"], mod);
13
  else // Plain browser env
14
    mod(CodeMirror);
15
})(function(CodeMirror) {
16
"use strict";
17

18
CodeMirror.defineMode('mathematica', function(_config, _parserConfig) {
19

20
  // used pattern building blocks
21
  var Identifier = '[a-zA-Z\\$][a-zA-Z0-9\\$]*';
22
  var pBase      = "(?:\\d+)";
23
  var pFloat     = "(?:\\.\\d+|\\d+\\.\\d*|\\d+)";
24
  var pFloatBase = "(?:\\.\\w+|\\w+\\.\\w*|\\w+)";
25
  var pPrecision = "(?:`(?:`?"+pFloat+")?)";
26

27
  // regular expressions
28
  var reBaseForm        = new RegExp('(?:'+pBase+'(?:\\^\\^'+pFloatBase+pPrecision+'?(?:\\*\\^[+-]?\\d+)?))');
29
  var reFloatForm       = new RegExp('(?:' + pFloat + pPrecision + '?(?:\\*\\^[+-]?\\d+)?)');
30
  var reIdInContext     = new RegExp('(?:`?)(?:' + Identifier + ')(?:`(?:' + Identifier + '))*(?:`?)');
31

32
  function tokenBase(stream, state) {
33
    var ch;
34

35
    // get next character
36
    ch = stream.next();
37

38
    // string
39
    if (ch === '"') {
40
      state.tokenize = tokenString;
41
      return state.tokenize(stream, state);
42
    }
43

44
    // comment
45
    if (ch === '(') {
46
      if (stream.eat('*')) {
47
        state.commentLevel++;
48
        state.tokenize = tokenComment;
49
        return state.tokenize(stream, state);
50
      }
51
    }
52

53
    // go back one character
54
    stream.backUp(1);
55

56
    // look for numbers
57
    // Numbers in a baseform
58
    if (stream.match(reBaseForm, true, false)) {
59
      return 'number';
60
    }
61

62
    // Mathematica numbers. Floats (1.2, .2, 1.) can have optionally a precision (`float) or an accuracy definition
63
    // (``float). Note: while 1.2` is possible 1.2`` is not. At the end an exponent (float*^+12) can follow.
64
    if (stream.match(reFloatForm, true, false)) {
65
      return 'number';
66
    }
67

68
    /* In[23] and Out[34] */
69
    if (stream.match(/(?:In|Out)\[[0-9]*\]/, true, false)) {
70
      return 'atom';
71
    }
72

73
    // usage
74
    if (stream.match(/([a-zA-Z\$][a-zA-Z0-9\$]*(?:`[a-zA-Z0-9\$]+)*::usage)/, true, false)) {
75
      return 'meta';
76
    }
77

78
    // message
79
    if (stream.match(/([a-zA-Z\$][a-zA-Z0-9\$]*(?:`[a-zA-Z0-9\$]+)*::[a-zA-Z\$][a-zA-Z0-9\$]*):?/, true, false)) {
80
      return 'string-2';
81
    }
82

83
    // this makes a look-ahead match for something like variable:{_Integer}
84
    // the match is then forwarded to the mma-patterns tokenizer.
85
    if (stream.match(/([a-zA-Z\$][a-zA-Z0-9\$]*\s*:)(?:(?:[a-zA-Z\$][a-zA-Z0-9\$]*)|(?:[^:=>~@\^\&\*\)\[\]'\?,\|])).*/, true, false)) {
86
      return 'variable-2';
87
    }
88

89
    // catch variables which are used together with Blank (_), BlankSequence (__) or BlankNullSequence (___)
90
    // Cannot start with a number, but can have numbers at any other position. Examples
91
    // blub__Integer, a1_, b34_Integer32
92
    if (stream.match(/[a-zA-Z\$][a-zA-Z0-9\$]*_+[a-zA-Z\$][a-zA-Z0-9\$]*/, true, false)) {
93
      return 'variable-2';
94
    }
95
    if (stream.match(/[a-zA-Z\$][a-zA-Z0-9\$]*_+/, true, false)) {
96
      return 'variable-2';
97
    }
98
    if (stream.match(/_+[a-zA-Z\$][a-zA-Z0-9\$]*/, true, false)) {
99
      return 'variable-2';
100
    }
101

102
    // Named characters in Mathematica, like \[Gamma].
103
    if (stream.match(/\\\[[a-zA-Z\$][a-zA-Z0-9\$]*\]/, true, false)) {
104
      return 'variable-3';
105
    }
106

107
    // Match all braces separately
108
    if (stream.match(/(?:\[|\]|{|}|\(|\))/, true, false)) {
109
      return 'bracket';
110
    }
111

112
    // Catch Slots (#, ##, #3, ##9 and the V10 named slots #name). I have never seen someone using more than one digit after #, so we match
113
    // only one.
114
    if (stream.match(/(?:#[a-zA-Z\$][a-zA-Z0-9\$]*|#+[0-9]?)/, true, false)) {
115
      return 'variable-2';
116
    }
117

118
    // Literals like variables, keywords, functions
119
    if (stream.match(reIdInContext, true, false)) {
120
      return 'keyword';
121
    }
122

123
    // operators. Note that operators like @@ or /; are matched separately for each symbol.
124
    if (stream.match(/(?:\\|\+|\-|\*|\/|,|;|\.|:|@|~|=|>|<|&|\||_|`|'|\^|\?|!|%)/, true, false)) {
125
      return 'operator';
126
    }
127

128
    // everything else is an error
129
    stream.next(); // advance the stream.
130
    return 'error';
131
  }
132

133
  function tokenString(stream, state) {
134
    var next, end = false, escaped = false;
135
    while ((next = stream.next()) != null) {
136
      if (next === '"' && !escaped) {
137
        end = true;
138
        break;
139
      }
140
      escaped = !escaped && next === '\\';
141
    }
142
    if (end && !escaped) {
143
      state.tokenize = tokenBase;
144
    }
145
    return 'string';
146
  };
147

148
  function tokenComment(stream, state) {
149
    var prev, next;
150
    while(state.commentLevel > 0 && (next = stream.next()) != null) {
151
      if (prev === '(' && next === '*') state.commentLevel++;
152
      if (prev === '*' && next === ')') state.commentLevel--;
153
      prev = next;
154
    }
155
    if (state.commentLevel <= 0) {
156
      state.tokenize = tokenBase;
157
    }
158
    return 'comment';
159
  }
160

161
  return {
162
    startState: function() {return {tokenize: tokenBase, commentLevel: 0};},
163
    token: function(stream, state) {
164
      if (stream.eatSpace()) return null;
165
      return state.tokenize(stream, state);
166
    },
167
    blockCommentStart: "(*",
168
    blockCommentEnd: "*)"
169
  };
170
});
171

172
CodeMirror.defineMIME('text/x-mathematica', {
173
  name: 'mathematica'
174
});
175

176
});
177

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.