Page sizes in xsl-fo

Page Layout

1. Different page sizes in same stylesheet
2. Insert a static page
3. Text at the bottom of the page
4. logo in upper right corner of page
5. page master sequencing
6. New section to start on odd page
7. Center the contents in page
8. body border and background color
9. How many items per page?
10. Unwanted blank pages showing
11. Creating a blank page
12. Blank Pages
13. Absolute positioning
14. Create alternate blank pages
15. Start on odd page
16. Crop marks?
17. Relative indents
18. FO and continued on next page
19. Align to bottom of page
20. Blank page at the end of a document

1.

Different page sizes in same stylesheet

G Ken Holman



>My question is regarding the page width settings and margins in our XSL 
>Style sheet, would I have to create a
>style sheet for each of the possible print outs (A4, A3 & Letter) or is 
>there a much simpler way of approaching
>this, where we would only have one style sheet but with multiple 
>layout-master-set/s?

The latter ... you can create the bunch of page masters that you need, and then in your XSLT where you create the result <page-sequence> you could use an attribute value template to determine from passed parameters which sequence you would want:

   <xsl:param name="page-type" select="'A4'"/>
   ...
   <simple-page-master master-name="pages-A4" .../>
   <simple-page-master master-name="pages-A3" .../>
   <simple-page-master master-name="pages-Letter" .../>
   ...
   <page-sequence master-reference="pages-{$page-type}">
   ...

>Our product would obviously detect the current country settings and 
>determine the required print format.

... and pass the required print format as a command-line argument.

>If this is possible how would we then set our widths on the table-column 
>column-width settings?

I suggest you use proportional widths that react to the width of the page:

   <table-column column-width="proportional-column-width(...some
value...)"/>
   ...
   <table-column column-width="proportional-column-width(...other
value...)"/>

This will give you proportionally the same in all results.

2.

Insert a static page

Ken Holman



>   We need to insert a static page as the "second" page of a pdf document.
>How do we force the static page to always appear as the second page ?

By creating a page sequence stating that you need a particular page geometry as the second page of the sequence, as in this example:

   <page-sequence-master master-name="frame-pages">
     <single-page-master-reference master-reference="frame"/>
     <single-page-master-reference master-reference="frame-static"/>
     <repeatable-page-master-reference master-reference="frame"/>
   </page-sequence-master>

The body of the simple-page-master named (in this example) "frame-static" would be assigned the content you always want to show up only on the second page.

3.

Text at the bottom of the page

Ken Holman



> I want XYZ to always appear at the very bottom of the page like so:
>
>text text text
>text text text
><linefeed>
>...
><linefeed>
>XYZ
>bottom of page

I'm assuming you only mean the bottom of the last page and not the bottom of every page.

Use an empty block at the end of your flow with a footnote construct with an empty inline for the footnote citation and the text that you want at the bottom of the page as the footnote-body.

This was my proposed solution for a disclaimer at the end of the body of some text:

Remember that XSL-FO is a layout language and if there is a layout construct giving you what you want, then ignore what the name of the construct is and use it to do what you need.

David Tolpin expands

It would be really nice if it were so. It is not, unfortunately. XSL FO is a mix of lower-level layout elements, presentation elements which have more or less fixed layout role, as well as of higher-level elements describing a document's structure.

While your advice is absolutely right for tables or lists -- data put in tables is not necessary tabular data -- it is less safe to use footnotes for positioning signatures and disclaimers, unless the signatures and disclaimers ARE footnotes indeed.

An alternative approach would be to omit the notion of footnote completely and introduce 'bottom-floats' along with 'top-' and 'side-' floats. Since currently XSL FO is a compromise between a layout assembler and a document structure description language, points where the language uses semantically loaded constructs should be regarded and the constructs used according to their intended roles and meanings.

table-caption, footnote, title are structural elements. They should be used in accordance with their meaning; a somewhat exaggerated example of importance of such use is a speech-based XSL FO browser; it would interpret this elements according to their intended roles and would be confused. While an XSL FO reader is mostly a theoretical issue, an XSL FO browser for PDAs or other special devices may interpret these constructs in a semantically reasonable but rather unexpected way.

Besides that, use of footnote as a bottom-float breaks extensibility and forward-compatibility: unexpected effects can eventually be discovered when bottom-floats are indeed included in the language.

If you had meant the bottom of every page, check the use of static-content for a footer.

David Tolpin offers

Isn't specifying a different page-master for the last page and static content just for that page a better solution?

4.

logo in upper right corner of page

Ken Holman



>i would like to get a page with a 1 inch page right margin for the body,
>
>but in the region-before i want to place a logo exactly in the upper
>right corner,
>with a right-margin of 0 inches.
>can that be done somehow?

