annotate .cms/lib/codemirror/mode/smarty/smarty.js @ 0:78edf6b517a0 draft

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