Article / 30th Aug 2007

Graphs, Python and CSS

After my first attempt at providing some way for people to style graphs in Graphication, which ended up being a rather ugly system with an odd set of nested dictionaries, a thought struck me; we already have a language for specifying presentation, and which has inheritance and other nifty time-saving shortcuts: CSS.

I could only find one python CSS library, cssutils, and while that seemed to have very decent CSS2 support for parsing into a document tree, I couldn't see any immediate way of using it for retrieving the applicable values for, say, a grid object with class "minor" inside a wavegraph object.

First, I wrote a very lightweight CSS parser and rule matcher. Code examples always show off these things best; first you do something like

css_string = """wavegraph {color: #369; font-size: 12; } grid.minor { color: #eee; } """ import css stylesheet = css.CssStylesheet.from_css(css_string)

If you're feeling like using stylesheets a lot, you can make them external (e.g. a file "default_css.css") and use the import hook:

import css css.install_hook() import graphication.default_css as stylesheet

Then, querying properties is pretty simple:

`>>> stylesheet.props("wavegraph") {"color": "#369", "font-size": "12"}

stylesheet.props("wavegraph").get("color") "#369" stylesheet.props("wavegraph").get_int("font-size") 12 stylesheet.props("wavegraph grid.minor line") {"color": "#eee", "font-size": "12"}`

This means all the styling crud previously used can be replaced with these simple css-selector-ish queries, and different graph styles can simply ship as different css files.

So, hopefully, graph styling will be a lot more accessible once I roll this fully into the graph system, as well as a lot nicer to deal with for most uses. In the meantime, if you want to look at this CSS parser code, have a look at the current subversion copy.