Date
2026-04-28
Category
Programming

In the latest blog post about SlenderSite, my work-in-progress static site generator, I wrote:

It's not entirely hyperbole: there are multiple SSGs written in shell script. They're surprisingly capable tools, but they can get hairy. I wanted to put my money where my mouth is and see if it's really doable in just a few lines. Turns out, the answer is yes. A useful tool can take 24 lines of code; one less than my PHP prototype from two weeks ago:

#!/bin/sh

FOLDER=_site
FILE_EXT=.md
PARSER=markdown

TEMPLATE='
<!DOCTYPE html>
<meta charset="utf-8">
<title>{title}</title>

{content}
'

SUBST1='/{title}/ { gsub("{title}", title) } { print }'
SUBST2='/{content}/ { gsub("{content}", content) } { print }'

for i in "$FOLDER"/*"$FILE_EXT"; do
    TITLE=$(basename "$i" "$FILE_EXT")
    CONTENT=$($PARSER "$i")
    OUTPUT=$(echo "$TEMPLATE" | awk -v title="$TITLE" "$SUBST1")
    OUTPUT=$(echo "$OUTPUT" | awk -v content="$CONTENT" "$SUBST2")
    echo "$OUTPUT" > "$TITLE.html"
done

Naturally, at this size it's very incomplete and not exactly flexible (though very easy to customize). Works as advertised anyway, and can be extended into a proper command-line program easily enough. It won't ever rival Big Serious Apps, but the whole point is, maybe they don't need to be so big and serious.

The script is written in portable shell script. It works in dash but also Bash, Zsh and ksh93.

P.S. Turns out, the method used above to perform text replacement in Awk has a fatal flaw; trying to fix that led to a more elegant solution. Conversely, passing all that data around on the command line is less of a problem than it may seem at first sight: the limit appears to be around 100-200K on the machines I have easy access to.


Errata: the first published version got the quoting wrong in the for loop and only happened to work for me on early test data.


Blog | Tips for outlining >