Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider extending :hiccup style to handle reagent's :> shorthand for reagent/adapt-react-class #324

Open
eval-on-point opened this issue Jul 2, 2024 · 1 comment

Comments

@eval-on-point
Copy link

Reagent has a non-standard element, :>, which is a shorthand for an internal function call on the next element in the vector. See reagent/doc/InteropWithReact.md at master · reagent-project/reagent for the official explanation.

Given the popularity of reagent, I think zprint may want to consider either

  1. handling this element specially within the :hiccup style or
  2. adding a new :reagent-hiccup style which handles it.

A very simple first pass at this (extending the :hiccup style in the documentation) which handles both traditional and reagent hiccups looks like this:

:style-map {:reagent-hiccup
              {:vector
                 {:option-fn
                    (fn [opts n exprs]
                      (let [hiccup?         (and (>= n 2)
                                                 (or (keyword? (first exprs))
                                                     (symbol? (first exprs)))
                                                 (map? (second exprs)))
                            reagent-hiccup? (or (and (>= n 3)
                                                     (= :> (first exprs))))]
                        (cond (and reagent-hiccup? (map? (nth exprs 2)) (not (:fn-format (:vector opts))))
                                {:vector {:fn-format :arg2-force-nl}}
                              (and (or hiccup? reagent-hiccup?) (not (:fn-format (:vector opts))))
                                {:vector {:fn-format :arg1-force-nl}}
                              (and (not hiccup?) (:fn-format (:vector opts)))
                                {:vector {:fn-format nil}}
                              :else nil)))
                  :wrap? false}
               :vector-fn {:indent 1 :indent-arg 1}}}

This style formats

[:> Component {:prop "val"} []]

[:> Component []]

[:> Component {:prop "val"}]

[:> Component]

[:div []]

[:div {:prop "val"} []]

as

[:> Component {:prop "val"}
 []]

[:> Component
 []]

[:> Component {:prop "val"}]

[:> Component]

[:div []]

[:div {:prop "val"}
 []]
@eval-on-point
Copy link
Author

For anyone interested in this, my team noticed the above :option-fn did not correctly handle nested :hiccup. I have made a slight improvement here:

(fn [opts n exprs]
  (let [reagent-hiccup? (and (= :> (first exprs))
                             (>= n 3))
        vanilla-hiccup? (and (>= n 2)
                             (or (keyword? (first exprs))
                                 (symbol? (first exprs)))
                             (map? (second exprs)))
        any-hiccup?     (or reagent-hiccup? vanilla-hiccup?)
        fn-format?      (:fn-format (:vector opts))]
    (cond (and reagent-hiccup? (map? (nth exprs 2)) (not fn-format?))
            {:vector             {:fn-format :arg2-force-nl}
             :next-inner-restore [[:vector :fn-format]]}
          (and any-hiccup? (not fn-format?))
            {:vector             {:fn-format :arg1-force-nl}
             :next-inner-restore [[:vector :fn-format]]}
          (and (not any-hiccup?) fn-format?)
            {:vector {:fn-format nil}}
          :else nil)))

This handles hiccup like this:

[:> box {}
 [:> box {}
  [:div {}
   [:> box {}]]]]

I am not 100% sure what the signifigance of the last two clauses were in the original :hiccup style, and why :next-inner-restore was not used in the first place, so copy this with caution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant