Commit 9271e08b1a
Unsigned
Layout: unified · split
build.sh +122 −50
| @@ -1,56 +1,128 @@ | ||
| 1 | #!/bin/bash | |
| 2 | ||
| 3 | # Ensure the latest post is included on the home page | |
| 4 | printf "Did you update the 'Recent Blog Posts' section? [yn] " | |
| 5 | read answer | |
| 6 | ||
| 7 | # Only continue if latest post is included on the home page | |
| 8 | if [[ "$answer" =~ ^[Yy]$ ]]; then | |
| 9 | # Check if the environment flag is set to PROD | |
| 10 | if [[ "$ENV" == "prod" ]]; then | |
| 11 | echo "Environment: Production" | |
| 12 | ||
| 13 | # Check if publishing via LAN or remotely | |
| 14 | printf "Publishing on remote or LAN? [r|l] " | |
| 15 | ||
| 16 | # Update ubuntu_server variable based on answer | |
| 17 | read method | |
| 18 | if [[ "$method" =~ ^[Rr]$ ]]; then | |
| 19 | ubuntu_server="ubuntu-remote" | |
| 20 | elif [[ "$method" =~ ^[Ll]$ ]]; then | |
| 21 | ubuntu_server="ubuntu" | |
| 22 | else | |
| 23 | echo "Invalid input. Assuming LAN (ubuntu)" | |
| 24 | ubuntu_server="ubuntu" | |
| 25 | fi | |
| 26 | ||
| 27 | # Remove previous build | |
| 28 | rm -rf .build/* | |
| 29 | ||
| 30 | # Minify CSS | |
| 31 | minify -o theme/static/styles.min.css theme/static/styles.css | |
| 32 | ||
| 33 | # Run publishing script | |
| 34 | emacs --script publish.el &>/dev/null | |
| 35 | ||
| 36 | # Deploy changes | |
| 37 | rsync -r --delete-before .build/* $ubuntu_server:/var/www/cleberg.net/ | |
| 38 | else | |
| 39 | echo "Environment: Development" | |
| 1 | #!/usr/bin/env bash | |
| 2 | set -e | |
| 3 | ||
| 4 | # ----------------------------------------------------------------------------- | |
| 5 | # Function: generate_recent_posts | |
| 6 | # After publishing to .build/, finds the 3 newest HTML files under .build/blog | |
| 7 | # (excluding blog index.html), extracts each post’s date/title/tags by: | |
| 8 | # - <time datetime="..."> | |
| 9 | # - <h1>…</h1> | |
| 10 | # - <span class="tag">…</span> lines | |
| 11 | # Replaces everything between <!-- RECENT-POSTS-START --> and | |
| 12 | # <!-- RECENT-POSTS-END --> in .build/index.html. | |
| 13 | # Tested on macOS. | |
| 14 | # ----------------------------------------------------------------------------- | |
| 15 | generate_recent_posts() { | |
| 16 | BUILD_DIR="${SCRIPT_DIR}/.build" | |
| 17 | INDEXFILE="$BUILD_DIR/index.html" | |
| 18 | BLOGDIR="$BUILD_DIR/blog" | |
| 19 | TMPFILE="$(mktemp)" | |
| 20 | MARKER_START="<!-- RECENT-POSTS-START -->" | |
| 21 | MARKER_END="<!-- RECENT-POSTS-END -->" | |
| 22 | ||
| 23 | # 1) Verify generated index.html exists | |
| 24 | if [[ ! -f "$INDEXFILE" ]]; then | |
| 25 | echo "Error: Generated index.html not found at $INDEXFILE" >&2 | |
| 26 | exit 1 | |
| 27 | fi | |
| 28 | ||
| 29 | # 2) Verify .build/blog exists | |
| 30 | if [[ ! -d "$BLOGDIR" ]]; then | |
| 31 | echo "Error: Generated blog directory not found at $BLOGDIR" >&2 | |
| 32 | exit 1 | |
| 33 | fi | |
| 34 | ||
| 35 | # 3) Collect the three newest post HTML files, excluding /index.html | |
| 36 | POSTS=() | |
| 37 | for FILEPATH in $(ls -1t "$BLOGDIR"/*.html 2>/dev/null | grep -v "/index.html\$" | head -n 3); do | |
| 38 | [[ -f "$FILEPATH" ]] && POSTS+=("$FILEPATH") | |
| 39 | done | |
| 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 | |
| 40 | 60 | |
| 41 | # Remove previous build | |
| 42 | rm -rf .build/* | |
| 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)" | |
| 43 | 64 | |
| 44 | # Minify CSS | |
| 45 | minify -o theme/static/styles.min.css theme/static/styles.css | |
| 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" | |
| 46 | 79 | |
| 47 | # Run publishing script | |
| 48 | emacs --script publish.el | |
| 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" | |
| 49 | 87 | |
| 50 | # Launch development web server | |
| 51 | cd .build/ | |
| 52 | python3 -m http.server | |
| 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 | ||
| 99 | # Step 2: Minify CSS | |
| 100 | minify -o "${SCRIPT_DIR}/theme/static/styles.min.css" "${SCRIPT_DIR}/theme/static/styles.css" | |
| 101 | ||
| 102 | # Step 3: Run Emacs publish.el (outputs into .build/) | |
| 103 | emacs --script "${SCRIPT_DIR}/publish.el" &>/dev/null | |
| 104 | ||
| 105 | # Step 4: Inject the “Recent Blog Posts” section into the generated index.html | |
| 106 | generate_recent_posts | |
| 107 | ||
| 108 | if [[ "$ENV" == "prod" ]]; then | |
| 109 | echo "Environment: Production" | |
| 110 | printf "Publishing on remote or LAN? [r|l] " | |
| 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" | |
| 53 | 119 | fi |
| 120 | ||
| 121 | # Step 5: Deploy via rsync | |
| 122 | rsync -r --delete-before "${SCRIPT_DIR}/.build/" "$ubuntu_server":/var/www/cleberg.net/ | |
| 54 | 123 | else |
| 55 | echo "Please update the 'Recent Blog Posts' section before publishing!" | |
| 56 | fi | |
| 124 | echo "Environment: Development" | |
| 125 | # Step 5: Launch local HTTP server from .build/ | |
| 126 | cd "${SCRIPT_DIR}/.build/" || exit | |
| 127 | python3 -m http.server | |
| 128 | fi | |
| \ No newline at end of file | ||
theme/templates/index.html +3 −39
| @@ -8,45 +8,9 @@ sub rsa4096 2022-11-16 [E]</pre> | ||
| 8 | 8 | </section> |
| 9 | 9 | <section> |
| 10 | 10 | <h2>Recent Blog Posts</h2> |
| 11 | ||
| 12 | ||
| 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 /> | |
| 11 | <!-- RECENT-POSTS-START --> | |
| 12 | <!-- RECENT-POSTS-END --> | |
| 13 | <br> | |
| 50 | 14 | <a href="/blog/">All Posts →</a> |
| 51 | 15 | </section> |
| 52 | 16 | |