Skip to content

Instantly share code, notes, and snippets.

@edw
Created May 5, 2011 14:22
Show Gist options
  • Select an option

  • Save edw/957123 to your computer and use it in GitHub Desktop.

Select an option

Save edw/957123 to your computer and use it in GitHub Desktop.
Sass in Scheme, Take 2
;;
;; Sass in Scheme, Take 2
;; Copyright 2011 Edwin Watkeys. All rights reserved.
;;
;; [Imagine the two-clause MIT license inserted here.]
;;
;; CSS can be a pain. There is apparently a tool called Sass that some
;; people use to deal with some of the issues that accompany non-trivial
;; applications of CSS.
;;
;; For fun, I decided to write a Sass-like tool in Scheme. This is my
;; second take on the problem. I wrote the first version in response to a
;; Hacker News submission:
;;
;; http://news.ycombinator.com/item?id=2514799)
;;
;; My comments on that submission got pummeled with down-votes by people
;; who don't know how to spell "syntactic" and apparently easily take
;; offense and would rather have a community filled with polite morons
;; than people who call bullshit when they see it. Letting people down-
;; vote simply because they've squirreled away enough karma through
;; hundreds of innocuous—and superfluous—comments is no way to run an
;; operation like Hacker News. God knows I'll be tempted to down-vote
;; the shit out of anyone who displeases me if I ever manage to whore
;; my way to five-hundred or whatever karma.
;;
;; So anyway, consider this the extended fuck you re-mix. Enjoy!
;;
;; The previous version (https://gist.github.com/956113) required too
;; many parentheses. Compare the old usage:
;;
;; (make-css
;; '(("body.loading"
;; (font-size "12px")
;; (color "#fff")
;; (" ul#sidenav"
;; (" li"
;; (blah "blah"))))))
;;
;; To the new:
;;
;; (make-css
;; '(("body.loading"
;; font-size "12px"
;; color "#fff"
;; (" ul#sidenav"
;; (" li"
;; blah "blah")))))
;;
;; Both return the same output:
;;
;; body.loading { font-size: 12px; color: #fff; }
;; body.loading ul#sidenav li { blah: blah; }
;;
;; Note that you can use all the standard powers of Scheme, such as
;; variables and procedures in concert with quasi-quotation to serve all
;; of your composition needs. E.g.:
;;
;; (make-css
;; (let ((base-font-size "12px")
;; (random-color (lambda () "#fff"))
;; (blah-declaration '(blah "blah")))
;; `(("body.loading"
;; font-size ,base-font-size
;; color ,(random-color)
;; (" ul#sidenav"
;; (" li"
;; ,@blah-declaration))))))
;;
;; The above, when evaluated, produces identical output to the first
;; example. I believe that this gives you all of the compositional
;; power of Sass.
;;
;; This code should work in any R5RS Scheme.
(define (make-css rules)
(define sa string-append)
(define (do-rules rules ctx out)
(define (do-rule rule ctx)
(let ((selector (car rule)))
(let loop ((decls (cdr rule)) (out "") (sub-out ""))
(if (null? decls)
(if (zero? (string-length out)) sub-out
(sa ctx selector " {" out " }\n" sub-out))
(let ((head (car decls)))
(if (pair? head)
(loop (cdr decls)
out
(sa sub-out (do-rule head (sa ctx selector))))
(loop
(cddr decls)
(sa out " " (symbol->string head) ": " (cadr decls) ";")
sub-out)))))))
(if (null? rules) out
(do-rules (cdr rules) ctx (sa out (do-rule (car rules) ctx)))))
(do-rules rules "" ""))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment