summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xCSSParser.py155
-rwxr-xr-xcmpcss125
2 files changed, 280 insertions, 0 deletions
diff --git a/CSSParser.py b/CSSParser.py
new file mode 100755
index 0000000..72c643e
--- /dev/null
+++ b/CSSParser.py
@@ -0,0 +1,155 @@
1#!/usr/bin/env python
2
3import sys, re
4
5class CSSUtils:
6 ColorRegex = re.compile('', re.I | re.M | re.U)
7
8 @staticmethod
9 def compress_color(color):
10 pass
11
12 @staticmethod
13 def is_color(color):
14 pass
15
16class CSSContainer:
17 selector = ''
18
19 def __init__(self):
20 pass
21
22class CSSParser:
23 ValidProperties = (
24 'azimuth',
25 'background',
26 'background-color',
27 'background-image',
28 'background-repeat',
29 'background-attachment',
30 'background-position',
31 'border',
32 'border-top',
33 'border-right',
34 'border-left',
35 'border-bottom',
36 'border-color',
37 'border-top-color',
38 'border-right-color',
39 'border-bottom-color',
40 'border-left-color',
41 'border-style',
42 'border-top-style',
43 'border-right-style',
44 'border-bottom-style',
45 'border-left-style',
46 'border-width',
47 'border-top-width',
48 'border-left-width',
49 'border-right-width',
50 'border-bottom-width',
51 'border-collapse',
52 'border-spacing',
53 'bottom',
54 'clear',
55 'clip',
56 'color',
57 'cursor',
58 'direction',
59 'display',
60 'float',
61 'font',
62 'font-family',
63 'font-size',
64 'font-style',
65 'font-variant',
66 'font-weight',
67 'height',
68 'left',
69 'letter-spacing',
70 'line-height',
71 'list-style',
72 'list-style-image',
73 'list-style-position',
74 'list-style-type',
75 'margin',
76 'margin-top',
77 'margin-right',
78 'margin-bottom',
79 'margin-left',
80 'marker-offset',
81 'marks',
82 'overflow',
83 'padding',
84 'padding-top',
85 'padding-bottom',
86 'padding-right',
87 'padding-left',
88 'page-break-before',
89 'position',
90 'right',
91 'size',
92 'src',
93 'table-layout',
94 'text-align',
95 'text-decoration',
96 'text-indent',
97 'text-transform',
98 'top',
99 'vertical-align',
100 'visibility',
101 'white-space',
102 'width',
103 'z-index'
104 )
105
106 CSSRegex = re.compile(r'([^{]+)\s?{\s?([^}]*)\s?}', re.I | re.M | re.U)
107 PropertyRegex = re.compile(r'([^:]+):([^;]+);', re.I | re.M | re.U)
108 CommentRegex = re.compile(r'/\*(.|[\r\n])*?\*/', re.I | re.M | re.U)
109
110 def __init__(self):
111 pass
112
113 def parse(self):
114 pass
115
116 def duplicate_check(self):
117 pass
118
119def load_file(filename):
120 """ Loads a file line by line into a variable and returns it."""
121 infile = ''
122
123 try:
124 theFile = file(filename, "r")
125 except IOError:
126 sys.exit()
127
128 for line in theFile:
129 infile += line
130
131 return infile
132
133if __name__ == '__main__':
134 output = CSSParser.CommentRegex.sub(' ', load_file(sys.argv[1]))
135 output = CSSParser.CSSRegex.findall(output)
136
137 containers = 0
138 errors = 0
139
140 for item in output:
141 containers += 1
142 properties = re.sub('\s+', ' ', item[1])
143 proparray = CSSParser.PropertyRegex.findall(properties)
144 container = item[0].strip()
145
146 #print "Container: %s" % item[0].strip()
147 #print "Contents: %s" % properties
148 print "Property Array: %s \n\n" % proparray
149
150 for item in proparray:
151 if item[0].strip().lower() not in CSSParser.ValidProperties:
152 errors += 1
153 print "WARNING: Invalid property '%s' in container '%s'" % (item[0].strip(), container)
154
155 print "---\n\nFound %s containers and %s errors" % (containers, errors)
diff --git a/cmpcss b/cmpcss
new file mode 100755
index 0000000..d347a63
--- /dev/null
+++ b/cmpcss
@@ -0,0 +1,125 @@
1#!/usr/bin/python
2###############
3# cmpcss
4# Compress a CSS file in prepration for production use.
5#
6# AUTHOR
7# Michael Crute (mcrute@gmail.com)
8# DATE
9# 16 June 2006
10# VERSION
11# 1.0
12# PURPOSE
13# An implementation of a CSS compressor in Python. Written to
14# prepare development CSS to production ready CSS. Does the
15# following:
16# * Removes spaces intelligently
17# * Removes charset declarations
18# * Removes extra semicolons
19# * Flattens the file (tabs and line breaks)
20# USAGE
21# cmpcss site_dev.css > site_prod.css
22# LICENSE
23# You may copy and redistribute this program as you see fit, with no
24# restrictions.
25# WARRANTY
26# This program comes with NO warranty, real or implied. If it eats
27# your CSS, it's not my problem, you should have kept a backup.
28###############
29
30import sys
31import re
32#import string
33
34# The chewy caramel center of the program
35# Don't bitch about the short variable names, it makes it easy to read
36def cleanline(theLine):
37 # Kills line breaks, tabs, and double spaces
38 p = re.compile('(\n|\r|\t|\f|\v)+')
39 m = p.sub('',theLine)
40
41 # Kills double spaces
42 p = re.compile('( )+')
43 m = p.sub(' ',m)
44
45 # Removes last semicolon before }
46 p = re.compile('(; }|;})+')
47 m = p.sub('}',m)
48
49 # Removes space before {
50 p = re.compile('({ )+')
51 m = p.sub('{',m)
52
53 # Removes all comments
54 p = re.compile('/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/')
55 m = p.sub('',m)
56
57 # Strip off the Charset
58 p = re.compile('@CHARSET .*;')
59 m = p.sub('',m)
60
61 # Strip spaces before the {
62 p = re.compile(' {')
63 m = p.sub('{',m)
64
65 # Strip space after :
66 p = re.compile(': ')
67 m = p.sub(':',m)
68
69 # Strip space after ,
70 p = re.compile(', ')
71 m = p.sub(',',m)
72
73 # Strip space after ;
74 p = re.compile('; ')
75 m = p.sub(';',m)
76
77# May return to add color code compression
78# not a huge space saver so also not high priority
79# p = re.compile('.*#[0-9A-F]{6}.*')
80# cc = p.match(m)
81
82# if cc:
83# cc = compcolor(m)
84
85 return m
86
87#def compcolor(m):
88
89# Boring usage info for people too dumb to use the program
90def printusage():
91 print ''
92 print 'SoftGroup CSS Compressor'
93 print ''
94 print 'This is a compressor for CSS files.'
95 print 'As far as I know it doesn\'t break the standards'
96 print 'compliance of the file. If you can find a way'
97 print 'to make it break a file please email me.'
98 print ''
99 print 'Usage: cmpcss <filename>'
100 sys.exit()
101
102# The main routine
103if ( __name__ == "__main__" ):
104 if (len(sys.argv) <= 1):
105 printusage()
106
107 # Open the file for reading
108 try:
109 theFile = file(sys.argv[1], "r")
110 except IOError:
111 print 'I couldn\'t open your file.'
112 sys.exit()
113
114 # Initialize temp so it's not scoped to the for loop
115 temp = ''
116
117 # Loop through the file line by line and clean it
118 for line in theFile:
119 temp = temp + cleanline(line)
120
121 # Once more, clean the entire file string
122 print cleanline(temp)
123
124 # Cleanup after ourselves
125 theFile.close()