#!/usr/bin/env bash # nanowrimo -- daily word count progress tracker toward a goal set -euo pipefail usage() { echo "Usage: nanowrimo [--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