The Oil In The Machine
At least I’m not 30 yet
I can’t hide the guilt that I have for how many years it has taken me to have a usable blog for myself.
It is like the last leftover of my past wishes for myself. Two years ago, somewhere mid-Azar, I decised to stop procrastinating and begin prioritizing. Ali Bandari once said: there is no such thing as procrastinating, it is either a hand problem, a heart problem, or a head problem.
Note:
Ali Bandari probably learned this from
The neuroscientist Anne-Laure Le Cunff’s “Head, Heart, Hand Method” for overcoming procrastination. Who in turn must have gotten inspiration from
John Wooden’s coaching philosophy: “It’s either a problem with the hand, the heart, or the head.”
- The Hand: Refers to a physical or technical error, suggesting the player lacks the fundamental skills or physical execution. The remedy is usually more practice and repetition.
- The Head: Indicates a mental mistake, where the player may not understand the strategy, lacks focus, or is making poor decisions. This requires better teaching and mental preparation.
- The Heart: Points to an issue with effort, character, or motivation. This is often considered the most difficult problem to correct, as it involves the player’s inner drive and attitude.
Who might have gotten the idea from the
18th-century quote by Edward Gibbon: “A heart to resolve, a head to contrive and a hand to execute,”
Be that as it may, I had begun a long-term project to track down every task that is keeping my head busy and finish it. It took me one year to do that and I almost did.
That attempt mostly focused on responsibilities that I had, but after some time of having more time for me, older fantacies began to surface, from my network status indicator in awesomeWM to my lookup binding that also export to anki. From adding commands and shortcuts that I wanted to learn to awesome’s cheatsheet to tagging my music with beets and listening with mpd. And after all was done, thanks to Virgool’s identification of my last post (29-03-24-a-courtesy-of-etc-hosts) as advertisement and blocking me from posting it. I finally made myself do this.
Kudos to 1. Virgool for inducing a resolving rage in me. 2. Deepseek for assisting me to contrive this as my exocortex. 2. And meyk for being the HAND that will do all the hard work from now on.
Behold the mighty meyk
#!/bin/zsh
# Usage: new "post title"
# Configuration
BLOG_DIR="blog"
EDITOR="vim"
INDEX_FILE="$BLOG_DIR/index.html"
MARKER="<!-- INSERT NEW POSTS HERE -->"
TEMPLATE="$BLOG_DIR/template.html"
if [ -z "$1" ]; then
echo "Usage: new \"post title\""
exit 1
fi
TITLE="$1"
SLUG=$(echo "$TITLE" | tr '[:upper:]' '[:lower:]' | sed 's/ /-/g' | sed 's/[^a-z0-9-]//g')
# Relative date (duration since 1997-01-22), zero-padded
REL_DATE=$(datediff 1997-01-22 $(date +%Y-%m-%d) -f "%Y-%m-%d" | sed -E 's/\b([0-9])\b/0\1/g')
POST_DIR="$BLOG_DIR/$REL_DATE-$SLUG"
mkdir -p "$POST_DIR"
if [ -f "$POST_DIR/README.md" ]; then
echo "Warning: "$POST_DIR/README.md" already exists. Opening it." >&2
else
printf '%s\n\n%s\n\n##\n' "# $TITLE" "XP: $REL_DATE" > "$POST_DIR/README.md"
echo "Info: Wrote $POST_DIR/README.md"
fi
$EDITOR "$POST_DIR/README.md"
# ─── Post‑processing after editor closes ───────────────────────────────
if [ -f "$POST_DIR/README.md" ]; then
if [ ! -f "$POST_DIR/index.html" ]; then
# Check if lowdown is installed
if ! command -v lowdown &> /dev/null; then
echo "Error: lowdown is not installed. Please install it first." >&2
exit 1
fi
# Render Markdown to HTML using lowdown
article_content=$(lowdown "$POST_DIR/README.md")
if [ -z "$article_content" ]; then
echo "Error: lowdown produced no output from $POST_DIR/README.md" >&2
exit 1
fi
# Escape variables for sed's s|...|...| (delimiter-safe)
title_escaped=$(printf '%s' "$TITLE" | sed 's/[\\&|]/\\&/g')
date_escaped=$(printf '%s' "$REL_DATE" | sed 's/[\\&|]/\\&/g')
if [ -f "$TEMPLATE" ]; then
echo "Info: Using template: $TEMPLATE" >&2
# Write article content to a temp file so sed -r can read it safely
tmp_content=$(mktemp) || { echo "Error: Cannot create tempfile" >&2; exit 1; }
printf '%s' "$article_content" > "$tmp_content"
echo "Info: Wrote rendered HTML to tempfile $tmp_content"
sed -e "s|{{TITLE}}|$title_escaped|g" \
-e "s|{{DATE}}|$date_escaped|g" \
-e "/{{CONTENT}}/r $tmp_content" \
-e "/{{CONTENT}}/d" \
"$TEMPLATE" > "$POST_DIR/index.html"
firefox "$POST_DIR/index.html"
echo "Info: Created $POST_DIR/index.html and opened with firefox" >&2
rm -f "$tmp_content"
echo "Info: Deleted $tmp_content"
else
echo "Error: $TEMPLATE not found. Exiting" >&2
exit 1
fi
else
echo "Info: $POST_DIR/index.html already exists. Moving on..." >&2
fi
else
echo "Error: $POST_DIR/README.md not found. Exiting..." >&2
exit 1
fi
# ─── Add entry to the table in the main blog index ────────────────────
if [ -f "$INDEX_FILE" ]; then
if grep -qF "$REL_DATE-$SLUG" "$INDEX_FILE"; then
echo "Warning: Entry already exists in $INDEX_FILE. Skipping." >&2
else
if grep -qF "$MARKER" "$INDEX_FILE"; then
SORT_DATE=$(datediff 1997-01-22 $(date +%Y-%m-%d) -f "%S")
echo "Info: Calculated seconds for today's date to sort the table with"
WORD_COUNT=$(wc -w < "$POST_DIR/README.md" | tr -d ' ')
echo "Info: $POST_DIR/README.md has $WORD_COUNT words."
# Table raws to insert. Preserving the formatting.
entry=$'<tr>\n <td sortable-data="'"$SLUG"'"><span class="ellipsis"><a class="file" href="'"$REL_DATE"'-'"$SLUG"'/index.html">'"$SLUG"'</a></span></td>\n <td sortable-data="'"$WORD_COUNT"'">'"$WORD_COUNT"' W</td>\n <td sortable-data="'"$SORT_DATE"'">'"$REL_DATE"'</td>\n <td sortable-data="'"$SORT_DATE"'">'"$REL_DATE"'</td>\n </tr>'"$MARKER"
awk -v marker="$MARKER" -v entry="$entry" '{gsub(marker, entry)} 1' "$INDEX_FILE" > "$INDEX_FILE.tmp" && mv "$INDEX_FILE.tmp" "$INDEX_FILE" || {
echo "Error: Failed to insert the new entry in the table. Exiting..."
exit 1
}
echo "Info: Added new entry to $INDEX_FILE" >&2
else
echo "Error: Marker not found in $INDEX_FILE." >&2
echo "Info: Please manually add before </tbody>:" >&2
printf '%s\n%s\n' "$entry" "$MARKER" >&2
fi
fi
else
echo "Error: $INDEX_FILE does not exist. Exiting..." >&2
exit 1
fi
exit 0
Sample output
Christopher[14:45][main L|✚11…7]0xd.ir$ ./meyk the oil in the machine
Info: Wrote blog/29-03-26-the/README.md
Info: Using template: blog/template.html
Info: Wrote rendered HTML to tempfile /tmp/tmp.Ntrz1LgjWX
Info: Created blog/29-03-26-the/index.html and opened with firefox
Info: Deleted /tmp/tmp.Ntrz1LgjWX
Info: Calculated seconds for today's date to sort the table with
Info: blog/29-03-26-the/README.md has 917 words.
Info: Added new entry to blog/index.html
Christopher[15:16][main L|✚11…8]0xd.ir$ vim blog/index.html
Christopher[15:17][main L|✚11…8]0xd.ir$ mv blog/29-03-26-the blog/29-03-26-the-oil-in-the-machine
Christopher[15:17][main L|✚11…8]0xd.ir$ rm blog/29-03-26-the-oil-in-the-machine/index.html
Christopher[15:18][main L|✚11…8]0xd.ir$ ./meyk "The Oil In The Machine"
Warning: blog/29-03-26-the-oil-in-the-machine/README.md already exists. Opening it.
Info: Using template: blog/template.html
Info: Wrote rendered HTML to tempfile /tmp/tmp.zKzHGA4YP4
Info: Created blog/29-03-26-the-oil-in-the-machine/index.html and opened with firefox
Info: Deleted /tmp/tmp.zKzHGA4YP4
Warning: Entry already exists in blog/index.html. Skipping.
Christopher[15:19][main L|✚11…8]0xd.ir$ rm blog/29-03-26-the-oil-in-the-machine/index.html
Christopher[15:18][main L|✚11…8]0xd.ir$ ./meyk "The Oil In The Machine"
Christopher[15:22][main L|✚11…8]0xd.ir$ wc -w blog/29-03-26-the-oil-in-the-machine/README.md
1076 blog/29-03-26-the-oil-in-the-machine/README.md
Only Werner Heisenberg would know how hard it was to get the last line right…
Spoilers: Ran this twice😉.
:r! wc -w blog/29-03-26-the-oil-in-the-machine/README.md
Update: three weeks later
Christopher[13:21][main L|✚5…9]0xd.ir$ ./meyk
Render? [Y/n] Y
Info: Using template: blog/template.html
Rendered: blog/2026-05-18-the-oil-in-the-machine/index.html, Opening with firefox
Update index? [Y/n] Y
Index updated 2026-05-18-the-oil-in-the-machine (1127 W, mod=29-04-16)
Publish? [y/N] y
Dry run:
.d..t...... ./
<f..t...... index.html
.d..t...... 2026-05-18-the-oil-in-the-machine/
<f.st...... 2026-05-18-the-oil-in-the-machine/README.md
<f.st...... 2026-05-18-the-oil-in-the-machine/index.html
Synchronize server? [y/N] y
Done.