Skip to content

Instantly share code, notes, and snippets.

@kaushalmodi
Created July 6, 2017 18:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kaushalmodi/af385e18b50cf665cd93d4b7f167302d to your computer and use it in GitHub Desktop.
Save kaushalmodi/af385e18b50cf665cd93d4b7f167302d to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# Time-stamp: <2017-04-21 17:44:04 kmodi>
# https://discuss.gohugo.io/t/auto-generate-file-name-based-on-title/4648/2?u=kaushalmodi
# This script uses the unofficial strict mode as explained in
# http://redsymbol.net/articles/unofficial-bash-strict-mode
#
# Also checks have been done with www.shellcheck.net to have a level of
# confidence that this script will be free of loopholes.. or is it? :)
set -euo pipefail # http://redsymbol.net/articles/unofficial-bash-strict-mode
IFS=$'\n\t'
h="
┌─────────────────────────────────────────────────────────────────────────────────┐
│ │
│ Script : hugo_new_post.sh │
│ Description : Script to generate a hugo post file using the title specified │
│ at the command line. │
│ Usage Example : hugo_new_post.sh -b \"/home/$USER/hugo/myblog\" -t \"My New Post\" │
│ │
│ │
│ OPTIONS │
│ │
│ -b|--blogpath <path> : Root of hugo blog. (Mandatory argument) │
│ --blogpath \"/home/\$USER/hugo/myblog\" │
│ │
│ -t|--title <string> : Title string of the post. (Mandatory argument) │
| Use double quotes if the title contains spaces. │
│ --title \"My New Post\" │
│ │
│ -s|--section <dir> : Sub-directory in the 'content/' dir where the post │
│ should be created. (Default: posts) │
│ --section \"blog\" │
│ │
│ │
│ -h|--help : Show this help │
│ -d|--debug : Debug mode │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘"
blog_path=""
section="posts"
title=""
extra_args=""
here=$(pwd)
fext=".md" # default file extension is .md
debug=0
help=0
while [ $# -gt 0 ]
do
case "$1" in
"-b"|"--blogpath" ) shift
blog_path="$1";;
"-t"|"--title" ) shift
title="$1";;
"-s"|"--section" ) shift
section="$1";;
"-o"|"--org" ) fext=".org";;
"-m"|"--md" ) fext=".md";;
"-d"|"--debug" ) debug=1;;
"-h"|"--help" ) help=1;;
* ) extra_args="${extra_args} $1";;
esac
shift # expose next argument
done
if [[ ${debug} -eq 1 ]]
then
echo "blog path = ${blog_path}"
echo "title = ${title}"
echo "sub dir = ${section}"
echo "extra args = ${extra_args}"
fi
main () {
# Remove leading and trailing whitespace from ${title}
title=$(echo "${title}" | sed -r -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
# Using ${title}
# - Replace '&' with "and", and '.' with "dot".
# - Then lower-case the whole title.
# - Then replace all characters except a-z, 0-9 and '-' with spaces.
# - Then remove leading/trailing spaces if any.
# - Then replace one or more spaces with a single hyphen.
# For example, converts "This, That \& Other!" to "this-that-and-other.md"
# (Note that we need to escape & with \ above, in the shell.)
fname=$(echo "${title}" \
| sed -r -e 's/&/ and /g' \
-e 's/\./ dot /g' \
-e 's/./\L\0/g' \
-e 's/[^a-z0-9-]/ /g' \
-e 's/^[[:space:]]*//g' \
-e 's/[[:space:]]*$//g' \
-e 's/[[:space:]]+/-/g');
fpath="${blog_path}/content/${section}/${fname}${fext}"
if [[ ${debug} -eq 1 ]]
then
echo "fname = ${fname}"
echo "fpath = ${fpath}"
fi
# Create the new post
# Need to first cd to the hugo blog root dir
cd "${blog_path}" || exit
hugo new "${section}/${fname}${fext}" "${extra_args}"
# Replace the title in TOML front matter with ${title}, and add slug
tmp_file="/tmp/${USER}_hugo_post"
cp -f "${fpath}" "${tmp_file}"
sed -r -e 's/^(\s*title = ).*/\1"'"${title}"'"/' \
-e 's/^(\s*title = .*)/\1\nslug = "'"${fname}"'"/' \
"${tmp_file}" > "${fpath}"
rm -f "${tmp_file}"
# Insert summary divider at the end of the file
echo -e '\n<!--more-->' >> "${fpath}"
# Convert front-matter from TOML to org-mode style for .org content
if [[ ${fext} == ".org" ]]
then
cp -f "${fpath}" "${tmp_file}"
# - Delete the TOML +++ markers
# - Change 'title = "foo"' to '#+TITLE: foo', and similar for other
# front-matter variables.
# - Delete '[""]' from lines (like empty categories in TOML representation)
# - Replace '<!--more-->' to '# more'
sed -r -e "/^\+\+\+/d" \
-e "s/^([a-z]+) =/#+\U\1\E:/" \
-e "s/: \"(.*)\"/: \1/" \
-e "s/\[\"\"\]//" \
-e "s/^<!--(more)-->/# \1/" \
"${tmp_file}" > "${fpath}"
rm -f "${tmp_file}"
fi
# Go back to the directory from where you launched this script
cd "${here}" || exit
# Open the file in EDITOR with cursor placed above the summary divider line
# containing "<!--more-->" (for .md) or "# more" (for .org)
line_num=$(wc -l "${fpath}" | awk '{ print $1 }') # last line -- contains 'more' divider
line_num=$((line_num-2)) # get 2 lines above 'more'
open_file_cmd="${EDITOR} +${line_num} ${fpath} &"
if [[ ${debug} -eq 1 ]]
then
echo "last line = ${line_num}"
echo "open file cmd = ${open_file_cmd}"
fi
eval "${open_file_cmd}"
}
help () {
echo "${h}"
}
if [[ ${help} -eq 1 ]]
then
help
exit 0
elif [[ -z ${blog_path} || -z ${title} ]]
then
echo "Error: Both '-b' and '-t' are mandatory arguments"
help
exit 1
else
main
exit 0
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment