host all files locally

Jessa 2025-02-18 18:14:22 -08:00
parent 432fdb8c7e
commit 9c4402ef77
46 changed files with 8426 additions and 58 deletions

7
css/bootstrap-grid.min.css vendored Normal file

File diff suppressed because one or more lines are too long

8
css/codemirror.min.css vendored Normal file

File diff suppressed because one or more lines are too long

8
css/dracula.min.css vendored Normal file
View File

@ -0,0 +1,8 @@
/**
* Minified by jsDelivr using clean-css v5.3.2.
* Original file: /npm/codemirror@5.65.5/theme/dracula.css
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
.cm-s-dracula .CodeMirror-gutters,.cm-s-dracula.CodeMirror{background-color:#282a36!important;color:#f8f8f2!important;border:none}.cm-s-dracula .CodeMirror-gutters{color:#282a36}.cm-s-dracula .CodeMirror-cursor{border-left:solid thin #f8f8f0}.cm-s-dracula .CodeMirror-linenumber{color:#6d8a88}.cm-s-dracula .CodeMirror-selected{background:rgba(255,255,255,.1)}.cm-s-dracula .CodeMirror-line::selection,.cm-s-dracula .CodeMirror-line>span::selection,.cm-s-dracula .CodeMirror-line>span>span::selection{background:rgba(255,255,255,.1)}.cm-s-dracula .CodeMirror-line::-moz-selection,.cm-s-dracula .CodeMirror-line>span::-moz-selection,.cm-s-dracula .CodeMirror-line>span>span::-moz-selection{background:rgba(255,255,255,.1)}.cm-s-dracula span.cm-comment{color:#6272a4}.cm-s-dracula span.cm-string,.cm-s-dracula span.cm-string-2{color:#f1fa8c}.cm-s-dracula span.cm-number{color:#bd93f9}.cm-s-dracula span.cm-variable{color:#50fa7b}.cm-s-dracula span.cm-variable-2{color:#fff}.cm-s-dracula span.cm-def{color:#50fa7b}.cm-s-dracula span.cm-operator{color:#ff79c6}.cm-s-dracula span.cm-keyword{color:#ff79c6}.cm-s-dracula span.cm-atom{color:#bd93f9}.cm-s-dracula span.cm-meta{color:#f8f8f2}.cm-s-dracula span.cm-tag{color:#ff79c6}.cm-s-dracula span.cm-attribute{color:#50fa7b}.cm-s-dracula span.cm-qualifier{color:#50fa7b}.cm-s-dracula span.cm-property{color:#66d9ef}.cm-s-dracula span.cm-builtin{color:#50fa7b}.cm-s-dracula span.cm-type,.cm-s-dracula span.cm-variable-3{color:#ffb86c}.cm-s-dracula .CodeMirror-activeline-background{background:rgba(255,255,255,.1)}.cm-s-dracula .CodeMirror-matchingbracket{text-decoration:underline;color:#fff!important}
/*# sourceMappingURL=/sm/ba8d009adc9d54938ea88252c099a2b773ed3a4f5515ae9c2f937a8a4cb399df.map */

15
css/microtip.min.css vendored Normal file

File diff suppressed because one or more lines are too long

66
css/simplescrollbars.css Normal file
View File

@ -0,0 +1,66 @@
.CodeMirror-simplescroll-horizontal div, .CodeMirror-simplescroll-vertical div {
position: absolute;
background: #ccc;
-moz-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #bbb;
border-radius: 2px;
}
.CodeMirror-simplescroll-horizontal, .CodeMirror-simplescroll-vertical {
position: absolute;
z-index: 6;
background: #eee;
}
.CodeMirror-simplescroll-horizontal {
bottom: 0; left: 0;
height: 8px;
}
.CodeMirror-simplescroll-horizontal div {
bottom: 0;
height: 100%;
}
.CodeMirror-simplescroll-vertical {
right: 0; top: 0;
width: 8px;
}
.CodeMirror-simplescroll-vertical div {
right: 0;
width: 100%;
}
.CodeMirror-overlayscroll .CodeMirror-scrollbar-filler, .CodeMirror-overlayscroll .CodeMirror-gutter-filler {
display: none;
}
.CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div {
position: absolute;
background: #bcd;
border-radius: 3px;
}
.CodeMirror-overlayscroll-horizontal, .CodeMirror-overlayscroll-vertical {
position: absolute;
z-index: 6;
}
.CodeMirror-overlayscroll-horizontal {
bottom: 0; left: 0;
height: 6px;
}
.CodeMirror-overlayscroll-horizontal div {
bottom: 0;
height: 100%;
}
.CodeMirror-overlayscroll-vertical {
right: 0; top: 0;
width: 6px;
}
.CodeMirror-overlayscroll-vertical div {
right: 0;
width: 100%;
}

1
css/slimselect.min.css vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

BIN
fonts/roboto-v20.woff2 Normal file

Binary file not shown.

View File

@ -6,29 +6,20 @@
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>NoPaste - No-database paste service</title>
<link
rel="stylesheet"
type="text/css"
href="https://cdn.jsdelivr.net/combine/
npm/bootstrap@4.6.1/dist/css/bootstrap-grid.min.css,
npm/slim-select@1.27.1/dist/slimselect.min.css,
npm/codemirror@5.65.5/lib/codemirror.min.css,
npm/codemirror@5.65.5/addon/scroll/simplescrollbars.css,
npm/codemirror@5.65.5/theme/dracula.min.css,
npm/microtip@0.2.2/microtip.min.css
"
/>
<link rel="stylesheet" type="text/css" href="css/bootstrap-grid.min.css" />
<link rel="stylesheet" type="text/css" href="css/slimselect.min.css" />
<link rel="stylesheet" type="text/css" href="css/codemirror.min.css" />
<link rel="stylesheet" type="text/css" href="css/simplescrollbars.css" />
<link rel="stylesheet" type="text/css" href="css/dracula.min.css" />
<link rel="stylesheet" type="text/css" href="css/microtip.min.css" />
<link rel="stylesheet" href="style.css" />
<link href="favicon.ico" rel="icon" type="image/x-icon" />
<link rel="canonical" href="https://nopaste.boris.sh/" />
<meta
name="description"
property="og:description"
content="NoPaste is a client-side paste service which works with no database, and no back-end code. The data is stored entirely in the links and nowhere else"
/>
<meta property="og:title" content="NoPaste - No-database paste service" />
<meta property="og:image" content="https://cdn.jsdelivr.net/gh/bokub/nopaste@images/logo.png" />
<meta property="og:url" content="https://nopaste.boris.sh/" />
<meta property="og:type" content="website" />
</head>
<body class="m-0">
@ -164,19 +155,17 @@ npm/microtip@0.2.2/microtip.min.css
</div>
</div>
<script src="https://cdn.jsdelivr.net/combine/
npm/lzma@2.3.2/src/lzma.min.js,
npm/slim-select@1.27.1/dist/slimselect.min.js,
npm/clipboard@2.0.11/dist/clipboard.min.js,
npm/micromodal@0.4.10/dist/micromodal.min.js,
npm/codemirror@5.65.5,
npm/codemirror@5.65.5/addon/mode/loadmode.min.js,
npm/codemirror@5.65.5/addon/mode/overlay.min.js,
npm/codemirror@5.65.5/addon/mode/multiplex.min.js,
npm/codemirror@5.65.5/addon/mode/simple.min.js,
npm/codemirror@5.65.5/addon/scroll/simplescrollbars.js,
npm/codemirror@5.65.5/mode/meta.min.js
"></script>
<script src="js/lzma.min.js"></script>
<script src="js/slimselect.min.js"></script>
<script src="js/clipboard.min.js"></script>
<script src="js/micromodal.min.js"></script>
<script src="js/codemirror.min.js"></script>
<script src="js/loadmode.min.js"></script>
<script src="js/overlay.min.js"></script>
<script src="js/multiplex.min.js"></script>
<script src="js/simple.min.js"></script>
<script src="js/simplescrollbars.js"></script>
<script src="js/meta.min.js"></script>
<script src="script.js"></script>
</body>
</html>

7
js/clipboard.min.js vendored Normal file

File diff suppressed because one or more lines are too long

8
js/codemirror.min.js vendored Normal file

File diff suppressed because one or more lines are too long

8
js/loadmode.min.js vendored Normal file
View File

