Skip to content

Commit 8e4c972

Browse files
authored
Merge pull request #1 from daslu/clay-workflow
Proposed Clay workflow
2 parents fc1cf82 + 53b6fdb commit 8e4c972

19 files changed

+4954
-9
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ results*.txt
1616
# Clay notebook output (deployed to gh-pages, not in main branch)
1717
docs/
1818
_site/
19+
20+
# Clay temp directory
21+
.clay-temp/

clay.edn

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1-
{:base-target-path "docs"
2-
:subdirs-to-sync ["notebooks"]
3-
:show false}
1+
{:remote-repo {:git-url "https://github.com/replikativ/stratum"
2+
:branch "main"}
3+
:quarto {:format {:html {:toc true
4+
:toc-expand 3
5+
:number-depth 1
6+
:toc-depth 4
7+
:theme [:cosmo "notebooks/custom.scss"]}}}
8+
:base-target-path ".clay-temp"}

deps.edn

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@
7474
;; tablecloth for high-level dataframe operations
7575
scicloj/tablecloth {:mvn/version "7.062"}
7676
;; Kindly for notebook rendering hints
77-
org.scicloj/kindly {:mvn/version "4-beta21"}
77+
org.scicloj/kindly {:mvn/version "4-beta23"}
7878
;; Clay for rendering notebooks
79-
org.scicloj/clay {:mvn/version "2.0.2"}
79+
org.scicloj/clay {:mvn/version "2.0.13"}
8080
;; Datahike for entity DB integration examples
8181
io.replikativ/datahike {:mvn/version "0.6.1570"}
8282
;; DuckDB JDBC for benchmark validation
@@ -102,9 +102,9 @@
102102
;; tablecloth for high-level dataframe operations
103103
scicloj/tablecloth {:mvn/version "7.062"}
104104
;; Kindly for notebook rendering hints
105-
org.scicloj/kindly {:mvn/version "4-beta21"}
105+
org.scicloj/kindly {:mvn/version "4-beta23"}
106106
;; Clay for rendering notebooks
107-
org.scicloj/clay {:mvn/version "2.0.2"}
107+
org.scicloj/clay {:mvn/version "2.0.13"}
108108
;; Datahike for entity DB integration notebooks
109109
io.replikativ/datahike {:mvn/version "0.6.1570"}
110110
;; DuckDB JDBC for benchmark validation
@@ -141,7 +141,7 @@
141141
;; tablecloth for high-level dataframe operations (test-only)
142142
scicloj/tablecloth {:mvn/version "7.062"}
143143
;; Kindly for notebook rendering hints
144-
org.scicloj/kindly {:mvn/version "4-beta21"}
144+
org.scicloj/kindly {:mvn/version "4-beta23"}
145145
;; Yggdrasil for CoW protocol compliance (optional, test-only)
146146
org.replikativ/yggdrasil {:mvn/version "0.2.20"}}
147147
:jvm-opts ["--add-modules=jdk.incubator.vector"
@@ -157,7 +157,7 @@
157157
org.clojure/test.check {:mvn/version "1.1.1"}
158158
techascent/tech.ml.dataset {:mvn/version "7.037"}
159159
scicloj/tablecloth {:mvn/version "7.062"}
160-
org.scicloj/kindly {:mvn/version "4-beta21"}}
160+
org.scicloj/kindly {:mvn/version "4-beta23"}}
161161
:jvm-opts ["--add-modules=jdk.incubator.vector"
162162
"--enable-native-access=ALL-UNNAMED"
163163
"--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"]

notebooks/WORKFLOW.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Stratum Notebooks
2+
3+
Literate documentation and tests for Stratum, rendered as a
4+
[Quarto](https://quarto.org/) book via [Clay](https://scicloj.github.io/clay/).
5+
6+
## Structure
7+
8+
```
9+
notebooks/
10+
├── chapters.edn # book outline — parts and chapter filenames
11+
├── index.clj # landing page (renders README.md)
12+
├── dev.clj # build helpers (make-book!, make-gfm!)
13+
├── custom.scss # Quarto styling (Fira Code, table tweaks)
14+
└── stratum_book/ # chapters live here
15+
├── quickstart.clj
16+
├── csv_import.clj
17+
├── columnar_internals.clj
18+
├── dataset_persistence.clj
19+
├── tablecloth_interop.clj
20+
└── api_reference.clj
21+
22+
test/stratum_book/ # generated by Clay from kind/test-last
23+
├── quickstart_generated_test.clj
24+
├── csv_import_generated_test.clj
25+
├── columnar_internals_generated_test.clj
26+
├── dataset_persistence_generated_test.clj
27+
├── tablecloth_interop_generated_test.clj
28+
└── api_reference_generated_test.clj
29+
30+
clay.edn # Clay config (Quarto theme, target paths)
31+
```
32+
33+
## Requirements
34+
35+
The Quarto CLI needs to be [installed](https://quarto.org/docs/get-started/).
36+
37+
## How it works
38+
39+
Each `.clj` file under `stratum_book/` is a regular Clojure namespace
40+
that doubles as a notebook. Prose goes in `;;` comments (rendered as
41+
Markdown), and top-level expressions become evaluated code cells.
42+
43+
Assertions use `kind/test-last`:
44+
45+
```clojure
46+
(st/q {:from data :agg [[:count]]})
47+
48+
(kind/test-last
49+
[(fn [result] (= 1 (count result)))])
50+
```
51+
notebooks/
52+
├── chapters.edn # book outline — parts and chapter filenames
53+
├── index.clj # landing page (renders README.md)
54+
├── dev.clj # build helpers (make-book!, make-gfm!)
55+
├── custom.scss # Quarto styling (Fira Code, table tweaks)
56+
└── stratum_book/ # chapters live here
57+
├── quickstart.clj
58+
├── csv_import.clj
59+
├── columnar_internals.clj
60+
├── dataset_persistence.clj
61+
├── tablecloth_interop.clj
62+
└── api_reference.clj
63+
64+
test/stratum_book/ # generated by Clay from kind/test-last
65+
├── quickstart_generated_test.clj
66+
├── csv_import_generated_test.clj
67+
├── columnar_internals_generated_test.clj
68+
├── dataset_persistence_generated_test.clj
69+
├── tablecloth_interop_generated_test.clj
70+
└── api_reference_generated_test.clj
71+
72+
clay.edn # Clay config (Quarto theme, target paths)
73+
```
74+
75+
Then, instead of writing manual `### heading` comments, call
76+
`kind/doc` on the var:
77+
78+
```clojure
79+
(kind/doc #'st/q)
80+
81+
;; Free-form prose and examples follow as usual.
82+
83+
(st/q {:from data :agg [[:sum :qty]]})
84+
85+
(kind/test-last
86+
[(fn [result] (= 1 (count result)))])
87+
```
88+
notebooks/
89+
├── chapters.edn # book outline — parts and chapter filenames
90+
├── index.clj # landing page (renders README.md)
91+
├── dev.clj # build helpers (make-book!, make-gfm!)
92+
├── custom.scss # Quarto styling (Fira Code, table tweaks)
93+
└── stratum_book/ # chapters live here
94+
├── quickstart.clj
95+
├── csv_import.clj
96+
├── columnar_internals.clj
97+
├── dataset_persistence.clj
98+
├── tablecloth_interop.clj
99+
└── api_reference.clj
100+
101+
test/stratum_book/ # generated by Clay from kind/test-last
102+
├── quickstart_generated_test.clj
103+
├── csv_import_generated_test.clj
104+
├── columnar_internals_generated_test.clj
105+
├── dataset_persistence_generated_test.clj
106+
├── tablecloth_interop_generated_test.clj
107+
└── api_reference_generated_test.clj
108+
109+
clay.edn # Clay config (Quarto theme, target paths)
110+
```
111+
112+
`make-book!` reads `chapters.edn` to assemble the book structure,
113+
then calls Clay which:
114+
115+
1. Evaluates each `.clj` file top-to-bottom
116+
2. Converts the output to `.qmd` (Quarto Markdown)
117+
3. Runs Quarto to produce the HTML site in `docs/`
118+
119+
## Adding a chapter
120+
121+
1. Create `notebooks/stratum_book/my_chapter.clj` with an `(ns stratum-book.my-chapter ...)` form
122+
2. Add `"my_chapter"` to the appropriate part in `chapters.edn`
123+
3. Run `(make-book!)` to verify
124+
125+
## Running tests
126+
127+
The notebooks are on the `:test` classpath. `kind/test-last`
128+
annotations [generate](https://scicloj.github.io/clay/clay_book.test_generation.html)
129+
`deftest` forms that the test runner picks up
130+
alongside traditional `deftest` tests.
131+

notebooks/chapters.edn

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{"Getting Started" ["quickstart"]
2+
"Internals" ["columnar_internals"
3+
"dataset_persistence"
4+
"tablecloth_interop"]
5+
"Reference" ["api_reference"]}

notebooks/custom.scss

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@import url(https://cdn.jsdelivr.net/npm/firacode@6.2.0/distr/fira_code.css);
2+
3+
/*-- scss:rules --*/
4+
.table {width:auto;}
5+
6+
code {font-family: 'Fira Code Medium', monospace;}
7+
8+
.table {
9+
@extend .table-striped;
10+
@extend .table-hover;
11+
@extend .table-responsive;
12+
}
13+
14+
.clay-dataset {
15+
max-height:400px;
16+
overflow-y: auto;
17+
}
18+
19+
.sourceCode.clojure {
20+
max-height:500px;
21+
overflow-y: auto;
22+
}

notebooks/dev.clj

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
(ns dev
2+
(:require [scicloj.clay.v2.api :as clay]))
3+
4+
(defn- read-chapters []
5+
(-> "notebooks/chapters.edn" slurp clojure.edn/read-string))
6+
7+
(defn- chapters->source-paths
8+
"Convert chapters map to flat vector of source paths."
9+
[chapters]
10+
(into [] (mapcat (fn [[_part names]]
11+
(map #(format "stratum_book/%s.clj" %) names)))
12+
chapters))
13+
14+
(defn- chapters->parts
15+
"Convert chapters map to Clay's :source-path part structure."
16+
[chapters]
17+
(mapv (fn [[part names]]
18+
{:part part
19+
:chapters (mapv #(format "stratum_book/%s.clj" %) names)})
20+
chapters))
21+
22+
(defn make-book!
23+
"Render book HTML through Quarto."
24+
[]
25+
(clay/make! {:format [:quarto :html]
26+
:base-source-path "notebooks"
27+
:source-path (into ["index.clj"] (chapters->parts (read-chapters)))
28+
:base-target-path "docs"
29+
:book {:title "Stratum"}
30+
;; Comment this out to wipe the whole target on every render:
31+
;; :clean-up-target-dir true
32+
}))
33+
34+
(defn make-gfm!
35+
"Render all (or specified) notebooks as GitHub-flavored Markdown."
36+
[& paths]
37+
(clay/make! {:format [:gfm]
38+
:base-source-path "notebooks"
39+
:source-path (or (seq paths)
40+
(into ["index.clj"]
41+
(chapters->source-paths (read-chapters))))
42+
:base-target-path "gfm"
43+
:show false}))
44+
45+
(comment
46+
(make-book!)
47+
(make-gfm!)
48+
(make-gfm! "stratum_book/quickstart.clj"))

notebooks/index.clj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
;; # Preface
2+
;;
3+
4+
^{:clay {:hide-code true}}
5+
(ns index
6+
(:require
7+
[clojure.string :as str]
8+
[scicloj.kindly.v4.kind :as kind]))
9+
10+
^{:kindly/hide-code true
11+
:kind/md true}
12+
(->> "README.md"
13+
slurp
14+
str/split-lines
15+
(drop 1)
16+
(str/join "\n"))

0 commit comments

Comments
 (0)