From 6424191145503198ab957fa32d9cb801cd317359 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 11 Aug 2025 12:43:02 +0200 Subject: [PATCH 01/24] wip [skip ci] --- bb.edn | 2 +- src/nextjournal/clerk/builder.clj | 4 +++- src/nextjournal/clerk/render.cljs | 9 +++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/bb.edn b/bb.edn index efc2c9548..8b55601d6 100644 --- a/bb.edn +++ b/bb.edn @@ -20,7 +20,7 @@ build:js {:doc "Builds JS" :depends [yarn-install] - :task (clojure "-M:sci:demo:dev release viewer")} + :task (apply clojure "-M:sci:demo:dev release viewer" *command-line-args*)} build+upload-viewer-resources {:doc "Refreshes assets stored on CDN (google storage)" :extra-paths ["src"] diff --git a/src/nextjournal/clerk/builder.clj b/src/nextjournal/clerk/builder.clj index 186f0a70d..debaf98a4 100644 --- a/src/nextjournal/clerk/builder.clj +++ b/src/nextjournal/clerk/builder.clj @@ -193,6 +193,7 @@ in (str "import '" viewer-js "';" "globalThis.CLERK_SSR = true;" "console.log(nextjournal.clerk.sci_env.ssr(" (pr-str (pr-str state)) "))")] + (spit "in.mjs" in) (sh {:in in} "node" "--abort-on-uncaught-exception" @@ -390,11 +391,12 @@ (build-static-app! {:index "notebooks/document_linking.clj" :paths ["notebooks/viewers/html.clj" "notebooks/rule_30.clj"]}) + ;; document is not defined (build-static-app! {:ssr? true :exclude-js? true ;; test against cljs release `bb build:js` :resource->url {"/js/viewer.js" "./build/viewer.js"} - :index "notebooks/rule_30.clj"}) + :index "notebooks/scratch.clj"}) (build-static-app! {:ssr? true :exclude-js? true diff --git a/src/nextjournal/clerk/render.cljs b/src/nextjournal/clerk/render.cljs index 9cc5b252a..f0a525348 100644 --- a/src/nextjournal/clerk/render.cljs +++ b/src/nextjournal/clerk/render.cljs @@ -21,7 +21,8 @@ [reagent.ratom :as ratom] [sci.core :as sci] [sci.ctx-store] - [shadow.cljs.modern :refer [defclass]])) + [shadow.cljs.modern :refer [defclass]] + [shadow.esm :as esm])) (r/set-default-compiler! (r/create-compiler {:function-components true})) @@ -981,7 +982,11 @@ default-loading-view)))) (defn render-katex [tex-string {:keys [inline?]}] - (let [katex (hooks/use-d3-require "katex@0.16.4")] + (let [katex (if (some-> (unchecked-get js/globalThis "process") + (unchecked-get "versions") + (unchecked-get "node")) + (hooks/use-dynamic-import "katex@0.16.4") + (hooks/use-d3-require "katex@0.16.4"))] (if katex [:span {:dangerouslySetInnerHTML (r/unsafe-html (.renderToString katex tex-string (j/obj :displayMode (not inline?) :throwOnError false)))}] default-loading-view))) From 9477d99eac12aa2e77d2df6a266313fed943511f Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 11 Aug 2025 14:21:50 +0200 Subject: [PATCH 02/24] wip [skip ci] --- src/nextjournal/clerk/builder.clj | 2 ++ src/nextjournal/clerk/render.cljs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/nextjournal/clerk/builder.clj b/src/nextjournal/clerk/builder.clj index debaf98a4..bc0b0a31b 100644 --- a/src/nextjournal/clerk/builder.clj +++ b/src/nextjournal/clerk/builder.clj @@ -191,6 +191,8 @@ tmp) viewer-js) in (str "import '" viewer-js "';" + "import katex from \"katex\";" + "globalThis.clerk$katex = katex;" "globalThis.CLERK_SSR = true;" "console.log(nextjournal.clerk.sci_env.ssr(" (pr-str (pr-str state)) "))")] (spit "in.mjs" in) diff --git a/src/nextjournal/clerk/render.cljs b/src/nextjournal/clerk/render.cljs index f0a525348..e95161bd9 100644 --- a/src/nextjournal/clerk/render.cljs +++ b/src/nextjournal/clerk/render.cljs @@ -985,7 +985,7 @@ (let [katex (if (some-> (unchecked-get js/globalThis "process") (unchecked-get "versions") (unchecked-get "node")) - (hooks/use-dynamic-import "katex@0.16.4") + (unchecked-get js/globalThis "clerk$katex") (hooks/use-d3-require "katex@0.16.4"))] (if katex [:span {:dangerouslySetInnerHTML (r/unsafe-html (.renderToString katex tex-string (j/obj :displayMode (not inline?) :throwOnError false)))}] From b9f9f3d0bc1aba16b89086bf97a9528385ec781f Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 11 Aug 2025 17:22:13 +0200 Subject: [PATCH 03/24] new katex file --- shadow-cljs.edn | 4 +++- src/nextjournal/clerk/sci_env.cljs | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/shadow-cljs.edn b/shadow-cljs.edn index 01ac70f3d..2ee0c45e7 100644 --- a/shadow-cljs.edn +++ b/shadow-cljs.edn @@ -8,7 +8,9 @@ :compiler-options {:source-map true} :dev {:modules {:viewer {:entries [devtools]}}} :modules {:viewer {:entries [nextjournal.clerk.sci-env - nextjournal.clerk.trim-image]}} + nextjournal.clerk.trim-image]} + :katex {:entries ["katex"] + :depends-on #{:viewer}}} :js-options {:output-feature-set :es8} :build-hooks [(shadow.cljs.build-report/hook {:output-to "report.html" :print-table true})]}}} diff --git a/src/nextjournal/clerk/sci_env.cljs b/src/nextjournal/clerk/sci_env.cljs index 7e6fac134..5224e8bb7 100644 --- a/src/nextjournal/clerk/sci_env.cljs +++ b/src/nextjournal/clerk/sci_env.cljs @@ -8,7 +8,6 @@ ["@lezer/highlight" :as lezer-highlight] ["@nextjournal/lang-clojure" :as lang-clojure] ["framer-motion" :as framer-motion] - ["katex" :as katex] ["react" :as react] ["react-dom" :as react-dom] ["w3c-keyname" :as w3c-keyname] @@ -160,7 +159,7 @@ "@lezer/highlight" lezer-highlight "@nextjournal/lang-clojure" lang-clojure "framer-motion" framer-motion - "katex" katex + #_#_"katex" katex "react" react "react-dom" react-dom "w3c-keyname" w3c-keyname} From bf1c5437b469d1b50172f43293da31903834d9a2 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 11 Aug 2025 20:16:16 +0200 Subject: [PATCH 04/24] wip --- shadow-cljs.edn | 5 +++-- src/nextjournal/clerk/builder.clj | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/shadow-cljs.edn b/shadow-cljs.edn index 2ee0c45e7..5ae6544d0 100644 --- a/shadow-cljs.edn +++ b/shadow-cljs.edn @@ -9,8 +9,9 @@ :dev {:modules {:viewer {:entries [devtools]}}} :modules {:viewer {:entries [nextjournal.clerk.sci-env nextjournal.clerk.trim-image]} - :katex {:entries ["katex"] - :depends-on #{:viewer}}} + :katex {:entries [#_katex nextjournal.clerk.katex] + :depends-on #{:viewer} + :exports {renderToString nextjournal.clerk.katex/renderToString}}} :js-options {:output-feature-set :es8} :build-hooks [(shadow.cljs.build-report/hook {:output-to "report.html" :print-table true})]}}} diff --git a/src/nextjournal/clerk/builder.clj b/src/nextjournal/clerk/builder.clj index bc0b0a31b..2389c37d8 100644 --- a/src/nextjournal/clerk/builder.clj +++ b/src/nextjournal/clerk/builder.clj @@ -191,11 +191,11 @@ tmp) viewer-js) in (str "import '" viewer-js "';" - "import katex from \"katex\";" - "globalThis.clerk$katex = katex;" + #_"import katex from \"katex\";" + #_"globalThis.clerk$katex = katex;" "globalThis.CLERK_SSR = true;" "console.log(nextjournal.clerk.sci_env.ssr(" (pr-str (pr-str state)) "))")] - (spit "in.mjs" in) + #_(spit "in.mjs" in) (sh {:in in} "node" "--abort-on-uncaught-exception" From 5bba429f9c2791f38db52905c3a1118be682a569 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 11 Aug 2025 20:16:24 +0200 Subject: [PATCH 05/24] wip --- src/nextjournal/clerk/katex.cljs | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/nextjournal/clerk/katex.cljs diff --git a/src/nextjournal/clerk/katex.cljs b/src/nextjournal/clerk/katex.cljs new file mode 100644 index 000000000..c8710d288 --- /dev/null +++ b/src/nextjournal/clerk/katex.cljs @@ -0,0 +1,5 @@ +(ns nextjournal.clerk.katex + (:require ["katex" :as katex])) + +(defn renderToString [s] + (katex/renderToString s)) From 39b73a0acf0b29ff8fef70ff462f170c21026a3f Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 11 Aug 2025 20:20:59 +0200 Subject: [PATCH 06/24] kondo --- src/nextjournal/clerk/render.cljs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/nextjournal/clerk/render.cljs b/src/nextjournal/clerk/render.cljs index e95161bd9..2233add1b 100644 --- a/src/nextjournal/clerk/render.cljs +++ b/src/nextjournal/clerk/render.cljs @@ -21,8 +21,7 @@ [reagent.ratom :as ratom] [sci.core :as sci] [sci.ctx-store] - [shadow.cljs.modern :refer [defclass]] - [shadow.esm :as esm])) + [shadow.cljs.modern :refer [defclass]])) (r/set-default-compiler! (r/create-compiler {:function-components true})) From 13d1f80d9138487188d4190641338a38dd8a2509 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Tue, 12 Aug 2025 16:09:31 +0200 Subject: [PATCH 07/24] Bump markdown --- deps.edn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps.edn b/deps.edn index b0df4b976..2fe085c69 100644 --- a/deps.edn +++ b/deps.edn @@ -6,7 +6,7 @@ weavejester/dependency {:mvn/version "0.2.1"} com.nextjournal/beholder {:mvn/version "1.0.3"} org.flatland/ordered {:mvn/version "1.15.12"} - io.github.nextjournal/markdown {:mvn/version "0.7.186"} + io.github.nextjournal/markdown {:mvn/version "0.7.189"} babashka/process {:mvn/version "0.4.16"} io.github.nextjournal/dejavu {:git/sha "7276cd9cec1bad001d595b52cee9e83a60d43bf0"} io.github.babashka/sci.nrepl {:mvn/version "0.0.2"} From 31427bbf60c57d34226d0441f881f515f97d3c22 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Tue, 12 Aug 2025 16:23:43 +0200 Subject: [PATCH 08/24] add katex to entries --- shadow-cljs.edn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadow-cljs.edn b/shadow-cljs.edn index 5ae6544d0..68cb9b074 100644 --- a/shadow-cljs.edn +++ b/shadow-cljs.edn @@ -9,7 +9,7 @@ :dev {:modules {:viewer {:entries [devtools]}}} :modules {:viewer {:entries [nextjournal.clerk.sci-env nextjournal.clerk.trim-image]} - :katex {:entries [#_katex nextjournal.clerk.katex] + :katex {:entries [katex nextjournal.clerk.katex] :depends-on #{:viewer} :exports {renderToString nextjournal.clerk.katex/renderToString}}} :js-options {:output-feature-set :es8} From 5c8065c734606d1bc1b4d2c5c58ef7af3d431f4d Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Tue, 12 Aug 2025 21:03:17 +0200 Subject: [PATCH 09/24] wip [skip ci] --- src/nextjournal/clerk/view.clj | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/nextjournal/clerk/view.clj b/src/nextjournal/clerk/view.clj index 0d2a41c54..b2f588f4e 100644 --- a/src/nextjournal/clerk/view.clj +++ b/src/nextjournal/clerk/view.clj @@ -2,15 +2,32 @@ (:require [clojure.java.io :as io] [clojure.string :as str] [hiccup.page :as hiccup] + [nextjournal.clerk.cljs-libs :as cljs-libs] [nextjournal.clerk.viewer :as v] - [nextjournal.clerk.cljs-libs :as cljs-libs]) + [nextjournal.clerk.walk :as w]) (:import (java.net URI))) +(def !state (atom #{})) + +(defn viewer-names [state] + (prn :state...) + (def s state) + (let [] + (w/postwalk (fn [v] + (if-let [viewer (v/get-safe v :nextjournal/viewer)] + (do (swap! !state conj (:name viewer)) + v) + v)) + state) + (def x @!state) + state)) + (defn doc->viewer ([doc] (doc->viewer {} doc)) ([opts {:as doc :keys [ns file]}] (binding [*ns* ns] - (-> (merge doc opts) v/notebook v/present (cljs-libs/prepend-required-cljs opts))))) + (-> (merge doc opts) v/notebook v/present (cljs-libs/prepend-required-cljs opts) + (viewer-names))))) #_(doc->viewer (nextjournal.clerk/eval-file "notebooks/hello.clj")) #_(nextjournal.clerk/show! "notebooks/test.clj") From 2a5493937900676f27117348148f0b6d0a268b69 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 18 Aug 2025 14:33:14 +0200 Subject: [PATCH 10/24] wip --- dev/nextjournal/clerk/ssr.clj | 67 ------------------------------- src/nextjournal/clerk/builder.clj | 13 +++--- src/nextjournal/clerk/view.clj | 9 +---- 3 files changed, 10 insertions(+), 79 deletions(-) delete mode 100644 dev/nextjournal/clerk/ssr.clj diff --git a/dev/nextjournal/clerk/ssr.clj b/dev/nextjournal/clerk/ssr.clj deleted file mode 100644 index a958483e2..000000000 --- a/dev/nextjournal/clerk/ssr.clj +++ /dev/null @@ -1,67 +0,0 @@ -(ns nextjournal.clerk.ssr - "Server-side-rendering using `reagent.dom.server` on GraalJS. - - Status: working in GraalJS `org.graalvm.js/js {:mvn/version \"22.3.0\"}` - - To try this ad the dep above to e.g. the `:sci` alias." - (:require [clojure.java.io :as io] - [clojure.edn :as edn] - [clojure.string :as str] - [nextjournal.clerk.config :as config]) - (:import (org.graalvm.polyglot Context Source))) - -(def context-builder - (doto (Context/newBuilder (into-array ["js"])) - (.option "js.timer-resolution" "1") - (.option "js.java-package-globals" "false") - (.out System/out) - (.err System/err) - (.allowAllAccess true) - (.allowNativeAccess true))) - -(def context (.build context-builder)) - -(defn execute-fn [context fn & args] - (let [fn-ref (.eval context "js" fn) - args (into-array Object args)] - (assert (.canExecute fn-ref) (str "cannot execute " fn)) - (.execute fn-ref args))) - -(defn viewer-js-path [] - (@config/!asset-map "/js/viewer.js") - ;; uncomment the following to test against a local js bundle - #_"build/viewer.js") - -(def viewer-js-source - ;; run `bb build:js` on shell to generate - (.build (Source/newBuilder "js" (str (slurp "https://gist.githubusercontent.com/Yaffle/5458286/raw/1aa5caa5cdd9938fe0fe202357db6c6b33af24f4/TextEncoderTextDecoder.js") ;; tiny utf8 only TextEncoder polyfill - "\n" - (slurp (viewer-js-path))) "viewer.mjs"))) - - -(def !eval-viewer-source - (delay (.eval context viewer-js-source))) - -(defn render [edn-string] - (force !eval-viewer-source) - (execute-fn context "nextjournal.clerk.sci_env.ssr" edn-string)) - - -(comment - (do - (require '[nextjournal.clerk :as clerk] - '[nextjournal.clerk.eval :as eval] - '[nextjournal.clerk.builder :as builder] - '[nextjournal.clerk.view :as view]) - - (defn file->static-app-opts [file] - (-> (eval/eval-file file) - (as-> doc (assoc doc :viewer (view/doc->viewer {} doc))) - (as-> doc+viewer (builder/build-static-app-opts (builder/process-build-opts {:index file}) [doc+viewer])))) - - (spit "build/static_app_state_hello.edn" (pr-str (file->static-app-opts "notebooks/hello.clj"))) - (spit "build/static_app_state_rule_30.edn" (pr-str (file->static-app-opts "notebooks/rule_30.clj"))) - - (time (render (slurp "build/static_app_state_hello.edn"))))) - - diff --git a/src/nextjournal/clerk/builder.clj b/src/nextjournal/clerk/builder.clj index 2389c37d8..27de2f017 100644 --- a/src/nextjournal/clerk/builder.clj +++ b/src/nextjournal/clerk/builder.clj @@ -181,7 +181,9 @@ :or {viewer-js ;; for local REPL testing "./public/js/viewer.js"}}] - (let [viewer-js (if (str/starts-with? viewer-js "http") + (def s state) + (let [katex? (-> state :doc :katex?) + viewer-js (if (str/starts-with? viewer-js "http") (let [tmp (-> (fs/create-temp-file {:suffix ".mjs"}) (fs/file) (fs/delete-on-exit) @@ -191,11 +193,12 @@ tmp) viewer-js) in (str "import '" viewer-js "';" - #_"import katex from \"katex\";" - #_"globalThis.clerk$katex = katex;" + (when katex? + (str "import katex from \"katex\";" + "globalThis.clerk$katex = katex;")) "globalThis.CLERK_SSR = true;" "console.log(nextjournal.clerk.sci_env.ssr(" (pr-str (pr-str state)) "))")] - #_(spit "in.mjs" in) + (spit "in.mjs" in) (sh {:in in} "node" "--abort-on-uncaught-exception" @@ -251,7 +254,7 @@ (dissoc :path->doc) cleanup)))))) (when browse? - (browse/browse-url (if-let [server-url (and (= out-path "public/build") (webserver/server-url))] + (browse/browse-url (if-let [server-url (and (= "public/build" out-path) (webserver/server-url))] (str server-url "/build/") (-> index-html fs/absolutize .toString path-to-url-canonicalize)))) {:docs docs diff --git a/src/nextjournal/clerk/view.clj b/src/nextjournal/clerk/view.clj index b2f588f4e..6083a7e33 100644 --- a/src/nextjournal/clerk/view.clj +++ b/src/nextjournal/clerk/view.clj @@ -7,20 +7,15 @@ [nextjournal.clerk.walk :as w]) (:import (java.net URI))) -(def !state (atom #{})) - (defn viewer-names [state] - (prn :state...) - (def s state) - (let [] + (let [!state (atom #{})] (w/postwalk (fn [v] (if-let [viewer (v/get-safe v :nextjournal/viewer)] (do (swap! !state conj (:name viewer)) v) v)) state) - (def x @!state) - state)) + (assoc state :katex? (contains? @!state 'nextjournal.clerk.viewer/katex-viewer)))) (defn doc->viewer ([doc] (doc->viewer {} doc)) From dda7ccb2dd3247b4525c79e335384ff542fe7199 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 18 Aug 2025 17:03:28 +0200 Subject: [PATCH 11/24] wip --- render/deps.edn | 2 +- src/nextjournal/clerk/builder.clj | 33 ++++++++++++++++++------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/render/deps.edn b/render/deps.edn index a12ba3fda..9edde0445 100644 --- a/render/deps.edn +++ b/render/deps.edn @@ -8,7 +8,7 @@ io.github.babashka/sci.configs {:git/sha "8253c69a537bcc82e8ff122e5f905fe9d1e303f0" :exclusions [org.babashka/sci]} io.github.nextjournal/clojure-mode {:git/sha "1f55406087814a0dda6806396aa596dbe13ea302"} - thheller/shadow-cljs {:mvn/version "3.0.4"} + thheller/shadow-cljs {:mvn/version "3.2.0"} io.github.squint-cljs/cherry {;; :local/root "/Users/borkdude/dev/cherry" :git/sha "8de9f27" :git/tag "v0.4.26" diff --git a/src/nextjournal/clerk/builder.clj b/src/nextjournal/clerk/builder.clj index 27de2f017..bf370e267 100644 --- a/src/nextjournal/clerk/builder.clj +++ b/src/nextjournal/clerk/builder.clj @@ -176,29 +176,34 @@ response (.send client request (java.net.http.HttpResponse$BodyHandlers/ofString))] (.body response))) +(defn local-js [url] + (if (str/starts-with? url "http") + (let [tmp (-> (fs/create-temp-file {:suffix ".mjs"}) + (fs/file) + (fs/delete-on-exit) + str) + src (download-text-file url)] + (spit tmp src) + tmp) + url)) + (defn- node-ssr! [{:keys [viewer-js state] :or {viewer-js ;; for local REPL testing "./public/js/viewer.js"}}] - (def s state) (let [katex? (-> state :doc :katex?) - viewer-js (if (str/starts-with? viewer-js "http") - (let [tmp (-> (fs/create-temp-file {:suffix ".mjs"}) - (fs/file) - (fs/delete-on-exit) - str) - src (download-text-file viewer-js)] - (spit tmp src) - tmp) - viewer-js) + [viewer-js katex-js] [(local-js viewer-js) + (when katex? + (local-js (str/replace viewer-js #"viewer.js$" "katex.js")))] in (str "import '" viewer-js "';" (when katex? - (str "import katex from \"katex\";" - "globalThis.clerk$katex = katex;")) + (format (str "import * as katex from \"%s\";" + "globalThis.clerk$katex = katex;") + katex-js)) "globalThis.CLERK_SSR = true;" - "console.log(nextjournal.clerk.sci_env.ssr(" (pr-str (pr-str state)) "))")] - (spit "in.mjs" in) + "console.log(nextjournal.clerk.sci_env.ssr(" (pr-str (pr-str state )) "))")] + #_(spit "in.mjs" in) (sh {:in in} "node" "--abort-on-uncaught-exception" From f1ab3cbf23822bd097641d26c35db298b7526ca8 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 18 Aug 2025 20:58:54 +0200 Subject: [PATCH 12/24] wip --- notebooks/viewers/katex.clj | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 notebooks/viewers/katex.clj diff --git a/notebooks/viewers/katex.clj b/notebooks/viewers/katex.clj new file mode 100644 index 000000000..2c1456d5c --- /dev/null +++ b/notebooks/viewers/katex.clj @@ -0,0 +1,16 @@ +;; # Katex + +(ns katex + (:require [nextjournal.clerk] + [nextjournal.clerk.viewer])) + +;; Inline formula: $x^2$ + + +;; Block level formula: +;; $$x^2$$ + +;; Manual viewer: +(nextjournal.clerk/with-viewer + nextjournal.clerk.viewer/katex-viewer "x^2") + From e58564d4ad51b5a0636a1dfa54f817f23c6260eb Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Tue, 19 Aug 2025 13:41:13 +0200 Subject: [PATCH 13/24] wip --- src/nextjournal/clerk/builder.clj | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/nextjournal/clerk/builder.clj b/src/nextjournal/clerk/builder.clj index bf370e267..36210b54d 100644 --- a/src/nextjournal/clerk/builder.clj +++ b/src/nextjournal/clerk/builder.clj @@ -176,13 +176,17 @@ response (.send client request (java.net.http.HttpResponse$BodyHandlers/ofString))] (.body response))) -(defn local-js [url] +(defn local-js [url tmp-dir] (if (str/starts-with? url "http") - (let [tmp (-> (fs/create-temp-file {:suffix ".mjs"}) - (fs/file) + (let [tmp (-> tmp-dir + (fs/file (-> (fs/file-name url) + (str/split #"\?") + (first) + (str/replace #".js$" ".mjs"))) (fs/delete-on-exit) str) - src (download-text-file url)] + src (download-text-file url) + src (str/replace src "viewer.js" "viewer.mjs")] (spit tmp src) tmp) url)) @@ -192,10 +196,11 @@ :or {viewer-js ;; for local REPL testing "./public/js/viewer.js"}}] - (let [katex? (-> state :doc :katex?) - [viewer-js katex-js] [(local-js viewer-js) + (let [tmp-dir (fs/create-temp-dir) + katex? (-> state :doc :katex?) + [viewer-js katex-js] [(local-js viewer-js tmp-dir) (when katex? - (local-js (str/replace viewer-js #"viewer.js$" "katex.js")))] + (local-js (str/replace viewer-js "viewer.js" "katex.js") tmp-dir))] in (str "import '" viewer-js "';" (when katex? (format (str "import * as katex from \"%s\";" From 2b3546814916a50c6c3f7369d4e1112a2a4dbfdc Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Tue, 19 Aug 2025 13:47:34 +0200 Subject: [PATCH 14/24] ssr --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 403e42a16..33512eaa2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -251,7 +251,7 @@ jobs: run: echo $(yarn global dir)/node_modules - name: ๐Ÿงช Build Rule 30 Notebook with SSR - run: NODE_PATH=$(yarn global dir)/node_modules clojure -J-Dclojure.main.report=stdout -X:demo:nextjournal/clerk :git/sha '"${{ github.sha }}"' :git/url '"https://github.com/nextjournal/clerk"' :index '"notebooks/rule_30.clj"' :paths [] :ssr true :compile-css true :exclude-js true + run: NODE_PATH=$(yarn global dir)/node_modules clojure -J-Dclojure.main.report=stdout -X:demo:nextjournal/clerk :git/sha '"${{ github.sha }}"' :git/url '"https://github.com/nextjournal/clerk"' :paths '["notebooks/rule_30.clj" "notebooks/viewers/katex.clj"]' :ssr true :compile-css true :exclude-js true - name: ๐Ÿ” Google Auth uses: google-github-actions/auth@v2.1.6 From aa753720ed2618b2f06e4bb9b82d0b6f412d5a2e Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Tue, 19 Aug 2025 21:02:07 +0200 Subject: [PATCH 15/24] wip --- src/nextjournal/clerk/builder.clj | 22 +++++++++++++--------- src/nextjournal/clerk/render.cljs | 3 ++- src/nextjournal/clerk/view.clj | 2 ++ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/nextjournal/clerk/builder.clj b/src/nextjournal/clerk/builder.clj index 36210b54d..05f993ed0 100644 --- a/src/nextjournal/clerk/builder.clj +++ b/src/nextjournal/clerk/builder.clj @@ -206,14 +206,16 @@ (format (str "import * as katex from \"%s\";" "globalThis.clerk$katex = katex;") katex-js)) - "globalThis.CLERK_SSR = true;" + "globalThis.CLERK_SSR = true; + new Promise((resolve) => { setTimeout(resolve, 2000)});\n" "console.log(nextjournal.clerk.sci_env.ssr(" (pr-str (pr-str state )) "))")] - #_(spit "in.mjs" in) - (sh {:in in} - "node" - "--abort-on-uncaught-exception" - "--input-type=module" - "--trace-warnings"))) + (spit "in.mjs" in) + (sh + {:out :string :in in :err :inherit} + "node" + "--abort-on-uncaught-exception" + "--input-type=module" + "--trace-warnings"))) (comment (declare so) ;; captured in REPL in ssr! function @@ -239,8 +241,10 @@ (throw (ex-info (str "Clerk ssr! failed\n" out "\n" err) result))))) (defn cleanup [build-opts] - (select-keys build-opts - [:package :render-router :path->doc :current-path :resource->url :exclude-js? :index :html])) + (cond-> (select-keys build-opts + [:package :render-router :path->doc :current-path :resource->url :exclude-js? :index :html]) + (-> build-opts :doc :katex?) + (assoc :katex? true))) (defn write-static-app! [opts docs] diff --git a/src/nextjournal/clerk/render.cljs b/src/nextjournal/clerk/render.cljs index 2233add1b..f75e5f39f 100644 --- a/src/nextjournal/clerk/render.cljs +++ b/src/nextjournal/clerk/render.cljs @@ -987,7 +987,8 @@ (unchecked-get js/globalThis "clerk$katex") (hooks/use-d3-require "katex@0.16.4"))] (if katex - [:span {:dangerouslySetInnerHTML (r/unsafe-html (.renderToString katex tex-string (j/obj :displayMode (not inline?) :throwOnError false)))}] + (let [html (.renderToString katex tex-string (j/obj :displayMode (not inline?) :throwOnError false))] + [:span {:dangerouslySetInnerHTML (r/unsafe-html html)}]) default-loading-view))) (defn render-mathjax [value] diff --git a/src/nextjournal/clerk/view.clj b/src/nextjournal/clerk/view.clj index 6083a7e33..8d1a8194d 100644 --- a/src/nextjournal/clerk/view.clj +++ b/src/nextjournal/clerk/view.clj @@ -53,6 +53,8 @@ (defn include-css+js [state] (list (include-viewer-css state) + (when (:katex? state) + (hiccup/include-css "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.12.0/katex.min.js")) [:script {:type "module" :src (adjust-relative-path state (get-in state [:resource->url "/js/viewer.js"]))}] (hiccup/include-css "https://cdn.jsdelivr.net/npm/katex@0.13.13/dist/katex.min.css") [:link {:rel "preconnect" :href "https://fonts.bunny.net"}] From 43b194b09c700f082797bfd81361da28baa732da Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Tue, 19 Aug 2025 21:02:30 +0200 Subject: [PATCH 16/24] wip --- src/nextjournal/clerk/builder.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nextjournal/clerk/builder.clj b/src/nextjournal/clerk/builder.clj index 05f993ed0..fde4032cf 100644 --- a/src/nextjournal/clerk/builder.clj +++ b/src/nextjournal/clerk/builder.clj @@ -209,7 +209,7 @@ "globalThis.CLERK_SSR = true; new Promise((resolve) => { setTimeout(resolve, 2000)});\n" "console.log(nextjournal.clerk.sci_env.ssr(" (pr-str (pr-str state )) "))")] - (spit "in.mjs" in) + #_(spit "in.mjs" in) (sh {:out :string :in in :err :inherit} "node" From e923f98dd000019a669004019d8b03b753101c0e Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Tue, 19 Aug 2025 21:14:53 +0200 Subject: [PATCH 17/24] fix css --- src/nextjournal/clerk/view.clj | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/nextjournal/clerk/view.clj b/src/nextjournal/clerk/view.clj index 8d1a8194d..9cd55f543 100644 --- a/src/nextjournal/clerk/view.clj +++ b/src/nextjournal/clerk/view.clj @@ -50,11 +50,14 @@ (str/replace #"require\(.*\)" ""))] [:style {:type "text/tailwindcss"} (slurp (io/resource "stylesheets/viewer.css"))]))) +(defn include-katex-css [state] + (when (:katex? state) + (hiccup/include-css "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.12.0/katex.min.css"))) + (defn include-css+js [state] (list (include-viewer-css state) - (when (:katex? state) - (hiccup/include-css "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.12.0/katex.min.js")) + (include-katex-css state) [:script {:type "module" :src (adjust-relative-path state (get-in state [:resource->url "/js/viewer.js"]))}] (hiccup/include-css "https://cdn.jsdelivr.net/npm/katex@0.13.13/dist/katex.min.css") [:link {:rel "preconnect" :href "https://fonts.bunny.net"}] @@ -80,7 +83,8 @@ }"]) (when current-path (v/open-graph-metas (-> state :path->doc (get current-path) v/->value :open-graph))) (if exclude-js? - (include-viewer-css state) + (list (include-viewer-css state) + (include-katex-css state)) (include-css+js state))] [:body.dark:bg-gray-900 [:div#clerk html] From cc794641a58aea2d1b69f34f06935a1292388cd8 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 25 Aug 2025 15:27:19 +0200 Subject: [PATCH 18/24] Fix ui build] --- .github/workflows/main.yml | 2 +- ui_tests/playwright_tests.cljs | 13 ++++++++++--- ui_tests/ssr.cljs | 10 +++++----- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 33512eaa2..5007e83aa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -318,7 +318,7 @@ jobs: run: | bb test:static-app :sha ${{ github.sha }} :skip-install true bb test:static-app :skip-install true :url https://snapshots.nextjournal.com/clerk/book/${{ github.sha }}/book/index.html :index false :selector "h1:has-text(\"Book of Clerk\")" - bb test:static-app :skip-install true :url https://snapshots.nextjournal.com/clerk-ssr/build/${{ github.sha }}/index.html :index false :selector "h1:has-text(\"Rule 30\")" + bb test:static-app :skip-install true :url https://snapshots.nextjournal.com/clerk-ssr/build/${{ github.sha }}/index.html :index true deploy: needs: [build-and-upload-viewer-resources, test] diff --git a/ui_tests/playwright_tests.cljs b/ui_tests/playwright_tests.cljs index 03883fa93..522c6d65a 100644 --- a/ui_tests/playwright_tests.cljs +++ b/ui_tests/playwright_tests.cljs @@ -46,23 +46,30 @@ (def console-errors (atom [])) +(def page-selectors {"notebooks/rule_30.clj" "h1:has-text(\"Rule 30\")" + "notebooks/viewers/katex.clj" "span.katex"}) + (defn test-notebook ([page url] (println "Visiting" url) (p/do (goto page url) (.waitForLoadState page "networkidle") - (p/let [selector (or (:selector @!opts) "div") + (p/let [selector (or (:selector @!opts) + "div") _ (prn :selector selector) loc (.locator page selector #js {:timeout 10000}) loc (.first loc #js {:timeout 10000}) _ (.waitFor loc #js {:state "visible"}) visible? (.isVisible loc)] (is visible?)))) + ;; called from index-page-test ([page url link] - (p/let [txt (.innerText link)] + (p/let [txt (.innerText link) + selector (or (get page-selectors txt) + "div")] (println "Visiting" (str url "#/" txt)) (p/do (.click link) - (p/let [loc (.locator page "div") + (p/let [loc (.locator page selector) loc (.first loc #js {:timeout 10000}) _ (.waitFor loc #js {:state "visible"}) visible? (.isVisible loc)] diff --git a/ui_tests/ssr.cljs b/ui_tests/ssr.cljs index 7651ba0d3..79fc3e0e0 100644 --- a/ui_tests/ssr.cljs +++ b/ui_tests/ssr.cljs @@ -3,12 +3,12 @@ Use this to iterate on it, then make sure the advanced bundle works in Graal via `nextjournal.clerk.ssr`." - (:require ["./../public/js/viewer.js" :as viewer] - ;; the above is the dev build, the one below the relase (generate it via `bb release:js`) + (:require ["./../public/js/viewer.js"] + ;; the above is the dev build, the one below the release (generate it via `bb release:js`) #_["./../build/viewer.js" :as viewer] [babashka.cli :as cli] - [promesa.core :as p] - [nbb.core :refer [slurp]])) + [nbb.core :refer [slurp]] + [promesa.core :as p])) (defn -main [& args] (p/let [{:keys [file edn url]} (:opts (cli/parse-args args {:alias {:u :url :f :file}})) @@ -16,7 +16,7 @@ edn edn)] (if edn-string (println (js/nextjournal.clerk.sci_env.ssr edn-string)) - (binding [*out* *err*] + (binding [*print-fn* *print-err-fn*] (println "must provide --file or --edn arg"))))) From 7058dd46ef277bf1f1fdc2a843aa7039b49f97a2 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 25 Aug 2025 20:29:27 +0200 Subject: [PATCH 19/24] fix build --- deps.edn | 1 + src/nextjournal/clerk/builder.clj | 8 ++------ src/nextjournal/clerk/viewer.cljc | 9 +++++++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/deps.edn b/deps.edn index 2fe085c69..f4030619e 100644 --- a/deps.edn +++ b/deps.edn @@ -2,6 +2,7 @@ :deps {org.clojure/clojure {:mvn/version "1.11.1"} org.clojure/java.classpath {:mvn/version "1.0.0"} babashka/fs {:mvn/version "0.5.22"} + org.babashka/http-client {:mvn/version "0.4.23"} borkdude/edamame {:mvn/version "1.4.28"} weavejester/dependency {:mvn/version "0.2.1"} com.nextjournal/beholder {:mvn/version "1.0.3"} diff --git a/src/nextjournal/clerk/builder.clj b/src/nextjournal/clerk/builder.clj index fde4032cf..f79a1eab2 100644 --- a/src/nextjournal/clerk/builder.clj +++ b/src/nextjournal/clerk/builder.clj @@ -1,6 +1,7 @@ (ns nextjournal.clerk.builder "Clerk's Static App Builder." (:require [babashka.fs :as fs] + [babashka.http-client :as http] [babashka.process :refer [sh]] [clojure.java.browse :as browse] [clojure.java.io :as io] @@ -169,12 +170,7 @@ :paths (vec (keys path->doc))))) (defn download-text-file [url] - (let [client (java.net.http.HttpClient/newHttpClient) - request (-> (java.net.http.HttpRequest/newBuilder) - (.uri (java.net.URI/create url)) - (.build)) - response (.send client request (java.net.http.HttpResponse$BodyHandlers/ofString))] - (.body response))) + (:body (http/get url))) (defn local-js [url tmp-dir] (if (str/starts-with? url "http") diff --git a/src/nextjournal/clerk/viewer.cljc b/src/nextjournal/clerk/viewer.cljc index fecfb0143..1debaf631 100644 --- a/src/nextjournal/clerk/viewer.cljc +++ b/src/nextjournal/clerk/viewer.cljc @@ -1,6 +1,7 @@ (ns nextjournal.clerk.viewer (:refer-clojure :exclude [var?]) - (:require [clojure.datafy :as datafy] + (:require #?(:clj [babashka.http-client :as http]) + [clojure.datafy :as datafy] [clojure.pprint :as pprint] [clojure.set :as set] [clojure.string :as str] @@ -616,7 +617,11 @@ (defn read-image [image-or-url] (ImageIO/read (if (string? image-or-url) - (URL. (cond->> image-or-url (not (.getScheme (URI. image-or-url))) (str "file:"))) + (let [scheme (.getScheme (URI. image-or-url)) + http? (str/starts-with? scheme "http")] + (if http? + (:body (http/get image-or-url {:as :stream})) + (URL. (cond->> image-or-url (not scheme) (str "file:"))))) image-or-url)))) #?(:clj From 016d0bc7c9a1bfaca9257998fdced1c9ccab564b Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 25 Aug 2025 20:29:27 +0200 Subject: [PATCH 20/24] fix build --- deps.edn | 1 + src/nextjournal/clerk/builder.clj | 8 ++------ src/nextjournal/clerk/viewer.cljc | 9 +++++++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/deps.edn b/deps.edn index b0df4b976..88f46fefb 100644 --- a/deps.edn +++ b/deps.edn @@ -2,6 +2,7 @@ :deps {org.clojure/clojure {:mvn/version "1.11.1"} org.clojure/java.classpath {:mvn/version "1.0.0"} babashka/fs {:mvn/version "0.5.22"} + org.babashka/http-client {:mvn/version "0.4.23"} borkdude/edamame {:mvn/version "1.4.28"} weavejester/dependency {:mvn/version "0.2.1"} com.nextjournal/beholder {:mvn/version "1.0.3"} diff --git a/src/nextjournal/clerk/builder.clj b/src/nextjournal/clerk/builder.clj index 186f0a70d..fd6ea0ed2 100644 --- a/src/nextjournal/clerk/builder.clj +++ b/src/nextjournal/clerk/builder.clj @@ -1,6 +1,7 @@ (ns nextjournal.clerk.builder "Clerk's Static App Builder." (:require [babashka.fs :as fs] + [babashka.http-client :as http] [babashka.process :refer [sh]] [clojure.java.browse :as browse] [clojure.java.io :as io] @@ -169,12 +170,7 @@ :paths (vec (keys path->doc))))) (defn download-text-file [url] - (let [client (java.net.http.HttpClient/newHttpClient) - request (-> (java.net.http.HttpRequest/newBuilder) - (.uri (java.net.URI/create url)) - (.build)) - response (.send client request (java.net.http.HttpResponse$BodyHandlers/ofString))] - (.body response))) + (:body (http/get url))) (defn- node-ssr! [{:keys [viewer-js state] diff --git a/src/nextjournal/clerk/viewer.cljc b/src/nextjournal/clerk/viewer.cljc index fecfb0143..1debaf631 100644 --- a/src/nextjournal/clerk/viewer.cljc +++ b/src/nextjournal/clerk/viewer.cljc @@ -1,6 +1,7 @@ (ns nextjournal.clerk.viewer (:refer-clojure :exclude [var?]) - (:require [clojure.datafy :as datafy] + (:require #?(:clj [babashka.http-client :as http]) + [clojure.datafy :as datafy] [clojure.pprint :as pprint] [clojure.set :as set] [clojure.string :as str] @@ -616,7 +617,11 @@ (defn read-image [image-or-url] (ImageIO/read (if (string? image-or-url) - (URL. (cond->> image-or-url (not (.getScheme (URI. image-or-url))) (str "file:"))) + (let [scheme (.getScheme (URI. image-or-url)) + http? (str/starts-with? scheme "http")] + (if http? + (:body (http/get image-or-url {:as :stream})) + (URL. (cond->> image-or-url (not scheme) (str "file:"))))) image-or-url)))) #?(:clj From 48e483f66d9fc76982945a141523daf584be771d Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 25 Aug 2025 20:36:50 +0200 Subject: [PATCH 21/24] fix npe --- src/nextjournal/clerk/viewer.cljc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nextjournal/clerk/viewer.cljc b/src/nextjournal/clerk/viewer.cljc index 1debaf631..1fd086af1 100644 --- a/src/nextjournal/clerk/viewer.cljc +++ b/src/nextjournal/clerk/viewer.cljc @@ -618,7 +618,7 @@ (ImageIO/read (if (string? image-or-url) (let [scheme (.getScheme (URI. image-or-url)) - http? (str/starts-with? scheme "http")] + http? (when scheme (str/starts-with? scheme "http"))] (if http? (:body (http/get image-or-url {:as :stream})) (URL. (cond->> image-or-url (not scheme) (str "file:"))))) From 70e60fbd63d7b511635607af968970c393e2f736 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 25 Aug 2025 20:54:48 +0200 Subject: [PATCH 22/24] fix notebook --- notebooks/viewers/table.clj | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/notebooks/viewers/table.clj b/notebooks/viewers/table.clj index 173e086c3..bdb2a1af8 100644 --- a/notebooks/viewers/table.clj +++ b/notebooks/viewers/table.clj @@ -1,12 +1,13 @@ ;; # Tables ๐Ÿ”ข (ns ^:nextjournal.clerk/no-cache viewers.table - (:require [clojure.data.csv :as csv] + (:require [babashka.http-client :as http] + [clojure.data.csv :as csv] [clojure.java.io :as io] [clojure.string :as str] + [honey.sql :as sql] [next.jdbc :as jdbc] [nextjournal.clerk :as clerk] - [nextjournal.clerk.viewer :as v] - [honey.sql :as sql])) + [nextjournal.clerk.viewer :as v])) ;; ## Empty table @@ -60,8 +61,11 @@ (-> (mapv (fn [char] (clojure.string/join "" (repeat 20 char))) (map char (range 97 127))))]}) +(defn read-image [url] + (javax.imageio.ImageIO/read (:body (http/get url {:as :stream})))) + ;; ## Table with images -(clerk/table [[1 2] [3 (javax.imageio.ImageIO/read (java.net.URL. "https://nextjournal.com/data/QmeyvaR3Q5XSwe14ZS6D5WBQGg1zaBaeG3SeyyuUURE2pq?filename=thermos.gif&content-type=image/gif"))]]) +(clerk/table [[1 2] [3 (read-image "https://nextjournal.com/data/QmeyvaR3Q5XSwe14ZS6D5WBQGg1zaBaeG3SeyyuUURE2pq?filename=thermos.gif&content-type=image/gif")]]) ;; ## Table within tables (clerk/table [[1 2] [3 (clerk/table [[1 2] [3 4]])]]) @@ -76,8 +80,8 @@ (clerk/with-viewers (clerk/add-viewers [(assoc v/image-viewer :render-fn '(fn [blob] [:img {:width "30px" :height "30px" :src (nextjournal.clerk.viewer/url-for blob)}]))]) (clerk/table {:rows (map (juxt identity dec) (range 1 100)) - :head [(javax.imageio.ImageIO/read (java.net.URL. "https://upload.wikimedia.org/wikipedia/commons/1/17/Plus_img_364976.png")) - (javax.imageio.ImageIO/read (java.net.URL. "https://upload.wikimedia.org/wikipedia/commons/thumb/d/df/OCR-A_char_Hyphen-Minus.svg/543px-OCR-A_char_Hyphen-Minus.svg.png"))]})) + :head [(read-image "https://upload.wikimedia.org/wikipedia/commons/1/17/Plus_img_364976.png") + (read-image "https://upload.wikimedia.org/wikipedia/commons/thumb/d/df/OCR-A_char_Hyphen-Minus.svg/543px-OCR-A_char_Hyphen-Minus.svg.png")]})) ;; ## Custom Table Viewers ;; override single table components From fa1cf4fc8255ef97539d9de44ebaba6c7ab09e1d Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Mon, 1 Sep 2025 15:18:46 +0200 Subject: [PATCH 23/24] Additional fixes --- src/nextjournal/clerk/builder.clj | 2 +- src/nextjournal/clerk/view.clj | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/nextjournal/clerk/builder.clj b/src/nextjournal/clerk/builder.clj index f79a1eab2..32e44a6da 100644 --- a/src/nextjournal/clerk/builder.clj +++ b/src/nextjournal/clerk/builder.clj @@ -411,7 +411,7 @@ :exclude-js? true ;; test against cljs release `bb build:js` :resource->url {"/js/viewer.js" "./build/viewer.js"} - :index "notebooks/scratch.clj"}) + :index "notebooks/viewers/katex.clj"}) (build-static-app! {:ssr? true :exclude-js? true diff --git a/src/nextjournal/clerk/view.clj b/src/nextjournal/clerk/view.clj index 9cd55f543..f9d6dd2f1 100644 --- a/src/nextjournal/clerk/view.clj +++ b/src/nextjournal/clerk/view.clj @@ -8,14 +8,17 @@ (:import (java.net URI))) (defn viewer-names [state] - (let [!state (atom #{})] + (let [!viewers (atom #{})] (w/postwalk (fn [v] (if-let [viewer (v/get-safe v :nextjournal/viewer)] - (do (swap! !state conj (:name viewer)) + (do (swap! !viewers conj (:name viewer)) v) v)) state) - (assoc state :katex? (contains? @!state 'nextjournal.clerk.viewer/katex-viewer)))) + (let [viewers @!viewers] + (assoc state :katex? (some viewers #{'nextjournal.clerk.viewer/katex-viewer + :nextjournal.markdown/formula + :nextjournal.markdown/block-formula}))))) (defn doc->viewer ([doc] (doc->viewer {} doc)) From 7cc646a7aea0c19dd7e01f2081839cd3f5df2325 Mon Sep 17 00:00:00 2001 From: Martin Kavalar Date: Tue, 2 Sep 2025 09:34:13 +0200 Subject: [PATCH 24/24] Move katex to render --- shadow-cljs.edn | 4 ++-- src/nextjournal/clerk/{ => render}/katex.cljs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/nextjournal/clerk/{ => render}/katex.cljs (71%) diff --git a/shadow-cljs.edn b/shadow-cljs.edn index 68cb9b074..425b2822c 100644 --- a/shadow-cljs.edn +++ b/shadow-cljs.edn @@ -9,9 +9,9 @@ :dev {:modules {:viewer {:entries [devtools]}}} :modules {:viewer {:entries [nextjournal.clerk.sci-env nextjournal.clerk.trim-image]} - :katex {:entries [katex nextjournal.clerk.katex] + :katex {:entries [katex nextjournal.clerk.render.katex] :depends-on #{:viewer} - :exports {renderToString nextjournal.clerk.katex/renderToString}}} + :exports {renderToString nextjournal.clerk.render.katex/renderToString}}} :js-options {:output-feature-set :es8} :build-hooks [(shadow.cljs.build-report/hook {:output-to "report.html" :print-table true})]}}} diff --git a/src/nextjournal/clerk/katex.cljs b/src/nextjournal/clerk/render/katex.cljs similarity index 71% rename from src/nextjournal/clerk/katex.cljs rename to src/nextjournal/clerk/render/katex.cljs index c8710d288..962d90b2e 100644 --- a/src/nextjournal/clerk/katex.cljs +++ b/src/nextjournal/clerk/render/katex.cljs @@ -1,4 +1,4 @@ -(ns nextjournal.clerk.katex +(ns nextjournal.clerk.render.katex (:require ["katex" :as katex])) (defn renderToString [s]