Commit Diff


commit - b75f3ee48e0b3093f45127022f706dea2a80d489
commit + d72c4e8fb702687b971a66742d22e7398d34401f
blob - /dev/null
blob + fec278614a31c13821728a8387e2d417a122d07d (mode 644)
--- /dev/null
+++ resources/pages/crest.gmi
@@ -0,0 +1,6 @@
+# CREST
+
+crest(1) is a REPL for HTTP.  It has a nice (in my opinion) grammar and that's that.
+
+=> https://git.omarpolo.com/crest       git repository
+=> https://github.com/omar-polo/crest   github mirror
blob - /dev/null
blob + 7d408738cf83c4231f2f219c59e7aaef467c1fc5 (mode 644)
--- /dev/null
+++ resources/pages/gmid.gmi
@@ -0,0 +1,34 @@
+# gmid
+
+gmid is a small, almost no-dependencies, gemini server for static content.  I wrote it because I needed one and I disliked the ones that I found (or I wasn't able to compile them)
+
+It's a very short C program (less than 500 lines of code at the moment), that uses libtls (a GREAT tls library from the OpenBSD folks.)
+
+It doesn't support virtual hosts (it completely ignores the host part of the requested URL) and can only serve static content.
+
+=> https://git.omarpolo.com/gmid        gmid git repository
+
+You can fetch the code with git
+```
+git clone https://git.omarpolo.com/gmid
+```
+or via the github mirror
+```
+git clone https://github.com/omar-polo/gmid
+```
+
+## Future plans
+
+This is mostly a TODO/wish list of things, just to get an idea of what I'm gonna do (and to remind to myself too).
+
+* performance
+I don't want to over-engineer this, but at least I would like to replace the naïve accept-read-write loop with a slightly more sophisticated one based on poll(2).
+
+* MIME types
+At the moment I'm serving every file with the text/gemini MIME type.  It's still OK for my current use case, but I need to fix this.
+
+* virtual hosts
+mapping hosts to different directories would be really handy
+
+* directory listings
+It's currently not supported, and I'm not even sure it could be useful.
blob - /dev/null
blob + 2949e00d4fa26de1f11ecee135be8d892a09ac30 (mode 644)
--- /dev/null
+++ resources/pages/projects.gmi
@@ -0,0 +1,15 @@
+# Projects
+
+Here are some projects I'm working on.
+
+=> star-platinum.gmi    star-platinum - take control of your applications, one key at the time
+It's a keybinding manager for X11.  It lets you assign keys on other application and bind custom action to them.  You can execute external commands or send fake keys.  I'm using it to "emacs-ify" firefox, but can do more.
+
+=> gmid.gmi             gmid - dead simple zero configuration gemini server
+(If you're browsing this page over gemini this is the server that you're talking to.)  A simple, zero-conf, gemini server for static content.  Written for fun with libtls.
+
+=> crest.gmi            CREST - see your rest endpoints
+Interactive REPL for HTTP requests with a simple and intuitive language.
+
+=> sam-el.gmi           sam.el - An editor for the best OS
+sam.el is an implementation of the text editor sam for plan9 for emacs.  It's still far, far away from being usable.
blob - /dev/null
blob + 6d616d98b61f03692c106f8c9a085b656c900a7a (mode 644)
--- /dev/null
+++ resources/pages/sam-el.gmi
@@ -0,0 +1,6 @@
+# sam.el
+
+sam.el is a WIP sam emulator for emacs.
+
+=> https://git.omarpolo.com/sam.el      git repository
+=> https://github.com/omar-polo/sam.el  github mirror
blob - /dev/null
blob + 894c0ac4e850ab339e79695a2e55a2e32a7eb15f (mode 644)
--- /dev/null
+++ resources/pages/star-platinum.gmi
@@ -0,0 +1,41 @@
+# star-platinum
+
+It's a key binding manager for X11.  It lets you assign keys on other application and bind custom action to them.  You can execute external commands or send fake keys.  I'm using it to "emacs-ify" firefox, but can do more.
+
+Let's take a look at a sample configuration file
+
+```
+match all
+on "C-<F5>" do exec 'notify-send "hello world"'
+
+match class 'Firefox'
+match class 'Chromium-browser'
+on "C-w" do "C-x"
+on "M-w" do "C-c"
+on "C-y" do "C-v"
+```
+
+I binded globally control+F5 to that command, and on firefox and chromium I've re-binded control-w to cut, alt-w to copy and control-y to paste.  The key syntax is heavily inspired by emacs.
+
+=> https://git.omarpolo.com/star-platinum star-platinum git repository
+
+You can fetch the sources with
+```
+git clone https://git.omarpolo.com/star-platinum
+```
+or via the github mirror
+```
+git clone https://github.com/omar-polo/star-platinum
+```
+
+To build you need a C compiler (anything from GCC 4.2 onward should work – that is, anything from the last 15 years), lex/flex, yacc/bison and make.  Check out the README for more information on building.
+
+## Planned work
+
+This is a sort of TODO list of things I want to develop.
+
+* bind keys directly on the windows
+I'm currently binding the key globally and send fake copy of the event if the window doesn't match.  But binding the keys globally can interfere with other programs that, by defaults, ignores fake keys (like XTerm).
+
+* define state / better keymap
+I should introduce keymaps.  This should let me allow arbitrary keys, like "C-x C-s", and also introduce the idea of "states" for our vi friends.
blob - /dev/null
blob + d6a11ee4bca18a1cbb63b1306bcc638b1bee7d41 (mode 644)
--- /dev/null
+++ resources/pages.edn
@@ -0,0 +1,10 @@
+[{:title "Projects"
+  :slug  "projects"}
+ {:title "star-platinum - take control of your applications, one key at the time"
+  :slug  "star-platinum"}
+ {:title "gmid - dead simple zero configuration gemini server"
+  :slug  "gmid"}
+ {:title "crest - see your rest endpoints"
+  :slug  "crest"}
+ {:title "sam.el - An editor for the best OS"
+  :slug  "sam-el"}]
blob - 18e4d87fce13503fa91d8383c9b7f4c0924bd332
blob + 41562124cbce4ce6e295b245ae5b41ed6e3c7f2f
--- src/blog/core.clj
+++ src/blog/core.clj
@@ -24,6 +24,7 @@
         (assoc  :body (-> (str "posts/" slug ext) io/resource slurp))
         (update :date time/parse))))
 
