Skip to content

Commit

Permalink
Merge branch 'main' into dedupe-viewer-fns
Browse files Browse the repository at this point in the history
  • Loading branch information
mk committed Aug 28, 2023
2 parents 493b1b8 + f6d9d89 commit c00e6e1
Show file tree
Hide file tree
Showing 44 changed files with 1,425 additions and 744 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ jobs:
uses: google-github-actions/setup-gcloud@v0.3.0

- name: 📓 Build Clerk Book
run: clojure -J-Dclojure.main.report=stderr -X:demo:nextjournal/clerk :git/sha '"${{ github.sha }}"' :git/url '"https://github.com/nextjournal/clerk"' :paths '["book.clj" "CHANGELOG.md"]'
run: |
cp notebooks/editor.clj editor.clj
clojure -J-Dclojure.main.report=stderr -X:demo:nextjournal/clerk :git/sha '"${{ github.sha }}"' :git/url '"https://github.com/nextjournal/clerk"' :paths '["book.clj" "CHANGELOG.md" "editor.clj"]'
- name: 🏗 Build Clerk Static App with default Notebooks
run: clojure -J-Dclojure.main.report=stderr -X:demo:nextjournal/clerk :git/sha '"${{ github.sha }}"' :git/url '"https://github.com/nextjournal/clerk"' :bundle true
Expand Down
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,37 @@ Changes can be:

* 🚨 Rename `:nextjournal.clerk/opts` to `:nextjournal.clerk/render-opts` to clarify this options map is available as the second arg to parametrize the `:render-fn`. Still support the `:nextjournal.clerk/opts` for now.

* 🚨 Simplify html rendering internals

Removed

* `nextjournal.clerk.viewer/reagent-viewer`,
* `nextjournal.clerk.render/html-viewer`,
* `nextjournal.clerk.render/html`, and
* `nextjournal.clerk.render/render-reagent`.

From now on, please use
* `nextjournal.clerk.viewer/html-viewer`, and
* `nextjournal.clerk.viewer/html` instead.

Also rename `nextjournal.clerk.render/html-render` to `nextjournal.clerk.render/render-html` and make `nextjournal.clerk.viewer/html` use it when called from a reactive context.

* 🚨 Unify the link handling between `build!` and `serve!`

By no longer using extensions in either mode (was `.clj|md` in `serve!` and `.html` in `build!`).

To support this in the unbundled static build, we're now writing directories with `index.html` for each notebook. This makes links in this build no longer accessible without a http server. If you're looking for a self-contained html that works without a webserver, set the `:bundle` option.

* 📖 Improve Table of Contents design and fixing re-rendering issues. Also added suport for chapter expansion.

* 📒 Mention Tap Inspector in Book of Clerk & on Homepage

* 🛠 Upgrade `framer-motion` dep to `10.12.16`.

* 💫 Assign `:name` to every viewer in `default-viewers`

* 🐞 Don't run existing files through `fs/glob`, fixes [#504](https://github.com/nextjournal/clerk/issues/504). Also improves performance of homepage.

* 🐞 Show correct non-var return value for deflike form, fixes [#499](https://github.com/nextjournal/clerk/issues/499)

## 0.14.919 (2023-06-13)
Expand Down
18 changes: 15 additions & 3 deletions book.clj
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,6 @@
;; nmap <silent> <localleader>cs :execute ClerkShow()<CR>
;; ```



;; ## 🔍 Viewers

;; Clerk comes with a number of useful built-in viewers e.g. for
Expand Down Expand Up @@ -913,6 +911,20 @@ v/table-viewer

^{::clerk/budget nil ::clerk/auto-expand-results? true} rows

;; ## 🚰 Tap Inspector

;; Clerk comes with an inspector notebook for Clojure's tap system. Use the following form from your REPL to show it.

;;```clojure
;;(nextjournal.clerk/show! 'nextjournal.clerk.tap)
;;```

;; You can then call `tap>` from anywhere in your codebase and the Tap Inspector will show your value. This supports the full viewer api described above.

;;```clojure
;;(tap> (clerk/html [:h1 "Hello 🚰 Tap Inspector 👋"]))
;;```

;; ## 🧱 Static Building

;; Clerk can make a static HTML build from a collection of notebooks.
Expand All @@ -928,7 +940,7 @@ v/table-viewer
;; Also notably, there is a `:compile-css` option which compiles a css
;; file containing only the used CSS classes from the generated
;; markup. (Otherwise, Clerk is using Tailwind's Play CDN script which
;; can the page flicker, initially.)
;; can make the page flicker, initially.)

;; If set, the `:ssr` option will use React's server-side-rendering to
;; include the generated markup in the build HTML.
Expand Down
4 changes: 2 additions & 2 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

:aliases {:nextjournal/clerk {:extra-deps {org.clojure/clojure {:mvn/version "1.11.1"} ;; for `:as-alias` support in static build
org.slf4j/slf4j-nop {:mvn/version "2.0.7"}
org.babashka/cli {:mvn/version "0.6.50"}}
org.babashka/cli {:mvn/version "0.7.52"}}
:extra-paths ["notebooks"]
:exec-fn nextjournal.clerk/build!
:exec-args {:paths-fn nextjournal.clerk.builder/clerk-docs}
Expand Down Expand Up @@ -71,7 +71,7 @@
sicmutils/sicmutils {:mvn/version "0.20.0"}
io.github.mentat-collective/emmy {:git/sha "b98fef51d80d3edcff3100562b929f9980ff34d7"
:exclusions [org.babashka/sci]}
io.github.nextjournal/clerk-slideshow {:git/sha "0e6e890fd4f862fa3535290cb7e29591c6e0ec85"}}}
io.github.nextjournal/clerk-slideshow {:git/sha "11a83fea564da04b9d17734f2031a4921d917893"}}}

:build {:deps {io.github.nextjournal/clerk {:local/root "."}
io.github.nextjournal/cas-client {:git/sha "84ab35c3321c1e51a589fddbeee058aecd055bf8"}
Expand Down
5 changes: 3 additions & 2 deletions index.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
(clerk/html
[:div.viewer-markdown
[:ul
[:li [:a.underline {:href (clerk/doc-url "notebooks/rule_30.clj")} "Rule 30"]]
[:li [:a.underline {:href (clerk/doc-url "notebooks/markdown.md")} "Markdown"]]]])
[:li [:a.underline {:href (clerk/doc-url "notebooks/rule_30")} "Rule 30"]]
[:li [:a.underline {:href (clerk/doc-url "notebooks/links")} "Link Design"]]
[:li [:a.underline {:href (clerk/doc-url "notebooks/markdown")} "Markdown"]]]])
27 changes: 10 additions & 17 deletions notebooks/cards.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
;; # 🃏 CLJS Cards
^{:nextjournal.clerk/toc true :nextjournal.clerk/visibility {:code :hide}}
(ns cards
{:nextjournal.clerk/no-cache true}
{:nextjournal.clerk/toc true
:nextjournal.clerk/no-cache true
:nextjournal.clerk/visibility {:code :hide}}
(:require [applied-science.js-interop :as-alias j]
[cards-macro :as c]
[nextjournal.clerk :as clerk]
Expand Down Expand Up @@ -126,13 +127,12 @@
(reagent/as-element [:h1 "♻️"]))

(c/card
(v/with-viewer `v/reagent-viewer
(fn []
(reagent/with-let [c (reagent/atom 0)]
[:<>
[:h2 "Count: " @c]
[:button.rounded.bg-blue-500.text-white.py-2.px-4.font-bold.mr-2 {:on-click #(swap! c inc)} "increment"]
[:button.rounded.bg-blue-500.text-white.py-2.px-4.font-bold {:on-click #(swap! c dec)} "decrement"]]))))
(v/with-viewer '(fn [] (reagent/with-let [c (reagent/atom 0)]
[:<>
[:h2 "Count: " @c]
[:button.rounded.bg-blue-500.text-white.py-2.px-4.font-bold.mr-2 {:on-click #(swap! c inc)} "increment"]
[:button.rounded.bg-blue-500.text-white.py-2.px-4.font-bold {:on-click #(swap! c dec)} "decrement"]]))
{}))

;; ## Using `v/with-viewer`
(c/card
Expand Down Expand Up @@ -223,13 +223,6 @@
(update doc :blocks (partial map (fn [{:as b :keys [type text]}]
(cond-> b
(= :code type)
(assoc :result
{:nextjournal/value
(let [val (eval (read-string text))]
;; FIXME: this won't be necessary once we unify v/html in SCI env to be the same as in nextjournal.clerk.viewer
;; v/html is currently html-render for supporting legacy render-fns
(cond->> val
(nextjournal.clerk.render/valid-react-element? val)
(v/with-viewer v/reagent-viewer)))})))))
(assoc :result {:nextjournal/value (eval (read-string text))})))))
(v/with-viewer v/notebook-viewer {::clerk/width :wide} doc))
)
17 changes: 9 additions & 8 deletions notebooks/cherry.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
;; # Compile viewer functions using cherry
;; # 🍒 Compile viewer functions using cherry
(ns cherry
{:nextjournal.clerk/render-evaluator :cherry}
{:nextjournal.clerk/render-evaluator :cherry
:nextjournal.clerk/toc true}
(:require [nextjournal.clerk :as clerk]
[nextjournal.clerk.viewer :as viewer]))

Expand All @@ -19,7 +20,7 @@
(pr-str (interleave (cycle [1]) (frequencies [1 2 3 1 2 3])))))])
{:nextjournal.clerk/render-evaluator :sci} nil)

;; Better performance:
;; ## ⏱️ Better performance:

(clerk/with-viewer
'(fn [value]
Expand Down Expand Up @@ -54,7 +55,7 @@
:key "id" :fields ["rate"]}}]
:projection {:type "albersUsa"} :mark "geoshape" :encoding {:color {:field "rate" :type "quantitative"}}})

