So here it is:
<!-- Finds the length of the longest line in the given text -->
<xsl:function name="vaadin:longestLineLength">
<xsl:param name="listing">
<xsl:variable name="firstLineLength">
<xsl:choose>
<xsl:when test="contains($listing, '
')">
<xsl:value-of select="string-length(substring-before($listing, '
'))">
</xsl:value-of></xsl:when>
<xsl:otherwise>
<xsl:value-of select="string-length($listing)">
</xsl:value-of></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="longestInRest">
<xsl:choose>
<xsl:when test="contains($listing, '
')">
<xsl:value-of select="vaadin:longestLineLength(substring-after($listing, '
'))">
</xsl:value-of></xsl:when>
<xsl:otherwise>
<xsl:value-of select="number(0)">
</xsl:value-of></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<!-- Must use number() here or otherwise it'll use string comparison. -->
<xsl:when test="number($longestInRest) > number($firstLineLength)">
<xsl:value-of select="$longestInRest">
</xsl:value-of></xsl:when>
<xsl:otherwise>
<xsl:value-of select="$firstLineLength">
</xsl:value-of></xsl:otherwise>
</xsl:choose>
</xsl:param></xsl:function>
It can be called for example as follows:<xsl:template match="programlisting | screen">
<!-- Extract text content by eliminating formatting tags -->
<xsl:variable name="content">
<xsl:apply-templates select="* | text()" mode="text-listing"/>
</xsl:variable>
<xsl:variable name="longestLineLength">
<xsl:value-of select="vaadin:longestLineLength($content)"/>
</xsl:variable>
<xsl:copy>
<xsl:if test="$longestLineLength > 50">
<xsl:attribute name="dbscaling">
<!-- This should give 65% scaling for lines 63 chars long -->
<xsl:value-of select="(50.0 div $longestLineLength) * 95"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
Note how you need to give the listing as pure text to the method, and node as an input node structure.