Tuesday, December 6, 2011

Table of Contents using XSL-FO

XSL-FO lets you convert XML into formatted text for use on the web of in PDFs.

A neat feature to have in you PDFs is a table of content. In your fo:root tag, after setting the 'layout-master-set' and before handling the sections of your xml:
<fo:page-sequence master-reference="A4" force-page-count="no-force">
<xsl:call-template name="header"/>
<xsl:call-template name="footer"/>
<fo:flow flow-name="xsl-region-body" font-family="Arial" font-size="10pt">
<fo:block color="white" keep-with-next.within-page="always">&#160;</fo:block>
<fo:block background-color="white" text-align="center" border="2pt solid black" font-weight="bold" font-size="12pt" keep-with-next.within-page="always">
Contents
</fo:block>
<fo:block color="white" keep-with-next.within-page="always">&#160;</fo:block>
<xsl:for-each select="section">
<fo:block text-align-last="justify">
<xsl:value-of select="header"/>
<fo:leader leader-pattern="dots" leader-length.maximum="100%"/>
<fo:page-number-citation ref-id="{@sectionid}"/>
</fo:block>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>


Remember for XSL to find the place you are linking to, you need to create a block item with id attribute of the correct section id value:
<fo:block id="{@sectionid}" />
e.g.
<xsl:template match="section">
<fo:page-sequence master-reference="A4" force-page-count="no-force">
<xsl:call-template name="header"/>
<xsl:call-template name="footer"/>
<fo:flow flow-name="xsl-region-body" font-family="Arial" font-size="10pt">
<fo:block id="{@sectionid}" />
<xsl:apply-templates select="header" />
<xsl:apply-templates select="content" />
<xsl:apply-templates select="lastpage" />
</fo:flow>
</fo:page-sequence>
</xsl:template>



NOTE: ref-id may let you select the id with or without curly brackets "{@sectionid}" or "@sectionid".


Also if you want to have a clickable link to the pages listed wrap the line in a basic-link tag:
<fo:basic-link internal-destination="{@sectionid}"></fo:basic-link>
e.g.
<fo:block text-align-last="justify">
<fo:basic-link internal-destination="{@sectionid}">
<xsl:value-of select="header"/>
<fo:leader leader-pattern="dots" leader-length.maximum="100%"/>
<fo:page-number-citation ref-id="{@sectionid}"/>
</fo:basic-link>
</fo:block>


Sources:
http://www.mail-archive.com/fop-users@xmlgraphics.apache.org/msg00300.html
http://www.stylusstudio.com/xsllist/200503/post30180.html
http://www.dpawson.co.uk/xsl/sect3/N8703.html
http://www.xmlpdf.com/tableofcontents.html
http://stackoverflow.com/questions/541370/xslt-how-to-select-xml-attribute-by-attribute
http://www.dpawson.co.uk/xsl/examples.html

No comments:

Post a Comment