LaravelTest
225 строк · 6.7 Кб
1// CodeMirror, copyright (c) by Marijn Haverbeke and others
2// Distributed under an MIT license: https://codemirror.net/LICENSE
3
4/**
5* Smarty 2 and 3 mode.
6*/
7
8(function(mod) {9if (typeof exports == "object" && typeof module == "object") // CommonJS10mod(require("../../lib/codemirror"));11else if (typeof define == "function" && define.amd) // AMD12define(["../../lib/codemirror"], mod);13else // Plain browser env14mod(CodeMirror);15})(function(CodeMirror) {16"use strict";17
18CodeMirror.defineMode("smarty", function(config, parserConf) {19var rightDelimiter = parserConf.rightDelimiter || "}";20var leftDelimiter = parserConf.leftDelimiter || "{";21var version = parserConf.version || 2;22var baseMode = CodeMirror.getMode(config, parserConf.baseMode || "null");23
24var keyFunctions = ["debug", "extends", "function", "include", "literal"];25var regs = {26operatorChars: /[+\-*&%=<>!?]/,27validIdentifier: /[a-zA-Z0-9_]/,28stringChar: /['"]/29};30
31var last;32function cont(style, lastType) {33last = lastType;34return style;35}36
37function chain(stream, state, parser) {38state.tokenize = parser;39return parser(stream, state);40}41
42// Smarty 3 allows { and } surrounded by whitespace to NOT slip into Smarty mode43function doesNotCount(stream, pos) {44if (pos == null) pos = stream.pos;45return version === 3 && leftDelimiter == "{" &&46(pos == stream.string.length || /\s/.test(stream.string.charAt(pos)));47}48
49function tokenTop(stream, state) {50var string = stream.string;51for (var scan = stream.pos;;) {52var nextMatch = string.indexOf(leftDelimiter, scan);53scan = nextMatch + leftDelimiter.length;54if (nextMatch == -1 || !doesNotCount(stream, nextMatch + leftDelimiter.length)) break;55}56if (nextMatch == stream.pos) {57stream.match(leftDelimiter);58if (stream.eat("*")) {59return chain(stream, state, tokenBlock("comment", "*" + rightDelimiter));60} else {61state.depth++;62state.tokenize = tokenSmarty;63last = "startTag";64return "tag";65}66}67
68if (nextMatch > -1) stream.string = string.slice(0, nextMatch);69var token = baseMode.token(stream, state.base);70if (nextMatch > -1) stream.string = string;71return token;72}73
74// parsing Smarty content75function tokenSmarty(stream, state) {76if (stream.match(rightDelimiter, true)) {77if (version === 3) {78state.depth--;79if (state.depth <= 0) {80state.tokenize = tokenTop;81}82} else {83state.tokenize = tokenTop;84}85return cont("tag", null);86}87
88if (stream.match(leftDelimiter, true)) {89state.depth++;90return cont("tag", "startTag");91}92
93var ch = stream.next();94if (ch == "$") {95stream.eatWhile(regs.validIdentifier);96return cont("variable-2", "variable");97} else if (ch == "|") {98return cont("operator", "pipe");99} else if (ch == ".") {100return cont("operator", "property");101} else if (regs.stringChar.test(ch)) {102state.tokenize = tokenAttribute(ch);103return cont("string", "string");104} else if (regs.operatorChars.test(ch)) {105stream.eatWhile(regs.operatorChars);106return cont("operator", "operator");107} else if (ch == "[" || ch == "]") {108return cont("bracket", "bracket");109} else if (ch == "(" || ch == ")") {110return cont("bracket", "operator");111} else if (/\d/.test(ch)) {112stream.eatWhile(/\d/);113return cont("number", "number");114} else {115
116if (state.last == "variable") {117if (ch == "@") {118stream.eatWhile(regs.validIdentifier);119return cont("property", "property");120} else if (ch == "|") {121stream.eatWhile(regs.validIdentifier);122return cont("qualifier", "modifier");123}124} else if (state.last == "pipe") {125stream.eatWhile(regs.validIdentifier);126return cont("qualifier", "modifier");127} else if (state.last == "whitespace") {128stream.eatWhile(regs.validIdentifier);129return cont("attribute", "modifier");130} if (state.last == "property") {131stream.eatWhile(regs.validIdentifier);132return cont("property", null);133} else if (/\s/.test(ch)) {134last = "whitespace";135return null;136}137
138var str = "";139if (ch != "/") {140str += ch;141}142var c = null;143while (c = stream.eat(regs.validIdentifier)) {144str += c;145}146for (var i=0, j=keyFunctions.length; i<j; i++) {147if (keyFunctions[i] == str) {148return cont("keyword", "keyword");149}150}151if (/\s/.test(ch)) {152return null;153}154return cont("tag", "tag");155}156}157
158function tokenAttribute(quote) {159return function(stream, state) {160var prevChar = null;161var currChar = null;162while (!stream.eol()) {163currChar = stream.peek();164if (stream.next() == quote && prevChar !== '\\') {165state.tokenize = tokenSmarty;166break;167}168prevChar = currChar;169}170return "string";171};172}173
174function tokenBlock(style, terminator) {175return function(stream, state) {176while (!stream.eol()) {177if (stream.match(terminator)) {178state.tokenize = tokenTop;179break;180}181stream.next();182}183return style;184};185}186
187return {188startState: function() {189return {190base: CodeMirror.startState(baseMode),191tokenize: tokenTop,192last: null,193depth: 0194};195},196copyState: function(state) {197return {198base: CodeMirror.copyState(baseMode, state.base),199tokenize: state.tokenize,200last: state.last,201depth: state.depth202};203},204innerMode: function(state) {205if (state.tokenize == tokenTop)206return {mode: baseMode, state: state.base};207},208token: function(stream, state) {209var style = state.tokenize(stream, state);210state.last = last;211return style;212},213indent: function(state, text, line) {214if (state.tokenize == tokenTop && baseMode.indent)215return baseMode.indent(state.base, text, line);216else217return CodeMirror.Pass;218},219blockCommentStart: leftDelimiter + "*",220blockCommentEnd: "*" + rightDelimiter221};222});223
224CodeMirror.defineMIME("text/x-smarty", "smarty");225});226