Skip to content

Instantly share code, notes, and snippets.

@janhicken
Created October 29, 2024 07:57
Show Gist options
  • Save janhicken/5f7a197501d4af551761ec29da0736a4 to your computer and use it in GitHub Desktop.
Save janhicken/5f7a197501d4af551761ec29da0736a4 to your computer and use it in GitHub Desktop.
Print a nice ASCII-style section header / separator
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
print_usage() {
printf 'Usage: %s [-p PREFIX] [-w WIDTH] [WORDS...]\n' "$(basename "$0")" >&2
}
width=80
prefix=''
# .- causes opt to be set to ':' in case an opt arg is missing
# / .- help (no arg)
# |/ .- width w/ arg
# ||/| .- prefix w/ arg
# ||||/
while getopts ':hw:p:' opt; do
case "$opt" in
h)
print_usage
exit
;;
p)
prefix="$OPTARG"
;;
w)
if [[ "$OPTARG" =~ ^[[:digit:]]+$ ]]; then
width="$OPTARG"
else
printf 'Width must be a natural number.\n' >&2
exit 1
fi
;;
:)
printf 'Option -%s requires an argument.\n' "$OPTARG" >&2
print_usage
exit 1
;;
\?)
printf 'Invalid option: -%s\n' "$OPTARG" >&2
print_usage
exit 1
esac
done
shift $((OPTIND - 1))
heading="$*"
len="${#heading}"
prefix_len="${#prefix}"
horiz=$((width - prefix_len - 2))
if (( prefix_len > width )); then
printf 'Error: Prefix is too long.\n' >&2
exit 1
elif (( len > horiz )); then
printf 'Error: Text is too long.\n' >&2
exit 1
fi
# Upper line
printf '%s╔' "$prefix"
printf '═%.0s' $(seq $horiz)
printf '╗\n'
# Mid line
right=$(((horiz - len + 1) / 2))
left=$(((horiz - len) / 2 + len))
printf "%s║%0${left}s%0${right}s║\n" "$prefix" "${heading}" ''
# Lower line
printf '%s╚' "$prefix"
printf '═%.0s' $(seq $horiz)
printf '╝\n'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment