fun with style sheets

Mark McEahern mark at
Fri Aug 23 16:05:16 CEST 2002

I have a movabletype blog and I finally overcame my inertia to edit the
style sheet.  For reasons that probably make sense to someone, the default
movabletype stylesheets use tabs instead of spaces.  [Insert religious holy
war about tabs vs. spaces.]  The thing that seems odd about that in this
particular case is that nominally at least the idea is to edit the
stylesheet in a rather tiny TEXTAREA on some web page.  Um, how do you
insert [tab] into a TEXTAREA?  (Answer:  Use the clipboard to paste one in.
The answer is a reductio ad absurdum, in case you hadn't noticed.)

So, you either do the clipboard trick to insert tabs when you're editing the
stylesheet or you end up with some horrible looking stylesheet, some lines
with tabs, others without.  It smashes any aesthetic expectation you might
have had and what seems awful about that is this is an extremely dissonant
experience to have when editing a "style" sheet.

Anyway, so I came up with the truly amateurish style sheet fixer code below.
Basically, it aims to normalize each block in the style sheet so that they
all end up like this:

  style: value;
  style2: value;

In other words, minimal, but consistent spacing.  If I weren't half as dumb
as I am, I'd probably just make some emacs Lisp macro to do this and be done
with it.

The code is at the very bottom of the message.

So my question is:

1.  Anybody have a css-mode for emacs?  (I confess I haven't searched for
one yet.)
2.  Aside from the utter lack of modularity in the code, how would you
improve it?  Am I missing something obvious?
3.  Any other tips or pointers on the general idea?  Take a file, use some
rules to modify its format, output the result.  Is that a parser?  (I'm
serious about my ignorance here and welcome any help.)


// mark

#!/usr/bin/env python

import re

f = file("style.css")
original =

s = original

# Put braces on their own line, no spacing before or after.
s = s.replace(" {", "\n{\n")
s = s.replace("}", "\n}\n")

# Make sure colons have a space after them--this is brute force; later we'll
# cleanup multiple spaces.
s = s.replace(":", ": ")

# Make sure semi-colons end the line--brute force; later we clean up
# multiple blank lines.
s = s.replace(";", ";\n")

# Cleanup multiple spaces.
pat = re.compile(" +")
s = pat.sub(" ", s)

# Get rid of \r.
s = s.replace("\r", "\n")

# No spaces before or after new lines.
pat = re.compile(" *\n *")
s = pat.sub("\n", s)

# Cleanup multiple new lines.
pat = re.compile("\n+")
s = pat.sub("\n", s)

# Walk through the lines and indent appropriately.
indent_this = False
indent_next = False

for l in s.split("\n"):
    indent_this = indent_next

    if l.find("}") >= 0:
        indent_this = False
        indent_next = False
    if l.find("{") >= 0:
        indent_this = False
        indent_next = True

    print "%s%s" % ((indent_this and "\t" or ""), l)


More information about the Python-list mailing list