garden

rap1ds 2021-01-18T09:20:02.022100Z

@guswill Sure, here:

;; CLJ

(defn- extract-docstring
  "Takes `args` as a parameter where the first item may or may not be a
  docstring and returns tuple of `[docstring rest-args]`. In case there's
  no docstring, returns [nil args]"
  [args]
  (if (string? (first args))
    [(first args) (rest args)]
    [nil args]))

(defmacro defstyle
  "Macro to define a new style declaration. Style declations that are
  defined with this macro can be later picked by `style-defs'
  function."
  [sym & args]
  (let [[doc [style]] (extract-docstring args)
        m (cond-> {::style true}
            doc (assoc :doc doc))]
    `(def ~(with-meta sym m) ~style)))

(defmacro defclass
  "Macro to define a new class that can be referred from ClojureScript code.

  See also the CLJS variant (def-cljs namespace)"
  [sym & args]
  (let [[doc rules] (extract-docstring args)
        style (vec (concat [(str "." (util/identifier *ns* sym))]
                           rules))]
    (if doc
      `(defstyle ~sym ~doc ~style)
      `(defstyle ~sym ~style))))

;; CLJS

(defn- extract-docstring
  "Takes `args` as a parameter where the first item may or may not be a
  docstring and returns tuple of `[docstring rest-args]`. In case there's
  no docstring, returns [nil args]"
  [args]
  (if (string? (first args))
    [(first args) (rest args)]
    [nil args]))

(defmacro defstyle
  "Macro to define a new style declaration. The ClojureScript version
  discards the style rules. Defines a new var with a style name."
  [sym & args]
  (let [[doc [_style]] (extract-docstring args)]
    (if doc
      `(def ~sym ~doc ~(util/identifier *ns* sym))
      `(def ~sym ~(util/identifier *ns* sym)))))

(defmacro defclass
  "Macro to define a new class. The ClojureScript version discards the
  style rules. Defines a new var with a class name that can be refered
  ClojureScript code.

  See also the Clojure variant (def-clj namespace)"
  [sym & args]
  (let [[doc rules] (extract-docstring args)]
    (if doc
      `(defstyle ~sym ~doc ~rules)
      `(defstyle ~sym ~rules))))
The util/identifier is a helper that build the namespaces class name. The ::style metadata is there so that I can pick all the styles for the lein garden build

🎉 2