[Home] [By Thread] [By Date] [Recent Entries]
Michael Ludwig schrieb:
Michael Ludwig <?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:output method="text"/> <xsl:variable name="t0" select="'abcde abcde abcde abcde abcde abcde abcde abcde abcde abcde abcde abcde abcde abcde abcde abcde abcde'"/> <xsl:variable name="t1" select="'abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd'"/> <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="queue" tunnel="yes" as="xs:string*" /> <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="offset" as="xs:integer" select="1" /> <xsl:param name="length" as="xs:integer" select="1" /> <xsl:param name="chars-left" as="xs:integer" select="$chars-max - string-length( $queue[1])" /> <xsl:variable name="next" as="xs:string?" select="$queue[$offset + $length]"/> <xsl:variable name="next-len" as="xs:integer" select="string-length( $next)"/> <xsl:variable name="full" as="xs:boolean" select="not($next) or $sep-len + $next-len > $chars-left" /> <xsl:if test="$full">
<xsl:for-each select="1 to (($chars-left + 1) idiv 2) - 1">
<xsl:text> </xsl:text>
</xsl:for-each>
<xsl:value-of select="string-join(
subsequence( $queue, $offset, $length), $separator)"/>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:if test="$next">
<xsl:call-template name="wrap">
<xsl:with-param name="offset" select="
if ($full) then $offset + $length
else $offset"/>
<xsl:with-param name="length" select="
if ($full) then 1 else $length + 1"/>
<xsl:with-param name="chars-left" select="
if ($full) then $chars-max - $next-len
else $chars-left - $sep-len - $next-len"/>
</xsl:call-template>
</xsl:if>
</xsl:template> <xsl:template match="/">
<xsl:variable name="tokenizer" select="'\s+'" />
<xsl:for-each select="( $t0, $t1, $text, $text2 )">
<xsl:call-template name="wrap">
<xsl:with-param name="queue" tunnel="yes"
select="tokenize( . , $tokenizer)" />
<!--
<xsl:with-param name="separator" select="'__'" tunnel="yes"/>
-->
</xsl:call-template>
</xsl:for-each>
</xsl:template></xsl:stylesheet>
|

Cart