;; ## Input text and compile on the fly with cherry
;; ## 🔨 Input text and compile on the fly with cherry

(clerk/with-viewer
{;; :evaluator :cherry
Expand All @@ -80,15 +81,15 @@
{:nextjournal.clerk/render-evaluator :cherry}
nil)

;; ## Functions defined with `defn` are part of the global context
;; ## 🌍 Functions defined with `defn` are part of the global context

;; (for now) and can be called in successive expressions

(clerk/eval-cljs-str "(defn foo [x] (this-as this (inc x)))")

(clerk/eval-cljs-str "(foo 1)")

;; ## Async/await works cherry
;; ## 🚦Async/await works cherry

;; Here we dynamically import a module, await its value and then pull out the
;; default function, which we expose as a global function. Because s-expressions
Expand All @@ -112,7 +113,7 @@
[nextjournal.clerk.render/render-promise
(emoji-picker)]) nil)

;; ## Macros
;; ## 🧩 Macros

(clerk/eval-cljs
'(defn clicks []
Expand All @@ -123,7 +124,7 @@

(clerk/with-viewer '(fn [_] (this-as this [clicks])) nil)

;; ## Evaluator option as form metadata
;; ## 👻 Evaluator option as form metadata
^{::clerk/visibility {:code :hide :result :hide} ::clerk/no-cache true}
(clerk/add-viewers! [(assoc viewer/code-block-viewer :transform-fn (viewer/update-val :text))])

Expand Down
20 changes: 12 additions & 8 deletions notebooks/document_linking.clj
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
;; # 🖇️ Document Linking
(ns document-linking
{:nextjournal.clerk/toc true}
(:require [nextjournal.clerk :as clerk]))

;; ## `clerk/doc-url` helper
;; The helper `clerk/doc-url` allows to reference notebooks by path. We currently support relative paths with respect to the directory which started the Clerk application. An optional trailing hash fragment can appended to the path in order for the page to be scrolled up to the indicated identifier.
(clerk/html
[:ol
[:li [:a {:href (clerk/doc-url "notebooks/viewers/html.clj")} "HTML"]]
[:li [:a {:href (clerk/doc-url "notebooks/viewers/image.clj")} "Images"]]
[:li [:a {:href (clerk/doc-url "notebooks/markdown.md" "appendix")} "Markdown / Appendix"]]
[:li [:a {:href (clerk/doc-url "notebooks/how_clerk_works.clj" "step-3:-analyzer")} "Clerk Analyzer"]]
[:li [:a {:href (clerk/doc-url "book.clj")} "The 📕Book"]]
[:li [:a {:href (clerk/doc-url "notebooks/viewers/html")} "HTML"]]
[:li [:a {:href (clerk/doc-url "notebooks/viewers/image")} "Images"]]
[:li [:a {:href (clerk/doc-url "notebooks/markdown" "appendix")} "Markdown / Appendix"]]
[:li [:a {:href (clerk/doc-url "notebooks/how_clerk_works" "step-3:-analyzer")} "Clerk Analyzer"]]
[:li [:a {:href (clerk/doc-url "book")} "The 📕Book"]]
[:li [:a {:href (clerk/doc-url "")} "Homepage"]]])


;; ## Client Side
;; The same functionality is available in the SCI context when building render functions.
(clerk/with-viewer
'(fn [_ _]
[:ol
[:li [:a {:href (nextjournal.clerk.viewer/doc-url "notebooks/viewers/html.clj")} "HTML"]]
[:li [:a {:href (nextjournal.clerk.viewer/doc-url "notebooks/markdown.md")} "Markdown"]]
[:li [:a {:href (nextjournal.clerk.viewer/doc-url "notebooks/viewer_api.clj")} "Viewer API / Tables"]]]) nil)
[:li [:a {:href (nextjournal.clerk.viewer/doc-url "notebooks/viewers/html")} "HTML"]]
[:li [:a {:href (nextjournal.clerk.viewer/doc-url "notebooks/markdown")} "Markdown"]]
[:li [:a {:href (nextjournal.clerk.viewer/doc-url "notebooks/viewer_api")} "Viewer API / Tables"]]]) nil)
9 changes: 9 additions & 0 deletions notebooks/editor.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(ns editor
{:nextjournal.clerk/visibility {:code :hide}
:nextjournal.clerk/doc-css-class [:overflow-hidden :p-0]}
(:require [nextjournal.clerk :as clerk]))

