shite

Static site generator script
git clone _git@git.zakaria.org/shite.git
Log | Files | Refs | README

rss.sh (2900B)


      1 #!/bin/sh
      2 
      3 env="${1:-./.env}"
      4 # shellcheck source=./.env.template
      5 . "$env"
      6 
      7 exclude_files="${exclude_files}"
      8 meta_ext="${meta_ext:-.meta}"
      9 site_root="${site_root}"
     10 html_dir="${html_dir:-html}"
     11 post_dir="${post_dir:-posts}"
     12 
     13 rss_root="${rss_root}"
     14 rss_title="${rss_title}"
     15 rss_description="${rss_description}"
     16 rss_link="${rss_link}"
     17 
     18 log() {
     19 	printf 'shite: [%s] %s\n' "$1" "$2" >&2
     20 }
     21 info() {
     22 	log "$(printf '\033[32minfo\033[0m')" "$1"
     23 }
     24 warn() {
     25 	log "$(printf '\033[33mwarn\033[0m')" "$1"
     26 }
     27 error() {
     28 	log "$(printf '\033[31merror\033[0m')" "$1"
     29 }
     30 die() {
     31 	error "$1"
     32 	printf 'exiting...\n' >&2
     33 	exit 1
     34 }
     35 
     36 # convert input date to RFC2822
     37 # time and tz are set to 00:00:00 +0000
     38 # $1 - input date
     39 to_rfc2822() {
     40         date="$1"
     41         format="%F"
     42         rfc2822="+%a, %d %b %Y 00:00:00 +0000"
     43 
     44         # if on Linux, use GNU date syntax
     45         if [ "$(uname)" = "Linux" ]; then
     46                 date -d "$date" "$rfc2822"
     47         else
     48                 date -j -f "$format" "$date" "$rfc2822"
     49         fi
     50 }
     51 
     52 rss_preamble() {
     53 	printf '<rss version="2.0" xml:base="%s">\n' "$rss_root"
     54 	printf '<channel>\n'
     55 	printf '<title>%s</title>\n' "$rss_title"
     56 	if [ -n "$rss_description" ]; then
     57 		printf '<description>\n'
     58 		printf '%s\n' "$rss_description"
     59 		printf '</description>\n'
     60 	else
     61 		printf '<description/>\n'
     62 	fi
     63 	printf '<link>%s</link>\n' "$rss_link"
     64 }
     65 
     66 rss_postamble() {
     67 	printf '</channel>\n'
     68 	printf '</rss>\n'
     69 }
     70 
     71 gen_rss() {
     72 	find "${site_root}/${post_dir}/" -name '*.md' | while read -r post; do
     73 		post_html="${post%.*}.html"
     74 		post_meta="${post%.*}${meta_ext}"
     75 		post_url="/posts/$(basename "$post_html")"
     76 
     77 		excluded=0
     78 		for ex in $exclude_files; do
     79 			if [ "$(basename "$post")" = "$ex" ]; then
     80 				excluded=1
     81 			fi
     82 		done
     83 	
     84 		if [ "$excluded" -eq 1 ]; then
     85 			warn "${post} excluded"
     86 			continue
     87 		fi
     88 
     89 		# parse metadata if .meta file exists
     90 		if [ -f "$post_meta" ]; then
     91 			# read the 'key: value' .meta file
     92 			while IFS=': ' read -r key val; do
     93 				[ "${key##\#*}" ] || continue
     94 				# export each key as a variable; '$post_<key>'
     95 				export "post_${key}=${val}" 2>/dev/null || \
     96 					warn "'${key}' is not a valid meta tag name"
     97 			done < "$post_meta"
     98 		else
     99 			warn "no ${meta_ext} - skipping metadata parsing"
    100 		fi
    101 	
    102 		echo "${post_date}|${post_title}|${post_url}|${post}" >> rss.meta
    103 
    104 		unset post_date
    105 		unset post_title
    106 		unset post_image
    107 		unset post_description
    108 		unset post_url
    109 	done
    110 
    111 	rss_preamble
    112 	sort -r rss.meta | while IFS='|' read -r post_date post_title post_url post_md; do
    113 		[ -z "$post_date" ] && continue
    114 		rfcdate="$(to_rfc2822 "$post_date")"
    115 		printf '<item>\n'
    116 		printf '<link>%s%s</link>\n' "$rss_root" "$post_url"
    117 		printf '<title>%s</title>\n' "$post_title"
    118 		printf '<pubDate>%s</pubDate>\n' "$rfcdate"
    119 		printf '<description>\n'
    120 		lowdown -Thtml < "$post_md"
    121 		printf '</description>\n'
    122 		printf '</item>\n'
    123 	done
    124 	rss_postamble
    125 }
    126 
    127 gen_rss
    128 rm -i rss.meta