Friday, December 12, 2008

Problem fix in fop 0.20. Hard return not recognized.

Several days ago we had an issue with fop pdf generator. Fop wasn't recognizing hard returns in user comments and putting all of them in one big giant paragraph. It was an annoying problem.

In fop-0.93 there is an easy way to fix this problem:
<fo:block treatment="preserve">


For people who are stuck with fop 0.2 like we are have to use below workaround:


I'm using "splitstring" template to parse value from node "Comments" with pattern "hard return" which is represented by &xD . The strings generated by splitting are displayed in their own fo:block, thus preserving hard returns.

Below is the code.


<xsl:call-template name="splitstring">
<xsl:with-param name="string">
<xsl:value-of select="Comments">
</xsl:value-of>
<xsl:with-param name="pattern">
<xsl:value-of select="'&#xD'">
</xsl:value-of>
</xsl:with-param>



I found split string function here:
http://www.exslt.org/str/functions/split/str.split.template.xsl.html

Code for the same is as below:


<xsl:call-template name="splitstring">
<xsl:with-param name="string">
<xsl:value-of select="Comments">
</xsl:value-of>
<xsl:with-param name="pattern">
<xsl:value-of select="''">
</xsl:value-of>
</xsl:with-param>
<xsl:template name="splitstring">
<xsl:param name="string"/>
<xsl:param name="pattern"/>
<xsl:choose>
<xsl:when test="not($string)" />
<xsl:when test="not($pattern)">
<xsl:call-template name="split-characters">
<xsl:with-param name="string"
select="$string" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="split-pattern">
<xsl:with-param name="string"
select="$string" />
<xsl:with-param name="pattern"
select="$pattern" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template name="split-characters">
<xsl:param name="string" />
<xsl:if test="$string">
<fo:block>
<xsl:value-of select="substring($string, 1, 1)" />
</fo:block>
<xsl:call-template name="split-characters">
<xsl:with-param name="string"
select="substring($string, 2)" />
</xsl:call-template>
</xsl:if>
</xsl:template>

<xsl:template name="split-pattern">
<xsl:param name="string" />
<xsl:param name="pattern" />
<xsl:choose>
<xsl:when test="contains($string, $pattern)">
<xsl:if test="not(starts-with($string, $pattern))">
<fo:block>
<xsl:value-of select="substring-before($string, $pattern)" />
</fo:block>
</xsl:if>
<xsl:call-template name="split-pattern">
<xsl:with-param name="string"
select="substring-after($string, $pattern)" />
<xsl:with-param name="pattern"
select="$pattern" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<fo:block>
<xsl:value-of select="$string" />
</fo:block>
</xsl:otherwise>
</xsl:choose>
</xsl:template>





No comments: