]> Lady’s Gitweb - Shushe/commitdiff
Refactor transforms & add 书社:application stage 0.6.0
authorLady <redacted>
Thu, 8 Feb 2024 03:41:33 +0000 (22:41 -0500)
committerLady <redacted>
Thu, 8 Feb 2024 03:54:13 +0000 (22:54 -0500)
The main goal of this commit was to add a
`<书社:apply-attributes-to-root>` element, to allow transforms to pass
attributes up to the root element of the result, for example `@lang`
information. This required an extensive refactor of a lot of the
transform infrastructure and the creation of a new transform stage,
`书社:application`, which follows the ordinary transform and solely
handles `<书社:apply-attributes-to-root>` and
`<书社:apply-attributes>`. Other `@书社:*` attributes are removed at
this stage, but it isn’t generally recommended that transforms try to
hook in here.

This commit also makes a number of smaller changes :⁠—

- Use `node()` in place of element wildcards anywhere where
  specifically only matching elements wasn’t intended.

  In particular, even in places where text is not expected, there may
  be comments to preserve.

- Only add `@itemscope` and `@itemtype` attributes to H·T·M·L elements,
  since they are only defined for elements in that namespace.

- Provide `@书社:identifier` on documents and embeds to get the
  `about:shushe` u·r·i of the resource.

- In transforms which generate transforms, `<xsla:text>` elements which
  provide only white·space need `<xslt:text>` children to ensure the
  whitespace isn’t stripped. (Note: In the actual source text, `xsla:`
  is given the `xslt:` prefix and `xslt:` is the default prefix.)
  Similarly, it’s necessary to provide attribute value templates using
  a `<xslt:attribute>` element rather than with the literal result
  element syntax, to prevent them from being prematurely applied.

GNUmakefile
README.markdown
lib/catalog2parser.xslt
lib/catalog2transform.xslt
transforms/asset.xslt
transforms/attributes.xslt [deleted file]

