Re: [xsl] XSL-FO: page-breaking with all block-containers having absolute-position="fixed"

Subject: Re: [xsl] XSL-FO: page-breaking with all block-containers having absolute-position="fixed"
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Wed, 25 Feb 2004 19:24:12 -0500
At 2004-02-25 16:47 -0500, Kyle Partridge wrote:
(The main portion of) the xml document is laid
out like the below segment.  Note that each attribute on the region
elements represents a numerical measurement in pts that is supposed to
represent the fixed, absolute-positioning of the region.

        <region left="36" top="14.25" width="120.75" height="12"
align-x="36" align-y="24">
           <text use-page-width="false" push-down="false"
                <p style="Normal">Area 1: this is a text region.</p>
        <region left="480" top="26.25" width="225" height="60"
align-x="480" align-y="36">
           <text use-page-width="false" push-down="false"
                <p style="Normal">Region - might be page 3 now.
Curiously,<br/>                 the page break I inserted on the first
page seems to be<br/>
                influencing the height of THIS page, as well I
                know what's up with that, but sadly, I have to
                the behavior if I can.</p>
        <region left="36" top="44.25" width="329.25" height="12"
align-x="36" align-y="54">
           <text use-page-width="false" push-down="false"
                <p style="Normal">Area 2: another text region.</p>
        <region left="0" top="216" width="6000" height="6" align-x="0"
        <region left="42" top="314.25" width="350.25" height="12"
align-x="42" align-y="324">
           <text use-page-width="false" push-down="false"
                <p style="Indent">Here is an indent styled item. It
                really be on page 2.</p>
        <region left="498" top="482.25" width="171.75" height="60"
align-x="498" align-y="492">
           <text use-page-width="false" push-down="false"
                <p style="Normal">Here's another region.<sp
count="2"/>This region is</p>
                <p style="Normal">on some other page - given the 8.5
                <p style="Normal">11 inch page layout currently in use.
                <p style="Normal">think it might be considered page 4,
                <p style="Normal">I'm not too sure how this works!</p>

        <region left="96" top="590.25" width="270.75" height="12"
align-x="96" align-y="600">
           <text use-page-width="false" push-down="false"
                <p style="Normal">Something at the bottom of the page -
let's see what happens!!</p>

So far, I'm rendering this document using fo:block-containers with absolute-position="fixed" and transferring the coordinates of the regions (in pts) from the xml into my fo document. The trouble is, I can't find a way to properly render page breaks in the document????

Have you tried empty blocks with a break: <block break-before="page"/>

        I don't like the idea of having to draw each page separately,
using always another fo:page-sequence and would be great if
the regions could just cascade from one page to the next, behaving as-if
they were all on one continual page (except in the case of a hard page
break) because the region-coordinates in the xml (you may have noted!)
simply continue to grow and grow, regardless of the document's stated

But choosing "fixed" is basing your locations on the containing area. Have you considered in your XSLT doing the arithmetic of positioning and determining where a page break belongs? That would give you the option of zeroing out your running top indicator at the last specified value for top and reducing the subsequent values by that last specified value until you run out of page size again.

        Let's say the page size (conveyed in the xml document) is height
= 792pts and width=612pts (an 8.5 x 11 page) - so I'm setting this page
size on the fo:simple-page-master, like so:

<fo:simple-page-master master-name="worksheet" page-height="792pt"

        Then I've got my fo:block-containers - I convert each to move it
away from the page edge(s) (margins are specified in the xml as 86.4pts
each, top, left, right, and bottom)...but as you can see from the region
attributes in the xml snippet above, **the region sizes just continue to
grow, regardless of any hard page breaks**.

Then arithmetic should tell you were to place a hard break and the block at the top of a break becomes the "deduction" for the regions on that page.

 So in the case of a hard
page break, regions prior to the break would have positioning
coordinates equal to the existing position coordinates on the region
element, but regions AFTER the break would have top and bottom
positioning coordinates equal to the page-height minus the top and
bottom coordinate??? Yuck.

Why "yuck"? Either you let XSL-FO do the yucky pagination or you do the yucky pagination.

Have you considered just using blocks and using a space-before= of the difference between blocks? Using start-indent= and end-indent= will handle your sides.

        I hope this is making some sense, and that someone can give me
some advice on a *better way* to do this!

I still don't understand why you are mapping an absolutely positioned set of regions to a paginated medium ... I suspect you can get close to what you want by just using blocks and letting the processor do the pagination. Remember to use keep-together.within-column="1" to keep your regions together on a single page (unless you don't mind the hard breaks in the middle of a region).

  The rendered results are so
far excellent, but the coding methods seem to me to leave a lot to be

There are alternatives to your use of XSLT as I've noted below.

<xsl:template match="ws:region">
<xsl:variable name="top_add" select="//ws:pageModel//ws:margins/@top"/>
<xsl:variable name="left_add"
<xsl:element name="fo:block-container">
        <!-- *** absolute-position *** -->
        <xsl:attribute name="absolute-position">
        <!-- *** top *** -->
        <xsl:attribute name="top">
                <xsl:value-of select="number(@top)+$top_add"/>
                <xsl:value-of select="$units"/>
        <!-- *** left *** -->
        <xsl:attribute name="left">
                <xsl:value-of select="number(@left)+$left_add"/>
                <xsl:value-of select="$units"/>

Instead of the above, why not just use literal result elements and attribute value templates:

 <fo:block-container absolute-position="fixed"
 ... and so on ...>

None of the elaborate calculations you've given in your example need to be done in <xsl:attribute> instructions.

        <!-- *** inner block *** -->
        <xsl:element name="fo:block">

Why not:


I hope this helps.

........................ Ken

US XSL training: Washington,DC March 15; San Francisco,CA March 22
World-wide on-site corporate, government & user group XML training
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.
Box 266, Kars, Ontario CANADA K0A-2E0    +1(613)489-0999 (F:-0995)
Male Breast Cancer Awareness

XSL-List info and archive:

Current Thread