Yes ... set your page margins to zero and your body margins to whatever you need. The region-before lives between the page margins, so it will extend to the page limits.

> it seems
>I cannot set 0 margin for the region-before, 15mm for the body and
>and lets say 20mm for the region-after. Is that so?

No .. regions cannot have margins ... looking at 6.4.15 I don't see the availability of margin specifications. Note that even though padding and border-width properties are listed indirectly through a common property set, these must be 0pt, which means this technique is not available to you.

To get the effect you want, you will need to squeeze in the sides of the region-after by using extents on region-start and region-end ... then, to go beyond these sides in region-before, you need to change the precedence from the default of "false" to "true".

The example below gives you what you need, based on the requirements you have described so far, when using Antenna House. If there are more requirements, then I can't say if this will suffice or not.

The following example gives me what you are asking for.


<root font-family="Times" font-size="20pt"
       xmlns="http://www.w3.org/1999/XSL/Format">

<layout-master-set>
   <simple-page-master master-name="frame"
                       page-height="297mm" page-width="210mm">
     <region-body region-name="frame-body"
                  margin-top="15mm" margin-bottom="15mm"
                  margin-left="15mm" margin-right="15mm"/>
     <region-before region-name="frame-before" extent="15mm"
                    precedence="true"/>
     <region-after region-name="frame-after" extent="15mm"/>
     <region-start region-name="frame-start" extent="15mm"/>
     <region-end region-name="frame-end" extent="15mm"/>
   </simple-page-master>
</layout-master-set>

<page-sequence master-reference="frame">

<static-content flow-name="frame-before">
   <block text-align="end">
     <external-graphic src="smflags.bmp"/>
   </block>
</static-content>
<static-content flow-name="frame-after">
   <block text-align="end">
     <external-graphic src="smflags.bmp"/>
   </block>
</static-content>
<flow flow-name="frame-body">

   <block border="solid 1px">This is a test
   <footnote>
     <inline/>
     <footnote-body>
       <block text-align="end" border="solid 1px">
         End of body region
       </block>
     </footnote-body>
   </footnote>
  </block>

</flow>
</page-sequence>
</root>

5.

page master sequencing

Nikolai Grigoriev

Just a suggestion: you can take the master for the first page out of the first fo:repeatable-page-master-alternatives, like this:

<page-sequence-master master-name="pages">

   <!-- Sequence for single-page documents -->
   <repeatable-page-master-alternatives maximum-repeats="1">
        <conditional-page-master-reference page-position="last"
            master-reference="the-only-page"/>
    </repeatable-page-master-alternatives>

   <!-- Sequence for multi-page documents -->
     <repeatable-page-master-alternatives>
       <conditional-page-master-reference page-position="first"
           master-reference="first-page-out-of-many"/>
       <conditional-page-master-reference page-position="last"
           master-reference="last-page-out-of-many"/>
       <conditional-page-master-reference
           master-reference="page-that-is-neither-first-nor-last"/>
     </repeatable-page-master-alternatives>

</page-sequence-master>

The first subsequence will match if and only if there is exactly one page in the sequence. If there are two pages or more, the processing finds no suitable page-masters in the first subsequence, and moves to the second subsequence, skipping the first one.

This is equivalent to your solution, but has a benefit of better logical separation between masters applicable to single-page sequences, and those applicable to multi-page ones.

6.

New section to start on odd page

Paul Grosso



>This looks like FOP is not supporting the FO page-sequence
>property  initial-page-number="auto-odd".  The newer
>versions use that property instead of force-page-count="end-on-even",
>which FOP did support. 

initial-page-number is a basic property that all implementations must support whereas force-page-count is an extended property.

Also, use of initial-page-number="auto-odd" on the initial page that is supposed to be odd (recto) is much more intuitive and better practice than trying to make chapters start on recto pages by trying to make whatever page-sequence might precede a chapter end on an even page.

7.

Center the contents in page

Ken Holman



>I'm new to XSL-FO, and I would like to center the whole content of my page,
>and can't find weather it is possible or not with FOP.

The XSL-FO for this is display-align="center" and you can place this on your body region and every page's content is centred in the region.

8.

body border and background color

Eliot Kimber



> I've tried (I think) to control the border 
> an background colour from the page's region-body.

> I've tried the following:

> <fo:region-body margin-top="2.53968253968254cm"
> margin-left="3cm" margin-right="3cm"
> margin-bottom="2.5cm" background-color="rgb(226, 226, 226)"
> border-color="rgb(0, 0, 0)" border-style="solid" border-width="1pt" />

