Skip to content

Instantly share code, notes, and snippets.

@capjamesg
Created September 19, 2022 19:20
Show Gist options
  • Save capjamesg/a546ba1ab8737b7f9a8ef3f9f8c4b7ed to your computer and use it in GitHub Desktop.
Save capjamesg/a546ba1ab8737b7f9a8ef3f9f8c4b7ed to your computer and use it in GitHub Desktop.
Static site generator for my /projects page
;; static site generator built in Lisp
;; codename: apple (that is the full name!)
;; application level code
(defun attr (name &optional value)
;; create an attribute key="value" pair
(if value
(concatenate 'string name "='" value "' ")
(concatenate 'string name)))
(defun checkclosing (name)
;; check if a closing tag is needed
(if (member name '(img br hr DOCTYPE))
(concatenate 'string ">")
(concatenate 'string "</" name ">")))
(defun tag (name &optional contents attributes)
;; convert contents and attribuets to flat lists of strings if a list is provided
(if (listp contents)
(setq contents (apply 'concatenate 'string contents)))
(if (listp attributes)
(setq attributes (apply 'concatenate 'string attributes)))
(if (> (length attributes) 0)
(concatenate 'string "<" name " " attributes ">" contents (checkclosing name))
(concatenate 'string "<" name ">" contents (checkclosing name))))
(defun rel (val url)
;; create a rel link
(tag "link" "" (list (attr "rel" val) (attr "href" url))))
(defun head (pageurl)
;; website <head> tag
(list
(tag "title" "Projects | James' Coffee Blog")
(tag "link" "" (list (attr "rel" "stylesheet") (attr "href" "https://jamesg.blog/assets/styles/styles.css")))
(tag "meta" "" (attr "charset" "utf-8"))
(rel "me" "mailto:jamesg@jamesg.blog")
(rel "me" "https://indieweb.rocks/jamesg.blog")
(rel "manifest" "/assets/manifest.json")
(rel "search" "/assets/search.xml")
(rel "icon" "/favicon.ico")
(rel "apple-touch-icon-precomposed" "/favicon.ico")
(rel "canonical" (concatenate 'string "https://jamesg.blog" pageurl))
(rel "webmention" "https://webmention.io/jamesg.blog/webmention")
(rel "pingback" "https://webmention.io/jamesg.blog/xmlrpc")))
(defun box (title description links &optional image alt)
;; box for the projects page
(concatenate 'string
(if image (tag "img" "" (list (attr "src" image) (attr "alt" alt))))
(tag "h2" title)
(tag "p" description)
(apply 'concatenate 'string links)))
(defun link (text anchor)
;; define an <a> link
(tag "p"
(tag "a" text
(list
(attr "href" anchor)))))
(defun projectscontent ()
;; body for the projects page
(tag "main"
(list
(tag "h1" "Projects")
(tag "p" "This page displays a few of the projects I have worked on.")
(tag "p" "To see the full list, view my GitHub page.")
(box "IndieWeb Search" "A search engine and crawler that indexes web pages made
by IndieWeb community members."
(list
(link "View Project (currently under maintenance)" "https://indieweb-search.jamesg.blog")
(link "View Source Code" "https://github.com/capjamesg/indieweb-search"))
"https://jamesg.blog/assets/indieweb_search_engine.png"
"Search Engine homepage screenshot")))
(box "Webmention Sender and Receiver" "A server that can receive, process, and send webmentions."
(list
(link "View Project (currently under maintenance)" "https://indieweb-search.jamesg.blog")
(link "View Source Code" "https://github.com/capjamesg/indieweb-search"))
"https://jamesg.blog/assets/webmention_receiver_dashboard.png"
"Webmention receiver dashboard screenshot"))
(defun projectspage (pageurl)
;; projects page
(tag "html"
(list
(tag "head" (head pageurl))
(tag "body" (projectscontent)))))
(with-open-file (stream "index.html" :direction :output :if-does-not-exist :create :if-exists :supersede)
(format stream (projectspage "/")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment