3 SPDX-FileCopyrightText: 2023, 2024, 2025 Lady <https://www.ladys.computer/about/#lady>
4 SPDX-License-Identifier: MPL-2.0
7 ⁌ ⛩📰 书社 ∷ lib/expandmetadata.xslt
9 © 2023–2025 Lady [@ Ladys Computer].
11 This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0.
12 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/>.
15 xmlns="http://www.w3.org/1999/XSL/Transform"
16 xmlns:exsl="http://exslt.org/common"
17 xmlns:exslstr="http://exslt.org/strings"
18 xmlns:nie="http://www.semanticdesktop.org/ontologies/2007/01/19/nie#"
19 xmlns:nfo="http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#"
20 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
21 xmlns:xlink="http://www.w3.org/1999/xlink"
22 xmlns:书社="urn:fdc:ladys.computer:20231231:Shu1She4"
23 xmlns:书社vocab="urn:fdc:ladys.computer:20231231:Shu1She4:vocab:"
24 extension-element-prefixes="exsl exslstr"
27 <variable name="builddir" select="//书社vocab:BuildDirectory/@nfo:fileUrl"/>
28 <variable name="files" select="//书社vocab:SourceFile|//书社vocab:IncludeFile"/>
29 <variable name="stated-dependencies-fragment">
30 <for-each select="$files[nie:interpretedAs/nfo:PlainTextDocument]">
31 <variable name="uri" select="书社vocab:hasParsedFile/@nfo:fileUrl"/>
32 <书社:Dependencies for="{@rdf:about}">
33 <for-each select="document($uri)//书社:link">
34 <variable name="spaced-show">
36 <when test="@xlink:show">
38 <value-of select="@xlink:show"/>
46 <variable name="actuate">
48 <when test="@xlink:actuate">
49 <value-of select="@xlink:actuate"/>
52 <text>none</text><!-- not the true default in all cases, but in the ones that matter -->
56 <variable name="name" select="string(@name)"/>
57 <if test="contains(' embed other none ', $spaced-show) and $actuate='none'">
58 <variable name="identifier" select="string(@xlink:href)"/>
59 <variable name="is-dir" select="substring($identifier, string-length($identifier))='/'"/>
60 <for-each select="$files/@rdf:about[string(.)=$identifier or $is-dir and starts-with(., $identifier)]">
61 <sort select="." data-type="text" lang="zxx" case-order="upper-first"/>
63 <when test="$spaced-show=' embed '">
64 <书社:dependency name="{$name}">
65 <value-of select="."/>
68 <when test="$spaced-show=' other '">
69 <书社:transitive-soft-dependency name="{$name}">
70 <value-of select="."/>
71 </书社:transitive-soft-dependency>
74 <书社:soft-dependency name="{$name}">
75 <value-of select="."/>
85 <variable name="stated-dependencies" select="exsl:node-set($stated-dependencies-fragment)/*"/>
86 <template name="书社:collect-dependency-paths">
87 <param name="path" select="/.."/>
88 <variable name="parent" select="$path/*[last()]"/>
89 <variable name="children-fragment">
90 <for-each select="$stated-dependencies[@for=string($parent)]/*">
92 <when test="$path/*[string()=current()]">
93 <if test="self::书社:dependency">
94 <书社:recursive-dependency name="{@name}">
95 <value-of select="."/>
96 </书社:recursive-dependency>
100 <copy-of select="."/>
105 <variable name="children" select="exsl:node-set($children-fragment)/*"/>
106 <variable name="child-paths-fragment">
107 <for-each select="$children">
109 <when test="self::书社:recursive-dependency">
111 <copy-of select="$path/*[string()=current()][1]/preceding-sibling::*"/>
112 <copy-of select="."/><!-- replace first instance with recursive dependency -->
113 </书社:dependency-path>
115 <when test="$parent/self::书社:transitive-soft-dependency and string(@name)!=string($parent/@name)"/>
116 <when test="self::书社:soft-dependency">
118 <copy-of select="$path"/>
119 <copy-of select="."/>
120 </书社:dependency-path>
123 <variable name="path-fragment">
124 <copy-of select="$path"/>
126 <when test="self::书社:dependency and $path/书社:transitive-soft-dependency">
127 <书社:transitive-soft-dependency name="{@name}">
128 <value-of select="."/>
129 </书社:transitive-soft-dependency>
132 <copy-of select="."/>
136 <call-template name="书社:collect-dependency-paths">
137 <with-param name="path" select="exsl:node-set($path-fragment)"/>
138 </call-template><!-- a little inefficient in the case of reflexive dependencies, as the path will be traversed once in each direction, but improving on this is a hard problem in X·S·L·T -->
143 <variable name="child-paths" select="exsl:node-set($child-paths-fragment)/*"/>
145 <when test="$child-paths">
146 <copy-of select="$child-paths"/>
148 <otherwise><!-- fallback result is just the input path -->
150 <copy-of select="$path"/>
151 </书社:dependency-path>
155 <template match="nie:interpretedAs/*" priority="1">
157 <apply-templates select="@*|node()"/>
158 <for-each select="../../书社vocab:hasParsedFileWithMetadata">
159 <copy-of select="document(@nfo:fileUrl)/书社:parsed/书社:metadata/rdf:RDF/rdf:Description/node()"/>
163 <template match="//书社vocab:SourceFile[not(nie:interpretedAs/nfo:PlainTextDocument)]" priority="1">
165 <apply-templates select="@*"/>
166 <apply-templates select="node()"/>
167 <element name="书社vocab:destination">
168 <value-of select="@书社vocab:path"/>
172 <template match="//书社vocab:SourceFile[nie:interpretedAs/nfo:PlainTextDocument]" priority="1">
173 <variable name="parsed" select="document(书社vocab:hasParsedFile/@nfo:fileUrl)"/>
174 <variable name="provided-destinations" select="normalize-space($parsed/*/@书社:destination)"/>
175 <variable name="destinations-fragment">
176 <if test="$provided-destinations!=''">
177 <for-each select="exslstr:tokenize($provided-destinations)">
178 <element name="书社vocab:destination">
179 <value-of select="."/>
184 <variable name="destinations" select="exsl:node-set($destinations-fragment)/node()"/>
185 <variable name="bad-destinations-fragment">
186 <for-each select="$destinations">
187 <variable name="destination-delim" select="concat('/', ., '/')"/>
188 <if test="contains($destination-delim, '//') or contains($destination-delim, '/./') or contains($destination-delim, '/../')">
189 <copy-of select="."/>
193 <variable name="bad-destinations" select="exsl:node-set($bad-destinations-fragment)/node()"/>
195 <apply-templates select="@*"/>
196 <apply-templates select="node()"/>
197 <apply-templates select="." mode="书社:dependencies"/>
199 <when test="not($destinations)">
200 <element name="书社vocab:destination">
201 <value-of select="@书社vocab:path"/>
204 <when test="$bad-destinations">
205 <message terminate="no">
206 <text>Bad destinations: </text>
207 <for-each select="$bad-destinations">
208 <if test="position()>1">
212 <value-of select="."/>
216 <element name="书社vocab:destination">
217 <value-of select="@书社vocab:path"/>
221 <for-each select="$destinations">
222 <element name="书社vocab:destination">
223 <value-of select="."/>
230 <template match="//书社vocab:IncludeFile[nie:interpretedAs/nfo:PlainTextDocument]" priority="1">
232 <apply-templates select="@*|node()"/>
233 <apply-templates select="." mode="书社:dependencies"/>
236 <template match="书社vocab:hasParsedFileWithMetadata" priority="1"/>
238 <variable name="result-fragment">
241 <variable name="result" select="exsl:node-set($result-fragment)"/>
242 <copy-of select="$result/*"/>
243 <exsl:document href="dependencies" method="text" encoding="UTF-8">
244 <for-each select="$result/rdf:RDF/*[nie:interpretedAs/nfo:PlainTextDocument]">
245 <value-of select="@rdf:about"/>
247 <for-each select="书社vocab:hasRecursiveDependencyOn/@rdf:resource">
249 <value-of select="."/>
252 <for-each select="书社vocab:hasSoftDependencyOn/@rdf:resource">
254 <value-of select="."/>
257 <for-each select="书社vocab:hasDependencyOn/@rdf:resource">
259 <value-of select="."/>
264 <exsl:document href="destinations" method="text" encoding="UTF-8">
265 <for-each select="$result//书社vocab:SourceFile">
266 <value-of select="@rdf:about"/>
268 <for-each select="书社vocab:destination">
269 <if test="position()>1">
272 <value-of select="."/>
278 <template match="@*|node()">
280 <apply-templates select="@*|node()"/>
283 <template match="书社vocab:SourceFile|书社vocab:IncludeFile" mode="书社:dependencies">
284 <if test="nie:interpretedAs/nfo:PlainTextDocument">
285 <variable name="path-fragment">
286 <element name="书社:dependency-root">
287 <value-of select="@rdf:about"/>
290 <variable name="paths-fragment">
291 <call-template name="书社:collect-dependency-paths">
292 <with-param name="path" select="exsl:node-set($path-fragment)"/>
295 <variable name="paths-document" select="exsl:node-set($paths-fragment)"/>
296 <for-each select="$paths-document//书社:recursive-dependency">
297 <if test="not(preceding::*[string()=string(current())])">
298 <element name="书社vocab:hasRecursiveDependencyOn">
299 <attribute name="rdf:resource">
300 <value-of select="."/>
305 <for-each select="$paths-document//书社:dependency">
306 <if test="not((preceding::*|//书社:recursive-dependency)[string()=string(current())])">
307 <element name="书社vocab:hasDependencyOn">
308 <attribute name="rdf:resource">
309 <value-of select="."/>
314 <for-each select="$paths-document//*[self::书社:soft-dependency or self::书社:transitive-soft-dependency]">
315 <if test="not((preceding::*|//书社:recursive-dependency|//书社:dependency)[string()=string(current())])">
316 <element name="书社vocab:hasSoftDependencyOn">
317 <attribute name="rdf:resource">
318 <value-of select="."/>
325 <output method="xml" encoding="UTF-8"/>