Last active
August 29, 2015 14:07
-
-
Save bmcculley/974861be9198af7c3bc7 to your computer and use it in GitHub Desktop.
A simple script to minify (multiple) CSS files.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys, re | |
css = "" | |
saveFileName = "default.css" | |
flag = False; | |
for n, i in enumerate(sys.argv): | |
if n == 0: | |
pass | |
elif i == "-h": | |
print "Add CSS files space seperated to be combined and minified. Add -s followed by the name of the new CSS file." | |
break | |
elif i == "-o": | |
flag = True | |
elif flag: | |
saveFileName = i | |
flag = False | |
else: | |
css = css + open( i, 'r' ).read() | |
# remove comments - this will break a lot of hacks :-P | |
css = re.sub( r'\s*/\*\s*\*/', "$$HACK1$$", css ) # preserve IE<6 comment hack | |
css = re.sub( r'/\*[\s\S]*?\*/', "", css ) | |
css = css.replace( "$$HACK1$$", '/**/' ) # preserve IE<6 comment hack | |
# url() doesn't need quotes | |
css = re.sub( r'url\((["\'])([^)]*)\1\)', r'url(\2)', css ) | |
# spaces may be safely collapsed as generated content will collapse them anyway | |
css = re.sub( r'\s+', ' ', css ) | |
# shorten collapsable colors: #aabbcc to #abc | |
css = re.sub( r'#([0-9a-f])\1([0-9a-f])\2([0-9a-f])\3(\s|;)', r'#\1\2\3\4', css ) | |
# fragment values can loose zeros | |
css = re.sub( r':\s*0(\.\d+([cm]m|e[mx]|in|p[ctx]))\s*;', r':\1;', css ) | |
for rule in re.findall( r'([^{]+){([^}]*)}', css ): | |
# we don't need spaces around operators | |
selectors = [re.sub( r'(?<=[\[\(>+=])\s+|\s+(?=[=~^$*|>+\]\)])', r'', selector.strip() ) for selector in rule[0].split( ',' )] | |
# order is important, but we still want to discard repetitions | |
properties = {} | |
porder = [] | |
for prop in re.findall( '(.*?):(.*?)(;|$)', rule[1] ): | |
key = prop[0].strip().lower() | |
if key not in porder: porder.append( key ) | |
properties[ key ] = prop[1].strip() | |
# output rule if it contains any declarations | |
if properties: | |
f = open(saveFileName,'a') | |
f.write("%s{%s}" % ( ','.join( selectors ), ''.join(['%s:%s;' % (key, properties[key]) for key in porder])[:-1] ) ) | |
f.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
An example usage: