lmi
[Top][All Lists]
Advanced

[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 &lt;= $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 &lt; $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 &lt; $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 &lt;= $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 &lt; $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 &lt; $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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]