convert.sh (3677B)
1 #!/bin/bash 2 set -euo pipefail 3 4 BLOG_TITLE="Andrew's Blog" 5 BLOG_DESCRIPTION="Latest posts from Andrew's blog" 6 BLOG_URL="https://blog.laack.co" 7 AUTHOR_EMAIL="andrew@laack.co" 8 9 mkdir -p posts/site 10 rm -f posts/site/*.html 11 12 INDEX_FILE="posts/site/index.html" 13 GEMINI_INDEX_FILE="posts/gemini/index.gmi" 14 RSS_FILE="posts/site/feed.xml" 15 GEMINI_RSS_FILE="posts/gemini/feed.xml" 16 GEMINI_RSS_FILE_TEMP="posts/gemini/feed.tmp.xml" 17 18 # TODO: Should this be an rss over gemini? 19 cat > "$GEMINI_INDEX_FILE" <<EOF 20 # Andrew's Blog 21 22 => gemini://blog.laack.co/feed.xml 23 24 EOF 25 26 27 cat > "$INDEX_FILE" <<EOF 28 <!DOCTYPE html> 29 <html> 30 <head> 31 <meta charset="UTF-8"> 32 <meta name="description" content="Andrew Laack's personal blog." /> 33 <title>$BLOG_TITLE</title> 34 <link rel="stylesheet" href="style.css"> 35 <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="feed.xml"> 36 </head> 37 <body> 38 <h1>Andrew's Blog</h1> 39 <p><a href="feed.xml">RSS Feed</a></p> 40 <ol> 41 EOF 42 43 cat > "$RSS_FILE" <<EOF 44 <?xml version="1.0" encoding="UTF-8"?> 45 <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> 46 <channel> 47 <title>$BLOG_TITLE</title> 48 <link>$BLOG_URL</link> 49 <description>$BLOG_DESCRIPTION</description> 50 <language>en-us</language> 51 <managingEditor>$AUTHOR_EMAIL</managingEditor> 52 <webMaster>$AUTHOR_EMAIL</webMaster> 53 <lastBuildDate>$(date -R)</lastBuildDate> 54 <atom:link href="$BLOG_URL/feed.xml" rel="self" type="application/rss+xml"/> 55 EOF 56 57 58 59 60 61 62 TMP_SORT_FILE=$(mktemp) 63 64 for FILE in posts/entries/*.md; do 65 [ -e "$FILE" ] || continue 66 BASENAME="$(basename "$FILE" .md)" 67 68 sed -i 's/\r$//' "$FILE" || true 69 70 pandoc "$FILE" -o "posts/site/$BASENAME.html" -s --css=style.css --wrap=none 71 72 DATE_LINE=$(grep -m1 '^## Date:' "$FILE" || true) 73 DATE=${DATE_LINE#'## Date: '} 74 75 SORTABLE_DATE=$(date -d "$DATE" +"%Y-%m-%d" 2>/dev/null || echo "1970-01-01") 76 77 echo "$SORTABLE_DATE|$DATE|$FILE" >> "$TMP_SORT_FILE" 78 done 79 80 sort -r "$TMP_SORT_FILE" | while IFS='|' read -r SORTABLE_DATE DATE FILE; do 81 BASENAME="$(basename "$FILE" .md)" 82 83 printf '<li><a href="%s.html">%s</a> - <em>%s</em></li>\n' "$BASENAME" "$BASENAME" "$DATE" >> "$INDEX_FILE" 84 85 printf '=> %s.gmi %s %s\n' "$BASENAME" "$BASENAME" "$DATE" >> "$GEMINI_INDEX_FILE" 86 87 TITLE=$(grep -m1 '^# ' "$FILE" | sed 's/^# //') 88 [ -z "$TITLE" ] && TITLE="$BASENAME" 89 90 RAW_MARKDOWN=$(sed -e '/^# /d' -e '/^## Date:/d' "$FILE") 91 FULL_CONTENT=$(printf '%s' "$RAW_MARKDOWN" | pandoc -f markdown -t html --wrap=none || true) 92 93 DESCRIPTION=$(printf '%s' "$FULL_CONTENT" \ 94 | tr '\r' ' ' \ 95 | tr '\n' ' ' \ 96 | sed -E 's/>[[:space:]]+</></g' \ 97 | sed -E 's/[[:space:]]+/ /g' \ 98 | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') 99 100 DESCRIPTION=${DESCRIPTION//]]>/]]]]><![CDATA[>} 101 102 [ -z "$DESCRIPTION" ] && DESCRIPTION="Blog post: $TITLE" 103 104 if [[ "$DATE" =~ ^[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}$ ]]; then 105 RSS_DATE=$(date -d "$DATE" -R 2>/dev/null || echo "$DATE") 106 else 107 RSS_DATE="$DATE" 108 fi 109 110 cat >> "$RSS_FILE" <<EOF 111 <item> 112 <title><![CDATA[$TITLE]]></title> 113 <link>$BLOG_URL/$BASENAME.html</link> 114 <description><![CDATA[$DESCRIPTION]]></description> 115 <pubDate>$RSS_DATE</pubDate> 116 <guid>$BLOG_URL/$BASENAME.html</guid> 117 </item> 118 EOF 119 done 120 121 cat >> "$INDEX_FILE" <<EOF 122 </ol> 123 </body> 124 </html> 125 EOF 126 127 cat >> "$RSS_FILE" <<EOF 128 </channel> 129 </rss> 130 EOF 131 132 rm -f "$TMP_SORT_FILE" 133 134 echo "Blog generated successfully!" 135 echo "- HTML index: $INDEX_FILE" 136 echo "- RSS feed: $RSS_FILE" 137 138 cp $RSS_FILE $GEMINI_RSS_FILE 139 140 cat $GEMINI_RSS_FILE | \ 141 sed -e 's/https:\/\/blog.laack.co/gemini:\/\/blog.laack.co/g' \ 142 -e 's/\.html/\.gmi/g' >> $GEMINI_RSS_FILE_TEMP 143 mv $GEMINI_RSS_FILE_TEMP $GEMINI_RSS_FILE