]> Lady’s Gitweb - Shushe/blobdiff - GNUmakefile
Support pagination
[Shushe] / GNUmakefile
index 90b769f39fcdaf71057caf6d2dcf2146d82830b4..2cb311f3ce7e09bc7ecd177f546311f97351ccb1 100644 (file)
@@ -28,6 +28,7 @@ override define makefileinfo
 ║│ • grep                                                     │║
 ║│ • git (optional)                                           │║
 ║│ • ln                                                       │║
+║│ • ls                                                       │║
 ║│ • mkdir (requires support for `-p´)                        │║
 ║│ • mv                                                       │║
 ║│ • od (requires support for `-t x1´)                        │║
@@ -109,6 +110,7 @@ FIND := find
 GIT := git
 GREP := grep
 LN := ln
+LS := ls
 MKDIR := mkdir
 MV := mv
 OD := od
@@ -173,7 +175,7 @@ THISDIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
 # By default, `find´ will ignore files which begin with a period and those which are likely to cause problems for `make´.
 EXTRAFINDRULES :=
 EXTRAFINDINCLUDERULES :=
-FINDRULES := ! '(' '(' -name '[.-]*' -o -name '*[][*?:|$$%\#\\; ]*' -o -name '*[)]' ')' -a -prune ')'$(if $(EXTRAFINDRULES), -a $(EXTRAFINDRULES),)
+FINDRULES := ! '(' '(' -name '[.-]*' -o -name '*[][*?:|$$%\#\\; ]*' -o -name '*"{*' -o -name '*}"*' -o -name '*[)]' ')' -a -prune ')'$(if $(EXTRAFINDRULES), -a $(EXTRAFINDRULES),)
 FINDINCLUDERULES := $(FINDRULES)$(if $(EXTRAFINDINCLUDERULES), -a $(EXTRAFINDINCLUDERULES),)
 
 # The list of magic files to use when determining media types.
@@ -219,6 +221,9 @@ endif
 #
 # • ‹ urn:fdc:ladys.computer:20231231:Shu1She4:mode:archive ›:
 #   Generates archive files from parse results.
+#
+# • ‹ urn:fdc:ladys.computer:20231231:Shu1She4:mode:paged ›:
+#   Generates paginated files from parse results.
 MODE := urn:fdc:ladys.computer:20231231:Shu1She4:mode:default
 
 # Set to a non·empty value to print all commands as they run.
@@ -270,8 +275,14 @@ override xpath = $(XMLLINT) --xpath $(call quote,$1) $(call quote,$2) > /dev/nul
 # (callable) Extract the value of the text nodes in the provided X·M·L document and print them to `stdout´.
 override extracttext = $(PRINTF) '%s' '<transform xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0"><output method="text" encoding="UTF-8"/></transform>' | $(XSLTPROC) --nonet --novalid - $(call quote,$1)
 
+# (callable) List the files in the provided directory which are associated with the provided filename, one per line.
+override associatedfiles = $(LS) -1 $(call quote,$1) | $(SED) '/.*"{.*}".*/!d;s/^\(.*\)"{.*}"\(.*\)$$/\1\2|&/' | $(GREP) -F -e $(call quote,$2|) | $(SED) 's/^.*|//'
+
+# (callable) Remove files associated with the provided file.
+override removeassociatedfiles = ASSOCIATED="$$($(call associatedfiles,$(dir $1),$(notdir $1)) | $(TR) '\n' ' ')"; if $(TEST) -n "$$ASSOCIATED"; then cd $(call quote,$(dir $1)) && $(PRINTF) '%s\n' "$$ASSOCIATED" | $(TR) ' ' '\n' | $(SED) $(call quote,/^$$/d;s/'/'"'"'/g;s/^/'/;s/$$/'/) | $(TR) '\n' ' ' | $(XARGS) $(RM); fi
+
 # (callable) Process the provided transformation result and output the result to the provided location, given the provided relative path.
-override processresultto = if $(call xpath,/*[local-name()="raw-text" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(RM) -f $(call quote,$2); $(call extracttext,$1) > $(call quote,$2); elif $(call xpath,/*[local-name()="base64-binary" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(RM) -f $(call quote,$2); $(call extracttext,$1) | $(TR) -d '\t\n\f\r ' | $(XARGS) -0 $(PRINTF) 'begin-base64 644 -\n%s\n====\n' | $(UUDECODE) -o /dev/stdout > $(call quote,$2); elif $(call xpath,/*[local-name()="archive" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(RM) -f $(call quote,$2); $(MAKE) -f $(call quote,$(abspath $(THISDIR)/GNUmakefile)) $(call quote,$2) NAME=$(call quote,$3) SRC=$(call quote,$1) BUILDDIR=$(call quote,$(BUILDDIR)/archive/$3) DESTDIR=$(call quote,$(patsubst %/,%,$(dir $2))) MODE='urn:fdc:ladys.computer:20231231:Shu1She4:mode:archive'; else $(RM) -f $(call quote,$2); $(XMLLINT) --nsclean $(call quote,$1) > $(call quote,$2); fi
+override processresultto = if $(call xpath,/*[local-name()="raw-text" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(call extracttext,$1) > $(call quote,$2); $(call removeassociatedfiles,$2); elif $(call xpath,/*[local-name()="base64-binary" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(call extracttext,$1) | $(TR) -d '\t\n\f\r ' | $(XARGS) -0 $(PRINTF) 'begin-base64 644 -\n%s\n====\n' | $(UUDECODE) -o /dev/stdout > $(call quote,$2); $(call removeassociatedfiles,$2); elif $(call xpath,/*[local-name()="archive" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(MAKE) -f $(call quote,$(abspath $(THISDIR)/GNUmakefile)) $(call quote,$2) NAME=$(call quote,$3) SRC=$(call quote,$1) BUILDDIR=$(call quote,$(BUILDDIR)/archive/$3) DESTDIR=$(call quote,$(patsubst %/,%,$(dir $2))) MODE='urn:fdc:ladys.computer:20231231:Shu1She4:mode:archive'; $(call removeassociatedfiles,$2); elif $(call xpath,//*[local-name()="page" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(MAKE) -f $(call quote,$(abspath $(THISDIR)/GNUmakefile)) $(call quote,$2) NAME=$(call quote,$3) SRC=$(call quote,$1) BUILDDIR=$(call quote,$(BUILDDIR)/paged/$3) DESTDIR=$(call quote,$(patsubst %/,%,$(dir $2))) MODE='urn:fdc:ladys.computer:20231231:Shu1She4:mode:paged'; else $(XMLLINT) --nsclean $(call quote,$1) > $(call quote,$2); $(call removeassociatedfiles,$2);  fi
 
 # ━ § BEGIN DEFAULT MAKE·FILE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
@@ -634,6 +645,7 @@ $(call installed,$(recursivefiles) $(installablefiles)) : $(DESTDIR)/% : $(BUILD
        @$(PRINTF) '%s\n' $(call quote,Installing </$*>…)
        $(silent)$(call ensuredirectory,$(dir $@))
        $(silent)$(CP) $(call quote,$<) $(call quote,$@)
+       $(silent)for associated in $$($(call associatedfiles,$(dir $<),$(notdir $<))); do $(PRINTF) '%s\n' "$$associated" | $(SED) 's/^\(.*\)"{\(.*\)}"\(.*\)$$/\1\2\3/' | $(XARGS) -0 $(PRINTF) '%s%s\n' $(call quote,$(dir $@)) | $(XARGS) -0 $(CP) $(call quote,$(dir $<))"$$associated"; done
 
 # ━ § BEGIN ARCHIVE MAKE·FILE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
@@ -689,6 +701,61 @@ $(DESTDIR)/% : $(foreach file,$(archivefiles),$(BUILDDIR)/files/$(file))
        $(silent)$(call ensuredirectory,$(dir $@))
        $(silent)cd $(call quote,$(BUILDDIR)/files); $(PRINTF) '%s\n' $(foreach file,$(archivefiles),$(call quote,$(file))) | $(PAX) -w > $(call quote,$(abspath $@))
 
+# ━ § BEGIN PAGED MAKE·FILE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+else ifeq ($(MODE),urn:fdc:ladys.computer:20231231:Shu1She4:mode:paged)
+
+# ─ ¶ Non‐Recipe Variable Definitions ─────────────────────────────────
+
+# Get the list of pages.
+ifneq ($(wildcard $(BUILDDIR)/index),)
+override pagefiles := $(patsubst ./pages/%,%,$(shell $(CAT) $(call quote,$(BUILDDIR)/index)))
+endif
+
+# ─ ¶ Recipe Variable Definitions ─────────────────────────────────────
+
+# ─ ¶ Phony Targets ───────────────────────────────────────────────────
+
+# ─ ¶ Special Targets ─────────────────────────────────────────────────
+
+# Reload this make·file if the pages have changed.
+$(THISDIR)/GNUmakefile : $(BUILDDIR)/index
+       $(silent)$(TOUCH) $(THISDIR)/GNUmakefile
+       @$(PRINTF) '%b\n' $(call quote,\0033[1mPages for </$(NAME)> updated. Restarting…\0033[22m)
+
+# ─ ¶ Build Targets ───────────────────────────────────────────────────
+
+# Build the extractor transform for extracting the pages of the paged source file.
+$(BUILDDIR)/extractor.xslt : $(SRC) $(THISDIR)/lib/paged2extractor.xslt
+       $(silent)$(call ensuredirectory,$(dir $@))
+       $(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) --stringparam NAME $(call quote,$(call notdir,$<)) $(call quote,$(THISDIR)/lib/paged2extractor.xslt) $(call quote,$<)
+
+# Use the extractor transform to extract the paged source file out into its pages.
+#
+# This target sleeps for 1 second to ensure the resulting index will always be newer than this make·file.
+$(BUILDDIR)/index : $(BUILDDIR)/extractor.xslt $(SRC)
+       @$(PRINTF) '%s\n' $(call quote,Extracting pages for </$(NAME)>…)
+       $(silent)$(SLEEP) 1
+       $(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) --writesubtree $(call quote,$(dir $@)) $(call quote,$<) $(call quote,$(SRC))
+
+# All other pages are extracted alongside the base.
+$(foreach file,$(pagefiles),$(BUILDDIR)/pages/$(file)) : $(BUILDDIR)/index ;
+
+# Process each page into its final form.
+$(foreach file,$(pagefiles),$(BUILDDIR)/public/$(file)) : $(BUILDDIR)/public/% : $(BUILDDIR)/pages/%
+       @$(PRINTF) '%s\n' $(call quote,Building page `$(subst }",,$(subst "{,,$*))´ of </$(NAME)>…)
+       $(silent)$(call ensuredirectory,$(dir $@))
+       $(silent)$(call processresultto,$<,$@,$*)
+
+# Archive all components in the file to the destination.
+#
+# This is a match‐anything target, with the assumption that this make·file is being called recursively from the default mode.
+$(DESTDIR)/% : $(foreach file,$(pagefiles),$(BUILDDIR)/public/$(file))
+       @$(PRINTF) '%s\n' $(call quote,Collecting pages for </$(NAME)>…)
+       $(silent)$(call ensuredirectory,$(dir $@))
+       $(silent)$(call removeassociatedfiles,$@)
+       $(silent)cp $(foreach file,$(pagefiles),$(call quote,$(BUILDDIR)/public/$(file))) $(DESTDIR)
+
 # ━ § END DEFINED MAKE·FILE MODES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
 else
This page took 0.027956 seconds and 4 git commands to generate.