Added coding style modes to SimpleMDE (#3286)

* Added coding style modes to SimpleMDE

* Moved the CodeMirror addon from simplemd to codemirror directory
This commit is contained in:
Richard Mahn 2016-07-22 23:29:20 -06:00 committed by 无闻
parent cf85e9eb7b
commit 69dae1ec1c
286 changed files with 49679 additions and 0 deletions

View file

@ -0,0 +1,195 @@
<!doctype html>
<title>CodeMirror: Julia mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="julia.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Julia</a>
</ul>
</div>
<article>
<h2>Julia mode</h2>
<div><textarea id="code" name="code">
#numbers
1234
1234im
.234
.234im
2.23im
2.3f3
23e2
0x234
#strings
'a'
"asdf"
r"regex"
b"bytestring"
"""
multiline string
"""
#identifiers
a
as123
function_name!
#unicode identifiers
# a = x\ddot
a⃗ = ẍ
# a = v\dot
a⃗ = v̇
#F\vec = m \cdotp a\vec
F⃗ = m·a⃗
#literal identifier multiples
3x
4[1, 2, 3]
#dicts and indexing
x=[1, 2, 3]
x[end-1]
x={"julia"=>"language of technical computing"}
#exception handling
try
f()
catch
@printf "Error"
finally
g()
end
#types
immutable Color{T<:Number}
r::T
g::T
b::T
end
#functions
function change!(x::Vector{Float64})
for i = 1:length(x)
x[i] *= 2
end
end
#function invocation
f('b', (2, 3)...)
#operators
|=
&=
^=
\-
%=
*=
+=
-=
<=
>=
!=
==
%
*
+
-
<
>
!
=
|
&
^
\
?
~
:
$
<:
.<
.>
<<
<<=
>>
>>>>
>>=
>>>=
<<=
<<<=
.<=
.>=
.==
->
//
in
...
//
:=
.//=
.*=
./=
.^=
.%=
.+=
.-=
\=
\\=
||
===
&&
|=
.|=
<:
>:
|>
<|
::
x ? y : z
#macros
@spawnat 2 1+1
@eval(:x)
#keywords and operators
if else elseif while for
begin let end do
try catch finally return break continue
global local const
export import importall using
function macro module baremodule
type immutable quote
true false enumerate
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: {name: "julia",
},
lineNumbers: true,
indentUnit: 4,
matchBrackets: true
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-julia</code>.</p>
</article>

View file

@ -0,0 +1,392 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(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("julia", function(_conf, parserConf) {
var ERRORCLASS = 'error';
function wordRegexp(words, end) {
if (typeof end === 'undefined') { end = "\\b"; }
return new RegExp("^((" + words.join(")|(") + "))" + end);
}
var octChar = "\\\\[0-7]{1,3}";
var hexChar = "\\\\x[A-Fa-f0-9]{1,2}";
var specialChar = "\\\\[abfnrtv0%?'\"\\\\]";
var singleChar = "([^\\u0027\\u005C\\uD800-\\uDFFF]|[\\uD800-\\uDFFF][\\uDC00-\\uDFFF])";
var operators = parserConf.operators || /^\.?[|&^\\%*+\-<>!=\/]=?|\?|~|:|\$|\.[<>]|<<=?|>>>?=?|\.[<>=]=|->?|\/\/|\bin\b(?!\()|[\u2208\u2209](?!\()/;
var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
var identifiers = parserConf.identifiers || /^[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/;
var charsList = [octChar, hexChar, specialChar, singleChar];
var blockOpeners = ["begin", "function", "type", "immutable", "let", "macro", "for", "while", "quote", "if", "else", "elseif", "try", "finally", "catch", "do"];
var blockClosers = ["end", "else", "elseif", "catch", "finally"];
var keywordList = ['if', 'else', 'elseif', 'while', 'for', 'begin', 'let', 'end', 'do', 'try', 'catch', 'finally', 'return', 'break', 'continue', 'global', 'local', 'const', 'export', 'import', 'importall', 'using', 'function', 'macro', 'module', 'baremodule', 'type', 'immutable', 'quote', 'typealias', 'abstract', 'bitstype'];
var builtinList = ['true', 'false', 'nothing', 'NaN', 'Inf'];
//var stringPrefixes = new RegExp("^[br]?('|\")")
var stringPrefixes = /^(`|"{3}|([brv]?"))/;
var chars = wordRegexp(charsList, "'");
var keywords = wordRegexp(keywordList);
var builtins = wordRegexp(builtinList);
var openers = wordRegexp(blockOpeners);
var closers = wordRegexp(blockClosers);
var macro = /^@[_A-Za-z][\w]*/;
var symbol = /^:[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/;
var typeAnnotation = /^::[^,;"{()=$\s]+({[^}]*}+)*/;
function inArray(state) {
var ch = currentScope(state);
if (ch == '[') {
return true;
}
return false;
}
function currentScope(state) {
if (state.scopes.length == 0) {
return null;
}
return state.scopes[state.scopes.length - 1];
}
// tokenizers
function tokenBase(stream, state) {
// Handle multiline comments
if (stream.match(/^#=/, false)) {
state.tokenize = tokenComment;
return state.tokenize(stream, state);
}
// Handle scope changes
var leavingExpr = state.leavingExpr;
if (stream.sol()) {
leavingExpr = false;
}
state.leavingExpr = false;
if (leavingExpr) {
if (stream.match(/^'+/)) {
return 'operator';
}
}
if (stream.match(/^\.{2,3}/)) {
return 'operator';
}
if (stream.eatSpace()) {
return null;
}
var ch = stream.peek();
// Handle single line comments
if (ch === '#') {
stream.skipToEnd();
return 'comment';
}
if (ch === '[') {
state.scopes.push('[');
}
if (ch === '(') {
state.scopes.push('(');
}
var scope = currentScope(state);
if (scope == '[' && ch === ']') {
state.scopes.pop();
state.leavingExpr = true;
}
if (scope == '(' && ch === ')') {
state.scopes.pop();
state.leavingExpr = true;
}
var match;
if (!inArray(state) && (match=stream.match(openers, false))) {
state.scopes.push(match);
}
if (!inArray(state) && stream.match(closers, false)) {
state.scopes.pop();
}
if (inArray(state)) {
if (state.lastToken == 'end' && stream.match(/^:/)) {
return 'operator';
}
if (stream.match(/^end/)) {
return 'number';
}
}
if (stream.match(/^=>/)) {
return 'operator';
}
// Handle Number Literals
if (stream.match(/^[0-9\.]/, false)) {
var imMatcher = RegExp(/^im\b/);
var numberLiteral = false;
// Floats
if (stream.match(/^\d*\.(?!\.)\d*([Eef][\+\-]?\d+)?/i)) { numberLiteral = true; }
if (stream.match(/^\d+\.(?!\.)\d*/)) { numberLiteral = true; }
if (stream.match(/^\.\d+/)) { numberLiteral = true; }
if (stream.match(/^0x\.[0-9a-f]+p[\+\-]?\d+/i)) { numberLiteral = true; }
// Integers
if (stream.match(/^0x[0-9a-f]+/i)) { numberLiteral = true; } // Hex
if (stream.match(/^0b[01]+/i)) { numberLiteral = true; } // Binary
if (stream.match(/^0o[0-7]+/i)) { numberLiteral = true; } // Octal
if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) { numberLiteral = true; } // Decimal
// Zero by itself with no other piece of number.
if (stream.match(/^0(?![\dx])/i)) { numberLiteral = true; }
if (numberLiteral) {
// Integer literals may be "long"
stream.match(imMatcher);
state.leavingExpr = true;
return 'number';
}
}
if (stream.match(/^<:/)) {
return 'operator';
}
if (stream.match(typeAnnotation)) {
return 'builtin';
}
// Handle symbols
if (!leavingExpr && stream.match(symbol) || stream.match(/:\./)) {
return 'builtin';
}
// Handle parametric types
if (stream.match(/^{[^}]*}(?=\()/)) {
return 'builtin';
}
// Handle operators and Delimiters
if (stream.match(operators)) {
return 'operator';
}
// Handle Chars
if (stream.match(/^'/)) {
state.tokenize = tokenChar;
return state.tokenize(stream, state);
}
// Handle Strings
if (stream.match(stringPrefixes)) {
state.tokenize = tokenStringFactory(stream.current());
return state.tokenize(stream, state);
}
if (stream.match(macro)) {
return 'meta';
}
if (stream.match(delimiters)) {
return null;
}
if (stream.match(keywords)) {
return 'keyword';
}
if (stream.match(builtins)) {
return 'builtin';
}
var isDefinition = state.isDefinition ||
state.lastToken == 'function' ||
state.lastToken == 'macro' ||
state.lastToken == 'type' ||
state.lastToken == 'immutable';
if (stream.match(identifiers)) {
if (isDefinition) {
if (stream.peek() === '.') {
state.isDefinition = true;
return 'variable';
}
state.isDefinition = false;
return 'def';
}
if (stream.match(/^({[^}]*})*\(/, false)) {
return callOrDef(stream, state);
}
state.leavingExpr = true;
return 'variable';
}
// Handle non-detected items
stream.next();
return ERRORCLASS;
}
function callOrDef(stream, state) {
var match = stream.match(/^(\(\s*)/);
if (match) {
if (state.firstParenPos < 0)
state.firstParenPos = state.scopes.length;
state.scopes.push('(');
state.charsAdvanced += match[1].length;
}
if (currentScope(state) == '(' && stream.match(/^\)/)) {
state.scopes.pop();
state.charsAdvanced += 1;
if (state.scopes.length <= state.firstParenPos) {
var isDefinition = stream.match(/^\s*?=(?!=)/, false);
stream.backUp(state.charsAdvanced);
state.firstParenPos = -1;
state.charsAdvanced = 0;
if (isDefinition)
return 'def';
return 'builtin';
}
}
// Unfortunately javascript does not support multiline strings, so we have
// to undo anything done upto here if a function call or definition splits
// over two or more lines.
if (stream.match(/^$/g, false)) {
stream.backUp(state.charsAdvanced);
while (state.scopes.length > state.firstParenPos)
state.scopes.pop();
state.firstParenPos = -1;
state.charsAdvanced = 0;
return 'builtin';
}
state.charsAdvanced += stream.match(/^([^()]*)/)[1].length;
return callOrDef(stream, state);
}
function tokenComment(stream, state) {
if (stream.match(/^#=/)) {
state.weakScopes++;
}
if (!stream.match(/.*?(?=(#=|=#))/)) {
stream.skipToEnd();
}
if (stream.match(/^=#/)) {
state.weakScopes--;
if (state.weakScopes == 0)
state.tokenize = tokenBase;
}
return 'comment';
}
function tokenChar(stream, state) {
var isChar = false, match;
if (stream.match(chars)) {
isChar = true;
} else if (match = stream.match(/\\u([a-f0-9]{1,4})(?=')/i)) {
var value = parseInt(match[1], 16);
if (value <= 55295 || value >= 57344) { // (U+0,U+D7FF), (U+E000,U+FFFF)
isChar = true;
stream.next();
}
} else if (match = stream.match(/\\U([A-Fa-f0-9]{5,8})(?=')/)) {
var value = parseInt(match[1], 16);
if (value <= 1114111) { // U+10FFFF
isChar = true;
stream.next();
}
}
if (isChar) {
state.leavingExpr = true;
state.tokenize = tokenBase;
return 'string';
}
if (!stream.match(/^[^']+(?=')/)) { stream.skipToEnd(); }
if (stream.match(/^'/)) { state.tokenize = tokenBase; }
return ERRORCLASS;
}
function tokenStringFactory(delimiter) {
while ('bruv'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
delimiter = delimiter.substr(1);
}
var OUTCLASS = 'string';
function tokenString(stream, state) {
while (!stream.eol()) {
stream.eatWhile(/[^"\\]/);
if (stream.eat('\\')) {
stream.next();
} else if (stream.match(delimiter)) {
state.tokenize = tokenBase;
state.leavingExpr = true;
return OUTCLASS;
} else {
stream.eat(/["]/);
}
}
return OUTCLASS;
}
tokenString.isString = true;
return tokenString;
}
var external = {
startState: function() {
return {
tokenize: tokenBase,
scopes: [],
weakScopes: 0,
lastToken: null,
leavingExpr: false,
isDefinition: false,
charsAdvanced: 0,
firstParenPos: -1
};
},
token: function(stream, state) {
var style = state.tokenize(stream, state);
var current = stream.current();
if (current && style) {
state.lastToken = current;
}
// Handle '.' connected identifiers
if (current === '.') {
style = stream.match(identifiers, false) || stream.match(macro, false) ||
stream.match(/\(/, false) ? 'operator' : ERRORCLASS;
}
return style;
},
indent: function(state, textAfter) {
var delta = 0;
if (textAfter == "]" || textAfter == ")" || textAfter == "end" || textAfter == "else" || textAfter == "elseif" || textAfter == "catch" || textAfter == "finally") {
delta = -1;
}
return (state.scopes.length + delta) * _conf.indentUnit;
},
electricInput: /(end|else(if)?|catch|finally)$/,
lineComment: "#",
fold: "indent"
};
return external;
});
CodeMirror.defineMIME("text/x-julia", "julia");
});