Skip to content

Instantly share code, notes, and snippets.

@owainlewis
Last active December 22, 2015 17:59
Show Gist options
  • Save owainlewis/6509815 to your computer and use it in GitHub Desktop.
Save owainlewis/6509815 to your computer and use it in GitHub Desktop.
A prototype for writing stylesheets in LISP
(ns sexp-css.core)
(defn- wrap [forms]
(str "{" forms "}"))
;; Suggested DSL
;; (defselector "h2"
;; :a {:width "100px"}
;; :li {:font-size "20px"})
(defn map-to-form
"Takes a single map and converts it to a CSS form"
[m]
(let [outer-forms (reduce
(fn [out-vec [k v]]
(conj out-vec (str (name k) " : " v))) [] m)
inner-forms (->> outer-forms (interpose ";") (apply str))]
(wrap inner-forms)))
(defn px [n]
(when (number? n)
(str n "px")))
(def eg {:h1 {:font-size (px 10)}
:a {:color "#FF5"}})
(defn build-nested-form
"Builds a nested form i.e h1 -> a -> styles"
[parent-selector child-selector m]
(let [parts [parent-selector " " child-selector (map-to-form m)]]
(->> parts (apply str))))
(defmacro defrule
"Define a rule. Takes any number of
styles and merges them to produce the final
styles"
[selector & forms]
`(str ~selector
(map-to-form
(apply merge-with conj (vector ~@forms)))))
(def bold {:font-weight "bold"})
(def italic {:font-style "italic"})
;; (defrule "h2"
;; bold italic))
(defn mixin
"Basically this merges styles into an existing selector"
[rule & forms]
(merge rule (into {} forms)))
(def my-mixin
{:height "20px"
:width "100px"})
(def sample
(defrule "h2"
(let [line-height 24
font-size 16]
(mixin
{:font-size (px (* font-size line-height))
:color "#FFF"} my-mixin))))
@owainlewis
Copy link
Author

(def red "#FF5")

(defrule "h2"
  {:font-size "12px"
   :color red}))

;; => h1{font-size : 12px;color : #FF5}

@owainlewis
Copy link
Author

Using mixins (thanks rod!)

 (defrule "h2"
    (let [line-height 24
          font-size 16]
    (mixin 
      {:font-size (px (* font-size line-height))
       :color "#FFF"} my-mixin)))


;; => h2{ height : 20px;width : 100px;font-size : 384px;color : #FFF}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment