Skip to content

Commit debf1a4

Browse files
zampinophilippamarkovicsmk
committed
Improve Table of Contents (#512)
Overhaul design and fix re-rendering issues. Also added suport for chapter expansion. --------- Co-authored-by: Philippa Markovics <[email protected]> Co-authored-by: Martin Kavalar <[email protected]>
1 parent 45a1129 commit debf1a4

File tree

15 files changed

+305
-336
lines changed

15 files changed

+305
-336
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ Changes can be:
1818

1919
* 🚨 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.
2020

21+
* 📖 Improve Table of Contents design and fixing re-rendering issues. Also added suport for chapter expansion.
22+
2123
* 💫 Assign `:name` to every viewer in `default-viewers`
2224

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

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

27-
2829
## 0.14.919 (2023-06-13)
2930

3031
* 🚨 Breaking Changes:

notebooks/cherry.clj

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
;; # Compile viewer functions using cherry
1+
;; # 🍒 Compile viewer functions using cherry
22
(ns cherry
3-
{:nextjournal.clerk/render-evaluator :cherry}
3+
{:nextjournal.clerk/render-evaluator :cherry
4+
:nextjournal.clerk/toc true}
45
(:require [nextjournal.clerk :as clerk]
56
[nextjournal.clerk.viewer :as viewer]))
67

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

22-
;; Better performance:
23+
;; ## ⏱️ Better performance:
2324

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

57-
;; ## Input text and compile on the fly with cherry
58+
;; ## 🔨 Input text and compile on the fly with cherry
5859

5960
(clerk/with-viewer
6061
{;; :evaluator :cherry
@@ -80,15 +81,15 @@
8081
{:nextjournal.clerk/render-evaluator :cherry}
8182
nil)
8283

83-
;; ## Functions defined with `defn` are part of the global context
84+
;; ## 🌍 Functions defined with `defn` are part of the global context
8485

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

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

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

91-
;; ## Async/await works cherry
92+
;; ## 🚦Async/await works cherry
9293

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

115-
;; ## Macros
116+
;; ## 🧩 Macros
116117

117118
(clerk/eval-cljs
118119
'(defn clicks []
@@ -123,7 +124,7 @@
123124

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

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

notebooks/document_linking.clj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
;; # 🖇️ Document Linking
22
(ns document-linking
3+
{:nextjournal.clerk/toc true}
34
(:require [nextjournal.clerk :as clerk]))
45

6+
;; ## `clerk/doc-url` helper
57
;; 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.
68
(clerk/html
79
[:ol
@@ -12,6 +14,8 @@
1214
[:li [:a {:href (clerk/doc-url "book.clj")} "The 📕Book"]]
1315
[:li [:a {:href (clerk/doc-url "")} "Homepage"]]])
1416

17+
18+
;; ## Client Side
1519
;; The same functionality is available in the SCI context when building render functions.
1620
(clerk/with-viewer
1721
'(fn [_ _]

notebooks/how_clerk_works.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
;; # How Clerk Works 🕵🏻‍♀️
2-
^{:nextjournal.clerk/toc true}
32
(ns how-clerk-works
3+
{:nextjournal.clerk/toc true}
44
(:require [next.jdbc :as jdbc]
55
[nextjournal.clerk :as clerk]
66
[nextjournal.clerk.parser :as parser]

notebooks/meta_toc.clj

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
;; # 📕 Meta Table of Contents
2+
(ns meta-toc
3+
{:nextjournal.clerk/toc true}
4+
(:require [nextjournal.clerk :as clerk]
5+
[nextjournal.clerk.parser :as parser]
6+
[nextjournal.markdown.transform :as md.transform]
7+
[nextjournal.clerk.viewer :as v]))
8+
9+
;; This assembles the table of contents programmatically from a
10+
;; collection of notebooks.
11+
12+
;; ## Notebooks
13+
(def notebooks
14+
["notebooks/how_clerk_works.clj"
15+
"notebooks/cherry.clj"
16+
"notebooks/tracer.clj"
17+
"notebooks/document_linking.clj"])
18+
19+
(defn md-toc->navbar-items [current-notebook file {:keys [children]}]
20+
(mapv (fn [{:as item :keys [emoji attrs]}]
21+
{:title (md.transform/->text item)
22+
:expanded? (= current-notebook file)
23+
:scroll-to-anchor? false
24+
:emoji emoji
25+
:path (clerk/doc-url file (:id attrs))
26+
:items (md-toc->navbar-items current-notebook file item)}) children))
27+
28+
(defn meta-toc [current-notebook paths]
29+
(into []
30+
(mapcat (comp (fn [{:keys [toc file]}] (md-toc->navbar-items current-notebook file toc))
31+
(partial parser/parse-file {:doc? true})))
32+
paths))
33+
34+
(def book-viewer
35+
(update v/notebook-viewer
36+
:transform-fn (fn [original-transform]
37+
(fn [wrapped-value]
38+
(-> wrapped-value
39+
original-transform
40+
(assoc :nextjournal/opts {:expandable? true})
41+
(assoc-in [:nextjournal/value :toc]
42+
(meta-toc (:file (v/->value wrapped-value)) notebooks)))))))
43+
44+
#_(clerk/add-viewers! [book-viewer])
45+
46+
;; Test actual cross-doc toc
47+
(clerk/add-viewers! [book-viewer])

notebooks/profile.clj

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@
1717

1818

1919

20-
(do (time (analyzer/build-graph analyzed)) :done)
20+
(time
21+
(prof/profile (dotimes [_ 10]
22+
(analyzer/build-graph analyzed))))
2123

2224

2325

24-
(prof/profile (analyzer/build-graph analyzed))
26+
(prof/profile
27+
(dotimes [_ 10]
28+
(nextjournal.clerk/show! "notebooks/rule_30.clj")))
2529

2630
(prof/profile (analyzer/build-graph analyzed))
2731

notebooks/tracer.clj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
;; # 👩🏻‍💻 Show the code
2-
^{:nextjournal.clerk/visibility {:code :hide}}
2+
33
(ns tracer
4+
{:nextjournal.clerk/visibility {:code :hide}
5+
:nextjournal.clerk/toc true}
46
(:require [nextjournal.clerk :as clerk]))
57

68
;; ## Tracer

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"@nextjournal/lezer-clojure": "1.0.0",
1919
"d3-require": "^1.2.4",
2020
"emoji-regex": "^10.0.0",
21-
"framer-motion": "^6.2.8",
21+
"framer-motion": "^10.12.16",
2222
"katex": "^0.12.0",
2323
"lezer-clojure": "1.0.0-rc.2",
2424
"markdown-it": "^12.2.0",

src/nextjournal/clerk/analyzer.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@
379379
(or (when-let [{:as cached-analysis :keys [file-sha]} (@!file->analysis-cache file)]
380380
(when (= file-sha current-file-sha)
381381
cached-analysis))
382-
(let [analysis (analyze-doc {:file-sha current-file-sha} (parser/parse-file {} file))]
382+
(let [analysis (analyze-doc {:file-sha current-file-sha :graph (dep/graph)} (parser/parse-file {} file))]
383383
(swap! !file->analysis-cache assoc file analysis)
384384
analysis))))
385385
([state file]

src/nextjournal/clerk/builder.clj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"fragments"
3737
"hiding_clerk_metadata"
3838
"js_import"
39+
"meta_toc"
3940
"multiviewer"
4041
"pagination"
4142
"paren_soup"

0 commit comments

Comments
 (0)