+(def pages (atom nil))
 (def per-tag (atom {}))
 (def posts (atom []))
 
@@ -42,13 +43,26 @@
                 edn/read-string)]
     (add-post! p)))
 
+(defn load-pages! []
+  (reset! pages (->> "pages.edn"
+                     io/resource
+                     slurp
+                     edn/read-string
+                     (map (fn [{:keys [slug] :as p}]
+                            (assoc p :body (as-> slug $
+                                                (str "pages/" $ ".gmi")
+                                                (io/resource $)
+                                                (slurp $))))))))
+
 (defn create-dirs! []
   (doseq [d ["resources/out"
              "resources/out/gemini"
+             "resources/out/gemini/pages"
              "resources/out/gemini/post"
              "resources/out/gemini/tag"
              "resources/out/http"
              "resources/out/http/css"
+             "resources/out/http/pages"
              "resources/out/http/post"
              "resources/out/http/tag"
              "resources/out/http/img"]]
@@ -80,6 +94,15 @@
       (update 0                        assoc :has-prev false)
       (update (dec (count post-pages)) assoc :has-next false)))
 
+(defn render-pages [pagefn proto ext]
+  (doseq [page @pages
+          :let [{:keys [slug]} page
+                filename (str "resources/out/"
+                              (name proto) "/pages/"
+                              slug ext)]]
+    (spit filename
+          (pagefn page))))
+
 (defn render-post-list [viewfn proto]
   (doseq [p    (fix-next-last (post-pages {:proto proto}))
           :let [{:keys [filename]} p]]
@@ -135,9 +158,10 @@
   (create-dirs!)
   (copy-assets)
   (render-rss)
-  (doseq [[proto ffn ext homefn postfn tagsfn tagfn]
-          [[:http identity ".html" http/home-page http/post-page http/tags-page http/tag-page]
-           [:gemini gemini-post ".gmi" gemini/home-page gemini/post-page gemini/tags-page gemini/tag-page]]]
+  (doseq [[proto ffn ext homefn postfn tagsfn tagfn pagefn]
+          [[:http identity ".html" http/home-page http/post-page http/tags-page http/tag-page http/custom-page]
+           [:gemini gemini-post ".gmi" gemini/home-page gemini/post-page gemini/tags-page gemini/tag-page gemini/custom-page]]]
+    (render-pages pagefn proto ext)
     (render-post-list homefn proto)
     (doseq [p (filter ffn @posts)]
       (render-post postfn proto ext p))
@@ -182,6 +206,7 @@
 
 (defn -main [& actions]
   (load-posts!)
+  (load-pages!)
   (doseq [action actions]
     (case action
       "clean"  (clean)
@@ -193,7 +218,8 @@
 (comment
   (do
     (load-posts!)
-    (clean)
+    (load-pages!)
+    ;; (clean)
     (build)
     (local-deploy))
   (serve)
blob - 09a4edfd97ae0033f1ee98812a333943d8ee1adb
blob + 44a2e6d011dc6975f5e0a541b63caae132d9abb8
--- src/blog/gemini.clj
+++ src/blog/gemini.clj
@@ -17,7 +17,7 @@
     [:paragraph ""]
     [:link "/" "Home"]
     [:link "/tags.gmi" "All Tags"]
-    [:link "https://git.omarpolo.com" "Git repos"]
+    [:link "/pages/projects.gmi" "Projects"]
     [:paragraph ""]
     body
     [:paragraph ""]
@@ -67,6 +67,10 @@
       [:link (str "/" (inc nth) ".gmi")
        "Older Posts"])))
 
+(defn custom-page [{:keys [body]}]
+  (with-page {}
+    (gemtext/parse body)))
+
 (defn post-page [{:keys [title short] :as post}]
   (with-page {}
     (post-fragment {:full? true}
blob - 46ef03206748b4f809f1b84a5c46db4a8a06981a
blob + 6393d3b55d7c1e0098b5a3a200516fc75c79399e
--- src/blog/http.clj
+++ src/blog/http.clj
@@ -2,6 +2,8 @@
   (:require
    [blog.time :as time]
    [blog.gemtext :as gemtext]
+   [clojure.string :as str]
+   [clojure.walk :as walk]
    [hiccup.page :refer [html5 include-css]]
    [commonmark-hiccup.core :refer [markdown->hiccup default-config]]))
 
@@ -15,8 +17,8 @@
      [:ul
       (link-item {:url "/", :text "Home"})
       (link-item {:url "/tags.html", :text "All Tags"})
-      (link-item {:url "gemini://gemini.omarpolo.com" :text "gemini://"})
-      (link-item {:url "https://git.omarpolo.com", :text "Git repos"})]]
+      (link-item {:url "/pages/projects.html", :text "Projects"})
+      (link-item {:url "gemini://gemini.omarpolo.com" :text "gemini://"})]]
     [:div
      [:h1 [:a {:href "/"} "yumh"]]
      [:p "writing about things, sometimes."]]]))
@@ -106,6 +108,18 @@
        [:a.next {:href (str "/" (inc nth) ".html")}
         "Older Posts »"])]))
 
+(defn custom-page [{:keys [title body]}]
+  (with-page {:title title}
+    ;; warning: hack ahead
+    (walk/prewalk
+     (fn [item]
+       (if-not (and (vector? item) (= (first item) :a))
+         item
+         (let [[_ attrs & body] item]
+           [:a (update attrs :href str/replace #"\.gmi$" ".html")
+            body])))
+     (-> body gemtext/parse gemtext/to-hiccup))))
+
 (defn post-page
   [{:keys [title short], :as post}]
   (with-page {:title title