我想我应该编写一个快速脚本来整合我在多个CSS文件中分发的CSS规则,然后我可以缩小它。
我对Python不熟悉,但我认为这是一个尝试新语言的好练习。我的主循环没有像我想象的那样解析CSS。
我用从css文件中解析的选择器填充一个列表,以按顺序返回css规则。在脚本的后面,列表包含字典中找不到的元素。
for line in self.file.readlines():
if self.hasSelector(line):
selector = self.getSelector(line)
if selector not in self.order:
self.order.append(selector)
elif selector and self.hasProperty(line):
# rules.setdefault(selector,[]).append(self.getProperty(line))
property = self.getProperty(line)
properties = [] if selector not in rules else rules[selector]
if property not in properties:
properties.append(property)
rules[selector] = properties
# print "%s :: %s" % (selector, "".join(rules[selector]))
return rules
遇到错误:
$ css-combine combined.css test1.css test2.css
Traceback (most recent call last):
File "css-combine", line 108, in <module>
c.run(outfile, stylesheets)
File "css-combine", line 64, in run
[(selector, rules[selector]) for selector in parser.order],
KeyError: 'p'
交换输入:
$ css-combine combined.css test2.css test1.css
Traceback (most recent call last):
File "css-combine", line 108, in <module>
c.run(outfile, stylesheets)
File "css-combine", line 64, in run
[(selector, rules[selector]) for selector in parser.order],
KeyError: '#header_.title'
我在代码中做了一些奇怪的事情,比如在字典键名中使用下划线的子空格,以防出现问题——也许这是一个良性的预防措施?根据输入顺序,在字典中找不到其他键。
剧本:
#!/usr/bin/env python
import optparse
import re
class CssParser:
def __init__(self):
self.file = False
self.order = [] # store rules assignment order
def parse(self, rules = {}):
if self.file == False:
raise IOError("No file to parse")
selector = False
for line in self.file.readlines():
if self.hasSelector(line):
selector = self.getSelector(line)
if selector not in self.order:
self.order.append(selector)
elif selector and self.hasProperty(line):
# rules.setdefault(selector,[]).append(self.getProperty(line))
property = self.getProperty(line)
properties = [] if selector not in rules else rules[selector]
if property not in properties:
properties.append(property)
rules[selector] = properties
# print "%s :: %s" % (selector, "".join(rules[selector]))
return rules
def hasSelector(self, line):
return True if re.search("^([#a-z,\.:\s]+){", line) else False
def getSelector(self, line):
s = re.search("^([#a-z,:\.\s]+){", line).group(1)
return "_".join(s.strip().split())
def hasProperty(self, line):
return True if re.search("^\s?[a-z-]+:[^;]+;", line) else False
def getProperty(self, line):
return re.search("([a-z-]+:[^;]+;)", line).group(1)
class Consolidator:
"""Class to consolidate CSS rule attributes"""
def run(self, outfile, files):
parser = CssParser()
rules = {}
for file in files:
try:
parser.file = open(file)
rules = parser.parse(rules)
except IOError:
print "Cannot read file: " + file
finally:
parser.file.close()
self.serialize(
[(selector, rules[selector]) for selector in parser.order],
outfile
)
def serialize(self, rules, outfile):
try:
f = open(outfile, "w")
for rule in rules:
f.write(
"%s {\n\t%s\n}\n\n" % (
" ".join(rule[0].split("_")), "\n\t".join(rule[1])
)
)
except IOError:
print "Cannot write output to: " + outfile
finally:
f.close()
def init():
op = optparse.OptionParser(
usage="Usage: %prog [options] <output file> <stylesheet1> " +
"<stylesheet2> ... <stylesheetN>",
description="Combine CSS rules spread across multiple " +
"stylesheets into a single file"
)
opts, args = op.parse_args()
if len(args) < 3:
if len(args) == 1:
print "Error: No input files specified.\n"
elif len(args) == 2:
print "Error: One input file specified, nothing to combine.\n"
op.print_help();
exit(-1)
return [opts, args]
if __name__ == '__main__':
opts, args = init()
outfile, stylesheets = [args[0], args[1:]]
c = Consolidator()
c.run(outfile, stylesheets)
测试CSS文件1:
body {
background-color: #e7e7e7;
}
p {
margin: 1em 0em;
}
文件2:
body {
font-size: 16px;
}
#header .title {
font-family: Tahoma, Geneva, sans-serif;
font-size: 1.9em;
}
#header .title a, #header .title a:hover {
color: #f5f5f5;
border-bottom: none;
text-shadow: 2px 2px 3px rgba(0, 0, 0, 1);
}
事先谢谢。