From: Lady <redacted>
Date: Sat, 26 Apr 2025 02:53:07 +0000 (-0400)
Subject: Use set functions rather than generate-id()
X-Git-Tag: 0.5.0~9
X-Git-Url: https://git.ladys.computer/LesML/commitdiff_plain/5776803ccc0eba18d1bd4259830f2adc18a7228a?ds=inline

Use set functions rather than generate-id()

These should be faster, and are generally cleaner and more readable
besides.
---

diff --git a/parser.xslt b/parser.xslt
index 8772693..e726a9e 100644
--- a/parser.xslt
+++ b/parser.xslt
@@ -21,6 +21,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 	xmlns="http://www.w3.org/1999/XSL/Transform"
 	xmlns:LesML="urn:fdc:ladys.computer:20240512:LesML"
 	xmlns:exsl="http://exslt.org/common"
+	xmlns:exslset="http://exslt.org/sets"
 	xmlns:exslstr="http://exslt.org/strings"
 	xmlns:html="http://www.w3.org/1999/xhtml"
 	xmlns:书社="urn:fdc:ladys.computer:20231231:Shu1She4"
@@ -212,7 +213,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 		<variable name="params" select="exsl:node-set($params-fragment)/*"/>
 		<variable name="noshebang" select="$lines[position()>1 or not(starts-with(., '#!lesml') or starts-with(., '##'))]"/>
 		<variable name="docsep" select="$noshebang[starts-with(., '#!lesml') or starts-with(., '##')][1]"/>
-		<variable name="doclines" select="$noshebang[not($docsep) or following-sibling::*[generate-id()=generate-id($docsep)]]"/>
+		<variable name="doclines" select="exslset:leading($noshebang, $docsep)"/>
 		<if test="starts-with($first-line, '##') and $first-line!='##'">
 			<comment>
 				<value-of select="substring-after($first-line, '##')"/>
@@ -242,14 +243,14 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 						<for-each select="$record-separators">
 							<variable name="position" select="position()"/>
 							<variable name="prev-separator" select="$record-separators[($position)-1]"/>
-							<variable name="fields" select="$noshebang[following-sibling::*[generate-id()=generate-id(current())] and (not($prev-separator) or preceding-sibling::*[generate-id()=generate-id($prev-separator)])]"/>
+							<variable name="fields" select="exslset:leading(exslset:trailing($doclines, $prev-separator), .)"/>
 							<if test="$fields">
 								<element name="dl" namespace="&xhtml;">
 									<for-each select="$fields">
 										<choose>
-											<when test="starts-with(., ' ') and $fields[generate-id()=generate-id(current()/preceding-sibling::*[1])]"/>
+											<when test="starts-with(., ' ') and exslset:leading($fields, .)"/>
 											<otherwise>
-												<variable name="next" select="following-sibling::*[not(starts-with(., ' '))]"/>
+												<variable name="next" select="exslset:intersection(following-sibling::*[not(starts-with(., ' '))][1], $fields)"/>
 												<element name="div" namespace="&xhtml;">
 													<element name="dt" namespace="&xhtml;">
 														<value-of select="normalize-space(substring-before(., ':'))"/>
@@ -273,7 +274,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 																<value-of select="$firstline"/>
 															</otherwise>
 														</choose>
-														<for-each select="following-sibling::*[starts-with(., ' ') and not(preceding-sibling::*[generate-id()=generate-id($next)])]">
+														<for-each select="exslset:intersection(following-sibling::*[starts-with(., ' ')], exslset:leading($fields, $next))">
 															<variable name="nextline" select="normalize-space(.)"/>
 															<choose>
 																<when test="substring($nextline, string-length($nextline))='\' and following-sibling::*[position()=1 and starts-with(., ' ')]">
@@ -304,14 +305,14 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 						<text>body</text>
 					</attribute>
 					<call-template name="LesML:paragraphize">
