Skip to content

Instantly share code, notes, and snippets.

@whacked
Created September 19, 2020 03:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whacked/7b04e10392a7aa29ff9851490e15a60a to your computer and use it in GitHub Desktop.
Save whacked/7b04e10392a7aa29ff9851490e15a60a to your computer and use it in GitHub Desktop.
quick and very-dirty css -> garden transformer. not complete! but will save 95% effort from hand-conversion
#!/usr/bin/env bb
(def input-file
(or (first *command-line-args*)
"defaults.css"))
(defn parse-css [text]
(let [render-buffer (fn [buf]
(apply str buf))]
(loop [ch-remain text
mode-stack (list)
buf []
out []
niter 0]
(if (empty? ch-remain)
(let []
out)
(let [ch (first ch-remain)
prev-ch (last buf)
next-ch-remain (rest ch-remain)]
(cond (= (peek mode-stack) :comment)
(if (and (= prev-ch \*)
(= ch \/))
(recur next-ch-remain
(pop mode-stack)
[]
(conj out [(peek mode-stack)
(render-buffer
(butlast buf))])
(inc niter))
(recur next-ch-remain
mode-stack
(conj buf ch)
out
(inc niter)))
(and (= prev-ch \/)
(= ch \*))
(do
(recur next-ch-remain
(conj mode-stack :comment)
[]
(conj out [(peek mode-stack)
(render-buffer (butlast buf))])
(inc niter)))
(and (= ch \{)
(= (peek mode-stack) nil))
(do
(recur next-ch-remain
(conj mode-stack :ruleset)
[]
(conj out
[:rulename (clojure.string/trim (render-buffer buf))])
(inc niter)))
(and (= (peek mode-stack) :ruleset)
(= ch \}))
(recur next-ch-remain
(pop mode-stack)
[]
(conj out
[:ruleset (render-buffer buf)])
(inc niter))
:else
(do
(recur next-ch-remain
mode-stack
(cond
(= (peek mode-stack) :comment)
(if (= ch \newline)
(conj buf ";;" ch)
(conj buf ch))
:else
(conj buf ch))
out
(inc niter)))))))))
(defn render-css [parsed-css]
(->> parsed-css
(map (fn [[type text]]
(case type
:comment
(->> (interleave
(clojure.string/split-lines text)
(repeat "\n;; "))
(apply str ";; "))
:rulename
(str "[:" text)
:ruleset
(str
"{"
(->> (clojure.string/split-lines text)
(map (fn [line]
(-> line
(clojure.string/replace #";\s*$" "")
(clojure.string/trim))))
(remove empty?)
(map (fn [line]
(let [[attr value] (clojure.string/split line #":\s*" 2)
value-string (if (= value "0")
value
(str "\""
(clojure.string/replace
value #"\"" "\\\\\"")
"\""))]
(str " :" attr " " value-string "\n"))))
(apply str)
(clojure.string/trim))
"}]")
text)))
(interpose "\n")
(apply str)))
(-> input-file
(slurp)
(parse-css)
(render-css)
(println))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment