GPQAPP

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

4
/*
5
 * Author: Constantin Jucovschi (c.jucovschi@jacobs-university.de)
6
 * Licence: MIT
7
 */
8

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

19
  CodeMirror.defineMode("stex", function(_config, parserConfig) {
20
    "use strict";
21

22
    function pushCommand(state, command) {
23
      state.cmdState.push(command);
24
    }
25

26
    function peekCommand(state) {
27
      if (state.cmdState.length > 0) {
28
        return state.cmdState[state.cmdState.length - 1];
29
      } else {
30
        return null;
31
      }
32
    }
33

34
    function popCommand(state) {
35
      var plug = state.cmdState.pop();
36
      if (plug) {
37
        plug.closeBracket();
38
      }
39
    }
40

41
    // returns the non-default plugin closest to the end of the list
42
    function getMostPowerful(state) {
43
      var context = state.cmdState;
44
      for (var i = context.length - 1; i >= 0; i--) {
45
        var plug = context[i];
46
        if (plug.name == "DEFAULT") {
47
          continue;
48
        }
49
        return plug;
50
      }
51
      return { styleIdentifier: function() { return null; } };
52
    }
53

54
    function addPluginPattern(pluginName, cmdStyle, styles) {
55
      return function () {
56
        this.name = pluginName;
57
        this.bracketNo = 0;
58
        this.style = cmdStyle;
59
        this.styles = styles;
60
        this.argument = null;   // \begin and \end have arguments that follow. These are stored in the plugin
61

62
        this.styleIdentifier = function() {
63
          return this.styles[this.bracketNo - 1] || null;
64
        };
65
        this.openBracket = function() {
66
          this.bracketNo++;
67
          return "bracket";
68
        };
69
        this.closeBracket = function() {};
70
      };
71
    }
72

73
    var plugins = {};
74

75
    plugins["importmodule"] = addPluginPattern("importmodule", "tag", ["string", "builtin"]);
76
    plugins["documentclass"] = addPluginPattern("documentclass", "tag", ["", "atom"]);
77
    plugins["usepackage"] = addPluginPattern("usepackage", "tag", ["atom"]);
78
    plugins["begin"] = addPluginPattern("begin", "tag", ["atom"]);
79
    plugins["end"] = addPluginPattern("end", "tag", ["atom"]);
80

81
    plugins["label"    ] = addPluginPattern("label"    , "tag", ["atom"]);
82
    plugins["ref"      ] = addPluginPattern("ref"      , "tag", ["atom"]);
83
    plugins["eqref"    ] = addPluginPattern("eqref"    , "tag", ["atom"]);
84
    plugins["cite"     ] = addPluginPattern("cite"     , "tag", ["atom"]);
85
    plugins["bibitem"  ] = addPluginPattern("bibitem"  , "tag", ["atom"]);
86
    plugins["Bibitem"  ] = addPluginPattern("Bibitem"  , "tag", ["atom"]);
87
    plugins["RBibitem" ] = addPluginPattern("RBibitem" , "tag", ["atom"]);
88

89
    plugins["DEFAULT"] = function () {
90
      this.name = "DEFAULT";
91
      this.style = "tag";
92

93
      this.styleIdentifier = this.openBracket = this.closeBracket = function() {};
94
    };
95

96
    function setState(state, f) {
97
      state.f = f;
98
    }
99

100
    // called when in a normal (no environment) context
101
    function normal(source, state) {
102
      var plug;
103
      // Do we look like '\command' ?  If so, attempt to apply the plugin 'command'
104
      if (source.match(/^\\[a-zA-Z@]+/)) {
105
        var cmdName = source.current().slice(1);
106
        plug = plugins.hasOwnProperty(cmdName) ? plugins[cmdName] : plugins["DEFAULT"];
107
        plug = new plug();
108
        pushCommand(state, plug);
109
        setState(state, beginParams);
110
        return plug.style;
111
      }
112

113
      // escape characters
114
      if (source.match(/^\\[$&%#{}_]/)) {
115
        return "tag";
116
      }
117

118
      // white space control characters
119
      if (source.match(/^\\[,;!\/\\]/)) {
120
        return "tag";
121
      }
122

123
      // find if we're starting various math modes
124
      if (source.match("\\[")) {
125
        setState(state, function(source, state){ return inMathMode(source, state, "\\]"); });
126
        return "keyword";
127
      }
128
      if (source.match("\\(")) {
129
        setState(state, function(source, state){ return inMathMode(source, state, "\\)"); });
130
        return "keyword";
131
      }
132
      if (source.match("$$")) {
133
        setState(state, function(source, state){ return inMathMode(source, state, "$$"); });
134
        return "keyword";
135
      }
136
      if (source.match("$")) {
137
        setState(state, function(source, state){ return inMathMode(source, state, "$"); });
138
        return "keyword";
139
      }
140

141
      var ch = source.next();
142
      if (ch == "%") {
143
        source.skipToEnd();
144
        return "comment";
145
      } else if (ch == '}' || ch == ']') {
146
        plug = peekCommand(state);
147
        if (plug) {
148
          plug.closeBracket(ch);
149
          setState(state, beginParams);
150
        } else {
151
          return "error";
152
        }
153
        return "bracket";
154
      } else if (ch == '{' || ch == '[') {
155
        plug = plugins["DEFAULT"];
156
        plug = new plug();
157
        pushCommand(state, plug);
158
        return "bracket";
159
      } else if (/\d/.test(ch)) {
160
        source.eatWhile(/[\w.%]/);
161
        return "atom";
162
      } else {
163
        source.eatWhile(/[\w\-_]/);
164
        plug = getMostPowerful(state);
165
        if (plug.name == 'begin') {
166
          plug.argument = source.current();
167
        }
168
        return plug.styleIdentifier();
169
      }
170
    }
171

172
    function inMathMode(source, state, endModeSeq) {
173
      if (source.eatSpace()) {
174
        return null;
175
      }
176
      if (endModeSeq && source.match(endModeSeq)) {
177
        setState(state, normal);
178
        return "keyword";
179
      }
180
      if (source.match(/^\\[a-zA-Z@]+/)) {
181
        return "tag";
182
      }
183
      if (source.match(/^[a-zA-Z]+/)) {
184
        return "variable-2";
185
      }
186
      // escape characters
187
      if (source.match(/^\\[$&%#{}_]/)) {
188
        return "tag";
189
      }
190
      // white space control characters
191
      if (source.match(/^\\[,;!\/]/)) {
192
        return "tag";
193
      }
194
      // special math-mode characters
195
      if (source.match(/^[\^_&]/)) {
196
        return "tag";
197
      }
198
      // non-special characters
199
      if (source.match(/^[+\-<>|=,\/@!*:;'"`~#?]/)) {
200
        return null;
201
      }
202
      if (source.match(/^(\d+\.\d*|\d*\.\d+|\d+)/)) {
203
        return "number";
204
      }
205
      var ch = source.next();
206
      if (ch == "{" || ch == "}" || ch == "[" || ch == "]" || ch == "(" || ch == ")") {
207
        return "bracket";
208
      }
209

210
      if (ch == "%") {
211
        source.skipToEnd();
212
        return "comment";
213
      }
214
      return "error";
215
    }
216

217
    function beginParams(source, state) {
218
      var ch = source.peek(), lastPlug;
219
      if (ch == '{' || ch == '[') {
220
        lastPlug = peekCommand(state);
221
        lastPlug.openBracket(ch);
222
        source.eat(ch);
223
        setState(state, normal);
224
        return "bracket";
225
      }
226
      if (/[ \t\r]/.test(ch)) {
227
        source.eat(ch);
228
        return null;
229
      }
230
      setState(state, normal);
231
      popCommand(state);
232

233
      return normal(source, state);
234
    }
235

236
    return {
237
      startState: function() {
238
        var f = parserConfig.inMathMode ? function(source, state){ return inMathMode(source, state); } : normal;
239
        return {
240
          cmdState: [],
241
          f: f
242
        };
243
      },
244
      copyState: function(s) {
245
        return {
246
          cmdState: s.cmdState.slice(),
247
          f: s.f
248
        };
249
      },
250
      token: function(stream, state) {
251
        return state.f(stream, state);
252
      },
253
      blankLine: function(state) {
254
        state.f = normal;
255
        state.cmdState.length = 0;
256
      },
257
      lineComment: "%"
258
    };
259
  });
260

261
  CodeMirror.defineMIME("text/x-stex", "stex");
262
  CodeMirror.defineMIME("text/x-latex", "stex");
263

264
});
265

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

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

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

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