move a few things away in to-be-integrated/
[myslice.git] / to-be-integrated / third-party / codemirror-3.15 / mode / smarty / smarty.js
diff --git a/to-be-integrated/third-party/codemirror-3.15/mode/smarty/smarty.js b/to-be-integrated/third-party/codemirror-3.15/mode/smarty/smarty.js
new file mode 100644 (file)
index 0000000..826c2b9
--- /dev/null
@@ -0,0 +1,205 @@
+/**
+ * Smarty 2 and 3 mode.
+ */
+CodeMirror.defineMode("smarty", function(config) {
+  "use strict";
+
+  // our default settings; check to see if they're overridden
+  var settings = {
+    rightDelimiter: '}',
+    leftDelimiter: '{',
+    smartyVersion: 2 // for backward compatibility
+  };
+  if (config.hasOwnProperty("leftDelimiter")) {
+    settings.leftDelimiter = config.leftDelimiter;
+  }
+  if (config.hasOwnProperty("rightDelimiter")) {
+    settings.rightDelimiter = config.rightDelimiter;
+  }
+  if (config.hasOwnProperty("smartyVersion") && config.smartyVersion === 3) {
+    settings.smartyVersion = 3;
+  }
+
+  var keyFunctions = ["debug", "extends", "function", "include", "literal"];
+  var last;
+  var regs = {
+    operatorChars: /[+\-*&%=<>!?]/,
+    validIdentifier: /[a-zA-Z0-9_]/,
+    stringChar: /['"]/
+  };
+
+  var helpers = {
+    cont: function(style, lastType) {
+      last = lastType;
+      return style;
+    },
+    chain: function(stream, state, parser) {
+      state.tokenize = parser;
+      return parser(stream, state);
+    }
+  };
+
+
+  // our various parsers
+  var parsers = {
+
+    // the main tokenizer
+    tokenizer: function(stream, state) {
+      if (stream.match(settings.leftDelimiter, true)) {
+        if (stream.eat("*")) {
+          return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
+        } else {
+          // Smarty 3 allows { and } surrounded by whitespace to NOT slip into Smarty mode
+          state.depth++;
+          var isEol = stream.eol();
+          var isFollowedByWhitespace = /\s/.test(stream.peek());
+          if (settings.smartyVersion === 3 && settings.leftDelimiter === "{" && (isEol || isFollowedByWhitespace)) {
+            state.depth--;
+            return null;
+          } else {
+            state.tokenize = parsers.smarty;
+            last = "startTag";
+            return "tag";
+          }
+        }
+      } else {
+        stream.next();
+        return null;
+      }
+    },
+
+    // parsing Smarty content
+    smarty: function(stream, state) {
+      if (stream.match(settings.rightDelimiter, true)) {
+        if (settings.smartyVersion === 3) {
+          state.depth--;
+          if (state.depth <= 0) {
+            state.tokenize = parsers.tokenizer;
+          }
+        } else {
+          state.tokenize = parsers.tokenizer;
+        }
+        return helpers.cont("tag", null);
+      }
+
+      if (stream.match(settings.leftDelimiter, true)) {
+        state.depth++;
+        return helpers.cont("tag", "startTag");
+      }
+
+      var ch = stream.next();
+      if (ch == "$") {
+        stream.eatWhile(regs.validIdentifier);
+        return helpers.cont("variable-2", "variable");
+      } else if (ch == "|") {
+        return helpers.cont("operator", "pipe");
+      } else if (ch == ".") {
+        return helpers.cont("operator", "property");
+      } else if (regs.stringChar.test(ch)) {
+        state.tokenize = parsers.inAttribute(ch);
+        return helpers.cont("string", "string");
+      } else if (regs.operatorChars.test(ch)) {
+        stream.eatWhile(regs.operatorChars);
+        return helpers.cont("operator", "operator");
+      } else if (ch == "[" || ch == "]") {
+        return helpers.cont("bracket", "bracket");
+      } else if (ch == "(" || ch == ")") {
+        return helpers.cont("bracket", "operator");
+      } else if (/\d/.test(ch)) {
+        stream.eatWhile(/\d/);
+        return helpers.cont("number", "number");
+      } else {
+
+        if (state.last == "variable") {
+          if (ch == "@") {
+            stream.eatWhile(regs.validIdentifier);
+            return helpers.cont("property", "property");
+          } else if (ch == "|") {
+            stream.eatWhile(regs.validIdentifier);
+            return helpers.cont("qualifier", "modifier");
+          }
+        } else if (state.last == "pipe") {
+          stream.eatWhile(regs.validIdentifier);
+          return helpers.cont("qualifier", "modifier");
+        } else if (state.last == "whitespace") {
+          stream.eatWhile(regs.validIdentifier);
+          return helpers.cont("attribute", "modifier");
+        } if (state.last == "property") {
+          stream.eatWhile(regs.validIdentifier);
+          return helpers.cont("property", null);
+        } else if (/\s/.test(ch)) {
+          last = "whitespace";
+          return null;
+        }
+
+        var str = "";
+        if (ch != "/") {
+          str += ch;
+        }
+        var c = null;
+        while (c = stream.eat(regs.validIdentifier)) {
+          str += c;
+        }
+        for (var i=0, j=keyFunctions.length; i<j; i++) {
+          if (keyFunctions[i] == str) {
+            return helpers.cont("keyword", "keyword");
+          }
+        }
+        if (/\s/.test(ch)) {
+          return null;
+        }
+        return helpers.cont("tag", "tag");
+      }
+    },
+
+    inAttribute: function(quote) {
+      return function(stream, state) {
+        var prevChar = null;
+        var currChar = null;
+        while (!stream.eol()) {
+          currChar = stream.peek();
+          if (stream.next() == quote && prevChar !== '\\') {
+            state.tokenize = parsers.smarty;
+            break;
+          }
+          prevChar = currChar;
+        }
+        return "string";
+      };
+    },
+
+    inBlock: function(style, terminator) {
+      return function(stream, state) {
+        while (!stream.eol()) {
+          if (stream.match(terminator)) {
+            state.tokenize = parsers.tokenizer;
+            break;
+          }
+          stream.next();
+        }
+        return style;
+      };
+    }
+  };
+
+
+  // the public API for CodeMirror
+  return {
+    startState: function() {
+      return {
+        tokenize: parsers.tokenizer,
+        mode: "smarty",
+        last: null,
+        depth: 0
+      };
+    },
+    token: function(stream, state) {
+      var style = state.tokenize(stream, state);
+      state.last = last;
+      return style;
+    },
+    electricChars: ""
+  };
+});
+
+CodeMirror.defineMIME("text/x-smarty", "smarty");