Googled and found clojure.core.strint which reads "a~{b}c"
and string interpolation and replaces b
. Then I noticed such namespace is not available in ClojureScript.
Any other libraries I can use? Or I have to build my own?
Googled and found clojure.core.strint which reads "a~{b}c"
and string interpolation and replaces b
. Then I noticed such namespace is not available in ClojureScript.
Any other libraries I can use? Or I have to build my own?
I’m using Cuerdas library for this purpose, it also has many more useful utilities for strings https://funcool.github.io/cuerdas/latest/#interpolate
I looked for string interpolation when I started Clojure, mostly because I was used to it from ruby. Nowadays I think just using str
is better in every way possible.
;; from cuerdas
(str/istr "value = ~(inc value)")
;; plain str
(str "value = " (inc value))
Usually it is equal or less amount of code and it doesn’t degrade when you want “longer” things interpolated.
(str "prefix"
(->> some-seq
(map str/upper-case)
(str/join " "))
"suffix")
You also don’t loose syntax support since no editor I know of recognizes ~()
inside strings as clojure code.
Just my 2 cents.
There might be a situation like:
<path id="testPath" d="M3.858,58.607 c16.784-5.985,33.921-10.518,51.695-12.99c50.522-7.028,101.982,0.51,151.892,8.283c17.83,2.777,35.632,5.711,53.437,8.628 c51.69,8.469,103.241,11.438,155.3,3.794c53.714-7.887,106.383-20.968,159.374-32.228c11.166-2.373,27.644-7.155,39.231-4.449" />
and I want to interpolate all numbers in d
attribute. The first time came to my mind is string interpolation. However I notices using function composition might be a better solution.
In your case, how would you do string interpolation? you have plenty of parameters, not just a fixed set like:
You have ${coins} left for a total of ${amount}
So - though I don’t know jack about SVG - I would use a clojure structure that represents a path with a function to turn it into an SVG tag by mapping and then I would have a final go to put everything together as (apply str ....)
.
that depends on how the macro str/istr
is implemented, which I’m not sure…
I usually do this (the SVG example) using map
and interpose
, which I find much cleaner than string interpolation (which invents an opaque DSL inside the string).
I’m thinking about going further. Clojure checks function arities, so by using functions, I can get static checking fot those numbers. Something like https://gist.github.com/potch/4214346
Ended up with a function to assemble path data for me:
(respo.util.format/path-data :M 10 10 :l 20 20 :Z)
You might consider something like this:
(def key->params
{:q 4, :L 2, :M 2, :v 1, :A 7, :Q 4, :m 2, :Z 0, :T 2, :C 6, :s 4, :l 2, :z 0, :c 6, :h 1, :t 2, :H 1, :V 1, :S 4, :a 7})
(defn concat-path-data [acc xs]
(if (empty? xs)
acc
(let [cursor (first xs)
following (rest xs)
num-params (key->params cursor)]
(assert num-params (str "Unknown command: " cursor))
(let [params (take num-params following)]
(assert (and (= num-params (count params)) (every? number? params))
(str cursor " takes " num-params " numbers"))
(recur (str acc " " (name cursor) (string/join "," params)) (drop num-params following))))))
In general, I prefer to write a short function that uses a lookup table over a long function that repeats boilerplate. Another way to phrase that is: it’s often better to program with data than with code.
Exactly what I thought after woke in the morning!