(clerk/with-viewer
{:render-fn 'nextjournal.clerk.render.editor/view
:transform-fn clerk/mark-presented}
(slurp "notebooks/rule_30.clj"))
24 changes: 21 additions & 3 deletions notebooks/exec_status.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
;; # 💈 Execution Status
(ns exec-status
{:nextjournal.clerk/toc true}
(:require [nextjournal.clerk :as clerk]))
(:require [nextjournal.clerk :as clerk]
[nextjournal.clerk.webserver :as webserver]))

;; To see what's going on while waiting for a long-running
;; computation, Clerk will now show an execution status bar on the
Expand All @@ -25,20 +26,37 @@

{:progress 0.15 :status "Analyzing…"}

{:progress 0.55 :status "Evaluating…"}
{:progress 0.55 :cell-progress 0.34 :status "Evaluating…"}

{:progress 0.95 :status "Presenting…"}

(defn set-cell-progress! [progress]
(swap! webserver/!doc (fn [doc] (if-let [status (-> doc meta :status)]
(let [status+progress (assoc status :cell-progress progress)]
(when-let [send-future (-> doc meta ::webserver/!send-status-future)]
(future-cancel send-future))
(webserver/broadcast-status! status+progress)
(-> doc
(vary-meta dissoc ::!send-status-future)
(vary-meta assoc :status status+progress)))
doc))))

