Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
A very naive static site generator in clojure
(ns core
(:require [clojure.string :as string]
[markdown.core :as md]
[clojure.java.io :as io]
[clojure.data.xml :as xml]))
(def pattern #"__([\w-]+)__")
(defn replacement [match m]
(let [fallback (first match)
k (-> match last keyword)]
(str (get m k fallback))))
(defn fill [m s]
(string/replace s pattern #(replacement % m)))
(defn front-matter [k s]
(some-> (re-pattern (format "%s:(.+)" (name (or k :nothing))))
(re-find s)
(second)
(string/trim)))
(def title (partial front-matter :title))
(def date (partial front-matter :date))
(def preview (partial front-matter :preview))
(defn drop-front-matter [s]
(some-> (string/replace s #"(?s)---(.*)---" "")
(string/trim)))
(defn post [filename]
(let [filepath (format "src/posts/%s" filename)
s (slurp filepath)
preview (-> (preview s)
(md/md-to-html-string))
title (title s)
date (date s)
markdown (drop-front-matter s)
content (md/md-to-html-string markdown)
url (format "posts/%s" (string/replace filename #".md" ".html"))]
{:title title
:date date
:url url
:markdown markdown
:content content
:preview preview}))
(defn render-post-preview [post]
(let [layout (slurp "src/posts/post.html")]
(fill post layout)))
(defn render-post [post]
(let [layout (slurp "src/posts/layout.html")
post-html (fill post layout)
html (fill {:content post-html
:relative "../"} (slurp "src/layout.html"))]
(spit (:url post) html)))
(defn posts []
(->> (io/file "src/posts")
(file-seq)
(filter #(.isFile %))
(map #(.getName %))
(filter #(.endsWith % ".md"))
(sort)
(reverse)
(map post)))
(defn index []
(let [s (slurp "src/layout.html")
content (->> (posts)
(map render-post-preview)
(string/join "\n"))
html (fill {:content content
:relative ""} (slurp "src/layout.html"))]
(spit "index.html" html)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment