║│ Requires G·N·U Make, at least version 3.81, a version of │║
║│ uuencode with base64 support, and the various programs │║
║│ offered by libxml2 and libxslt. Beyond this, only programs │║
-║│ required by Posix are used, altho there is a chance of │║
+║│ required by Posix are required, altho there is a chance of │║
║│ version incompatibilities. The full list of program │║
║│ requirements is as follows :— │║
║│ │║
║│ • echo │║
║│ • file │║
║│ • find │║
+║│ • git (optional) │║
║│ • mkdir (requires support for `-p´) │║
║│ • mv │║
║│ • od (requires support for `-t x1´) │║
ECHO := echo
FILE := file
FIND := find
+GIT := git
MKDIR := mkdir
MV := mv
OD := od
# source directory, removing any which are also includes.
sourcefiles := $(filter-out $(sourceincludes),$(shell $(FIND) $(FINDOPTS) $(SRCDIR) -type f '(' $(FINDRULES) ')'))
+ifdef GIT
+ifneq ($(wildcard $(THISDIR)/.git),)
+# (overridable) The name of the current revision of ⛩️📰 书社, or its
+# hash if the current revision is not a tag.
+thisrev = $(shell cd $(THISDIR); $(GIT) describe 2> /dev/null || $(GIT) rev-parse HEAD)
+endif
+
+ifneq ($(wildcard .git),)
+# (overridable) The name of the current revision of the working
+# directory, or its hash if the current revision is not a tag.
+srcrev = $(shell $(GIT) describe 2> /dev/null || $(GIT) rev-parse HEAD)
+endif
+endif
+
# Figure out the file type of each source file and source include.
ifneq ($(wildcard $(BUILDDIR)/magic.mgc),)
override types := $(shell $(SED) 's/^ *//;s/ *$$//;s/ {2,}/ /g' <<< $(call quote,$(sourcefiles) $(sourceincludes)) | $(TR) ' ' '\n' | $(FILE) -m $(call quote,$(BUILDDIR)/magic.mgc) --mime-type --separator '|' --files-from - | $(SED) 's/| */|/g')
$(call parsed,$(sourcefiles) $(sourceincludes)): %: $$(call unparsed,$$@) $(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,$<)" 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,$@) --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 unparsed,$@)))'$(if $(thisrev), --stringparam VERSION $(call quote,$(thisrev)),)$(if $(srcrev), --stringparam SRCREV $(call quote,$(srcrev)),) $(call quote,$(BUILDDIR)/parser.xslt) -)
# Generate a catalog of all parsed files, for use when processing
# includes. This does not depend on actually transforming the files.
$(call compiled,$(compilablefiles)): $(BUILDDIR)/public/%: $$(call parsed,$$(call uncompiled,$$@)) $(BUILDDIR)/transform.xslt $$(call parsed,$$(call dependencies,$$(call uncompiled,$$@)))
$(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,$(call uncompiled,$@)))' --stringparam path $(call quote,/$*) $(call quote,$(BUILDDIR)/transform.xslt) $(call quote,$<)
+ $(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,/$*)$(if $(thisrev), --stringparam VERSION $(call quote,$(thisrev)),)$(if $(srcrev), --stringparam SRCREV $(call quote,$(srcrev)),) $(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 $@))
- `echo`
- `file`
- `find`
+- `git` (optional; set `GIT=` to disable)
- `mkdir` (requires support for `-p`)
- `mv`
- `od` (requires support for `-t x1`)
- Set `@exclude-result-prefixes` on the root `xslt:transform` element
to reduce the number of declared namespaces in the final result.
-The params `$buildtime`, `$srctime`, and `$path` are available within
- transforms and are initialized to the current time, the time that the
- source file was last modified, and the path of the output file within
- $(DESTDIR).
+## Global Params
+
+The following params are made available globally in parsers and
+ transforms :—
+
+- **`BUILDTIME`:**
+ The current time.
+
+- **`SRCREV`:**
+ The tag or hash of the current commit in the working directory (if
+ `GIT` is defined and `./.git` exists).
+
+- **`SRCTIME`:**
+ The time at which the source file was last modified.
+
+- **`VERSION`:**
+ The tag or hash of the current commit in `THISDIR` (if `GIT` is
+ defined and `$(THISDIR)/.git` exists).
+
+The following params are only available in transforms :—
+
+- **`CATALOG`:**
+ The path of the catalog file (within `BUILDDIR`).
+
+- **`PATH`:**
+ The path of the output file (within `DESTDIR`).
## Output Wrapping
<namespace-alias stylesheet-prefix="xslt" result-prefix="#default"/>
<template match="/">
<xslt:transform exclude-result-prefixes="catalog exsl exslstr" version="1.0">
- <xslt:param name="buildtime" select="'1972-12-31T00:00:00Z'"/>
- <xslt:param name="catalog" select="'catalog'"/>
- <xslt:param name="srctime" select="'1972-12-31T00:00:00Z'"/>
- <xslt:param name="path" select="'/unknown'"/>
+ <xslt:param name="BUILDTIME" select="'1972-12-31T00:00:00Z'"/>
+ <xslt:param name="CATALOG" select="'catalog'"/>
+ <xslt:param name="SRCTIME" select="'1972-12-31T00:00:00Z'"/>
+ <xslt:param name="PATH" select="'/unknown'"/>
+ <xslt:param name="VERSION" select="false"/>
+ <xslt:param name="SRCREV" select="false"/>
<xslt:variable name="书社:expansion">
<xslt:apply-templates select="/" mode="书社:expand"/>
</xslt:variable>
<xslt:when test="exsl:node-set($书社:result)/*[@书社:disable-output-wrapping]">
<xslt:for-each select="exsl:node-set($书社:result)/*">
<xslt:copy>
- <xslt:copy-of select="@*[not(namespace-uri()='&书社;' and local-name()='disable-output-wrapping')]|node()"/>
+ <xslt:if test="$VERSION">
+ <xslt:attribute name="书社:version">
+ <xslt:value-of select="$VERSION"/>
+ </xslt:attribute>
+ </xslt:if>
+ <xslt:copy-of select="@*[not(namespace-uri()='&书社;' and contains('disable-output-wrapping version', local-name()))]|node()"/>
</xslt:copy>
</xslt:for-each>
</xslt:when>
</xslt:copy>
</xslt:template>
<xslt:template match="书社:link[@xlink:show='embed']" mode="书社:expand" priority="1">
- <xslt:variable name="uri" select="substring-before(document($catalog)//catalog:uri[@name=current()/@xlink:href]/@uri[1], '#')"/>
+ <xslt:variable name="uri" select="substring-before(document($CATALOG)//catalog:uri[@name=current()/@xlink:href]/@uri[1], '#')"/>
<xslt:choose>
<xslt:when test="$uri">
<xslt:variable name="expanded">
<xslt:apply-templates select="document('')/xslt:transform/xslt:include" mode="书社:metadata"/>
</xslt:variable>
<html:html>
+ <xslt:if test="$VERSION">
+ <xslt:attribute name="书社:version">
+ <xslt:value-of select="$VERSION"/>
+ </xslt:attribute>
+ </xslt:if>
<xslt:copy-of select="html:html/@*|*/@xml:lang|html:*/@lang|svg:*/@lang"/>
<html:head>
<xslt:copy-of select="html:html/html:head/@*"/>
</html:title>
<xslt:copy-of select="exsl:node-set($metadata)/node()[self::comment() or self::* and not(self::html:title)]"/>
<xslt:if test="not(exsl:node-set($metadata)/html:meta[@name='generator'])">
- <html:meta name="generator" content="⛩️📰 书社"/>
+ <html:meta name="generator">
+ <xslt:attribute name="content">
+ <xslt:text>⛩️📰 书社</xslt:text>
+ <xslt:if test="$VERSION">
+ <xslt:text> (</xslt:text>
+ <xslt:value-of select="$VERSION"/>
+ <xslt:text>)</xslt:text>
+ </xslt:if>
+ </xslt:attribute>
+ </html:meta>
</xslt:if>
</html:head>
<html:body>