XSL-FO: Forced Wrap on Table Entries

I have a problem when I publish my modspecs for pdf (XSL-FO). My tables have problems when the contents of a cell overflow its column into the next. How to force a text break so that a new line is created instead?

I cannot manually insert zero-space characters, since the entries in the table are entered programmatically. I am looking for a simple solution that I can simply add to docbook_pdf.xsl (either as an attribute xsl: param or xsl :).

EDIT: This is where I am now:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:fo="http://www.w3.org/1999/XSL/Format"> <xsl:import href="urn:docbkx:stylesheet"/> ...(the beginning of my stylesheet for pdf generation, eg header and footer content stuff) <xsl:template match="text()"> <xsl:call-template name="intersperse-with-zero-spaces"> <xsl:with-param name="str" select="."/> </xsl:call-template> </xsl:template> <xsl:template name="intersperse-with-zero-spaces"> <xsl:param name="str"/> <xsl:variable name="spacechars"> &#x9;&#xA; &#x2000;&#x2001;&#x2002;&#x2003;&#x2004;&#x2005; &#x2006;&#x2007;&#x2008;&#x2009;&#x200A;&#x200B; </xsl:variable> <xsl:if test="string-length($str) &gt; 0"> <xsl:variable name="c1" select="substring($str, 1, 1)"/> <xsl:variable name="c2" select="substring($str, 2, 1)"/> <xsl:value-of select="$c1"/> <xsl:if test="$c2 != '' and not(contains($spacechars, $c1) or contains($spacechars, $c2))"> <xsl:text>&#x200B;</xsl:text> </xsl:if> <xsl:call-template name="intersperse-with-zero-spaces"> <xsl:with-param name="str" select="substring($str, 2)"/> </xsl:call-template> </xsl:if> </xsl:template> </xsl:stylesheet> 

At the same time, long words are successfully divided into table cells! Unfortunately, a side effect is that plain text in another place (for example, in interlinear X) now splits words so that they appear on separate lines. Is there a way to isolate the process described above with tables?

+2
source share
2 answers

In long words, try inserting the character space width between the characters where the gap is allowed.

+15
source

Since you are using XSLT 2.0:

 <xsl:template match="text()"> <xsl:value-of select="replace(replace(., '(\P{Zs})(\P{Zs})', '$1&#x200B;$2'), '([^\p{Zs}&#x200B;])([^\p{Zs}&#x200B;])', '$1&#x200B;$2')" /> </xsl:template> 

This is using the escapes categories ( http://www.w3.org/TR/xmlschema-2/#nt-catEsc ) and not an explicit list of characters to match, but you can do it this way instead. It needs two replace() , because internal replace() can only insert a character between every second character. External replace() matches characters that are not space characters or a character added by internal replace() .


Insert after every thirteenth non-spatial character:

 <xsl:template match="text()"> <xsl:value-of select="replace(replace(., '(\P{Zs}{13})', '$1&#x200B;'), '&#x200B;(\p{Zs})', '$1')" /> </xsl:template> 

The inner replace() inserts a character after every 13 non-spatial characters, and the outer replace() corrects it if the 14th character was a whitespace character.


If you use AH Formatter, you can use axf:word-break="break-all" to allow AH Formatter to break anywhere in the word. See https://www.antennahouse.com/product/ahf64/ahf-ext.html#axf.word-break .

+4
source

All Articles