#!/bin/sh trampoline=; define()(:) # -*- makefile -*- ########################################### ## C H U M : Code Htmlizer Using Make(1) ## ## Make a website out of a code repo, ez ## ## Quickstart: cd project; vi .chum ---> ## ## [change variables given below]. see ## ## README for details ##################### ########################################### define trampoline if command -v gmake >/dev/null 2>&1 then exec gmake -kr -f "$0" "$@" else exec make -kr -f "$0" "$@" fi endef ####################### code starts here ## # Project metadata NAME = $(notdir $(PWD)) AUTHOR = DESCRIPTION = # Build config OUTDIR = out SERVER = @printf 'Generated files are in %s/\n' VDUMPF = # used by chums # Project files SOURCES = README = READMEFILTER = cat LICENSE = TARBALL = $(OUTDIR)/$(NAME).tar.gz STATICS = # Project web stuff REMOTE = URL_ROOT = / URL_CLONE = URL_DOWNLOAD = $(URL_ROOT)$(notdir $(TARBALL)) define TEMPLATE = {{FILENAME}}

{{DIRECTORY}}/{{FILENAME}}

{{DESCRIPTION}}
{{CONTENT}}
endef define STYLE = .ll{display:inline-block;width:3em; padding-right:0.5em;margin-right:0.5em;} endef # Internal stuff -include .chum _FILES = $(README) $(LICENSE) $(SOURCES) define _CHUM BEGIN { if (template) TEMPLATE = template else TEMPLATE = "

{{FILENAME}}

{{CONTENT}}" TMPLV["STYLE"] = style TMPLV["CLONE"] = "$(URL_CLONE)" TMPLV["DOWNLOAD"] = "$(URL_DOWNLOAD)" TMPLV["DESCRIPTION"] = "$(DESCRIPTION)" TMPLV["AUTHOR"] = "$(AUTHOR)" TMPLV["ROOT"] = "$(URL_ROOT)" "pwd" | getline TMPLV["DIRECTORY"]; close("pwd") TMPLV["DIRECTORY"] = outfn(TMPLV["DIRECTORY"], 3) for (f in ARGV) if (f && system("test -f " ARGV[f])) delete ARGV[f] } FNR == 1 { if (NR > 1) finish() OUTFILE = outfn(FILENAME) sub(/^\.\.?\//, "", FILENAME) TMPLV["FILENAME"] = FILENAME TMPLV["OUTFILE"] = OUTFILE FILES[f++] = FILENAME printf("%-24s -> %s\n", FILENAME, OUTFILE) if (system("mkdir -p $(OUTDIR)/" outfn(FILENAME, 2))) die(1, "Can't make directory: " outfn(FILENAME, 2)) if (!system("cp " FILENAME " " outfn(FILENAME, 4) ".txt")) TMPLV["RAWFILE"] = outfn(FILENAME, 3) ".txt" OUTSTR = "" } END { if (dead) exit dead finish() doindex() copy_statics() } { gsub(/&/, "\\&"); gsub(//, "\\>") OUTSTR = OUTSTR sprintf("" \ "%d" \ "%s\n", FNR, FNR, FNR, $$0) } function slurp (file, o) { if (!file) return 0 while ((getline < file) > 0) o = o (o?"\n":"") $$0 return o } function outfn (file, mod) { if (!mod) { # foo.txt => $(OUTDIR)/foo.txt.html sub(/^/, "$(OUTDIR)/", file) sub(/$$/, ".html", file) } else if (mod == 1) { # foo.txt => foo.txt.html sub(/$$/, ".html", file) } else if (mod == 2) { # foo.txt => / ; foo/bar.txt => foo/ if (!sub(/\/[^\/]*$$/, "/", file)) file = "/" } else if (mod == 3) { # foo/bar.txt => bar.txt (basename) sub(/.*\//, "", file) } else if (mod == 4) { # foo/bar.txt => $(OUTDIR)/foo/bar.txt sub(/^/, "$(OUTDIR)/", file) } return file } function template_replace (str) { if (OUTFILE == "$(OUTDIR)/index.html") { gsub(//, "", str) } else { gsub(//, "", str) } for (ts in TMPLV) { gsub("{{"ts"}}", TMPLV[ts], str) } gsub(/&/, "\\\\&", OUTSTR) sub("{{CONTENT}}", OUTSTR, str) return str } function finish () { sub("\n$$", "", OUTSTR) if (OUTFILE == "$(OUTDIR)/index.html") { TMPLV["FILENAME"] = TMPLV["DIRECTORY"] OUTSTR = "
" if ("$(README)") { OUTSTR = OUTSTR "
" while ((("$(READMEFILTER) $(README)") | getline) > 0) OUTSTR = OUTSTR "\n" $$0 OUTSTR = OUTSTR "
" } } else { OUTSTR = "
" OUTSTR "
" } print(template_replace(TEMPLATE)) > OUTFILE close(OUTFILE) } function doindex () { OUTFILE = "$(OUTDIR)/index.html" OUTSTR = "" printf("[build] %s\n", OUTFILE) for (f in FILES) { OUTSTR = OUTSTR \ sprintf("
  • %s
  • \n", outfn(FILES[f], 1), FILES[f]) } finish() } function die(code, message) { print(message) > "/dev/stderr" dead = code exit code } function copy_statics () { split(static, STATICS, / */) for (s in STATICS) { printf("Copying %s\n", STATICS[s]) if (system("cp " STATICS[s] " $(OUTDIR)/" outfn(STATICS[s], 3))) die(2, "Can't copy static file: " STATICS[s]) } } endef # Internal recipes $(OUTDIR): export _TMPL:=-vtemplate=$(TEMPLATE) $(OUTDIR): export _STYLE:=-vstyle=$(STYLE) $(OUTDIR): export _STATICS:=-vstatic=$(STATICS) $(OUTDIR): export _CHUM:=$(_CHUM) $(OUTDIR): $(_FILES) .chum @awk "$${_TMPL}" "$${_STYLE}" "$${_STATICS}" "$${_CHUM}" $(_FILES) ifdef VDUMPF printf '%s\t%s\t%s\n' $(NAME) $(URL_ROOT) "$(DESCRIPTION)" >> $(VDUMPF) endif $(TARBALL): $(_FILES) .chum @printf '[build] %s\n' $(TARBALL) @tar -cf $@ $(_FILES) .PHONY: build serve publish clean build: $(OUTDIR) $(TARBALL) serve: $(OUTDIR) $(SERVER) $(OUTDIR) publish: $(TARBALL) rsync -zaP $(OUTDIR)/ $(REMOTE)/ clean: rm -rf $(OUTDIR)