GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • The Python Code
  • Tutorials
  • Ethical Hacking
  • Machine Learning
  • General Python Tutorials
  • Web Scraping
  • Finance
  • Computer Vision
  • Python Standard Library
  • Application Programming Interfaces
  • Database
  • Game Development
  • Web Programming
  • Digital Forensics

This view

  • Original page
  • New address

GeezerVison is showing thepythoncode.com — Code for How to Minify CSS with Python - Python Code


Code for How to Minify CSS with Python


View on Github

minify_css_tutorial.py

import cssutils
import re
import logging
import os
import time
cssutils.log.setLevel(logging.CRITICAL)

startTime = time.time()
os.system('cls')

def getFilesByExtension(ext, root):
    foundFiles = []
    for root, directories, files in os.walk(root):
        for f in files:
            if f.endswith(ext):
                # os.path.join(root, f) is the full path to the file
                foundFiles.append(os.path.join(root, f)) 
    return foundFiles


def flattenStyleSheet(sheet):
    ruleList = []
    for rule in sheet.cssRules:
        if rule.typeString == 'MEDIA_RULE':
            ruleList += rule.cssRules
        elif rule.typeString == 'STYLE_RULE':
            ruleList.append(rule)
    return ruleList


def findAllCSSClasses():
    usedClasses = {}
    # Find all used classes
    for htmlFile in htmlFiles:
        with open(htmlFile, 'r') as f:
            htmlContent = f.read()
        regex = r'class="(.*?)"'
        # re.DOTALL is needed to match newlines
        matched = re.finditer(regex, htmlContent, re.MULTILINE | re.DOTALL) 
        # matched is a list of re.Match objects
        for i in matched:
            for className in i.groups()[0].split(' '): # i.groups()[0] is the first group in the regex
                usedClasses[className] = ''
    return list(usedClasses.keys())


def translateUsedClasses(classList):
    for i, usedClass in enumerate(classList):
        for translation in translations:
            # If the class is found in the translations list, replace it
            regex = translation[0]
            subst = translation[1]
            if re.search(regex, usedClass):
                # re.sub() replaces the regex with the subst
                result = re.sub(regex, subst, usedClass, 1, re.MULTILINE) # 1 is the max number of replacements
                # Replace the class in the list
                classList[i] = result
    return classList


htmlFiles = getFilesByExtension('.html', '.')

cssFiles = getFilesByExtension('.css', 'style')

# Use Translations if the class names in the Markup dont exactly 
# match the CSS Selector ( Except for the dot at the begining. )
translations = [
    [
        '@',
        '\\@'
    ],
    [
        r"(.*?):(.*)",
        r"\g<1>\\:\g<2>:\g<1>",
    ],
    [
        r"child(.*)",
        "child\\g<1> > *",
    ],
]

usedClasses = findAllCSSClasses()
usedClasses = translateUsedClasses(usedClasses)

output = 'min.css'

newCSS = ''

for cssFile in cssFiles:
    # Parse the CSS File
    sheet = cssutils.parseFile(cssFile)
    rules = flattenStyleSheet(sheet)
    noClassSelectors = []
    for rule in rules:
        for usedClass in usedClasses:
            if '.' + usedClass == rule.selectorText:
                # If the class is used in the HTML, add it to the new CSS
                usedClasses.remove(usedClass) # Remove the class from the list
                if rule.parentRule:
                    newCSS += str(rule.parentRule.cssText)
                else:
                    newCSS += str(rule.cssText)
        if rule.selectorText[0] != '.' and not rule.selectorText in noClassSelectors: 
            # If the selector doesnt start with a dot and is not already in the list,
            # add it
            noClassSelectors.append(rule.selectorText)
            if rule.parentRule:
                newCSS += str(rule.parentRule.cssText)
            else:
                newCSS += str(rule.cssText)

newCSS = newCSS.replace('\n', '')
newCSS = newCSS.replace('  ', '')

with open(output, 'w') as f:
    f.write(newCSS)


print('TIME: ', time.time() - startTime)
Ethical Hacking with Python EBook - Author - Top

Get our free Python guides

Join 50,000+ Python programmers and enthusiasts like you!

Topics
Ethical Hacking Machine Learning General Python Tutorials Web Scraping Finance Computer Vision Python Standard Library Application Programming Interfaces Database Game Development Web Programming Digital Forensics Natural Language Processing Healthcare PDF File Handling Python for Multimedia GUI Programming Cryptography Packet Manipulation Using Scapy
Mastering YOLO - Yacine Author - Middle
New tutorials View all
  • How AI Text Detection Works: The Technology Behind Modern AI Detectors
  • Beyond Guesswork: How Python Helps Identify AI-Generated Text
  • Discover the Possibilities of Python Programming
  • How to Track Your AI Visibility with Python
  • How to Automate Excel Reports in Python using Openpyxl
Popular tutorials View all
  • How to Convert Speech to Text in Python
  • How to Read Emails in Python
  • How to Extract Tables from PDF in Python
  • How to Control your Mouse in Python
  • How to Make a Keylogger in Python
Practical Python PDF Processing EBook - Tutorials - Bottom
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.