nextjournal / clerk

⚡️ Moldable Live Programming for Clojure
https://clerk.vision
ISC License
1.74k stars 75 forks source link
clojure live-programming moldable-development notebook repl visualization

Clerk: Local-First Notebooks for Clojure

Clerk

Clojars Project

Moldable Live Programming for Clojure

🎪 View Demos📖 Book of Clerk 👩‍🎨 Using Clerk🪚 Development

Clerk takes a Clojure namespace and turns it into a notebook:

Clerk Screenshot

🎪 Demos

Clerk comes with a demo repo full of interesting use cases. Check them out and feel free to add your own via PRs.

⚖️ Rationale

Computational notebooks allow arguing from evidence by mixing prose with executable code. For a good overview of problems users encounter in traditional notebooks like Jupyter, see I don't like notebooks and What’s Wrong with Computational Notebooks? Pain Points, Needs, and Design Opportunities.

Specifically Clerk wants to address the following problems:

Clerk is a notebook library for Clojure that aims to address these problems by doing less, namely:

🚦 Status

ALPHA, expect breaking changes.

👩‍🎨 Using Clerk

To use Clerk in your project, you'll need Java 11+ and clojure. Add the following dependency to your deps.edn:

{:deps {io.github.nextjournal/clerk {:mvn/version "0.16.1016"}}}

Require and start Clerk as part of your system start, e.g. in user.clj:

(require '[nextjournal.clerk :as clerk])

;; start Clerk's built-in webserver on the default port 7777, opening the browser when done
(clerk/serve! {:browse true})

;; either call `clerk/show!` explicitly
(clerk/show! "notebooks/rule_30.clj")

;; or let Clerk watch the given `:paths` for changes
(clerk/serve! {:watch-paths ["notebooks" "src"]})

;; start with watcher and show filter function to enable notebook pinning
(clerk/serve! {:watch-paths ["notebooks" "src"] :show-filter-fn #(clojure.string/starts-with? % "notebooks")})

;; Build a html file from the given notebook notebooks.
;; See the docstring for more options.
(clerk/build! {:paths ["notebooks/rule_30.clj"]})

You can then access Clerk at http://localhost:7777.

See the /notebooks folder in the Clerk repository for a number of sample notebooks.

Editor Workflow

For even better flow states, we recommend you bind clerk/show! to a shortcut in your favorite editor:

Emacs

In Emacs, add the following to your config:

(defun clerk-show ()
  (interactive)
  (when-let
      ((filename
        (buffer-file-name)))
    (save-buffer)
    (cider-interactive-eval
     (concat "(nextjournal.clerk/show! \"" filename "\")"))))

(define-key clojure-mode-map (kbd "<M-return>") 'clerk-show)

IntelliJ/Cursive

In IntelliJ/Cursive, you can set up REPL commands via:

Neovim + Conjure

With neovim + conjure one can use the following vimscript function to save the file and show it with Clerk:

function! ClerkShow()
  exe "w"
  exe "ConjureEval (nextjournal.clerk/show! \"" . expand("%:p") . "\")"
endfunction

nmap <silent> <localleader>cs :execute ClerkShow()<CR>

🪚 Developing Clerk

Make sure you have Babashka installed, and run:

bb dev :browse true

The will start everything needed to develop Clerk and open your default browser. You can connect your favorite editor to it using nREPL.

Any trailing arguments to bb dev will be forwarded to clojure -X and clerk/serve!. So if you prefer to not open your browser, leave out the :browse true arguments.

🐞 Known Issues

See notebooks/onwards.md.

Citing Clerk

If you are a researcher and use Clerk in your work, we encourage you to cite our work. You can use the following BibTeX citation:

@misc{clerk-github,
  author =  {Martin Kavalar and
             Jack Rusher},
  title = {{Clerk Source Code}},
  howpublished = {\url{https://github.com/nextjournal/clerk}},
  month        = feb,
  year         = 2023
}