index f0c9e8a1ab5745b0d652e05eb1f6060c4f0fa53b..16979033e5bbed8ae3f878629bb705f482792379 100644 (file)
@@ -497,7 +497,7 @@ $(BUILDDIR)/parser.xslt : $(BUILDDIR)/parser.catalog $(THISDIR)/lib/catalog2pars
 $(call parsed,$(sourcefiles) $(sourceincludes)) : % : $$(call unparsed,$$@) $(BUILDDIR)/parser.xslt $(typeupdates)
        @$(PRINTF) '%s\n' $(call quote,Processing `$<´…)
        $(silent)$(call ensuredirectory,$(dir $@))
 $(call parsed,$(sourcefiles) $(sourceincludes)) : % : $$(call unparsed,$$@) $(BUILDDIR)/parser.xslt $(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,$@) --stringparam BUILDTIME $$(TZ= $(DATE) '+%Y-%m-%dT%H:%M:%SZ') --stringparam SRCTIME $$(TZ= $(STAT) -f '%Sm' -t '%Y-%m-%dT%H:%M:%SZ' $(call quote,$<)) --stringparam CKSUM $$($(CKSUM) $(call quote,$<) | $(SED) 's/[ ].*//')$(if $(THISREV), --stringparam THISREV $(call quote,$(THISREV)),)$(if $(SRCREV), --stringparam SRCREV $(call quote,$(SRCREV)),) $(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 $$(TZ= $(DATE) '+%Y-%m-%dT%H:%M:%SZ') --stringparam IDENTIFIER $(call quote,$(call localuri,$<)) --stringparam SRCTIME $$(TZ= $(STAT) -f '%Sm' -t '%Y-%m-%dT%H:%M:%SZ' $(call quote,$<)) --stringparam CKSUM $$($(CKSUM) $(call quote,$<) | $(SED) 's/[ ].*//')$(if $(THISREV), --stringparam THISREV $(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.
 #
 
 # Generate a catalog of all parsed files, for use when processing includes.
 #
@@ -533,7 +533,7 @@ $(BUILDDIR)/transform.xslt : $(BUILDDIR)/transform.catalog $(THISDIR)/lib/catalo
 $(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 </$*>…)
 $(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 $$(TZ= $(DATE) '+%Y-%m-%dT%H:%M:%SZ') --stringparam SRCTIME $$(TZ= $(STAT) -f '%Sm' -t '%Y-%m-%dT%H:%M:%SZ' $(call quote,$(call uncompiled,$@))) --stringparam PATH $(call quote,/$*) --stringparam CKSUM $$($(CKSUM) $(call quote,$(call uncompiled,$@)) | $(SED) 's/[ ].*//')$(if $(THISREV), --stringparam THISREV $(call quote,$(THISREV)),)$(if $(SRCREV), --stringparam SRCREV $(call quote,$(SRCREV)),) $(call quote,$(BUILDDIR)/transform.xslt) $(call quote,$<)
+       $(silent)$(XSLTPROC) -o $(call quote,$@) --stringparam CATALOG 'catalog' --stringparam BUILDTIME $$(TZ= $(DATE) '+%Y-%m-%dT%H:%M:%SZ') --stringparam SRCTIME $$(TZ= $(STAT) -f '%Sm' -t '%Y-%m-%dT%H:%M:%SZ' $(call quote,$(call uncompiled,$@))) --stringparam IDENTIFIER $(call quote,$(call localuri,$(call uncompiled,$@))) --stringparam PATH $(call quote,/$*) --stringparam CKSUM $$($(CKSUM) $(call quote,$(call uncompiled,$@)) | $(SED) 's/[ ].*//')$(if $(THISREV), --stringparam THISREV $(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 $@))
 $(call compiled,$(filter $(assetfiles),$(sourcefiles))) : $(BUILDDIR)/public/% : $$(call uncompiled,$$@)
        @$(PRINTF) '%s\n' $(call quote,Compiling </$*>…)
        $(silent)$(call ensuredirectory,$(dir $@))
index 6b4f06ed18627a3a8dc344f94b5595b74bb85ba3..f6a08642353a226246ec11eaa60b873e764cfb1d 100644 (file)
@@ -379,6 +379,8 @@ Embeds are replaced with the parsed contents of a file, unless the file
   is an asset, in which case an `<html:object>` element is produced
   instead (with the contents of the asset file provided as a base64
   `data:` u·r·i).
   is an asset, in which case an `<html:object>` element is produced
   instead (with the contents of the asset file provided as a base64
   `data:` u·r·i).
+Embed replacements will be given a `@书社:identifier` attribute whose
+  value will match the `@xlink:href` of the embed.
 
 Embedding takes place after parsing but before transformation, so
   parsers are able to generate their own embeds.
 
 Embedding takes place after parsing but before transformation, so
   parsers are able to generate their own embeds.
@@ -401,14 +403,6 @@ Transforms are used to convert X·M·L files into their final output,
   after all necessary parsing and embedding has taken place.
 ⛩️📰 书社 comes with some transforms; namely :⁠—
 
   after all necessary parsing and embedding has taken place.
 ⛩️📰 书社 comes with some transforms; namely :⁠—
 
-- **`transforms/attributes.xslt`:**
-  Applies transforms to the children of any `<书社:apply-attributes>`
-    elements, and then applies the attributes of the
-    `<书社:apply-attributes>` to each result child, replacing the
-    element with the result.
-  This is useful in combination with image embeds to apply alt‐text to
-    the resulting `<html:img>`.
-
 - **`transforms/asset.xslt`:**
   Converts `<html:object>` elements which correspond to recognized
     media types into the appropriate H·T·M·L elements, and deletes
 - **`transforms/asset.xslt`:**
   Converts `<html:object>` elements which correspond to recognized
     media types into the appropriate H·T·M·L elements, and deletes
@@ -423,8 +417,8 @@ Transforms are used to convert X·M·L files into their final output,
   - **`urn:fdc:ladys.computer:20231231:Shu1She4:title`:**
     Provides the title of the page.
 
   - **`urn:fdc:ladys.computer:20231231:Shu1She4:title`:**
     Provides the title of the page.
 
-  ⛩️📰 书社 automatically encapsulates embeds so that their metadata
-    does not propogate up to the embedding document.
+  ⛩️📰 书社 automatically encapsulates H·T·M·L embeds so that their
+    metadata does not propogate up to the embedding document.
   To undo this behaviour, remove the `@itemscope` and `@itemtype`
     attributes from the embed during the transformation phase.
 
   To undo this behaviour, remove the `@itemscope` and `@itemtype`
     attributes from the embed during the transformation phase.
 
@@ -451,6 +445,10 @@ The following params are made available globally in parsers and
 - **`CKSUM`:**
   The checksum of the source file (⅌ `cksum`).
 
 - **`CKSUM`:**
   The checksum of the source file (⅌ `cksum`).
 
+- **`IDENTIFIER`:**
+  The ⛩️📰 书社 identifier of the source file (a u·r·i beginning with
+    `about:shushe`).
+
 - **`SRCREV`:**
   The value of the `SRCREV` variable (if present).
 
 - **`SRCREV`:**
   The value of the `SRCREV` variable (if present).
 
@@ -520,6 +518,29 @@ This mechanism can be used to allow transforms to insert content
 Output wrapping can be entirely disabled by adding a
   `@书社:disable-output-wrapping` attribute to the top‐level element in
   the result tree.
 Output wrapping can be entirely disabled by adding a
   `@书社:disable-output-wrapping` attribute to the top‐level element in
   the result tree.
+This attribute will also prevent wrapping non‐H·T·M·L embeds with an
+  `<html:div>`.
+
+## Applying Attributes
+
+The `<书社:apply-attributes>` element will apply any attributes on the
+  element to the element(s) it wraps.
+It is especially useful in combination with embeds.
+
+The `<书社:apply-attributes-to-root>` element will apply any attributes
+  on the element to the root node of the final transformation result.
+It is especially useful in combination with output wrapping.
+
+In both cases, attributes from various sources are combined with
+  white·space between them.
+Attribute application takes place after all ordinary transforms have
+  completed.
+
+Both elements ignore attributes in the `xml:` namespace, except for
+  `@xml:lang`, which ignores all but the first definition (including
+  any already present on the root element).
+On H·T·M·L and S·V·G elements, `@lang` has the same behaviour as
+  `@xml:lang`.
 
 ## License
 
 
 ## License
 
index 4ea7bda48a5f95e5ea2cd8640172f79d346cef43..1faa880f7e619a30cf508c597dbcc5a2a369f668 100644 (file)
@@ -24,6 +24,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                <xslt:transform version="1.0">
                        <xslt:param name="BUILDTIME" select="'1972-12-31T00:00:00Z'"/>
                        <xslt:param name="CKSUM" select="false"/>
                <xslt:transform version="1.0">
                        <xslt:param name="BUILDTIME" select="'1972-12-31T00:00:00Z'"/>
                        <xslt:param name="CKSUM" select="false"/>
+                       <xslt:param name="IDENTIFIER" select="false"/>
                        <xslt:param name="SRCREV" select="false"/>
                        <xslt:param name="SRCTIME" select="'1972-12-31T00:00:00Z'"/>
                        <xslt:param name="THISREV" select="false"/>
                        <xslt:param name="SRCREV" select="false"/>
                        <xslt:param name="SRCTIME" select="'1972-12-31T00:00:00Z'"/>
                        <xslt:param name="THISREV" select="false"/>
@@ -94,7 +95,9 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                                                                        <xslt:attribute name="书社:parsed-by">
                                                                                <xslt:value-of select="$id"/>
                                                                                <xslt:if test="@书社:parsed-by">
                                                                        <xslt:attribute name="书社:parsed-by">
                                                                                <xslt:value-of select="$id"/>
                                                                                <xslt:if test="@书社:parsed-by">
-                                                                                       <xslt:text> </xslt:text>
+                                                                                       <xslt:text>
+                                                                                               <text> </text>
+                                                                                       </xslt:text>
                                                                                        <xslt:value-of select="@书社:parsed-by"/>
                                                                                </xslt:if>
                                                                        </xslt:attribute>
                                                                                        <xslt:value-of select="@书社:parsed-by"/>
                                                                                </xslt:if>
                                                                        </xslt:attribute>
index a6c83d6ef9e1e9300c43695657659688d5904f64..b53e12ab9f29bed8f2bc8ae827e38377eecb9452 100644 (file)
@@ -9,6 +9,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 -->
 <!DOCTYPE transform [
        <!ENTITY 书社 "urn:fdc:ladys.computer:20231231:Shu1She4">
 -->
 <!DOCTYPE transform [
        <!ENTITY 书社 "urn:fdc:ladys.computer:20231231:Shu1She4">
+       <!ENTITY xml "http://www.w3.org/XML/1998/namespace">
 ]>
 <transform
        xmlns="http://www.w3.org/1999/XSL/Transform"
 ]>
 <transform
        xmlns="http://www.w3.org/1999/XSL/Transform"
@@ -28,15 +29,17 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                        <xslt:param name="BUILDTIME" select="'1972-12-31T00:00:00Z'"/>
                        <xslt:param name="CKSUM" select="false"/>
                        <xslt:param name="CATALOG" select="'catalog'"/>
                        <xslt:param name="BUILDTIME" select="'1972-12-31T00:00:00Z'"/>
                        <xslt:param name="CKSUM" select="false"/>
                        <xslt:param name="CATALOG" select="'catalog'"/>
+                       <xslt:param name="IDENTIFIER" select="false"/>
                        <xslt:param name="PATH" select="'/unknown'"/>
                        <xslt:param name="SRCREV" select="false"/>
                        <xslt:param name="SRCTIME" select="'1972-12-31T00:00:00Z'"/>
                        <xslt:param name="THISREV" select="false"/>
                        <xslt:param name="PATH" select="'/unknown'"/>
                        <xslt:param name="SRCREV" select="false"/>
                        <xslt:param name="SRCTIME" select="'1972-12-31T00:00:00Z'"/>
                        <xslt:param name="THISREV" select="false"/>
+                       <xslt:variable name="书社:source" select="/"/>
                        <xslt:variable name="书社:expansion">
                        <xslt:variable name="书社:expansion">
-                               <xslt:apply-templates select="/" mode="书社:expand"/>
+                               <xslt:apply-templates select="$书社:source/node()" mode="书社:expand"/>
                        </xslt:variable>
                        <xslt:variable name="书社:result">
                        </xslt:variable>
                        <xslt:variable name="书社:result">
-                               <xslt:apply-templates select="exsl:node-set($书社:expansion)/*"/>
+                               <xslt:apply-templates select="exsl:node-set($书社:expansion)/node()"/>
                        </xslt:variable>
                        <for-each select="//catalog:uri">
                                <xslt:include href="{@uri}">
                        </xslt:variable>
                        <for-each select="//catalog:uri">
                                <xslt:include href="{@uri}">
@@ -47,62 +50,290 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                                        </if>
                                </xslt:include>
                        </for-each>
                                        </if>
                                </xslt:include>
                        </for-each>
-                       <xslt:template match="/" priority="1">
-                               <xslt:choose>
-                                       <xslt:when test="exsl:node-set($书社:result)/*[@书社:disable-output-wrapping]">
-                                               <xslt:for-each select="exsl:node-set($书社:result)/*">
+                       <xslt:template name="书社:apply-attributes">
+                               <xslt:param name="and-version" select="false"/>
+                               <xslt:param name="context-nodes" select="/.."/>
+                               <xslt:param name="destination-nodes" select="/.."/>
+                               <xslt:variable name="additional-attributes" select="$context-nodes/@*"/>
+                               <xslt:for-each select="$destination-nodes">
+                                       <xslt:variable name="existing-attributes" select="@*"/>
+                                       <xslt:choose>
+                                               <xslt:when test="self::*">
+                                                       <xslt:variable name="context" select="."/>
+                                                       <xslt:variable name="attribute-names">
+                                                               <xslt:for-each select="$existing-attributes|$additional-attributes">
+                                                                       <书社:attribute>
+                                                                               <attribute name="local-name">
+                                                                                       <text>{local-name()}</text>
+                                                                               </attribute>
+                                                                               <attribute name="name">
+                                                                                       <text>{name()}</text>
+                                                                               </attribute>
+                                                                               <attribute name="namespace-uri">
+                                                                                       <text>{namespace-uri()}</text>
+                                                                               </attribute>
+                                                                       </书社:attribute>
+                                                               </xslt:for-each>
+                                                       </xslt:variable>
+                                                       <xslt:variable name="lang">
+                                                               <xslt:choose>
+                                                                       <xslt:when test="(self::html:*|self::svg:*)/@lang">
+                                                                               <xslt:value-of select="@lang"/>
+                                                                       </xslt:when>
+                                                                       <xslt:when test="@xml:lang">
+                                                                               <xslt:value-of select="@xml:lang"/>
+                                                                       </xslt:when>
+                                                                       <xslt:when test="$additional-attributes[(parent::html:* or parent::svg:*) and namespace-uri()='' and local-name()='lang']">
+                                                                               <xslt:value-of select="$additional-attributes[(parent::html:* or parent::svg:*) and namespace-uri()='' and local-name()='lang']"/>
+                                                                       </xslt:when>
+                                                                       <xslt:when test="(self::html:* or self::svg:*) and $additional-attributes[(parent::书社:apply-attributes or parent::书社:apply-attributes-to-root) and namespace-uri()='' and local-name()='lang']">
+                                                                               <xslt:value-of select="$additional-attributes[(parent::书社:apply-attributes or parent::书社:apply-attributes-to-root) and namespace-uri()='' and local-name()='lang']"/>
+                                                                       </xslt:when>
+                                                                       <xslt:when test="$additional-attributes[namespace-uri()='&xml;' and local-name()='lang']">
+                                                                               <xslt:value-of select="$additional-attributes[namespace-uri()='&xml;' and local-name()='lang']"/>
+                                                                       </xslt:when>
+                                                               </xslt:choose>
+                                                       </xslt:variable>
                                                        <xslt:copy>
                                                        <xslt:copy>
-                                                               <xslt:if test="$THISREV">
+                                                               <xslt:if test="$and-version and $THISREV">
                                                                        <xslt:attribute name="书社:version">
                                                                                <xslt:value-of select="$THISREV"/>
                                                                        </xslt:attribute>
                                                                </xslt:if>
                                                                        <xslt:attribute name="书社:version">
                                                                                <xslt:value-of select="$THISREV"/>
                                                                        </xslt:attribute>
                                                                </xslt:if>
-                                                               <xslt:copy-of select="@*[not(namespace-uri()='&书社;' and contains('disable-output-wrapping version', local-name()))]|node()"/>
+                                                               <xslt:if test="string($lang)!=''">
+                                                                       <xslt:if test="self::html:* or self::svg:*">
+                                                                               <xslt:attribute name="lang">
+                                                                                       <xslt:value-of select="$lang"/>
+                                                                               </xslt:attribute>
+                                                                       </xslt:if>
+                                                                       <xslt:attribute name="xml:lang">
+                                                                               <xslt:value-of select="$lang"/>
+                                                                       </xslt:attribute>
+                                                               </xslt:if>
+                                                               <xslt:for-each select="exsl:node-set($attribute-names)/*">
+                                                                       <xslt:choose>
+                                                                               <xslt:when test="@namespace-uri='&xml;'"/>
+                                                                               <xslt:when test="$context[self::html:* or self::svg:*] and @namespace-uri='' and @local-name='lang'"/>
+                                                                               <xslt:when test="@namespace-uri='&书社;' and (@local-name='destination' or @local-name='disable-output-wrapping' or @local-name='version')"/>
+                                                                               <xslt:when test="preceding-sibling::*[@local-name=current()/@local-name and @namespace-uri=current()/@namespace-uri]"/>
+                                                                               <xslt:otherwise>
+                                                                                       <xslt:attribute>
+                                                                                               <attribute name="name">
+                                                                                                       <text>{@name}</text>
+                                                                                               </attribute>
+                                                                                               <attribute name="namespace">
+                                                                                                       <text>{@namespace-uri}</text>
+                                                                                               </attribute>
+                                                                                               <xslt:for-each select="$existing-attributes[local-name()=current()/@local-name and namespace-uri()=current()/@namespace-uri]">
+                                                                                                       <xslt:value-of select="."/>
+                                                                                                       <xslt:if test="position()!=last()">
+                                                                                                               <xslt:text>
+                                                                                                                       <text> </text>
+                                                                                                               </xslt:text>
+                                                                                                       </xslt:if>
+                                                                                               </xslt:for-each>
+                                                                                               <xslt:if test="$existing-attributes[local-name()=current()/@local-name and namespace-uri()=current()/@namespace-uri] and $additional-attributes[local-name()=current()/@local-name and namespace-uri()=current()/@namespace-uri]">
+                                                                                                       <xslt:text>
+                                                                                                               <text> </text>
+                                                                                                       </xslt:text>
+                                                                                               </xslt:if>
+                                                                                               <xslt:for-each select="$additional-attributes[local-name()=current()/@local-name and namespace-uri()=current()/@namespace-uri]">
+                                                                                                       <xslt:value-of select="."/>
+                                                                                                       <xslt:if test="position()!=last()">
+                                                                                                               <xslt:text>
+                                                                                                                       <text> </text>
+                                                                                                               </xslt:text>
+                                                                                                       </xslt:if>
+                                                                                               </xslt:for-each>
+                                                                                       </xslt:attribute>
+                                                                               </xslt:otherwise>
+                                                                       </xslt:choose>
+                                                               </xslt:for-each>
+                                                               <xslt:copy-of select="node()"/>
                                                        </xslt:copy>
                                                        </xslt:copy>
-                                               </xslt:for-each>
-                                       </xslt:when>
-                                       <xslt:otherwise>
-                                               <xslt:apply-templates select="exsl:node-set($书社:result)" mode="书社:wrap"/>
-                                       </xslt:otherwise>
-                               </xslt:choose>
+                                               </xslt:when>
+                                               <xslt:otherwise>
+                                                       <xslt:copy-of select="."/>
+                                               </xslt:otherwise>
+                                       </xslt:choose>
+                               </xslt:for-each>
+                       </xslt:template>
+                       <xslt:template name="书社:wrap">
+                               <xslt:param name="nodes" select="/.."/>
+                               <xslt:variable name="modalinput">
+                                       <xslt:copy-of select="$nodes"/>
+                                       <xslt:copy-of select="document('')/xslt:transform/xslt:include"/>
+                               </xslt:variable>
+                               <xslt:variable name="metadata">
+                                       <xslt:copy-of select="$nodes[self::html:html]/html:head/node()|$nodes[self::html:head]/node()"/>
+                                       <xslt:apply-templates select="exsl:node-set($modalinput)/node()" mode="书社:metadata"/>
+                               </xslt:variable>
+                               <html:html>
+                                       <xslt:copy-of select="$nodes[self::html:html]/@*"/>
+                                       <xslt:if test="not($nodes[self::html:html]/@lang) and $nodes[self::html:*]/@lang|$nodes[self::svg:*]/@lang|$nodes/@xml:lang">
+                                               <xslt:attribute name="lang">
+                                                       <xslt:value-of select="$nodes[self::html:*]/@lang|$nodes[self::svg:*]/@lang|$nodes/@xml:lang"/>
+                                               </xslt:attribute>
+                                       </xslt:if>
+                                       <xslt:if test="not($nodes[self::html:html]/@xml:lang) and $nodes[self::html:*]/@lang|$nodes[self::svg:*]/@lang|$nodes/@xml:lang">
+                                               <xslt:attribute name="xml:lang">
+                                                       <xslt:value-of select="$nodes[self::html:*]/@lang|$nodes[self::svg:*]/@lang|$nodes/@xml:lang"/>
+                                               </xslt:attribute>
+                                       </xslt:if>
+                                       <html:head>
+                                               <xslt:copy-of select="$nodes[self::html:html]/html:head/@*|$nodes[self::html:head]/@*"/>
+                                               <html:title>
+                                                       <xslt:for-each select="exsl:node-set($metadata)/html:title">
+                                                               <xslt:value-of select="."/>
+                                                               <xslt:if test="position()!=last()">
+                                                                       <xslt:text>
+                                                                               <text> </text>
+                                                                       </xslt:text>
+                                                               </xslt:if>
+                                                       </xslt:for-each>
+                                               </html:title>
+                                               <xslt:copy-of select="exsl:node-set($metadata)/node()[not(self::html:title)]"/>
+                                               <html:meta name="generator">
+                                                       <xslt:attribute name="content">
+                                                               <xslt:for-each select="exsl:node-set($metadata)/html:meta[@name='generator']">
+                                                                       <xslt:value-of select="@content"/>
+                                                                       <xslt:text>
+                                                                               <text>, </text>
+                                                                       </xslt:text>
+                                                               </xslt:for-each>
+                                                               <xslt:text>
+                                                                       <text>⛩️📰 书社</text>
+                                                               </xslt:text>
+                                                               <xslt:if test="$THISREV">
+                                                                       <xslt:text>
+                                                                               <text> (</text>
+                                                                       </xslt:text>
+                                                                       <xslt:value-of select="$THISREV"/>
+                                                                       <xslt:text>
+                                                                               <text>)</text>
+                                                                       </xslt:text>
+                                                               </xslt:if>
+                                                       </xslt:attribute>
+                                               </html:meta>
+                                       </html:head>
+                                       <html:body>
+                                               <xslt:copy-of select="$nodes[self::html:html]/html:body/@*|$nodes[self::html:body]/@*"/>
+                                               <xslt:apply-templates select="exsl:node-set($modalinput)/node()" mode="书社:header"/>
+                                               <xslt:copy-of select="$nodes[not(self::html:html or self::html:head or self::html:body)]|$nodes[self::html:html]/node()[not(self::html:head or self::html:body)]|$nodes[self::html:html]/html:body/node()|$nodes[self::html:body]/node()"/>
+                                               <xslt:apply-templates select="exsl:node-set($modalinput)/node()" mode="书社:footer"/>
+                                       </html:body>
+                               </html:html>
+                       </xslt:template>
+                       <xslt:template match="/" priority="1">
+                               <xslt:variable name="result-nodes" select="exsl:node-set($书社:result)/node()[not(self::书社:apply-attributes-to-root)]|exsl:node-set($书社:result)/书社:apply-attributes-to-root/descendant::node()[not(self::书社:apply-attributes-to-root) and not(ancestor::*[not(self::书社:apply-attributes-to-root)])]"/>
+                               <xslt:variable name="root-with-attributes">
+                                       <xslt:choose>
+                                               <xslt:when test="$result-nodes/@书社:disable-output-wrapping|exsl:node-set($书社:result)//书社:apply-attributes-to-root/@书社:disable-output-wrapping">
+                                                       <xslt:call-template name="书社:apply-attributes">
+                                                               <xslt:with-param name="and-version" select="true"/>
+                                                               <xslt:with-param name="context-nodes" select="exsl:node-set($书社:result)//书社:apply-attributes-to-root"/>
+                                                               <xslt:with-param name="destination-nodes" select="$result-nodes"/>
+                                                       </xslt:call-template>
+                                               </xslt:when>
+                                               <xslt:otherwise>
+                                                       <xslt:variable name="wrapped-result">
+                                                               <xslt:call-template name="书社:wrap">
+                                                                       <xslt:with-param name="nodes" select="$result-nodes"/>
+                                                               </xslt:call-template>
+                                                       </xslt:variable>
+                                                       <xslt:call-template name="书社:apply-attributes">
+                                                               <xslt:with-param name="and-version" select="true"/>
+                                                               <xslt:with-param name="context-nodes" select="exsl:node-set($书社:result)//书社:apply-attributes-to-root"/>
+                                                               <xslt:with-param name="destination-nodes" select="exsl:node-set($wrapped-result)/node()"/>
+                                                       </xslt:call-template>
+                                               </xslt:otherwise>
+                                       </xslt:choose>
+                               </xslt:variable>
+                               <xslt:apply-templates select="exsl:node-set($root-with-attributes)/node()" mode="书社:application"/>
                        </xslt:template>
                        </xslt:template>
-                       <xslt:template match="/*/*//@书社:disable-output-wrapping|//@书社:destination" priority="0"/>
                        <xslt:template match="@*|node()" priority="-1">
                                <xslt:copy>
                                        <xslt:apply-templates select="@*|node()"/>
                                </xslt:copy>
                        </xslt:template>
                        <xslt:template match="@*|node()" priority="-1">
                                <xslt:copy>
                                        <xslt:apply-templates select="@*|node()"/>
                                </xslt:copy>
                        </xslt:template>
-                       <xslt:template match="/*" mode="书社:expand" priority="0">
+                       <xslt:template match="@*|node()" mode="书社:application">
                                <xslt:copy>
                                <xslt:copy>
-                                       <xslt:attribute name="itemscope">itemscope</xslt:attribute>
-                                       <xslt:attribute name="itemtype">
-                                               <xslt:text>&书社;:document</xslt:text>
-                                               <xslt:for-each select="exslstr:tokenize(@itemtype)/token">
-                                                       <xslt:text> </xslt:text>
-                                                       <xslt:value-of select="."/>
-                                               </xslt:for-each>
+                                       <xslt:apply-templates select="@*|node()" mode="书社:application"/>
+                               </xslt:copy>
+                       </xslt:template>
+                       <xslt:template match="@书社:destination|@书社:disable-output-wrapping" mode="书社:application" priority="1"/>
+                       <xslt:template match="书社:apply-attributes" mode="书社:application" priority="1">
+                               <xslt:variable name="children">
+                                       <xslt:apply-templates select="node()" mode="书社:application"/>
+                               </xslt:variable>
+                               <xslt:call-template name="书社:apply-attributes">
+                                       <xslt:with-param name="context-nodes" select="."/>
+                                       <xslt:with-param name="destination-nodes" select="exsl:node-set($children)/node()"/>
+                               </xslt:call-template>
+                       </xslt:template>
+                       <xslt:template match="书社:apply-attributes-to-root" mode="书社:application" priority="1">
+                               <xslt:apply-templates select="node()" mode="书社:application"/>
+                       </xslt:template>
+                       <xslt:template match="/node()" mode="书社:expand" priority="0">
+                               <xslt:copy>
+                                       <xslt:attribute name="书社:identifier">
+                                               <xslt:value-of select="$IDENTIFIER"/>
                                        </xslt:attribute>
                                        </xslt:attribute>
-                                       <xslt:apply-templates select="@*[not(namespace-uri()='' and (local-name()='itemscope' or local-name()='itemtype'))]|node()" mode="书社:expand"/>
+                                       <xslt:choose>
+                                               <xslt:when test="self::html:*">
+                                                       <xslt:attribute name="itemscope">itemscope</xslt:attribute>
+                                                       <xslt:attribute name="itemtype">
+                                                               <xslt:text>
+                                                                       <text>&书社;:document</text>
+                                                               </xslt:text>
+                                                               <xslt:for-each select="exslstr:tokenize(@itemtype)/token">
+                                                                       <xslt:text>
+                                                                               <text> </text>
+                                                                       </xslt:text>
+                                                                       <xslt:value-of select="."/>
+                                                               </xslt:for-each>
+                                                       </xslt:attribute>
+                                                       <xslt:apply-templates select="@*[not(namespace-uri()='' and (local-name()='itemscope' or local-name()='itemtype'))]|node()" mode="书社:expand"/>
+                                               </xslt:when>
+                                               <xslt:otherwise>
+                                                       <xslt:apply-templates select="@*|node()" mode="书社:expand"/>
+                                               </xslt:otherwise>
+                                       </xslt:choose>
                                </xslt:copy>
                        </xslt:template>
                        <xslt:template match="书社:link[@xlink:show='embed']" mode="书社:expand" priority="1">
                                </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="identifier" select="string(@xlink:href)"/>
+                               <xslt:variable name="uri" select="substring-before(document($CATALOG)//catalog:uri[@name=$identifier]/@uri[1], '#')"/>
                                <xslt:choose>
                                        <xslt:when test="$uri">
                                                <xslt:variable name="expanded">
                                                        <xslt:apply-templates select="document($uri)" mode="书社:expand"/>
                                                </xslt:variable>
                                <xslt:choose>
                                        <xslt:when test="$uri">
                                                <xslt:variable name="expanded">
                                                        <xslt:apply-templates select="document($uri)" mode="书社:expand"/>
                                                </xslt:variable>
-                                               <xslt:for-each select="exsl:node-set($expanded)/*">
+                                               <xslt:for-each select="exsl:node-set($expanded)/node()">
                                                        <xslt:copy>
                                                        <xslt:copy>
-                                                               <xslt:attribute name="itemscope">itemscope</xslt:attribute>
-                                                               <xslt:attribute name="itemtype">
-                                                                       <xslt:text>&书社;:embed</xslt:text>
-                                                                       <xslt:for-each select="exslstr:tokenize(@itemtype)/token[string()!='&书社;:document']">
-                                                                               <xslt:text> </xslt:text>
-                                                                               <xslt:value-of select="."/>
-                                                                       </xslt:for-each>
+                                                               <xslt:attribute name="书社:identifier">
+                                                                       <xslt:value-of select="$identifier"/>
                                                                </xslt:attribute>
                                                                </xslt:attribute>
-                                                               <xslt:copy-of select="@*[not(namespace-uri()='' and (local-name()='itemscope' or local-name()='itemtype'))]|node()"/>
+                                                               <xslt:choose>
+                                                                       <xslt:when test="self::html:*">
+                                                                               <xslt:attribute name="itemscope">itemscope</xslt:attribute>
+                                                                               <xslt:attribute name="itemtype">
+                                                                                       <xslt:text>
+                                                                                               <text>&书社;:embed</text>
+                                                                                       </xslt:text>
+                                                                                       <xslt:for-each select="exslstr:tokenize(@itemtype)/token[string()!='&书社;:document']">
+                                                                                               <xslt:text>
+                                                                                                       <text> </text>
+                                                                                               </xslt:text>
+                                                                                               <xslt:value-of select="."/>
+                                                                                       </xslt:for-each>
+                                                                               </xslt:attribute>
+                                                                               <xslt:copy-of select="@*[not(namespace-uri()='' and (local-name()='itemscope' or local-name()='itemtype')) and not(namespace-uri()='&书社;' and local-name()='identifier')]|node()"/>
+                                                                       </xslt:when>
+                                                                       <xslt:otherwise>
+                                                                               <xslt:apply-templates select="@*[not(namespace-uri()='&书社;' and local-name()='identifier')]|node()" mode="书社:expand"/>
+                                                                       </xslt:otherwise>
+                                                               </xslt:choose>
                                                        </xslt:copy>
                                                </xslt:for-each>
                                        </xslt:when>
                                                        </xslt:copy>
                                                </xslt:for-each>
                                        </xslt:when>
@@ -113,7 +344,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                                        </xslt:otherwise>
                                </xslt:choose>
                        </xslt:template>
                                        </xslt:otherwise>
                                </xslt:choose>
                        </xslt:template>
-                       <xslt:template match="@*|text()|*[not(self::书社:link) or not(@xlink:show='embed')]" mode="书社:expand" priority="-1">
+                       <xslt:template match="@*|node()[not(self::书社:link) or not(@xlink:show='embed')]" mode="书社:expand" priority="-1">
                                <xslt:copy>
                                        <xslt:apply-templates select="@*|node()" mode="书社:expand"/>
                                </xslt:copy>
                                <xslt:copy>
                                        <xslt:apply-templates select="@*|node()" mode="书社:expand"/>
                                </xslt:copy>
@@ -121,63 +352,6 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                        <xslt:template match="text()" mode="书社:header"/>
                        <xslt:template match="text()" mode="书社:footer"/>
                        <xslt:template match="text()" mode="书社:metadata"/>
                        <xslt:template match="text()" mode="书社:header"/>
                        <xslt:template match="text()" mode="书社:footer"/>
                        <xslt:template match="text()" mode="书社:metadata"/>
-                       <xslt:template match="/" mode="书社:wrap">
-                               <xslt:variable name="modalinput">
-                                       <xslt:copy-of select="node()"/>
-                                       <xslt:copy-of select="document('')/xslt:transform/xslt:include"/>
-                               </xslt:variable>
-                               <xslt:variable name="metadata">
-                                       <xslt:copy-of select="html:html/html:head/node()|html:head/node()"/>
-                                       <xslt:apply-templates select="exsl:node-set($modalinput)" mode="书社:metadata"/>
-                               </xslt:variable>
-                               <html:html>
-                                       <xslt:if test="$THISREV">
-                                               <xslt:attribute name="书社:version">
-                                                       <xslt:value-of select="$THISREV"/>
-                                               </xslt:attribute>
-                                       </xslt:if>
-                                       <xslt:copy-of select="html:html/@*"/>
-                                       <xslt:if test="not(html:html/@lang) and (html:*/@lang|svg:*/@lang|*/@xml:lang)">
-                                               <xslt:attribute name="lang">
-                                                       <xslt:value-of select="html:*/@lang|svg:*/@lang|*/@xml:lang"/>
-                                               </xslt:attribute>
-                                       </xslt:if>
-                                       <xslt:if test="not(html:html/@xml:lang) and (html:*/@lang|svg:*/@lang|*/@xml:lang)">
-                                               <xslt:attribute name="xml:lang">
-                                                       <xslt:value-of select="html:*/@lang|svg:*/@lang|*/@xml:lang"/>
-                                               </xslt:attribute>
-                                       </xslt:if>
-                                       <html:head>
-                                               <xslt:copy-of select="html:html/html:head/@*|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)/node()[not(self::*) or not(self::html:title)]"/>
-                                               <html:meta name="generator">
-                                                       <xslt:attribute name="content">
-                                                               <xslt:for-each select="exsl:node-set($metadata)/html:meta[@name='generator']">
-                                                                       <xslt:value-of select="@content"/>
-                                                                       <xslt:text>, </xslt:text>
-                                                               </xslt:for-each>
-                                                               <xslt:text>⛩️📰 书社</xslt:text>
-                                                               <xslt:if test="$THISREV">
-                                                                       <xslt:text> (</xslt:text>
-                                                                       <xslt:value-of select="$THISREV"/>
-                                                                       <xslt:text>)</xslt:text>
-                                                               </xslt:if>
-                                                       </xslt:attribute>
-                                               </html:meta>
-                                       </html:head>
-                                       <html:body>
-                                               <xslt:copy-of select="html:html/html:body/@*|html:body/@*"/>
-                                               <xslt:apply-templates select="exsl:node-set($modalinput)" mode="书社:header"/>
-                                               <xslt:copy-of select="node()[not(self::html:html or self::html:head or self::html:body)]|html:html/node()[not(self::html:head or self::html:body)]|html:html/html:body/node()|html:body/node()"/>
-                                               <xslt:apply-templates select="exsl:node-set($modalinput)" mode="书社:footer"/>
-                                       </html:body>
-                               </html:html>
-                       </xslt:template>
                        <xslt:output method="xml" encoding="UTF-8" cdata-section-elements="html:script html:style html:textarea"/>
                </xslt:transform>
        </template>
                        <xslt:output method="xml" encoding="UTF-8" cdata-section-elements="html:script html:style html:textarea"/>
                </xslt:transform>
        </template>
index 0242f435a688f567af665e6761f792a0e36c6db9..55b449b64ea5fbe05ca12d9b53bfc0b2c4184d2b 100644 (file)
@@ -19,20 +19,30 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
        <书社:id>urn:fdc:ladys.computer:20231231:Shu1She4:asset.xslt</书社:id>
        <template match="html:style|html:object[@type='text/css']"/>
        <template match="html:object[@type='text/javascript']">
        <书社:id>urn:fdc:ladys.computer:20231231:Shu1She4:asset.xslt</书社:id>
        <template match="html:style|html:object[@type='text/css']"/>
        <template match="html:object[@type='text/javascript']">
-               <html:script type="{@type}" src="{@data}"/>
+               <html:script type="{@type}" src="{@data}">
+                       <copy-of select="@书社:identifier"/>
+               </html:script>
        </template>
        <template match="html:object[starts-with(@type, 'audio/')]">
        </template>
        <template match="html:object[starts-with(@type, 'audio/')]">
-               <html:audio controls="" src="{@data}"/>
+               <html:audio controls="" src="{@data}">
+                       <copy-of select="@书社:identifier"/>
+               </html:audio>
        </template>
        <template match="html:object[starts-with(@type, 'image/') and not(@type='image/svg+xml')]">
        </template>
        <template match="html:object[starts-with(@type, 'image/') and not(@type='image/svg+xml')]">
-               <html:img src="{@data}"/>
+               <html:img src="{@data}">
+                       <copy-of select="@书社:identifier"/>
+               </html:img>
        </template>
        <template match="html:object[starts-with(@type, 'video/')]">
        </template>
        <template match="html:object[starts-with(@type, 'video/')]">
-               <html:video controls="" src="{@data}"/>
+               <html:video controls="" src="{@data}">
+                       <copy-of select="@书社:identifier"/>
+               </html:video>
        </template>
        <template match="xslt:include[@书社:id='urn:fdc:ladys.computer:20231231:Shu1She4:asset.xslt']" mode="书社:metadata">
                <for-each select="exsl:node-set($书社:expansion)//html:object[@type='text/css']">
        </template>
        <template match="xslt:include[@书社:id='urn:fdc:ladys.computer:20231231:Shu1She4:asset.xslt']" mode="书社:metadata">
                <for-each select="exsl:node-set($书社:expansion)//html:object[@type='text/css']">
-                       <html:link rel="stylesheet" type="text/css" href="{@data}"/>
+                       <html:link rel="stylesheet" type="text/css" href="{@data}">
+                               <copy-of select="@书社:identifier"/>
+                       </html:link>
                </for-each>
                <for-each select="exsl:node-set($书社:expansion)//html:style">
                        <copy-of select="."/>
                </for-each>
                <for-each select="exsl:node-set($书社:expansion)//html:style">
                        <copy-of select="."/>
diff --git a/transforms/attributes.xslt b/transforms/attributes.xslt
deleted file mode 100644 (file)
index e91e7cb..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0"?>
-<!--
-⁌ ⛩️📰 书社 ∷ transforms/attributes.xslt
-
-© 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/>.
--->
-<transform
-       xmlns="http://www.w3.org/1999/XSL/Transform"
-       xmlns:exsl="http://exslt.org/common"
-       xmlns:书社="urn:fdc:ladys.computer:20231231:Shu1She4"
-       exclude-result-prefixes="exsl"
-       version="1.0"
->
-       <书社:id>urn:fdc:ladys.computer:20231231:Shu1She4:attributes.xslt</书社:id>
-       <template match="书社:apply-attributes">
-               <for-each select="node()">
-                       <choose>
-                               <when test="self::*">
-                                       <variable name="original" select="."/>
-                                       <variable name="result">
-                                               <apply-templates select="."/>
-                                       </variable>
-                                       <for-each select="exsl:node-set($result)/*">
-                                               <copy>
-                                                       <for-each select="@*|$original/../@*">
-                                                               <copy/>
-                                                       </for-each>
-                                                       <apply-templates/>
-                                               </copy>
-                                       </for-each>
-                               </when>
-                               <otherwise>
-                                       <apply-templates select="."/>
-                               </otherwise>
-                       </choose>
-               </for-each>
-       </template>
-</transform>
This page took 0.094751 seconds and 4 git commands to generate.