1 CodeMirror
.defineMode("smarty", function(config
) {
2 var keyFuncs
= ["debug", "extends", "function", "include", "literal"];
5 operatorChars
: /[+\-*&%=<>!?]/,
6 validIdentifier
: /[a-zA-Z0-9\_]/,
9 var leftDelim
= (typeof config
.mode
.leftDelimiter
!= 'undefined') ? config
.mode
.leftDelimiter
: "{";
10 var rightDelim
= (typeof config
.mode
.rightDelimiter
!= 'undefined') ? config
.mode
.rightDelimiter
: "}";
11 function ret(style
, lst
) { last
= lst
; return style
; }
14 function tokenizer(stream
, state
) {
15 function chain(parser
) {
16 state
.tokenize
= parser
;
17 return parser(stream
, state
);
20 if (stream
.match(leftDelim
, true)) {
21 if (stream
.eat("*")) {
22 return chain(inBlock("comment", "*" + rightDelim
));
25 state
.tokenize
= inSmarty
;
30 // I'd like to do an eatWhile() here, but I can't get it to eat only up to the rightDelim string/char
36 function inSmarty(stream
, state
) {
37 if (stream
.match(rightDelim
, true)) {
38 state
.tokenize
= tokenizer
;
39 return ret("tag", null);
42 var ch
= stream
.next();
44 stream
.eatWhile(regs
.validIdentifier
);
45 return ret("variable-2", "variable");
48 return ret("operator", "property");
50 else if (regs
.stringChar
.test(ch
)) {
51 state
.tokenize
= inAttribute(ch
);
52 return ret("string", "string");
54 else if (regs
.operatorChars
.test(ch
)) {
55 stream
.eatWhile(regs
.operatorChars
);
56 return ret("operator", "operator");
58 else if (ch
== "[" || ch
== "]") {
59 return ret("bracket", "bracket");
61 else if (/\d/.test(ch
)) {
62 stream
.eatWhile(/\d/);
63 return ret("number", "number");
66 if (state
.last
== "variable") {
68 stream
.eatWhile(regs
.validIdentifier
);
69 return ret("property", "property");
72 stream
.eatWhile(regs
.validIdentifier
);
73 return ret("qualifier", "modifier");
76 else if (state
.last
== "whitespace") {
77 stream
.eatWhile(regs
.validIdentifier
);
78 return ret("attribute", "modifier");
80 else if (state
.last
== "property") {
81 stream
.eatWhile(regs
.validIdentifier
);
82 return ret("property", null);
84 else if (/\s/.test(ch
)) {
94 while ((c
= stream
.eat(regs
.validIdentifier
))) {
98 for (i
=0, j
=keyFuncs
.length
; i
<j
; i
++) {
99 if (keyFuncs
[i
] == str
) {
100 return ret("keyword", "keyword");
106 return ret("tag", "tag");
110 function inAttribute(quote
) {
111 return function(stream
, state
) {
112 while (!stream
.eol()) {
113 if (stream
.next() == quote
) {
114 state
.tokenize
= inSmarty
;
122 function inBlock(style
, terminator
) {
123 return function(stream
, state
) {
124 while (!stream
.eol()) {
125 if (stream
.match(terminator
)) {
126 state
.tokenize
= tokenizer
;
136 startState: function() {
137 return { tokenize
: tokenizer
, mode
: "smarty", last
: null };
139 token: function(stream
, state
) {
140 var style
= state
.tokenize(stream
, state
);
148 CodeMirror
.defineMIME("text/x-smarty", "smarty");