Я ищу простой скрипт Python, который может минимизировать CSS как часть процесса развертывания веб-сайта. (Python - единственный язык сценариев, поддерживаемый на сервере, и полнофункциональные парсеры, такие как CSS-утилиты, являются излишними для этого проекта).
В принципе, мне бы хотелось jsmin.py для CSS. Единый скрипт без зависимостей.
Есть идеи?






Я не знаю готовых минификаторов python css, но, как вы сказали, у css utils есть опция. После проверки и подтверждения того, что лицензия позволяет это, вы можете просмотреть исходный код и вырезать части, которые выполняют минимизацию самостоятельно. Затем вставьте это в один сценарий и вуаля! Вот и все.
Для начала, функция csscombine в ... / trunk / src / cssutils / script.py, похоже, выполняет работу по минимизации где-то около строки 361 (я проверил ревизию 1499). Обратите внимание на аргумент логической функции, называемый «minify».
Для меня это показалось хорошей задачей - освоить питон, который уже давно не решен. Настоящим я представляю свой первый скрипт на Python:
import sys, re
with open( sys.argv[1] , 'r' ) as f:
css = f.read()
# remove comments - this will break a lot of hacks :-P
css = re.sub( r'\s*/\*\s*\*/', "$$HACK1$$", css ) # preserve IE<6 comment hack
css = re.sub( r'/\*[\s\S]*?\*/', "", css )
css = css.replace( "$$HACK1$$", '/**/' ) # preserve IE<6 comment hack
# url() doesn't need quotes
css = re.sub( r'url\((["\'])([^)]*)\1\)', r'url(\2)', css )
# spaces may be safely collapsed as generated content will collapse them anyway
css = re.sub( r'\s+', ' ', css )
# shorten collapsable colors: #aabbcc to #abc
css = re.sub( r'#([0-9a-f])\1([0-9a-f])\2([0-9a-f])\3(\s|;)', r'#\1\2\3\4', css )
# fragment values can loose zeros
css = re.sub( r':\s*0(\.\d+([cm]m|e[mx]|in|p[ctx]))\s*;', r':\1;', css )
for rule in re.findall( r'([^{]+){([^}]*)}', css ):
# we don't need spaces around operators
selectors = [re.sub( r'(?<=[\[\(>+=])\s+|\s+(?=[=~^$*|>+\]\)])', r'', selector.strip() ) for selector in rule[0].split( ',' )]
# order is important, but we still want to discard repetitions
properties = {}
porder = []
for prop in re.findall( '(.*?):(.*?)(;|$)', rule[1] ):
key = prop[0].strip().lower()
if key not in porder: porder.append( key )
properties[ key ] = prop[1].strip()
# output rule if it contains any declarations
if properties:
print "%s{%s}" % ( ','.join( selectors ), ''.join(['%s:%s;' % (key, properties[key]) for key in porder])[:-1] )
Я верю, что это сработает, и результаты его тестов отлично подходят для недавних версий Safari, Opera и Firefox. Это сломает другие хаки CSS, кроме хаков подчеркивания и / ** /! Не используйте минификатор, если у вас много взломов (или поместите их в отдельный файл).
Любые советы по моему питону оценены. Пожалуйста, будь нежным, это мой первый раз. :-)
Спасибо за советы. Я исправил это и еще несколько вещей. Python - действительно хороший язык. :-)
просто потрясающе. Самое приятное, что теперь это будет частью сценария развертывания!
Это добавит лишние конечные точки с запятой, но не приведет к сокращению цветов. Если вы хотите сделать первое, вы можете просто сохранить результат в строке, а затем заменить (';}', '}'). Чтобы сделать это позже, вам нужно выполнить re.sub для '# ([0-9a-f] {6})' с обратным вызовом, который проверяет, находится ли цветовой код в форме #aabbcc, и возвращает #abc (или полная строка, если ее нельзя сократить).
Хорошие моменты. Я добавил еще несколько вещей: цвета, значения фрагментов с отсчетом от нуля, удаление пробелов вокруг операторов селектора и конечную точку с запятой. Это в тот момент, когда он начинает ломать вещи, например: div: content ("| = ") будет разделен на div: content ("| = "). Я думаю, что если вам нужно что-то еще, вы все равно должны использовать настоящий инструмент.
Хорошо сделано! Незначительная проблема: "Уменьшает" /* */ до /**/.
Спустя годы ... все еще полезно :) Теперь часть моего процесса сборки
@AtesGoral Почему это проблема?
Не буду педантичным - потому что это здорово - но не похоже, что это будет обрабатывать директивы CSS3 @.
div*{} - это синтаксическая ошибка. Быстрое решение - удалить звездочку из этого регулярного выражения.
Большое спасибо за то, что поделились, вы действительно сделали мой день.
Можно ли повторно использовать и изменять этот сценарий для других проектов с открытым исходным кодом?
Для python доступен порт компрессора CSS YUI.
Вот его страница проекта на PyPi: http://pypi.python.org/pypi/cssmin/0.1.1
К сожалению, больше не поддерживается.
Есть хороший онлайн-инструмент cssminifier, который также имеет довольно простой и легкий в использовании API. Я сделал небольшой скрипт на Python, который отправляет содержимое файла CSS в API этого инструмента, возвращает минимизированный CSS и сохраняет его в файл «style.min.css». Мне это нравится, потому что это небольшой код, который можно хорошо интегрировать в сценарий автоматического развертывания:
import requests
f = open("style.css", "r")
css_text = f.read()
f.close()
r = requests.post("http://cssminifier.com/raw", data = {"input":css_text})
css_minified = r.text
f2 = open("style.min.css", "w")
f2.write(css_minified)
f2.close()
С сайта cssminifier: cssminifier.com/python
У меня ошибка при отправке запросов на «http» url. «Https» URL-адреса cssminifier.com и javascript-minifier.com работают нормально.
Если кто-то столкнулся с этим вопросом и использует Django, для этого есть часто используемый пакет под названием Компрессор Django:
Compresses linked and inline JavaScript or CSS into a single cached file.
JS/CSS belong in the templates
Flexibility
It doesn’t get in the way
Full test suite
В документации веб-активы вы можете найти ссылки на несколько компрессоров и компиляторов. Из этого списка я выбрал pyScss, который также минимизирует результирующий CSS.
Если вам нужен только компрессор CSS, вы можете попробовать csscompressor:
Almost exact port of YUI CSS Compressor. Passes all original unittests.
Более общий инструмент - css-html-prettify:
StandAlone Async single-file cross-platform Unicode-ready Python3 Prettifier Beautifier for the Web.
Вы можете использовать индекс -1 для ссылки на последний элемент в последовательности. Таким образом, вы можете использовать .append () вместо .insert () и избежать .reverse (). Кроме того, если len (lst)> 0: обычно выполняется так, как если бы lst: