⛩️📰 书社 might be called from another script or make·file, which
might have built files of its own. It would be a pain if each parent
script needed to copy all the source files into a new build directory
at every step, and it’s much easier to just allow ⛩️📰 书社 to support
multiple source directories (one for the original sources, and
additional ones for any files built by other scripts).
Naturally, ⛩️📰 书社 can’t support the same file subpath across
multiple source directories, as these would compile to the same place.
This commit tries to migitage this by just taking the first match, but
it hasn’t been tested and the behaviour should formally be considered
undefined.
XSLTPROC := xsltproc
# The directory which contains the source files.
XSLTPROC := xsltproc
# The directory which contains the source files.
+#
+# Multiple directories can be given so long as files with the same name
+# do not exist in each.
SRCDIR := sources
# The directory which contains “includes”: Files which may be included
# in other files but for which no final output will be generated.
#
SRCDIR := sources
# The directory which contains “includes”: Files which may be included
# in other files but for which no final output will be generated.
#
-# This can be inside of `SOURCES_DIRECTORY´ if desired.
+# 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.
INCLUDEDIR := sources/includes
# The directory in which to generate temporary buildfiles.
INCLUDEDIR := sources/includes
# The directory in which to generate temporary buildfiles.
# expressions.
override sedesc = $(subst /,[/],$(subst $$,\$$,$(subst *,\*,$(subst .,\.,$(subst [,\[,$(subst ^,\^,$(subst \,\\,$1)))))))
# expressions.
override sedesc = $(subst /,[/],$(subst $$,\$$,$(subst *,\*,$(subst .,\.,$(subst [,\[,$(subst ^,\^,$(subst \,\\,$1)))))))
-# Collect all of the applicable includes from the includes directory.
+# (overridable) Collect all of the applicable includes from the
+# includes directory.
sourceincludes := $(shell $(FIND) $(FINDOPTS) $(INCLUDEDIR) -type f '(' $(FINDRULES) ')')
sourceincludes := $(shell $(FIND) $(FINDOPTS) $(INCLUDEDIR) -type f '(' $(FINDRULES) ')')
-# Collect all of the applicable source files from the source directory,
-# removing any which are also includes.
+# (overridable) Collect all of the applicable source files from the
+# source directory, removing any which are also includes.
sourcefiles := $(filter-out $(sourceincludes),$(shell $(FIND) $(FINDOPTS) $(SRCDIR) -type f '(' $(FINDRULES) ')'))
# Figure out the file type of each source file and source include.
sourcefiles := $(filter-out $(sourceincludes),$(shell $(FIND) $(FINDOPTS) $(SRCDIR) -type f '(' $(FINDRULES) ')'))
# Figure out the file type of each source file and source include.
# (callable) Get the identifier for the given transform.
override id = $(or $(shell $(XMLLINT) --xpath '/*/*[local-name()="id" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"]/text()[1]' $1),$(basename $(notdir $1)) | $(SED))
# (callable) Get the identifier for the given transform.
override id = $(or $(shell $(XMLLINT) --xpath '/*/*[local-name()="id" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"]/text()[1]' $1),$(basename $(notdir $1)) | $(SED))
+# (callable) Get the local path for the given source file.
+override sourcepath = $(firstword $(foreach directory,$(SRCDIR),$(if $(filter $(directory)/%,$1),$(patsubst $(directory)/%,%,$1),)))
+
+# (callable) Get the local path for the given include.
+override includepath = $(firstword $(foreach directory,$(INCLUDEDIR),$(if $(filter $(directory)/%,$1),$(patsubst $(directory)/%,%,$1),)))
+
# (callable) Get base64 data u·r·i’s for the given files.
override datauri = $(foreach file,$1,data:$(call typeoffile,$(file));base64,$(shell $(UUENCODE) -m -r $(call quote,$(file)) _ | tr -d ' \n'))
# (callable) Get local leiris for the given files.
# (callable) Get base64 data u·r·i’s for the given files.
override datauri = $(foreach file,$1,data:$(call typeoffile,$(file));base64,$(shell $(UUENCODE) -m -r $(call quote,$(file)) _ | tr -d ' \n'))
# (callable) Get local leiris for the given files.
-override localuri = $(foreach file,$1,$(if $(filter $(file),$(sourceincludes)),$(patsubst $(INCLUDEDIR)/%,about:shushe?include=%,$(file)),$(patsubst $(SRCDIR)/%,about:shushe?source=%,$(file))))
+override localuri = $(foreach file,$1,$(if $(filter $(file),$(sourceincludes)),about:shushe?include=$(call includepath,$(file)),about:shushe?source=$(call sourcepath,$(file))))
+
+# Pair each source file and include with its local u·r·i.
+override sourcelocalpair = $(foreach file,$(sourcefiles) $(sourceincludes),$(file)`$(call localuri,$(file)))
# (callable) Get the source files for the given local leiris.
# (callable) Get the source files for the given local leiris.
-override sourcefile = $(foreach file,$1,$(if $(filter about:shushe?include=%,$(file)),$(patsubst about:shushe?include=%,$(INCLUDEDIR)/%,$(file)),$(patsubst about:shushe?source=%,$(SRCDIR)/%,$(file))))
+override sourcefile = $(foreach local,$1,$(patsubst %`$(local),%,$(filter %`$(local),$(sourcelocalpair))))
# Adds a requirement on `$(BUILDDIR)/.update-types´ if the file is
# present.
# Adds a requirement on `$(BUILDDIR)/.update-types´ if the file is
# present.
# (callable) Get the location of the transformed X·M·L files for the
# given source files.
# (callable) Get the location of the transformed X·M·L files for the
# given source files.
-override parsed = $(foreach file,$1,$(if $(filter $(file),$(sourceincludes)),$(patsubst $(INCLUDEDIR)/%,$(BUILDDIR)/includes/%,$(file)),$(patsubst $(SRCDIR)/%,$(BUILDDIR)/sources/%,$(file))))
+override parsed = $(foreach file,$1,$(if $(filter $(file),$(sourceincludes)),$(BUILDDIR)/includes/$(call includepath,$(file)),$(BUILDDIR)/sources/$(call sourcepath,$(file))))
+
+# Pair each source file and include with its parsed location.
+override sourceparsedpair = $(foreach file,$(sourcefiles) $(sourceincludes),$(file)`$(call parsed,$(file)))
+
+# (callable) Get the source files for the given parsed file.
+override unparsed = $(foreach file,$1,$(patsubst %`$(file),%,$(filter %`$(file),$(sourceparsedpair))))
ifneq ($(wildcard $(BUILDDIR)/dependencies),)
# Pair each file with a list of dependencies for it.
ifneq ($(wildcard $(BUILDDIR)/dependencies),)
# Pair each file with a list of dependencies for it.
override compilablefiles := $(filter-out $(assetfiles) $(recursivefiles),$(sourcefiles))
# (callable) Get the compiled locations for the given source files.
override compilablefiles := $(filter-out $(assetfiles) $(recursivefiles),$(sourcefiles))
# (callable) Get the compiled locations for the given source files.
-override compiled = $(patsubst $(SRCDIR)/%,$(BUILDDIR)/public/%,$(1))
+override compiled = $(foreach file,$1,$(BUILDDIR)/public/$(call sourcepath,$(file)))
+
+# Pair each source file and include with its compiled location.
+override sourcecompiledpair = $(foreach file,$(sourcefiles) $(sourceincludes),$(file)`$(call compiled,$(file)))
+
+# (callable) Get the source files for the given compiled file.
+override uncompiled = $(foreach file,$1,$(patsubst %`$(file),%,$(filter %`$(file),$(sourcecompiledpair))))
# (callable) Get the installed locations for the given source files.
# (callable) Get the installed locations for the given source files.
-override installed = $(patsubst $(SRCDIR)/%,$(DESTDIR)/%,$(1))
+override installed = $(foreach file,$1,$(DESTDIR)/$(call sourcepath,$(file)))
# ─ ¶ Recipe Variable Definitions ─────────────────────────────────────
# ─ ¶ Recipe Variable Definitions ─────────────────────────────────────
# Even plain X·M·L files are parsed, because they may contain X·H·T·M·L
# `<script>´ elements which contain other kinds of data. Asset files
# are turned into H·T·M·L embeds pointing to `data:´ U·R·I’s.
# Even plain X·M·L files are parsed, because they may contain X·H·T·M·L
# `<script>´ elements which contain other kinds of data. Asset files
# are turned into H·T·M·L embeds pointing to `data:´ U·R·I’s.
-$(call parsed,$(sourceincludes)): $(BUILDDIR)/includes/%: $(INCLUDEDIR)/% $(typeupdates)
- @$(PRINTF) '%s\n' $(call quote,Processing `$<´…)
- $(silent)$(call ensuredirectory,$(dir $@))
- $(silent)$(if $(filter $<,$(assetfiles)),$(PRINTF) '%s\n' $(call quote,<object xmlns="http://www.w3.org/1999/xhtml" type="$(call typeoffile,$(INCLUDEDIR)/$*)" data="$(call datauri,$<)"/>) > $(call quote,$@),$(if $(filter $<,$(plaintextfiles)),$(call wrapplaintext,$<),$(CAT) $(call quote,$<)) | $(XSLTPROC) -o $(call quote,$@) $(call quote,$(BUILDDIR)/parser.xslt) -)
-$(call parsed,$(sourcefiles)): $(BUILDDIR)/sources/%: $(SRCDIR)/% $(typeupdates)
+$(call parsed,$(sourcefiles) $(sourceincludes)): %: $$(call unparsed,$$@) $(typeupdates)
@$(PRINTF) '%s\n' $(call quote,Processing `$<´…)
$(silent)$(call ensuredirectory,$(dir $@))
@$(PRINTF) '%s\n' $(call quote,Processing `$<´…)
$(silent)$(call ensuredirectory,$(dir $@))
- $(silent)$(if $(filter $<,$(assetfiles)),$(PRINTF) '%s\n' $(call quote,<object xmlns="http://www.w3.org/1999/xhtml" type="$(call typeoffile,$(SRCDIR)/$*)" data="$(call datauri,$<)"/>) > $(call quote,$@),$(if $(filter $<,$(plaintextfiles)),$(call wrapplaintext,$<),$(CAT) $(call quote,$<)) | $(XSLTPROC) -o $(call quote,$@) $(call quote,$(BUILDDIR)/parser.xslt) -)
+ $(silent)$(if $(filter $<,$(assetfiles)),$(PRINTF) '%s\n' $(call quote,<object xmlns="http://www.w3.org/1999/xhtml" type="$(call typeoffile,$<)" data="$(call datauri,$<)"/>) > $(call quote,$@),$(if $(filter $<,$(plaintextfiles)),$(call wrapplaintext,$<),$(CAT) $(call quote,$<)) | $(XSLTPROC) -o $(call quote,$@) $(call quote,$(BUILDDIR)/parser.xslt) -)
# Generate a catalog of all transformed files, for use when processing
# includes. This does not depend on actually transforming the files.
# Generate a catalog of all transformed files, for use when processing
# includes. This does not depend on actually transforming the files.
$(silent)$(XSLTPROC) -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2transform.xslt) $(call quote,$<)
# Generate the output files using the dependencies as necessary.
$(silent)$(XSLTPROC) -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2transform.xslt) $(call quote,$<)
# Generate the output files using the dependencies as necessary.
-$(call compiled,$(compilablefiles)): $(BUILDDIR)/public/%: $$(call parsed,$(SRCDIR)/%) $(BUILDDIR)/transform.xslt $$(call parsed,$$(call dependencies,$(SRCDIR)/%))
+$(call compiled,$(compilablefiles)): $(BUILDDIR)/public/%: $$(call parsed,$$(call uncompiled,$$@)) $(BUILDDIR)/transform.xslt $$(call parsed,$$(call dependencies,$$(call uncompiled,$$@)))
$(silent)$(call ensuredirectory,$(dir $@))
$(silent)$(call ensuredirectory,$(dir $@))
- @$(PRINTF) '%s\n' $(call quote,Compiling `$*´…)
- $(silent)$(XSLTPROC) -o $(call quote,$@) --stringparam catalog 'catalog' --stringparam buildtime '$(shell TZ= $(DATE) '+%Y-%m-%dT%H:%M:%SZ')' --stringparam srctime '$(shell TZ= $(STAT) -f '%Sm' -t '%Y-%m-%dT%H:%M:%SZ' $(call quote,$(SRCDIR)/$*))' --stringparam path $(call quote,/$*) $(call quote,$(BUILDDIR)/transform.xslt) $(call quote,$<)
-$(call compiled,$(filter $(assetfiles),$(sourcefiles))): $(BUILDDIR)/public/%: $(SRCDIR)/%
- @$(PRINTF) '%s\n' $(call quote,Compiling `$*´…)
+ @$(PRINTF) '%s\n' $(call quote,Compiling </$*>…)
+ $(silent)$(XSLTPROC) -o $(call quote,$@) --stringparam catalog 'catalog' --stringparam buildtime '$(shell TZ= $(DATE) '+%Y-%m-%dT%H:%M:%SZ')' --stringparam srctime '$(shell TZ= $(STAT) -f '%Sm' -t '%Y-%m-%dT%H:%M:%SZ' $(call quote,$(call uncompiled,$@)))' --stringparam path $(call quote,/$*) $(call quote,$(BUILDDIR)/transform.xslt) $(call quote,$<)
+$(call compiled,$(filter $(assetfiles),$(sourcefiles))): $(BUILDDIR)/public/%: $$(call uncompiled,$$@)
+ @$(PRINTF) '%s\n' $(call quote,Compiling </$*>…)
$(silent)$(call ensuredirectory,$(dir $@))
$(silent)$(CP) $(call quote,$<) $(call quote,$@)
# Install compiled files (or error in the case of recursive ones).
$(call installed,$(filter $(assetfiles),$(sourcefiles)) $(recursivefiles) $(compilablefiles)): $(DESTDIR)/%: $(BUILDDIR)/public/%
$(silent)$(call ensuredirectory,$(dir $@))
$(silent)$(CP) $(call quote,$<) $(call quote,$@)
# Install compiled files (or error in the case of recursive ones).
$(call installed,$(filter $(assetfiles),$(sourcefiles)) $(recursivefiles) $(compilablefiles)): $(DESTDIR)/%: $(BUILDDIR)/public/%
- @$(PRINTF) '%s\n' $(call quote,Installing `$*´…)
+ @$(PRINTF) '%s\n' $(call quote,Installing </$*>…)
$(silent)$(call ensuredirectory,$(dir $@))
$(silent)$(CP) $(call quote,$<) $(call quote,$@)
$(silent)$(call ensuredirectory,$(dir $@))
$(silent)$(CP) $(call quote,$<) $(call quote,$@)
- **`SRCDIR`:**
The location of the source files (default: `sources`).
- **`SRCDIR`:**
The location of the source files (default: `sources`).
+ Multiple source directories can be provided, so long as the same
+ file subpath doesn’t exist in more than one of them.
- The location of the source files (default: `sources/includes`).
+ The location of source includes (default: `sources/includes`).
This can be inside of `SRCDIR`, but needn’t be.
This can be inside of `SRCDIR`, but needn’t be.
+ Multiple include directories can be provided, so long as the same
+ file subpath doesn’t exist in more than one of them.
- **`BUILDDIR`:**
The location of the (temporary) build directory (default: `build`).
- **`BUILDDIR`:**
The location of the (temporary) build directory (default: `build`).