[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [lmi] help with orphan-control in xsl-fo
From: |
Vaclav Slavik |
Subject: |
RE: [lmi] help with orphan-control in xsl-fo |
Date: |
Wed, 01 Jul 2009 21:20:05 +0200 |
Hi,
On Sat, 2009-05-16 at 21:36 +0200, Vaclav Slavik wrote:
> I'm sorry, I misunderstood that as a suggestion on how to fix the bug
> rather than as a feature request. That's why I implemented what I
> considered more robust fix: my patch uses markup intended for exactly
> this situation (keeping rows together) and will work even if you
> change
> page size, footers/headers or font size in the future. On the other
> hand, any of such changes could easily break the assumption that 30
> lines is just the right amount of content.
>
> I'll have a look at XSL-FO to see if we can limit number of rows per
> page somehow.
I was hoping for a "proper" way to express this in XSL-FO as a
constraint on the table/page, but I don't think it's possible after all.
So I went with the next best thing, which is in hindsight probably the
right way to approach this in XSL-FO. Instead of grouping rows into
groups of five with the keep-with-next property, I changed the
stylesheet to do the following:
1. keep visual grouping of 5 rows with padding-bottom=8pt
2. use keep-with-next=always to keep groups of _30_ rows together
3. force page break after every 30 rows with break-after=page
I only tested this with fop-0.95 and it does the right thing as far as I
can tell. Note that this only works if there's enough room for 30 rows
on the page. If there isn't, it breaks horribly (e.g. one page with 1
row followed by a page with 29 rows).
It yields noticeable improvement over my previous group-by-five patch:
previously, there could be a 25-rows page followed by 30-rows page in
the output. The new version nicely formats the table so that the
incomplete page is the last one. On the other hand, it's less flexible:
it doesn't adapt to different paper sizes anymore (it requires space for
30 rows and wouldn't use any available space over that), but I don't
expect that to be a problem for you.
Here is a patch against a tree with all my previous patches applied:
=== modified file 'fo_common.xsl'
--- fo_common.xsl revid:address@hidden
+++ fo_common.xsl 2009-07-01 18:48:34 +0000
@@ -663,20 +663,26 @@
<xsl:param name="add-dummy-row-if-empty" select="boolean(1)"/>
<xsl:if test="$counter <= $max-counter">
<fo:table-row>
- <!-- Ensure that a group of 5 rows is never split across multiple
pages -->
- <xsl:if test="($counter + $inforceyear) mod 5 != 0">
+ <!-- Ensure that there's always 30 rows on page -->
+ <xsl:if test="($counter + $inforceyear) mod 30 != 0">
<!-- but only if it's not the last row of the table -->
<xsl:if test="$counter < $max-counter">
<xsl:attribute name="keep-with-next">always</xsl:attribute>
</xsl:if>
</xsl:if>
+ <xsl:if test="($counter + $inforceyear) mod 30 = 0">
+ <xsl:attribute name="break-after">page</xsl:attribute>
+ </xsl:if>
<xsl:for-each select="$columns">
<fo:table-cell padding="1pt .5pt 0">
<!-- Add some space after each 5th year -->
<xsl:if test="($counter + $inforceyear) mod 5 = 0">
<!-- but only if it's not the last row of the table -->
<xsl:if test="$counter < $max-counter">
- <xsl:attribute name="padding-bottom">8pt</xsl:attribute>
+ <xsl:if test="($counter + $inforceyear) mod 30 != 0">
+ <!-- or the last row on the page -->
+ <xsl:attribute name="padding-bottom">8pt</xsl:attribute>
+ </xsl:if>
</xsl:if>
</xsl:if>
<fo:block text-align="right">
And the same change compared to vanilla CVS sources:
--- ../cvs/fo_common.xsl 2009-06-28 19:24:43.000000000 +0200
+++ fo_common.xsl 2009-07-01 20:48:34.000000000 +0200
@@ -663,13 +663,26 @@
<xsl:param name="add-dummy-row-if-empty" select="boolean(1)"/>
<xsl:if test="$counter <= $max-counter">
<fo:table-row>
+ <!-- Ensure that there's always 30 rows on page -->
+ <xsl:if test="($counter + $inforceyear) mod 30 != 0">
+ <!-- but only if it's not the last row of the table -->
+ <xsl:if test="$counter < $max-counter">
+ <xsl:attribute name="keep-with-next">always</xsl:attribute>
+ </xsl:if>
+ </xsl:if>
+ <xsl:if test="($counter + $inforceyear) mod 30 = 0">
+ <xsl:attribute name="break-after">page</xsl:attribute>
+ </xsl:if>
<xsl:for-each select="$columns">
<fo:table-cell padding="1pt .5pt 0">
<!-- Add some space after each 5th year -->
<xsl:if test="($counter + $inforceyear) mod 5 = 0">
<!-- but only if it's not the last row of the table -->
<xsl:if test="$counter < $max-counter">
- <xsl:attribute name="padding-bottom">8pt</xsl:attribute>
+ <xsl:if test="($counter + $inforceyear) mod 30 != 0">
+ <!-- or the last row on the page -->
+ <xsl:attribute name="padding-bottom">8pt</xsl:attribute>
+ </xsl:if>
</xsl:if>
</xsl:if>
<fo:block text-align="right">
@@ -698,16 +711,6 @@
</fo:block>
</fo:table-cell>
</xsl:for-each>
- <!--
- Ensure that a group of 5 rows is never split across multiple pages.
- Add a dummy cell, that spans 5 rows. Since FOP avoids breaking cells,
- this cell remains on one page, so will the group of 5 rows.
- -->
- <xsl:if test="($counter + $inforceyear) mod 5 = 1">
- <fo:table-cell number-rows-spanned="5">
- <fo:block/>
- </fo:table-cell>
- </xsl:if>
</fo:table-row>
<xsl:call-template name="generate-table-values">
<xsl:with-param name="columns" select="$columns"/>
Regards,
Vaclav
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- RE: [lmi] help with orphan-control in xsl-fo,
Vaclav Slavik <=