@ -0,0 +1,8 @@
/**
* Minified by jsDelivr using Terser v5.19.2.
* Original file: /npm/codemirror@5.65.5/addon/mode/loadmode.js
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror"),"cjs"):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],(function(o){e(o,"amd")})):e(CodeMirror,"plain")}((function(e,o){e.modeURL||(e.modeURL="../mode/%N/%N.js");var r={};function n(o,r,n){var t=e.modes[o],i=t&&t.dependencies;if(!i)return r();for(var d=[],a=0;a<i.length;++a)e.modes.hasOwnProperty(i[a])||d.push(i[a]);if(!d.length)return r();var f=function(e,o){var r=o;return function(){0==--r&&e()}}(r,d.length);for(a=0;a<d.length;++a)e.requireMode(d[a],f,n)}e.requireMode=function(t,i,d){if("string"!=typeof t&&(t=t.name),e.modes.hasOwnProperty(t))return n(t,i,d);if(r.hasOwnProperty(t))return r[t].push(i);var a=d&&d.path?d.path(t):e.modeURL.replace(/%N/g,t);if(d&&d.loadMode)d.loadMode(a,(function(){n(t,i,d)}));else if("plain"==o){var f=document.createElement("script");f.src=a;var u=document.getElementsByTagName("script")[0],c=r[t]=[i];e.on(f,"load",(function(){n(t,(function(){for(var e=0;e<c.length;++e)c[e]()}),d)})),u.parentNode.insertBefore(f,u)}else"cjs"==o?(require(a),i()):"amd"==o&&requirejs([a],i)},e.autoLoadMode=function(o,r,n){e.modes.hasOwnProperty(r)||e.requireMode(r,(function(){o.setOption("mode",o.getOption("mode"))}),n)}}));
//# sourceMappingURL=/sm/79e1bd89cf74f4f96b857ebce03ffca414a55775fd74580cf6192e542b73f4c9.map

9
js/lzma.min.js vendored Normal file
View File

@ -0,0 +1,9 @@
/**
* Minified by jsDelivr using Terser v5.19.2.
* Original file: /npm/lzma@2.3.2/src/lzma.js
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
//! © 2015 Nathan Rugg <nmrugg@gmail.com> | MIT
"undefined"==typeof Worker||"undefined"!=typeof location&&"file:"===location.protocol?"undefined"!=typeof global&&"undefined"!=typeof require?this.LZMA=function(n){return require(n||"./lzma_worker.js").LZMA}:"undefined"!=typeof window&&window.document?function(){var n,e=this;function o(r){var t;return function(n){var r=document.createElement("script");r.type="text/javascript",r.src=n,r.onload=function(){e.LZMA=o},document.getElementsByTagName("head")[0].appendChild(r)}(r),t={compress:function(e,o,r,i){n.LZMA_WORKER?n.LZMA_WORKER.compress(e,o,r,i):setTimeout((function(){t.compress(e,o,r,i)}),50)},decompress:function(e,o,r){n.LZMA_WORKER?n.LZMA_WORKER.decompress(e,o,r):setTimeout((function(){t.decompress(e,o,r)}),50)},worker:function(){return null}}}"undefined"!=typeof window?n=window:global&&(n=global),e.LZMA=o}():console.error("Can't load the worker. Sorry."):this.LZMA=function(n){var e={},o=new Worker(n||"./lzma_worker-min.js");return o.onmessage=function(n){3===n.data.action?e[n.data.cbn]&&"function"==typeof e[n.data.cbn].on_progress&&e[n.data.cbn].on_progress(n.data.result):e[n.data.cbn]&&"function"==typeof e[n.data.cbn].on_finish&&(e[n.data.cbn].on_finish(n.data.result,n.data.error),delete e[n.data.cbn])},o.onerror=function(n){var o=new Error(n.message+" ("+n.filename+":"+n.lineno+")");for(var r in e)e[r].on_finish(null,o);console.error("Uncaught error in lzma_worker",o)},function(){function n(n,r,t,i,a){var c;do{c=Math.floor(1e7*Math.random())}while(void 0!==e[c]);e[c]={on_finish:i,on_progress:a},o.postMessage({action:n,cbn:c,data:r,mode:t})}return{compress:function(e,o,r,t){n(1,e,o,r,t)},decompress:function(e,o,r){n(2,e,!1,o,r)},worker:function(){return o}}}()};
//# sourceMappingURL=/sm/9a8373aaafa520c6b52bb32def0da02deb037ef21e4015734a0e533b7aa5bcb9.map

8
js/lzma_worker.min.js vendored Normal file

File diff suppressed because one or more lines are too long

8
js/meta.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
js/micromodal.min.js vendored Normal file

File diff suppressed because one or more lines are too long

940
js/mode/clike.js Normal file
View File

@ -0,0 +1,940 @@
// 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 (numberStart.test(ch)) {
stream.backUp(1)
if (stream.match(number)) return "number"
stream.next()
}
if (isPunctuationChar.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)) {
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";
// Keywords from https://en.cppreference.com/w/cpp/keyword includes C++20.
var cppKeywords = "alignas alignof and and_eq audit axiom bitand bitor catch " +
"class compl concept constexpr const_cast decltype delete dynamic_cast " +
"explicit export final friend import module mutable namespace new noexcept " +
"not not_eq operator or or_eq override private protected public " +
"reinterpret_cast requires static_assert static_cast template this " +
"thread_local throw try typeid typename using virtual xor xor_eq";
var objCKeywords = "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";
var objCBuiltins = "FOUNDATION_EXPORT FOUNDATION_EXTERN NS_INLINE NS_FORMAT_FUNCTION " +
" NS_RETURNS_RETAINEDNS_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"
// 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 + " " + cppKeywords),
types: cTypes,
blockKeywords: words(cBlockKeywords + " class try catch"),
defKeywords: words(cDefKeywords + " class namespace"),
typeFirstDefinitions: true,
atoms: words("true false NULL nullptr"),
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 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("var 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";
},
'"': function(stream, state) {
if (!stream.match(/""$/)) return false;
state.tokenize = tokenTripleString;
return state.tokenize(stream, state);
}
},
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 value"
),
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) {
return state.prevToken == '.' ? 'variable' : 'operator';
},
'"': function(stream, state) {
state.tokenize = tokenKotlinString(stream.match('""'));
return state.tokenize(stream, state);
},
"/": function(stream, state) {
if (!stream.eat("*")) return false;
state.tokenize = tokenNestedComment(1);
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.context.type != "}") ||
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_TextureMatrixTranspose 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 + " " + objCKeywords),
types: objCTypes,
builtin: words(objCBuiltins),
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-objectivec++", {
name: "clike",
keywords: words(cKeywords + " " + objCKeywords + " " + cppKeywords),
types: objCTypes,
builtin: words(objCBuiltins),
blockKeywords: words(cBlockKeywords + " @synthesize @try @catch @finally @autoreleasepool @synchronized class try catch"),
defKeywords: words(cDefKeywords + " @interface @implementation @protocol @class class namespace"),
dontIndentStatements: /^@.*$|^template$/,
typeFirstDefinitions: true,
atoms: words("YES NO NULL Nil nil true false nullptr"),
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-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: '"'}
}
});
});

862
js/mode/css.js Normal file
View File

@ -0,0 +1,862 @@
// 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,
highlightNonStandardPropertyKeywords = config.highlightNonStandardPropertyKeywords !== false;
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 (stream.match(/^[\w-.]+(?=\()/)) {
if (/^(url(-prefix)?|domain|regexp)$/i.test(stream.current())) {
state.tokenize = tokenParenthesized;
}
return ret("variable callee", "variable");
} 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 = highlightNonStandardPropertyKeywords ? "string-2" : "property";
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 = highlightNonStandardPropertyKeywords ? "string-2" : "property";
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", "prefers-color-scheme",
"dynamic-range", "video-dynamic-range"
], mediaFeatures = keySet(mediaFeatures_);
var mediaValueKeywords_ = [
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
"interlace", "progressive",
"dark", "light",
"standard", "high"
], mediaValueKeywords = keySet(mediaValueKeywords_);
var propertyKeywords_ = [
"align-content", "align-items", "align-self", "alignment-adjust",
"alignment-baseline", "all", "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", "backdrop-filter",
"backface-visibility", "background", "background-attachment",
"background-blend-mode", "background-clip", "background-color",
"background-image", "background-origin", "background-position",
"background-position-x", "background-position-y", "background-repeat",
"background-size", "baseline-shift", "binding", "bleed", "block-size",
"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", "contain",
"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-content", "fit-position",
"flex", "flex-basis", "flex-direction", "flex-flow", "flex-grow",
"flex-shrink", "flex-wrap", "float", "float-offset", "flow-from", "flow-into",
"font", "font-family", "font-feature-settings", "font-kerning",
"font-language-override", "font-optical-sizing", "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-variation-settings", "font-weight", "gap",
"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",
"inset", "inset-block", "inset-block-end", "inset-block-start", "inset-inline",
"inset-inline-end", "inset-inline-start", "isolation", "justify-content",
"justify-items", "justify-self", "left", "letter-spacing", "line-break",
"line-height", "line-height-step", "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", "mask-clip", "mask-composite", "mask-image", "mask-mode",
"mask-origin", "mask-position", "mask-repeat", "mask-size","mask-type",
"max-block-size", "max-height", "max-inline-size",
"max-width", "min-block-size", "min-height", "min-inline-size", "min-width",
"mix-blend-mode", "move-to", "nav-down", "nav-index", "nav-left", "nav-right",
"nav-up", "object-fit", "object-position", "offset", "offset-anchor",
"offset-distance", "offset-path", "offset-position", "offset-rotate",
"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", "rotate", "rotation", "rotation-point",
"row-gap", "ruby-align", "ruby-overhang", "ruby-position", "ruby-span",
"scale", "scroll-behavior", "scroll-margin", "scroll-margin-block",
"scroll-margin-block-end", "scroll-margin-block-start", "scroll-margin-bottom",
"scroll-margin-inline", "scroll-margin-inline-end",
"scroll-margin-inline-start", "scroll-margin-left", "scroll-margin-right",
"scroll-margin-top", "scroll-padding", "scroll-padding-block",
"scroll-padding-block-end", "scroll-padding-block-start",
"scroll-padding-bottom", "scroll-padding-inline", "scroll-padding-inline-end",
"scroll-padding-inline-start", "scroll-padding-left", "scroll-padding-right",
"scroll-padding-top", "scroll-snap-align", "scroll-snap-type",
"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-combine-upright", "text-decoration",
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
"text-decoration-skip-ink", "text-decoration-style", "text-emphasis",
"text-emphasis-color", "text-emphasis-position", "text-emphasis-style",
"text-height", "text-indent", "text-justify", "text-orientation",
"text-outline", "text-overflow", "text-rendering", "text-shadow",
"text-size-adjust", "text-space-collapse", "text-transform",
"text-underline-position", "text-wrap", "top", "touch-action", "transform", "transform-origin",
"transform-style", "transition", "transition-delay", "transition-duration",
"transition-property", "transition-timing-function", "translate",
"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", "writing-mode", "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", "paint-order", "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_ = [
"accent-color", "aspect-ratio", "border-block", "border-block-color", "border-block-end",
"border-block-end-color", "border-block-end-style", "border-block-end-width",
"border-block-start", "border-block-start-color", "border-block-start-style",
"border-block-start-width", "border-block-style", "border-block-width",
"border-inline", "border-inline-color", "border-inline-end",
"border-inline-end-color", "border-inline-end-style",
"border-inline-end-width", "border-inline-start", "border-inline-start-color",
"border-inline-start-style", "border-inline-start-width",
"border-inline-style", "border-inline-width", "content-visibility", "margin-block",
"margin-block-end", "margin-block-start", "margin-inline", "margin-inline-end",
"margin-inline-start", "overflow-anchor", "overscroll-behavior", "padding-block", "padding-block-end",
"padding-block-start", "padding-inline", "padding-inline-end",
"padding-inline-start", "scroll-snap-stop", "scrollbar-3d-light-color",
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
"scrollbar-track-color", "searchfield-cancel-button", "searchfield-decoration",
"searchfield-results-button", "searchfield-results-decoration", "shape-inside", "zoom"
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
var fontProperties_ = [
"font-display", "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", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen",
"darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
"darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet",
"deeppink", "deepskyblue", "dimgray", "dimgrey", "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", "lightgrey", "lightpink",
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey",
"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", "slategrey", "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", "axis-pan", "background", "backwards", "baseline", "below", "bidi-override", "binary",
"bengali", "blink", "block", "block-axis", "blur", "bold", "bolder", "border", "border-box",
"both", "bottom", "break", "break-all", "break-word", "brightness", "bullets", "button",
"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", "conic-gradient", "contain", "content", "contents",
"content-box", "context-menu", "continuous", "contrast", "copy", "counter", "counters", "cover", "crop",
"cross", "crosshair", "cubic-bezier", "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", "drop-shadow", "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", "fill-box", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
"forwards", "from", "geometricPrecision", "georgian", "grayscale", "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", "hue-rotate", "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", "manipulation", "match", "matrix", "matrix3d",
"media-play-button", "media-slider", "media-sliderthumb",
"media-volume-slider", "media-volume-sliderthumb", "medium",
"menu", "menulist", "menulist-button",
"menutext", "message-box", "middle", "min-intrinsic",
"mix", "mongolian", "monospace", "move", "multiple", "multiple_mask_images", "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", "pinch-zoom", "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",
"repeating-conic-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", "saturate", "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", "sepia", "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", "stroke-box", "sub",
"subpixel-antialiased", "svg_masks", "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", "unidirectional-pan", "unset", "up",
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
"var", "vertical", "vertical-text", "view-box", "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"
});
});

47
js/mode/diff.js Normal file
View File

@ -0,0 +1,47 @@
// 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("diff", function() {
var TOKEN_NAMES = {
'+': 'positive',
'-': 'negative',
'@': 'meta'
};
return {
token: function(stream) {
var tw_pos = stream.string.search(/[\t ]+?$/);
if (!stream.sol() || tw_pos === 0) {
stream.skipToEnd();
return ("error " + (
TOKEN_NAMES[stream.string.charAt(0)] || '')).replace(/ $/, '');
}
var token_name = TOKEN_NAMES[stream.peek()] || stream.skipToEnd();
if (tw_pos === -1) {
stream.skipToEnd();
} else {
stream.pos = tw_pos;
}
return token_name;
}
};
});
CodeMirror.defineMIME("text/x-diff", "diff");
});

619
js/mode/erlang.js Normal file
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(/^\s*([^\s%])/, false)
return m ? m[1] : "";
}
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: "%"
};
});
});

187
js/mode/go.js 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");
});

70
js/mode/handlebars.js Normal file
View File

@ -0,0 +1,70 @@
// 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"), require("../../addon/mode/multiplex"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../../addon/mode/simple", "../../addon/mode/multiplex"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineSimpleMode("handlebars-tags", {
start: [
{ regex: /\{\{\{/, push: "handlebars_raw", token: "tag" },
{ regex: /\{\{!--/, push: "dash_comment", token: "comment" },
{ regex: /\{\{!/, push: "comment", token: "comment" },
{ regex: /\{\{/, push: "handlebars", token: "tag" }
],
handlebars_raw: [
{ regex: /\}\}\}/, pop: true, token: "tag" },
],
handlebars: [
{ regex: /\}\}/, pop: true, token: "tag" },
// Double and single quotes
{ regex: /"(?:[^\\"]|\\.)*"?/, token: "string" },
{ regex: /'(?:[^\\']|\\.)*'?/, token: "string" },
// Handlebars keywords
{ regex: />|[#\/]([A-Za-z_]\w*)/, token: "keyword" },
{ regex: /(?:else|this)\b/, token: "keyword" },
// Numeral
{ regex: /\d+/i, token: "number" },
// Atoms like = and .
{ regex: /=|~|@|true|false/, token: "atom" },
// Paths
{ regex: /(?:\.\.\/)*(?:[A-Za-z_][\w\.]*)+/, token: "variable-2" }
],
dash_comment: [
{ regex: /--\}\}/, pop: true, token: "comment" },
// Commented code
{ regex: /./, token: "comment"}
],
comment: [
{ regex: /\}\}/, pop: true, token: "comment" },
{ regex: /./, token: "comment" }
],
meta: {
blockCommentStart: "{{--",
blockCommentEnd: "--}}"
}
});
CodeMirror.defineMode("handlebars", function(config, parserConfig) {
var handlebars = CodeMirror.getMode(config, "handlebars-tags");
if (!parserConfig || !parserConfig.base) return handlebars;
return CodeMirror.multiplexingMode(
CodeMirror.getMode(config, parserConfig.base),
{open: "{{", close: /\}\}\}?/, mode: handlebars, parseDelimiters: true}
);
});
CodeMirror.defineMIME("text/x-handlebars-template", "handlebars");
});

113
js/mode/http.js 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");
});

960
js/mode/javascript.js Normal file
View File

@ -0,0 +1,960 @@
// 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 trackScope = parserConfig.trackScope !== false
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[\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-Fa-f_]+|o[0-7_]+|b[01_]+)n?/)) {
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.peek() == "!") {
stream.skipToEnd();
return ret("meta", "meta");
} else if (ch == "#" && stream.eatWhile(wordRE)) {
return ret("variable", "property")
} else if (ch == "<" && stream.match("!--") ||
(ch == "-" && stream.match("->") && !/\S/.test(stream.string.slice(0, stream.start)))) {
stream.skipToEnd()
return ret("comment", "comment")
} 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)
}
}
if (ch == "?" && stream.eat(".")) return ret(".")
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)) {
for (;; --pos) {
if (pos == 0) return
var next = stream.string.charAt(pos - 1)
if (next == ch && stream.string.charAt(pos - 2) != "\\") { pos--; break }
}
} 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, "import": 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) {
if (!trackScope) return false
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 (!trackScope) return
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
}
pushcontext.lex = pushblockcontext.lex = true
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"), pushblockcontext, forspec, statement, popcontext, poplex);
if (type == "class" || (isTS && value == "interface")) {
cx.marked = "keyword"
return cont(pushlex("form", type == "class" ? type : value), 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(typename, 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, statement, 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(")"), maybeexpression, 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));
return cont();
}
function maybeexpression(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expression);
}
function maybeoperatorComma(type, value) {
if (type == ",") return cont(maybeexpression);
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(maybeexpression, 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();
if (sep && sep.indexOf(";") > -1) return pass(what)
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 maybetypeOrIn(type, value) {
if (isTS && (type == ":" || value == "in")) return cont(typeexpr)
}
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" || value == "infer" || value == "readonly") {
cx.marked = "keyword"
return cont(value == "typeof" ? expressionNoComma : typeexpr)
}
if (type == "variable" || value == "void") {
cx.marked = "type"
return cont(afterType)
}
if (value == "|" || value == "&") return cont(typeexpr)
if (type == "string" || type == "number" || type == "atom") return cont(afterType);
if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType)
if (type == "{") return cont(pushlex("}"), typeprops, poplex, afterType)
if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType, afterType)
if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr)
if (type == "quasi") { return pass(quasiType, afterType); }
}
function maybeReturnType(type) {
if (type == "=>") return cont(typeexpr)
}
function typeprops(type) {
if (type.match(/[\}\)\]]/)) return cont()
if (type == "," || type == ";") return cont(typeprops)
return pass(typeprop, typeprops)
}
function typeprop(type, value) {
if (type == "variable" || cx.style == "keyword") {
cx.marked = "property"
return cont(typeprop)
} else if (value == "?" || type == "number" || type == "string") {
return cont(typeprop)
} else if (type == ":") {
return cont(typeexpr)
} else if (type == "[") {
return cont(expect("variable"), maybetypeOrIn, expect("]"), typeprop)
} else if (type == "(") {
return pass(functiondecl, typeprop)
} else if (!type.match(/[;\}\)\],]/)) {
return cont()
}
}
function quasiType(type, value) {
if (type != "quasi") return pass();
if (value.slice(value.length - 2) != "${") return cont(quasiType);
return cont(typeexpr, continueQuasiType);
}
function continueQuasiType(type) {
if (type == "}") {
cx.marked = "string-2";
cx.state.tokenize = tokenQuasi;
return cont(quasiType);
}
}
function typearg(type, value) {
if (type == "variable" && cx.stream.match(/^\s*[?:]/, false) || value == "?") return cont(typearg)
if (type == ":") return cont(typeexpr)
if (type == "spread") return cont(typearg)
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(typeexpr, expect("]"), afterType)
if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) }
if (value == "?") return cont(typeexpr, expect(":"), 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();
if (type == "[") return cont(expression, expect(']'), expect(':'), proppattern);
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, poplex);
}
function forspec1(type) {
if (type == "var") return cont(vardef, forspec2);
if (type == "variable") return cont(forspec2);
return pass(forspec2)
}
function forspec2(type, value) {
if (type == ")") return cont()
if (type == ";") return cont(forspec2)
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression, forspec2) }
return pass(expression, forspec2)
}
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 functiondecl(type, value) {
if (value == "*") {cx.marked = "keyword"; return cont(functiondecl);}
if (type == "variable") {register(value); return cont(functiondecl);}
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, popcontext);
if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondecl)
}
function typename(type, value) {
if (type == "keyword" || type == "variable") {
cx.marked = "type"
return cont(typename)
} else if (value == "<") {
return cont(pushlex(">"), commasep(typeparam, ">"), poplex)
}
}
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); }
if (isTS && type == "this") return cont(maybetype, maybeAssign)
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(classfield, classBody);
}
if (type == "number" || type == "string") return cont(classfield, classBody);
if (type == "[")
return cont(expression, maybetype, expect("]"), classfield, classBody)
if (value == "*") {
cx.marked = "keyword";
return cont(classBody);
}
if (isTS && type == "(") return pass(functiondecl, classBody)
if (type == ";" || type == ",") return cont(classBody);
if (type == "}") return cont();
if (value == "@") return cont(expression, classBody)
}
function classfield(type, value) {
if (value == "!") return cont(classfield)
if (value == "?") return cont(classfield)
if (type == ":") return cont(typeexpr, maybeAssign)
if (value == "=") return cont(expressionNoComma)
var context = cx.state.lexical.prev, isInterface = context && context.info == "interface"
return pass(isInterface ? functiondecl : 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);
if (type == ".") return pass(maybeoperatorComma);
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 || state.tokenize == tokenQuasi) 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 && c != popcontext) 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) {
parseJS(state, "atom", "atom", "true", new CodeMirror.StringStream("", 2, null))
}
};
});
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/manifest+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 });
});

146
js/mode/jinja2.js Normal file
View File

@ -0,0 +1,146 @@
// 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("jinja2", function() {
var keywords = ["and", "as", "block", "endblock", "by", "cycle", "debug", "else", "elif",
"extends", "filter", "endfilter", "firstof", "for",
"endfor", "if", "endif", "ifchanged", "endifchanged",
"ifequal", "endifequal", "ifnotequal",
"endifnotequal", "in", "include", "load", "not", "now", "or",
"parsed", "regroup", "reversed", "spaceless",
"endspaceless", "ssi", "templatetag", "openblock",
"closeblock", "openvariable", "closevariable",
"openbrace", "closebrace", "opencomment",
"closecomment", "widthratio", "url", "with", "endwith",
"get_current_language", "trans", "endtrans", "noop", "blocktrans",
"endblocktrans", "get_available_languages",
"get_current_language_bidi", "plural"],
operator = /^[+\-*&%=<>!?|~^]/,
sign = /^[:\[\(\{]/,
atom = ["true", "false"],
number = /^(\d[+\-\*\/])?\d+(\.\d+)?/;
keywords = new RegExp("((" + keywords.join(")|(") + "))\\b");
atom = new RegExp("((" + atom.join(")|(") + "))\\b");
function tokenBase (stream, state) {
var ch = stream.peek();
//Comment
if (state.incomment) {
if(!stream.skipTo("#}")) {
stream.skipToEnd();
} else {
stream.eatWhile(/\#|}/);
state.incomment = false;
}
return "comment";
//Tag
} else if (state.intag) {
//After operator
if(state.operator) {
state.operator = false;
if(stream.match(atom)) {
return "atom";
}
if(stream.match(number)) {
return "number";
}
}
//After sign
if(state.sign) {
state.sign = false;
if(stream.match(atom)) {
return "atom";
}
if(stream.match(number)) {
return "number";
}
}
if(state.instring) {
if(ch == state.instring) {
state.instring = false;
}
stream.next();
return "string";
} else if(ch == "'" || ch == '"') {
state.instring = ch;
stream.next();
return "string";
} else if(stream.match(state.intag + "}") || stream.eat("-") && stream.match(state.intag + "}")) {
state.intag = false;
return "tag";
} else if(stream.match(operator)) {
state.operator = true;
return "operator";
} else if(stream.match(sign)) {
state.sign = true;
} else {
if(stream.eat(" ") || stream.sol()) {
if(stream.match(keywords)) {
return "keyword";
}
if(stream.match(atom)) {
return "atom";
}
if(stream.match(number)) {
return "number";
}
if(stream.sol()) {
stream.next();
}
} else {
stream.next();
}
}
return "variable";
} else if (stream.eat("{")) {
if (stream.eat("#")) {
state.incomment = true;
if(!stream.skipTo("#}")) {
stream.skipToEnd();
} else {
stream.eatWhile(/\#|}/);
state.incomment = false;
}
return "comment";
//Open tag
} else if (ch = stream.eat(/\{|%/)) {
//Cache close tag
state.intag = ch;
if(ch == "{") {
state.intag = "}";
}
stream.eat("-");
return "tag";
}
}
stream.next();
};
return {
startState: function () {
return {tokenize: tokenBase};
},
token: function (stream, state) {
return state.tokenize(stream, state);
},
blockCommentStart: "{#",
blockCommentEnd: "#}"
};
});
CodeMirror.defineMIME("text/jinja2", "jinja2");
});

148
js/mode/jsx.js 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)) {
state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "", "")),
xmlMode, 0, state.context)
jsMode.skipExpression(cx.state)
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}})
});

160
js/mode/lua.js Normal file
View File

@ -0,0 +1,160 @@
// 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));
},
electricInput: /^\s*(?:end|until|else|\)|\})$/,
lineComment: "--",
blockCommentStart: "--[[",
blockCommentEnd: "]]"
};
});
CodeMirror.defineMIME("text/x-lua", "lua");
});

886
js/mode/markdown.js Normal file
View File

@ -0,0 +1,886 @@
// 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.fencedCodeBlockDefaultMode === undefined)
modeCfg.fencedCodeBlockDefaultMode = 'text/plain';
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 = /^ {0,3}(?:\={1,}|-{2,})\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) {
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);
// Reset inline styles which shouldn't propagate across list items
state.em = false;
state.strong = false;
state.code = false;
state.strikethrough = false;
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] || modeCfg.fencedCodeBlockDefaultMode );
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");
});

836
js/mode/perl.js Normal file
View File

@ -0,0 +1,836 @@
// 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 filesystem
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 string
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[\d_]*)?\.\d+(e[+-]?\d+)?|\d+\.\d*)|0x[\da-fA-F_]+|0b[01_]+|\d[\d_]*(e[+-]?\d+)?)/))
return 'number';
if(stream.match(/^<<(?=[_a-zA-Z])/)){ // 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;
}
});

234
js/mode/php.js Normal file

File diff suppressed because one or more lines are too long

72
js/mode/protobuf.js 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"));
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,
fold: "brace"
};
});
CodeMirror.defineMIME("text/x-protobuf", "protobuf");
});

402
js/mode/python.js Normal file
View File

@ -0,0 +1,402 @@
// 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-compatibility 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)|(rb)|(fr)|(rf))?('{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, inFormat) {
if (stream.eatSpace()) return null;
// Handle Comments
if (!inFormat && 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(), state.tokenize);
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 inFormat ? null :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 tokenNestedExpr(depth) {
return function(stream, state) {
var inner = tokenBaseInner(stream, state, true)
if (inner == "punctuation") {
if (stream.current() == "{") {
state.tokenize = tokenNestedExpr(depth + 1)
} else if (stream.current() == "}") {
if (depth > 1) state.tokenize = tokenNestedExpr(depth - 1)
else state.tokenize = tokenString
}
}
return inner
}
}
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 = tokenNestedExpr(0)
if (stream.current()) return OUTCLASS;
else return state.tokenize(stream, state)
} 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, tokenOuter) {
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 = tokenOuter;
return OUTCLASS;
} else {
stream.eat(/['"]/);
}
}
if (singleline) {
if (parserConf.singleLineStringErrors)
return ERRORCLASS;
else
state.tokenize = tokenOuter;
}
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;
state.dedent = false;
}
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 = true;
if (current == "lambda") state.lambda = true;
if (current == ":" && !state.lambda && top(state).type == "py" && stream.match(/^\s*(?:#|$)/, false))
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 && stream.eol() && top(state).type == "py" && state.scopes.length > 1)
state.scopes.pop();
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)
var closing = scope.type == textAfter.charAt(0) ||
scope.type == "py" && !state.dedent && /^(else:|elif |except |finally:)/.test(textAfter)
if (scope.align != null)
return scope.align - (closing ? 1 : 0)
else
return scope.offset - (closing ? hangingIndent : 0)
},
electricInput: /^\s*([\}\]\)]|else:|elif |except |finally:)$/,
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")
});
});

72
js/mode/rust.js 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|union)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/, token: ["keyword", null, "def"]},
{regex: /(?:abstract|alignof|as|async|await|box|break|continue|const|crate|do|dyn|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|union|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");
});

168
js/mode/shell.js Normal file
View File

@ -0,0 +1,168 @@
// 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('shell', function() {
var words = {};
function define(style, dict) {
for(var i = 0; i < dict.length; i++) {
words[dict[i]] = style;
}
};
var commonAtoms = ["true", "false"];
var commonKeywords = ["if", "then", "do", "else", "elif", "while", "until", "for", "in", "esac", "fi",
"fin", "fil", "done", "exit", "set", "unset", "export", "function"];
var commonCommands = ["ab", "awk", "bash", "beep", "cat", "cc", "cd", "chown", "chmod", "chroot", "clear",
"cp", "curl", "cut", "diff", "echo", "find", "gawk", "gcc", "get", "git", "grep", "hg", "kill", "killall",
"ln", "ls", "make", "mkdir", "openssl", "mv", "nc", "nl", "node", "npm", "ping", "ps", "restart", "rm",
"rmdir", "sed", "service", "sh", "shopt", "shred", "source", "sort", "sleep", "ssh", "start", "stop",
"su", "sudo", "svn", "tee", "telnet", "top", "touch", "vi", "vim", "wall", "wc", "wget", "who", "write",
"yes", "zsh"];
CodeMirror.registerHelper("hintWords", "shell", commonAtoms.concat(commonKeywords, commonCommands));
define('atom', commonAtoms);
define('keyword', commonKeywords);
define('builtin', commonCommands);
function tokenBase(stream, state) {
if (stream.eatSpace()) return null;
var sol = stream.sol();
var ch = stream.next();
if (ch === '\\') {
stream.next();
return null;
}
if (ch === '\'' || ch === '"' || ch === '`') {
state.tokens.unshift(tokenString(ch, ch === "`" ? "quote" : "string"));
return tokenize(stream, state);
}
if (ch === '#') {
if (sol && stream.eat('!')) {
stream.skipToEnd();
return 'meta'; // 'comment'?
}
stream.skipToEnd();
return 'comment';
}
if (ch === '$') {
state.tokens.unshift(tokenDollar);
return tokenize(stream, state);
}
if (ch === '+' || ch === '=') {
return 'operator';
}
if (ch === '-') {
stream.eat('-');
stream.eatWhile(/\w/);
return 'attribute';
}
if (ch == "<") {
if (stream.match("<<")) return "operator"
var heredoc = stream.match(/^<-?\s*['"]?([^'"]*)['"]?/)
if (heredoc) {
state.tokens.unshift(tokenHeredoc(heredoc[1]))
return 'string-2'
}
}
if (/\d/.test(ch)) {
stream.eatWhile(/\d/);
if(stream.eol() || !/\w/.test(stream.peek())) {
return 'number';
}
}
stream.eatWhile(/[\w-]/);
var cur = stream.current();
if (stream.peek() === '=' && /\w+/.test(cur)) return 'def';
return words.hasOwnProperty(cur) ? words[cur] : null;
}
function tokenString(quote, style) {
var close = quote == "(" ? ")" : quote == "{" ? "}" : quote
return function(stream, state) {
var next, escaped = false;
while ((next = stream.next()) != null) {
if (next === close && !escaped) {
state.tokens.shift();
break;
} else if (next === '$' && !escaped && quote !== "'" && stream.peek() != close) {
escaped = true;
stream.backUp(1);
state.tokens.unshift(tokenDollar);
break;
} else if (!escaped && quote !== close && next === quote) {
state.tokens.unshift(tokenString(quote, style))
return tokenize(stream, state)
} else if (!escaped && /['"]/.test(next) && !/['"]/.test(quote)) {
state.tokens.unshift(tokenStringStart(next, "string"));
stream.backUp(1);
break;
}
escaped = !escaped && next === '\\';
}
return style;
};
};
function tokenStringStart(quote, style) {
return function(stream, state) {
state.tokens[0] = tokenString(quote, style)
stream.next()
return tokenize(stream, state)
}
}
var tokenDollar = function(stream, state) {
if (state.tokens.length > 1) stream.eat('$');
var ch = stream.next()
if (/['"({]/.test(ch)) {
state.tokens[0] = tokenString(ch, ch == "(" ? "quote" : ch == "{" ? "def" : "string");
return tokenize(stream, state);
}
if (!/\d/.test(ch)) stream.eatWhile(/\w/);
state.tokens.shift();
return 'def';
};
function tokenHeredoc(delim) {
return function(stream, state) {
if (stream.sol() && stream.string == delim) state.tokens.shift()
stream.skipToEnd()
return "string-2"
}
}
function tokenize(stream, state) {
return (state.tokens[0] || tokenBase) (stream, state);
};
return {
startState: function() {return {tokens:[]};},
token: function(stream, state) {
return tokenize(stream, state);
},
closeBrackets: "()[]{}''\"\"``",
lineComment: '#',
fold: "brace"
};
});
CodeMirror.defineMIME('text/x-sh', 'shell');
// Apache uses a slightly different Media Type for Shell scripts
// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
CodeMirror.defineMIME('application/x-sh', 'shell');
});

503
js/mode/sql.js Normal file

File diff suppressed because one or more lines are too long

88
js/mode/toml.js Normal file
View File

@ -0,0 +1,88 @@
// 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("toml", function () {
return {
startState: function () {
return {
inString: false,
stringType: "",
lhs: true,
inArray: 0
};
},
token: function (stream, state) {
//check for state changes
if (!state.inString && ((stream.peek() == '"') || (stream.peek() == "'"))) {
state.stringType = stream.peek();
stream.next(); // Skip quote
state.inString = true; // Update state
}
if (stream.sol() && state.inArray === 0) {
state.lhs = true;
}
//return state
if (state.inString) {
while (state.inString && !stream.eol()) {
if (stream.peek() === state.stringType) {
stream.next(); // Skip quote
state.inString = false; // Clear flag
} else if (stream.peek() === '\\') {
stream.next();
stream.next();
} else {
stream.match(/^.[^\\\"\']*/);
}
}
return state.lhs ? "property string" : "string"; // Token style
} else if (state.inArray && stream.peek() === ']') {
stream.next();
state.inArray--;
return 'bracket';
} else if (state.lhs && stream.peek() === '[' && stream.skipTo(']')) {
stream.next();//skip closing ]
// array of objects has an extra open & close []
if (stream.peek() === ']') stream.next();
return "atom";
} else if (stream.peek() === "#") {
stream.skipToEnd();
return "comment";
} else if (stream.eatSpace()) {
return null;
} else if (state.lhs && stream.eatWhile(function (c) { return c != '=' && c != ' '; })) {
return "property";
} else if (state.lhs && stream.peek() === "=") {
stream.next();
state.lhs = false;
return null;
} else if (!state.lhs && stream.match(/^\d\d\d\d[\d\-\:\.T]*Z/)) {
return 'atom'; //date
} else if (!state.lhs && (stream.match('true') || stream.match('false'))) {
return 'atom';
} else if (!state.lhs && stream.peek() === '[') {
state.inArray++;
stream.next();
return 'bracket';
} else if (!state.lhs && stream.match(/^\-?\d+(?:\.\d+)?/)) {
return 'number';
} else if (!stream.eatSpace()) {
stream.next();
}
return null;
}
};
});
CodeMirror.defineMIME('text/x-toml', 'toml');
});

417
js/mode/xml.js Normal file
View File

@ -0,0 +1,417 @@
// 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";
var htmlConfig = {
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
'track': true, 'wbr': true, 'menuitem': true},
implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
'th': true, 'tr': true},
contextGrabbers: {
'dd': {'dd': true, 'dt': true},
'dt': {'dd': true, 'dt': true},
'li': {'li': true},
'option': {'option': true, 'optgroup': true},
'optgroup': {'optgroup': true},
'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
'rp': {'rp': true, 'rt': true},
'rt': {'rp': true, 'rt': true},
'tbody': {'tbody': true, 'tfoot': true},
'td': {'td': true, 'th': true},
'tfoot': {'tbody': true},
'th': {'td': true, 'th': true},
'thead': {'tbody': true, 'tfoot': true},
'tr': {'tr': true}
},
doNotIndent: {"pre": true},
allowUnquoted: true,
allowMissing: true,
caseFold: true
}
var xmlConfig = {
autoSelfClosers: {},
implicitlyClosed: {},
contextGrabbers: {},
doNotIndent: {},
allowUnquoted: false,
allowMissing: false,
allowMissingTagName: false,
caseFold: false
}
CodeMirror.defineMode("xml", function(editorConf, config_) {
var indentUnit = editorConf.indentUnit
var config = {}
var defaults = config_.htmlMode ? htmlConfig : xmlConfig
for (var prop in defaults) config[prop] = defaults[prop]
for (var prop in config_) config[prop] = config_[prop]
// Return variables for tokenizers
var type, setStyle;
function inText(stream, state) {
function chain(parser) {
state.tokenize = parser;
return parser(stream, state);
}
var ch = stream.next();
if (ch == "<") {
if (stream.eat("!")) {
if (stream.eat("[")) {
if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
else return null;
} else if (stream.match("--")) {
return chain(inBlock("comment", "-->"));
} else if (stream.match("DOCTYPE", true, true)) {
stream.eatWhile(/[\w\._\-]/);
return chain(doctype(1));
} else {
return null;
}
} else if (stream.eat("?")) {
stream.eatWhile(/[\w\._\-]/);
state.tokenize = inBlock("meta", "?>");
return "meta";
} else {
type = stream.eat("/") ? "closeTag" : "openTag";
state.tokenize = inTag;
return "tag bracket";
}
} else if (ch == "&") {
var ok;
if (stream.eat("#")) {
if (stream.eat("x")) {
ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
} else {
ok = stream.eatWhile(/[\d]/) && stream.eat(";");
}
} else {
ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
}
return ok ? "atom" : "error";
} else {
stream.eatWhile(/[^&<]/);
return null;
}
}
inText.isInText = true;
function inTag(stream, state) {
var ch = stream.next();
if (ch == ">" || (ch == "/" && stream.eat(">"))) {
state.tokenize = inText;
type = ch == ">" ? "endTag" : "selfcloseTag";
return "tag bracket";
} else if (ch == "=") {
type = "equals";
return null;
} else if (ch == "<") {
state.tokenize = inText;
state.state = baseState;
state.tagName = state.tagStart = null;
var next = state.tokenize(stream, state);
return next ? next + " tag error" : "tag error";
} else if (/[\'\"]/.test(ch)) {
state.tokenize = inAttribute(ch);
state.stringStartCol = stream.column();
return state.tokenize(stream, state);
} else {
stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
return "word";
}
}
function inAttribute(quote) {
var closure = function(stream, state) {
while (!stream.eol()) {
if (stream.next() == quote) {
state.tokenize = inTag;
break;
}
}
return "string";
};
closure.isInAttribute = true;
return closure;
}
function inBlock(style, terminator) {
return function(stream, state) {
while (!stream.eol()) {
if (stream.match(terminator)) {
state.tokenize = inText;
break;
}
stream.next();
}
return style;
}
}
function doctype(depth) {
return function(stream, state) {
var ch;
while ((ch = stream.next()) != null) {
if (ch == "<") {
state.tokenize = doctype(depth + 1);
return state.tokenize(stream, state);
} else if (ch == ">") {
if (depth == 1) {
state.tokenize = inText;
break;
} else {
state.tokenize = doctype(depth - 1);
return state.tokenize(stream, state);
}
}
}
return "meta";
};
}
function lower(tagName) {
return tagName && tagName.toLowerCase();
}
function Context(state, tagName, startOfLine) {
this.prev = state.context;
this.tagName = tagName || "";
this.indent = state.indented;
this.startOfLine = startOfLine;
if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
this.noIndent = true;
}
function popContext(state) {
if (state.context) state.context = state.context.prev;
}
function maybePopContext(state, nextTagName) {
var parentTagName;
while (true) {
if (!state.context) {
return;
}
parentTagName = state.context.tagName;
if (!config.contextGrabbers.hasOwnProperty(lower(parentTagName)) ||
!config.contextGrabbers[lower(parentTagName)].hasOwnProperty(lower(nextTagName))) {
return;
}
popContext(state);
}
}
function baseState(type, stream, state) {
if (type == "openTag") {
state.tagStart = stream.column();
return tagNameState;
} else if (type == "closeTag") {
return closeTagNameState;
} else {
return baseState;
}
}
function tagNameState(type, stream, state) {
if (type == "word") {
state.tagName = stream.current();
setStyle = "tag";
return attrState;
} else if (config.allowMissingTagName && type == "endTag") {
setStyle = "tag bracket";
return attrState(type, stream, state);
} else {
setStyle = "error";
return tagNameState;
}
}
function closeTagNameState(type, stream, state) {
if (type == "word") {
var tagName = stream.current();
if (state.context && state.context.tagName != tagName &&
config.implicitlyClosed.hasOwnProperty(lower(state.context.tagName)))
popContext(state);
if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
setStyle = "tag";
return closeState;
} else {
setStyle = "tag error";
return closeStateErr;
}
} else if (config.allowMissingTagName && type == "endTag") {
setStyle = "tag bracket";
return closeState(type, stream, state);
} else {
setStyle = "error";
return closeStateErr;
}
}
function closeState(type, _stream, state) {
if (type != "endTag") {
setStyle = "error";
return closeState;
}
popContext(state);
return baseState;
}
function closeStateErr(type, stream, state) {
setStyle = "error";
return closeState(type, stream, state);
}
function attrState(type, _stream, state) {
if (type == "word") {
setStyle = "attribute";
return attrEqState;
} else if (type == "endTag" || type == "selfcloseTag") {
var tagName = state.tagName, tagStart = state.tagStart;
state.tagName = state.tagStart = null;
if (type == "selfcloseTag" ||
config.autoSelfClosers.hasOwnProperty(lower(tagName))) {
maybePopContext(state, tagName);
} else {
maybePopContext(state, tagName);
state.context = new Context(state, tagName, tagStart == state.indented);
}
return baseState;
}
setStyle = "error";
return attrState;
}
function attrEqState(type, stream, state) {
if (type == "equals") return attrValueState;
if (!config.allowMissing) setStyle = "error";
return attrState(type, stream, state);
}
function attrValueState(type, stream, state) {
if (type == "string") return attrContinuedState;
if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
setStyle = "error";
return attrState(type, stream, state);
}
function attrContinuedState(type, stream, state) {
if (type == "string") return attrContinuedState;
return attrState(type, stream, state);
}
return {
startState: function(baseIndent) {
var state = {tokenize: inText,
state: baseState,
indented: baseIndent || 0,
tagName: null, tagStart: null,
context: null}
if (baseIndent != null) state.baseIndent = baseIndent
return state
},
token: function(stream, state) {
if (!state.tagName && stream.sol())
state.indented = stream.indentation();
if (stream.eatSpace()) return null;
type = null;
var style = state.tokenize(stream, state);
if ((style || type) && style != "comment") {
setStyle = null;
state.state = state.state(type || style, stream, state);
if (setStyle)
style = setStyle == "error" ? style + " error" : setStyle;
}
return style;
},
indent: function(state, textAfter, fullLine) {
var context = state.context;
// Indent multi-line strings (e.g. css).
if (state.tokenize.isInAttribute) {
if (state.tagStart == state.indented)
return state.stringStartCol + 1;
else
return state.indented + indentUnit;
}
if (context && context.noIndent) return CodeMirror.Pass;
if (state.tokenize != inTag && state.tokenize != inText)
return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
// Indent the starts of attribute names.
if (state.tagName) {
if (config.multilineTagIndentPastTag !== false)
return state.tagStart + state.tagName.length + 2;
else
return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
}
if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
if (tagAfter && tagAfter[1]) { // Closing tag spotted
while (context) {
if (context.tagName == tagAfter[2]) {
context = context.prev;
break;
} else if (config.implicitlyClosed.hasOwnProperty(lower(context.tagName))) {
context = context.prev;
} else {
break;
}
}
} else if (tagAfter) { // Opening tag spotted
while (context) {
var grabbers = config.contextGrabbers[lower(context.tagName)];
if (grabbers && grabbers.hasOwnProperty(lower(tagAfter[2])))
context = context.prev;
else
break;
}
}
while (context && context.prev && !context.startOfLine)
context = context.prev;
if (context) return context.indent + indentUnit;
else return state.baseIndent || 0;
},
electricInput: /<\/[\s\w:]+>$/,
blockCommentStart: "<!--",
blockCommentEnd: "-->",
configuration: config.htmlMode ? "html" : "xml",
helperType: config.htmlMode ? "html" : "xml",
skipAttribute: function(state) {
if (state.state == attrValueState)
state.state = attrState
},
xmlCurrentTag: function(state) {
return state.tagName ? {name: state.tagName, close: state.type == "closeTag"} : null
},
xmlCurrentContext: function(state) {
var context = []
for (var cx = state.context; cx; cx = cx.prev)
context.push(cx.tagName)
return context.reverse()
}
};
});
CodeMirror.defineMIME("text/xml", "xml");
CodeMirror.defineMIME("application/xml", "xml");
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
});

