Commit 6006eecc2d
Unsigned
Layout: unified · split
build.sh +50 −122
| @@ -1,128 +1,56 @@ | |||
| 1 | #!/usr/bin/env bash | 1 | #!/bin/bash |
| 2 | set -e | 2 | |
| 3 | 3 | # Ensure the latest post is included on the home page | |
| 4 | # ----------------------------------------------------------------------------- | 4 | printf "Did you update the 'Recent Blog Posts' section? [yn] " |
| 5 | # Function: generate_recent_posts | 5 | read answer |
| 6 | # After publishing to .build/, finds the 3 newest HTML files under .build/blog | 6 | |
| 7 | # (excluding blog index.html), extracts each post’s date/title/tags by: | 7 | # Only continue if latest post is included on the home page |
| 8 | # - <time datetime="..."> | 8 | if [[ "$answer" =~ ^[Yy]$ ]]; then |
| 9 | # - <h1>…</h1> | 9 | # Check if the environment flag is set to PROD |
| 10 | # - <span class="tag">…</span> lines | 10 | if [[ "$ENV" == "prod" ]]; then |
| 11 | # Replaces everything between <!-- RECENT-POSTS-START --> and | 11 | echo "Environment: Production" |
| 12 | # <!-- RECENT-POSTS-END --> in .build/index.html. | 12 | |
| 13 | # Tested on macOS. | 13 | # Check if publishing via LAN or remotely |
| 14 | # ----------------------------------------------------------------------------- | 14 | printf "Publishing on remote or LAN? [r|l] " |
| 15 | generate_recent_posts() { | 15 | |
| 16 | BUILD_DIR="${SCRIPT_DIR}/.build" | 16 | # Update ubuntu_server variable based on answer |
| 17 | INDEXFILE="$BUILD_DIR/index.html" | 17 | read method |
| 18 | BLOGDIR="$BUILD_DIR/blog" | 18 | if [[ "$method" =~ ^[Rr]$ ]]; then |
| 19 | TMPFILE="$(mktemp)" | 19 | ubuntu_server="ubuntu-remote" |
| 20 | MARKER_START="<!-- RECENT-POSTS-START -->" | 20 | elif [[ "$method" =~ ^[Ll]$ ]]; then |
| 21 | MARKER_END="<!-- RECENT-POSTS-END -->" | 21 | ubuntu_server="ubuntu" |
| 22 | 22 | else | |
| 23 | # 1) Verify generated index.html exists | 23 | echo "Invalid input. Assuming LAN (ubuntu)" |
| 24 | if [[ ! -f "$INDEXFILE" ]]; then | 24 | ubuntu_server="ubuntu" |
| 25 | echo "Error: Generated index.html not found at $INDEXFILE" >&2 | 25 | fi |
| 26 | exit 1 | 26 | |
| 27 | fi | 27 | # Remove previous build |
| 28 | 28 | rm -rf .build/* | |
| 29 | # 2) Verify .build/blog exists | 29 | |
| 30 | if [[ ! -d "$BLOGDIR" ]]; then | 30 | # Minify CSS |
| 31 | echo "Error: Generated blog directory not found at $BLOGDIR" >&2 | 31 | minify -o theme/static/styles.min.css theme/static/styles.css |
| 32 | exit 1 | 32 | |
| 33 | fi | 33 | # Run publishing script |
| 34 | 34 | emacs --script publish.el &>/dev/null | |
| 35 | # 3) Collect the three newest post HTML files, excluding /index.html | 35 | |
| 36 | POSTS=() | 36 | # Deploy changes |
| 37 | for FILEPATH in $(ls -1t "$BLOGDIR"/*.html 2>/dev/null | grep -v "/index.html\$" | head -n 3); do | 37 | rsync -r --delete-before .build/* $ubuntu_server:/var/www/cleberg.net/ |
| 38 | [[ -f "$FILEPATH" ]] && POSTS+=("$FILEPATH") | 38 | else |
| 39 | done | 39 | echo "Environment: Development" |
| 40 | |||
| 41 | # 4) Build the HTML snippet into TMPFILE | ||
| 42 | { | ||
| 43 | for POST in "${POSTS[@]}"; do | ||
| 44 | BASENAME="$(basename "$POST")" | ||
| 45 | URL="/blog/${BASENAME}" | ||
| 46 | |||
| 47 | # 4a) DATE: extract from first <time datetime="..."> | ||
| 48 | POST_DATE_FULL="$(sed -n 's/.*<time datetime="\([^"]*\)".*/\1/p' "$POST" | head -n1)" | ||
| 49 | if [[ -n "$POST_DATE_FULL" ]]; then | ||
| 50 | POST_DATE="${POST_DATE_FULL%% *}" | ||
| 51 | else | ||
| 52 | POST_DATE="$(stat -f "%Sm" -t "%Y-%m-%d" "$POST")" | ||
| 53 | fi | ||
| 54 | |||
| 55 | # 4b) TITLE: extract from first <h1>…</h1> | ||
| 56 | TITLE="$(sed -n 's/.*<h1[^>]*>\(.*\)<\/h1>.*/\1/p' "$POST" | head -n1)" | ||
| 57 | if [[ -z "$TITLE" ]]; then | ||
| 58 | TITLE="${BASENAME%.html}" | ||
| 59 | fi | ||
| 60 | |||
| 61 | # 4c) TAGS: extract each <span class="tag">…</span> line, re-indent by 6 spaces | ||
| 62 | TAGSPAN="$(grep -o '^[[:space:]]*<span class="tag">[^<]*</span>' "$POST" \ | ||
| 63 | | sed 's/^[[:space:]]*/ /' || true)" | ||
| 64 | |||
| 65 | # 4d) Emit one <div class="post">…</div> block | ||
| 66 | cat <<EOF | ||
| 67 | <div class="post"> | ||
| 68 | <time datetime="${POST_DATE}">${POST_DATE}</time> | ||
| 69 | <div class="post-content"> | ||
| 70 | <a href="${URL}">${TITLE}</a> | ||
| 71 | <div class="post-tags"> | ||
| 72 | $(printf "%s\n" "$TAGSPAN") | ||
| 73 | </div> | ||
| 74 | </div> | ||
| 75 | </div> | ||
| 76 | EOF | ||
| 77 | done | ||
| 78 | } > "$TMPFILE" | ||
| 79 | |||
| 80 | # 5) Replace everything between the markers in .build/index.html (keeping markers) | ||
| 81 | sed -i '' -e "/${MARKER_START}/,/${MARKER_END}/{ | ||
| 82 | /${MARKER_START}/{p; r $TMPFILE | ||
| 83 | }; | ||
| 84 | /${MARKER_END}/p; | ||
| 85 | d | ||
| 86 | }" "$INDEXFILE" | ||
| 87 | |||
| 88 | rm "$TMPFILE" | ||
| 89 | echo "→ Injected up to 3 newest posts into $INDEXFILE" | ||
| 90 | } | ||
| 91 | |||
| 92 | |||
| 93 | # -------------------- Main build.sh logic -------------------- | ||
| 94 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| 95 | |||
| 96 | # Step 1: Clean previous build | ||
| 97 | rm -rf "${SCRIPT_DIR}/.build"/* | ||
| 98 | 40 | ||
| 99 | # Step 2: Minify CSS | 41 | # Remove previous build |
| 100 | minify -o "${SCRIPT_DIR}/theme/static/styles.min.css" "${SCRIPT_DIR}/theme/static/styles.css" | 42 | rm -rf .build/* |
| 101 | 43 | ||
| 102 | # Step 3: Run Emacs publish.el (outputs into .build/) | 44 | # Minify CSS |
| 103 | emacs --script "${SCRIPT_DIR}/publish.el" &>/dev/null | 45 | minify -o theme/static/styles.min.css theme/static/styles.css |
| 104 | 46 | ||
| 105 | # Step 4: Inject the “Recent Blog Posts” section into the generated index.html | 47 | # Run publishing script |
| 106 | generate_recent_posts | 48 | emacs --script publish.el |
| 107 | 49 | ||
| 108 | if [[ "$ENV" == "prod" ]]; then | 50 | # Launch development web server |
| 109 | echo "Environment: Production" | 51 | cd .build/ |
| 110 | printf "Publishing on remote or LAN? [r|l] " | 52 | python3 -m http.server |
| 111 | read -r method | ||
| 112 | if [[ "$method" =~ ^[Rr]$ ]]; then | ||
| 113 | ubuntu_server="ubuntu-remote" | ||
| 114 | elif [[ "$method" =~ ^[Ll]$ ]]; then | ||
| 115 | ubuntu_server="ubuntu" | ||
| 116 | else | ||
| 117 | echo "Invalid input. Assuming LAN (ubuntu)" | ||
| 118 | ubuntu_server="ubuntu" | ||
| 119 | fi | 53 | fi |
| 120 | |||
| 121 | # Step 5: Deploy via rsync | ||
| 122 | rsync -r --delete-before "${SCRIPT_DIR}/.build/" "$ubuntu_server":/var/www/cleberg.net/ | ||
| 123 | else | 54 | else |
| 124 | echo "Environment: Development" | 55 | echo "Please update the 'Recent Blog Posts' section before publishing!" |
| 125 | # Step 5: Launch local HTTP server from .build/ | 56 | fi |
| 126 | cd "${SCRIPT_DIR}/.build/" || exit | ||
| 127 | python3 -m http.server | ||
| 128 | fi\ No newline at end of file | ||
theme/templates/index.html +39 −3
| @@ -8,9 +8,45 @@ sub rsa4096 2022-11-16 [E]</pre> | |||
| 8 | </section> | 8 | </section> |
| 9 | <section> | 9 | <section> |
| 10 | <h2>Recent Blog Posts</h2> | 10 | <h2>Recent Blog Posts</h2> |
| 11 | <!-- RECENT-POSTS-START --> | 11 | |
| 12 | <!-- RECENT-POSTS-END --> | 12 | |
| 13 | <br> | 13 | <div class="post"> |
| 14 | <time datetime="2025-06-02 15:26:05">2025-06-02</time> | ||
| 15 | <div class="post-content"> | ||
| 16 | <a href="/blog/private-ios-apps.html">Selection of Privacy-Focused iOS Applications for Minimalist Users</a> | ||
| 17 | <div class="post-tags"> | ||
| 18 | <span class="tag">ios</span> | ||
| 19 | <span class="tag">privacy</span> | ||
| 20 | <span class="tag">security</span> | ||
| 21 | </div> | ||
| 22 | </div> | ||
| 23 | </div> | ||
| 24 | |||
| 25 | <div class="post"> | ||
| 26 | <time datetime="2025-05-30 10:53:28">2025-05-30</time> | ||
| 27 | <div class="post-content"> | ||
| 28 | <a href="/blog/it-audit-career.html">Career Advancement through Mastery of Emerging Technologies in IT Audit</a> | ||
| 29 | <div class="post-tags"> | ||
| 30 | <span class="tag">audit</span> | ||
| 31 | <span class="tag">technology</span> | ||
| 32 | <span class="tag">career</span> | ||
| 33 | </div> | ||
| 34 | </div> | ||
| 35 | </div> | ||
| 36 | |||
| 37 | <div class="post"> | ||
| 38 | <time datetime="2025-05-02 Fri 21:10:00">2025-05-02</time> | ||
| 39 | <div class="post-content"> | ||
| 40 | <a href="/blog/asahi-linux.html">Performance and Compatibility Report of Asahi Linux on Apple M2 MacBook Pro 16"</a> | ||
| 41 | <div class="post-tags"> | ||
| 42 | <span class="tag">mac</span> | ||
| 43 | <span class="tag">apple</span> | ||
| 44 | <span class="tag">linux</span> | ||
| 45 | </div> | ||
| 46 | </div> | ||
| 47 | </div> | ||
| 48 | |||
| 49 | <br /> | ||
| 14 | <a href="/blog/">All Posts →</a> | 50 | <a href="/blog/">All Posts →</a> |
| 15 | </section> | 51 | </section> |
| 16 | 52 | ||