Use Case 2: Display Footnotes Below Tables
Suppose you want to separate the footnotes displayed in the WebHelp Responsive pages so that all footnotes are displayed at the end of the page except those within tables that are displayed just after them.
To add this functionality using a Oxygen Publishing Template, follow these steps:
- If you have not already created a Publishing Template, see How to Create a Publishing Template.
- Link the folder associated with the publishing template to your
current project in the Project Explorer view.
Step Result: You should have the custom_template folder linked in your project.
- Using the Project Explorer
view, create an xsl folder inside the project root folder.
Step Result: You should have the custom_template/xsl folder in your project.
- Create your customization stylesheet (for example,
tablesFootnotes.xsl) in the custom_template/xsl folder with
the following
content:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oxy="http://www.oxygenxml.com/extensions/author" exclude-result-prefixes="#all" version="3.0"> <!-- Match only top level tables (i.e tables that are not nested in other tables), that contains some footnotes. --> <xsl:template match=" *[contains(@class, 'topic/table')] [not(ancestor::*[contains(@class, 'topic/table')])] [//*[contains(@class, 'topic/fn')]]"> <xsl:variable name="top-level-table" select="."/> <xsl:next-match> <xsl:with-param name="top-level-table" select="$top-level-table" tunnel="yes"/> </xsl:next-match> <!-- Create a list with all the footnotes from the current table. --> <div outputclass="table-fn-container"> <xsl:for-each select=".//*[contains(@class, 'topic/fn')]"> <!-- Try to preserve the footnote ID, if available, so that the xrefs will have a target. --> <div id="{if(@id) then @id else generate-id(.)}"> <xsl:variable name="unique-id" select="generate-id($top-level-table)"/> <xsl:variable name="fn-id"> <xsl:number from="$top-level-table" level="any"/> </xsl:variable> <xsl:call-template name="commonattributes"/> <a name="tbl_{$unique-id}_fntarg_{$fn-id}" href="#tbl_{$unique-id}_fnsrc_{$fn-id}"> <sup> <xsl:value-of select="$fn-id"/> </sup> </a> <xsl:text> </xsl:text> <xsl:apply-templates/> </div> </xsl:for-each> </div> </xsl:template> <!-- Process footnotes both inside and outside tables (based on the top-level-table parameter). --> <xsl:template match="*[contains(@class, ' topic/fn ')]" name="topic.fn"> <xsl:param name="xref"/> <xsl:param name="top-level-table" tunnel="yes"/> <!-- Footnotes with IDs must be ignored, they are accessible only through xrefs. --> <xsl:if test="not(@id) or $xref = 'yes'"> <xsl:variable name="unique-id" select=" if ($top-level-table) then generate-id($top-level-table) else ()"/> <xsl:variable name="fn-id" select=" if ($top-level-table) then index-of($top-level-table//*[contains(@class, 'topic/fn')], .) else index-of(//*[contains(@class, 'topic/fn')] [not(ancestor::*[contains(@class, 'topic/entry')])], .)"/> <xsl:variable name="callout" select="@callout"/> <xsl:variable name="converged-callout" select=" if (string-length($callout) > 0) then $callout else $fn-id"/> <a> <!-- Generate different attributes based on the presence of a parent table. --> <xsl:attribute name="name" select=" if ($top-level-table) then concat('tbl_', $unique-id,'_fnsrc_', $fn-id) else concat('fnsrc_', $fn-id)"/> <xsl:attribute name="href" select=" if ($top-level-table) then concat('#tbl_', $unique-id,'_fntarg_', $fn-id) else concat('#fntarg_', $fn-id)"/> <sup> <xsl:value-of select="$converged-callout"/> </sup> </a> </xsl:if> </xsl:template> <!-- The xrefs to footnotes with IDs inside table-cells. We need to recalculate their indexes if their referenced footnote is also in the table. --> <xsl:template match=" *[contains(@class, 'topic/xref')][@type = 'fn'] [ancestor::*[contains(@class, 'topic/entry')]]"> <xsl:param name="top-level-table" tunnel="yes"/> <xsl:variable name="topic-id" select="substring-after(@href, '#')"/> <xsl:variable name="element-id" select="substring-after($topic-id, '/')"/> <xsl:variable name="destination"> <xsl:choose> <xsl:when test="$element-id = ''"> <xsl:value-of select="$topic-id"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$element-id"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="fn" select=" $top-level-table//*[contains(@class, 'topic/fn')][@id = $destination]"/> <xsl:choose> <xsl:when test="$fn"> <xsl:variable name="unique-id" select="generate-id($top-level-table)"/> <!-- There is a reference in the table, recalculate index. --> <xsl:variable name="fn-id" select=" index-of($top-level-table//*[contains(@class, 'topic/fn')], $fn)"/> <a name="tbl_{$unique-id}_fnsrc_{$fn-id}" href="#tbl_{$unique-id}_fntarg_{$fn-id}"> <sup> <xsl:value-of select="$fn-id"/> </sup> </a> </xsl:when> <xsl:otherwise> <!-- There is no reference in the table, keep original index. --> <xsl:next-match/> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- Output footnotes below tables and at the end of the topic. --> <xsl:template match="*[contains(@class, ' topic/fn ')]" mode="genEndnote"> <!-- Do not process footnotes from tables. --> <xsl:if test="not(node()/ancestor::*[contains(@class, 'topic/table')])"> <div> <!-- Do not number footnotes from tables. --> <xsl:variable name="fn-id" select="index-of(//*[contains(@class, 'topic/fn')] [not(ancestor::*[contains(@class, 'topic/entry')])], .)"/> <xsl:variable name="callout" select="@callout"/> <xsl:variable name="converged-callout" select=" if (string-length($callout) > 0) then $callout else $fn-id"/> <xsl:call-template name="commonattributes"/> <xsl:choose> <xsl:when test="@id and not(@id = '')"> <xsl:variable name="topic-id" select=" ancestor::*[contains(@class, ' topic/topic ')][1]/@id"/> <xsl:variable name="ref-id" select="concat($topic-id, '/', @id)"/> <xsl:choose> <xsl:when test="key('xref', $ref-id)"> <a> <xsl:call-template name="setid"/> <sup> <xsl:value-of select="$converged-callout"/> </sup> </a> <xsl:text> </xsl:text> </xsl:when> <xsl:otherwise> <sup> <xsl:value-of select="$converged-callout"/> </sup> <xsl:text> </xsl:text> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <a name="fntarg_{$fn-id}" href="#fnsrc_{$fn-id}"> <sup> <xsl:value-of select="$converged-callout"/> </sup> </a> <xsl:text> </xsl:text> </xsl:otherwise> </xsl:choose> <xsl:apply-templates/> </div> </xsl:if> </xsl:template> </xsl:stylesheet>
- Open the template
descriptor file associated with your publishing template and set the XSLT
stylesheet created in the previous step with the
com.oxygenxml.webhelp.xsl.dita2webhelp XSLT extension
point.
<publishing-template> ... <webhelp> ... <xslt> <extension file="xslt/tablesFootnotes.xsl" id="com.oxygenxml.webhelp.xsl.dita2webhelp"/>
- Open the DITA Map WebHelp Responsive transformation scenario.
- Click the Choose Custom Publishing Template link and select your template.
- Click OK to save the changes to the transformation scenario.
- Run the transformation scenario.