-						<with-param name="lines" select="$doclines[not($record-separators) or preceding-sibling::*[generate-id()=generate-id($record-separators[last()])]]"/>
+						<with-param name="lines" select="exslset:trailing($doclines, $record-separators[last()])"/>
 					</call-template>
 				</element>
 			</element>
 		</if>
 		<if test="$docsep">
 			<call-template name="LesML:parse">
-				<with-param name="lines" select="$docsep|$lines[preceding-sibling::*[generate-id()=generate-id($docsep)]]"/>
+				<with-param name="lines" select="$docsep|exslset:trailing($lines, $docsep)"/>
 				<with-param name="parent-params" select="$params"/>
 			</call-template>
 		</if>
@@ -323,7 +324,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 			<for-each select="$last-lines">
 				<variable name="position" select="position()"/>
 				<variable name="prev-last" select="$last-lines[($position)-1]"/>
-				<variable name="linespans" select="$lines[following-sibling::*[generate-id()=generate-id(current())] and (not($prev-last) or preceding-sibling::*[generate-id()=generate-id($prev-last)]) and normalize-space()!='']|."/>
+				<variable name="linespans" select="(exslset:intersection(exslset:trailing($lines, $prev-last), exslset:leading($lines, .))|.)[normalize-space()!='']"/>
 				<variable name="quoted" select="not($linespans[not(starts-with(., ' ') or starts-with(., '&#x9;'))])"/>
 				<variable name="preformatted" select="not($linespans[not(starts-with(normalize-space(), '|'))])"/>
 				<variable name="text">
@@ -647,7 +648,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 			<variable name="notquote" select="following-sibling::node()[not(self::html:blockquote)][1]"/>
 			<variable name="contents">
 				<copy-of select="node()"/>
-				<for-each select="following-sibling::node()[not($notquote) or following-sibling::node()[generate-id()=generate-id($notquote)]]">
+				<for-each select="exslset:leading(following-sibling::node(), $notquote)">
 					<copy-of select="node()"/>
 				</for-each>
 			</variable>
@@ -686,7 +687,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 			<variable name="notcontinuation" select="following-sibling::node()[not(self::html:div and @class='continuation')][1]"/>
 			<copy>
 				<apply-templates select="@*|node()" mode="LesML:finalize-tree"/>
-				<for-each select="following-sibling::node()[not($notcontinuation) or following-sibling::node()[generate-id()=generate-id($notcontinuation)]]">
+				<for-each select="exslset:leading(following-sibling::node(), $notcontinuation)">
 					<apply-templates select="node()" mode="LesML:finalize-tree"/>
 				</for-each>
 			</copy>
@@ -713,11 +714,11 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 		</variable>
 		<variable name="notinlist" select="following-sibling::node()[not(self::html:div and @class='continuation' or self::html:li and (@data-level>$current-level or @data-level=$current-level and @class=$current-class))][1]"/>
 		<element name="{$wrapper}" namespace="&xhtml;">
-			<for-each select=".|following-sibling::html:li[@data-level=$current-level and (not($notinlist) or following-sibling::node()[generate-id()=generate-id($notinlist)])]">
+			<for-each select=".|exslset:leading(following-sibling::node(), $notinlist)[self::html:li and @data-level=$current-level]">
 				<variable name="notcontinuation" select="following-sibling::node()[not(self::html:div and @class='continuation')][1]"/>
 				<copy>
 					<apply-templates select="@*|node()" mode="LesML:finalize-tree"/>
-					<for-each select="following-sibling::node()[not($notcontinuation) or following-sibling::node()[generate-id()=generate-id($notcontinuation)]]">
+					<for-each select="exslset:leading(following-sibling::node(), $notcontinuation)">
 						<apply-templates select="node()" mode="LesML:finalize-tree"/>
 					</for-each>
 					<if test="$notcontinuation/self::html:li[@data-level>$current-level]">