6 if (typeof exports
== "object" && typeof module
== "object") // CommonJS
7 mod(require("../../lib/codemirror"));
8 else if (typeof define
== "function" && define
.amd
) // AMD
9 define(["../../lib/codemirror"], mod
);
10 else // Plain browser env
12 })(function(CodeMirror
) {
15 CodeMirror
.defineMode("smarty", function(config
) {
18 // our default settings; check to see if they're overridden
22 smartyVersion
: 2 // for backward compatibility
24 if (config
.hasOwnProperty("leftDelimiter")) {
25 settings
.leftDelimiter
= config
.leftDelimiter
;
27 if (config
.hasOwnProperty("rightDelimiter")) {
28 settings
.rightDelimiter
= config
.rightDelimiter
;
30 if (config
.hasOwnProperty("smartyVersion") && config
.smartyVersion
=== 3) {
31 settings
.smartyVersion
= 3;
34 var keyFunctions
= ["debug", "extends", "function", "include", "literal"];
37 operatorChars
: /[+\-*&%=<>!?]/,
38 validIdentifier
: /[a-zA-Z0-9_]/,
43 cont: function(style
, lastType
) {
47 chain: function(stream
, state
, parser
) {
48 state
.tokenize
= parser
;
49 return parser(stream
, state
);
54 // our various parsers
58 tokenizer: function(stream
, state
) {
59 if (stream
.match(settings
.leftDelimiter
, true)) {
60 if (stream
.eat("*")) {
61 return helpers
.chain(stream
, state
, parsers
.inBlock("comment", "*" + settings
.rightDelimiter
));
63 // Smarty 3 allows { and } surrounded by whitespace to NOT slip into Smarty mode
65 var isEol
= stream
.eol();
66 var isFollowedByWhitespace
= /\s/.test(stream
.peek());
67 if (settings
.smartyVersion
=== 3 && settings
.leftDelimiter
=== "{" && (isEol
|| isFollowedByWhitespace
)) {
71 state
.tokenize
= parsers
.smarty
;
82 // parsing Smarty content
83 smarty: function(stream
, state
) {
84 if (stream
.match(settings
.rightDelimiter
, true)) {
85 if (settings
.smartyVersion
=== 3) {
87 if (state
.depth
<= 0) {
88 state
.tokenize
= parsers
.tokenizer
;
91 state
.tokenize
= parsers
.tokenizer
;
93 return helpers
.cont("tag", null);
96 if (stream
.match(settings
.leftDelimiter
, true)) {
98 return helpers
.cont("tag", "startTag");
101 var ch
= stream
.next();
103 stream
.eatWhile(regs
.validIdentifier
);
104 return helpers
.cont("variable-2", "variable");
105 } else if (ch
== "|") {
106 return helpers
.cont("operator", "pipe");
107 } else if (ch
== ".") {
108 return helpers
.cont("operator", "property");
109 } else if (regs
.stringChar
.test(ch
)) {
110 state
.tokenize
= parsers
.inAttribute(ch
);
111 return helpers
.cont("string", "string");
112 } else if (regs
.operatorChars
.test(ch
)) {
113 stream
.eatWhile(regs
.operatorChars
);
114 return helpers
.cont("operator", "operator");
115 } else if (ch
== "[" || ch
== "]") {
116 return helpers
.cont("bracket", "bracket");
117 } else if (ch
== "(" || ch
== ")") {
118 return helpers
.cont("bracket", "operator");
119 } else if (/\d/.test(ch
)) {
120 stream
.eatWhile(/\d/);
121 return helpers
.cont("number", "number");
124 if (state
.last
== "variable") {
126 stream
.eatWhile(regs
.validIdentifier
);
127 return helpers
.cont("property", "property");
128 } else if (ch
== "|") {
129 stream
.eatWhile(regs
.validIdentifier
);
130 return helpers
.cont("qualifier", "modifier");
132 } else if (state
.last
== "pipe") {
133 stream
.eatWhile(regs
.validIdentifier
);
134 return helpers
.cont("qualifier", "modifier");
135 } else if (state
.last
== "whitespace") {
136 stream
.eatWhile(regs
.validIdentifier
);
137 return helpers
.cont("attribute", "modifier");
138 } if (state
.last
== "property") {
139 stream
.eatWhile(regs
.validIdentifier
);
140 return helpers
.cont("property", null);
141 } else if (/\s/.test(ch
)) {
151 while (c
= stream
.eat(regs
.validIdentifier
)) {
154 for (var i
=0, j
=keyFunctions
.length
; i
<j
; i
++) {
155 if (keyFunctions
[i
] == str
) {
156 return helpers
.cont("keyword", "keyword");
162 return helpers
.cont("tag", "tag");
166 inAttribute: function(quote
) {
167 return function(stream
, state
) {
170 while (!stream
.eol()) {
171 currChar
= stream
.peek();
172 if (stream
.next() == quote
&& prevChar
!== '\\') {
173 state
.tokenize
= parsers
.smarty
;
182 inBlock: function(style
, terminator
) {
183 return function(stream
, state
) {
184 while (!stream
.eol()) {
185 if (stream
.match(terminator
)) {
186 state
.tokenize
= parsers
.tokenizer
;
197 // the public API for CodeMirror
199 startState: function() {
201 tokenize
: parsers
.tokenizer
,
207 token: function(stream
, state
) {
208 var style
= state
.tokenize(stream
, state
);
216 CodeMirror
.defineMIME("text/x-smarty", "smarty");