From: Lady <redacted>
Date: Mon, 1 Jan 2024 22:07:51 +0000 (-0500)
Subject: Add a basic record-jar parser
X-Git-Tag: 0.2.0~2
X-Git-Url: https://git.ladys.computer/Shushe/commitdiff_plain/edacd9742b9feb3d3d6e10f41b6b077cb51e8002

Add a basic record-jar parser
---

diff --git a/README.markdown b/README.markdown
index 5b5b84c..f2cfdd9 100644
--- a/README.markdown
+++ b/README.markdown
@@ -175,6 +175,8 @@ Supported magic numbers include :⁠—
 - `#!js` for `text/javascript` files
 - `@charset "` for `text/css` files
 - `#!tsv` for `text/tab-separated-values` files
+- `%%` for `text/record-jar` files (unregistered; see
+    [[draft-phillips-record-jar-01][]])
 
 Text formats with associated X·S·L·T parsers are wrapped in a H·T·M·L
   `<script>` element whose `@type` gives its media type, and then
@@ -365,3 +367,5 @@ Output wrapping can be entirely disabled by adding a
 Source files are licensed under the terms of the <cite>Mozilla Public
   License, version 2.0</cite>.
 For more information, see [LICENSE](./LICENSE).
+
+[draft-phillips-record-jar-01]: <https://datatracker.ietf.org/doc/html/draft-phillips-record-jar-01>
\ No newline at end of file
diff --git a/magic/record-jar b/magic/record-jar
new file mode 100644
index 0000000..f4140d3
--- /dev/null
+++ b/magic/record-jar
@@ -0,0 +1,10 @@
+0  string     %%   record-jar text
+!:mime text/record-jar
+!:strength + 255
+
+0     byte    0xEF
+>1    byte    0xBB
+>>2   byte    0xBF
+>>>3  string  %%   record-jar text
+!:mime text/record-jar
+!:strength + 255
diff --git a/parsers/record-jar.xslt b/parsers/record-jar.xslt
new file mode 100644
index 0000000..db8948e
--- /dev/null
+++ b/parsers/record-jar.xslt
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+<!--
+⁌ ⛩️📰 书社 ∷ parsers/record-jar.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: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:record-jar.xslt</书社:id>
+	<template match="html:script[@type='text/record-jar']">
+		<variable name="lines" select="exslstr:tokenize(., '&#xA;')"/>
+		<html:div class="record-jar">
+			<for-each select="$lines[not(position()=1) and starts-with(., '%%')]">
+				<variable name="end" select="."/>
+				<variable name="start" select="preceding-sibling::*[starts-with(., '%%')][1]"/>
+				<variable name="fields" select="($start/following-sibling::*|$lines[not($start)])[not(preceding-sibling::*[generate-id()=generate-id($end)]) and not(starts-with(., '%%'))]"/>
+				<if test="$fields">
+					<html:dl>
+						<for-each select="$fields">
+							<choose>
+								<when test="starts-with(., ' ') and $fields[generate-id()=generate-id(current()/preceding-sibling::*[1])]"/>
+								<otherwise>
+									<variable name="next" select="following-sibling::*[not(starts-with(., ' '))]"/>
+									<html:div>
+										<html:dt>
+											<value-of select="normalize-space(substring-before(., ':'))"/>
+										</html:dt>
+										<html:dd>
+											<variable name="firstline">
+												<choose>
+													<when test="contains(., ':')">
+														<value-of select="normalize-space(substring-after(., ':'))"/>
+													</when>
+													<otherwise>
+														<value-of select="normalize-space(.)"/>
+													</otherwise>
+												</choose>
+											</variable>
+											<choose>
+												<when test="substring($firstline, string-length($firstline))='\' and following-sibling::*[position()=1 and starts-with(., ' ')]">
+													<value-of select="substring($firstline, 1, string-length($firstline)-1)"/>
+												</when>
+												<otherwise>
+													<value-of select="$firstline"/>
+												</otherwise>
+											</choose>
+											<for-each select="following-sibling::*[starts-with(., ' ') and not(preceding-sibling::*[generate-id()=generate-id($next)])]">
+												<variable name="nextline" select="normalize-space(.)"/>
+												<choose>
+													<when test="substring($nextline, string-length($nextline))='\' and following-sibling::*[position()=1 and starts-with(., ' ')]">
+														<value-of select="substring($nextline, 1, string-length($nextline)-1)"/>
+													</when>
+													<otherwise>
+														<value-of select="$nextline"/>
+													</otherwise>
+												</choose>
+											</for-each>
+										</html:dd>
+									</html:div>
+								</otherwise>
+							</choose>
+						</for-each>
+					</html:dl>
+				</if>
+			</for-each>
+		</html:div>
+	</template>
+</transform>