nextjournal 2021-12-08

weโ€™d like to cut a Clerk release, would appreciate it if folks could take io.github.nextjournal/clerk {:git/sha "aa6ed09880316d15b0d3c76ae50505d1978e4008"} for a spin and let me know if thereโ€™s anything we missed. Preliminary changelog is at https://github.com/nextjournal/clerk/blob/main/CHANGELOG.md#unreleased

@carsten.behring @daslu I believe both of you asked for being able to let Clerk serve arbitrary things. In the latest main a viewer can provide a fetch-fn to enable this by returning a map with :nextjournal/content-type and :nextjournal/value keys, see https://github.com/nextjournal/clerk/blob/main/notebooks/viewers/image.clj for an example. This will also inline the blob for the static builds. Curious to hear if that serves your needs.

Wonderful, many thanks, @mkvlr. I hope to look into that soon.

๐Ÿ™ 1

Thanks. Looking at the example seems to say, that it satisfies the "general need", of being able to load / generate byte arrays in image format and show them on the web. This would allow Clerk , for example, to render plots where the plotting library can only generate "desktop" graphics, typically PNGs.

I was a bit wondering, if there is a limitation that I need to set a global viewer for any type of "bytes" (= same viewer for all byte arrays).

no, you could also set a viewer e.g. on java.io.File and match on an extension

the bytes? is just an example

and probably not a super good one

think we might want to add the file viewers as defaults

Is there documentation which function a pred? can be ?

so what exactly gets passed to the function specified in :pred?

The "evaluation result" ?

I just looked at teh code, and relaized how

clerk/set-viewers!
clerk/with-viewer
clerk/with-viewers
So I have ultimate control on the "active viewers" That's fine. So pred?: true would works as well, if i am inside a with-viewer block. That was my doubt.

I will try it a bit.

it is supposed to work with with-viewers ?

This fails:

(clerk/with-viewers [{:pred bytes?
                      :fetch-fn (fn [_ bytes] {:nextjournal/content-type "image/png"}
                                              :nextjournal/value bytes)
                      :render-fn (fn [blob] (v/html [:img {:src (v/url-for blob)}]))}]

  (.. (HttpClient/newHttpClient)
      (send (.build (HttpRequest/newBuilder (URI. "")))
            (HttpResponse$BodyHandlers/ofByteArray)) body))

with-viewers works

The issue went away. The image supports is working, thanks @mkvlr

@carsten.behring good to hear. Btw you should also be able to register the predicate on the file and use a :transform-fn to convert it to bytes

and you can use clerk/set-viewers!

then creating a file object is enough to display it as an image

;; # ๐Ÿž Customizing Fetch
;; Showing how to use a custom `fetch-fn` with a `content-type` to let Clerk serve arbitrary things, in this case a PNG image.
(ns ^:nextjournal.clerk/no-cache image
  (:require [ :as io]
            [nextjournal.clerk :as clerk])
  (:import (java.nio.file Files)))

;; We set a custom viewer for `java.io.File` that includes a `:fetch-fn`, returning a wrapped value with a `:nextjournal/content-type` key set.
(clerk/set-viewers! [{:pred #(instance? File %)
                      :fetch-fn (fn [_ file] {:nextjournal/content-type "image/png"
                                              :nextjournal/value (Files/readAllBytes (.toPath file))})
                      :render-fn (fn [blob] (v/html [:img {:src (v/url-for blob)}]))}])


(io/file "/Users/mk/Downloads/James_Clerk_Maxwell.png")

this is just for pngs but could check the extension or sniff the content type to extend this

Maybe something for the docu: Avoid a namespace like:

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


(clerk/show! "notebooks/wordclouds.clj")

โœ… 1

endless loop ... while evaluating last line

I was looking at the visibility control in the new version of Clerk. Nice !

This allows now precise control what to hide and what to show. Nevertheless I found myself quite a lot of times using clerk/hide-result It is maybe possible to use the hide-result as metadata and have an option to hide results for the whole ns and switch it on for a few forms only ? A good use case for this is "documentation of Clojure libraries", where maybe a lot of code / results is hidden.

this use case is actually something we want to support better

but want to explore the minimum thing needed in Clerk to support this first

I see 4 use cases: 1. I know I do a data science notebook for me, so I want to see all code and all results 2. I know I want to do docu, so I want to show some (most code, most results) 3. I do a data science notebook , and a static rendering I want to hide all code (for my manager) (= override the visibility settings) 4. I want to do a specially nice output. So I need to be sure to be able to disable all ugly output/code The fact that Clerk renders as well "one lines" on def / nil makes this control more important

So the same as for "hide and "fold"

To get this result:

I need to use "hide-result" a lot

This is maybe not for the typical data science notebook use case, I agree.

I changed a bit the code and it seemed to work very nice. I made a PR to replace the hide-result fn with meta data :hide-result :show-result https://github.com/nextjournal/clerk/pull/24

An other idea for a feature: Allow "copy" from a code cell with one keypress. And eventually as well for whole rendered namespace.

copy the result you mean?

just a simple button, which copies the code from a code cell, without need to "mark" by mouse