Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions src/nextjournal/clerk/viewer.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -431,27 +431,30 @@
(defn var-from-def? [x]
(var? (get-safe x :nextjournal.clerk/var-from-def)))

(def unwrap-var-value (some-fn :nextjournal.clerk/var-snapshot
(comp deref :nextjournal.clerk/var-from-def)))

(def var-from-def-viewer
{:name `var-from-def-viewer
:pred var-from-def?
:transform-fn (update-val (some-fn :nextjournal.clerk/var-snapshot
(comp deref :nextjournal.clerk/var-from-def)))})
:transform-fn (update-val unwrap-var-value)})

(defn apply-viewer-unwrapping-var-from-def
"Applies the `viewer` (if set) to the given result `result`. In case
the `value` is a `var-from-def?` it will be unwrapped unless the
viewer opts out with a truthy `:nextjournal.clerk/var-from-def`."
the return value is a `var-from-def?` it will be unwrapped unless the
viewer opts out with a truthy `:var-from-def?`."
[{:as result :nextjournal/keys [value viewer]}]
(if viewer
(let [value+viewer (if (or (var? viewer) (fn? viewer))
(viewer value)
{:nextjournal/value value
:nextjournal/viewer (normalize-viewer viewer)})
{unwrap-var :transform-fn var-from-def? :pred} var-from-def-viewer]
(assoc result :nextjournal/value (cond-> value+viewer
(and (var-from-def? value)
(-> value+viewer ->viewer :var-from-def? not))
unwrap-var)))
result-value (:nextjournal/value value+viewer)
unwrap? (and (var-from-def? result-value)
(-> value+viewer ->viewer :var-from-def? not))]
(assoc result :nextjournal/value
(cond-> value+viewer
unwrap? (update :nextjournal/value unwrap-var-value))))
result))

#?(:clj
Expand Down
37 changes: 25 additions & 12 deletions test/nextjournal/clerk/viewer_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -212,20 +212,33 @@
(is (= [{:render-fn 'foo}] (v/get-viewers 'nextjournal.clerk.viewer-test.random-ns-name)))))

(def my-test-var [:h1 "hi"])
(def my-test-var2 1)

(def apply+get-value #(-> % v/apply-viewer-unwrapping-var-from-def :nextjournal/value :nextjournal/value))
(deftest apply-viewer-unwrapping-var-from-def
(let [apply+get-value #(-> % v/apply-viewer-unwrapping-var-from-def :nextjournal/value :nextjournal/value)]
(testing "unwraps var when viewer doens't opt out"
(is (= my-test-var
(apply+get-value {:nextjournal/value [:h1 "hi"] :nextjournal/viewer v/html})
(apply+get-value {:nextjournal/value {:nextjournal.clerk/var-from-def #'my-test-var} :nextjournal/viewer v/html})
(apply+get-value {:nextjournal/value {:nextjournal.clerk/var-from-def #'my-test-var} :nextjournal/viewer v/html-viewer}))))

(testing "leaves var wrapped when viewer opts out"
(is (= {:nextjournal.clerk/var-from-def #'my-test-var}
(apply+get-value {:nextjournal/value {:nextjournal.clerk/var-from-def #'my-test-var}
:nextjournal/viewer (assoc v/html-viewer :var-from-def? true)}))))))

(testing "unwraps var when viewer doens't opt out"
(is (= my-test-var
(apply+get-value {:nextjournal/value [:h1 "hi"] :nextjournal/viewer v/html})
(apply+get-value {:nextjournal/value {:nextjournal.clerk/var-from-def #'my-test-var} :nextjournal/viewer v/html})
(apply+get-value {:nextjournal/value {:nextjournal.clerk/var-from-def #'my-test-var} :nextjournal/viewer v/html-viewer}))))

(testing "leaves var wrapped when viewer opts out"
(is (= {:nextjournal.clerk/var-from-def #'my-test-var}
(apply+get-value {:nextjournal/value {:nextjournal.clerk/var-from-def #'my-test-var}
:nextjournal/viewer (assoc v/html-viewer :var-from-def? true)}))))

(testing "function viewer with var-from-def"
(is (= [{:nextjournal.clerk/var-from-def #'nextjournal.clerk.viewer-test/my-test-var2, :nextjournal.clerk/var-snapshot 1}]
(apply+get-value {:nextjournal/value {:nextjournal.clerk/var-from-def #'my-test-var2
:nextjournal.clerk/var-snapshot 1}
:nextjournal/viewer v/row}))))
(testing "function viewer that preserves var-from-def"
(let [viewer-fn (fn [v] (v/with-viewer (assoc v/html-viewer :var-from-def? true) v))]
(is (= {:nextjournal.clerk/var-from-def #'my-test-var
:nextjournal.clerk/var-snapshot [:h1 "hi"]}
(apply+get-value {:nextjournal/value {:nextjournal.clerk/var-from-def #'my-test-var
:nextjournal.clerk/var-snapshot [:h1 "hi"]}
:nextjournal/viewer viewer-fn}))))))

(deftest resolve-aliases
(testing "it resolves aliases"
Expand Down
Loading