#!/usr/bin/env bash
# nanowrimo -- daily word count progress tracker toward a goal
set -euo pipefail
usage() {
echo "Usage: nanowrimo <dir-or-file> [--goal N] [--days N] [--start YYYY-MM-DD]"
echo ""
echo "Defaults: 50000 words, 30 days, start=today"
exit 1
}
[ $# -lt 1 ] && usage
target="$1"; shift
goal=50000 total_days=30 start_date=""
while [ $# -gt 0 ]; do
case "$1" in
--goal) goal="$2"; shift 2 ;;
--days) total_days="$2"; shift 2 ;;
--start) start_date="$2"; shift 2 ;;
*) echo "Unknown option: $1"; usage ;;
esac
done
[ -z "$start_date" ] && start_date=$(date +%Y-%m-%d)
# Count current words
if [ -f "$target" ]; then
current=$(wc -w < "$target")
else
current=$(find "$target" -name '*.md' -o -name '*.mdx' -o -name '*.txt' 2>/dev/null | xargs cat 2>/dev/null | wc -w)
fi
# Calculate days elapsed
today=$(date +%s)
start=$(date -d "$start_date" +%s 2>/dev/null || date -jf "%Y-%m-%d" "$start_date" +%s 2>/dev/null)
elapsed=$(( (today - start) / 86400 ))
[ "$elapsed" -lt 0 ] && elapsed=0
remaining_days=$((total_days - elapsed))
[ "$remaining_days" -lt 1 ] && remaining_days=1
remaining_words=$((goal - current))
[ "$remaining_words" -lt 0 ] && remaining_words=0
daily_needed=$((remaining_words / remaining_days))
pct=$((current * 100 / goal))
# Progress bar
bar_width=40
filled=$((pct * bar_width / 100))
[ "$filled" -gt "$bar_width" ] && filled=$bar_width
empty=$((bar_width - filled))
bar=$(printf '%0.s#' $(seq 1 $filled 2>/dev/null) 2>/dev/null || true)
gap=$(printf '%0.s-' $(seq 1 $empty 2>/dev/null) 2>/dev/null || true)
echo "Goal: $goal words in $total_days days (started $start_date)"
echo ""
echo "Progress: [$bar$gap] $pct%"
echo ""
echo "Current: $current words"
echo "Remaining: $remaining_words words"
echo "Days elapsed: $elapsed / $total_days"
echo "Days left: $remaining_days"
echo "Daily needed: $daily_needed words/day"
if [ "$elapsed" -gt 0 ]; then
daily_avg=$((current / elapsed))
echo "Daily average: $daily_avg words/day"
if [ "$daily_avg" -ge "$daily_needed" ]; then
echo "Status: ON TRACK"
else
echo "Status: BEHIND (need $(( daily_needed - daily_avg )) more/day)"
fi
fi