120
js/mode/yaml.js Normal file
View File

@ -0,0 +1,120 @@
// 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("yaml", function() {
var cons = ['true', 'false', 'on', 'off', 'yes', 'no'];
var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i');
return {
token: function(stream, state) {
var ch = stream.peek();
var esc = state.escaped;
state.escaped = false;
/* comments */
if (ch == "#" && (stream.pos == 0 || /\s/.test(stream.string.charAt(stream.pos - 1)))) {
stream.skipToEnd();
return "comment";
}
if (stream.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))
return "string";
if (state.literal && stream.indentation() > state.keyCol) {
stream.skipToEnd(); return "string";
} else if (state.literal) { state.literal = false; }
if (stream.sol()) {
state.keyCol = 0;
state.pair = false;
state.pairStart = false;
/* document start */
if(stream.match('---')) { return "def"; }
/* document end */
if (stream.match('...')) { return "def"; }
/* array list item */
if (stream.match(/\s*-\s+/)) { return 'meta'; }
}
/* inline pairs/lists */
if (stream.match(/^(\{|\}|\[|\])/)) {
if (ch == '{')
state.inlinePairs++;
else if (ch == '}')
state.inlinePairs--;
else if (ch == '[')
state.inlineList++;
else
state.inlineList--;
return 'meta';
}
/* list separator */
if (state.inlineList > 0 && !esc && ch == ',') {
stream.next();
return 'meta';
}
/* pairs separator */
if (state.inlinePairs > 0 && !esc && ch == ',') {
state.keyCol = 0;
state.pair = false;
state.pairStart = false;
stream.next();
return 'meta';
}
/* start of value of a pair */
if (state.pairStart) {
/* block literals */
if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; };
/* references */
if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; }
/* numbers */
if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; }
if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; }
/* keywords */
if (stream.match(keywordRegex)) { return 'keyword'; }
}
/* pairs (associative arrays) -> key */
if (!state.pair && stream.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)) {
state.pair = true;
state.keyCol = stream.indentation();
return "atom";
}
if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; }
/* nothing found, continue */
state.pairStart = false;
state.escaped = (ch == '\\');
stream.next();
return null;
},
startState: function() {
return {
pair: false,
pairStart: false,
keyCol: 0,
inlinePairs: 0,
inlineList: 0,
literal: false,
escaped: false
};
},
lineComment: "#",
fold: "indent"
};
});
CodeMirror.defineMIME("text/x-yaml", "yaml");
CodeMirror.defineMIME("text/yaml", "yaml");
});

