4 [blog.gemtext :as gemtext]
5 [clojure.string :as str]
6 [clojure.walk :as walk]
7 [hiccup.page :refer [html5 include-css]]
8 [commonmark-hiccup.core :refer [markdown->hiccup default-config]]))
10 (defn link-item [{:keys [url text title]}]
11 [:li [:a (cond-> {:href url}
12 title (assoc :title title))
15 (defn header [{:keys [skip-banner?]}]
20 (link-item {:url "/", :text "Home"})
21 (link-item {:url "/tags.html", :text "All Tags"})
22 (link-item {:url "/pages/projects.html", :text "Projects"})
23 #_(link-item {:url "/dots", :text "dotfiles"})
24 (link-item {:url "gemini://gemini.omarpolo.com" :text "gemini://"
25 :title "This website in the gemini space."})]]
26 (when-not skip-banner?
28 [:h1 [:a {:href "/"} "yumh"]]
29 [:p "writing about things, sometimes."]])]))
32 [{:keys [title class description skip-banner?], :as d} & body]
35 [:meta {:charset "utf8"}]
36 [:meta {:name "viewport", :content "width=device-width, initial-scale=1"}]
37 [:link {:rel "shortcut icon", :href "/favicon.ico"}]
38 [:link {:rel "alternative" :type "application/rss+xml" :href "https://www.omarpolo.com/rss.xml"}]
40 [:meta {:name "description" :content description}])
42 (include-css "/css/style.css")]
43 [:body {:class (or class "")}
47 [:p "text: CC-BY-SA-4.0; code: MIT (unless specified otherwise)"]
48 [:p "Blog proudly generated with "
49 [:a {:href "https://git.omarpolo.com/blog/"}
50 [:code "(clojure)"]]]]
52 [:img {:src "https://goatcounter.omarpolo.com/count?p=/test-img"}]]
55 if (window.location.host !== 'www.omarpolo.com')
56 window.goatcounter = {no_onload: true}
58 [:script {:data-goatcounter "https://goatcounter.omarpolo.com/count"
60 :src "//goatcounter.omarpolo.com/count.js"}]]))
63 "traverse `doc` and replace every link to an image to an `img` tag."
67 (if-not (and (vector? item) (= (first item) :a))
69 (let [[_ {:keys [href] :as attrs} text] item]
76 [{:keys [full? title-with-link?]}
77 {:keys [title date slug tags short body toot music xkcd gemtext?], :as post}]
84 [:a {:href (str "/post/" slug ".html")} title]
86 [:p.author "Written by " [:em "Omar Polo"] " on " (time/fmt-loc date)
89 (let [b (list "“" [:em (:title music)] "”"
90 (when-let [by (:by music)]
91 (list " by " [:em by])))]
92 (list " while listening to "
93 (if-let [url (:url music)]
100 [:ul.tags (map #(vector :li [:a {:href (str "/tag/" (name %) ".html")}
104 [:p [:a {:href (str "https://xkcd.com/" xkcd)
111 :rel "noopener"} "Comments over ActivityPub"]])]
115 (-> body gemtext/parse gemtext/to-hiccup)
116 (markdown->hiccup default-config body))
120 [{:keys [posts has-next has-prev nth]}]
121 (with-page {:title "Home"}
122 [:p "Hello! Sometimes I remember that I have a blog and post something here. "
123 "You can find me " [:strike "wasting time"]
124 " posting interesting stuff on the fediverse too: "
125 ;; <a rel="me" href="https://bsd.network/@op">Mastodon</a>
126 [:a {:href "https://bsd.network/@op"
128 "@op@bsd.network"] "."]
129 (map (partial post-fragment {:title-with-link? true})
131 [:nav.post-navigation
133 [:a.prev {:href (str "/" (if (= (dec nth) 1)
138 [:a.next {:href (str "/" (inc nth) ".html")}
141 (defn custom-page [{:keys [title body]}]
142 (with-page {:title title
144 ;; warning: hack ahead
147 (if-not (and (vector? item) (= (first item) :a))
149 (let [[_ attrs & body] item]
150 [:a (update attrs :href str/replace #"\.gmi$" ".html")
152 (-> body gemtext/parse gemtext/to-hiccup))))
155 [{:keys [title short], :as post}]
156 (with-page {:title title
159 (post-fragment {:full? true}
164 (with-page {:title "All tags"
169 (map #(vector :li [:a {:href (str "/tag/" (name %) ".html")} (str "#" (name %))])
171 (compare (.toLowerCase (name a))
172 (.toLowerCase (name b)))) tags))]]))
176 (with-page {:title (str "Posts tagged with #" tag)
178 [:h2 "Posts tagged with " [:code "#" tag]]
179 (map (partial post-fragment {:title-with-link? true})