#!/usr/bin/env bash
BUILD=.build/
function extract_metadata() {
local name=$1
local file=$2
local val=$(sed -nE "/^--${name}: .+$/s/^--${name}: (.+)$/\1/p" $file)
if [ -z "$val" ]; then
echo ""
return 1
else
echo "$val"
return 0
fi
}
function mktemp_file() {
local name=$1
local var=$(mktemp -p $BUILD "${name}_XXXXXX")
echo "${var}"
return 0
}
function extract_title() {
sed -n -E "1,/<\/h1>/s/.*
(.+)<\/h1>.*/\1/p1" $1
}
function generate_index() {
local base_dir=$1
echo "Generating index for $base_dir"
local page_file=$(mktemp_file "index_page")
local content_file=$(mktemp_file "index_content")
local indexed_files=$(mktemp_file "indexed_files")
local title=$(basename ${base_dir})
echo "
${title} index
" > $content_file
find $base_dir -type f -iname "*.html" | sort -hr > $indexed_files
while read post; do
post_date=$(sed -n -E "1,/datetime=/s/Posted:.*datetime=.([0-9-]+).*/\1/p1" $post)
post_title=$(extract_title $post)
if [ -z "${post_date}" ]; then
echo "${post_title} " >> $content_file
else
echo "${post_date} — ${post_title} " >> $content_file
fi
done <$indexed_files
echo " " >> $content_file
sed -i "s,${base_dir},.,g" $content_file
generate_page "index" $content_file $page_file
# strip out the footer
sed -i '1,/<\/footer>/{//,$d}' $page_file
#tidy
tidy_file $page_file
echo "Copying $page_file to $base_dir/index.html"
cp $page_file $base_dir/index.html
echo "Searching for more directories to index"
for dir in $base_dir/*; do
if [ ! -d $dir ]; then
continue;
fi
generate_index $dir
done
}
# generates the base page structure
# any "special" functions can go in their various code_paths
function generate_page() {
local type=$1
local content_file=$2
local page_file=$3
echo "Using $page_file for file"
cat templates/page.html > $page_file
echo "Using $content_file for content"
sed -i "/^--/d" $content_file
echo "Injecting content from $content_file into $page_file"
sed -i -e "/CONTENT/ {
r ${content_file}
d}" $page_file
echo "Injecting CSS into $page_file"
sed -i -e "/STYLE/ {
r templates/index.css
d}" $page_file
echo "Extracting page title"
page_title=$(sed -nE "/<\/h1>/s,.*(.+) .*,\1,1p" $content_file)
sed -i -E "s/[{]PAGE_TITLE[}]/${page_title/\//\\/}/1" $page_file
echo "Setting type"
if [ -z "$type" ]; then
sed -i -E "s/[{]TYPE[}]//" $page_file
else
sed -i -E "s,[{]TYPE[}],/${type}," $page_file
fi
return 0
}
function set_tags() {
local tags=$1
local post_file=$2
if [ -z "$tags" ]; then
sed -i -E "s/[{]TAGS[}]//" $post_file
else
local tags_html_file=$(mktemp_file "tags_html")
echo "Using tags file $tags_html_file"
echo "Tags: [ ${tags} ] " > $tags_html_file
sed -i -e "/TAGS/ {
r $tags_html_file
d}" $post_file
fi
}
function set_post_date () {
local post_date=$1
local post_file=$2
match=$(echo $post_date | sed -n -E "s/^([0-9-]+)$/\1/p")
if [ -z "$match" ]; then
sed -i -E "s/[{]POST_DATE[}]//" $post_file
else
local post_date_html=$(mktemp_file "post_date")
display_date=$(date -d "${post_date}" +"%B %d, %Y")
echo "
Posted: ${display_date}
" > $post_date_html
sed -i -e "/POST_DATE/ {
r $post_date_html
d}" $post_file
fi
}
function set_updated_at() {
local updated_at=$1
local post_file=$2
if [ -z "$updated_at" ]; then
sed -i -E "s/[{]UPDATED[}]//" $post_file
else
updated_html_file=$(mktemp_file "updated_html")
updated_disp=$(date -d "${updated_at}" +"%B %d, %Y")
echo "
Updated on: ${updated_disp}
" > $updated_html_file
sed -i -e "/UPDATED/ {
r ${updated_html_file}
d}" $post_file
fi
}
function push_pin() {
local post_date=$1
local post_url=$2
local post_title=$3
local pin_file=$4
local pin_text=""
matched=$(echo "${post_date}" | sed -n -E "s/^([0-9-]+)$/\1/p")
if [ ! -z "${matched}" ]; then
pin_text="${pin_text}${post_date} — "
fi
pin_text="${pin_text}${post_title} "
echo $pin_text >> $pin_file
}
function add_to_rss() {
local post_date=$1
local post_url=$2
local post_title=$3
local content_file=$4
local rss_data=$5
local pub_date=$(date -d "${post_date}" -R)
sed -E -e "{
s/[{]TITLE[}]/${post_title/\//\\/}/1;
s,[{]LINK[}],${post_url},g;
s/[{]PUBDATE[}]/${pub_date}/1;
/CONTENT/ {
r ${content_file}
d}
}" templates/rss-item.xml >> ${rss_data}
}
function tidy_file() {
local file=$1
tidy -mq -config tidy.conf $file
}
echo "Clearing build-cache"
rm -rf $BUILD
mkdir $BUILD
echo "Cleaning up prod folders"
echo "Deleting www"
rm -rf www
mkdir www
echo "Deleting gemini"
rm -rf gemini
mkdir gemini
echo "Building html"
pinned_html=$(mktemp_file "pinned")
rss_data=$(mktemp_file "rss_data")
echo "Using pinned file: $pinned_html"
for post in posts/*.*; do
echo "Processing $post"
post_date=$(extract_metadata "post-date" $post)
if [ -z "$post_date" ]; then
# post is not ready to be posted
# requires a post date
echo "No data"
continue;
fi
echo "Extracting metadata"
updated_at=$(extract_metadata "updated-at" $post)
tags=$(extract_metadata "tags" $post)
type=$(extract_metadata "type" $post)
pinned=$(extract_metadata "pinned" $post)
notidy=$(extract_metadata "notidy" $post)
post_file=$(mktemp_file "post")
content_file=$(mktemp_file "content")
# Check if gmi or HTML
extension="${post##*.}"
if [ "${extension}" == "gmi" ]; then
echo "Converting gemtext 2 html"
gmihtml="$BUILD/$(basename ${post%.*}).html"
# todo - make gmi2html post as an article
echo "" > $gmihtml
./modules/gmi2html/gmi2html.sh <(sed "/^--.*$/d" $post) >> $gmihtml
echo " " >> $gmihtml
post=$gmihtml # set post file to be the temporary HTML file
fi
echo "Copying $post data into $content_file"
cp $post $content_file
generate_page $type $content_file $post_file
echo "Setting post date"
set_post_date "$post_date" $post_file
echo "Setting updated at"
set_updated_at "$updated_at" $post_file
echo "Setting tags"
set_tags "$tags" $post_file
# tidy
if [-z "$notidy" ]; then
echo "Tidying post"
tidy_file $post_file
else
echo "Skipping tidy for $post_file"
fi
echo "Copying temp_file to www/"
filename=$(basename $post)
url=""
if [ "$type" == "blog" ]; then
year=$(date -d "$post_date" +%Y)
month=$(date -d "$post_date" +%m)
day=$(date -d "$post_date" +%d)
mkdir -p www/blog/$year/$month/$day
cp $post_file www/blog/$year/$month/$day/$filename
title="$(extract_title $post_file)"
if [ ! -z "$pinned" ]; then
push_pin "$post_date" \
"/blog/$year/$month/$day/$filename" \
"${title}" \
$pinned_html
fi
add_to_rss "$post_date" \
"/blog/$year/$month/$day/$filename" \
"${title}" \
${content_file} \
${rss_data}
else
path=$(extract_metadata "path" $post)
mkdir -p www/$path
cp $post_file www/$path/$filename
dest=$(echo "/$path/$filename" | sed -E "s,/+,/,g")
if [ ! -z "$pinned" ]; then
push_pin "$post_date" \
"$dest" \
"$(extract_title $post_file)" \
$pinned_html
fi
fi
done
function set_pinned() {
local pinned_html=$1
local file=$2
if [ -z "$pinned_html" ]; then
sed -i -E "s/[{]PINNED[}]//" $file
else
sort -r -o $pinned_html $pinned_html
sed -i -e "/PINNED/ {
r $pinned_html
d}" $file
fi
}
echo "Generate homepage"
homepage=$(mktemp_file "homepage")
generate_page "home" posts/index.html $homepage
# clear extra tag content
set_post_date "" $homepage
set_updated_at "$(date --iso)" $homepage
set_tags "" $homepage
set_pinned "${pinned_html}" $homepage
cp $homepage www/index.html
echo "Copying static-html"
cp -r static-html/* www/
echo "Copying res to www"
cp -r res/ www/media/
echo "Building http rss"
feed=$(mktemp_file "rss_feed")
year="$(date +%Y)"
build_date="$(date -R)"
sed -E -e "{
s/[{]YEAR[}]/$year/1;
s/[{]BUILDDATE[}]/$build_date/g;
/ITEMS/ {
r ${rss_data}
d}
}" templates/feed.rss > $feed
cp $feed www/blog/feed.rss
echo "Generating index files"
generate_index "www/blog"
generate_index "www/music"
echo "Granting permissions"
chmod -R 755 www
echo "Done generating HTML"
echo "Building gmi"
# TODO
echo "Copying static-gemini"
cp -r static-gemini/ gemini/
echo "Copying res to gemini"
cp -r res/ gemini/media/
echo "Building gemini atom"
# TODO