]> Lady’s Gitweb - Shushe/commitdiff
Allow creation of metadata without matching result
authorLady <redacted>
Mon, 1 Jan 2024 16:19:37 +0000 (11:19 -0500)
committerLady <redacted>
Tue, 2 Jan 2024 18:26:37 +0000 (13:26 -0500)
Each node in the result can only be matched once in any given mode, and
transforms need a mechanism for inserting elements without requiring a
match. This commit gives them a means of doing so by also matching
every `<xslt:include>` in the main transform. If a transform has a
`书社:id` top‐level element which is an i·r·i, then its include will
have a corresponding attribute, and transforms can (by convention)
match this include without fear of conflicts.

This commit also makes the expansion and result available as top‐level
variables in the `书社:` namespace, so that transforms can easily match
within them.

GNUmakefile
README.markdown
lib/catalog2parser.xslt
lib/catalog2transform.xslt
parsers/plain.xslt
parsers/tsv.xslt
transforms/asset.xslt
transforms/metadata.xslt

index e0cb8e17ec906c0b99e712ff7bc47db62bc3ade3..72712c8521086ebaec9269aedbb958141ecedfc4 100644 (file)
@@ -224,6 +224,9 @@ override assetfiles := $(filter-out $(xmlfiles) $(plaintextfiles),$(sourcefiles)
 # (callable) Get the types of the given files.
 override typeoffile = $(patsubst $(foreach file,$1,$(file)?type=%),%,$(filter $(foreach file,$1,$(file)?type=%),$(types)))
 
 # (callable) Get the types of the given files.
 override typeoffile = $(patsubst $(foreach file,$1,$(file)?type=%),%,$(filter $(foreach file,$1,$(file)?type=%),$(types)))
 
+# (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 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 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'))
 
@@ -378,7 +381,7 @@ $(BUILDDIR)/magic.mgc: $(wildcard $(MAGICDIR)/*)
 $(BUILDDIR)/parser.catalog: $(PARSERS)
        @$(ECHO) "Generating catalog of parsers…"
        $(silent)$(XMLCATALOG) --create --noout $(call quote,$@)
 $(BUILDDIR)/parser.catalog: $(PARSERS)
        @$(ECHO) "Generating catalog of parsers…"
        $(silent)$(XMLCATALOG) --create --noout $(call quote,$@)
-       $(foreach parser,$(PARSERS),$(silent)$(XMLCATALOG) --add uri $(call quote,$(basename $(notdir $(parser)))) $(call quote,../$(parser)) --noout $(call quote,$@)$(newline))
+       $(foreach parser,$(PARSERS),$(silent)$(XMLCATALOG) --add uri $(call quote,$(call id,$(parser))) $(call quote,../$(parser)) --noout $(call quote,$@)$(newline))
 $(BUILDDIR)/parser.xslt: $(BUILDDIR)/parser.catalog $(THISDIR)/lib/catalog2parser.xslt
        @$(ECHO) "Generating main parser…"
        $(silent)$(XSLTPROC) -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2parser.xslt) $(call quote,$<)
 $(BUILDDIR)/parser.xslt: $(BUILDDIR)/parser.catalog $(THISDIR)/lib/catalog2parser.xslt
        @$(ECHO) "Generating main parser…"
        $(silent)$(XSLTPROC) -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2parser.xslt) $(call quote,$<)
@@ -419,7 +422,7 @@ $(BUILDDIR)/dependencies: $(BUILDDIR)/catalog $(call parsed,$(plaintextfiles) $(
 $(BUILDDIR)/transform.catalog: $(TRANSFORMS)
        @$(ECHO) "Generating catalog of transforms…"
        $(silent)$(XMLCATALOG) --create --noout $(call quote,$@)
 $(BUILDDIR)/transform.catalog: $(TRANSFORMS)
        @$(ECHO) "Generating catalog of transforms…"
        $(silent)$(XMLCATALOG) --create --noout $(call quote,$@)
-       $(foreach transform,$(TRANSFORMS),$(silent)$(XMLCATALOG) --add uri $(call quote,$(basename $(notdir $(transform)))) $(call quote,../$(transform)) --noout $(call quote,$@)$(newline))
+       $(foreach transform,$(TRANSFORMS),$(silent)$(XMLCATALOG) --add uri $(call quote,$(call id,$(transform))) $(call quote,../$(transform)) --noout $(call quote,$@)$(newline))
 $(BUILDDIR)/transform.xslt: $(BUILDDIR)/transform.catalog $(THISDIR)/lib/catalog2transform.xslt
        @$(ECHO) "Generating main transform…"
        $(silent)$(XSLTPROC) -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2transform.xslt) $(call quote,$<)
 $(BUILDDIR)/transform.xslt: $(BUILDDIR)/transform.catalog $(THISDIR)/lib/catalog2transform.xslt
        @$(ECHO) "Generating main transform…"
        $(silent)$(XSLTPROC) -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2transform.xslt) $(call quote,$<)
index 2dd0eff9a54e61711e6e07238c32e37198e1eeab..84c320639c5d95a387f1c29248dc79ac33d06b0c 100644 (file)
@@ -313,10 +313,41 @@ The following are recommendations on effective creation of
 ⛩️📰 书社 will wrap the final output of the transforms in appropriate
   `<html:html>` and `<html:body>` elements, so it is not necessary for
   transforms to do this explicitly.
 ⛩️📰 书社 will wrap the final output of the transforms in appropriate
   `<html:html>` and `<html:body>` elements, so it is not necessary for
   transforms to do this explicitly.
-The `<html:head>` of the output will contain the result tree generated
-  by matching the root node in the `书社:metadata` mode; the provided
-  `transforms/metadata.xslt` transform uses this mode to generate basic
-  metadata, but it is possible for other transforms to add their own.
+After performing the initial transform, ⛩️📰 书社 will match the root
+  node of the result in the following modes to fill in areas of the
+  wrapper :⁠—
+
+- **`书社:metadata`:**
+  The result of matching in this mode is inserted into the
+    `<html:head>` of the output.
+
+In addition to being called with the transform result, each of these
+  modes will additionally be called with a `<xslt:include>` element
+  corresponding to each transform.
+If a transform has a `<书社:id>` top‐level element whose value is an
+  i·r·i, its `<xslt:import>` element will have a corresponding
+  `@书社:id` attribute.
+This mechanism can be used to allow transforms to insert content
+  without matching any elements in the result; for example, the
+  following transform adds a link to a stylesheet to the `<html:head>`
+  of every page :⁠—
+
+```xml
+<?xml version="1.0"?>
+<transform
+       xmlns="http://www.w3.org/1999/XSL/Transform"
+       xmlns:html="http://www.w3.org/1999/xhtml"
+       xmlns:xslt="http://www.w3.org/1999/XSL/Transform"
+       xmlns:书社="urn:fdc:ladys.computer:20231231:Shu1She4"
+       exclude-result-prefixes="书社"
+       version="1.0"
+>
+       <书社:id>example:add-stylesheet-links.xslt</书社:id>
+       <template match="xslt:include[@书社:id='example:add-stylesheet-links.xslt']" mode="书社:metadata">
+         <html:link rel="stylesheet" type="text/css" href="/style.css"/>
+       </template>
+</transform>
+```
 
 ## License
 
 
 ## License
 
index d044503332104cc0e175a02a593112b6e1ac3590..0da26b853831943a649a03bcf77a88d7cd97662f 100644 (file)
@@ -2,7 +2,7 @@
 <!--
 ⁌ ⛩️📰 书社 ∷ lib/catalog2parser.xslt
 
 <!--
 ⁌ ⛩️📰 书社 ∷ lib/catalog2parser.xslt
 
-© 2023 Lady [@ Lady’s Computer]
+© 2023–2024 Lady [@ Lady’s Computer]
 
 This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0.
 If a copy of the M·P·L was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
 
 This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0.
 If a copy of the M·P·L was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
@@ -10,21 +10,28 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 <transform
        xmlns="http://www.w3.org/1999/XSL/Transform"
        xmlns:catalog="urn:oasis:names:tc:entity:xmlns:xml:catalog"
 <transform
        xmlns="http://www.w3.org/1999/XSL/Transform"
        xmlns:catalog="urn:oasis:names:tc:entity:xmlns:xml:catalog"
-       xmlns:xsla="http://www.w3.org/1999/XSL/TransformAlias"
+       xmlns:xslt="http://www.w3.org/1999/XSL/TransformAlias"
+       xmlns:书社="urn:fdc:ladys.computer:20231231:Shu1She4"
        exclude-result-prefixes="catalog"
        version="1.0"
 >
        exclude-result-prefixes="catalog"
        version="1.0"
 >
-       <namespace-alias stylesheet-prefix="xsla" result-prefix="#default"/>
+       <namespace-alias stylesheet-prefix="xslt" result-prefix="#default"/>
        <template match="/">
        <template match="/">
-               <xsla:transform version="1.0">
+               <xslt:transform version="1.0">
                        <for-each select="//catalog:uri">
                        <for-each select="//catalog:uri">
-                               <xsla:include href="{@uri}"/>
+                               <xslt:include href="{@uri}">
+                                       <if test="contains(@name, ':')">
+                                               <attribute name="书社:id">
+                                                       <value-of select="@name"/>
+                                               </attribute>
+                                       </if>
+                               </xslt:include>
                        </for-each>
                        </for-each>
-                       <xsla:template match="@*|node()" priority="-1">
-                               <xsla:copy>
-                                       <xsla:apply-templates select="@*|node()"/>
-                               </xsla:copy>
-                       </xsla:template>
-               </xsla:transform>
+                       <xslt:template match="@*|node()" priority="-1">
+                               <xslt:copy>
+                                       <xslt:apply-templates select="@*|node()"/>
+                               </xslt:copy>
+                       </xslt:template>
+               </xslt:transform>
        </template>
 </transform>
        </template>
 </transform>
index 4a09235475aef4d5556f172843342bc47c5918db..e7640e8c97e606f51899eee34c1324803e86ac54 100644 (file)
@@ -2,7 +2,7 @@
 <!--
 ⁌ ⛩️📰 书社 ∷ lib/catalog2transform.xslt
 
 <!--
 ⁌ ⛩️📰 书社 ∷ lib/catalog2transform.xslt
 
-© 2023 Lady [@ Lady’s Computer]
+© 2023–2024 Lady [@ Lady’s Computer]
 
 This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0.
 If a copy of the M·P·L was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
 
 This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0.
 If a copy of the M·P·L was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
@@ -21,36 +21,43 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
        <template match="/">
                <xslt:transform exclude-result-prefixes="catalog exsl" version="1.0">
                        <xslt:param name="catalog" select="'catalog'"/>
        <template match="/">
                <xslt:transform exclude-result-prefixes="catalog exsl" version="1.0">
                        <xslt:param name="catalog" select="'catalog'"/>
+                       <xslt:variable name="书社:expansion">
+                               <xslt:apply-templates select="/" mode="书社:expand"/>
+                       </xslt:variable>
+                       <xslt:variable name="书社:result">
+                               <xslt:apply-templates select="exsl:node-set($书社:expansion)/*"/>
+                       </xslt:variable>
                        <for-each select="//catalog:uri">
                        <for-each select="//catalog:uri">
-                               <xslt:include href="{@uri}"/>
+                               <xslt:include href="{@uri}">
+                                       <if test="contains(@name, ':')">
+                                               <attribute name="书社:id">
+                                                       <value-of select="@name"/>
+                                               </attribute>
+                                       </if>
+                               </xslt:include>
                        </for-each>
                        <xslt:template match="/" priority="1">
                        </for-each>
                        <xslt:template match="/" priority="1">
-                               <xslt:variable name="expansion">
-                                       <xslt:apply-templates select="." mode="书社:expand"/>
-                               </xslt:variable>
-                               <xslt:variable name="result">
-                                       <xslt:apply-templates select="exsl:node-set($expansion)/*"/>
-                               </xslt:variable>
                                <xslt:variable name="metadata">
                                <xslt:variable name="metadata">
-                                       <xslt:copy-of select="exsl:node-set($result)/html/head/*"/>
-                                       <xslt:apply-templates select="exsl:node-set($result)" mode="书社:metadata"/>
+                                       <xslt:copy-of select="exsl:node-set($书社:result)/html/head/*"/>
+                                       <xslt:apply-templates select="exsl:node-set($书社:result)" mode="书社:metadata"/>
+                                       <xslt:apply-templates select="document('')/xslt:transform/xslt:include" mode="书社:metadata"/>
                                </xslt:variable>
                                <html:html>
                                </xslt:variable>
                                <html:html>
-                                       <xslt:copy-of select="exsl:node-set($result)/html:html/@*"/>
+                                       <xslt:copy-of select="exsl:node-set($书社:result)/html:html/@*"/>
                                        <html:head>
                                        <html:head>
-                                               <xslt:copy-of select="exsl:node-set($result)/html:html/html:head/@*"/>
+                                               <xslt:copy-of select="exsl:node-set($书社:result)/html:html/html:head/@*"/>
                                                <html:title>
                                                        <xslt:for-each select="exsl:node-set($metadata)/html:title">
                                                                <xslt:value-of select="."/>
                                                        </xslt:for-each>
                                                </html:title>
                                                <html:title>
                                                        <xslt:for-each select="exsl:node-set($metadata)/html:title">
                                                                <xslt:value-of select="."/>
                                                        </xslt:for-each>
                                                </html:title>
-                                               <xslt:copy-of select="exsl:node-set($metadata)/*[not(self::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="⛩️📰 书社"/>
                                                </xslt:if>
                                        </html:head>
                                        <html:body>
                                                <xslt:if test="not(exsl:node-set($metadata)/html:meta[@name='generator'])">
                                                        <html:meta name="generator" content="⛩️📰 书社"/>
                                                </xslt:if>
                                        </html:head>
                                        <html:body>
-                                               <xslt:copy-of select="exsl:node-set($result)/*[not(self::html:html or self::html:body)]|exsl:node-set($result)/html:html/*[not(self::html:head or self::html:body)]|exsl:node-set($result)/html:html/html:body/*|exsl:node-set($result)/html:body/*"/>
+                                               <xslt:copy-of select="exsl:node-set($书社:result)/*[not(self::html:html or self::html:body)]|exsl:node-set($书社:result)/html:html/*[not(self::html:head or self::html:body)]|exsl:node-set($书社:result)/html:html/html:body/*|exsl:node-set($书社:result)/html:body/*"/>
                                        </html:body>
                                </html:html>
                        </xslt:template>
                                        </html:body>
                                </html:html>
                        </xslt:template>
index 0f61bfecf5a4211aac79ae4537aa927b1536d40c..c12cbe50295a59175c8236be97c482b344fbff75 100644 (file)
@@ -2,7 +2,7 @@
 <!--
 ⁌ ⛩️📰 书社 ∷ parsers/plain.xslt
 
 <!--
 ⁌ ⛩️📰 书社 ∷ parsers/plain.xslt
 
-© 2023 Lady [@ Lady’s Computer]
+© 2023–2024 Lady [@ Lady’s Computer]
 
 This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0.
 If a copy of the M·P·L was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
 
 This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0.
 If a copy of the M·P·L was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
@@ -10,9 +10,11 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 <transform
        xmlns="http://www.w3.org/1999/XSL/Transform"
        xmlns:html="http://www.w3.org/1999/xhtml"
 <transform
        xmlns="http://www.w3.org/1999/XSL/Transform"
        xmlns:html="http://www.w3.org/1999/xhtml"
+       xmlns:书社="urn:fdc:ladys.computer:20231231:Shu1She4"
        version="1.0"
 >
        version="1.0"
 >
+       <书社:id>urn:fdc:ladys.computer:20231231:Shu1She4:plain.xslt</书社:id>
        <template match="html:script[@type='text/plain']">
        <template match="html:script[@type='text/plain']">
-               <html:pre><value-of select="."/></html:pre>
+               <html:pre class="plain"><value-of select="."/></html:pre>
        </template>
 </transform>
        </template>
 </transform>
index 4de3b9853401f6b838ac84afb2bdf2fe121ac0c5..ad7052e2fad764a55d610721ddc4401be6dd0b37 100644 (file)
@@ -2,7 +2,7 @@
 <!--
 ⁌ ⛩️📰 书社 ∷ parsers/tsv.xslt
 
 <!--
 ⁌ ⛩️📰 书社 ∷ parsers/tsv.xslt
 
-© 2023 Lady [@ Lady’s Computer]
+© 2023–2024 Lady [@ Lady’s Computer]
 
 This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0.
 If a copy of the M·P·L was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
 
 This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0.
 If a copy of the M·P·L was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
@@ -12,25 +12,27 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
        xmlns:exsl="http://exslt.org/common"
        xmlns:exslstr="http://exslt.org/strings"
        xmlns:html="http://www.w3.org/1999/xhtml"
        xmlns:exsl="http://exslt.org/common"
        xmlns:exslstr="http://exslt.org/strings"
        xmlns:html="http://www.w3.org/1999/xhtml"
+       xmlns:书社="urn:fdc:ladys.computer:20231231:Shu1She4"
        exclude-result-prefixes="exsl exslstr"
        version="1.0"
 >
        exclude-result-prefixes="exsl exslstr"
        version="1.0"
 >
+       <书社:id>urn:fdc:ladys.computer:20231231:Shu1She4:tsv.xslt</书社:id>
        <template match="html:script[@type='text/tab-separated-values']">
                <variable name="rows" select="exslstr:tokenize(., '&#xA;')[normalize-space(.) and not(starts-with(., '#'))]"/>
        <template match="html:script[@type='text/tab-separated-values']">
                <variable name="rows" select="exslstr:tokenize(., '&#xA;')[normalize-space(.) and not(starts-with(., '#'))]"/>
-               <variable name="head" select="exsl:node-set($rows)[1]"/>
-               <variable name="body" select="exsl:node-set($rows)[not(position()=1)]"/>
-               <html:table>
+               <variable name="head" select="$rows[1]"/>
+               <variable name="body" select="$rows[not(position()=1)]"/>
+               <html:table class="tsv">
                        <html:thead>
                                <html:tr>
                                        <for-each select="exslstr:tokenize($head, '&#x9;')">
                        <html:thead>
                                <html:tr>
                                        <for-each select="exslstr:tokenize($head, '&#x9;')">
-                                               <html:th scope="row">
+                                               <html:th scope="col">
                                                        <value-of select="."/>
                                                </html:th>
                                        </for-each>
                                </html:tr>
                        </html:thead>
                        <html:tbody>
                                                        <value-of select="."/>
                                                </html:th>
                                        </for-each>
                                </html:tr>
                        </html:thead>
                        <html:tbody>
-                               <for-each select="exsl:node-set($body)">
+                               <for-each select="$body">
                                        <html:tr>
                                                <for-each select="exslstr:tokenize(., '&#x9;')">
                                                        <html:td>
                                        <html:tr>
                                                <for-each select="exslstr:tokenize(., '&#x9;')">
                                                        <html:td>
index a85c891c3dbbedfd0da5ddc0a9c58f5a215559b7..90c8dbd0b420f93fc48bfbe28ac80f928d2c88cc 100644 (file)
@@ -2,7 +2,7 @@
 <!--
 ⁌ ⛩️📰 书社 ∷ transforms/asset.xslt
 
 <!--
 ⁌ ⛩️📰 书社 ∷ transforms/asset.xslt
 
-© 2023 Lady [@ Lady’s Computer]
+© 2023–2024 Lady [@ Lady’s Computer]
 
 This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0.
 If a copy of the M·P·L was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
 
 This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0.
 If a copy of the M·P·L was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
@@ -14,6 +14,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
        exclude-result-prefixes="书社"
        version="1.0"
 >
        exclude-result-prefixes="书社"
        version="1.0"
 >
+       <书社:id>urn:fdc:ladys.computer:20231231:Shu1She4:asset.xslt</书社:id>
        <template match="html:object[@type='text/css']">
                <comment>
                        <text>[书社:CSS] </text>
        <template match="html:object[@type='text/css']">
                <comment>
                        <text>[书社:CSS] </text>
index d4be49327dc6013e32413878d9fb0e9159c3d8aa..88877a46fa7ee5d632e45832f814c8cd877b8fb7 100644 (file)
@@ -2,7 +2,7 @@
 <!--
 ⁌ ⛩️📰 书社 ∷ transforms/metadata.xslt
 
 <!--
 ⁌ ⛩️📰 书社 ∷ transforms/metadata.xslt
 
-© 2023 Lady [@ Lady’s Computer]
+© 2023–2024 Lady [@ Lady’s Computer]
 
 This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0.
 If a copy of the M·P·L was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
 
 This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0.
 If a copy of the M·P·L was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
@@ -14,6 +14,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
        exclude-result-prefixes="书社"
        version="1.0"
 >
        exclude-result-prefixes="书社"
        version="1.0"
 >
+       <书社:id>urn:fdc:ladys.computer:20231231:Shu1She4:metadata.xslt</书社:id>
        <template match="html:*[@itemscope][1]//html:meta[not(@name) and starts-with(@itemprop, 'urn:fdc:ladys.computer:20231231:Shu1She4:')]">
                <comment>
                        <text>[书社:META] </text>
        <template match="html:*[@itemscope][1]//html:meta[not(@name) and starts-with(@itemprop, 'urn:fdc:ladys.computer:20231231:Shu1She4:')]">
                <comment>
                        <text>[书社:META] </text>
This page took 0.076471 seconds and 4 git commands to generate.