Skip to content

Instantly share code, notes, and snippets.

@francoisdevlin
Created December 16, 2009 02:49
Show Gist options
  • Select an option

  • Save francoisdevlin/257549 to your computer and use it in GitHub Desktop.

Select an option

Save francoisdevlin/257549 to your computer and use it in GitHub Desktop.
;;Code courtesy of Chas Emerick
(let [slurp* (fn [f]
(with-open [#^java.io.BufferedReader r (java.io.BufferedReader. f)]
(let [sb (StringBuilder.)]
(loop [c (.read r)]
(if (neg? c)
(str sb)
(do (.append sb (char c))
(recur (.read r))))))))]
(defn silent-read
[s]
(try
(let [r (-> s java.io.StringReader. java.io.PushbackReader.)]
[(read r) (slurp* r)])
(catch Exception e))))
(defn interpolate-worker
([s atom?]
(lazy-seq
(if-let [[form rest] (silent-read (subs s (if atom? 2 1)))]
(cons form (interpolate-worker (if atom? (subs rest 1) rest)))
(cons (subs s 0 2) (interpolate-worker (subs s 2))))))
([#^String s]
(let [start (max (.indexOf s "~{") (.indexOf s "~("))]
(if (== start -1)
[s]
(lazy-seq (cons
(subs s 0 start)
(interpolate-worker (subs s start) (= \{ (.charAt s (inc start))))))))))
(defmacro interpolate-s
[s]
`(str ~@(interpolate-worker s)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment