- Date
- 2026-04-28
- Category
- Programming
In the latest blog post about SlenderSite, my work-in-progress static site generator, I wrote:
For one thing: you don't need half the Python ecosystem to run a text file through the markdown utility and stick the output into a template. That can be done with a few lines of shell script and Awk.
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.