From: Lady <redacted> Date: Mon, 1 Jan 2024 16:19:37 +0000 (-0500) Subject: Allow creation of metadata without matching result X-Git-Tag: 0.2.0~8 X-Git-Url: https://git.ladys.computer/Shushe/commitdiff_plain/af8b42c720c6aaa54199b556a656d40e8b8951a6 Allow creation of metadata without matching result 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. --- diff --git a/GNUmakefile b/GNUmakefile index e0cb8e1..72712c8 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -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 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')) @@ -378,7 +381,7 @@ $(BUILDDIR)/magic.mgc: $(wildcard $(MAGICDIR)/*) $(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,$<) @@ -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,$@) - $(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,$<) diff --git a/README.markdown b/README.markdown index 2dd0eff..84c3206 100644 --- a/README.markdown +++ b/README.markdown @@ -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. -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 diff --git a/lib/catalog2parser.xslt b/lib/catalog2parser.xslt index d044503..0da26b8 100644 --- a/lib/catalog2parser.xslt +++ b/lib/catalog2parser.xslt @@ -2,7 +2,7 @@ <!-- ⁌ ⛩️📰 书社 ∷ 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/>. @@ -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" - 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" > - <namespace-alias stylesheet-prefix="xsla" result-prefix="#default"/> + <namespace-alias stylesheet-prefix="xslt" result-prefix="#default"/> <template match="/"> - <xsla:transform version="1.0"> + <xslt:transform version="1.0"> <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> - <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> diff --git a/lib/catalog2transform.xslt b/lib/catalog2transform.xslt index 4a09235..e7640e8 100644 --- a/lib/catalog2transform.xslt +++ b/lib/catalog2transform.xslt @@ -2,7 +2,7 @@ <!-- ⁌ ⛩️📰 书社 ∷ 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/>. @@ -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'"/> + <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"> - <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"> - <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: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:copy-of select="exsl:node-set($result)/html:html/@*"/> + <xslt:copy-of select="exsl:node-set($书社:result)/html:html/@*"/> <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> - <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: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> diff --git a/parsers/plain.xslt b/parsers/plain.xslt index 0f61bfe..c12cbe5 100644 --- a/parsers/plain.xslt +++ b/parsers/plain.xslt @@ -2,7 +2,7 @@ <!-- ⁌ ⛩️📰 书社 ∷ 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/>. @@ -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" + xmlns:书社="urn:fdc:ladys.computer:20231231:Shu1She4" version="1.0" > + <书社:id>urn:fdc:ladys.computer:20231231:Shu1She4:plain.xslt</书社:id> <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> diff --git a/parsers/tsv.xslt b/parsers/tsv.xslt index 4de3b98..ad7052e 100644 --- a/parsers/tsv.xslt +++ b/parsers/tsv.xslt @@ -2,7 +2,7 @@ <!-- ⁌ ⛩️📰 书社 ∷ 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/>. @@ -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:书社="urn:fdc:ladys.computer:20231231:Shu1She4" 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(., '
')[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, '	')"> - <html:th scope="row"> + <html:th scope="col"> <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(., '	')"> <html:td> diff --git a/transforms/asset.xslt b/transforms/asset.xslt index a85c891..90c8dbd 100644 --- a/transforms/asset.xslt +++ b/transforms/asset.xslt @@ -2,7 +2,7 @@ <!-- ⁌ ⛩️📰 书社 ∷ 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/>. @@ -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" > + <书社:id>urn:fdc:ladys.computer:20231231:Shu1She4:asset.xslt</书社:id> <template match="html:object[@type='text/css']"> <comment> <text>[书社:CSS] </text> diff --git a/transforms/metadata.xslt b/transforms/metadata.xslt index d4be493..88877a4 100644 --- a/transforms/metadata.xslt +++ b/transforms/metadata.xslt @@ -2,7 +2,7 @@ <!-- ⁌ ⛩️📰 书社 ∷ 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/>. @@ -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" > + <书社: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>