--- /dev/null
+#!/usr/bin/python\r
+\r
+# This code is original from jsmin by Douglas Crockford, it was translated to\r
+# Python by Baruch Even. The original code had the following copyright and\r
+# license.\r
+#\r
+# /* jsmin.c\r
+# 2007-05-22\r
+#\r
+# Copyright (c) 2002 Douglas Crockford (www.crockford.com)\r
+#\r
+# Permission is hereby granted, free of charge, to any person obtaining a copy of\r
+# this software and associated documentation files (the "Software"), to deal in\r
+# the Software without restriction, including without limitation the rights to\r
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\r
+# of the Software, and to permit persons to whom the Software is furnished to do\r
+# so, subject to the following conditions:\r
+#\r
+# The above copyright notice and this permission notice shall be included in all\r
+# copies or substantial portions of the Software.\r
+#\r
+# The Software shall be used for Good, not Evil.\r
+#\r
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+# SOFTWARE.\r
+# */\r
+\r
+from StringIO import StringIO\r
+\r
+def jsmin(js):\r
+ ins = StringIO(js)\r
+ outs = StringIO()\r
+ JavascriptMinify().minify(ins, outs)\r
+ str = outs.getvalue()\r
+ if len(str) > 0 and str[0] == '\n':\r
+ str = str[1:]\r
+ return str\r
+\r
+def isAlphanum(c):\r
+ """return true if the character is a letter, digit, underscore,\r
+ dollar sign, or non-ASCII character.\r
+ """\r
+ return ((c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') or\r
+ (c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\' or (c is not None and ord(c) > 126));\r
+\r
+class UnterminatedComment(Exception):\r
+ pass\r
+\r
+class UnterminatedStringLiteral(Exception):\r
+ pass\r
+\r
+class UnterminatedRegularExpression(Exception):\r
+ pass\r
+\r
+class JavascriptMinify(object):\r
+\r
+ def _outA(self):\r
+ self.outstream.write(self.theA)\r
+ def _outB(self):\r
+ self.outstream.write(self.theB)\r
+\r
+ def _get(self):\r
+ """return the next character from stdin. Watch out for lookahead. If\r
+ the character is a control character, translate it to a space or\r
+ linefeed.\r
+ """\r
+ c = self.theLookahead\r
+ self.theLookahead = None\r
+ if c == None:\r
+ c = self.instream.read(1)\r
+ if c >= ' ' or c == '\n':\r
+ return c\r
+ if c == '': # EOF\r
+ return '\000'\r
+ if c == '\r':\r
+ return '\n'\r
+ return ' '\r
+\r
+ def _peek(self):\r
+ self.theLookahead = self._get()\r
+ return self.theLookahead\r
+\r
+ def _next(self):\r
+ """get the next character, excluding comments. peek() is used to see\r
+ if an unescaped '/' is followed by a '/' or '*'.\r
+ """\r
+ c = self._get()\r
+ if c == '/' and self.theA != '\\':\r
+ p = self._peek()\r
+ if p == '/':\r
+ c = self._get()\r
+ while c > '\n':\r
+ c = self._get()\r
+ return c\r
+ if p == '*':\r
+ c = self._get()\r
+ while 1:\r
+ c = self._get()\r
+ if c == '*':\r
+ if self._peek() == '/':\r
+ self._get()\r
+ return ' '\r
+ if c == '\000':\r
+ raise UnterminatedComment()\r
+\r
+ return c\r
+\r
+ def _action(self, action):\r
+ """do something! What you do is determined by the argument:\r
+ 1 Output A. Copy B to A. Get the next B.\r
+ 2 Copy B to A. Get the next B. (Delete A).\r
+ 3 Get the next B. (Delete B).\r
+ action treats a string as a single character. Wow!\r
+ action recognizes a regular expression if it is preceded by ( or , or =.\r
+ """\r
+ if action <= 1:\r
+ self._outA()\r
+\r
+ if action <= 2:\r
+ self.theA = self.theB\r
+ if self.theA == "'" or self.theA == '"':\r
+ while 1:\r
+ self._outA()\r
+ self.theA = self._get()\r
+ if self.theA == self.theB:\r
+ break\r
+ if self.theA <= '\n':\r
+ raise UnterminatedStringLiteral()\r
+ if self.theA == '\\':\r
+ self._outA()\r
+ self.theA = self._get()\r
+\r
+\r
+ if action <= 3:\r
+ self.theB = self._next()\r
+ if self.theB == '/' and (self.theA == '(' or self.theA == ',' or\r
+ self.theA == '=' or self.theA == ':' or\r
+ self.theA == '[' or self.theA == '?' or\r
+ self.theA == '!' or self.theA == '&' or\r
+ self.theA == '|' or self.theA == ';' or\r
+ self.theA == '{' or self.theA == '}' or\r
+ self.theA == '\n'):\r
+ self._outA()\r
+ self._outB()\r
+ while 1:\r
+ self.theA = self._get()\r
+ if self.theA == '/':\r
+ break\r
+ elif self.theA == '\\':\r
+ self._outA()\r
+ self.theA = self._get()\r
+ elif self.theA <= '\n':\r
+ raise UnterminatedRegularExpression()\r
+ self._outA()\r
+ self.theB = self._next()\r
+\r
+\r
+ def _jsmin(self):\r
+ """Copy the input to the output, deleting the characters which are\r
+ insignificant to JavaScript. Comments will be removed. Tabs will be\r
+ replaced with spaces. Carriage returns will be replaced with linefeeds.\r
+ Most spaces and linefeeds will be removed.\r
+ """\r
+ self.theA = '\n'\r
+ self._action(3)\r
+\r
+ while self.theA != '\000':\r
+ if self.theA == ' ':\r
+ if isAlphanum(self.theB):\r
+ self._action(1)\r
+ else:\r
+ self._action(2)\r
+ elif self.theA == '\n':\r
+ if self.theB in ['{', '[', '(', '+', '-']:\r
+ self._action(1)\r
+ elif self.theB == ' ':\r
+ self._action(3)\r
+ else:\r
+ if isAlphanum(self.theB):\r
+ self._action(1)\r
+ else:\r
+ self._action(2)\r
+ else:\r
+ if self.theB == ' ':\r
+ if isAlphanum(self.theA):\r
+ self._action(1)\r
+ else:\r
+ self._action(3)\r
+ elif self.theB == '\n':\r
+ if self.theA in ['}', ']', ')', '+', '-', '"', '\'']:\r
+ self._action(1)\r
+ else:\r
+ if isAlphanum(self.theA):\r
+ self._action(1)\r
+ else:\r
+ self._action(3)\r
+ else:\r
+ self._action(1)\r
+\r
+ def minify(self, instream, outstream):\r
+ self.instream = instream\r
+ self.outstream = outstream\r
+ self.theA = '\n'\r
+ self.theB = None\r
+ self.theLookahead = None\r
+\r
+ self._jsmin()\r
+ self.instream.close()\r
+\r
+if __name__ == '__main__':\r
+ import sys\r
+ jsm = JavascriptMinify()\r
+ jsm.minify(sys.stdin, sys.stdout)\r