Fork me on GitHub
#nextjournal
<
2022-02-01
>
genmeblog16:02:35

Hi. I've seen TOC is possible (after PR56) but how to make it visible?

mkvlr16:02:16

@U9EQP1K0X worked on that and we decided to not show it yet as we want to add more styling. Not sure if it's already possible to show it.

genmeblog16:02:03

ok! It'll be a great feature. So waiting.

🙏 2
genmeblog16:02:25

and (possibly asked that before): how to hide result? Having comment block with ^{:nextjournal.clerk/visibility #{:hide}}, the block is hidden but result nil is visible.

mkvlr16:02:49

Need to also set ^{:nextjournal.clerk/viewer :hide-result}. See https://github.com/nextjournal/clerk/pull/59

genmeblog16:02:07

ah! thanks! I'm now pretty sure I've seen that before.

jhemann22:02:26

I wanted to +1 the approach suggested in https://clojurians.slack.com/archives/C01GH5EN7JA/p1638997812197500 that resulted in https://github.com/nextjournal/clerk/pull/24. The use case I have is wanting to show code in a notebook but 1. Not show the result 2. Not complicate the code I want people to read with having to do (clerk/hide-result (the-code-I-actually-want-to-show)) I like having the ^{::clerk/visibility :hide} metadata because I can control what code I do not want the reader to have to see. I would also like to have a ^{::clerk/visibility :hide-result} option as that would let me show the reader the code, without the result (which may be distracting) and without having to distract from the code with (clerk/hide-result...

jhemann22:02:08

That being said, Clerk is awesome and I really appreciate everyone’s work on it! I used to be a huge user of Python and Jupyter notebooks but using Clojure more now, I greatly prefer the Clojure REPL development experience while still being able to do literate programming with Clerk.

❤️ 2
mkvlr08:02:20

@U0D6MPESW did you see that ^{::clerk/viewer :hide-result} is supported as of https://github.com/nextjournal/clerk/pull/59? Controlling both result and code cell visibility with a single keyword leads to a combinatorial state explosion that I think is better avoided.

jhemann23:02:33

Thanks @mkvlr, I had not seen that updated but just updated the version of clerk I was using and my .clj file and it works great!

jhemann23:02:35

Is there a configuration that can hide the ^{…} metadata annotation? For example, I want to talk about this bit of code but would like to hide the metadata used by Clerk. It is in my .clj and gets rendered as

^{::clerk/viewer :hide-result}
(def scratch-db-uri "asami:")

mkvlr16:02:09

not yet but it’s on the roadmap

genmeblog17:02:17

@mkvlr I'll be spamming with some specific issues I have 🙂

mkvlr17:02:46

please do!

🙏 1
genmeblog17:02:14

First one: when I make custom viewer, how can I use external functions in :render-fn ?

genmeblog17:02:55

The example is:

genmeblog17:02:00

(defn make-color-div
  [c]
  (clerk/html [:div {:style {:background-color "#aaaaaa"}} c]))
(clerk/set-viewers! [{:name :color :render-fn `make-color-div}])

genmeblog17:02:42

Which doesn't work and produces:

genmeblog17:02:47

while (clerk/set-viewers! [{:name :color :render-fn '#(v/html [:div {:style {:background-color "#aaaaaa"}} %])}]) works

genmeblog17:02:42

making render-fn without the access to other namespaces is very limiting

mkvlr17:02:20

do you already have code you’d like to use there? Is it ClojureScript?

mkvlr17:02:06

asking because you can extend the environment and hence what namespaces you can use in :render-fn but that means you also have to do your own ClojureScript compilation

mkvlr17:02:13

this adds some complexity, which may or may not be a problem for you. If you already have a cljs pipeline on this project it’s pretty simple

genmeblog17:02:20

Hmmm... I want to avoid this path. Maybe I should use transform-fn?

genmeblog17:02:35

Need to experiment more

mkvlr17:02:02

depends on what you want to generate, hiccup in the end?

mkvlr17:02:19

in that case you should be able to define a viewer with only a :transform-fn and return hiccup tagged with clerk/html

mkvlr17:02:41

and you can use all code on the JVM classpath in that case

genmeblog17:02:45

Yeah! Should work!

mkvlr17:02:56

(ns transform
  (:require [nextjournal.clerk :as clerk]))

(clerk/set-viewers! [{:pred vector? :transform-fn clerk/html}])

[:h1 "Hi Hiccup 👋"]

mkvlr17:02:40

along those lines

mkvlr17:02:10

:transform-fn can of course be more complex, but should call clerk/html eventually if you want to render hiccup

genmeblog17:02:09

Got it. Still building intuition about data flow.

👍 1
mkvlr17:02:27

me too 🙃

😀 1
genmeblog19:02:09

Ok. Following notebook hangs everything, eats all CPU, firefox claims that page is slow (and eats tons of memory). Any idea what happens?

genmeblog19:02:22

^{:nextjournal.clerk/visibility :hide-ns}
(ns notebooks.color
  (:require [nextjournal.clerk :as clerk]
            [nextjournal.clerk.config :as config]
            [clojure2d.color :as c]))

(defn color-spans [c]
  (let [c (:nextjournal/value c)
        str-color (if (< (c/luma c) 128.0) "white" "black")
        n (c/format-hex c)]
    [:span {:style (str "background-color:" n ";color:" str-color ";")} (str "[" n "] " c)]))

(clerk/set-viewers! [{:name :color :render-fn (quote v/html)
                      :transform-fn color-spans}])

(color-spans {:nextjournal/value :red})
;; => [:span {:style "background-color:#ff0000;color:white;"} "[#ff0000] :red"]

#_(swap! config/!resource->url assoc "/css/viewer.css" "../docs/static/static.css")

;; # Color

(clerk/with-viewer :color 11)

;; ## Sub

^{::clerk/viewer :color}
(+ 1 2)

^{:nextjournal.clerk/visibility :hide
  :nextjournal.clerk/viewer :hide-result}
(comment
  (require '[nextjournal.clerk :as clerk])
  (clerk/serve! {:browse? true :watch-paths ["notebooks"]})
  (clerk/show! "notebooks/color.clj")
  (clerk/halt!))

👀 1
genmeblog20:02:15

@mkvlr let's continue here (don't to spam main channel)

genmeblog20:02:30

:transform-fn (comp clerk/html color-spans) doesn't change anything

mkvlr20:02:13

^{:nextjournal.clerk/visibility :hide-ns}
(ns ^:nextjournal.clerk/no-cache notebooks.color
  (:require [nextjournal.clerk :as clerk]
            [nextjournal.clerk.viewer :as v]
            [clojure2d.color :as c]))

(defn color-spans [c]
  (let [c (v/value c)
        str-color (if (< (c/luma c) 128.0) "white" "black")
        hex (c/format-hex c)]
    (v/html [:span {:style {:background-color hex :color str-color}}
             (str "[" hex "] " c)])))

(clerk/set-viewers! [{:name :color :pred #{:red 3 11} :transform-fn color-spans}])

:red

;; # Color
11

;; ## Sub
(+ 1 2)

#_(clerk/serve! {})

mkvlr20:02:47

the hiccup flavor we’re using (reagent) wants styles as maps

mkvlr20:02:20

I’d recommend working from a very concrete impl first to implement a viewer

mkvlr20:02:53

whoops, just fixed an error in the above

mkvlr20:02:10

now looks like this

mkvlr20:02:22

gtg now, will check back tomorrow

genmeblog20:02:50

thanks a lot!

genmeblog21:02:18

above works indeed, thanks for a hiccup hint. However, selecting viewer with metadata or using with-viewer produces unusable viewer

genmeblog21:02:26

> I’d recommend working from a very concrete impl first to implement a viewer

genmeblog21:02:39

^ what do you mean by that?

genmeblog23:02:02

Ok, eventually I decided not to use custom viewer at all. Just created a function which returns html view. No need to use meta tags etc.

genmeblog23:02:26

the only issue is that CSS is inlined

mkvlr08:02:00

re working from a concrete impl, I meant pretty much doing what you did above: start with a let statement and get the hiccup to render for concrete values, only then move things into a viewer. But you’re right that for your use case the viewers aren’t needed as you don’t seem to require the recursive nature of viewers.

👍 1
mkvlr08:02:33

and great to see you got things working!

genmeblog09:02:30

So far so good 🙂 I'm trying to prepare better doc for clojure2d.color namespace and above attempt was crucial to make it happen.

❤️ 1
genmeblog19:02:56

It hangs here (after interrupting in repl):

1. Unhandled java.lang.InterruptedException
   (No message)

               Object.java:   -2  java.lang.Object/wait
               Object.java:  338  java.lang.Object/wait
          ProcessImpl.java:  434  java.lang.ProcessImpl/waitFor
                 shell.clj:  127  clojure.java.shell/sh
                browse.clj:   74  clojure.java.browse/browse-url
                browse.clj:   66  clojure.java.browse/browse-url
                 clerk.clj:  306  nextjournal.clerk/serve!
                 clerk.clj:  284  nextjournal.clerk/serve!
                      REPL:   34  notebooks.color/eval30547

genmeblog10:02:58

@mkvlr regarding this issue. I think it might be connected to my setup which is WSL2 on Windows 11 with wslg (xserver). I tried to change browsers and google-chrome hangs everything during serve! while firefox hangs during show!

genmeblog10:02:28

firefox path can be interrupted and show! continues evaluation and displaying

mkvlr10:02:42

oh didn't realize this is still a problem for you.

genmeblog10:02:59

temporary solution is to set browse? false and manually open a browser

genmeblog10:02:06

which is not big deal for me

genmeblog10:02:36

just describing that for future reference if other people will face this issue

mkvlr10:02:37

ah so (clojure.java.browse/browse-url "") hangs for you?

genmeblog10:02:18

well, no! 😕 hmmm...

genmeblog10:02:05

on firefox the page opens

genmeblog10:02:14

google-chrome hangs

mkvlr10:02:56

ah ok, so you can’t load http://localhost:7777 in chrome?

genmeblog10:02:54

I can, but I can't (clojure.java.browse/browse-url "") with google-chrome as a default browser

genmeblog10:02:59

Don't bother with that, it's 99% related to JVM/WSL interop

mkvlr10:02:02

alright, good to know though, thanks

genmeblog22:02:43

Looks like this bug may be related to https://clojure.atlassian.net/browse/CLJ-2493

👍 1
genmeblog19:02:36

browser window is up and waiting

genmeblog19:02:09

Firefox hangs, eats cpu on getting data from tailwind.css...

genmeblog19:02:10

It's not deterministic on my setup, sometimes I can continue, sometimes I can't clerk/halt! helps or not. Anyway, currently at the stage where color-spans is called but nothing happens, ie. resulting div is empty:

genmeblog19:02:26

when I change transform-fn to identity I'm getting the value

Carsten Behring22:02:51

I replicated here https://scicloj.github.io/scicloj.ml-tutorials/userguide-models_clerk.html#/src/scicloj/ml/models_clerk.clj one of my userguides for Large part of it is "generated", now using clerk functions. It has as well quite some vega plots and other images. Most was rather easy to do, Clerk is getting really good. 👍 Overall three issues: 1. cannot control overall output width: https://github.com/nextjournal/clerk/issues/68 2. Non deterministic cach behavoiur if vars are defined multiple times: https://github.com/nextjournal/clerk/issues/66 3. A real TOC is missing. I used a workaround. Should come soon. 4. Cannot render verbatim text with newlines: https://github.com/nextjournal/clerk/issues/69 Great job overall !

🙌 2
Carsten Behring18:02:56

for 1): But this cannot be applied to all cells in one go, but needed to be done for each code expression, correct ? So I look for a way to set the default output width.

mkvlr18:02:41

correct. What you want to set the default to? Currently the table viewer defaults to :wide while most other cells default to :prose . Wide large images default to :full , others to :wide. So there’s not a single default and I’m unsure there should be as e.g. all images will no look good in :full.

1
mkvlr18:02:28

or are you looking for other options besides those three?

Carsten Behring21:02:48

Hmm . Not sure. I just know that I use "wide" or "full" often to show wide / full polts and tables. And combining this with the code in the normal ,, narrow style", looks ugly.