8
js/multiplex.min.js vendored Normal file
View File

@ -0,0 +1,8 @@
/**
* Minified by jsDelivr using Terser v5.19.2.
* Original file: /npm/codemirror@5.65.5/addon/mode/multiplex.js
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}((function(e){"use strict";e.multiplexingMode=function(n){var t=Array.prototype.slice.call(arguments,1);function r(e,n,t,r){if("string"==typeof n){var i=e.indexOf(n,t);return r&&i>-1?i+n.length:i}var o=n.exec(t?e.slice(t):e);return o?o.index+t+(r?o[0].length:0):-1}return{startState:function(){return{outer:e.startState(n),innerActive:null,inner:null,startingInner:!1}},copyState:function(t){return{outer:e.copyState(n,t.outer),innerActive:t.innerActive,inner:t.innerActive&&e.copyState(t.innerActive.mode,t.inner),startingInner:t.startingInner}},token:function(i,o){if(o.innerActive){var l=o.innerActive;a=i.string;if(!l.close&&i.sol())return o.innerActive=o.inner=null,this.token(i,o);if((v=l.close&&!o.startingInner?r(a,l.close,i.pos,l.parseDelimiters):-1)==i.pos&&!l.parseDelimiters)return i.match(l.close),o.innerActive=o.inner=null,l.delimStyle&&l.delimStyle+" "+l.delimStyle+"-close";v>-1&&(i.string=a.slice(0,v));var c=l.mode.token(i,o.inner);return v>-1?i.string=a:i.pos>i.start&&(o.startingInner=!1),v==i.pos&&l.parseDelimiters&&(o.innerActive=o.inner=null),l.innerStyle&&(c=c?c+" "+l.innerStyle:l.innerStyle),c}for(var s=1/0,a=i.string,u=0;u<t.length;++u){var v,d=t[u];if((v=r(a,d.open,i.pos))==i.pos){d.parseDelimiters||i.match(d.open),o.startingInner=!!d.parseDelimiters,o.innerActive=d;var f=0;if(n.indent){var m=n.indent(o.outer,"","");m!==e.Pass&&(f=m)}return o.inner=e.startState(d.mode,f),d.delimStyle&&d.delimStyle+" "+d.delimStyle+"-open"}-1!=v&&v<s&&(s=v)}s!=1/0&&(i.string=a.slice(0,s));var p=n.token(i,o.outer);return s!=1/0&&(i.string=a),p},indent:function(t,r,i){var o=t.innerActive?t.innerActive.mode:n;return o.indent?o.indent(t.innerActive?t.inner:t.outer,r,i):e.Pass},blankLine:function(r){var i=r.innerActive?r.innerActive.mode:n;if(i.blankLine&&i.blankLine(r.innerActive?r.inner:r.outer),r.innerActive)"\n"===r.innerActive.close&&(r.innerActive=r.inner=null);else for(var o=0;o<t.length;++o){var l=t[o];"\n"===l.open&&(r.innerActive=l,r.inner=e.startState(l.mode,i.indent?i.indent(r.outer,"",""):0))}},electricChars:n.electricChars,innerMode:function(e){return e.inner?{state:e.inner,mode:e.innerActive.mode}:{state:e.outer,mode:n}}}}}));
//# sourceMappingURL=/sm/872b30a8ff5d431cf47634b04e1f220f77066ccedc6cdebd46a0c10ef0fd9612.map

8
js/overlay.min.js vendored Normal file
View File

@ -0,0 +1,8 @@
/**
* Minified by jsDelivr using Terser v5.19.2.
* Original file: /npm/codemirror@5.65.5/addon/mode/overlay.js
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}((function(e){"use strict";e.overlayMode=function(o,r,a){return{startState:function(){return{base:e.startState(o),overlay:e.startState(r),basePos:0,baseCur:null,overlayPos:0,overlayCur:null,streamSeen:null}},copyState:function(a){return{base:e.copyState(o,a.base),overlay:e.copyState(r,a.overlay),basePos:a.basePos,baseCur:null,overlayPos:a.overlayPos,overlayCur:null}},token:function(e,n){return(e!=n.streamSeen||Math.min(n.basePos,n.overlayPos)<e.start)&&(n.streamSeen=e,n.basePos=n.overlayPos=e.start),e.start==n.basePos&&(n.baseCur=o.token(e,n.base),n.basePos=e.pos),e.start==n.overlayPos&&(e.pos=e.start,n.overlayCur=r.token(e,n.overlay),n.overlayPos=e.pos),e.pos=Math.min(n.basePos,n.overlayPos),null==n.overlayCur?n.baseCur:null!=n.baseCur&&n.overlay.combineTokens||a&&null==n.overlay.combineTokens?n.baseCur+" "+n.overlayCur:n.overlayCur},indent:o.indent&&function(e,r,a){return o.indent(e.base,r,a)},electricChars:o.electricChars,innerMode:function(e){return{state:e.base,mode:o}},blankLine:function(e){var n,t;return o.blankLine&&(n=o.blankLine(e.base)),r.blankLine&&(t=r.blankLine(e.overlay)),null==t?n:a&&null!=n?n+" "+t:t}}}}));
//# sourceMappingURL=/sm/87cdc3c2f083d42918850d81a0b216a046fa157ea29c1273e6f8218eac93726d.map

8
js/simple.min.js vendored Normal file
View File

@ -0,0 +1,8 @@
/**
* Minified by jsDelivr using Terser v5.19.2.
* Original file: /npm/codemirror@5.65.5/addon/mode/simple.js
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}((function(e){"use strict";function t(e,t){if(!e.hasOwnProperty(t))throw new Error("Undefined state "+t+" in simple mode")}function n(e,t){if(!e)return/(?:)/;var n="";return e instanceof RegExp?(e.ignoreCase&&(n="i"),e.unicode&&(n+="u"),e=e.source):e=String(e),new RegExp((!1===t?"":"^")+"(?:"+e+")",n)}function a(e,a){(e.next||e.push)&&t(a,e.next||e.push),this.regex=n(e.regex),this.token=function(e){if(!e)return null;if(e.apply)return e;if("string"==typeof e)return e.replace(/\./g," ");for(var t=[],n=0;n<e.length;n++)t.push(e[n]&&e[n].replace(/\./g," "));return t}(e.token),this.data=e}function r(e,t){return function(n,a){if(a.pending){var r=a.pending.shift();return 0==a.pending.length&&(a.pending=null),n.pos+=r.text.length,r.token}if(a.local){if(a.local.end&&n.match(a.local.end)){var o=a.local.endToken||null;return a.local=a.localState=null,o}var l;o=a.local.mode.token(n,a.localState);return a.local.endScan&&(l=a.local.endScan.exec(n.current()))&&(n.pos=n.start+l.index),o}for(var s=e[a.state],d=0;d<s.length;d++){var c=s[d],u=(!c.data.sol||n.sol())&&n.match(c.regex);if(u){c.data.next?a.state=c.data.next:c.data.push?((a.stack||(a.stack=[])).push(a.state),a.state=c.data.push):c.data.pop&&a.stack&&a.stack.length&&(a.state=a.stack.pop()),c.data.mode&&i(t,a,c.data.mode,c.token),c.data.indent&&a.indent.push(n.indentation()+t.indentUnit),c.data.dedent&&a.indent.pop();var p=c.token;if(p&&p.apply&&(p=p(u)),u.length>2&&c.token&&"string"!=typeof c.token){for(var f=2;f<u.length;f++)u[f]&&(a.pending||(a.pending=[])).push({text:u[f],token:c.token[f-1]});return n.backUp(u[0].length-(u[1]?u[1].length:0)),p[0]}return p&&p.join?p[0]:p}}return n.next(),null}}function o(e,t){if(e===t)return!0;if(!e||"object"!=typeof e||!t||"object"!=typeof t)return!1;var n=0;for(var a in e)if(e.hasOwnProperty(a)){if(!t.hasOwnProperty(a)||!o(e[a],t[a]))return!1;n++}for(var a in t)t.hasOwnProperty(a)&&n--;return 0==n}function i(t,a,r,i){var l;if(r.persistent)for(var s=a.persistentStates;s&&!l;s=s.next)(r.spec?o(r.spec,s.spec):r.mode==s.mode)&&(l=s);var d=l?l.mode:r.mode||e.getMode(t,r.spec),c=l?l.state:e.startState(d);r.persistent&&!l&&(a.persistentStates={mode:d,spec:r.spec,state:c,next:a.persistentStates}),a.localState=c,a.local={mode:d,end:r.end&&n(r.end),endScan:r.end&&!1!==r.forceEnd&&n(r.end,!1),endToken:i&&i.join?i[i.length-1]:i}}function l(t,n){return function(a,r,o){if(a.local&&a.local.mode.indent)return a.local.mode.indent(a.localState,r,o);if(null==a.indent||a.local||n.dontIndentStates&&function(e,t){for(var n=0;n<t.length;n++)if(t[n]===e)return!0}(a.state,n.dontIndentStates)>-1)return e.Pass;var i=a.indent.length-1,l=t[a.state];e:for(;;){for(var s=0;s<l.length;s++){var d=l[s];if(d.data.dedent&&!1!==d.data.dedentIfLineStart){var c=d.regex.exec(r);if(c&&c[0]){i--,(d.next||d.push)&&(l=t[d.next||d.push]),r=r.slice(c[0].length);continue e}}}break}return i<0?0:a.indent[i]}}e.defineSimpleMode=function(t,n){e.defineMode(t,(function(t){return e.simpleMode(t,n)}))},e.simpleMode=function(n,o){t(o,"start");var i={},s=o.meta||{},d=!1;for(var c in o)if(c!=s&&o.hasOwnProperty(c))for(var u=i[c]=[],p=o[c],f=0;f<p.length;f++){var h=p[f];u.push(new a(h,o)),(h.indent||h.dedent)&&(d=!0)}var g={startState:function(){return{state:"start",pending:null,local:null,localState:null,indent:d?[]:null}},copyState:function(t){var n={state:t.state,pending:t.pending,local:t.local,localState:null,indent:t.indent&&t.indent.slice(0)};t.localState&&(n.localState=e.copyState(t.local.mode,t.localState)),t.stack&&(n.stack=t.stack.slice(0));for(var a=t.persistentStates;a;a=a.next)n.persistentStates={mode:a.mode,spec:a.spec,state:a.state==t.localState?n.localState:e.copyState(a.mode,a.state),next:n.persistentStates};return n},token:r(i,n),innerMode:function(e){return e.local&&{mode:e.local.mode,state:e.localState}},indent:l(i,s)};if(s)for(var S in s)s.hasOwnProperty(S)&&(g[S]=s[S]);return g}}));
//# sourceMappingURL=/sm/f44a26a703e8cb7377e6a22ba23fa07309589ec7da4afccb66654a770d492c5d.map

152
js/simplescrollbars.js Normal file
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"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function Bar(cls, orientation, scroll) {
this.orientation = orientation;
this.scroll = scroll;
this.screen = this.total = this.size = 1;
this.pos = 0;
this.node = document.createElement("div");
this.node.className = cls + "-" + orientation;
this.inner = this.node.appendChild(document.createElement("div"));
var self = this;
CodeMirror.on(this.inner, "mousedown", function(e) {
if (e.which != 1) return;
CodeMirror.e_preventDefault(e);
var axis = self.orientation == "horizontal" ? "pageX" : "pageY";
var start = e[axis], startpos = self.pos;
function done() {
CodeMirror.off(document, "mousemove", move);
CodeMirror.off(document, "mouseup", done);
}
function move(e) {
if (e.which != 1) return done();
self.moveTo(startpos + (e[axis] - start) * (self.total / self.size));
}
CodeMirror.on(document, "mousemove", move);
CodeMirror.on(document, "mouseup", done);
});
CodeMirror.on(this.node, "click", function(e) {
CodeMirror.e_preventDefault(e);
var innerBox = self.inner.getBoundingClientRect(), where;
if (self.orientation == "horizontal")
where = e.clientX < innerBox.left ? -1 : e.clientX > innerBox.right ? 1 : 0;
else
where = e.clientY < innerBox.top ? -1 : e.clientY > innerBox.bottom ? 1 : 0;
self.moveTo(self.pos + where * self.screen);
});
function onWheel(e) {
var moved = CodeMirror.wheelEventPixels(e)[self.orientation == "horizontal" ? "x" : "y"];
var oldPos = self.pos;
self.moveTo(self.pos + moved);
if (self.pos != oldPos) CodeMirror.e_preventDefault(e);
}
CodeMirror.on(this.node, "mousewheel", onWheel);
CodeMirror.on(this.node, "DOMMouseScroll", onWheel);
}
Bar.prototype.setPos = function(pos, force) {
if (pos < 0) pos = 0;
if (pos > this.total - this.screen) pos = this.total - this.screen;
if (!force && pos == this.pos) return false;
this.pos = pos;
this.inner.style[this.orientation == "horizontal" ? "left" : "top"] =
(pos * (this.size / this.total)) + "px";
return true
};
Bar.prototype.moveTo = function(pos) {
if (this.setPos(pos)) this.scroll(pos, this.orientation);
}
var minButtonSize = 10;
Bar.prototype.update = function(scrollSize, clientSize, barSize) {
var sizeChanged = this.screen != clientSize || this.total != scrollSize || this.size != barSize
if (sizeChanged) {
this.screen = clientSize;
this.total = scrollSize;
this.size = barSize;
}
var buttonSize = this.screen * (this.size / this.total);
if (buttonSize < minButtonSize) {
this.size -= minButtonSize - buttonSize;
buttonSize = minButtonSize;
}
this.inner.style[this.orientation == "horizontal" ? "width" : "height"] =
buttonSize + "px";
this.setPos(this.pos, sizeChanged);
};
function SimpleScrollbars(cls, place, scroll) {
this.addClass = cls;
this.horiz = new Bar(cls, "horizontal", scroll);
place(this.horiz.node);
this.vert = new Bar(cls, "vertical", scroll);
place(this.vert.node);
this.width = null;
}
SimpleScrollbars.prototype.update = function(measure) {
if (this.width == null) {
var style = window.getComputedStyle ? window.getComputedStyle(this.horiz.node) : this.horiz.node.currentStyle;
if (style) this.width = parseInt(style.height);
}
var width = this.width || 0;
var needsH = measure.scrollWidth > measure.clientWidth + 1;
var needsV = measure.scrollHeight > measure.clientHeight + 1;
this.vert.node.style.display = needsV ? "block" : "none";
this.horiz.node.style.display = needsH ? "block" : "none";
if (needsV) {
this.vert.update(measure.scrollHeight, measure.clientHeight,
measure.viewHeight - (needsH ? width : 0));
this.vert.node.style.bottom = needsH ? width + "px" : "0";
}
if (needsH) {
this.horiz.update(measure.scrollWidth, measure.clientWidth,
measure.viewWidth - (needsV ? width : 0) - measure.barLeft);
this.horiz.node.style.right = needsV ? width + "px" : "0";
this.horiz.node.style.left = measure.barLeft + "px";
}
return {right: needsV ? width : 0, bottom: needsH ? width : 0};
};
SimpleScrollbars.prototype.setScrollTop = function(pos) {
this.vert.setPos(pos);
};
SimpleScrollbars.prototype.setScrollLeft = function(pos) {
this.horiz.setPos(pos);
};
SimpleScrollbars.prototype.clear = function() {
var parent = this.horiz.node.parentNode;
parent.removeChild(this.horiz.node);
parent.removeChild(this.vert.node);
};
CodeMirror.scrollbarModel.simple = function(place, scroll) {
return new SimpleScrollbars("CodeMirror-simplescroll", place, scroll);
};
CodeMirror.scrollbarModel.overlay = function(place, scroll) {
return new SimpleScrollbars("CodeMirror-overlayscroll", place, scroll);
};
});

1
js/slimselect.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
const blob = new Blob(['importScripts("https://cdn.jsdelivr.net/npm/lzma@2.3.2/src/lzma_worker.min.js");']);
const blob = new Blob(['importScripts("js/lzma_worker.min.js");']);
const lzma = new LZMA(window.URL.createObjectURL(blob));
let editor = null;
@ -16,7 +16,7 @@ const init = () => {
};
const initCodeEditor = () => {
CodeMirror.modeURL = 'https://cdn.jsdelivr.net/npm/codemirror@5.65.5/mode/%N/%N.js';
CodeMirror.modeURL = 'js/mode/%N.js';
editor = new CodeMirror(byId('editor'), {
lineNumbers: true,
theme: 'dracula',

View File

@ -174,8 +174,8 @@ button:hover {
/* Fonts */
@font-face {
font-family: 'JetBrainsMono';
src: url('https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono@2.242/fonts/webfonts/JetBrainsMono-Regular.woff2') format('woff2'),
url('https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono@2.242/fonts/ttf/JetBrainsMonoNL-Regular.ttf') format('truetype');
/* https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono@2.242/fonts/webfonts/JetBrainsMono-Regular.woff2 */
src: url('fonts/JetBrainsMono-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
}
@ -185,7 +185,8 @@ button:hover {
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v20/KFOmCnqEu92Fr1Mu4mxK.woff2) format('woff2');
/* https://fonts.gstatic.com/s/roboto/v20/KFOmCnqEu92Fr1Mu4mxK.woff2 */
src: local('Roboto'), local('Roboto-Regular'), url('fonts/roboto-v20.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

47
sw.js
View File

@ -3,7 +3,7 @@ const PRECACHE = 'precache-' + VERSION;
const MODES = 'modes-' + VERSION;
// A regexp to detect mode files
const MODE_REGEXP = /^https:\/\/cdn\.jsdelivr.net\/npm\/codemirror@.+?\/mode\//;
const MODE_REGEXP = /^js\/mode\//;
// A list of local resources we always want to be cached.
const PRECACHE_URLS = [
@ -11,29 +11,26 @@ const PRECACHE_URLS = [
'script.js',
'style.css',
'favicon.ico',
'https://cdn.jsdelivr.net/npm/lzma@2.3.2/src/lzma_worker.min.js',
'https://cdn.jsdelivr.net/combine/' +
'npm/lzma@2.3.2/src/lzma.min.js,' +
'npm/slim-select@1.27.1/dist/slimselect.min.js,' +
'npm/clipboard@2.0.11/dist/clipboard.min.js,' +
'npm/micromodal@0.4.10/dist/micromodal.min.js,' +
'npm/codemirror@5.65.5,' +
'npm/codemirror@5.65.5/addon/mode/loadmode.min.js,' +
'npm/codemirror@5.65.5/addon/mode/overlay.min.js,' +
'npm/codemirror@5.65.5/addon/mode/multiplex.min.js,' +
'npm/codemirror@5.65.5/addon/mode/simple.min.js,' +
'npm/codemirror@5.65.5/addon/scroll/simplescrollbars.js,' +
'npm/codemirror@5.65.5/mode/meta.min.js',
'https://cdn.jsdelivr.net/combine/' +
'npm/bootstrap@4.6.1/dist/css/bootstrap-grid.min.css,' +
'npm/slim-select@1.27.1/dist/slimselect.min.css,' +
'npm/codemirror@5.65.5/lib/codemirror.min.css,' +
'npm/codemirror@5.65.5/addon/scroll/simplescrollbars.css,' +
'npm/codemirror@5.65.5/theme/dracula.min.css,' +
'npm/microtip@0.2.2/microtip.min.css',
'https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono@2.242/fonts/webfonts/JetBrainsMono-Regular.woff2',
'https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono@2.242/fonts/ttf/JetBrainsMonoNL-Regular.ttf',
'https://fonts.gstatic.com/s/roboto/v20/KFOmCnqEu92Fr1Mu4mxK.woff2',
'js/lzma_worker.min.js',
'js/lzma.min.js',
'js/slimselect.min.js',
'js/clipboard.min.js',
'js/micromodal.min.js',
'js/codemirror.min.js',
'js/loadmode.min.js',
'js/overlay.min.js',
'js/multiplex.min.js',
'js/simple.min.js',
'js/simplescrollbars.js',
'js/meta.min.js',
'css/bootstrap-grid.min.css',
'css/slimselect.min.css',
'css/codemirror.min.css',
'css/simplescrollbars.css',
'css/dracula.min.css',
'css/microtip.min.css',
'fonts/JetBrainsMono-Regular.woff2',
'fonts/roboto-v20.woff2',
];
// The install handler takes care of precaching the resources we always need.
@ -70,7 +67,7 @@ self.addEventListener('activate', (event) => {
// If no response is found, it populates the runtime cache with the response
// from the network before returning it to the page.
self.addEventListener('fetch', (event) => {
if (!event.request.url.startsWith(self.location.origin) && !event.request.url.startsWith('https://cdn.jsdelivr.net')) {
if (!event.request.url.startsWith(self.location.origin)) {
return;
}
event.respondWith(