On Wed, 16 Feb 2005 18:17:53 +0000, "Brett Parker" iDunno@sommitrealweird.co.uk said:
Richard Lewis richardlewis@fastmail.co.uk wrote:
I hadn't noticed that. Um, {,n} and {n,} seem to work in sed, but {,n} causes a runtime error in XSLT saying that it expects a digit and if you use {0,n} it says it doesn't allow a regex that matches a 0 length string (presumably because its the replace() function). ({1,n} just splits it into single word strings...)
I'll keep fiddling.
You could just use the XSLT stylesheets I linked earlier which will tokenise and then split the strings to a certain character length... that link looked fairly useful for those type things... The link was: http://sources.redhat.com/ml/xsl-list/2001-12/msg00651.html
Which is a mailing list post, but following the links round there should give you an includable stylesheet that you can then just call with some parameters for the formatting.
I had a look through those templates and they're good, but they're designed for use with XSLT 1.0 really. I'm lucky enough to be working with XSLT 2.0 which gives me regular expressions in the form of replace(string, regex, replacement), matches(string, regex) and tokenize(string, onRegex) functions and an analyze-string template. Much of the hard work performed in those templates can be replaced with the tokenize() function.
Anyway, I'm sure you'll all be glad to know I've now found a working solution. The template I'm writing wraps text into an arbitrary polygon for use with transformations to SVG (the current version of which does not support text wrapping). The solution I've come up with first determines the path of the polygon from the given points and then fits rows of conceptual (not visible) horizontal rectangles inside it. The text is then displayed along these rows.
The regular expression came into it because I needed a way of selecting the correct portion of text for each row; i.e. a portion of text which has a length (in pixels) which is less than or equal to the length of the row but which does not allow the last word to be split. I decided that the regex idea wasn't going to work and did it like this:
<xsl:variable name="stringToDisplay"> <xsl:variable name="maxPortionOfText"> <xsl:value-of select="substring($remainingText,1,$maxStringWidthInChars)" /> </xsl:variable> xsl:choose <xsl:when test="string-length($maxPortionOfText) >= string-length($remainingText)"> <xsl:value-of select="$maxPortionOfText" /> </xsl:when> xsl:otherwise <xsl:for-each select="tokenize($maxPortionOfText,'\s+')"> <xsl:if test="position() < last() or position() = 1"> <xsl:value-of select="." /><xsl:if test="position()!=last()">xsl:text </xsl:text></xsl:if> </xsl:if> </xsl:for-each> </xsl:otherwise> </xsl:choose> </xsl:variable>
Thanks for your help on this.
Cheers, Richard