Created
March 12, 2026 20:24
-
-
Save darko-mesaros/f02667075735393f87c232016c491226 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # waddlesay - an ASCII duck that says things, wrapped in an HTML comment | |
| # Usage: waddlesay "Your message here" | |
| # echo "piped message" | ducksay | |
| # waddlesay -w 40 "message" (set max visual width) | |
| set -euo pipefail | |
| MAX_WIDTH=40 | |
| # ── Parse flags ───────────────────────────────────────────── | |
| while getopts "w:" opt; do | |
| case $opt in | |
| w) MAX_WIDTH="$OPTARG" ;; | |
| *) echo "Usage: ducksay [-w width] <message>" >&2; exit 1 ;; | |
| esac | |
| done | |
| shift $((OPTIND - 1)) | |
| # ── Read input ────────────────────────────────────────────── | |
| if [[ $# -gt 0 ]]; then | |
| msg="$*" | |
| else | |
| msg="$(cat)" | |
| fi | |
| msg="$(echo "$msg" | xargs)" | |
| if [[ -z "$msg" ]]; then | |
| echo "Usage: ducksay [-w width] <message>" >&2 | |
| exit 1 | |
| fi | |
| # ── Word wrap (max 2 lines) ──────────────────────────────── | |
| wrap() { | |
| local width=$1 | |
| lines=() | |
| if (( ${#msg} <= width )); then | |
| lines+=("$msg") | |
| return | |
| fi | |
| # Find last space within width | |
| local chunk="${msg:0:$width}" | |
| local cut=-1 | |
| for (( i=${#chunk}-1; i>=0; i-- )); do | |
| if [[ "${chunk:$i:1}" == " " ]]; then | |
| cut=$i | |
| break | |
| fi | |
| done | |
| if (( cut == -1 )); then | |
| lines+=("${msg:0:$width}") | |
| lines+=("${msg:$width}") | |
| else | |
| lines+=("${msg:0:$cut}") | |
| lines+=("${msg:$((cut + 1))}") | |
| fi | |
| } | |
| # ── Build the duck ────────────────────────────────────────── | |
| build() { | |
| local n=${#lines[@]} | |
| if (( n == 1 )); then | |
| echo '<!-- _' | |
| echo " .__( .)< (${lines[0]})" | |
| echo ' \___)' | |
| echo '~~~~~~~~~~~~~~~~~-->' | |
| else | |
| local max_len=${#lines[0]} | |
| (( ${#lines[1]} > max_len )) && max_len=${#lines[1]} | |
| local p1 p2 | |
| printf -v p1 "%-${max_len}s" "${lines[0]}" | |
| printf -v p2 "%-${max_len}s" "${lines[1]}" | |
| echo '<!-- _' | |
| echo " .__( .)< (${p1})" | |
| echo " \\___) . (${p2})" | |
| echo '~~~~~~~~~~~~~~~~~-->' | |
| fi | |
| } | |
| # ── Main ──────────────────────────────────────────────────── | |
| wrap "$MAX_WIDTH" | |
| if (( ${#lines[@]} > 2 )); then | |
| echo "Error: message too long to fit in 2 lines at width ${MAX_WIDTH}" >&2 | |
| echo "Tip: use -w with a larger width" >&2 | |
| exit 1 | |
| fi | |
| build |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment