I'm using Apache Fop (2.1) to generate RTF documents from XML. I want the first page to have a different heading than the other pages. I have set up two simple-page-masters, one for the first page, and one for the other pages. I am running into a problem getting to page position "first". It never gets there:
<fo:page-sequence-master master-name="my-sequence">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference page-position="first" master-reference="firstPage"/>
<fo:conditional-page-master-reference page-position="rest" master-reference="otherPage"/>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
It always gets to the page-position="rest", even for the first page of the document. Can anybody tell me why? How can I solve this?
Fop does give me this error:
Only simple-page-masters are supported on page-sequences. Using default simple-page-master from page-sequence-master "my-sequence"
Here is the rest of my xslt:
<fo:layout-master-set>
<fo:simple-page-master master-name="firstPage"
page-height="11in" page-width="8.5in"
margin-top=".5in" margin-left="1in" margin-right="1in" margin-bottom=".5in">
<fo:region-body />
<fo:region-before region-name="firstPageBefore"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="otherPage"
page-height="11in" page-width="8.5in"
margin-top=".5in" margin-left="1in" margin-right="1in" margin-bottom=".5in">
<fo:region-body />
<fo:region-before region-name="otherPageBefore"/>
</fo:simple-page-master>
<fo:page-sequence-master master-name="my-sequence">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference page-position="first" master-reference="firstPage"/>
<fo:conditional-page-master-reference page-position="rest" master-reference="otherPage"/>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="my-sequence">
<fo:static-content flow-name="firstPageBefore">
<fo:block>First page!</fo:block>
</fo:static-content>
<fo:static-content flow-name="otherPageBefore">
<fo:block>Other page!</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body" >
<xsl:apply-templates/>
</fo:flow>
</fo:page-sequence>
I use this sample:
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="firstPage"
page-height="11in" page-width="8.5in"
margin-top=".5in" margin-left="1in" margin-right="1in" margin-bottom=".5in">
<fo:region-body background-color="red"/>
<fo:region-before region-name="firstPageBefore"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="otherPage"
page-height="11in" page-width="8.5in"
margin-top=".5in" margin-left="1in" margin-right="1in" margin-bottom=".5in">
<fo:region-body />
<fo:region-before region-name="otherPageBefore"/>
</fo:simple-page-master>
<fo:page-sequence-master master-name="my-sequence">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference page-position="first" master-reference="firstPage"/>
<fo:conditional-page-master-reference page-position="rest" master-reference="otherPage"/>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="my-sequence">
<fo:flow flow-name="xsl-region-body" >
<fo:block break-after="page">First Page</fo:block>
<fo:block break-after="page">Second Page</fo:block>
<fo:block break-after="page">Third Page</fo:block>
<fo:block>Forth Page</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
Notice I color the background of only the first page "region-body" red. I get this output with Apache FOP 2.1:
Now, if I change only to format to RTF and not PDF, I do not get the expected output. If fact to test this, I even changed the first page to 5inx5in in size. If I examine the RTF produced, there is only one page layout which is the last one.
To prove this, I change the first page to 5x5 and the remainder pages to 11x8.5 landscape and the raw RTF shows this:
{*\generator Apache XML Graphics RTF Library;}
\fet0 \ftnbj \paperw15840 \paperh12240 \landscape \margt720 \margb720 \margl1440 \margr1440 \headery720 \footery720 \itap0
This is only one page template, it is not the first template. See image below, all pages landscape, no color applied at all.
This appears to be a bug or unsupported feature for Apache FOP RTF output.
Related
I am trying to set a footer only in the first page of a RTF document.
Approach
I defined two regions to show one in the first page and the other in the rest of pages.
Once it is done, I could just remove the second footer text to achieve my goal (the generated rtf document only has two pages).
Result
Unfortunately with the transformation below I am getting the "Rest of pages footer" in both pages. It seems XSL-FO never catches the matching criteria for page-position="first".
I also tried a similar approach with odd-or-even="odd" in the conditional-page-master-reference with the same result.
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="first"
page-height="29.7cm" page-width="21.0cm" margin-left="2.54cm"
margin-right="2.54cm" margin-top="1cm" margin-bottom="2.54cm">
<fo:region-body margin-top="1.54cm"/>
<fo:region-after region-name="footer-first" extent="2cm" display-align="after"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="rest"
page-height="29.7cm" page-width="21.0cm" margin-left="2.54cm"
margin-right="2.54cm" margin-top="1cm" margin-bottom="2.54cm">
<fo:region-body margin-top="1.54cm"/>
<fo:region-after region-name="footer-rest" extent="2cm" display-align="after" />
</fo:simple-page-master>
<fo:page-sequence-master master-name="document">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference page-position="first" master-reference="first" />
<fo:conditional-page-master-reference page-position="rest" master-reference="rest" />
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
</fo:layout-master-set>
<xsl:template match="WC">
<xsl:variable name="id.wc">id_<xsl:value-of select="normalize-space(Id/text())"/>
</xsl:variable>
<fo:page-sequence master-reference="document"
padding-top="1cm" initial-page-number="1">
<fo:static-content flow-name="footer-first">
<fo:block padding-top="10pt" font-size="8">
<fo:inline color="grey">
First page footer
</fo:inline>
</fo:block>
</fo:static-content>
<fo:static-content flow-name="footer-rest">
<fo:block text-align-last="center">Rest of pages footer</fo:block>
</fo:static-content>
<!-- Body continues... -->
FOP's RTF output supports only a single page master. See https://xmlgraphics.apache.org/fop/2.6/output.html#rtf
FWIW, you can get the footers with AH Formatter using the free-but-unsupported Word output option (see https://www.antennahouse.com/microsoft-word-output):
I want to add the page number in footer if the number of pages is more than one, but not for if there is only one page.
I tried the following code but it shows the page number in all cases :
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="singlePage" page-height="800pt" page-width="612pt" margin-top="0pt" margin-bottom="46pt" margin-left="26pt" margin-right="26pt">
<fo:region-body margin-top="110pt" margin-bottom="65pt" />
<fo:region-before extent="72pt" />
<fo:region-after region-name="xsl-region-after-single" extent="75pt" />
</fo:simple-page-master>
<fo:simple-page-master master-name="multiPage" page-height="800pt" page-width="612pt" margin-top="0pt" margin-bottom="46pt" margin-left="26pt" margin-right="26pt">
<fo:region-body margin-top="110pt" margin-bottom="65pt" />
<fo:region-before extent="72pt" />
<fo:region-after region-name="xsl-region-after-multi" extent="75pt" />
</fo:simple-page-master>
<fo:page-sequence-master master-name="allPages">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference page-position="any" master-reference="multiPage"/>
<fo:conditional-page-master-reference page-position="only" master-reference="singlePage"/>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="allPages">
<fo:static-content flow-name="xsl-region-before">
<fo:block>content</fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after-single">
<fo:block>content</fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after-multi">
<fo:block>content</fo:block>
<fo:block text-align="right">
<fo:inline><fo:page-number font-weight="normal"/>/<fo:page-number-citation ref-id = "lastPage"/></fo:inline>
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body" font-size="12pt" line-height="11pt">
<fo:block>content</fo:block>
<fo:block id = "lastPage"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
If I change the order of alternatives, then page number is never shown:
<fo:page-sequence-master master-name="allPages">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference page-position="only" master-reference="singlePage"/>
<fo:conditional-page-master-reference page-position="any" master-reference="multiPage"/>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
I'm using FOP 2.0
Thanks for your answers.
Your second alternative works for me with both FOP 2.0 and FOP 2.2:
<fo:page-sequence-master master-name="allPages">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference page-position="only" master-reference="singlePage"/>
<fo:conditional-page-master-reference page-position="any" master-reference="multiPage"/>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
Did you try it with enough content to make a second page? E.g., add <fo:block break-before="page">content</fo:block> to force a second page.
If you change the 'content' text in your fo:static-content for the fo:region-after then you'll get a better idea of which fo:conditional-page-master-reference is being used; e.g.:
<fo:static-content flow-name="xsl-region-after-single">
<fo:block>after single</fo:block>
</fo:static-content>
The way that fo:conditional-page-master-reference (https://www.w3.org/TR/xsl11/#fo_conditional-page-master-reference) works is that it is selected if it is the first alternative for which all of its sub-conditions are true. If there is enough content to make a second page, then the page-position="only" sub-condition is no longer true, so the formatter should try again with other alternatives.
The formatter should try again because if it doesn't, then the fo:repeatable-page-master-alternatives (https://www.w3.org/TR/xsl11/#fo_repeatable-page-master-alternatives) doesn't satisfy its constraints (my emphasis):
The sub-sequence of pages mapped to this sub-sequence-specifier satisfies the constraints of this sub-sequence-specifier if (a) the sub-sequence of pages consists of zero or more pages, (b) each page is generated using the fo:simple-page-master referenced by the one of the alternatives that are the children of the fo:repeatable-page-master-alternatives, (c) the conditions on that alternative are true, (d) that alternative is the first alternative in the sequence of children for which all the conditions are true, and (e) the length of the sub-sequence is less than or equal to the value of 'maximum-repeats'.
I have the xsl-fo template:
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master margin-right="1cm"
margin-left="2.7cm" margin-bottom="2cm" margin-top="2cm"
page-width="21.5cm" page-height="29.7cm" master-name="first">
<fo:region-body margin-right="1cm" margin-left="0cm" />
<fo:region-after region-name="xsl-region-after" display-align="before" extent="0.7in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="first">
<fo:static-content flow-name="xsl-region-after">
<fo:block text-align="center" font-size="10pt">
<fo:page-number />
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates select="rootElement" />
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
All works excellent, but first page have a page number.
I do not need number on first page.
Thanks y'all!
You have to create a separate page-sequence-master for the first page, that does not include the page number. Then use a statement like this to specify which master will be used for each page of the book:
<fo:page-sequence-master master-name="chapter">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference master-reference="page_first" page-position="first"/>
<fo:conditional-page-master-reference master-reference="page_even" odd-or-even="even"/>
<fo:conditional-page-master-reference master-reference="page_odd" odd-or-even="odd"/>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
(copied from one of my projects, so you'll have to adapt it to your structure)
I have the following (part of) xsl:fo template
<fo:root font-size="11pt" font-family="Arial">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4-portrait"
page-height="29.7cm" page-width="21.0cm" margin-top="1cm"
margin-left="1.5cm" margin-right="1cm" margin-bottom="1cm">
<fo:region-body />
<fo:region-after region-name="footer" extent="15mm"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="A4-landscape"
page-width="29.7cm" page-height="21.0cm" margin-top="1cm"
margin-left="1cm" margin-right="1cm" margin-bottom="1cm">
<fo:region-body />
<fo:region-after region-name="footer2" display-align="bottom" extent="0cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4-portrait">
...........
</fo:page-sequence>
<fo:page-sequence master-reference="A4-landscape" font-size="8pt" id="end">
<fo:static-content flow-name="footer2" font-size="7pt" font-family="Arial">
<fo:block text-align="center">
Page <fo:page-number/>/<fo:page-number-citation ref-id="end"/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
........................
</fo:flow>
</fo:page-sequence>
</fo:root>
The first page-sequence generates exactly one page. The second page-sequence generates multiple pages (for example 9), which I want to "decorate" with footers where I can display the page numbers. The problem is - for the last page, <fo:page-number> generates 10, 1 from the first page-sequence + 9 from the second page-sequence; and <fo:page-number-citation ref-id="end"/> generates 9. So, page 10 of 9 sounds like an overflow and it's embarrassing. Can anyone please help?
I hope this helps someone someday, I found the solution. I should've used <fo:page-number-citation-last ref-id="end"/>
I am using XSLT and XSL-FO for document creation. And the requirement is: in a document the page number should start from page 2 (on page 2 the number should be 1).
In layout-master-set I created 2 simple-page-master and tried in the following way:
<fo:layout-master-set>
<fo:simple-page-master master-name="cover" page-height="11in" page-width="8.5in">
<fo:region-body margin="0.1in 1.0in 0.45in 1.0in"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="master" page-height="11in" page-width="8.5in">
<fo:region-body margin="0.1in 1.0in 0.45in 1.0in"/>
<fo:region-after region-name="footer-first1" extent="1.2in"/>
</fo:simple-page-master>
<fo:page-sequence-master master-name="CoverPage1">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference master-reference="cover" page-position="first" />
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
<fo:page-sequence-master master-name="CoverPage">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference master-reference="cover" page-position="first" />
<fo:conditional-page-master-reference master-reference="master" page-position="rest"/>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="CoverPage1">
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates/>
</fo:flow>
</fo:page-sequence>
<fo:page-sequence initial-page-number="1" master-reference="CoverPage">
<fo:static-content flow-name="footer-first1">
<xsl:call-template name="footer1"/>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
and footer:
<xsl:template name="footer1">
<fo:block font-family="Times" text-align="center" font-size="10.5pt" space-before="45pt">
<fo:block><fo:leader leader-length="6.8in" leader-pattern="space"/><fo:page-number/></fo:block>
</fo:block>
</xsl:template>
When I remove
<fo:conditional-page-master-reference master-reference="cover"
page-position="first" />
from <fo:page-sequence-master master-name="CoverPage">,
FOP throws the following exception:
FOPException: subsequences exhausted in page-sequence-master 'CoverPage', cannot resolve
Any idea or help about how to handle this?