Скрипт Python для минимизации CSS?

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

В основном мне нужен jsmin.py для CSS. Один скрипт без зависимостей.

Любые идеи?


person Will Moffat    schedule 21.10.2008    source источник


Ответы (6)


Мне показалось, что это хорошая задача для изучения python, которая некоторое время откладывалась. Настоящим я представляю свой первый скрипт на 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, кроме хаков подчеркивания и /**/! Не используйте минификатор, если у вас много хаков (или поместите их в отдельный файл).

Любые советы по моему питону приветствуются. Пожалуйста, будьте нежны, это мой первый раз. :-)

person Borgar    schedule 21.10.2008
comment
Вы можете использовать индекс -1 для ссылки на последний элемент в последовательности. Таким образом, вы можете использовать .append() вместо .insert() и избегать .reverse(). Кроме того, если len(lst) › 0: обычно делается так, как если бы lst: - person recursive; 13.02.2009
comment
Спасибо за советы. Я исправил эти и некоторые другие вещи. Python действительно хороший язык. :-) - person Borgar; 15.02.2009
comment
просто потрясающе. Самое приятное то, что теперь это будет частью сценария развертывания! - person Soviut; 24.03.2009
comment
Это добавит лишние конечные точки с запятой, а не сократит цвета. Если вы хотите сделать первое, вы можете просто сохранить результат в строке, а затем заменить (';}','}'). Чтобы сделать это позже, вам нужно сделать re.sub на '#([0-9a-f]{6})' с обратным вызовом, который проверяет, имеет ли цветовой код форму #aabbcc и возвращает #abc (или полную строку, если ее нельзя сократить). - person Alan Plum; 29.09.2009
comment
Хорошие моменты. Я добавил еще несколько вещей: цвета, значения фрагментов, отсчитываемые от нуля, удаление пробелов вокруг операторов селектора и точку с запятой в конце. Однако это тот момент, когда он начинает ломать материал, например: div:content( |= ) будет разделен на div:content(|=). Я думаю, если вам нужно что-то еще, вы все равно должны использовать настоящий инструмент. - person Borgar; 29.09.2009
comment
Хорошо сделано! Незначительная проблема: уменьшает /* */ до /**/ - person Ates Goral; 14.04.2010
comment
Спустя годы .. все еще полезно :) Теперь часть моего процесса сборки - person Tim Post♦; 21.06.2011
comment
@AtesGoral Почему это проблема? - person Sophie Alpert; 01.07.2011
comment
Не буду педантичным — потому что это здорово — но не похоже, что это будет обрабатывать директивы CSS3 @. - person thom_nic; 30.08.2011
comment
нам не нужны пробелы вокруг операторов — по-видимому, иногда они нужны, потому что div*{} — это синтаксическая ошибка. Быстрое решение — удалить звездочку из этого регулярного выражения. - person Oleh Prypin; 04.02.2015
comment
Большое спасибо за то, что поделились, вы действительно сделали мой день. - person ; 05.02.2017
comment
Можно ли повторно использовать и изменять этот сценарий для других проектов с открытым исходным кодом? - person tjespe; 08.09.2017

Для Python доступен порт компрессора CSS YUI.

Вот его страница проекта на PyPi: http://pypi.python.org/pypi/cssmin/0.1.1

person Gregor Müllegger    schedule 07.03.2010
comment
К сожалению, больше не поддерживается. - person Wtower; 08.06.2015
comment
rCSSMin — еще один порт, который, похоже, поддерживается: github.com/ndparker/rcssmin - person Brutus; 16.06.2015

Существует хороший онлайн-инструмент 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()
person Yahya Yahyaoui    schedule 01.05.2015
comment
С сайта cssminifier: cssminifier.com/python - person nu everest; 09.12.2015
comment
Я получил ошибку, пытаясь отправить запросы на URL-адреса «http». URL-адреса «https» cssminifier.com и javascript-minifier.com работают нормально. - person Mikhail Gerasimov; 23.02.2016

На случай, если кто-то задаст этот вопрос и использует Django, для этого есть широко используемый пакет под названием Компрессор Джанго:

Сжимает связанный и встроенный JavaScript или CSS в один кэшированный файл.

  • JS/CSS принадлежат шаблонам

  • Гибкость

  • Это не мешает

  • Полный набор тестов

person Wtower    schedule 08.06.2015

Я не знаю каких-либо готовых минификаторов python css, но, как вы сказали, у css utils есть опция. После проверки и подтверждения того, что лицензия разрешает это, вы можете просмотреть исходный код и вырезать части, которые выполняют минимизацию самостоятельно. Затем вставьте это в один скрипт и вуаля! Ну вот.

В качестве форы функция csscombine в .../trunk/src/cssutils/script.py, кажется, выполняет работу по минимизации где-то в строке 361 (я проверил ревизию 1499). Обратите внимание на аргумент логической функции под названием «minify».

person Jeffrey Martinez    schedule 21.10.2008

В документах webassets вы можете найти ссылки на несколько компрессоров и компиляторов. . Из этого списка я выбрал pyScss, который также минимизирует результирующий CSS.

Если вам нужен только компрессор CSS, вы можете попробовать csscompressor:

Почти точный порт YUI CSS Compressor. Проходит все оригинальные юнит-тесты.

Более общий инструмент — css-html-prettify:

Автономный асинхронный однофайловый кроссплатформенный Python3 Prettifier Beautifier Beautifier для Интернета с поддержкой Unicode.

person alexandrul    schedule 21.12.2015