Crafting CSS with Scheme

News

  • GNU Artanis 1.1.0 has released!

    https://artanis.dev/blog/1.1.0-release.html

  • The Spritely Institute is having a fundraiser!

    https://spritely.institute/donate/

    The Spritely Institute is working hard on new tools and technologies that are very important to the future of the Internet and also the future of Scheme!

    Consider donating on a monthly basis to help them continue working toward these goals so that we can have a more friendly, fun Internet that isn't dominated by corporate interests.

Let's Generate CSS from Scheme!

  • Basic generation of CSS from s-expressions
  • Support some of the more advanced CSS syntax
  • Making it easy to serve generated CS from a Guile HTTP server
  • Making it easy to re-evaluate the CSS code at runtime

Garden for Clojure:

https://github.com/noprompt/garden

Another example:

https://www.more-magic.net/posts/lispy-dsl-scss.html

The final code

(use-modules (ice-9 match))

(define display-value
  (match-lambda
    ((head . ())
     (write head))
    ((head . rest)
     (write head)
     (display ", ")
     (display-value rest))
    (value (if (symbol? value)
               (display (symbol->string value))
               (write value)))))

(define (write-attrs attrs)
  (for-each (match-lambda
              ((key value)
               (format #t "  ~a: " key)
               (display-value value)
               (display ";\n")))
            attrs))

(define* (scss->css tree #:optional port)
  (with-output-to-port (or port
                           (current-output-port))
    (lambda ()
      (for-each (lambda (rule)
                  (match rule
                    (((element . rest) . attrs)
                     (display-value (cons element rest))
                     (display " {\n")
                     (write-attrs attrs)
                     (display "}\n\n"))
                    ((element . attrs)
                     (format #t "~a {\n" element)
                     (write-attrs attrs)
                     (display "}\n\n"))))
                tree))))

(define fg-color "#eeffff")

(scss->css
 `((html (font-size "16px"))
   (body (margin 0)
         (font-family ("Jost*" sans-serif))
         (line-neight 1.5)
         (color ,fg-color)
         (background-color "#292d3e"))
   ((h1 h2 h3 h4 h5 h6)
    (font-weight 600)
    (line-height 1.3)
    (margin-top 1.3rem)
    (margin-bottom 0.5rem)
    (color ,fg-color))
   ((a:hover a:focus)
    (color "#82aaff")))

   ;; Special syntax for media queries needed!
   ;; ((@media screen and (max-width 767px))
   ;;  (html (font-size 16px))
 ;;  (.logo (max-width 200px))))

 (current-output-port))

Enjoyed this stream? Explore our hands-on courses for deeper, structured learning on Guile Scheme and more.

Get the System Crafters Newsletter
Updates on open source tools, tutorials, and community projects. We'll also occasionally let you know about new courses and resources.
Name (optional)
Email Address