Permalink
Browse files

Initial commit

  • Loading branch information...
StephenBrown committed Apr 21, 2011
0 parents commit 0f8e2bf0478c73a0951a1a654464a45f5ca558bf
@@ -0,0 +1,9 @@
+*\.hg
+*\.hgignore
+
+*.pyc
+
+*.swp
+*.swo
+
+*.temp
2 README
@@ -0,0 +1,2 @@
+Dependencies:
+ configobj
5 TODO
@@ -0,0 +1,5 @@
+- Add ability to save version numbers
+ - Possibly in external file
+ - Allow for dates for a checksum
+
+- Add other compressor engines
No changes.
@@ -0,0 +1,124 @@
+#!/usr/bin/env python
+
+import os
+import os.path
+from optparse import OptionParser
+from configobj import ConfigObj
+
+#path to compressor
+YUI_COMPRESSOR = os.path.relpath('./yuicompressor-2.4.2.jar')
+
+# path to base directory of resources
+resources = os.path.relpath('./resources')
+
+def combine(in_files, out_file):
+ open_out_file = open(out_file, 'w')
+ for in_file in in_files:
+ open_in_file = open(in_file)
+ data = open_in_file.read()
+ open_in_file.close()
+ open_out_file.write(data)
+ print ' + %s' % in_file
+ print 'Combined: %s' % out_file
+ open_out_file.close()
+
+def compress(in_file, out_file, compressor=YUI_COMPRESSOR, temp_file='debug_compress.temp', in_type='js', verbose=False):
+ open_temp = open(temp_file, 'w')
+ open_in_file = open(in_file, 'r')
+ data = open_in_file.read()
+ open_in_file.close()
+ open_temp.write(data)
+ open_temp.close()
+
+ options = ['-o "%s"' % out_file,
+ '--type %s' % in_type]
+ if verbose:
+ options.append('-v')
+
+ if compressor == YUI_COMPRESSOR:
+ os.system('java -jar "%s" %s "%s"' % (YUI_COMPRESSOR,
+ ' '.join(options),
+ temp_file))
+
+ original_size = os.path.getsize(temp_file)
+ new_size = os.path.getsize(out_file)
+
+ print ' + %s' % in_file
+ print 'Combined and compressed: %s' % out_file
+ print 'Original: %.2f kB' % (original_size / 1024.0)
+ print 'Compressed: %.2f kB' % (new_size / 1024.0)
+ print 'Reduction: %.1f%%' % (float(original_size - new_size) / original_size * 100)
+
+def run_scripts(do_compress=True, verbose=False):
+ for file_set in config['scripts']:
+ print 'Combining JavaScript...'
+ combine(file_set['files-to-combine'],
+ file_set['out-file-combined-path'])
+ if do_compress:
+ print 'Compressing JavaScript...'
+ compress(file_set['out-file-combined-path'],
+ file_set['out-file-combined-compressed-path'],
+ verbose=verbose)
+
+def run_styles(config, do_compress=True, verbose=False):
+ for file_set in config['stylesheets']:
+ print 'Combining CSS...'
+ combine(file_set['files-to-combine'],
+ file_set['out-file-combined_path'])
+ if do_compress:
+ print 'Compressing CSS...'
+ compress(file_set['out-file-combined_path'],
+ file_set['out-file-combined-compressed-path'],
+ in_type='css', verbose=verbose)
+
+def parse_config(filename):
+ config = ConfigObj(filename)
+ config.walk(lower_config_keys, call_on_sections=True)
+ config.walk(make_paths)
+ return config
+
+def lower_config_keys(section, key):
+ new_key = key.lower()
+ section.rename(key, new_key)
+
+def make_paths(section, key):
+ val = section[key]
+ section[key] = os.path.join(*val)
+
+def run(args, options):
+ config_options = parse_config(args[0])
+ if (options.scripts and options.minify) or \
+ (not options.scripts and not options.stylesheets and options.minify):
+ run_scripts(config_options, verbose=options.verbose)
+ elif (not options.scripts and not options.stylesheets) or \
+ (options.scripts and not options.stylesheets and options.combine):
+ run_scripts(config_options, False)
+ if (options.stylesheets and options.minify) or \
+ (not options.scripts and not options.stylesheets and options.minify):
+ run_styles(config_options, verbose=options.verbose)
+ elif (not options.scripts and not options.stylesheets) or \
+ (not options.scripts and options.stylesheets and options.combine):
+ run_styles(config_options, False)
+
+def main():
+ usage = 'usage: %prog [options] config_file'
+ parser = OptionParser(usage=usage)
+ parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
+ default=False, help='Add verbosity to compressor')
+ parser.add_option('-m', '--minify', action='store_true', dest='minify',
+ default=False, help='Combine then minify files')
+ parser.add_option('-c', '--combine', action='store_true', dest='combine',
+ default=False, help='Only combine files')
+ parser.add_option('-s', '--stylesheets', action='store_true', dest='stylesheets',
+ default=False, help='Do action to stylesheets')
+ parser.add_option('-j', '--scripts', action='store_true', dest='scripts',
+ default=False, help='Do action to scripts')
+
+ (options, args) = parser.parse_args()
+ if len(args) != 1:
+ parser.error('config_file is missing')
+
+ run(args, options)
+
+if __name__ == '__main__':
+ main()
218 jsmin.py
@@ -0,0 +1,218 @@
+#!/usr/bin/python
+
+# This code is original from jsmin by Douglas Crockford, it was translated to
+# Python by Baruch Even. The original code had the following copyright and
+# license.
+#
+# /* jsmin.c
+# 2007-05-22
+#
+# Copyright (c) 2002 Douglas Crockford (www.crockford.com)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is furnished to do
+# so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# The Software shall be used for Good, not Evil.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# */
+
+from StringIO import StringIO
+
+def jsmin(js):
+ ins = StringIO(js)
+ outs = StringIO()
+ JavascriptMinify().minify(ins, outs)
+ str = outs.getvalue()
+ if len(str) > 0 and str[0] == '\n':
+ str = str[1:]
+ return str
+
+def isAlphanum(c):
+ """return true if the character is a letter, digit, underscore,
+ dollar sign, or non-ASCII character.
+ """
+ return ((c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') or
+ (c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\' or (c is not None and ord(c) > 126));
+
+class UnterminatedComment(Exception):
+ pass
+
+class UnterminatedStringLiteral(Exception):
+ pass
+
+class UnterminatedRegularExpression(Exception):
+ pass
+
+class JavascriptMinify(object):
+
+ def _outA(self):
+ self.outstream.write(self.theA)
+ def _outB(self):
+ self.outstream.write(self.theB)
+
+ def _get(self):
+ """return the next character from stdin. Watch out for lookahead. If
+ the character is a control character, translate it to a space or
+ linefeed.
+ """
+ c = self.theLookahead
+ self.theLookahead = None
+ if c == None:
+ c = self.instream.read(1)
+ if c >= ' ' or c == '\n':
+ return c
+ if c == '': # EOF
+ return '\000'
+ if c == '\r':
+ return '\n'
+ return ' '
+
+ def _peek(self):
+ self.theLookahead = self._get()
+ return self.theLookahead
+
+ def _next(self):
+ """get the next character, excluding comments. peek() is used to see
+ if an unescaped '/' is followed by a '/' or '*'.
+ """
+ c = self._get()
+ if c == '/' and self.theA != '\\':
+ p = self._peek()
+ if p == '/':
+ c = self._get()
+ while c > '\n':
+ c = self._get()
+ return c
+ if p == '*':
+ c = self._get()
+ while 1:
+ c = self._get()
+ if c == '*':
+ if self._peek() == '/':
+ self._get()
+ return ' '
+ if c == '\000':
+ raise UnterminatedComment()
+
+ return c
+
+ def _action(self, action):
+ """do something! What you do is determined by the argument:
+ 1 Output A. Copy B to A. Get the next B.
+ 2 Copy B to A. Get the next B. (Delete A).
+ 3 Get the next B. (Delete B).
+ action treats a string as a single character. Wow!
+ action recognizes a regular expression if it is preceded by ( or , or =.
+ """
+ if action <= 1:
+ self._outA()
+
+ if action <= 2:
+ self.theA = self.theB
+ if self.theA == "'" or self.theA == '"':
+ while 1:
+ self._outA()
+ self.theA = self._get()
+ if self.theA == self.theB:
+ break
+ if self.theA <= '\n':
+ raise UnterminatedStringLiteral()
+ if self.theA == '\\':
+ self._outA()
+ self.theA = self._get()
+
+
+ if action <= 3:
+ self.theB = self._next()
+ if self.theB == '/' and (self.theA == '(' or self.theA == ',' or
+ self.theA == '=' or self.theA == ':' or
+ self.theA == '[' or self.theA == '?' or
+ self.theA == '!' or self.theA == '&' or
+ self.theA == '|' or self.theA == ';' or
+ self.theA == '{' or self.theA == '}' or
+ self.theA == '\n'):
+ self._outA()
+ self._outB()
+ while 1:
+ self.theA = self._get()
+ if self.theA == '/':
+ break
+ elif self.theA == '\\':
+ self._outA()
+ self.theA = self._get()
+ elif self.theA <= '\n':
+ raise UnterminatedRegularExpression()
+ self._outA()
+ self.theB = self._next()
+
+
+ def _jsmin(self):
+ """Copy the input to the output, deleting the characters which are
+ insignificant to JavaScript. Comments will be removed. Tabs will be
+ replaced with spaces. Carriage returns will be replaced with linefeeds.
+ Most spaces and linefeeds will be removed.
+ """
+ self.theA = '\n'
+ self._action(3)
+
+ while self.theA != '\000':
+ if self.theA == ' ':
+ if isAlphanum(self.theB):
+ self._action(1)
+ else:
+ self._action(2)
+ elif self.theA == '\n':
+ if self.theB in ['{', '[', '(', '+', '-']:
+ self._action(1)
+ elif self.theB == ' ':
+ self._action(3)
+ else:
+ if isAlphanum(self.theB):
+ self._action(1)
+ else:
+ self._action(2)
+ else:
+ if self.theB == ' ':
+ if isAlphanum(self.theA):
+ self._action(1)
+ else:
+ self._action(3)
+ elif self.theB == '\n':
+ if self.theA in ['}', ']', ')', '+', '-', '"', '\'']:
+ self._action(1)
+ else:
+ if isAlphanum(self.theA):
+ self._action(1)
+ else:
+ self._action(3)
+ else:
+ self._action(1)
+
+ def minify(self, instream, outstream):
+ self.instream = instream
+ self.outstream = outstream
+ self.theA = '\n'
+ self.theB = None
+ self.theLookahead = None
+
+ self._jsmin()
+ self.instream.close()
+
+if __name__ == '__main__':
+ import sys
+ jsm = JavascriptMinify()
+ jsm.minify(sys.stdin, sys.stdout)
@@ -0,0 +1,35 @@
+/* -----------------------------------------------------------------------
+
+
+ Blueprint CSS Framework 0.9
+ http://blueprintcss.org
+
+ * Copyright (c) 2007-Present. See LICENSE for more info.
+ * See README for instructions on how to use Blueprint.
+ * For credits and origins, see AUTHORS.
+ * This is a compressed file. See the sources in the 'src' directory.
+
+----------------------------------------------------------------------- */
+
+/* ie.css */
+body {text-align:center;}
+.container {text-align:left;}
+* html .column, * html .span-1, * html .span-2, * html .span-3, * html .span-4, * html .span-5, * html .span-6, * html .span-7, * html .span-8, * html .span-9, * html .span-10, * html .span-11, * html .span-12, * html .span-13, * html .span-14, * html .span-15, * html .span-16, * html .span-17, * html .span-18, * html .span-19, * html .span-20, * html .span-21, * html .span-22, * html .span-23, * html .span-24 {display:inline;overflow-x:hidden;}
+* html legend {margin:0px -8px 16px 0;padding:0;}
+sup {vertical-align:text-top;}
+sub {vertical-align:text-bottom;}
+html>body p code {*white-space:normal;}
+hr {margin:-8px auto 11px;}
+img {-ms-interpolation-mode:bicubic;}
+.clearfix, .container {display:inline-block;}
+* html .clearfix, * html .container {height:1%;}
+fieldset {padding-top:0;}
+textarea {overflow:auto;}
+input.text, input.title, textarea {background-color:#fff;border:1px solid #bbb;}
+input.text:focus, input.title:focus {border-color:#666;}
+input.text, input.title, textarea, select {margin:0.5em 0;}
+input.checkbox, input.radio {position:relative;top:.25em;}
+form.inline div, form.inline p {vertical-align:middle;}
+form.inline label {position:relative;top:-0.25em;}
+form.inline input.checkbox, form.inline input.radio, form.inline input.button, form.inline button {margin:0.5em 0;}
+button, input.button {position:relative;top:0.25em;}
Oops, something went wrong.

0 comments on commit 0f8e2bf

Please sign in to comment.