License Public Domain
Lines 107
Keywords
css (7)
Permissions
Owner: Stou S.
Viewable by Everyone
Editable by All Siafoo Users
Hide
Easily highlight source code for your blog with our Syntax Highlighter. Join Siafoo Now or Learn More

Quick and dirty CSS Minifier Atom Feed 1

In Brief It's quite ugly and was written in about two hours with no knowledge of regex. It should definitely be throughly cleaned up and tested.... more
# 's
  1#!/usr/bin/python
2from __future__ import division
3import sys
4import getopt
5import re
6
7def compress(input):
8
9 output = ''
10
11 while True:
12 open_c = input.find('/*')
13
14 if open_c == -1:
15 output += input
16 break;
17
18 output += input[ : open_c]
19 input = input[ open_c + 2 : ]
20
21 close_c = input.find('*/')
22
23 if close_c == -1:
24 print 'Runaway comment detected'
25 return output
26
27 input = input[close_c + 2: ]
28
29 # Replace tab with space
30 output = output.replace('\t', ' ')
31
32 # Remove double spaces
33 output = re.sub('\s{2,}', ' ', output)
34
35 # Remove spaces around stuff
36 output = re.sub('\s*;+\s*', ';', output)
37 output = re.sub('\s*:\s*', ':', output)
38 output = re.sub('\s*{\s*', '{', output)
39 output = re.sub('\s*}\s*', '}', output)
40
41 # Remove unecessary semicolon
42 output = output.replace(';}', '}')
43
44 # Split the directives on per line
45 output = output.replace('}', '}\n')
46
47 output = output.strip()
48
49 output = remove_dead(output)
50 output = shorten_colors(output)
51
52 # Remove all the newlines
53 output = output.replace('\n', '')
54 return output
55
56def remove_dead(input):
57 output = ''
58
59 for line in input.splitlines(True):
60 if not re.search('([\.#][\w_]*{})', line):
61 output += line
62
63 return output
64
65def shorten_colors(input):
66 output = ''
67
68 p = re.compile(':#([A-Fa-f0-9]{6})')
69
70 for line in input.splitlines(True):
71 m = p.search(line)
72
73 if m is not None:
74 old_c = m.group(1)
75
76 if old_c[0] == old_c[1] and old_c[2] == old_c[3] and old_c[4] == old_c[5]:
77 new_c = old_c[0] + old_c[2] + old_c[4]
78 output += line.replace(old_c, new_c)
79 continue
80
81 output += line
82
83 return output
84
85def main(argv):
86
87 try:
88 opts, args = getopt.getopt(argv, "i:o:", ["input=", "output="])
89
90 input_name = opts[0][1]
91 output_name = opts[1][1]
92 print 'Input file: ', input_name
93 print 'Output file: ', output_name
94
95 f_in = open(input_name, 'r')
96 f_out = open(output_name, 'w')
97
98 input = f_in.read()
99
100 output = compress(input)
101
102 # Write out the output
103 f_out.write(output)
104
105 # Close files
106 f_in.close()
107 f_out.close()
108
109 input_length = len(input)
110 output_length = len(output)
111
112 print 'Input length %i' % input_length
113 print 'Output length %i' % output_length
114 print 'Removed: %i' % (input_length - output_length)
115 print 'Compression: %.1f %%' % (100.0 - (output_length/input_length) * 100)
116
117 except getopt.GetoptError:
118 usage()
119 sys.exit(2)
120
121def usage():
122 print 'Usage: '
123 print '-i input_file'
124 print '-o output_File'
125
126if __name__ == "__main__":
127 main(sys.argv[1:])
Given an input and output file this script will perform the following minifcations:
  • Strips comments
  • Strip duplicate and unnecessary white-space
  • Strip duplicate semicolons
  • Strip the last semicolon in a block ';}' -> '}'
  • Convert colors to short-hand
  • Remove dead blocks (empty CSS directives)

It's quite ugly and was written in about two hours with no knowledge of regex. It should definitely be throughly cleaned up and tested.