Commit dceb9f2c by andreas.pelme

Added a filter with the Python port of CSSTidy by Dj Gilcrease (from django-assetpackager).


git-svn-id: https://django-compress.googlecode.com/svn/trunk@66 98d35234-f74b-0410-9e22-51d878bdf110
parent 80d68e3d
from django.conf import settings
from compress.filter_base import FilterBase
from compress.filters.csstidy.csstidy import CSSTidy
COMPRESS_CSSTIDY_SETTINGS = getattr(settings, 'COMPRESS_CSSTIDY_SETTINGS', {})
class CSSTidyFilter(FilterBase):
def filter_css(self, css):
tidy = CSSTidy()
for k, v in COMPRESS_CSSTIDY_SETTINGS.items():
tidy.setSetting(k, v)
tidy.parse(css)
r = tidy.Output('string')
return r
# CSSTidy - CSS Printer
#
# CSS Printer class
#
# This file is part of CSSTidy.
#
# CSSTidy is free software you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation either version 2 of the License, or
# (at your option) any later version.
#
# CSSTidy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with CSSTidy if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# @license http://opensource.org/licenses/gpl-license.php GNU Public License
# @package csstidy
# @author Dj Gilcrease (digitalxero at gmail dot com) 2005-2006
import data
class CSSPrinter(object):
def __init__(self, parser):
self.parser = parser
self._css = {}
self.__renderMethods = {'string': self.__renderString, 'file': self.__renderFile}
#PUBLIC METHODS
def prepare(self, css):
self._css = css
def render(self, output="string", *args, **kwargs):
return self.__renderMethods[output](*args, **kwargs)
#PRIVATE METHODS
def __renderString(self, *args, **kwargs):
##OPTIMIZE##
template = self.parser.getSetting('template')
ret = ""
if template == 'highest_compression':
top_line_end = ""
iner_line_end = ""
bottom_line_end = ""
indent = ""
elif template == 'high_compression':
top_line_end = "\n"
iner_line_end = ""
bottom_line_end = "\n"
indent = ""
elif template == 'default':
top_line_end = "\n"
iner_line_end = "\n"
bottom_line_end = "\n\n"
indent = ""
elif template == 'low_compression':
top_line_end = "\n"
iner_line_end = "\n"
bottom_line_end = "\n\n"
indent = " "
if self.parser.getSetting('timestamp'):
ret += '/# CSSTidy ' + self.parser.version + ': ' + datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000") + ' #/' + top_line_end
for item in self.parser._import:
ret += '@import(' + item + ');' + top_line_end
for item in self.parser._charset:
ret += '@charset(' + item + ');' + top_line_end
for item in self.parser._namespace:
ret += '@namespace(' + item + ');' + top_line_end
for media, css in self._css.iteritems():
for selector, cssdata in css.iteritems():
ret += selector + '{' + top_line_end
for item, value in cssdata.iteritems():
ret += indent + item + ':' + value + ';' + iner_line_end
ret += '}' + bottom_line_end
return ret
def __renderFile(self, filename=None, *args, **kwargs):
if filename is None:
return self.__renderString()
try:
f = open(filename, "w")
f.write(self.__renderString())
finally:
f.close()
\ No newline at end of file
class SortedDict(dict):
"""
A dictionary that keeps its keys in the order in which they're inserted.
"""
def __init__(self, data=None):
if data is None:
data = {}
super(SortedDict, self).__init__(data)
if isinstance(data, dict):
self.keyOrder = data.keys()
else:
self.keyOrder = []
for key, value in data:
if key not in self.keyOrder:
self.keyOrder.append(key)
def __deepcopy__(self, memo):
from copy import deepcopy
return self.__class__([(key, deepcopy(value, memo))
for key, value in self.iteritems()])
def __setitem__(self, key, value):
super(SortedDict, self).__setitem__(key, value)
if key not in self.keyOrder:
self.keyOrder.append(key)
def __delitem__(self, key):
super(SortedDict, self).__delitem__(key)
self.keyOrder.remove(key)
def __iter__(self):
for k in self.keyOrder:
yield k
def pop(self, k, *args):
result = super(SortedDict, self).pop(k, *args)
try:
self.keyOrder.remove(k)
except ValueError:
# Key wasn't in the dictionary in the first place. No problem.
pass
return result
def popitem(self):
result = super(SortedDict, self).popitem()
self.keyOrder.remove(result[0])
return result
def items(self):
return zip(self.keyOrder, self.values())
def iteritems(self):
for key in self.keyOrder:
yield key, super(SortedDict, self).__getitem__(key)
def keys(self):
return self.keyOrder[:]
def iterkeys(self):
return iter(self.keyOrder)
def values(self):
return [super(SortedDict, self).__getitem__(k) for k in self.keyOrder]
def itervalues(self):
for key in self.keyOrder:
yield super(SortedDict, self).__getitem__(key)
def update(self, dict_):
for k, v in dict_.items():
self.__setitem__(k, v)
def setdefault(self, key, default):
if key not in self.keyOrder:
self.keyOrder.append(key)
return super(SortedDict, self).setdefault(key, default)
def value_for_index(self, index):
"""Returns the value of the item at the given zero-based index."""
return self[self.keyOrder[index]]
def insert(self, index, key, value):
"""Inserts the key, value pair before the item with the given index."""
if key in self.keyOrder:
n = self.keyOrder.index(key)
del self.keyOrder[n]
if n < index:
index -= 1
self.keyOrder.insert(index, key)
super(SortedDict, self).__setitem__(key, value)
def copy(self):
"""Returns a copy of this object."""
# This way of initializing the copy means it works for subclasses, too.
obj = self.__class__(self)
obj.keyOrder = self.keyOrder[:]
return obj
def __repr__(self):
"""
Replaces the normal dict.__repr__ with a version that returns the keys
in their sorted order.
"""
return '{%s}' % ', '.join(['%r: %r' % (k, v) for k, v in self.items()])
def clear(self):
super(SortedDict, self).clear()
self.keyOrder = []
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment