Updating This Website

Goals

This website is suitable for a lazy engineer:

History

The first draft of this website used Emacs’ Org mode to write the content in. That was ok, but eventually fell apart - remembering the keyboard shortcuts to generate html (org-export if anyone was wondering) and move files around was an unnecessary roadblock when publishing. Building a deploy pipeline that wants to run Emacs in batch mode also just seems like a bad idea, I long ago got tired of any project where I might have to start using Elisp.

Getting Started

Deploy script

I set up a file directory like so:

owen@persistance:11:53:06:~/web$ tree
.
├── bb.edn
├── html
│   └── index.html
├── markdown
│   └── index.md
└── update.clj

With the files:

bb.edn

;; Not needed, makes Emacs' CIDER happier
{}

update.clj

#!/usr/bin/env bb

;; Run Clojure using Babashaka.
;; This file generates and uploads my website content. Inputs are stored in the
;; `markdown` folder. They are converted to HTML files by pandoc and put in the
;; `html` folder which is then uploaded to the web server with rsync.

(ns web.update
  (:require
   [babashka.process :as sh]
   [clojure.java.io :as io]
   [clojure.string :as string]
   [taoensso.timbre :as log]))

(log/set-level! :info)

(defn get-markdown-files
  "
  List all the files in ~/web/markdown. We assume that everything in that folder
  is a markdown file - pandoc will get confused if anything else is there.
  "
  []
  (->> "/home/owen/web/markdown" io/file .listFiles (map #(.getPath %))))

(defn to-html-path
  "
  Translate, eg, /home/owen/web/markdown/index.md ->
  /home/owen/web/html/index.html
  "
  [md-path]
  (-> md-path
      (string/replace-first "markdown" "html")
      (string/replace #".md$" ".html")))

(defn to-markdown
  "
  This command runs `pandoc`. Notes:

  - If we don't flag the output file with `-o` then there is an error, eg,
    openBinaryFile: does not exist (No such file or directory)
  - `--toc` adds a table of contents
  - `--standalone` adds HTML headers & footers
  "
  [md-path]
  (log/debug "Processing" md-path)
  (let [pandoc-options
        ["--standalone"
         "--toc"
         "--highlight-style=zenburn"
         "-o" (to-html-path md-path)
         md-path]]
    (apply sh/shell (into ["pandoc -f markdown -t html"] pandoc-options))))

(defn sync-site
  "Relies on ssh being configured"
  []
  (sh/shell "rsync --delete -v -r html/ [email protected]:/var/www/html/"))

(do
  ;; `map` is lazy, so we prefer `mapv` to stop this silently failing as Clojure
  ;; assumes there are no side effects and silently optimises this out.
  (->> (get-markdown-files) (mapv to-markdown))
  (sync-site))

Updates

2024/03