diff --git a/resources/public/img/named-tab.gif b/resources/public/img/named-tab.gif new file mode 100644 index 0000000..1e71b19 Binary files /dev/null and b/resources/public/img/named-tab.gif differ diff --git a/resources/public/style/custom.css b/resources/public/style/custom.css index e5b6f35..fd67d3b 100644 --- a/resources/public/style/custom.css +++ b/resources/public/style/custom.css @@ -4,7 +4,9 @@ html { pre, code { - font: 0.8em Monaco, monospace; + font: + 0.8em Monaco, + monospace; font-family: Monaco, monospace; } @@ -45,3 +47,31 @@ ol.footnote { /* ol.footnote li { */ /* list-style-position: inside; */ /* } */ + +td.listing-row { + vertical-align: top; + height: 0; +} + +td.pad-right { + padding-right: 0.5em; +} + +td.pad-left { + padding-left: 0.5em; +} + +table.listing-table { + border-collapse: separate; + border-spacing: 0 1em; +} + +img.center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.max-width-gif-316 { + max-width: 316px; +} diff --git a/resources/public/style/custom.min.css b/resources/public/style/custom.min.css index 61504a8..6c8ddac 100644 --- a/resources/public/style/custom.min.css +++ b/resources/public/style/custom.min.css @@ -1 +1 @@ -html{overflow-y:overlay}code[class*="language-"],pre[class*="language-"]{font:.8em Monaco,monospace}code{font-family:Monaco,monospace}a.in-nav{padding-right:8px}.aal_anchor{float:left;padding-right:4px;margin-left:-20px;line-height:1;text-decoration:none}.aal_anchor:focus{outline:0}.aal_svg{vertical-align:middle;visibility:hidden;display:inline-block;fill:currentColor}h1:hover .aal_svg,h2:hover .aal_svg,h3:hover .aal_svg,h4:hover .aal_svg,h5:hover .aal_svg,h6:hover .aal_svg{visibility:visible}ol.footnote{column-count:1;padding:0 20px 20px 20px} \ No newline at end of file +html{overflow-y:overlay}pre,code{font:.8em Monaco,monospace;font-family:Monaco,monospace}a.in-nav{padding-right:8px}.aal_anchor{float:left;padding-right:4px;margin-left:-20px;line-height:1;text-decoration:none}.aal_anchor:focus{outline:0}.aal_svg{vertical-align:middle;visibility:hidden;display:inline-block;fill:currentColor}h1:hover .aal_svg,h2:hover .aal_svg,h3:hover .aal_svg,h4:hover .aal_svg,h5:hover .aal_svg,h6:hover .aal_svg{visibility:visible}ol.footnote{column-count:1;padding:0 20px 20px 20px}td.listing-row{vertical-align:top;height:0}td.pad-right{padding-right:.5em}td.pad-left{padding-left:.5em}table.listing-table{border-collapse:separate;border-spacing:0 1em}img.center{display:block;margin-left:auto;margin-right:auto}img.max-width-gif-316{max-width:316px} \ No newline at end of file diff --git a/src/li/laratel/blog.clj b/src/li/laratel/blog.clj index bbedafd..75fb46f 100644 --- a/src/li/laratel/blog.clj +++ b/src/li/laratel/blog.clj @@ -14,16 +14,14 @@ {:title "Luciano Laratelli's Blog" :description "Listing of Luciano Laratelli's blog posts" :has-code? nil} - [:p - [:table {:style - {:border-collapse "collapse"}} + [:table.listing-table - (for [date ordered-dates] - (let [{:keys [date-str title blog-post-id]} (get posts-by-date date)] - [:tr - (table-row date-str) - (table-row - [:a {:href (str "/blog/" blog-post-id)} title])]))]]))) + (for [date ordered-dates] + (let [{:keys [date-str title blog-post-id]} (get posts-by-date date)] + [:tr.listing-row + [:td.listing-row.pad-right date-str] + [:td.listing-row.pad-left + [:a {:href (str "/blog/" blog-post-id)} title]]]))]))) (defn blog-post [{{:keys [blog-post-id]} :path-params}] (let [{:keys [body title description date-str]} diff --git a/src/li/laratel/core.clj b/src/li/laratel/core.clj index 7d89a89..3085bdb 100644 --- a/src/li/laratel/core.clj +++ b/src/li/laratel/core.clj @@ -6,7 +6,7 @@ [li.laratel.cv :as cv] [li.laratel.home :as home] [li.laratel.lowering :as lowering] - ;; [li.laratel.programs.programs :as programs] + [li.laratel.programs.programs :as programs] [org.httpkit.server :as http] [reitit.ring :as ring] [ring.middleware.defaults :refer [api-defaults wrap-defaults]] @@ -52,11 +52,10 @@ :parameters {:path {:blog-post-id string?}}}]] ["cv" {:get cv/cv}] - ;; ["programs" - ;; ["" {:get programs/programs}] - ;; ["/:program-id" {:get programs/program - ;; :parameters {:path {:program-id string?}}}]] - ]]) + ["programs" + ["" {:get programs/programs}] + ["/:program-id" {:get programs/program + :parameters {:path {:program-id string?}}}]]]]) (ring/routes ;; Handle trailing slash in routes - add it + redirect to it diff --git a/src/li/laratel/lowering.clj b/src/li/laratel/lowering.clj index 94cff9e..97f4b5c 100644 --- a/src/li/laratel/lowering.clj +++ b/src/li/laratel/lowering.clj @@ -72,7 +72,6 @@ ;; reason. Didn't want to spend time debugging (let [[_ _ content] (cm/parse-body content {:markdown/link-ref lower-link-ref}) content (conj content [:span " "] [:a {:href (str "#fnref-" id)} "↩"])] - (println content) [:li {:id (str "fn-" id)} [:div {"display" "inline"} content]])) diff --git a/src/li/laratel/programs/programs.clj b/src/li/laratel/programs/programs.clj new file mode 100644 index 0000000..72aa7ab --- /dev/null +++ b/src/li/laratel/programs/programs.clj @@ -0,0 +1,46 @@ +(ns li.laratel.programs.programs + (:require + [li.laratel.util :as util])) + +(defn programs [_request] + (util/site-page + {:title "Luciano Laratelli's Programs" + :description "Listing of some smaller programs written by Luciano Laratelli"} + [:table.listing-table + [:tr.lsiting-row + [:td.listing-row.pad-right "2024-03-05"] + [:td.listing-row.pad-left [:a {:href (str "/programs/" "named-tab")} "NamedTab"] " is a silly-but-useful tool that lets you set the title of a page."]]] + +;; [:p + ;; [:table {:style + ;; {:border-collapse "collapse"}} + ;; [:tr + ;; (util/table-row + ;; [:a {:href (str "/programs/" "reconciler")} "Reconciler"])]]] + )) + +#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} +(defn named-tab [] + (util/site-page + {:title "NamedTab" + :description "NamedTab is a silly-but-useful tool that lets you set the title of a page."} + [:p + "This page lets you set the name of the current tab. It uses " + [:a {:href "https://shields.io/"} "Shields.io"] + " to generate a favicon and will maintain a consistent color for the same + string. I use it in conjuction with " + [:a {:href "https://addons.mozilla.org/en-US/firefox/addon/tree-style-tab/"} "Tree Style Tab"] + " and some " [:a {:href "https://git.sr.ht/~luciano/.home/tree/main/item/userChrome.css"} "CSS"] + " my friend Elijah dug up (thanks again!) to achieve this functionality: " + [:p [:img.center.max-width-gif-316 {:src "/img/named-tab.gif" + :loading "lazy"}]] + [:div + "Your desired tab name:" + [:input {:id "the-input"}] + [:script + "const updateTitle = () => {\n const title = document.getElementById('the-input').value;\n document.title = title;\n }\n\n // https://stackoverflow.com/a/260876\n const changeFavicon = (src) => {\n var link = document.querySelector(\"link[rel~='icon']\");\n if (!link) {\n link = document.createElement('link');\n link.rel = 'icon';\n document.head.appendChild(link);\n }\n link.href = src;\n }\n\n // https://stackoverflow.com/a/16348977\n const stringToColor = (str) => {\n let hash = 0;\n str.split('').forEach(char => {\n hash = char.charCodeAt(0) + ((hash << 5) - hash)\n })\n let color = ''\n for (let i = 0; i < 3; i++) {\n const value = (hash >> (i * 8)) & 0xff\n color += value.toString(16).padStart(2, '0')\n }\n return color\n }\n\n const updateFavicon = () => {\n const title = document.getElementById('the-input').value;\n const color = stringToColor(title);\n const faviconUrl = `https://img.shields.io/badge/${title[0].toUpperCase()}-${color}`\n\n changeFavicon(faviconUrl);\n }\n\n document.getElementById('the-input').addEventListener(\"change\", updateTitle);\n document.getElementById('the-input').addEventListener(\"change\", updateFavicon);"]]])) + +(defn program [{{:keys [program-id]} :path-params}] + ;;sorry + (let [program-fn (ns-resolve (find-ns 'li.laratel.programs.programs) (symbol program-id))] + (program-fn))) diff --git a/src/li/laratel/util.clj b/src/li/laratel/util.clj index 3fe14c4..106ded5 100644 --- a/src/li/laratel/util.clj +++ b/src/li/laratel/util.clj @@ -49,7 +49,7 @@ [:a.in-nav {:href "/"} "Home"] [:a.in-nav {:href "/blog"} "Blog"] [:a.in-nav {:href "/cv"} "CV"] - ;; [:a.in-nav {:href "/programs"} "Programs"] + [:a.in-nav {:href "/programs"} "Programs"] ;; [:a.in-nav {:href "/projects"} "Projects"] ]])