I want to get a seq of every top-level form that starts with a specific token/symbol in a file. Which is to say, I want a seq (lazy or realized) that is every (defcard ...) in my file, and I want to spit it out into a new file with a prepended (in-ns 'game.cards.agendas) form. Is that something rewrite-clj can give me? How is the best way to do it? If I was writing a macro, I'd probably do something like (->> forms (filter #(= 'defcard (first %))) (run! save-to-new-file))
not sure if this works 100% of the times but it feels simple, just working at strings level with no parsing :
(->> "(ns ...) (defn ...) (defcard 1) (defn ...) (defcard 2)" ;; replace by (slurp "file.clj")
(re-seq #"(\(defcard.+?\))")
(map (fn [[dc-form-str]]
(str "(in-ns 'game.cards.agendas)\n" dc-form-str "\n")))
(apply str)
(println)) ;; replace by (spit "output.clj")
(in-ns 'game.cards.agendas)
(defcard 1)
(in-ns 'game.cards.agendas)
(defcard 2)Yeah, I tried doing string parsing, but I ran into issues with incorrect whitespace or similar issues, so seemed better to reach for the correct tool
This has been edited for clarity:
(loop [zloc (z/of-file (format "src/clj/game/cards/%s.clj" card-type))]
(when-not (z/end? zloc)
(let [form (z/next zloc)]
(when (= 'defcard (z/sexpr form))
(let [card-name (-> form z/next z/sexpr)
filename (str (slugify card-name "_") ".clj")]
(spit (format "src/clj/game/cards/%s/%s" card-type filename)
(n/string (n/forms-node
[(p/parse-string-all (format "(in-ns 'game.cards.%s)"
card-type))
(n/newlines 2)
(z/node (z/up form))
(n/newlines 1)])))))
(recur (z/right zloc)))))
Loop over the top-level forms with z/right, get the z/next token and see if it matches 'defcard, then "slugify" the card name (defcard "Day Job" -> "day_job", then create a new "forms" node containing the node (in-ns 'game.cards.X) and the whole defcard node (`(z/node (z/up form))`), plus some newlines and stuff, and spit out out to a file named for the slugyeah, the regex solution will not work at all now I think a little bit more about it
i figured out a solution, but it's late, so i'll post it in the morning
Yeah, I think rewrite-clj is a good choice for this. Looking forward to seeing what you came up with!