From d641dd302a643877f1d6eef364011180180f93fb Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Mon, 8 Aug 2022 10:54:08 -0500 Subject: Uh, thangs --- ht | 127 +++++++++++++++++++++++++++++++++++++++++------------------------ ht.awk | 26 ++++++++++++-- 2 files changed, 104 insertions(+), 49 deletions(-) diff --git a/ht b/ht index c8cef5c..39f86d0 100755 --- a/ht +++ b/ht @@ -35,31 +35,43 @@ EOF main() { configure "$@" shift $((OPTIND - 1)) + test $# -eq 0 && usage 1 + prepare static_copy for input; do - page_write "$PAGE_TEMPLATE" "$input" + case "$input" in + _* | */_*) continue ;; + *) page_write "$PAGE_TEMPLATE" "$input" ;; + esac done - if [ -n "$INDEXEACH" ]; then + if okp && [ -n "$INDEXEACH" ]; then index_write "$INDEX_TEMPLATE" "$INDEXEACH" "$OUTD/$INDEXNAME" fi - if [ -n "$FEEDEACH" ]; then + if okp && [ -n "$FEEDEACH" ]; then index_write "$FEED_TEMPLATE" "$FEEDEACH" "$OUTD/$FEEDNAME" fi + printf 'Done. ' >&2 - if test -f "$WORKD/ok"; then + if okp; then eprint "No errors reported." else eprint "There were errors." fi } +htawk_resolve() { + if ! command -v ht.awk 2>/dev/null; then + print ./ht.awk + fi +} + configure() { OUTD="${HT_OUT_DIR:-./out}" WORKD="${HT_WORKD:-/tmp/ht}" - PROC="${HT_PROC:-./ht.awk}" # XXX: Needs better resolution + PROC="${HT_PROC:-$(htawk_resolve)}" BASEURL="${HT_BASEURL:-https://example.com}" PAGE_TEMPLATE="${HT_PAGE_TEMPLATE:-./page.tmpl.htm}" INDEX_TEMPLATE="${HT_INDEX_TEMPLATE:-./index.tmpl.htm}" @@ -94,7 +106,7 @@ configure() { fi # shellcheck disable=2034 # BASEURL is used in templates - while getopts hBo:w:p:i:I:f:F:u:s:S: opt; do + while getopts ho:w:p:P:i:I:f:F:u:Bs:S: opt; do case "$opt" in h) usage ;; o) OUTD="$OPTARG" ;; @@ -113,16 +125,17 @@ configure() { esac done + STATICOUT="${HT_STATIC_OUTPUT_DIR:-${OUTD}/static}" INDEX="$WORKD/index.txt" } prepare() { test -n "$WORKD" && rm -rf "$WORKD" mkdir -p "$OUTD" "$WORKD" - test -x "$PROC" || { + if ! test -x "$PROC"; then eprint "Can't find processor: $PROC" exit 2 - } + fi touch "$WORKD/ok" } @@ -136,6 +149,14 @@ eprint() { print "$@" >&2 } +okp() { + test -f "$WORKD/ok" +} + +notok() { + rm "$WORKD/ok" 2>/dev/null +} + olderp() { # olderp REF OTHER # Is REF older than OTHER ? Necessary b/c test -ot is not POSIX. a="$1" @@ -174,6 +195,7 @@ uptodate() { # uptodate FILE DEPENDENCIES... # && return file="$1" shift for dep in "$@"; do + olderp "$dep" "$file" && uptodate=0 done return $uptodate @@ -182,28 +204,21 @@ uptodate() { # uptodate FILE DEPENDENCIES... # && return ### File conversion template_expand() { # template_expand TEMPLATES... - end="tmpl_$(date +%s)_${count:=0}" - eval "$( - print "cat <<$end" - cat "$@" - print - print "$end" - )" - count=$((count + 1)) + if test "$noproc"; then + cat - + else + end="tmpl_$(date +%s)_${count:=0}" + eval "$( + print "cat <<$end" + cat "$@" + print + print "$end" + )" && count=$((count + 1)) + fi } -meta_save() { # meta_save [-c COMMENTCH] [-m METACH] META_FILE < INPUT - COMMENTCH=';' - METACH='@' - while getopts c:m: opt; do - case "$opt" in - c) COMMENTCH="$OPTARG" ;; - m) METACH="$OPTARG" ;; - *) ;; - esac - done - shift $((OPTIND - 1)) - sed -n "s/^${COMMENTCH}${COMMENTCH}${METACH}//p" 2>/dev/null | tee "$1" +meta_save() { # meta_save META_FILE < INPUT + sed -n "s/^;;@//p" 2>/dev/null | tee "$1" } meta_clear() { # meta_clear META_FILE @@ -219,27 +234,38 @@ meta_clear() { # meta_clear META_FILE page_write() { # html_write TEMPLATE INPUT template="$1" file="$2" + noproc= # File can set `noproc' in their metadata to not be processed. + + if ! test -f "$file"; then + eprint "ERROR: File doesn't exist: $file" + notok + return 1 + fi fn="${file##*/}" fn="${fn%%.*}" out="${OUTD}/${fn}/index.html" mkdir -p "${out%/*}" meta="$WORKD/${fn}.meta" + body="$WORKD/${fn}.body" eval "$(meta_save "$meta" <"$file")" stat -c "%Y ${fn} $meta" "$file" >>"$INDEX" - uptodate "$out" "$template" "$file" && return + # uptodate "$out" "$template" "$file" && return eprint "Page: $file -> $out" - if - ! "$PROC" "$file" | - tee "$WORKD/${fn}.body" | - template_expand "$template" >"$out" - then - eprint "$file -> $out ... ERROR!" - rm "$WORKD/ok" - return + test "$noproc" || "$PROC" "$file" >"$body" + if ! [ -f "$body" ]; then + eprint "ERROR: Conversion: $file" + notok + return 2 + fi + test "$noproc" || body="$(template_expand "${body}")" + if ! template_expand "$template" >"$out"; then + eprint "ERROR: Expansion: $file" + notok + return 3 fi meta_clear "$meta" } @@ -249,8 +275,10 @@ index_write() { # index_write TEMPLATE EACH OUTFILE each="$2" out="$3" - test -f "$INDEX" || return 1 - uptodate "$out" "$template" "$INDEX" && return + if ! test -f "$INDEX"; then + : >"$INDEX" + fi + # uptodate "$out" "$template" "$INDEX" && return eprint "Index: $out" # shellcheck disable=2034 # file and time can be used in `each' @@ -258,9 +286,11 @@ index_write() { # index_write TEMPLATE EACH OUTFILE while IFS=' ' read -r time file meta; do # shellcheck disable=1090 . "$meta" + # shellcheck disable=2154 # noindex is a file var + [ "$noindex" ] && continue if ! item="$(eval print "\"$each\"")"; then eprint "ERROR: couldn't add '$file' to $out" - rm "$WORKD/ok" + notok fi print "$item" meta_clear "$meta" @@ -271,14 +301,17 @@ index_write() { # index_write TEMPLATE EACH OUTFILE ### Static files static_copy() { # static_copy - test -d "$STATICD" || return 1 - if command -v rsync 2>/dev/null; then - eprint rsync -avz "$STATICD/" "$STATICOUT/" - rsync -avz "$STATICD/" "$STATICOUT/" - else - eprint cp -r "$STATICD"/* "$STATICOUT/" - cp -r "$STATICD"/* "$STATICOUT/" + if ! test -d "$STATICD"; then + return 1 fi + mkdir -p "$STATICOUT" + for f in "$STATICD"/*; do + if [ -d "$f" ]; then + cp -r "$f" "$STATICOUT/" + else + cp "$f" "$STATICOUT/" + fi + done } ### Do the thing diff --git a/ht.awk b/ht.awk index 7581cdb..c15ccc0 100755 --- a/ht.awk +++ b/ht.awk @@ -62,6 +62,10 @@ $0 ~ ("^" COMMENT_DELIM) { } else { sep = "\n" } + # Sanitize HTML + gsub(/&/, "\\\\\\&", $0) + gsub(//, "\\\\\\>", $0) # Loop through BLOCK_TYPES for (bt in BLOCK_TYPES) { if (match($0, "^" bt "[ \t]*")) { @@ -105,8 +109,26 @@ $0 ~ ("^" COMMENT_DELIM) { if (match($0, "^" lt "[ \t]*")) { $0 = substr($0, RSTART + RLENGTH) templ = LINE_TYPES[lt] - while (match(templ, /\$[0-9]+/)) { - sub(/\$[0-9]+/, $(substr(templ, RSTART + 1, RLENGTH - 1)), templ) + while (match(templ, /\$[0-9-]+/)) { + if (substr(templ, RSTART + 1, 1) == "-") { + # Up to $field + f = "" + n = substr(templ, RSTART + 2, RLENGTH - 2) + for (i = 1; i <= n; i++) { + f = f (f ? " " : "") $i + } + sub(/\$[0-9-]+/, f, templ) + } else if (substr(templ, RSTART + RLENGTH - 1, 1) == "-") { + # $Field to end + f = "" + n = substr(templ, RSTART + 1, RLENGTH - 2) + for (i = n; i <= NF; i++) { + f = f (f ? " " : "") $i + } + sub(/\$[0-9-]+/, f, templ) + } else { + sub(/\$[0-9]+/, $(substr(templ, RSTART + 1, RLENGTH - 1)), templ) + } } $0 = templ } -- cgit 1.4.1-21-gabe81