#!/bin/bash ## ## Just-the-Facts (JTF) blog posts. A post lives in a directory holding ## outline.org (outline, corrections, guardrails, resources, sources); generate turns it ## into a Blogger-ready post.html via claude. Push with bloggerassist. ## CMD=$(basename $0) TMP=$HOME/.tmp/$CMD ; mkdir -p $TMP TENTEN_DIR=$(dirname "$(dirname "$(realpath "${BASH_SOURCE[0]}")")") LIBEXEC="$TENTEN_DIR/libexec/$CMD" . "$TENTEN_DIR/config/$CMD/default.config" [ -f "$HOME/.config/$CMD/default.config" ] && . "$HOME/.config/$CMD/default.config" usage() { echo "Usage: $CMD -a new -n title [-d dir]" echo " $CMD -a generate [-d dir] [-K]" echo " $CMD -a revise [-d dir]" echo " $CMD -a add-image -f image [-d dir] [-G]" echo " $CMD -a preview [-d dir] [-t tab] [-L]" echo echo "Actions:" echo " new Create dir/outline.org for a post titled title" echo " generate Write dir/post.html (and dir/notes.txt) from dir/outline.org" echo " revise Update dir/post.html to match an edited outline.org, keeping the rest of the draft" echo " add-image Upload image (full, web and thumbnail sizes) and add its URL to Images, or Gallery with -G" echo " preview Push dir/post.html as a Blogger draft and show Blogger's preview in Chrome" echo echo "Options:" echo " -d dir Post directory, e.g. projects/travel/denver-2026/posts/day-03 (default: .)" echo " -n title Post title (new)" echo " -f image Local image file (add-image)" echo " -G Add to the end-of-post Gallery instead of the top-of-post Images (add-image)" echo " -K Keep the existing post body; rebuild only the banner, resources and outline block (generate)" echo " -L Preview the local file instead of pushing (preview)" echo " -t tab Open the preview in a new tab next to this one: an id, or text matched against its title or URL (preview; default: JTF_PREVIEW_TAB)" exit 1 } file_url() { if [ -n "$WSL_DISTRO_NAME" ]; then echo "file://wsl.localhost/$WSL_DISTRO_NAME$1" else echo "file://$1" fi } unset ACTION TITLE TAB LOCAL KEEP IMAGE GALLERY DIR=. while getopts ":ha:d:n:t:f:LKG" o; do case "$o" in a) ACTION=$OPTARG ;; d) DIR=$OPTARG ;; n) TITLE=$OPTARG ;; t) TAB=$OPTARG ;; L) LOCAL=yes ;; K) KEEP=yes ;; f) IMAGE=$OPTARG ;; G) GALLERY=yes ;; *|h) usage ;; esac done DIR=$(realpath -m "$DIR") case "$ACTION" in new) [ -n "$TITLE" ] || usage outline="$DIR/outline.org" [ -e "$outline" ] && { echo "$outline already exists" >&2; exit 1; } mkdir -p "$DIR" cat > "$outline" <&2; exit 1; } JTF_S3_BUCKET=$JTF_S3_BUCKET JTF_FILES_BASE=$JTF_FILES_BASE JTF_AWS_PROFILE=$JTF_AWS_PROFILE \ python3 "$LIBEXEC/generate.py" "$DIR" "$JTF_PROMPT" "$BLOG_ID" "$JTF_EXPLAINER_URL" ${KEEP:+keep} ;; revise) [ -f "$DIR/post.html" ] || { echo "No post.html in $DIR to revise" >&2; exit 1; } JTF_S3_BUCKET=$JTF_S3_BUCKET JTF_FILES_BASE=$JTF_FILES_BASE JTF_AWS_PROFILE=$JTF_AWS_PROFILE \ python3 "$LIBEXEC/generate.py" "$DIR" "$JTF_PROMPT" "$BLOG_ID" "$JTF_EXPLAINER_URL" revise ;; add-image) [ -n "$IMAGE" ] || usage [ -f "$DIR/outline.org" ] || { echo "No outline.org in $DIR" >&2; exit 1; } section=Images [ -n "$GALLERY" ] && section=Gallery JTF_S3_BUCKET=$JTF_S3_BUCKET JTF_FILES_BASE=$JTF_FILES_BASE JTF_AWS_PROFILE=$JTF_AWS_PROFILE \ python3 "$LIBEXEC/add_image.py" "$DIR" "$IMAGE" "$section" ;; preview) post="$DIR/post.html" [ -f "$post" ] || { echo "No post.html in $DIR" >&2; exit 1; } if [ -n "$LOCAL" ]; then url=$(file_url "$post") else bloggerassist -a push "$post" > /dev/null || exit 1 id=$(grep -m1 '^.*//') [ -n "$id" ] || { echo "No BLOGGER-ID in $post after push" >&2; exit 1; } url="https://www.blogger.com/blog/post/edit/preview/$BLOG_ID/$id" fi TAB=${TAB:-$JTF_PREVIEW_TAB} anchor=$(chromeassist -a tabs | awk -F'|' -v t="$TAB" '$1 == t || index($2, t) || index($3, t) {print $1; exit}') [ -n "$anchor" ] || { echo "No Chrome tab matching '$TAB'" >&2; exit 1; } if [ -n "$LOCAL" ]; then before=$(chromeassist -a tabs | cut -d'|' -f1 | sort) chromeassist -a new-tab -t "$anchor" -u about:blank > /dev/null tab_id=$(comm -13 <(echo "$before") <(chromeassist -a tabs | cut -d'|' -f1 | sort) | head -1) [ -n "$tab_id" ] || { echo "Could not open a tab next to '$TAB'" >&2; exit 1; } chromeassist -a navigate -t "$tab_id" -u "$url" > /dev/null else chromeassist -a new-tab -t "$anchor" -u "$url" > /dev/null fi echo "$url" ;; *) usage ;; esac