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="' &#xa;'"/>
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="'&#xa;'"/>
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() &lt; 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