[xep-support] Re: Getting a page number into a basic-link

Michael Sulyaev msulyaev at renderx.com
Sat Jan 15 01:16:48 PST 2011


On 01/15/2011 06:56 AM, Dave Thomas wrote:
> So, in the static-content for the page footer, I have
>
>         <fo:basic-link>
>           <xsl:attribute name="external-destination">
>             <xsl:text>url(http://pragprog.com/titles/</xsl:text>
>             <xsl:value-of select="$book-code"/>
>             <xsl:text>/errata/add?pdf_page=</xsl:text>
>             <fo:page-number/>
>             <xsl:text>)</xsl:text>
>           </xsl:attribute>
>           Report erratum on page<fo:page-number/>
>         </fo:basic-link>
>
> That doesn't seem to work—I'm getting nothing for the page number
> inside the link (but it is displaying correctly in the static text).
>
> Now, I understand why I can't use<fo:page-number/>  in a variable, but
> I'm not sure I see why this particular use shouldn't work: isn't the
> substitution into the link going to use the same mechanism as the
> substitution into the text?
>
> And, if not—is there any way to do what I'd like to do?

Hello Dave,

Overall, it's a two stage process:
1. Transformation: XML + XSL = XSLFO
2. Rendering: XSLFO --> PDF

During transformation there is no information about page numbers, 
because page numbers is one of the results of rendering.

During rendering no XSLTish calculations happen.
You request to have a way to alter an 
fo:basic-link/@external-destination with the value of a page-number 
received during rendering stage, evolves to the request to alter 
anything in the input using something from the output, which is clearly 
and correctly forbidden by the spec.

With XEP there is a way to do what you need, doing some simple 
manipulation on the XEP Intermediate Format. The idea is to alter the 
url using the current page number as written in it's parent xep:page 
element. You'll understand everything from the command line and files below:


$ cat erratum.fo \
   | ./xep -fo - -xep - 2>/dev/null \
   | xsltproc patch-erratum-url.xsl - \
   | ./xep -xep - -pdf erratum.pdf 2>/dev/null

$ cat erratum.fo
<?xml version="1.0" encoding="utf-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <fo:layout-master-set>
       <fo:simple-page-master master-name="all-pages">
          <fo:region-body region-name="xsl-region-body" margin="0.7in"/>
          <fo:region-after region-name="xsl-region-after" extent="0.7in"
	     display-align="before" padding="6pt 0.7in"/>
       </fo:simple-page-master>
    </fo:layout-master-set>
    <fo:page-sequence master-reference="all-pages"
                      initial-page-number="2011">
       <fo:static-content flow-name="xsl-region-after">
	<fo:block>
	  <fo:basic-link 
external-destination="url(http://pragprog.com/titles/book-code/errata/add?pdf_page=)">
	    Report erratum on page <fo:page-number/>.
	  </fo:basic-link>
         </fo:block>
       </fo:static-content>
       <fo:flow flow-name="xsl-region-body">
         <fo:block>hello erratum, this is page <fo:page-number/>
	</fo:block>
       </fo:flow>
    </fo:page-sequence>
</fo:root>

$ cat patch-erratum-url.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
	        xmlns:xep="http://www.renderx.com/XEP/xep"
		xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="@*|node()">
     <xsl:copy>
       <xsl:apply-templates select="@*|node()"/>
     </xsl:copy>
   </xsl:template>
   <xsl:template 
match="xep:external-link/@destination[.='http://pragprog.com/titles/book-code/errata/add?pdf_page=']">
     <xsl:attribute name="destination">
 
<xsl:text>http://pragprog.com/titles/book-code/errata/add?pdf_page=</xsl:text>
       <xsl:value-of select="../../@page-id"/>
     </xsl:attribute>
   </xsl:template>
</xsl:stylesheet>

Of course, post-processing of this kind may be implemented in different 
ways, including Java integration of XEP. I just love pipes.

Regards,
Michael Sulyaev
RenderX


More information about the Xep-support mailing list