#!/bin/sh

# Maky's poorly written build script for https://maky.me. This is the first (slightly bigger) shell script that I actually use.
# Last modified 2023.01.30.

# This assumes that the current directory name is the domain of the website. You can manually change it if you want to.
domain=${PWD##*/}

# Generate the base of the website.
#
## Delete existing build.
rm -rf _public/*

## Create base directories.
for basedir in $(find -mindepth 1 -not -path "*/\.*" -not -path "*/\_*" -type d | cut -d'/' -f2-); do
    mkdir -p _public/"$basedir"
done

## Create directories for each webpage.
for pagedir in $(find -mindepth 1 -not -path "*/\.*" -not -path "*/\_*" -not -name "index.md" -name "*.md" -type f | cut -d'/' -f2-); do
    mkdir -p _public/"${pagedir%.*}"
done

## Convert index.md files to index.html using pandoc.
### Strip out unnecessary metadata on the template file first,
grep -v '\$date\$' template.html > template.index.html
grep -v '\$author\$' template.index.html > template.index.html.tmp; mv template.index.html.tmp template.index.html
grep -v '\$date-meta\$' template.index.html > template.index.html.tmp; mv template.index.html.tmp template.index.html
grep -v '\$keywords\$' template.index.html > template.index.html.tmp; mv template.index.html.tmp template.index.html
### then do the main conversion process using pandoc,
for indexmd in $(find -mindepth 1 -not -path "*/\.*" -not -path "*/\_*" -name "index.md" -type f | cut -d'/' -f2-); do
    pandoc $indexmd --wrap=none --template=template.index.html -o _public/"${indexmd%.*}".html
done
### and finally remove the modified template.
rm template.index.html

## Convert *.md files to *.html files using pandoc for non-index.md files.
for page in $(find -not -path "*/\.*" -not -path "*/\_*" -not -name "index.md" -name "*.md" -type f | cut -d '/' -f2-); do
    pandoc $page --wrap=none --template=template.html -o _public/"${page%.*}/index.html"
done
 
## Copy all non-markdown files. This ignores build.sh and template.html files.
for file in $(find -not -path "*/\.*" -not -path "*/\_*" -not -name "*.md" -not -name "build.sh" -not -name "template.html" -type f | cut -d '/' -f2-); do
    cp "$file" _public/"$file"
done

# Create the blog index.
#
## Create a temporary file to sort the entries by date.
touch _public/blog/sort.tmp
## Sort the date by taking the title and date metadata and copying it to the temporary file.
for pagelink in $(find -not -path "*/\.*" -not -path "*/\_*" -not -name "index.md" -path "*blog/*" -name "*.md" -type f | cut -d '/' -f3-); do
    ## Grabbing the title from the original markdown file prevents the blog post title from changing if the template.html has other characters in the <title> field. E.g., "<title>$title$ - Awesome Website Name</title>".
    metatitle=$(grep -m1 'title:' blog/$pagelink | sed 's/title:\ //g')
    ## Grabbing the date from the generated HTML file as it is converted in numerical form already.
    metadate=$(grep -m1 '<meta name="date"' _public/blog/${pagelink%.*}/index.html | sed -e s/'<meta name="date" content="//' -e s/'">//')
    printf '<li><code>'"$metadate"'\ </code><a href='\""${pagelink%.*}"\"'>'"$metatitle"'</a></li>\n' >> _public/blog/sort.tmp
done
## Sort the entries.
sort -r _public/blog/sort.tmp -o _public/blog/sort.tmp

# Create keyword filters
#
## Using sort.tmp, grab an entry
mkdir _public/blog/tags
cat _public/blog/sort.tmp | while read entry; do
    link=$(echo $entry | sed -n '/"/!{/\n/{P;b}};s/"/\n/g;D')
    ## Then read its keywords from the HTML file.
    grep -m1 '<meta name="keywords"' _public/blog/$link/index.html | sed -e s/'<meta name="keywords" content="//' -e s/'">//' -e 's/,\ /\n/g' -e '/^$/d' | while read keyword; do
        ## For each keyword add a link of the entry to keyword/word.html.
        if [ -f "_public/blog/tags/$keyword.html" ]
            then
                true
            else
                cp _public/blog/index.html "_public/blog/tags/$keyword.html"
                sed -i "/<\/main>/i<ul>" "_public/blog/tags/$keyword.html"
        fi
        sed -i "/<\/main>/i$(echo $entry | sed 's/\ /\\\ /g')" "_public/blog/tags/$keyword.html"
        sed -i 's#'$link'#/blog/'$link'#g' "_public/blog/tags/$keyword.html"
    done
done
#marker=$(grep -A1 '\$body\$' template.html | sed 1d | sed 's|/|\\/|g')
for keywordurl in _public/blog/tags/*.html; do
    sed -i "/<\/main>/i<\/ul>" "$keywordurl"
    keyword=$(echo $keywordurl | cut -d '/' -f4- | sed 's/\.html//g')
    sed -i "/<\/main>/i<small><b>Showing only: \"$keyword\".\ </b><a href=/blog>↩<\/a><\/small>" "_public/blog/tags/$keyword.html"
done

ls -1NS _public/blog/tags | sed -e 's/.html//g' | while read keyword; do
    nospace=$(echo $keyword | sed -e 's/\ /-/g')
    printf '<a href=\"/blog/tags/'"$nospace"'\">'"$keyword"'</a>, ' >> _public/blog/keywordslist.tmp
    mkdir _public/blog/tags/$nospace
    mv '_public/blog/tags/'"$keyword"'.html' _public/blog/tags/$nospace/index.html
done
# remove last two characters (, )
sed -i 's/..$//' '_public/blog/keywordslist.tmp'

# Using keywordslist.tmp, create the entries
#keywordlist=$(cat _public/blog/keywordslist.tmp)
#sed -i "/<\/main>/i<small>Filter by keyword: $keywordlist.\ <\/small>" "_public/blog/index.html"
#rm _public/blog/keywordslist.tmp

## Insert each new line into the body of the blog.
#marker=$(grep -A1 '\$body\$' template.html | sed 1d | sed 's|/|\\/|g')
sed -i "/<\/main>/i<ul>" _public/blog/index.html
cat _public/blog/sort.tmp | while read entry; do
    sed -i "/<\/main>/i$(echo $entry | sed 's/\ /\\\ /g')" _public/blog/index.html
done
sed -i "/<\/main>/i<\/ul>" _public/blog/index.html
keywordlist=$(cat _public/blog/keywordslist.tmp)
sed -i "/<\/main>/i<small>Filter by keyword: $keywordlist.\ <\/small>" "_public/blog/index.html"
rm _public/blog/keywordslist.tmp

# Create the RSS feed.
## Insert the base of the RSS feed.
cat > _public/blog/rss.xml<< EOF
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<atom:link href="https://$domain/blog/rss.xml" rel="self" type="application/rss+xml" />
<title>$(grep title: blog/index.md | cut -d ':' -f2 | sed 's/ //') @ $domain</title>
<description>$(grep description blog/index.md | cut -d ':' -f2 | sed 's/ //')</description>
<link>https://$domain/blog</link>
<lastBuildDate>$(date +"%a, %d %b %Y %H:%M:%S %z")</lastBuildDate>
EOF
## Using the sort.tmp file, generate each RSS feed entry by taking the title and date metadata, then copying the content of $body$ of template.html which is expected to be in between "<main>" and "</main>"
sed -n '/"/!{/\n/{P;b}};s/"/\n/g;D' _public/blog/sort.tmp | while read entry; do
    printf '<item>\n' >> _public/blog/rss.xml
    printf '<guid>https://'"$domain"'/blog/'"$entry"'</guid>\n' >> _public/blog/rss.xml
    printf '<link>https://'"$domain"'/blog/'"$entry"'</link>\n' >> _public/blog/rss.xml
    pubDate=$(grep -m1 '<meta name="date"' _public/blog/$entry/index.html | sed -e s/'<meta name="date" content="//' -e s/'">//')
    printf '<pubDate>'"$pubDate"'</pubDate>\n' >> _public/blog/rss.xml
    title=$(grep -m1 'title:' blog/$entry.md | sed 's/title:\ //g')
    printf '<title>'"$title"'</title>\n' >> _public/blog/rss.xml
    description=$(sed -n -e '/<main>/,/<\/main>/ p' _public/blog/${entry}/index.html | sed 1d | sed '$d')
    printf '<description><![CDATA[\n' >> _public/blog/rss.xml
    printf '\n' >> _public/blog/rss.xml
    printf ''"$description"'\n' >> _public/blog/rss.xml
    printf '\n' >> _public/blog/rss.xml
    printf ']]></description>\n' >> _public/blog/rss.xml
    printf '</item>\n' >> _public/blog/rss.xml
    printf '\n' >> _public/blog/rss.xml
done
## End the RSS feed.
printf '</channel></rss>' >> _public/blog/rss.xml
## Delete the temporary sorting file we created earlier.
rm _public/blog/sort.tmp

# Create keyword filters.

# Generate the sitemap.xml
#
## Create the base of the sitemap.
cat > _public/sitemap.xml<< EOF
<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
EOF

## Insert each link for the site map.
for page in $(find _public/ -not -path "*/\.*" -name "index.html" -type f | cut -d '/' -f2- | sed -e 's/index.html//g'); do
    printf '<url><loc>https://'"$domain"'/'"${page%.*}"'</loc><lastmod>'"$(date +%Y-%m-%d)"'</lastmod><priority>1.0</priority></url>\n' >> _public/sitemap.xml
done
## End the sitemap.
printf '</urlset>' >> _public/sitemap.xml

# Nyaaa~ OwO You've reached the bottom of the script!
# I got bored. Here's Neko-chan!
