Jugando con python: CSSmin
Me gusta jugar.
Un día, se me ocurrió retomar mis juegos con python que había dejado por jugar con otras cosas. Pensé en hacer un editor de código pero era demasiado ambicioso para mi xD
Así que hice un script para minimizar css y aprender en el camino algo de python.
¿Qué no hay cosos hechos para minimizar CSS?
Sí, pero no hay nada como hacer algo tu mismo ñ_ñ.
Bueno, una noche saque a komodo Edit de su arena de juegos y “metimos las manos en la obra”
.
El script debería no sólo minimizar CSS quitando saltos de línea y espacios sobrantes. Sino que debería incluir CSS que sean importados con la propiedad “@import”.
De esa forma puedo tener un archivo principal que importe todas las demás hojas de estilo y luego, al terminar, minimizar todo usando algo así como:
cssmin media/css/main.css
Y de un plumazo hacer un “merge” de todos los estilos.
Este script está pensado para ser usado en línea de comandos. Como trabajo en windows, era necesario un archivo “.bat” para poder usarlo en cualquier parte del árbol de carpetas.
cssmin.bat
@echo off
python d:\jos\bin\cssmin.py %*
En este caso mis scripts los pongo en una carpeta llamada bin, dentro de mi carpeta personal en la unidad d.
Para poder llamar a cssmin.bat en cualquier parte del árbol del sistema de windows, es necesario agregar la ruta completa donde está cssmin.bat a la variable “path” del sistema.
Agregando ruta de cssmin.bat a la variable path de windows
Para hacer esto hay que seguir los siguientes pasos.
- Click botón derecho sobre “MI PC” y elegir propiedades. Esto lanzara una ventana.
- En la ventana que fue lanzada, elegir la pestaña “Opciones Avanzadas” y luego pulsar el botón “variables de entorno”. Saltará una nueva ventana.
- En la ventana de titulo “variables de entorno” buscar en el listado “variables del sistema” la variable “path” y pulsar el botón “modificar”. Nos saltará otra ventana
- En la ventana para modificar la variable “path” en el campo “valor de variable”, copiaremos la ruta hasta la carpeta donde esta el cssmin.bat. No olvidando agregar un punto y coma “;” al final de nuestra ruta. Ya que cada ruta es separada por un “;”
- Luego es aceptar, aplicar, aceptar… etc, etc, etc.
Con esto deberíamos poder usar el cssmin.bat desde la consola.
CSSmin
CSSmin solo puede importar estilos que este declarados así: “@import url(css/blog.css)” <- sin comillas.
Otra cosa, los archivos css deben estar en UTF-8 y con salto de línea UNIX ... xD es que no he probado con otro tipos de archivos y así es como trabajo yo
Acá el código.
#!/usr/bin/env python
import sys
import re
info = “”"/** cssmin 0.1b por Jose Ayon **/”"”
def getname(path):
“”"
Devuelve una lista con el path y el nombre del archivo.
“”"
try:
fname = fpath = path
# obtenemos el nombre del archivo
c = re.compile(‘/’)
if(c.search(fname) != None):
n = c.split(fname)
else:
n = fname.split(‘\\’)
n.reverse()
n = n[0]
# optenemos el path hacia el archivo
cpl = re.compile(n)
p = cpl.sub(”,fpath)
return [p,n]
except:
print ‘error getname’
def read(path):
“”"Lee un archivo y retorna el contenido”"”
try:
f = open(path,’r')
r = f.read()
f.close()
return r
except:
print ‘error read’
def clean(string):
“”"
Limpia de comentarios saltos de linea y espacios sobrantes en la cadena.
Borra tambien los import css. Retorna la cadena “limpia”
“”"
#try:
# quitando elementos sobrantes
comment = ‘\/\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/’ # /* comentarios */
imports = ‘@import url\(.+\);’ # imports css
# compile search, al compilar el patron de busqueda se aumenta el rendimiento
cls = re.compile(‘\n|\t|’+comment+’|'+imports) # saltos de linea, tabs, comentarios e imports
keys = re.compile(‘{\s+’) # espacios luego de las llaves de apertura llaves
comas = re.compile(‘;\s+’) # espacios luego de las comas
lineas = cls.sub(”,string)
lineas = keys.sub(‘{‘,lineas)
lineas = comas.sub(‘;’,lineas)
return lineas
#except:
#print “error clean”
def cssmin(path):
“”"
cssmin(path) -> void:
argumento path, string, path al archivo css a minimizar
Crea una copia del original siguiendo la siguiente estructura
“src.file.css”.
No se crea copia de los archivos css importados en el archivo css actual.
Lee el contenido buscando imports css.
Luego incluye el contenido de estos archivos al archivo css actual y escribe comentarios de los
imports css para poder reconstruir el con sus imports sin necesidad de editar el archivo
original
“”"
#try:
# obtenemos el nombre y el path del archivo
fopt = getname(path)
fpath = fopt[0] # path
fname = fopt[1] # nombre
# abrimos archivo actual y extraemos su contenidos
f = open(path,’U')
completo = f.read()
f.close()
# obteniendo todos los paths css incluidos en el archivo actual
paths = re.findall(‘@import url\((.+)\);’,completo)
# creamos archivo minimizado
w = open(fpath + ‘min.’ + fname,’w')
w.writelines(info+’\n’) # info de cssmin
# volcando el contenido de cada archivo importado y del archivo actual
for i in paths:
w.writelines(“/*** @import url(‘”+ i +”‘); ***/\n”) # escribiendo referencia
w.writelines(clean(read(fpath +i))+’\n’) # volcando datos
# volcando archivo actual
w.writelines(“/*** “+ fname +” ***/\n”)
w.writelines(clean(completo))
w.close()
#except:
#print ‘error cssmin’
def main(argv):
argv.pop(0)
if(len(argv)>1):
for i in argv:
print i
cssmin(i)
else:
cssmin(argv[0])
if(len(sys.argv) > 1):
main(sys.argv)
else:
print ‘Debes indicar el nombre del archivo’
Este script es superArchiMulti_mejorable, pero funciona hasta ahora y le haré mejoras. Ahora quiero que no solo minimice CSS sino que también lo haga con javascript. Que pueda hacer "merge" de dos o más hojas de estilo sin depender de los "@import". Que pueda buscar más formas de escribir "@import" en css y que no dependa de la codificación o el salto de línea
.
En la actualidad hay sin fin de herramientas que hacen este tipo de cosas pero como ya dije, no hay nada como jugar un rato y hacer algo tu mismo.
Por cierto, para que esto funcione (si alguien se anima a usarlo) deben tener python 2.5 o superior instalado en windows. aunque creo que no estoy seguro si funciona en python 3
Saludos.

















