##// END OF EJS Templates
svn-support: Use utf-8 to encode mod_dav_svn configuration before writing to disk....
svn-support: Use utf-8 to encode mod_dav_svn configuration before writing to disk. Repository or group names may contain non ASCII characters. Therfore we have to encode the configuration before writing it to the file.

File last commit:

r1:854a839a default
r830:7ca2d1db default
Show More
mathematica.js
175 lines | 5.4 KiB | application/javascript | JavascriptLexer
// 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
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'
});
});