Blob


1 (ns blog.gemini
2 (:require
3 [blog.time :as time]
4 [blog.gemtext :as gemtext]))
6 (defn with-page [_ & body]
7 (gemtext/unparse
8 (list
9 [:verbatim
10 " _
11 _ _ _ _ _ __ ___ | |__
12 | | | | | | | '_ ` _ \\| '_ \\ Writing about things,
13 | |_| | |_| | | | | | | | | | sometimes.
14 \\__, |\\__,_|_| |_| |_|_| |_|
15 |___/"]
16 [:paragraph ""]
17 [:link "/" "Home"]
18 [:link "/tags.gmi" "All Tags"]
19 [:link "/pages/projects.gmi" "Projects"]
20 [:paragraph ""]
21 body
22 [:paragraph ""]
23 [:paragraph ""]
24 [:paragraph ""]
25 [:paragraph "-- text: CC-BY-SA-4.0; code: ISC (unless specified otherwise)"]
26 [:paragraph "Capsule proudly assembled with Clojure"]
27 [:link "https://git.omarpolo.com/blog/" "sources"])))
29 (defn post-fragment
30 [{:keys [full? title-with-link?]}
31 {:keys [title date slug tags short body toot music xkcd] :as post}]
32 (list
33 (if title-with-link?
34 [:link (str "/post/" slug ".gmi") title]
35 [(if full? :h1 :h2) title])
36 (when full?
37 [:paragraph ""])
38 [:paragraph (str "Written by Omar Polo on " (time/fmt-loc date)
39 (when music
40 (str " while listening to “" (:title music) "”"
41 (when-let [by (:by music)]
42 (str " by " by)) ))
43 ".")]
44 [:paragraph "Tagged with:"]
45 (map #(vector :link (str "/tag/" (name %) ".gmi") (str "#" (name %)))
46 tags)
47 (when xkcd
48 [:link (str "https://xkcd.com/" xkcd) (format "Relevant XKCD – #%d" xkcd)])
49 (if full?
50 (list [:paragraph ""]
51 (gemtext/parse body))
52 (when short [:blockquote short]))
53 [:paragraph ""]))
55 (defn home-page [{:keys [posts has-next has-prev nth]}]
56 (with-page {}
57 [:h2 "Recent posts"]
58 [:paragraph ""]
59 (map (partial post-fragment {:title-with-link? true})
60 posts)
61 (when has-prev
62 [:link (str "/"
63 (if (= (dec nth) 1)
64 "index"
65 (dec nth))
66 ".gmi")
67 "Newer Posts"])
68 (when has-next
69 [:link (str "/" (inc nth) ".gmi")
70 "Older Posts"])))
72 (defn custom-page [{:keys [body]}]
73 (with-page {}
74 (gemtext/parse body)))
76 (defn post-page [{:keys [title short] :as post}]
77 (with-page {}
78 (post-fragment {:full? true}
79 post)))
81 (defn tags-page [tags]
82 (with-page {}
83 [:h2 "All tags"]
84 [:paragraph ""]
85 (map #(vector :link (str "/tag/" (name %) ".gmi") (str "#" (name %)))
86 (sort (fn [a b]
87 (compare (.toLowerCase (name a))
88 (.toLowerCase (name b)))) tags))))
90 (defn tag-page [tag posts]
91 (with-page {}
92 [:h2 (format "Posts tagged with #%s" tag)]
93 [:paragraph ""]
94 [:paragraph "Note: note every post is currently available over Gemini."]
95 [:paragraph ""]
96 (map (partial post-fragment {:title-with-link? true})
97 (->> posts
98 (sort-by :date)
99 (reverse)))))