mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-27 01:36:20 +00:00
96d4a3ecf7
Due to historical reasons, the code is in subfolder "1". With SVN removal, we place the code back and remove the annoying "1" folder.
222 lines
6.3 KiB
JavaScript
222 lines
6.3 KiB
JavaScript
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
|
|
|
/**
|
|
* Smarty 2 and 3 mode.
|
|
*/
|
|
|
|
(function(mod) {
|
|
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
mod(require("../../lib/codemirror"));
|
|
else if (typeof define == "function" && define.amd) // AMD
|
|
define(["../../lib/codemirror"], mod);
|
|
else // Plain browser env
|
|
mod(CodeMirror);
|
|
})(function(CodeMirror) {
|
|
"use strict";
|
|
|
|
CodeMirror.defineMode("smarty", function(config) {
|
|
"use strict";
|
|
|
|
// our default settings; check to see if they're overridden
|
|
var settings = {
|
|
rightDelimiter: '}',
|
|
leftDelimiter: '{',
|
|
smartyVersion: 2 // for backward compatibility
|
|
};
|
|
if (config.hasOwnProperty("leftDelimiter")) {
|
|
settings.leftDelimiter = config.leftDelimiter;
|
|
}
|
|
if (config.hasOwnProperty("rightDelimiter")) {
|
|
settings.rightDelimiter = config.rightDelimiter;
|
|
}
|
|
if (config.hasOwnProperty("smartyVersion") && config.smartyVersion === 3) {
|
|
settings.smartyVersion = 3;
|
|
}
|
|
|
|
var keyFunctions = ["debug", "extends", "function", "include", "literal"];
|
|
var last;
|
|
var regs = {
|
|
operatorChars: /[+\-*&%=<>!?]/,
|
|
validIdentifier: /[a-zA-Z0-9_]/,
|
|
stringChar: /['"]/
|
|
};
|
|
|
|
var helpers = {
|
|
cont: function(style, lastType) {
|
|
last = lastType;
|
|
return style;
|
|
},
|
|
chain: function(stream, state, parser) {
|
|
state.tokenize = parser;
|
|
return parser(stream, state);
|
|
}
|
|
};
|
|
|
|
|
|
// our various parsers
|
|
var parsers = {
|
|
|
|
// the main tokenizer
|
|
tokenizer: function(stream, state) {
|
|
if (stream.match(settings.leftDelimiter, true)) {
|
|
if (stream.eat("*")) {
|
|
return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
|
|
} else {
|
|
// Smarty 3 allows { and } surrounded by whitespace to NOT slip into Smarty mode
|
|
state.depth++;
|
|
var isEol = stream.eol();
|
|
var isFollowedByWhitespace = /\s/.test(stream.peek());
|
|
if (settings.smartyVersion === 3 && settings.leftDelimiter === "{" && (isEol || isFollowedByWhitespace)) {
|
|
state.depth--;
|
|
return null;
|
|
} else {
|
|
state.tokenize = parsers.smarty;
|
|
last = "startTag";
|
|
return "tag";
|
|
}
|
|
}
|
|
} else {
|
|
stream.next();
|
|
return null;
|
|
}
|
|
},
|
|
|
|
// parsing Smarty content
|
|
smarty: function(stream, state) {
|
|
if (stream.match(settings.rightDelimiter, true)) {
|
|
if (settings.smartyVersion === 3) {
|
|
state.depth--;
|
|
if (state.depth <= 0) {
|
|
state.tokenize = parsers.tokenizer;
|
|
}
|
|
} else {
|
|
state.tokenize = parsers.tokenizer;
|
|
}
|
|
return helpers.cont("tag", null);
|
|
}
|
|
|
|
if (stream.match(settings.leftDelimiter, true)) {
|
|
state.depth++;
|
|
return helpers.cont("tag", "startTag");
|
|
}
|
|
|
|
var ch = stream.next();
|
|
if (ch == "$") {
|
|
stream.eatWhile(regs.validIdentifier);
|
|
return helpers.cont("variable-2", "variable");
|
|
} else if (ch == "|") {
|
|
return helpers.cont("operator", "pipe");
|
|
} else if (ch == ".") {
|
|
return helpers.cont("operator", "property");
|
|
} else if (regs.stringChar.test(ch)) {
|
|
state.tokenize = parsers.inAttribute(ch);
|
|
return helpers.cont("string", "string");
|
|
} else if (regs.operatorChars.test(ch)) {
|
|
stream.eatWhile(regs.operatorChars);
|
|
return helpers.cont("operator", "operator");
|
|
} else if (ch == "[" || ch == "]") {
|
|
return helpers.cont("bracket", "bracket");
|
|
} else if (ch == "(" || ch == ")") {
|
|
return helpers.cont("bracket", "operator");
|
|
} else if (/\d/.test(ch)) {
|
|
stream.eatWhile(/\d/);
|
|
return helpers.cont("number", "number");
|
|
} else {
|
|
|
|
if (state.last == "variable") {
|
|
if (ch == "@") {
|
|
stream.eatWhile(regs.validIdentifier);
|
|
return helpers.cont("property", "property");
|
|
} else if (ch == "|") {
|
|
stream.eatWhile(regs.validIdentifier);
|
|
return helpers.cont("qualifier", "modifier");
|
|
}
|
|
} else if (state.last == "pipe") {
|
|
stream.eatWhile(regs.validIdentifier);
|
|
return helpers.cont("qualifier", "modifier");
|
|
} else if (state.last == "whitespace") {
|
|
stream.eatWhile(regs.validIdentifier);
|
|
return helpers.cont("attribute", "modifier");
|
|
} if (state.last == "property") {
|
|
stream.eatWhile(regs.validIdentifier);
|
|
return helpers.cont("property", null);
|
|
} else if (/\s/.test(ch)) {
|
|
last = "whitespace";
|
|
return null;
|
|
}
|
|
|
|
var str = "";
|
|
if (ch != "/") {
|
|
str += ch;
|
|
}
|
|
var c = null;
|
|
while (c = stream.eat(regs.validIdentifier)) {
|
|
str += c;
|
|
}
|
|
for (var i=0, j=keyFunctions.length; i<j; i++) {
|
|
if (keyFunctions[i] == str) {
|
|
return helpers.cont("keyword", "keyword");
|
|
}
|
|
}
|
|
if (/\s/.test(ch)) {
|
|
return null;
|
|
}
|
|
return helpers.cont("tag", "tag");
|
|
}
|
|
},
|
|
|
|
inAttribute: function(quote) {
|
|
return function(stream, state) {
|
|
var prevChar = null;
|
|
var currChar = null;
|
|
while (!stream.eol()) {
|
|
currChar = stream.peek();
|
|
if (stream.next() == quote && prevChar !== '\\') {
|
|
state.tokenize = parsers.smarty;
|
|
break;
|
|
}
|
|
prevChar = currChar;
|
|
}
|
|
return "string";
|
|
};
|
|
},
|
|
|
|
inBlock: function(style, terminator) {
|
|
return function(stream, state) {
|
|
while (!stream.eol()) {
|
|
if (stream.match(terminator)) {
|
|
state.tokenize = parsers.tokenizer;
|
|
break;
|
|
}
|
|
stream.next();
|
|
}
|
|
return style;
|
|
};
|
|
}
|
|
};
|
|
|
|
|
|
// the public API for CodeMirror
|
|
return {
|
|
startState: function() {
|
|
return {
|
|
tokenize: parsers.tokenizer,
|
|
mode: "smarty",
|
|
last: null,
|
|
depth: 0
|
|
};
|
|
},
|
|
token: function(stream, state) {
|
|
var style = state.tokenize(stream, state);
|
|
state.last = last;
|
|
return style;
|
|
},
|
|
electricChars: ""
|
|
};
|
|
});
|
|
|
|
CodeMirror.defineMIME("text/x-smarty", "smarty");
|
|
|
|
});
|