# Multiple directories can be given so long as files with the same name do not exist in each.
#
# These can be inside of `SRCDIR´ directories if desired.
+#
+# This variable is also used by the two‐stage `MODE´, where it gives the include directory for the second stage.
INCLUDEDIR := $(foreach dir,$(SRCDIR),$(dir)/includes)
+# The directory which contains the data files.
+#
+# Only used in the two‐stage `MODE´, and defaults to that `MODE´ if this directory exists.
+# This directory is used as the include directory in the first stage.
+#
+# Multiple directories can be given so long as files with the same name do not exist in each.
+DATADIR :=
+
# The directory in which to generate temporary buildfiles.
#
-# This variable is also used by the archiving `MODE´.
+# This variable is also used by the archiving and two‐stage `MODE´s.
BUILDDIR := build
# The directory into which to output files on `make install´.
#
# By default, this is inferred from the variable `MAKEFILE_LIST´.
#
-# This variable is also used by the archiving `MODE´.
+# This variable is also used by the archiving and two‐stage `MODE´s.
THISDIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
# Configuration of `find´.
#
# By default, `find´ will ignore files which begin with a period and those which are likely to cause problems for `make´.
+#
+# These variables are also used by the two‐stage `MODE´.
EXTRAFINDRULES :=
EXTRAFINDINCLUDERULES :=
-FINDRULES := ! '(' '(' -name '[.-]*' -a ! -name '.' -o -name '*[][*?:|$$%\#\\; ]*' -o -name '*[)]' ')' -a -prune ')'$(if $(EXTRAFINDRULES), -a '(' $(EXTRAFINDRULES) ')',)
+FINDRULES := '!' '(' '(' -name '[.-]*' -a '!' -name '.' -o -name '*[][*?:|$$%\#\\; ]*' -o -name '*[)]' ')' -a -prune ')'$(if $(EXTRAFINDRULES), -a '(' $(EXTRAFINDRULES) ')',)
FINDINCLUDERULES := $(FINDRULES)$(if $(EXTRAFINDINCLUDERULES), -a '(' $(EXTRAFINDINCLUDERULES) ')',)
+# File extensions which indicate files in `SRCDIR´ which should be built as part of the first, rather than second, stage of the two‐stage `MODE´.
+DATAEXT := rdf
+
+# Rules for identifying files in `SRCDIR´ which should be built as part of the first, rather than second, stage of the two‐stage `MODE´.
+#
+# By default, this just constructs rules from `DATAEXT´.
+EXTRAFINDDATARULES :=
+FINDDATARULES := -name '.' $(foreach ext,$(DATAEXT), -o -name '$(subst ','"'"',[!.]*.$(ext))')$(if $(EXTRAFINDDATARULES), -a '(' $(EXTRAFINDDATARULES) ')',)
+
# The list of magic files to use when determining media types.
#
# Some are provided as part of this repository, but you can add more if you need different media type detection.
# The following modes are available :—
#
# • ‹ urn:fdc:ladys.computer:20231231:Shu1She4:mode:default ›:
-# The default mode; typical Shushe behaviours.
+# The default mode; typical ⛩📰 书社 behaviours.
#
# • ‹ urn:fdc:ladys.computer:20231231:Shu1She4:mode:archive ›:
# Generates archive files from parse results.
-MODE := urn:fdc:ladys.computer:20231231:Shu1She4:mode:default
+#
+# • ‹ urn:fdc:ladys.computer:20231231:Shu1She4:mode:_2stage ›:
+# Two‐stage build; runs ⛩📰 书社 twice.
+MODE := urn:fdc:ladys.computer:20231231:Shu1She4:mode:$(if $(DATADIR),$(shell if $(TEST) -d $(call quote,$(DATADIR)); then $(PRINTF) '%s\n' '_2stage'; else $(PRINTF) '%s\n' 'default'; fi),default)
# Set to a non·empty value to silence informative messages.
QUIET :=
.SUFFIXES : ;
# Don’t delete these files even if Make is stopped in the process of rebuilding them.
-.PRECIOUS : GNUmakefile ;
+.PRECIOUS : $(THISDIR)/GNUmakefile ;
# Phony rules; always consider these out·of·date.
-.PHONY : FORCE all default clean gone info install list listout uninstall $(call built,$(recursivefiles)) ;
+.PHONY : FORCE all clean gone help install list listout uninstall $(call built,$(recursivefiles)) ;
ifeq ($(notbuilding),)
# Reload this make·file if the magic file, parser, dependencies, or destinations have changed.
# ─ ¶ Special Targets ─────────────────────────────────────────────────
+# Don’t use any implicit rules.
+.SUFFIXES : ;
+
+# Don’t delete these files even if Make is stopped in the process of rebuilding them.
+.PRECIOUS : $(THISDIR)/GNUmakefile ;
+
# Reload this make·file if the archive components have changed.
$(THISDIR)/GNUmakefile : $(BUILDDIR)/index
$(silent)$(TOUCH) $(THISDIR)/GNUmakefile
$(silent)$(RM) -f -R $(call quote,$@)
$(silent)$(CD) $(call quote,$(BUILDDIR)/files); if $(call xpath,/*/@*[local-name()="expanded" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$(abspath $<)); then $(MKDIR) -p $(call quote,$(abspath $@)); $(PRINTF) '%s\n' $(foreach file,$(archivefiles),$(call quote,$(file))) | $(PAX) -r -w $(call quote,$(abspath $@)); else $(PRINTF) '%s\n' $(foreach file,$(archivefiles),$(call quote,$(file))) | $(PAX) -w -x ustar >|$(call quote,$(abspath $@)); fi
+# ━ § BEGIN TWO‐STEP MAKE·FILE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+else ifeq ($(MODE),urn:fdc:ladys.computer:20231231:Shu1She4:mode:_2stage)
+
+# ─ ¶ Non‐Recipe Variable Definitions ─────────────────────────────────
+
+override makefile := $(abspath $(THISDIR)/GNUmakefile)
+
+# (overridable) Options to use when calling ⛩📰 书社 the first time.
+shushedataopts := INCLUDEDIR=$(call quote,$(DATADIR)) BUILDDIR=$(call quote,$(BUILDDIR)/stage1) DESTDIR=$(call quote,$(BUILDDIR)/data) FINDRULES=$(call quote,$(FINDRULES) -a '(' $(FINDDATARULES) ')') FINDINCLUDERULES=$(call quote,$(FINDINCLUDERULES)) MODE='urn:fdc:ladys.computer:20231231:Shu1She4:mode:default'
+
+# (overridable) Options to use when calling ⛩📰 书社 the second time.
+shushesiteopts := INCLUDEDIR=$(call quote,$(INCLUDEDIR) $(BUILDDIR)/data) BUILDDIR=$(call quote,$(BUILDDIR)/stage2) FINDRULES=$(call quote,$(FINDRULES) -a '!' '(' $(FINDDATARULES) ')') FINDINCLUDERULES=$(call quote,$(FINDINCLUDERULES)) MODE='urn:fdc:ladys.computer:20231231:Shu1She4:mode:default'
+
+# ─ ¶ Recipe Variable Definitions ─────────────────────────────────────
+
+# ─ ¶ Phony Targets ───────────────────────────────────────────────────
+
+# Compile all files, or error if any are recursive.
+all : data
+ @$(MAKE) -f $(call quote,$(makefile)) $(shushesiteopts)
+
+# Destroy buildfiles.
+clean :
+ $(if $(BUILDDIR),$(silent)$(RM) -f -R $(call quote,$(BUILDDIR)/),)
+
+# Build the data and remove outdated data files.
+data : $(BUILDDIR)/data.out
+ @$(MAKE) -f $(call quote,$(makefile)) install $(shushedataopts)
+ $(silent)$(FIND) $(call quote,$(BUILDDIR)/data) '!' -exec $(GREP) -F -q -x '{}' $(call quote,$<) ';' -a '(' -type d -o -print ')' | $(xargsmultiquote) | $(XARGS) -E '' $(RM)
+
+# Destroy build directory and installed files.
+gone : clean uninstall ;
+
+# Install the compiled files into `DESTDIR´.
+install : all
+ @$(MAKE) -f $(call quote,$(makefile)) $@ $(shushesiteopts)
+ @$(MAKE) -f $(call quote,$(makefile)) $(foreach dest,$(patsubst $(BUILDDIR)/data/%,$(DESTDIR)/%,$(shell $(CAT) $(call quote,$(BUILDDIR)/data.out))),$(call quote,$(dest)))
+
+# List all source files and includes and their computed types.
+list listout : data
+ @$(MAKE) -f $(call quote,$(makefile)) $@ $(shushesiteopts)
+
+# Destroy installed files.
+uninstall :
+ @$(MAKE) -f $(call quote,$(makefile)) $@ $(shushesiteopts)
+
+# Add as a prerequisite to treat the target as tho it were phony.
+FORCE : ;
+
+# ─ ¶ Special Targets ─────────────────────────────────────────────────
+
+# Don’t use any implicit rules.
+.SUFFIXES : ;
+
+# Phony rules; always consider these out·of·date.
+.PHONY : FORCE all data clean gone install list listout uninstall ;
+
+# ─ ¶ Build Targets ───────────────────────────────────────────────────
+
+$(BUILDDIR)/data.out : FORCE
+ @$(MAKE) -f $(call quote,$(makefile)) $(shushedataopts)
+ @$(MAKE) -s -f $(call quote,$(makefile)) listout QUIET=1 $(shushedataopts) | $(TR) ' ' '\n' | $(xargsmultiquote) | $(XARGS) -E '' $(PRINTF) $(call quote,$(BUILDDIR)/data/%s\n) >$(call quote,$(BUILDDIR)/data.out)
+
+$(BUILDDIR)/stage1/% : FORCE
+ @$(MAKE) -f $(call quote,$(makefile)) $@ $(shushedataopts)
+
+$(BUILDDIR)/data/% : FORCE
+ @$(MAKE) -f $(call quote,$(makefile)) $@ $(shushedataopts)
+
+$(BUILDDIR)/stage2/% : data
+ @$(MAKE) -f $(call quote,$(makefile)) $@ $(shushesiteopts)
+
+$(DESTDIR)/% : data
+ $(if $(shell $(GREP) -F -x $(call quote,$(BUILDDIR)/data/$*) $(BUILDDIR)/data.out),$(call inform $(PRINTF) '%s\n' $(call quote,Copying over </$*>…) >&2)$(newline),$(CP) $(call quote,$(BUILDDIR)/data/$*) $(call quote,$@),@$(MAKE) -f $(call quote,$(makefile)) $@ $(shushesiteopts))
+
# ━ § END DEFINED MAKE·FILE MODES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
else