A Makefile is Fine, Too

12/28/2019

I'm not sure where I first saw a link to "Your blog probably doesn't need a static site generator" by Zain Amro. Maybe it was on Mastodon. Maybe it was on that orange-tinted forum where Silicon Valley techies hang out and brag about their prowess. It doesn't really matter.

What matters is that they're right. If you want to write on the internet, tinkering with content management systems like WordPress or static site generators like Jekyll are just going to slow you down. Moreover, I find their process quite refreshing.

Today, my process is enjoyably unsophisticated. When I want to post something, I first write it in a text file, copy my last blog post’s HTML file, paste in my new article, make some slight adjustments, update my list of posts, add it to my RSS file, and that’s basically it.

However, I don't follow it myself. Simply copying over an existing file and wiping out the contents before starting something new isn't my style. Furthermore, I don't like having my files cluttered with a lot of boilerplate like the <head> element, and I absolutely loathe the necessity of repeating myself. It starts with typing the title twice, once in <head> and once in your page's heading for the user to see, but it can get worse from there. What if you want to provide navigation links on every page, but decide to change your navigation menu later on?

If you try to do all of this by hand, you're gonna have a bad time. This is one of the reasons we started using content management systems and blogging software in the first place.

Zain Amro solves this potential problem by dispensing with such niceties. Their website is unabashedly brutalist, and he makes no concessions to the expectations of nontechnical readers who happen upon his site by mistake. If they can't use their browser's back button to get around, that's evidently their problem.

I won't deny that I'm tempted, but I think there's a better way. Unix systems have had the M4 macro processor since 1977. It still survives as a tool for generating Sendmail configurations and a dependency for GNU Autoconf, but there is no reason why it can't be put to other uses. Most of the BSDs come with their own implementation, and if you don't already have it on your GNU/Linux installation, chances are you need only install the m4 package using your distribution's package mangler.

If you're wondering if it's hard to use M4: it isn't. If you've any experience as a programmer of any kind, I think you'll have little trouble picking up M4. It's not like the M4 manual page is especially long or hard to read.

The hard part is processing all of your pages so that the M4 macros get expanded and you actually end up with something you can push to a server. This is a process best automated. You could use a shell script, or a fancy build tool, but I prefer to stick to reliable classics like make. Here's the (BSD) makefile I use to build my website.

.SUFFIXES: .m4 .m4html .html .xml

.m4html.html:
        @m4 -P -E -I ./inc "$<" | tidy -iuq -utf8 -w > "$@"

.m4.xml:
        @m4 -P -E -I ./inc "$<" | grep "^[:blank:]" > "$@"

SITE!=find src/ -name "*.m4html"
FEEDS!=find feeds/ -name "*.m4"
SITEMAPS!=find sitemaps/ -name "*.m4"

HTML=${SITE:.m4html=.html}
FEED=${FEEDS:.m4=.xml}
SITEMAP=${SITEMAPS:.m4=.xml}

SSH_OPTS=-o StrictHostKeyChecking=no
REMOTE_HOST=""
REMOTE_PATH=""

all: $(HTML) $(FEED) $(SITEMAP)
        @mkdir dest
        @cp -aR src/* dest/
        @cp -a src/.htaccess dest/
        @cp -a feeds/feed.xml dest/
        @cp -a sitemaps/sitemap.xml dest/
        @find dest/ -name '*.m4html' -print0 | xargs -0 -P 4 rm

deploy:
        @openrsync --rsh="ssh ${SSH_OPTS}" --del -Dgloprv dest/ ${REMOTE_HOST}:${REMOTE_PATH}

clean:
        @rm $(HTML)
        @rm $(FEED)
        @rm $(SITEMAP)
        @rm -rf dest

Is this complicated? Perhaps a little. However, using make gives me some advantages that I might not get from other tools or a custom shell script:

Of course, there are downsides to using make as well:

If you can get past the pitfalls, I think that using classic tools like M4 and make can allow you to continue to automate some the less pleasant aspects of maintaining a website with a blog while retaining the sense of freedom one can find while writing raw HTML. It's how I've built this website. If you're interested in doing the same, I have a Git repository that you're welcome to clone and use as a starting point for your next project.

If you're interested in a bit of extra reading, the Wayback Machine has a couple of old Linux Journal articles that deal with M4 as a tool for building and maintaining websites.

Feel free to let me know if you find this helpful. Better still, let me know if you end up using this for a project of your own.