Last active
August 8, 2021 14:08
-
-
Save swlkr/65e68ad068d461767bbf78591f3415c4 to your computer and use it in GitHub Desktop.
A very naive static site generator in clojure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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