Hello, Mauricio had talked about customising rendering on Chlorine via CLJS config. I was unable to find how to do this, from reading the docs on Atom's site, and the linked FAQ. Is this an upcoming thing, or are the details somewhere I haven't looked?
Also, is there a way for me to write a modified version of evaluate-top-block
that does one level down if the top block happens to be a comment
form?
Hi, yes, it is already on Chlorine and Clover, but it's not really that well documented.
For now, you need to write a custom eval command with the "interactive eval". It's on the path to becoming more easy and better to write :)
Also, yes, there's a way to write this modified command. It's not that easy to do what you want, because you'll be transforming strings, but you can replace the command with do
, for example. Let me get into a computer and I'll open a thread with examples on how to handle both cases @jaihindhreddy
Ok, so for this case of converting comment
into do
:
(defn top-block-ignoring-comment []
(p/let [code (editor/get-top-block)
code (update code :text #(str/replace-first % #"\(.*?comment" "(do "))]
(editor/eval-and-render code)))
As for the way to customize the rendering, there's some documentation here: https://github.com/mauricioszabo/atom-chlorine/blob/master/docs/extending.md#interactive-results and also here: https://github.com/mauricioszabo/atom-chlorine/blob/master/docs/custom-renderers.md
But the idea, if you don't need to use external JS libraries (for example, if you don't want to plot, or use d3, etc) is to create a custom command that will evaluate something that returns a map with :html
, :state
, and :fns
keys
So, :html
will be a hiccup representing the HTML that you want to render. It'll bind the variable ?state
into the state.
This is an example on how to evaluate a map and render as a table:
(defn map-as-table []
(p/let [code (editor/get-top-block)
text (pr-str '{:html '[:div.rows
[:div.title "Result"]
[:table {:border "2"}
[:tbody
(for [[k v] ?state]
[:tr {:key k}
[:td (pr-str k)]
[:td (pr-str v)]])]]]
:state ?placeholder})
code (update code :text #(str/replace-first text "?placeholder" %))]
(editor/eval-interactive code)))
Place notice the quoting for the map form (so it's easier to prepare the code that will be evaluated in the REPL so that it returns the map structure that I want) and the quoting just after :html
(it will ask for clojure to ALSO quote that hiccup for, when you run into the REPL).
If you don't add the quote after :html
, the Clojure REPL will think that ?state
is a variable, and try to evaluate it - and we don't really want this 😄
If you want this code to work with other data structure too, you can add a guard/use :div/clj
to render as the default way
So, in this case, the code will be:
(defn map-as-table []
(p/let [code (editor/get-top-block)
text (pr-str '{:html '[:div.rows
[:div.title "Result"]
(if (map? ?state)
[:table {:border "2"}
[:tbody
(for [[k v] ?state]
[:tr {:key k}
[:td (pr-str k)]
[:td (pr-str v)]])]]
[:div/clj ?state])]
:state ?placeholder})
code (update code :text #(str/replace-first text "?placeholder" %))]
(editor/eval-interactive code)))
I really hope that helps, @jaihindhreddy 🙂
In the future, the idea is that Chlorine should be able to add metadata to results, and these will be used to render the results. It'll become way easier 🙂
Helps a lot! Thanks!
Please, don't hesitate to ask for more info 🙂. I'm aware that this implementation is a little bit confusing too 😄