Minifying CSS with Clojure

Updated: Thanks to Alan Malloy for poking me about the comment-related regular expression in the snippet below being too greedy.

A recent project had me looking into minifying CSS.  This is unfamiliar territory for me since I've rarely cared much about the size of website assets.  In the beginning of the project, minifying the Javascript that was floating around was more of a priority, so I folded Google Closure into my build process (which beat out YUI's Javascript minification by a substantial margin for my codebase – though I was quite disappointed that Google Closure's advanced compilation appears to be unusable by mere mortals).  So, when I needed to also minify CSS (something Closure doesn't do), I didn't want to fritter away more time messing with YUI as well.

Thus, I reinvented the wheel – something I am usually extraordinarily reluctant to do, but this was simply too easy to pass up:

[sourcecode language="clojure"] (require 'clojure.string)

(defn minify-css "Minifies the given CSS string, returning the result. If you're minifying static files, please use YUI." [css] (-> css (clojure.string/replace #"[\n|\r]" "") (clojure.string/replace #"/*.?*/" "") (clojure.string/replace #"\s+" " ") (clojure.string/replace #"\s:\s" ":") (clojure.string/replace #"\s,\s" ",") (clojure.string/replace #"\s{\s" "{") (clojure.string/replace #"\s}\s" "}") (clojure.string/replace #"\s;\s*" ";") (clojure.string/replace #";}" "}"))) [/sourcecode]

I'm guessing this wouldn't fare well with the various CSS syntax tricks sometimes played by those having to accommodate multiple archaic versions of IE, but itworksforme. Caveat emptor, in any case.

It can be very handy to have minification routines available at runtime without digging into the frightening APIs of either Closure or YUI, both of which are intended to be used only from the command line.  Sometimes assets are generated dynamically, and sometimes it's handy to be able to drop them straight into outgoing HTML pages (especially so if you want to produce a standalone version of a page, for example).

There's scads of CSS minification snippets around that use regular expressions, so this is nothing special, but I thought some Clojure web developers might appreciate it.