[xsl] Reformatting stylesheet (lines do not always wrap)

Subject: [xsl] Reformatting stylesheet (lines do not always wrap)
From: Tim Meals <tim@xxxxxxxxxxxx>
Date: Mon, 19 Apr 2004 14:00:49 -0700
I've developed a stylesheet to reformat text into a fixed width,
suitable for inclusion in text output transforms.  It works fine, except
sometimes a line will go longer than the max allowed length.  Could
someone please help me isolate where my problem lies?

Thanks,
Tim

Stylesheet:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
    <xsl:output method="text"/>

    <xsl:variable name="newline">
<xsl:text>
</xsl:text>
    </xsl:variable>

    <xsl:variable name="space">
        <xsl:text> </xsl:text>
    </xsl:variable>

    <xsl:param name="textwidth" select="72"/>

    <xsl:template match="text()">
        <xsl:value-of select="normalize-space(.)"/>
    </xsl:template>

    <xsl:template name="reformat">
        <xsl:param name="text"/>
        <xsl:param name="hanging-indent">0</xsl:param><!-- OPTIONAL -->
        <xsl:param name="indent">0</xsl:param><!-- OPTIONAL -->
        <xsl:param name="bullet"/><!-- OPTIONAL -->

        <!-- internal parameters -->
        <xsl:param name="line_length" select="$indent + string-length(
$bullet )"/>
        <xsl:param name="_hanging-padding">0</xsl:param>
        <xsl:param name="_first-line" select="boolean( 1 )"/>

        <xsl:variable name="normalized_text">
            <xsl:value-of select="normalize-space( $text )"/>
        </xsl:variable>
        <xsl:variable name="first_part" select="substring-before(
$normalized_text, ' ')"/>
        <xsl:choose>
            <xsl:when test="string-length( $first_part ) > 0">
                <xsl:choose>
                    <xsl:when test="( $line_length + string-length(
$first_part ) ) >= $textwidth">
                        <xsl:value-of select="$newline"/>
                        <xsl:value-of select="substring(
'                                                    ', 0, $indent )"/>
                        <xsl:value-of select="substring(
'                                                    ', 0,
$hanging-indent )"/>
                        <xsl:call-template name="reformat">
                            <xsl:with-param name="text" select="concat(
$first_part, substring-after( $normalized_text, $first_part ) )"/>
                            <xsl:with-param name="line_length"
select="$hanging-indent + $indent"/>
                            <xsl:with-param name="indent"
select="$indent"/>
                            <xsl:with-param name="bullet"
select="$bullet"/>
                            <xsl:with-param name="hanging-indent"
select="$hanging-indent"/>
                            <xsl:with-param name="_hanging-padding"
select="$hanging-indent"/>
                            <xsl:with-param name="_first-line"
select="boolean( 0 )"/>
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:if test="$_first-line">
                            <xsl:value-of select="substring(
'                                                    ', 0, $indent )"/>
                            <xsl:value-of select="$bullet"/>
                        </xsl:if>
                        <xsl:value-of select="$first_part"/><xsl:text>
</xsl:text>
                        <xsl:call-template name="reformat">
                            <xsl:with-param name="text"
select="substring-after( $normalized_text, concat( $first_part, ' ' )
)"/>
                            <xsl:with-param name="line_length"
select="$line_length + 1 + string-length( $first_part )"/>
                            <xsl:with-param name="indent"
select="$indent"/>
                            <xsl:with-param name="bullet"
select="$bullet"/>
                            <xsl:with-param name="hanging-indent"
select="$hanging-indent"/>
                            <xsl:with-param name="_first-line"
select="boolean( 0 )"/>
                        </xsl:call-template>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$normalized_text"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

Sorry if some of that wrapped.  If it's a real problem, please let me
know and I'll repost it as an attachment.

________________________________________________________________________

Tim Meals
Applications Developer Consultant

Current Thread