xsl-list
[Top] [All Lists]

Re: [xsl] Line break algorithm

2020-05-03 14:31:08
Rick,
So I am old fashion with V2 but recursion works for me:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
xmlns:xs="http://www.w3.org/2001/XMLSchema"; exclude-result-prefixes="xs"
    version="3.0">
    <!-- badger 2020-05-03 -->
    <!-- start here -->
    <xsl:template match="/*">
        <xsl:result-document href="p-normal.xml">
            <wrapper>
                <!-- work the string from left to right with after cleanup and 
a space at the end -->
                <xsl:call-template name="recurse">
                    <xsl:with-param name="string" select="normalize-space(.) || 
' '"/>
                    <xsl:with-param name="count" select="0"/>
                </xsl:call-template>
            </wrapper>
        </xsl:result-document>
    </xsl:template>
    <!-- takes one word at a time and if less that 35 characters so far outputs 
it and adds the space back except at the end -->
    <xsl:template name="recurse">
        <xsl:param name="string" as="xs:string"/>
        <xsl:param name="count" as="xs:integer"/>
        <xsl:variable name="item" select="replace($string, '(\S*)(\s)(.*)?', 
'$1')"/>
        <xsl:choose>
            <xsl:when test="$item != '' and $count + string-length($item) + 1 
le 35">
                <xsl:value-of select="$item"/>
                <xsl:if test="replace($string, '(\S*)(\s)(.*)?', '$3') != ''">
                    <xsl:text> </xsl:text>
                </xsl:if>
                <xsl:call-template name="recurse">
                    <xsl:with-param name="string" select="replace($string, 
'(\S*)(\s)(.*)?', '$3')"/>
                    <xsl:with-param name="count" select="$count + 
string-length($item) + 1"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$item != '' and $count + string-length($item) + 1 
gt 35">
                <break/>
                <xsl:call-template name="recurse">
                    <xsl:with-param name="string" select="$string"/>
                    <xsl:with-param name="count" select="0"/>
                </xsl:call-template>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>



Terry






On Sunday, May 3, 2020, 11:24:29 AM EDT, Rick Quatro 
rick(_at_)rickquatro(_dot_)com 
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote: 






Thank you Michael. This is my first use of xsl:iterate and very useful in 
understanding how it works. Here is my finished test stylesheet:
 
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
    xmlns:xs="http://www.w3.org/2001/XMLSchema";
    xmlns:rq="http://www.frameexpert.com";
    exclude-result-prefixes="xs rq"
    version="3.0" expand-text="yes">
    
    <xsl:output indent="yes"/>
    
    <xsl:param name="line" select="'Acceptable HAZMAT Items - Carry-On Or 
Checked Bags - Passenger and Cargo Flights'"/>
    
    <xsl:template name="xsl:initial-template">
        <xsl:message select="''"/>
        <line>
            <xsl:call-template name="line">
                <xsl:with-param name="input" select="$line"/>
                <xsl:with-param name="break-count" select="34" as="xs:integer"/>
            </xsl:call-template>
        </line>
    </xsl:template>    
    
    <xsl:template name="line">
        <xsl:param name="input"/>
        <xsl:param name="break-count" as="xs:integer"/>
        <xsl:iterate select="tokenize($input)">
            <xsl:param name="line-length" select="0"/>
            <xsl:param name="break-count" select="$break-count"/>
            <xsl:message select="position()=last()"></xsl:message>
            <xsl:choose>
                <xsl:when test="$line-length gt $break-count">
                    <break/>
                    <xsl:value-of select="concat(.,if(position()!=last()) then 
' ' else '')"/>
                    <xsl:next-iteration>
                        <xsl:with-param name="line-length" 
select="string-length(.) + 1"/>
                        <xsl:with-param name="break-count" select="$break-count 
- 5"/>
                    </xsl:next-iteration>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="concat(.,if(position()!=last()) then 
' ' else '')"/>
                    <xsl:next-iteration>
                        <xsl:with-param name="line-length" select="$line-length 
+ string-length(.) + 1"/>
                        <xsl:with-param name="break-count" 
select="$break-count"/>
                    </xsl:next-iteration>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:iterate>
    </xsl:template>
    
</xsl:stylesheet>    
 
which gives me this:
 
<?xml version="1.0" encoding="UTF-8"?>
<line>Acceptable HAZMAT Items - Carry-On <break/>Or Checked Bags - Passenger 
and <break/>Cargo Flights</line> 
 
Thanks again!

-Rick

  XSL-List info and archive 
EasyUnsubscribe (by email) 
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--

<Prev in Thread] Current Thread [Next in Thread>