1<?xml version="1.0"?>
2
3<xsl:stylesheet version="1.0"
4 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5 xmlns:str="http://exslt.org/strings"
6 xmlns:exsl="http://exslt.org/common"
7 xmlns:db="http://docbook.org/ns/docbook"
8 xmlns:nixos="tag:nixos.org"
9 extension-element-prefixes="str exsl">
10 <xsl:output method='xml' encoding="UTF-8" />
11
12 <xsl:template match="@*|node()">
13 <xsl:copy>
14 <xsl:apply-templates select="@*|node()" />
15 </xsl:copy>
16 </xsl:template>
17
18 <xsl:template name="break-up-description">
19 <xsl:param name="input" />
20 <xsl:param name="buffer" />
21
22 <!-- Every time we have two newlines following each other, we want to
23 break it into </para><para>. -->
24 <xsl:variable name="parbreak" select="'

'" />
25
26 <!-- Similar to "(head:tail) = input" in Haskell. -->
27 <xsl:variable name="head" select="$input[1]" />
28 <xsl:variable name="tail" select="$input[position() > 1]" />
29
30 <xsl:choose>
31 <xsl:when test="$head/self::text() and contains($head, $parbreak)">
32 <!-- If the haystack provided to str:split() directly starts or
33 ends with $parbreak, it doesn't generate a <token/> for that,
34 so we are doing this here. -->
35 <xsl:variable name="splitted-raw">
36 <xsl:if test="starts-with($head, $parbreak)"><token /></xsl:if>
37 <xsl:for-each select="str:split($head, $parbreak)">
38 <token><xsl:value-of select="node()" /></token>
39 </xsl:for-each>
40 <!-- Something like ends-with($head, $parbreak), but there is
41 no ends-with() in XSLT, so we need to use substring(). -->
42 <xsl:if test="
43 substring($head, string-length($head) -
44 string-length($parbreak) + 1) = $parbreak
45 "><token /></xsl:if>
46 </xsl:variable>
47 <xsl:variable name="splitted"
48 select="exsl:node-set($splitted-raw)/token" />
49 <!-- The buffer we had so far didn't contain any text nodes that
50 contain a $parbreak, so we can put the buffer along with the
51 first token of $splitted into a para element. -->
52 <para xmlns="http://docbook.org/ns/docbook">
53 <xsl:apply-templates select="exsl:node-set($buffer)" />
54 <xsl:apply-templates select="$splitted[1]/node()" />
55 </para>
56 <!-- We have already emitted the first splitted result, so the
57 last result is going to be set as the new $buffer later
58 because its contents may not be directly followed up by a
59 $parbreak. -->
60 <xsl:for-each select="$splitted[position() > 1
61 and position() < last()]">
62 <para xmlns="http://docbook.org/ns/docbook">
63 <xsl:apply-templates select="node()" />
64 </para>
65 </xsl:for-each>
66 <xsl:call-template name="break-up-description">
67 <xsl:with-param name="input" select="$tail" />
68 <xsl:with-param name="buffer" select="$splitted[last()]/node()" />
69 </xsl:call-template>
70 </xsl:when>
71 <!-- Either non-text node or one without $parbreak, which we just
72 want to buffer and continue recursing. -->
73 <xsl:when test="$input">
74 <xsl:call-template name="break-up-description">
75 <xsl:with-param name="input" select="$tail" />
76 <!-- This essentially appends $head to $buffer. -->
77 <xsl:with-param name="buffer">
78 <xsl:if test="$buffer">
79 <xsl:for-each select="exsl:node-set($buffer)">
80 <xsl:apply-templates select="." />
81 </xsl:for-each>
82 </xsl:if>
83 <xsl:apply-templates select="$head" />
84 </xsl:with-param>
85 </xsl:call-template>
86 </xsl:when>
87 <!-- No more $input, just put the remaining $buffer in a para. -->
88 <xsl:otherwise>
89 <para xmlns="http://docbook.org/ns/docbook">
90 <xsl:apply-templates select="exsl:node-set($buffer)" />
91 </para>
92 </xsl:otherwise>
93 </xsl:choose>
94 </xsl:template>
95
96 <xsl:template match="nixos:option-description">
97 <xsl:choose>
98 <!--
99 Only process nodes that are comprised of a single <para/> element,
100 because if that's not the case the description already contains
101 </para><para> in between and we need no further processing.
102 -->
103 <xsl:when test="count(db:para) > 1">
104 <xsl:apply-templates select="node()" />
105 </xsl:when>
106 <xsl:otherwise>
107 <xsl:call-template name="break-up-description">
108 <xsl:with-param name="input"
109 select="exsl:node-set(db:para/node())" />
110 </xsl:call-template>
111 </xsl:otherwise>
112 </xsl:choose>
113 </xsl:template>
114
115</xsl:stylesheet>