Sometimes I think I have more fun scripting for my blog than I do actually blogging. But that’s okay. As long as I’m being creative and getting my brain working, it all works out. Or at least, that’s what I tell myself.

A few days ago, I wrote about how I had rewritten the script to incorporate rofi selection. The idea was a giant case statement that would essentially allow me to run several scripts depending on the choice I made with rofi.

Well, as I said in that post, I had more ideas. Now, it works with both of my Hugo blogs, which is great. But it also allows me to browse through my drafts folders for both blogs and then select a draft for editing.


#!/usr/bin/env bash

# The purpose of this script is to create a blog post template, save it where it needs to go,
# and enter Emacs with the cursor in the correct place—or to update Hugo.

# Edited now to allow draft selection and editing. Now works with both blogs


# Written by Matthew Weber
# Created on 6/25/2025
# Updated on 8/12/2025
# Version 1.3

set -euo pipefail

# MTWB Directory Variables
CURRENT_YEAR=$(date +%Y)
CURRENT_DATETIME=$(date +'%Y-%m-%dT%H:%M:%S%:z')
BASE_DIR="$HOME/mhome/Documents/Pages/hugo/mtwb/content/posts"
YEAR_DIR="$BASE_DIR/$CURRENT_YEAR"
DRAFTS_DIR="$YEAR_DIR/drafts"

# TLC Directory Variables
CURRENT_YEAR=$(date +%Y)
CURRENT_DATETIME=$(date +'%Y-%m-%dT%H:%M:%S%:z')
TLC_BASE_DIR="$HOME/mhome/Documents/Pages/hugo/TLC/content/posts"
TLC_YEAR_DIR="$TLC_BASE_DIR/$CURRENT_YEAR"
TLC_DRAFTS_DIR="$TLC_YEAR_DIR/drafts"


# Check to see if Drafts exists
if [ -e $DRAFTS_DIR ]; then
    break
else
    notify-send "ERROR: No Drafts Directory" && exit 1
fi

# Rofi menu options
options=(
  "New MTWB Post"
  "New TLC Post"
  "Edit a MTWB Draft"
  "Edit a TLC Draft"
  "Update MTWB"
  "Update TLC"
)

choice=$(printf '%s\n' "${options[@]}" \
  | rofi -dmenu -i -p 'What Do You Want to Do?')

case "$choice" in
  "New MTWB Post")
    # Prompt for a title
    RAW_TITLE=$(rofi -dmenu -p 'Enter a title: ')

    # Make that title into Title Case worthy slug
    SLUG=$(echo "$RAW_TITLE" \
      | tr '[:upper:]' '[:lower:]' \
      | sed -E 's/[^a-z0-9 ]//g' \
      | sed 's/[[:space:]]\+/-/g')

    # Convert slug back into a pretty Title Case string
    TITLE=$(echo "$SLUG" \
      | sed 's/-/ /g' \
      | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2));}1')

    FILENAME="$SLUG.md"
    FULL_PATH="$DRAFTS_DIR/$FILENAME"

    # Write front matter
    cat > "$FULL_PATH" <<EOF
+++
title       = "$TITLE"
date        = "$CURRENT_DATETIME"
description = ""
draft       = true
tags        = [""]
rssFullText = true

[params]
  author = "Matt"
+++
EOF

    echo "✅ Created draft: $FULL_PATH"

    emacs "$FULL_PATH"
    ;;

  "New TLC Post")
    # Prompt for a title
    RAW_TITLE=$(rofi -dmenu -p 'Enter a title: ')

    # Make that title into Title Case worthy slug
    SLUG=$(echo "$RAW_TITLE" \
      | tr '[:upper:]' '[:lower:]' \
      | sed -E 's/[^a-z0-9 ]//g' \
      | sed 's/[[:space:]]\+/-/g')

    # Convert slug back into a pretty Title Case string
    TITLE=$(echo "$SLUG" \
      | sed 's/-/ /g' \
      | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2));}1')

    FILENAME="$SLUG.md"
    FULL_PATH="$TLC_DRAFTS_DIR/$FILENAME"

    # Write front matter
    cat > "$FULL_PATH" <<EOF
+++
title       = "$TITLE"
date        = "$CURRENT_DATETIME"
description = ""
draft       = true
tags        = [""]
rssFullText = true

[params]
  author = "Matt"
+++
EOF

    echo "✅ Created draft: $FULL_PATH"

    emacs "$FULL_PATH"
    ;;

"Update MTWB")
    echo "🔄 Running mtblog to update Hugo…"
    mtblog
    notify-send "Updating Hugo"
    ;;

"Update TLC")
    echo "🔄 Running updatetlc to update Hugo…"
    updatetlc
    notify-send "Updating Hugo"
    ;;

"Edit a MTWB Draft")

    shopt -s nullglob
    mtwbdrafts=( "$DRAFTS_DIR"/* )  
    mtwbchoice="$(printf '%s\n' "${mtwbdrafts[@]##*/}" | rofi -dmenu -i -p 'Choose draft')"
    [[ -z $mtwbchoice ]] && exit 0
    emacs "$DRAFTS_DIR/$mtwbchoice"
    ;;

"Edit a TLC Draft")

    shopt -s nullglob
    tlcdrafts=( "$TLC_DRAFTS_DIR"/* )
    tlcchoice="$(printf '%s\n' "${tlcdrafts[@]##*/}" | rofi -dmenu -i -p 'Choose draft')"
    [[ -z $tlcchoice ]] && exit 0
    emacs "$TLC_DRAFTS_DIR/$tlcchoice"
    ;;

  *)
    echo "⏹ Program Terminated."
    exit 1
    ;;
esac

It’s still not done, though. For one thing, I’ve realized that the if statement at the beginning is completely borked. break only works in for and while loops, not in if statements. Why I thought otherwise, I don’t know. I’ll fix that later.

I’m also going to have to clean it up now that it does mostly what I want it to do. I’m sure there are ways to make this more efficient. I have a ton of variables here that probably can be consolidated. I’m also sure that some of the construction of the dates is over developed.

I should also go through and normalize the variable names. Some are ALL CAPITALIZED and some are all lowercase. I used the former when I first started, then got lazy. I’m also not sure if I have to have both shopt lines or if the first one is enough. I’ll have to try with just one and see if it works. Theoretically, one should be enough, but we’ll see. I’m sure there will be more things I want to do, of course. I still want to do one of these for notes. I have so many ideas flowing through me right now. I haven’t felt like scripting this much in ages. I’m sure as those ideas come to fruition, I’ll blog about them.


This is day 12 of Blaugust 2025.