(defonce !rand
(atom 0))

^::clerk/no-cache (reset! !rand (rand-int 100))
(Thread/sleep (+ 2000 @!rand))

(def sleepy-cell
(Thread/sleep (+ 2001 @!rand)))
(let [total (+ 2001 @!rand)]
(doseq [i (range total)]
(do
(Thread/sleep 10)
(set-cell-progress! (/ i (float total)))))))

(Thread/sleep (+ 2002 @!rand))

(def sleepy-cell-2
(Thread/sleep (+ 2003 @!rand)))


2 changes: 1 addition & 1 deletion notebooks/how_clerk_works.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
;; # How Clerk Works 🕵🏻‍♀️
^{:nextjournal.clerk/toc true}
(ns how-clerk-works
{:nextjournal.clerk/toc true}
(:require [next.jdbc :as jdbc]
[nextjournal.clerk :as clerk]
[nextjournal.clerk.parser :as parser]
Expand Down
67 changes: 67 additions & 0 deletions notebooks/links.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Links
```clojure
(ns links
{:nextjournal.clerk/toc true}
(:require [nextjournal.clerk :as clerk]))
```
## Design

We have three different modes to consider for links:

1. Interactive mode `serve!`
2. Static build unbundled `(build! {:bundle false})`
3. Static build bundled `(build! {:bundle true})`

The behaviour when triggering links we want is:

1. Interactive mode: trigger a js event `(clerk-eval 'nextjournal.clerk.webserver/navigate! ,,,)`, the doc will in turn be updated via the websocket
2. Static build unbundled: not intercept the link, let the browser perform its normal navigation
3. Static build bundled: trigger a js event to update the doc, update the browser's hash so the doc state is persisted on reload

We can allow folks to write normal (relative) links. The limitations here being that things like open in new tab would not work and we can't support a routing function. Both these limitations means we probably want to continue encouraging the use of a helper like `clerk/doc-url` going forward.

We currently don't support navigating to headings / table of contents sections in the bundled build. This could be supported however by introducing a way to encode that in the hash e.g. with `#page:section`.


## Examples


### JVM-Side

The helper `clerk/doc-url` allows to reference notebooks by path. We currently support relative paths with respect to the directory which started the Clerk application. An optional trailing hash fragment can appended to the path in order for the page to be scrolled up to the indicated identifier.


```clojure
(clerk/html
[:ol
[:li [:a {:href (clerk/doc-url 'nextjournal.clerk.home)} "Home"]]
[:li [:a {:href (clerk/doc-url "notebooks/viewers/html")} "HTML"]]
[:li [:a {:href (clerk/doc-url "notebooks/viewers/image")} "Images"]]
[:li [:a {:href (clerk/doc-url "notebooks/markdown.md" "appendix")} "Markdown / Appendix"]]
[:li [:a {:href (clerk/doc-url "notebooks/how_clerk_works" "step-3:-analyzer")} "Clerk Analyzer"]]
[:li [:a {:href (clerk/doc-url "book")} "The 📕Book"]]
[:li [:a {:href (clerk/doc-url "")} "Homepage"]]])
```

### Render

The same functionality is available in the SCI context when building render functions.

```clojure
(clerk/with-viewer
'(fn [_ _]
[:ol
[:li [:a {:href (nextjournal.clerk.viewer/doc-url "notebooks/viewers/html")} "HTML"]]
[:li [:a {:href (nextjournal.clerk.viewer/doc-url "notebooks/markdown")} "Markdown"]]
[:li [:a {:href (nextjournal.clerk.viewer/doc-url "notebooks/viewer_api")} "Viewer API / Tables"]]]) nil)

```


### Inside Markdown

Links should work inside markdown as well.

* [HTML](../notebooks/viewers/html) (relative link)
* [HTML](clerk/doc-url,"notebooks/viewers/html") (doc url, currently not functional)

Loading

0 comments on commit c00e6e1

Please sign in to comment.