105 lines
2.8 KiB
Python
105 lines
2.8 KiB
Python
#!/usr/bin/env python
|
|
# Copyright 2016 The Chromium Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
import re
|
|
import sys
|
|
|
|
class CSSMinimizer(object):
|
|
|
|
INITIAL = 0
|
|
MAYBE_COMMENT_START = 1
|
|
INSIDE_COMMENT = 2
|
|
MAYBE_COMMENT_END = 3
|
|
INSIDE_SINGLE_QUOTE = 4
|
|
INSIDE_SINGLE_QUOTE_ESCAPE = 5
|
|
INSIDE_DOUBLE_QUOTE = 6
|
|
INSIDE_DOUBLE_QUOTE_ESCAPE = 7
|
|
|
|
def __init__(self):
|
|
self._output = ''
|
|
self._codeblock = ''
|
|
|
|
def flush_codeblock(self):
|
|
stripped = re.sub(r"\s+", ' ', self._codeblock)
|
|
stripped = re.sub(r";?\s*(?P<op>[{};])\s*", r'\g<op>', stripped)
|
|
self._output += stripped
|
|
self._codeblock = ''
|
|
|
|
def parse(self, content):
|
|
state = self.INITIAL
|
|
for char in content:
|
|
if state == self.INITIAL:
|
|
if char == '/':
|
|
state = self.MAYBE_COMMENT_START
|
|
elif char == "'":
|
|
self.flush_codeblock()
|
|
self._output += char
|
|
state = self.INSIDE_SINGLE_QUOTE
|
|
elif char == '"':
|
|
self.flush_codeblock()
|
|
self._output += char
|
|
state = self.INSIDE_DOUBLE_QUOTE
|
|
else:
|
|
self._codeblock += char
|
|
elif state == self.MAYBE_COMMENT_START:
|
|
if char == '*':
|
|
self.flush_codeblock()
|
|
state = self.INSIDE_COMMENT
|
|
else:
|
|
self._codeblock += '/' + char
|
|
state = self.INITIAL
|
|
elif state == self.INSIDE_COMMENT:
|
|
if char == '*':
|
|
state = self.MAYBE_COMMENT_END
|
|
else:
|
|
pass
|
|
elif state == self.MAYBE_COMMENT_END:
|
|
if char == '/':
|
|
state = self.INITIAL
|
|
else:
|
|
state = self.INSIDE_COMMENT
|
|
elif state == self.INSIDE_SINGLE_QUOTE:
|
|
if char == '\\':
|
|
self._output += char
|
|
state = self.INSIDE_SINGLE_QUOTE_ESCAPE
|
|
elif char == "'":
|
|
self._output += char
|
|
state = self.INITIAL
|
|
else:
|
|
self._output += char
|
|
elif state == self.INSIDE_SINGLE_QUOTE_ESCAPE:
|
|
self._output += char
|
|
state = self.INSIDE_SINGLE_QUOTE
|
|
elif state == self.INSIDE_DOUBLE_QUOTE:
|
|
if char == '\\':
|
|
self._output += char
|
|
state = self.INSIDE_DOUBLE_QUOTE_ESCAPE
|
|
elif char == '"':
|
|
self._output += char
|
|
state = self.INITIAL
|
|
else:
|
|
self._output += char
|
|
elif state == self.INSIDE_DOUBLE_QUOTE_ESCAPE:
|
|
self._output += char
|
|
state = self.INSIDE_DOUBLE_QUOTE
|
|
|
|
self.flush_codeblock()
|
|
self._output = self._output.strip()
|
|
return self._output
|
|
|
|
@classmethod
|
|
def minimize_css(cls, content):
|
|
minimizer = CSSMinimizer()
|
|
return minimizer.parse(content)
|
|
|
|
def main():
|
|
result = ''
|
|
try:
|
|
result = CSSMinimizer.minimize_css(sys.stdin.read())
|
|
finally:
|
|
print(result)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|