I wrote a script to automate blog-posting, both for use directly on devuan, and remotely (such as work).

The script is designed to do the boiler-plate stuff and make jotting down a few notes quick and easy.

#!/bin/bash

BLOGUSER=dominic
BLOGHOST=devuan
if [ -z "$BLOGDIR" ]
then
  BLOGDIR="${HOME}/blog"
fi

_comp_blog()
{
  # provides filename completion for blog command
  k=${#COMREPLY[@]}
  for j in $( compgen -f "${BLOGDIR}/_posts/*${2}*" )
  do
    # drop dir 
    file=${j##*/}
    # drop extension
    file=${file%%.*}
    # get length of date-time bit
    n=`expr ${file} '[-0-9]*'`
    file=${file:$n}
    COMPREPLY[k++]=${file}
  done
}

usage()
{
  echo "Usage: $0 [-p] [-c category] [-i image] [-v video] [-d desc] <title>"
  echo
  echo "The title will be used as-is for in the blog post filename."
  echo "The title will be used with the first letter capitalised, and"
  echo "and underscores substituted for spaces, as the title."
  echo
  echo "An image will be used, and will be processed into a srcset of"
  echo "different resolutions so browsers can choose a suitable size."
  echo
  echo "A video will be used, and will be processed into both webm and"
  echo "mp4 types in different resolutions to offer the user a choice"
  echo "depending on their browser support, bandwidth and screen size."

  exit 1
}

start_dir=$PWD

while getopts "c:i:v:d:p" o
do
  case "${o}" in
    c)
      category=${OPTARG}
      ;;
    i)
      echo "Processing web-optimized images"
      img_dir=${OPTARG%/*}
      if [ "${img_dir:0:1}" != "/" ]
      then
        img_dir="${PWD}/${img_dir}"
      fi
      file=${OPTARG##*/}
      (
        cd ~/fresh/assets/img
        mk_srcset "$img_dir/${file}"
      )
      image=${file%%.*}
      ;;
    v)
      echo "Processing web-optimized video"
      mov_dir=${OPTARG%/*}
      if [ "${mov_dir:0:1}" != "/" ]
      then
        mov_dir="${PWD}/${mov_dir}"
      fi
      file=${OPTARG##*/}
      (
        cd ~/fresh/assets/video
        mk_video -y -2 -r 720,480 -f webm,mp4 "${mov_dir}/${file}"
      )
      video=${file%%.*}
      ;;
    d)
      desc=${OPTARG}
      ;;
    p)
      post=1
      ;;
    *)
      usage
      ;;
  esac
done
shift $((OPTIND-1))

if [ $# -lt 1 ]
then
  usage
fi

dir="${BLOGDIR}/_posts"
title="${1}"
if [ -e "${dir}/"*"${title}.md" ]
then
  files=("${dir}/"*"${title}.md")
  file="${files[-1]}"
else
  date=$(date '+%F-%I:%M')
  file="${dir}/${date}-${title}.md"
fi

# substitute ' ' for _ in title.
title=${title//_/ }

if [ ! -e "${file}" ]
then
  cat <<HERE > "${file}"
---
layout: post
title: ${title^}
author: ${USER}
description: ${desc}
category: ${category}
img: ${image}
video: ${video}
---
HERE
fi

# launch your preferred editor on the blog-post
"${VISUAL:-"${EDITOR:-vi}"}" "${file}"

if [ -n "${post}" ]
then
  if [ $(hostname) == "${BLOGHOST}" ]
  then
    cd ~/fresh
    bundle exec jekyll build
    cp -R _site/* /var/www/html
  else
    scp -P 1122 "${file}" dominic@mail.lbs.ca:${BLOGDIR}/_posts/
    echo "You will need to run bundle and cp site on host"
  fi
fi
---
HERE
fi

vi "${file}"

if [ -n "${post}" ]
then
  if [ $(hostname) == 'devuan' ]
  then
    cd ~/fresh
    bundle exec jekyll build
    cp -R _site/* /var/www/html
  else
    scp -P 1122 "${file}" dominic@mail.lbs.ca:fresh/_posts/
    echo "You will need to run bundle and cp site on host"
  fi
fi

I just made some changes to capture posts made earlier properly.

Then I pondered: it would be nice if I didn’t have to remember past blog-posts exactly. If bash-completion worked on my blog posts. So I did some research on bash_completion. I figured out that I could add my own bash_completion extension for my own application (or any other).

So I wrote another script! One to implement bash_completion for my blog script.

# provides filename completion for blog command
# requires BLOGDIR to be set to repo of your blog
# then call 
#
# . ./comp_blog
# complete -F _compl_blog blog
#
_comp_blog()
{
  k=${#COMREPLY[@]}
  for j in $( compgen -f ${BLOGDIR}/_posts/*${2}* )
  do
    # drop dir 
    file=${j##*/}
    # drop extension
    file=${file%%.*}
    # get length of date-time bit
    n=`expr ${file} : '[-:0-9]*'`
    file=${file:$n}
    COMPREPLY[k++]=${file}
  done
  return 0
}

complete -F _comp_blog blog

I put an instruction to source this script in my .profile, and it works! In fact, I used it to call up this blog post and add what you are reading now.