Max Weylandt.

← Back

How this website works

10 January, 2023

I really enjoy writing HTML by hand. I’ve been doing it for a while and I never tire of the process.1

For the last four years my website has been pretty basic, just a bio and contact links. I’m now getting to the point where I have things I want to share. Sometimes I want to share a useful piece of code, other times I find something in a survey that’s interesting but not quite enough for a paper. 2 So I need the option to post separate pages that sometimes contain code and/or images.

I knew I wanted a static site.3 There are powerful and popular static site generators like Hugo and Jekyll. By all accounts these work well with RMarkdown and academics like them. I played with one or the other for an afternoon - can’t remember which - and ran into some or other error. Plus, the HTML they generate often looks quite messy.

I’m also annoyed with the bloat on the modern web. This is not a novel complaint, but it’s still valid: many websites load an unholy amount of javascript and other files, leading to noticeable load times even as internet speed increases. And they track you to death, which I resent.

In short I wanted:

  1. tidy and easy-to read static HTML
  2. file sizes as small as possible.
  3. no trackers, unnecessary javascript, and any other bloat. (see 1.)
  4. a simple – almost brutalist – design

To avoid copy-pasting HTML files from page to page, I’ve now build something of a static site generator of my own using R and batch scripts. It’s extremely hacky and janky and almost certainly only works for my specific setup, but I think it will work well for me.

Essentially, this is how it works when I write a new blogpost:

  1. Write post in markdown. If It’s text-only, I write it directly in regular markdown, likely using Atom because I have super-fast autocomplete for citations setup there. If I’m incorporating data analysis and want to show outputs, I write in RMarkdown and render to .md. Either way, the YAML contains the title, author (always me!), date, and whether the blog post contains code/math.4

  2. I then double-click on a .bat file, which:

    1. runs another batchfile which converts all of the .md documents to html using pandoc, and using an html template I’ve created (I did say it’s janky!)
    2. runs an R script that converts pandoc code chunks to the standard format that prism.js can highlight.
    3. runs an R script that scans the blog folder, creates a table of posts, and inserts it into the index.html file.

The whole build process takes a few seconds at present.

Why don’t I just write the posts in Rmarkdown/quarto and render to HTML? Why go to the trouble of using pandoc directly from the command line? Well, the HTML files I get from rendering RMarkdown to HTML are full of Javascript and other code I don’t quite see the point of. I’m sure it has a function, but the results look the same to me so I’ll go with the simpler source. (also let’s be real, I got the idea of coding my own static site generator and it sounded interesting)

I might make the code public at some point, but I’m not in a rush – again, because it’s not good code and won’t be of use to others. I may however rewrite the whole thing in python to practice that language, and add a feature or two like dark mode/blue light filter/tags for blog posts.

For now, I’m happy with this hand-built house of cards.


  1. When I first learned html, the whole page’s layout relied on tables and iframes. I’ve since also coded websites using templates, or frameworks like bootstrap – but it’s just not as satisfying as starting with a blank document in the text editor and doing it all from scratch.↩︎

  2. books should be papers, papers should be blogs!↩︎

  3. I once had a wordpress blog where someone exploited a vulnerability to create additional users, and with them, a phishing page. I really didn’t enjoy that experience.↩︎

  4. I haven’t implemented this feature yet, but in the future I will only load the MathJax and prism libraries (for math and code highlighting, respectively) on pages where they are needed.↩︎


← Back ↑ Top