Subject: Re: [xsl] Center string From: Michael Ludwig <mlu@xxxxxxxxxxxxx> Date: Thu, 11 Jun 2009 18:14:03 +0200 |
Just curious if it has already been done : I need to center a string with a max line length. The words must be uncut and balanced between lines.
Here's a solution. Any comments concerning possible XSLT improvements very welcome.
<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="text" select="'Just curious if it has already been done : I need to center a string with a max line length. The words must be uncut and balanced between lines.'" /> <xsl:variable name="text2" select="'Centering the lines is not a problem. The most difficult part is to balance words with line-length. Did somebody already do this with XSL ?'" />
<xsl:template name="wrap"> <xsl:param name="chars-max" tunnel="yes" as="xs:integer" select="30"/> <xsl:param name="separator" tunnel="yes" as="xs:string" select="' '"/> <xsl:param name="sep-len" tunnel="yes" as="xs:integer" select="string-length($separator)" /> <!-- invariants tunneled above, others below --> <xsl:param name="buffer" as="xs:string*" /> <xsl:param name="queue" as="xs:string*" /> <xsl:param name="chars-left" as="xs:integer" select="$chars-max" /> <!-- <xsl:message select="string-join(( string($chars-left), $buffer), '_')"/> --> <xsl:variable name="next" as="xs:string?" select="$queue[1]"/> <xsl:variable name="add-len" as="xs:integer" select="string-length( $next) + $sep-len"/> <xsl:variable name="full" as="xs:boolean" select="not($next) or $add-len > $chars-left" /> <xsl:if test="$full"> <xsl:for-each select="1 to ($chars-left + 1) idiv 2"> <xsl:text> </xsl:text> </xsl:for-each> <xsl:value-of select="string-join( $buffer, $separator)"/> <xsl:text> </xsl:text> </xsl:if> <xsl:if test="$next"> <xsl:call-template name="wrap"> <xsl:with-param name="buffer" select=" if ($full) then $next else ($buffer, $next)"/> <xsl:with-param name="queue" select="$queue[ position() > 1 ]"/> <xsl:with-param name="chars-left" select=" if ($full) then $chars-max - $add-len else $chars-left - $add-len"/> </xsl:call-template> </xsl:if> </xsl:template>
<xsl:template match="/"> <xsl:variable name="tokenizer" select="'\s+'" /> <xsl:for-each select="( $text, $text2 )"> <xsl:call-template name="wrap"> <xsl:with-param name="queue" select="tokenize( . , $tokenizer)" /> <!-- <xsl:with-param name="separator" select="'__'" tunnel="yes"/> --> </xsl:call-template> </xsl:for-each> </xsl:template>
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Center string, Frédéric Schwebel | Thread | Re: [xsl] Center string, Michael Ludwig |
Re: [xsl] Center string, Frédéric Schwebel | Date | Re: [xsl] Discrepancy in handling c, Alain |
Month |