123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- CodeMirror.defineMode("smarty", function(config) {
- var keyFuncs = ["debug", "extends", "function", "include", "literal"];
- var last;
- var regs = {
- operatorChars: /[+\-*&%=<>!?]/,
- validIdentifier: /[a-zA-Z0-9\_]/,
- stringChar: /[\'\"]/
- };
- var leftDelim = (typeof config.mode.leftDelimiter != 'undefined') ? config.mode.leftDelimiter : "{";
- var rightDelim = (typeof config.mode.rightDelimiter != 'undefined') ? config.mode.rightDelimiter : "}";
- function ret(style, lst) { last = lst; return style; }
- function tokenizer(stream, state) {
- function chain(parser) {
- state.tokenize = parser;
- return parser(stream, state);
- }
- if (stream.match(leftDelim, true)) {
- if (stream.eat("*")) {
- return chain(inBlock("comment", "*" + rightDelim));
- }
- else {
- state.tokenize = inSmarty;
- return "tag";
- }
- }
- else {
- // I'd like to do an eatWhile() here, but I can't get it to eat only up to the rightDelim string/char
- stream.next();
- return null;
- }
- }
- function inSmarty(stream, state) {
- if (stream.match(rightDelim, true)) {
- state.tokenize = tokenizer;
- return ret("tag", null);
- }
- var ch = stream.next();
- if (ch == "$") {
- stream.eatWhile(regs.validIdentifier);
- return ret("variable-2", "variable");
- }
- else if (ch == ".") {
- return ret("operator", "property");
- }
- else if (regs.stringChar.test(ch)) {
- state.tokenize = inAttribute(ch);
- return ret("string", "string");
- }
- else if (regs.operatorChars.test(ch)) {
- stream.eatWhile(regs.operatorChars);
- return ret("operator", "operator");
- }
- else if (ch == "[" || ch == "]") {
- return ret("bracket", "bracket");
- }
- else if (/\d/.test(ch)) {
- stream.eatWhile(/\d/);
- return ret("number", "number");
- }
- else {
- if (state.last == "variable") {
- if (ch == "@") {
- stream.eatWhile(regs.validIdentifier);
- return ret("property", "property");
- }
- else if (ch == "|") {
- stream.eatWhile(regs.validIdentifier);
- return ret("qualifier", "modifier");
- }
- }
- else if (state.last == "whitespace") {
- stream.eatWhile(regs.validIdentifier);
- return ret("attribute", "modifier");
- }
- else if (state.last == "property") {
- stream.eatWhile(regs.validIdentifier);
- return ret("property", null);
- }
- else if (/\s/.test(ch)) {
- last = "whitespace";
- return null;
- }
- var str = "";
- if (ch != "/") {
- str += ch;
- }
- var c = "";
- while ((c = stream.eat(regs.validIdentifier))) {
- str += c;
- }
- var i, j;
- for (i=0, j=keyFuncs.length; i<j; i++) {
- if (keyFuncs[i] == str) {
- return ret("keyword", "keyword");
- }
- }
- if (/\s/.test(ch)) {
- return null;
- }
- return ret("tag", "tag");
- }
- }
- function inAttribute(quote) {
- return function(stream, state) {
- while (!stream.eol()) {
- if (stream.next() == quote) {
- state.tokenize = inSmarty;
- break;
- }
- }
- return "string";
- };
- }
- function inBlock(style, terminator) {
- return function(stream, state) {
- while (!stream.eol()) {
- if (stream.match(terminator)) {
- state.tokenize = tokenizer;
- break;
- }
- stream.next();
- }
- return style;
- };
- }
- return {
- startState: function() {
- return { tokenize: tokenizer, mode: "smarty", last: null };
- },
- token: function(stream, state) {
- var style = state.tokenize(stream, state);
- state.last = last;
- return style;
- },
- electricChars: ""
- };
- });
- CodeMirror.defineMIME("text/x-smarty", "smarty");
|