at 22.05-pre 4.9 kB view raw
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="'&#xa;&#xa;'" /> 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() &gt; 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() &gt; 1 61 and position() &lt; 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>