实现基础的通知媒介管理

This commit is contained in:
刘祥超
2021-04-05 20:48:13 +08:00
parent 27421bbd46
commit f85b3a40ea
291 changed files with 60492 additions and 5 deletions

View File

@@ -0,0 +1,879 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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";
function Context(indented, column, type, info, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.info = info;
this.align = align;
this.prev = prev;
}
function pushContext(state, col, type, info) {
var indent = state.indented;
if (state.context && state.context.type == "statement" && type != "statement")
indent = state.context.indented;
return state.context = new Context(indent, col, type, info, null, state.context);
}
function popContext(state) {
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}
function typeBefore(stream, state, pos) {
if (state.prevToken == "variable" || state.prevToken == "type") return true;
if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, pos))) return true;
if (state.typeAtEndOfLine && stream.column() == stream.indentation()) return true;
}
function isTopScope(context) {
for (;;) {
if (!context || context.type == "top") return true;
if (context.type == "}" && context.prev.info != "namespace") return false;
context = context.prev;
}
}
CodeMirror.defineMode("clike", function(config, parserConfig) {
var indentUnit = config.indentUnit,
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
dontAlignCalls = parserConfig.dontAlignCalls,
keywords = parserConfig.keywords || {},
types = parserConfig.types || {},
builtin = parserConfig.builtin || {},
blockKeywords = parserConfig.blockKeywords || {},
defKeywords = parserConfig.defKeywords || {},
atoms = parserConfig.atoms || {},
hooks = parserConfig.hooks || {},
multiLineStrings = parserConfig.multiLineStrings,
indentStatements = parserConfig.indentStatements !== false,
indentSwitch = parserConfig.indentSwitch !== false,
namespaceSeparator = parserConfig.namespaceSeparator,
isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/,
numberStart = parserConfig.numberStart || /[\d\.]/,
number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,
isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/,
isIdentifierChar = parserConfig.isIdentifierChar || /[\w\$_\xa1-\uffff]/,
// An optional function that takes a {string} token and returns true if it
// should be treated as a builtin.
isReservedIdentifier = parserConfig.isReservedIdentifier || false;
var curPunc, isDefKeyword;
function tokenBase(stream, state) {
var ch = stream.next();
if (hooks[ch]) {
var result = hooks[ch](stream, state);
if (result !== false) return result;
}
if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (isPunctuationChar.test(ch)) {
curPunc = ch;
return null;
}
if (numberStart.test(ch)) {
stream.backUp(1)
if (stream.match(number)) return "number"
stream.next()
}
if (ch == "/") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
}
if (stream.eat("/")) {
stream.skipToEnd();
return "comment";
}
}
if (isOperatorChar.test(ch)) {
while (!stream.match(/^\/[\/*]/, false) && stream.eat(isOperatorChar)) {}
return "operator";
}
stream.eatWhile(isIdentifierChar);
if (namespaceSeparator) while (stream.match(namespaceSeparator))
stream.eatWhile(isIdentifierChar);
var cur = stream.current();
if (contains(keywords, cur)) {
if (contains(blockKeywords, cur)) curPunc = "newstatement";
if (contains(defKeywords, cur)) isDefKeyword = true;
return "keyword";
}
if (contains(types, cur)) return "type";
if (contains(builtin, cur)
|| (isReservedIdentifier && isReservedIdentifier(cur))) {
if (contains(blockKeywords, cur)) curPunc = "newstatement";
return "builtin";
}
if (contains(atoms, cur)) return "atom";
return "variable";
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, next, end = false;
while ((next = stream.next()) != null) {
if (next == quote && !escaped) {end = true; break;}
escaped = !escaped && next == "\\";
}
if (end || !(escaped || multiLineStrings))
state.tokenize = null;
return "string";
};
}
function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = null;
break;
}
maybeEnd = (ch == "*");
}
return "comment";
}
function maybeEOL(stream, state) {
if (parserConfig.typeFirstDefinitions && stream.eol() && isTopScope(state.context))
state.typeAtEndOfLine = typeBefore(stream, state, stream.pos)
}
// Interface
return {
startState: function(basecolumn) {
return {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", null, false),
indented: 0,
startOfLine: true,
prevToken: null
};
},
token: function(stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
}
if (stream.eatSpace()) { maybeEOL(stream, state); return null; }
curPunc = isDefKeyword = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment" || style == "meta") return style;
if (ctx.align == null) ctx.align = true;
if (curPunc == ";" || curPunc == ":" || (curPunc == "," && stream.match(/^\s*(?:\/\/.*)?$/, false)))
while (state.context.type == "statement") popContext(state);
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}") {
while (ctx.type == "statement") ctx = popContext(state);
if (ctx.type == "}") ctx = popContext(state);
while (ctx.type == "statement") ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
else if (indentStatements &&
(((ctx.type == "}" || ctx.type == "top") && curPunc != ";") ||
(ctx.type == "statement" && curPunc == "newstatement"))) {
pushContext(state, stream.column(), "statement", stream.current());
}
if (style == "variable" &&
((state.prevToken == "def" ||
(parserConfig.typeFirstDefinitions && typeBefore(stream, state, stream.start) &&
isTopScope(state.context) && stream.match(/^\s*\(/, false)))))
style = "def";
if (hooks.token) {
var result = hooks.token(stream, state, style);
if (result !== undefined) style = result;
}
if (style == "def" && parserConfig.styleDefs === false) style = "variable";
state.startOfLine = false;
state.prevToken = isDefKeyword ? "def" : style || curPunc;
maybeEOL(stream, state);
return style;
},
indent: function(state, textAfter) {
if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass;
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
var closing = firstChar == ctx.type;
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
if (parserConfig.dontIndentStatements)
while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info))
ctx = ctx.prev
if (hooks.indent) {
var hook = hooks.indent(state, ctx, textAfter, indentUnit);
if (typeof hook == "number") return hook
}
var switchBlock = ctx.prev && ctx.prev.info == "switch";
if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
return ctx.indented
}
if (ctx.type == "statement")
return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
return ctx.column + (closing ? 0 : 1);
if (ctx.type == ")" && !closing)
return ctx.indented + statementIndentUnit;
return ctx.indented + (closing ? 0 : indentUnit) +
(!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0);
},
electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
blockCommentStart: "/*",
blockCommentEnd: "*/",
blockCommentContinue: " * ",
lineComment: "//",
fold: "brace"
};
});
function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
function contains(words, word) {
if (typeof words === "function") {
return words(word);
} else {
return words.propertyIsEnumerable(word);
}
}
var cKeywords = "auto if break case register continue return default do sizeof " +
"static else struct switch extern typedef union for goto while enum const " +
"volatile inline restrict asm fortran";
// Do not use this. Use the cTypes function below. This is global just to avoid
// excessive calls when cTypes is being called multiple times during a parse.
var basicCTypes = words("int long char short double float unsigned signed " +
"void bool");
// Do not use this. Use the objCTypes function below. This is global just to avoid
// excessive calls when objCTypes is being called multiple times during a parse.
var basicObjCTypes = words("SEL instancetype id Class Protocol BOOL");
// Returns true if identifier is a "C" type.
// C type is defined as those that are reserved by the compiler (basicTypes),
// and those that end in _t (Reserved by POSIX for types)
// http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html
function cTypes(identifier) {
return contains(basicCTypes, identifier) || /.+_t/.test(identifier);
}
// Returns true if identifier is a "Objective C" type.
function objCTypes(identifier) {
return cTypes(identifier) || contains(basicObjCTypes, identifier);
}
var cBlockKeywords = "case do else for if switch while struct enum union";
var cDefKeywords = "struct enum union";
function cppHook(stream, state) {
if (!state.startOfLine) return false
for (var ch, next = null; ch = stream.peek();) {
if (ch == "\\" && stream.match(/^.$/)) {
next = cppHook
break
} else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) {
break
}
stream.next()
}
state.tokenize = next
return "meta"
}
function pointerHook(_stream, state) {
if (state.prevToken == "type") return "type";
return false;
}
// For C and C++ (and ObjC): identifiers starting with __
// or _ followed by a capital letter are reserved for the compiler.
function cIsReservedIdentifier(token) {
if (!token || token.length < 2) return false;
if (token[0] != '_') return false;
return (token[1] == '_') || (token[1] !== token[1].toLowerCase());
}
function cpp14Literal(stream) {
stream.eatWhile(/[\w\.']/);
return "number";
}
function cpp11StringHook(stream, state) {
stream.backUp(1);
// Raw strings.
if (stream.match(/(R|u8R|uR|UR|LR)/)) {
var match = stream.match(/"([^\s\\()]{0,16})\(/);
if (!match) {
return false;
}
state.cpp11RawStringDelim = match[1];
state.tokenize = tokenRawString;
return tokenRawString(stream, state);
}
// Unicode strings/chars.
if (stream.match(/(u8|u|U|L)/)) {
if (stream.match(/["']/, /* eat */ false)) {
return "string";
}
return false;
}
// Ignore this hook.
stream.next();
return false;
}
function cppLooksLikeConstructor(word) {
var lastTwo = /(\w+)::~?(\w+)$/.exec(word);
return lastTwo && lastTwo[1] == lastTwo[2];
}
// C#-style strings where "" escapes a quote.
function tokenAtString(stream, state) {
var next;
while ((next = stream.next()) != null) {
if (next == '"' && !stream.eat('"')) {
state.tokenize = null;
break;
}
}
return "string";
}
// C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
// <delim> can be a string up to 16 characters long.
function tokenRawString(stream, state) {
// Escape characters that have special regex meanings.
var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&');
var match = stream.match(new RegExp(".*?\\)" + delim + '"'));
if (match)
state.tokenize = null;
else
stream.skipToEnd();
return "string";
}
function def(mimes, mode) {
if (typeof mimes == "string") mimes = [mimes];
var words = [];
function add(obj) {
if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
words.push(prop);
}
add(mode.keywords);
add(mode.types);
add(mode.builtin);
add(mode.atoms);
if (words.length) {
mode.helperType = mimes[0];
CodeMirror.registerHelper("hintWords", mimes[0], words);
}
for (var i = 0; i < mimes.length; ++i)
CodeMirror.defineMIME(mimes[i], mode);
}
def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
name: "clike",
keywords: words(cKeywords),
types: cTypes,
blockKeywords: words(cBlockKeywords),
defKeywords: words(cDefKeywords),
typeFirstDefinitions: true,
atoms: words("NULL true false"),
isReservedIdentifier: cIsReservedIdentifier,
hooks: {
"#": cppHook,
"*": pointerHook,
},
modeProps: {fold: ["brace", "include"]}
});
def(["text/x-c++src", "text/x-c++hdr"], {
name: "clike",
keywords: words(cKeywords + " dynamic_cast namespace reinterpret_cast try explicit new " +
"static_cast typeid catch operator template typename class friend private " +
"this using const_cast public throw virtual delete mutable protected " +
"alignas alignof constexpr decltype nullptr noexcept thread_local final " +
"static_assert override"),
types: cTypes,
blockKeywords: words(cBlockKeywords +" class try catch finally"),
defKeywords: words(cDefKeywords + " class namespace"),
typeFirstDefinitions: true,
atoms: words("true false NULL"),
dontIndentStatements: /^template$/,
isIdentifierChar: /[\w\$_~\xa1-\uffff]/,
isReservedIdentifier: cIsReservedIdentifier,
hooks: {
"#": cppHook,
"*": pointerHook,
"u": cpp11StringHook,
"U": cpp11StringHook,
"L": cpp11StringHook,
"R": cpp11StringHook,
"0": cpp14Literal,
"1": cpp14Literal,
"2": cpp14Literal,
"3": cpp14Literal,
"4": cpp14Literal,
"5": cpp14Literal,
"6": cpp14Literal,
"7": cpp14Literal,
"8": cpp14Literal,
"9": cpp14Literal,
token: function(stream, state, style) {
if (style == "variable" && stream.peek() == "(" &&
(state.prevToken == ";" || state.prevToken == null ||
state.prevToken == "}") &&
cppLooksLikeConstructor(stream.current()))
return "def";
}
},
namespaceSeparator: "::",
modeProps: {fold: ["brace", "include"]}
});
def("text/x-java", {
name: "clike",
keywords: words("abstract assert break case catch class const continue default " +
"do else enum extends final finally float for goto if implements import " +
"instanceof interface native new package private protected public " +
"return static strictfp super switch synchronized this throw throws transient " +
"try volatile while @interface"),
types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
"Integer Long Number Object Short String StringBuffer StringBuilder Void"),
blockKeywords: words("catch class do else finally for if switch try while"),
defKeywords: words("class interface enum @interface"),
typeFirstDefinitions: true,
atoms: words("true false null"),
number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
hooks: {
"@": function(stream) {
// Don't match the @interface keyword.
if (stream.match('interface', false)) return false;
stream.eatWhile(/[\w\$_]/);
return "meta";
}
},
modeProps: {fold: ["brace", "import"]}
});
def("text/x-csharp", {
name: "clike",
keywords: words("abstract as async await base break case catch checked class const continue" +
" default delegate do else enum event explicit extern finally fixed for" +
" foreach goto if implicit in interface internal is lock namespace new" +
" operator out override params private protected public readonly ref return sealed" +
" sizeof stackalloc static struct switch this throw try typeof unchecked" +
" unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
" global group into join let orderby partial remove select set value var yield"),
types: words("Action Boolean Byte Char DateTime DateTimeOffset Decimal Double Func" +
" Guid Int16 Int32 Int64 Object SByte Single String Task TimeSpan UInt16 UInt32" +
" UInt64 bool byte char decimal double short int long object" +
" sbyte float string ushort uint ulong"),
blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
defKeywords: words("class interface namespace struct var"),
typeFirstDefinitions: true,
atoms: words("true false null"),
hooks: {
"@": function(stream, state) {
if (stream.eat('"')) {
state.tokenize = tokenAtString;
return tokenAtString(stream, state);
}
stream.eatWhile(/[\w\$_]/);
return "meta";
}
}
});
function tokenTripleString(stream, state) {
var escaped = false;
while (!stream.eol()) {
if (!escaped && stream.match('"""')) {
state.tokenize = null;
break;
}
escaped = stream.next() == "\\" && !escaped;
}
return "string";
}
function tokenNestedComment(depth) {
return function (stream, state) {
var ch
while (ch = stream.next()) {
if (ch == "*" && stream.eat("/")) {
if (depth == 1) {
state.tokenize = null
break
} else {
state.tokenize = tokenNestedComment(depth - 1)
return state.tokenize(stream, state)
}
} else if (ch == "/" && stream.eat("*")) {
state.tokenize = tokenNestedComment(depth + 1)
return state.tokenize(stream, state)
}
}
return "comment"
}
}
def("text/x-scala", {
name: "clike",
keywords: words(
/* scala */
"abstract case catch class def do else extends final finally for forSome if " +
"implicit import lazy match new null object override package private protected return " +
"sealed super this throw trait try type val var while with yield _ " +
/* package scala */
"assert assume require print println printf readLine readBoolean readByte readShort " +
"readChar readInt readLong readFloat readDouble"
),
types: words(
"AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
"Enumeration Equiv Error Exception Fractional Function IndexedSeq Int Integral Iterable " +
"Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
"Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
"StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector " +
/* package java.lang */
"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
),
multiLineStrings: true,
blockKeywords: words("catch class enum do else finally for forSome if match switch try while"),
defKeywords: words("class enum def object package trait type val var"),
atoms: words("true false null"),
indentStatements: false,
indentSwitch: false,
isOperatorChar: /[+\-*&%=<>!?|\/#:@]/,
hooks: {
"@": function(stream) {
stream.eatWhile(/[\w\$_]/);
return "meta";
},
'"': function(stream, state) {
if (!stream.match('""')) return false;
state.tokenize = tokenTripleString;
return state.tokenize(stream, state);
},
"'": function(stream) {
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
return "atom";
},
"=": function(stream, state) {
var cx = state.context
if (cx.type == "}" && cx.align && stream.eat(">")) {
state.context = new Context(cx.indented, cx.column, cx.type, cx.info, null, cx.prev)
return "operator"
} else {
return false
}
},
"/": function(stream, state) {
if (!stream.eat("*")) return false
state.tokenize = tokenNestedComment(1)
return state.tokenize(stream, state)
}
},
modeProps: {closeBrackets: {pairs: '()[]{}""', triples: '"'}}
});
function tokenKotlinString(tripleString){
return function (stream, state) {
var escaped = false, next, end = false;
while (!stream.eol()) {
if (!tripleString && !escaped && stream.match('"') ) {end = true; break;}
if (tripleString && stream.match('"""')) {end = true; break;}
next = stream.next();
if(!escaped && next == "$" && stream.match('{'))
stream.skipTo("}");
escaped = !escaped && next == "\\" && !tripleString;
}
if (end || !tripleString)
state.tokenize = null;
return "string";
}
}
def("text/x-kotlin", {
name: "clike",
keywords: words(
/*keywords*/
"package as typealias class interface this super val operator " +
"var fun for is in This throw return annotation " +
"break continue object if else while do try when !in !is as? " +
/*soft keywords*/
"file import where by get set abstract enum open inner override private public internal " +
"protected catch finally out final vararg reified dynamic companion constructor init " +
"sealed field property receiver param sparam lateinit data inline noinline tailrec " +
"external annotation crossinline const operator infix suspend actual expect setparam"
),
types: words(
/* package java.lang */
"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void Annotation Any BooleanArray " +
"ByteArray Char CharArray DeprecationLevel DoubleArray Enum FloatArray Function Int IntArray Lazy " +
"LazyThreadSafetyMode LongArray Nothing ShortArray Unit"
),
intendSwitch: false,
indentStatements: false,
multiLineStrings: true,
number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+(\.\d+)?|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
blockKeywords: words("catch class do else finally for if where try while enum"),
defKeywords: words("class val var object interface fun"),
atoms: words("true false null this"),
hooks: {
"@": function(stream) {
stream.eatWhile(/[\w\$_]/);
return "meta";
},
'"': function(stream, state) {
state.tokenize = tokenKotlinString(stream.match('""'));
return state.tokenize(stream, state);
},
indent: function(state, ctx, textAfter, indentUnit) {
var firstChar = textAfter && textAfter.charAt(0);
if ((state.prevToken == "}" || state.prevToken == ")") && textAfter == "")
return state.indented;
if (state.prevToken == "operator" && textAfter != "}" ||
state.prevToken == "variable" && firstChar == "." ||
(state.prevToken == "}" || state.prevToken == ")") && firstChar == ".")
return indentUnit * 2 + ctx.indented;
if (ctx.align && ctx.type == "}")
return ctx.indented + (state.context.type == (textAfter || "").charAt(0) ? 0 : indentUnit);
}
},
modeProps: {closeBrackets: {triples: '"'}}
});
def(["x-shader/x-vertex", "x-shader/x-fragment"], {
name: "clike",
keywords: words("sampler1D sampler2D sampler3D samplerCube " +
"sampler1DShadow sampler2DShadow " +
"const attribute uniform varying " +
"break continue discard return " +
"for while do if else struct " +
"in out inout"),
types: words("float int bool void " +
"vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
"mat2 mat3 mat4"),
blockKeywords: words("for while do if else struct"),
builtin: words("radians degrees sin cos tan asin acos atan " +
"pow exp log exp2 sqrt inversesqrt " +
"abs sign floor ceil fract mod min max clamp mix step smoothstep " +
"length distance dot cross normalize ftransform faceforward " +
"reflect refract matrixCompMult " +
"lessThan lessThanEqual greaterThan greaterThanEqual " +
"equal notEqual any all not " +
"texture1D texture1DProj texture1DLod texture1DProjLod " +
"texture2D texture2DProj texture2DLod texture2DProjLod " +
"texture3D texture3DProj texture3DLod texture3DProjLod " +
"textureCube textureCubeLod " +
"shadow1D shadow2D shadow1DProj shadow2DProj " +
"shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
"dFdx dFdy fwidth " +
"noise1 noise2 noise3 noise4"),
atoms: words("true false " +
"gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
"gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
"gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
"gl_FogCoord gl_PointCoord " +
"gl_Position gl_PointSize gl_ClipVertex " +
"gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
"gl_TexCoord gl_FogFragCoord " +
"gl_FragCoord gl_FrontFacing " +
"gl_FragData gl_FragDepth " +
"gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
"gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
"gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
"gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
"gl_ProjectionMatrixInverseTranspose " +
"gl_ModelViewProjectionMatrixInverseTranspose " +
"gl_TextureMatrixInverseTranspose " +
"gl_NormalScale gl_DepthRange gl_ClipPlane " +
"gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
"gl_FrontLightModelProduct gl_BackLightModelProduct " +
"gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
"gl_FogParameters " +
"gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
"gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
"gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
"gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
"gl_MaxDrawBuffers"),
indentSwitch: false,
hooks: {"#": cppHook},
modeProps: {fold: ["brace", "include"]}
});
def("text/x-nesc", {
name: "clike",
keywords: words(cKeywords + " as atomic async call command component components configuration event generic " +
"implementation includes interface module new norace nx_struct nx_union post provides " +
"signal task uses abstract extends"),
types: cTypes,
blockKeywords: words(cBlockKeywords),
atoms: words("null true false"),
hooks: {"#": cppHook},
modeProps: {fold: ["brace", "include"]}
});
def("text/x-objectivec", {
name: "clike",
keywords: words(cKeywords + " bycopy byref in inout oneway out self super atomic nonatomic retain copy " +
"readwrite readonly strong weak assign typeof nullable nonnull null_resettable _cmd " +
"@interface @implementation @end @protocol @encode @property @synthesize @dynamic @class " +
"@public @package @private @protected @required @optional @try @catch @finally @import " +
"@selector @encode @defs @synchronized @autoreleasepool @compatibility_alias @available"),
types: objCTypes,
builtin: words("FOUNDATION_EXPORT FOUNDATION_EXTERN NS_INLINE NS_FORMAT_FUNCTION NS_RETURNS_RETAINED " +
"NS_ERROR_ENUM NS_RETURNS_NOT_RETAINED NS_RETURNS_INNER_POINTER NS_DESIGNATED_INITIALIZER " +
"NS_ENUM NS_OPTIONS NS_REQUIRES_NIL_TERMINATION NS_ASSUME_NONNULL_BEGIN " +
"NS_ASSUME_NONNULL_END NS_SWIFT_NAME NS_REFINED_FOR_SWIFT"),
blockKeywords: words(cBlockKeywords + " @synthesize @try @catch @finally @autoreleasepool @synchronized"),
defKeywords: words(cDefKeywords + " @interface @implementation @protocol @class"),
dontIndentStatements: /^@.*$/,
typeFirstDefinitions: true,
atoms: words("YES NO NULL Nil nil true false nullptr"),
isReservedIdentifier: cIsReservedIdentifier,
hooks: {
"#": cppHook,
"*": pointerHook,
},
modeProps: {fold: ["brace", "include"]}
});
def("text/x-squirrel", {
name: "clike",
keywords: words("base break clone continue const default delete enum extends function in class" +
" foreach local resume return this throw typeof yield constructor instanceof static"),
types: cTypes,
blockKeywords: words("case catch class else for foreach if switch try while"),
defKeywords: words("function local class"),
typeFirstDefinitions: true,
atoms: words("true false null"),
hooks: {"#": cppHook},
modeProps: {fold: ["brace", "include"]}
});
// Ceylon Strings need to deal with interpolation
var stringTokenizer = null;
function tokenCeylonString(type) {
return function(stream, state) {
var escaped = false, next, end = false;
while (!stream.eol()) {
if (!escaped && stream.match('"') &&
(type == "single" || stream.match('""'))) {
end = true;
break;
}
if (!escaped && stream.match('``')) {
stringTokenizer = tokenCeylonString(type);
end = true;
break;
}
next = stream.next();
escaped = type == "single" && !escaped && next == "\\";
}
if (end)
state.tokenize = null;
return "string";
}
}
def("text/x-ceylon", {
name: "clike",
keywords: words("abstracts alias assembly assert assign break case catch class continue dynamic else" +
" exists extends finally for function given if import in interface is let module new" +
" nonempty object of out outer package return satisfies super switch then this throw" +
" try value void while"),
types: function(word) {
// In Ceylon all identifiers that start with an uppercase are types
var first = word.charAt(0);
return (first === first.toUpperCase() && first !== first.toLowerCase());
},
blockKeywords: words("case catch class dynamic else finally for function if interface module new object switch try while"),
defKeywords: words("class dynamic function interface module object package value"),
builtin: words("abstract actual aliased annotation by default deprecated doc final formal late license" +
" native optional sealed see serializable shared suppressWarnings tagged throws variable"),
isPunctuationChar: /[\[\]{}\(\),;\:\.`]/,
isOperatorChar: /[+\-*&%=<>!?|^~:\/]/,
numberStart: /[\d#$]/,
number: /^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i,
multiLineStrings: true,
typeFirstDefinitions: true,
atoms: words("true false null larger smaller equal empty finished"),
indentSwitch: false,
styleDefs: false,
hooks: {
"@": function(stream) {
stream.eatWhile(/[\w\$_]/);
return "meta";
},
'"': function(stream, state) {
state.tokenize = tokenCeylonString(stream.match('""') ? "triple" : "single");
return state.tokenize(stream, state);
},
'`': function(stream, state) {
if (!stringTokenizer || !stream.match('`')) return false;
state.tokenize = stringTokenizer;
stringTokenizer = null;
return state.tokenize(stream, state);
},
"'": function(stream) {
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
return "atom";
},
token: function(_stream, state, style) {
if ((style == "variable" || style == "type") &&
state.prevToken == ".") {
return "variable-2";
}
}
},
modeProps: {
fold: ["brace", "import"],
closeBrackets: {triples: '"'}
}
});
});

View File

@@ -0,0 +1,380 @@
<!doctype html>
<title>CodeMirror: C-like 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="../../addon/edit/matchbrackets.js"></script>
<link rel="stylesheet" href="../../addon/hint/show-hint.css">
<script src="../../addon/hint/show-hint.js"></script>
<script src="clike.js"></script>
<style>.CodeMirror {border: 2px inset #dee;}</style>
<div id=nav>
<a href="https://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="#">C-like</a>
</ul>
</div>
<article>
<h2>C-like mode</h2>
<div><textarea id="c-code">
/* C demo code */
#include <zmq.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#include <stdio.h>
#include <fcntl.h>
#include <malloc.h>
typedef struct {
void* arg_socket;
zmq_msg_t* arg_msg;
char* arg_string;
unsigned long arg_len;
int arg_int, arg_command;
int signal_fd;
int pad;
void* context;
sem_t sem;
} acl_zmq_context;
#define p(X) (context->arg_##X)
void* zmq_thread(void* context_pointer) {
acl_zmq_context* context = (acl_zmq_context*)context_pointer;
char ok = 'K', err = 'X';
int res;
while (1) {
while ((res = sem_wait(&amp;context->sem)) == EINTR);
if (res) {write(context->signal_fd, &amp;err, 1); goto cleanup;}
switch(p(command)) {
case 0: goto cleanup;
case 1: p(socket) = zmq_socket(context->context, p(int)); break;
case 2: p(int) = zmq_close(p(socket)); break;
case 3: p(int) = zmq_bind(p(socket), p(string)); break;
case 4: p(int) = zmq_connect(p(socket), p(string)); break;
case 5: p(int) = zmq_getsockopt(p(socket), p(int), (void*)p(string), &amp;p(len)); break;
case 6: p(int) = zmq_setsockopt(p(socket), p(int), (void*)p(string), p(len)); break;
case 7: p(int) = zmq_send(p(socket), p(msg), p(int)); break;
case 8: p(int) = zmq_recv(p(socket), p(msg), p(int)); break;
case 9: p(int) = zmq_poll(p(socket), p(int), p(len)); break;
}
p(command) = errno;
write(context->signal_fd, &amp;ok, 1);
}
cleanup:
close(context->signal_fd);
free(context_pointer);
return 0;
}
void* zmq_thread_init(void* zmq_context, int signal_fd) {
acl_zmq_context* context = malloc(sizeof(acl_zmq_context));
pthread_t thread;
context->context = zmq_context;
context->signal_fd = signal_fd;
sem_init(&amp;context->sem, 1, 0);
pthread_create(&amp;thread, 0, &amp;zmq_thread, context);
pthread_detach(thread);
return context;
}
</textarea></div>
<h2>C++ example</h2>
<div><textarea id="cpp-code">
#include <iostream>
#include "mystuff/util.h"
namespace {
enum Enum {
VAL1, VAL2, VAL3
};
char32_t unicode_string = U"\U0010FFFF";
string raw_string = R"delim(anything
you
want)delim";
int Helper(const MyType& param) {
return 0;
}
} // namespace
class ForwardDec;
template <class T, class V>
class Class : public BaseClass {
const MyType<T, V> member_;
public:
const MyType<T, V>& Method() const {
return member_;
}
void Method2(MyType<T, V>* value);
}
template <class T, class V>
void Class::Method2(MyType<T, V>* value) {
std::out << 1 >> method();
value->Method3(member_);
member_ = value;
}
</textarea></div>
<h2>Objective-C example</h2>
<div><textarea id="objectivec-code">
/*
This is a longer comment
That spans two lines
*/
#import "MyClass.h"
#import <AFramework/AFrameork.h>
@import BFrameworkModule;
NS_ENUM(SomeValues) {
aValue = 1;
};
// A Class Extension with some properties
@interface MyClass ()<AProtocol>
@property(atomic, readwrite, assign) NSInteger anInt;
@property(nonatomic, strong, nullable) NSString *aString;
@end
@implementation YourAppDelegate
- (instancetype)initWithString:(NSString *)aStringVar {
if ((self = [super init])) {
aString = aStringVar;
}
return self;
}
- (BOOL)doSomething:(float)progress {
NSString *myString = @"This is a ObjC string %f ";
myString = [[NSString stringWithFormat:myString, progress] stringByAppendingString:self.aString];
return myString.length > 100 ? NO : YES;
}
@end
</textarea></div>
<h2>Java example</h2>
<div><textarea id="java-code">
import com.demo.util.MyType;
import com.demo.util.MyInterface;
public enum Enum {
VAL1, VAL2, VAL3
}
public class Class<T, V> implements MyInterface {
public static final MyType<T, V> member;
private class InnerClass {
public int zero() {
return 0;
}
}
@Override
public MyType method() {
return member;
}
public void method2(MyType<T, V> value) {
method();
value.method3();
member = value;
}
}
</textarea></div>
<h2>Scala example</h2>
<div><textarea id="scala-code">
object FilterTest extends App {
def filter(xs: List[Int], threshold: Int) = {
def process(ys: List[Int]): List[Int] =
if (ys.isEmpty) ys
else if (ys.head < threshold) ys.head :: process(ys.tail)
else process(ys.tail)
process(xs)
}
println(filter(List(1, 9, 2, 8, 3, 7, 4), 5))
}
</textarea></div>
<h2>Kotlin mode</h2>
<div><textarea id="kotlin-code">
package org.wasabi.http
import java.util.concurrent.Executors
import java.net.InetSocketAddress
import org.wasabi.app.AppConfiguration
import io.netty.bootstrap.ServerBootstrap
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioServerSocketChannel
import org.wasabi.app.AppServer
public class HttpServer(private val appServer: AppServer) {
val bootstrap: ServerBootstrap
val primaryGroup: NioEventLoopGroup
val workerGroup: NioEventLoopGroup
init {
// Define worker groups
primaryGroup = NioEventLoopGroup()
workerGroup = NioEventLoopGroup()
// Initialize bootstrap of server
bootstrap = ServerBootstrap()
bootstrap.group(primaryGroup, workerGroup)
bootstrap.channel(javaClass<NioServerSocketChannel>())
bootstrap.childHandler(NettyPipelineInitializer(appServer))
}
public fun start(wait: Boolean = true) {
val channel = bootstrap.bind(appServer.configuration.port)?.sync()?.channel()
if (wait) {
channel?.closeFuture()?.sync()
}
}
public fun stop() {
// Shutdown all event loops
primaryGroup.shutdownGracefully()
workerGroup.shutdownGracefully()
// Wait till all threads are terminated
primaryGroup.terminationFuture().sync()
workerGroup.terminationFuture().sync()
}
}
</textarea></div>
<h2>Ceylon mode</h2>
<div><textarea id="ceylon-code">
"Produces the [[stream|Iterable]] that results from repeated
application of the given [[function|next]] to the given
[[first]] element of the stream, until the function first
returns [[finished]]. If the given function never returns
`finished`, the resulting stream is infinite.
For example:
loop(0)(2.plus).takeWhile(10.largerThan)
produces the stream `{ 0, 2, 4, 6, 8 }`."
tagged("Streams")
shared {Element+} loop&lt;Element&gt;(
"The first element of the resulting stream."
Element first)(
"The function that produces the next element of the
stream, given the current element. The function may
return [[finished]] to indicate the end of the
stream."
Element|Finished next(Element element))
=&gt; let (start = first)
object satisfies {Element+} {
first =&gt; start;
empty =&gt; false;
function nextElement(Element element)
=&gt; next(element);
iterator()
=&gt; object satisfies Iterator&lt;Element&gt; {
variable Element|Finished current = start;
shared actual Element|Finished next() {
if (!is Finished result = current) {
current = nextElement(result);
return result;
}
else {
return finished;
}
}
};
};
</textarea></div>
<script>
var cEditor = CodeMirror.fromTextArea(document.getElementById("c-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-csrc"
});
var cppEditor = CodeMirror.fromTextArea(document.getElementById("cpp-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-c++src"
});
var javaEditor = CodeMirror.fromTextArea(document.getElementById("java-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-java"
});
var objectivecEditor = CodeMirror.fromTextArea(document.getElementById("objectivec-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-objectivec"
});
var scalaEditor = CodeMirror.fromTextArea(document.getElementById("scala-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-scala"
});
var kotlinEditor = CodeMirror.fromTextArea(document.getElementById("kotlin-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-kotlin"
});
var ceylonEditor = CodeMirror.fromTextArea(document.getElementById("ceylon-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-ceylon"
});
var mac = CodeMirror.keyMap.default == CodeMirror.keyMap.macDefault;
CodeMirror.keyMap.default[(mac ? "Cmd" : "Ctrl") + "-Space"] = "autocomplete";
</script>
<p>Simple mode that tries to handle C-like languages as well as it
can. Takes two configuration parameters: <code>keywords</code>, an
object whose property names are the keywords in the language,
and <code>useCPP</code>, which determines whether C preprocessor
directives are recognized.</p>
<p><strong>MIME types defined:</strong> <code>text/x-csrc</code>
(C), <code>text/x-c++src</code> (C++), <code>text/x-java</code>
(Java), <code>text/x-csharp</code> (C#),
<code>text/x-objectivec</code> (Objective-C),
<code>text/x-scala</code> (Scala), <code>text/x-vertex</code>
<code>x-shader/x-fragment</code> (shader programs),
<code>text/x-squirrel</code> (Squirrel) and
<code>text/x-ceylon</code> (Ceylon)</p>
</article>

View File

@@ -0,0 +1,767 @@
<!doctype html>
<title>CodeMirror: Scala mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/ambiance.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="clike.js"></script>
<div id=nav>
<a href="https://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="#">Scala</a>
</ul>
</div>
<article>
<h2>Scala mode</h2>
<form>
<textarea id="code" name="code">
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.collection
import generic._
import mutable.{ Builder, ListBuffer }
import annotation.{tailrec, migration, bridge}
import annotation.unchecked.{ uncheckedVariance => uV }
import parallel.ParIterable
/** A template trait for traversable collections of type `Traversable[A]`.
*
* $traversableInfo
* @define mutability
* @define traversableInfo
* This is a base trait of all kinds of $mutability Scala collections. It
* implements the behavior common to all collections, in terms of a method
* `foreach` with signature:
* {{{
* def foreach[U](f: Elem => U): Unit
* }}}
* Collection classes mixing in this trait provide a concrete
* `foreach` method which traverses all the
* elements contained in the collection, applying a given function to each.
* They also need to provide a method `newBuilder`
* which creates a builder for collections of the same kind.
*
* A traversable class might or might not have two properties: strictness
* and orderedness. Neither is represented as a type.
*
* The instances of a strict collection class have all their elements
* computed before they can be used as values. By contrast, instances of
* a non-strict collection class may defer computation of some of their
* elements until after the instance is available as a value.
* A typical example of a non-strict collection class is a
* <a href="../immutable/Stream.html" target="ContentFrame">
* `scala.collection.immutable.Stream`</a>.
* A more general class of examples are `TraversableViews`.
*
* If a collection is an instance of an ordered collection class, traversing
* its elements with `foreach` will always visit elements in the
* same order, even for different runs of the program. If the class is not
* ordered, `foreach` can visit elements in different orders for
* different runs (but it will keep the same order in the same run).'
*
* A typical example of a collection class which is not ordered is a
* `HashMap` of objects. The traversal order for hash maps will
* depend on the hash codes of its elements, and these hash codes might
* differ from one run to the next. By contrast, a `LinkedHashMap`
* is ordered because it's `foreach` method visits elements in the
* order they were inserted into the `HashMap`.
*
* @author Martin Odersky
* @version 2.8
* @since 2.8
* @tparam A the element type of the collection
* @tparam Repr the type of the actual collection containing the elements.
*
* @define Coll Traversable
* @define coll traversable collection
*/
trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
with FilterMonadic[A, Repr]
with TraversableOnce[A]
with GenTraversableLike[A, Repr]
with Parallelizable[A, ParIterable[A]]
{
self =>
import Traversable.breaks._
/** The type implementing this traversable */
protected type Self = Repr
/** The collection of type $coll underlying this `TraversableLike` object.
* By default this is implemented as the `TraversableLike` object itself,
* but this can be overridden.
*/
def repr: Repr = this.asInstanceOf[Repr]
/** The underlying collection seen as an instance of `$Coll`.
* By default this is implemented as the current collection object itself,
* but this can be overridden.
*/
protected[this] def thisCollection: Traversable[A] = this.asInstanceOf[Traversable[A]]
/** A conversion from collections of type `Repr` to `$Coll` objects.
* By default this is implemented as just a cast, but this can be overridden.
*/
protected[this] def toCollection(repr: Repr): Traversable[A] = repr.asInstanceOf[Traversable[A]]
/** Creates a new builder for this collection type.
*/
protected[this] def newBuilder: Builder[A, Repr]
protected[this] def parCombiner = ParIterable.newCombiner[A]
/** Applies a function `f` to all elements of this $coll.
*
* Note: this method underlies the implementation of most other bulk operations.
* It's important to implement this method in an efficient way.
*
*
* @param f the function that is applied for its side-effect to every element.
* The result of function `f` is discarded.
*
* @tparam U the type parameter describing the result of function `f`.
* This result will always be ignored. Typically `U` is `Unit`,
* but this is not necessary.
*
* @usecase def foreach(f: A => Unit): Unit
*/
def foreach[U](f: A => U): Unit
/** Tests whether this $coll is empty.
*
* @return `true` if the $coll contain no elements, `false` otherwise.
*/
def isEmpty: Boolean = {
var result = true
breakable {
for (x <- this) {
result = false
break
}
}
result
}
/** Tests whether this $coll is known to have a finite size.
* All strict collections are known to have finite size. For a non-strict collection
* such as `Stream`, the predicate returns `true` if all elements have been computed.
* It returns `false` if the stream is not yet evaluated to the end.
*
* Note: many collection methods will not work on collections of infinite sizes.
*
* @return `true` if this collection is known to have finite size, `false` otherwise.
*/
def hasDefiniteSize = true
def ++[B >: A, That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
if (that.isInstanceOf[IndexedSeqLike[_, _]]) b.sizeHint(this, that.seq.size)
b ++= thisCollection
b ++= that.seq
b.result
}
@bridge
def ++[B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That =
++(that: GenTraversableOnce[B])(bf)
/** Concatenates this $coll with the elements of a traversable collection.
* It differs from ++ in that the right operand determines the type of the
* resulting collection rather than the left one.
*
* @param that the traversable to append.
* @tparam B the element type of the returned collection.
* @tparam That $thatinfo
* @param bf $bfinfo
* @return a new collection of type `That` which contains all elements
* of this $coll followed by all elements of `that`.
*
* @usecase def ++:[B](that: TraversableOnce[B]): $Coll[B]
*
* @return a new $coll which contains all elements of this $coll
* followed by all elements of `that`.
*/
def ++:[B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
if (that.isInstanceOf[IndexedSeqLike[_, _]]) b.sizeHint(this, that.size)
b ++= that
b ++= thisCollection
b.result
}
/** This overload exists because: for the implementation of ++: we should reuse
* that of ++ because many collections override it with more efficient versions.
* Since TraversableOnce has no '++' method, we have to implement that directly,
* but Traversable and down can use the overload.
*/
def ++:[B >: A, That](that: Traversable[B])(implicit bf: CanBuildFrom[Repr, B, That]): That =
(that ++ seq)(breakOut)
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
b.sizeHint(this)
for (x <- this) b += f(x)
b.result
}
def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
for (x <- this) b ++= f(x).seq
b.result
}
/** Selects all elements of this $coll which satisfy a predicate.
*
* @param p the predicate used to test elements.
* @return a new $coll consisting of all elements of this $coll that satisfy the given
* predicate `p`. The order of the elements is preserved.
*/
def filter(p: A => Boolean): Repr = {
val b = newBuilder
for (x <- this)
if (p(x)) b += x
b.result
}
/** Selects all elements of this $coll which do not satisfy a predicate.
*
* @param p the predicate used to test elements.
* @return a new $coll consisting of all elements of this $coll that do not satisfy the given
* predicate `p`. The order of the elements is preserved.
*/
def filterNot(p: A => Boolean): Repr = filter(!p(_))
def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
for (x <- this) if (pf.isDefinedAt(x)) b += pf(x)
b.result
}
/** Builds a new collection by applying an option-valued function to all
* elements of this $coll on which the function is defined.
*
* @param f the option-valued function which filters and maps the $coll.
* @tparam B the element type of the returned collection.
* @tparam That $thatinfo
* @param bf $bfinfo
* @return a new collection of type `That` resulting from applying the option-valued function
* `f` to each element and collecting all defined results.
* The order of the elements is preserved.
*
* @usecase def filterMap[B](f: A => Option[B]): $Coll[B]
*
* @param pf the partial function which filters and maps the $coll.
* @return a new $coll resulting from applying the given option-valued function
* `f` to each element and collecting all defined results.
* The order of the elements is preserved.
def filterMap[B, That](f: A => Option[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
for (x <- this)
f(x) match {
case Some(y) => b += y
case _ =>
}
b.result
}
*/
/** Partitions this $coll in two ${coll}s according to a predicate.
*
* @param p the predicate on which to partition.
* @return a pair of ${coll}s: the first $coll consists of all elements that
* satisfy the predicate `p` and the second $coll consists of all elements
* that don't. The relative order of the elements in the resulting ${coll}s
* is the same as in the original $coll.
*/
def partition(p: A => Boolean): (Repr, Repr) = {
val l, r = newBuilder
for (x <- this) (if (p(x)) l else r) += x
(l.result, r.result)
}
def groupBy[K](f: A => K): immutable.Map[K, Repr] = {
val m = mutable.Map.empty[K, Builder[A, Repr]]
for (elem <- this) {
val key = f(elem)
val bldr = m.getOrElseUpdate(key, newBuilder)
bldr += elem
}
val b = immutable.Map.newBuilder[K, Repr]
for ((k, v) <- m)
b += ((k, v.result))
b.result
}
/** Tests whether a predicate holds for all elements of this $coll.
*
* $mayNotTerminateInf
*
* @param p the predicate used to test elements.
* @return `true` if the given predicate `p` holds for all elements
* of this $coll, otherwise `false`.
*/
def forall(p: A => Boolean): Boolean = {
var result = true
breakable {
for (x <- this)
if (!p(x)) { result = false; break }
}
result
}
/** Tests whether a predicate holds for some of the elements of this $coll.
*
* $mayNotTerminateInf
*
* @param p the predicate used to test elements.
* @return `true` if the given predicate `p` holds for some of the
* elements of this $coll, otherwise `false`.
*/
def exists(p: A => Boolean): Boolean = {
var result = false
breakable {
for (x <- this)
if (p(x)) { result = true; break }
}
result
}
/** Finds the first element of the $coll satisfying a predicate, if any.
*
* $mayNotTerminateInf
* $orderDependent
*
* @param p the predicate used to test elements.
* @return an option value containing the first element in the $coll
* that satisfies `p`, or `None` if none exists.
*/
def find(p: A => Boolean): Option[A] = {
var result: Option[A] = None
breakable {
for (x <- this)
if (p(x)) { result = Some(x); break }
}
result
}
def scan[B >: A, That](z: B)(op: (B, B) => B)(implicit cbf: CanBuildFrom[Repr, B, That]): That = scanLeft(z)(op)
def scanLeft[B, That](z: B)(op: (B, A) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
b.sizeHint(this, 1)
var acc = z
b += acc
for (x <- this) { acc = op(acc, x); b += acc }
b.result
}
@migration(2, 9,
"This scanRight definition has changed in 2.9.\n" +
"The previous behavior can be reproduced with scanRight.reverse."
)
def scanRight[B, That](z: B)(op: (A, B) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
var scanned = List(z)
var acc = z
for (x <- reversed) {
acc = op(x, acc)
scanned ::= acc
}
val b = bf(repr)
for (elem <- scanned) b += elem
b.result
}
/** Selects the first element of this $coll.
* $orderDependent
* @return the first element of this $coll.
* @throws `NoSuchElementException` if the $coll is empty.
*/
def head: A = {
var result: () => A = () => throw new NoSuchElementException
breakable {
for (x <- this) {
result = () => x
break
}
}
result()
}
/** Optionally selects the first element.
* $orderDependent
* @return the first element of this $coll if it is nonempty, `None` if it is empty.
*/
def headOption: Option[A] = if (isEmpty) None else Some(head)
/** Selects all elements except the first.
* $orderDependent
* @return a $coll consisting of all elements of this $coll
* except the first one.
* @throws `UnsupportedOperationException` if the $coll is empty.
*/
override def tail: Repr = {
if (isEmpty) throw new UnsupportedOperationException("empty.tail")
drop(1)
}
/** Selects the last element.
* $orderDependent
* @return The last element of this $coll.
* @throws NoSuchElementException If the $coll is empty.
*/
def last: A = {
var lst = head
for (x <- this)
lst = x
lst
}
/** Optionally selects the last element.
* $orderDependent
* @return the last element of this $coll$ if it is nonempty, `None` if it is empty.
*/
def lastOption: Option[A] = if (isEmpty) None else Some(last)
/** Selects all elements except the last.
* $orderDependent
* @return a $coll consisting of all elements of this $coll
* except the last one.
* @throws `UnsupportedOperationException` if the $coll is empty.
*/
def init: Repr = {
if (isEmpty) throw new UnsupportedOperationException("empty.init")
var lst = head
var follow = false
val b = newBuilder
b.sizeHint(this, -1)
for (x <- this.seq) {
if (follow) b += lst
else follow = true
lst = x
}
b.result
}
def take(n: Int): Repr = slice(0, n)
def drop(n: Int): Repr =
if (n <= 0) {
val b = newBuilder
b.sizeHint(this)
b ++= thisCollection result
}
else sliceWithKnownDelta(n, Int.MaxValue, -n)
def slice(from: Int, until: Int): Repr = sliceWithKnownBound(math.max(from, 0), until)
// Precondition: from >= 0, until > 0, builder already configured for building.
private[this] def sliceInternal(from: Int, until: Int, b: Builder[A, Repr]): Repr = {
var i = 0
breakable {
for (x <- this.seq) {
if (i >= from) b += x
i += 1
if (i >= until) break
}
}
b.result
}
// Precondition: from >= 0
private[scala] def sliceWithKnownDelta(from: Int, until: Int, delta: Int): Repr = {
val b = newBuilder
if (until <= from) b.result
else {
b.sizeHint(this, delta)
sliceInternal(from, until, b)
}
}
// Precondition: from >= 0
private[scala] def sliceWithKnownBound(from: Int, until: Int): Repr = {
val b = newBuilder
if (until <= from) b.result
else {
b.sizeHintBounded(until - from, this)
sliceInternal(from, until, b)
}
}
def takeWhile(p: A => Boolean): Repr = {
val b = newBuilder
breakable {
for (x <- this) {
if (!p(x)) break
b += x
}
}
b.result
}
def dropWhile(p: A => Boolean): Repr = {
val b = newBuilder
var go = false
for (x <- this) {
if (!p(x)) go = true
if (go) b += x
}
b.result
}
def span(p: A => Boolean): (Repr, Repr) = {
val l, r = newBuilder
var toLeft = true
for (x <- this) {
toLeft = toLeft && p(x)
(if (toLeft) l else r) += x
}
(l.result, r.result)
}
def splitAt(n: Int): (Repr, Repr) = {
val l, r = newBuilder
l.sizeHintBounded(n, this)
if (n >= 0) r.sizeHint(this, -n)
var i = 0
for (x <- this) {
(if (i < n) l else r) += x
i += 1
}
(l.result, r.result)
}
/** Iterates over the tails of this $coll. The first value will be this
* $coll and the final one will be an empty $coll, with the intervening
* values the results of successive applications of `tail`.
*
* @return an iterator over all the tails of this $coll
* @example `List(1,2,3).tails = Iterator(List(1,2,3), List(2,3), List(3), Nil)`
*/
def tails: Iterator[Repr] = iterateUntilEmpty(_.tail)
/** Iterates over the inits of this $coll. The first value will be this
* $coll and the final one will be an empty $coll, with the intervening
* values the results of successive applications of `init`.
*
* @return an iterator over all the inits of this $coll
* @example `List(1,2,3).inits = Iterator(List(1,2,3), List(1,2), List(1), Nil)`
*/
def inits: Iterator[Repr] = iterateUntilEmpty(_.init)
/** Copies elements of this $coll to an array.
* Fills the given array `xs` with at most `len` elements of
* this $coll, starting at position `start`.
* Copying will stop once either the end of the current $coll is reached,
* or the end of the array is reached, or `len` elements have been copied.
*
* $willNotTerminateInf
*
* @param xs the array to fill.
* @param start the starting index.
* @param len the maximal number of elements to copy.
* @tparam B the type of the elements of the array.
*
*
* @usecase def copyToArray(xs: Array[A], start: Int, len: Int): Unit
*/
def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) {
var i = start
val end = (start + len) min xs.length
breakable {
for (x <- this) {
if (i >= end) break
xs(i) = x
i += 1
}
}
}
def toTraversable: Traversable[A] = thisCollection
def toIterator: Iterator[A] = toStream.iterator
def toStream: Stream[A] = toBuffer.toStream
/** Converts this $coll to a string.
*
* @return a string representation of this collection. By default this
* string consists of the `stringPrefix` of this $coll,
* followed by all elements separated by commas and enclosed in parentheses.
*/
override def toString = mkString(stringPrefix + "(", ", ", ")")
/** Defines the prefix of this object's `toString` representation.
*
* @return a string representation which starts the result of `toString`
* applied to this $coll. By default the string prefix is the
* simple name of the collection class $coll.
*/
def stringPrefix : String = {
var string = repr.asInstanceOf[AnyRef].getClass.getName
val idx1 = string.lastIndexOf('.' : Int)
if (idx1 != -1) string = string.substring(idx1 + 1)
val idx2 = string.indexOf('$')
if (idx2 != -1) string = string.substring(0, idx2)
string
}
/** Creates a non-strict view of this $coll.
*
* @return a non-strict view of this $coll.
*/
def view = new TraversableView[A, Repr] {
protected lazy val underlying = self.repr
override def foreach[U](f: A => U) = self foreach f
}
/** Creates a non-strict view of a slice of this $coll.
*
* Note: the difference between `view` and `slice` is that `view` produces
* a view of the current $coll, whereas `slice` produces a new $coll.
*
* Note: `view(from, to)` is equivalent to `view.slice(from, to)`
* $orderDependent
*
* @param from the index of the first element of the view
* @param until the index of the element following the view
* @return a non-strict view of a slice of this $coll, starting at index `from`
* and extending up to (but not including) index `until`.
*/
def view(from: Int, until: Int): TraversableView[A, Repr] = view.slice(from, until)
/** Creates a non-strict filter of this $coll.
*
* Note: the difference between `c filter p` and `c withFilter p` is that
* the former creates a new collection, whereas the latter only
* restricts the domain of subsequent `map`, `flatMap`, `foreach`,
* and `withFilter` operations.
* $orderDependent
*
* @param p the predicate used to test elements.
* @return an object of class `WithFilter`, which supports
* `map`, `flatMap`, `foreach`, and `withFilter` operations.
* All these operations apply to those elements of this $coll which
* satisfy the predicate `p`.
*/
def withFilter(p: A => Boolean): FilterMonadic[A, Repr] = new WithFilter(p)
/** A class supporting filtered operations. Instances of this class are
* returned by method `withFilter`.
*/
class WithFilter(p: A => Boolean) extends FilterMonadic[A, Repr] {
/** Builds a new collection by applying a function to all elements of the
* outer $coll containing this `WithFilter` instance that satisfy predicate `p`.
*
* @param f the function to apply to each element.
* @tparam B the element type of the returned collection.
* @tparam That $thatinfo
* @param bf $bfinfo
* @return a new collection of type `That` resulting from applying
* the given function `f` to each element of the outer $coll
* that satisfies predicate `p` and collecting the results.
*
* @usecase def map[B](f: A => B): $Coll[B]
*
* @return a new $coll resulting from applying the given function
* `f` to each element of the outer $coll that satisfies
* predicate `p` and collecting the results.
*/
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
for (x <- self)
if (p(x)) b += f(x)
b.result
}
/** Builds a new collection by applying a function to all elements of the
* outer $coll containing this `WithFilter` instance that satisfy
* predicate `p` and concatenating the results.
*
* @param f the function to apply to each element.
* @tparam B the element type of the returned collection.
* @tparam That $thatinfo
* @param bf $bfinfo
* @return a new collection of type `That` resulting from applying
* the given collection-valued function `f` to each element
* of the outer $coll that satisfies predicate `p` and
* concatenating the results.
*
* @usecase def flatMap[B](f: A => TraversableOnce[B]): $Coll[B]
*
* @return a new $coll resulting from applying the given collection-valued function
* `f` to each element of the outer $coll that satisfies predicate `p` and concatenating the results.
*/
def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
for (x <- self)
if (p(x)) b ++= f(x).seq
b.result
}
/** Applies a function `f` to all elements of the outer $coll containing
* this `WithFilter` instance that satisfy predicate `p`.
*
* @param f the function that is applied for its side-effect to every element.
* The result of function `f` is discarded.
*
* @tparam U the type parameter describing the result of function `f`.
* This result will always be ignored. Typically `U` is `Unit`,
* but this is not necessary.
*
* @usecase def foreach(f: A => Unit): Unit
*/
def foreach[U](f: A => U): Unit =
for (x <- self)
if (p(x)) f(x)
/** Further refines the filter for this $coll.
*
* @param q the predicate used to test elements.
* @return an object of class `WithFilter`, which supports
* `map`, `flatMap`, `foreach`, and `withFilter` operations.
* All these operations apply to those elements of this $coll which
* satisfy the predicate `q` in addition to the predicate `p`.
*/
def withFilter(q: A => Boolean): WithFilter =
new WithFilter(x => p(x) && q(x))
}
// A helper for tails and inits.
private def iterateUntilEmpty(f: Traversable[A @uV] => Traversable[A @uV]): Iterator[Repr] = {
val it = Iterator.iterate(thisCollection)(f) takeWhile (x => !x.isEmpty)
it ++ Iterator(Nil) map (newBuilder ++= _ result)
}
}
</textarea>
</form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
theme: "ambiance",
mode: "text/x-scala"
});
</script>
</article>

139
web/public/codemirror/mode/clike/test.js vendored Normal file
View File

@@ -0,0 +1,139 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-c");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
MT("indent",
"[type void] [def foo]([type void*] [variable a], [type int] [variable b]) {",
" [type int] [variable c] [operator =] [variable b] [operator +]",
" [number 1];",
" [keyword return] [operator *][variable a];",
"}");
MT("indent_switch",
"[keyword switch] ([variable x]) {",
" [keyword case] [number 10]:",
" [keyword return] [number 20];",
" [keyword default]:",
" [variable printf]([string \"foo %c\"], [variable x]);",
"}");
MT("def",
"[type void] [def foo]() {}",
"[keyword struct] [def bar]{}",
"[keyword enum] [def zot]{}",
"[keyword union] [def ugh]{}",
"[type int] [type *][def baz]() {}");
MT("def_new_line",
"::[variable std]::[variable SomeTerribleType][operator <][variable T][operator >]",
"[def SomeLongMethodNameThatDoesntFitIntoOneLine]([keyword const] [variable MyType][operator &] [variable param]) {}")
MT("double_block",
"[keyword for] (;;)",
" [keyword for] (;;)",
" [variable x][operator ++];",
"[keyword return];");
MT("preprocessor",
"[meta #define FOO 3]",
"[type int] [variable foo];",
"[meta #define BAR\\]",
"[meta 4]",
"[type unsigned] [type int] [variable bar] [operator =] [number 8];",
"[meta #include <baz> ][comment // comment]")
MT("c_underscores",
"[builtin __FOO];",
"[builtin _Complex];",
"[builtin __aName];",
"[variable _aName];");
MT("c_types",
"[type int];",
"[type long];",
"[type char];",
"[type short];",
"[type double];",
"[type float];",
"[type unsigned];",
"[type signed];",
"[type void];",
"[type bool];",
"[type foo_t];",
"[variable foo_T];",
"[variable _t];");
var mode_cpp = CodeMirror.getMode({indentUnit: 2}, "text/x-c++src");
function MTCPP(name) { test.mode(name, mode_cpp, Array.prototype.slice.call(arguments, 1)); }
MTCPP("cpp14_literal",
"[number 10'000];",
"[number 0b10'000];",
"[number 0x10'000];",
"[string '100000'];");
MTCPP("ctor_dtor",
"[def Foo::Foo]() {}",
"[def Foo::~Foo]() {}");
MTCPP("cpp_underscores",
"[builtin __FOO];",
"[builtin _Complex];",
"[builtin __aName];",
"[variable _aName];");
var mode_objc = CodeMirror.getMode({indentUnit: 2}, "text/x-objectivec");
function MTOBJC(name) { test.mode(name, mode_objc, Array.prototype.slice.call(arguments, 1)); }
MTOBJC("objc_underscores",
"[builtin __FOO];",
"[builtin _Complex];",
"[builtin __aName];",
"[variable _aName];");
MTOBJC("objc_interface",
"[keyword @interface] [def foo] {",
" [type int] [variable bar];",
"}",
"[keyword @property] ([keyword atomic], [keyword nullable]) [variable NSString][operator *] [variable a];",
"[keyword @property] ([keyword nonatomic], [keyword assign]) [type int] [variable b];",
"[operator -]([type instancetype])[variable initWithFoo]:([type int])[variable a] " +
"[builtin NS_DESIGNATED_INITIALIZER];",
"[keyword @end]");
MTOBJC("objc_implementation",
"[keyword @implementation] [def foo] {",
" [type int] [variable bar];",
"}",
"[keyword @property] ([keyword readwrite]) [type SEL] [variable a];",
"[operator -]([type instancetype])[variable initWithFoo]:([type int])[variable a] {",
" [keyword if](([keyword self] [operator =] [[[keyword super] [variable init] ]])) {}",
" [keyword return] [keyword self];",
"}",
"[keyword @end]");
MTOBJC("objc_types",
"[type int];",
"[type foo_t];",
"[variable foo_T];",
"[type id];",
"[type SEL];",
"[type instancetype];",
"[type Class];",
"[type Protocol];",
"[type BOOL];"
);
var mode_scala = CodeMirror.getMode({indentUnit: 2}, "text/x-scala");
function MTSCALA(name) { test.mode("scala_" + name, mode_scala, Array.prototype.slice.call(arguments, 1)); }
MTSCALA("nested_comments",
"[comment /*]",
"[comment But wait /* this is a nested comment */ for real]",
"[comment /**** let * me * show * you ****/]",
"[comment ///// let / me / show / you /////]",
"[comment */]");
})();

View File

@@ -0,0 +1,292 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("clojure", function (options) {
var atoms = ["false", "nil", "true"];
var specialForms = [".", "catch", "def", "do", "if", "monitor-enter",
"monitor-exit", "new", "quote", "recur", "set!", "throw", "try", "var"];
var coreSymbols = ["*", "*'", "*1", "*2", "*3", "*agent*",
"*allow-unresolved-vars*", "*assert*", "*clojure-version*",
"*command-line-args*", "*compile-files*", "*compile-path*",
"*compiler-options*", "*data-readers*", "*default-data-reader-fn*", "*e",
"*err*", "*file*", "*flush-on-newline*", "*fn-loader*", "*in*",
"*math-context*", "*ns*", "*out*", "*print-dup*", "*print-length*",
"*print-level*", "*print-meta*", "*print-namespace-maps*",
"*print-readably*", "*read-eval*", "*reader-resolver*", "*source-path*",
"*suppress-read*", "*unchecked-math*", "*use-context-classloader*",
"*verbose-defrecords*", "*warn-on-reflection*", "+", "+'", "-", "-'",
"->", "->>", "->ArrayChunk", "->Eduction", "->Vec", "->VecNode",
"->VecSeq", "-cache-protocol-fn", "-reset-methods", "..", "/", "<", "<=",
"=", "==", ">", ">=", "EMPTY-NODE", "Inst", "StackTraceElement->vec",
"Throwable->map", "accessor", "aclone", "add-classpath", "add-watch",
"agent", "agent-error", "agent-errors", "aget", "alength", "alias",
"all-ns", "alter", "alter-meta!", "alter-var-root", "amap", "ancestors",
"and", "any?", "apply", "areduce", "array-map", "as->", "aset",
"aset-boolean", "aset-byte", "aset-char", "aset-double", "aset-float",
"aset-int", "aset-long", "aset-short", "assert", "assoc", "assoc!",
"assoc-in", "associative?", "atom", "await", "await-for", "await1",
"bases", "bean", "bigdec", "bigint", "biginteger", "binding", "bit-and",
"bit-and-not", "bit-clear", "bit-flip", "bit-not", "bit-or", "bit-set",
"bit-shift-left", "bit-shift-right", "bit-test", "bit-xor", "boolean",
"boolean-array", "boolean?", "booleans", "bound-fn", "bound-fn*",
"bound?", "bounded-count", "butlast", "byte", "byte-array", "bytes",
"bytes?", "case", "cast", "cat", "char", "char-array",
"char-escape-string", "char-name-string", "char?", "chars", "chunk",
"chunk-append", "chunk-buffer", "chunk-cons", "chunk-first", "chunk-next",
"chunk-rest", "chunked-seq?", "class", "class?", "clear-agent-errors",
"clojure-version", "coll?", "comment", "commute", "comp", "comparator",
"compare", "compare-and-set!", "compile", "complement", "completing",
"concat", "cond", "cond->", "cond->>", "condp", "conj", "conj!", "cons",
"constantly", "construct-proxy", "contains?", "count", "counted?",
"create-ns", "create-struct", "cycle", "dec", "dec'", "decimal?",
"declare", "dedupe", "default-data-readers", "definline", "definterface",
"defmacro", "defmethod", "defmulti", "defn", "defn-", "defonce",
"defprotocol", "defrecord", "defstruct", "deftype", "delay", "delay?",
"deliver", "denominator", "deref", "derive", "descendants", "destructure",
"disj", "disj!", "dissoc", "dissoc!", "distinct", "distinct?", "doall",
"dorun", "doseq", "dosync", "dotimes", "doto", "double", "double-array",
"double?", "doubles", "drop", "drop-last", "drop-while", "eduction",
"empty", "empty?", "ensure", "ensure-reduced", "enumeration-seq",
"error-handler", "error-mode", "eval", "even?", "every-pred", "every?",
"ex-data", "ex-info", "extend", "extend-protocol", "extend-type",
"extenders", "extends?", "false?", "ffirst", "file-seq", "filter",
"filterv", "find", "find-keyword", "find-ns", "find-protocol-impl",
"find-protocol-method", "find-var", "first", "flatten", "float",
"float-array", "float?", "floats", "flush", "fn", "fn?", "fnext", "fnil",
"for", "force", "format", "frequencies", "future", "future-call",
"future-cancel", "future-cancelled?", "future-done?", "future?",
"gen-class", "gen-interface", "gensym", "get", "get-in", "get-method",
"get-proxy-class", "get-thread-bindings", "get-validator", "group-by",
"halt-when", "hash", "hash-combine", "hash-map", "hash-ordered-coll",
"hash-set", "hash-unordered-coll", "ident?", "identical?", "identity",
"if-let", "if-not", "if-some", "ifn?", "import", "in-ns", "inc", "inc'",
"indexed?", "init-proxy", "inst-ms", "inst-ms*", "inst?", "instance?",
"int", "int-array", "int?", "integer?", "interleave", "intern",
"interpose", "into", "into-array", "ints", "io!", "isa?", "iterate",
"iterator-seq", "juxt", "keep", "keep-indexed", "key", "keys", "keyword",
"keyword?", "last", "lazy-cat", "lazy-seq", "let", "letfn", "line-seq",
"list", "list*", "list?", "load", "load-file", "load-reader",
"load-string", "loaded-libs", "locking", "long", "long-array", "longs",
"loop", "macroexpand", "macroexpand-1", "make-array", "make-hierarchy",
"map", "map-entry?", "map-indexed", "map?", "mapcat", "mapv", "max",
"max-key", "memfn", "memoize", "merge", "merge-with", "meta",
"method-sig", "methods", "min", "min-key", "mix-collection-hash", "mod",
"munge", "name", "namespace", "namespace-munge", "nat-int?", "neg-int?",
"neg?", "newline", "next", "nfirst", "nil?", "nnext", "not", "not-any?",
"not-empty", "not-every?", "not=", "ns", "ns-aliases", "ns-imports",
"ns-interns", "ns-map", "ns-name", "ns-publics", "ns-refers",
"ns-resolve", "ns-unalias", "ns-unmap", "nth", "nthnext", "nthrest",
"num", "number?", "numerator", "object-array", "odd?", "or", "parents",
"partial", "partition", "partition-all", "partition-by", "pcalls", "peek",
"persistent!", "pmap", "pop", "pop!", "pop-thread-bindings", "pos-int?",
"pos?", "pr", "pr-str", "prefer-method", "prefers",
"primitives-classnames", "print", "print-ctor", "print-dup",
"print-method", "print-simple", "print-str", "printf", "println",
"println-str", "prn", "prn-str", "promise", "proxy",
"proxy-call-with-super", "proxy-mappings", "proxy-name", "proxy-super",
"push-thread-bindings", "pvalues", "qualified-ident?",
"qualified-keyword?", "qualified-symbol?", "quot", "rand", "rand-int",
"rand-nth", "random-sample", "range", "ratio?", "rational?",
"rationalize", "re-find", "re-groups", "re-matcher", "re-matches",
"re-pattern", "re-seq", "read", "read-line", "read-string",
"reader-conditional", "reader-conditional?", "realized?", "record?",
"reduce", "reduce-kv", "reduced", "reduced?", "reductions", "ref",
"ref-history-count", "ref-max-history", "ref-min-history", "ref-set",
"refer", "refer-clojure", "reify", "release-pending-sends", "rem",
"remove", "remove-all-methods", "remove-method", "remove-ns",
"remove-watch", "repeat", "repeatedly", "replace", "replicate", "require",
"reset!", "reset-meta!", "reset-vals!", "resolve", "rest",
"restart-agent", "resultset-seq", "reverse", "reversible?", "rseq",
"rsubseq", "run!", "satisfies?", "second", "select-keys", "send",
"send-off", "send-via", "seq", "seq?", "seqable?", "seque", "sequence",
"sequential?", "set", "set-agent-send-executor!",
"set-agent-send-off-executor!", "set-error-handler!", "set-error-mode!",
"set-validator!", "set?", "short", "short-array", "shorts", "shuffle",
"shutdown-agents", "simple-ident?", "simple-keyword?", "simple-symbol?",
"slurp", "some", "some->", "some->>", "some-fn", "some?", "sort",
"sort-by", "sorted-map", "sorted-map-by", "sorted-set", "sorted-set-by",
"sorted?", "special-symbol?", "spit", "split-at", "split-with", "str",
"string?", "struct", "struct-map", "subs", "subseq", "subvec", "supers",
"swap!", "swap-vals!", "symbol", "symbol?", "sync", "tagged-literal",
"tagged-literal?", "take", "take-last", "take-nth", "take-while", "test",
"the-ns", "thread-bound?", "time", "to-array", "to-array-2d",
"trampoline", "transduce", "transient", "tree-seq", "true?", "type",
"unchecked-add", "unchecked-add-int", "unchecked-byte", "unchecked-char",
"unchecked-dec", "unchecked-dec-int", "unchecked-divide-int",
"unchecked-double", "unchecked-float", "unchecked-inc",
"unchecked-inc-int", "unchecked-int", "unchecked-long",
"unchecked-multiply", "unchecked-multiply-int", "unchecked-negate",
"unchecked-negate-int", "unchecked-remainder-int", "unchecked-short",
"unchecked-subtract", "unchecked-subtract-int", "underive", "unquote",
"unquote-splicing", "unreduced", "unsigned-bit-shift-right", "update",
"update-in", "update-proxy", "uri?", "use", "uuid?", "val", "vals",
"var-get", "var-set", "var?", "vary-meta", "vec", "vector", "vector-of",
"vector?", "volatile!", "volatile?", "vreset!", "vswap!", "when",
"when-first", "when-let", "when-not", "when-some", "while",
"with-bindings", "with-bindings*", "with-in-str", "with-loading-context",
"with-local-vars", "with-meta", "with-open", "with-out-str",
"with-precision", "with-redefs", "with-redefs-fn", "xml-seq", "zero?",
"zipmap"];
var haveBodyParameter = [
"->", "->>", "as->", "binding", "bound-fn", "case", "catch", "comment",
"cond", "cond->", "cond->>", "condp", "def", "definterface", "defmethod",
"defn", "defmacro", "defprotocol", "defrecord", "defstruct", "deftype",
"do", "doseq", "dotimes", "doto", "extend", "extend-protocol",
"extend-type", "fn", "for", "future", "if", "if-let", "if-not", "if-some",
"let", "letfn", "locking", "loop", "ns", "proxy", "reify", "struct-map",
"some->", "some->>", "try", "when", "when-first", "when-let", "when-not",
"when-some", "while", "with-bindings", "with-bindings*", "with-in-str",
"with-loading-context", "with-local-vars", "with-meta", "with-open",
"with-out-str", "with-precision", "with-redefs", "with-redefs-fn"];
CodeMirror.registerHelper("hintWords", "clojure",
[].concat(atoms, specialForms, coreSymbols));
var atom = createLookupMap(atoms);
var specialForm = createLookupMap(specialForms);
var coreSymbol = createLookupMap(coreSymbols);
var hasBodyParameter = createLookupMap(haveBodyParameter);
var delimiter = /^(?:[\\\[\]\s"(),;@^`{}~]|$)/;
var numberLiteral = /^(?:[+\-]?\d+(?:(?:N|(?:[eE][+\-]?\d+))|(?:\.?\d*(?:M|(?:[eE][+\-]?\d+))?)|\/\d+|[xX][0-9a-fA-F]+|r[0-9a-zA-Z]+)?(?=[\\\[\]\s"#'(),;@^`{}~]|$))/;
var characterLiteral = /^(?:\\(?:backspace|formfeed|newline|return|space|tab|o[0-7]{3}|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{4}|.)?(?=[\\\[\]\s"(),;@^`{}~]|$))/;
// simple-namespace := /^[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*/
// simple-symbol := /^(?:\/|[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*)/
// qualified-symbol := (<simple-namespace>(<.><simple-namespace>)*</>)?<simple-symbol>
var qualifiedSymbol = /^(?:(?:[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*(?:\.[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*)*\/)?(?:\/|[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*)*(?=[\\\[\]\s"(),;@^`{}~]|$))/;
function base(stream, state) {
if (stream.eatSpace()) return ["space", null];
if (stream.match(numberLiteral)) return [null, "number"];
if (stream.match(characterLiteral)) return [null, "string-2"];
if (stream.eat(/^"/)) return (state.tokenize = inString)(stream, state);
if (stream.eat(/^[(\[{]/)) return ["open", "bracket"];
if (stream.eat(/^[)\]}]/)) return ["close", "bracket"];
if (stream.eat(/^;/)) {stream.skipToEnd(); return ["space", "comment"];}
if (stream.eat(/^[#'@^`~]/)) return [null, "meta"];
var matches = stream.match(qualifiedSymbol);
var symbol = matches && matches[0];
if (!symbol) {
// advance stream by at least one character so we don't get stuck.
stream.next();
stream.eatWhile(function (c) {return !is(c, delimiter);});
return [null, "error"];
}
if (symbol === "comment" && state.lastToken === "(")
return (state.tokenize = inComment)(stream, state);
if (is(symbol, atom) || symbol.charAt(0) === ":") return ["symbol", "atom"];
if (is(symbol, specialForm) || is(symbol, coreSymbol)) return ["symbol", "keyword"];
if (state.lastToken === "(") return ["symbol", "builtin"]; // other operator
return ["symbol", "variable"];
}
function inString(stream, state) {
var escaped = false, next;
while (next = stream.next()) {
if (next === "\"" && !escaped) {state.tokenize = base; break;}
escaped = !escaped && next === "\\";
}
return [null, "string"];
}
function inComment(stream, state) {
var parenthesisCount = 1;
var next;
while (next = stream.next()) {
if (next === ")") parenthesisCount--;
if (next === "(") parenthesisCount++;
if (parenthesisCount === 0) {
stream.backUp(1);
state.tokenize = base;
break;
}
}
return ["space", "comment"];
}
function createLookupMap(words) {
var obj = {};
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
function is(value, test) {
if (test instanceof RegExp) return test.test(value);
if (test instanceof Object) return test.propertyIsEnumerable(value);
}
return {
startState: function () {
return {
ctx: {prev: null, start: 0, indentTo: 0},
lastToken: null,
tokenize: base
};
},
token: function (stream, state) {
if (stream.sol() && (typeof state.ctx.indentTo !== "number"))
state.ctx.indentTo = state.ctx.start + 1;
var typeStylePair = state.tokenize(stream, state);
var type = typeStylePair[0];
var style = typeStylePair[1];
var current = stream.current();
if (type !== "space") {
if (state.lastToken === "(" && state.ctx.indentTo === null) {
if (type === "symbol" && is(current, hasBodyParameter))
state.ctx.indentTo = state.ctx.start + options.indentUnit;
else state.ctx.indentTo = "next";
} else if (state.ctx.indentTo === "next") {
state.ctx.indentTo = stream.column();
}
state.lastToken = current;
}
if (type === "open")
state.ctx = {prev: state.ctx, start: stream.column(), indentTo: null};
else if (type === "close") state.ctx = state.ctx.prev || state.ctx;
return style;
},
indent: function (state) {
var i = state.ctx.indentTo;
return (typeof i === "number") ?
i :
state.ctx.start + 1;
},
closeBrackets: {pairs: "()[]{}\"\""},
lineComment: ";;"
};
});
CodeMirror.defineMIME("text/x-clojure", "clojure");
CodeMirror.defineMIME("text/x-clojurescript", "clojure");
CodeMirror.defineMIME("application/edn", "clojure");
});

View File

@@ -0,0 +1,95 @@
<!doctype html>
<title>CodeMirror: Clojure 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="../../addon/edit/closebrackets.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="clojure.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="https://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="#">Clojure</a>
</ul>
</div>
<article>
<h2>Clojure mode</h2>
<form><textarea id="code" name="code">
(ns game-of-life
"Conway's Game of Life, based on the work of
Christophe Grand (http://clj-me.cgrand.net/2011/08/19/conways-game-of-life)
and Laurent Petit (https://gist.github.com/1200343).")
;;; Core game of life's algorithm functions
(defn neighbors
"Given a cell's coordinates `[x y]`, returns the coordinates of its
neighbors."
[[x y]]
(for [dx [-1 0 1]
dy (if (zero? dx)
[-1 1]
[-1 0 1])]
[(+ dx x) (+ dy y)]))
(defn step
"Given a set of living `cells`, computes the new set of living cells."
[cells]
(set (for [[cell n] (frequencies (mapcat neighbors cells))
:when (or (= n 3)
(and (= n 2)
(cells cell)))]
cell)))
;;; Utility methods for displaying game on a text terminal
(defn print-grid
"Prints a `grid` of `w` columns and `h` rows, on *out*, representing a
step in the game."
[grid w h]
(doseq [x (range (inc w))
y (range (inc h))]
(when (= y 0) (println))
(print (if (grid [x y])
"[X]"
" . "))))
(defn print-grids
"Prints a sequence of `grids` of `w` columns and `h` rows on *out*,
representing several steps."
[grids w h]
(doseq [grid grids]
(print-grid grid w h)
(println)))
;;; Launches an example grid
(def grid
"`grid` represents the initial set of living cells"
#{[2 1] [2 2] [2 3]})
(print-grids (take 3 (iterate step grid)) 5 5)</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
autoCloseBrackets: true,
lineNumbers: true,
matchBrackets: true,
mode: 'text/x-clojure'
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-clojure</code>.</p>
</article>

View File

@@ -0,0 +1,384 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function () {
var mode = CodeMirror.getMode({indentUnit: 2}, "clojure");
function MT(name) {
test.mode(name, mode, Array.prototype.slice.call(arguments, 1));
}
MT("atoms",
"[atom false]",
"[atom nil]",
"[atom true]"
);
MT("keywords",
"[atom :foo]",
"[atom ::bar]",
"[atom :foo/bar]",
"[atom :foo.bar/baz]"
);
MT("numbers",
"[number 42] [number +42] [number -421]",
"[number 42N] [number +42N] [number -42N]",
"[number 0.42] [number +0.42] [number -0.42]",
"[number 42M] [number +42M] [number -42M]",
"[number 42.42M] [number +42.42M] [number -42.42M]",
"[number 1/42] [number +1/42] [number -1/42]",
"[number 0x42af] [number +0x42af] [number -0x42af]",
"[number 0x42AF] [number +0x42AF] [number -0x42AF]",
"[number 1e2] [number 1e+2] [number 1e-2]",
"[number +1e2] [number +1e+2] [number +1e-2]",
"[number -1e2] [number -1e+2] [number -1e-2]",
"[number -1.0e2] [number -0.1e+2] [number -1.01e-2]",
"[number 1E2] [number 1E+2] [number 1E-2]",
"[number +1E2] [number +1E+2] [number +1E-2]",
"[number -1E2] [number -1E+2] [number -1E-2]",
"[number -1.0E2] [number -0.1E+2] [number -1.01E-2]",
"[number 2r101010] [number +2r101010] [number -2r101010]",
"[number 2r101010] [number +2r101010] [number -2r101010]",
"[number 8r52] [number +8r52] [number -8r52]",
"[number 36rhello] [number +36rhello] [number -36rhello]",
"[number 36rz] [number +36rz] [number -36rz]",
"[number 36rZ] [number +36rZ] [number -36rZ]",
// invalid numbers
"[error 42foo]",
"[error 42Nfoo]",
"[error 42Mfoo]",
"[error 42.42Mfoo]",
"[error 42.42M!]",
"[error 42!]",
"[error 0x42afm]"
);
MT("characters",
"[string-2 \\1]",
"[string-2 \\a]",
"[string-2 \\a\\b\\c]",
"[string-2 \\#]",
"[string-2 \\\\]",
"[string-2 \\\"]",
"[string-2 \\(]",
"[string-2 \\A]",
"[string-2 \\backspace]",
"[string-2 \\formfeed]",
"[string-2 \\newline]",
"[string-2 \\space]",
"[string-2 \\return]",
"[string-2 \\tab]",
"[string-2 \\u1000]",
"[string-2 \\uAaAa]",
"[string-2 \\u9F9F]",
"[string-2 \\o123]",
"[string-2 \\符]",
"[string-2 \\シ]",
"[string-2 \\ۇ]",
// FIXME
// "[string-2 \\🙂]",
// invalid character literals
"[error \\abc]",
"[error \\a123]",
"[error \\a!]",
"[error \\newlines]",
"[error \\NEWLINE]",
"[error \\u9F9FF]",
"[error \\o1234]"
);
MT("strings",
"[string \"I'm a teapot.\"]",
"[string \"I'm a \\\"teapot\\\".\"]",
"[string \"I'm]", // this is
"[string a]", // a multi-line
"[string teapot.\"]" // string
// TODO unterminated (multi-line) strings?
);
MT("comments",
"[comment ; this is an in-line comment.]",
"[comment ;; this is a line comment.]",
"[keyword comment]",
"[bracket (][comment comment (foo 1 2 3)][bracket )]"
);
MT("reader macro characters",
"[meta #][variable _]",
"[meta #][variable -Inf]",
"[meta ##][variable Inf]",
"[meta ##][variable NaN]",
"[meta @][variable x]",
"[meta ^][bracket {][atom :tag] [variable String][bracket }]",
"[meta `][bracket (][builtin f] [variable x][bracket )]",
"[meta ~][variable foo#]",
"[meta '][number 1]",
"[meta '][atom :foo]",
"[meta '][string \"foo\"]",
"[meta '][variable x]",
"[meta '][bracket (][builtin a] [variable b] [variable c][bracket )]",
"[meta '][bracket [[][variable a] [variable b] [variable c][bracket ]]]",
"[meta '][bracket {][variable a] [number 1] [atom :foo] [number 2] [variable c] [number 3][bracket }]",
"[meta '#][bracket {][variable a] [number 1] [atom :foo][bracket }]"
);
MT("symbols",
"[variable foo!]",
"[variable foo#]",
"[variable foo$]",
"[variable foo&]",
"[variable foo']",
"[variable foo*]",
"[variable foo+]",
"[variable foo-]",
"[variable foo.]",
"[variable foo/bar]",
"[variable foo:bar]",
"[variable foo<]",
"[variable foo=]",
"[variable foo>]",
"[variable foo?]",
"[variable foo_]",
"[variable foo|]",
"[variable foobarBaz]",
"[variable foo¡]",
"[variable 符号]",
"[variable シンボル]",
"[variable ئۇيغۇر]",
"[variable 🙂❤🇺🇸]",
// invalid symbols
"[error 3foo]",
"[error 3+]",
"[error 3|]",
"[error 3_]"
);
MT("numbers and other forms",
"[number 42][bracket (][builtin foo][bracket )]",
"[number 42][bracket [[][variable foo][bracket ]]]",
"[number 42][meta #][bracket {][variable foo][bracket }]",
"[number 42][bracket {][atom :foo] [variable bar][bracket }]",
"[number 42][meta `][variable foo]",
"[number 42][meta ~][variable foo]",
"[number 42][meta #][variable foo]"
);
var specialForms = [".", "catch", "def", "do", "if", "monitor-enter",
"monitor-exit", "new", "quote", "recur", "set!", "throw", "try", "var"];
MT("should highlight special forms as keywords",
typeTokenPairs("keyword", specialForms)
);
var coreSymbols1 = [
"*", "*'", "*1", "*2", "*3", "*agent*", "*allow-unresolved-vars*", "*assert*",
"*clojure-version*", "*command-line-args*", "*compile-files*", "*compile-path*", "*compiler-options*",
"*data-readers*", "*default-data-reader-fn*", "*e", "*err*", "*file*", "*flush-on-newline*", "*fn-loader*",
"*in*", "*math-context*", "*ns*", "*out*", "*print-dup*", "*print-length*", "*print-level*", "*print-meta*",
"*print-namespace-maps*", "*print-readably*", "*read-eval*", "*reader-resolver*", "*source-path*",
"*suppress-read*", "*unchecked-math*", "*use-context-classloader*", "*verbose-defrecords*",
"*warn-on-reflection*", "+", "+'", "-", "-'", "->", "->>", "->ArrayChunk", "->Eduction", "->Vec", "->VecNode",
"->VecSeq", "-cache-protocol-fn", "-reset-methods", "..", "/", "<", "<=", "=", "==", ">", ">=",
"EMPTY-NODE", "Inst", "StackTraceElement->vec", "Throwable->map", "accessor", "aclone", "add-classpath",
"add-watch", "agent", "agent-error", "agent-errors", "aget", "alength", "alias", "all-ns", "alter",
"alter-meta!", "alter-var-root", "amap", "ancestors", "and", "any?", "apply", "areduce", "array-map",
"as->", "aset", "aset-boolean", "aset-byte", "aset-char", "aset-double", "aset-float", "aset-int",
"aset-long", "aset-short", "assert", "assoc", "assoc!", "assoc-in", "associative?", "atom", "await",
"await-for", "await1", "bases", "bean", "bigdec", "bigint", "biginteger", "binding", "bit-and", "bit-and-not",
"bit-clear", "bit-flip", "bit-not", "bit-or", "bit-set", "bit-shift-left", "bit-shift-right", "bit-test",
"bit-xor", "boolean", "boolean-array", "boolean?", "booleans", "bound-fn", "bound-fn*", "bound?",
"bounded-count", "butlast", "byte", "byte-array", "bytes", "bytes?", "case", "cast", "cat", "char",
"char-array", "char-escape-string", "char-name-string", "char?", "chars", "chunk", "chunk-append",
"chunk-buffer", "chunk-cons", "chunk-first", "chunk-next", "chunk-rest", "chunked-seq?", "class", "class?",
"clear-agent-errors", "clojure-version", "coll?", "comment", "commute", "comp", "comparator", "compare",
"compare-and-set!", "compile", "complement", "completing", "concat", "cond", "cond->", "cond->>", "condp",
"conj", "conj!", "cons", "constantly", "construct-proxy", "contains?", "count", "counted?", "create-ns",
"create-struct", "cycle", "dec", "dec'", "decimal?", "declare", "dedupe", "default-data-readers", "definline",
"definterface", "defmacro", "defmethod", "defmulti", "defn", "defn-", "defonce", "defprotocol", "defrecord",
"defstruct", "deftype", "delay", "delay?", "deliver", "denominator", "deref", "derive", "descendants",
"destructure", "disj", "disj!", "dissoc", "dissoc!", "distinct", "distinct?", "doall", "dorun", "doseq",
"dosync", "dotimes", "doto", "double", "double-array", "double?", "doubles", "drop", "drop-last", "drop-while",
"eduction", "empty", "empty?", "ensure", "ensure-reduced", "enumeration-seq", "error-handler", "error-mode",
"eval", "even?", "every-pred", "every?", "ex-data", "ex-info", "extend", "extend-protocol", "extend-type",
"extenders", "extends?", "false?", "ffirst", "file-seq", "filter", "filterv", "find", "find-keyword", "find-ns",
"find-protocol-impl", "find-protocol-method", "find-var", "first", "flatten", "float", "float-array", "float?",
"floats", "flush", "fn", "fn?", "fnext", "fnil", "for", "force", "format", "frequencies", "future", "future-call",
"future-cancel", "future-cancelled?", "future-done?", "future?", "gen-class", "gen-interface", "gensym", "get",
"get-in", "get-method", "get-proxy-class", "get-thread-bindings", "get-validator", "group-by", "halt-when", "hash",
"hash-combine", "hash-map", "hash-ordered-coll", "hash-set", "hash-unordered-coll", "ident?", "identical?",
"identity", "if-let", "if-not", "if-some", "ifn?", "import", "in-ns", "inc", "inc'", "indexed?", "init-proxy",
"inst-ms", "inst-ms*", "inst?", "instance?", "int", "int-array", "int?", "integer?", "interleave", "intern",
"interpose", "into", "into-array", "ints", "io!", "isa?", "iterate", "iterator-seq", "juxt", "keep", "keep-indexed",
"key", "keys", "keyword", "keyword?", "last", "lazy-cat", "lazy-seq", "let", "letfn", "line-seq", "list", "list*",
"list?", "load", "load-file", "load-reader", "load-string", "loaded-libs", "locking", "long", "long-array", "longs",
"loop", "macroexpand", "macroexpand-1", "make-array", "make-hierarchy", "map", "map-entry?", "map-indexed", "map?",
"mapcat", "mapv", "max", "max-key", "memfn", "memoize", "merge", "merge-with", "meta", "method-sig", "methods"];
var coreSymbols2 = [
"min", "min-key", "mix-collection-hash", "mod", "munge", "name", "namespace", "namespace-munge", "nat-int?",
"neg-int?", "neg?", "newline", "next", "nfirst", "nil?", "nnext", "not", "not-any?", "not-empty", "not-every?",
"not=", "ns", "ns-aliases", "ns-imports", "ns-interns", "ns-map", "ns-name", "ns-publics", "ns-refers", "ns-resolve",
"ns-unalias", "ns-unmap", "nth", "nthnext", "nthrest", "num", "number?", "numerator", "object-array", "odd?", "or",
"parents", "partial", "partition", "partition-all", "partition-by", "pcalls", "peek", "persistent!", "pmap", "pop",
"pop!", "pop-thread-bindings", "pos-int?", "pos?", "pr", "pr-str", "prefer-method", "prefers",
"primitives-classnames", "print", "print-ctor", "print-dup", "print-method", "print-simple", "print-str", "printf",
"println", "println-str", "prn", "prn-str", "promise", "proxy", "proxy-call-with-super", "proxy-mappings",
"proxy-name", "proxy-super", "push-thread-bindings", "pvalues", "qualified-ident?", "qualified-keyword?",
"qualified-symbol?", "quot", "rand", "rand-int", "rand-nth", "random-sample", "range", "ratio?", "rational?",
"rationalize", "re-find", "re-groups", "re-matcher", "re-matches", "re-pattern", "re-seq", "read", "read-line",
"read-string", "reader-conditional", "reader-conditional?", "realized?", "record?", "reduce", "reduce-kv", "reduced",
"reduced?", "reductions", "ref", "ref-history-count", "ref-max-history", "ref-min-history", "ref-set", "refer",
"refer-clojure", "reify", "release-pending-sends", "rem", "remove", "remove-all-methods", "remove-method", "remove-ns",
"remove-watch", "repeat", "repeatedly", "replace", "replicate", "require", "reset!", "reset-meta!", "reset-vals!",
"resolve", "rest", "restart-agent", "resultset-seq", "reverse", "reversible?", "rseq", "rsubseq", "run!", "satisfies?",
"second", "select-keys", "send", "send-off", "send-via", "seq", "seq?", "seqable?", "seque", "sequence", "sequential?",
"set", "set-agent-send-executor!", "set-agent-send-off-executor!", "set-error-handler!", "set-error-mode!",
"set-validator!", "set?", "short", "short-array", "shorts", "shuffle", "shutdown-agents", "simple-ident?",
"simple-keyword?", "simple-symbol?", "slurp", "some", "some->", "some->>", "some-fn", "some?", "sort", "sort-by",
"sorted-map", "sorted-map-by", "sorted-set", "sorted-set-by", "sorted?", "special-symbol?", "spit", "split-at",
"split-with", "str", "string?", "struct", "struct-map", "subs", "subseq", "subvec", "supers", "swap!", "swap-vals!",
"symbol", "symbol?", "sync", "tagged-literal", "tagged-literal?", "take", "take-last", "take-nth", "take-while", "test",
"the-ns", "thread-bound?", "time", "to-array", "to-array-2d", "trampoline", "transduce", "transient", "tree-seq",
"true?", "type", "unchecked-add", "unchecked-add-int", "unchecked-byte", "unchecked-char", "unchecked-dec",
"unchecked-dec-int", "unchecked-divide-int", "unchecked-double", "unchecked-float", "unchecked-inc", "unchecked-inc-int",
"unchecked-int", "unchecked-long", "unchecked-multiply", "unchecked-multiply-int", "unchecked-negate",
"unchecked-negate-int", "unchecked-remainder-int", "unchecked-short", "unchecked-subtract", "unchecked-subtract-int",
"underive", "unquote", "unquote-splicing", "unreduced", "unsigned-bit-shift-right", "update", "update-in",
"update-proxy", "uri?", "use", "uuid?", "val", "vals", "var-get", "var-set", "var?", "vary-meta", "vec", "vector",
"vector-of", "vector?", "volatile!", "volatile?", "vreset!", "vswap!", "when", "when-first", "when-let", "when-not",
"when-some", "while", "with-bindings", "with-bindings*", "with-in-str", "with-loading-context", "with-local-vars",
"with-meta", "with-open", "with-out-str", "with-precision", "with-redefs", "with-redefs-fn", "xml-seq", "zero?",
"zipmap"
];
MT("should highlight core symbols as keywords (part 1/2)",
typeTokenPairs("keyword", coreSymbols1)
);
MT("should highlight core symbols as keywords (part 2/2)",
typeTokenPairs("keyword", coreSymbols2)
);
MT("should properly indent forms in list literals",
"[bracket (][builtin foo] [atom :a] [number 1] [atom true] [atom nil][bracket )]",
"",
"[bracket (][builtin foo] [atom :a]",
" [number 1]",
" [atom true]",
" [atom nil][bracket )]",
"",
"[bracket (][builtin foo] [atom :a] [number 1]",
" [atom true]",
" [atom nil][bracket )]",
"",
"[bracket (]",
" [builtin foo]",
" [atom :a]",
" [number 1]",
" [atom true]",
" [atom nil][bracket )]",
"",
"[bracket (][builtin foo] [bracket [[][atom :a][bracket ]]]",
" [number 1]",
" [atom true]",
" [atom nil][bracket )]"
);
MT("should properly indent forms in vector literals",
"[bracket [[][atom :a] [number 1] [atom true] [atom nil][bracket ]]]",
"",
"[bracket [[][atom :a]",
" [number 1]",
" [atom true]",
" [atom nil][bracket ]]]",
"",
"[bracket [[][atom :a] [number 1]",
" [atom true]",
" [atom nil][bracket ]]]",
"",
"[bracket [[]",
" [variable foo]",
" [atom :a]",
" [number 1]",
" [atom true]",
" [atom nil][bracket ]]]"
);
MT("should properly indent forms in map literals",
"[bracket {][atom :a] [atom :a] [atom :b] [number 1] [atom :c] [atom true] [atom :d] [atom nil] [bracket }]",
"",
"[bracket {][atom :a] [atom :a]",
" [atom :b] [number 1]",
" [atom :c] [atom true]",
" [atom :d] [atom nil][bracket }]",
"",
"[bracket {][atom :a]",
" [atom :a]",
" [atom :b]",
" [number 1]",
" [atom :c]",
" [atom true]",
" [atom :d]",
" [atom nil][bracket }]",
"",
"[bracket {]",
" [atom :a] [atom :a]",
" [atom :b] [number 1]",
" [atom :c] [atom true]",
" [atom :d] [atom nil][bracket }]"
);
MT("should properly indent forms in set literals",
"[meta #][bracket {][atom :a] [number 1] [atom true] [atom nil] [bracket }]",
"",
"[meta #][bracket {][atom :a]",
" [number 1]",
" [atom true]",
" [atom nil][bracket }]",
"",
"[meta #][bracket {]",
" [atom :a]",
" [number 1]",
" [atom true]",
" [atom nil][bracket }]"
);
var haveBodyParameter = [
"->", "->>", "as->", "binding", "bound-fn", "case", "catch", "cond",
"cond->", "cond->>", "condp", "def", "definterface", "defmethod", "defn",
"defmacro", "defprotocol", "defrecord", "defstruct", "deftype", "do",
"doseq", "dotimes", "doto", "extend", "extend-protocol", "extend-type",
"fn", "for", "future", "if", "if-let", "if-not", "if-some", "let",
"letfn", "locking", "loop", "ns", "proxy", "reify", "some->", "some->>",
"struct-map", "try", "when", "when-first", "when-let", "when-not",
"when-some", "while", "with-bindings", "with-bindings*", "with-in-str",
"with-loading-context", "with-local-vars", "with-meta", "with-open",
"with-out-str", "with-precision", "with-redefs", "with-redefs-fn"];
function testFormsThatHaveBodyParameter(forms) {
for (var i = 0; i < forms.length; i++) {
MT("should indent body argument of `" + forms[i] + "` by `options.indentUnit` spaces",
"[bracket (][keyword " + forms[i] + "] [variable foo] [variable bar]",
" [variable baz]",
" [variable qux][bracket )]"
);
}
}
testFormsThatHaveBodyParameter(haveBodyParameter);
MT("should indent body argument of `comment` by `options.indentUnit` spaces",
"[bracket (][comment comment foo bar]",
"[comment baz]",
"[comment qux][bracket )]"
);
function typeTokenPairs(type, tokens) {
return "[" + type + " " + tokens.join("] [" + type + " ") + "]";
}
})();

View File

@@ -0,0 +1,97 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object")
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd)
define(["../../lib/codemirror"], mod);
else
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("cmake", function () {
var variable_regex = /({)?[a-zA-Z0-9_]+(})?/;
function tokenString(stream, state) {
var current, prev, found_var = false;
while (!stream.eol() && (current = stream.next()) != state.pending) {
if (current === '$' && prev != '\\' && state.pending == '"') {
found_var = true;
break;
}
prev = current;
}
if (found_var) {
stream.backUp(1);
}
if (current == state.pending) {
state.continueString = false;
} else {
state.continueString = true;
}
return "string";
}
function tokenize(stream, state) {
var ch = stream.next();
// Have we found a variable?
if (ch === '$') {
if (stream.match(variable_regex)) {
return 'variable-2';
}
return 'variable';
}
// Should we still be looking for the end of a string?
if (state.continueString) {
// If so, go through the loop again
stream.backUp(1);
return tokenString(stream, state);
}
// Do we just have a function on our hands?
// In 'cmake_minimum_required (VERSION 2.8.8)', 'cmake_minimum_required' is matched
if (stream.match(/(\s+)?\w+\(/) || stream.match(/(\s+)?\w+\ \(/)) {
stream.backUp(1);
return 'def';
}
if (ch == "#") {
stream.skipToEnd();
return "comment";
}
// Have we found a string?
if (ch == "'" || ch == '"') {
// Store the type (single or double)
state.pending = ch;
// Perform the looping function to find the end
return tokenString(stream, state);
}
if (ch == '(' || ch == ')') {
return 'bracket';
}
if (ch.match(/[0-9]/)) {
return 'number';
}
stream.eatWhile(/[\w-]/);
return null;
}
return {
startState: function () {
var state = {};
state.inDefinition = false;
state.inInclude = false;
state.continueString = false;
state.pending = false;
return state;
},
token: function (stream, state) {
if (stream.eatSpace()) return null;
return tokenize(stream, state);
}
};
});
CodeMirror.defineMIME("text/x-cmake", "cmake");
});

View File

@@ -0,0 +1,129 @@
<!doctype html>
<title>CodeMirror: CMake 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="../../addon/edit/matchbrackets.js"></script>
<script src="cmake.js"></script>
<style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
.cm-s-default span.cm-arrow { color: red; }
</style>
<div id=nav>
<a href="https://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="#">CMake</a>
</ul>
</div>
<article>
<h2>CMake mode</h2>
<form><textarea id="code" name="code">
# vim: syntax=cmake
if(NOT CMAKE_BUILD_TYPE)
# default to Release build for GCC builds
set(CMAKE_BUILD_TYPE Release CACHE STRING
"Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel."
FORCE)
endif()
message(STATUS "cmake version ${CMAKE_VERSION}")
if(POLICY CMP0025)
cmake_policy(SET CMP0025 OLD) # report Apple's Clang as just Clang
endif()
if(POLICY CMP0042)
cmake_policy(SET CMP0042 NEW) # MACOSX_RPATH
endif()
project (x265)
cmake_minimum_required (VERSION 2.8.8) # OBJECT libraries require 2.8.8
include(CheckIncludeFiles)
include(CheckFunctionExists)
include(CheckSymbolExists)
include(CheckCXXCompilerFlag)
# X265_BUILD must be incremented each time the public API is changed
set(X265_BUILD 48)
configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
"${PROJECT_BINARY_DIR}/x265.def")
configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
"${PROJECT_BINARY_DIR}/x265_config.h")
SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" "${CMAKE_MODULE_PATH}")
# System architecture detection
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" SYSPROC)
set(X86_ALIASES x86 i386 i686 x86_64 amd64)
list(FIND X86_ALIASES "${SYSPROC}" X86MATCH)
if("${SYSPROC}" STREQUAL "" OR X86MATCH GREATER "-1")
message(STATUS "Detected x86 target processor")
set(X86 1)
add_definitions(-DX265_ARCH_X86=1)
if("${CMAKE_SIZEOF_VOID_P}" MATCHES 8)
set(X64 1)
add_definitions(-DX86_64=1)
endif()
elseif(${SYSPROC} STREQUAL "armv6l")
message(STATUS "Detected ARM target processor")
set(ARM 1)
add_definitions(-DX265_ARCH_ARM=1 -DHAVE_ARMV6=1)
else()
message(STATUS "CMAKE_SYSTEM_PROCESSOR value `${CMAKE_SYSTEM_PROCESSOR}` is unknown")
message(STATUS "Please add this value near ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE}")
endif()
if(UNIX)
list(APPEND PLATFORM_LIBS pthread)
find_library(LIBRT rt)
if(LIBRT)
list(APPEND PLATFORM_LIBS rt)
endif()
find_package(Numa)
if(NUMA_FOUND)
list(APPEND CMAKE_REQUIRED_LIBRARIES ${NUMA_LIBRARY})
check_symbol_exists(numa_node_of_cpu numa.h NUMA_V2)
if(NUMA_V2)
add_definitions(-DHAVE_LIBNUMA)
message(STATUS "libnuma found, building with support for NUMA nodes")
list(APPEND PLATFORM_LIBS ${NUMA_LIBRARY})
link_directories(${NUMA_LIBRARY_DIR})
include_directories(${NUMA_INCLUDE_DIR})
endif()
endif()
mark_as_advanced(LIBRT NUMA_FOUND)
endif(UNIX)
if(X64 AND NOT WIN32)
option(ENABLE_PIC "Enable Position Independent Code" ON)
else()
option(ENABLE_PIC "Enable Position Independent Code" OFF)
endif(X64 AND NOT WIN32)
# Compiler detection
if(CMAKE_GENERATOR STREQUAL "Xcode")
set(XCODE 1)
endif()
if (APPLE)
add_definitions(-DMACOS)
endif()
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "text/x-cmake",
matchBrackets: true,
indentUnit: 4
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-cmake</code>.</p>
</article>

View File

@@ -0,0 +1,359 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
/**
* Link to the project's GitHub page:
* https://github.com/pickhardt/coffeescript-codemirror-mode
*/
(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("coffeescript", function(conf, parserConf) {
var ERRORCLASS = "error";
function wordRegexp(words) {
return new RegExp("^((" + words.join(")|(") + "))\\b");
}
var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/;
var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
var atProp = /^@[_A-Za-z$][_A-Za-z$0-9]*/;
var wordOperators = wordRegexp(["and", "or", "not",
"is", "isnt", "in",
"instanceof", "typeof"]);
var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
"switch", "try", "catch", "finally", "class"];
var commonKeywords = ["break", "by", "continue", "debugger", "delete",
"do", "in", "of", "new", "return", "then",
"this", "@", "throw", "when", "until", "extends"];
var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
indentKeywords = wordRegexp(indentKeywords);
var stringPrefixes = /^('{3}|\"{3}|['\"])/;
var regexPrefixes = /^(\/{3}|\/)/;
var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
var constants = wordRegexp(commonConstants);
// Tokenizers
function tokenBase(stream, state) {
// Handle scope changes
if (stream.sol()) {
if (state.scope.align === null) state.scope.align = false;
var scopeOffset = state.scope.offset;
if (stream.eatSpace()) {
var lineOffset = stream.indentation();
if (lineOffset > scopeOffset && state.scope.type == "coffee") {
return "indent";
} else if (lineOffset < scopeOffset) {
return "dedent";
}
return null;
} else {
if (scopeOffset > 0) {
dedent(stream, state);
}
}
}
if (stream.eatSpace()) {
return null;
}
var ch = stream.peek();
// Handle docco title comment (single line)
if (stream.match("####")) {
stream.skipToEnd();
return "comment";
}
// Handle multi line comments
if (stream.match("###")) {
state.tokenize = longComment;
return state.tokenize(stream, state);
}
// Single line comment
if (ch === "#") {
stream.skipToEnd();
return "comment";
}
// Handle number literals
if (stream.match(/^-?[0-9\.]/, false)) {
var floatLiteral = false;
// Floats
if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
floatLiteral = true;
}
if (stream.match(/^-?\d+\.\d*/)) {
floatLiteral = true;
}
if (stream.match(/^-?\.\d+/)) {
floatLiteral = true;
}
if (floatLiteral) {
// prevent from getting extra . on 1..
if (stream.peek() == "."){
stream.backUp(1);
}
return "number";
}
// Integers
var intLiteral = false;
// Hex
if (stream.match(/^-?0x[0-9a-f]+/i)) {
intLiteral = true;
}
// Decimal
if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
intLiteral = true;
}
// Zero by itself with no other piece of number.
if (stream.match(/^-?0(?![\dx])/i)) {
intLiteral = true;
}
if (intLiteral) {
return "number";
}
}
// Handle strings
if (stream.match(stringPrefixes)) {
state.tokenize = tokenFactory(stream.current(), false, "string");
return state.tokenize(stream, state);
}
// Handle regex literals
if (stream.match(regexPrefixes)) {
if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
state.tokenize = tokenFactory(stream.current(), true, "string-2");
return state.tokenize(stream, state);
} else {
stream.backUp(1);
}
}
// Handle operators and delimiters
if (stream.match(operators) || stream.match(wordOperators)) {
return "operator";
}
if (stream.match(delimiters)) {
return "punctuation";
}
if (stream.match(constants)) {
return "atom";
}
if (stream.match(atProp) || state.prop && stream.match(identifiers)) {
return "property";
}
if (stream.match(keywords)) {
return "keyword";
}
if (stream.match(identifiers)) {
return "variable";
}
// Handle non-detected items
stream.next();
return ERRORCLASS;
}
function tokenFactory(delimiter, singleline, outclass) {
return function(stream, state) {
while (!stream.eol()) {
stream.eatWhile(/[^'"\/\\]/);
if (stream.eat("\\")) {
stream.next();
if (singleline && stream.eol()) {
return outclass;
}
} else if (stream.match(delimiter)) {
state.tokenize = tokenBase;
return outclass;
} else {
stream.eat(/['"\/]/);
}
}
if (singleline) {
if (parserConf.singleLineStringErrors) {
outclass = ERRORCLASS;
} else {
state.tokenize = tokenBase;
}
}
return outclass;
};
}
function longComment(stream, state) {
while (!stream.eol()) {
stream.eatWhile(/[^#]/);
if (stream.match("###")) {
state.tokenize = tokenBase;
break;
}
stream.eatWhile("#");
}
return "comment";
}
function indent(stream, state, type) {
type = type || "coffee";
var offset = 0, align = false, alignOffset = null;
for (var scope = state.scope; scope; scope = scope.prev) {
if (scope.type === "coffee" || scope.type == "}") {
offset = scope.offset + conf.indentUnit;
break;
}
}
if (type !== "coffee") {
align = null;
alignOffset = stream.column() + stream.current().length;
} else if (state.scope.align) {
state.scope.align = false;
}
state.scope = {
offset: offset,
type: type,
prev: state.scope,
align: align,
alignOffset: alignOffset
};
}
function dedent(stream, state) {
if (!state.scope.prev) return;
if (state.scope.type === "coffee") {
var _indent = stream.indentation();
var matched = false;
for (var scope = state.scope; scope; scope = scope.prev) {
if (_indent === scope.offset) {
matched = true;
break;
}
}
if (!matched) {
return true;
}
while (state.scope.prev && state.scope.offset !== _indent) {
state.scope = state.scope.prev;
}
return false;
} else {
state.scope = state.scope.prev;
return false;
}
}
function tokenLexer(stream, state) {
var style = state.tokenize(stream, state);
var current = stream.current();
// Handle scope changes.
if (current === "return") {
state.dedent = true;
}
if (((current === "->" || current === "=>") && stream.eol())
|| style === "indent") {
indent(stream, state);
}
var delimiter_index = "[({".indexOf(current);
if (delimiter_index !== -1) {
indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
}
if (indentKeywords.exec(current)){
indent(stream, state);
}
if (current == "then"){
dedent(stream, state);
}
if (style === "dedent") {
if (dedent(stream, state)) {
return ERRORCLASS;
}
}
delimiter_index = "])}".indexOf(current);
if (delimiter_index !== -1) {
while (state.scope.type == "coffee" && state.scope.prev)
state.scope = state.scope.prev;
if (state.scope.type == current)
state.scope = state.scope.prev;
}
if (state.dedent && stream.eol()) {
if (state.scope.type == "coffee" && state.scope.prev)
state.scope = state.scope.prev;
state.dedent = false;
}
return style;
}
var external = {
startState: function(basecolumn) {
return {
tokenize: tokenBase,
scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
prop: false,
dedent: 0
};
},
token: function(stream, state) {
var fillAlign = state.scope.align === null && state.scope;
if (fillAlign && stream.sol()) fillAlign.align = false;
var style = tokenLexer(stream, state);
if (style && style != "comment") {
if (fillAlign) fillAlign.align = true;
state.prop = style == "punctuation" && stream.current() == "."
}
return style;
},
indent: function(state, text) {
if (state.tokenize != tokenBase) return 0;
var scope = state.scope;
var closer = text && "])}".indexOf(text.charAt(0)) > -1;
if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev;
var closes = closer && scope.type === text.charAt(0);
if (scope.align)
return scope.alignOffset - (closes ? 1 : 0);
else
return (closes ? scope.prev : scope).offset;
},
lineComment: "#",
fold: "indent"
};
return external;
});
// IANA registered media type
// https://www.iana.org/assignments/media-types/
CodeMirror.defineMIME("application/vnd.coffeescript", "coffeescript");
CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
CodeMirror.defineMIME("text/coffeescript", "coffeescript");
});

View File

@@ -0,0 +1,740 @@
<!doctype html>
<title>CodeMirror: CoffeeScript 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="coffeescript.js"></script>
<style>.CodeMirror {border-top: 1px solid silver; border-bottom: 1px solid silver;}</style>
<div id=nav>
<a href="https://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="#">CoffeeScript</a>
</ul>
</div>
<article>
<h2>CoffeeScript mode</h2>
<form><textarea id="code" name="code">
# CoffeeScript mode for CodeMirror
# Copyright (c) 2011 Jeff Pickhardt, released under
# the MIT License.
#
# Modified from the Python CodeMirror mode, which also is
# under the MIT License Copyright (c) 2010 Timothy Farrell.
#
# The following script, Underscore.coffee, is used to
# demonstrate CoffeeScript mode for CodeMirror.
#
# To download CoffeeScript mode for CodeMirror, go to:
# https://github.com/pickhardt/coffeescript-codemirror-mode
# **Underscore.coffee
# (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.**
# Underscore is freely distributable under the terms of the
# [MIT license](http://en.wikipedia.org/wiki/MIT_License).
# Portions of Underscore are inspired by or borrowed from
# [Prototype.js](http://prototypejs.org/api), Oliver Steele's
# [Functional](http://osteele.com), and John Resig's
# [Micro-Templating](http://ejohn.org).
# For all details and documentation:
# http://documentcloud.github.com/underscore/
# Baseline setup
# --------------
# Establish the root object, `window` in the browser, or `global` on the server.
root = this
# Save the previous value of the `_` variable.
previousUnderscore = root._
### Multiline
comment
###
# Establish the object that gets thrown to break out of a loop iteration.
# `StopIteration` is SOP on Mozilla.
breaker = if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration
#### Docco style single line comment (title)
# Helper function to escape **RegExp** contents, because JS doesn't have one.
escapeRegExp = (string) -> string.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1')
# Save bytes in the minified (but not gzipped) version:
ArrayProto = Array.prototype
ObjProto = Object.prototype
# Create quick reference variables for speed access to core prototypes.
slice = ArrayProto.slice
unshift = ArrayProto.unshift
toString = ObjProto.toString
hasOwnProperty = ObjProto.hasOwnProperty
propertyIsEnumerable = ObjProto.propertyIsEnumerable
# All **ECMA5** native implementations we hope to use are declared here.
nativeForEach = ArrayProto.forEach
nativeMap = ArrayProto.map
nativeReduce = ArrayProto.reduce
nativeReduceRight = ArrayProto.reduceRight
nativeFilter = ArrayProto.filter
nativeEvery = ArrayProto.every
nativeSome = ArrayProto.some
nativeIndexOf = ArrayProto.indexOf
nativeLastIndexOf = ArrayProto.lastIndexOf
nativeIsArray = Array.isArray
nativeKeys = Object.keys
# Create a safe reference to the Underscore object for use below.
_ = (obj) -> new wrapper(obj)
# Export the Underscore object for **CommonJS**.
if typeof(exports) != 'undefined' then exports._ = _
# Export Underscore to global scope.
root._ = _
# Current version.
_.VERSION = '1.1.0'
# Collection Functions
# --------------------
# The cornerstone, an **each** implementation.
# Handles objects implementing **forEach**, arrays, and raw objects.
_.each = (obj, iterator, context) ->
try
if nativeForEach and obj.forEach is nativeForEach
obj.forEach iterator, context
else if _.isNumber obj.length
iterator.call context, obj[i], i, obj for i in [0...obj.length]
else
iterator.call context, val, key, obj for own key, val of obj
catch e
throw e if e isnt breaker
obj
# Return the results of applying the iterator to each element. Use JavaScript
# 1.6's version of **map**, if possible.
_.map = (obj, iterator, context) ->
return obj.map(iterator, context) if nativeMap and obj.map is nativeMap
results = []
_.each obj, (value, index, list) ->
results.push iterator.call context, value, index, list
results
# **Reduce** builds up a single result from a list of values. Also known as
# **inject**, or **foldl**. Uses JavaScript 1.8's version of **reduce**, if possible.
_.reduce = (obj, iterator, memo, context) ->
if nativeReduce and obj.reduce is nativeReduce
iterator = _.bind iterator, context if context
return obj.reduce iterator, memo
_.each obj, (value, index, list) ->
memo = iterator.call context, memo, value, index, list
memo
# The right-associative version of **reduce**, also known as **foldr**. Uses
# JavaScript 1.8's version of **reduceRight**, if available.
_.reduceRight = (obj, iterator, memo, context) ->
if nativeReduceRight and obj.reduceRight is nativeReduceRight
iterator = _.bind iterator, context if context
return obj.reduceRight iterator, memo
reversed = _.clone(_.toArray(obj)).reverse()
_.reduce reversed, iterator, memo, context
# Return the first value which passes a truth test.
_.detect = (obj, iterator, context) ->
result = null
_.each obj, (value, index, list) ->
if iterator.call context, value, index, list
result = value
_.breakLoop()
result
# Return all the elements that pass a truth test. Use JavaScript 1.6's
# **filter**, if it exists.
_.filter = (obj, iterator, context) ->
return obj.filter iterator, context if nativeFilter and obj.filter is nativeFilter
results = []
_.each obj, (value, index, list) ->
results.push value if iterator.call context, value, index, list
results
# Return all the elements for which a truth test fails.
_.reject = (obj, iterator, context) ->
results = []
_.each obj, (value, index, list) ->
results.push value if not iterator.call context, value, index, list
results
# Determine whether all of the elements match a truth test. Delegate to
# JavaScript 1.6's **every**, if it is present.
_.every = (obj, iterator, context) ->
iterator ||= _.identity
return obj.every iterator, context if nativeEvery and obj.every is nativeEvery
result = true
_.each obj, (value, index, list) ->
_.breakLoop() unless (result = result and iterator.call(context, value, index, list))
result
# Determine if at least one element in the object matches a truth test. Use
# JavaScript 1.6's **some**, if it exists.
_.some = (obj, iterator, context) ->
iterator ||= _.identity
return obj.some iterator, context if nativeSome and obj.some is nativeSome
result = false
_.each obj, (value, index, list) ->
_.breakLoop() if (result = iterator.call(context, value, index, list))
result
# Determine if a given value is included in the array or object,
# based on `===`.
_.include = (obj, target) ->
return _.indexOf(obj, target) isnt -1 if nativeIndexOf and obj.indexOf is nativeIndexOf
return true for own key, val of obj when val is target
false
# Invoke a method with arguments on every item in a collection.
_.invoke = (obj, method) ->
args = _.rest arguments, 2
(if method then val[method] else val).apply(val, args) for val in obj
# Convenience version of a common use case of **map**: fetching a property.
_.pluck = (obj, key) ->
_.map(obj, (val) -> val[key])
# Return the maximum item or (item-based computation).
_.max = (obj, iterator, context) ->
return Math.max.apply(Math, obj) if not iterator and _.isArray(obj)
result = computed: -Infinity
_.each obj, (value, index, list) ->
computed = if iterator then iterator.call(context, value, index, list) else value
computed >= result.computed and (result = {value: value, computed: computed})
result.value
# Return the minimum element (or element-based computation).
_.min = (obj, iterator, context) ->
return Math.min.apply(Math, obj) if not iterator and _.isArray(obj)
result = computed: Infinity
_.each obj, (value, index, list) ->
computed = if iterator then iterator.call(context, value, index, list) else value
computed < result.computed and (result = {value: value, computed: computed})
result.value
# Sort the object's values by a criterion produced by an iterator.
_.sortBy = (obj, iterator, context) ->
_.pluck(((_.map obj, (value, index, list) ->
{value: value, criteria: iterator.call(context, value, index, list)}
).sort((left, right) ->
a = left.criteria; b = right.criteria
if a < b then -1 else if a > b then 1 else 0
)), 'value')
# Use a comparator function to figure out at what index an object should
# be inserted so as to maintain order. Uses binary search.
_.sortedIndex = (array, obj, iterator) ->
iterator ||= _.identity
low = 0
high = array.length
while low < high
mid = (low + high) >> 1
if iterator(array[mid]) < iterator(obj) then low = mid + 1 else high = mid
low
# Convert anything iterable into a real, live array.
_.toArray = (iterable) ->
return [] if (!iterable)
return iterable.toArray() if (iterable.toArray)
return iterable if (_.isArray(iterable))
return slice.call(iterable) if (_.isArguments(iterable))
_.values(iterable)
# Return the number of elements in an object.
_.size = (obj) -> _.toArray(obj).length
# Array Functions
# ---------------
# Get the first element of an array. Passing `n` will return the first N
# values in the array. Aliased as **head**. The `guard` check allows it to work
# with **map**.
_.first = (array, n, guard) ->
if n and not guard then slice.call(array, 0, n) else array[0]
# Returns everything but the first entry of the array. Aliased as **tail**.
# Especially useful on the arguments object. Passing an `index` will return
# the rest of the values in the array from that index onward. The `guard`
# check allows it to work with **map**.
_.rest = (array, index, guard) ->
slice.call(array, if _.isUndefined(index) or guard then 1 else index)
# Get the last element of an array.
_.last = (array) -> array[array.length - 1]
# Trim out all falsy values from an array.
_.compact = (array) -> item for item in array when item
# Return a completely flattened version of an array.
_.flatten = (array) ->
_.reduce array, (memo, value) ->
return memo.concat(_.flatten(value)) if _.isArray value
memo.push value
memo
, []
# Return a version of the array that does not contain the specified value(s).
_.without = (array) ->
values = _.rest arguments
val for val in _.toArray(array) when not _.include values, val
# Produce a duplicate-free version of the array. If the array has already
# been sorted, you have the option of using a faster algorithm.
_.uniq = (array, isSorted) ->
memo = []
for el, i in _.toArray array
memo.push el if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el))
memo
# Produce an array that contains every item shared between all the
# passed-in arrays.
_.intersect = (array) ->
rest = _.rest arguments
_.select _.uniq(array), (item) ->
_.all rest, (other) ->
_.indexOf(other, item) >= 0
# Zip together multiple lists into a single array -- elements that share
# an index go together.
_.zip = ->
length = _.max _.pluck arguments, 'length'
results = new Array length
for i in [0...length]
results[i] = _.pluck arguments, String i
results
# If the browser doesn't supply us with **indexOf** (I'm looking at you, MSIE),
# we need this function. Return the position of the first occurrence of an
# item in an array, or -1 if the item is not included in the array.
_.indexOf = (array, item) ->
return array.indexOf item if nativeIndexOf and array.indexOf is nativeIndexOf
i = 0; l = array.length
while l - i
if array[i] is item then return i else i++
-1
# Provide JavaScript 1.6's **lastIndexOf**, delegating to the native function,
# if possible.
_.lastIndexOf = (array, item) ->
return array.lastIndexOf(item) if nativeLastIndexOf and array.lastIndexOf is nativeLastIndexOf
i = array.length
while i
if array[i] is item then return i else i--
-1
# Generate an integer Array containing an arithmetic progression. A port of
# [the native Python **range** function](http://docs.python.org/library/functions.html#range).
_.range = (start, stop, step) ->
a = arguments
solo = a.length <= 1
i = start = if solo then 0 else a[0]
stop = if solo then a[0] else a[1]
step = a[2] or 1
len = Math.ceil((stop - start) / step)
return [] if len <= 0
range = new Array len
idx = 0
loop
return range if (if step > 0 then i - stop else stop - i) >= 0
range[idx] = i
idx++
i+= step
# Function Functions
# ------------------
# Create a function bound to a given object (assigning `this`, and arguments,
# optionally). Binding with arguments is also known as **curry**.
_.bind = (func, obj) ->
args = _.rest arguments, 2
-> func.apply obj or root, args.concat arguments
# Bind all of an object's methods to that object. Useful for ensuring that
# all callbacks defined on an object belong to it.
_.bindAll = (obj) ->
funcs = if arguments.length > 1 then _.rest(arguments) else _.functions(obj)
_.each funcs, (f) -> obj[f] = _.bind obj[f], obj
obj
# Delays a function for the given number of milliseconds, and then calls
# it with the arguments supplied.
_.delay = (func, wait) ->
args = _.rest arguments, 2
setTimeout((-> func.apply(func, args)), wait)
# Memoize an expensive function by storing its results.
_.memoize = (func, hasher) ->
memo = {}
hasher or= _.identity
->
key = hasher.apply this, arguments
return memo[key] if key of memo
memo[key] = func.apply this, arguments
# Defers a function, scheduling it to run after the current call stack has
# cleared.
_.defer = (func) ->
_.delay.apply _, [func, 1].concat _.rest arguments
# Returns the first function passed as an argument to the second,
# allowing you to adjust arguments, run code before and after, and
# conditionally execute the original function.
_.wrap = (func, wrapper) ->
-> wrapper.apply wrapper, [func].concat arguments
# Returns a function that is the composition of a list of functions, each
# consuming the return value of the function that follows.
_.compose = ->
funcs = arguments
->
args = arguments
for i in [funcs.length - 1..0] by -1
args = [funcs[i].apply(this, args)]
args[0]
# Object Functions
# ----------------
# Retrieve the names of an object's properties.
_.keys = nativeKeys or (obj) ->
return _.range 0, obj.length if _.isArray(obj)
key for key, val of obj
# Retrieve the values of an object's properties.
_.values = (obj) ->
_.map obj, _.identity
# Return a sorted list of the function names available in Underscore.
_.functions = (obj) ->
_.filter(_.keys(obj), (key) -> _.isFunction(obj[key])).sort()
# Extend a given object with all of the properties in a source object.
_.extend = (obj) ->
for source in _.rest(arguments)
obj[key] = val for key, val of source
obj
# Create a (shallow-cloned) duplicate of an object.
_.clone = (obj) ->
return obj.slice 0 if _.isArray obj
_.extend {}, obj
# Invokes interceptor with the obj, and then returns obj.
# The primary purpose of this method is to "tap into" a method chain,
# in order to perform operations on intermediate results within
the chain.
_.tap = (obj, interceptor) ->
interceptor obj
obj
# Perform a deep comparison to check if two objects are equal.
_.isEqual = (a, b) ->
# Check object identity.
return true if a is b
# Different types?
atype = typeof(a); btype = typeof(b)
return false if atype isnt btype
# Basic equality test (watch out for coercions).
return true if `a == b`
# One is falsy and the other truthy.
return false if (!a and b) or (a and !b)
# One of them implements an `isEqual()`?
return a.isEqual(b) if a.isEqual
# Check dates' integer values.
return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b)
# Both are NaN?
return false if _.isNaN(a) and _.isNaN(b)
# Compare regular expressions.
if _.isRegExp(a) and _.isRegExp(b)
return a.source is b.source and
a.global is b.global and
a.ignoreCase is b.ignoreCase and
a.multiline is b.multiline
# If a is not an object by this point, we can't handle it.
return false if atype isnt 'object'
# Check for different array lengths before comparing contents.
return false if a.length and (a.length isnt b.length)
# Nothing else worked, deep compare the contents.
aKeys = _.keys(a); bKeys = _.keys(b)
# Different object sizes?
return false if aKeys.length isnt bKeys.length
# Recursive comparison of contents.
return false for key, val of a when !(key of b) or !_.isEqual(val, b[key])
true
# Is a given array or object empty?
_.isEmpty = (obj) ->
return obj.length is 0 if _.isArray(obj) or _.isString(obj)
return false for own key of obj
true
# Is a given value a DOM element?
_.isElement = (obj) -> obj and obj.nodeType is 1
# Is a given value an array?
_.isArray = nativeIsArray or (obj) -> !!(obj and obj.concat and obj.unshift and not obj.callee)
# Is a given variable an arguments object?
_.isArguments = (obj) -> obj and obj.callee
# Is the given value a function?
_.isFunction = (obj) -> !!(obj and obj.constructor and obj.call and obj.apply)
# Is the given value a string?
_.isString = (obj) -> !!(obj is '' or (obj and obj.charCodeAt and obj.substr))
# Is a given value a number?
_.isNumber = (obj) -> (obj is +obj) or toString.call(obj) is '[object Number]'
# Is a given value a boolean?
_.isBoolean = (obj) -> obj is true or obj is false
# Is a given value a Date?
_.isDate = (obj) -> !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear)
# Is the given value a regular expression?
_.isRegExp = (obj) -> !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false))
# Is the given value NaN -- this one is interesting. `NaN != NaN`, and
# `isNaN(undefined) == true`, so we make sure it's a number first.
_.isNaN = (obj) -> _.isNumber(obj) and window.isNaN(obj)
# Is a given value equal to null?
_.isNull = (obj) -> obj is null
# Is a given variable undefined?
_.isUndefined = (obj) -> typeof obj is 'undefined'
# Utility Functions
# -----------------
# Run Underscore.js in noConflict mode, returning the `_` variable to its
# previous owner. Returns a reference to the Underscore object.
_.noConflict = ->
root._ = previousUnderscore
this
# Keep the identity function around for default iterators.
_.identity = (value) -> value
# Run a function `n` times.
_.times = (n, iterator, context) ->
iterator.call context, i for i in [0...n]
# Break out of the middle of an iteration.
_.breakLoop = -> throw breaker
# Add your own custom functions to the Underscore object, ensuring that
# they're correctly added to the OOP wrapper as well.
_.mixin = (obj) ->
for name in _.functions(obj)
addToWrapper name, _[name] = obj[name]
# Generate a unique integer id (unique within the entire client session).
# Useful for temporary DOM ids.
idCounter = 0
_.uniqueId = (prefix) ->
(prefix or '') + idCounter++
# By default, Underscore uses **ERB**-style template delimiters, change the
# following template settings to use alternative delimiters.
_.templateSettings = {
start: '<%'
end: '%>'
interpolate: /<%=(.+?)%>/g
}
# JavaScript templating a-la **ERB**, pilfered from John Resig's
# *Secrets of the JavaScript Ninja*, page 83.
# Single-quote fix from Rick Strahl.
# With alterations for arbitrary delimiters, and to preserve whitespace.
_.template = (str, data) ->
c = _.templateSettings
endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g")
fn = new Function 'obj',
'var p=[],print=function(){p.push.apply(p,arguments);};' +
'with(obj||{}){p.push(\'' +
str.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
.replace(/\t/g, '\\t')
.replace(endMatch,"<22><><EFBFBD>")
.split("'").join("\\'")
.split("<22><><EFBFBD>").join("'")
.replace(c.interpolate, "',$1,'")
.split(c.start).join("');")
.split(c.end).join("p.push('") +
"');}return p.join('');"
if data then fn(data) else fn
# Aliases
# -------
_.forEach = _.each
_.foldl = _.inject = _.reduce
_.foldr = _.reduceRight
_.select = _.filter
_.all = _.every
_.any = _.some
_.contains = _.include
_.head = _.first
_.tail = _.rest
_.methods = _.functions
# Setup the OOP Wrapper
# ---------------------
# If Underscore is called as a function, it returns a wrapped object that
# can be used OO-style. This wrapper holds altered versions of all the
# underscore functions. Wrapped objects may be chained.
wrapper = (obj) ->
this._wrapped = obj
this
# Helper function to continue chaining intermediate results.
result = (obj, chain) ->
if chain then _(obj).chain() else obj
# A method to easily add functions to the OOP wrapper.
addToWrapper = (name, func) ->
wrapper.prototype[name] = ->
args = _.toArray arguments
unshift.call args, this._wrapped
result func.apply(_, args), this._chain
# Add all ofthe Underscore functions to the wrapper object.
_.mixin _
# Add all mutator Array functions to the wrapper.
_.each ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], (name) ->
method = Array.prototype[name]
wrapper.prototype[name] = ->
method.apply(this._wrapped, arguments)
result(this._wrapped, this._chain)
# Add all accessor Array functions to the wrapper.
_.each ['concat', 'join', 'slice'], (name) ->
method = Array.prototype[name]
wrapper.prototype[name] = ->
result(method.apply(this._wrapped, arguments), this._chain)
# Start chaining a wrapped Underscore object.
wrapper::chain = ->
this._chain = true
this
# Extracts the result from a wrapped and chained object.
wrapper::value = -> this._wrapped
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
</script>
<p><strong>MIME types defined:</strong> <code>application/vnd.coffeescript</code>, <code>text/coffeescript</code>, <code>text/x-coffeescript</code>.</p>
<p>The CoffeeScript mode was written by Jeff Pickhardt.</p>
</article>

832
web/public/codemirror/mode/css/css.js vendored Normal file
View File

@@ -0,0 +1,832 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("css", function(config, parserConfig) {
var inline = parserConfig.inline
if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
var indentUnit = config.indentUnit,
tokenHooks = parserConfig.tokenHooks,
documentTypes = parserConfig.documentTypes || {},
mediaTypes = parserConfig.mediaTypes || {},
mediaFeatures = parserConfig.mediaFeatures || {},
mediaValueKeywords = parserConfig.mediaValueKeywords || {},
propertyKeywords = parserConfig.propertyKeywords || {},
nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
fontProperties = parserConfig.fontProperties || {},
counterDescriptors = parserConfig.counterDescriptors || {},
colorKeywords = parserConfig.colorKeywords || {},
valueKeywords = parserConfig.valueKeywords || {},
allowNested = parserConfig.allowNested,
lineComment = parserConfig.lineComment,
supportsAtComponent = parserConfig.supportsAtComponent === true;
var type, override;
function ret(style, tp) { type = tp; return style; }
// Tokenizers
function tokenBase(stream, state) {
var ch = stream.next();
if (tokenHooks[ch]) {
var result = tokenHooks[ch](stream, state);
if (result !== false) return result;
}
if (ch == "@") {
stream.eatWhile(/[\w\\\-]/);
return ret("def", stream.current());
} else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
return ret(null, "compare");
} else if (ch == "\"" || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
} else if (ch == "#") {
stream.eatWhile(/[\w\\\-]/);
return ret("atom", "hash");
} else if (ch == "!") {
stream.match(/^\s*\w*/);
return ret("keyword", "important");
} else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
} else if (ch === "-") {
if (/[\d.]/.test(stream.peek())) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
} else if (stream.match(/^-[\w\\\-]+/)) {
stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false))
return ret("variable-2", "variable-definition");
return ret("variable-2", "variable");
} else if (stream.match(/^\w+-/)) {
return ret("meta", "meta");
}
} else if (/[,+>*\/]/.test(ch)) {
return ret(null, "select-op");
} else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
return ret("qualifier", "qualifier");
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch);
} else if (((ch == "u" || ch == "U") && stream.match(/rl(-prefix)?\(/i)) ||
((ch == "d" || ch == "D") && stream.match("omain(", true, true)) ||
((ch == "r" || ch == "R") && stream.match("egexp(", true, true))) {
stream.backUp(1);
state.tokenize = tokenParenthesized;
return ret("property", "word");
} else if (/[\w\\\-]/.test(ch)) {
stream.eatWhile(/[\w\\\-]/);
return ret("property", "word");
} else {
return ret(null, null);
}
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, ch;
while ((ch = stream.next()) != null) {
if (ch == quote && !escaped) {
if (quote == ")") stream.backUp(1);
break;
}
escaped = !escaped && ch == "\\";
}
if (ch == quote || !escaped && quote != ")") state.tokenize = null;
return ret("string", "string");
};
}
function tokenParenthesized(stream, state) {
stream.next(); // Must be '('
if (!stream.match(/\s*[\"\')]/, false))
state.tokenize = tokenString(")");
else
state.tokenize = null;
return ret(null, "(");
}
// Context management
function Context(type, indent, prev) {
this.type = type;
this.indent = indent;
this.prev = prev;
}
function pushContext(state, stream, type, indent) {
state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
return type;
}
function popContext(state) {
if (state.context.prev)
state.context = state.context.prev;
return state.context.type;
}
function pass(type, stream, state) {
return states[state.context.type](type, stream, state);
}
function popAndPass(type, stream, state, n) {
for (var i = n || 1; i > 0; i--)
state.context = state.context.prev;
return pass(type, stream, state);
}
// Parser
function wordAsValue(stream) {
var word = stream.current().toLowerCase();
if (valueKeywords.hasOwnProperty(word))
override = "atom";
else if (colorKeywords.hasOwnProperty(word))
override = "keyword";
else
override = "variable";
}
var states = {};
states.top = function(type, stream, state) {
if (type == "{") {
return pushContext(state, stream, "block");
} else if (type == "}" && state.context.prev) {
return popContext(state);
} else if (supportsAtComponent && /@component/i.test(type)) {
return pushContext(state, stream, "atComponentBlock");
} else if (/^@(-moz-)?document$/i.test(type)) {
return pushContext(state, stream, "documentTypes");
} else if (/^@(media|supports|(-moz-)?document|import)$/i.test(type)) {
return pushContext(state, stream, "atBlock");
} else if (/^@(font-face|counter-style)/i.test(type)) {
state.stateArg = type;
return "restricted_atBlock_before";
} else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(type)) {
return "keyframes";
} else if (type && type.charAt(0) == "@") {
return pushContext(state, stream, "at");
} else if (type == "hash") {
override = "builtin";
} else if (type == "word") {
override = "tag";
} else if (type == "variable-definition") {
return "maybeprop";
} else if (type == "interpolation") {
return pushContext(state, stream, "interpolation");
} else if (type == ":") {
return "pseudo";
} else if (allowNested && type == "(") {
return pushContext(state, stream, "parens");
}
return state.context.type;
};
states.block = function(type, stream, state) {
if (type == "word") {
var word = stream.current().toLowerCase();
if (propertyKeywords.hasOwnProperty(word)) {
override = "property";
return "maybeprop";
} else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
override = "string-2";
return "maybeprop";
} else if (allowNested) {
override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
return "block";
} else {
override += " error";
return "maybeprop";
}
} else if (type == "meta") {
return "block";
} else if (!allowNested && (type == "hash" || type == "qualifier")) {
override = "error";
return "block";
} else {
return states.top(type, stream, state);
}
};
states.maybeprop = function(type, stream, state) {
if (type == ":") return pushContext(state, stream, "prop");
return pass(type, stream, state);
};
states.prop = function(type, stream, state) {
if (type == ";") return popContext(state);
if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
if (type == "}" || type == "{") return popAndPass(type, stream, state);
if (type == "(") return pushContext(state, stream, "parens");
if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
override += " error";
} else if (type == "word") {
wordAsValue(stream);
} else if (type == "interpolation") {
return pushContext(state, stream, "interpolation");
}
return "prop";
};
states.propBlock = function(type, _stream, state) {
if (type == "}") return popContext(state);
if (type == "word") { override = "property"; return "maybeprop"; }
return state.context.type;
};
states.parens = function(type, stream, state) {
if (type == "{" || type == "}") return popAndPass(type, stream, state);
if (type == ")") return popContext(state);
if (type == "(") return pushContext(state, stream, "parens");
if (type == "interpolation") return pushContext(state, stream, "interpolation");
if (type == "word") wordAsValue(stream);
return "parens";
};
states.pseudo = function(type, stream, state) {
if (type == "meta") return "pseudo";
if (type == "word") {
override = "variable-3";
return state.context.type;
}
return pass(type, stream, state);
};
states.documentTypes = function(type, stream, state) {
if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
override = "tag";
return state.context.type;
} else {
return states.atBlock(type, stream, state);
}
};
states.atBlock = function(type, stream, state) {
if (type == "(") return pushContext(state, stream, "atBlock_parens");
if (type == "}" || type == ";") return popAndPass(type, stream, state);
if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
if (type == "interpolation") return pushContext(state, stream, "interpolation");
if (type == "word") {
var word = stream.current().toLowerCase();
if (word == "only" || word == "not" || word == "and" || word == "or")
override = "keyword";
else if (mediaTypes.hasOwnProperty(word))
override = "attribute";
else if (mediaFeatures.hasOwnProperty(word))
override = "property";
else if (mediaValueKeywords.hasOwnProperty(word))
override = "keyword";
else if (propertyKeywords.hasOwnProperty(word))
override = "property";
else if (nonStandardPropertyKeywords.hasOwnProperty(word))
override = "string-2";
else if (valueKeywords.hasOwnProperty(word))
override = "atom";
else if (colorKeywords.hasOwnProperty(word))
override = "keyword";
else
override = "error";
}
return state.context.type;
};
states.atComponentBlock = function(type, stream, state) {
if (type == "}")
return popAndPass(type, stream, state);
if (type == "{")
return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
if (type == "word")
override = "error";
return state.context.type;
};
states.atBlock_parens = function(type, stream, state) {
if (type == ")") return popContext(state);
if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
return states.atBlock(type, stream, state);
};
states.restricted_atBlock_before = function(type, stream, state) {
if (type == "{")
return pushContext(state, stream, "restricted_atBlock");
if (type == "word" && state.stateArg == "@counter-style") {
override = "variable";
return "restricted_atBlock_before";
}
return pass(type, stream, state);
};
states.restricted_atBlock = function(type, stream, state) {
if (type == "}") {
state.stateArg = null;
return popContext(state);
}
if (type == "word") {
if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
(state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
override = "error";
else
override = "property";
return "maybeprop";
}
return "restricted_atBlock";
};
states.keyframes = function(type, stream, state) {
if (type == "word") { override = "variable"; return "keyframes"; }
if (type == "{") return pushContext(state, stream, "top");
return pass(type, stream, state);
};
states.at = function(type, stream, state) {
if (type == ";") return popContext(state);
if (type == "{" || type == "}") return popAndPass(type, stream, state);
if (type == "word") override = "tag";
else if (type == "hash") override = "builtin";
return "at";
};
states.interpolation = function(type, stream, state) {
if (type == "}") return popContext(state);
if (type == "{" || type == ";") return popAndPass(type, stream, state);
if (type == "word") override = "variable";
else if (type != "variable" && type != "(" && type != ")") override = "error";
return "interpolation";
};
return {
startState: function(base) {
return {tokenize: null,
state: inline ? "block" : "top",
stateArg: null,
context: new Context(inline ? "block" : "top", base || 0, null)};
},
token: function(stream, state) {
if (!state.tokenize && stream.eatSpace()) return null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style && typeof style == "object") {
type = style[1];
style = style[0];
}
override = style;
if (type != "comment")
state.state = states[state.state](type, stream, state);
return override;
},
indent: function(state, textAfter) {
var cx = state.context, ch = textAfter && textAfter.charAt(0);
var indent = cx.indent;
if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
if (cx.prev) {
if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
// Resume indentation from parent context.
cx = cx.prev;
indent = cx.indent;
} else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
// Dedent relative to current context.
indent = Math.max(0, cx.indent - indentUnit);
}
}
return indent;
},
electricChars: "}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
blockCommentContinue: " * ",
lineComment: lineComment,
fold: "brace"
};
});
function keySet(array) {
var keys = {};
for (var i = 0; i < array.length; ++i) {
keys[array[i].toLowerCase()] = true;
}
return keys;
}
var documentTypes_ = [
"domain", "regexp", "url", "url-prefix"
], documentTypes = keySet(documentTypes_);
var mediaTypes_ = [
"all", "aural", "braille", "handheld", "print", "projection", "screen",
"tty", "tv", "embossed"
], mediaTypes = keySet(mediaTypes_);
var mediaFeatures_ = [
"width", "min-width", "max-width", "height", "min-height", "max-height",
"device-width", "min-device-width", "max-device-width", "device-height",
"min-device-height", "max-device-height", "aspect-ratio",
"min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
"min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
"max-color", "color-index", "min-color-index", "max-color-index",
"monochrome", "min-monochrome", "max-monochrome", "resolution",
"min-resolution", "max-resolution", "scan", "grid", "orientation",
"device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
"pointer", "any-pointer", "hover", "any-hover"
], mediaFeatures = keySet(mediaFeatures_);
var mediaValueKeywords_ = [
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
"interlace", "progressive"
], mediaValueKeywords = keySet(mediaValueKeywords_);
var propertyKeywords_ = [
"align-content", "align-items", "align-self", "alignment-adjust",
"alignment-baseline", "anchor-point", "animation", "animation-delay",
"animation-direction", "animation-duration", "animation-fill-mode",
"animation-iteration-count", "animation-name", "animation-play-state",
"animation-timing-function", "appearance", "azimuth", "backface-visibility",
"background", "background-attachment", "background-blend-mode", "background-clip",
"background-color", "background-image", "background-origin", "background-position",
"background-repeat", "background-size", "baseline-shift", "binding",
"bleed", "bookmark-label", "bookmark-level", "bookmark-state",
"bookmark-target", "border", "border-bottom", "border-bottom-color",
"border-bottom-left-radius", "border-bottom-right-radius",
"border-bottom-style", "border-bottom-width", "border-collapse",
"border-color", "border-image", "border-image-outset",
"border-image-repeat", "border-image-slice", "border-image-source",
"border-image-width", "border-left", "border-left-color",
"border-left-style", "border-left-width", "border-radius", "border-right",
"border-right-color", "border-right-style", "border-right-width",
"border-spacing", "border-style", "border-top", "border-top-color",
"border-top-left-radius", "border-top-right-radius", "border-top-style",
"border-top-width", "border-width", "bottom", "box-decoration-break",
"box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
"caption-side", "caret-color", "clear", "clip", "color", "color-profile", "column-count",
"column-fill", "column-gap", "column-rule", "column-rule-color",
"column-rule-style", "column-rule-width", "column-span", "column-width",
"columns", "content", "counter-increment", "counter-reset", "crop", "cue",
"cue-after", "cue-before", "cursor", "direction", "display",
"dominant-baseline", "drop-initial-after-adjust",
"drop-initial-after-align", "drop-initial-before-adjust",
"drop-initial-before-align", "drop-initial-size", "drop-initial-value",
"elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
"flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
"float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
"font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
"font-stretch", "font-style", "font-synthesis", "font-variant",
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
"font-variant-ligatures", "font-variant-numeric", "font-variant-position",
"font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
"grid-auto-rows", "grid-column", "grid-column-end", "grid-column-gap",
"grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap",
"grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns",
"grid-template-rows", "hanging-punctuation", "height", "hyphens",
"icon", "image-orientation", "image-rendering", "image-resolution",
"inline-box-align", "justify-content", "justify-items", "justify-self", "left", "letter-spacing",
"line-break", "line-height", "line-stacking", "line-stacking-ruby",
"line-stacking-shift", "line-stacking-strategy", "list-style",
"list-style-image", "list-style-position", "list-style-type", "margin",
"margin-bottom", "margin-left", "margin-right", "margin-top",
"marks", "marquee-direction", "marquee-loop",
"marquee-play-count", "marquee-speed", "marquee-style", "max-height",
"max-width", "min-height", "min-width", "mix-blend-mode", "move-to", "nav-down", "nav-index",
"nav-left", "nav-right", "nav-up", "object-fit", "object-position",
"opacity", "order", "orphans", "outline",
"outline-color", "outline-offset", "outline-style", "outline-width",
"overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
"padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
"page", "page-break-after", "page-break-before", "page-break-inside",
"page-policy", "pause", "pause-after", "pause-before", "perspective",
"perspective-origin", "pitch", "pitch-range", "place-content", "place-items", "place-self", "play-during", "position",
"presentation-level", "punctuation-trim", "quotes", "region-break-after",
"region-break-before", "region-break-inside", "region-fragment",
"rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
"right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
"ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
"shape-outside", "size", "speak", "speak-as", "speak-header",
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
"tab-size", "table-layout", "target", "target-name", "target-new",
"target-position", "text-align", "text-align-last", "text-decoration",
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
"text-decoration-style", "text-emphasis", "text-emphasis-color",
"text-emphasis-position", "text-emphasis-style", "text-height",
"text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
"text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
"text-wrap", "top", "transform", "transform-origin", "transform-style",
"transition", "transition-delay", "transition-duration",
"transition-property", "transition-timing-function", "unicode-bidi",
"user-select", "vertical-align", "visibility", "voice-balance", "voice-duration",
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
"voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break",
"word-spacing", "word-wrap", "z-index",
// SVG-specific
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
"color-interpolation", "color-interpolation-filters",
"color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
"marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
"stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
"glyph-orientation-vertical", "text-anchor", "writing-mode"
], propertyKeywords = keySet(propertyKeywords_);
var nonStandardPropertyKeywords_ = [
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
"scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
"searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
"searchfield-results-decoration", "zoom"
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
var fontProperties_ = [
"font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
"font-stretch", "font-weight", "font-style"
], fontProperties = keySet(fontProperties_);
var counterDescriptors_ = [
"additive-symbols", "fallback", "negative", "pad", "prefix", "range",
"speak-as", "suffix", "symbols", "system"
], counterDescriptors = keySet(counterDescriptors_);
var colorKeywords_ = [
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
"darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
"darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
"darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
"deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
"floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
"gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
"hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
"lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
"lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
"lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
"maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
"mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
"mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
"navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
"orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
"papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
"purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
"salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
"slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
"whitesmoke", "yellow", "yellowgreen"
], colorKeywords = keySet(colorKeywords_);
var valueKeywords_ = [
"above", "absolute", "activeborder", "additive", "activecaption", "afar",
"after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
"arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page",
"avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
"bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
"both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
"cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
"col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
"compact", "condensed", "contain", "content", "contents",
"content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
"cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
"decimal-leading-zero", "default", "default-button", "dense", "destination-atop",
"destination-in", "destination-out", "destination-over", "devanagari", "difference",
"disc", "discard", "disclosure-closed", "disclosure-open", "document",
"dot-dash", "dot-dot-dash",
"dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
"element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
"ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
"ethiopic-halehame-gez", "ethiopic-halehame-om-et",
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
"ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
"forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove",
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
"inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert",
"italic", "japanese-formal", "japanese-informal", "justify", "kannada",
"katakana", "katakana-iroha", "keep-all", "khmer",
"korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
"landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
"line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
"lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
"media-controls-background", "media-current-time-display",
"media-fullscreen-button", "media-mute-button", "media-play-button",
"media-return-to-realtime-button", "media-rewind-button",
"media-seek-back-button", "media-seek-forward-button", "media-slider",
"media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
"media-volume-slider-container", "media-volume-sliderthumb", "medium",
"menu", "menulist", "menulist-button", "menulist-text",
"menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
"mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
"ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote",
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
"painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
"pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
"progress", "push-button", "radial-gradient", "radio", "read-only",
"read-write", "read-write-plaintext-only", "rectangle", "region",
"relative", "repeat", "repeating-linear-gradient",
"repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
"rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
"rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
"s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
"scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
"searchfield-cancel-button", "searchfield-decoration",
"searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end",
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
"simp-chinese-formal", "simp-chinese-informal", "single",
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
"source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square",
"square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
"subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
"table-caption", "table-cell", "table-column", "table-column-group",
"table-footer-group", "table-header-group", "table-row", "table-row-group",
"tamil",
"telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
"trad-chinese-formal", "trad-chinese-informal", "transform",
"translate", "translate3d", "translateX", "translateY", "translateZ",
"transparent", "ultra-condensed", "ultra-expanded", "underline", "unset", "up",
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
"var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
"window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
"xx-large", "xx-small"
], valueKeywords = keySet(valueKeywords_);
var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
.concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
.concat(valueKeywords_);
CodeMirror.registerHelper("hintWords", "css", allWords);
function tokenCComment(stream, state) {
var maybeEnd = false, ch;
while ((ch = stream.next()) != null) {
if (maybeEnd && ch == "/") {
state.tokenize = null;
break;
}
maybeEnd = (ch == "*");
}
return ["comment", "comment"];
}
CodeMirror.defineMIME("text/css", {
documentTypes: documentTypes,
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
mediaValueKeywords: mediaValueKeywords,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
fontProperties: fontProperties,
counterDescriptors: counterDescriptors,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
tokenHooks: {
"/": function(stream, state) {
if (!stream.eat("*")) return false;
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
}
},
name: "css"
});
CodeMirror.defineMIME("text/x-scss", {
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
mediaValueKeywords: mediaValueKeywords,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
fontProperties: fontProperties,
allowNested: true,
lineComment: "//",
tokenHooks: {
"/": function(stream, state) {
if (stream.eat("/")) {
stream.skipToEnd();
return ["comment", "comment"];
} else if (stream.eat("*")) {
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
} else {
return ["operator", "operator"];
}
},
":": function(stream) {
if (stream.match(/\s*\{/, false))
return [null, null]
return false;
},
"$": function(stream) {
stream.match(/^[\w-]+/);
if (stream.match(/^\s*:/, false))
return ["variable-2", "variable-definition"];
return ["variable-2", "variable"];
},
"#": function(stream) {
if (!stream.eat("{")) return false;
return [null, "interpolation"];
}
},
name: "css",
helperType: "scss"
});
CodeMirror.defineMIME("text/x-less", {
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
mediaValueKeywords: mediaValueKeywords,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
fontProperties: fontProperties,
allowNested: true,
lineComment: "//",
tokenHooks: {
"/": function(stream, state) {
if (stream.eat("/")) {
stream.skipToEnd();
return ["comment", "comment"];
} else if (stream.eat("*")) {
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
} else {
return ["operator", "operator"];
}
},
"@": function(stream) {
if (stream.eat("{")) return [null, "interpolation"];
if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/i, false)) return false;
stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false))
return ["variable-2", "variable-definition"];
return ["variable-2", "variable"];
},
"&": function() {
return ["atom", "atom"];
}
},
name: "css",
helperType: "less"
});
CodeMirror.defineMIME("text/x-gss", {
documentTypes: documentTypes,
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
fontProperties: fontProperties,
counterDescriptors: counterDescriptors,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
supportsAtComponent: true,
tokenHooks: {
"/": function(stream, state) {
if (!stream.eat("*")) return false;
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
}
},
name: "css",
helperType: "gss"
});
});

104
web/public/codemirror/mode/css/gss.html vendored Normal file
View File

@@ -0,0 +1,104 @@
<!doctype html>
<title>CodeMirror: Closure Stylesheets (GSS) mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../addon/hint/show-hint.css">
<script src="../../lib/codemirror.js"></script>
<script src="css.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="../../addon/hint/show-hint.js"></script>
<script src="../../addon/hint/css-hint.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="https://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="#">Closure Stylesheets (GSS)</a>
</ul>
</div>
<article>
<h2>Closure Stylesheets (GSS) mode</h2>
<form><textarea id="code" name="code">
/* Some example Closure Stylesheets */
@provide 'some.styles';
@require 'other.styles';
@component {
@def FONT_FAMILY "Times New Roman", Georgia, Serif;
@def FONT_SIZE_NORMAL 15px;
@def FONT_NORMAL normal FONT_SIZE_NORMAL FONT_FAMILY;
@def BG_COLOR rgb(235, 239, 249);
@def DIALOG_BORDER_COLOR rgb(107, 144, 218);
@def DIALOG_BG_COLOR BG_COLOR;
@def LEFT_HAND_NAV_WIDTH 180px;
@def LEFT_HAND_NAV_PADDING 3px;
@defmixin size(WIDTH, HEIGHT) {
width: WIDTH;
height: HEIGHT;
}
body {
background-color: BG_COLOR;
margin: 0;
padding: 3em 6em;
font: FONT_NORMAL;
color: #000;
}
#navigation a {
font-weight: bold;
text-decoration: none !important;
}
.dialog {
background-color: DIALOG_BG_COLOR;
border: 1px solid DIALOG_BORDER_COLOR;
}
.content {
position: absolute;
margin-left: add(LEFT_HAND_NAV_PADDING, /* padding left */
LEFT_HAND_NAV_WIDTH,
LEFT_HAND_NAV_PADDING); /* padding right */
}
.logo {
@mixin size(150px, 55px);
background-image: url('http://www.google.com/images/logo_sm.gif');
}
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
extraKeys: {"Ctrl-Space": "autocomplete"},
lineNumbers: true,
matchBrackets: true,
mode: "text/x-gss"
});
</script>
<p>A mode for <a href="https://github.com/google/closure-stylesheets">Closure Stylesheets</a> (GSS).</p>
<p><strong>MIME type defined:</strong> <code>text/x-gss</code>.</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#gss_*">normal</a>, <a href="../../test/index.html#verbose,gss_*">verbose</a>.</p>
</article>

View File

@@ -0,0 +1,17 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
"use strict";
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-gss");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "gss"); }
MT("atComponent",
"[def @component] {",
"[tag foo] {",
" [property color]: [keyword black];",
"}",
"}");
})();

View File

@@ -0,0 +1,75 @@
<!doctype html>
<title>CodeMirror: CSS mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../addon/hint/show-hint.css">
<script src="../../lib/codemirror.js"></script>
<script src="css.js"></script>
<script src="../../addon/hint/show-hint.js"></script>
<script src="../../addon/hint/css-hint.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="https://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="#">CSS</a>
</ul>
</div>
<article>
<h2>CSS mode</h2>
<form><textarea id="code" name="code">
/* Some example CSS */
@import url("something.css");
body {
margin: 0;
padding: 3em 6em;
font-family: tahoma, arial, sans-serif;
color: #000;
}
#navigation a {
font-weight: bold;
text-decoration: none !important;
}
h1 {
font-size: 2.5em;
}
h2 {
font-size: 1.7em;
}
h1:before, h2:before {
content: "::";
}
code {
font-family: courier, monospace;
font-size: 80%;
color: #418A8A;
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
extraKeys: {"Ctrl-Space": "autocomplete"}
});
</script>
<p><strong>MIME types defined:</strong> <code>text/css</code>, <code>text/x-scss</code> (<a href="scss.html">demo</a>), <code>text/x-less</code> (<a href="less.html">demo</a>).</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#css_*">normal</a>, <a href="../../test/index.html#verbose,css_*">verbose</a>.</p>
</article>

152
web/public/codemirror/mode/css/less.html vendored Normal file
View File

@@ -0,0 +1,152 @@
<!doctype html>
<title>CodeMirror: LESS 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="../../addon/edit/matchbrackets.js"></script>
<script src="css.js"></script>
<style>.CodeMirror {border: 1px solid #ddd; line-height: 1.2;}</style>
<div id=nav>
<a href="https://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="#">LESS</a>
</ul>
</div>
<article>
<h2>LESS mode</h2>
<form><textarea id="code" name="code">@media screen and (device-aspect-ratio: 16/9) { … }
@media screen and (device-aspect-ratio: 1280/720) { … }
@media screen and (device-aspect-ratio: 2560/1440) { … }
html:lang(fr-be)
tr:nth-child(2n+1) /* represents every odd row of an HTML table */
img:nth-of-type(2n+1) { float: right; }
img:nth-of-type(2n) { float: left; }
body > h2:not(:first-of-type):not(:last-of-type)
html|*:not(:link):not(:visited)
*|*:not(:hover)
p::first-line { text-transform: uppercase }
@namespace foo url(http://www.example.com);
foo|h1 { color: blue } /* first rule */
span[hello="Ocean"][goodbye="Land"]
E[foo]{
padding:65px;
}
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5
}
button::-moz-focus-inner,
input::-moz-focus-inner { // Inner padding and border oddities in FF3/4
padding: 0;
border: 0;
}
.btn {
// reset here as of 2.0.3 due to Recess property order
border-color: #ccc;
border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);
}
fieldset span button, fieldset span input[type="file"] {
font-size:12px;
font-family:Arial, Helvetica, sans-serif;
}
.rounded-corners (@radius: 5px) {
border-radius: @radius;
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
}
@import url("something.css");
@light-blue: hsl(190, 50%, 65%);
#menu {
position: absolute;
width: 100%;
z-index: 3;
clear: both;
display: block;
background-color: @blue;
height: 42px;
border-top: 2px solid lighten(@alpha-blue, 20%);
border-bottom: 2px solid darken(@alpha-blue, 25%);
.box-shadow(0, 1px, 8px, 0.6);
-moz-box-shadow: 0 0 0 #000; // Because firefox sucks.
&.docked {
background-color: hsla(210, 60%, 40%, 0.4);
}
&:hover {
background-color: @blue;
}
#dropdown {
margin: 0 0 0 117px;
padding: 0;
padding-top: 5px;
display: none;
width: 190px;
border-top: 2px solid @medium;
color: @highlight;
border: 2px solid darken(@medium, 25%);
border-left-color: darken(@medium, 15%);
border-right-color: darken(@medium, 15%);
border-top-width: 0;
background-color: darken(@medium, 10%);
ul {
padding: 0px;
}
li {
font-size: 14px;
display: block;
text-align: left;
padding: 0;
border: 0;
a {
display: block;
padding: 0px 15px;
text-decoration: none;
color: white;
&:hover {
background-color: darken(@medium, 15%);
text-decoration: none;
}
}
}
.border-radius(5px, bottom);
.box-shadow(0, 6px, 8px, 0.5);
}
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-less"
});
</script>
<p>The LESS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>).</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#less_*">normal</a>, <a href="../../test/index.html#verbose,less_*">verbose</a>.</p>
</article>

View File

@@ -0,0 +1,54 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
"use strict";
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-less");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "less"); }
MT("variable",
"[variable-2 @base]: [atom #f04615];",
"[qualifier .class] {",
" [property width]: [variable percentage]([number 0.5]); [comment // returns `50%`]",
" [property color]: [variable saturate]([variable-2 @base], [number 5%]);",
"}");
MT("amp",
"[qualifier .child], [qualifier .sibling] {",
" [qualifier .parent] [atom &] {",
" [property color]: [keyword black];",
" }",
" [atom &] + [atom &] {",
" [property color]: [keyword red];",
" }",
"}");
MT("mixin",
"[qualifier .mixin] ([variable dark]; [variable-2 @color]) {",
" [property color]: [atom darken]([variable-2 @color], [number 10%]);",
"}",
"[qualifier .mixin] ([variable light]; [variable-2 @color]) {",
" [property color]: [atom lighten]([variable-2 @color], [number 10%]);",
"}",
"[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {",
" [property display]: [atom block];",
"}",
"[variable-2 @switch]: [variable light];",
"[qualifier .class] {",
" [qualifier .mixin]([variable-2 @switch]; [atom #888]);",
"}");
MT("nest",
"[qualifier .one] {",
" [def @media] ([property width]: [number 400px]) {",
" [property font-size]: [number 1.2em];",
" [def @media] [attribute print] [keyword and] [property color] {",
" [property color]: [keyword blue];",
" }",
" }",
"}");
MT("interpolation", ".@{[variable foo]} { [property font-weight]: [atom bold]; }");
})();

158
web/public/codemirror/mode/css/scss.html vendored Normal file
View File

@@ -0,0 +1,158 @@
<!doctype html>
<title>CodeMirror: SCSS 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="../../addon/edit/matchbrackets.js"></script>
<script src="css.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="https://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="#">SCSS</a>
</ul>
</div>
<article>
<h2>SCSS mode</h2>
<form><textarea id="code" name="code">
/* Some example SCSS */
@import "compass/css3";
$variable: #333;
$blue: #3bbfce;
$margin: 16px;
.content-navigation {
#nested {
background-color: black;
}
border-color: $blue;
color:
darken($blue, 9%);
}
.border {
padding: $margin / 2;
margin: $margin / 2;
border-color: $blue;
}
@mixin table-base {
th {
text-align: center;
font-weight: bold;
}
td, th {padding: 2px}
}
table.hl {
margin: 2em 0;
td.ln {
text-align: right;
}
}
li {
font: {
family: serif;
weight: bold;
size: 1.2em;
}
}
@mixin left($dist) {
float: left;
margin-left: $dist;
}
#data {
@include left(10px);
@include table-base;
}
.source {
@include flow-into(target);
border: 10px solid green;
margin: 20px;
width: 200px; }
.new-container {
@include flow-from(target);
border: 10px solid red;
margin: 20px;
width: 200px; }
body {
margin: 0;
padding: 3em 6em;
font-family: tahoma, arial, sans-serif;
color: #000;
}
@mixin yellow() {
background: yellow;
}
.big {
font-size: 14px;
}
.nested {
@include border-radius(3px);
@extend .big;
p {
background: whitesmoke;
a {
color: red;
}
}
}
#navigation a {
font-weight: bold;
text-decoration: none !important;
}
h1 {
font-size: 2.5em;
}
h2 {
font-size: 1.7em;
}
h1:before, h2:before {
content: "::";
}
code {
font-family: courier, monospace;
font-size: 80%;
color: #418A8A;
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-scss"
});
</script>
<p>The SCSS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>).</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#scss_*">normal</a>, <a href="../../test/index.html#verbose,scss_*">verbose</a>.</p>
</article>

View File

@@ -0,0 +1,110 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); }
MT('url_with_quotation',
"[tag foo] { [property background]:[atom url]([string test.jpg]) }");
MT('url_with_double_quotes',
"[tag foo] { [property background]:[atom url]([string \"test.jpg\"]) }");
MT('url_with_single_quotes',
"[tag foo] { [property background]:[atom url]([string \'test.jpg\']) }");
MT('string',
"[def @import] [string \"compass/css3\"]");
MT('important_keyword',
"[tag foo] { [property background]:[atom url]([string \'test.jpg\']) [keyword !important] }");
MT('variable',
"[variable-2 $blue]:[atom #333]");
MT('variable_as_attribute',
"[tag foo] { [property color]:[variable-2 $blue] }");
MT('numbers',
"[tag foo] { [property padding]:[number 10px] [number 10] [number 10em] [number 8in] }");
MT('number_percentage',
"[tag foo] { [property width]:[number 80%] }");
MT('selector',
"[builtin #hello][qualifier .world]{}");
MT('singleline_comment',
"[comment // this is a comment]");
MT('multiline_comment',
"[comment /*foobar*/]");
MT('attribute_with_hyphen',
"[tag foo] { [property font-size]:[number 10px] }");
MT('string_after_attribute',
"[tag foo] { [property content]:[string \"::\"] }");
MT('directives',
"[def @include] [qualifier .mixin]");
MT('basic_structure',
"[tag p] { [property background]:[keyword red]; }");
MT('nested_structure',
"[tag p] { [tag a] { [property color]:[keyword red]; } }");
MT('mixin',
"[def @mixin] [tag table-base] {}");
MT('number_without_semicolon',
"[tag p] {[property width]:[number 12]}",
"[tag a] {[property color]:[keyword red];}");
MT('atom_in_nested_block',
"[tag p] { [tag a] { [property color]:[atom #000]; } }");
MT('interpolation_in_property',
"[tag foo] { #{[variable-2 $hello]}:[number 2]; }");
MT('interpolation_in_selector',
"[tag foo]#{[variable-2 $hello]} { [property color]:[atom #000]; }");
MT('interpolation_error',
"[tag foo]#{[variable foo]} { [property color]:[atom #000]; }");
MT("divide_operator",
"[tag foo] { [property width]:[number 4] [operator /] [number 2] }");
MT('nested_structure_with_id_selector',
"[tag p] { [builtin #hello] { [property color]:[keyword red]; } }");
MT('indent_mixin',
"[def @mixin] [tag container] (",
" [variable-2 $a]: [number 10],",
" [variable-2 $b]: [number 10])",
"{}");
MT('indent_nested',
"[tag foo] {",
" [tag bar] {",
" }",
"}");
MT('indent_parentheses',
"[tag foo] {",
" [property color]: [atom darken]([variable-2 $blue],",
" [number 9%]);",
"}");
MT('indent_vardef',
"[variable-2 $name]:",
" [string 'val'];",
"[tag tag] {",
" [tag inner] {",
" [property margin]: [number 3px];",
" }",
"}");
})();

209
web/public/codemirror/mode/css/test.js vendored Normal file
View File

@@ -0,0 +1,209 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "css");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
// Error, because "foobarhello" is neither a known type or property, but
// property was expected (after "and"), and it should be in parentheses.
MT("atMediaUnknownType",
"[def @media] [attribute screen] [keyword and] [error foobarhello] { }");
// Soft error, because "foobarhello" is not a known property or type.
MT("atMediaUnknownProperty",
"[def @media] [attribute screen] [keyword and] ([error foobarhello]) { }");
// Make sure nesting works with media queries
MT("atMediaMaxWidthNested",
"[def @media] [attribute screen] [keyword and] ([property max-width]: [number 25px]) { [tag foo] { } }");
MT("atMediaFeatureValueKeyword",
"[def @media] ([property orientation]: [keyword landscape]) { }");
MT("atMediaUnknownFeatureValueKeyword",
"[def @media] ([property orientation]: [error upsidedown]) { }");
MT("atMediaUppercase",
"[def @MEDIA] ([property orienTAtion]: [keyword landScape]) { }");
MT("tagSelector",
"[tag foo] { }");
MT("classSelector",
"[qualifier .foo-bar_hello] { }");
MT("idSelector",
"[builtin #foo] { [error #foo] }");
MT("tagSelectorUnclosed",
"[tag foo] { [property margin]: [number 0] } [tag bar] { }");
MT("tagStringNoQuotes",
"[tag foo] { [property font-family]: [variable hello] [variable world]; }");
MT("tagStringDouble",
"[tag foo] { [property font-family]: [string \"hello world\"]; }");
MT("tagStringSingle",
"[tag foo] { [property font-family]: [string 'hello world']; }");
MT("tagColorKeyword",
"[tag foo] {",
" [property color]: [keyword black];",
" [property color]: [keyword navy];",
" [property color]: [keyword yellow];",
"}");
MT("tagColorHex3",
"[tag foo] { [property background]: [atom #fff]; }");
MT("tagColorHex4",
"[tag foo] { [property background]: [atom #ffff]; }");
MT("tagColorHex6",
"[tag foo] { [property background]: [atom #ffffff]; }");
MT("tagColorHex8",
"[tag foo] { [property background]: [atom #ffffffff]; }");
MT("tagColorHex5Invalid",
"[tag foo] { [property background]: [atom&error #fffff]; }");
MT("tagColorHexInvalid",
"[tag foo] { [property background]: [atom&error #ffg]; }");
MT("tagNegativeNumber",
"[tag foo] { [property margin]: [number -5px]; }");
MT("tagPositiveNumber",
"[tag foo] { [property padding]: [number 5px]; }");
MT("tagVendor",
"[tag foo] { [meta -foo-][property box-sizing]: [meta -foo-][atom border-box]; }");
MT("tagBogusProperty",
"[tag foo] { [property&error barhelloworld]: [number 0]; }");
MT("tagTwoProperties",
"[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }");
MT("tagTwoPropertiesURL",
"[tag foo] { [property background]: [atom url]([string //example.com/foo.png]); [property padding]: [number 0]; }");
MT("indent_tagSelector",
"[tag strong], [tag em] {",
" [property background]: [atom rgba](",
" [number 255], [number 255], [number 0], [number .2]",
" );",
"}");
MT("indent_atMedia",
"[def @media] {",
" [tag foo] {",
" [property color]:",
" [keyword yellow];",
" }",
"}");
MT("indent_comma",
"[tag foo] {",
" [property font-family]: [variable verdana],",
" [atom sans-serif];",
"}");
MT("indent_parentheses",
"[tag foo]:[variable-3 before] {",
" [property background]: [atom url](",
"[string blahblah]",
"[string etc]",
"[string ]) [keyword !important];",
"}");
MT("font_face",
"[def @font-face] {",
" [property font-family]: [string 'myfont'];",
" [error nonsense]: [string 'abc'];",
" [property src]: [atom url]([string http://blah]),",
" [atom url]([string http://foo]);",
"}");
MT("empty_url",
"[def @import] [atom url]() [attribute screen];");
MT("parens",
"[qualifier .foo] {",
" [property background-image]: [variable fade]([atom #000], [number 20%]);",
" [property border-image]: [atom linear-gradient](",
" [atom to] [atom bottom],",
" [variable fade]([atom #000], [number 20%]) [number 0%],",
" [variable fade]([atom #000], [number 20%]) [number 100%]",
" );",
"}");
MT("css_variable",
":[variable-3 root] {",
" [variable-2 --main-color]: [atom #06c];",
"}",
"[tag h1][builtin #foo] {",
" [property color]: [atom var]([variable-2 --main-color]);",
"}");
MT("supports",
"[def @supports] ([keyword not] (([property text-align-last]: [atom justify]) [keyword or] ([meta -moz-][property text-align-last]: [atom justify])) {",
" [property text-align-last]: [atom justify];",
"}");
MT("document",
"[def @document] [tag url]([string http://blah]),",
" [tag url-prefix]([string https://]),",
" [tag domain]([string blah.com]),",
" [tag regexp]([string \".*blah.+\"]) {",
" [builtin #id] {",
" [property background-color]: [keyword white];",
" }",
" [tag foo] {",
" [property font-family]: [variable Verdana], [atom sans-serif];",
" }",
"}");
MT("document_url",
"[def @document] [tag url]([string http://blah]) { [qualifier .class] { } }");
MT("document_urlPrefix",
"[def @document] [tag url-prefix]([string https://]) { [builtin #id] { } }");
MT("document_domain",
"[def @document] [tag domain]([string blah.com]) { [tag foo] { } }");
MT("document_regexp",
"[def @document] [tag regexp]([string \".*blah.+\"]) { [builtin #id] { } }");
MT("counter-style",
"[def @counter-style] [variable binary] {",
" [property system]: [atom numeric];",
" [property symbols]: [number 0] [number 1];",
" [property suffix]: [string \".\"];",
" [property range]: [atom infinite];",
" [property speak-as]: [atom numeric];",
"}");
MT("counter-style-additive-symbols",
"[def @counter-style] [variable simple-roman] {",
" [property system]: [atom additive];",
" [property additive-symbols]: [number 10] [variable X], [number 5] [variable V], [number 1] [variable I];",
" [property range]: [number 1] [number 49];",
"}");
MT("counter-style-use",
"[tag ol][qualifier .roman] { [property list-style]: [variable simple-roman]; }");
MT("counter-style-symbols",
"[tag ol] { [property list-style]: [atom symbols]([atom cyclic] [string \"*\"] [string \"\\2020\"] [string \"\\2021\"] [string \"\\A7\"]); }");
MT("comment-does-not-disrupt",
"[def @font-face] [comment /* foo */] {",
" [property src]: [atom url]([string x]);",
" [property font-family]: [variable One];",
"}")
})();

223
web/public/codemirror/mode/d/d.js vendored Normal file
View File

@@ -0,0 +1,223 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("d", function(config, parserConfig) {
var indentUnit = config.indentUnit,
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
keywords = parserConfig.keywords || {},
builtin = parserConfig.builtin || {},
blockKeywords = parserConfig.blockKeywords || {},
atoms = parserConfig.atoms || {},
hooks = parserConfig.hooks || {},
multiLineStrings = parserConfig.multiLineStrings;
var isOperatorChar = /[+\-*&%=<>!?|\/]/;
var curPunc;
function tokenBase(stream, state) {
var ch = stream.next();
if (hooks[ch]) {
var result = hooks[ch](stream, state);
if (result !== false) return result;
}
if (ch == '"' || ch == "'" || ch == "`") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
curPunc = ch;
return null;
}
if (/\d/.test(ch)) {
stream.eatWhile(/[\w\.]/);
return "number";
}
if (ch == "/") {
if (stream.eat("+")) {
state.tokenize = tokenNestedComment;
return tokenNestedComment(stream, state);
}
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
}
if (stream.eat("/")) {
stream.skipToEnd();
return "comment";
}
}
if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return "operator";
}
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
var cur = stream.current();
if (keywords.propertyIsEnumerable(cur)) {
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
return "keyword";
}
if (builtin.propertyIsEnumerable(cur)) {
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
return "builtin";
}
if (atoms.propertyIsEnumerable(cur)) return "atom";
return "variable";
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, next, end = false;
while ((next = stream.next()) != null) {
if (next == quote && !escaped) {end = true; break;}
escaped = !escaped && next == "\\";
}
if (end || !(escaped || multiLineStrings))
state.tokenize = null;
return "string";
};
}
function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = null;
break;
}
maybeEnd = (ch == "*");
}
return "comment";
}
function tokenNestedComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = null;
break;
}
maybeEnd = (ch == "+");
}
return "comment";
}
function Context(indented, column, type, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.align = align;
this.prev = prev;
}
function pushContext(state, col, type) {
var indent = state.indented;
if (state.context && state.context.type == "statement")
indent = state.context.indented;
return state.context = new Context(indent, col, type, null, state.context);
}
function popContext(state) {
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}
// Interface
return {
startState: function(basecolumn) {
return {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
indented: 0,
startOfLine: true
};
},
token: function(stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
}
if (stream.eatSpace()) return null;
curPunc = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment" || style == "meta") return style;
if (ctx.align == null) ctx.align = true;
if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}") {
while (ctx.type == "statement") ctx = popContext(state);
if (ctx.type == "}") ctx = popContext(state);
while (ctx.type == "statement") ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
else if (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || (ctx.type == "statement" && curPunc == "newstatement"))
pushContext(state, stream.column(), "statement");
state.startOfLine = false;
return style;
},
indent: function(state, textAfter) {
if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
var closing = firstChar == ctx.type;
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
else if (ctx.align) return ctx.column + (closing ? 0 : 1);
else return ctx.indented + (closing ? 0 : indentUnit);
},
electricChars: "{}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
blockCommentContinue: " * ",
lineComment: "//",
fold: "brace"
};
});
function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
var blockKeywords = "body catch class do else enum for foreach foreach_reverse if in interface mixin " +
"out scope struct switch try union unittest version while with";
CodeMirror.defineMIME("text/x-d", {
name: "d",
keywords: words("abstract alias align asm assert auto break case cast cdouble cent cfloat const continue " +
"debug default delegate delete deprecated export extern final finally function goto immutable " +
"import inout invariant is lazy macro module new nothrow override package pragma private " +
"protected public pure ref return shared short static super synchronized template this " +
"throw typedef typeid typeof volatile __FILE__ __LINE__ __gshared __traits __vector __parameters " +
blockKeywords),
blockKeywords: words(blockKeywords),
builtin: words("bool byte char creal dchar double float idouble ifloat int ireal long real short ubyte " +
"ucent uint ulong ushort wchar wstring void size_t sizediff_t"),
atoms: words("exit failure success true false null"),
hooks: {
"@": function(stream, _state) {
stream.eatWhile(/[\w\$_]/);
return "meta";
}
}
});
});

273
web/public/codemirror/mode/d/index.html vendored Normal file
View File

@@ -0,0 +1,273 @@
<!doctype html>
<title>CodeMirror: D 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="../../addon/edit/matchbrackets.js"></script>
<script src="d.js"></script>
<style>.CodeMirror {border: 2px inset #dee;}</style>
<div id=nav>
<a href="https://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="#">D</a>
</ul>
</div>
<article>
<h2>D mode</h2>
<form><textarea id="code" name="code">
/* D demo code // copied from phobos/sd/metastrings.d */
// Written in the D programming language.
/**
Templates with which to do compile-time manipulation of strings.
Macros:
WIKI = Phobos/StdMetastrings
Copyright: Copyright Digital Mars 2007 - 2009.
License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
Authors: $(WEB digitalmars.com, Walter Bright),
Don Clugston
Source: $(PHOBOSSRC std/_metastrings.d)
*/
/*
Copyright Digital Mars 2007 - 2009.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
module std.metastrings;
/**
Formats constants into a string at compile time. Analogous to $(XREF
string,format).
Parameters:
A = tuple of constants, which can be strings, characters, or integral
values.
Formats:
* The formats supported are %s for strings, and %%
* for the % character.
Example:
---
import std.metastrings;
import std.stdio;
void main()
{
string s = Format!("Arg %s = %s", "foo", 27);
writefln(s); // "Arg foo = 27"
}
* ---
*/
template Format(A...)
{
static if (A.length == 0)
enum Format = "";
else static if (is(typeof(A[0]) : const(char)[]))
enum Format = FormatString!(A[0], A[1..$]);
else
enum Format = toStringNow!(A[0]) ~ Format!(A[1..$]);
}
template FormatString(const(char)[] F, A...)
{
static if (F.length == 0)
enum FormatString = Format!(A);
else static if (F.length == 1)
enum FormatString = F[0] ~ Format!(A);
else static if (F[0..2] == "%s")
enum FormatString
= toStringNow!(A[0]) ~ FormatString!(F[2..$],A[1..$]);
else static if (F[0..2] == "%%")
enum FormatString = "%" ~ FormatString!(F[2..$],A);
else
{
static assert(F[0] != '%', "unrecognized format %" ~ F[1]);
enum FormatString = F[0] ~ FormatString!(F[1..$],A);
}
}
unittest
{
auto s = Format!("hel%slo", "world", -138, 'c', true);
assert(s == "helworldlo-138ctrue", "[" ~ s ~ "]");
}
/**
* Convert constant argument to a string.
*/
template toStringNow(ulong v)
{
static if (v < 10)
enum toStringNow = "" ~ cast(char)(v + '0');
else
enum toStringNow = toStringNow!(v / 10) ~ toStringNow!(v % 10);
}
unittest
{
static assert(toStringNow!(1uL << 62) == "4611686018427387904");
}
/// ditto
template toStringNow(long v)
{
static if (v < 0)
enum toStringNow = "-" ~ toStringNow!(cast(ulong) -v);
else
enum toStringNow = toStringNow!(cast(ulong) v);
}
unittest
{
static assert(toStringNow!(0x100000000) == "4294967296");
static assert(toStringNow!(-138L) == "-138");
}
/// ditto
template toStringNow(uint U)
{
enum toStringNow = toStringNow!(cast(ulong)U);
}
/// ditto
template toStringNow(int I)
{
enum toStringNow = toStringNow!(cast(long)I);
}
/// ditto
template toStringNow(bool B)
{
enum toStringNow = B ? "true" : "false";
}
/// ditto
template toStringNow(string S)
{
enum toStringNow = S;
}
/// ditto
template toStringNow(char C)
{
enum toStringNow = "" ~ C;
}
/********
* Parse unsigned integer literal from the start of string s.
* returns:
* .value = the integer literal as a string,
* .rest = the string following the integer literal
* Otherwise:
* .value = null,
* .rest = s
*/
template parseUinteger(const(char)[] s)
{
static if (s.length == 0)
{
enum value = "";
enum rest = "";
}
else static if (s[0] >= '0' && s[0] <= '9')
{
enum value = s[0] ~ parseUinteger!(s[1..$]).value;
enum rest = parseUinteger!(s[1..$]).rest;
}
else
{
enum value = "";
enum rest = s;
}
}
/********
Parse integer literal optionally preceded by $(D '-') from the start
of string $(D s).
Returns:
.value = the integer literal as a string,
.rest = the string following the integer literal
Otherwise:
.value = null,
.rest = s
*/
template parseInteger(const(char)[] s)
{
static if (s.length == 0)
{
enum value = "";
enum rest = "";
}
else static if (s[0] >= '0' && s[0] <= '9')
{
enum value = s[0] ~ parseUinteger!(s[1..$]).value;
enum rest = parseUinteger!(s[1..$]).rest;
}
else static if (s.length >= 2 &&
s[0] == '-' && s[1] >= '0' && s[1] <= '9')
{
enum value = s[0..2] ~ parseUinteger!(s[2..$]).value;
enum rest = parseUinteger!(s[2..$]).rest;
}
else
{
enum value = "";
enum rest = s;
}
}
unittest
{
assert(parseUinteger!("1234abc").value == "1234");
assert(parseUinteger!("1234abc").rest == "abc");
assert(parseInteger!("-1234abc").value == "-1234");
assert(parseInteger!("-1234abc").rest == "abc");
}
/**
Deprecated aliases held for backward compatibility.
*/
deprecated alias toStringNow ToString;
/// Ditto
deprecated alias parseUinteger ParseUinteger;
/// Ditto
deprecated alias parseUinteger ParseInteger;
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
indentUnit: 4,
mode: "text/x-d"
});
</script>
<p>Simple mode that handle D-Syntax (<a href="http://www.dlang.org">DLang Homepage</a>).</p>
<p><strong>MIME types defined:</strong> <code>text/x-d</code>
.</p>
</article>

11
web/public/codemirror/mode/d/test.js vendored Normal file
View File

@@ -0,0 +1,11 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "d");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
MT("nested_comments",
"[comment /+]","[comment comment]","[comment +/]","[variable void] [variable main](){}");
})();

157
web/public/codemirror/mode/dart/dart.js vendored Normal file
View File

@@ -0,0 +1,157 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../clike/clike"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../clike/clike"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var keywords = ("this super static final const abstract class extends external factory " +
"implements mixin get native set typedef with enum throw rethrow " +
"assert break case continue default in return new deferred async await covariant " +
"try catch finally do else for if switch while import library export " +
"part of show hide is as").split(" ");
var blockKeywords = "try catch finally do else for if switch while".split(" ");
var atoms = "true false null".split(" ");
var builtins = "void bool num int double dynamic var String".split(" ");
function set(words) {
var obj = {};
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
function pushInterpolationStack(state) {
(state.interpolationStack || (state.interpolationStack = [])).push(state.tokenize);
}
function popInterpolationStack(state) {
return (state.interpolationStack || (state.interpolationStack = [])).pop();
}
function sizeInterpolationStack(state) {
return state.interpolationStack ? state.interpolationStack.length : 0;
}
CodeMirror.defineMIME("application/dart", {
name: "clike",
keywords: set(keywords),
blockKeywords: set(blockKeywords),
builtin: set(builtins),
atoms: set(atoms),
hooks: {
"@": function(stream) {
stream.eatWhile(/[\w\$_\.]/);
return "meta";
},
// custom string handling to deal with triple-quoted strings and string interpolation
"'": function(stream, state) {
return tokenString("'", stream, state, false);
},
"\"": function(stream, state) {
return tokenString("\"", stream, state, false);
},
"r": function(stream, state) {
var peek = stream.peek();
if (peek == "'" || peek == "\"") {
return tokenString(stream.next(), stream, state, true);
}
return false;
},
"}": function(_stream, state) {
// "}" is end of interpolation, if interpolation stack is non-empty
if (sizeInterpolationStack(state) > 0) {
state.tokenize = popInterpolationStack(state);
return null;
}
return false;
},
"/": function(stream, state) {
if (!stream.eat("*")) return false
state.tokenize = tokenNestedComment(1)
return state.tokenize(stream, state)
}
}
});
function tokenString(quote, stream, state, raw) {
var tripleQuoted = false;
if (stream.eat(quote)) {
if (stream.eat(quote)) tripleQuoted = true;
else return "string"; //empty string
}
function tokenStringHelper(stream, state) {
var escaped = false;
while (!stream.eol()) {
if (!raw && !escaped && stream.peek() == "$") {
pushInterpolationStack(state);
state.tokenize = tokenInterpolation;
return "string";
}
var next = stream.next();
if (next == quote && !escaped && (!tripleQuoted || stream.match(quote + quote))) {
state.tokenize = null;
break;
}
escaped = !raw && !escaped && next == "\\";
}
return "string";
}
state.tokenize = tokenStringHelper;
return tokenStringHelper(stream, state);
}
function tokenInterpolation(stream, state) {
stream.eat("$");
if (stream.eat("{")) {
// let clike handle the content of ${...},
// we take over again when "}" appears (see hooks).
state.tokenize = null;
} else {
state.tokenize = tokenInterpolationIdentifier;
}
return null;
}
function tokenInterpolationIdentifier(stream, state) {
stream.eatWhile(/[\w_]/);
state.tokenize = popInterpolationStack(state);
return "variable";
}
function tokenNestedComment(depth) {
return function (stream, state) {
var ch
while (ch = stream.next()) {
if (ch == "*" && stream.eat("/")) {
if (depth == 1) {
state.tokenize = null
break
} else {
state.tokenize = tokenNestedComment(depth - 1)
return state.tokenize(stream, state)
}
} else if (ch == "/" && stream.eat("*")) {
state.tokenize = tokenNestedComment(depth + 1)
return state.tokenize(stream, state)
}
}
return "comment"
}
}
CodeMirror.registerHelper("hintWords", "application/dart", keywords.concat(atoms).concat(builtins));
// This is needed to make loading through meta.js work.
CodeMirror.defineMode("dart", function(conf) {
return CodeMirror.getMode(conf, "application/dart");
}, "clike");
});

View File

@@ -0,0 +1,71 @@
<!doctype html>
<title>CodeMirror: Dart 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="../clike/clike.js"></script>
<script src="dart.js"></script>
<style>.CodeMirror {border: 1px solid #dee;}</style>
<div id=nav>
<a href="https://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="#">Dart</a>
</ul>
</div>
<article>
<h2>Dart mode</h2>
<form>
<textarea id="code" name="code">
import 'dart:math' show Random;
void main() {
print(new Die(n: 12).roll());
}
// Define a class.
class Die {
// Define a class variable.
static Random shaker = new Random();
// Define instance variables.
int sides, value;
// Define a method using shorthand syntax.
String toString() => '$value';
// Define a constructor.
Die({int n: 6}) {
if (4 <= n && n <= 20) {
sides = n;
} else {
// Support for errors and exceptions.
throw new ArgumentError(/* */);
}
}
// Define an instance method.
int roll() {
return value = shaker.nextInt(sides) + 1;
}
}
</textarea>
</form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "application/dart"
});
</script>
</article>

View File

@@ -0,0 +1,356 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"),
require("../../addon/mode/overlay"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
"../../addon/mode/overlay"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("django:inner", function() {
var keywords = ["block", "endblock", "for", "endfor", "true", "false", "filter", "endfilter",
"loop", "none", "self", "super", "if", "elif", "endif", "as", "else", "import",
"with", "endwith", "without", "context", "ifequal", "endifequal", "ifnotequal",
"endifnotequal", "extends", "include", "load", "comment", "endcomment",
"empty", "url", "static", "trans", "blocktrans", "endblocktrans", "now",
"regroup", "lorem", "ifchanged", "endifchanged", "firstof", "debug", "cycle",
"csrf_token", "autoescape", "endautoescape", "spaceless", "endspaceless",
"ssi", "templatetag", "verbatim", "endverbatim", "widthratio"],
filters = ["add", "addslashes", "capfirst", "center", "cut", "date",
"default", "default_if_none", "dictsort",
"dictsortreversed", "divisibleby", "escape", "escapejs",
"filesizeformat", "first", "floatformat", "force_escape",
"get_digit", "iriencode", "join", "last", "length",
"length_is", "linebreaks", "linebreaksbr", "linenumbers",
"ljust", "lower", "make_list", "phone2numeric", "pluralize",
"pprint", "random", "removetags", "rjust", "safe",
"safeseq", "slice", "slugify", "stringformat", "striptags",
"time", "timesince", "timeuntil", "title", "truncatechars",
"truncatechars_html", "truncatewords", "truncatewords_html",
"unordered_list", "upper", "urlencode", "urlize",
"urlizetrunc", "wordcount", "wordwrap", "yesno"],
operators = ["==", "!=", "<", ">", "<=", ">="],
wordOperators = ["in", "not", "or", "and"];
keywords = new RegExp("^\\b(" + keywords.join("|") + ")\\b");
filters = new RegExp("^\\b(" + filters.join("|") + ")\\b");
operators = new RegExp("^\\b(" + operators.join("|") + ")\\b");
wordOperators = new RegExp("^\\b(" + wordOperators.join("|") + ")\\b");
// We have to return "null" instead of null, in order to avoid string
// styling as the default, when using Django templates inside HTML
// element attributes
function tokenBase (stream, state) {
// Attempt to identify a variable, template or comment tag respectively
if (stream.match("{{")) {
state.tokenize = inVariable;
return "tag";
} else if (stream.match("{%")) {
state.tokenize = inTag;
return "tag";
} else if (stream.match("{#")) {
state.tokenize = inComment;
return "comment";
}
// Ignore completely any stream series that do not match the
// Django template opening tags.
while (stream.next() != null && !stream.match(/\{[{%#]/, false)) {}
return null;
}
// A string can be included in either single or double quotes (this is
// the delimiter). Mark everything as a string until the start delimiter
// occurs again.
function inString (delimiter, previousTokenizer) {
return function (stream, state) {
if (!state.escapeNext && stream.eat(delimiter)) {
state.tokenize = previousTokenizer;
} else {
if (state.escapeNext) {
state.escapeNext = false;
}
var ch = stream.next();
// Take into account the backslash for escaping characters, such as
// the string delimiter.
if (ch == "\\") {
state.escapeNext = true;
}
}
return "string";
};
}
// Apply Django template variable syntax highlighting
function inVariable (stream, state) {
// Attempt to match a dot that precedes a property
if (state.waitDot) {
state.waitDot = false;
if (stream.peek() != ".") {
return "null";
}
// Dot followed by a non-word character should be considered an error.
if (stream.match(/\.\W+/)) {
return "error";
} else if (stream.eat(".")) {
state.waitProperty = true;
return "null";
} else {
throw Error ("Unexpected error while waiting for property.");
}
}
// Attempt to match a pipe that precedes a filter
if (state.waitPipe) {
state.waitPipe = false;
if (stream.peek() != "|") {
return "null";
}
// Pipe followed by a non-word character should be considered an error.
if (stream.match(/\.\W+/)) {
return "error";
} else if (stream.eat("|")) {
state.waitFilter = true;
return "null";
} else {
throw Error ("Unexpected error while waiting for filter.");
}
}
// Highlight properties
if (state.waitProperty) {
state.waitProperty = false;
if (stream.match(/\b(\w+)\b/)) {
state.waitDot = true; // A property can be followed by another property
state.waitPipe = true; // A property can be followed by a filter
return "property";
}
}
// Highlight filters
if (state.waitFilter) {
state.waitFilter = false;
if (stream.match(filters)) {
return "variable-2";
}
}
// Ignore all white spaces
if (stream.eatSpace()) {
state.waitProperty = false;
return "null";
}
// Identify numbers
if (stream.match(/\b\d+(\.\d+)?\b/)) {
return "number";
}
// Identify strings
if (stream.match("'")) {
state.tokenize = inString("'", state.tokenize);
return "string";
} else if (stream.match('"')) {
state.tokenize = inString('"', state.tokenize);
return "string";
}
// Attempt to find the variable
if (stream.match(/\b(\w+)\b/) && !state.foundVariable) {
state.waitDot = true;
state.waitPipe = true; // A property can be followed by a filter
return "variable";
}
// If found closing tag reset
if (stream.match("}}")) {
state.waitProperty = null;
state.waitFilter = null;
state.waitDot = null;
state.waitPipe = null;
state.tokenize = tokenBase;
return "tag";
}
// If nothing was found, advance to the next character
stream.next();
return "null";
}
function inTag (stream, state) {
// Attempt to match a dot that precedes a property
if (state.waitDot) {
state.waitDot = false;
if (stream.peek() != ".") {
return "null";
}
// Dot followed by a non-word character should be considered an error.
if (stream.match(/\.\W+/)) {
return "error";
} else if (stream.eat(".")) {
state.waitProperty = true;
return "null";
} else {
throw Error ("Unexpected error while waiting for property.");
}
}
// Attempt to match a pipe that precedes a filter
if (state.waitPipe) {
state.waitPipe = false;
if (stream.peek() != "|") {
return "null";
}
// Pipe followed by a non-word character should be considered an error.
if (stream.match(/\.\W+/)) {
return "error";
} else if (stream.eat("|")) {
state.waitFilter = true;
return "null";
} else {
throw Error ("Unexpected error while waiting for filter.");
}
}
// Highlight properties
if (state.waitProperty) {
state.waitProperty = false;
if (stream.match(/\b(\w+)\b/)) {
state.waitDot = true; // A property can be followed by another property
state.waitPipe = true; // A property can be followed by a filter
return "property";
}
}
// Highlight filters
if (state.waitFilter) {
state.waitFilter = false;
if (stream.match(filters)) {
return "variable-2";
}
}
// Ignore all white spaces
if (stream.eatSpace()) {
state.waitProperty = false;
return "null";
}
// Identify numbers
if (stream.match(/\b\d+(\.\d+)?\b/)) {
return "number";
}
// Identify strings
if (stream.match("'")) {
state.tokenize = inString("'", state.tokenize);
return "string";
} else if (stream.match('"')) {
state.tokenize = inString('"', state.tokenize);
return "string";
}
// Attempt to match an operator
if (stream.match(operators)) {
return "operator";
}
// Attempt to match a word operator
if (stream.match(wordOperators)) {
return "keyword";
}
// Attempt to match a keyword
var keywordMatch = stream.match(keywords);
if (keywordMatch) {
if (keywordMatch[0] == "comment") {
state.blockCommentTag = true;
}
return "keyword";
}
// Attempt to match a variable
if (stream.match(/\b(\w+)\b/)) {
state.waitDot = true;
state.waitPipe = true; // A property can be followed by a filter
return "variable";
}
// If found closing tag reset
if (stream.match("%}")) {
state.waitProperty = null;
state.waitFilter = null;
state.waitDot = null;
state.waitPipe = null;
// If the tag that closes is a block comment tag, we want to mark the
// following code as comment, until the tag closes.
if (state.blockCommentTag) {
state.blockCommentTag = false; // Release the "lock"
state.tokenize = inBlockComment;
} else {
state.tokenize = tokenBase;
}
return "tag";
}
// If nothing was found, advance to the next character
stream.next();
return "null";
}
// Mark everything as comment inside the tag and the tag itself.
function inComment (stream, state) {
if (stream.match(/^.*?#\}/)) state.tokenize = tokenBase
else stream.skipToEnd()
return "comment";
}
// Mark everything as a comment until the `blockcomment` tag closes.
function inBlockComment (stream, state) {
if (stream.match(/\{%\s*endcomment\s*%\}/, false)) {
state.tokenize = inTag;
stream.match("{%");
return "tag";
} else {
stream.next();
return "comment";
}
}
return {
startState: function () {
return {tokenize: tokenBase};
},
token: function (stream, state) {
return state.tokenize(stream, state);
},
blockCommentStart: "{% comment %}",
blockCommentEnd: "{% endcomment %}"
};
});
CodeMirror.defineMode("django", function(config) {
var htmlBase = CodeMirror.getMode(config, "text/html");
var djangoInner = CodeMirror.getMode(config, "django:inner");
return CodeMirror.overlayMode(htmlBase, djangoInner);
});
CodeMirror.defineMIME("text/x-django", "django");
});

View File

@@ -0,0 +1,73 @@
<!doctype html>
<title>CodeMirror: Django template mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/mdn-like.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/mode/overlay.js"></script>
<script src="../xml/xml.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="django.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">Django</a>
</ul>
</div>
<article>
<h2>Django template mode</h2>
<form><textarea id="code" name="code">
<!doctype html>
<html>
<head>
<title>My Django web application</title>
</head>
<body>
<h1>
{{ page.title|capfirst }}
</h1>
<ul class="my-list">
{# traverse a list of items and produce links to their views. #}
{% for item in items %}
<li>
<a href="{% url 'item_view' item.name|slugify %}">
{{ item.name }}
</a>
</li>
{% empty %}
<li>You have no items in your list.</li>
{% endfor %}
</ul>
{% comment "this is a forgotten footer" %}
<footer></footer>
{% endcomment %}
</body>
</html>
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "django",
indentUnit: 2,
indentWithTabs: true,
theme: "mdn-like"
});
</script>
<p>Mode for HTML with embedded Django template markup.</p>
<p><strong>MIME types defined:</strong> <code>text/x-django</code></p>
</article>

View File

@@ -0,0 +1,211 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../../addon/mode/simple"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var from = "from";
var fromRegex = new RegExp("^(\\s*)\\b(" + from + ")\\b", "i");
var shells = ["run", "cmd", "entrypoint", "shell"];
var shellsAsArrayRegex = new RegExp("^(\\s*)(" + shells.join('|') + ")(\\s+\\[)", "i");
var expose = "expose";
var exposeRegex = new RegExp("^(\\s*)(" + expose + ")(\\s+)", "i");
var others = [
"arg", "from", "maintainer", "label", "env",
"add", "copy", "volume", "user",
"workdir", "onbuild", "stopsignal", "healthcheck", "shell"
];
// Collect all Dockerfile directives
var instructions = [from, expose].concat(shells).concat(others),
instructionRegex = "(" + instructions.join('|') + ")",
instructionOnlyLine = new RegExp("^(\\s*)" + instructionRegex + "(\\s*)(#.*)?$", "i"),
instructionWithArguments = new RegExp("^(\\s*)" + instructionRegex + "(\\s+)", "i");
CodeMirror.defineSimpleMode("dockerfile", {
start: [
// Block comment: This is a line starting with a comment
{
regex: /^\s*#.*$/,
sol: true,
token: "comment"
},
{
regex: fromRegex,
token: [null, "keyword"],
sol: true,
next: "from"
},
// Highlight an instruction without any arguments (for convenience)
{
regex: instructionOnlyLine,
token: [null, "keyword", null, "error"],
sol: true
},
{
regex: shellsAsArrayRegex,
token: [null, "keyword", null],
sol: true,
next: "array"
},
{
regex: exposeRegex,
token: [null, "keyword", null],
sol: true,
next: "expose"
},
// Highlight an instruction followed by arguments
{
regex: instructionWithArguments,
token: [null, "keyword", null],
sol: true,
next: "arguments"
},
{
regex: /./,
token: null
}
],
from: [
{
regex: /\s*$/,
token: null,
next: "start"
},
{
// Line comment without instruction arguments is an error
regex: /(\s*)(#.*)$/,
token: [null, "error"],
next: "start"
},
{
regex: /(\s*\S+\s+)(as)/i,
token: [null, "keyword"],
next: "start"
},
// Fail safe return to start
{
token: null,
next: "start"
}
],
single: [
{
regex: /(?:[^\\']|\\.)/,
token: "string"
},
{
regex: /'/,
token: "string",
pop: true
}
],
double: [
{
regex: /(?:[^\\"]|\\.)/,
token: "string"
},
{
regex: /"/,
token: "string",
pop: true
}
],
array: [
{
regex: /\]/,
token: null,
next: "start"
},
{
regex: /"(?:[^\\"]|\\.)*"?/,
token: "string"
}
],
expose: [
{
regex: /\d+$/,
token: "number",
next: "start"
},
{
regex: /[^\d]+$/,
token: null,
next: "start"
},
{
regex: /\d+/,
token: "number"
},
{
regex: /[^\d]+/,
token: null
},
// Fail safe return to start
{
token: null,
next: "start"
}
],
arguments: [
{
regex: /^\s*#.*$/,
sol: true,
token: "comment"
},
{
regex: /"(?:[^\\"]|\\.)*"?$/,
token: "string",
next: "start"
},
{
regex: /"/,
token: "string",
push: "double"
},
{
regex: /'(?:[^\\']|\\.)*'?$/,
token: "string",
next: "start"
},
{
regex: /'/,
token: "string",
push: "single"
},
{
regex: /[^#"']+[\\`]$/,
token: null
},
{
regex: /[^#"']+$/,
token: null,
next: "start"
},
{
regex: /[^#"']+/,
token: null
},
// Fail safe return to start
{
token: null,
next: "start"
}
],
meta: {
lineComment: "#"
}
});
CodeMirror.defineMIME("text/x-dockerfile", "dockerfile");
});

View File

@@ -0,0 +1,73 @@
<!doctype html>
<title>CodeMirror: Dockerfile 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="../../addon/mode/simple.js"></script>
<script src="dockerfile.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">Dockerfile</a>
</ul>
</div>
<article>
<h2>Dockerfile mode</h2>
<form><textarea id="code" name="code"># Install Ghost blogging platform and run development environment
#
# VERSION 1.0.0
FROM ubuntu:12.10
MAINTAINER Amer Grgic "amer@livebyt.es"
WORKDIR /data/ghost
# Install dependencies for nginx installation
RUN apt-get update
RUN apt-get install -y python g++ make software-properties-common --force-yes
RUN add-apt-repository ppa:chris-lea/node.js
RUN apt-get update
# Install unzip
RUN apt-get install -y unzip
# Install curl
RUN apt-get install -y curl
# Install nodejs & npm
RUN apt-get install -y rlwrap
RUN apt-get install -y nodejs
# Download Ghost v0.4.1
RUN curl -L https://ghost.org/zip/ghost-latest.zip -o /tmp/ghost.zip
# Unzip Ghost zip to /data/ghost
RUN unzip -uo /tmp/ghost.zip -d /data/ghost
# Add custom config js to /data/ghost
ADD ./config.example.js /data/ghost/config.js
# Install Ghost with NPM
RUN cd /data/ghost/ && npm install --production
# Expose port 2368
EXPOSE 2368
# Run Ghost
CMD ["npm","start"]
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "dockerfile"
});
</script>
<p>Dockerfile syntax highlighting for CodeMirror. Depends on
the <a href="../../demo/simplemode.html">simplemode</a> addon.</p>
<p><strong>MIME types defined:</strong> <code>text/x-dockerfile</code></p>
</article>

View File

@@ -0,0 +1,128 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-dockerfile");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
MT("simple_nodejs_dockerfile",
"[keyword FROM] node:carbon",
"[comment # Create app directory]",
"[keyword WORKDIR] /usr/src/app",
"[comment # Install app dependencies]",
"[comment # A wildcard is used to ensure both package.json AND package-lock.json are copied]",
"[comment # where available (npm@5+)]",
"[keyword COPY] package*.json ./",
"[keyword RUN] npm install",
"[keyword COPY] . .",
"[keyword EXPOSE] [number 8080] [number 3000]",
"[keyword ENV] NODE_ENV development",
"[keyword CMD] [[ [string \"npm\"], [string \"start\"] ]]");
// Ideally the last space should not be highlighted.
MT("instruction_without_args_1",
"[keyword CMD] ");
MT("instruction_without_args_2",
"[comment # An instruction without args...]",
"[keyword ARG] [error #...is an error]");
MT("multiline",
"[keyword RUN] apt-get update && apt-get install -y \\",
" mercurial \\",
" subversion \\",
" && apt-get clean \\",
" && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*");
MT("from_comment",
" [keyword FROM] debian:stretch # I tend to use stable as that is more stable",
" [keyword FROM] debian:stretch [keyword AS] stable # I am even more stable",
" [keyword FROM] [error # this is an error]");
MT("from_as",
"[keyword FROM] golang:1.9.2-alpine3.6 [keyword AS] build",
"[keyword COPY] --from=build /bin/project /bin/project",
"[keyword ENTRYPOINT] [[ [string \"/bin/project\"] ]]",
"[keyword CMD] [[ [string \"--help\"] ]]");
MT("arg",
"[keyword ARG] VERSION=latest",
"[keyword FROM] busybox:$VERSION",
"[keyword ARG] VERSION",
"[keyword RUN] echo $VERSION > image_version");
MT("label",
"[keyword LABEL] com.example.label-with-value=[string \"foo\"]");
MT("label_multiline",
"[keyword LABEL] description=[string \"This text illustrates ]\\",
"[string that label-values can span multiple lines.\"]");
MT("maintainer",
"[keyword MAINTAINER] Foo Bar [string \"foo@bar.com\"] ",
"[keyword MAINTAINER] Bar Baz <bar@baz.com>");
MT("env",
"[keyword ENV] BUNDLE_PATH=[string \"$GEM_HOME\"] \\",
" BUNDLE_APP_CONFIG=[string \"$GEM_HOME\"]");
MT("verify_keyword",
"[keyword RUN] add-apt-repository ppa:chris-lea/node.js");
MT("scripts",
"[comment # Set an entrypoint, to automatically install node modules]",
"[keyword ENTRYPOINT] [[ [string \"/bin/bash\"], [string \"-c\"], [string \"if [[ ! -d node_modules ]]; then npm install; fi; exec \\\"${@:0}\\\";\"] ]]",
"[keyword CMD] npm start",
"[keyword RUN] npm run build && \\",
"[comment # a comment between the shell commands]",
" npm run test");
MT("strings_single",
"[keyword FROM] buildpack-deps:stretch",
"[keyword RUN] { \\",
" echo [string 'install: --no-document']; \\",
" echo [string 'update: --no-document']; \\",
" } >> /usr/local/etc/gemrc");
MT("strings_single_multiline",
"[keyword RUN] set -ex \\",
" \\",
" && buildDeps=[string ' ]\\",
"[string bison ]\\",
"[string dpkg-dev ]\\",
"[string libgdbm-dev ]\\",
"[string ruby ]\\",
"[string '] \\",
" && apt-get update");
MT("strings_single_multiline_2",
"[keyword RUN] echo [string 'say \\' ]\\",
"[string it works'] ");
MT("strings_double",
"[keyword RUN] apt-get install -y --no-install-recommends $buildDeps \\",
" \\",
" && wget -O ruby.tar.xz [string \"https://cache.ruby-lang.org/pub/ruby/${RUBY_MAJOR%-rc}/ruby-$RUBY_VERSION.tar.xz\"] \\",
" && echo [string \"$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz\"] | sha256sum -c - ");
MT("strings_double_multiline",
"[keyword RUN] echo [string \"say \\\" ]\\",
"[string it works\"] ");
MT("escape",
"[comment # escape=`]",
"[keyword FROM] microsoft/windowsservercore",
"[keyword RUN] powershell.exe -Command `",
" $ErrorActionPreference = [string 'Stop']; `",
" wget https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile c:\python-3.5.1.exe ; `",
" Start-Process c:\python-3.5.1.exe -ArgumentList [string '/quiet InstallAllUsers=1 PrependPath=1'] -Wait ; `",
" Remove-Item c:\python-3.5.1.exe -Force)");
MT("escape_strings",
"[comment # escape=`]",
"[keyword FROM] python:3.6-windowsservercore [keyword AS] python",
"[keyword RUN] $env:PATH = [string 'C:\\Python;C:\\Python\\Scripts;{0}'] -f $env:PATH ; `",
// It should not consider \' as escaped.
// " Set-ItemProperty -Path [string 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\\'] -Name Path -Value $env:PATH ;");
" Set-ItemProperty -Path [string 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\\' -Name Path -Value $env:PATH ;]");
})();

142
web/public/codemirror/mode/dtd/dtd.js vendored Normal file
View File

@@ -0,0 +1,142 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
/*
DTD mode
Ported to CodeMirror by Peter Kroon <plakroon@gmail.com>
Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues
GitHub: @peterkroon
*/
(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("dtd", function(config) {
var indentUnit = config.indentUnit, type;
function ret(style, tp) {type = tp; return style;}
function tokenBase(stream, state) {
var ch = stream.next();
if (ch == "<" && stream.eat("!") ) {
if (stream.eatWhile(/[\-]/)) {
state.tokenize = tokenSGMLComment;
return tokenSGMLComment(stream, state);
} else if (stream.eatWhile(/[\w]/)) return ret("keyword", "doindent");
} else if (ch == "<" && stream.eat("?")) { //xml declaration
state.tokenize = inBlock("meta", "?>");
return ret("meta", ch);
} else if (ch == "#" && stream.eatWhile(/[\w]/)) return ret("atom", "tag");
else if (ch == "|") return ret("keyword", "seperator");
else if (ch.match(/[\(\)\[\]\-\.,\+\?>]/)) return ret(null, ch);//if(ch === ">") return ret(null, "endtag"); else
else if (ch.match(/[\[\]]/)) return ret("rule", ch);
else if (ch == "\"" || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
} else if (stream.eatWhile(/[a-zA-Z\?\+\d]/)) {
var sc = stream.current();
if( sc.substr(sc.length-1,sc.length).match(/\?|\+/) !== null )stream.backUp(1);
return ret("tag", "tag");
} else if (ch == "%" || ch == "*" ) return ret("number", "number");
else {
stream.eatWhile(/[\w\\\-_%.{,]/);
return ret(null, null);
}
}
function tokenSGMLComment(stream, state) {
var dashes = 0, ch;
while ((ch = stream.next()) != null) {
if (dashes >= 2 && ch == ">") {
state.tokenize = tokenBase;
break;
}
dashes = (ch == "-") ? dashes + 1 : 0;
}
return ret("comment", "comment");
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, ch;
while ((ch = stream.next()) != null) {
if (ch == quote && !escaped) {
state.tokenize = tokenBase;
break;
}
escaped = !escaped && ch == "\\";
}
return ret("string", "tag");
};
}
function inBlock(style, terminator) {
return function(stream, state) {
while (!stream.eol()) {
if (stream.match(terminator)) {
state.tokenize = tokenBase;
break;
}
stream.next();
}
return style;
};
}
return {
startState: function(base) {
return {tokenize: tokenBase,
baseIndent: base || 0,
stack: []};
},
token: function(stream, state) {
if (stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
var context = state.stack[state.stack.length-1];
if (stream.current() == "[" || type === "doindent" || type == "[") state.stack.push("rule");
else if (type === "endtag") state.stack[state.stack.length-1] = "endtag";
else if (stream.current() == "]" || type == "]" || (type == ">" && context == "rule")) state.stack.pop();
else if (type == "[") state.stack.push("[");
return style;
},
indent: function(state, textAfter) {
var n = state.stack.length;
if( textAfter.match(/\]\s+|\]/) )n=n-1;
else if(textAfter.substr(textAfter.length-1, textAfter.length) === ">"){
if(textAfter.substr(0,1) === "<") {}
else if( type == "doindent" && textAfter.length > 1 ) {}
else if( type == "doindent")n--;
else if( type == ">" && textAfter.length > 1) {}
else if( type == "tag" && textAfter !== ">") {}
else if( type == "tag" && state.stack[state.stack.length-1] == "rule")n--;
else if( type == "tag")n++;
else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule" && type === ">")n--;
else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule") {}
else if( textAfter.substr(0,1) !== "<" && textAfter.substr(0,1) === ">" )n=n-1;
else if( textAfter === ">") {}
else n=n-1;
//over rule them all
if(type == null || type == "]")n--;
}
return state.baseIndent + n * indentUnit;
},
electricChars: "]>"
};
});
CodeMirror.defineMIME("application/xml-dtd", "dtd");
});

View File

@@ -0,0 +1,89 @@
<!doctype html>
<title>CodeMirror: DTD 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="dtd.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">DTD</a>
</ul>
</div>
<article>
<h2>DTD mode</h2>
<form><textarea id="code" name="code"><?xml version="1.0" encoding="UTF-8"?>
<!ATTLIST title
xmlns CDATA #FIXED "http://docbook.org/ns/docbook"
role CDATA #IMPLIED
%db.common.attributes;
%db.common.linking.attributes;
>
<!--
Try: http://docbook.org/xml/5.0/dtd/docbook.dtd
-->
<!DOCTYPE xsl:stylesheet
[
<!ENTITY nbsp "&amp;#160;">
<!ENTITY copy "&amp;#169;">
<!ENTITY reg "&amp;#174;">
<!ENTITY trade "&amp;#8482;">
<!ENTITY mdash "&amp;#8212;">
<!ENTITY ldquo "&amp;#8220;">
<!ENTITY rdquo "&amp;#8221;">
<!ENTITY pound "&amp;#163;">
<!ENTITY yen "&amp;#165;">
<!ENTITY euro "&amp;#8364;">
<!ENTITY mathml "http://www.w3.org/1998/Math/MathML">
]
>
<!ELEMENT title (#PCDATA|inlinemediaobject|remark|superscript|subscript|xref|link|olink|anchor|biblioref|alt|annotation|indexterm|abbrev|acronym|date|emphasis|footnote|footnoteref|foreignphrase|phrase|quote|wordasword|firstterm|glossterm|coref|trademark|productnumber|productname|database|application|hardware|citation|citerefentry|citetitle|citebiblioid|author|person|personname|org|orgname|editor|jobtitle|replaceable|package|parameter|termdef|nonterminal|systemitem|option|optional|property|inlineequation|tag|markup|token|symbol|literal|code|constant|email|uri|guiicon|guibutton|guimenuitem|guimenu|guisubmenu|guilabel|menuchoice|mousebutton|keycombo|keycap|keycode|keysym|shortcut|accel|prompt|envar|filename|command|computeroutput|userinput|function|varname|returnvalue|type|classname|exceptionname|interfacename|methodname|modifier|initializer|ooclass|ooexception|oointerface|errorcode|errortext|errorname|errortype)*>
<!ENTITY % db.common.attributes "
xml:id ID #IMPLIED
version CDATA #IMPLIED
xml:lang CDATA #IMPLIED
xml:base CDATA #IMPLIED
remap CDATA #IMPLIED
xreflabel CDATA #IMPLIED
revisionflag (changed|added|deleted|off) #IMPLIED
dir (ltr|rtl|lro|rlo) #IMPLIED
arch CDATA #IMPLIED
audience CDATA #IMPLIED
condition CDATA #IMPLIED
conformance CDATA #IMPLIED
os CDATA #IMPLIED
revision CDATA #IMPLIED
security CDATA #IMPLIED
userlevel CDATA #IMPLIED
vendor CDATA #IMPLIED
wordsize CDATA #IMPLIED
annotations CDATA #IMPLIED
"></textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: {name: "dtd", alignCDATA: true},
lineNumbers: true,
lineWrapping: true
});
</script>
<p><strong>MIME types defined:</strong> <code>application/xml-dtd</code>.</p>
</article>

View File

@@ -0,0 +1,619 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
/*jshint unused:true, eqnull:true, curly:true, bitwise:true */
/*jshint undef:true, latedef:true, trailing:true */
/*global CodeMirror:true */
// erlang mode.
// tokenizer -> token types -> CodeMirror styles
// tokenizer maintains a parse stack
// indenter uses the parse stack
// TODO indenter:
// bit syntax
// old guard/bif/conversion clashes (e.g. "float/1")
// type/spec/opaque
(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.defineMIME("text/x-erlang", "erlang");
CodeMirror.defineMode("erlang", function(cmCfg) {
"use strict";
/////////////////////////////////////////////////////////////////////////////
// constants
var typeWords = [
"-type", "-spec", "-export_type", "-opaque"];
var keywordWords = [
"after","begin","catch","case","cond","end","fun","if",
"let","of","query","receive","try","when"];
var separatorRE = /[\->,;]/;
var separatorWords = [
"->",";",","];
var operatorAtomWords = [
"and","andalso","band","bnot","bor","bsl","bsr","bxor",
"div","not","or","orelse","rem","xor"];
var operatorSymbolRE = /[\+\-\*\/<>=\|:!]/;
var operatorSymbolWords = [
"=","+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-","!"];
var openParenRE = /[<\(\[\{]/;
var openParenWords = [
"<<","(","[","{"];
var closeParenRE = /[>\)\]\}]/;
var closeParenWords = [
"}","]",")",">>"];
var guardWords = [
"is_atom","is_binary","is_bitstring","is_boolean","is_float",
"is_function","is_integer","is_list","is_number","is_pid",
"is_port","is_record","is_reference","is_tuple",
"atom","binary","bitstring","boolean","function","integer","list",
"number","pid","port","record","reference","tuple"];
var bifWords = [
"abs","adler32","adler32_combine","alive","apply","atom_to_binary",
"atom_to_list","binary_to_atom","binary_to_existing_atom",
"binary_to_list","binary_to_term","bit_size","bitstring_to_list",
"byte_size","check_process_code","contact_binary","crc32",
"crc32_combine","date","decode_packet","delete_module",
"disconnect_node","element","erase","exit","float","float_to_list",
"garbage_collect","get","get_keys","group_leader","halt","hd",
"integer_to_list","internal_bif","iolist_size","iolist_to_binary",
"is_alive","is_atom","is_binary","is_bitstring","is_boolean",
"is_float","is_function","is_integer","is_list","is_number","is_pid",
"is_port","is_process_alive","is_record","is_reference","is_tuple",
"length","link","list_to_atom","list_to_binary","list_to_bitstring",
"list_to_existing_atom","list_to_float","list_to_integer",
"list_to_pid","list_to_tuple","load_module","make_ref","module_loaded",
"monitor_node","node","node_link","node_unlink","nodes","notalive",
"now","open_port","pid_to_list","port_close","port_command",
"port_connect","port_control","pre_loaded","process_flag",
"process_info","processes","purge_module","put","register",
"registered","round","self","setelement","size","spawn","spawn_link",
"spawn_monitor","spawn_opt","split_binary","statistics",
"term_to_binary","time","throw","tl","trunc","tuple_size",
"tuple_to_list","unlink","unregister","whereis"];
// upper case: [A-Z] [Ø-Þ] [À-Ö]
// lower case: [a-z] [ß-ö] [ø-ÿ]
var anumRE = /[\w@Ø-ÞÀ-Öß-öø-ÿ]/;
var escapesRE =
/[0-7]{1,3}|[bdefnrstv\\"']|\^[a-zA-Z]|x[0-9a-zA-Z]{2}|x{[0-9a-zA-Z]+}/;
/////////////////////////////////////////////////////////////////////////////
// tokenizer
function tokenizer(stream,state) {
// in multi-line string
if (state.in_string) {
state.in_string = (!doubleQuote(stream));
return rval(state,stream,"string");
}
// in multi-line atom
if (state.in_atom) {
state.in_atom = (!singleQuote(stream));
return rval(state,stream,"atom");
}
// whitespace
if (stream.eatSpace()) {
return rval(state,stream,"whitespace");
}
// attributes and type specs
if (!peekToken(state) &&
stream.match(/-\s*[a-zß-öø-ÿ][\wØ-ÞÀ-Öß-öø-ÿ]*/)) {
if (is_member(stream.current(),typeWords)) {
return rval(state,stream,"type");
}else{
return rval(state,stream,"attribute");
}
}
var ch = stream.next();
// comment
if (ch == '%') {
stream.skipToEnd();
return rval(state,stream,"comment");
}
// colon
if (ch == ":") {
return rval(state,stream,"colon");
}
// macro
if (ch == '?') {
stream.eatSpace();
stream.eatWhile(anumRE);
return rval(state,stream,"macro");
}
// record
if (ch == "#") {
stream.eatSpace();
stream.eatWhile(anumRE);
return rval(state,stream,"record");
}
// dollar escape
if (ch == "$") {
if (stream.next() == "\\" && !stream.match(escapesRE)) {
return rval(state,stream,"error");
}
return rval(state,stream,"number");
}
// dot
if (ch == ".") {
return rval(state,stream,"dot");
}
// quoted atom
if (ch == '\'') {
if (!(state.in_atom = (!singleQuote(stream)))) {
if (stream.match(/\s*\/\s*[0-9]/,false)) {
stream.match(/\s*\/\s*[0-9]/,true);
return rval(state,stream,"fun"); // 'f'/0 style fun
}
if (stream.match(/\s*\(/,false) || stream.match(/\s*:/,false)) {
return rval(state,stream,"function");
}
}
return rval(state,stream,"atom");
}
// string
if (ch == '"') {
state.in_string = (!doubleQuote(stream));
return rval(state,stream,"string");
}
// variable
if (/[A-Z_Ø-ÞÀ-Ö]/.test(ch)) {
stream.eatWhile(anumRE);
return rval(state,stream,"variable");
}
// atom/keyword/BIF/function
if (/[a-z_ß-öø-ÿ]/.test(ch)) {
stream.eatWhile(anumRE);
if (stream.match(/\s*\/\s*[0-9]/,false)) {
stream.match(/\s*\/\s*[0-9]/,true);
return rval(state,stream,"fun"); // f/0 style fun
}
var w = stream.current();
if (is_member(w,keywordWords)) {
return rval(state,stream,"keyword");
}else if (is_member(w,operatorAtomWords)) {
return rval(state,stream,"operator");
}else if (stream.match(/\s*\(/,false)) {
// 'put' and 'erlang:put' are bifs, 'foo:put' is not
if (is_member(w,bifWords) &&
((peekToken(state).token != ":") ||
(peekToken(state,2).token == "erlang"))) {
return rval(state,stream,"builtin");
}else if (is_member(w,guardWords)) {
return rval(state,stream,"guard");
}else{
return rval(state,stream,"function");
}
}else if (lookahead(stream) == ":") {
if (w == "erlang") {
return rval(state,stream,"builtin");
} else {
return rval(state,stream,"function");
}
}else if (is_member(w,["true","false"])) {
return rval(state,stream,"boolean");
}else{
return rval(state,stream,"atom");
}
}
// number
var digitRE = /[0-9]/;
var radixRE = /[0-9a-zA-Z]/; // 36#zZ style int
if (digitRE.test(ch)) {
stream.eatWhile(digitRE);
if (stream.eat('#')) { // 36#aZ style integer
if (!stream.eatWhile(radixRE)) {
stream.backUp(1); //"36#" - syntax error
}
} else if (stream.eat('.')) { // float
if (!stream.eatWhile(digitRE)) {
stream.backUp(1); // "3." - probably end of function
} else {
if (stream.eat(/[eE]/)) { // float with exponent
if (stream.eat(/[-+]/)) {
if (!stream.eatWhile(digitRE)) {
stream.backUp(2); // "2e-" - syntax error
}
} else {
if (!stream.eatWhile(digitRE)) {
stream.backUp(1); // "2e" - syntax error
}
}
}
}
}
return rval(state,stream,"number"); // normal integer
}
// open parens
if (nongreedy(stream,openParenRE,openParenWords)) {
return rval(state,stream,"open_paren");
}
// close parens
if (nongreedy(stream,closeParenRE,closeParenWords)) {
return rval(state,stream,"close_paren");
}
// separators
if (greedy(stream,separatorRE,separatorWords)) {
return rval(state,stream,"separator");
}
// operators
if (greedy(stream,operatorSymbolRE,operatorSymbolWords)) {
return rval(state,stream,"operator");
}
return rval(state,stream,null);
}
/////////////////////////////////////////////////////////////////////////////
// utilities
function nongreedy(stream,re,words) {
if (stream.current().length == 1 && re.test(stream.current())) {
stream.backUp(1);
while (re.test(stream.peek())) {
stream.next();
if (is_member(stream.current(),words)) {
return true;
}
}
stream.backUp(stream.current().length-1);
}
return false;
}
function greedy(stream,re,words) {
if (stream.current().length == 1 && re.test(stream.current())) {
while (re.test(stream.peek())) {
stream.next();
}
while (0 < stream.current().length) {
if (is_member(stream.current(),words)) {
return true;
}else{
stream.backUp(1);
}
}
stream.next();
}
return false;
}
function doubleQuote(stream) {
return quote(stream, '"', '\\');
}
function singleQuote(stream) {
return quote(stream,'\'','\\');
}
function quote(stream,quoteChar,escapeChar) {
while (!stream.eol()) {
var ch = stream.next();
if (ch == quoteChar) {
return true;
}else if (ch == escapeChar) {
stream.next();
}
}
return false;
}
function lookahead(stream) {
var m = stream.match(/([\n\s]+|%[^\n]*\n)*(.)/,false);
return m ? m.pop() : "";
}
function is_member(element,list) {
return (-1 < list.indexOf(element));
}
function rval(state,stream,type) {
// parse stack
pushToken(state,realToken(type,stream));
// map erlang token type to CodeMirror style class
// erlang -> CodeMirror tag
switch (type) {
case "atom": return "atom";
case "attribute": return "attribute";
case "boolean": return "atom";
case "builtin": return "builtin";
case "close_paren": return null;
case "colon": return null;
case "comment": return "comment";
case "dot": return null;
case "error": return "error";
case "fun": return "meta";
case "function": return "tag";
case "guard": return "property";
case "keyword": return "keyword";
case "macro": return "variable-2";
case "number": return "number";
case "open_paren": return null;
case "operator": return "operator";
case "record": return "bracket";
case "separator": return null;
case "string": return "string";
case "type": return "def";
case "variable": return "variable";
default: return null;
}
}
function aToken(tok,col,ind,typ) {
return {token: tok,
column: col,
indent: ind,
type: typ};
}
function realToken(type,stream) {
return aToken(stream.current(),
stream.column(),
stream.indentation(),
type);
}
function fakeToken(type) {
return aToken(type,0,0,type);
}
function peekToken(state,depth) {
var len = state.tokenStack.length;
var dep = (depth ? depth : 1);
if (len < dep) {
return false;
}else{
return state.tokenStack[len-dep];
}
}
function pushToken(state,token) {
if (!(token.type == "comment" || token.type == "whitespace")) {
state.tokenStack = maybe_drop_pre(state.tokenStack,token);
state.tokenStack = maybe_drop_post(state.tokenStack);
}
}
function maybe_drop_pre(s,token) {
var last = s.length-1;
if (0 < last && s[last].type === "record" && token.type === "dot") {
s.pop();
}else if (0 < last && s[last].type === "group") {
s.pop();
s.push(token);
}else{
s.push(token);
}
return s;
}
function maybe_drop_post(s) {
if (!s.length) return s
var last = s.length-1;
if (s[last].type === "dot") {
return [];
}
if (last > 1 && s[last].type === "fun" && s[last-1].token === "fun") {
return s.slice(0,last-1);
}
switch (s[last].token) {
case "}": return d(s,{g:["{"]});
case "]": return d(s,{i:["["]});
case ")": return d(s,{i:["("]});
case ">>": return d(s,{i:["<<"]});
case "end": return d(s,{i:["begin","case","fun","if","receive","try"]});
case ",": return d(s,{e:["begin","try","when","->",
",","(","[","{","<<"]});
case "->": return d(s,{r:["when"],
m:["try","if","case","receive"]});
case ";": return d(s,{E:["case","fun","if","receive","try","when"]});
case "catch":return d(s,{e:["try"]});
case "of": return d(s,{e:["case"]});
case "after":return d(s,{e:["receive","try"]});
default: return s;
}
}
function d(stack,tt) {
// stack is a stack of Token objects.
// tt is an object; {type:tokens}
// type is a char, tokens is a list of token strings.
// The function returns (possibly truncated) stack.
// It will descend the stack, looking for a Token such that Token.token
// is a member of tokens. If it does not find that, it will normally (but
// see "E" below) return stack. If it does find a match, it will remove
// all the Tokens between the top and the matched Token.
// If type is "m", that is all it does.
// If type is "i", it will also remove the matched Token and the top Token.
// If type is "g", like "i", but add a fake "group" token at the top.
// If type is "r", it will remove the matched Token, but not the top Token.
// If type is "e", it will keep the matched Token but not the top Token.
// If type is "E", it behaves as for type "e", except if there is no match,
// in which case it will return an empty stack.
for (var type in tt) {
var len = stack.length-1;
var tokens = tt[type];
for (var i = len-1; -1 < i ; i--) {
if (is_member(stack[i].token,tokens)) {
var ss = stack.slice(0,i);
switch (type) {
case "m": return ss.concat(stack[i]).concat(stack[len]);
case "r": return ss.concat(stack[len]);
case "i": return ss;
case "g": return ss.concat(fakeToken("group"));
case "E": return ss.concat(stack[i]);
case "e": return ss.concat(stack[i]);
}
}
}
}
return (type == "E" ? [] : stack);
}
/////////////////////////////////////////////////////////////////////////////
// indenter
function indenter(state,textAfter) {
var t;
var unit = cmCfg.indentUnit;
var wordAfter = wordafter(textAfter);
var currT = peekToken(state,1);
var prevT = peekToken(state,2);
if (state.in_string || state.in_atom) {
return CodeMirror.Pass;
}else if (!prevT) {
return 0;
}else if (currT.token == "when") {
return currT.column+unit;
}else if (wordAfter === "when" && prevT.type === "function") {
return prevT.indent+unit;
}else if (wordAfter === "(" && currT.token === "fun") {
return currT.column+3;
}else if (wordAfter === "catch" && (t = getToken(state,["try"]))) {
return t.column;
}else if (is_member(wordAfter,["end","after","of"])) {
t = getToken(state,["begin","case","fun","if","receive","try"]);
return t ? t.column : CodeMirror.Pass;
}else if (is_member(wordAfter,closeParenWords)) {
t = getToken(state,openParenWords);
return t ? t.column : CodeMirror.Pass;
}else if (is_member(currT.token,[",","|","||"]) ||
is_member(wordAfter,[",","|","||"])) {
t = postcommaToken(state);
return t ? t.column+t.token.length : unit;
}else if (currT.token == "->") {
if (is_member(prevT.token, ["receive","case","if","try"])) {
return prevT.column+unit+unit;
}else{
return prevT.column+unit;
}
}else if (is_member(currT.token,openParenWords)) {
return currT.column+currT.token.length;
}else{
t = defaultToken(state);
return truthy(t) ? t.column+unit : 0;
}
}
function wordafter(str) {
var m = str.match(/,|[a-z]+|\}|\]|\)|>>|\|+|\(/);
return truthy(m) && (m.index === 0) ? m[0] : "";
}
function postcommaToken(state) {
var objs = state.tokenStack.slice(0,-1);
var i = getTokenIndex(objs,"type",["open_paren"]);
return truthy(objs[i]) ? objs[i] : false;
}
function defaultToken(state) {
var objs = state.tokenStack;
var stop = getTokenIndex(objs,"type",["open_paren","separator","keyword"]);
var oper = getTokenIndex(objs,"type",["operator"]);
if (truthy(stop) && truthy(oper) && stop < oper) {
return objs[stop+1];
} else if (truthy(stop)) {
return objs[stop];
} else {
return false;
}
}
function getToken(state,tokens) {
var objs = state.tokenStack;
var i = getTokenIndex(objs,"token",tokens);
return truthy(objs[i]) ? objs[i] : false;
}
function getTokenIndex(objs,propname,propvals) {
for (var i = objs.length-1; -1 < i ; i--) {
if (is_member(objs[i][propname],propvals)) {
return i;
}
}
return false;
}
function truthy(x) {
return (x !== false) && (x != null);
}
/////////////////////////////////////////////////////////////////////////////
// this object defines the mode
return {
startState:
function() {
return {tokenStack: [],
in_string: false,
in_atom: false};
},
token:
function(stream, state) {
return tokenizer(stream, state);
},
indent:
function(state, textAfter) {
return indenter(state,textAfter);
},
lineComment: "%"
};
});
});

View File

@@ -0,0 +1,76 @@
<!doctype html>
<title>CodeMirror: Erlang mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/erlang-dark.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="erlang.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">Erlang</a>
</ul>
</div>
<article>
<h2>Erlang mode</h2>
<form><textarea id="code" name="code">
%% -*- mode: erlang; erlang-indent-level: 2 -*-
%%% Created : 7 May 2012 by mats cronqvist <masse@klarna.com>
%% @doc
%% Demonstrates how to print a record.
%% @end
-module('ex').
-author('mats cronqvist').
-export([demo/0,
rec_info/1]).
-record(demo,{a="One",b="Two",c="Three",d="Four"}).
rec_info(demo) -> record_info(fields,demo).
demo() -> expand_recs(?MODULE,#demo{a="A",b="BB"}).
expand_recs(M,List) when is_list(List) ->
[expand_recs(M,L)||L<-List];
expand_recs(M,Tup) when is_tuple(Tup) ->
case tuple_size(Tup) of
L when L < 1 -> Tup;
L ->
try
Fields = M:rec_info(element(1,Tup)),
L = length(Fields)+1,
lists:zip(Fields,expand_recs(M,tl(tuple_to_list(Tup))))
catch
_:_ -> list_to_tuple(expand_recs(M,tuple_to_list(Tup)))
end
end;
expand_recs(_,Term) ->
Term.
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
extraKeys: {"Tab": "indentAuto"},
theme: "erlang-dark"
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-erlang</code>.</p>
</article>

187
web/public/codemirror/mode/go/go.js vendored Normal file
View File

@@ -0,0 +1,187 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("go", function(config) {
var indentUnit = config.indentUnit;
var keywords = {
"break":true, "case":true, "chan":true, "const":true, "continue":true,
"default":true, "defer":true, "else":true, "fallthrough":true, "for":true,
"func":true, "go":true, "goto":true, "if":true, "import":true,
"interface":true, "map":true, "package":true, "range":true, "return":true,
"select":true, "struct":true, "switch":true, "type":true, "var":true,
"bool":true, "byte":true, "complex64":true, "complex128":true,
"float32":true, "float64":true, "int8":true, "int16":true, "int32":true,
"int64":true, "string":true, "uint8":true, "uint16":true, "uint32":true,
"uint64":true, "int":true, "uint":true, "uintptr":true, "error": true,
"rune":true
};
var atoms = {
"true":true, "false":true, "iota":true, "nil":true, "append":true,
"cap":true, "close":true, "complex":true, "copy":true, "delete":true, "imag":true,
"len":true, "make":true, "new":true, "panic":true, "print":true,
"println":true, "real":true, "recover":true
};
var isOperatorChar = /[+\-*&^%:=<>!|\/]/;
var curPunc;
function tokenBase(stream, state) {
var ch = stream.next();
if (ch == '"' || ch == "'" || ch == "`") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (/[\d\.]/.test(ch)) {
if (ch == ".") {
stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/);
} else if (ch == "0") {
stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/);
} else {
stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/);
}
return "number";
}
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
curPunc = ch;
return null;
}
if (ch == "/") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
}
if (stream.eat("/")) {
stream.skipToEnd();
return "comment";
}
}
if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return "operator";
}
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
var cur = stream.current();
if (keywords.propertyIsEnumerable(cur)) {
if (cur == "case" || cur == "default") curPunc = "case";
return "keyword";
}
if (atoms.propertyIsEnumerable(cur)) return "atom";
return "variable";
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, next, end = false;
while ((next = stream.next()) != null) {
if (next == quote && !escaped) {end = true; break;}
escaped = !escaped && quote != "`" && next == "\\";
}
if (end || !(escaped || quote == "`"))
state.tokenize = tokenBase;
return "string";
};
}
function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = tokenBase;
break;
}
maybeEnd = (ch == "*");
}
return "comment";
}
function Context(indented, column, type, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.align = align;
this.prev = prev;
}
function pushContext(state, col, type) {
return state.context = new Context(state.indented, col, type, null, state.context);
}
function popContext(state) {
if (!state.context.prev) return;
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}
// Interface
return {
startState: function(basecolumn) {
return {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
indented: 0,
startOfLine: true
};
},
token: function(stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
if (ctx.type == "case") ctx.type = "}";
}
if (stream.eatSpace()) return null;
curPunc = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment") return style;
if (ctx.align == null) ctx.align = true;
if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "case") ctx.type = "case";
else if (curPunc == "}" && ctx.type == "}") popContext(state);
else if (curPunc == ctx.type) popContext(state);
state.startOfLine = false;
return style;
},
indent: function(state, textAfter) {
if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
if (ctx.type == "case" && /^(?:case|default)\b/.test(textAfter)) {
state.context.type = "}";
return ctx.indented;
}
var closing = firstChar == ctx.type;
if (ctx.align) return ctx.column + (closing ? 0 : 1);
else return ctx.indented + (closing ? 0 : indentUnit);
},
electricChars: "{}):",
closeBrackets: "()[]{}''\"\"``",
fold: "brace",
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: "//"
};
});
CodeMirror.defineMIME("text/x-go", "go");
});

View File

@@ -0,0 +1,85 @@
<!doctype html>
<title>CodeMirror: Go mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/elegant.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="go.js"></script>
<style>.CodeMirror {border:1px solid #999; background:#ffc}</style>
<div id=nav>
<a href="https://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="#">Go</a>
</ul>
</div>
<article>
<h2>Go mode</h2>
<form><textarea id="code" name="code">
// Prime Sieve in Go.
// Taken from the Go specification.
// Copyright © The Go Authors.
package main
import "fmt"
// Send the sequence 2, 3, 4, ... to channel 'ch'.
func generate(ch chan&lt;- int) {
for i := 2; ; i++ {
ch &lt;- i // Send 'i' to channel 'ch'
}
}
// Copy the values from channel 'src' to channel 'dst',
// removing those divisible by 'prime'.
func filter(src &lt;-chan int, dst chan&lt;- int, prime int) {
for i := range src { // Loop over values received from 'src'.
if i%prime != 0 {
dst &lt;- i // Send 'i' to channel 'dst'.
}
}
}
// The prime sieve: Daisy-chain filter processes together.
func sieve() {
ch := make(chan int) // Create a new channel.
go generate(ch) // Start generate() as a subprocess.
for {
prime := &lt;-ch
fmt.Print(prime, "\n")
ch1 := make(chan int)
go filter(ch, ch1, prime)
ch = ch1
}
}
func main() {
sieve()
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
theme: "elegant",
matchBrackets: true,
indentUnit: 8,
tabSize: 8,
indentWithTabs: true,
mode: "text/x-go"
});
</script>
<p><strong>MIME type:</strong> <code>text/x-go</code></p>
</article>

View File

@@ -0,0 +1,230 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("groovy", function(config) {
function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
var keywords = words(
"abstract as assert boolean break byte case catch char class const continue def default " +
"do double else enum extends final finally float for goto if implements import in " +
"instanceof int interface long native new package private protected public return " +
"short static strictfp super switch synchronized threadsafe throw throws trait transient " +
"try void volatile while");
var blockKeywords = words("catch class def do else enum finally for if interface switch trait try while");
var standaloneKeywords = words("return break continue");
var atoms = words("null true false this");
var curPunc;
function tokenBase(stream, state) {
var ch = stream.next();
if (ch == '"' || ch == "'") {
return startString(ch, stream, state);
}
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
curPunc = ch;
return null;
}
if (/\d/.test(ch)) {
stream.eatWhile(/[\w\.]/);
if (stream.eat(/eE/)) { stream.eat(/\+\-/); stream.eatWhile(/\d/); }
return "number";
}
if (ch == "/") {
if (stream.eat("*")) {
state.tokenize.push(tokenComment);
return tokenComment(stream, state);
}
if (stream.eat("/")) {
stream.skipToEnd();
return "comment";
}
if (expectExpression(state.lastToken, false)) {
return startString(ch, stream, state);
}
}
if (ch == "-" && stream.eat(">")) {
curPunc = "->";
return null;
}
if (/[+\-*&%=<>!?|\/~]/.test(ch)) {
stream.eatWhile(/[+\-*&%=<>|~]/);
return "operator";
}
stream.eatWhile(/[\w\$_]/);
if (ch == "@") { stream.eatWhile(/[\w\$_\.]/); return "meta"; }
if (state.lastToken == ".") return "property";
if (stream.eat(":")) { curPunc = "proplabel"; return "property"; }
var cur = stream.current();
if (atoms.propertyIsEnumerable(cur)) { return "atom"; }
if (keywords.propertyIsEnumerable(cur)) {
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
else if (standaloneKeywords.propertyIsEnumerable(cur)) curPunc = "standalone";
return "keyword";
}
return "variable";
}
tokenBase.isBase = true;
function startString(quote, stream, state) {
var tripleQuoted = false;
if (quote != "/" && stream.eat(quote)) {
if (stream.eat(quote)) tripleQuoted = true;
else return "string";
}
function t(stream, state) {
var escaped = false, next, end = !tripleQuoted;
while ((next = stream.next()) != null) {
if (next == quote && !escaped) {
if (!tripleQuoted) { break; }
if (stream.match(quote + quote)) { end = true; break; }
}
if (quote == '"' && next == "$" && !escaped && stream.eat("{")) {
state.tokenize.push(tokenBaseUntilBrace());
return "string";
}
escaped = !escaped && next == "\\";
}
if (end) state.tokenize.pop();
return "string";
}
state.tokenize.push(t);
return t(stream, state);
}
function tokenBaseUntilBrace() {
var depth = 1;
function t(stream, state) {
if (stream.peek() == "}") {
depth--;
if (depth == 0) {
state.tokenize.pop();
return state.tokenize[state.tokenize.length-1](stream, state);
}
} else if (stream.peek() == "{") {
depth++;
}
return tokenBase(stream, state);
}
t.isBase = true;
return t;
}
function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize.pop();
break;
}
maybeEnd = (ch == "*");
}
return "comment";
}
function expectExpression(last, newline) {
return !last || last == "operator" || last == "->" || /[\.\[\{\(,;:]/.test(last) ||
last == "newstatement" || last == "keyword" || last == "proplabel" ||
(last == "standalone" && !newline);
}
function Context(indented, column, type, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.align = align;
this.prev = prev;
}
function pushContext(state, col, type) {
return state.context = new Context(state.indented, col, type, null, state.context);
}
function popContext(state) {
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}
// Interface
return {
startState: function(basecolumn) {
return {
tokenize: [tokenBase],
context: new Context((basecolumn || 0) - config.indentUnit, 0, "top", false),
indented: 0,
startOfLine: true,
lastToken: null
};
},
token: function(stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
// Automatic semicolon insertion
if (ctx.type == "statement" && !expectExpression(state.lastToken, true)) {
popContext(state); ctx = state.context;
}
}
if (stream.eatSpace()) return null;
curPunc = null;
var style = state.tokenize[state.tokenize.length-1](stream, state);
if (style == "comment") return style;
if (ctx.align == null) ctx.align = true;
if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
// Handle indentation for {x -> \n ... }
else if (curPunc == "->" && ctx.type == "statement" && ctx.prev.type == "}") {
popContext(state);
state.context.align = false;
}
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}") {
while (ctx.type == "statement") ctx = popContext(state);
if (ctx.type == "}") ctx = popContext(state);
while (ctx.type == "statement") ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
pushContext(state, stream.column(), "statement");
state.startOfLine = false;
state.lastToken = curPunc || style;
return style;
},
indent: function(state, textAfter) {
if (!state.tokenize[state.tokenize.length-1].isBase) return CodeMirror.Pass;
var firstChar = textAfter && textAfter.charAt(0), ctx = state.context;
if (ctx.type == "statement" && !expectExpression(state.lastToken, true)) ctx = ctx.prev;
var closing = firstChar == ctx.type;
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : config.indentUnit);
else if (ctx.align) return ctx.column + (closing ? 0 : 1);
else return ctx.indented + (closing ? 0 : config.indentUnit);
},
electricChars: "{}",
closeBrackets: {triples: "'\""},
fold: "brace"
};
});
CodeMirror.defineMIME("text/x-groovy", "groovy");
});

View File

@@ -0,0 +1,84 @@
<!doctype html>
<title>CodeMirror: Groovy 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="../../addon/edit/matchbrackets.js"></script>
<script src="groovy.js"></script>
<style>.CodeMirror {border-top: 1px solid #500; border-bottom: 1px solid #500;}</style>
<div id=nav>
<a href="https://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="#">Groovy</a>
</ul>
</div>
<article>
<h2>Groovy mode</h2>
<form><textarea id="code" name="code">
//Pattern for groovy script
def p = ~/.*\.groovy/
new File( 'd:\\scripts' ).eachFileMatch(p) {f ->
// imports list
def imports = []
f.eachLine {
// condition to detect an import instruction
ln -> if ( ln =~ '^import .*' ) {
imports << "${ln - 'import '}"
}
}
// print thmen
if ( ! imports.empty ) {
println f
imports.each{ println " $it" }
}
}
/* Coin changer demo code from http://groovy.codehaus.org */
enum UsCoin {
quarter(25), dime(10), nickel(5), penny(1)
UsCoin(v) { value = v }
final value
}
enum OzzieCoin {
fifty(50), twenty(20), ten(10), five(5)
OzzieCoin(v) { value = v }
final value
}
def plural(word, count) {
if (count == 1) return word
word[-1] == 'y' ? word[0..-2] + "ies" : word + "s"
}
def change(currency, amount) {
currency.values().inject([]){ list, coin ->
int count = amount / coin.value
amount = amount % coin.value
list += "$count ${plural(coin.toString(), count)}"
}
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-groovy"
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-groovy</code></p>
</article>

View File

@@ -0,0 +1,43 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function (mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../haskell/haskell"))
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../haskell/haskell"], mod)
else // Plain browser env
mod(CodeMirror)
})(function (CodeMirror) {
"use strict"
CodeMirror.defineMode("haskell-literate", function (config, parserConfig) {
var baseMode = CodeMirror.getMode(config, (parserConfig && parserConfig.base) || "haskell")
return {
startState: function () {
return {
inCode: false,
baseState: CodeMirror.startState(baseMode)
}
},
token: function (stream, state) {
if (stream.sol()) {
if (state.inCode = stream.eat(">"))
return "meta"
}
if (state.inCode) {
return baseMode.token(stream, state.baseState)
} else {
stream.skipToEnd()
return "comment"
}
},
innerMode: function (state) {
return state.inCode ? {state: state.baseState, mode: baseMode} : null
}
}
}, "haskell")
CodeMirror.defineMIME("text/x-literate-haskell", "haskell-literate")
});

View File

@@ -0,0 +1,282 @@
<!doctype html>
<title>CodeMirror: Haskell-literate 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="haskell-literate.js"></script>
<script src="../haskell/haskell.js"></script>
<style>.CodeMirror {
border-top : 1px solid #DDDDDD;
border-bottom : 1px solid #DDDDDD;
}</style>
<div id=nav>
<a href="https://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="#">Haskell-literate</a>
</ul>
</div>
<article>
<h2>Haskell literate mode</h2>
<form>
<textarea id="code" name="code">
> {-# LANGUAGE OverloadedStrings #-}
> {-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
> import Control.Applicative ((<$>), (<*>))
> import Data.Maybe (isJust)
> import Data.Text (Text)
> import Text.Blaze ((!))
> import qualified Data.Text as T
> import qualified Happstack.Server as Happstack
> import qualified Text.Blaze.Html5 as H
> import qualified Text.Blaze.Html5.Attributes as A
> import Text.Digestive
> import Text.Digestive.Blaze.Html5
> import Text.Digestive.Happstack
> import Text.Digestive.Util
Simple forms and validation
---------------------------
Let's start by creating a very simple datatype to represent a user:
> data User = User
> { userName :: Text
> , userMail :: Text
> } deriving (Show)
And dive in immediately to create a `Form` for a user. The `Form v m a` type
has three parameters:
- `v`: the type for messages and errors (usually a `String`-like type, `Text` in
this case);
- `m`: the monad we are operating in, not specified here;
- `a`: the return type of the `Form`, in this case, this is obviously `User`.
> userForm :: Monad m => Form Text m User
We create forms by using the `Applicative` interface. A few form types are
provided in the `Text.Digestive.Form` module, such as `text`, `string`,
`bool`...
In the `digestive-functors` library, the developer is required to label each
field using the `.:` operator. This might look like a bit of a burden, but it
allows you to do some really useful stuff, like separating the `Form` from the
actual HTML layout.
> userForm = User
> <$> "name" .: text Nothing
> <*> "mail" .: check "Not a valid email address" checkEmail (text Nothing)
The `check` function enables you to validate the result of a form. For example,
we can validate the email address with a really naive `checkEmail` function.
> checkEmail :: Text -> Bool
> checkEmail = isJust . T.find (== '@')
More validation
---------------
For our example, we also want descriptions of Haskell libraries, and in order to
do that, we need package versions...
> type Version = [Int]
We want to let the user input a version number such as `0.1.0.0`. This means we
need to validate if the input `Text` is of this form, and then we need to parse
it to a `Version` type. Fortunately, we can do this in a single function:
`validate` allows conversion between values, which can optionally fail.
`readMaybe :: Read a => String -> Maybe a` is a utility function imported from
`Text.Digestive.Util`.
> validateVersion :: Text -> Result Text Version
> validateVersion = maybe (Error "Cannot parse version") Success .
> mapM (readMaybe . T.unpack) . T.split (== '.')
A quick test in GHCi:
ghci> validateVersion (T.pack "0.3.2.1")
Success [0,3,2,1]
ghci> validateVersion (T.pack "0.oops")
Error "Cannot parse version"
It works! This means we can now easily add a `Package` type and a `Form` for it:
> data Category = Web | Text | Math
> deriving (Bounded, Enum, Eq, Show)
> data Package = Package Text Version Category
> deriving (Show)
> packageForm :: Monad m => Form Text m Package
> packageForm = Package
> <$> "name" .: text Nothing
> <*> "version" .: validate validateVersion (text (Just "0.0.0.1"))
> <*> "category" .: choice categories Nothing
> where
> categories = [(x, T.pack (show x)) | x <- [minBound .. maxBound]]
Composing forms
---------------
A release has an author and a package. Let's use this to illustrate the
composability of the digestive-functors library: we can reuse the forms we have
written earlier on.
> data Release = Release User Package
> deriving (Show)
> releaseForm :: Monad m => Form Text m Release
> releaseForm = Release
> <$> "author" .: userForm
> <*> "package" .: packageForm
Views
-----
As mentioned before, one of the advantages of using digestive-functors is
separation of forms and their actual HTML layout. In order to do this, we have
another type, `View`.
We can get a `View` from a `Form` by supplying input. A `View` contains more
information than a `Form`, it has:
- the original form;
- the input given by the user;
- any errors that have occurred.
It is this view that we convert to HTML. For this tutorial, we use the
[blaze-html] library, and some helpers from the `digestive-functors-blaze`
library.
[blaze-html]: http://jaspervdj.be/blaze/
Let's write a view for the `User` form. As you can see, we here refer to the
different fields in the `userForm`. The `errorList` will generate a list of
errors for the `"mail"` field.
> userView :: View H.Html -> H.Html
> userView view = do
> label "name" view "Name: "
> inputText "name" view
> H.br
>
> errorList "mail" view
> label "mail" view "Email address: "
> inputText "mail" view
> H.br
Like forms, views are also composable: let's illustrate that by adding a view
for the `releaseForm`, in which we reuse `userView`. In order to do this, we
take only the parts relevant to the author from the view by using `subView`. We
can then pass the resulting view to our own `userView`.
We have no special view code for `Package`, so we can just add that to
`releaseView` as well. `childErrorList` will generate a list of errors for each
child of the specified form. In this case, this means a list of errors from
`"package.name"` and `"package.version"`. Note how we use `foo.bar` to refer to
nested forms.
> releaseView :: View H.Html -> H.Html
> releaseView view = do
> H.h2 "Author"
> userView $ subView "author" view
>
> H.h2 "Package"
> childErrorList "package" view
>
> label "package.name" view "Name: "
> inputText "package.name" view
> H.br
>
> label "package.version" view "Version: "
> inputText "package.version" view
> H.br
>
> label "package.category" view "Category: "
> inputSelect "package.category" view
> H.br
The attentive reader might have wondered what the type parameter for `View` is:
it is the `String`-like type used for e.g. error messages.
But wait! We have
releaseForm :: Monad m => Form Text m Release
releaseView :: View H.Html -> H.Html
... doesn't this mean that we need a `View Text` rather than a `View Html`? The
answer is yes -- but having `View Html` allows us to write these views more
easily with the `digestive-functors-blaze` library. Fortunately, we will be able
to fix this using the `Functor` instance of `View`.
fmap :: Monad m => (v -> w) -> View v -> View w
A backend
---------
To finish this tutorial, we need to be able to actually run this code. We need
an HTTP server for that, and we use [Happstack] for this tutorial. The
`digestive-functors-happstack` library gives about everything we need for this.
[Happstack]: http://happstack.com/
> site :: Happstack.ServerPart Happstack.Response
> site = do
> Happstack.decodeBody $ Happstack.defaultBodyPolicy "/tmp" 4096 4096 4096
> r <- runForm "test" releaseForm
> case r of
> (view, Nothing) -> do
> let view' = fmap H.toHtml view
> Happstack.ok $ Happstack.toResponse $
> template $
> form view' "/" $ do
> releaseView view'
> H.br
> inputSubmit "Submit"
> (_, Just release) -> Happstack.ok $ Happstack.toResponse $
> template $ do
> css
> H.h1 "Release received"
> H.p $ H.toHtml $ show release
>
> main :: IO ()
> main = Happstack.simpleHTTP Happstack.nullConf site
Utilities
---------
> template :: H.Html -> H.Html
> template body = H.docTypeHtml $ do
> H.head $ do
> H.title "digestive-functors tutorial"
> css
> H.body body
> css :: H.Html
> css = H.style ! A.type_ "text/css" $ do
> "label {width: 130px; float: left; clear: both}"
> "ul.digestive-functors-error-list {"
> " color: red;"
> " list-style-type: none;"
> " padding-left: 0px;"
> "}"
</textarea>
</form>
<p><strong>MIME types
defined:</strong> <code>text/x-literate-haskell</code>.</p>
<p>Parser configuration parameters recognized: <code>base</code> to
set the base mode (defaults to <code>"haskell"</code>).</p>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "haskell-literate"});
</script>
</article>

View File

@@ -0,0 +1,268 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("haskell", function(_config, modeConfig) {
function switchState(source, setState, f) {
setState(f);
return f(source, setState);
}
// These should all be Unicode extended, as per the Haskell 2010 report
var smallRE = /[a-z_]/;
var largeRE = /[A-Z]/;
var digitRE = /\d/;
var hexitRE = /[0-9A-Fa-f]/;
var octitRE = /[0-7]/;
var idRE = /[a-z_A-Z0-9'\xa1-\uffff]/;
var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:]/;
var specialRE = /[(),;[\]`{}]/;
var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer
function normal(source, setState) {
if (source.eatWhile(whiteCharRE)) {
return null;
}
var ch = source.next();
if (specialRE.test(ch)) {
if (ch == '{' && source.eat('-')) {
var t = "comment";
if (source.eat('#')) {
t = "meta";
}
return switchState(source, setState, ncomment(t, 1));
}
return null;
}
if (ch == '\'') {
if (source.eat('\\')) {
source.next(); // should handle other escapes here
}
else {
source.next();
}
if (source.eat('\'')) {
return "string";
}
return "string error";
}
if (ch == '"') {
return switchState(source, setState, stringLiteral);
}
if (largeRE.test(ch)) {
source.eatWhile(idRE);
if (source.eat('.')) {
return "qualifier";
}
return "variable-2";
}
if (smallRE.test(ch)) {
source.eatWhile(idRE);
return "variable";
}
if (digitRE.test(ch)) {
if (ch == '0') {
if (source.eat(/[xX]/)) {
source.eatWhile(hexitRE); // should require at least 1
return "integer";
}
if (source.eat(/[oO]/)) {
source.eatWhile(octitRE); // should require at least 1
return "number";
}
}
source.eatWhile(digitRE);
var t = "number";
if (source.match(/^\.\d+/)) {
t = "number";
}
if (source.eat(/[eE]/)) {
t = "number";
source.eat(/[-+]/);
source.eatWhile(digitRE); // should require at least 1
}
return t;
}
if (ch == "." && source.eat("."))
return "keyword";
if (symbolRE.test(ch)) {
if (ch == '-' && source.eat(/-/)) {
source.eatWhile(/-/);
if (!source.eat(symbolRE)) {
source.skipToEnd();
return "comment";
}
}
var t = "variable";
if (ch == ':') {
t = "variable-2";
}
source.eatWhile(symbolRE);
return t;
}
return "error";
}
function ncomment(type, nest) {
if (nest == 0) {
return normal;
}
return function(source, setState) {
var currNest = nest;
while (!source.eol()) {
var ch = source.next();
if (ch == '{' && source.eat('-')) {
++currNest;
}
else if (ch == '-' && source.eat('}')) {
--currNest;
if (currNest == 0) {
setState(normal);
return type;
}
}
}
setState(ncomment(type, currNest));
return type;
};
}
function stringLiteral(source, setState) {
while (!source.eol()) {
var ch = source.next();
if (ch == '"') {
setState(normal);
return "string";
}
if (ch == '\\') {
if (source.eol() || source.eat(whiteCharRE)) {
setState(stringGap);
return "string";
}
if (source.eat('&')) {
}
else {
source.next(); // should handle other escapes here
}
}
}
setState(normal);
return "string error";
}
function stringGap(source, setState) {
if (source.eat('\\')) {
return switchState(source, setState, stringLiteral);
}
source.next();
setState(normal);
return "error";
}
var wellKnownWords = (function() {
var wkw = {};
function setType(t) {
return function () {
for (var i = 0; i < arguments.length; i++)
wkw[arguments[i]] = t;
};
}
setType("keyword")(
"case", "class", "data", "default", "deriving", "do", "else", "foreign",
"if", "import", "in", "infix", "infixl", "infixr", "instance", "let",
"module", "newtype", "of", "then", "type", "where", "_");
setType("keyword")(
"\.\.", ":", "::", "=", "\\", "<-", "->", "@", "~", "=>");
setType("builtin")(
"!!", "$!", "$", "&&", "+", "++", "-", ".", "/", "/=", "<", "<*", "<=",
"<$>", "<*>", "=<<", "==", ">", ">=", ">>", ">>=", "^", "^^", "||", "*",
"*>", "**");
setType("builtin")(
"Applicative", "Bool", "Bounded", "Char", "Double", "EQ", "Either", "Enum",
"Eq", "False", "FilePath", "Float", "Floating", "Fractional", "Functor",
"GT", "IO", "IOError", "Int", "Integer", "Integral", "Just", "LT", "Left",
"Maybe", "Monad", "Nothing", "Num", "Ord", "Ordering", "Rational", "Read",
"ReadS", "Real", "RealFloat", "RealFrac", "Right", "Show", "ShowS",
"String", "True");
setType("builtin")(
"abs", "acos", "acosh", "all", "and", "any", "appendFile", "asTypeOf",
"asin", "asinh", "atan", "atan2", "atanh", "break", "catch", "ceiling",
"compare", "concat", "concatMap", "const", "cos", "cosh", "curry",
"cycle", "decodeFloat", "div", "divMod", "drop", "dropWhile", "either",
"elem", "encodeFloat", "enumFrom", "enumFromThen", "enumFromThenTo",
"enumFromTo", "error", "even", "exp", "exponent", "fail", "filter",
"flip", "floatDigits", "floatRadix", "floatRange", "floor", "fmap",
"foldl", "foldl1", "foldr", "foldr1", "fromEnum", "fromInteger",
"fromIntegral", "fromRational", "fst", "gcd", "getChar", "getContents",
"getLine", "head", "id", "init", "interact", "ioError", "isDenormalized",
"isIEEE", "isInfinite", "isNaN", "isNegativeZero", "iterate", "last",
"lcm", "length", "lex", "lines", "log", "logBase", "lookup", "map",
"mapM", "mapM_", "max", "maxBound", "maximum", "maybe", "min", "minBound",
"minimum", "mod", "negate", "not", "notElem", "null", "odd", "or",
"otherwise", "pi", "pred", "print", "product", "properFraction", "pure",
"putChar", "putStr", "putStrLn", "quot", "quotRem", "read", "readFile",
"readIO", "readList", "readLn", "readParen", "reads", "readsPrec",
"realToFrac", "recip", "rem", "repeat", "replicate", "return", "reverse",
"round", "scaleFloat", "scanl", "scanl1", "scanr", "scanr1", "seq",
"sequence", "sequence_", "show", "showChar", "showList", "showParen",
"showString", "shows", "showsPrec", "significand", "signum", "sin",
"sinh", "snd", "span", "splitAt", "sqrt", "subtract", "succ", "sum",
"tail", "take", "takeWhile", "tan", "tanh", "toEnum", "toInteger",
"toRational", "truncate", "uncurry", "undefined", "unlines", "until",
"unwords", "unzip", "unzip3", "userError", "words", "writeFile", "zip",
"zip3", "zipWith", "zipWith3");
var override = modeConfig.overrideKeywords;
if (override) for (var word in override) if (override.hasOwnProperty(word))
wkw[word] = override[word];
return wkw;
})();
return {
startState: function () { return { f: normal }; },
copyState: function (s) { return { f: s.f }; },
token: function(stream, state) {
var t = state.f(stream, function(s) { state.f = s; });
var w = stream.current();
return wellKnownWords.hasOwnProperty(w) ? wellKnownWords[w] : t;
},
blockCommentStart: "{-",
blockCommentEnd: "-}",
lineComment: "--"
};
});
CodeMirror.defineMIME("text/x-haskell", "haskell");
});

View File

@@ -0,0 +1,73 @@
<!doctype html>
<title>CodeMirror: Haskell mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/elegant.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="haskell.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">Haskell</a>
</ul>
</div>
<article>
<h2>Haskell mode</h2>
<form><textarea id="code" name="code">
module UniquePerms (
uniquePerms
)
where
-- | Find all unique permutations of a list where there might be duplicates.
uniquePerms :: (Eq a) => [a] -> [[a]]
uniquePerms = permBag . makeBag
-- | An unordered collection where duplicate values are allowed,
-- but represented with a single value and a count.
type Bag a = [(a, Int)]
makeBag :: (Eq a) => [a] -> Bag a
makeBag [] = []
makeBag (a:as) = mix a $ makeBag as
where
mix a [] = [(a,1)]
mix a (bn@(b,n):bs) | a == b = (b,n+1):bs
| otherwise = bn : mix a bs
permBag :: Bag a -> [[a]]
permBag [] = [[]]
permBag bs = concatMap (\(f,cs) -> map (f:) $ permBag cs) . oneOfEach $ bs
where
oneOfEach [] = []
oneOfEach (an@(a,n):bs) =
let bs' = if n == 1 then bs else (a,n-1):bs
in (a,bs') : mapSnd (an:) (oneOfEach bs)
apSnd f (a,b) = (a, f b)
mapSnd = map . apSnd
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
theme: "elegant"
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-haskell</code>.</p>
</article>

View File

@@ -0,0 +1,37 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"),
require("../../addon/mode/multiplex"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
"../../addon/mode/multiplex"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
var closeComment = parserConfig.closeComment || "--%>"
return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), {
open: parserConfig.openComment || "<%--",
close: closeComment,
delimStyle: "comment",
mode: {token: function(stream) {
stream.skipTo(closeComment) || stream.skipToEnd()
return "comment"
}}
}, {
open: parserConfig.open || parserConfig.scriptStartRegex || "<%",
close: parserConfig.close || parserConfig.scriptEndRegex || "%>",
mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec)
});
}, "htmlmixed");
CodeMirror.defineMIME("application/x-ejs", {name: "htmlembedded", scriptingModeSpec:"javascript"});
CodeMirror.defineMIME("application/x-aspx", {name: "htmlembedded", scriptingModeSpec:"text/x-csharp"});
CodeMirror.defineMIME("application/x-jsp", {name: "htmlembedded", scriptingModeSpec:"text/x-java"});
CodeMirror.defineMIME("application/x-erb", {name: "htmlembedded", scriptingModeSpec:"ruby"});
});

View File

@@ -0,0 +1,60 @@
<!doctype html>
<title>CodeMirror: Html Embedded Scripts 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="../xml/xml.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="../../addon/mode/multiplex.js"></script>
<script src="htmlembedded.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">Html Embedded Scripts</a>
</ul>
</div>
<article>
<h2>Html Embedded Scripts mode</h2>
<form><textarea id="code" name="code">
<%
function hello(who) {
return "Hello " + who;
}
%>
This is an example of EJS (embedded javascript)
<p>The program says <%= hello("world") %>.</p>
<script>
alert("And here is some normal JS code"); // also colored
</script>
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "application/x-ejs",
indentUnit: 4,
indentWithTabs: true
});
</script>
<p>Mode for html embedded scripts like JSP and ASP.NET. Depends on multiplex and HtmlMixed which in turn depends on
JavaScript, CSS and XML.<br />Other dependencies include those of the scripting language chosen.</p>
<p><strong>MIME types defined:</strong> <code>application/x-aspx</code> (ASP.NET),
<code>application/x-ejs</code> (Embedded Javascript), <code>application/x-jsp</code> (JavaServer Pages)
and <code>application/x-erb</code></p>
</article>

View File

@@ -0,0 +1,152 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var defaultTags = {
script: [
["lang", /(javascript|babel)/i, "javascript"],
["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i, "javascript"],
["type", /./, "text/plain"],
[null, null, "javascript"]
],
style: [
["lang", /^css$/i, "css"],
["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"],
["type", /./, "text/plain"],
[null, null, "css"]
]
};
function maybeBackup(stream, pat, style) {
var cur = stream.current(), close = cur.search(pat);
if (close > -1) {
stream.backUp(cur.length - close);
} else if (cur.match(/<\/?$/)) {
stream.backUp(cur.length);
if (!stream.match(pat, false)) stream.match(cur);
}
return style;
}
var attrRegexpCache = {};
function getAttrRegexp(attr) {
var regexp = attrRegexpCache[attr];
if (regexp) return regexp;
return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*");
}
function getAttrValue(text, attr) {
var match = text.match(getAttrRegexp(attr))
return match ? /^\s*(.*?)\s*$/.exec(match[2])[1] : ""
}
function getTagRegexp(tagName, anchored) {
return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i");
}
function addTags(from, to) {
for (var tag in from) {
var dest = to[tag] || (to[tag] = []);
var source = from[tag];
for (var i = source.length - 1; i >= 0; i--)
dest.unshift(source[i])
}
}
function findMatchingMode(tagInfo, tagText) {
for (var i = 0; i < tagInfo.length; i++) {
var spec = tagInfo[i];
if (!spec[0] || spec[1].test(getAttrValue(tagText, spec[0]))) return spec[2];
}
}
CodeMirror.defineMode("htmlmixed", function (config, parserConfig) {
var htmlMode = CodeMirror.getMode(config, {
name: "xml",
htmlMode: true,
multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag
});
var tags = {};
var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes;
addTags(defaultTags, tags);
if (configTags) addTags(configTags, tags);
if (configScript) for (var i = configScript.length - 1; i >= 0; i--)
tags.script.unshift(["type", configScript[i].matches, configScript[i].mode])
function html(stream, state) {
var style = htmlMode.token(stream, state.htmlState), tag = /\btag\b/.test(style), tagName
if (tag && !/[<>\s\/]/.test(stream.current()) &&
(tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase()) &&
tags.hasOwnProperty(tagName)) {
state.inTag = tagName + " "
} else if (state.inTag && tag && />$/.test(stream.current())) {
var inTag = /^([\S]+) (.*)/.exec(state.inTag)
state.inTag = null
var modeSpec = stream.current() == ">" && findMatchingMode(tags[inTag[1]], inTag[2])
var mode = CodeMirror.getMode(config, modeSpec)
var endTagA = getTagRegexp(inTag[1], true), endTag = getTagRegexp(inTag[1], false);
state.token = function (stream, state) {
if (stream.match(endTagA, false)) {
state.token = html;
state.localState = state.localMode = null;
return null;
}
return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState));
};
state.localMode = mode;
state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, ""));
} else if (state.inTag) {
state.inTag += stream.current()
if (stream.eol()) state.inTag += " "
}
return style;
};
return {
startState: function () {
var state = CodeMirror.startState(htmlMode);
return {token: html, inTag: null, localMode: null, localState: null, htmlState: state};
},
copyState: function (state) {
var local;
if (state.localState) {
local = CodeMirror.copyState(state.localMode, state.localState);
}
return {token: state.token, inTag: state.inTag,
localMode: state.localMode, localState: local,
htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
},
token: function (stream, state) {
return state.token(stream, state);
},
indent: function (state, textAfter, line) {
if (!state.localMode || /^\s*<\//.test(textAfter))
return htmlMode.indent(state.htmlState, textAfter);
else if (state.localMode.indent)
return state.localMode.indent(state.localState, textAfter, line);
else
return CodeMirror.Pass;
},
innerMode: function (state) {
return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
}
};
}, "xml", "javascript", "css");
CodeMirror.defineMIME("text/html", "htmlmixed");
});

View File

@@ -0,0 +1,100 @@
<!doctype html>
<title>CodeMirror: HTML mixed 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="../../addon/selection/selection-pointer.js"></script>
<script src="../xml/xml.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../vbscript/vbscript.js"></script>
<script src="htmlmixed.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">HTML mixed</a>
</ul>
</div>
<article>
<h2>HTML mixed mode</h2>
<form><textarea id="code" name="code">
<html style="color: green">
<!-- this is a comment -->
<head>
<title>Mixed HTML Example</title>
<style>
h1 {font-family: comic sans; color: #f0f;}
div {background: yellow !important;}
body {
max-width: 50em;
margin: 1em 2em 1em 5em;
}
</style>
</head>
<body>
<h1>Mixed HTML Example</h1>
<script>
function jsFunc(arg1, arg2) {
if (arg1 && arg2) document.body.innerHTML = "achoo";
}
</script>
</body>
</html>
</textarea></form>
<script>
// Define an extended mixed-mode that understands vbscript and
// leaves mustache/handlebars embedded templates in html mode
var mixedMode = {
name: "htmlmixed",
scriptTypes: [{matches: /\/x-handlebars-template|\/x-mustache/i,
mode: null},
{matches: /(text|application)\/(x-)?vb(a|script)/i,
mode: "vbscript"}]
};
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: mixedMode,
selectionPointer: true
});
</script>
<p>The HTML mixed mode depends on the XML, JavaScript, and CSS modes.</p>
<p>It takes an optional mode configuration
option, <code>tags</code>, which can be used to add custom
behavior for specific tags. When given, it should be an object
mapping tag names (for example <code>script</code>) to arrays or
three-element arrays. Those inner arrays indicate [attributeName,
valueRegexp, <a href="../../doc/manual.html#option_mode">modeSpec</a>]
specifications. For example, you could use <code>["type", /^foo$/,
"foo"]</code> to map the attribute <code>type="foo"</code> to
the <code>foo</code> mode. When the first two fields are null
(<code>[null, null, "mode"]</code>), the given mode is used for
any such tag that doesn't match any of the previously given
attributes. For example:</p>
<pre>var myModeSpec = {
name: "htmlmixed",
tags: {
style: [["type", /^text\/(x-)?scss$/, "text/x-scss"],
[null, null, "css"]],
custom: [[null, null, "customMode"]]
}
}</pre>
<p><strong>MIME types defined:</strong> <code>text/html</code>
(redefined, only takes effect if you load this parser after the
XML parser).</p>
</article>

113
web/public/codemirror/mode/http/http.js vendored Normal file
View File

@@ -0,0 +1,113 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("http", function() {
function failFirstLine(stream, state) {
stream.skipToEnd();
state.cur = header;
return "error";
}
function start(stream, state) {
if (stream.match(/^HTTP\/\d\.\d/)) {
state.cur = responseStatusCode;
return "keyword";
} else if (stream.match(/^[A-Z]+/) && /[ \t]/.test(stream.peek())) {
state.cur = requestPath;
return "keyword";
} else {
return failFirstLine(stream, state);
}
}
function responseStatusCode(stream, state) {
var code = stream.match(/^\d+/);
if (!code) return failFirstLine(stream, state);
state.cur = responseStatusText;
var status = Number(code[0]);
if (status >= 100 && status < 200) {
return "positive informational";
} else if (status >= 200 && status < 300) {
return "positive success";
} else if (status >= 300 && status < 400) {
return "positive redirect";
} else if (status >= 400 && status < 500) {
return "negative client-error";
} else if (status >= 500 && status < 600) {
return "negative server-error";
} else {
return "error";
}
}
function responseStatusText(stream, state) {
stream.skipToEnd();
state.cur = header;
return null;
}
function requestPath(stream, state) {
stream.eatWhile(/\S/);
state.cur = requestProtocol;
return "string-2";
}
function requestProtocol(stream, state) {
if (stream.match(/^HTTP\/\d\.\d$/)) {
state.cur = header;
return "keyword";
} else {
return failFirstLine(stream, state);
}
}
function header(stream) {
if (stream.sol() && !stream.eat(/[ \t]/)) {
if (stream.match(/^.*?:/)) {
return "atom";
} else {
stream.skipToEnd();
return "error";
}
} else {
stream.skipToEnd();
return "string";
}
}
function body(stream) {
stream.skipToEnd();
return null;
}
return {
token: function(stream, state) {
var cur = state.cur;
if (cur != header && cur != body && stream.eatSpace()) return null;
return cur(stream, state);
},
blankLine: function(state) {
state.cur = body;
},
startState: function() {
return {cur: start};
}
};
});
CodeMirror.defineMIME("message/http", "http");
});

View File

@@ -0,0 +1,45 @@
<!doctype html>
<title>CodeMirror: HTTP 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="http.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">HTTP</a>
</ul>
</div>
<article>
<h2>HTTP mode</h2>
<div><textarea id="code" name="code">
POST /somewhere HTTP/1.1
Host: example.com
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
Content-Type: application/x-www-form-urlencoded;
charset=utf-8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.11 (KHTML, like Gecko) Ubuntu/12.04 Chromium/20.0.1132.47 Chrome/20.0.1132.47 Safari/536.11
This is the request body!
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
</script>
<p><strong>MIME types defined:</strong> <code>message/http</code>.</p>
</article>

165
web/public/codemirror/mode/index.html vendored Normal file
View File

@@ -0,0 +1,165 @@
<!doctype html>
<title>CodeMirror: Language Modes</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<div id=nav>
<a href="https://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 class=active href="#">Language modes</a>
</ul>
</div>
<article>
<h2>Language modes</h2>
<p>This is a list of every mode in the distribution. Each mode lives
in a subdirectory of the <code>mode/</code> directory, and typically
defines a single JavaScript file that implements the mode. Loading
such file will make the language available to CodeMirror, through
the <a href="../doc/manual.html#option_mode"><code>mode</code></a>
option.</p>
<div style="-webkit-columns: 100px 2; -moz-columns: 100px 2; columns: 100px 2;">
<ul style="margin-top: 0">
<li><a href="apl/index.html">APL</a></li>
<li><a href="asn.1/index.html">ASN.1</a></li>
<li><a href="asterisk/index.html">Asterisk dialplan</a></li>
<li><a href="brainfuck/index.html">Brainfuck</a></li>
<li><a href="clike/index.html">C, C++, C#</a></li>
<li><a href="clike/index.html">Ceylon</a></li>
<li><a href="clojure/index.html">Clojure</a></li>
<li><a href="css/gss.html">Closure Stylesheets (GSS)</a></li>
<li><a href="cmake/index.html">CMake</a></li>
<li><a href="cobol/index.html">COBOL</a></li>
<li><a href="coffeescript/index.html">CoffeeScript</a></li>
<li><a href="commonlisp/index.html">Common Lisp</a></li>
<li><a href="crystal/index.html">Crystal</a></li>
<li><a href="css/index.html">CSS</a></li>
<li><a href="cypher/index.html">Cypher</a></li>
<li><a href="python/index.html">Cython</a></li>
<li><a href="d/index.html">D</a></li>
<li><a href="dart/index.html">Dart</a></li>
<li><a href="django/index.html">Django</a> (templating language)</li>
<li><a href="dockerfile/index.html">Dockerfile</a></li>
<li><a href="diff/index.html">diff</a></li>
<li><a href="dtd/index.html">DTD</a></li>
<li><a href="dylan/index.html">Dylan</a></li>
<li><a href="ebnf/index.html">EBNF</a></li>
<li><a href="ecl/index.html">ECL</a></li>
<li><a href="eiffel/index.html">Eiffel</a></li>
<li><a href="https://github.com/optick/codemirror-mode-elixir">Elixir</a></li>
<li><a href="elm/index.html">Elm</a></li>
<li><a href="erlang/index.html">Erlang</a></li>
<li><a href="factor/index.html">Factor</a></li>
<li><a href="fcl/index.html">FCL</a></li>
<li><a href="forth/index.html">Forth</a></li>
<li><a href="fortran/index.html">Fortran</a></li>
<li><a href="mllike/index.html">F#</a></li>
<li><a href="gas/index.html">Gas</a> (AT&amp;T-style assembly)</li>
<li><a href="gherkin/index.html">Gherkin</a></li>
<li><a href="go/index.html">Go</a></li>
<li><a href="groovy/index.html">Groovy</a></li>
<li><a href="haml/index.html">HAML</a></li>
<li><a href="handlebars/index.html">Handlebars</a></li>
<li><a href="haskell/index.html">Haskell</a> (<a href="haskell-literate/index.html">Literate</a>)</li>
<li><a href="haxe/index.html">Haxe</a></li>
<li><a href="htmlembedded/index.html">HTML embedded</a> (JSP, ASP.NET)</li>
<li><a href="htmlmixed/index.html">HTML mixed-mode</a></li>
<li><a href="http/index.html">HTTP</a></li>
<li><a href="idl/index.html">IDL</a></li>
<li><a href="clike/index.html">Java</a></li>
<li><a href="javascript/index.html">JavaScript</a> (<a href="jsx/index.html">JSX</a>)</li>
<li><a href="jinja2/index.html">Jinja2</a></li>
<li><a href="julia/index.html">Julia</a></li>
<li><a href="clike/index.html">Kotlin</a></li>
<li><a href="css/less.html">LESS</a></li>
<li><a href="livescript/index.html">LiveScript</a></li>
<li><a href="lua/index.html">Lua</a></li>
<li><a href="markdown/index.html">Markdown</a> (<a href="gfm/index.html">GitHub-flavour</a>)</li>
<li><a href="mathematica/index.html">Mathematica</a></li>
<li><a href="mbox/index.html">mbox</a></li>
<li><a href="mirc/index.html">mIRC</a></li>
<li><a href="modelica/index.html">Modelica</a></li>
<li><a href="mscgen/index.html">MscGen</a></li>
<li><a href="mumps/index.html">MUMPS</a></li>
<li><a href="nginx/index.html">Nginx</a></li>
<li><a href="nsis/index.html">NSIS</a></li>
<li><a href="ntriples/index.html">N-Triples/N-Quads</a></li>
<li><a href="clike/index.html">Objective C</a></li>
<li><a href="mllike/index.html">OCaml</a></li>
<li><a href="octave/index.html">Octave</a> (MATLAB)</li>
<li><a href="oz/index.html">Oz</a></li>
<li><a href="pascal/index.html">Pascal</a></li>
<li><a href="pegjs/index.html">PEG.js</a></li>
<li><a href="perl/index.html">Perl</a></li>
<li><a href="asciiarmor/index.html">PGP (ASCII armor)</a></li>
<li><a href="php/index.html">PHP</a></li>
<li><a href="pig/index.html">Pig Latin</a></li>
<li><a href="powershell/index.html">PowerShell</a></li>
<li><a href="properties/index.html">Properties files</a></li>
<li><a href="protobuf/index.html">ProtoBuf</a></li>
<li><a href="pug/index.html">Pug</a></li>
<li><a href="puppet/index.html">Puppet</a></li>
<li><a href="python/index.html">Python</a></li>
<li><a href="q/index.html">Q</a></li>
<li><a href="r/index.html">R</a></li>
<li><a href="rpm/index.html">RPM</a></li>
<li><a href="rst/index.html">reStructuredText</a></li>
<li><a href="ruby/index.html">Ruby</a></li>
<li><a href="rust/index.html">Rust</a></li>
<li><a href="sas/index.html">SAS</a></li>
<li><a href="sass/index.html">Sass</a></li>
<li><a href="spreadsheet/index.html">Spreadsheet</a></li>
<li><a href="clike/scala.html">Scala</a></li>
<li><a href="scheme/index.html">Scheme</a></li>
<li><a href="css/scss.html">SCSS</a></li>
<li><a href="shell/index.html">Shell</a></li>
<li><a href="sieve/index.html">Sieve</a></li>
<li><a href="slim/index.html">Slim</a></li>
<li><a href="smalltalk/index.html">Smalltalk</a></li>
<li><a href="smarty/index.html">Smarty</a></li>
<li><a href="solr/index.html">Solr</a></li>
<li><a href="soy/index.html">Soy</a></li>
<li><a href="stylus/index.html">Stylus</a></li>
<li><a href="sql/index.html">SQL</a> (several dialects)</li>
<li><a href="sparql/index.html">SPARQL</a></li>
<li><a href="clike/index.html">Squirrel</a></li>
<li><a href="swift/index.html">Swift</a></li>
<li><a href="stex/index.html">sTeX, LaTeX</a></li>
<li><a href="tcl/index.html">Tcl</a></li>
<li><a href="textile/index.html">Textile</a></li>
<li><a href="tiddlywiki/index.html">Tiddlywiki</a></li>
<li><a href="tiki/index.html">Tiki wiki</a></li>
<li><a href="toml/index.html">TOML</a></li>
<li><a href="tornado/index.html">Tornado</a> (templating language)</li>
<li><a href="troff/index.html">troff</a> (for manpages)</li>
<li><a href="ttcn/index.html">TTCN</a></li>
<li><a href="ttcn-cfg/index.html">TTCN Configuration</a></li>
<li><a href="turtle/index.html">Turtle</a></li>
<li><a href="twig/index.html">Twig</a></li>
<li><a href="vb/index.html">VB.NET</a></li>
<li><a href="vbscript/index.html">VBScript</a></li>
<li><a href="velocity/index.html">Velocity</a></li>
<li><a href="verilog/index.html">Verilog/SystemVerilog</a></li>
<li><a href="vhdl/index.html">VHDL</a></li>
<li><a href="vue/index.html">Vue.js app</a></li>
<li><a href="webidl/index.html">Web IDL</a></li>
<li><a href="xml/index.html">XML/HTML</a></li>
<li><a href="xquery/index.html">XQuery</a></li>
<li><a href="yacas/index.html">Yacas</a></li>
<li><a href="yaml/index.html">YAML</a></li>
<li><a href="yaml-frontmatter/index.html">YAML frontmatter</a></li>
<li><a href="z80/index.html">Z80</a></li>
</ul>
</div>
</article>

View File

@@ -0,0 +1,114 @@
<!doctype html>
<title>CodeMirror: JavaScript 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="../../addon/edit/matchbrackets.js"></script>
<script src="../../addon/comment/continuecomment.js"></script>
<script src="../../addon/comment/comment.js"></script>
<script src="javascript.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">JavaScript</a>
</ul>
</div>
<article>
<h2>JavaScript mode</h2>
<div><textarea id="code" name="code">
// Demo code (the actual new parser character stream implementation)
function StringStream(string) {
this.pos = 0;
this.string = string;
}
StringStream.prototype = {
done: function() {return this.pos >= this.string.length;},
peek: function() {return this.string.charAt(this.pos);},
next: function() {
if (this.pos &lt; this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch &amp;&amp; match.test ? match.test(ch) : match(ch);
if (ok) {this.pos++; return ch;}
},
eatWhile: function(match) {
var start = this.pos;
while (this.eat(match));
if (this.pos > start) return this.string.slice(start, this.pos);
},
backUp: function(n) {this.pos -= n;},
column: function() {return this.pos;},
eatSpace: function() {
var start = this.pos;
while (/\s/.test(this.string.charAt(this.pos))) this.pos++;
return this.pos - start;
},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
if (consume !== false) this.pos += str.length;
return true;
}
}
else {
var match = this.string.slice(this.pos).match(pattern);
if (match &amp;&amp; consume !== false) this.pos += match[0].length;
return match;
}
}
};
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
continueComments: "Enter",
extraKeys: {"Ctrl-Q": "toggleComment"}
});
</script>
<p>
JavaScript mode supports several configuration options:
<ul>
<li><code>json</code> which will set the mode to expect JSON
data rather than a JavaScript program.</li>
<li><code>jsonld</code> which will set the mode to expect
<a href="http://json-ld.org">JSON-LD</a> linked data rather
than a JavaScript program (<a href="json-ld.html">demo</a>).</li>
<li><code>typescript</code> which will activate additional
syntax highlighting and some other things for TypeScript code
(<a href="typescript.html">demo</a>).</li>
<li><code>statementIndent</code> which (given a number) will
determine the amount of indentation to use for statements
continued on a new line.</li>
<li><code>wordCharacters</code>, a regexp that indicates which
characters should be considered part of an identifier.
Defaults to <code>/[\w$]/</code>, which does not handle
non-ASCII identifiers. Can be set to something more elaborate
to improve Unicode support.</li>
</ul>
</p>
<p><strong>MIME types defined:</strong> <code>text/javascript</code>, <code>application/json</code>, <code>application/ld+json</code>, <code>text/typescript</code>, <code>application/typescript</code>.</p>
</article>

View File

@@ -0,0 +1,899 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("javascript", function(config, parserConfig) {
var indentUnit = config.indentUnit;
var statementIndent = parserConfig.statementIndent;
var jsonldMode = parserConfig.jsonld;
var jsonMode = parserConfig.json || jsonldMode;
var isTS = parserConfig.typescript;
var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
// Tokenizer
var keywords = function(){
function kw(type) {return {type: type, style: "keyword"};}
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d");
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
return {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
"return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
"debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
"function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator,
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
"this": kw("this"), "class": kw("class"), "super": kw("atom"),
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
"await": C
};
}();
var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
function readRegexp(stream) {
var escaped = false, next, inSet = false;
while ((next = stream.next()) != null) {
if (!escaped) {
if (next == "/" && !inSet) return;
if (next == "[") inSet = true;
else if (inSet && next == "]") inSet = false;
}
escaped = !escaped && next == "\\";
}
}
// Used as scratch variables to communicate multiple values without
// consing up tons of objects.
var type, content;
function ret(tp, style, cont) {
type = tp; content = cont;
return style;
}
function tokenBase(stream, state) {
var ch = stream.next();
if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
} else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
return ret("number", "number");
} else if (ch == "." && stream.match("..")) {
return ret("spread", "meta");
} else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
return ret(ch);
} else if (ch == "=" && stream.eat(">")) {
return ret("=>", "operator");
} else if (ch == "0" && stream.match(/^(?:x[\da-f]+|o[0-7]+|b[01]+)n?/i)) {
return ret("number", "number");
} else if (/\d/.test(ch)) {
stream.match(/^\d*(?:n|(?:\.\d*)?(?:[eE][+\-]?\d+)?)?/);
return ret("number", "number");
} else if (ch == "/") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
} else if (stream.eat("/")) {
stream.skipToEnd();
return ret("comment", "comment");
} else if (expressionAllowed(stream, state, 1)) {
readRegexp(stream);
stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/);
return ret("regexp", "string-2");
} else {
stream.eat("=");
return ret("operator", "operator", stream.current());
}
} else if (ch == "`") {
state.tokenize = tokenQuasi;
return tokenQuasi(stream, state);
} else if (ch == "#") {
stream.skipToEnd();
return ret("error", "error");
} else if (isOperatorChar.test(ch)) {
if (ch != ">" || !state.lexical || state.lexical.type != ">") {
if (stream.eat("=")) {
if (ch == "!" || ch == "=") stream.eat("=")
} else if (/[<>*+\-]/.test(ch)) {
stream.eat(ch)
if (ch == ">") stream.eat(ch)
}
}
return ret("operator", "operator", stream.current());
} else if (wordRE.test(ch)) {
stream.eatWhile(wordRE);
var word = stream.current()
if (state.lastType != ".") {
if (keywords.propertyIsEnumerable(word)) {
var kw = keywords[word]
return ret(kw.type, kw.style, word)
}
if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\[\(\w]/, false))
return ret("async", "keyword", word)
}
return ret("variable", "variable", word)
}
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, next;
if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
state.tokenize = tokenBase;
return ret("jsonld-keyword", "meta");
}
while ((next = stream.next()) != null) {
if (next == quote && !escaped) break;
escaped = !escaped && next == "\\";
}
if (!escaped) state.tokenize = tokenBase;
return ret("string", "string");
};
}
function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = tokenBase;
break;
}
maybeEnd = (ch == "*");
}
return ret("comment", "comment");
}
function tokenQuasi(stream, state) {
var escaped = false, next;
while ((next = stream.next()) != null) {
if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
state.tokenize = tokenBase;
break;
}
escaped = !escaped && next == "\\";
}
return ret("quasi", "string-2", stream.current());
}
var brackets = "([{}])";
// This is a crude lookahead trick to try and notice that we're
// parsing the argument patterns for a fat-arrow function before we
// actually hit the arrow token. It only works if the arrow is on
// the same line as the arguments and there's no strange noise
// (comments) in between. Fallback is to only notice when we hit the
// arrow, and not declare the arguments as locals for the arrow
// body.
function findFatArrow(stream, state) {
if (state.fatArrowAt) state.fatArrowAt = null;
var arrow = stream.string.indexOf("=>", stream.start);
if (arrow < 0) return;
if (isTS) { // Try to skip TypeScript return type declarations after the arguments
var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow))
if (m) arrow = m.index
}
var depth = 0, sawSomething = false;
for (var pos = arrow - 1; pos >= 0; --pos) {
var ch = stream.string.charAt(pos);
var bracket = brackets.indexOf(ch);
if (bracket >= 0 && bracket < 3) {
if (!depth) { ++pos; break; }
if (--depth == 0) { if (ch == "(") sawSomething = true; break; }
} else if (bracket >= 3 && bracket < 6) {
++depth;
} else if (wordRE.test(ch)) {
sawSomething = true;
} else if (/["'\/]/.test(ch)) {
return;
} else if (sawSomething && !depth) {
++pos;
break;
}
}
if (sawSomething && !depth) state.fatArrowAt = pos;
}
// Parser
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
function JSLexical(indented, column, type, align, prev, info) {
this.indented = indented;
this.column = column;
this.type = type;
this.prev = prev;
this.info = info;
if (align != null) this.align = align;
}
function inScope(state, varname) {
for (var v = state.localVars; v; v = v.next)
if (v.name == varname) return true;
for (var cx = state.context; cx; cx = cx.prev) {
for (var v = cx.vars; v; v = v.next)
if (v.name == varname) return true;
}
}
function parseJS(state, style, type, content, stream) {
var cc = state.cc;
// Communicate our context to the combinators.
// (Less wasteful than consing up a hundred closures on every call.)
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = true;
while(true) {
var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
if (combinator(type, content)) {
while(cc.length && cc[cc.length - 1].lex)
cc.pop()();
if (cx.marked) return cx.marked;
if (type == "variable" && inScope(state, content)) return "variable-2";
return style;
}
}
}
// Combinator utils
var cx = {state: null, column: null, marked: null, cc: null};
function pass() {
for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
}
function cont() {
pass.apply(null, arguments);
return true;
}
function inList(name, list) {
for (var v = list; v; v = v.next) if (v.name == name) return true
return false;
}
function register(varname) {
var state = cx.state;
cx.marked = "def";
if (state.context) {
if (state.lexical.info == "var" && state.context && state.context.block) {
// FIXME function decls are also not block scoped
var newContext = registerVarScoped(varname, state.context)
if (newContext != null) {
state.context = newContext
return
}
} else if (!inList(varname, state.localVars)) {
state.localVars = new Var(varname, state.localVars)
return
}
}
// Fall through means this is global
if (parserConfig.globalVars && !inList(varname, state.globalVars))
state.globalVars = new Var(varname, state.globalVars)
}
function registerVarScoped(varname, context) {
if (!context) {
return null
} else if (context.block) {
var inner = registerVarScoped(varname, context.prev)
if (!inner) return null
if (inner == context.prev) return context
return new Context(inner, context.vars, true)
} else if (inList(varname, context.vars)) {
return context
} else {
return new Context(context.prev, new Var(varname, context.vars), false)
}
}
function isModifier(name) {
return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly"
}
// Combinators
function Context(prev, vars, block) { this.prev = prev; this.vars = vars; this.block = block }
function Var(name, next) { this.name = name; this.next = next }
var defaultVars = new Var("this", new Var("arguments", null))
function pushcontext() {
cx.state.context = new Context(cx.state.context, cx.state.localVars, false)
cx.state.localVars = defaultVars
}
function pushblockcontext() {
cx.state.context = new Context(cx.state.context, cx.state.localVars, true)
cx.state.localVars = null
}
function popcontext() {
cx.state.localVars = cx.state.context.vars
cx.state.context = cx.state.context.prev
}
popcontext.lex = true
function pushlex(type, info) {
var result = function() {
var state = cx.state, indent = state.indented;
if (state.lexical.type == "stat") indent = state.lexical.indented;
else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
indent = outer.indented;
state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
};
result.lex = true;
return result;
}
function poplex() {
var state = cx.state;
if (state.lexical.prev) {
if (state.lexical.type == ")")
state.indented = state.lexical.indented;
state.lexical = state.lexical.prev;
}
}
poplex.lex = true;
function expect(wanted) {
function exp(type) {
if (type == wanted) return cont();
else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass();
else return cont(exp);
};
return exp;
}
function statement(type, value) {
if (type == "var") return cont(pushlex("vardef", value), vardef, expect(";"), poplex);
if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex);
if (type == "debugger") return cont(expect(";"));
if (type == "{") return cont(pushlex("}"), pushblockcontext, block, poplex, popcontext);
if (type == ";") return cont();
if (type == "if") {
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
cx.state.cc.pop()();
return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
}
if (type == "function") return cont(functiondef);
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), className, poplex); }
if (type == "variable") {
if (isTS && value == "declare") {
cx.marked = "keyword"
return cont(statement)
} else if (isTS && (value == "module" || value == "enum" || value == "type") && cx.stream.match(/^\s*\w/, false)) {
cx.marked = "keyword"
if (value == "enum") return cont(enumdef);
else if (value == "type") return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
else return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
} else if (isTS && value == "namespace") {
cx.marked = "keyword"
return cont(pushlex("form"), expression, block, poplex)
} else if (isTS && value == "abstract") {
cx.marked = "keyword"
return cont(statement)
} else {
return cont(pushlex("stat"), maybelabel);
}
}
if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), pushblockcontext,
block, poplex, poplex, popcontext);
if (type == "case") return cont(expression, expect(":"));
if (type == "default") return cont(expect(":"));
if (type == "catch") return cont(pushlex("form"), pushcontext, maybeCatchBinding, statement, poplex, popcontext);
if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
if (type == "async") return cont(statement)
if (value == "@") return cont(expression, statement)
return pass(pushlex("stat"), expression, expect(";"), poplex);
}
function maybeCatchBinding(type) {
if (type == "(") return cont(funarg, expect(")"))
}
function expression(type, value) {
return expressionInner(type, value, false);
}
function expressionNoComma(type, value) {
return expressionInner(type, value, true);
}
function parenExpr(type) {
if (type != "(") return pass()
return cont(pushlex(")"), expression, expect(")"), poplex)
}
function expressionInner(type, value, noComma) {
if (cx.state.fatArrowAt == cx.stream.start) {
var body = noComma ? arrowBodyNoComma : arrowBody;
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext);
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
}
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef, maybeop);
if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); }
if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression);
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
if (type == "quasi") return pass(quasi, maybeop);
if (type == "new") return cont(maybeTarget(noComma));
if (type == "import") return cont(expression);
return cont();
}
function maybeexpression(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expression);
}
function maybeoperatorComma(type, value) {
if (type == ",") return cont(expression);
return maybeoperatorNoComma(type, value, false);
}
function maybeoperatorNoComma(type, value, noComma) {
var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
var expr = noComma == false ? expression : expressionNoComma;
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "operator") {
if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me);
if (isTS && value == "<" && cx.stream.match(/^([^>]|<.*?>)*>\s*\(/, false))
return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me);
if (value == "?") return cont(expression, expect(":"), expr);
return cont(expr);
}
if (type == "quasi") { return pass(quasi, me); }
if (type == ";") return;
if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
if (type == ".") return cont(property, me);
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) }
if (type == "regexp") {
cx.state.lastType = cx.marked = "operator"
cx.stream.backUp(cx.stream.pos - cx.stream.start - 1)
return cont(expr)
}
}
function quasi(type, value) {
if (type != "quasi") return pass();
if (value.slice(value.length - 2) != "${") return cont(quasi);
return cont(expression, continueQuasi);
}
function continueQuasi(type) {
if (type == "}") {
cx.marked = "string-2";
cx.state.tokenize = tokenQuasi;
return cont(quasi);
}
}
function arrowBody(type) {
findFatArrow(cx.stream, cx.state);
return pass(type == "{" ? statement : expression);
}
function arrowBodyNoComma(type) {
findFatArrow(cx.stream, cx.state);
return pass(type == "{" ? statement : expressionNoComma);
}
function maybeTarget(noComma) {
return function(type) {
if (type == ".") return cont(noComma ? targetNoComma : target);
else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma)
else return pass(noComma ? expressionNoComma : expression);
};
}
function target(_, value) {
if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
}
function targetNoComma(_, value) {
if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
}
function maybelabel(type) {
if (type == ":") return cont(poplex, statement);
return pass(maybeoperatorComma, expect(";"), poplex);
}
function property(type) {
if (type == "variable") {cx.marked = "property"; return cont();}
}
function objprop(type, value) {
if (type == "async") {
cx.marked = "property";
return cont(objprop);
} else if (type == "variable" || cx.style == "keyword") {
cx.marked = "property";
if (value == "get" || value == "set") return cont(getterSetter);
var m // Work around fat-arrow-detection complication for detecting typescript typed arrow params
if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false)))
cx.state.fatArrowAt = cx.stream.pos + m[0].length
return cont(afterprop);
} else if (type == "number" || type == "string") {
cx.marked = jsonldMode ? "property" : (cx.style + " property");
return cont(afterprop);
} else if (type == "jsonld-keyword") {
return cont(afterprop);
} else if (isTS && isModifier(value)) {
cx.marked = "keyword"
return cont(objprop)
} else if (type == "[") {
return cont(expression, maybetype, expect("]"), afterprop);
} else if (type == "spread") {
return cont(expressionNoComma, afterprop);
} else if (value == "*") {
cx.marked = "keyword";
return cont(objprop);
} else if (type == ":") {
return pass(afterprop)
}
}
function getterSetter(type) {
if (type != "variable") return pass(afterprop);
cx.marked = "property";
return cont(functiondef);
}
function afterprop(type) {
if (type == ":") return cont(expressionNoComma);
if (type == "(") return pass(functiondef);
}
function commasep(what, end, sep) {
function proceed(type, value) {
if (sep ? sep.indexOf(type) > -1 : type == ",") {
var lex = cx.state.lexical;
if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
return cont(function(type, value) {
if (type == end || value == end) return pass()
return pass(what)
}, proceed);
}
if (type == end || value == end) return cont();
return cont(expect(end));
}
return function(type, value) {
if (type == end || value == end) return cont();
return pass(what, proceed);
};
}
function contCommasep(what, end, info) {
for (var i = 3; i < arguments.length; i++)
cx.cc.push(arguments[i]);
return cont(pushlex(end, info), commasep(what, end), poplex);
}
function block(type) {
if (type == "}") return cont();
return pass(statement, block);
}
function maybetype(type, value) {
if (isTS) {
if (type == ":") return cont(typeexpr);
if (value == "?") return cont(maybetype);
}
}
function mayberettype(type) {
if (isTS && type == ":") {
if (cx.stream.match(/^\s*\w+\s+is\b/, false)) return cont(expression, isKW, typeexpr)
else return cont(typeexpr)
}
}
function isKW(_, value) {
if (value == "is") {
cx.marked = "keyword"
return cont()
}
}
function typeexpr(type, value) {
if (value == "keyof" || value == "typeof") {
cx.marked = "keyword"
return cont(value == "keyof" ? typeexpr : expressionNoComma)
}
if (type == "variable" || value == "void") {
cx.marked = "type"
return cont(afterType)
}
if (type == "string" || type == "number" || type == "atom") return cont(afterType);
if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType)
if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType)
if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr)
}
function maybeReturnType(type) {
if (type == "=>") return cont(typeexpr)
}
function typeprop(type, value) {
if (type == "variable" || cx.style == "keyword") {
cx.marked = "property"
return cont(typeprop)
} else if (value == "?") {
return cont(typeprop)
} else if (type == ":") {
return cont(typeexpr)
} else if (type == "[") {
return cont(expression, maybetype, expect("]"), typeprop)
}
}
function typearg(type, value) {
if (type == "variable" && cx.stream.match(/^\s*[?:]/, false) || value == "?") return cont(typearg)
if (type == ":") return cont(typeexpr)
return pass(typeexpr)
}
function afterType(type, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
if (value == "|" || type == "." || value == "&") return cont(typeexpr)
if (type == "[") return cont(expect("]"), afterType)
if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) }
}
function maybeTypeArgs(_, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
}
function typeparam() {
return pass(typeexpr, maybeTypeDefault)
}
function maybeTypeDefault(_, value) {
if (value == "=") return cont(typeexpr)
}
function vardef(_, value) {
if (value == "enum") {cx.marked = "keyword"; return cont(enumdef)}
return pass(pattern, maybetype, maybeAssign, vardefCont);
}
function pattern(type, value) {
if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) }
if (type == "variable") { register(value); return cont(); }
if (type == "spread") return cont(pattern);
if (type == "[") return contCommasep(eltpattern, "]");
if (type == "{") return contCommasep(proppattern, "}");
}
function proppattern(type, value) {
if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
register(value);
return cont(maybeAssign);
}
if (type == "variable") cx.marked = "property";
if (type == "spread") return cont(pattern);
if (type == "}") return pass();
return cont(expect(":"), pattern, maybeAssign);
}
function eltpattern() {
return pass(pattern, maybeAssign)
}
function maybeAssign(_type, value) {
if (value == "=") return cont(expressionNoComma);
}
function vardefCont(type) {
if (type == ",") return cont(vardef);
}
function maybeelse(type, value) {
if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
}
function forspec(type, value) {
if (value == "await") return cont(forspec);
if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
}
function forspec1(type) {
if (type == "var") return cont(vardef, expect(";"), forspec2);
if (type == ";") return cont(forspec2);
if (type == "variable") return cont(formaybeinof);
return pass(expression, expect(";"), forspec2);
}
function formaybeinof(_type, value) {
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
return cont(maybeoperatorComma, forspec2);
}
function forspec2(type, value) {
if (type == ";") return cont(forspec3);
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
return pass(expression, expect(";"), forspec3);
}
function forspec3(type) {
if (type != ")") cont(expression);
}
function functiondef(type, value) {
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
if (type == "variable") {register(value); return cont(functiondef);}
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext);
if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef)
}
function funarg(type, value) {
if (value == "@") cont(expression, funarg)
if (type == "spread") return cont(funarg);
if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); }
return pass(pattern, maybetype, maybeAssign);
}
function classExpression(type, value) {
// Class expressions may have an optional name.
if (type == "variable") return className(type, value);
return classNameAfter(type, value);
}
function className(type, value) {
if (type == "variable") {register(value); return cont(classNameAfter);}
}
function classNameAfter(type, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter)
if (value == "extends" || value == "implements" || (isTS && type == ",")) {
if (value == "implements") cx.marked = "keyword";
return cont(isTS ? typeexpr : expression, classNameAfter);
}
if (type == "{") return cont(pushlex("}"), classBody, poplex);
}
function classBody(type, value) {
if (type == "async" ||
(type == "variable" &&
(value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) &&
cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) {
cx.marked = "keyword";
return cont(classBody);
}
if (type == "variable" || cx.style == "keyword") {
cx.marked = "property";
return cont(isTS ? classfield : functiondef, classBody);
}
if (type == "[")
return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody)
if (value == "*") {
cx.marked = "keyword";
return cont(classBody);
}
if (type == ";") return cont(classBody);
if (type == "}") return cont();
if (value == "@") return cont(expression, classBody)
}
function classfield(type, value) {
if (value == "?") return cont(classfield)
if (type == ":") return cont(typeexpr, maybeAssign)
if (value == "=") return cont(expressionNoComma)
return pass(functiondef)
}
function afterExport(type, value) {
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
if (type == "{") return cont(commasep(exportField, "}"), maybeFrom, expect(";"));
return pass(statement);
}
function exportField(type, value) {
if (value == "as") { cx.marked = "keyword"; return cont(expect("variable")); }
if (type == "variable") return pass(expressionNoComma, exportField);
}
function afterImport(type) {
if (type == "string") return cont();
if (type == "(") return pass(expression);
return pass(importSpec, maybeMoreImports, maybeFrom);
}
function importSpec(type, value) {
if (type == "{") return contCommasep(importSpec, "}");
if (type == "variable") register(value);
if (value == "*") cx.marked = "keyword";
return cont(maybeAs);
}
function maybeMoreImports(type) {
if (type == ",") return cont(importSpec, maybeMoreImports)
}
function maybeAs(_type, value) {
if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
}
function maybeFrom(_type, value) {
if (value == "from") { cx.marked = "keyword"; return cont(expression); }
}
function arrayLiteral(type) {
if (type == "]") return cont();
return pass(commasep(expressionNoComma, "]"));
}
function enumdef() {
return pass(pushlex("form"), pattern, expect("{"), pushlex("}"), commasep(enummember, "}"), poplex, poplex)
}
function enummember() {
return pass(pattern, maybeAssign);
}
function isContinuedStatement(state, textAfter) {
return state.lastType == "operator" || state.lastType == "," ||
isOperatorChar.test(textAfter.charAt(0)) ||
/[,.]/.test(textAfter.charAt(0));
}
function expressionAllowed(stream, state, backUp) {
return state.tokenize == tokenBase &&
/^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
(state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
}
// Interface
return {
startState: function(basecolumn) {
var state = {
tokenize: tokenBase,
lastType: "sof",
cc: [],
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
localVars: parserConfig.localVars,
context: parserConfig.localVars && new Context(null, null, false),
indented: basecolumn || 0
};
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
state.globalVars = parserConfig.globalVars;
return state;
},
token: function(stream, state) {
if (stream.sol()) {
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = false;
state.indented = stream.indentation();
findFatArrow(stream, state);
}
if (state.tokenize != tokenComment && stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
if (type == "comment") return style;
state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
return parseJS(state, style, type, content, stream);
},
indent: function(state, textAfter) {
if (state.tokenize == tokenComment) return CodeMirror.Pass;
if (state.tokenize != tokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top
// Kludge to prevent 'maybelse' from blocking lexical scope pops
if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
var c = state.cc[i];
if (c == poplex) lexical = lexical.prev;
else if (c != maybeelse) break;
}
while ((lexical.type == "stat" || lexical.type == "form") &&
(firstChar == "}" || ((top = state.cc[state.cc.length - 1]) &&
(top == maybeoperatorComma || top == maybeoperatorNoComma) &&
!/^[,\.=+\-*:?[\(]/.test(textAfter))))
lexical = lexical.prev;
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
lexical = lexical.prev;
var type = lexical.type, closing = firstChar == type;
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info.length + 1 : 0);
else if (type == "form" && firstChar == "{") return lexical.indented;
else if (type == "form") return lexical.indented + indentUnit;
else if (type == "stat")
return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
else return lexical.indented + (closing ? 0 : indentUnit);
},
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/",
blockCommentContinue: jsonMode ? null : " * ",
lineComment: jsonMode ? null : "//",
fold: "brace",
closeBrackets: "()[]{}''\"\"``",
helperType: jsonMode ? "json" : "javascript",
jsonldMode: jsonldMode,
jsonMode: jsonMode,
expressionAllowed: expressionAllowed,
skipExpression: function(state) {
var top = state.cc[state.cc.length - 1]
if (top == expression || top == expressionNoComma) state.cc.pop()
}
};
});
CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
CodeMirror.defineMIME("text/javascript", "javascript");
CodeMirror.defineMIME("text/ecmascript", "javascript");
CodeMirror.defineMIME("application/javascript", "javascript");
CodeMirror.defineMIME("application/x-javascript", "javascript");
CodeMirror.defineMIME("application/ecmascript", "javascript");
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
});

View File

@@ -0,0 +1,72 @@
<!doctype html>
<title>CodeMirror: JSON-LD 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="../../addon/edit/matchbrackets.js"></script>
<script src="../../addon/comment/continuecomment.js"></script>
<script src="../../addon/comment/comment.js"></script>
<script src="javascript.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id="nav">
<a href="https://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="#">JSON-LD</a>
</ul>
</div>
<article>
<h2>JSON-LD mode</h2>
<div><textarea id="code" name="code">
{
"@context": {
"name": "http://schema.org/name",
"description": "http://schema.org/description",
"image": {
"@id": "http://schema.org/image",
"@type": "@id"
},
"geo": "http://schema.org/geo",
"latitude": {
"@id": "http://schema.org/latitude",
"@type": "xsd:float"
},
"longitude": {
"@id": "http://schema.org/longitude",
"@type": "xsd:float"
},
"xsd": "http://www.w3.org/2001/XMLSchema#"
},
"name": "The Empire State Building",
"description": "The Empire State Building is a 102-story landmark in New York City.",
"image": "http://www.civil.usherbrooke.ca/cours/gci215a/empire-state-building.jpg",
"geo": {
"latitude": "40.75",
"longitude": "73.98"
}
}
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
matchBrackets: true,
autoCloseBrackets: true,
mode: "application/ld+json",
lineWrapping: true
});
</script>
<p>This is a specialization of the <a href="index.html">JavaScript mode</a>.</p>
</article>

View File

@@ -0,0 +1,482 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "javascript");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
MT("locals",
"[keyword function] [def foo]([def a], [def b]) { [keyword var] [def c] [operator =] [number 10]; [keyword return] [variable-2 a] [operator +] [variable-2 c] [operator +] [variable d]; }");
MT("comma-and-binop",
"[keyword function](){ [keyword var] [def x] [operator =] [number 1] [operator +] [number 2], [def y]; }");
MT("destructuring",
"([keyword function]([def a], [[[def b], [def c] ]]) {",
" [keyword let] {[def d], [property foo]: [def c][operator =][number 10], [def x]} [operator =] [variable foo]([variable-2 a]);",
" [[[variable-2 c], [variable y] ]] [operator =] [variable-2 c];",
"})();");
MT("destructure_trailing_comma",
"[keyword let] {[def a], [def b],} [operator =] [variable foo];",
"[keyword let] [def c];"); // Parser still in good state?
MT("class_body",
"[keyword class] [def Foo] {",
" [property constructor]() {}",
" [property sayName]() {",
" [keyword return] [string-2 `foo${][variable foo][string-2 }oo`];",
" }",
"}");
MT("class",
"[keyword class] [def Point] [keyword extends] [variable SuperThing] {",
" [keyword get] [property prop]() { [keyword return] [number 24]; }",
" [property constructor]([def x], [def y]) {",
" [keyword super]([string 'something']);",
" [keyword this].[property x] [operator =] [variable-2 x];",
" }",
"}");
MT("anonymous_class_expression",
"[keyword const] [def Adder] [operator =] [keyword class] [keyword extends] [variable Arithmetic] {",
" [property add]([def a], [def b]) {}",
"};");
MT("named_class_expression",
"[keyword const] [def Subber] [operator =] [keyword class] [def Subtract] {",
" [property sub]([def a], [def b]) {}",
"};");
MT("class_async_method",
"[keyword class] [def Foo] {",
" [property sayName1]() {}",
" [keyword async] [property sayName2]() {}",
"}");
MT("import",
"[keyword function] [def foo]() {",
" [keyword import] [def $] [keyword from] [string 'jquery'];",
" [keyword import] { [def encrypt], [def decrypt] } [keyword from] [string 'crypto'];",
"}");
MT("import_trailing_comma",
"[keyword import] {[def foo], [def bar],} [keyword from] [string 'baz']")
MT("import_dynamic",
"[keyword import]([string 'baz']).[property then]")
MT("import_dynamic",
"[keyword const] [def t] [operator =] [keyword import]([string 'baz']).[property then]")
MT("const",
"[keyword function] [def f]() {",
" [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];",
"}");
MT("for/of",
"[keyword for]([keyword let] [def of] [keyword of] [variable something]) {}");
MT("for await",
"[keyword for] [keyword await]([keyword let] [def of] [keyword of] [variable something]) {}");
MT("generator",
"[keyword function*] [def repeat]([def n]) {",
" [keyword for]([keyword var] [def i] [operator =] [number 0]; [variable-2 i] [operator <] [variable-2 n]; [operator ++][variable-2 i])",
" [keyword yield] [variable-2 i];",
"}");
MT("let_scoping",
"[keyword function] [def scoped]([def n]) {",
" { [keyword var] [def i]; } [variable-2 i];",
" { [keyword let] [def j]; [variable-2 j]; } [variable j];",
" [keyword if] ([atom true]) { [keyword const] [def k]; [variable-2 k]; } [variable k];",
"}");
MT("switch_scoping",
"[keyword switch] ([variable x]) {",
" [keyword default]:",
" [keyword let] [def j];",
" [keyword return] [variable-2 j]",
"}",
"[variable j];")
MT("leaving_scope",
"[keyword function] [def a]() {",
" {",
" [keyword const] [def x] [operator =] [number 1]",
" [keyword if] ([atom true]) {",
" [keyword let] [def y] [operator =] [number 2]",
" [keyword var] [def z] [operator =] [number 3]",
" [variable console].[property log]([variable-2 x], [variable-2 y], [variable-2 z])",
" }",
" [variable console].[property log]([variable-2 x], [variable y], [variable-2 z])",
" }",
" [variable console].[property log]([variable x], [variable y], [variable-2 z])",
"}")
MT("quotedStringAddition",
"[keyword let] [def f] [operator =] [variable a] [operator +] [string 'fatarrow'] [operator +] [variable c];");
MT("quotedFatArrow",
"[keyword let] [def f] [operator =] [variable a] [operator +] [string '=>'] [operator +] [variable c];");
MT("fatArrow",
"[variable array].[property filter]([def a] [operator =>] [variable-2 a] [operator +] [number 1]);",
"[variable a];", // No longer in scope
"[keyword let] [def f] [operator =] ([[ [def a], [def b] ]], [def c]) [operator =>] [variable-2 a] [operator +] [variable-2 c];",
"[variable c];");
MT("spread",
"[keyword function] [def f]([def a], [meta ...][def b]) {",
" [variable something]([variable-2 a], [meta ...][variable-2 b]);",
"}");
MT("quasi",
"[variable re][string-2 `fofdlakj${][variable x] [operator +] ([variable re][string-2 `foo`]) [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]");
MT("quasi_no_function",
"[variable x] [operator =] [string-2 `fofdlakj${][variable x] [operator +] [string-2 `foo`] [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]");
MT("indent_statement",
"[keyword var] [def x] [operator =] [number 10]",
"[variable x] [operator +=] [variable y] [operator +]",
" [atom Infinity]",
"[keyword debugger];");
MT("indent_if",
"[keyword if] ([number 1])",
" [keyword break];",
"[keyword else] [keyword if] ([number 2])",
" [keyword continue];",
"[keyword else]",
" [number 10];",
"[keyword if] ([number 1]) {",
" [keyword break];",
"} [keyword else] [keyword if] ([number 2]) {",
" [keyword continue];",
"} [keyword else] {",
" [number 10];",
"}");
MT("indent_for",
"[keyword for] ([keyword var] [def i] [operator =] [number 0];",
" [variable i] [operator <] [number 100];",
" [variable i][operator ++])",
" [variable doSomething]([variable i]);",
"[keyword debugger];");
MT("indent_c_style",
"[keyword function] [def foo]()",
"{",
" [keyword debugger];",
"}");
MT("indent_else",
"[keyword for] (;;)",
" [keyword if] ([variable foo])",
" [keyword if] ([variable bar])",
" [number 1];",
" [keyword else]",
" [number 2];",
" [keyword else]",
" [number 3];");
MT("indent_funarg",
"[variable foo]([number 10000],",
" [keyword function]([def a]) {",
" [keyword debugger];",
"};");
MT("indent_below_if",
"[keyword for] (;;)",
" [keyword if] ([variable foo])",
" [number 1];",
"[number 2];");
MT("indent_semicolonless_if",
"[keyword function] [def foo]() {",
" [keyword if] ([variable x])",
" [variable foo]()",
"}")
MT("indent_semicolonless_if_with_statement",
"[keyword function] [def foo]() {",
" [keyword if] ([variable x])",
" [variable foo]()",
" [variable bar]()",
"}")
MT("multilinestring",
"[keyword var] [def x] [operator =] [string 'foo\\]",
"[string bar'];");
MT("scary_regexp",
"[string-2 /foo[[/]]bar/];");
MT("indent_strange_array",
"[keyword var] [def x] [operator =] [[",
" [number 1],,",
" [number 2],",
"]];",
"[number 10];");
MT("param_default",
"[keyword function] [def foo]([def x] [operator =] [string-2 `foo${][number 10][string-2 }bar`]) {",
" [keyword return] [variable-2 x];",
"}");
MT("new_target",
"[keyword function] [def F]([def target]) {",
" [keyword if] ([variable-2 target] [operator &&] [keyword new].[keyword target].[property name]) {",
" [keyword return] [keyword new]",
" .[keyword target];",
" }",
"}");
MT("async",
"[keyword async] [keyword function] [def foo]([def args]) { [keyword return] [atom true]; }");
MT("async_assignment",
"[keyword const] [def foo] [operator =] [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; };");
MT("async_object",
"[keyword let] [def obj] [operator =] { [property async]: [atom false] };");
// async be highlighet as keyword and foo as def, but it requires potentially expensive look-ahead. See #4173
MT("async_object_function",
"[keyword let] [def obj] [operator =] { [property async] [property foo]([def args]) { [keyword return] [atom true]; } };");
MT("async_object_properties",
"[keyword let] [def obj] [operator =] {",
" [property prop1]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },",
" [property prop2]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },",
" [property prop3]: [keyword async] [keyword function] [def prop3]([def args]) { [keyword return] [atom true]; },",
"};");
MT("async_arrow",
"[keyword const] [def foo] [operator =] [keyword async] ([def args]) [operator =>] { [keyword return] [atom true]; };");
MT("async_jquery",
"[variable $].[property ajax]({",
" [property url]: [variable url],",
" [property async]: [atom true],",
" [property method]: [string 'GET']",
"});");
MT("async_variable",
"[keyword const] [def async] [operator =] {[property a]: [number 1]};",
"[keyword const] [def foo] [operator =] [string-2 `bar ${][variable async].[property a][string-2 }`];")
MT("bigint", "[number 1n] [operator +] [number 0x1afn] [operator +] [number 0o064n] [operator +] [number 0b100n];")
MT("async_comment",
"[keyword async] [comment /**/] [keyword function] [def foo]([def args]) { [keyword return] [atom true]; }");
MT("indent_switch",
"[keyword switch] ([variable x]) {",
" [keyword default]:",
" [keyword return] [number 2]",
"}")
MT("regexp_corner_case",
"[operator +]{} [operator /] [atom undefined];",
"[[[meta ...][string-2 /\\//] ]];",
"[keyword void] [string-2 /\\//];",
"[keyword do] [string-2 /\\//]; [keyword while] ([number 0]);",
"[keyword if] ([number 0]) {} [keyword else] [string-2 /\\//];",
"[string-2 `${][variable async][operator ++][string-2 }//`];",
"[string-2 `${]{} [operator /] [string-2 /\\//}`];")
MT("return_eol",
"[keyword return]",
"{} [string-2 /5/]")
var ts_mode = CodeMirror.getMode({indentUnit: 2}, "application/typescript")
function TS(name) {
test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1))
}
TS("typescript_extend_type",
"[keyword class] [def Foo] [keyword extends] [type Some][operator <][type Type][operator >] {}")
TS("typescript_arrow_type",
"[keyword let] [def x]: ([variable arg]: [type Type]) [operator =>] [type ReturnType]")
TS("typescript_class",
"[keyword class] [def Foo] {",
" [keyword public] [keyword static] [property main]() {}",
" [keyword private] [property _foo]: [type string];",
"}")
TS("typescript_literal_types",
"[keyword import] [keyword *] [keyword as] [def Sequelize] [keyword from] [string 'sequelize'];",
"[keyword interface] [def MyAttributes] {",
" [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];",
" [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];",
"}",
"[keyword interface] [def MyInstance] [keyword extends] [type Sequelize].[type Instance] [operator <] [type MyAttributes] [operator >] {",
" [property rawAttributes]: [type MyAttributes];",
" [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];",
" [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];",
"}")
TS("typescript_extend_operators",
"[keyword export] [keyword interface] [def UserModel] [keyword extends]",
" [type Sequelize].[type Model] [operator <] [type UserInstance], [type UserAttributes] [operator >] {",
" [property findById]: (",
" [variable userId]: [type number]",
" ) [operator =>] [type Promise] [operator <] [type Array] [operator <] { [property id], [property name] } [operator >>];",
" [property updateById]: (",
" [variable userId]: [type number],",
" [variable isActive]: [type boolean]",
" ) [operator =>] [type Promise] [operator <] [type AccountHolderNotificationPreferenceInstance] [operator >];",
" }")
TS("typescript_interface_with_const",
"[keyword const] [def hello]: {",
" [property prop1][operator ?]: [type string];",
" [property prop2][operator ?]: [type string];",
"} [operator =] {};")
TS("typescript_double_extend",
"[keyword export] [keyword interface] [def UserAttributes] {",
" [property id][operator ?]: [type number];",
" [property createdAt][operator ?]: [type Date];",
"}",
"[keyword export] [keyword interface] [def UserInstance] [keyword extends] [type Sequelize].[type Instance][operator <][type UserAttributes][operator >], [type UserAttributes] {",
" [property id]: [type number];",
" [property createdAt]: [type Date];",
"}");
TS("typescript_index_signature",
"[keyword interface] [def A] {",
" [[ [variable prop]: [type string] ]]: [type any];",
" [property prop1]: [type any];",
"}");
TS("typescript_generic_class",
"[keyword class] [def Foo][operator <][type T][operator >] {",
" [property bar]() {}",
" [property foo](): [type Foo] {}",
"}")
TS("typescript_type_when_keyword",
"[keyword export] [keyword type] [type AB] [operator =] [type A] [operator |] [type B];",
"[keyword type] [type Flags] [operator =] {",
" [property p1]: [type string];",
" [property p2]: [type boolean];",
"};")
TS("typescript_type_when_not_keyword",
"[keyword class] [def HasType] {",
" [property type]: [type string];",
" [property constructor]([def type]: [type string]) {",
" [keyword this].[property type] [operator =] [variable-2 type];",
" }",
" [property setType]({ [def type] }: { [property type]: [type string]; }) {",
" [keyword this].[property type] [operator =] [variable-2 type];",
" }",
"}")
TS("typescript_function_generics",
"[keyword function] [def a]() {}",
"[keyword function] [def b][operator <][type IA] [keyword extends] [type object], [type IB] [keyword extends] [type object][operator >]() {}",
"[keyword function] [def c]() {}")
TS("typescript_complex_return_type",
"[keyword function] [def A]() {",
" [keyword return] [keyword this].[property property];",
"}",
"[keyword function] [def B](): [type Promise][operator <]{ [[ [variable key]: [type string] ]]: [type any] } [operator |] [atom null][operator >] {",
" [keyword return] [keyword this].[property property];",
"}")
TS("typescript_complex_type_casting",
"[keyword const] [def giftpay] [operator =] [variable config].[property get]([string 'giftpay']) [keyword as] { [[ [variable platformUuid]: [type string] ]]: { [property version]: [type number]; [property apiCode]: [type string]; } };")
TS("typescript_keyof",
"[keyword function] [def x][operator <][type T] [keyword extends] [keyword keyof] [type X][operator >]([def a]: [type T]) {",
" [keyword return]")
TS("typescript_new_typeargs",
"[keyword let] [def x] [operator =] [keyword new] [variable Map][operator <][type string], [type Date][operator >]([string-2 `foo${][variable bar][string-2 }`])")
TS("modifiers",
"[keyword class] [def Foo] {",
" [keyword public] [keyword abstract] [property bar]() {}",
" [property constructor]([keyword readonly] [keyword private] [def x]) {}",
"}")
TS("arrow prop",
"({[property a]: [def p] [operator =>] [variable-2 p]})")
TS("generic in function call",
"[keyword this].[property a][operator <][type Type][operator >]([variable foo]);",
"[keyword this].[property a][operator <][variable Type][operator >][variable foo];")
TS("type guard",
"[keyword class] [def Appler] {",
" [keyword static] [property assertApple]([def fruit]: [type Fruit]): [variable-2 fruit] [keyword is] [type Apple] {",
" [keyword if] ([operator !]([variable-2 fruit] [keyword instanceof] [variable Apple]))",
" [keyword throw] [keyword new] [variable Error]();",
" }",
"}")
TS("type as variable",
"[variable type] [operator =] [variable x] [keyword as] [type Bar];");
TS("enum body",
"[keyword export] [keyword const] [keyword enum] [def CodeInspectionResultType] {",
" [def ERROR] [operator =] [string 'problem_type_error'],",
" [def WARNING] [operator =] [string 'problem_type_warning'],",
" [def META],",
"}")
TS("parenthesized type",
"[keyword class] [def Foo] {",
" [property x] [operator =] [keyword new] [variable A][operator <][type B], [type string][operator |](() [operator =>] [type void])[operator >]();",
" [keyword private] [property bar]();",
"}")
TS("abstract class",
"[keyword export] [keyword abstract] [keyword class] [def Foo] {}")
var jsonld_mode = CodeMirror.getMode(
{indentUnit: 2},
{name: "javascript", jsonld: true}
);
function LD(name) {
test.mode(name, jsonld_mode, Array.prototype.slice.call(arguments, 1));
}
LD("json_ld_keywords",
'{',
' [meta "@context"]: {',
' [meta "@base"]: [string "http://example.com"],',
' [meta "@vocab"]: [string "http://xmlns.com/foaf/0.1/"],',
' [property "likesFlavor"]: {',
' [meta "@container"]: [meta "@list"]',
' [meta "@reverse"]: [string "@beFavoriteOf"]',
' },',
' [property "nick"]: { [meta "@container"]: [meta "@set"] },',
' [property "nick"]: { [meta "@container"]: [meta "@index"] }',
' },',
' [meta "@graph"]: [[ {',
' [meta "@id"]: [string "http://dbpedia.org/resource/John_Lennon"],',
' [property "name"]: [string "John Lennon"],',
' [property "modified"]: {',
' [meta "@value"]: [string "2010-05-29T14:17:39+02:00"],',
' [meta "@type"]: [string "http://www.w3.org/2001/XMLSchema#dateTime"]',
' }',
' } ]]',
'}');
LD("json_ld_fake",
'{',
' [property "@fake"]: [string "@fake"],',
' [property "@contextual"]: [string "@identifier"],',
' [property "user@domain.com"]: [string "@graphical"],',
' [property "@ID"]: [string "@@ID"]',
'}');
})();

View File

@@ -0,0 +1,62 @@
<!doctype html>
<title>CodeMirror: TypeScript 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="../../addon/edit/matchbrackets.js"></script>
<script src="javascript.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">TypeScript</a>
</ul>
</div>
<article>
<h2>TypeScript mode</h2>
<div><textarea id="code" name="code">
class Greeter {
greeting: string;
constructor (message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
var greeter = new Greeter("world");
var button = document.createElement('button')
button.innerText = "Say Hello"
button.onclick = function() {
alert(greeter.greet())
}
document.body.appendChild(button)
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/typescript"
});
</script>
<p>This is a specialization of the <a href="index.html">JavaScript mode</a>.</p>
</article>

View File

@@ -0,0 +1,89 @@
<!doctype html>
<title>CodeMirror: JSX 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="../javascript/javascript.js"></script>
<script src="../xml/xml.js"></script>
<script src="jsx.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">JSX</a>
</ul>
</div>
<article>
<h2>JSX mode</h2>
<div><textarea id="code" name="code">// Code snippets from http://facebook.github.io/react/docs/jsx-in-depth.html
// Rendering HTML tags
var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.getElementById('example'));
// Rendering React components
var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
ReactDOM.render(myElement, document.getElementById('example'));
// Namespaced components
var Form = MyFormComponent;
var App = (
<Form>
<Form.Row>
<Form.Label />
<Form.Input />
</Form.Row>
</Form>
);
// Attribute JavaScript expressions
var person = <Person name={window.isLoggedIn ? window.name : ''} />;
// Boolean attributes
<input type="button" disabled />;
<input type="button" disabled={true} />;
// Child JavaScript expressions
var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;
// Comments
var content = (
<Nav>
{/* child comment, put {} around */}
<Person
/* multi
line
comment */
name={window.isLoggedIn ? window.name : ''} // end of line comment
/>
</Nav>
);
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "jsx"
})
</script>
<p>JSX Mode for <a href="http://facebook.github.io/react">React</a>'s
JavaScript syntax extension.</p>
<p><strong>MIME types defined:</strong> <code>text/jsx</code>, <code>text/typescript-jsx</code>.</p>
</article>

148
web/public/codemirror/mode/jsx/jsx.js vendored Normal file
View File

@@ -0,0 +1,148 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"))
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript"], mod)
else // Plain browser env
mod(CodeMirror)
})(function(CodeMirror) {
"use strict"
// Depth means the amount of open braces in JS context, in XML
// context 0 means not in tag, 1 means in tag, and 2 means in tag
// and js block comment.
function Context(state, mode, depth, prev) {
this.state = state; this.mode = mode; this.depth = depth; this.prev = prev
}
function copyContext(context) {
return new Context(CodeMirror.copyState(context.mode, context.state),
context.mode,
context.depth,
context.prev && copyContext(context.prev))
}
CodeMirror.defineMode("jsx", function(config, modeConfig) {
var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false, allowMissingTagName: true})
var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript")
function flatXMLIndent(state) {
var tagName = state.tagName
state.tagName = null
var result = xmlMode.indent(state, "")
state.tagName = tagName
return result
}
function token(stream, state) {
if (state.context.mode == xmlMode)
return xmlToken(stream, state, state.context)
else
return jsToken(stream, state, state.context)
}
function xmlToken(stream, state, cx) {
if (cx.depth == 2) { // Inside a JS /* */ comment
if (stream.match(/^.*?\*\//)) cx.depth = 1
else stream.skipToEnd()
return "comment"
}
if (stream.peek() == "{") {
xmlMode.skipAttribute(cx.state)
var indent = flatXMLIndent(cx.state), xmlContext = cx.state.context
// If JS starts on same line as tag
if (xmlContext && stream.match(/^[^>]*>\s*$/, false)) {
while (xmlContext.prev && !xmlContext.startOfLine)
xmlContext = xmlContext.prev
// If tag starts the line, use XML indentation level
if (xmlContext.startOfLine) indent -= config.indentUnit
// Else use JS indentation level
else if (cx.prev.state.lexical) indent = cx.prev.state.lexical.indented
// Else if inside of tag
} else if (cx.depth == 1) {
indent += config.indentUnit
}
state.context = new Context(CodeMirror.startState(jsMode, indent),
jsMode, 0, state.context)
return null
}
if (cx.depth == 1) { // Inside of tag
if (stream.peek() == "<") { // Tag inside of tag
xmlMode.skipAttribute(cx.state)
state.context = new Context(CodeMirror.startState(xmlMode, flatXMLIndent(cx.state)),
xmlMode, 0, state.context)
return null
} else if (stream.match("//")) {
stream.skipToEnd()
return "comment"
} else if (stream.match("/*")) {
cx.depth = 2
return token(stream, state)
}
}
var style = xmlMode.token(stream, cx.state), cur = stream.current(), stop
if (/\btag\b/.test(style)) {
if (/>$/.test(cur)) {
if (cx.state.context) cx.depth = 0
else state.context = state.context.prev
} else if (/^</.test(cur)) {
cx.depth = 1
}
} else if (!style && (stop = cur.indexOf("{")) > -1) {
stream.backUp(cur.length - stop)
}
return style
}
function jsToken(stream, state, cx) {
if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) {
jsMode.skipExpression(cx.state)
state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")),
xmlMode, 0, state.context)
return null
}
var style = jsMode.token(stream, cx.state)
if (!style && cx.depth != null) {
var cur = stream.current()
if (cur == "{") {
cx.depth++
} else if (cur == "}") {
if (--cx.depth == 0) state.context = state.context.prev
}
}
return style
}
return {
startState: function() {
return {context: new Context(CodeMirror.startState(jsMode), jsMode)}
},
copyState: function(state) {
return {context: copyContext(state.context)}
},
token: token,
indent: function(state, textAfter, fullLine) {
return state.context.mode.indent(state.context.state, textAfter, fullLine)
},
innerMode: function(state) {
return state.context
}
}
}, "xml", "javascript")
CodeMirror.defineMIME("text/jsx", "jsx")
CodeMirror.defineMIME("text/typescript-jsx", {name: "jsx", base: {name: "javascript", typescript: true}})
});

91
web/public/codemirror/mode/jsx/test.js vendored Normal file
View File

@@ -0,0 +1,91 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "jsx")
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)) }
MT("selfclose",
"[keyword var] [def x] [operator =] [bracket&tag <] [tag foo] [bracket&tag />] [operator +] [number 1];")
MT("openclose",
"([bracket&tag <][tag foo][bracket&tag >]hello [atom &amp;][bracket&tag </][tag foo][bracket&tag >][operator ++])")
MT("openclosefragment",
"([bracket&tag <><][tag foo][bracket&tag >]hello [atom &amp;][bracket&tag </][tag foo][bracket&tag ></>][operator ++])")
MT("attr",
"([bracket&tag <][tag foo] [attribute abc]=[string 'value'][bracket&tag >]hello [atom &amp;][bracket&tag </][tag foo][bracket&tag >][operator ++])")
MT("braced_attr",
"([bracket&tag <][tag foo] [attribute abc]={[number 10]}[bracket&tag >]hello [atom &amp;][bracket&tag </][tag foo][bracket&tag >][operator ++])")
MT("braced_text",
"([bracket&tag <][tag foo][bracket&tag >]hello {[number 10]} [atom &amp;][bracket&tag </][tag foo][bracket&tag >][operator ++])")
MT("nested_tag",
"([bracket&tag <][tag foo][bracket&tag ><][tag bar][bracket&tag ></][tag bar][bracket&tag ></][tag foo][bracket&tag >][operator ++])")
MT("nested_jsx",
"[keyword return] (",
" [bracket&tag <][tag foo][bracket&tag >]",
" say {[number 1] [operator +] [bracket&tag <][tag bar] [attribute attr]={[number 10]}[bracket&tag />]}!",
" [bracket&tag </][tag foo][bracket&tag >][operator ++]",
")")
MT("preserve_js_context",
"[variable x] [operator =] [string-2 `quasi${][bracket&tag <][tag foo][bracket&tag />][string-2 }quoted`]")
MT("string_interpolation",
"[variable x] [operator =] [string-2 `quasi<code>${] [number 10] [string-2 }</code>`]")
MT("line_comment",
"([bracket&tag <][tag foo] [comment // hello]",
" [bracket&tag ></][tag foo][bracket&tag >][operator ++])")
MT("line_comment_not_in_tag",
"([bracket&tag <][tag foo][bracket&tag >] // hello",
" [bracket&tag </][tag foo][bracket&tag >][operator ++])")
MT("block_comment",
"([bracket&tag <][tag foo] [comment /* hello]",
"[comment line 2]",
"[comment line 3 */] [bracket&tag ></][tag foo][bracket&tag >][operator ++])")
MT("block_comment_not_in_tag",
"([bracket&tag <][tag foo][bracket&tag >]/* hello",
" line 2",
" line 3 */ [bracket&tag </][tag foo][bracket&tag >][operator ++])")
MT("missing_attr",
"([bracket&tag <][tag foo] [attribute selected][bracket&tag />][operator ++])")
MT("indent_js",
"([bracket&tag <][tag foo][bracket&tag >]",
" [bracket&tag <][tag bar] [attribute baz]={[keyword function]() {",
" [keyword return] [number 10]",
" }}[bracket&tag />]",
" [bracket&tag </][tag foo][bracket&tag >])")
MT("spread",
"([bracket&tag <][tag foo] [attribute bar]={[meta ...][variable baz] [operator /][number 2]}[bracket&tag />])")
MT("tag_attribute",
"([bracket&tag <][tag foo] [attribute bar]=[bracket&tag <][tag foo][bracket&tag />/>][operator ++])")
var ts_mode = CodeMirror.getMode({indentUnit: 2}, "text/typescript-jsx")
function TS(name) { test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1)) }
TS("tsx_react_integration",
"[keyword interface] [def Props] {",
" [property foo]: [type string];",
"}",
"[keyword class] [def MyComponent] [keyword extends] [type React].[type Component] [operator <] [type Props], [type any] [operator >] {",
" [property render]() {",
" [keyword return] [bracket&tag <][tag span][bracket&tag >]{[keyword this].[property props].[property foo]}[bracket&tag </][tag span][bracket&tag >]",
" }",
"}",
"[bracket&tag <][tag MyComponent] [attribute foo]=[string \"bar\"] [bracket&tag />]; [comment //ok]",
"[bracket&tag <][tag MyComponent] [attribute foo]={[number 0]} [bracket&tag />]; [comment //error]")
})()

View File

@@ -0,0 +1,196 @@
<!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="../../addon/edit/matchbrackets.js"></script>
<script src="julia.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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,433 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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(config, parserConf) {
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 sChar = "\\\\[abefnrtv0%?'\"\\\\]";
var uChar = "([^\\u0027\\u005C\\uD800-\\uDFFF]|[\\uD800-\\uDFFF][\\uDC00-\\uDFFF])";
var operators = parserConf.operators || wordRegexp([
"[<>]:", "[<>=]=", "<<=?", ">>>?=?", "=>", "->", "\\/\\/",
"[\\\\%*+\\-<>!=\\/^|&\\u00F7\\u22BB]=?", "\\?", "\\$", "~", ":",
"\\u00D7", "\\u2208", "\\u2209", "\\u220B", "\\u220C", "\\u2218",
"\\u221A", "\\u221B", "\\u2229", "\\u222A", "\\u2260", "\\u2264",
"\\u2265", "\\u2286", "\\u2288", "\\u228A", "\\u22C5",
"\\b(in|isa)\\b(?!\.?\\()"], "");
var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
var identifiers = parserConf.identifiers ||
/^[_A-Za-z\u00A1-\u2217\u2219-\uFFFF][\w\u00A1-\u2217\u2219-\uFFFF]*!*/;
var chars = wordRegexp([octChar, hexChar, sChar, uChar], "'");
var commonOpeners = ["begin", "function", "type", "struct", "immutable",
"let", "macro", "for", "while", "quote", "if", "else", "elseif", "try",
"finally", "catch", "do"];
var commonClosers = ["end", "else", "elseif", "catch", "finally"];
var commonKeywords = ["if", "else", "elseif", "while", "for", "begin",
"let", "end", "do", "try", "catch", "finally", "return", "break",
"continue", "global", "local", "const", "export", "import", "importall",
"using", "function", "where", "macro", "module", "baremodule", "struct",
"type", "mutable", "immutable", "quote", "typealias", "abstract",
"primitive", "bitstype"];
var commonBuiltins = ["true", "false", "nothing", "NaN", "Inf"];
CodeMirror.registerHelper("hintWords", "julia", commonKeywords.concat(commonBuiltins));
var openers = wordRegexp(commonOpeners);
var closers = wordRegexp(commonClosers);
var keywords = wordRegexp(commonKeywords);
var builtins = wordRegexp(commonBuiltins);
var macro = /^@[_A-Za-z][\w]*/;
var symbol = /^:[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/;
var stringPrefixes = /^(`|([_A-Za-z\u00A1-\uFFFF]*"("")?))/;
function inArray(state) {
return inGenerator(state, '[')
}
function inGenerator(state, bracket, depth) {
if (typeof(bracket) === "undefined") { bracket = '('; }
if (typeof(depth) === "undefined") { depth = 0; }
var scope = currentScope(state, depth);
if ((depth == 0 && scope === "if" && inGenerator(state, bracket, depth + 1)) ||
(scope === "for" && inGenerator(state, bracket, depth + 1)) ||
(scope === bracket)) {
return true;
}
return false;
}
function currentScope(state, n) {
if (typeof(n) === "undefined") { n = 0; }
if (state.scopes.length <= n) {
return null;
}
return state.scopes[state.scopes.length - (n + 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(/\.{4,}/)) {
return "error";
} else if (stream.match(/\.{1,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('(');
}
if (inArray(state) && ch === ']') {
if (currentScope(state) === "if") { state.scopes.pop(); }
while (currentScope(state) === "for") { state.scopes.pop(); }
state.scopes.pop();
state.leavingExpr = true;
}
if (inGenerator(state) && ch === ')') {
if (currentScope(state) === "if") { state.scopes.pop(); }
while (currentScope(state) === "for") { state.scopes.pop(); }
state.scopes.pop();
state.leavingExpr = true;
}
if (inArray(state)) {
if (state.lastToken == "end" && stream.match(/^:/)) {
return "operator";
}
if (stream.match(/^end/)) {
return "number";
}
}
var match;
if (match = stream.match(openers)) {
state.scopes.push(match[0]);
return "keyword";
}
if (stream.match(closers)) {
state.scopes.pop();
return "keyword";
}
// Handle type annotations
if (stream.match(/^::(?![:\$])/)) {
state.tokenize = tokenAnnotation;
return state.tokenize(stream, state);
}
// Handle symbols
if (!leavingExpr && stream.match(symbol) ||
stream.match(/:([<>]:|<<=?|>>>?=?|->|\/\/|\.{2,3}|[\.\\%*+\-<>!\/^|&]=?|[~\?\$])/)) {
return "builtin";
}
// Handle parametric types
//if (stream.match(/^{[^}]*}(?=\()/)) {
// return "builtin";
//}
// Handle operators and Delimiters
if (stream.match(operators)) {
return "operator";
}
// Handle Number Literals
if (stream.match(/^\.?\d/, 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";
}
}
// 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 == "struct" || 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)) {
state.tokenize = tokenCallOrDef;
return state.tokenize(stream, state);
}
state.leavingExpr = true;
return "variable";
}
// Handle non-detected items
stream.next();
return "error";
}
function tokenCallOrDef(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*where\s+[^\s=]+)*\s*?=(?!=)/, false);
stream.backUp(state.charsAdvanced);
state.firstParenPos = -1;
state.charsAdvanced = 0;
state.tokenize = tokenBase;
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;
state.tokenize = tokenBase;
return "builtin";
}
state.charsAdvanced += stream.match(/^([^()]*)/)[1].length;
return state.tokenize(stream, state);
}
function tokenAnnotation(stream, state) {
stream.match(/.*?(?=,|;|{|}|\(|\)|=|$|\s)/);
if (stream.match(/^{/)) {
state.nestedLevels++;
} else if (stream.match(/^}/)) {
state.nestedLevels--;
}
if (state.nestedLevels > 0) {
stream.match(/.*?(?={|})/) || stream.next();
} else if (state.nestedLevels == 0) {
state.tokenize = tokenBase;
}
return "builtin";
}
function tokenComment(stream, state) {
if (stream.match(/^#=/)) {
state.nestedLevels++;
}
if (!stream.match(/.*?(?=(#=|=#))/)) {
stream.skipToEnd();
}
if (stream.match(/^=#/)) {
state.nestedLevels--;
if (state.nestedLevels == 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 "error";
}
function tokenStringFactory(delimiter) {
if (delimiter.substr(-3) === '"""') {
delimiter = '"""';
} else if (delimiter.substr(-1) === '"') {
delimiter = '"';
}
function tokenString(stream, state) {
if (stream.eat('\\')) {
stream.next();
} else if (stream.match(delimiter)) {
state.tokenize = tokenBase;
state.leavingExpr = true;
return "string";
} else {
stream.eat(/[`"]/);
}
stream.eatWhile(/[^\\`"]/);
return "string";
}
return tokenString;
}
var external = {
startState: function() {
return {
tokenize: tokenBase,
scopes: [],
lastToken: null,
leavingExpr: false,
isDefinition: false,
nestedLevels: 0,
charsAdvanced: 0,
firstParenPos: -1
};
},
token: function(stream, state) {
var style = state.tokenize(stream, state);
var current = stream.current();
if (current && style) {
state.lastToken = current;
}
return style;
},
indent: function(state, textAfter) {
var delta = 0;
if ( textAfter === ']' || textAfter === ')' || textAfter === "end" ||
textAfter === "else" || textAfter === "catch" || textAfter === "elseif" ||
textAfter === "finally" ) {
delta = -1;
}
return (state.scopes.length + delta) * config.indentUnit;
},
electricInput: /\b(end|else|catch|finally)\b/,
blockCommentStart: "#=",
blockCommentEnd: "=#",
lineComment: "#",
fold: "indent"
};
return external;
});
CodeMirror.defineMIME("text/x-julia", "julia");
});

View File

@@ -0,0 +1,459 @@
<!doctype html>
<title>CodeMirror: LiveScript mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/solarized.css">
<script src="../../lib/codemirror.js"></script>
<script src="livescript.js"></script>
<style>.CodeMirror {font-size: 80%;border-top: 1px solid silver; border-bottom: 1px solid silver;}</style>
<div id=nav>
<a href="https://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="#">LiveScript</a>
</ul>
</div>
<article>
<h2>LiveScript mode</h2>
<form><textarea id="code" name="code">
# LiveScript mode for CodeMirror
# The following script, prelude.ls, is used to
# demonstrate LiveScript mode for CodeMirror.
# https://github.com/gkz/prelude-ls
export objToFunc = objToFunc = (obj) ->
(key) -> obj[key]
export each = (f, xs) -->
if typeof! xs is \Object
for , x of xs then f x
else
for x in xs then f x
xs
export map = (f, xs) -->
f = objToFunc f if typeof! f isnt \Function
type = typeof! xs
if type is \Object
{[key, f x] for key, x of xs}
else
result = [f x for x in xs]
if type is \String then result * '' else result
export filter = (f, xs) -->
f = objToFunc f if typeof! f isnt \Function
type = typeof! xs
if type is \Object
{[key, x] for key, x of xs when f x}
else
result = [x for x in xs when f x]
if type is \String then result * '' else result
export reject = (f, xs) -->
f = objToFunc f if typeof! f isnt \Function
type = typeof! xs
if type is \Object
{[key, x] for key, x of xs when not f x}
else
result = [x for x in xs when not f x]
if type is \String then result * '' else result
export partition = (f, xs) -->
f = objToFunc f if typeof! f isnt \Function
type = typeof! xs
if type is \Object
passed = {}
failed = {}
for key, x of xs
(if f x then passed else failed)[key] = x
else
passed = []
failed = []
for x in xs
(if f x then passed else failed)push x
if type is \String
passed *= ''
failed *= ''
[passed, failed]
export find = (f, xs) -->
f = objToFunc f if typeof! f isnt \Function
if typeof! xs is \Object
for , x of xs when f x then return x
else
for x in xs when f x then return x
void
export head = export first = (xs) ->
return void if not xs.length
xs.0
export tail = (xs) ->
return void if not xs.length
xs.slice 1
export last = (xs) ->
return void if not xs.length
xs[*-1]
export initial = (xs) ->
return void if not xs.length
xs.slice 0 xs.length - 1
export empty = (xs) ->
if typeof! xs is \Object
for x of xs then return false
return yes
not xs.length
export values = (obj) ->
[x for , x of obj]
export keys = (obj) ->
[x for x of obj]
export len = (xs) ->
xs = values xs if typeof! xs is \Object
xs.length
export cons = (x, xs) -->
if typeof! xs is \String then x + xs else [x] ++ xs
export append = (xs, ys) -->
if typeof! ys is \String then xs + ys else xs ++ ys
export join = (sep, xs) -->
xs = values xs if typeof! xs is \Object
xs.join sep
export reverse = (xs) ->
if typeof! xs is \String
then (xs / '')reverse! * ''
else xs.slice!reverse!
export fold = export foldl = (f, memo, xs) -->
if typeof! xs is \Object
for , x of xs then memo = f memo, x
else
for x in xs then memo = f memo, x
memo
export fold1 = export foldl1 = (f, xs) --> fold f, xs.0, xs.slice 1
export foldr = (f, memo, xs) --> fold f, memo, xs.slice!reverse!
export foldr1 = (f, xs) -->
xs.=slice!reverse!
fold f, xs.0, xs.slice 1
export unfoldr = export unfold = (f, b) -->
if (f b)?
[that.0] ++ unfoldr f, that.1
else
[]
export andList = (xs) ->
for x in xs when not x
return false
true
export orList = (xs) ->
for x in xs when x
return true
false
export any = (f, xs) -->
f = objToFunc f if typeof! f isnt \Function
for x in xs when f x
return yes
no
export all = (f, xs) -->
f = objToFunc f if typeof! f isnt \Function
for x in xs when not f x
return no
yes
export unique = (xs) ->
result = []
if typeof! xs is \Object
for , x of xs when x not in result then result.push x
else
for x in xs when x not in result then result.push x
if typeof! xs is \String then result * '' else result
export sort = (xs) ->
xs.concat!sort (x, y) ->
| x > y => 1
| x < y => -1
| _ => 0
export sortBy = (f, xs) -->
return [] unless xs.length
xs.concat!sort f
export compare = (f, x, y) -->
| (f x) > (f y) => 1
| (f x) < (f y) => -1
| otherwise => 0
export sum = (xs) ->
result = 0
if typeof! xs is \Object
for , x of xs then result += x
else
for x in xs then result += x
result
export product = (xs) ->
result = 1
if typeof! xs is \Object
for , x of xs then result *= x
else
for x in xs then result *= x
result
export mean = export average = (xs) -> (sum xs) / len xs
export concat = (xss) -> fold append, [], xss
export concatMap = (f, xs) --> fold ((memo, x) -> append memo, f x), [], xs
export listToObj = (xs) ->
{[x.0, x.1] for x in xs}
export maximum = (xs) -> fold1 (>?), xs
export minimum = (xs) -> fold1 (<?), xs
export scan = export scanl = (f, memo, xs) -->
last = memo
if typeof! xs is \Object
then [memo] ++ [last = f last, x for , x of xs]
else [memo] ++ [last = f last, x for x in xs]
export scan1 = export scanl1 = (f, xs) --> scan f, xs.0, xs.slice 1
export scanr = (f, memo, xs) -->
xs.=slice!reverse!
scan f, memo, xs .reverse!
export scanr1 = (f, xs) -->
xs.=slice!reverse!
scan f, xs.0, xs.slice 1 .reverse!
export replicate = (n, x) -->
result = []
i = 0
while i < n, ++i then result.push x
result
export take = (n, xs) -->
| n <= 0
if typeof! xs is \String then '' else []
| not xs.length => xs
| otherwise => xs.slice 0, n
export drop = (n, xs) -->
| n <= 0 => xs
| not xs.length => xs
| otherwise => xs.slice n
export splitAt = (n, xs) --> [(take n, xs), (drop n, xs)]
export takeWhile = (p, xs) -->
return xs if not xs.length
p = objToFunc p if typeof! p isnt \Function
result = []
for x in xs
break if not p x
result.push x
if typeof! xs is \String then result * '' else result
export dropWhile = (p, xs) -->
return xs if not xs.length
p = objToFunc p if typeof! p isnt \Function
i = 0
for x in xs
break if not p x
++i
drop i, xs
export span = (p, xs) --> [(takeWhile p, xs), (dropWhile p, xs)]
export breakIt = (p, xs) --> span (not) << p, xs
export zip = (xs, ys) -->
result = []
for zs, i in [xs, ys]
for z, j in zs
result.push [] if i is 0
result[j]?push z
result
export zipWith = (f,xs, ys) -->
f = objToFunc f if typeof! f isnt \Function
if not xs.length or not ys.length
[]
else
[f.apply this, zs for zs in zip.call this, xs, ys]
export zipAll = (...xss) ->
result = []
for xs, i in xss
for x, j in xs
result.push [] if i is 0
result[j]?push x
result
export zipAllWith = (f, ...xss) ->
f = objToFunc f if typeof! f isnt \Function
if not xss.0.length or not xss.1.length
[]
else
[f.apply this, xs for xs in zipAll.apply this, xss]
export compose = (...funcs) ->
->
args = arguments
for f in funcs
args = [f.apply this, args]
args.0
export curry = (f) ->
curry$ f # using util method curry$ from livescript
export id = (x) -> x
export flip = (f, x, y) --> f y, x
export fix = (f) ->
( (g, x) -> -> f(g g) ...arguments ) do
(g, x) -> -> f(g g) ...arguments
export lines = (str) ->
return [] if not str.length
str / \\n
export unlines = (strs) -> strs * \\n
export words = (str) ->
return [] if not str.length
str / /[ ]+/
export unwords = (strs) -> strs * ' '
export max = (>?)
export min = (<?)
export negate = (x) -> -x
export abs = Math.abs
export signum = (x) ->
| x < 0 => -1
| x > 0 => 1
| otherwise => 0
export quot = (x, y) --> ~~(x / y)
export rem = (%)
export div = (x, y) --> Math.floor x / y
export mod = (%%)
export recip = (1 /)
export pi = Math.PI
export tau = pi * 2
export exp = Math.exp
export sqrt = Math.sqrt
# changed from log as log is a
# common function for logging things
export ln = Math.log
export pow = (^)
export sin = Math.sin
export tan = Math.tan
export cos = Math.cos
export asin = Math.asin
export acos = Math.acos
export atan = Math.atan
export atan2 = (x, y) --> Math.atan2 x, y
# sinh
# tanh
# cosh
# asinh
# atanh
# acosh
export truncate = (x) -> ~~x
export round = Math.round
export ceiling = Math.ceil
export floor = Math.floor
export isItNaN = (x) -> x isnt x
export even = (x) -> x % 2 == 0
export odd = (x) -> x % 2 != 0
export gcd = (x, y) -->
x = Math.abs x
y = Math.abs y
until y is 0
z = x % y
x = y
y = z
x
export lcm = (x, y) -->
Math.abs Math.floor (x / (gcd x, y) * y)
# meta
export installPrelude = !(target) ->
unless target.prelude?isInstalled
target <<< out$ # using out$ generated by livescript
target <<< target.prelude.isInstalled = true
export prelude = out$
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
theme: "solarized light",
lineNumbers: true
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-livescript</code>.</p>
<p>The LiveScript mode was written by Kenneth Bentley.</p>
</article>

View File

@@ -0,0 +1,280 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
/**
* Link to the project's GitHub page:
* https://github.com/duralog/CodeMirror
*/
(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('livescript', function(){
var tokenBase = function(stream, state) {
var next_rule = state.next || "start";
if (next_rule) {
state.next = state.next;
var nr = Rules[next_rule];
if (nr.splice) {
for (var i$ = 0; i$ < nr.length; ++i$) {
var r = nr[i$];
if (r.regex && stream.match(r.regex)) {
state.next = r.next || state.next;
return r.token;
}
}
stream.next();
return 'error';
}
if (stream.match(r = Rules[next_rule])) {
if (r.regex && stream.match(r.regex)) {
state.next = r.next;
return r.token;
} else {
stream.next();
return 'error';
}
}
}
stream.next();
return 'error';
};
var external = {
startState: function(){
return {
next: 'start',
lastToken: {style: null, indent: 0, content: ""}
};
},
token: function(stream, state){
while (stream.pos == stream.start)
var style = tokenBase(stream, state);
state.lastToken = {
style: style,
indent: stream.indentation(),
content: stream.current()
};
return style.replace(/\./g, ' ');
},
indent: function(state){
var indentation = state.lastToken.indent;
if (state.lastToken.content.match(indenter)) {
indentation += 2;
}
return indentation;
}
};
return external;
});
var identifier = '(?![\\d\\s])[$\\w\\xAA-\\uFFDC](?:(?!\\s)[$\\w\\xAA-\\uFFDC]|-[A-Za-z])*';
var indenter = RegExp('(?:[({[=:]|[-~]>|\\b(?:e(?:lse|xport)|d(?:o|efault)|t(?:ry|hen)|finally|import(?:\\s*all)?|const|var|let|new|catch(?:\\s*' + identifier + ')?))\\s*$');
var keywordend = '(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))';
var stringfill = {
token: 'string',
regex: '.+'
};
var Rules = {
start: [
{
token: 'comment.doc',
regex: '/\\*',
next: 'comment'
}, {
token: 'comment',
regex: '#.*'
}, {
token: 'keyword',
regex: '(?:t(?:h(?:is|row|en)|ry|ypeof!?)|c(?:on(?:tinue|st)|a(?:se|tch)|lass)|i(?:n(?:stanceof)?|mp(?:ort(?:\\s+all)?|lements)|[fs])|d(?:e(?:fault|lete|bugger)|o)|f(?:or(?:\\s+own)?|inally|unction)|s(?:uper|witch)|e(?:lse|x(?:tends|port)|val)|a(?:nd|rguments)|n(?:ew|ot)|un(?:less|til)|w(?:hile|ith)|o[fr]|return|break|let|var|loop)' + keywordend
}, {
token: 'constant.language',
regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend
}, {
token: 'invalid.illegal',
regex: '(?:p(?:ackage|r(?:ivate|otected)|ublic)|i(?:mplements|nterface)|enum|static|yield)' + keywordend
}, {
token: 'language.support.class',
regex: '(?:R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|Array|Boolean|Date|Function|Number|Object|TypeError|URIError)' + keywordend
}, {
token: 'language.support.function',
regex: '(?:is(?:NaN|Finite)|parse(?:Int|Float)|Math|JSON|(?:en|de)codeURI(?:Component)?)' + keywordend
}, {
token: 'variable.language',
regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend
}, {
token: 'identifier',
regex: identifier + '\\s*:(?![:=])'
}, {
token: 'variable',
regex: identifier
}, {
token: 'keyword.operator',
regex: '(?:\\.{3}|\\s+\\?)'
}, {
token: 'keyword.variable',
regex: '(?:@+|::|\\.\\.)',
next: 'key'
}, {
token: 'keyword.operator',
regex: '\\.\\s*',
next: 'key'
}, {
token: 'string',
regex: '\\\\\\S[^\\s,;)}\\]]*'
}, {
token: 'string.doc',
regex: '\'\'\'',
next: 'qdoc'
}, {
token: 'string.doc',
regex: '"""',
next: 'qqdoc'
}, {
token: 'string',
regex: '\'',
next: 'qstring'
}, {
token: 'string',
regex: '"',
next: 'qqstring'
}, {
token: 'string',
regex: '`',
next: 'js'
}, {
token: 'string',
regex: '<\\[',
next: 'words'
}, {
token: 'string.regex',
regex: '//',
next: 'heregex'
}, {
token: 'string.regex',
regex: '\\/(?:[^[\\/\\n\\\\]*(?:(?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[\\/\\n\\\\]*)*)\\/[gimy$]{0,4}',
next: 'key'
}, {
token: 'constant.numeric',
regex: '(?:0x[\\da-fA-F][\\da-fA-F_]*|(?:[2-9]|[12]\\d|3[0-6])r[\\da-zA-Z][\\da-zA-Z_]*|(?:\\d[\\d_]*(?:\\.\\d[\\d_]*)?|\\.\\d[\\d_]*)(?:e[+-]?\\d[\\d_]*)?[\\w$]*)'
}, {
token: 'lparen',
regex: '[({[]'
}, {
token: 'rparen',
regex: '[)}\\]]',
next: 'key'
}, {
token: 'keyword.operator',
regex: '\\S+'
}, {
token: 'text',
regex: '\\s+'
}
],
heregex: [
{
token: 'string.regex',
regex: '.*?//[gimy$?]{0,4}',
next: 'start'
}, {
token: 'string.regex',
regex: '\\s*#{'
}, {
token: 'comment.regex',
regex: '\\s+(?:#.*)?'
}, {
token: 'string.regex',
regex: '\\S+'
}
],
key: [
{
token: 'keyword.operator',
regex: '[.?@!]+'
}, {
token: 'identifier',
regex: identifier,
next: 'start'
}, {
token: 'text',
regex: '',
next: 'start'
}
],
comment: [
{
token: 'comment.doc',
regex: '.*?\\*/',
next: 'start'
}, {
token: 'comment.doc',
regex: '.+'
}
],
qdoc: [
{
token: 'string',
regex: ".*?'''",
next: 'key'
}, stringfill
],
qqdoc: [
{
token: 'string',
regex: '.*?"""',
next: 'key'
}, stringfill
],
qstring: [
{
token: 'string',
regex: '[^\\\\\']*(?:\\\\.[^\\\\\']*)*\'',
next: 'key'
}, stringfill
],
qqstring: [
{
token: 'string',
regex: '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"',
next: 'key'
}, stringfill
],
js: [
{
token: 'string',
regex: '[^\\\\`]*(?:\\\\.[^\\\\`]*)*`',
next: 'key'
}, stringfill
],
words: [
{
token: 'string',
regex: '.*?\\]>',
next: 'key'
}, stringfill
]
};
for (var idx in Rules) {
var r = Rules[idx];
if (r.splice) {
for (var i = 0, len = r.length; i < len; ++i) {
var rr = r[i];
if (typeof rr.regex === 'string') {
Rules[idx][i].regex = new RegExp('^' + rr.regex);
}
}
} else if (typeof rr.regex === 'string') {
Rules[idx].regex = new RegExp('^' + r.regex);
}
}
CodeMirror.defineMIME('text/x-livescript', 'livescript');
});

View File

@@ -0,0 +1,85 @@
<!doctype html>
<title>CodeMirror: Lua mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/neat.css">
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="../../lib/codemirror.js"></script>
<script src="lua.js"></script>
<style>.CodeMirror {border: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">Lua</a>
</ul>
</div>
<article>
<h2>Lua mode</h2>
<form><textarea id="code" name="code">
--[[
example useless code to show lua syntax highlighting
this is multiline comment
]]
function blahblahblah(x)
local table = {
"asd" = 123,
"x" = 0.34,
}
if x ~= 3 then
print( x )
elseif x == "string"
my_custom_function( 0x34 )
else
unknown_function( "some string" )
end
--single line comment
end
function blablabla3()
for k,v in ipairs( table ) do
--abcde..
y=[=[
x=[[
x is a multi line string
]]
but its definition is iside a highest level string!
]=]
print(" \"\" ")
s = math.sin( x )
end
end
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
matchBrackets: true,
theme: "neat"
});
</script>
<p>Loosely based on Franciszek
Wawrzak's <a href="https://codemirror.net/1/contrib/lua">CodeMirror
1 mode</a>. One configuration parameter is
supported, <code>specials</code>, to which you can provide an
array of strings to have those identifiers highlighted with
the <code>lua-special</code> style.</p>
<p><strong>MIME types defined:</strong> <code>text/x-lua</code>.</p>
</article>

159
web/public/codemirror/mode/lua/lua.js vendored Normal file
View File

@@ -0,0 +1,159 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// LUA mode. Ported to CodeMirror 2 from Franciszek Wawrzak's
// CodeMirror 1 mode.
// highlights keywords, strings, comments (no leveling supported! ("[==[")), tokens, basic indenting
(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("lua", function(config, parserConfig) {
var indentUnit = config.indentUnit;
function prefixRE(words) {
return new RegExp("^(?:" + words.join("|") + ")", "i");
}
function wordRE(words) {
return new RegExp("^(?:" + words.join("|") + ")$", "i");
}
var specials = wordRE(parserConfig.specials || []);
// long list of standard functions from lua manual
var builtins = wordRE([
"_G","_VERSION","assert","collectgarbage","dofile","error","getfenv","getmetatable","ipairs","load",
"loadfile","loadstring","module","next","pairs","pcall","print","rawequal","rawget","rawset","require",
"select","setfenv","setmetatable","tonumber","tostring","type","unpack","xpcall",
"coroutine.create","coroutine.resume","coroutine.running","coroutine.status","coroutine.wrap","coroutine.yield",
"debug.debug","debug.getfenv","debug.gethook","debug.getinfo","debug.getlocal","debug.getmetatable",
"debug.getregistry","debug.getupvalue","debug.setfenv","debug.sethook","debug.setlocal","debug.setmetatable",
"debug.setupvalue","debug.traceback",
"close","flush","lines","read","seek","setvbuf","write",
"io.close","io.flush","io.input","io.lines","io.open","io.output","io.popen","io.read","io.stderr","io.stdin",
"io.stdout","io.tmpfile","io.type","io.write",
"math.abs","math.acos","math.asin","math.atan","math.atan2","math.ceil","math.cos","math.cosh","math.deg",
"math.exp","math.floor","math.fmod","math.frexp","math.huge","math.ldexp","math.log","math.log10","math.max",
"math.min","math.modf","math.pi","math.pow","math.rad","math.random","math.randomseed","math.sin","math.sinh",
"math.sqrt","math.tan","math.tanh",
"os.clock","os.date","os.difftime","os.execute","os.exit","os.getenv","os.remove","os.rename","os.setlocale",
"os.time","os.tmpname",
"package.cpath","package.loaded","package.loaders","package.loadlib","package.path","package.preload",
"package.seeall",
"string.byte","string.char","string.dump","string.find","string.format","string.gmatch","string.gsub",
"string.len","string.lower","string.match","string.rep","string.reverse","string.sub","string.upper",
"table.concat","table.insert","table.maxn","table.remove","table.sort"
]);
var keywords = wordRE(["and","break","elseif","false","nil","not","or","return",
"true","function", "end", "if", "then", "else", "do",
"while", "repeat", "until", "for", "in", "local" ]);
var indentTokens = wordRE(["function", "if","repeat","do", "\\(", "{"]);
var dedentTokens = wordRE(["end", "until", "\\)", "}"]);
var dedentPartial = prefixRE(["end", "until", "\\)", "}", "else", "elseif"]);
function readBracket(stream) {
var level = 0;
while (stream.eat("=")) ++level;
stream.eat("[");
return level;
}
function normal(stream, state) {
var ch = stream.next();
if (ch == "-" && stream.eat("-")) {
if (stream.eat("[") && stream.eat("["))
return (state.cur = bracketed(readBracket(stream), "comment"))(stream, state);
stream.skipToEnd();
return "comment";
}
if (ch == "\"" || ch == "'")
return (state.cur = string(ch))(stream, state);
if (ch == "[" && /[\[=]/.test(stream.peek()))
return (state.cur = bracketed(readBracket(stream), "string"))(stream, state);
if (/\d/.test(ch)) {
stream.eatWhile(/[\w.%]/);
return "number";
}
if (/[\w_]/.test(ch)) {
stream.eatWhile(/[\w\\\-_.]/);
return "variable";
}
return null;
}
function bracketed(level, style) {
return function(stream, state) {
var curlev = null, ch;
while ((ch = stream.next()) != null) {
if (curlev == null) {if (ch == "]") curlev = 0;}
else if (ch == "=") ++curlev;
else if (ch == "]" && curlev == level) { state.cur = normal; break; }
else curlev = null;
}
return style;
};
}
function string(quote) {
return function(stream, state) {
var escaped = false, ch;
while ((ch = stream.next()) != null) {
if (ch == quote && !escaped) break;
escaped = !escaped && ch == "\\";
}
if (!escaped) state.cur = normal;
return "string";
};
}
return {
startState: function(basecol) {
return {basecol: basecol || 0, indentDepth: 0, cur: normal};
},
token: function(stream, state) {
if (stream.eatSpace()) return null;
var style = state.cur(stream, state);
var word = stream.current();
if (style == "variable") {
if (keywords.test(word)) style = "keyword";
else if (builtins.test(word)) style = "builtin";
else if (specials.test(word)) style = "variable-2";
}
if ((style != "comment") && (style != "string")){
if (indentTokens.test(word)) ++state.indentDepth;
else if (dedentTokens.test(word)) --state.indentDepth;
}
return style;
},
indent: function(state, textAfter) {
var closing = dedentPartial.test(textAfter);
return state.basecol + indentUnit * (state.indentDepth - (closing ? 1 : 0));
},
lineComment: "--",
blockCommentStart: "--[[",
blockCommentEnd: "]]"
};
});
CodeMirror.defineMIME("text/x-lua", "lua");
});

View File

@@ -0,0 +1,411 @@
<!doctype html>
<title>CodeMirror: Markdown 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="../../addon/edit/continuelist.js"></script>
<script src="../xml/xml.js"></script>
<script src="markdown.js"></script>
<style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
.cm-s-default .cm-trailing-space-a:before,
.cm-s-default .cm-trailing-space-b:before {position: absolute; content: "\00B7"; color: #777;}
.cm-s-default .cm-trailing-space-new-line:before {position: absolute; content: "\21B5"; color: #777;}
</style>
<div id=nav>
<a href="https://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="#">Markdown</a>
</ul>
</div>
<article>
<h2>Markdown mode</h2>
<form><textarea id="code" name="code">
Markdown: Basics
================
&lt;ul id="ProjectSubmenu"&gt;
&lt;li&gt;&lt;a href="/projects/markdown/" title="Markdown Project Page"&gt;Main&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="selected" title="Markdown Basics"&gt;Basics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/projects/markdown/syntax" title="Markdown Syntax Documentation"&gt;Syntax&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/projects/markdown/license" title="Pricing and License Information"&gt;License&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/projects/markdown/dingus" title="Online Markdown Web Form"&gt;Dingus&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
Getting the Gist of Markdown's Formatting Syntax
------------------------------------------------
This page offers a brief overview of what it's like to use Markdown.
The [syntax page] [s] provides complete, detailed documentation for
every feature, but Markdown should be very easy to pick up simply by
looking at a few examples of it in action. The examples on this page
are written in a before/after style, showing example syntax and the
HTML output produced by Markdown.
It's also helpful to simply try Markdown out; the [Dingus] [d] is a
web application that allows you type your own Markdown-formatted text
and translate it to XHTML.
**Note:** This document is itself written using Markdown; you
can [see the source for it by adding '.text' to the URL] [src].
[s]: /projects/markdown/syntax "Markdown Syntax"
[d]: /projects/markdown/dingus "Markdown Dingus"
[src]: /projects/markdown/basics.text
## Paragraphs, Headers, Blockquotes ##
A paragraph is simply one or more consecutive lines of text, separated
by one or more blank lines. (A blank line is any line that looks like
a blank line -- a line containing nothing but spaces or tabs is
considered blank.) Normal paragraphs should not be indented with
spaces or tabs.
Markdown offers two styles of headers: *Setext* and *atx*.
Setext-style headers for `&lt;h1&gt;` and `&lt;h2&gt;` are created by
"underlining" with equal signs (`=`) and hyphens (`-`), respectively.
To create an atx-style header, you put 1-6 hash marks (`#`) at the
beginning of the line -- the number of hashes equals the resulting
HTML header level.
Blockquotes are indicated using email-style '`&gt;`' angle brackets.
Markdown:
A First Level Header
====================
A Second Level Header
---------------------
Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.
The quick brown fox jumped over the lazy
dog's back.
### Header 3
&gt; This is a blockquote.
&gt;
&gt; This is the second paragraph in the blockquote.
&gt;
&gt; ## This is an H2 in a blockquote
Output:
&lt;h1&gt;A First Level Header&lt;/h1&gt;
&lt;h2&gt;A Second Level Header&lt;/h2&gt;
&lt;p&gt;Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.&lt;/p&gt;
&lt;p&gt;The quick brown fox jumped over the lazy
dog's back.&lt;/p&gt;
&lt;h3&gt;Header 3&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a blockquote.&lt;/p&gt;
&lt;p&gt;This is the second paragraph in the blockquote.&lt;/p&gt;
&lt;h2&gt;This is an H2 in a blockquote&lt;/h2&gt;
&lt;/blockquote&gt;
### Phrase Emphasis ###
Markdown uses asterisks and underscores to indicate spans of emphasis.
Markdown:
Some of these words *are emphasized*.
Some of these words _are emphasized also_.
Use two asterisks for **strong emphasis**.
Or, if you prefer, __use two underscores instead__.
Output:
&lt;p&gt;Some of these words &lt;em&gt;are emphasized&lt;/em&gt;.
Some of these words &lt;em&gt;are emphasized also&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Use two asterisks for &lt;strong&gt;strong emphasis&lt;/strong&gt;.
Or, if you prefer, &lt;strong&gt;use two underscores instead&lt;/strong&gt;.&lt;/p&gt;
## Lists ##
Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,
`+`, and `-`) as list markers. These three markers are
interchangable; this:
* Candy.
* Gum.
* Booze.
this:
+ Candy.
+ Gum.
+ Booze.
and this:
- Candy.
- Gum.
- Booze.
all produce the same output:
&lt;ul&gt;
&lt;li&gt;Candy.&lt;/li&gt;
&lt;li&gt;Gum.&lt;/li&gt;
&lt;li&gt;Booze.&lt;/li&gt;
&lt;/ul&gt;
Ordered (numbered) lists use regular numbers, followed by periods, as
list markers:
1. Red
2. Green
3. Blue
Output:
&lt;ol&gt;
&lt;li&gt;Red&lt;/li&gt;
&lt;li&gt;Green&lt;/li&gt;
&lt;li&gt;Blue&lt;/li&gt;
&lt;/ol&gt;
If you put blank lines between items, you'll get `&lt;p&gt;` tags for the
list item text. You can create multi-paragraph list items by indenting
the paragraphs by 4 spaces or 1 tab:
* A list item.
With multiple paragraphs.
* Another item in the list.
Output:
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A list item.&lt;/p&gt;
&lt;p&gt;With multiple paragraphs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another item in the list.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
### Links ###
Markdown supports two styles for creating links: *inline* and
*reference*. With both styles, you use square brackets to delimit the
text you want to turn into a link.
Inline-style links use parentheses immediately after the link text.
For example:
This is an [example link](http://example.com/).
Output:
&lt;p&gt;This is an &lt;a href="http://example.com/"&gt;
example link&lt;/a&gt;.&lt;/p&gt;
Optionally, you may include a title attribute in the parentheses:
This is an [example link](http://example.com/ "With a Title").
Output:
&lt;p&gt;This is an &lt;a href="http://example.com/" title="With a Title"&gt;
example link&lt;/a&gt;.&lt;/p&gt;
Reference-style links allow you to refer to your links by names, which
you define elsewhere in your document:
I get 10 times more traffic from [Google][1] than from
[Yahoo][2] or [MSN][3].
[1]: http://google.com/ "Google"
[2]: http://search.yahoo.com/ "Yahoo Search"
[3]: http://search.msn.com/ "MSN Search"
Output:
&lt;p&gt;I get 10 times more traffic from &lt;a href="http://google.com/"
title="Google"&gt;Google&lt;/a&gt; than from &lt;a href="http://search.yahoo.com/"
title="Yahoo Search"&gt;Yahoo&lt;/a&gt; or &lt;a href="http://search.msn.com/"
title="MSN Search"&gt;MSN&lt;/a&gt;.&lt;/p&gt;
The title attribute is optional. Link names may contain letters,
numbers and spaces, but are *not* case sensitive:
I start my morning with a cup of coffee and
[The New York Times][NY Times].
[ny times]: http://www.nytimes.com/
Output:
&lt;p&gt;I start my morning with a cup of coffee and
&lt;a href="http://www.nytimes.com/"&gt;The New York Times&lt;/a&gt;.&lt;/p&gt;
### Images ###
Image syntax is very much like link syntax.
Inline (titles are optional):
![alt text](/path/to/img.jpg "Title")
Reference-style:
![alt text][id]
[id]: /path/to/img.jpg "Title"
Both of the above examples produce the same output:
&lt;img src="/path/to/img.jpg" alt="alt text" title="Title" /&gt;
### Code ###
In a regular paragraph, you can create code span by wrapping text in
backtick quotes. Any ampersands (`&amp;`) and angle brackets (`&lt;` or
`&gt;`) will automatically be translated into HTML entities. This makes
it easy to use Markdown to write about HTML example code:
I strongly recommend against using any `&lt;blink&gt;` tags.
I wish SmartyPants used named entities like `&amp;mdash;`
instead of decimal-encoded entites like `&amp;#8212;`.
Output:
&lt;p&gt;I strongly recommend against using any
&lt;code&gt;&amp;lt;blink&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;
&lt;p&gt;I wish SmartyPants used named entities like
&lt;code&gt;&amp;amp;mdash;&lt;/code&gt; instead of decimal-encoded
entites like &lt;code&gt;&amp;amp;#8212;&lt;/code&gt;.&lt;/p&gt;
To specify an entire block of pre-formatted code, indent every line of
the block by 4 spaces or 1 tab. Just like with code spans, `&amp;`, `&lt;`,
and `&gt;` characters will be escaped automatically.
Markdown:
If you want your page to validate under XHTML 1.0 Strict,
you've got to put paragraph tags in your blockquotes:
&lt;blockquote&gt;
&lt;p&gt;For example.&lt;/p&gt;
&lt;/blockquote&gt;
Output:
&lt;p&gt;If you want your page to validate under XHTML 1.0 Strict,
you've got to put paragraph tags in your blockquotes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;blockquote&amp;gt;
&amp;lt;p&amp;gt;For example.&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
## Fenced code blocks (and syntax highlighting)
```javascript
for (var i = 0; i < items.length; i++) {
console.log(items[i], i); // log them
}
```
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: 'markdown',
lineNumbers: true,
theme: "default",
extraKeys: {"Enter": "newlineAndIndentContinueMarkdownList"}
});
</script>
<p>If you also want support <code>strikethrough</code>, <code>emoji</code> and few other goodies, check out <a href="../gfm/index.html">Github-Flavored Markdown mode</a>.</p>
<p>Optionally depends on other modes for properly highlighted code blocks,
and XML mode for properly highlighted inline XML blocks.</p>
<p>Markdown mode supports these options:</p>
<ul>
<li>
<d1>
<dt><code>highlightFormatting: boolean</code></dt>
<dd>Whether to separately highlight markdown meta characterts (<code>*[]()</code>etc.) (default: <code>false</code>).</dd>
</d1>
</li>
<li>
<d1>
<dt><code>maxBlockquoteDepth: boolean</code></dt>
<dd>Maximum allowed blockquote nesting (default: <code>0</code> - infinite nesting).</dd>
</d1>
</li>
<li>
<d1>
<dt><code>xml: boolean</code></dt>
<dd>Whether to highlight inline XML (default: <code>true</code>).</dd>
</d1>
</li>
<li>
<d1>
<dt><code>fencedCodeBlockHighlighting: boolean</code></dt>
<dd>Whether to syntax-highlight fenced code blocks, if given mode is included (default: <code>true</code>).</dd>
</d1>
</li>
<li>
<d1>
<dt><code>tokenTypeOverrides: Object</code></dt>
<dd>When you want ot override default token type names (e.g. <code>{code: "code"}</code>).</dd>
</d1>
</li>
<li>
<d1>
<dt><code>allowAtxHeaderWithoutSpace: boolean</code></dt>
<dd>Allow lazy headers without whitespace between hashtag and text (default: <code>false</code>).</dd>
</d1>
</li>
</ul>
<p><strong>MIME types defined:</strong> <code>text/x-markdown</code>.</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#markdown_*">normal</a>, <a href="../../test/index.html#verbose,markdown_*">verbose</a>.</p>
</article>

View File

@@ -0,0 +1,884 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../xml/xml", "../meta"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
var htmlMode = CodeMirror.getMode(cmCfg, "text/html");
var htmlModeMissing = htmlMode.name == "null"
function getMode(name) {
if (CodeMirror.findModeByName) {
var found = CodeMirror.findModeByName(name);
if (found) name = found.mime || found.mimes[0];
}
var mode = CodeMirror.getMode(cmCfg, name);
return mode.name == "null" ? null : mode;
}
// Should characters that affect highlighting be highlighted separate?
// Does not include characters that will be output (such as `1.` and `-` for lists)
if (modeCfg.highlightFormatting === undefined)
modeCfg.highlightFormatting = false;
// Maximum number of nested blockquotes. Set to 0 for infinite nesting.
// Excess `>` will emit `error` token.
if (modeCfg.maxBlockquoteDepth === undefined)
modeCfg.maxBlockquoteDepth = 0;
// Turn on task lists? ("- [ ] " and "- [x] ")
if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
// Turn on strikethrough syntax
if (modeCfg.strikethrough === undefined)
modeCfg.strikethrough = false;
if (modeCfg.emoji === undefined)
modeCfg.emoji = false;
if (modeCfg.fencedCodeBlockHighlighting === undefined)
modeCfg.fencedCodeBlockHighlighting = true;
if (modeCfg.xml === undefined)
modeCfg.xml = true;
// Allow token types to be overridden by user-provided token types.
if (modeCfg.tokenTypeOverrides === undefined)
modeCfg.tokenTypeOverrides = {};
var tokenTypes = {
header: "header",
code: "comment",
quote: "quote",
list1: "variable-2",
list2: "variable-3",
list3: "keyword",
hr: "hr",
image: "image",
imageAltText: "image-alt-text",
imageMarker: "image-marker",
formatting: "formatting",
linkInline: "link",
linkEmail: "link",
linkText: "link",
linkHref: "string",
em: "em",
strong: "strong",
strikethrough: "strikethrough",
emoji: "builtin"
};
for (var tokenType in tokenTypes) {
if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) {
tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType];
}
}
var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
, listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/
, taskListRE = /^\[(x| )\](?=\s)/i // Must follow listRE
, atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
, setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
, textRE = /^[^#!\[\]*_\\<>` "'(~:]+/
, fencedCodeRE = /^(~~~+|```+)[ \t]*([\w+#-]*)[^\n`]*$/
, linkDefRE = /^\s*\[[^\]]+?\]:.*$/ // naive link-definition
, punctuation = /[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E42\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDF3C-\uDF3E]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]/
, expandedTab = " " // CommonMark specifies tab as 4 spaces
function switchInline(stream, state, f) {
state.f = state.inline = f;
return f(stream, state);
}
function switchBlock(stream, state, f) {
state.f = state.block = f;
return f(stream, state);
}
function lineIsEmpty(line) {
return !line || !/\S/.test(line.string)
}
// Blocks
function blankLine(state) {
// Reset linkTitle state
state.linkTitle = false;
state.linkHref = false;
state.linkText = false;
// Reset EM state
state.em = false;
// Reset STRONG state
state.strong = false;
// Reset strikethrough state
state.strikethrough = false;
// Reset state.quote
state.quote = 0;
// Reset state.indentedCode
state.indentedCode = false;
if (state.f == htmlBlock) {
var exit = htmlModeMissing
if (!exit) {
var inner = CodeMirror.innerMode(htmlMode, state.htmlState)
exit = inner.mode.name == "xml" && inner.state.tagStart === null &&
(!inner.state.context && inner.state.tokenize.isInText)
}
if (exit) {
state.f = inlineNormal;
state.block = blockNormal;
state.htmlState = null;
}
}
// Reset state.trailingSpace
state.trailingSpace = 0;
state.trailingSpaceNewLine = false;
// Mark this line as blank
state.prevLine = state.thisLine
state.thisLine = {stream: null}
return null;
}
function blockNormal(stream, state) {
var firstTokenOnLine = stream.column() === state.indentation;
var prevLineLineIsEmpty = lineIsEmpty(state.prevLine.stream);
var prevLineIsIndentedCode = state.indentedCode;
var prevLineIsHr = state.prevLine.hr;
var prevLineIsList = state.list !== false;
var maxNonCodeIndentation = (state.listStack[state.listStack.length - 1] || 0) + 3;
state.indentedCode = false;
var lineIndentation = state.indentation;
// compute once per line (on first token)
if (state.indentationDiff === null) {
state.indentationDiff = state.indentation;
if (prevLineIsList) {
// Reset inline styles which shouldn't propagate aross list items
state.em = false;
state.strong = false;
state.code = false;
state.strikethrough = false;
state.list = null;
// While this list item's marker's indentation is less than the deepest
// list item's content's indentation,pop the deepest list item
// indentation off the stack, and update block indentation state
while (lineIndentation < state.listStack[state.listStack.length - 1]) {
state.listStack.pop();
if (state.listStack.length) {
state.indentation = state.listStack[state.listStack.length - 1];
// less than the first list's indent -> the line is no longer a list
} else {
state.list = false;
}
}
if (state.list !== false) {
state.indentationDiff = lineIndentation - state.listStack[state.listStack.length - 1]
}
}
}
// not comprehensive (currently only for setext detection purposes)
var allowsInlineContinuation = (
!prevLineLineIsEmpty && !prevLineIsHr && !state.prevLine.header &&
(!prevLineIsList || !prevLineIsIndentedCode) &&
!state.prevLine.fencedCodeEnd
);
var isHr = (state.list === false || prevLineIsHr || prevLineLineIsEmpty) &&
state.indentation <= maxNonCodeIndentation && stream.match(hrRE);
var match = null;
if (state.indentationDiff >= 4 && (prevLineIsIndentedCode || state.prevLine.fencedCodeEnd ||
state.prevLine.header || prevLineLineIsEmpty)) {
stream.skipToEnd();
state.indentedCode = true;
return tokenTypes.code;
} else if (stream.eatSpace()) {
return null;
} else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
state.quote = 0;
state.header = match[1].length;
state.thisLine.header = true;
if (modeCfg.highlightFormatting) state.formatting = "header";
state.f = state.inline;
return getType(state);
} else if (state.indentation <= maxNonCodeIndentation && stream.eat('>')) {
state.quote = firstTokenOnLine ? 1 : state.quote + 1;
if (modeCfg.highlightFormatting) state.formatting = "quote";
stream.eatSpace();
return getType(state);
} else if (!isHr && !state.setext && firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(listRE))) {
var listType = match[1] ? "ol" : "ul";
state.indentation = lineIndentation + stream.current().length;
state.list = true;
state.quote = 0;
// Add this list item's content's indentation to the stack
state.listStack.push(state.indentation);
if (modeCfg.taskLists && stream.match(taskListRE, false)) {
state.taskList = true;
}
state.f = state.inline;
if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
return getType(state);
} else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(fencedCodeRE, true))) {
state.quote = 0;
state.fencedEndRE = new RegExp(match[1] + "+ *$");
// try switching mode
state.localMode = modeCfg.fencedCodeBlockHighlighting && getMode(match[2]);
if (state.localMode) state.localState = CodeMirror.startState(state.localMode);
state.f = state.block = local;
if (modeCfg.highlightFormatting) state.formatting = "code-block";
state.code = -1
return getType(state);
// SETEXT has lowest block-scope precedence after HR, so check it after
// the others (code, blockquote, list...)
} else if (
// if setext set, indicates line after ---/===
state.setext || (
// line before ---/===
(!allowsInlineContinuation || !prevLineIsList) && !state.quote && state.list === false &&
!state.code && !isHr && !linkDefRE.test(stream.string) &&
(match = stream.lookAhead(1)) && (match = match.match(setextHeaderRE))
)
) {
if ( !state.setext ) {
state.header = match[0].charAt(0) == '=' ? 1 : 2;
state.setext = state.header;
} else {
state.header = state.setext;
// has no effect on type so we can reset it now
state.setext = 0;
stream.skipToEnd();
if (modeCfg.highlightFormatting) state.formatting = "header";
}
state.thisLine.header = true;
state.f = state.inline;
return getType(state);
} else if (isHr) {
stream.skipToEnd();
state.hr = true;
state.thisLine.hr = true;
return tokenTypes.hr;
} else if (stream.peek() === '[') {
return switchInline(stream, state, footnoteLink);
}
return switchInline(stream, state, state.inline);
}
function htmlBlock(stream, state) {
var style = htmlMode.token(stream, state.htmlState);
if (!htmlModeMissing) {
var inner = CodeMirror.innerMode(htmlMode, state.htmlState)
if ((inner.mode.name == "xml" && inner.state.tagStart === null &&
(!inner.state.context && inner.state.tokenize.isInText)) ||
(state.md_inside && stream.current().indexOf(">") > -1)) {
state.f = inlineNormal;
state.block = blockNormal;
state.htmlState = null;
}
}
return style;
}
function local(stream, state) {
var currListInd = state.listStack[state.listStack.length - 1] || 0;
var hasExitedList = state.indentation < currListInd;
var maxFencedEndInd = currListInd + 3;
if (state.fencedEndRE && state.indentation <= maxFencedEndInd && (hasExitedList || stream.match(state.fencedEndRE))) {
if (modeCfg.highlightFormatting) state.formatting = "code-block";
var returnType;
if (!hasExitedList) returnType = getType(state)
state.localMode = state.localState = null;
state.block = blockNormal;
state.f = inlineNormal;
state.fencedEndRE = null;
state.code = 0
state.thisLine.fencedCodeEnd = true;
if (hasExitedList) return switchBlock(stream, state, state.block);
return returnType;
} else if (state.localMode) {
return state.localMode.token(stream, state.localState);
} else {
stream.skipToEnd();
return tokenTypes.code;
}
}
// Inline
function getType(state) {
var styles = [];
if (state.formatting) {
styles.push(tokenTypes.formatting);
if (typeof state.formatting === "string") state.formatting = [state.formatting];
for (var i = 0; i < state.formatting.length; i++) {
styles.push(tokenTypes.formatting + "-" + state.formatting[i]);
if (state.formatting[i] === "header") {
styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header);
}
// Add `formatting-quote` and `formatting-quote-#` for blockquotes
// Add `error` instead if the maximum blockquote nesting depth is passed
if (state.formatting[i] === "quote") {
if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote);
} else {
styles.push("error");
}
}
}
}
if (state.taskOpen) {
styles.push("meta");
return styles.length ? styles.join(' ') : null;
}
if (state.taskClosed) {
styles.push("property");
return styles.length ? styles.join(' ') : null;
}
if (state.linkHref) {
styles.push(tokenTypes.linkHref, "url");
} else { // Only apply inline styles to non-url text
if (state.strong) { styles.push(tokenTypes.strong); }
if (state.em) { styles.push(tokenTypes.em); }
if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
if (state.emoji) { styles.push(tokenTypes.emoji); }
if (state.linkText) { styles.push(tokenTypes.linkText); }
if (state.code) { styles.push(tokenTypes.code); }
if (state.image) { styles.push(tokenTypes.image); }
if (state.imageAltText) { styles.push(tokenTypes.imageAltText, "link"); }
if (state.imageMarker) { styles.push(tokenTypes.imageMarker); }
}
if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); }
if (state.quote) {
styles.push(tokenTypes.quote);
// Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
styles.push(tokenTypes.quote + "-" + state.quote);
} else {
styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth);
}
}
if (state.list !== false) {
var listMod = (state.listStack.length - 1) % 3;
if (!listMod) {
styles.push(tokenTypes.list1);
} else if (listMod === 1) {
styles.push(tokenTypes.list2);
} else {
styles.push(tokenTypes.list3);
}
}
if (state.trailingSpaceNewLine) {
styles.push("trailing-space-new-line");
} else if (state.trailingSpace) {
styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
}
return styles.length ? styles.join(' ') : null;
}
function handleText(stream, state) {
if (stream.match(textRE, true)) {
return getType(state);
}
return undefined;
}
function inlineNormal(stream, state) {
var style = state.text(stream, state);
if (typeof style !== 'undefined')
return style;
if (state.list) { // List marker (*, +, -, 1., etc)
state.list = null;
return getType(state);
}
if (state.taskList) {
var taskOpen = stream.match(taskListRE, true)[1] === " ";
if (taskOpen) state.taskOpen = true;
else state.taskClosed = true;
if (modeCfg.highlightFormatting) state.formatting = "task";
state.taskList = false;
return getType(state);
}
state.taskOpen = false;
state.taskClosed = false;
if (state.header && stream.match(/^#+$/, true)) {
if (modeCfg.highlightFormatting) state.formatting = "header";
return getType(state);
}
var ch = stream.next();
// Matches link titles present on next line
if (state.linkTitle) {
state.linkTitle = false;
var matchCh = ch;
if (ch === '(') {
matchCh = ')';
}
matchCh = (matchCh+'').replace(/([.?*+^\[\]\\(){}|-])/g, "\\$1");
var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
if (stream.match(new RegExp(regex), true)) {
return tokenTypes.linkHref;
}
}
// If this block is changed, it may need to be updated in GFM mode
if (ch === '`') {
var previousFormatting = state.formatting;
if (modeCfg.highlightFormatting) state.formatting = "code";
stream.eatWhile('`');
var count = stream.current().length
if (state.code == 0 && (!state.quote || count == 1)) {
state.code = count
return getType(state)
} else if (count == state.code) { // Must be exact
var t = getType(state)
state.code = 0
return t
} else {
state.formatting = previousFormatting
return getType(state)
}
} else if (state.code) {
return getType(state);
}
if (ch === '\\') {
stream.next();
if (modeCfg.highlightFormatting) {
var type = getType(state);
var formattingEscape = tokenTypes.formatting + "-escape";
return type ? type + " " + formattingEscape : formattingEscape;
}
}
if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
state.imageMarker = true;
state.image = true;
if (modeCfg.highlightFormatting) state.formatting = "image";
return getType(state);
}
if (ch === '[' && state.imageMarker && stream.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/, false)) {
state.imageMarker = false;
state.imageAltText = true
if (modeCfg.highlightFormatting) state.formatting = "image";
return getType(state);
}
if (ch === ']' && state.imageAltText) {
if (modeCfg.highlightFormatting) state.formatting = "image";
var type = getType(state);
state.imageAltText = false;
state.image = false;
state.inline = state.f = linkHref;
return type;
}
if (ch === '[' && !state.image) {
if (state.linkText && stream.match(/^.*?\]/)) return getType(state)
state.linkText = true;
if (modeCfg.highlightFormatting) state.formatting = "link";
return getType(state);
}
if (ch === ']' && state.linkText) {
if (modeCfg.highlightFormatting) state.formatting = "link";
var type = getType(state);
state.linkText = false;
state.inline = state.f = stream.match(/\(.*?\)| ?\[.*?\]/, false) ? linkHref : inlineNormal
return type;
}
if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
state.f = state.inline = linkInline;
if (modeCfg.highlightFormatting) state.formatting = "link";
var type = getType(state);
if (type){
type += " ";
} else {
type = "";
}
return type + tokenTypes.linkInline;
}
if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
state.f = state.inline = linkInline;
if (modeCfg.highlightFormatting) state.formatting = "link";
var type = getType(state);
if (type){
type += " ";
} else {
type = "";
}
return type + tokenTypes.linkEmail;
}
if (modeCfg.xml && ch === '<' && stream.match(/^(!--|\?|!\[CDATA\[|[a-z][a-z0-9-]*(?:\s+[a-z_:.\-]+(?:\s*=\s*[^>]+)?)*\s*(?:>|$))/i, false)) {
var end = stream.string.indexOf(">", stream.pos);
if (end != -1) {
var atts = stream.string.substring(stream.start, end);
if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true;
}
stream.backUp(1);
state.htmlState = CodeMirror.startState(htmlMode);
return switchBlock(stream, state, htmlBlock);
}
if (modeCfg.xml && ch === '<' && stream.match(/^\/\w*?>/)) {
state.md_inside = false;
return "tag";
} else if (ch === "*" || ch === "_") {
var len = 1, before = stream.pos == 1 ? " " : stream.string.charAt(stream.pos - 2)
while (len < 3 && stream.eat(ch)) len++
var after = stream.peek() || " "
// See http://spec.commonmark.org/0.27/#emphasis-and-strong-emphasis
var leftFlanking = !/\s/.test(after) && (!punctuation.test(after) || /\s/.test(before) || punctuation.test(before))
var rightFlanking = !/\s/.test(before) && (!punctuation.test(before) || /\s/.test(after) || punctuation.test(after))
var setEm = null, setStrong = null
if (len % 2) { // Em
if (!state.em && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before)))
setEm = true
else if (state.em == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after)))
setEm = false
}
if (len > 1) { // Strong
if (!state.strong && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before)))
setStrong = true
else if (state.strong == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after)))
setStrong = false
}
if (setStrong != null || setEm != null) {
if (modeCfg.highlightFormatting) state.formatting = setEm == null ? "strong" : setStrong == null ? "em" : "strong em"
if (setEm === true) state.em = ch
if (setStrong === true) state.strong = ch
var t = getType(state)
if (setEm === false) state.em = false
if (setStrong === false) state.strong = false
return t
}
} else if (ch === ' ') {
if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
if (stream.peek() === ' ') { // Surrounded by spaces, ignore
return getType(state);
} else { // Not surrounded by spaces, back up pointer
stream.backUp(1);
}
}
}
if (modeCfg.strikethrough) {
if (ch === '~' && stream.eatWhile(ch)) {
if (state.strikethrough) {// Remove strikethrough
if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
var t = getType(state);
state.strikethrough = false;
return t;
} else if (stream.match(/^[^\s]/, false)) {// Add strikethrough
state.strikethrough = true;
if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
return getType(state);
}
} else if (ch === ' ') {
if (stream.match(/^~~/, true)) { // Probably surrounded by space
if (stream.peek() === ' ') { // Surrounded by spaces, ignore
return getType(state);
} else { // Not surrounded by spaces, back up pointer
stream.backUp(2);
}
}
}
}
if (modeCfg.emoji && ch === ":" && stream.match(/^(?:[a-z_\d+][a-z_\d+-]*|\-[a-z_\d+][a-z_\d+-]*):/)) {
state.emoji = true;
if (modeCfg.highlightFormatting) state.formatting = "emoji";
var retType = getType(state);
state.emoji = false;
return retType;
}
if (ch === ' ') {
if (stream.match(/^ +$/, false)) {
state.trailingSpace++;
} else if (state.trailingSpace) {
state.trailingSpaceNewLine = true;
}
}
return getType(state);
}
function linkInline(stream, state) {
var ch = stream.next();
if (ch === ">") {
state.f = state.inline = inlineNormal;
if (modeCfg.highlightFormatting) state.formatting = "link";
var type = getType(state);
if (type){
type += " ";
} else {
type = "";
}
return type + tokenTypes.linkInline;
}
stream.match(/^[^>]+/, true);
return tokenTypes.linkInline;
}
function linkHref(stream, state) {
// Check if space, and return NULL if so (to avoid marking the space)
if(stream.eatSpace()){
return null;
}
var ch = stream.next();
if (ch === '(' || ch === '[') {
state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
if (modeCfg.highlightFormatting) state.formatting = "link-string";
state.linkHref = true;
return getType(state);
}
return 'error';
}
var linkRE = {
")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,
"]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/
}
function getLinkHrefInside(endChar) {
return function(stream, state) {
var ch = stream.next();
if (ch === endChar) {
state.f = state.inline = inlineNormal;
if (modeCfg.highlightFormatting) state.formatting = "link-string";
var returnState = getType(state);
state.linkHref = false;
return returnState;
}
stream.match(linkRE[endChar])
state.linkHref = true;
return getType(state);
};
}
function footnoteLink(stream, state) {
if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) {
state.f = footnoteLinkInside;
stream.next(); // Consume [
if (modeCfg.highlightFormatting) state.formatting = "link";
state.linkText = true;
return getType(state);
}
return switchInline(stream, state, inlineNormal);
}
function footnoteLinkInside(stream, state) {
if (stream.match(/^\]:/, true)) {
state.f = state.inline = footnoteUrl;
if (modeCfg.highlightFormatting) state.formatting = "link";
var returnType = getType(state);
state.linkText = false;
return returnType;
}
stream.match(/^([^\]\\]|\\.)+/, true);
return tokenTypes.linkText;
}
function footnoteUrl(stream, state) {
// Check if space, and return NULL if so (to avoid marking the space)
if(stream.eatSpace()){
return null;
}
// Match URL
stream.match(/^[^\s]+/, true);
// Check for link title
if (stream.peek() === undefined) { // End of line, set flag to check next line
state.linkTitle = true;
} else { // More content on line, check if link title
stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
}
state.f = state.inline = inlineNormal;
return tokenTypes.linkHref + " url";
}
var mode = {
startState: function() {
return {
f: blockNormal,
prevLine: {stream: null},
thisLine: {stream: null},
block: blockNormal,
htmlState: null,
indentation: 0,
inline: inlineNormal,
text: handleText,
formatting: false,
linkText: false,
linkHref: false,
linkTitle: false,
code: 0,
em: false,
strong: false,
header: 0,
setext: 0,
hr: false,
taskList: false,
list: false,
listStack: [],
quote: 0,
trailingSpace: 0,
trailingSpaceNewLine: false,
strikethrough: false,
emoji: false,
fencedEndRE: null
};
},
copyState: function(s) {
return {
f: s.f,
prevLine: s.prevLine,
thisLine: s.thisLine,
block: s.block,
htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
indentation: s.indentation,
localMode: s.localMode,
localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
inline: s.inline,
text: s.text,
formatting: false,
linkText: s.linkText,
linkTitle: s.linkTitle,
linkHref: s.linkHref,
code: s.code,
em: s.em,
strong: s.strong,
strikethrough: s.strikethrough,
emoji: s.emoji,
header: s.header,
setext: s.setext,
hr: s.hr,
taskList: s.taskList,
list: s.list,
listStack: s.listStack.slice(0),
quote: s.quote,
indentedCode: s.indentedCode,
trailingSpace: s.trailingSpace,
trailingSpaceNewLine: s.trailingSpaceNewLine,
md_inside: s.md_inside,
fencedEndRE: s.fencedEndRE
};
},
token: function(stream, state) {
// Reset state.formatting
state.formatting = false;
if (stream != state.thisLine.stream) {
state.header = 0;
state.hr = false;
if (stream.match(/^\s*$/, true)) {
blankLine(state);
return null;
}
state.prevLine = state.thisLine
state.thisLine = {stream: stream}
// Reset state.taskList
state.taskList = false;
// Reset state.trailingSpace
state.trailingSpace = 0;
state.trailingSpaceNewLine = false;
if (!state.localState) {
state.f = state.block;
if (state.f != htmlBlock) {
var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, expandedTab).length;
state.indentation = indentation;
state.indentationDiff = null;
if (indentation > 0) return null;
}
}
}
return state.f(stream, state);
},
innerMode: function(state) {
if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};
if (state.localState) return {state: state.localState, mode: state.localMode};
return {state: state, mode: mode};
},
indent: function(state, textAfter, line) {
if (state.block == htmlBlock && htmlMode.indent) return htmlMode.indent(state.htmlState, textAfter, line)
if (state.localState && state.localMode.indent) return state.localMode.indent(state.localState, textAfter, line)
return CodeMirror.Pass
},
blankLine: blankLine,
getType: getType,
blockCommentStart: "<!--",
blockCommentEnd: "-->",
closeBrackets: "()[]{}''\"\"``",
fold: "markdown"
};
return mode;
}, "xml");
CodeMirror.defineMIME("text/markdown", "markdown");
CodeMirror.defineMIME("text/x-markdown", "markdown");
});

File diff suppressed because it is too large Load Diff

217
web/public/codemirror/mode/meta.js vendored Normal file
View File

@@ -0,0 +1,217 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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.modeInfo = [
{name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]},
{name: "PGP", mimes: ["application/pgp", "application/pgp-encrypted", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["asc", "pgp", "sig"]},
{name: "ASN.1", mime: "text/x-ttcn-asn", mode: "asn.1", ext: ["asn", "asn1"]},
{name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i},
{name: "Brainfuck", mime: "text/x-brainfuck", mode: "brainfuck", ext: ["b", "bf"]},
{name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h", "ino"]},
{name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]},
{name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]},
{name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp"]},
{name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj", "cljc", "cljx"]},
{name: "ClojureScript", mime: "text/x-clojurescript", mode: "clojure", ext: ["cljs"]},
{name: "Closure Stylesheets (GSS)", mime: "text/x-gss", mode: "css", ext: ["gss"]},
{name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists.txt$/},
{name: "CoffeeScript", mimes: ["application/vnd.coffeescript", "text/coffeescript", "text/x-coffeescript"], mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]},
{name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]},
{name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]},
{name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]},
{name: "Crystal", mime: "text/x-crystal", mode: "crystal", ext: ["cr"]},
{name: "CSS", mime: "text/css", mode: "css", ext: ["css"]},
{name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]},
{name: "D", mime: "text/x-d", mode: "d", ext: ["d"]},
{name: "Dart", mimes: ["application/dart", "text/x-dart"], mode: "dart", ext: ["dart"]},
{name: "diff", mime: "text/x-diff", mode: "diff", ext: ["diff", "patch"]},
{name: "Django", mime: "text/x-django", mode: "django"},
{name: "Dockerfile", mime: "text/x-dockerfile", mode: "dockerfile", file: /^Dockerfile$/},
{name: "DTD", mime: "application/xml-dtd", mode: "dtd", ext: ["dtd"]},
{name: "Dylan", mime: "text/x-dylan", mode: "dylan", ext: ["dylan", "dyl", "intr"]},
{name: "EBNF", mime: "text/x-ebnf", mode: "ebnf"},
{name: "ECL", mime: "text/x-ecl", mode: "ecl", ext: ["ecl"]},
{name: "edn", mime: "application/edn", mode: "clojure", ext: ["edn"]},
{name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]},
{name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]},
{name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]},
{name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]},
{name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]},
{name: "Esper", mime: "text/x-esper", mode: "sql"},
{name: "Factor", mime: "text/x-factor", mode: "factor", ext: ["factor"]},
{name: "FCL", mime: "text/x-fcl", mode: "fcl"},
{name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]},
{name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90"]},
{name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]},
{name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]},
{name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]},
{name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history).md$/i},
{name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]},
{name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy", "gradle"], file: /^Jenkinsfile$/},
{name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]},
{name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]},
{name: "Haskell (Literate)", mime: "text/x-literate-haskell", mode: "haskell-literate", ext: ["lhs"]},
{name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]},
{name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]},
{name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]},
{name: "HTML", mime: "text/html", mode: "htmlmixed", ext: ["html", "htm", "handlebars", "hbs"], alias: ["xhtml"]},
{name: "HTTP", mime: "message/http", mode: "http"},
{name: "IDL", mime: "text/x-idl", mode: "idl", ext: ["pro"]},
{name: "Pug", mime: "text/x-pug", mode: "pug", ext: ["jade", "pug"], alias: ["jade"]},
{name: "Java", mime: "text/x-java", mode: "clike", ext: ["java"]},
{name: "Java Server Pages", mime: "application/x-jsp", mode: "htmlembedded", ext: ["jsp"], alias: ["jsp"]},
{name: "JavaScript", mimes: ["text/javascript", "text/ecmascript", "application/javascript", "application/x-javascript", "application/ecmascript"],
mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]},
{name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]},
{name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]},
{name: "JSX", mime: "text/jsx", mode: "jsx", ext: ["jsx"]},
{name: "Jinja2", mime: "null", mode: "jinja2", ext: ["j2", "jinja", "jinja2"]},
{name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]},
{name: "Kotlin", mime: "text/x-kotlin", mode: "clike", ext: ["kt"]},
{name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]},
{name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]},
{name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]},
{name: "Markdown", mime: "text/x-markdown", mode: "markdown", ext: ["markdown", "md", "mkd"]},
{name: "mIRC", mime: "text/mirc", mode: "mirc"},
{name: "MariaDB SQL", mime: "text/x-mariadb", mode: "sql"},
{name: "Mathematica", mime: "text/x-mathematica", mode: "mathematica", ext: ["m", "nb"]},
{name: "Modelica", mime: "text/x-modelica", mode: "modelica", ext: ["mo"]},
{name: "MUMPS", mime: "text/x-mumps", mode: "mumps", ext: ["mps"]},
{name: "MS SQL", mime: "text/x-mssql", mode: "sql"},
{name: "mbox", mime: "application/mbox", mode: "mbox", ext: ["mbox"]},
{name: "MySQL", mime: "text/x-mysql", mode: "sql"},
{name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i},
{name: "NSIS", mime: "text/x-nsis", mode: "nsis", ext: ["nsh", "nsi"]},
{name: "NTriples", mimes: ["application/n-triples", "application/n-quads", "text/n-triples"],
mode: "ntriples", ext: ["nt", "nq"]},
{name: "Objective-C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"], alias: ["objective-c", "objc"]},
{name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]},
{name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]},
{name: "Oz", mime: "text/x-oz", mode: "oz", ext: ["oz"]},
{name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]},
{name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]},
{name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]},
{name: "PHP", mimes: ["text/x-php", "application/x-httpd-php", "application/x-httpd-php-open"], mode: "php", ext: ["php", "php3", "php4", "php5", "php7", "phtml"]},
{name: "Pig", mime: "text/x-pig", mode: "pig", ext: ["pig"]},
{name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]},
{name: "PLSQL", mime: "text/x-plsql", mode: "sql", ext: ["pls"]},
{name: "PowerShell", mime: "application/x-powershell", mode: "powershell", ext: ["ps1", "psd1", "psm1"]},
{name: "Properties files", mime: "text/x-properties", mode: "properties", ext: ["properties", "ini", "in"], alias: ["ini", "properties"]},
{name: "ProtoBuf", mime: "text/x-protobuf", mode: "protobuf", ext: ["proto"]},
{name: "Python", mime: "text/x-python", mode: "python", ext: ["BUILD", "bzl", "py", "pyw"], file: /^(BUCK|BUILD)$/},
{name: "Puppet", mime: "text/x-puppet", mode: "puppet", ext: ["pp"]},
{name: "Q", mime: "text/x-q", mode: "q", ext: ["q"]},
{name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r", "R"], alias: ["rscript"]},
{name: "reStructuredText", mime: "text/x-rst", mode: "rst", ext: ["rst"], alias: ["rst"]},
{name: "RPM Changes", mime: "text/x-rpm-changes", mode: "rpm"},
{name: "RPM Spec", mime: "text/x-rpm-spec", mode: "rpm", ext: ["spec"]},
{name: "Ruby", mime: "text/x-ruby", mode: "ruby", ext: ["rb"], alias: ["jruby", "macruby", "rake", "rb", "rbx"]},
{name: "Rust", mime: "text/x-rustsrc", mode: "rust", ext: ["rs"]},
{name: "SAS", mime: "text/x-sas", mode: "sas", ext: ["sas"]},
{name: "Sass", mime: "text/x-sass", mode: "sass", ext: ["sass"]},
{name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]},
{name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]},
{name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]},
{name: "Shell", mimes: ["text/x-sh", "application/x-sh"], mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"], file: /^PKGBUILD$/},
{name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]},
{name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]},
{name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]},
{name: "Smarty", mime: "text/x-smarty", mode: "smarty", ext: ["tpl"]},
{name: "Solr", mime: "text/x-solr", mode: "solr"},
{name: "SML", mime: "text/x-sml", mode: "mllike", ext: ["sml", "sig", "fun", "smackspec"]},
{name: "Soy", mime: "text/x-soy", mode: "soy", ext: ["soy"], alias: ["closure template"]},
{name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]},
{name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]},
{name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]},
{name: "SQLite", mime: "text/x-sqlite", mode: "sql"},
{name: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]},
{name: "Stylus", mime: "text/x-styl", mode: "stylus", ext: ["styl"]},
{name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]},
{name: "sTeX", mime: "text/x-stex", mode: "stex"},
{name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx", "tex"], alias: ["tex"]},
{name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v", "sv", "svh"]},
{name: "Tcl", mime: "text/x-tcl", mode: "tcl", ext: ["tcl"]},
{name: "Textile", mime: "text/x-textile", mode: "textile", ext: ["textile"]},
{name: "TiddlyWiki ", mime: "text/x-tiddlywiki", mode: "tiddlywiki"},
{name: "Tiki wiki", mime: "text/tiki", mode: "tiki"},
{name: "TOML", mime: "text/x-toml", mode: "toml", ext: ["toml"]},
{name: "Tornado", mime: "text/x-tornado", mode: "tornado"},
{name: "troff", mime: "text/troff", mode: "troff", ext: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]},
{name: "TTCN", mime: "text/x-ttcn", mode: "ttcn", ext: ["ttcn", "ttcn3", "ttcnpp"]},
{name: "TTCN_CFG", mime: "text/x-ttcn-cfg", mode: "ttcn-cfg", ext: ["cfg"]},
{name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]},
{name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]},
{name: "TypeScript-JSX", mime: "text/typescript-jsx", mode: "jsx", ext: ["tsx"], alias: ["tsx"]},
{name: "Twig", mime: "text/x-twig", mode: "twig"},
{name: "Web IDL", mime: "text/x-webidl", mode: "webidl", ext: ["webidl"]},
{name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]},
{name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]},
{name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]},
{name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]},
{name: "VHDL", mime: "text/x-vhdl", mode: "vhdl", ext: ["vhd", "vhdl"]},
{name: "Vue.js Component", mimes: ["script/x-vue", "text/x-vue"], mode: "vue", ext: ["vue"]},
{name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd", "svg"], alias: ["rss", "wsdl", "xsd"]},
{name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]},
{name: "Yacas", mime: "text/x-yacas", mode: "yacas", ext: ["ys"]},
{name: "YAML", mimes: ["text/x-yaml", "text/yaml"], mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]},
{name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]},
{name: "mscgen", mime: "text/x-mscgen", mode: "mscgen", ext: ["mscgen", "mscin", "msc"]},
{name: "xu", mime: "text/x-xu", mode: "mscgen", ext: ["xu"]},
{name: "msgenny", mime: "text/x-msgenny", mode: "mscgen", ext: ["msgenny"]}
];
// Ensure all modes have a mime property for backwards compatibility
for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
var info = CodeMirror.modeInfo[i];
if (info.mimes) info.mime = info.mimes[0];
}
CodeMirror.findModeByMIME = function(mime) {
mime = mime.toLowerCase();
for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
var info = CodeMirror.modeInfo[i];
if (info.mime == mime) return info;
if (info.mimes) for (var j = 0; j < info.mimes.length; j++)
if (info.mimes[j] == mime) return info;
}
if (/\+xml$/.test(mime)) return CodeMirror.findModeByMIME("application/xml")
if (/\+json$/.test(mime)) return CodeMirror.findModeByMIME("application/json")
};
CodeMirror.findModeByExtension = function(ext) {
for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
var info = CodeMirror.modeInfo[i];
if (info.ext) for (var j = 0; j < info.ext.length; j++)
if (info.ext[j] == ext) return info;
}
};
CodeMirror.findModeByFileName = function(filename) {
for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
var info = CodeMirror.modeInfo[i];
if (info.file && info.file.test(filename)) return info;
}
var dot = filename.lastIndexOf(".");
var ext = dot > -1 && filename.substring(dot + 1, filename.length);
if (ext) return CodeMirror.findModeByExtension(ext);
};
CodeMirror.findModeByName = function(name) {
name = name.toLowerCase();
for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
var info = CodeMirror.modeInfo[i];
if (info.name.toLowerCase() == name) return info;
if (info.alias) for (var j = 0; j < info.alias.length; j++)
if (info.alias[j].toLowerCase() == name) return info;
}
};
});

View File

@@ -0,0 +1,181 @@
<!doctype html>
<head>
<title>CodeMirror: NGINX 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="nginx.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<style>
body {
margin: 0em auto;
}
.CodeMirror, .CodeMirror-scroll {
height: 600px;
}
</style>
<div id=nav>
<a href="https://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="#">NGINX</a>
</ul>
</div>
<article>
<h2>NGINX mode</h2>
<form><textarea id="code" name="code" style="height: 800px;">
server {
listen 173.255.219.235:80;
server_name website.com.au;
rewrite / $scheme://www.$host$request_uri permanent; ## Forcibly prepend a www
}
server {
listen 173.255.219.235:443;
server_name website.com.au;
rewrite / $scheme://www.$host$request_uri permanent; ## Forcibly prepend a www
}
server {
listen 173.255.219.235:80;
server_name www.website.com.au;
root /data/www;
index index.html index.php;
location / {
index index.html index.php; ## Allow a static html file to be shown first
try_files $uri $uri/ @handler; ## If missing pass the URI to Magento's front handler
expires 30d; ## Assume all files are cachable
}
## These locations would be hidden by .htaccess normally
location /app/ { deny all; }
location /includes/ { deny all; }
location /lib/ { deny all; }
location /media/downloadable/ { deny all; }
location /pkginfo/ { deny all; }
location /report/config.xml { deny all; }
location /var/ { deny all; }
location /var/export/ { ## Allow admins only to view export folder
auth_basic "Restricted"; ## Message shown in login window
auth_basic_user_file /rs/passwords/testfile; ## See /etc/nginx/htpassword
autoindex on;
}
location /. { ## Disable .htaccess and other hidden files
return 404;
}
location @handler { ## Magento uses a common front handler
rewrite / /index.php;
}
location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
rewrite ^/(.*.php)/ /$1 last;
}
location ~ \.php$ {
if (!-e $request_filename) { rewrite / /index.php last; } ## Catch 404s that try_files miss
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /rs/confs/nginx/fastcgi_params;
}
}
server {
listen 173.255.219.235:443;
server_name website.com.au www.website.com.au;
root /data/www;
index index.html index.php;
ssl on;
ssl_certificate /rs/ssl/ssl.crt;
ssl_certificate_key /rs/ssl/ssl.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
location / {
index index.html index.php; ## Allow a static html file to be shown first
try_files $uri $uri/ @handler; ## If missing pass the URI to Magento's front handler
expires 30d; ## Assume all files are cachable
}
## These locations would be hidden by .htaccess normally
location /app/ { deny all; }
location /includes/ { deny all; }
location /lib/ { deny all; }
location /media/downloadable/ { deny all; }
location /pkginfo/ { deny all; }
location /report/config.xml { deny all; }
location /var/ { deny all; }
location /var/export/ { ## Allow admins only to view export folder
auth_basic "Restricted"; ## Message shown in login window
auth_basic_user_file htpasswd; ## See /etc/nginx/htpassword
autoindex on;
}
location /. { ## Disable .htaccess and other hidden files
return 404;
}
location @handler { ## Magento uses a common front handler
rewrite / /index.php;
}
location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
rewrite ^/(.*.php)/ /$1 last;
}
location ~ .php$ { ## Execute PHP scripts
if (!-e $request_filename) { rewrite /index.php last; } ## Catch 404s that try_files miss
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /rs/confs/nginx/fastcgi_params;
fastcgi_param HTTPS on;
}
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-nginx-conf</code>.</p>
</article>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,61 @@
<!doctype html>
<title>CodeMirror: Pascal 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="pascal.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">Pascal</a>
</ul>
</div>
<article>
<h2>Pascal mode</h2>
<div><textarea id="code" name="code">
(* Example Pascal code *)
while a <> b do writeln('Waiting');
if a > b then
writeln('Condition met')
else
writeln('Condition not met');
for i := 1 to 10 do
writeln('Iteration: ', i:1);
repeat
a := a + 1
until a = 10;
case i of
0: write('zero');
1: write('one');
2: write('two')
end;
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "text/x-pascal"
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-pascal</code>.</p>
</article>

View File

@@ -0,0 +1,121 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("pascal", function() {
function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
var keywords = words(
"absolute and array asm begin case const constructor destructor div do " +
"downto else end file for function goto if implementation in inherited " +
"inline interface label mod nil not object of operator or packed procedure " +
"program record reintroduce repeat self set shl shr string then to type " +
"unit until uses var while with xor as class dispinterface except exports " +
"finalization finally initialization inline is library on out packed " +
"property raise resourcestring threadvar try absolute abstract alias " +
"assembler bitpacked break cdecl continue cppdecl cvar default deprecated " +
"dynamic enumerator experimental export external far far16 forward generic " +
"helper implements index interrupt iocheck local message name near " +
"nodefault noreturn nostackframe oldfpccall otherwise overload override " +
"pascal platform private protected public published read register " +
"reintroduce result safecall saveregisters softfloat specialize static " +
"stdcall stored strict unaligned unimplemented varargs virtual write");
var atoms = {"null": true};
var isOperatorChar = /[+\-*&%=<>!?|\/]/;
function tokenBase(stream, state) {
var ch = stream.next();
if (ch == "#" && state.startOfLine) {
stream.skipToEnd();
return "meta";
}
if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (ch == "(" && stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
}
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
return null;
}
if (/\d/.test(ch)) {
stream.eatWhile(/[\w\.]/);
return "number";
}
if (ch == "/") {
if (stream.eat("/")) {
stream.skipToEnd();
return "comment";
}
}
if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return "operator";
}
stream.eatWhile(/[\w\$_]/);
var cur = stream.current();
if (keywords.propertyIsEnumerable(cur)) return "keyword";
if (atoms.propertyIsEnumerable(cur)) return "atom";
return "variable";
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, next, end = false;
while ((next = stream.next()) != null) {
if (next == quote && !escaped) {end = true; break;}
escaped = !escaped && next == "\\";
}
if (end || !escaped) state.tokenize = null;
return "string";
};
}
function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == ")" && maybeEnd) {
state.tokenize = null;
break;
}
maybeEnd = (ch == "*");
}
return "comment";
}
// Interface
return {
startState: function() {
return {tokenize: null};
},
token: function(stream, state) {
if (stream.eatSpace()) return null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment" || style == "meta") return style;
return style;
},
electricChars: "{}"
};
});
CodeMirror.defineMIME("text/x-pascal", "pascal");
});

View File

@@ -0,0 +1,75 @@
<!doctype html>
<title>CodeMirror: Perl 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="perl.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">Perl</a>
</ul>
</div>
<article>
<h2>Perl mode</h2>
<div><textarea id="code" name="code">
#!/usr/bin/perl
use Something qw(func1 func2);
# strings
my $s1 = qq'single line';
our $s2 = q(multi-
line);
=item Something
Example.
=cut
my $html=<<'HTML'
<html>
<title>hi!</title>
</html>
HTML
print "first,".join(',', 'second', qq~third~);
if($s1 =~ m[(?<!\s)(l.ne)\z]o) {
$h->{$1}=$$.' predefined variables';
$s2 =~ s/\-line//ox;
$s1 =~ s[
line ]
[
block
]ox;
}
1; # numbers and comments
__END__
something...
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-perl</code>.</p>
</article>

837
web/public/codemirror/mode/perl/perl.js vendored Normal file
View File

@@ -0,0 +1,837 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// CodeMirror2 mode/perl/perl.js (text/x-perl) beta 0.10 (2011-11-08)
// This is a part of CodeMirror from https://github.com/sabaca/CodeMirror_mode_perl (mail@sabaca.com)
(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("perl",function(){
// http://perldoc.perl.org
var PERL={ // null - magic touch
// 1 - keyword
// 2 - def
// 3 - atom
// 4 - operator
// 5 - variable-2 (predefined)
// [x,y] - x=1,2,3; y=must be defined if x{...}
// PERL operators
'->' : 4,
'++' : 4,
'--' : 4,
'**' : 4,
// ! ~ \ and unary + and -
'=~' : 4,
'!~' : 4,
'*' : 4,
'/' : 4,
'%' : 4,
'x' : 4,
'+' : 4,
'-' : 4,
'.' : 4,
'<<' : 4,
'>>' : 4,
// named unary operators
'<' : 4,
'>' : 4,
'<=' : 4,
'>=' : 4,
'lt' : 4,
'gt' : 4,
'le' : 4,
'ge' : 4,
'==' : 4,
'!=' : 4,
'<=>' : 4,
'eq' : 4,
'ne' : 4,
'cmp' : 4,
'~~' : 4,
'&' : 4,
'|' : 4,
'^' : 4,
'&&' : 4,
'||' : 4,
'//' : 4,
'..' : 4,
'...' : 4,
'?' : 4,
':' : 4,
'=' : 4,
'+=' : 4,
'-=' : 4,
'*=' : 4, // etc. ???
',' : 4,
'=>' : 4,
'::' : 4,
// list operators (rightward)
'not' : 4,
'and' : 4,
'or' : 4,
'xor' : 4,
// PERL predefined variables (I know, what this is a paranoid idea, but may be needed for people, who learn PERL, and for me as well, ...and may be for you?;)
'BEGIN' : [5,1],
'END' : [5,1],
'PRINT' : [5,1],
'PRINTF' : [5,1],
'GETC' : [5,1],
'READ' : [5,1],
'READLINE' : [5,1],
'DESTROY' : [5,1],
'TIE' : [5,1],
'TIEHANDLE' : [5,1],
'UNTIE' : [5,1],
'STDIN' : 5,
'STDIN_TOP' : 5,
'STDOUT' : 5,
'STDOUT_TOP' : 5,
'STDERR' : 5,
'STDERR_TOP' : 5,
'$ARG' : 5,
'$_' : 5,
'@ARG' : 5,
'@_' : 5,
'$LIST_SEPARATOR' : 5,
'$"' : 5,
'$PROCESS_ID' : 5,
'$PID' : 5,
'$$' : 5,
'$REAL_GROUP_ID' : 5,
'$GID' : 5,
'$(' : 5,
'$EFFECTIVE_GROUP_ID' : 5,
'$EGID' : 5,
'$)' : 5,
'$PROGRAM_NAME' : 5,
'$0' : 5,
'$SUBSCRIPT_SEPARATOR' : 5,
'$SUBSEP' : 5,
'$;' : 5,
'$REAL_USER_ID' : 5,
'$UID' : 5,
'$<' : 5,
'$EFFECTIVE_USER_ID' : 5,
'$EUID' : 5,
'$>' : 5,
'$a' : 5,
'$b' : 5,
'$COMPILING' : 5,
'$^C' : 5,
'$DEBUGGING' : 5,
'$^D' : 5,
'${^ENCODING}' : 5,
'$ENV' : 5,
'%ENV' : 5,
'$SYSTEM_FD_MAX' : 5,
'$^F' : 5,
'@F' : 5,
'${^GLOBAL_PHASE}' : 5,
'$^H' : 5,
'%^H' : 5,
'@INC' : 5,
'%INC' : 5,
'$INPLACE_EDIT' : 5,
'$^I' : 5,
'$^M' : 5,
'$OSNAME' : 5,
'$^O' : 5,
'${^OPEN}' : 5,
'$PERLDB' : 5,
'$^P' : 5,
'$SIG' : 5,
'%SIG' : 5,
'$BASETIME' : 5,
'$^T' : 5,
'${^TAINT}' : 5,
'${^UNICODE}' : 5,
'${^UTF8CACHE}' : 5,
'${^UTF8LOCALE}' : 5,
'$PERL_VERSION' : 5,
'$^V' : 5,
'${^WIN32_SLOPPY_STAT}' : 5,
'$EXECUTABLE_NAME' : 5,
'$^X' : 5,
'$1' : 5, // - regexp $1, $2...
'$MATCH' : 5,
'$&' : 5,
'${^MATCH}' : 5,
'$PREMATCH' : 5,
'$`' : 5,
'${^PREMATCH}' : 5,
'$POSTMATCH' : 5,
"$'" : 5,
'${^POSTMATCH}' : 5,
'$LAST_PAREN_MATCH' : 5,
'$+' : 5,
'$LAST_SUBMATCH_RESULT' : 5,
'$^N' : 5,
'@LAST_MATCH_END' : 5,
'@+' : 5,
'%LAST_PAREN_MATCH' : 5,
'%+' : 5,
'@LAST_MATCH_START' : 5,
'@-' : 5,
'%LAST_MATCH_START' : 5,
'%-' : 5,
'$LAST_REGEXP_CODE_RESULT' : 5,
'$^R' : 5,
'${^RE_DEBUG_FLAGS}' : 5,
'${^RE_TRIE_MAXBUF}' : 5,
'$ARGV' : 5,
'@ARGV' : 5,
'ARGV' : 5,
'ARGVOUT' : 5,
'$OUTPUT_FIELD_SEPARATOR' : 5,
'$OFS' : 5,
'$,' : 5,
'$INPUT_LINE_NUMBER' : 5,
'$NR' : 5,
'$.' : 5,
'$INPUT_RECORD_SEPARATOR' : 5,
'$RS' : 5,
'$/' : 5,
'$OUTPUT_RECORD_SEPARATOR' : 5,
'$ORS' : 5,
'$\\' : 5,
'$OUTPUT_AUTOFLUSH' : 5,
'$|' : 5,
'$ACCUMULATOR' : 5,
'$^A' : 5,
'$FORMAT_FORMFEED' : 5,
'$^L' : 5,
'$FORMAT_PAGE_NUMBER' : 5,
'$%' : 5,
'$FORMAT_LINES_LEFT' : 5,
'$-' : 5,
'$FORMAT_LINE_BREAK_CHARACTERS' : 5,
'$:' : 5,
'$FORMAT_LINES_PER_PAGE' : 5,
'$=' : 5,
'$FORMAT_TOP_NAME' : 5,
'$^' : 5,
'$FORMAT_NAME' : 5,
'$~' : 5,
'${^CHILD_ERROR_NATIVE}' : 5,
'$EXTENDED_OS_ERROR' : 5,
'$^E' : 5,
'$EXCEPTIONS_BEING_CAUGHT' : 5,
'$^S' : 5,
'$WARNING' : 5,
'$^W' : 5,
'${^WARNING_BITS}' : 5,
'$OS_ERROR' : 5,
'$ERRNO' : 5,
'$!' : 5,
'%OS_ERROR' : 5,
'%ERRNO' : 5,
'%!' : 5,
'$CHILD_ERROR' : 5,
'$?' : 5,
'$EVAL_ERROR' : 5,
'$@' : 5,
'$OFMT' : 5,
'$#' : 5,
'$*' : 5,
'$ARRAY_BASE' : 5,
'$[' : 5,
'$OLD_PERL_VERSION' : 5,
'$]' : 5,
// PERL blocks
'if' :[1,1],
elsif :[1,1],
'else' :[1,1],
'while' :[1,1],
unless :[1,1],
'for' :[1,1],
foreach :[1,1],
// PERL functions
'abs' :1, // - absolute value function
accept :1, // - accept an incoming socket connect
alarm :1, // - schedule a SIGALRM
'atan2' :1, // - arctangent of Y/X in the range -PI to PI
bind :1, // - binds an address to a socket
binmode :1, // - prepare binary files for I/O
bless :1, // - create an object
bootstrap :1, //
'break' :1, // - break out of a "given" block
caller :1, // - get context of the current subroutine call
chdir :1, // - change your current working directory
chmod :1, // - changes the permissions on a list of files
chomp :1, // - remove a trailing record separator from a string
chop :1, // - remove the last character from a string
chown :1, // - change the ownership on a list of files
chr :1, // - get character this number represents
chroot :1, // - make directory new root for path lookups
close :1, // - close file (or pipe or socket) handle
closedir :1, // - close directory handle
connect :1, // - connect to a remote socket
'continue' :[1,1], // - optional trailing block in a while or foreach
'cos' :1, // - cosine function
crypt :1, // - one-way passwd-style encryption
dbmclose :1, // - breaks binding on a tied dbm file
dbmopen :1, // - create binding on a tied dbm file
'default' :1, //
defined :1, // - test whether a value, variable, or function is defined
'delete' :1, // - deletes a value from a hash
die :1, // - raise an exception or bail out
'do' :1, // - turn a BLOCK into a TERM
dump :1, // - create an immediate core dump
each :1, // - retrieve the next key/value pair from a hash
endgrent :1, // - be done using group file
endhostent :1, // - be done using hosts file
endnetent :1, // - be done using networks file
endprotoent :1, // - be done using protocols file
endpwent :1, // - be done using passwd file
endservent :1, // - be done using services file
eof :1, // - test a filehandle for its end
'eval' :1, // - catch exceptions or compile and run code
'exec' :1, // - abandon this program to run another
exists :1, // - test whether a hash key is present
exit :1, // - terminate this program
'exp' :1, // - raise I to a power
fcntl :1, // - file control system call
fileno :1, // - return file descriptor from filehandle
flock :1, // - lock an entire file with an advisory lock
fork :1, // - create a new process just like this one
format :1, // - declare a picture format with use by the write() function
formline :1, // - internal function used for formats
getc :1, // - get the next character from the filehandle
getgrent :1, // - get next group record
getgrgid :1, // - get group record given group user ID
getgrnam :1, // - get group record given group name
gethostbyaddr :1, // - get host record given its address
gethostbyname :1, // - get host record given name
gethostent :1, // - get next hosts record
getlogin :1, // - return who logged in at this tty
getnetbyaddr :1, // - get network record given its address
getnetbyname :1, // - get networks record given name
getnetent :1, // - get next networks record
getpeername :1, // - find the other end of a socket connection
getpgrp :1, // - get process group
getppid :1, // - get parent process ID
getpriority :1, // - get current nice value
getprotobyname :1, // - get protocol record given name
getprotobynumber :1, // - get protocol record numeric protocol
getprotoent :1, // - get next protocols record
getpwent :1, // - get next passwd record
getpwnam :1, // - get passwd record given user login name
getpwuid :1, // - get passwd record given user ID
getservbyname :1, // - get services record given its name
getservbyport :1, // - get services record given numeric port
getservent :1, // - get next services record
getsockname :1, // - retrieve the sockaddr for a given socket
getsockopt :1, // - get socket options on a given socket
given :1, //
glob :1, // - expand filenames using wildcards
gmtime :1, // - convert UNIX time into record or string using Greenwich time
'goto' :1, // - create spaghetti code
grep :1, // - locate elements in a list test true against a given criterion
hex :1, // - convert a string to a hexadecimal number
'import' :1, // - patch a module's namespace into your own
index :1, // - find a substring within a string
'int' :1, // - get the integer portion of a number
ioctl :1, // - system-dependent device control system call
'join' :1, // - join a list into a string using a separator
keys :1, // - retrieve list of indices from a hash
kill :1, // - send a signal to a process or process group
last :1, // - exit a block prematurely
lc :1, // - return lower-case version of a string
lcfirst :1, // - return a string with just the next letter in lower case
length :1, // - return the number of bytes in a string
'link' :1, // - create a hard link in the filesytem
listen :1, // - register your socket as a server
local : 2, // - create a temporary value for a global variable (dynamic scoping)
localtime :1, // - convert UNIX time into record or string using local time
lock :1, // - get a thread lock on a variable, subroutine, or method
'log' :1, // - retrieve the natural logarithm for a number
lstat :1, // - stat a symbolic link
m :null, // - match a string with a regular expression pattern
map :1, // - apply a change to a list to get back a new list with the changes
mkdir :1, // - create a directory
msgctl :1, // - SysV IPC message control operations
msgget :1, // - get SysV IPC message queue
msgrcv :1, // - receive a SysV IPC message from a message queue
msgsnd :1, // - send a SysV IPC message to a message queue
my : 2, // - declare and assign a local variable (lexical scoping)
'new' :1, //
next :1, // - iterate a block prematurely
no :1, // - unimport some module symbols or semantics at compile time
oct :1, // - convert a string to an octal number
open :1, // - open a file, pipe, or descriptor
opendir :1, // - open a directory
ord :1, // - find a character's numeric representation
our : 2, // - declare and assign a package variable (lexical scoping)
pack :1, // - convert a list into a binary representation
'package' :1, // - declare a separate global namespace
pipe :1, // - open a pair of connected filehandles
pop :1, // - remove the last element from an array and return it
pos :1, // - find or set the offset for the last/next m//g search
print :1, // - output a list to a filehandle
printf :1, // - output a formatted list to a filehandle
prototype :1, // - get the prototype (if any) of a subroutine
push :1, // - append one or more elements to an array
q :null, // - singly quote a string
qq :null, // - doubly quote a string
qr :null, // - Compile pattern
quotemeta :null, // - quote regular expression magic characters
qw :null, // - quote a list of words
qx :null, // - backquote quote a string
rand :1, // - retrieve the next pseudorandom number
read :1, // - fixed-length buffered input from a filehandle
readdir :1, // - get a directory from a directory handle
readline :1, // - fetch a record from a file
readlink :1, // - determine where a symbolic link is pointing
readpipe :1, // - execute a system command and collect standard output
recv :1, // - receive a message over a Socket
redo :1, // - start this loop iteration over again
ref :1, // - find out the type of thing being referenced
rename :1, // - change a filename
require :1, // - load in external functions from a library at runtime
reset :1, // - clear all variables of a given name
'return' :1, // - get out of a function early
reverse :1, // - flip a string or a list
rewinddir :1, // - reset directory handle
rindex :1, // - right-to-left substring search
rmdir :1, // - remove a directory
s :null, // - replace a pattern with a string
say :1, // - print with newline
scalar :1, // - force a scalar context
seek :1, // - reposition file pointer for random-access I/O
seekdir :1, // - reposition directory pointer
select :1, // - reset default output or do I/O multiplexing
semctl :1, // - SysV semaphore control operations
semget :1, // - get set of SysV semaphores
semop :1, // - SysV semaphore operations
send :1, // - send a message over a socket
setgrent :1, // - prepare group file for use
sethostent :1, // - prepare hosts file for use
setnetent :1, // - prepare networks file for use
setpgrp :1, // - set the process group of a process
setpriority :1, // - set a process's nice value
setprotoent :1, // - prepare protocols file for use
setpwent :1, // - prepare passwd file for use
setservent :1, // - prepare services file for use
setsockopt :1, // - set some socket options
shift :1, // - remove the first element of an array, and return it
shmctl :1, // - SysV shared memory operations
shmget :1, // - get SysV shared memory segment identifier
shmread :1, // - read SysV shared memory
shmwrite :1, // - write SysV shared memory
shutdown :1, // - close down just half of a socket connection
'sin' :1, // - return the sine of a number
sleep :1, // - block for some number of seconds
socket :1, // - create a socket
socketpair :1, // - create a pair of sockets
'sort' :1, // - sort a list of values
splice :1, // - add or remove elements anywhere in an array
'split' :1, // - split up a string using a regexp delimiter
sprintf :1, // - formatted print into a string
'sqrt' :1, // - square root function
srand :1, // - seed the random number generator
stat :1, // - get a file's status information
state :1, // - declare and assign a state variable (persistent lexical scoping)
study :1, // - optimize input data for repeated searches
'sub' :1, // - declare a subroutine, possibly anonymously
'substr' :1, // - get or alter a portion of a stirng
symlink :1, // - create a symbolic link to a file
syscall :1, // - execute an arbitrary system call
sysopen :1, // - open a file, pipe, or descriptor
sysread :1, // - fixed-length unbuffered input from a filehandle
sysseek :1, // - position I/O pointer on handle used with sysread and syswrite
system :1, // - run a separate program
syswrite :1, // - fixed-length unbuffered output to a filehandle
tell :1, // - get current seekpointer on a filehandle
telldir :1, // - get current seekpointer on a directory handle
tie :1, // - bind a variable to an object class
tied :1, // - get a reference to the object underlying a tied variable
time :1, // - return number of seconds since 1970
times :1, // - return elapsed time for self and child processes
tr :null, // - transliterate a string
truncate :1, // - shorten a file
uc :1, // - return upper-case version of a string
ucfirst :1, // - return a string with just the next letter in upper case
umask :1, // - set file creation mode mask
undef :1, // - remove a variable or function definition
unlink :1, // - remove one link to a file
unpack :1, // - convert binary structure into normal perl variables
unshift :1, // - prepend more elements to the beginning of a list
untie :1, // - break a tie binding to a variable
use :1, // - load in a module at compile time
utime :1, // - set a file's last access and modify times
values :1, // - return a list of the values in a hash
vec :1, // - test or set particular bits in a string
wait :1, // - wait for any child process to die
waitpid :1, // - wait for a particular child process to die
wantarray :1, // - get void vs scalar vs list context of current subroutine call
warn :1, // - print debugging info
when :1, //
write :1, // - print a picture record
y :null}; // - transliterate a string
var RXstyle="string-2";
var RXmodifiers=/[goseximacplud]/; // NOTE: "m", "s", "y" and "tr" need to correct real modifiers for each regexp type
function tokenChain(stream,state,chain,style,tail){ // NOTE: chain.length > 2 is not working now (it's for s[...][...]geos;)
state.chain=null; // 12 3tail
state.style=null;
state.tail=null;
state.tokenize=function(stream,state){
var e=false,c,i=0;
while(c=stream.next()){
if(c===chain[i]&&!e){
if(chain[++i]!==undefined){
state.chain=chain[i];
state.style=style;
state.tail=tail;}
else if(tail)
stream.eatWhile(tail);
state.tokenize=tokenPerl;
return style;}
e=!e&&c=="\\";}
return style;};
return state.tokenize(stream,state);}
function tokenSOMETHING(stream,state,string){
state.tokenize=function(stream,state){
if(stream.string==string)
state.tokenize=tokenPerl;
stream.skipToEnd();
return "string";};
return state.tokenize(stream,state);}
function tokenPerl(stream,state){
if(stream.eatSpace())
return null;
if(state.chain)
return tokenChain(stream,state,state.chain,state.style,state.tail);
if(stream.match(/^\-?[\d\.]/,false))
if(stream.match(/^(\-?(\d*\.\d+(e[+-]?\d+)?|\d+\.\d*)|0x[\da-fA-F]+|0b[01]+|\d+(e[+-]?\d+)?)/))
return 'number';
if(stream.match(/^<<(?=\w)/)){ // NOTE: <<SOMETHING\n...\nSOMETHING\n
stream.eatWhile(/\w/);
return tokenSOMETHING(stream,state,stream.current().substr(2));}
if(stream.sol()&&stream.match(/^\=item(?!\w)/)){// NOTE: \n=item...\n=cut\n
return tokenSOMETHING(stream,state,'=cut');}
var ch=stream.next();
if(ch=='"'||ch=="'"){ // NOTE: ' or " or <<'SOMETHING'\n...\nSOMETHING\n or <<"SOMETHING"\n...\nSOMETHING\n
if(prefix(stream, 3)=="<<"+ch){
var p=stream.pos;
stream.eatWhile(/\w/);
var n=stream.current().substr(1);
if(n&&stream.eat(ch))
return tokenSOMETHING(stream,state,n);
stream.pos=p;}
return tokenChain(stream,state,[ch],"string");}
if(ch=="q"){
var c=look(stream, -2);
if(!(c&&/\w/.test(c))){
c=look(stream, 0);
if(c=="x"){
c=look(stream, 1);
if(c=="("){
eatSuffix(stream, 2);
return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}
if(c=="["){
eatSuffix(stream, 2);
return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}
if(c=="{"){
eatSuffix(stream, 2);
return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}
if(c=="<"){
eatSuffix(stream, 2);
return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}
if(/[\^'"!~\/]/.test(c)){
eatSuffix(stream, 1);
return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers);}}
else if(c=="q"){
c=look(stream, 1);
if(c=="("){
eatSuffix(stream, 2);
return tokenChain(stream,state,[")"],"string");}
if(c=="["){
eatSuffix(stream, 2);
return tokenChain(stream,state,["]"],"string");}
if(c=="{"){
eatSuffix(stream, 2);
return tokenChain(stream,state,["}"],"string");}
if(c=="<"){
eatSuffix(stream, 2);
return tokenChain(stream,state,[">"],"string");}
if(/[\^'"!~\/]/.test(c)){
eatSuffix(stream, 1);
return tokenChain(stream,state,[stream.eat(c)],"string");}}
else if(c=="w"){
c=look(stream, 1);
if(c=="("){
eatSuffix(stream, 2);
return tokenChain(stream,state,[")"],"bracket");}
if(c=="["){
eatSuffix(stream, 2);
return tokenChain(stream,state,["]"],"bracket");}
if(c=="{"){
eatSuffix(stream, 2);
return tokenChain(stream,state,["}"],"bracket");}
if(c=="<"){
eatSuffix(stream, 2);
return tokenChain(stream,state,[">"],"bracket");}
if(/[\^'"!~\/]/.test(c)){
eatSuffix(stream, 1);
return tokenChain(stream,state,[stream.eat(c)],"bracket");}}
else if(c=="r"){
c=look(stream, 1);
if(c=="("){
eatSuffix(stream, 2);
return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}
if(c=="["){
eatSuffix(stream, 2);
return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}
if(c=="{"){
eatSuffix(stream, 2);
return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}
if(c=="<"){
eatSuffix(stream, 2);
return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}
if(/[\^'"!~\/]/.test(c)){
eatSuffix(stream, 1);
return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers);}}
else if(/[\^'"!~\/(\[{<]/.test(c)){
if(c=="("){
eatSuffix(stream, 1);
return tokenChain(stream,state,[")"],"string");}
if(c=="["){
eatSuffix(stream, 1);
return tokenChain(stream,state,["]"],"string");}
if(c=="{"){
eatSuffix(stream, 1);
return tokenChain(stream,state,["}"],"string");}
if(c=="<"){
eatSuffix(stream, 1);
return tokenChain(stream,state,[">"],"string");}
if(/[\^'"!~\/]/.test(c)){
return tokenChain(stream,state,[stream.eat(c)],"string");}}}}
if(ch=="m"){
var c=look(stream, -2);
if(!(c&&/\w/.test(c))){
c=stream.eat(/[(\[{<\^'"!~\/]/);
if(c){
if(/[\^'"!~\/]/.test(c)){
return tokenChain(stream,state,[c],RXstyle,RXmodifiers);}
if(c=="("){
return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}
if(c=="["){
return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}
if(c=="{"){
return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}
if(c=="<"){
return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}}}}
if(ch=="s"){
var c=/[\/>\]})\w]/.test(look(stream, -2));
if(!c){
c=stream.eat(/[(\[{<\^'"!~\/]/);
if(c){
if(c=="[")
return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
if(c=="{")
return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
if(c=="<")
return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
if(c=="(")
return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}
if(ch=="y"){
var c=/[\/>\]})\w]/.test(look(stream, -2));
if(!c){
c=stream.eat(/[(\[{<\^'"!~\/]/);
if(c){
if(c=="[")
return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
if(c=="{")
return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
if(c=="<")
return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
if(c=="(")
return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}
if(ch=="t"){
var c=/[\/>\]})\w]/.test(look(stream, -2));
if(!c){
c=stream.eat("r");if(c){
c=stream.eat(/[(\[{<\^'"!~\/]/);
if(c){
if(c=="[")
return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
if(c=="{")
return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
if(c=="<")
return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
if(c=="(")
return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}}
if(ch=="`"){
return tokenChain(stream,state,[ch],"variable-2");}
if(ch=="/"){
if(!/~\s*$/.test(prefix(stream)))
return "operator";
else
return tokenChain(stream,state,[ch],RXstyle,RXmodifiers);}
if(ch=="$"){
var p=stream.pos;
if(stream.eatWhile(/\d/)||stream.eat("{")&&stream.eatWhile(/\d/)&&stream.eat("}"))
return "variable-2";
else
stream.pos=p;}
if(/[$@%]/.test(ch)){
var p=stream.pos;
if(stream.eat("^")&&stream.eat(/[A-Z]/)||!/[@$%&]/.test(look(stream, -2))&&stream.eat(/[=|\\\-#?@;:&`~\^!\[\]*'"$+.,\/<>()]/)){
var c=stream.current();
if(PERL[c])
return "variable-2";}
stream.pos=p;}
if(/[$@%&]/.test(ch)){
if(stream.eatWhile(/[\w$\[\]]/)||stream.eat("{")&&stream.eatWhile(/[\w$\[\]]/)&&stream.eat("}")){
var c=stream.current();
if(PERL[c])
return "variable-2";
else
return "variable";}}
if(ch=="#"){
if(look(stream, -2)!="$"){
stream.skipToEnd();
return "comment";}}
if(/[:+\-\^*$&%@=<>!?|\/~\.]/.test(ch)){
var p=stream.pos;
stream.eatWhile(/[:+\-\^*$&%@=<>!?|\/~\.]/);
if(PERL[stream.current()])
return "operator";
else
stream.pos=p;}
if(ch=="_"){
if(stream.pos==1){
if(suffix(stream, 6)=="_END__"){
return tokenChain(stream,state,['\0'],"comment");}
else if(suffix(stream, 7)=="_DATA__"){
return tokenChain(stream,state,['\0'],"variable-2");}
else if(suffix(stream, 7)=="_C__"){
return tokenChain(stream,state,['\0'],"string");}}}
if(/\w/.test(ch)){
var p=stream.pos;
if(look(stream, -2)=="{"&&(look(stream, 0)=="}"||stream.eatWhile(/\w/)&&look(stream, 0)=="}"))
return "string";
else
stream.pos=p;}
if(/[A-Z]/.test(ch)){
var l=look(stream, -2);
var p=stream.pos;
stream.eatWhile(/[A-Z_]/);
if(/[\da-z]/.test(look(stream, 0))){
stream.pos=p;}
else{
var c=PERL[stream.current()];
if(!c)
return "meta";
if(c[1])
c=c[0];
if(l!=":"){
if(c==1)
return "keyword";
else if(c==2)
return "def";
else if(c==3)
return "atom";
else if(c==4)
return "operator";
else if(c==5)
return "variable-2";
else
return "meta";}
else
return "meta";}}
if(/[a-zA-Z_]/.test(ch)){
var l=look(stream, -2);
stream.eatWhile(/\w/);
var c=PERL[stream.current()];
if(!c)
return "meta";
if(c[1])
c=c[0];
if(l!=":"){
if(c==1)
return "keyword";
else if(c==2)
return "def";
else if(c==3)
return "atom";
else if(c==4)
return "operator";
else if(c==5)
return "variable-2";
else
return "meta";}
else
return "meta";}
return null;}
return {
startState: function() {
return {
tokenize: tokenPerl,
chain: null,
style: null,
tail: null
};
},
token: function(stream, state) {
return (state.tokenize || tokenPerl)(stream, state);
},
lineComment: '#'
};
});
CodeMirror.registerHelper("wordChars", "perl", /[\w$]/);
CodeMirror.defineMIME("text/x-perl", "perl");
// it's like "peek", but need for look-ahead or look-behind if index < 0
function look(stream, c){
return stream.string.charAt(stream.pos+(c||0));
}
// return a part of prefix of current stream from current position
function prefix(stream, c){
if(c){
var x=stream.pos-c;
return stream.string.substr((x>=0?x:0),c);}
else{
return stream.string.substr(0,stream.pos-1);
}
}
// return a part of suffix of current stream from current position
function suffix(stream, c){
var y=stream.string.length;
var x=y-stream.pos+1;
return stream.string.substr(stream.pos,(c&&c<y?c:x));
}
// eating and vomiting a part of stream from current position
function eatSuffix(stream, c){
var x=stream.pos+c;
var y;
if(x<=0)
stream.pos=0;
else if(x>=(y=stream.string.length-1))
stream.pos=y;
else
stream.pos=x;
}
});

View File

@@ -0,0 +1,64 @@
<!doctype html>
<title>CodeMirror: PHP 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="../../addon/edit/matchbrackets.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="../xml/xml.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../clike/clike.js"></script>
<script src="php.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">PHP</a>
</ul>
</div>
<article>
<h2>PHP mode</h2>
<form><textarea id="code" name="code">
<?php
$a = array('a' => 1, 'b' => 2, 3 => 'c');
echo "$a[a] ${a[3] /* } comment */} {$a[b]} \$a[a]";
function hello($who) {
return "Hello $who!";
}
?>
<p>The program says <?= hello("World") ?>.</p>
<script>
alert("And here is some JS code"); // also colored
</script>
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
mode: "application/x-httpd-php",
indentUnit: 4,
indentWithTabs: true
});
</script>
<p>Simple HTML/PHP mode based on
the <a href="../clike/">C-like</a> mode. Depends on XML,
JavaScript, CSS, HTMLMixed, and C-like modes.</p>
<p><strong>MIME types defined:</strong> <code>application/x-httpd-php</code> (HTML with PHP code), <code>text/x-php</code> (plain, non-wrapped PHP code).</p>
</article>

234
web/public/codemirror/mode/php/php.js vendored Normal file

File diff suppressed because one or more lines are too long

154
web/public/codemirror/mode/php/test.js vendored Normal file
View File

@@ -0,0 +1,154 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "php");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
MT('simple_test',
'[meta <?php] ' +
'[keyword echo] [string "aaa"]; ' +
'[meta ?>]');
MT('variable_interpolation_non_alphanumeric',
'[meta <?php]',
'[keyword echo] [string "aaa$~$!$@$#$$$%$^$&$*$($)$.$<$>$/$\\$}$\\\"$:$;$?$|$[[$]]$+$=aaa"]',
'[meta ?>]');
MT('variable_interpolation_digits',
'[meta <?php]',
'[keyword echo] [string "aaa$1$2$3$4$5$6$7$8$9$0aaa"]',
'[meta ?>]');
MT('variable_interpolation_simple_syntax_1',
'[meta <?php]',
'[keyword echo] [string "aaa][variable-2 $aaa][string .aaa"];',
'[meta ?>]');
MT('variable_interpolation_simple_syntax_2',
'[meta <?php]',
'[keyword echo] [string "][variable-2 $aaaa][[','[number 2]', ']][string aa"];',
'[keyword echo] [string "][variable-2 $aaaa][[','[number 2345]', ']][string aa"];',
'[keyword echo] [string "][variable-2 $aaaa][[','[number 2.3]', ']][string aa"];',
'[keyword echo] [string "][variable-2 $aaaa][[','[variable aaaaa]', ']][string aa"];',
'[keyword echo] [string "][variable-2 $aaaa][[','[variable-2 $aaaaa]',']][string aa"];',
'[keyword echo] [string "1aaa][variable-2 $aaaa][[','[number 2]', ']][string aa"];',
'[keyword echo] [string "aaa][variable-2 $aaaa][[','[number 2345]', ']][string aa"];',
'[keyword echo] [string "aaa][variable-2 $aaaa][[','[number 2.3]', ']][string aa"];',
'[keyword echo] [string "aaa][variable-2 $aaaa][[','[variable aaaaa]', ']][string aa"];',
'[keyword echo] [string "aaa][variable-2 $aaaa][[','[variable-2 $aaaaa]',']][string aa"];',
'[meta ?>]');
MT('variable_interpolation_simple_syntax_3',
'[meta <?php]',
'[keyword echo] [string "aaa][variable-2 $aaaa]->[variable aaaaa][string .aaaaaa"];',
'[keyword echo] [string "aaa][variable-2 $aaaa][string ->][variable-2 $aaaaa][string .aaaaaa"];',
'[keyword echo] [string "aaa][variable-2 $aaaa]->[variable aaaaa][string [[2]].aaaaaa"];',
'[keyword echo] [string "aaa][variable-2 $aaaa]->[variable aaaaa][string ->aaaa2.aaaaaa"];',
'[meta ?>]');
MT('variable_interpolation_escaping',
'[meta <?php] [comment /* Escaping */]',
'[keyword echo] [string "aaa\\$aaaa->aaa.aaa"];',
'[keyword echo] [string "aaa\\$aaaa[[2]]aaa.aaa"];',
'[keyword echo] [string "aaa\\$aaaa[[asd]]aaa.aaa"];',
'[keyword echo] [string "aaa{\\$aaaa->aaa.aaa"];',
'[keyword echo] [string "aaa{\\$aaaa[[2]]aaa.aaa"];',
'[keyword echo] [string "aaa{\\aaaaa[[asd]]aaa.aaa"];',
'[keyword echo] [string "aaa\\${aaaa->aaa.aaa"];',
'[keyword echo] [string "aaa\\${aaaa[[2]]aaa.aaa"];',
'[keyword echo] [string "aaa\\${aaaa[[asd]]aaa.aaa"];',
'[meta ?>]');
MT('variable_interpolation_complex_syntax_1',
'[meta <?php]',
'[keyword echo] [string "aaa][variable-2 $]{[variable aaaa]}[string ->aaa.aaa"];',
'[keyword echo] [string "aaa][variable-2 $]{[variable-2 $aaaa]}[string ->aaa.aaa"];',
'[keyword echo] [string "aaa][variable-2 $]{[variable-2 $aaaa][[',' [number 42]',']]}[string ->aaa.aaa"];',
'[keyword echo] [string "aaa][variable-2 $]{[variable aaaa][meta ?>]aaaaaa');
MT('variable_interpolation_complex_syntax_2',
'[meta <?php] [comment /* Monsters */]',
'[keyword echo] [string "][variable-2 $]{[variable aaa][comment /*}?>} $aaa<?php } */]}[string ->aaa.aaa"];',
'[keyword echo] [string "][variable-2 $]{[variable aaa][comment /*}?>*/][[',' [string "aaa][variable-2 $aaa][string {}][variable-2 $]{[variable aaa]}[string "]',']]}[string ->aaa.aaa"];',
'[keyword echo] [string "][variable-2 $]{[variable aaa][comment /*} } $aaa } */]}[string ->aaa.aaa"];');
function build_recursive_monsters(nt, t, n){
var monsters = [t];
for (var i = 1; i <= n; ++i)
monsters[i] = nt.join(monsters[i - 1]);
return monsters;
}
var m1 = build_recursive_monsters(
['[string "][variable-2 $]{[variable aaa] [operator +] ', '}[string "]'],
'[comment /* }?>} */] [string "aaa][variable-2 $aaa][string .aaa"]',
10
);
MT('variable_interpolation_complex_syntax_3_1',
'[meta <?php] [comment /* Recursive monsters */]',
'[keyword echo] ' + m1[4] + ';',
'[keyword echo] ' + m1[7] + ';',
'[keyword echo] ' + m1[8] + ';',
'[keyword echo] ' + m1[5] + ';',
'[keyword echo] ' + m1[1] + ';',
'[keyword echo] ' + m1[6] + ';',
'[keyword echo] ' + m1[9] + ';',
'[keyword echo] ' + m1[0] + ';',
'[keyword echo] ' + m1[10] + ';',
'[keyword echo] ' + m1[2] + ';',
'[keyword echo] ' + m1[3] + ';',
'[keyword echo] [string "end"];',
'[meta ?>]');
var m2 = build_recursive_monsters(
['[string "a][variable-2 $]{[variable aaa] [operator +] ', ' [operator +] ', '}[string .a"]'],
'[comment /* }?>{{ */] [string "a?>}{{aa][variable-2 $aaa][string .a}a?>a"]',
5
);
MT('variable_interpolation_complex_syntax_3_2',
'[meta <?php] [comment /* Recursive monsters 2 */]',
'[keyword echo] ' + m2[0] + ';',
'[keyword echo] ' + m2[1] + ';',
'[keyword echo] ' + m2[5] + ';',
'[keyword echo] ' + m2[4] + ';',
'[keyword echo] ' + m2[2] + ';',
'[keyword echo] ' + m2[3] + ';',
'[keyword echo] [string "end"];',
'[meta ?>]');
function build_recursive_monsters_2(mf1, mf2, nt, t, n){
var monsters = [t];
for (var i = 1; i <= n; ++i)
monsters[i] = nt[0] + mf1[i - 1] + nt[1] + mf2[i - 1] + nt[2] + monsters[i - 1] + nt[3];
return monsters;
}
var m3 = build_recursive_monsters_2(
m1,
m2,
['[string "a][variable-2 $]{[variable aaa] [operator +] ', ' [operator +] ', ' [operator +] ', '}[string .a"]'],
'[comment /* }?>{{ */] [string "a?>}{{aa][variable-2 $aaa][string .a}a?>a"]',
4
);
MT('variable_interpolation_complex_syntax_3_3',
'[meta <?php] [comment /* Recursive monsters 2 */]',
'[keyword echo] ' + m3[4] + ';',
'[keyword echo] ' + m3[0] + ';',
'[keyword echo] ' + m3[3] + ';',
'[keyword echo] ' + m3[1] + ';',
'[keyword echo] ' + m3[2] + ';',
'[keyword echo] [string "end"];',
'[meta ?>]');
MT("variable_interpolation_heredoc",
"[meta <?php]",
"[string <<<here]",
"[string doc ][variable-2 $]{[variable yay]}[string more]",
"[string here]; [comment // normal]");
})();

View File

@@ -0,0 +1,205 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Powershell mode</title>
<link rel="stylesheet" href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="powershell.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
</head>
<body>
<div id=nav>
<a href="https://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="#">JavaScript</a>
</ul>
</div>
<article>
<h2>PowerShell mode</h2>
<div><textarea id="code" name="code">
# Number Literals
0 12345
12kb 12mb 12gB 12Tb 12PB 12L 12D 12lkb 12dtb
1.234 1.234e56 1. 1.e2 .2 .2e34
1.2MB 1.kb .1dTb 1.e1gb
0x1 0xabcdef 0x3tb 0xelmb
# String Literals
'Literal escaping'''
'Literal $variable'
"Escaping 1`""
"Escaping 2"""
"Escaped `$variable"
"Text, $variable and more text"
"Text, ${variable with spaces} and more text."
"Text, $($expression + 3) and more text."
"Text, $("interpolation $("inception")") and more text."
@"
Multiline
string
"@
# --
@"
Multiline
string with quotes "'
"@
# --
@'
Multiline literal
string with quotes "'
'@
# Array and Hash literals
@( 'a','b','c' )
@{ 'key': 'value' }
# Variables
$Variable = 5
$global:variable = 5
${Variable with spaces} = 5
# Operators
= += -= *= /= %=
++ -- .. -f * / % + -
-not ! -bnot
-split -isplit -csplit
-join
-is -isnot -as
-eq -ieq -ceq -ne -ine -cne
-gt -igt -cgt -ge -ige -cge
-lt -ilt -clt -le -ile -cle
-like -ilike -clike -notlike -inotlike -cnotlike
-match -imatch -cmatch -notmatch -inotmatch -cnotmatch
-contains -icontains -ccontains -notcontains -inotcontains -cnotcontains
-replace -ireplace -creplace
-band -bor -bxor
-and -or -xor
# Punctuation
() [] {} , : ` = ; .
# Keywords
elseif begin function for foreach return else trap while do data dynamicparam
until end break if throw param continue finally in switch exit filter from try
process catch
# Built-in variables
$$ $? $^ $_
$args $ConfirmPreference $ConsoleFileName $DebugPreference $Error
$ErrorActionPreference $ErrorView $ExecutionContext $false $FormatEnumerationLimit
$HOME $Host $input $MaximumAliasCount $MaximumDriveCount $MaximumErrorCount
$MaximumFunctionCount $MaximumHistoryCount $MaximumVariableCount $MyInvocation
$NestedPromptLevel $null $OutputEncoding $PID $PROFILE $ProgressPreference
$PSBoundParameters $PSCommandPath $PSCulture $PSDefaultParameterValues
$PSEmailServer $PSHOME $PSScriptRoot $PSSessionApplicationName
$PSSessionConfigurationName $PSSessionOption $PSUICulture $PSVersionTable $PWD
$ShellId $StackTrace $true $VerbosePreference $WarningPreference $WhatIfPreference
$true $false $null
# Built-in functions
A:
Add-Computer Add-Content Add-History Add-Member Add-PSSnapin Add-Type
B:
C:
Checkpoint-Computer Clear-Content Clear-EventLog Clear-History Clear-Host Clear-Item
Clear-ItemProperty Clear-Variable Compare-Object Complete-Transaction Connect-PSSession
ConvertFrom-Csv ConvertFrom-Json ConvertFrom-SecureString ConvertFrom-StringData
Convert-Path ConvertTo-Csv ConvertTo-Html ConvertTo-Json ConvertTo-SecureString
ConvertTo-Xml Copy-Item Copy-ItemProperty
D:
Debug-Process Disable-ComputerRestore Disable-PSBreakpoint Disable-PSRemoting
Disable-PSSessionConfiguration Disconnect-PSSession
E:
Enable-ComputerRestore Enable-PSBreakpoint Enable-PSRemoting Enable-PSSessionConfiguration
Enter-PSSession Exit-PSSession Export-Alias Export-Clixml Export-Console Export-Counter
Export-Csv Export-FormatData Export-ModuleMember Export-PSSession
F:
ForEach-Object Format-Custom Format-List Format-Table Format-Wide
G:
Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command Get-ComputerRestorePoint
Get-Content Get-ControlPanelItem Get-Counter Get-Credential Get-Culture Get-Date
Get-Event Get-EventLog Get-EventSubscriber Get-ExecutionPolicy Get-FormatData Get-Help
Get-History Get-Host Get-HotFix Get-Item Get-ItemProperty Get-Job Get-Location Get-Member
Get-Module Get-PfxCertificate Get-Process Get-PSBreakpoint Get-PSCallStack Get-PSDrive
Get-PSProvider Get-PSSession Get-PSSessionConfiguration Get-PSSnapin Get-Random Get-Service
Get-TraceSource Get-Transaction Get-TypeData Get-UICulture Get-Unique Get-Variable Get-Verb
Get-WinEvent Get-WmiObject Group-Object
H:
help
I:
Import-Alias Import-Clixml Import-Counter Import-Csv Import-LocalizedData Import-Module
Import-PSSession ImportSystemModules Invoke-Command Invoke-Expression Invoke-History
Invoke-Item Invoke-RestMethod Invoke-WebRequest Invoke-WmiMethod
J:
Join-Path
K:
L:
Limit-EventLog
M:
Measure-Command Measure-Object mkdir more Move-Item Move-ItemProperty
N:
New-Alias New-Event New-EventLog New-Item New-ItemProperty New-Module New-ModuleManifest
New-Object New-PSDrive New-PSSession New-PSSessionConfigurationFile New-PSSessionOption
New-PSTransportOption New-Service New-TimeSpan New-Variable New-WebServiceProxy
New-WinEvent
O:
oss Out-Default Out-File Out-GridView Out-Host Out-Null Out-Printer Out-String
P:
Pause Pop-Location prompt Push-Location
Q:
R:
Read-Host Receive-Job Receive-PSSession Register-EngineEvent Register-ObjectEvent
Register-PSSessionConfiguration Register-WmiEvent Remove-Computer Remove-Event
Remove-EventLog Remove-Item Remove-ItemProperty Remove-Job Remove-Module
Remove-PSBreakpoint Remove-PSDrive Remove-PSSession Remove-PSSnapin Remove-TypeData
Remove-Variable Remove-WmiObject Rename-Computer Rename-Item Rename-ItemProperty
Reset-ComputerMachinePassword Resolve-Path Restart-Computer Restart-Service
Restore-Computer Resume-Job Resume-Service
S:
Save-Help Select-Object Select-String Select-Xml Send-MailMessage Set-Acl Set-Alias
Set-AuthenticodeSignature Set-Content Set-Date Set-ExecutionPolicy Set-Item
Set-ItemProperty Set-Location Set-PSBreakpoint Set-PSDebug
Set-PSSessionConfiguration Set-Service Set-StrictMode Set-TraceSource Set-Variable
Set-WmiInstance Show-Command Show-ControlPanelItem Show-EventLog Sort-Object
Split-Path Start-Job Start-Process Start-Service Start-Sleep Start-Transaction
Start-Transcript Stop-Computer Stop-Job Stop-Process Stop-Service Stop-Transcript
Suspend-Job Suspend-Service
T:
TabExpansion2 Tee-Object Test-ComputerSecureChannel Test-Connection
Test-ModuleManifest Test-Path Test-PSSessionConfigurationFile Trace-Command
U:
Unblock-File Undo-Transaction Unregister-Event Unregister-PSSessionConfiguration
Update-FormatData Update-Help Update-List Update-TypeData Use-Transaction
V:
W:
Wait-Event Wait-Job Wait-Process Where-Object Write-Debug Write-Error Write-EventLog
Write-Host Write-Output Write-Progress Write-Verbose Write-Warning
X:
Y:
Z:</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "powershell",
lineNumbers: true,
indentUnit: 4,
tabMode: "shift",
matchBrackets: true
});
</script>
<p><strong>MIME types defined:</strong> <code>application/x-powershell</code>.</p>
</article>
</body>
</html>

View File

@@ -0,0 +1,398 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
'use strict';
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(window.CodeMirror);
})(function(CodeMirror) {
'use strict';
CodeMirror.defineMode('powershell', function() {
function buildRegexp(patterns, options) {
options = options || {};
var prefix = options.prefix !== undefined ? options.prefix : '^';
var suffix = options.suffix !== undefined ? options.suffix : '\\b';
for (var i = 0; i < patterns.length; i++) {
if (patterns[i] instanceof RegExp) {
patterns[i] = patterns[i].source;
}
else {
patterns[i] = patterns[i].replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
}
return new RegExp(prefix + '(' + patterns.join('|') + ')' + suffix, 'i');
}
var notCharacterOrDash = '(?=[^A-Za-z\\d\\-_]|$)';
var varNames = /[\w\-:]/
var keywords = buildRegexp([
/begin|break|catch|continue|data|default|do|dynamicparam/,
/else|elseif|end|exit|filter|finally|for|foreach|from|function|if|in/,
/param|process|return|switch|throw|trap|try|until|where|while/
], { suffix: notCharacterOrDash });
var punctuation = /[\[\]{},;`\.]|@[({]/;
var wordOperators = buildRegexp([
'f',
/b?not/,
/[ic]?split/, 'join',
/is(not)?/, 'as',
/[ic]?(eq|ne|[gl][te])/,
/[ic]?(not)?(like|match|contains)/,
/[ic]?replace/,
/b?(and|or|xor)/
], { prefix: '-' });
var symbolOperators = /[+\-*\/%]=|\+\+|--|\.\.|[+\-*&^%:=!|\/]|<(?!#)|(?!#)>/;
var operators = buildRegexp([wordOperators, symbolOperators], { suffix: '' });
var numbers = /^((0x[\da-f]+)|((\d+\.\d+|\d\.|\.\d+|\d+)(e[\+\-]?\d+)?))[ld]?([kmgtp]b)?/i;
var identifiers = /^[A-Za-z\_][A-Za-z\-\_\d]*\b/;
var symbolBuiltins = /[A-Z]:|%|\?/i;
var namedBuiltins = buildRegexp([
/Add-(Computer|Content|History|Member|PSSnapin|Type)/,
/Checkpoint-Computer/,
/Clear-(Content|EventLog|History|Host|Item(Property)?|Variable)/,
/Compare-Object/,
/Complete-Transaction/,
/Connect-PSSession/,
/ConvertFrom-(Csv|Json|SecureString|StringData)/,
/Convert-Path/,
/ConvertTo-(Csv|Html|Json|SecureString|Xml)/,
/Copy-Item(Property)?/,
/Debug-Process/,
/Disable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)/,
/Disconnect-PSSession/,
/Enable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)/,
/(Enter|Exit)-PSSession/,
/Export-(Alias|Clixml|Console|Counter|Csv|FormatData|ModuleMember|PSSession)/,
/ForEach-Object/,
/Format-(Custom|List|Table|Wide)/,
new RegExp('Get-(Acl|Alias|AuthenticodeSignature|ChildItem|Command|ComputerRestorePoint|Content|ControlPanelItem|Counter|Credential'
+ '|Culture|Date|Event|EventLog|EventSubscriber|ExecutionPolicy|FormatData|Help|History|Host|HotFix|Item|ItemProperty|Job'
+ '|Location|Member|Module|PfxCertificate|Process|PSBreakpoint|PSCallStack|PSDrive|PSProvider|PSSession|PSSessionConfiguration'
+ '|PSSnapin|Random|Service|TraceSource|Transaction|TypeData|UICulture|Unique|Variable|Verb|WinEvent|WmiObject)'),
/Group-Object/,
/Import-(Alias|Clixml|Counter|Csv|LocalizedData|Module|PSSession)/,
/ImportSystemModules/,
/Invoke-(Command|Expression|History|Item|RestMethod|WebRequest|WmiMethod)/,
/Join-Path/,
/Limit-EventLog/,
/Measure-(Command|Object)/,
/Move-Item(Property)?/,
new RegExp('New-(Alias|Event|EventLog|Item(Property)?|Module|ModuleManifest|Object|PSDrive|PSSession|PSSessionConfigurationFile'
+ '|PSSessionOption|PSTransportOption|Service|TimeSpan|Variable|WebServiceProxy|WinEvent)'),
/Out-(Default|File|GridView|Host|Null|Printer|String)/,
/Pause/,
/(Pop|Push)-Location/,
/Read-Host/,
/Receive-(Job|PSSession)/,
/Register-(EngineEvent|ObjectEvent|PSSessionConfiguration|WmiEvent)/,
/Remove-(Computer|Event|EventLog|Item(Property)?|Job|Module|PSBreakpoint|PSDrive|PSSession|PSSnapin|TypeData|Variable|WmiObject)/,
/Rename-(Computer|Item(Property)?)/,
/Reset-ComputerMachinePassword/,
/Resolve-Path/,
/Restart-(Computer|Service)/,
/Restore-Computer/,
/Resume-(Job|Service)/,
/Save-Help/,
/Select-(Object|String|Xml)/,
/Send-MailMessage/,
new RegExp('Set-(Acl|Alias|AuthenticodeSignature|Content|Date|ExecutionPolicy|Item(Property)?|Location|PSBreakpoint|PSDebug' +
'|PSSessionConfiguration|Service|StrictMode|TraceSource|Variable|WmiInstance)'),
/Show-(Command|ControlPanelItem|EventLog)/,
/Sort-Object/,
/Split-Path/,
/Start-(Job|Process|Service|Sleep|Transaction|Transcript)/,
/Stop-(Computer|Job|Process|Service|Transcript)/,
/Suspend-(Job|Service)/,
/TabExpansion2/,
/Tee-Object/,
/Test-(ComputerSecureChannel|Connection|ModuleManifest|Path|PSSessionConfigurationFile)/,
/Trace-Command/,
/Unblock-File/,
/Undo-Transaction/,
/Unregister-(Event|PSSessionConfiguration)/,
/Update-(FormatData|Help|List|TypeData)/,
/Use-Transaction/,
/Wait-(Event|Job|Process)/,
/Where-Object/,
/Write-(Debug|Error|EventLog|Host|Output|Progress|Verbose|Warning)/,
/cd|help|mkdir|more|oss|prompt/,
/ac|asnp|cat|cd|chdir|clc|clear|clhy|cli|clp|cls|clv|cnsn|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|dnsn|ebp/,
/echo|epal|epcsv|epsn|erase|etsn|exsn|fc|fl|foreach|ft|fw|gal|gbp|gc|gci|gcm|gcs|gdr|ghy|gi|gjb|gl|gm|gmo|gp|gps/,
/group|gsn|gsnp|gsv|gu|gv|gwmi|h|history|icm|iex|ihy|ii|ipal|ipcsv|ipmo|ipsn|irm|ise|iwmi|iwr|kill|lp|ls|man|md/,
/measure|mi|mount|move|mp|mv|nal|ndr|ni|nmo|npssc|nsn|nv|ogv|oh|popd|ps|pushd|pwd|r|rbp|rcjb|rcsn|rd|rdr|ren|ri/,
/rjb|rm|rmdir|rmo|rni|rnp|rp|rsn|rsnp|rujb|rv|rvpa|rwmi|sajb|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls/,
/sort|sp|spjb|spps|spsv|start|sujb|sv|swmi|tee|trcm|type|where|wjb|write/
], { prefix: '', suffix: '' });
var variableBuiltins = buildRegexp([
/[$?^_]|Args|ConfirmPreference|ConsoleFileName|DebugPreference|Error|ErrorActionPreference|ErrorView|ExecutionContext/,
/FormatEnumerationLimit|Home|Host|Input|MaximumAliasCount|MaximumDriveCount|MaximumErrorCount|MaximumFunctionCount/,
/MaximumHistoryCount|MaximumVariableCount|MyInvocation|NestedPromptLevel|OutputEncoding|Pid|Profile|ProgressPreference/,
/PSBoundParameters|PSCommandPath|PSCulture|PSDefaultParameterValues|PSEmailServer|PSHome|PSScriptRoot|PSSessionApplicationName/,
/PSSessionConfigurationName|PSSessionOption|PSUICulture|PSVersionTable|Pwd|ShellId|StackTrace|VerbosePreference/,
/WarningPreference|WhatIfPreference/,
/Event|EventArgs|EventSubscriber|Sender/,
/Matches|Ofs|ForEach|LastExitCode|PSCmdlet|PSItem|PSSenderInfo|This/,
/true|false|null/
], { prefix: '\\$', suffix: '' });
var builtins = buildRegexp([symbolBuiltins, namedBuiltins, variableBuiltins], { suffix: notCharacterOrDash });
var grammar = {
keyword: keywords,
number: numbers,
operator: operators,
builtin: builtins,
punctuation: punctuation,
identifier: identifiers
};
// tokenizers
function tokenBase(stream, state) {
// Handle Comments
//var ch = stream.peek();
var parent = state.returnStack[state.returnStack.length - 1];
if (parent && parent.shouldReturnFrom(state)) {
state.tokenize = parent.tokenize;
state.returnStack.pop();
return state.tokenize(stream, state);
}
if (stream.eatSpace()) {
return null;
}
if (stream.eat('(')) {
state.bracketNesting += 1;
return 'punctuation';
}
if (stream.eat(')')) {
state.bracketNesting -= 1;
return 'punctuation';
}
for (var key in grammar) {
if (stream.match(grammar[key])) {
return key;
}
}
var ch = stream.next();
// single-quote string
if (ch === "'") {
return tokenSingleQuoteString(stream, state);
}
if (ch === '$') {
return tokenVariable(stream, state);
}
// double-quote string
if (ch === '"') {
return tokenDoubleQuoteString(stream, state);
}
if (ch === '<' && stream.eat('#')) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
}
if (ch === '#') {
stream.skipToEnd();
return 'comment';
}
if (ch === '@') {
var quoteMatch = stream.eat(/["']/);
if (quoteMatch && stream.eol()) {
state.tokenize = tokenMultiString;
state.startQuote = quoteMatch[0];
return tokenMultiString(stream, state);
} else if (stream.eol()) {
return 'error';
} else if (stream.peek().match(/[({]/)) {
return 'punctuation';
} else if (stream.peek().match(varNames)) {
// splatted variable
return tokenVariable(stream, state);
}
}
return 'error';
}
function tokenSingleQuoteString(stream, state) {
var ch;
while ((ch = stream.peek()) != null) {
stream.next();
if (ch === "'" && !stream.eat("'")) {
state.tokenize = tokenBase;
return 'string';
}
}
return 'error';
}
function tokenDoubleQuoteString(stream, state) {
var ch;
while ((ch = stream.peek()) != null) {
if (ch === '$') {
state.tokenize = tokenStringInterpolation;
return 'string';
}
stream.next();
if (ch === '`') {
stream.next();
continue;
}
if (ch === '"' && !stream.eat('"')) {
state.tokenize = tokenBase;
return 'string';
}
}
return 'error';
}
function tokenStringInterpolation(stream, state) {
return tokenInterpolation(stream, state, tokenDoubleQuoteString);
}
function tokenMultiStringReturn(stream, state) {
state.tokenize = tokenMultiString;
state.startQuote = '"'
return tokenMultiString(stream, state);
}
function tokenHereStringInterpolation(stream, state) {
return tokenInterpolation(stream, state, tokenMultiStringReturn);
}
function tokenInterpolation(stream, state, parentTokenize) {
if (stream.match('$(')) {
var savedBracketNesting = state.bracketNesting;
state.returnStack.push({
/*jshint loopfunc:true */
shouldReturnFrom: function(state) {
return state.bracketNesting === savedBracketNesting;
},
tokenize: parentTokenize
});
state.tokenize = tokenBase;
state.bracketNesting += 1;
return 'punctuation';
} else {
stream.next();
state.returnStack.push({
shouldReturnFrom: function() { return true; },
tokenize: parentTokenize
});
state.tokenize = tokenVariable;
return state.tokenize(stream, state);
}
}
function tokenComment(stream, state) {
var maybeEnd = false, ch;
while ((ch = stream.next()) != null) {
if (maybeEnd && ch == '>') {
state.tokenize = tokenBase;
break;
}
maybeEnd = (ch === '#');
}
return 'comment';
}
function tokenVariable(stream, state) {
var ch = stream.peek();
if (stream.eat('{')) {
state.tokenize = tokenVariableWithBraces;
return tokenVariableWithBraces(stream, state);
} else if (ch != undefined && ch.match(varNames)) {
stream.eatWhile(varNames);
state.tokenize = tokenBase;
return 'variable-2';
} else {
state.tokenize = tokenBase;
return 'error';
}
}
function tokenVariableWithBraces(stream, state) {
var ch;
while ((ch = stream.next()) != null) {
if (ch === '}') {
state.tokenize = tokenBase;
break;
}
}
return 'variable-2';
}
function tokenMultiString(stream, state) {
var quote = state.startQuote;
if (stream.sol() && stream.match(new RegExp(quote + '@'))) {
state.tokenize = tokenBase;
}
else if (quote === '"') {
while (!stream.eol()) {
var ch = stream.peek();
if (ch === '$') {
state.tokenize = tokenHereStringInterpolation;
return 'string';
}
stream.next();
if (ch === '`') {
stream.next();
}
}
}
else {
stream.skipToEnd();
}
return 'string';
}
var external = {
startState: function() {
return {
returnStack: [],
bracketNesting: 0,
tokenize: tokenBase
};
},
token: function(stream, state) {
return state.tokenize(stream, state);
},
blockCommentStart: '<#',
blockCommentEnd: '#>',
lineComment: '#',
fold: 'brace'
};
return external;
});
CodeMirror.defineMIME('application/x-powershell', 'powershell');
});

View File

@@ -0,0 +1,74 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "powershell");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
function forEach(arr, f) { for (var i = 0; i < arr.length; i++) f(arr[i], i) }
MT('comment', '[number 1][comment # A]');
MT('comment_multiline', '[number 1][comment <#]',
'[comment ABC]',
'[comment #>][number 2]');
forEach([
'0', '1234',
'12kb', '12mb', '12Gb', '12Tb', '12PB', '12L', '12D', '12lkb', '12dtb',
'1.234', '1.234e56', '1.', '1.e2', '.2', '.2e34',
'1.2MB', '1.kb', '.1dTB', '1.e1gb', '.2', '.2e34',
'0x1', '0xabcdef', '0x3tb', '0xelmb'
], function(number) {
MT("number_" + number, "[number " + number + "]");
});
MT('string_literal_escaping', "[string 'a''']");
MT('string_literal_variable', "[string 'a $x']");
MT('string_escaping_1', '[string "a `""]');
MT('string_escaping_2', '[string "a """]');
MT('string_variable_escaping', '[string "a `$x"]');
MT('string_variable', '[string "a ][variable-2 $x][string b"]');
MT('string_variable_spaces', '[string "a ][variable-2 ${x y}][string b"]');
MT('string_expression', '[string "a ][punctuation $(][variable-2 $x][operator +][number 3][punctuation )][string b"]');
MT('string_expression_nested', '[string "A][punctuation $(][string "a][punctuation $(][string "w"][punctuation )][string b"][punctuation )][string B"]');
MT('string_heredoc', '[string @"]',
'[string abc]',
'[string "@]');
MT('string_heredoc_quotes', '[string @"]',
'[string abc "\']',
'[string "@]');
MT('string_heredoc_variable', '[string @"]',
'[string a ][variable-2 $x][string b]',
'[string "@]');
MT('string_heredoc_nested_string', '[string @"]',
'[string a][punctuation $(][string "w"][punctuation )][string b]',
'[string "@]');
MT('string_heredoc_literal_quotes', "[string @']",
'[string abc "\']',
"[string '@]");
MT('array', "[punctuation @(][string 'a'][punctuation ,][string 'b'][punctuation )]");
MT('hash', "[punctuation @{][string 'key'][operator :][string 'value'][punctuation }]");
MT('variable', "[variable-2 $test]");
MT('variable_global', "[variable-2 $global:test]");
MT('variable_spaces', "[variable-2 ${test test}]");
MT('operator_splat', "[variable-2 @x]");
MT('variable_builtin', "[builtin $ErrorActionPreference]");
MT('variable_builtin_symbols', "[builtin $$]");
MT('operator', "[operator +]");
MT('operator_unary', "[operator +][number 3]");
MT('operator_long', "[operator -match]");
forEach([
'(', ')', '[[', ']]', '{', '}', ',', '`', ';', '.'
], function(punctuation) {
MT("punctuation_" + punctuation.replace(/^[\[\]]/,''), "[punctuation " + punctuation + "]");
});
MT('keyword', "[keyword if]");
MT('call_builtin', "[builtin Get-ChildItem]");
})();

View File

@@ -0,0 +1,53 @@
<!doctype html>
<title>CodeMirror: Properties files 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="properties.js"></script>
<style>.CodeMirror {border-top: 1px solid #ddd; border-bottom: 1px solid #ddd;}</style>
<div id=nav>
<a href="https://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="#">Properties files</a>
</ul>
</div>
<article>
<h2>Properties files mode</h2>
<form><textarea id="code" name="code">
# This is a properties file
a.key = A value
another.key = http://example.com
! Exclamation mark as comment
but.not=Within ! A value # indeed
# Spaces at the beginning of a line
spaces.before.key=value
backslash=Used for multi\
line entries,\
that's convenient.
# Unicode sequences
unicode.key=This is \u0020 Unicode
no.multiline=here
# Colons
colons : can be used too
# Spaces
spaces\ in\ keys=Not very common...
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-properties</code>,
<code>text/x-ini</code>.</p>
</article>

View File

@@ -0,0 +1,78 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("properties", function() {
return {
token: function(stream, state) {
var sol = stream.sol() || state.afterSection;
var eol = stream.eol();
state.afterSection = false;
if (sol) {
if (state.nextMultiline) {
state.inMultiline = true;
state.nextMultiline = false;
} else {
state.position = "def";
}
}
if (eol && ! state.nextMultiline) {
state.inMultiline = false;
state.position = "def";
}
if (sol) {
while(stream.eatSpace()) {}
}
var ch = stream.next();
if (sol && (ch === "#" || ch === "!" || ch === ";")) {
state.position = "comment";
stream.skipToEnd();
return "comment";
} else if (sol && ch === "[") {
state.afterSection = true;
stream.skipTo("]"); stream.eat("]");
return "header";
} else if (ch === "=" || ch === ":") {
state.position = "quote";
return null;
} else if (ch === "\\" && state.position === "quote") {
if (stream.eol()) { // end of line?
// Multiline value
state.nextMultiline = true;
}
}
return state.position;
},
startState: function() {
return {
position : "def", // Current position, "def", "quote" or "comment"
nextMultiline : false, // Is the next line multiline value
inMultiline : false, // Is the current line a multiline value
afterSection : false // Did we just open a section
};
}
};
});
CodeMirror.defineMIME("text/x-properties", "properties");
CodeMirror.defineMIME("text/x-ini", "properties");
});

View File

@@ -0,0 +1,104 @@
<!doctype html>
<title>CodeMirror: ProtoBuf 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="protobuf.js"></script>
<style>.CodeMirror { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; }</style>
<div id=nav>
<a href="https://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="#">ProtoBuf</a>
</ul>
</div>
<article>
<h2>ProtoBuf mode</h2>
<form><textarea id="code" name="code">
package addressbook;
message Address {
required string street = 1;
required string postCode = 2;
}
message PhoneNumber {
required string number = 1;
}
message Person {
optional int32 id = 1;
required string name = 2;
required string surname = 3;
optional Address address = 4;
repeated PhoneNumber phoneNumbers = 5;
optional uint32 age = 6;
repeated uint32 favouriteNumbers = 7;
optional string license = 8;
enum Gender {
MALE = 0;
FEMALE = 1;
}
optional Gender gender = 9;
optional fixed64 lastUpdate = 10;
required bool deleted = 11 [default = false];
}
</textarea>
<textarea id="code2" name="code2">
syntax = "proto3";
package tutorial;
import "google/protobuf/timestamp.proto";
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
option csharp_namespace = "Google.Protobuf.Examples.AddressBook";
message Person {
string name = 1;
int32 id = 2; // Unique ID number for this person.
string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4;
google.protobuf.Timestamp last_updated = 5;
}
// Our address book file is just one of these.
message AddressBook {
repeated Person people = 1;
}
service Test {
rpc SayHello (HelloRequest) returns (HelloReply) {}
rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}</textarea>
</form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
var editor = CodeMirror.fromTextArea(document.getElementById("code2"), {});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-protobuf</code>.</p>
</article>

View File

@@ -0,0 +1,69 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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";
function wordRegexp(words) {
return new RegExp("^((" + words.join(")|(") + "))\\b", "i");
};
var keywordArray = [
"package", "message", "import", "syntax",
"required", "optional", "repeated", "reserved", "default", "extensions", "packed",
"bool", "bytes", "double", "enum", "float", "string",
"int32", "int64", "uint32", "uint64", "sint32", "sint64", "fixed32", "fixed64", "sfixed32", "sfixed64",
"option", "service", "rpc", "returns"
];
var keywords = wordRegexp(keywordArray);
CodeMirror.registerHelper("hintWords", "protobuf", keywordArray);
var identifiers = new RegExp("^[_A-Za-z\xa1-\uffff][_A-Za-z0-9\xa1-\uffff]*");
function tokenBase(stream) {
// whitespaces
if (stream.eatSpace()) return null;
// Handle one line Comments
if (stream.match("//")) {
stream.skipToEnd();
return "comment";
}
// Handle Number Literals
if (stream.match(/^[0-9\.+-]/, false)) {
if (stream.match(/^[+-]?0x[0-9a-fA-F]+/))
return "number";
if (stream.match(/^[+-]?\d*\.\d+([EeDd][+-]?\d+)?/))
return "number";
if (stream.match(/^[+-]?\d+([EeDd][+-]?\d+)?/))
return "number";
}
// Handle Strings
if (stream.match(/^"([^"]|(""))*"/)) { return "string"; }
if (stream.match(/^'([^']|(''))*'/)) { return "string"; }
// Handle words
if (stream.match(keywords)) { return "keyword"; }
if (stream.match(identifiers)) { return "variable"; } ;
// Handle non-detected items
stream.next();
return null;
};
CodeMirror.defineMode("protobuf", function() {
return {token: tokenBase};
});
CodeMirror.defineMIME("text/x-protobuf", "protobuf");
});

View File

@@ -0,0 +1,121 @@
<!doctype html>
<title>CodeMirror: Puppet 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="../../addon/edit/matchbrackets.js"></script>
<script src="puppet.js"></script>
<style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
.cm-s-default span.cm-arrow { color: red; }
</style>
<div id=nav>
<a href="https://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="#">Puppet</a>
</ul>
</div>
<article>
<h2>Puppet mode</h2>
<form><textarea id="code" name="code">
# == Class: automysqlbackup
#
# Puppet module to install AutoMySQLBackup for periodic MySQL backups.
#
# class { 'automysqlbackup':
# backup_dir => '/mnt/backups',
# }
#
class automysqlbackup (
$bin_dir = $automysqlbackup::params::bin_dir,
$etc_dir = $automysqlbackup::params::etc_dir,
$backup_dir = $automysqlbackup::params::backup_dir,
$install_multicore = undef,
$config = {},
$config_defaults = {},
) inherits automysqlbackup::params {
# Ensure valid paths are assigned
validate_absolute_path($bin_dir)
validate_absolute_path($etc_dir)
validate_absolute_path($backup_dir)
# Create a subdirectory in /etc for config files
file { $etc_dir:
ensure => directory,
owner => 'root',
group => 'root',
mode => '0750',
}
# Create an example backup file, useful for reference
file { "${etc_dir}/automysqlbackup.conf.example":
ensure => file,
owner => 'root',
group => 'root',
mode => '0660',
source => 'puppet:///modules/automysqlbackup/automysqlbackup.conf',
}
# Add files from the developer
file { "${etc_dir}/AMB_README":
ensure => file,
source => 'puppet:///modules/automysqlbackup/AMB_README',
}
file { "${etc_dir}/AMB_LICENSE":
ensure => file,
source => 'puppet:///modules/automysqlbackup/AMB_LICENSE',
}
# Install the actual binary file
file { "${bin_dir}/automysqlbackup":
ensure => file,
owner => 'root',
group => 'root',
mode => '0755',
source => 'puppet:///modules/automysqlbackup/automysqlbackup',
}
# Create the base backup directory
file { $backup_dir:
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
# If you'd like to keep your config in hiera and pass it to this class
if !empty($config) {
create_resources('automysqlbackup::backup', $config, $config_defaults)
}
# If using RedHat family, must have the RPMforge repo's enabled
if $install_multicore {
package { ['pigz', 'pbzip2']: ensure => installed }
}
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "text/x-puppet",
matchBrackets: true,
indentUnit: 4
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-puppet</code>.</p>
</article>

View File

@@ -0,0 +1,220 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("puppet", function () {
// Stores the words from the define method
var words = {};
// Taken, mostly, from the Puppet official variable standards regex
var variable_regex = /({)?([a-z][a-z0-9_]*)?((::[a-z][a-z0-9_]*)*::)?[a-zA-Z0-9_]+(})?/;
// Takes a string of words separated by spaces and adds them as
// keys with the value of the first argument 'style'
function define(style, string) {
var split = string.split(' ');
for (var i = 0; i < split.length; i++) {
words[split[i]] = style;
}
}
// Takes commonly known puppet types/words and classifies them to a style
define('keyword', 'class define site node include import inherits');
define('keyword', 'case if else in and elsif default or');
define('atom', 'false true running present absent file directory undef');
define('builtin', 'action augeas burst chain computer cron destination dport exec ' +
'file filebucket group host icmp iniface interface jump k5login limit log_level ' +
'log_prefix macauthorization mailalias maillist mcx mount nagios_command ' +
'nagios_contact nagios_contactgroup nagios_host nagios_hostdependency ' +
'nagios_hostescalation nagios_hostextinfo nagios_hostgroup nagios_service ' +
'nagios_servicedependency nagios_serviceescalation nagios_serviceextinfo ' +
'nagios_servicegroup nagios_timeperiod name notify outiface package proto reject ' +
'resources router schedule scheduled_task selboolean selmodule service source ' +
'sport ssh_authorized_key sshkey stage state table tidy todest toports tosource ' +
'user vlan yumrepo zfs zone zpool');
// After finding a start of a string ('|") this function attempts to find the end;
// If a variable is encountered along the way, we display it differently when it
// is encapsulated in a double-quoted string.
function tokenString(stream, state) {
var current, prev, found_var = false;
while (!stream.eol() && (current = stream.next()) != state.pending) {
if (current === '$' && prev != '\\' && state.pending == '"') {
found_var = true;
break;
}
prev = current;
}
if (found_var) {
stream.backUp(1);
}
if (current == state.pending) {
state.continueString = false;
} else {
state.continueString = true;
}
return "string";
}
// Main function
function tokenize(stream, state) {
// Matches one whole word
var word = stream.match(/[\w]+/, false);
// Matches attributes (i.e. ensure => present ; 'ensure' would be matched)
var attribute = stream.match(/(\s+)?\w+\s+=>.*/, false);
// Matches non-builtin resource declarations
// (i.e. "apache::vhost {" or "mycustomclasss {" would be matched)
var resource = stream.match(/(\s+)?[\w:_]+(\s+)?{/, false);
// Matches virtual and exported resources (i.e. @@user { ; and the like)
var special_resource = stream.match(/(\s+)?[@]{1,2}[\w:_]+(\s+)?{/, false);
// Finally advance the stream
var ch = stream.next();
// Have we found a variable?
if (ch === '$') {
if (stream.match(variable_regex)) {
// If so, and its in a string, assign it a different color
return state.continueString ? 'variable-2' : 'variable';
}
// Otherwise return an invalid variable
return "error";
}
// Should we still be looking for the end of a string?
if (state.continueString) {
// If so, go through the loop again
stream.backUp(1);
return tokenString(stream, state);
}
// Are we in a definition (class, node, define)?
if (state.inDefinition) {
// If so, return def (i.e. for 'class myclass {' ; 'myclass' would be matched)
if (stream.match(/(\s+)?[\w:_]+(\s+)?/)) {
return 'def';
}
// Match the rest it the next time around
stream.match(/\s+{/);
state.inDefinition = false;
}
// Are we in an 'include' statement?
if (state.inInclude) {
// Match and return the included class
stream.match(/(\s+)?\S+(\s+)?/);
state.inInclude = false;
return 'def';
}
// Do we just have a function on our hands?
// In 'ensure_resource("myclass")', 'ensure_resource' is matched
if (stream.match(/(\s+)?\w+\(/)) {
stream.backUp(1);
return 'def';
}
// Have we matched the prior attribute regex?
if (attribute) {
stream.match(/(\s+)?\w+/);
return 'tag';
}
// Do we have Puppet specific words?
if (word && words.hasOwnProperty(word)) {
// Negates the initial next()
stream.backUp(1);
// rs move the stream
stream.match(/[\w]+/);
// We want to process these words differently
// do to the importance they have in Puppet
if (stream.match(/\s+\S+\s+{/, false)) {
state.inDefinition = true;
}
if (word == 'include') {
state.inInclude = true;
}
// Returns their value as state in the prior define methods
return words[word];
}
// Is there a match on a reference?
if (/(^|\s+)[A-Z][\w:_]+/.test(word)) {
// Negate the next()
stream.backUp(1);
// Match the full reference
stream.match(/(^|\s+)[A-Z][\w:_]+/);
return 'def';
}
// Have we matched the prior resource regex?
if (resource) {
stream.match(/(\s+)?[\w:_]+/);
return 'def';
}
// Have we matched the prior special_resource regex?
if (special_resource) {
stream.match(/(\s+)?[@]{1,2}/);
return 'special';
}
// Match all the comments. All of them.
if (ch == "#") {
stream.skipToEnd();
return "comment";
}
// Have we found a string?
if (ch == "'" || ch == '"') {
// Store the type (single or double)
state.pending = ch;
// Perform the looping function to find the end
return tokenString(stream, state);
}
// Match all the brackets
if (ch == '{' || ch == '}') {
return 'bracket';
}
// Match characters that we are going to assume
// are trying to be regex
if (ch == '/') {
stream.match(/.*?\//);
return 'variable-3';
}
// Match all the numbers
if (ch.match(/[0-9]/)) {
stream.eatWhile(/[0-9]+/);
return 'number';
}
// Match the '=' and '=>' operators
if (ch == '=') {
if (stream.peek() == '>') {
stream.next();
}
return "operator";
}
// Keep advancing through all the rest
stream.eatWhile(/[\w-]/);
// Return a blank line for everything else
return null;
}
// Start it all
return {
startState: function () {
var state = {};
state.inDefinition = false;
state.inInclude = false;
state.continueString = false;
state.pending = false;
return state;
},
token: function (stream, state) {
// Strip the spaces, but regex will account for them eitherway
if (stream.eatSpace()) return null;
// Go through the main process
return tokenize(stream, state);
}
};
});
CodeMirror.defineMIME("text/x-puppet", "puppet");
});

View File

@@ -0,0 +1,207 @@
<!doctype html>
<title>CodeMirror: Python 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="../../addon/edit/matchbrackets.js"></script>
<script src="python.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">Python</a>
</ul>
</div>
<article>
<h2>Python mode</h2>
<div><textarea id="code" name="code">
# Literals
1234
0.0e101
.123
0b01010011100
0o01234567
0x0987654321abcdef
7
2147483647
3L
79228162514264337593543950336L
0x100000000L
79228162514264337593543950336
0xdeadbeef
3.14j
10.j
10j
.001j
1e100j
3.14e-10j
# String Literals
'For\''
"God\""
"""so loved
the world"""
'''that he gave
his only begotten\' '''
'that whosoever believeth \
in him'
''
# Identifiers
__a__
a.b
a.b.c
#Unicode identifiers on Python3
# a = x\ddot
a⃗ = ẍ
# a = v\dot
a⃗ = v̇
#F\vec = m \cdot a\vec
F⃗ = m•a⃗
# Operators
+ - * / % & | ^ ~ < >
== != <= >= <> << >> // **
and or not in is
#infix matrix multiplication operator (PEP 465)
A @ B
# Delimiters
() [] {} , : ` = ; @ . # Note that @ and . require the proper context on Python 2.
+= -= *= /= %= &= |= ^=
//= >>= <<= **=
# Keywords
as assert break class continue def del elif else except
finally for from global if import lambda pass raise
return try while with yield
# Python 2 Keywords (otherwise Identifiers)
exec print
# Python 3 Keywords (otherwise Identifiers)
nonlocal
# Types
bool classmethod complex dict enumerate float frozenset int list object
property reversed set slice staticmethod str super tuple type
# Python 2 Types (otherwise Identifiers)
basestring buffer file long unicode xrange
# Python 3 Types (otherwise Identifiers)
bytearray bytes filter map memoryview open range zip
# Some Example code
import os
from package import ParentClass
@nonsenseDecorator
def doesNothing():
pass
class ExampleClass(ParentClass):
@staticmethod
def example(inputStr):
a = list(inputStr)
a.reverse()
return ''.join(a)
def __init__(self, mixin = 'Hello'):
self.mixin = mixin
# Python 3.6 f-strings (https://www.python.org/dev/peps/pep-0498/)
f'My name is {name}, my age next year is {age+1}, my anniversary is {anniversary:%A, %B %d, %Y}.'
f'He said his name is {name!r}.'
f"""He said his name is {name!r}."""
f'{"quoted string"}'
f'{{ {4*10} }}'
f'This is an error }'
f'This is ok }}'
fr'x={4*10}\n'
</textarea></div>
<h2>Cython mode</h2>
<div><textarea id="code-cython" name="code-cython">
import numpy as np
cimport cython
from libc.math cimport sqrt
@cython.boundscheck(False)
@cython.wraparound(False)
def pairwise_cython(double[:, ::1] X):
cdef int M = X.shape[0]
cdef int N = X.shape[1]
cdef double tmp, d
cdef double[:, ::1] D = np.empty((M, M), dtype=np.float64)
for i in range(M):
for j in range(M):
d = 0.0
for k in range(N):
tmp = X[i, k] - X[j, k]
d += tmp * tmp
D[i, j] = sqrt(d)
return np.asarray(D)
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: {name: "python",
version: 3,
singleLineStringErrors: false},
lineNumbers: true,
indentUnit: 4,
matchBrackets: true
});
CodeMirror.fromTextArea(document.getElementById("code-cython"), {
mode: {name: "text/x-cython",
version: 2,
singleLineStringErrors: false},
lineNumbers: true,
indentUnit: 4,
matchBrackets: true
});
</script>
<h2>Configuration Options for Python mode:</h2>
<ul>
<li>version - 2/3 - The version of Python to recognize. Default is 3.</li>
<li>singleLineStringErrors - true/false - If you have a single-line string that is not terminated at the end of the line, this will show subsequent lines as errors if true, otherwise it will consider the newline as the end of the string. Default is false.</li>
<li>hangingIndent - int - If you want to write long arguments to a function starting on a new line, how much that line should be indented. Defaults to one normal indentation unit.</li>
</ul>
<h2>Advanced Configuration Options:</h2>
<p>Usefull for superset of python syntax like Enthought enaml, IPython magics and questionmark help</p>
<ul>
<li>singleOperators - RegEx - Regular Expression for single operator matching, default : <pre>^[\\+\\-\\*/%&amp;|\\^~&lt;&gt;!]</pre> including <pre>@</pre> on Python 3</li>
<li>singleDelimiters - RegEx - Regular Expression for single delimiter matching, default : <pre>^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]</pre></li>
<li>doubleOperators - RegEx - Regular Expression for double operators matching, default : <pre>^((==)|(!=)|(&lt;=)|(&gt;=)|(&lt;&gt;)|(&lt;&lt;)|(&gt;&gt;)|(//)|(\\*\\*))</pre></li>
<li>doubleDelimiters - RegEx - Regular Expression for double delimiters matching, default : <pre>^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&amp;=)|(\\|=)|(\\^=))</pre></li>
<li>tripleDelimiters - RegEx - Regular Expression for triple delimiters matching, default : <pre>^((//=)|(&gt;&gt;=)|(&lt;&lt;=)|(\\*\\*=))</pre></li>
<li>identifiers - RegEx - Regular Expression for identifier, default : <pre>^[_A-Za-z][_A-Za-z0-9]*</pre> on Python 2 and <pre>^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*</pre> on Python 3.</li>
<li>extra_keywords - list of string - List of extra words ton consider as keywords</li>
<li>extra_builtins - list of string - List of extra words ton consider as builtins</li>
</ul>
<p><strong>MIME types defined:</strong> <code>text/x-python</code> and <code>text/x-cython</code>.</p>
</article>

View File

@@ -0,0 +1,409 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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";
function wordRegexp(words) {
return new RegExp("^((" + words.join(")|(") + "))\\b");
}
var wordOperators = wordRegexp(["and", "or", "not", "is"]);
var commonKeywords = ["as", "assert", "break", "class", "continue",
"def", "del", "elif", "else", "except", "finally",
"for", "from", "global", "if", "import",
"lambda", "pass", "raise", "return",
"try", "while", "with", "yield", "in"];
var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callable", "chr",
"classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod",
"enumerate", "eval", "filter", "float", "format", "frozenset",
"getattr", "globals", "hasattr", "hash", "help", "hex", "id",
"input", "int", "isinstance", "issubclass", "iter", "len",
"list", "locals", "map", "max", "memoryview", "min", "next",
"object", "oct", "open", "ord", "pow", "property", "range",
"repr", "reversed", "round", "set", "setattr", "slice",
"sorted", "staticmethod", "str", "sum", "super", "tuple",
"type", "vars", "zip", "__import__", "NotImplemented",
"Ellipsis", "__debug__"];
CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonBuiltins));
function top(state) {
return state.scopes[state.scopes.length - 1];
}
CodeMirror.defineMode("python", function(conf, parserConf) {
var ERRORCLASS = "error";
var delimiters = parserConf.delimiters || parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.\\]/;
// (Backwards-compatiblity with old, cumbersome config system)
var operators = [parserConf.singleOperators, parserConf.doubleOperators, parserConf.doubleDelimiters, parserConf.tripleDelimiters,
parserConf.operators || /^([-+*/%\/&|^]=?|[<>=]+|\/\/=?|\*\*=?|!=|[~!@])/]
for (var i = 0; i < operators.length; i++) if (!operators[i]) operators.splice(i--, 1)
var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
var myKeywords = commonKeywords, myBuiltins = commonBuiltins;
if (parserConf.extra_keywords != undefined)
myKeywords = myKeywords.concat(parserConf.extra_keywords);
if (parserConf.extra_builtins != undefined)
myBuiltins = myBuiltins.concat(parserConf.extra_builtins);
var py3 = !(parserConf.version && Number(parserConf.version) < 3)
if (py3) {
// since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]);
myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]);
var stringPrefixes = new RegExp("^(([rbuf]|(br)|(fr))?('{3}|\"{3}|['\"]))", "i");
} else {
var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
myKeywords = myKeywords.concat(["exec", "print"]);
myBuiltins = myBuiltins.concat(["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
"file", "intern", "long", "raw_input", "reduce", "reload",
"unichr", "unicode", "xrange", "False", "True", "None"]);
var stringPrefixes = new RegExp("^(([rubf]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
}
var keywords = wordRegexp(myKeywords);
var builtins = wordRegexp(myBuiltins);
// tokenizers
function tokenBase(stream, state) {
var sol = stream.sol() && state.lastToken != "\\"
if (sol) state.indent = stream.indentation()
// Handle scope changes
if (sol && top(state).type == "py") {
var scopeOffset = top(state).offset;
if (stream.eatSpace()) {
var lineOffset = stream.indentation();
if (lineOffset > scopeOffset)
pushPyScope(state);
else if (lineOffset < scopeOffset && dedent(stream, state) && stream.peek() != "#")
state.errorToken = true;
return null;
} else {
var style = tokenBaseInner(stream, state);
if (scopeOffset > 0 && dedent(stream, state))
style += " " + ERRORCLASS;
return style;
}
}
return tokenBaseInner(stream, state);
}
function tokenBaseInner(stream, state) {
if (stream.eatSpace()) return null;
// Handle Comments
if (stream.match(/^#.*/)) return "comment";
// Handle Number Literals
if (stream.match(/^[0-9\.]/, false)) {
var floatLiteral = false;
// Floats
if (stream.match(/^[\d_]*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
if (stream.match(/^[\d_]+\.\d*/)) { floatLiteral = true; }
if (stream.match(/^\.\d+/)) { floatLiteral = true; }
if (floatLiteral) {
// Float literals may be "imaginary"
stream.eat(/J/i);
return "number";
}
// Integers
var intLiteral = false;
// Hex
if (stream.match(/^0x[0-9a-f_]+/i)) intLiteral = true;
// Binary
if (stream.match(/^0b[01_]+/i)) intLiteral = true;
// Octal
if (stream.match(/^0o[0-7_]+/i)) intLiteral = true;
// Decimal
if (stream.match(/^[1-9][\d_]*(e[\+\-]?[\d_]+)?/)) {
// Decimal literals may be "imaginary"
stream.eat(/J/i);
// TODO - Can you have imaginary longs?
intLiteral = true;
}
// Zero by itself with no other piece of number.
if (stream.match(/^0(?![\dx])/i)) intLiteral = true;
if (intLiteral) {
// Integer literals may be "long"
stream.eat(/L/i);
return "number";
}
}
// Handle Strings
if (stream.match(stringPrefixes)) {
var isFmtString = stream.current().toLowerCase().indexOf('f') !== -1;
if (!isFmtString) {
state.tokenize = tokenStringFactory(stream.current());
return state.tokenize(stream, state);
} else {
state.tokenize = formatStringFactory(stream.current(), state.tokenize);
return state.tokenize(stream, state);
}
}
for (var i = 0; i < operators.length; i++)
if (stream.match(operators[i])) return "operator"
if (stream.match(delimiters)) return "punctuation";
if (state.lastToken == "." && stream.match(identifiers))
return "property";
if (stream.match(keywords) || stream.match(wordOperators))
return "keyword";
if (stream.match(builtins))
return "builtin";
if (stream.match(/^(self|cls)\b/))
return "variable-2";
if (stream.match(identifiers)) {
if (state.lastToken == "def" || state.lastToken == "class")
return "def";
return "variable";
}
// Handle non-detected items
stream.next();
return ERRORCLASS;
}
function formatStringFactory(delimiter, tokenOuter) {
while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
delimiter = delimiter.substr(1);
var singleline = delimiter.length == 1;
var OUTCLASS = "string";
function tokenFString(stream, state) {
// inside f-str Expression
if (stream.match(delimiter)) {
// expression ends pre-maturally, but very common in editing
// Could show error to remind users to close brace here
state.tokenize = tokenString
return OUTCLASS;
} else if (stream.match('{')) {
// starting brace, if not eaten below
return "punctuation";
} else if (stream.match('}')) {
// return to regular inside string state
state.tokenize = tokenString
return "punctuation";
} else {
// use tokenBaseInner to parse the expression
return tokenBaseInner(stream, state);
}
}
function tokenString(stream, state) {
while (!stream.eol()) {
stream.eatWhile(/[^'"\{\}\\]/);
if (stream.eat("\\")) {
stream.next();
if (singleline && stream.eol())
return OUTCLASS;
} else if (stream.match(delimiter)) {
state.tokenize = tokenOuter;
return OUTCLASS;
} else if (stream.match('{{')) {
// ignore {{ in f-str
return OUTCLASS;
} else if (stream.match('{', false)) {
// switch to nested mode
state.tokenize = tokenFString
if (stream.current()) {
return OUTCLASS;
} else {
// need to return something, so eat the starting {
stream.next();
return "punctuation";
}
} else if (stream.match('}}')) {
return OUTCLASS;
} else if (stream.match('}')) {
// single } in f-string is an error
return ERRORCLASS;
} else {
stream.eat(/['"]/);
}
}
if (singleline) {
if (parserConf.singleLineStringErrors)
return ERRORCLASS;
else
state.tokenize = tokenOuter;
}
return OUTCLASS;
}
tokenString.isString = true;
return tokenString;
}
function tokenStringFactory(delimiter) {
while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
delimiter = delimiter.substr(1);
var singleline = delimiter.length == 1;
var OUTCLASS = "string";
function tokenString(stream, state) {
while (!stream.eol()) {
stream.eatWhile(/[^'"\\]/);
if (stream.eat("\\")) {
stream.next();
if (singleline && stream.eol())
return OUTCLASS;
} else if (stream.match(delimiter)) {
state.tokenize = tokenBase;
return OUTCLASS;
} else {
stream.eat(/['"]/);
}
}
if (singleline) {
if (parserConf.singleLineStringErrors)
return ERRORCLASS;
else
state.tokenize = tokenBase;
}
return OUTCLASS;
}
tokenString.isString = true;
return tokenString;
}
function pushPyScope(state) {
while (top(state).type != "py") state.scopes.pop()
state.scopes.push({offset: top(state).offset + conf.indentUnit,
type: "py",
align: null})
}
function pushBracketScope(stream, state, type) {
var align = stream.match(/^([\s\[\{\(]|#.*)*$/, false) ? null : stream.column() + 1
state.scopes.push({offset: state.indent + hangingIndent,
type: type,
align: align})
}
function dedent(stream, state) {
var indented = stream.indentation();
while (state.scopes.length > 1 && top(state).offset > indented) {
if (top(state).type != "py") return true;
state.scopes.pop();
}
return top(state).offset != indented;
}
function tokenLexer(stream, state) {
if (stream.sol()) state.beginningOfLine = true;
var style = state.tokenize(stream, state);
var current = stream.current();
// Handle decorators
if (state.beginningOfLine && current == "@")
return stream.match(identifiers, false) ? "meta" : py3 ? "operator" : ERRORCLASS;
if (/\S/.test(current)) state.beginningOfLine = false;
if ((style == "variable" || style == "builtin")
&& state.lastToken == "meta")
style = "meta";
// Handle scope changes.
if (current == "pass" || current == "return")
state.dedent += 1;
if (current == "lambda") state.lambda = true;
if (current == ":" && !state.lambda && top(state).type == "py")
pushPyScope(state);
if (current.length == 1 && !/string|comment/.test(style)) {
var delimiter_index = "[({".indexOf(current);
if (delimiter_index != -1)
pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
delimiter_index = "])}".indexOf(current);
if (delimiter_index != -1) {
if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent
else return ERRORCLASS;
}
}
if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
if (state.scopes.length > 1) state.scopes.pop();
state.dedent -= 1;
}
return style;
}
var external = {
startState: function(basecolumn) {
return {
tokenize: tokenBase,
scopes: [{offset: basecolumn || 0, type: "py", align: null}],
indent: basecolumn || 0,
lastToken: null,
lambda: false,
dedent: 0
};
},
token: function(stream, state) {
var addErr = state.errorToken;
if (addErr) state.errorToken = false;
var style = tokenLexer(stream, state);
if (style && style != "comment")
state.lastToken = (style == "keyword" || style == "punctuation") ? stream.current() : style;
if (style == "punctuation") style = null;
if (stream.eol() && state.lambda)
state.lambda = false;
return addErr ? style + " " + ERRORCLASS : style;
},
indent: function(state, textAfter) {
if (state.tokenize != tokenBase)
return state.tokenize.isString ? CodeMirror.Pass : 0;
var scope = top(state), closing = scope.type == textAfter.charAt(0)
if (scope.align != null)
return scope.align - (closing ? 1 : 0)
else
return scope.offset - (closing ? hangingIndent : 0)
},
electricInput: /^\s*[\}\]\)]$/,
closeBrackets: {triples: "'\""},
lineComment: "#",
fold: "indent"
};
return external;
});
CodeMirror.defineMIME("text/x-python", "python");
var words = function(str) { return str.split(" "); };
CodeMirror.defineMIME("text/x-cython", {
name: "python",
extra_keywords: words("by cdef cimport cpdef ctypedef enum except "+
"extern gil include nogil property public "+
"readonly struct union DEF IF ELIF ELSE")
});
});

View File

@@ -0,0 +1,38 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 4},
{name: "python",
version: 3,
singleLineStringErrors: false});
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
// Error, because "foobarhello" is neither a known type or property, but
// property was expected (after "and"), and it should be in parentheses.
MT("decoratorStartOfLine",
"[meta @dec]",
"[keyword def] [def function]():",
" [keyword pass]");
MT("decoratorIndented",
"[keyword class] [def Foo]:",
" [meta @dec]",
" [keyword def] [def function]():",
" [keyword pass]");
MT("matmulWithSpace:", "[variable a] [operator @] [variable b]");
MT("matmulWithoutSpace:", "[variable a][operator @][variable b]");
MT("matmulSpaceBefore:", "[variable a] [operator @][variable b]");
var before_equal_sign = ["+", "-", "*", "/", "=", "!", ">", "<"];
for (var i = 0; i < before_equal_sign.length; ++i) {
var c = before_equal_sign[i]
MT("before_equal_sign_" + c, "[variable a] [operator " + c + "=] [variable b]");
}
MT("fValidStringPrefix", "[string f'this is a]{[variable formatted]}[string string']");
MT("fValidExpressioninFString", "[string f'expression ]{[number 100][operator *][number 5]}[string string']");
MT("fInvalidFString", "[error f'this is wrong}]");
MT("fNestedFString", "[string f'expression ]{[number 100] [operator +] [string f'inner]{[number 5]}[string ']}[string string']");
MT("uValidStringPrefix", "[string u'this is an unicode string']");
})();

144
web/public/codemirror/mode/q/index.html vendored Normal file
View File

@@ -0,0 +1,144 @@
<!doctype html>
<title>CodeMirror: Q 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="../../addon/edit/matchbrackets.js"></script>
<script src="q.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">Q</a>
</ul>
</div>
<article>
<h2>Q mode</h2>
<div><textarea id="code" name="code">
/ utilities to quickly load a csv file - for more exhaustive analysis of the csv contents see csvguess.q
/ 2009.09.20 - updated to match latest csvguess.q
/ .csv.colhdrs[file] - return a list of colhdrs from file
/ info:.csv.info[file] - return a table of information about the file
/ columns are:
/ c - column name; ci - column index; t - load type; mw - max width;
/ dchar - distinct characters in values; rule - rule that caught the type
/ maybe - needs checking, _could_ be say a date, but perhaps just a float?
/ .csv.info0[file;onlycols] - like .csv.info except that it only analyses <onlycols>
/ example:
/ info:.csv.info0[file;(.csv.colhdrs file)like"*price"]
/ info:.csv.infolike[file;"*price"]
/ show delete from info where t=" "
/ .csv.data[file;info] - use the info from .csv.info to read the data
/ .csv.data10[file;info] - like .csv.data but only returns the first 10 rows
/ bulkload[file;info] - bulk loads file into table DATA (which must be already defined :: DATA:() )
/ .csv.read[file]/read10[file] - for when you don't care about checking/tweaking the <info> before reading
\d .csv
DELIM:","
ZAPHDRS:0b / lowercase and remove _ from colhdrs (junk characters are always removed)
WIDTHHDR:25000 / number of characters read to get the header
READLINES:222 / number of lines read and used to guess the types
SYMMAXWIDTH:11 / character columns narrower than this are stored as symbols
SYMMAXGR:10 / max symbol granularity% before we give up and keep as a * string
FORCECHARWIDTH:30 / every field (of any type) with values this wide or more is forced to character "*"
DISCARDEMPTY:0b / completely ignore empty columns if true else set them to "C"
CHUNKSIZE:50000000 / used in fs2 (modified .Q.fs)
k)nameltrim:{$[~@x;.z.s'x;~(*x)in aA:.Q.a,.Q.A;(+/&\~x in aA)_x;x]}
k)fs2:{[f;s]((-7!s)>){[f;s;x]i:1+last@&0xa=r:1:(s;x;CHUNKSIZE);f@`\:i#r;x+i}[f;s]/0j}
cleanhdrs:{{$[ZAPHDRS;lower x except"_";x]}x where x in DELIM,.Q.an}
cancast:{nw:x$"";if[not x in"BXCS";nw:(min 0#;max 0#;::)@\:nw];$[not any nw in x$(11&count y)#y;$[11<count y;not any nw in x$y;1b];0b]}
read:{[file]data[file;info[file]]}
read10:{[file]data10[file;info[file]]}
colhdrs:{[file]
`$nameltrim DELIM vs cleanhdrs first read0(file;0;1+first where 0xa=read1(file;0;WIDTHHDR))}
data:{[file;info]
(exec c from info where not t=" ")xcol(exec t from info;enlist DELIM)0:file}
data10:{[file;info]
data[;info](file;0;1+last 11#where 0xa=read1(file;0;15*WIDTHHDR))}
info0:{[file;onlycols]
colhdrs:`$nameltrim DELIM vs cleanhdrs first head:read0(file;0;1+last where 0xa=read1(file;0;WIDTHHDR));
loadfmts:(count colhdrs)#"S";if[count onlycols;loadfmts[where not colhdrs in onlycols]:"C"];
breaks:where 0xa=read1(file;0;floor(10+READLINES)*WIDTHHDR%count head);
nas:count as:colhdrs xcol(loadfmts;enlist DELIM)0:(file;0;1+last((1+READLINES)&count breaks)#breaks);
info:([]c:key flip as;v:value flip as);as:();
reserved:key`.q;reserved,:.Q.res;reserved,:`i;
info:update res:c in reserved from info;
info:update ci:i,t:"?",ipa:0b,mdot:0,mw:0,rule:0,gr:0,ndv:0,maybe:0b,empty:0b,j10:0b,j12:0b from info;
info:update ci:`s#ci from info;
if[count onlycols;info:update t:" ",rule:10 from info where not c in onlycols];
info:update sdv:{string(distinct x)except`}peach v from info;
info:update ndv:count each sdv from info;
info:update gr:floor 0.5+100*ndv%nas,mw:{max count each x}peach sdv from info where 0<ndv;
info:update t:"*",rule:20 from info where mw>.csv.FORCECHARWIDTH; / long values
info:update t:"C "[.csv.DISCARDEMPTY],rule:30,empty:1b from info where t="?",mw=0; / empty columns
info:update dchar:{asc distinct raze x}peach sdv from info where t="?";
info:update mdot:{max sum each"."=x}peach sdv from info where t="?",{"."in x}each dchar;
info:update t:"n",rule:40 from info where t="?",{any x in"0123456789"}each dchar; / vaguely numeric..
info:update t:"I",rule:50,ipa:1b from info where t="n",mw within 7 15,mdot=3,{all x in".0123456789"}each dchar,.csv.cancast["I"]peach sdv; / ip-address
info:update t:"J",rule:60 from info where t="n",mdot=0,{all x in"+-0123456789"}each dchar,.csv.cancast["J"]peach sdv;
info:update t:"I",rule:70 from info where t="J",mw<12,.csv.cancast["I"]peach sdv;
info:update t:"H",rule:80 from info where t="I",mw<7,.csv.cancast["H"]peach sdv;
info:update t:"F",rule:90 from info where t="n",mdot<2,mw>1,.csv.cancast["F"]peach sdv;
info:update t:"E",rule:100,maybe:1b from info where t="F",mw<9;
info:update t:"M",rule:110,maybe:1b from info where t in"nIHEF",mdot<2,mw within 4 7,.csv.cancast["M"]peach sdv;
info:update t:"D",rule:120,maybe:1b from info where t in"nI",mdot in 0 2,mw within 6 11,.csv.cancast["D"]peach sdv;
info:update t:"V",rule:130,maybe:1b from info where t="I",mw in 5 6,7<count each dchar,{all x like"*[0-9][0-5][0-9][0-5][0-9]"}peach sdv,.csv.cancast["V"]peach sdv; / 235959 12345
info:update t:"U",rule:140,maybe:1b from info where t="H",mw in 3 4,7<count each dchar,{all x like"*[0-9][0-5][0-9]"}peach sdv,.csv.cancast["U"]peach sdv; /2359
info:update t:"U",rule:150,maybe:0b from info where t="n",mw in 4 5,mdot=0,{all x like"*[0-9]:[0-5][0-9]"}peach sdv,.csv.cancast["U"]peach sdv;
info:update t:"T",rule:160,maybe:0b from info where t="n",mw within 7 12,mdot<2,{all x like"*[0-9]:[0-5][0-9]:[0-5][0-9]*"}peach sdv,.csv.cancast["T"]peach sdv;
info:update t:"V",rule:170,maybe:0b from info where t="T",mw in 7 8,mdot=0,.csv.cancast["V"]peach sdv;
info:update t:"T",rule:180,maybe:1b from info where t in"EF",mw within 7 10,mdot=1,{all x like"*[0-9][0-5][0-9][0-5][0-9].*"}peach sdv,.csv.cancast["T"]peach sdv;
info:update t:"Z",rule:190,maybe:0b from info where t="n",mw within 11 24,mdot<4,.csv.cancast["Z"]peach sdv;
info:update t:"P",rule:200,maybe:1b from info where t="n",mw within 12 29,mdot<4,{all x like"[12]*"}peach sdv,.csv.cancast["P"]peach sdv;
info:update t:"N",rule:210,maybe:1b from info where t="n",mw within 3 28,mdot=1,.csv.cancast["N"]peach sdv;
info:update t:"?",rule:220,maybe:0b from info where t="n"; / reset remaining maybe numeric
info:update t:"C",rule:230,maybe:0b from info where t="?",mw=1; / char
info:update t:"B",rule:240,maybe:0b from info where t in"HC",mw=1,mdot=0,{$[all x in"01tTfFyYnN";(any"0fFnN"in x)and any"1tTyY"in x;0b]}each dchar; / boolean
info:update t:"B",rule:250,maybe:1b from info where t in"HC",mw=1,mdot=0,{all x in"01tTfFyYnN"}each dchar; / boolean
info:update t:"X",rule:260,maybe:0b from info where t="?",mw=2,{$[all x in"0123456789abcdefABCDEF";(any .Q.n in x)and any"abcdefABCDEF"in x;0b]}each dchar; /hex
info:update t:"S",rule:270,maybe:1b from info where t="?",mw<.csv.SYMMAXWIDTH,mw>1,gr<.csv.SYMMAXGR; / symbols (max width permitting)
info:update t:"*",rule:280,maybe:0b from info where t="?"; / the rest as strings
/ flag those S/* columns which could be encoded to integers (.Q.j10/x10/j12/x12) to avoid symbols
info:update j12:1b from info where t in"S*",mw<13,{all x in .Q.nA}each dchar;
info:update j10:1b from info where t in"S*",mw<11,{all x in .Q.b6}each dchar;
select c,ci,t,maybe,empty,res,j10,j12,ipa,mw,mdot,rule,gr,ndv,dchar from info}
info:info0[;()] / by default don't restrict columns
infolike:{[file;pattern] info0[file;{x where x like y}[lower colhdrs[file];pattern]]} / .csv.infolike[file;"*time"]
\d .
/ DATA:()
bulkload:{[file;info]
if[not`DATA in system"v";'`DATA.not.defined];
if[count DATA;'`DATA.not.empty];
loadhdrs:exec c from info where not t=" ";loadfmts:exec t from info;
.csv.fs2[{[file;loadhdrs;loadfmts] `DATA insert $[count DATA;flip loadhdrs!(loadfmts;.csv.DELIM)0:file;loadhdrs xcol(loadfmts;enlist .csv.DELIM)0:file]}[file;loadhdrs;loadfmts]];
count DATA}
@[.:;"\\l csvutil.custom.q";::]; / save your custom settings in csvutil.custom.q to override those set at the beginning of the file
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true
});
</script>
<p><strong>MIME type defined:</strong> <code>text/x-q</code>.</p>
</article>

139
web/public/codemirror/mode/q/q.js vendored Normal file
View File

@@ -0,0 +1,139 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("q",function(config){
var indentUnit=config.indentUnit,
curPunc,
keywords=buildRE(["abs","acos","aj","aj0","all","and","any","asc","asin","asof","atan","attr","avg","avgs","bin","by","ceiling","cols","cor","cos","count","cov","cross","csv","cut","delete","deltas","desc","dev","differ","distinct","div","do","each","ej","enlist","eval","except","exec","exit","exp","fby","fills","first","fkeys","flip","floor","from","get","getenv","group","gtime","hclose","hcount","hdel","hopen","hsym","iasc","idesc","if","ij","in","insert","inter","inv","key","keys","last","like","list","lj","load","log","lower","lsq","ltime","ltrim","mavg","max","maxs","mcount","md5","mdev","med","meta","min","mins","mmax","mmin","mmu","mod","msum","neg","next","not","null","or","over","parse","peach","pj","plist","prd","prds","prev","prior","rand","rank","ratios","raze","read0","read1","reciprocal","reverse","rload","rotate","rsave","rtrim","save","scan","select","set","setenv","show","signum","sin","sqrt","ss","ssr","string","sublist","sum","sums","sv","system","tables","tan","til","trim","txf","type","uj","ungroup","union","update","upper","upsert","value","var","view","views","vs","wavg","where","where","while","within","wj","wj1","wsum","xasc","xbar","xcol","xcols","xdesc","xexp","xgroup","xkey","xlog","xprev","xrank"]),
E=/[|/&^!+:\\\-*%$=~#;@><,?_\'\"\[\(\]\)\s{}]/;
function buildRE(w){return new RegExp("^("+w.join("|")+")$");}
function tokenBase(stream,state){
var sol=stream.sol(),c=stream.next();
curPunc=null;
if(sol)
if(c=="/")
return(state.tokenize=tokenLineComment)(stream,state);
else if(c=="\\"){
if(stream.eol()||/\s/.test(stream.peek()))
return stream.skipToEnd(),/^\\\s*$/.test(stream.current())?(state.tokenize=tokenCommentToEOF)(stream):state.tokenize=tokenBase,"comment";
else
return state.tokenize=tokenBase,"builtin";
}
if(/\s/.test(c))
return stream.peek()=="/"?(stream.skipToEnd(),"comment"):"whitespace";
if(c=='"')
return(state.tokenize=tokenString)(stream,state);
if(c=='`')
return stream.eatWhile(/[A-Za-z\d_:\/.]/),"symbol";
if(("."==c&&/\d/.test(stream.peek()))||/\d/.test(c)){
var t=null;
stream.backUp(1);
if(stream.match(/^\d{4}\.\d{2}(m|\.\d{2}([DT](\d{2}(:\d{2}(:\d{2}(\.\d{1,9})?)?)?)?)?)/)
|| stream.match(/^\d+D(\d{2}(:\d{2}(:\d{2}(\.\d{1,9})?)?)?)/)
|| stream.match(/^\d{2}:\d{2}(:\d{2}(\.\d{1,9})?)?/)
|| stream.match(/^\d+[ptuv]{1}/))
t="temporal";
else if(stream.match(/^0[NwW]{1}/)
|| stream.match(/^0x[\da-fA-F]*/)
|| stream.match(/^[01]+[b]{1}/)
|| stream.match(/^\d+[chijn]{1}/)
|| stream.match(/-?\d*(\.\d*)?(e[+\-]?\d+)?(e|f)?/))
t="number";
return(t&&(!(c=stream.peek())||E.test(c)))?t:(stream.next(),"error");
}
if(/[A-Za-z]|\./.test(c))
return stream.eatWhile(/[A-Za-z._\d]/),keywords.test(stream.current())?"keyword":"variable";
if(/[|/&^!+:\\\-*%$=~#;@><\.,?_\']/.test(c))
return null;
if(/[{}\(\[\]\)]/.test(c))
return null;
return"error";
}
function tokenLineComment(stream,state){
return stream.skipToEnd(),/\/\s*$/.test(stream.current())?(state.tokenize=tokenBlockComment)(stream,state):(state.tokenize=tokenBase),"comment";
}
function tokenBlockComment(stream,state){
var f=stream.sol()&&stream.peek()=="\\";
stream.skipToEnd();
if(f&&/^\\\s*$/.test(stream.current()))
state.tokenize=tokenBase;
return"comment";
}
function tokenCommentToEOF(stream){return stream.skipToEnd(),"comment";}
function tokenString(stream,state){
var escaped=false,next,end=false;
while((next=stream.next())){
if(next=="\""&&!escaped){end=true;break;}
escaped=!escaped&&next=="\\";
}
if(end)state.tokenize=tokenBase;
return"string";
}
function pushContext(state,type,col){state.context={prev:state.context,indent:state.indent,col:col,type:type};}
function popContext(state){state.indent=state.context.indent;state.context=state.context.prev;}
return{
startState:function(){
return{tokenize:tokenBase,
context:null,
indent:0,
col:0};
},
token:function(stream,state){
if(stream.sol()){
if(state.context&&state.context.align==null)
state.context.align=false;
state.indent=stream.indentation();
}
//if (stream.eatSpace()) return null;
var style=state.tokenize(stream,state);
if(style!="comment"&&state.context&&state.context.align==null&&state.context.type!="pattern"){
state.context.align=true;
}
if(curPunc=="(")pushContext(state,")",stream.column());
else if(curPunc=="[")pushContext(state,"]",stream.column());
else if(curPunc=="{")pushContext(state,"}",stream.column());
else if(/[\]\}\)]/.test(curPunc)){
while(state.context&&state.context.type=="pattern")popContext(state);
if(state.context&&curPunc==state.context.type)popContext(state);
}
else if(curPunc=="."&&state.context&&state.context.type=="pattern")popContext(state);
else if(/atom|string|variable/.test(style)&&state.context){
if(/[\}\]]/.test(state.context.type))
pushContext(state,"pattern",stream.column());
else if(state.context.type=="pattern"&&!state.context.align){
state.context.align=true;
state.context.col=stream.column();
}
}
return style;
},
indent:function(state,textAfter){
var firstChar=textAfter&&textAfter.charAt(0);
var context=state.context;
if(/[\]\}]/.test(firstChar))
while (context&&context.type=="pattern")context=context.prev;
var closing=context&&firstChar==context.type;
if(!context)
return 0;
else if(context.type=="pattern")
return context.col;
else if(context.align)
return context.col+(closing?0:1);
else
return context.indent+(closing?0:indentUnit);
}
};
});
CodeMirror.defineMIME("text/x-q","q");
});

88
web/public/codemirror/mode/r/index.html vendored Normal file
View File

@@ -0,0 +1,88 @@
<!doctype html>
<title>CodeMirror: R 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="r.js"></script>
<style>
.CodeMirror { border-top: 1px solid silver; border-bottom: 1px solid silver; }
.cm-s-default span.cm-semi { color: blue; font-weight: bold; }
.cm-s-default span.cm-dollar { color: orange; font-weight: bold; }
.cm-s-default span.cm-arrow { color: brown; }
.cm-s-default span.cm-arg-is { color: brown; }
</style>
<div id=nav>
<a href="https://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="#">R</a>
</ul>
</div>
<article>
<h2>R mode</h2>
<form><textarea id="code" name="code">
X <- list(height = 5.4, weight = 54)
cat("Printing objects: "); print(X)
print("Accessing individual elements:")
cat(sprintf("Your height is %s and your weight is %s\n", X$height, X$weight))
# Functions:
square <- function(x) {
return(x * x)
}
cat(sprintf("The square of 3 is %s\n", square(3)))
# In R, the last expression in a function is, by default, what is
# returned. The idiomatic way to write the function is:
square <- function(x) {
x * x
}
# or, for functions with short content:
square <- function(x) x * x
# Function arguments with default values:
cube <- function(x = 5) x * x * x
cat(sprintf("Calling cube with 2 : %s\n", cube(2)) # will give 2^3
cat(sprintf("Calling cube : %s\n", cube()) # will default to 5^3.
powers <- function(x) list(x2 = x*x, x3 = x*x*x, x4 = x*x*x*x)
cat("Powers of 3: "); print(powers(3))
# Data frames
df <- data.frame(letters = letters[1:5], '#letter' = 1:5)
print(df$letters)
print(df$`#letter`)
# Operators:
m1 <- matrix(1:6, 2, 3)
m2 <- m1 %*% t(m1)
cat("Matrix product: "); print(m2)
# Assignments:
a <- 1
b <<- 2
c = 3
4 -> d
5 ->> e
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-rsrc</code>.</p>
<p>Development of the CodeMirror R mode was kindly sponsored
by <a href="https://twitter.com/ubalo">Ubalo</a>.</p>
</article>

190
web/public/codemirror/mode/r/r.js vendored Normal file
View File

@@ -0,0 +1,190 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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.registerHelper("wordChars", "r", /[\w.]/);
CodeMirror.defineMode("r", function(config) {
function wordObj(words) {
var res = {};
for (var i = 0; i < words.length; ++i) res[words[i]] = true;
return res;
}
var commonAtoms = ["NULL", "NA", "Inf", "NaN", "NA_integer_", "NA_real_", "NA_complex_", "NA_character_", "TRUE", "FALSE"];
var commonBuiltins = ["list", "quote", "bquote", "eval", "return", "call", "parse", "deparse"];
var commonKeywords = ["if", "else", "repeat", "while", "function", "for", "in", "next", "break"];
var commonBlockKeywords = ["if", "else", "repeat", "while", "function", "for"];
CodeMirror.registerHelper("hintWords", "r", commonAtoms.concat(commonBuiltins, commonKeywords));
var atoms = wordObj(commonAtoms);
var builtins = wordObj(commonBuiltins);
var keywords = wordObj(commonKeywords);
var blockkeywords = wordObj(commonBlockKeywords);
var opChars = /[+\-*\/^<>=!&|~$:]/;
var curPunc;
function tokenBase(stream, state) {
curPunc = null;
var ch = stream.next();
if (ch == "#") {
stream.skipToEnd();
return "comment";
} else if (ch == "0" && stream.eat("x")) {
stream.eatWhile(/[\da-f]/i);
return "number";
} else if (ch == "." && stream.eat(/\d/)) {
stream.match(/\d*(?:e[+\-]?\d+)?/);
return "number";
} else if (/\d/.test(ch)) {
stream.match(/\d*(?:\.\d+)?(?:e[+\-]\d+)?L?/);
return "number";
} else if (ch == "'" || ch == '"') {
state.tokenize = tokenString(ch);
return "string";
} else if (ch == "`") {
stream.match(/[^`]+`/);
return "variable-3";
} else if (ch == "." && stream.match(/.[.\d]+/)) {
return "keyword";
} else if (/[\w\.]/.test(ch) && ch != "_") {
stream.eatWhile(/[\w\.]/);
var word = stream.current();
if (atoms.propertyIsEnumerable(word)) return "atom";
if (keywords.propertyIsEnumerable(word)) {
// Block keywords start new blocks, except 'else if', which only starts
// one new block for the 'if', no block for the 'else'.
if (blockkeywords.propertyIsEnumerable(word) &&
!stream.match(/\s*if(\s+|$)/, false))
curPunc = "block";
return "keyword";
}
if (builtins.propertyIsEnumerable(word)) return "builtin";
return "variable";
} else if (ch == "%") {
if (stream.skipTo("%")) stream.next();
return "operator variable-2";
} else if (
(ch == "<" && stream.eat("-")) ||
(ch == "<" && stream.match("<-")) ||
(ch == "-" && stream.match(/>>?/))
) {
return "operator arrow";
} else if (ch == "=" && state.ctx.argList) {
return "arg-is";
} else if (opChars.test(ch)) {
if (ch == "$") return "operator dollar";
stream.eatWhile(opChars);
return "operator";
} else if (/[\(\){}\[\];]/.test(ch)) {
curPunc = ch;
if (ch == ";") return "semi";
return null;
} else {
return null;
}
}
function tokenString(quote) {
return function(stream, state) {
if (stream.eat("\\")) {
var ch = stream.next();
if (ch == "x") stream.match(/^[a-f0-9]{2}/i);
else if ((ch == "u" || ch == "U") && stream.eat("{") && stream.skipTo("}")) stream.next();
else if (ch == "u") stream.match(/^[a-f0-9]{4}/i);
else if (ch == "U") stream.match(/^[a-f0-9]{8}/i);
else if (/[0-7]/.test(ch)) stream.match(/^[0-7]{1,2}/);
return "string-2";
} else {
var next;
while ((next = stream.next()) != null) {
if (next == quote) { state.tokenize = tokenBase; break; }
if (next == "\\") { stream.backUp(1); break; }
}
return "string";
}
};
}
var ALIGN_YES = 1, ALIGN_NO = 2, BRACELESS = 4
function push(state, type, stream) {
state.ctx = {type: type,
indent: state.indent,
flags: 0,
column: stream.column(),
prev: state.ctx};
}
function setFlag(state, flag) {
var ctx = state.ctx
state.ctx = {type: ctx.type,
indent: ctx.indent,
flags: ctx.flags | flag,
column: ctx.column,
prev: ctx.prev}
}
function pop(state) {
state.indent = state.ctx.indent;
state.ctx = state.ctx.prev;
}
return {
startState: function() {
return {tokenize: tokenBase,
ctx: {type: "top",
indent: -config.indentUnit,
flags: ALIGN_NO},
indent: 0,
afterIdent: false};
},
token: function(stream, state) {
if (stream.sol()) {
if ((state.ctx.flags & 3) == 0) state.ctx.flags |= ALIGN_NO
if (state.ctx.flags & BRACELESS) pop(state)
state.indent = stream.indentation();
}
if (stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
if (style != "comment" && (state.ctx.flags & ALIGN_NO) == 0) setFlag(state, ALIGN_YES)
if ((curPunc == ";" || curPunc == "{" || curPunc == "}") && state.ctx.type == "block") pop(state);
if (curPunc == "{") push(state, "}", stream);
else if (curPunc == "(") {
push(state, ")", stream);
if (state.afterIdent) state.ctx.argList = true;
}
else if (curPunc == "[") push(state, "]", stream);
else if (curPunc == "block") push(state, "block", stream);
else if (curPunc == state.ctx.type) pop(state);
else if (state.ctx.type == "block" && style != "comment") setFlag(state, BRACELESS)
state.afterIdent = style == "variable" || style == "keyword";
return style;
},
indent: function(state, textAfter) {
if (state.tokenize != tokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), ctx = state.ctx,
closing = firstChar == ctx.type;
if (ctx.flags & BRACELESS) ctx = ctx.prev
if (ctx.type == "block") return ctx.indent + (firstChar == "{" ? 0 : config.indentUnit);
else if (ctx.flags & ALIGN_YES) return ctx.column + (closing ? 0 : 1);
else return ctx.indent + (closing ? 0 : config.indentUnit);
},
lineComment: "#"
};
});
CodeMirror.defineMIME("text/x-rsrc", "r");
});

View File

@@ -0,0 +1,66 @@
<!doctype html>
<title>CodeMirror: RPM changes 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="changes.js"></script>
<link rel="stylesheet" href="../../../doc/docs.css">
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">RPM changes</a>
</ul>
</div>
<article>
<h2>RPM changes mode</h2>
<div><textarea id="code" name="code">
-------------------------------------------------------------------
Tue Oct 18 13:58:40 UTC 2011 - misterx@example.com
- Update to r60.3
- Fixes bug in the reflect package
* disallow Interface method on Value obtained via unexported name
-------------------------------------------------------------------
Thu Oct 6 08:14:24 UTC 2011 - misterx@example.com
- Update to r60.2
- Fixes memory leak in certain map types
-------------------------------------------------------------------
Wed Oct 5 14:34:10 UTC 2011 - misterx@example.com
- Tweaks for gdb debugging
- go.spec changes:
- move %go_arch definition to %prep section
- pass correct location of go specific gdb pretty printer and
functions to cpp as HOST_EXTRA_CFLAGS macro
- install go gdb functions & printer
- gdb-printer.patch
- patch linker (src/cmd/ld/dwarf.c) to emit correct location of go
gdb functions and pretty printer
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: {name: "changes"},
lineNumbers: true,
indentUnit: 4
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-rpm-changes</code>.</p>
</article>

View File

@@ -0,0 +1,149 @@
<!doctype html>
<title>CodeMirror: RPM changes 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="rpm.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">RPM</a>
</ul>
</div>
<article>
<h2>RPM changes mode</h2>
<div><textarea id="code" name="code">
-------------------------------------------------------------------
Tue Oct 18 13:58:40 UTC 2011 - misterx@example.com
- Update to r60.3
- Fixes bug in the reflect package
* disallow Interface method on Value obtained via unexported name
-------------------------------------------------------------------
Thu Oct 6 08:14:24 UTC 2011 - misterx@example.com
- Update to r60.2
- Fixes memory leak in certain map types
-------------------------------------------------------------------
Wed Oct 5 14:34:10 UTC 2011 - misterx@example.com
- Tweaks for gdb debugging
- go.spec changes:
- move %go_arch definition to %prep section
- pass correct location of go specific gdb pretty printer and
functions to cpp as HOST_EXTRA_CFLAGS macro
- install go gdb functions & printer
- gdb-printer.patch
- patch linker (src/cmd/ld/dwarf.c) to emit correct location of go
gdb functions and pretty printer
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: {name: "rpm-changes"},
lineNumbers: true,
indentUnit: 4
});
</script>
<h2>RPM spec mode</h2>
<div><textarea id="code2" name="code2">
#
# spec file for package minidlna
#
# Copyright (c) 2011, Sascha Peilicke <saschpe@gmx.de>
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
Name: libupnp6
Version: 1.6.13
Release: 0
Summary: Portable Universal Plug and Play (UPnP) SDK
Group: System/Libraries
License: BSD-3-Clause
Url: http://sourceforge.net/projects/pupnp/
Source0: http://downloads.sourceforge.net/pupnp/libupnp-%{version}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%description
The portable Universal Plug and Play (UPnP) SDK provides support for building
UPnP-compliant control points, devices, and bridges on several operating
systems.
%package -n libupnp-devel
Summary: Portable Universal Plug and Play (UPnP) SDK
Group: Development/Libraries/C and C++
Provides: pkgconfig(libupnp)
Requires: %{name} = %{version}
%description -n libupnp-devel
The portable Universal Plug and Play (UPnP) SDK provides support for building
UPnP-compliant control points, devices, and bridges on several operating
systems.
%prep
%setup -n libupnp-%{version}
%build
%configure --disable-static
make %{?_smp_mflags}
%install
%makeinstall
find %{buildroot} -type f -name '*.la' -exec rm -f {} ';'
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%defattr(-,root,root,-)
%doc ChangeLog NEWS README TODO
%{_libdir}/libixml.so.*
%{_libdir}/libthreadutil.so.*
%{_libdir}/libupnp.so.*
%files -n libupnp-devel
%defattr(-,root,root,-)
%{_libdir}/pkgconfig/libupnp.pc
%{_libdir}/libixml.so
%{_libdir}/libthreadutil.so
%{_libdir}/libupnp.so
%{_includedir}/upnp/
%changelog</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code2"), {
mode: {name: "rpm-spec"},
lineNumbers: true,
indentUnit: 4
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-rpm-spec</code>, <code>text/x-rpm-changes</code>.</p>
</article>

109
web/public/codemirror/mode/rpm/rpm.js vendored Normal file
View File

@@ -0,0 +1,109 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("rpm-changes", function() {
var headerSeperator = /^-+$/;
var headerLine = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ?\d{1,2} \d{2}:\d{2}(:\d{2})? [A-Z]{3,4} \d{4} - /;
var simpleEmail = /^[\w+.-]+@[\w.-]+/;
return {
token: function(stream) {
if (stream.sol()) {
if (stream.match(headerSeperator)) { return 'tag'; }
if (stream.match(headerLine)) { return 'tag'; }
}
if (stream.match(simpleEmail)) { return 'string'; }
stream.next();
return null;
}
};
});
CodeMirror.defineMIME("text/x-rpm-changes", "rpm-changes");
// Quick and dirty spec file highlighting
CodeMirror.defineMode("rpm-spec", function() {
var arch = /^(i386|i586|i686|x86_64|ppc64le|ppc64|ppc|ia64|s390x|s390|sparc64|sparcv9|sparc|noarch|alphaev6|alpha|hppa|mipsel)/;
var preamble = /^[a-zA-Z0-9()]+:/;
var section = /^%(debug_package|package|description|prep|build|install|files|clean|changelog|preinstall|preun|postinstall|postun|pretrans|posttrans|pre|post|triggerin|triggerun|verifyscript|check|triggerpostun|triggerprein|trigger)/;
var control_flow_complex = /^%(ifnarch|ifarch|if)/; // rpm control flow macros
var control_flow_simple = /^%(else|endif)/; // rpm control flow macros
var operators = /^(\!|\?|\<\=|\<|\>\=|\>|\=\=|\&\&|\|\|)/; // operators in control flow macros
return {
startState: function () {
return {
controlFlow: false,
macroParameters: false,
section: false
};
},
token: function (stream, state) {
var ch = stream.peek();
if (ch == "#") { stream.skipToEnd(); return "comment"; }
if (stream.sol()) {
if (stream.match(preamble)) { return "header"; }
if (stream.match(section)) { return "atom"; }
}
if (stream.match(/^\$\w+/)) { return "def"; } // Variables like '$RPM_BUILD_ROOT'
if (stream.match(/^\$\{\w+\}/)) { return "def"; } // Variables like '${RPM_BUILD_ROOT}'
if (stream.match(control_flow_simple)) { return "keyword"; }
if (stream.match(control_flow_complex)) {
state.controlFlow = true;
return "keyword";
}
if (state.controlFlow) {
if (stream.match(operators)) { return "operator"; }
if (stream.match(/^(\d+)/)) { return "number"; }
if (stream.eol()) { state.controlFlow = false; }
}
if (stream.match(arch)) {
if (stream.eol()) { state.controlFlow = false; }
return "number";
}
// Macros like '%make_install' or '%attr(0775,root,root)'
if (stream.match(/^%[\w]+/)) {
if (stream.match(/^\(/)) { state.macroParameters = true; }
return "keyword";
}
if (state.macroParameters) {
if (stream.match(/^\d+/)) { return "number";}
if (stream.match(/^\)/)) {
state.macroParameters = false;
return "keyword";
}
}
// Macros like '%{defined fedora}'
if (stream.match(/^%\{\??[\w \-\:\!]+\}/)) {
if (stream.eol()) { state.controlFlow = false; }
return "def";
}
//TODO: Include bash script sub-parser (CodeMirror supports that)
stream.next();
return null;
}
};
});
CodeMirror.defineMIME("text/x-rpm-spec", "rpm-spec");
});

View File

@@ -0,0 +1,183 @@
<!doctype html>
<title>CodeMirror: Ruby 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="../../addon/edit/matchbrackets.js"></script>
<script src="ruby.js"></script>
<style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
.cm-s-default span.cm-arrow { color: red; }
</style>
<div id=nav>
<a href="https://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="#">Ruby</a>
</ul>
</div>
<article>
<h2>Ruby mode</h2>
<form><textarea id="code" name="code">
# Code from http://sandbox.mc.edu/~bennet/ruby/code/poly_rb.html
#
# This program evaluates polynomials. It first asks for the coefficients
# of a polynomial, which must be entered on one line, highest-order first.
# It then requests values of x and will compute the value of the poly for
# each x. It will repeatly ask for x values, unless you the user enters
# a blank line. It that case, it will ask for another polynomial. If the
# user types quit for either input, the program immediately exits.
#
#
# Function to evaluate a polynomial at x. The polynomial is given
# as a list of coefficients, from the greatest to the least.
def polyval(x, coef)
sum = 0
coef = coef.clone # Don't want to destroy the original
while true
sum += coef.shift # Add and remove the next coef
break if coef.empty? # If no more, done entirely.
sum *= x # This happens the right number of times.
end
return sum
end
#
# Function to read a line containing a list of integers and return
# them as an array of integers. If the string conversion fails, it
# throws TypeError. If the input line is the word 'quit', then it
# converts it to an end-of-file exception
def readints(prompt)
# Read a line
print prompt
line = readline.chomp
raise EOFError.new if line == 'quit' # You can also use a real EOF.
# Go through each item on the line, converting each one and adding it
# to retval.
retval = [ ]
for str in line.split(/\s+/)
if str =~ /^\-?\d+$/
retval.push(str.to_i)
else
raise TypeError.new
end
end
return retval
end
#
# Take a coeff and an exponent and return the string representation, ignoring
# the sign of the coefficient.
def term_to_str(coef, exp)
ret = ""
# Show coeff, unless it's 1 or at the right
coef = coef.abs
ret = coef.to_s unless coef == 1 && exp > 0
ret += "x" if exp > 0 # x if exponent not 0
ret += "^" + exp.to_s if exp > 1 # ^exponent, if > 1.
return ret
end
#
# Create a string of the polynomial in sort-of-readable form.
def polystr(p)
# Get the exponent of first coefficient, plus 1.
exp = p.length
# Assign exponents to each term, making pairs of coeff and exponent,
# Then get rid of the zero terms.
p = (p.map { |c| exp -= 1; [ c, exp ] }).select { |p| p[0] != 0 }
# If there's nothing left, it's a zero
return "0" if p.empty?
# *** Now p is a non-empty list of [ coef, exponent ] pairs. ***
# Convert the first term, preceded by a "-" if it's negative.
result = (if p[0][0] < 0 then "-" else "" end) + term_to_str(*p[0])
# Convert the rest of the terms, in each case adding the appropriate
# + or - separating them.
for term in p[1...p.length]
# Add the separator then the rep. of the term.
result += (if term[0] < 0 then " - " else " + " end) +
term_to_str(*term)
end
return result
end
#
# Run until some kind of endfile.
begin
# Repeat until an exception or quit gets us out.
while true
# Read a poly until it works. An EOF will except out of the
# program.
print "\n"
begin
poly = readints("Enter a polynomial coefficients: ")
rescue TypeError
print "Try again.\n"
retry
end
break if poly.empty?
# Read and evaluate x values until the user types a blank line.
# Again, an EOF will except out of the pgm.
while true
# Request an integer.
print "Enter x value or blank line: "
x = readline.chomp
break if x == ''
raise EOFError.new if x == 'quit'
# If it looks bad, let's try again.
if x !~ /^\-?\d+$/
print "That doesn't look like an integer. Please try again.\n"
next
end
# Convert to an integer and print the result.
x = x.to_i
print "p(x) = ", polystr(poly), "\n"
print "p(", x, ") = ", polyval(x, poly), "\n"
end
end
rescue EOFError
print "\n=== EOF ===\n"
rescue Interrupt, SignalException
print "\n=== Interrupted ===\n"
else
print "--- Bye ---\n"
end
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "text/x-ruby",
matchBrackets: true,
indentUnit: 4
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-ruby</code>.</p>
<p>Development of the CodeMirror Ruby mode was kindly sponsored
by <a href="http://ubalo.com/">Ubalo</a>.</p>
</article>

296
web/public/codemirror/mode/ruby/ruby.js vendored Normal file
View File

@@ -0,0 +1,296 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://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("ruby", function(config) {
function wordObj(words) {
var o = {};
for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
return o;
}
var keywords = wordObj([
"alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else",
"elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or",
"redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
"until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
"caller", "lambda", "proc", "public", "protected", "private", "require", "load",
"require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__"
]);
var indentWords = wordObj(["def", "class", "case", "for", "while", "until", "module", "then",
"catch", "loop", "proc", "begin"]);
var dedentWords = wordObj(["end", "until"]);
var matching = {"[": "]", "{": "}", "(": ")"};
var curPunc;
function chain(newtok, stream, state) {
state.tokenize.push(newtok);
return newtok(stream, state);
}
function tokenBase(stream, state) {
if (stream.sol() && stream.match("=begin") && stream.eol()) {
state.tokenize.push(readBlockComment);
return "comment";
}
if (stream.eatSpace()) return null;
var ch = stream.next(), m;
if (ch == "`" || ch == "'" || ch == '"') {
return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
} else if (ch == "/") {
if (regexpAhead(stream))
return chain(readQuoted(ch, "string-2", true), stream, state);
else
return "operator";
} else if (ch == "%") {
var style = "string", embed = true;
if (stream.eat("s")) style = "atom";
else if (stream.eat(/[WQ]/)) style = "string";
else if (stream.eat(/[r]/)) style = "string-2";
else if (stream.eat(/[wxq]/)) { style = "string"; embed = false; }
var delim = stream.eat(/[^\w\s=]/);
if (!delim) return "operator";
if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
return chain(readQuoted(delim, style, embed, true), stream, state);
} else if (ch == "#") {
stream.skipToEnd();
return "comment";
} else if (ch == "<" && (m = stream.match(/^<-?[\`\"\']?([a-zA-Z_?]\w*)[\`\"\']?(?:;|$)/))) {
return chain(readHereDoc(m[1]), stream, state);
} else if (ch == "0") {
if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/);
else if (stream.eat("b")) stream.eatWhile(/[01]/);
else stream.eatWhile(/[0-7]/);
return "number";
} else if (/\d/.test(ch)) {
stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+\-]?[\d_]+)?/);
return "number";
} else if (ch == "?") {
while (stream.match(/^\\[CM]-/)) {}
if (stream.eat("\\")) stream.eatWhile(/\w/);
else stream.next();
return "string";
} else if (ch == ":") {
if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
// :> :>> :< :<< are valid symbols
if (stream.eat(/[\<\>]/)) {
stream.eat(/[\<\>]/);
return "atom";
}
// :+ :- :/ :* :| :& :! are valid symbols
if (stream.eat(/[\+\-\*\/\&\|\:\!]/)) {
return "atom";
}
// Symbols can't start by a digit
if (stream.eat(/[a-zA-Z$@_\xa1-\uffff]/)) {
stream.eatWhile(/[\w$\xa1-\uffff]/);
// Only one ? ! = is allowed and only as the last character
stream.eat(/[\?\!\=]/);
return "atom";
}
return "operator";
} else if (ch == "@" && stream.match(/^@?[a-zA-Z_\xa1-\uffff]/)) {
stream.eat("@");
stream.eatWhile(/[\w\xa1-\uffff]/);
return "variable-2";
} else if (ch == "$") {
if (stream.eat(/[a-zA-Z_]/)) {
stream.eatWhile(/[\w]/);
} else if (stream.eat(/\d/)) {
stream.eat(/\d/);
} else {
stream.next(); // Must be a special global like $: or $!
}
return "variable-3";
} else if (/[a-zA-Z_\xa1-\uffff]/.test(ch)) {
stream.eatWhile(/[\w\xa1-\uffff]/);
stream.eat(/[\?\!]/);
if (stream.eat(":")) return "atom";
return "ident";
} else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) {
curPunc = "|";
return null;
} else if (/[\(\)\[\]{}\\;]/.test(ch)) {
curPunc = ch;
return null;
} else if (ch == "-" && stream.eat(">")) {
return "arrow";
} else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) {
var more = stream.eatWhile(/[=+\-\/*:\.^%<>~|]/);
if (ch == "." && !more) curPunc = ".";
return "operator";
} else {
return null;
}
}
function regexpAhead(stream) {
var start = stream.pos, depth = 0, next, found = false, escaped = false
while ((next = stream.next()) != null) {
if (!escaped) {
if ("[{(".indexOf(next) > -1) {
depth++
} else if ("]})".indexOf(next) > -1) {
depth--
if (depth < 0) break
} else if (next == "/" && depth == 0) {
found = true
break
}
escaped = next == "\\"
} else {
escaped = false
}
}
stream.backUp(stream.pos - start)
return found
}
function tokenBaseUntilBrace(depth) {
if (!depth) depth = 1;
return function(stream, state) {
if (stream.peek() == "}") {
if (depth == 1) {
state.tokenize.pop();
return state.tokenize[state.tokenize.length-1](stream, state);
} else {
state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth - 1);
}
} else if (stream.peek() == "{") {
state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth + 1);
}
return tokenBase(stream, state);
};
}
function tokenBaseOnce() {
var alreadyCalled = false;
return function(stream, state) {
if (alreadyCalled) {
state.tokenize.pop();
return state.tokenize[state.tokenize.length-1](stream, state);
}
alreadyCalled = true;
return tokenBase(stream, state);
};
}
function readQuoted(quote, style, embed, unescaped) {
return function(stream, state) {
var escaped = false, ch;
if (state.context.type === 'read-quoted-paused') {
state.context = state.context.prev;
stream.eat("}");
}
while ((ch = stream.next()) != null) {
if (ch == quote && (unescaped || !escaped)) {
state.tokenize.pop();
break;
}
if (embed && ch == "#" && !escaped) {
if (stream.eat("{")) {
if (quote == "}") {
state.context = {prev: state.context, type: 'read-quoted-paused'};
}
state.tokenize.push(tokenBaseUntilBrace());
break;
} else if (/[@\$]/.test(stream.peek())) {
state.tokenize.push(tokenBaseOnce());
break;
}
}
escaped = !escaped && ch == "\\";
}
return style;
};
}
function readHereDoc(phrase) {
return function(stream, state) {
if (stream.match(phrase)) state.tokenize.pop();
else stream.skipToEnd();
return "string";
};
}
function readBlockComment(stream, state) {
if (stream.sol() && stream.match("=end") && stream.eol())
state.tokenize.pop();
stream.skipToEnd();
return "comment";
}
return {
startState: function() {
return {tokenize: [tokenBase],
indented: 0,
context: {type: "top", indented: -config.indentUnit},
continuedLine: false,
lastTok: null,
varList: false};
},
token: function(stream, state) {
curPunc = null;
if (stream.sol()) state.indented = stream.indentation();
var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
var thisTok = curPunc;
if (style == "ident") {
var word = stream.current();
style = state.lastTok == "." ? "property"
: keywords.propertyIsEnumerable(stream.current()) ? "keyword"
: /^[A-Z]/.test(word) ? "tag"
: (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def"
: "variable";
if (style == "keyword") {
thisTok = word;
if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
else if ((word == "if" || word == "unless") && stream.column() == stream.indentation())
kwtype = "indent";
else if (word == "do" && state.context.indented < state.indented)
kwtype = "indent";
}
}
if (curPunc || (style && style != "comment")) state.lastTok = thisTok;
if (curPunc == "|") state.varList = !state.varList;
if (kwtype == "indent" || /[\(\[\{]/.test(curPunc))
state.context = {prev: state.context, type: curPunc || style, indented: state.indented};
else if ((kwtype == "dedent" || /[\)\]\}]/.test(curPunc)) && state.context.prev)
state.context = state.context.prev;
if (stream.eol())
state.continuedLine = (curPunc == "\\" || style == "operator");
return style;
},
indent: function(state, textAfter) {
if (state.tokenize[state.tokenize.length-1] != tokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0);
var ct = state.context;
var closing = ct.type == matching[firstChar] ||
ct.type == "keyword" && /^(?:end|until|else|elsif|when|rescue)\b/.test(textAfter);
return ct.indented + (closing ? 0 : config.indentUnit) +
(state.continuedLine ? config.indentUnit : 0);
},
electricInput: /^\s*(?:end|rescue|elsif|else|\})$/,
lineComment: "#",
fold: "indent"
};
});
CodeMirror.defineMIME("text/x-ruby", "ruby");
});

16
web/public/codemirror/mode/ruby/test.js vendored Normal file
View File

@@ -0,0 +1,16 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "ruby");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
MT("divide_equal_operator",
"[variable bar] [operator /=] [variable foo]");
MT("divide_equal_operator_no_spacing",
"[variable foo][operator /=][number 42]");
MT("complex_regexp",
"[keyword if] [variable cr] [operator =~] [string-2 /(?: \\( #{][tag RE_NOT][string-2 }\\( | #{][tag RE_NOT_PAR_OR][string-2 }* #{][tag RE_OPA_OR][string-2 } )/][variable x]")
})();

View File

@@ -0,0 +1,64 @@
<!doctype html>
<title>CodeMirror: Rust 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="../../addon/mode/simple.js"></script>
<script src="rust.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://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="#">Rust</a>
</ul>
</div>
<article>
<h2>Rust mode</h2>
<div><textarea id="code" name="code">
// Demo code.
type foo<T> = int;
enum bar {
some(int, foo<float>),
none
}
fn check_crate(x: int) {
let v = 10;
match foo {
1 ... 3 {
print_foo();
if x {
blah().to_string();
}
}
(x, y) { "bye" }
_ { "hi" }
}
}
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
lineWrapping: true,
indentUnit: 4,
mode: "rust"
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-rustsrc</code>.</p>
</article>

72
web/public/codemirror/mode/rust/rust.js vendored Normal file
View File

@@ -0,0 +1,72 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../../addon/mode/simple"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineSimpleMode("rust",{
start: [
// string and byte string
{regex: /b?"/, token: "string", next: "string"},
// raw string and raw byte string
{regex: /b?r"/, token: "string", next: "string_raw"},
{regex: /b?r#+"/, token: "string", next: "string_raw_hash"},
// character
{regex: /'(?:[^'\\]|\\(?:[nrt0'"]|x[\da-fA-F]{2}|u\{[\da-fA-F]{6}\}))'/, token: "string-2"},
// byte
{regex: /b'(?:[^']|\\(?:['\\nrt0]|x[\da-fA-F]{2}))'/, token: "string-2"},
{regex: /(?:(?:[0-9][0-9_]*)(?:(?:[Ee][+-]?[0-9_]+)|\.[0-9_]+(?:[Ee][+-]?[0-9_]+)?)(?:f32|f64)?)|(?:0(?:b[01_]+|(?:o[0-7_]+)|(?:x[0-9a-fA-F_]+))|(?:[0-9][0-9_]*))(?:u8|u16|u32|u64|i8|i16|i32|i64|isize|usize)?/,
token: "number"},
{regex: /(let(?:\s+mut)?|fn|enum|mod|struct|type)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/, token: ["keyword", null, "def"]},
{regex: /(?:abstract|alignof|as|box|break|continue|const|crate|do|else|enum|extern|fn|for|final|if|impl|in|loop|macro|match|mod|move|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\b/, token: "keyword"},
{regex: /\b(?:Self|isize|usize|char|bool|u8|u16|u32|u64|f16|f32|f64|i8|i16|i32|i64|str|Option)\b/, token: "atom"},
{regex: /\b(?:true|false|Some|None|Ok|Err)\b/, token: "builtin"},
{regex: /\b(fn)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/,
token: ["keyword", null ,"def"]},
{regex: /#!?\[.*\]/, token: "meta"},
{regex: /\/\/.*/, token: "comment"},
{regex: /\/\*/, token: "comment", next: "comment"},
{regex: /[-+\/*=<>!]+/, token: "operator"},
{regex: /[a-zA-Z_]\w*!/,token: "variable-3"},
{regex: /[a-zA-Z_]\w*/, token: "variable"},
{regex: /[\{\[\(]/, indent: true},
{regex: /[\}\]\)]/, dedent: true}
],
string: [
{regex: /"/, token: "string", next: "start"},
{regex: /(?:[^\\"]|\\(?:.|$))*/, token: "string"}
],
string_raw: [
{regex: /"/, token: "string", next: "start"},
{regex: /[^"]*/, token: "string"}
],
string_raw_hash: [
{regex: /"#+/, token: "string", next: "start"},
{regex: /(?:[^"]|"(?!#))*/, token: "string"}
],
comment: [
{regex: /.*?\*\//, token: "comment", next: "start"},
{regex: /.*/, token: "comment"}
],
meta: {
dontIndentStates: ["comment"],
electricInput: /^\s*\}$/,
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: "//",
fold: "brace"
}
});
CodeMirror.defineMIME("text/x-rustsrc", "rust");
CodeMirror.defineMIME("text/rust", "rust");
});

Some files were not shown because too many files have changed in this diff Show More