Fork me on GitHub
#clerk
<
2023-02-05
>
Carsten Behring22:02:43

Currently a clerk viewer does not have an "id". It is just a map of 3 functions. I suppose that at a certain moment tooling comes up, which should allow to "select" a Clerk viewer. I started with such tooling for Cider. Such tooling would need to be able to select viewers based on some form of id. @mkvlr Have you thought about this more concrete ? Some viewers have a :name and some have a symbol, but none of this is "mandatory".

mkvlr07:02:44

the name / id I would recommend you use is the clojure var that holds the viewer.

mkvlr07:02:31

what are your needs exactly? I don’t think you’ll want to offer the full https://github.com/nextjournal/clerk/blob/19ba342cb7a992c27621ffc2355961bd2ecdb4e9/src/nextjournal/clerk/viewer.cljc#L1016-L1061 to choose from, or do you?

Carsten Behring13:02:49

Maybe indeed the full list... I work on some Cider - inspector feature https://github.com/clojure-emacs/cider/issues/3311 which would in some form to ask the user interactively "which viewer to use" and then attach the clerk specific metadata on a "value" on the fly and tap this (and I use Clerk tap inspector to show it) This does work "In principle"., see here for some emacs lisp code. https://github.com/clojure-emacs/cider/issues/3311#issuecomment-1405585049 I cannot see this working without having viewers a "unique id" (and which should be "human readable", so that user can see "what type of data" the viewer will likely work with... This might not work for all situations , but for quite some. Additionally I would like that the "options" can be dynamically requested, insteada of being a fixed list. (which does work, in principle) It is just not "clear" if and which viewers have a ":name" vs "a symbol" vs being a var I would therefore think as well that viewers should have "inside a running Clerk" a guaranteed unique id...

mkvlr13:02:27

not all viewers make sense

Carsten Behring13:02:32

I can only say that this is "very convenient" for Emacs users. I can drill down to any complex data structure with cider-inspector and send the "current value" to Clerk tap inspector for "rich rendering" (and Emacs asks me on teh fly on "which renderer" and atahced on-the-fly the metadata accordingly the teh value So this is "Clerk usage without any notebook", via Clerk tap Inspector

Carsten Behring13:02:41

(so maybe we need some viewer metadata of which viewer make sense), agree.

Carsten Behring13:02:26

My "examples", would be clearly: :html :vega-lite :latex (... hmm String will not work ...) and several "not build in", like: "cytoscope" and others "from the community"....

mkvlr13:02:17

seems you’re already using the viewer vars? So what other names do you need?

mkvlr13:02:16

would be best if you used the symbol nextjournal.clerk.viewer/,,,-viewer names consistently

👍 2
mkvlr13:02:31

does the code from the issue work?

mkvlr13:02:57

some stuff like nextjournal.clerk.viewer/string-viewer doesn’t make sense imo. When would you ever want to manually select such a viewer?

mkvlr13:02:21

also default maybe doesn’t make sense? If you want default, you can just use the normal tap?

mkvlr13:02:31

I think you’re missing a requiring-resolve in your code

Carsten Behring18:02:25

Maybe I did not paste the most recent version of the example. I have this function in my emacs config, which does work:

(defun clerk-get-current-viewers ()

  (read
   (nrepl-dict-get
    (nrepl-sync-request:eval
        "
 (do
 (require 'nextjournal.clerk)
 
 (conj
  (->>
   (nextjournal.clerk/get-default-viewers)
   (map :name)
   (remove nil?))
  :default))
"
     (cider-current-connection))
    "value")))

;;  Call while in `cider-inspector` to show current value in Clerk after a viewer is selected
(defun cider-inspector-tap-current-val-with-clerk-viewer (viewer)
  (interactive
   (list (completing-read "Choose viewer: " (clerk-get-current-viewers)
                          nil t)))

  (setq cider-inspector--current-repl (cider-current-repl))
  ;; pick some random name, which hopeuflly is never used...
  (when-let* ((ns "user")
              (var-name "cider-inspector-temp-hdhsad-hbjdbasjd842342")
              (value (cider-sync-request:inspect-def-current-val ns var-name)))

    (let ((tapped-form (concat "(clojure.core/->> "
                               (concat ns "/" var-name)
                               (if (equal ":default" viewer)
                                   (concat " (nextjournal.clerk/with-viewer {:transform-fn identity})")
                                 (if (string-prefix-p ":" viewer)
                                     (concat " (nextjournal.clerk/with-viewer " "(keyword \"" (substring viewer 1) "\")" ")")
                                   (concat " (nextjournal.clerk/with-viewer " "(symbol \"" viewer "\")" ")"))
                                 )

                               " (clojure.core/tap>))")))
      (cider-interactive-eval tapped-form
                              nil
                              nil
                              (cider--nrepl-pr-request-map)))


    (message "%s#'%s/%s = %s" cider-eval-result-prefix ns var-name value)))

Carsten Behring18:02:16

cider is missing a "inspect-tap-current-value" , so I need this ugly workarround for now, to define a var and then tap> that one. A PR for cider is on teh way to change this.

Carsten Behring18:02:09

It would be nice if I could indeed "filter" the viewers which make sense. So we needed some "viewer metadata", not sre in which form. Why does :html make sense and :string not ? I can see your point, what I am doubting is what differentiates "usefull from not usefull" ?

Carsten Behring18:02:50

and how can I get "user supplied viewers" into my "list" ? They won' have a symbol, will they ? (at least not in ns nextjournal.clerk.viewer)

Carsten Behring18:02:05

It seems that I am asking for a runtime "viewer registry" which is more dynamic then be based on symbols and vars in code.

mkvlr19:02:38

html-viewer makes sense because interpreting a vector or a string as html / hiccup isn’t the default. Whereas if you ask Clerk to display a string, it will use the string-viewer anyway.

mkvlr19:02:47

I would recommend to start with something simple, pick a few viewers that make sense. The public https://github.com/nextjournal/clerk/blob/0abef98cecc7e8d5528571902f67e7e54bb67f54/src/nextjournal/clerk/viewer.cljc#L1516-L1527 minus the notebook-viewer should be a reasonable starting set, so: • html-viewer • markdown-viewer • plotly-viewer • vega-lite-viewer • table-viewer • row-viewer • col-viewer • katex-viewer • code-viewer And give folks the ability to customize this set from Emacs and you’re good.

Carsten Behring19:02:09

So you would advise against a dynamic list ?

Carsten Behring19:02:47

In any case, Cider will never have this. Cider will , as I understood gain a function to simply "tap" the current value of the inspector. All the rest is "customization" via advise

Carsten Behring19:02:38

outside Cider, which make sense to me.

mkvlr19:02:45

what’s advise?

mkvlr19:02:24

by in cider I meant inside emacs, so a list that customizable from emacs

Carsten Behring19:02:26

yes, definitely an option. I will keep this in my had, once the cider functionality is there.

👍 2