License Public Domain
Lines 107
Keywords
css (7)
Permissions
Owner: Stou S.
Viewable by Everyone
Editable by All Siafoo Users

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.