git » homepage.git » commit 541ee14

tools improvements

author Alan Dipert
2025-10-08 20:21:01 UTC
committer Alan Dipert
2025-10-08 20:21:01 UTC
parent 6adf424946e00d146d80fb11f3c0db4e9e50bfa7

tools improvements

Makefile +11 -16
tools/build_page.sh +91 -0
tools/gen_index.sh +7 -2

diff --git a/Makefile b/Makefile
index b3382c1..9e7c942 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,9 @@ CSS := tpl/style.css
 MD2HTML ?= /usr/bin/cmark-gfm
 CMARK_FLAGS := --to html --extension table --validate-utf8 --unsafe
 BUILDINFO := tools/buildinfo.sh
+BUILDINFO_STAMP := $(OUT)/.buildinfo
+GIT_HEAD_REF := $(strip $(shell git symbolic-ref -q HEAD 2>/dev/null))
+GIT_HEAD_FILE := $(if $(GIT_HEAD_REF),.git/$(GIT_HEAD_REF),.git/HEAD)
 INDEX_HTML := $(OUT)/Index.html
 DEPLOY_HOST ?= arsien23i2@dreamhost:tailrecursion.com/~alan
 
@@ -16,6 +19,9 @@ HTML := $(patsubst $(SRC)/%.md,$(OUT)/%.html,$(MD_FILES))
 
 all: assets $(OUT)/style.css $(HTML) $(INDEX_HTML)
 
+$(BUILDINFO_STAMP): $(BUILDINFO) .git/HEAD $(GIT_HEAD_FILE) | $(OUT)
+	$(BUILDINFO) > $@
+
 $(OUT)/style.css: $(CSS)
 	mkdir -p $(OUT)
 	cp $(CSS) $@
@@ -23,27 +29,16 @@ $(OUT)/style.css: $(CSS)
 $(OUT):
 	mkdir -p $(OUT)
 
-$(OUT)/%.html: $(SRC)/%.md $(HEAD) $(FOOT) tools/mdlink2html.awk $(BUILDINFO) | $(OUT)
-	mkdir -p $(@D)
-	awk -f tools/mdlink2html.awk $< > $@.rewritten.md
-	$(MD2HTML) $(CMARK_FLAGS) $@.rewritten.md > $@.body.html
-	root_prefix="$$(dirname "$@" | sed -e 's#^$(OUT)##' -e 's#^/##' -e 's#[^/][^/]*#../#g')"; \
-		page_title=$$(basename "$<" .md); \
-		build_info=$$($(BUILDINFO)); \
-		build_info_esc=$$(printf '%s\n' "$$build_info" | sed 's/[\\/\&]/\\&/g'); \
-		page_title_esc=$$(printf '%s\n' "$$page_title" | sed 's/[\\/\&]/\\&/g'); \
-		sed -e "s|@ROOT@|$${root_prefix}|g" -e "s|@BUILDINFO@|$${build_info_esc}|g" -e "s|@TITLE@|$${page_title_esc}|g" $(HEAD) > $@.head.html; \
-		sed -e "s|@ROOT@|$${root_prefix}|g" -e "s|@BUILDINFO@|$${build_info_esc}|g" -e "s|@TITLE@|$${page_title_esc}|g" $(FOOT) > $@.foot.html; \
-		cat $@.head.html $@.body.html $@.foot.html > $@; \
-		rm -f $@.head.html $@.foot.html
-	rm -f $@.rewritten.md $@.body.html
+$(OUT)/%.html: $(SRC)/%.md $(HEAD) $(FOOT) tools/mdlink2html.awk tools/build_page.sh $(BUILDINFO_STAMP) | $(OUT)
+	OUT_DIR="$(OUT)" MD2HTML="$(MD2HTML)" CMARK_FLAGS="$(CMARK_FLAGS)" \
+	tools/build_page.sh "$@" "$<" "$(HEAD)" "$(FOOT)" "$(BUILDINFO_STAMP)" tools/mdlink2html.awk
 
 assets:
 	mkdir -p $(OUT)
 	rsync -a --include='*/' --exclude='*.md' --exclude='*.MD' --prune-empty-dirs $(SRC)/ $(OUT)/
 
-$(INDEX_HTML): $(HTML) tools/gen_index.sh tools/index_list.awk $(HEAD) $(FOOT) $(BUILDINFO) | $(OUT)
-	tools/gen_index.sh $@ $(SRC)
+$(INDEX_HTML): $(HTML) tools/gen_index.sh tools/index_list.awk $(HEAD) $(FOOT) $(BUILDINFO_STAMP) | $(OUT)
+	tools/gen_index.sh $@ $(SRC) $(BUILDINFO_STAMP)
 
 deploy: check-git-clean assets all
 	@if [ -z "$(DEPLOY_HOST)" ]; then \
diff --git a/tools/build_page.sh b/tools/build_page.sh
new file mode 100755
index 0000000..ff662a4
--- /dev/null
+++ b/tools/build_page.sh
@@ -0,0 +1,91 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+usage() {
+  cat <<'USAGE'
+Usage: build_page.sh OUTPUT INPUT HEAD FOOT BUILDINFO MDLINK_AWK
+
+Render a Markdown INPUT file into OUTPUT HTML using provided HEAD and FOOT templates.
+
+Environment:
+  MD2HTML      Path to the cmark-gfm executable (default: /usr/bin/cmark-gfm)
+  CMARK_FLAGS  Flags passed to cmark-gfm (default matches Makefile)
+  OUT_DIR      Root output directory used to compute relative links (default: out)
+USAGE
+}
+
+if [[ $# -ne 6 ]]; then
+  usage >&2
+  exit 1
+fi
+
+output=$1
+input_md=$2
+head_tpl=$3
+foot_tpl=$4
+buildinfo_stamp=$5
+mdlink_awk=$6
+
+MD2HTML=${MD2HTML:-/usr/bin/cmark-gfm}
+CMARK_FLAGS=${CMARK_FLAGS:---to html --extension table --validate-utf8 --unsafe}
+OUT_DIR=${OUT_DIR:-out}
+
+tmpdir=$(mktemp -d)
+cleanup() {
+  rm -rf "$tmpdir"
+}
+trap cleanup EXIT INT TERM
+
+mkdir -p "$(dirname "$output")"
+
+rewritten_md="$tmpdir/rewritten.md"
+body_html="$tmpdir/body.html"
+head_html="$tmpdir/head.html"
+foot_html="$tmpdir/foot.html"
+
+awk -f "$mdlink_awk" "$input_md" > "$rewritten_md"
+
+# shellcheck disable=SC2206 # we intentionally split CMARK_FLAGS into array words
+read -r -a cmark_args <<< "$CMARK_FLAGS"
+"$MD2HTML" "${cmark_args[@]}" "$rewritten_md" > "$body_html"
+
+page_title=$(basename "$input_md" .md)
+build_info=$(cat "$buildinfo_stamp")
+
+escape_sed() {
+  printf '%s\n' "$1" | sed 's/[\\/&]/\\&/g'
+}
+
+build_info_esc=$(escape_sed "$build_info")
+page_title_esc=$(escape_sed "$page_title")
+
+relative_path="${output#$OUT_DIR}"
+relative_path="${relative_path#/}"
+if [[ "$relative_path" == "$output" ]]; then
+  relative_path=""
+fi
+relative_dir="$relative_path"
+if [[ -n "$relative_dir" ]]; then
+  relative_dir=${relative_dir%/*}
+  if [[ "$relative_dir" == "$relative_path" ]]; then
+    relative_dir=""
+  fi
+fi
+
+root_prefix=""
+if [[ -n "$relative_dir" && "$relative_dir" != "." ]]; then
+  IFS='/' read -r -a segments <<< "$relative_dir"
+  for _ in "${segments[@]}"; do
+    root_prefix+="../"
+  done
+fi
+
+sed -e "s|@ROOT@|$root_prefix|g" \
+    -e "s|@BUILDINFO@|$build_info_esc|g" \
+    -e "s|@TITLE@|$page_title_esc|g" "$head_tpl" > "$head_html"
+
+sed -e "s|@ROOT@|$root_prefix|g" \
+    -e "s|@BUILDINFO@|$build_info_esc|g" \
+    -e "s|@TITLE@|$page_title_esc|g" "$foot_tpl" > "$foot_html"
+
+cat "$head_html" "$body_html" "$foot_html" > "$output"
diff --git a/tools/gen_index.sh b/tools/gen_index.sh
index fa0440c..453524e 100755
--- a/tools/gen_index.sh
+++ b/tools/gen_index.sh
@@ -1,13 +1,18 @@
 #!/usr/bin/env bash
 set -euo pipefail
 
-output=${1:?"usage: gen_index.sh out/Index.html [src-dir]"}
+output=${1:?"usage: gen_index.sh out/Index.html [src-dir] [buildinfo-file]"}
 src_dir=${2:-md}
+buildinfo_file=${3:-}
 script_dir=$(cd "$(dirname "$0")" && pwd)
 root_dir=$(cd "$script_dir/.." && pwd)
 cd "$root_dir"
 
-build_info=$(tools/buildinfo.sh)
+if [[ -n "$buildinfo_file" && -f "$buildinfo_file" ]]; then
+  build_info=$(<"$buildinfo_file")
+else
+  build_info=$(tools/buildinfo.sh)
+fi
 build_info_esc=$(printf '%s\n' "$build_info" | sed 's/[\/&]/\\&/g')
 css_prefix=""
 page_title="Index"