1 #!/bin/sh 2 3 # The most bloated, non-mantainable, non-readable static site generator 4 # by: Martin Kloeckner - https://kloeckner.com.ar 5 # Dependencies: sed, grep, lowdown. 6 7 # Template: the converted html text is placed on a copy of the template 8 # containing $body$ on it, $body$ then gets deleted. 9 # Also the template should contain an $article-title$, $article-date$ and 10 # $pagetitle$ 11 12 # The article title is considered to be the first h1 header found 13 # in the markdown file 14 15 div_article_title_w_logo() { 16 logo_src=$(echo $1 | grep -zoP '(?<=src=\")(.*?)(?=\")' | tr -d '\0') 17 logo_alt=$(echo $1 | grep -zoP '(?<=alt=\")(.*?)(?=\")' | tr -d '\0') 18 logo_title=$(echo $1 | grep -zoP '(?<=title=\")(.*?)(?=\")' | tr -d '\0') 19 h1_title=$(echo $2 | grep -zoP '(?<=<h1 id=article-title>)(.*?)(?=</h1>)' |\ 20 tr -d '\0') 21 } 22 23 usage() { 24 echo "usage: $0 -i <input_file> -t <template_file>" 25 } 26 27 missing_operand() { 28 echo "$0: missing operands" 29 usage 30 } 31 32 check_opt() { 33 local opt OPTIND 34 while getopts ":i:t:d:" opt; do 35 case $opt in 36 i) input="$OPTARG";; 37 t) templ="$OPTARG";; 38 d) dest_dir="$OPTARG";; 39 \?) printf "%s\n\n" "error: flag not found" && usage && exit 1;; 40 esac 41 done 42 43 [ $OPTIND -eq 1 ] && missing_operand && exit 2 44 shift "$((OPTIND-1))" 45 46 [ -z "$input" ] || [ ! -e "$input" ] &&\ 47 echo "error: no input file" && exit 1 48 [ -z "$templ" ] || [ ! -e "$templ" ] &&\ 49 echo "error: no template fshellile" && exit 1 50 [ -z "$dest_dir" ] && dest_dir="." 51 } 52 53 check_opt $@ 54 55 # deprecated format 56 # title=$(cat $input | head -n 3 | grep -oP '(?<=% title: \")(.*?)(?=\")') 57 # date=$(cat $input | head -n 3 | grep -oP '(?<=% date: \")(.*?)(?=\")') 58 59 title=$(cat $input | sed '/^%%/,/^%%/!d' | grep -oP '(?<=title: \")(.*?)(?=\")') 60 date=$(cat $input | sed '/^%%/,/^%%/!d' | grep -oP '(?<=date: \")(.*?)(?=\")') 61 pagetitle="Martin Klöckner's Webpage" 62 lang="en" 63 generator="Shell script" 64 template="$templ" 65 filename="$(basename $input | sed 's/\.[^.]*$//')" 66 # last_update="$(date -r $input '+%d-%b-%Y')" 67 last_update="$(LC_TIME=C git --no-pager log -n 1 --date=format:'%d-%b-%Y' --pretty=format:%cd $input)" 68 69 mkdir -p $dest_dir &> /dev/null 70 71 echo "title: $title" 72 echo "date: $date" 73 74 [ -z "$title" ] || [ -z "$date" ] \ 75 && echo "error: no metadata found on file $input" && exit 1 76 77 # generate body (skips lines starting with `%`, they're considered metadata) 78 # sed '/^% /d' $input | \ 79 # lowdown --html-no-head-ids --html-no-escapehtml --html-no-owasp > body.html 80 # sed '/^%%/,/^%%/' 81 sed '/^%%/,/^%%/d' $input |\ 82 lowdown --html-no-head-ids --parse-math\ 83 --html-no-skiphtml --html-no-escapehtml \ 84 --html-no-owasp > body.html 85 86 # puts id to <h1> tag and adds paragraph next to it with the article-date 87 echo "last update: \"$last_update\"" 88 if [ -n "$last_update" ]; then 89 last_update=" (last update $last_update)" 90 else 91 last_update="" 92 fi 93 94 sed -i -e 's/<h1>/<h1 id=article-title>/g' \ 95 -e "s/<\/h1>/<\/h1><p class=\"article-date\">$date$last_update<\/p>/"\ 96 body.html 97 98 sed -e "s/\$article-title\\$/$title/" -e "s/\$article-date\\$/$date/" \ 99 -e "s/\$pagetitle\\$/$pagetitle/" -e '/\$body\$/r./body.html' \ 100 -e "s/\$lang\\$/$lang/" -e "s/\$generator\\$/$generator/" \ 101 -e '/\$body\$/d' $template > "$dest_dir"/"$filename".html 102 103 logo_line=$(grep -zoP '<img.*?("article-icon").*?>' "$dest_dir"/"$filename".html | tr -d '\0') 104 title_line=$(grep -P '<h1.*?(article-title).*?>' "$dest_dir"/"$filename".html | tr -d '\0') 105 106 insert_div_article_title_w_logo() { 107 logo_line="$1" 108 title_line="$2" 109 110 div_article_title_w_logo "$logo_line" "$title_line" 111 112 sed -i -e "s^$title_line^\ 113 \ <div id=\"article-title-with-icon\">\ 114 \ <div id=\"article-icon\">\ 115 \ <img src=\"$logo_src\" title=\"$logo_title\" alt=\"$logo_alt\">\ 116 \ <\/div>\ 117 \ <h1 id=\"article-title\">$h1_title<\/h1>\ 118 \ <\/div>\ 119 \ <p class=\"article-date\">$date (last update $last_update)</p>^"\ 120 "$dest_dir"/"$filename".html 121 122 sed -i -E '/(^<p>).*?(article-icon).*?<\/p>/d' "$dest_dir"/"$filename".html 123 } 124 125 [ ! -z "$logo_line" ] && \ 126 insert_div_article_title_w_logo "$logo_line" "$title_line" 127 128 rm -v body.html &> /dev/null 129 130 ./scripts/syntax-highlight "$dest_dir"/"$filename".html > tmp.html 131 132 cp -v ./favicon.webp "$dest_dir"/ 133 134 mv -v tmp.html "$dest_dir"/index.html 135 136 echo "==> "$filename".html generated succesfully" 137 echo ""
