# blog -- blogging aliases and functions # ============================================================================ # BIN WRAPPERS # ============================================================================ alias bnew='blog-new' alias bstats='blog-stats' alias blinks='blog-links' alias blinkrot='blog-linkrot' alias bback='blog-backlinks' alias bfront='blog-frontmatter' alias bbuild='blog-build-check' alias brss='blog-rss-check' alias bfdates='blog-future-dates' alias bshot='blog-screenshot' alias btitle='blog-title' alias barch='blog-archive-url' alias bai='blog-ai-review' alias bdrafts='blog-draft-index' # ============================================================================ # CONTENT SEARCH # ============================================================================ alias bposts='find . \( -path "*/.git" -o -path "*/node_modules" -o -path "*/.next" -o -path "*/_site" -o -path "*/public" \) -prune -o \( -name "*.md" -o -name "*.mdx" -o -name "*.org" \) -print' alias btodos='rg -n --glob "*.md" --glob "*.mdx" --glob "*.org" "TK|TODO|FIXME|XXX|REVIEW|SOURCE\\?"' alias btypos='rg -n --glob "*.md" --glob "*.mdx" "\\b(teh|recieve|seperate|occured|wich|whcih|buitl|direcotry)\\b"' alias bdates='rg -n --glob "*.md" --glob "*.mdx" "^(date|created|updated|modified|start_date):"' alias btitles='rg -n --glob "*.md" --glob "*.mdx" "^(title:|# )"' alias btags='rg -n --glob "*.md" --glob "*.mdx" "^(tags|topics|category|categories):"' alias boutlinks='blog-links | sort -u' alias boutdomains='blog-links | awk -F/ "/^https?:/{print \$3}" | sort | uniq -c | sort -nr' # ============================================================================ # GIT INTEGRATION # ============================================================================ alias bchanged='git diff --name-only -- "*.md" "*.mdx" "*.org"' alias bstaged='git diff --cached --name-only -- "*.md" "*.mdx" "*.org"' alias bworddiff='git diff --word-diff=color -- "*.md" "*.mdx" "*.org"' # ============================================================================ # UTILITIES # ============================================================================ alias bserve='python3 -m http.server 8000' alias bfeed='find . -name "*.xml" -o -name "*.atom" -o -name "feed*" | sort' alias bimages='find . \( -name "*.png" -o -name "*.jpg" -o -name "*.jpeg" -o -name "*.webp" -o -name "*.gif" -o -name "*.svg" \) -print' alias bbig='find . -type f -size +5M -not -path "*/.git/*" -print' alias bempty='find . -type f \( -name "*.md" -o -name "*.mdx" -o -name "*.org" \) -size 0 -print' alias bdups='find . -type f \( -name "*.md" -o -name "*.mdx" \) -print0 | xargs -0 awk "{print FILENAME \":\" FNR \":\" \$0}" | rg -n "\\b([[:alpha:]]+)\\s+\\1\\b"' alias bsentences='perl -0777 -ne "while(/[A-Z][^.!?]{180,}[.!?]/g){print \"$ARGV:$.: $&\\n\"}"' # ============================================================================ # PANDOC # ============================================================================ alias bmd2html='pandoc --from=gfm --to=html5 --standalone' alias bmd2docx='pandoc --from=gfm --to=docx' alias bmd2epub='pandoc --from=gfm --to=epub3' # ============================================================================ # URL EXTRACTION # ============================================================================ alias bhtmltitles='rg -n "|<h1"' alias burls='rg -o "https?://[^\\]\\[()<>\"'"'"'[:space:]]+"' alias burls-md='rg -o "\\[[^]]+\\]\\(https?://[^)]+\\)"' # ============================================================================ # ARCHIVING # ============================================================================ alias barchivequeue='blog-links | sort -u > archive-queue.txt' alias barchivefeed='while read -r url; do blog-archive-url "$url"; done < archive-queue.txt' # ============================================================================ # LLM REVIEW # ============================================================================ alias bllm-summary='llm -s "Summarize this draft in 5 bullet points. Flag weak claims and missing sources."' alias bllm-title='llm -s "Suggest 20 concise titles. Avoid clickbait. Return one per line."' alias bllm-outline='llm -s "Turn this draft into a tight outline. Preserve the argument order."' alias bllm-counter='llm -s "Act as a skeptical editor. List the strongest objections and missing evidence."' alias bprompt='files-to-prompt . -e md -e mdx --ignore node_modules --ignore .git --ignore .next --markdown' # ============================================================================ # FUNCTIONS # ============================================================================ blog_root() { git rev-parse --show-toplevel 2>/dev/null || pwd } blog_post_dirs() { root=$(blog_root) for d in content posts post blog notes garden essays articles src/content src/pages _posts pages; do [ -d "$root/$d" ] && printf '%s\n' "$root/$d" done } blog_posts() { if [ "$#" -gt 0 ]; then printf '%s\n' "$@" return fi dirs=$(blog_post_dirs) if [ -n "$dirs" ]; then printf '%s\n' "$dirs" | while IFS= read -r d; do find "$d" -type f \( -name '*.md' -o -name '*.mdx' -o -name '*.org' \) done else find . \( -path '*/.git' -o -path '*/node_modules' -o -path '*/.next' -o -path '*/_site' \) -prune -o -type f \( -name '*.md' -o -name '*.mdx' -o -name '*.org' \) -print fi } blog_slug() { printf '%s' "$*" | tr '[:upper:]' '[:lower:]' | sed -e 's/[^a-z0-9]/-/g' -e 's/-\{2,\}/-/g' -e 's/^-//' -e 's/-$//' } blog_words() { blog_posts "$@" | while IFS= read -r f; do [ -f "$f" ] || continue words=$(sed -e '/^---$/,/^---$/d' "$f" | wc -w | tr -d ' ') printf '%7s %s\n' "$words" "$f" done | sort -nr } blog_recent() { blog_posts "$@" | xargs -r ls -lt | sed -n '1,40p' } blog_find() { if [ "$#" -eq 0 ]; then printf 'usage: blog_find PATTERN\n' >&2 return 2 fi blog_posts | xargs -r rg -n -- "$@" } blog_titles() { blog_posts "$@" | while IFS= read -r f; do title=$(sed -n -e 's/^title:[[:space:]]*//p' -e 's/^# //p' "$f" | sed -n '1p') [ -n "$title" ] || title="(untitled)" printf '%s\t%s\n' "$title" "$f" done } blog_extract_links() { blog-links "$@" } blog_archive_queue() { out="${1:-archive-queue.txt}" shift 2>/dev/null || true blog-links "$@" | sort -u > "$out" printf '%s\n' "$out" } blog_archive_all() { queue="${1:-archive-queue.txt}" [ -f "$queue" ] || blog_archive_queue "$queue" >/dev/null while IFS= read -r url; do [ -n "$url" ] && blog-archive-url "$url" done < "$queue" } blog_changed_posts() { git diff --name-only -- '*.md' '*.mdx' '*.org' } blog_staged_posts() { git diff --cached --name-only -- '*.md' '*.mdx' '*.org' } blog_review_changed() { files=$(blog_changed_posts) [ -n "$files" ] || return 0 printf '%s\n' "$files" | while IFS= read -r f; do blog-ai-review "$f" done } blog_reading_time() { blog_posts "$@" | while IFS= read -r f; do [ -f "$f" ] || continue words=$(wc -w < "$f" | tr -d ' ') mins=$(( (words + 224) / 225 )) printf '%3s min %7s words %s\n' "$mins" "$words" "$f" done | sort -n } blog_tk_context() { blog_posts "$@" | xargs -r rg -n -C 2 'TK|TODO|FIXME|XXX|SOURCE\?|CITE\?' } blog_domain_counts() { blog-links "$@" | awk -F/ '/^https?:/{print $3}' | sed 's/^www\.//' | sort | uniq -c | sort -nr }