Home | History | Annotate | Download | only in lib
      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