Website Source Code

Table of Contents

Programs must be written for people to read, and only incidentally for machines to execute.

– Harld Abelson, The Structure and Interpretation of Computer Programs


This is my the source code for my website. Currently it's only CSS, some emacs config, and a bit of HTML, but eventually I intend to add features for running ClojureScript in source code blocks among other things. Changes to this file will be noted in the changelog.

The entire document is done in a nonlinear format, so each section does not exactly relate to an individual file, but rather combines the various files used into one. If you want to get to the code, just skip the intro and go straight to Lein Setup. 1 Leinigen is great, though it's kind of interesting to note the transformation from the macro-heavy sort of language of Leinigen and the macro-free setup of things like garden.

Some History

I have been blogging (and attempting to make websites) for a few years, however with each website I built I would run into a number of issues.

In the beginning my issue was HTML, CSS, and JavaScript. All of them sucked quite a bit.

Initially it was just that the blog was in markdown and had a somewhat messy system to generate it from the markdown files using ruby.

I have also recently been organizing my OS and system configuration into a giant wiki 2 So far it's been going really well. given how my projects tend to go., so compatibility with that was also a necessary feature. I had attempted to do blogging in org mode before as well, though the ox-hugo option both lacked some features I wanted and left me with a somewhat lackluster experience when it came to linking files together. I probably was simply inexperienced, but it still left a bad taste in my mouth and didn't make me optimistic about the idea of having a public section to my personal wiki

However, when I read about the org-publish feature, I was very interested in writing my own website with it. So far the simple export feature has been all that it was advertised to be and seems to be more than sufficient to make a good blog.

Implementation Concept

The implementation itself is designed to be entirely local to this directory. So providing the org files should be roughly equivalent to providing the site itself (minus the color scheme of my Emacs configuration). It also adds free content if you will to the site.

Lein Setup

This sets up the Clojure project. Right now I don't actually really use the project per-se, but rather use it to generate CSS and HTML code from code blocks. Eventually I intend to add the ability to run ClojureScript in code blocks, but for now this works.

(defproject cons-blog "1.0.0"
  :description "Generate HTML and CSS for org mode export."
  :dependencies [[org.clojure/clojure "1.10.2"]
                 [org.clojure/clojurescript "1.10.891"]
                 [org.clojure/math.combinatorics "0.1.6"]
                 [org.clojure/math.numeric-tower "0.0.4"]
                 [org.clojure/core.match "1.0.0"]
                 [org.clojure/core.logic "1.0.0"]
                 [lambdaisland/regal "0.0.143"]
                 [com.cerner/clara-rules "0.21.1"]

Website Setup

This is the Emacs Lisp code used to define the website. I use the per-directory local variable functionality to set the org-html-publish settings. 3 For a while this was broken with some mysterious errors where my settings would be reset after a single run. It turned out that I had actually set the dir-locals in this directory with a hidden file that I had forgotten about. Oops.

Website Info

This gets the website info and sets the directories relative to the current one. It also sets the website name, adds the basic HTML publish / indent features, and excludes drafts from the project. (idea taken from John Louis Del Rosario).

"(cons dev nil) org"
:language "en"
:author "Inanna"
:exclude "level-.*\\|.*\.draft\.org"
:html-metadata-timestamp-format "%G-W%V-%u %H:%M"
:section-numbers nil
:publishing-function org-html-publish-to-tufte-html
:html-html5-fancy t
:html-head-include-default-style nil
:html-indent nil 

Source Directories

As of generating this file, thce directory above it contains the following files.

total 68
-rw-r--r-- 1 1000 998 17556 Feb 24 15:07 .cider-repl-history
drwxr-xr-x 2 1000 998  4096 Dec 10 18:37 classes
-rw-r--r-- 1 1000 998  5793 Mar 17 02:10 .dir-locals.el
-rw-r--r-- 1 1000 998    34 Jul 29  2021 .git
-rw-r--r-- 1 1000 998   240 Mar 17 02:10 .gitignore
-rw-r--r-- 1 1000 998    73 Dec 10 18:34 hello.clj
-rw-r--r-- 1 1000 998     5 Mar 17 01:42 .nrepl-port
-rw-r--r-- 1 1000 998   580 Mar 17 02:10 project.clj
drwxr-xr-x 7 1000 998  4096 Mar 17 02:12 public
drwxr-xr-x 8 1000 998  4096 Mar 17 02:10 src
drwxr-xr-x 4 1000 998  4096 Jan  9 23:47 target
-rw-r--r-- 1 1000 998  4050 Dec  2 14:01 test.css

The project.clj and target directories are automatically generated as are the dotfiles, while the src and public directories are not generated by any code. The src directory of course contains the org files while the public contains exported HTML. We set variables for these since the publishing function (WIP) also needs to know the directories. To find the location of the project itself I use projectile. 4 I can't help but shill for projectile. It's one of the better Emacs packages out there and allows you to quickly search through your directories.

(cd-source-dir (concat (projectile-project-root) "src/"))
(cd-publish-dir (concat (projectile-project-root) "public/"))

Here we add them to the project configuration. The :base-directory property is source for the project and the :publishing-directory is where the results of exporting are to be placed.

:base-directory ,cd-source-dir
:publishing-directory ,cd-publish-dir

Domain Data

This adds the CNAME data to the file. This is required for the site to serve properly under the A record I set up for it.


This configures the sitemap title and name. It is automatically generated for all pages to make my life easier. Currently I use a flat layout for my website, so it is simply a list of all nodes. Eventually I want it to be displayed as a graph of links.

:sitemap-title "(cons dev sitemap)"
:auto-sitemap t

Publishing Function

This will eventually automatically publish files. Currently it is WIP and is published primarily because it realtes to my emacs namespacing adventures.

The assumption in the design is that I only really need to see the diff on the org files and the HTML files will sort themselves out. Therefore I just create a magit commit and do the job from there. The only issue is that the magit functions simply create buffers. I think the solution is to create a function to temporarily modify the hooks run after some of the functions.

(defun cd-publish-files ()
  (org-publish "(cons dev nil)")
  (cd cd-source-dir)
  (shell-command-to-string (format "git add '%s'" cd-source-dir))
  ;(magit-git-push "main" "origin" "origin")
  (cd cd-publish-dir)
  (shell-command-to-string (format "git add '%s'" cd-publish-dir))
  (shell-command-to-string "git commit -m 'Automatically published, check website-src for details.'")
  (magit-git-push "main" "origin" "origin"))

Inserting Footnotes as Side Notes

I like the sort of tufte-css style side notes, so I decided to copy an implementation that someone else had done. 5 Why make when you can steal? Eventually I intend to add in some further features to document code block tangling and add RSS to the website. This website has some good examples of that I think, though I have yet to implement that.

(defun tufte-html-footnote-reference (footnote-reference contents info)
  "Create a footnote according to the tufte css format.
FOOTNOTE-REFERENCE is the org element, CONTENTS is nil.  INFO is
a plist holding contextual information."
  (let ((prev (org-export-get-previous-element footnote-reference info))
        (fn-id (org-export-get-footnote-number footnote-reference info)))
    (format <<sidenote-html()>>
            (org-trim (org-export-data (org-export-get-footnote-definition footnote-reference info) info)))))

(org-export-define-derived-backend 'tufte-html 'html
  :translate-alist '((footnote-reference . tufte-html-footnote-reference)
                     (footnote-definition . tufte-html-footnote-definition)))

(defun org-html-publish-to-tufte-html (plist filename pub-dir)
  "Publish an org file to HTML.

FILENAME is the filename of the Org file to be published.  PLIST
is the property list for the given project.  PUB-DIR is the
publishing directory.

Return output file name."
  (org-publish-org-to 'tufte-html filename
                      (concat (when (> (length org-html-extension) 0) ".")
                              (or (plist-get plist :html-extension)
                      plist pub-dir))

This is the HTML template for a sidenote feature.

(use 'hiccup.core)
(html    [:label {:class "sidenote-number"
                  :for   "%s"}
          [:sup "%s"]]
         [:input {:style   "display:none"
                  :type    'checkbox
                  :checked true
                  :id      "%s"}]
         [:span {:class "sidenote"}
          [:span {:class "sidenote-number"} " %s"]
          " %s"])

Directory Local Variables

This is the setup of the dir locals for the blog. They are used to keep the entire project local to the current directory.

((nil . ((eval
          . (progn
              (setq lexical-binding t)
              (lexical-let (
                 org-export-with-section-numbers nil
                 org-html-footnotes-section "<!-- %s --><!-- %s -->"
                 `(("(cons dev nil) images"
                    :base-directory "~/Memex/cons-site/src/images/"
                    :base-extension "svg\\|png\\|jpeg"
                    :publishing-directory "~/Memex/cons-site/public/images/"
                    :publishing-function org-publish-attachment)
                   ("(cons dev nil) other"
                    :base-directory "~/Memex/cons-site/src/other"
                    :base-extension "pdf\\|clj\\|sh"
                    :publishing-directory "~/Memex/cons-site/public/other/"
                    :publishing-function org-publish-attachment)
                   ("(cons dev nil) fonts"
                    :base-directory "~/Memex/cons-site/src/fonts"
                    :base-extension "*"
                    :publishing-directory "~/Memex/cons-site/public/fonts/"
                    :publishing-function org-publish-attachment)
                    :base-directory "~/Memex/cons-site/src/dodgy/resources/public/"
                    :base-extension "js\\|html"
                    :publishing-directory "~/Memex/cons-site/public/dodgy/resources/public/"
                    :publishing-function  org-publish-attachment
                    :recursive t)
                   ("(cons dev nil)"
                    :components ("(cons dev nil) org"
                                 "(cons dev nil) images"
                                 "(cons dev nil) other"

Git Setup

This is basically the (rather small) amount of setup used to ensure that generated files are not included in the git repository. It also ignores draft files.


# Lein related stuff                       


This is where I configure the HTML displayed by the system, for th emost part.


Here we import hiccup so we can write our HTML in Clojure. You may have noticed that I am slightly allergic to HTML. This is partially because I like to do

[hiccup "1.0.5"]

Preamble and Postamble

This is the first section of the program and the

License Info

This is the license info for my website. I selected the license because it provides one-way compatibility with the GPL-3.0 license. Thus I can license my code under the GPL, while licensing most of the text of the site under the CC-BY-SA 4.0 license. Currently it is displayed in the postamble on all pages, though I might want to alter that someday.

[:p {:class "license"}
 "Except where otherwise noted content on "
 [:a {:href ""} ""]
 " is licensed under a "
 [:a {:rel "license" :href ""}
  "Creative Commons Attribution-ShareAlike 4.0 International License"] "."]


This adds a few links to the beginning of the document to aid with navigation.

(use 'hiccup.core)
(html [:div
       [:a {:href "/index.html"}
        [:img {:id  "site-logo"
               :src "/images/website-logo.png"
               :alt "An abstract logo representing a series of three assembly line stamping machines with the words CONS, DEV, and NIL embalzoned in white on each machine."}]]])

This is the Emacs code that sets the preamble

:html-preamble t
:html-preamble-format '("en" <<emacs-html-preamble()>>)


The end of each document this adds a little bit of text containing the info about the program that created it, the date the file was modified, and licensing information

(use 'hiccup.core)
(html [:p {:class "date"} "Last Modified: %C"]
      [:p {:class "creator"} "Generated Using: %c"]

This code sets the postamble.

:html-postamble t
:html-postamble-format '("en" <<emacs-html-postamble()>>)


While org-html-export does an admirable job at exporting code in my preferred syntax highlighting style, it unfortunately does not replicate the other features of my org-mode buffers. To do that I use Garden, a Clojure library for defining CSS. The reason I use garden is mostly because I dislike using CSS directly and have a ton of features set up for structure editing lisp that I don't have for HTML and CSS.


[garden "1.3.10"]

Emacs Configuration

This adds the Emacs configuration for the stylesheets in the blog. It also adds a link to the fonts stylesheet.

(use 'hiccup.core)
(html [:link {:rel "stylesheet" :type "text/css" :href "/site.css"}]
      [:link {:rel "icon" :href "images/website-icon.png"}])

This property then sets the HTML head on every file to be the HTML generated by that.

:html-head <<html-head()>>

Create CSS File

This creates the CSS file in my public directory. It is automatically called every time the project is updated (thus generating the CSS file). This ensures that the state of this file is kept in sync with the actual state of the project itself.

(ns stylesheets
  "A namespace for stylesheets"
  (:require [garden.core :refer [css]]
            [garden.def :refer [defcssfn]]
            [garden.units :refer [em px percent vw]]
            [garden.selectors :refer [defpseudoelement > pre p a +]]
            [garden.stylesheet :refer [at-import at-media at-font-face]]))

(defcssfn url)
(defpseudoelement selection)
(def red "#e53935")
(def fg "#000")
(def fg-alt "#a4a4a4")
(def light-red "#ff6d60")
(def bg "#fff")
(def bg-alt "#f5f5f5")

(def mono-font "'Iosevka Term Web'")
(def title-font "'Jura'")
(def proportional-font "'Iosevka Aile Web'")

(spit "./public/site.css"
class clojure.lang.Compiler$CompilerException

Background and Foreground

This keeps the default background and foreground in sync with the rest of the system. To see the code blocks being called, view the helper blocks section. I also set up the I use here, in this case Iosevka, a pleasing DIN-like 6 How else am I to make my website as compliant with as many meaningless standards as possible? It's ISO-8601 compliant, DIN-1451 compliant (almost), RFC-791 compliant, and probably quite a few more. font that is entirely fixed-width for use in terminals.

The Iosevka Term Web font itself provides a css file that works rather well, as does the Iosevka Aile font.

(at-import (url "fonts/iosevka-term.css"))
(at-import (url "fonts/iosevka-aile.css"))
(at-font-face {:font-family title-fotnt
               :src         (url "fonts/ttf/Jura-VariableFont_wght.ttf")})
[:body {:background-color   bg
        :color              fg
        :font-family        proportional-font
        :-ms-overflow-style 'none
        :line-height        1.3
        :scrollbar-width    'none}
 [":-webkit-scrollbar" {:display 'none}]]


Tables are also nice to style, and I want them to have a subtle color scheme to make them more readable, center them in the body, and a system to automatically highlight the rows of the table. 7 Example table from the org-mode manual.

Func n x Result
exp(x) 1 x 1 + x
exp(x) 2 x 1 + x + x2 / 2
exp(x) 3 x 1 + x + x2 / 2 + x3 / 6
x2+sqrt(x) 2 x=0 x*(0.5 / 0) + x2 (2 - 0.25 / 0) / 2
x2+sqrt(x) 2 x=1 2 + 2.5 x - 2.5 + 0.875 (x - 1)2
tan(x) 3 x x pi / 180 + 5.72e-8 x3 pi3
[:table {:margin-left  'auto
         :margin-right 'auto}]
[:table :tr :td :thead :tbody
 {:border-width 0}]
[:thead {:background-color red
         :font-weight      'bold
         :color            bg
         :font-family      title-font}]
[:th :td {:text-align     'left
          :padding-bottom (em 0.25)
          :padding-top    (em 0.25)
          :padding-left   (em 0.5)
          :padding-right  (em 0.5)}]
[:tbody ["tr:hover" {:background-color bg-alt}]]


Here the lists are styled so I can make them look better and more interesting. List bullets are colored red 8 Implementation stolen from here. and the description lists also have their first elements colored red.

Example ul:

  • This
  • is
  • a
  • list

Example ol:

  1. A
  2. simple
  3. list

Example dl:

[:dt {:color red}]
[:ol {:list-style    'none
      :counter-reset 'li}
 [:li {:counter-increment 'li}]
 ["li::before" {:content      "counter(li)"
                :width        (em 1)
                :margin-right (em 0.5)
                :text-align   'right
                :direction    'rtl
                :margin-left  (em -1.5)}]]
[:ul {:list-style 'none}
 ["li::before" {:content     "'•'"
                :width       (em 1)
                :margin-left (em -1)}]]

["li::before" {:color   red
               :display 'inline-block}]
[:li {:margin-top (em 0.5)}]

Verses and Quotes

I decided that verses should be indented, but given minimal styling, while quotes should be indented, italicized, and have a quotation mark superimposed on them.

There is nothing quite like writing a long string of code.

– nil

The Eternal Flame by Julia Ecklar

I was taught Assembler in my second year of school
It's kinda like construction work –
With a toothpick for a tool
So when I made my senior year
I threw my code away
And learned the way to program
That I still prefer today

Now, some folks on the Internet
Put their faith in C++
They swear that it's so powerful
It's what God used for us
And maybe He lets mortals dredge
Their objects from the C
But I think that explains
Why only God can make a tree

For God wrote in Lisp code
When he filled the leaves with green
The fractal flowers and recursive roots:
The most lovely hack I've seen
And when I ponder snowflakes
Never finding two the same
I know God likes a language
With its own four-letter name
Now, I've used a SUN under Unix
So I've seen what C can hold
I've surfed for Perls, found what Fortran's for
Got that Java stuff down cold
Though the chance that I'd write COBOL code
Is a SNOBOL's chance in Hell
And I basically hate hieroglyphs
So I won't use APL

Now, God must know all these languages
And a few I haven't named
But the Lord made sure, when each sparrow falls
That its flesh will be reclaimed
And the Lord could not count grains of sand
With a 32-bit word
Who knows where we would go to
If Lisp weren't what he preferred?

And God wrote in Lisp code
Every creature great and small
Don't search the disk drive for man.c
When the listing's on the wall
And when I watch the lightning burn
Unbelievers to a crisp
I know God had six days to work
So he wrote it all in Lisp
Yes, God had a deadline
So he wrote it all in Lisp

[:blockquote {:font-style       'italic
              :background-color bg-alt
              :padding          (em 0.5)}]
["blockquote::before" {:content     "'\"'"
                       :font-size   (em 5)
                       :color       "rgba(0,0,0,0.1)" ; semi-transparent quote
                       :margin-left (em -0.15)
                       :margin-top  (em -0.15)
                       :height      (em 0)
                       :display     'block}]
[:.verse {:margin-left (em 3)}]

Embedded Content

Dynamic Size Switching

To ensure that the website looks good regardless of what you use 9 And I do mean regardless, I have put in some effort to ensure that it looks good even in a terminal browser, mostly by avoiding modifications to the org-exported HTML. I switch a large portion of the style of the website between two modes, a small single-column version for < 60em screens (phones and the like), and a large fully expanded one for > 60em screens (desktops, people with big browsing areas).

Non Dynamic Style

To start out some non-dynamic things need to be styled.

 {:background-color bg-alt}
 [:ul {:list-style-type 'none
       :padding-left    (em 0.5)}]
 ["li::before" {:content 'none}]]

[:.sidenote {:background-color bg-alt
             :padding          (em 0.5)
             :display          'block}]
[:.sidenote-number {:color red}]
[:#postamble {:color            fg-alt
              :background-color bg-alt
              :padding-left     (em 0.5)
              :padding-top      (em 0.5)
              :padding-bottom   (em 0.5)
              :marign-right     (em 1)}]

Wide Screen

The wide screen layout splits the website into three separate columns without changing the single-column HTML using some trickery with the margins and positioning. The leftmost column contains the table of contents, the next the document text, and the rightmost the sidenotes 10 Like this one!.

(at-media {:screen true :min-width (em 60)}
          [:.title  {:width "calc(100vw - 9.15em)" :margin-right (em 0.5)}]
          [:#postamble {:width "calc(100vw - 19.15em)" :margin-right (em 0.5)}]
          [:#table-of-contents {:height        (percent 100)
                                :width         (em 15)
                                :padding-right (em 0.5)
                                :padding-left  (em 0.5)
                                :margin-left   (em 0.5)
                                :position      'fixed
                                :z-index       1
                                :top           (em 10.5)
                                :left          0
                                :overflow-x    'hidden}]
          [:img {:max-width     (percent 90)
                 :margin-left   'auto
                 :margin-right  'auto
                 :margin-top    (em 0.5)
                 :margin-bottom (em 0.5)
                 :display       'block}]  
          [:body {:margin-left (em 17)
                  :text-align  'left
                  :max-width   "min(60em, 50%)"}]
          [:#site-logo {:position 'fixed
                        :width    (em 15)
                        :z-index  1
                        :padding  (em 0.5)
                        :top      0
                        :left     0}]
          [:.sidenote {:position     'absolute
                       :margin-left  "calc(50% + 2em)"
                       :margin-right (em 0.5)
                       :margin-top   (em -1.8)
                       :max-width    (em 30)}])

Narrow Screen

For narrow screens I inline everything and also do some trickery with the sidenotes by having them hidden but toggle-able with CSS buttons. This means that the page uses no JavaScript to display or hide them, keeping it NoScript friendly! 11 It's also kind of a fun Turing tarpit. Basically it's a phone-friendly UI that hopefully maintains most of the flare of the full layout.

(at-media {:screen true :max-width (em 60)}
          [:img {:max-width (percent 100)}]
          [:#site-logo {:max-width    "min(100%, 30em)"
                       :display      'block
                       :margin-left  'auto
                       :margin-right 'auto}]
          [:#table-of-contents {:position 'relative :top (em 0.5)}
           [:body {:margin-left  (em 1)
                   :margin-right (em 1)}]]

          [:sidenote-number {:text-decoration 'underline}]
          [(> :.sidenote-number :sup:hover) (> :.sidenote-number :sup:active)
           {:color            bg
            :background-color red
            :text-decoration  'none}]
          [(+ :input:checked :span) {:display 'none}])

Selected Text

This makes the text selection look good using the selection pseudo-element.

[(selection) {:background-color red
              :color            bg}]


Here I restyle the headlines using the style I currently use in Emacs. These code blocks automatically fetch them and return a string that can be inserted.

`[~@(map #(keyword (str "h" %)) (range 1 7))
  {:color       ~red
   :font-family ~title-font}]

Author and Title Information

The title, date, and author information in Emacs are usually the same color. So I set them here.

[:.title {:font-style       'italic
          :font-size        (em 2)
          :padding-top      (em 0.5)
          :padding-bottom   (em 0.5)
          :font-family      title-font
          :font-weight      'bold
          :color            bg
          :text-align       'center
          :background-color red}]
[:.subtitle {:font-style  'normal
             :font-size   (em 0.5)
             :line-height 1
             :padding     0}]

Code Blocks


This sets the background color and ensures that it is displayed with the standard monospace font.

[:code {:color            fg
        :background-color bg-alt
        :font-weight      'light
        :font-family      mono-font}]
[(pre :.src) {:background-color bg-alt
              :padding          (em 0.5)
              :overflow         'auto
              :font-family      mono-font
              :position         'relative}]

Hover Info

This adds the hover info to the SRC units

[(pre :.src ":before")
 {:display  'none
  :position 'absolute
  :top      (em 0.5)
  :right    (em 0.5)
  :padding  (em 0.5)}]
[(pre :.src ":hover" ":before")
 {:display          'inline
  :background-color bg}]

Here's a listing of the various languages supported by this. I may add more if I add more languages to the website.

(map (fn [e] [(keyword (str "pre.src-" (key e) ":before"))
              {:content (format "'%s'" (val e))}])
     {"clojure"       "Clojure"
      "clojurescript" "ClojureScript"
      "emacs-lisp"    "Emacs Lisp"
      "julia"         "Julia"
      "scheme"        "Scheme"
      "org"           "Org"
      "plantuml"      "Plantuml"})


his stylizes links to match the links in Emacs org-mode buffers.

[(a ":visited") (a ":link") {:color red}]
[(a ":hover") (a ":active")
 {:color            bg
  :background-color red
  :text-decoration  'none}]

Helper Code Blocks

These are little helper code blocks that fetch the face attributes I want automatically from emacs every time I regenerate the file. This ensures that my code remains in-sync with my Emacs configuration style.

This code block simply extracts the foreground color. Mostly used for headlines, but also for text in general.

(face-attribute (intern face) :foreground)

This finds the background color of a face. Mostly this just extracts colors for source code block backgrounds and the backgrounds for the main text documents.

(face-attribute (intern face) :background)

Last Modified: 2022-W11-4 02:10

Generated Using: Emacs 27.2 (Org mode 9.4.6)

Except where otherwise noted content on is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.