> This gives me a nice grey background, 
> but it doesn't enclose it in a border.

The XSL spec is very clear that the page regions always have an effective border width of zero. Note that both XEP and XSL Formatter 2.x (and probably 3.x, I haven't tested it) ignore this rule and will put borders on page regions. Don't know about FOP.

> Also, I would like to be able to control where the borders start (ie 
> not merely around the margins of the page) eg if the left margin is 
> 3cms from the left edge of the page, I might want the border and 
> background to start 1cm from the left edge of the page.  I tried 
> adding some padding, but it seemed to make no difference.

In general I find it easiest to not use page margins at all. It's important to remember that the page margins cannot have any marks--that is, they essentially define an unprintable area within the physical page.

It's generally easier to do everything with the page regions. For example, to generate registration marks around a 6x9-type page, I define the physical page as 8.5x11 (or A4 or whatever) and then use margins on the page regions to create an effect 6x9 printed page. I can then use one or more of the edge regions to hold the registration marks (which can be created using external graphics or inline SVG or EPS [XSL Formatter supports inline EPS graphics].

The only legal way to get a border on a page region is to use a block or block container. Using a block-container within static should work, but there may be some issues with z-index depending on how the FO implementation stacks things, but generally I would expect the static content to be rendered under the flowed content (but I don't know that this expectation is supported by or required by the FO spec).

9.

How many items per page?

J.Pietschmann


> I have an XSLT prescription generator that creates PDF file
> prescriptions for a hospital. A new anti-forgery requirement for this
> tool is to add a line on the page saying "X prescriptions on this page".

> My problem is that I don't know how to tell the number of
> prescriptions on a given page.

The pagination is done after the transformation, in an independent step. Therefore there is no way to get hold of the number of prescriptions laid out on a certain page in the transformation.

The layout process itself lacks higher level functionality like counting, so no easy solution here either.

You can try a variety of tricks:

- Make sure each prescription takes the same vertical space, for example by putting it into a fixed height box. You should know now how many prescription fit onto a page.
- Somehow estimate how many lines a prescription takes, and basically do pagination during the transformation. Some functionality like explicit page breaks, keeps and setting box heigths to the generously rounded up cumulated line heigth are probably of utility for keeping your layout estimation in sync with the actual pagination.
- Run a two stage process. Generate the result with a dummy value for the numbers per page, then extract the actual number of prescription for the pages, capture them in an XML file and then to the production run, using the real values. If your target format is PDF, you can mark the individual prescriptions with ids, add a table of contents with basic links referring to the ids (possibly appended as a dummy), then use a PDF library to extract the page number for each id from the internal PDF link directory. Getting the number of prescriptions per page from there is a simple grouping problem in XSLT. There are quite a few alternatives to get the number of prescriptions for the individual pages, be creative.

10.

Unwanted blank pages showing

Alexander Peshkov

The most probable reason of this problem is that you have every chapter in separate page-sequence with 'initial-page-number' property set on it. Normally, previous page-sequence will generate empty page so that to maintain correct parity order (odd-even-odd-...) of the document pages. This effect is caused by the default value of 'force-page-count' property that is 'auto'. If you set force-page-count="no-force" on every page-sequence those auto-generated pages will gone.

Another possible cause of 'unexpected' blank pages is use of empty blocks of this sort: <fo:block><fo:leader/></fo:block> to create '<br> effect'. If one of these blocks appears at the end of the flow it may became the only content of the page and thus generate 'blank' page.

11.

Creating a blank page

W. Eliot Kimber



> <fo:page-sequence-master master-name="image">
>   <fo:repeatable-page-master-alternatives>
>      <fo:conditional-page-master-reference master-reference="blankPage"
>         blank-or-not-blank="blank"/>
>      <fo:conditional-page-master-reference master-reference="theImage"/>
>   </fo:repeatable-page-master-alternatives>
> </fo:page-sequence-master>

> Essentially, what I'm trying to achieve here is an empty page and then 
> the contents of "theImage" on the following page.  I've also tried 
> making a fo:page-sequence-master all its own for the blank page with 
> its fo:flow containing no content, but that didn't seem to work 
> either.  At this point my output is the content of theImage page with 
> no blank neighboring pages.  In addition, I've confirmed the support 
> of this feature since I'm using the RenderX fo processor and its
>literature indicates this attribute is supported.

You've defined a page sequence master that will *accomodate* a blank page, not one that will force one.

That is, conditional-page-master-reference is used to associate page masters with particular types of pages: blank or not blank, odd or even, first or not first, last or not last.

To force a blank page, simply use an empty fo:block with a break-after="page" property--this will generate a blank page. You can then use the page master as you've defined it to define the characteristics of that blank page. E.g.:

<fo:block break-after="page">
  <fo:leader leader-pattern="space" leader-length="0pt"/> </fo:block>

[This use of fo:leader is the most reliable way to ensure the block is actually processed as some processors will ignore blocks with no non-blank content. If you need an empty block that takes no vertical space, set the line-height to "0pt" for the block.]

12.

Blank Pages

Ken Holman



>If there are 2 chapters, each consisting of 3 pages then it is printing
>7 pages. The 4th one is being printed as blank.

Yes, this has caught me in the past as well.

The reason the 4th one is being printed as blank is that the spec says that force-page-count="auto" (which is the default) requires that a given page sequence end on an even page if the first page number of the following page-sequence is odd. As it is with your situation.

The way around it is to have force-page-count="no-force" on all of your page sequences, then they won't extend to an even page number when the subsequent one starts with an odd page number.

13.

Absolute positioning

Eliot Kimber



> Do you know what the correct origin for absolute positioning should be - 
> is it relative to the page,
> or relative to the region?

When absolute=absolute, the block-container is positioned relative to its nearest ancestor reference area. For a block container that has no ancestor block containers, its nearest reference area will be the area for the page region that contains it (e.g., region-body, region-before, etc.).

When absolute=fixed, the block-container is positioned relative to the edges of the page (including any page margins, if specified).

Older versions of XEP only supported absolute=fixed. I believe that 4.x supports absolute=absolute as well as fixed.

14.

Create alternate blank pages

G. Ken Holman

To print on only ever other page, create a page sequence alternating between a page geometry with a flow (that accepts your content) and a page geometry without a flow (so that only static content is drawn). The formatter will render the page with only static content and then go to the "next" page geometry that will have your flow.

I've done this to create "Notes" pages by using static content of multiple horizontal rules with which to make lines for someone making notes. The formatter renders the page and then just continues the flow on the next.

It is not possible in XSL-FO to exclude page numbers from the page sequence.

Since your verso pages are blank and do not have any static content, and you don't want them included in your page count, I suggest that you render all of your pages in order without blanks and you use another tool with which to insert the blank pages. The free iText tool itext.sf.net is what I use to manipulate PDF pages that I create from XSL-FO engines. Since I don't know Java I use Python and Jython to call the PDF library and I create new PDF files with desired features using PDF files created by XSL-FO engines as inputs.

15.

Start on odd page

Eliot Kimber


> When you open a book, you have a page on the
> left side and another page on the right. So, I refer
> these as the left page and the right page. Usually the
> book starts at the right page, but sometimes I need
> the first page starts on the left. Since the left and
> right page's margins are different, I was wondering
> how/what I should specify in the page-sequence that
> would accomondate this requirements? I copied some
> portions of my layout below, thanks a lot for any
> lights.

If you specify initial-page-number="auto-even" on the fo:page-sequence element then the page sequence will start on an even (left) page.

Note that a (left-to-right) book cannot physically start on an even page--the first physical page will always be a right-hand page. So if the first page with content is even, you will need to generate a blank first page.

16.

Crop marks?

Mauritz Jeanson |Ryan Lubben




> I have a requirement to include crop marks for the print
> manual in xsl.
> Can anyone provide me related information how to introduce
> crop marks so
> that the output pdf contains the same?
>
> Is there any related example or references for the same?

XEP and AntennaHouse XSL Formatter have extensions for this: RenderX and Antenna House

or If you aren't using XSL-Formatter or XEP you could create crop marks using a background image.

<fo:simple-page-master master-name="Front_Cover" page-height="11.5in"
page-width="9.0in">
    <fo:region-body background-image="Crop_Marks.svg"/>
</fo:simple-page-master>

Another possibility would be to embed the SVG code for your crop marks directly in the stylesheet.

<fo:simple-page-master master-name="Front_Cover" page-height="11.5in"
page-width="9.0in">
    <fo:region-body/>
    <fo:region-start display-align="before" region-name="Crop_Marks"/>
</fo:simple-page-master>
<fo:static-content flow-name="Crop_Marks">
    <fo:block-container z-index="-222" position="absolute">
        <fo:block text-align="left">
            <fo:instream-foreign-object content-width="9.0in">
                <!--Add SVG Code-->
            </fo:instream-foreign-object>
        </fo:block>
    </fo:block-container>
</fo:static-content>

17.

Relative indents

Ken Holman



>Is there a way to form relative relative indents in XSL-FO 1.0?
>Here, the first "relative" means relative to the writing mode, and
>the second "relative" means relative to the containing block.
>I'm trying to create nested indents from nested source elements
>in a language-independent stylesheet, and I'm not finding
>the right property combination.

I can see an object combination and a property combination:

>For example, in left-to-right writing mode, I can use margin-left
>in nested fo:block elements:
>
><fo:block margin-left="1in">First block.
>  <fo:block margin-left="1in">Second block.
>    <fo:block margin-left="1in">Third block.
>    </fo:block>
>  </fo:block>
></fo:block>
>
>The third block will be indented 3in from the left region boundary.
>
>But "margin-left" is an absolute property.  If I use this stylesheet
>for a language in writing mode right-to-left, this does not have
>the intended effect.  At first I thought that
>space-start would be the corresponding property that is relative
>to the writing-mode.  But space-start only applies to inline areas,
>not block areas.

But they are relative to the reference area, so you could introduce a reference area in each block by a block-container.

>There doesn't seem to be a "margin-start" property, and start-indent
>does not produce the same additive effect.  Is there any way to
>accomplish this nesting of indents without having to resort to
>using nested list-blocks or computing a sum for a start-indent?

Remember that you can express the sum without computing the sum and let the FO processor do the computation for you ... will that help?

So, my two suggestions are nested block-containers and arithmetic expression.

Examples below.

<?xml version="1.0" encoding="US-ASCII"?><!--raw.fo-->
<root xmlns="http://www.w3.org/1999/XSL/Format";
      font-family="Times" font-size="20pt">

  <layout-master-set>
    <simple-page-master master-name="frame"
                        page-height="297mm" page-width="210mm"
                        margin-top="15mm" margin-bottom="15mm"
                        margin-left="15mm" margin-right="15mm">
      <region-body region-name="frame-body"/>
    </simple-page-master>
  </layout-master-set>

  <page-sequence master-reference="frame">
    <flow flow-name="frame-body" xmlns="http://www.w3.org/1999/XSL/Format";>
      <block>This is a test with margin-left</block>
<block margin-left="1in">First block.
 <block margin-left="1in">Second block.
   <block margin-left="1in">Third block.
   </block>
 </block>
</block>

      <block>This is a test with start-indent</block>
<block start-indent="1in">First block.
 <block start-indent="1in">Second block.
   <block start-indent="1in">Third block.
   </block>
 </block>
</block>

      <block>This is a test with arithmetic expressions</block>
<block start-indent="1in">First block.
 <block start-indent="1in+1in">Second block.
   <block start-indent="1in+1in+1in">Third block.
   </block>
 </block>
</block>

      <block>This is a test with block containers</block>
<block start-indent="1in">First block.
 <block-container>
   <block start-indent="1in">Second block.
     <block-container>
       <block start-indent="1in">Third block.
       </block>
     </block-container>
   </block>
 </block-container>
</block>

    </flow>
  </page-sequence>
</root>

18.

FO and continued on next page

J.Pietschmann


> I was wondering if there is a way of getting a "continued on the next
> pages" at the bottom of the page when a block is broken across pages or
> "continued..." at the top of a page when a block is broken across page
> in XSL FO.

The common workaround is to use markers. Define a marker with the "continued...." text at the beginning of the block you want to have marked as such, redefine it as empty at the end (or at the beginning of the next block, whatever fits your requirement), and retrieve the marker class in the footer. The drawback is that the "continued..." text is not part of the flow, resulting whitespace above the footer or different footer layouts, but people rarely notice.

19.

Align to bottom of page

Bob Stayton et al



>Is it possible to have text displayed at the bottom
>of a blank page, without setting it in a footer, and
>without "pushing" it with empty paragraphs? 

One method you could try is to put the fo:block containing the content into a fo:table with a single fo:row. That row should have height="100%" and display-align="after" attributes. That should make the row as tall as the page body area, and push the block to the bottom.

Francois Badier offers:

I needed the same thing once and wanted to avoid the table layout. Here is a block-container method ; works nicely with XEP.

%lt;fo:block-container 
	  display-align="after" 
	  block-progression-dimension="100%">
 %lt;fo:block>legal notice%lt;/fo:block>
%lt;/fo:block-container>

20.

Blank page at the end of a document

Ken Holman


>At the end of my document I have a
>page with 2-column layout (the rest is simple layout) which is generated
>only when condition is true. When condition is false I need to display
>nothing, instead of displaying blank page. Can anyone help me how could I
>avoid the blank page?

By not producing the page sequence.

Perhaps you have:

 <page-sequence master-reference="">
   <flow flow-name="">
     <xsl:if test="condition">
       ....

If so, you need to do this:

 <xsl:if test="condition">
   <page-sequence master-reference="">
     <flow flow-name="">
       ....