From: Lady <redacted>
Date: Mon, 1 Jan 2024 16:49:24 +0000 (-0500)
Subject: Automatically encapsulate metadata and preserve it
X-Git-Tag: 0.2.0~7
X-Git-Url: https://git.ladys.computer/Shushe/commitdiff_plain/0dbf03dfcc1a94ba1a07a0b1d7dd8c0f53824db3

Automatically encapsulate metadata and preserve it

During the embedding phase, give top‐level elements and embeds
`@itemscope` properties as well as a `@itemtype` which indicates which
they are. Don’t remove microdata from the output, and make use of these
properties when processing to ensure only document metadata is actually
used.
---

diff --git a/README.markdown b/README.markdown
index 84c3206..2bb1bce 100644
--- a/README.markdown
+++ b/README.markdown
@@ -228,13 +228,13 @@ For example, the trivial `text/plain` parser is defined as follows :⁠—
 ```xml
 <?xml version="1.0"?>
 <transform
-	xmlns="http://www.w3.org/1999/XSL/Transform"
-	xmlns:html="http://www.w3.org/1999/xhtml"
-	version="1.0"
+  xmlns="http://www.w3.org/1999/XSL/Transform"
+  xmlns:html="http://www.w3.org/1999/xhtml"
+  version="1.0"
 >
-	<template match="html:script[@type='text/plain']">
-		<html:pre><value-of select="."/></html:pre>
-	</template>
+  <template match="html:script[@type='text/plain']">
+    <html:pre><value-of select="."/></html:pre>
+  </template>
 </transform>
 ```
 
@@ -287,15 +287,17 @@ Transforms are used to convert X·M·L files into their final output,
 
 - **`transforms/metadata.xslt`:**
   Provides basic `<html:head>` metadata.
-  This metadata is generated from `<html:meta>` descendants of the
-    first element with an `@itemscope` attribute (recommended to just
-    be the root element).
-  Such elements can provide metadata using the following `@itemprop`
-    attributes :⁠—
+  This metadata is generated from `<html:meta>` elements with one o.
+    the following `@itemprop` attributes :⁠—
 
   - **`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.
+  To undo this behaviour, remove the `@itemscope` and `@itemtype`
+    attributes from the embed during the transformation phase.
+
 The following are recommendations on effective creation of
   transforms :⁠—
 
@@ -335,17 +337,17 @@ This mechanism can be used to allow transforms to insert content
 ```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"
+  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>
+  <书社: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>
 ```
 
diff --git a/lib/catalog2transform.xslt b/lib/catalog2transform.xslt
index e7640e8..08918b2 100644
--- a/lib/catalog2transform.xslt
+++ b/lib/catalog2transform.xslt
@@ -12,6 +12,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 	xmlns:html="http://www.w3.org/1999/xhtml"
 	xmlns:catalog="urn:oasis:names:tc:entity:xmlns:xml:catalog"
 	xmlns:exsl="http://exslt.org/common"
+	xmlns:exslstr="http://exslt.org/strings"
 	xmlns:xlink="http://www.w3.org/1999/xlink"
 	xmlns:xslt="http://www.w3.org/1999/XSL/TransformAlias"
 	xmlns:书社="urn:fdc:ladys.computer:20231231:Shu1She4"
@@ -66,11 +67,39 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 					<xslt:apply-templates select="@*|node()"/>
 				</xslt:copy>
 			</xslt:template>
-			<xslt:template match="书社:link[@xlink:show='embed']" mode="书社:expand">
+			<xslt:template match="/*" mode="书社:expand" priority="0">
+				<xslt:copy>
+					<xslt:attribute name="itemscope">itemscope</xslt:attribute>
+					<xslt:attribute name="itemtype">
+						<xslt:text>urn:fdc:ladys.computer:20231231:Shu1She4:document</xslt:text>
+						<xslt:for-each select="exslstr:tokenize(@itemtype)/token">
+							<xslt: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: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:choose>
 					<xslt:when test="$uri">
-						<xslt:apply-templates select="document($uri)" mode="书社:expand"/>
+						<xslt:variable name="expanded">
+							<xslt:apply-templates select="document($uri)" mode="书社:expand"/>
+						</xslt:variable>
+						<xslt:for-each select="exsl:node-set($expanded)/*">
+							<xslt:copy>
+								<xslt:attribute name="itemscope">itemscope</xslt:attribute>
+								<xslt:attribute name="itemtype">
+									<xslt:text>urn:fdc:ladys.computer:20231231:Shu1She4:embed</xslt:text>
+									<xslt:for-each select="exslstr:tokenize(@itemtype)/token[string()!='urn:fdc:ladys.computer:20231231:Shu1She4:document']">
+										<xslt: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'))]|node()"/>
+							</xslt:copy>
+						</xslt:for-each>
 					</xslt:when>
 					<xslt:otherwise>
 						<xslt:copy>
@@ -79,7 +108,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:template match="@*|text()|*[not(self::书社:link) or not(@xlink:show='embed')]" mode="书社:expand">
+			<xslt:template match="@*|text()|*[not(self::书社:link) or not(@xlink:show='embed')]" mode="书社:expand" priority="-1">
 				<xslt:copy>
 					<xslt:apply-templates select="@*|node()" mode="书社:expand"/>
 				</xslt:copy>
diff --git a/transforms/metadata.xslt b/transforms/metadata.xslt
index 88877a4..b5f180f 100644
--- a/transforms/metadata.xslt
+++ b/transforms/metadata.xslt
@@ -7,6 +7,10 @@
 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/>.
 -->
+<!DOCTYPE transform [
+	<!ENTITY attoplevel "ancestor::html:*[@itemscope and @itemtype='&书社;:document'] and not(ancestor::html:*[@itemscope]/ancestor::html:*[@itemscope and @itemtype='&书社;:document'] or preceding::html:*[@itemtype='&书社;:document'])">
+	<!ENTITY 书社 "urn:fdc:ladys.computer:20231231:Shu1She4">
+]>
 <transform
 	xmlns="http://www.w3.org/1999/XSL/Transform"
 	xmlns:html="http://www.w3.org/1999/xhtml"
@@ -15,23 +19,9 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 	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>
-			<value-of select="substring-after(@itemprop, 'urn:fdc:ladys.computer:20231231:Shu1She4:')"/>
-			<text>: </text>
+	<template match="html:meta[not(@name) and @itemprop='&书社;:title'][&attoplevel;]" mode="书社:metadata">
+		<html:title>
 			<value-of select="@content"/>
-		</comment>
-	</template>
-	<template match="comment()[starts-with(., '[书社:META] ')]" mode="书社:metadata">
-		<variable name="property" select="substring-before(substring-after(., '[书社:META] '), ': ')"/>
-		<variable name="value" select="substring-after(., concat('[书社:META] ', $property, ': '))"/>
-		<choose>
-			<when test="$property='title'">
-				<html:title>
-					<value-of select="$value"/>
-				</html:title>
-			</when>
-		</choose>
+		</html:title>
 	</template>
 </transform>