Question

I'm faced with a styling problem when using tables with a lot of text within the cells. Sometimes the text is unfortunately separated by the page break. As you can see in the following picture the paragraph1 from row3 is divided by the page break.

Unfortunate page-break within the cells of **row3**

What we need is that row3 paragraph1 line1 is put to the next page together with the rest of the paragraph.

We tried using attributes like "orphans" and "widows" but those do not seem to have any effect within table cells. We also tried using block with keep-together attribute, but paragraphs might be larger than one page so that content gets cut off. The only other thing, we could come up with, is to use keep-with-next with fo:blocks which we use on the first few paragraphs of a row. But this looks sloppy, complicated and more like a rule of thumb estimate.

I have put together a "minimal" example that can be tested using http://www.utilities-online.info/foprender/ . I hope you can help me with a solution. Maybe you could also tell me why "orphans" and "widows" does not seem to work here.

Thank you in advance!

XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <item>
        <heading>head1</heading>
        <description>
            <p>row1 paragraph1 line1
            row1 paragraph1 line2
            row1 paragraph1 line3
            row1 paragraph1 line4
            row1 paragraph1 line5</p>

            <p>row1 paragraph2 line1
            row1 paragraph2 line2
            row1 paragraph2 line3
            row1 paragraph2 line4</p>
        </description>
    </item>
    <item>
        <heading>head1</heading>
        <description>
            <p>row2 paragraph1 line1
            row2 paragraph1 line2
            row2 paragraph1 line3
            row2 paragraph1 line4
            row2 paragraph1 line5</p>

            <p>row2 paragraph2 line1
            row2 paragraph2 line2
            row2 paragraph2 line3
            row2 paragraph2 line4
            row2 paragraph2 line5
            row2 paragraph2 line6
            row2 paragraph2 line7</p>
        </description>
    </item>
    <item>
        <heading>head1</heading>
        <description>
            <p>row3 paragraph1 line1
            row3 paragraph1 line2
            row3 paragraph1 line3
            row3 paragraph1 line4
            row3 paragraph1 line5</p>

            <p>row3 paragraph2 line1
            row3 paragraph2 line2
            row3 paragraph2 line3
            row3 paragraph2 line4</p>
        </description>
    </item>
</root>

XSL

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
    <xsl:output encoding="UTF-8" indent="yes" method="xml" standalone="no" omit-xml-declaration="no"/>

    <xsl:template match="//root">
        <fo:root language="DE">
            <fo:layout-master-set>
                <fo:simple-page-master master-name="A4-landscape" page-height="21cm" page-width="29.7cm" margin-top="5mm" margin-bottom="5mm" margin-left="5mm" margin-right="5mm">
                    <fo:region-body margin-top="25mm" margin-bottom="20mm"/>
                    <fo:region-before region-name="xsl-region-before" extent="25mm" display-align="before" precedence="true"/>
                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="A4-landscape">
                <fo:flow reference-orientation="0" border-collapse="collapse" flow-name="xsl-region-body">
                    <fo:table>
                        <fo:table-column column-width="80%"/>
                        <fo:table-body>
                            <xsl:apply-templates select="item"/>
                        </fo:table-body>
                    </fo:table>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>

    <xsl:template match="item">
        <fo:table-row>
            <fo:table-cell border="solid">
                <fo:block>
                    <xsl:value-of select="heading"/>
                </fo:block>
                <fo:block linefeed-treatment="preserve" orphans="4" widows="4">
                    <xsl:apply-templates select="description"/>
                </fo:block>
            </fo:table-cell>
        </fo:table-row>
    </xsl:template>

    <xsl:template match="//description/p">
        <fo:inline><xsl:value-of select="text()"/></fo:inline>
    </xsl:template>
</xsl:stylesheet>

EDIT Added the p-tag to the xml input. I posted the wrong version of xml.

Was it helpful?

Solution

Given your input, you are probably out of luck unless the data is exactly as posed and you try some recursion to separate the data at a blank line. If your data was this (which surprising matches your XSL but you have no "p" element):

    <description>
        <p>row2 paragraph1 line1
        row2 paragraph1 line2
        row2 paragraph1 line3
        row2 paragraph1 line4
        row2 paragraph1 line5</p>
        <p>row2 paragraph2 line1
        row2 paragraph2 line2
        row2 paragraph2 line3
        row2 paragraph2 line4
        row2 paragraph2 line5
        row2 paragraph2 line6
        row2 paragraph2 line7</p>
    </description>

Then you could apply keeps at the "p" level to keep the content together. Because your input does not have that, you need to write a template that creates separate blocks and applies keeps on those blocks for the one text() node that is the child of the description element.

It would also need to preserve line breaks if that is also your intention.

OK, now if your data is truly as written (with line breaks and individual lines that you will live with in final output), then put each line into a table-row and use position to determine the few you wish to keep together.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top