1<?xml version="1.0" encoding="ISO-8859-1"?> <!-- -*- sgml -*- --> 2<xsl:stylesheet version="1.0" 3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 4 xmlns:ext="http://exslt.org/common" 5 xmlns:str-split2lines-func="f:str-split2lines-func" 6 exclude-result-prefixes="xsl ext str-split2lines-func"> 7 8 9<!-- how much do I love haskell ... --> 10<xsl:template name="str-foldl"> 11 <xsl:param name="pFunc" select="/.."/> 12 <xsl:param name="pA0"/> 13 <xsl:param name="pStr"/> 14 15 <xsl:choose> 16 <xsl:when test="not(string($pStr))"> 17 <xsl:copy-of select="$pA0"/> 18 </xsl:when> 19 <xsl:otherwise> 20 <xsl:variable name="vFunResult"> 21 <xsl:apply-templates select="$pFunc[1]"> 22 <xsl:with-param name="arg0" select="$pFunc[position() > 1]"/> 23 <xsl:with-param name="arg1" select="$pA0"/> 24 <xsl:with-param name="arg2" select="substring($pStr,1,1)"/> 25 </xsl:apply-templates> 26 </xsl:variable> 27 28 <xsl:call-template name="str-foldl"> 29 <xsl:with-param name="pFunc" select="$pFunc"/> 30 <xsl:with-param name="pStr" select="substring($pStr,2)"/> 31 <xsl:with-param name="pA0" select="ext:node-set($vFunResult)"/> 32 </xsl:call-template> 33 </xsl:otherwise> 34 </xsl:choose> 35 36</xsl:template> 37 38 39<str-split2lines-func:str-split2lines-func/> 40 41<xsl:template name="str-split-to-lines"> 42 <xsl:param name="pStr"/> 43 <xsl:param name="pLineLength" select="60"/> 44 <xsl:param name="pDelimiters" select="' 
'"/> 45 <xsl:variable name="vsplit2linesFun" 46 select="document('')/*/str-split2lines-func:*[1]"/> 47 48 <xsl:variable name="vrtfParams"> 49 <delimiters><xsl:value-of select="$pDelimiters"/></delimiters> 50 <lineLength><xsl:copy-of select="$pLineLength"/></lineLength> 51 </xsl:variable> 52 53 <xsl:variable name="vResult"> 54 <xsl:call-template name="str-foldl"> 55 <xsl:with-param name="pFunc" select="$vsplit2linesFun"/> 56 <xsl:with-param name="pStr" select="$pStr"/> 57 58 <xsl:with-param name="pA0" select="ext:node-set($vrtfParams)"/> 59 </xsl:call-template> 60 </xsl:variable> 61 62 <xsl:for-each select="ext:node-set($vResult)/line"> 63 <xsl:for-each select="word"> 64 <xsl:value-of select="concat(., ' ')"/> 65 </xsl:for-each> 66 <xsl:value-of select="'
'"/> 67 </xsl:for-each> 68</xsl:template> 69 70 71<xsl:template match="str-split2lines-func:*"> 72 <xsl:param name="arg1" select="/.."/> 73 <xsl:param name="arg2"/> 74 75 <xsl:copy-of select="$arg1/*[position() < 3]"/> 76 <xsl:copy-of select="$arg1/line[position() != last()]"/> 77 78 <xsl:choose> 79 <xsl:when test="contains($arg1/*[1], $arg2)"> 80 <xsl:if test="string($arg1/word)"> 81 <xsl:call-template name="fillLine"> 82 <xsl:with-param name="pLine" select="$arg1/line[last()]"/> 83 <xsl:with-param name="pWord" select="$arg1/word"/> 84 <xsl:with-param name="pLineLength" select="$arg1/*[2]"/> 85 </xsl:call-template> 86 </xsl:if> 87 </xsl:when> 88 <xsl:otherwise> 89 <xsl:copy-of select="$arg1/line[last()]"/> 90 <word><xsl:value-of select="concat($arg1/word, $arg2)"/></word> 91 </xsl:otherwise> 92 </xsl:choose> 93</xsl:template> 94 95 96<!-- This template recognises every new word and accumulates the result, --> 97<!-- which is a list of 'line' elements, each having a list of 'word' --> 98<!-- children. After the last 'line' element there's a single 'word', in --> 99<!-- which the 'current word; is being accumulated. Whenever the current --> 100<!-- character is one of the specified delimiters, this signals the --> 101<!-- formation of a new word. This word is either added to the last line --> 102<!-- (if the total line length will not exceed the specified line-length), --> 103<!-- or a new line is started and this word becomes the 1st in the new line --> 104<xsl:template name="fillLine"> 105 <xsl:param name="pLine" select="/.."/> 106 <xsl:param name="pWord" select="/.."/> 107 <xsl:param name="pLineLength" /> 108 109 <xsl:variable name="vnWordsInLine" select="count($pLine/word)"/> 110 <xsl:variable name="vLineLength" 111 select="string-length($pLine) + $vnWordsInLine"/> 112 113 <xsl:choose> 114 <xsl:when test="not($vLineLength + string-length($pWord) > $pLineLength)"> 115 <line> 116 <xsl:copy-of select="$pLine/*"/> 117 <xsl:copy-of select="$pWord"/> 118 </line> 119 </xsl:when> 120 <xsl:otherwise> 121 <xsl:copy-of select="$pLine"/> 122 <line> 123 <xsl:copy-of select="$pWord"/> 124 </line> 125 <word/> 126 </xsl:otherwise> 127 </xsl:choose> 128</xsl:template> 129 130 131</xsl:stylesheet> 132