Download Code feature.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
683efa1845
commit
f9c3a8cce7
|
@ -14,7 +14,8 @@
|
||||||
"@codemirror/view": "^6.10.1",
|
"@codemirror/view": "^6.10.1",
|
||||||
"@nextjournal/lang-clojure": "^1.0.0",
|
"@nextjournal/lang-clojure": "^1.0.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0"
|
"react-dom": "^18.2.0",
|
||||||
|
"tarts": "^2.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"shadow-cljs": "^2.23.3",
|
"shadow-cljs": "^2.23.3",
|
||||||
|
@ -2081,6 +2082,11 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tarts": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tarts/-/tarts-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-24hWg+6mn/v6Z2ekwmYhzk7zZajzjIN5KNjaKe9qmU5HdsF21/KE0qmsXLie4suE3rjqxj5lT5cKpjt77w+LyQ=="
|
||||||
|
},
|
||||||
"node_modules/terser": {
|
"node_modules/terser": {
|
||||||
"version": "5.17.1",
|
"version": "5.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz",
|
||||||
|
@ -4214,6 +4220,11 @@
|
||||||
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
|
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"tarts": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tarts/-/tarts-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-24hWg+6mn/v6Z2ekwmYhzk7zZajzjIN5KNjaKe9qmU5HdsF21/KE0qmsXLie4suE3rjqxj5lT5cKpjt77w+LyQ=="
|
||||||
|
},
|
||||||
"terser": {
|
"terser": {
|
||||||
"version": "5.17.1",
|
"version": "5.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz",
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
"@codemirror/view": "^6.10.1",
|
"@codemirror/view": "^6.10.1",
|
||||||
"@nextjournal/lang-clojure": "^1.0.0",
|
"@nextjournal/lang-clojure": "^1.0.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0"
|
"react-dom": "^18.2.0",
|
||||||
|
"tarts": "^2.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"shadow-cljs": "^2.23.3",
|
"shadow-cljs": "^2.23.3",
|
||||||
|
|
|
@ -78,7 +78,7 @@ In form two we can track local state inside a component a click counter being a
|
||||||
** Form 3 components
|
** Form 3 components
|
||||||
This form of component give's you full access to the react life cycle methods, so render did-mount did-unmount etc
|
This form of component give's you full access to the react life cycle methods, so render did-mount did-unmount etc
|
||||||
usually this form of component is only needed when rendering graphics or things like graphs, it's also useful for capturing errors and handling them as in the example below, which renders your components but if =component-did-catch= is trigger the error is caught and displayed instead.
|
usually this form of component is only needed when rendering graphics or things like graphs, it's also useful for capturing errors and handling them as in the example below, which renders your components but if =component-did-catch= is trigger the error is caught and displayed instead.
|
||||||
#+BEGIN_SRC clojurescript
|
#+BEGIN_SRC clojurescript :tangle "src/core.cljs"
|
||||||
(defn err-boundary
|
(defn err-boundary
|
||||||
[& children]
|
[& children]
|
||||||
(let [err-state (reagent/atom nil)]
|
(let [err-state (reagent/atom nil)]
|
||||||
|
@ -101,7 +101,7 @@ the hash map should take a name and view param at least but you can add in param
|
||||||
Reitit works as a backend and frontend routing library so you can share routes between the two.
|
Reitit works as a backend and frontend routing library so you can share routes between the two.
|
||||||
|
|
||||||
These are a few simple routes, the last takes parameters and does validation checking against the values.
|
These are a few simple routes, the last takes parameters and does validation checking against the values.
|
||||||
#+BEGIN_SRC clojurescript
|
#+BEGIN_SRC clojurescript :tangle "src/core.cljs"
|
||||||
(def routes
|
(def routes
|
||||||
[["/"
|
[["/"
|
||||||
{:name ::frontpage
|
{:name ::frontpage
|
||||||
|
@ -120,7 +120,7 @@ These are a few simple routes, the last takes parameters and does validation che
|
||||||
|
|
||||||
You need to connect your routes data structure to =ref/start!= this function take's your own function where you can handle what should happen on route change, in this example an atom is updated causing react to render the new page.
|
You need to connect your routes data structure to =ref/start!= this function take's your own function where you can handle what should happen on route change, in this example an atom is updated causing react to render the new page.
|
||||||
|
|
||||||
#+BEGIN_SRC clojurescript
|
#+BEGIN_SRC clojurescript :tangle "src/core.cljs"
|
||||||
(rfe/start!
|
(rfe/start!
|
||||||
(rf/router routes {:data {:coercion rss/coercion}})
|
(rf/router routes {:data {:coercion rss/coercion}})
|
||||||
(fn [m] (swap! site-state assoc :current-route m))
|
(fn [m] (swap! site-state assoc :current-route m))
|
||||||
|
@ -130,7 +130,6 @@ You need to connect your routes data structure to =ref/start!= this function tak
|
||||||
|
|
||||||
|
|
||||||
To create a link to a route, you can use the =rfe/href= function which takes a lookup key which you specified in your routes, in this instance the key is name spaced to the current namespace.
|
To create a link to a route, you can use the =rfe/href= function which takes a lookup key which you specified in your routes, in this instance the key is name spaced to the current namespace.
|
||||||
#+BEGIN_SRC clojurescript
|
#+BEGIN_SRC clojurescript :tangle "src/core.cljs"
|
||||||
[:a {:href (rfe/href ::frontpage)} "example link"]
|
[:a {:href (rfe/href ::frontpage)} "example link"]
|
||||||
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
|
@ -9,7 +9,7 @@ https://purelyfunctional.tv/guide/reagent/
|
||||||
Form one components are for simply rendering some html with values that are not going to change.
|
Form one components are for simply rendering some html with values that are not going to change.
|
||||||
|
|
||||||
In the example below the function just returns some hiccup with the parameters inserted, you need to specify =:key= when dynamically repeating the elements and these should be reproducible unique id's where possible not randomly generated or indexed numbers if the data is unordered.
|
In the example below the function just returns some hiccup with the parameters inserted, you need to specify =:key= when dynamically repeating the elements and these should be reproducible unique id's where possible not randomly generated or indexed numbers if the data is unordered.
|
||||||
#+BEGIN_SRC clojure
|
#+BEGIN_SRC clojure :tangle "src/core.cljs"
|
||||||
(defn navbar-link [{:keys [href title text] :or {text nil title nil}}]
|
(defn navbar-link [{:keys [href title text] :or {text nil title nil}}]
|
||||||
[:a.link.dim.dib.mr3 {:key href :href href :title title} text])
|
[:a.link.dim.dib.mr3 {:key href :href href :title title} text])
|
||||||
|
|
||||||
|
@ -41,7 +41,6 @@ In the example below the function just returns some hiccup with the parameters i
|
||||||
:link "http://placekitten.com/g/600/300"}]]
|
:link "http://placekitten.com/g/600/300"}]]
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
|
||||||
** Form 2 components
|
** Form 2 components
|
||||||
In form two we can track local state inside a component a click counter being a basic example.
|
In form two we can track local state inside a component a click counter being a basic example.
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
["@codemirror/view" :as cm-view :refer [EditorView ViewUpdate]]
|
["@codemirror/view" :as cm-view :refer [EditorView ViewUpdate]]
|
||||||
["@nextjournal/lang-clojure" :refer [clojure]]
|
["@nextjournal/lang-clojure" :refer [clojure]]
|
||||||
["react-dom/client" :refer [createRoot]]
|
["react-dom/client" :refer [createRoot]]
|
||||||
|
["tarts" :as tarts]
|
||||||
[ajax.core :refer [GET raw-response-format]]
|
[ajax.core :refer [GET raw-response-format]]
|
||||||
[cl-eorg.html :as h :refer [body headers org->replacements]]
|
[cl-eorg.html :as h :refer [body headers org->replacements]]
|
||||||
[cl-eorg.parser :as o :refer [parse]]
|
[cl-eorg.parser :as o :refer [parse]]
|
||||||
|
@ -80,6 +81,8 @@
|
||||||
[]
|
[]
|
||||||
transactions))
|
transactions))
|
||||||
|
|
||||||
|
(defn create-arcive [])
|
||||||
|
|
||||||
(defn code-editor
|
(defn code-editor
|
||||||
[{:keys [class results]} content]
|
[{:keys [class results]} content]
|
||||||
(let [language class
|
(let [language class
|
||||||
|
@ -163,8 +166,16 @@
|
||||||
(merge tachyon-theme
|
(merge tachyon-theme
|
||||||
{:HEADER1 (fn [v _] [:li [:a {:href (str "#" (slugify v))}
|
{:HEADER1 (fn [v _] [:li [:a {:href (str "#" (slugify v))}
|
||||||
[:span.f2.fw6.f3-ns.lh-title.mt0.mb2 v]]])
|
[:span.f2.fw6.f3-ns.lh-title.mt0.mb2 v]]])
|
||||||
:HEADER2 (fn [v _] [:li [:a {:href (str "#" (slugify v))}
|
:HEADER2 (fn [v _] [:li.ml2 [:a {:href (str "#" (slugify v))}
|
||||||
[:span.f2.fw6.f3-ns.lh-title.mt0.mb2 v]]])}))
|
[:span.f2.fw6.f3-ns.lh-title.mt0.mb2 v]]])
|
||||||
|
:HEADER3 (fn [v _] [:li.ml4 [:a {:href (str "#" (slugify v))}
|
||||||
|
[:span.f3.fw6.f3-ns.lh-title.mt0.mb2 v]]])
|
||||||
|
:HEADER4 (fn [v _] [:li.ml6 [:a {:href (str "#" (slugify v))}
|
||||||
|
[:span.f4.fw6.f3-ns.lh-title.mt0.mb2 v]]])
|
||||||
|
:HEADER5 (fn [v _] [:li.ml8 [:a {:href (str "#" (slugify v))}
|
||||||
|
[:span.f5.fw6.f3-ns.lh-title.mt0.mb2 v]]])
|
||||||
|
:HEADER6 (fn [v _] [:li.ml10 [:a {:href (str "#" (slugify v))}
|
||||||
|
[:span.f6.fw6.f3-ns.lh-title.mt0.mb2 v]]])}))
|
||||||
|
|
||||||
;; put constant data here
|
;; put constant data here
|
||||||
(def site-data
|
(def site-data
|
||||||
|
@ -296,18 +307,41 @@
|
||||||
:img-src "https://raw.githubusercontent.com/tonsky/datascript/master/extras/logo.svg"}]}]])
|
:img-src "https://raw.githubusercontent.com/tonsky/datascript/master/extras/logo.svg"}]}]])
|
||||||
|
|
||||||
(def toc (partial contains? (into #{} (map keyword [:HEADER1 :HEADER2 :HEDAER3 :HEADER4 :HEADER5 :HEADER6]))))
|
(def toc (partial contains? (into #{} (map keyword [:HEADER1 :HEADER2 :HEDAER3 :HEADER4 :HEADER5 :HEADER6]))))
|
||||||
|
(def org-code (partial contains? (into #{} (map keyword [:SRC]))))
|
||||||
|
|
||||||
|
;; #_(defn build-file-zip [code-blocks]
|
||||||
|
;; (let [archive (zip/JSZip.)]
|
||||||
|
;; (mapv (fn [block] #js
|
||||||
|
;; (.file archive (:tangle (second block)) (last block))
|
||||||
|
|
||||||
|
;; {:name (:tangle (second block))
|
||||||
|
;; :content (last block)}) code-blocks )
|
||||||
|
|
||||||
|
;; )
|
||||||
|
;; )
|
||||||
|
|
||||||
|
(defn build-file-tar [code-blocks]
|
||||||
|
(tarts (clj->js (mapv (fn [block] {:name (str (:tangle (second block)))
|
||||||
|
:content (str (last block))})
|
||||||
|
code-blocks ))))
|
||||||
|
|
||||||
|
(defn build-file-tar-hm [code-blocks]
|
||||||
|
(tarts (clj->js code-blocks )))
|
||||||
|
|
||||||
|
(defn build-tarts-map [blocks]
|
||||||
|
(->> blocks
|
||||||
|
(group-by (fn [block] (:tangle (second block))))
|
||||||
|
(reduce (fn [m [k v]] (conj m {:name (str k)
|
||||||
|
:content (str (concat (mapv last v)))})) [])))
|
||||||
|
|
||||||
(defn org->split2
|
(defn org->split2
|
||||||
"Split out meta and body"
|
"Split out meta and body"
|
||||||
[dsl]
|
[dsl]
|
||||||
{:header (filter (fn filter-headers [tag] (headers (first tag))) dsl)
|
{:header (filter (fn filter-headers [tag] (headers (first tag))) dsl)
|
||||||
:toc (filter (fn filter-headers [tag] (toc (first tag))) dsl)
|
:toc (filter (fn filter-toc [tag] (toc (first tag))) dsl)
|
||||||
|
:code (filter (fn filter-code [tag] (org-code (first tag))) dsl)
|
||||||
:body (filter (fn filter-body [tag] (body (first tag))) dsl)})
|
:body (filter (fn filter-body [tag] (body (first tag))) dsl)})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; form two component render demo
|
;; form two component render demo
|
||||||
;;(h/org->split (parse document1))
|
;;(h/org->split (parse document1))
|
||||||
(defn demo-page [route]
|
(defn demo-page [route]
|
||||||
|
@ -323,9 +357,22 @@
|
||||||
org->split2
|
org->split2
|
||||||
(reset! content)))})
|
(reset! content)))})
|
||||||
(fn [route]
|
(fn [route]
|
||||||
[:main.mt4
|
[:main.mt4.mw7.center.avenir
|
||||||
[:div.mw7.center.avenir (into [:ol] (org->replacements theme-toc (:toc @content)))]
|
|
||||||
[:div.mw7.center.avenir (into [:div] (org->replacements theme (:body @content)))]])))
|
[:h1 (:content (last (first (:header @content))))]
|
||||||
|
[:a.f6.link.dim.ph3.pv2.mb2.dib.white.bg-dark-blue
|
||||||
|
{:download "test.tar"
|
||||||
|
:href (.createObjectURL
|
||||||
|
js/URL
|
||||||
|
(js/Blob. #js [(build-file-tar-hm
|
||||||
|
(build-tarts-map
|
||||||
|
(:code @content)))]
|
||||||
|
{:type "application/tar"}))}
|
||||||
|
"Download Code"]
|
||||||
|
[:div.mw7.center.avenir
|
||||||
|
(into [:ol] (org->replacements theme-toc (:toc @content)))]
|
||||||
|
[:div.mw7.center.avenir
|
||||||
|
(into [:div] (org->replacements theme (:body @content)))]])))
|
||||||
|
|
||||||
|
|
||||||
;; form one render about page component
|
;; form one render about page component
|
||||||
|
|
Loading…
Reference in New Issue