diff --git a/build.sh b/build.sh index 9889dd4..a00318b 100755 --- a/build.sh +++ b/build.sh @@ -1,24 +1,32 @@ -#!/bin/bash +#!/usr/bin/env bash -BASE_PATH="$PWD" +set -o errexit # Stop executing when a command fails +set -o nounset # Stop executing when accessing an unset variable +set -o pipefail # Treat a pipeline as failing, even if one command in the pipeline fails + +if [[ "${TRACE-0}" == "1" ]]; then set -o xtrace; fi # Enable tracing (output of each command) if the TRACE variable is set + + + +BASE_PATH="$(dirname "$0")" check_for_dirs() { - if [ ! -d "${BASE_PATH}/source" ]; then - echo "ERROR: 'source' folder does not exist. Your content is sourced from this folder." + if [[ ! -d "${BASE_PATH}/source" ]]; then + echo "ERROR: 'source' folder does not exist. Your content is sourced from this folder." >&2 exit fi - if [ -d "${BASE_PATH}/temp" ]; then - echo "ERROR: You have an existing 'temp' folder. Please delete this folder, and run the script again." + if [[ -d "${BASE_PATH}/temp" ]]; then + echo "ERROR: You have an existing 'temp' folder. Please delete this folder, and run the script again." >&2 exit fi - if [ ! -f "${BASE_PATH}/header.html" ]; then - echo "ERROR: You do not have a header.html file. This file is used as a global header. Please create this file, and run the script again." + if [[ ! -f "${BASE_PATH}/header.html" ]]; then + echo "ERROR: You do not have a header.html file. This file is used as a global header. Please create this file, and run the script again." >&2 exit fi - if [ ! -f "${BASE_PATH}/footer.html" ]; then - echo "ERROR: You do not have a footer.html file. This file is used as a global footer. Please create this file, and run the script again." + if [[ ! -f "${BASE_PATH}/footer.html" ]]; then + echo "ERROR: You do not have a footer.html file. This file is used as a global footer. Please create this file, and run the script again." >&2 exit fi @@ -36,12 +44,12 @@ setup_output_dir() { } del_files_in_output() { - find $BASE_PATH/output -type f -name "*.md" -delete #Delete all .md files (which were copied over from 'source') in 'output' + find "$BASE_PATH/output" -type f -name "*.md" -delete #Delete all .md files (which were copied over from 'source') in 'output' } read_metadata() { # Read the metadata from the top of a .md file into a string - metadata=$(awk 'BEGIN{RS = "\n\n"} {print $0}; {exit}' $1) # Reads from the .md file until a double-newline is encountered + metadata=$(awk 'BEGIN{RS = "\n\n"} {print $0}; {exit}' "$1") # Reads from the .md file until a double-newline is encountered } convert_to_array() { @@ -57,52 +65,52 @@ convert_to_array() { } add_date_to_array() { - if [[ "${meta_array[date]}" == "auto" ]]; then # If the date is set to 'auto' + if [[ "${meta_array[date]-}" == "auto" ]]; then # If the date is set to 'auto' meta_array["date"]="$(date -r $1 +'%b %d, %Y')" fi } add_header_and_footer() { # Copy header to temporary location - cp $BASE_PATH/header.html $BASE_PATH/temp/temp_header.html + cp "$BASE_PATH/header.html" "$BASE_PATH/temp/temp_header.html" # Check for relevant metadata, and perform corresponding action - if test -z "${meta_array[date]}"; then #If there is no date - sed -i '$ d' $BASE_PATH/temp/temp_header.html # remove the 'date published' section of the header + if [[ ! -v "meta_array["date"]" ]]; then # If there is no date + sed -i '$ d' "$BASE_PATH/temp/temp_header.html" # remove the 'date published' section of the header fi - if [[ "${meta_array[noappend]}" == "true" ]]; then - sed -i 's/ - Two More Cents//g' $BASE_PATH/temp/temp_header.html # 'noappend' removes the suffix from the title + if [[ "${meta_array[noappend]-}" == "true" ]]; then + sed -i 's/ - Two More Cents//g' "$BASE_PATH/temp/temp_header.html" # 'noappend' removes the suffix from the title fi # Add header - cat $BASE_PATH/temp/temp_header.html | cat - $1 > $BASE_PATH/temp/temp.html + cat "$BASE_PATH/temp/temp_header.html" | cat - "$1" > "$BASE_PATH/temp/temp.html" # Add footer - echo >> $BASE_PATH/temp/temp.html - cat $BASE_PATH/footer.html >> $BASE_PATH/temp/temp.html + echo >> "$BASE_PATH/temp/temp.html" # Add newline + cat "$BASE_PATH/footer.html" >> "$BASE_PATH/temp/temp.html" # Move temp file to original location - mv $BASE_PATH/temp/temp.html $1 + mv "$BASE_PATH/temp/temp.html" "$1" } add_header_and_footer_to_index() { # Add header - cat $BASE_PATH/header.html | head -n -1 | cat - $1 > $BASE_PATH/temp/temp.html # For the index page, remove the last line of the header (date published) + cat "$BASE_PATH/header.html" | head -n -1 | cat - "$1" > "$BASE_PATH/temp/temp.html" # For the index page, remove the last line of the header (date published) # Add footer - echo >> $BASE_PATH/temp/temp.html - cat $BASE_PATH/footer.html >> $BASE_PATH/temp/temp.html + echo >> "$BASE_PATH/temp/temp.html" # Add newline + cat "$BASE_PATH/footer.html" >> "$BASE_PATH/temp/temp.html" # Move temp file to original location - mv $BASE_PATH/temp/temp.html $1 + mv "$BASE_PATH/temp/temp.html" "$1" } replace_vars() { # Loop through the keys of the 'meta_array' array, search for all occurences of the key in the HTML doc, and replace them with the corresponding value.. for arr_key in "${!meta_array[@]}"; do - meta_array[$arr_key]=${meta_array[$arr_key]/\//\\/} # Escape all forward slashes in the value - sed -i "s/[\$][\$]$arr_key[\$][\$]/${meta_array[$arr_key]}/g" $1 + meta_array["$arr_key"]="${meta_array["$arr_key"]/\//\\/}" # Escape all forward slashes in the value + sed -i "s/[\$][\$]$arr_key[\$][\$]/${meta_array[$arr_key]}/g" "$1" done } @@ -110,30 +118,30 @@ replace_vars() { md_to_html() { # Convert .md files from 'source' and place them into the correct locations into 'output' - files=$(find $BASE_PATH/source -name "*.md") + files=$(find "$BASE_PATH/source" -name "*.md") for file in $files; do - read_metadata $file # Sets the 'metadata' variable + read_metadata "$file" # Sets the 'metadata' variable convert_to_array "$metadata" #Sets the 'meta_array' array add_date_to_array "$file" #Uses 'meta_array' array # Copy file to temp dir and strip metadata - cp $file $BASE_PATH/temp/ + cp "$file" "$BASE_PATH/temp/" let num_lines=$(echo "$metadata" | wc -l)+1 - sed -i "1,${num_lines}d" $BASE_PATH/temp/`basename $file` + sed -i "1,${num_lines}d" "$BASE_PATH/temp/$(basename "$file")" # Construct path for output file - path_for_output=$(realpath --relative-to="${BASE_PATH}/source" $file) + path_for_output=$(realpath --relative-to="${BASE_PATH}/source" "$file") path_for_output="${BASE_PATH}/output/${path_for_output}" path_for_output="$(dirname $path_for_output)/$(basename $path_for_output .md).html" # Convert the file (using the given filters), and place the output in the correct location - pandoc --lua-filter pandoc_filters/* -f markdown --wrap=preserve $BASE_PATH/temp/`basename $file` > ${path_for_output} - rm $BASE_PATH/temp/* + pandoc --lua-filter "$BASE_PATH"/pandoc_filters/* -f markdown --wrap=preserve "$BASE_PATH/temp/$(basename "$file")" > "${path_for_output}" + rm "$BASE_PATH"/temp/* - add_header_and_footer $path_for_output # Uses 'meta_array' array - replace_vars $path_for_output #Uses 'meta_array' array + add_header_and_footer "$path_for_output" # Uses 'meta_array' array + replace_vars "$path_for_output" #Uses 'meta_array' array unset metadata meta_key meta_value meta_array done @@ -141,11 +149,12 @@ md_to_html() { gen_sorted_file_list() { # Generate a list of the HTMl files, sorted by when they were last modified (read from the contents of the HTML file) - files=$(find $BASE_PATH/output -name "*.html") + files=$(find "$BASE_PATH/output" -name "*.html") + local date_mod for file in $files; do - if grep -q "date-published" $file; then - echo "$file" >> $BASE_PATH/temp/file_listing.txt # Write files that have a date published to a temp file (we only want the files with date modified, because only these files can be listed with their date on the site map) + if grep -q "date-published" "$file" ; then + echo "$file" >> "$BASE_PATH/temp/file_listing.txt" # Write files that have a date published to a temp file (we only want the files with date modified, because only these files can be listed with their date on the site map) date_mod+=$(cat "$file" | grep "date-published" | awk -F'[<>]' '{print $3}' \ | cut -d' ' -f '1,2' --complement | tr -d "," | awk '{print $2" "$1" "$3}' \ @@ -155,16 +164,16 @@ gen_sorted_file_list() { # Generate a list of the HTMl files, sorted by when the # Line 2 re-arranges this information, and converts it into DD MM YY format # Line 3 converts this into a UNIX timestamp - date_mod+=$'\n' + date_mod+=$'\n' fi done - date_mod=$(echo "$date_mod" | head -n -1) # Remove last (empty) line from variable - echo "$date_mod" > $BASE_PATH/temp/date_mod.txt # Write the corresponding 'date modified' timestamps to a temp file + date_mod=$(echo "${date_mod-}" | head -n -1) # Remove last (empty) line from variable + echo "${date_mod-}" > "$BASE_PATH/temp/date_mod.txt" # Write the corresponding 'date modified' timestamps to a temp file - paste $BASE_PATH/temp/file_listing.txt $BASE_PATH/temp/date_mod.txt > $BASE_PATH/temp/new_file_list.txt # Combine file list and date modified into a single file + paste "$BASE_PATH/temp/file_listing.txt" "$BASE_PATH/temp/date_mod.txt" > "$BASE_PATH/temp/new_file_list.txt" # Combine file list and date modified into a single file - sorted_file_list=$(sort -r -k 2 $BASE_PATH/temp/new_file_list.txt) # Sort the data in the file based on the timestamp (from newest to oldest), and store it into a variable + sorted_file_list=$(sort -r -k 2 "$BASE_PATH/temp/new_file_list.txt") # Sort the data in the file based on the timestamp (from newest to oldest), and store it into a variable sorted_file_list=$(echo "$sorted_file_list" | awk '{print $1}') # Store only the first column (the file path) in the variable } @@ -173,16 +182,16 @@ gen_index_page() { # Generate an index page (site map) that includes links to th index_file_html="