From c3e77d14a49d52a6eb28b28bea9982a146e5492b Mon Sep 17 00:00:00 2001 From: Mike Crute Date: Sat, 16 Jan 2010 22:54:36 -0500 Subject: Initial import --- CSSParser.py | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cmpcss | 125 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 280 insertions(+) create mode 100755 CSSParser.py create mode 100755 cmpcss diff --git a/CSSParser.py b/CSSParser.py new file mode 100755 index 0000000..72c643e --- /dev/null +++ b/CSSParser.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python + +import sys, re + +class CSSUtils: + ColorRegex = re.compile('', re.I | re.M | re.U) + + @staticmethod + def compress_color(color): + pass + + @staticmethod + def is_color(color): + pass + +class CSSContainer: + selector = '' + + def __init__(self): + pass + +class CSSParser: + ValidProperties = ( + 'azimuth', + 'background', + 'background-color', + 'background-image', + 'background-repeat', + 'background-attachment', + 'background-position', + 'border', + 'border-top', + 'border-right', + 'border-left', + 'border-bottom', + 'border-color', + 'border-top-color', + 'border-right-color', + 'border-bottom-color', + 'border-left-color', + 'border-style', + 'border-top-style', + 'border-right-style', + 'border-bottom-style', + 'border-left-style', + 'border-width', + 'border-top-width', + 'border-left-width', + 'border-right-width', + 'border-bottom-width', + 'border-collapse', + 'border-spacing', + 'bottom', + 'clear', + 'clip', + 'color', + 'cursor', + 'direction', + 'display', + 'float', + 'font', + 'font-family', + 'font-size', + 'font-style', + 'font-variant', + 'font-weight', + 'height', + 'left', + 'letter-spacing', + 'line-height', + 'list-style', + 'list-style-image', + 'list-style-position', + 'list-style-type', + 'margin', + 'margin-top', + 'margin-right', + 'margin-bottom', + 'margin-left', + 'marker-offset', + 'marks', + 'overflow', + 'padding', + 'padding-top', + 'padding-bottom', + 'padding-right', + 'padding-left', + 'page-break-before', + 'position', + 'right', + 'size', + 'src', + 'table-layout', + 'text-align', + 'text-decoration', + 'text-indent', + 'text-transform', + 'top', + 'vertical-align', + 'visibility', + 'white-space', + 'width', + 'z-index' + ) + + CSSRegex = re.compile(r'([^{]+)\s?{\s?([^}]*)\s?}', re.I | re.M | re.U) + PropertyRegex = re.compile(r'([^:]+):([^;]+);', re.I | re.M | re.U) + CommentRegex = re.compile(r'/\*(.|[\r\n])*?\*/', re.I | re.M | re.U) + + def __init__(self): + pass + + def parse(self): + pass + + def duplicate_check(self): + pass + +def load_file(filename): + """ Loads a file line by line into a variable and returns it.""" + infile = '' + + try: + theFile = file(filename, "r") + except IOError: + sys.exit() + + for line in theFile: + infile += line + + return infile + +if __name__ == '__main__': + output = CSSParser.CommentRegex.sub(' ', load_file(sys.argv[1])) + output = CSSParser.CSSRegex.findall(output) + + containers = 0 + errors = 0 + + for item in output: + containers += 1 + properties = re.sub('\s+', ' ', item[1]) + proparray = CSSParser.PropertyRegex.findall(properties) + container = item[0].strip() + + #print "Container: %s" % item[0].strip() + #print "Contents: %s" % properties + print "Property Array: %s \n\n" % proparray + + for item in proparray: + if item[0].strip().lower() not in CSSParser.ValidProperties: + errors += 1 + print "WARNING: Invalid property '%s' in container '%s'" % (item[0].strip(), container) + + 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 @@ +#!/usr/bin/python +############### +# cmpcss +# Compress a CSS file in prepration for production use. +# +# AUTHOR +# Michael Crute (mcrute@gmail.com) +# DATE +# 16 June 2006 +# VERSION +# 1.0 +# PURPOSE +# An implementation of a CSS compressor in Python. Written to +# prepare development CSS to production ready CSS. Does the +# following: +# * Removes spaces intelligently +# * Removes charset declarations +# * Removes extra semicolons +# * Flattens the file (tabs and line breaks) +# USAGE +# cmpcss site_dev.css > site_prod.css +# LICENSE +# You may copy and redistribute this program as you see fit, with no +# restrictions. +# WARRANTY +# This program comes with NO warranty, real or implied. If it eats +# your CSS, it's not my problem, you should have kept a backup. +############### + +import sys +import re +#import string + +# The chewy caramel center of the program +# Don't bitch about the short variable names, it makes it easy to read +def cleanline(theLine): + # Kills line breaks, tabs, and double spaces + p = re.compile('(\n|\r|\t|\f|\v)+') + m = p.sub('',theLine) + + # Kills double spaces + p = re.compile('( )+') + m = p.sub(' ',m) + + # Removes last semicolon before } + p = re.compile('(; }|;})+') + m = p.sub('}',m) + + # Removes space before { + p = re.compile('({ )+') + m = p.sub('{',m) + + # Removes all comments + p = re.compile('/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/') + m = p.sub('',m) + + # Strip off the Charset + p = re.compile('@CHARSET .*;') + m = p.sub('',m) + + # Strip spaces before the { + p = re.compile(' {') + m = p.sub('{',m) + + # Strip space after : + p = re.compile(': ') + m = p.sub(':',m) + + # Strip space after , + p = re.compile(', ') + m = p.sub(',',m) + + # Strip space after ; + p = re.compile('; ') + m = p.sub(';',m) + +# May return to add color code compression +# not a huge space saver so also not high priority +# p = re.compile('.*#[0-9A-F]{6}.*') +# cc = p.match(m) + +# if cc: +# cc = compcolor(m) + + return m + +#def compcolor(m): + +# Boring usage info for people too dumb to use the program +def printusage(): + print '' + print 'SoftGroup CSS Compressor' + print '' + print 'This is a compressor for CSS files.' + print 'As far as I know it doesn\'t break the standards' + print 'compliance of the file. If you can find a way' + print 'to make it break a file please email me.' + print '' + print 'Usage: cmpcss ' + sys.exit() + +# The main routine +if ( __name__ == "__main__" ): + if (len(sys.argv) <= 1): + printusage() + + # Open the file for reading + try: + theFile = file(sys.argv[1], "r") + except IOError: + print 'I couldn\'t open your file.' + sys.exit() + + # Initialize temp so it's not scoped to the for loop + temp = '' + + # Loop through the file line by line and clean it + for line in theFile: + temp = temp + cleanline(line) + + # Once more, clean the entire file string + print cleanline(temp) + + # Cleanup after ourselves + theFile.close() -- cgit v1.2.3