Search code examples
xsltapache-fop

Line-break without space with fop 2.2 but keeping white-space="pre" to manage user manually indented text


I'm trying to manage white space treatment within a text in Fop 2.2.

The text area includes long sentences and manually indented text.

linefeed-treatment="preserve" allows to have a correct linebreak at the end of the pdf page and white lines are kept. Which is great.

The problem is that I have to allow users to include manually indented text and manage it correctly. Here is an example :

  1. Test 1

___1.1. Test 2

___1.2. Test 3

______1.2.1. Test 4

___1.3. Test 5

  1. Test 6

In order to keep the indented text, I have to use white-space="pre" which is working great.

But then, the problem with white-space="pre" is that after a breakline, I have a space at the beginning of the next line.

I'm trying to find a solution that will allow to manage both situations but I can't find any.

Edit : More information about this.

Actually, the xml is generated from an application where the users can fill multi-lines text areas in. Each text area can include long sentences and indented text. All the content of one text area is one single tag. This is why it gets more difficult, because I have to manage both possibilities into one fo:block

Here is the XML tag that is generated by the application :

<TXT_TEST newline="1" title="0" style="txtArea" label="" unformattedLabel="" isModified="0" toPrint="1" indentation="0" xmlStyle="" nextField="">Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. 

Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. 

Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. Ceci est une zone de texte longue avec passage à la ligne forcé. 

Et voici une indentation forcée : 

1. Test
   1.1. Test
      1.1.1. Test
      1.1.2. Test
      1.1.3. Test
   1.2. Test
      1.2.1. Test
2. Test
3. Test</TXT_TEST>

But here is a link to the result I get right now, which is incorrect : link

Here is the fo-block i have in my xsl :

<fo:block linefeed-treatment="preserve" white-space="pre" wrap-option="wrap" font-family="Helvetica" font-size="11pt">
<xsl:value-of select="TXT_TEST/text()"/>
</fo:block>

Solution

  • As suggested by @TonyGraham, I did a parse of the textarea, so I was able to process line by line. Here is the code I used :

    <xsl:template name="split-textarea">
        <xsl:param name="texta" />
    
        <xsl:choose >
            <xsl:when test="contains($texta,'&#xa;')">  
                <xsl:variable name="textbefore" select="substring-before($texta,'&#xa;')" />
                <xsl:variable name="textafter" select="substring-after($texta,'&#xa;')"/>
    
                <xsl:choose>
                    <xsl:when test="starts-with($textbefore, ' ')">
                        <fo:block wrap-option="wrap" white-space="pre" font-family="Helvetica" font-size="11pt">
                            <xsl:value-of select="$textbefore" />
                        </fo:block>
                    </xsl:when>
                    <xsl:otherwise>
                        <fo:block wrap-option="wrap" font-family="Helvetica" font-size="11pt">
                            <xsl:choose>
                                <xsl:when test="$textbefore != ''">
                                    <xsl:value-of select="$textbefore" />
                                </xsl:when>
                                <xsl:otherwise>
                                    <fo:block>&#xA0;</fo:block>
                                </xsl:otherwise>
                            </xsl:choose>
                        </fo:block>
                    </xsl:otherwise>
                </xsl:choose>
    
                <xsl:call-template name="split-textarea">
                    <xsl:with-param name="texta" select="$textafter" />
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <fo:block font-family="Helvetica" font-size="11pt">
                    <xsl:value-of select="$texta" />
                </fo:block>
                <fo:block>&#xA0;</fo:block>
            </xsl:otherwise>        
        </xsl:choose>       
    </xsl:template>