Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion htmlbook-xsl/chunk.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,8 @@ sect5:s
<!-- Only generate footnotes if the current node is a chunk -->
<xsl:if test="htmlbook:is-chunk(.)">

<xsl:variable name="all-footnotes" select="//h:span[@data-type='footnote']"/>
<!-- Get all footnotes that aren't in tables -->
<xsl:variable name="all-footnotes" select="//h:span[@data-type='footnote'][not(ancestor::h:table)]"/>

<!-- Get a list of all chunk filenames corresponding to each footnote node -->
<xsl:variable name="filenames-for-footnotes">
Expand Down
46 changes: 35 additions & 11 deletions htmlbook-xsl/elements.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,24 @@
</xsl:apply-templates>
</xsl:template>

<!-- Custom handling for tables that have footnotes -->
<xsl:template match="h:table[descendant::h:span[@data-type='footnote']]">
<xsl:param name="process.footnotes" select="$process.footnotes"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<!-- Put table footnotes in a tfoot -->
<tfoot class="footnotes">
<tr>
<td>
<xsl:for-each select="descendant::h:span[@data-type='footnote']">
<xsl:apply-templates select="." mode="generate.footnote"/>
</xsl:for-each>
</td>
</tr>
</tfoot>
</xsl:copy>
</xsl:template>

<xsl:template match="h:figure">
<xsl:param name="html4.structural.elements" select="$html4.structural.elements"/>
<xsl:param name="figure.border.div" select="$figure.border.div"/>
Expand Down Expand Up @@ -273,7 +291,7 @@
<xsl:param name="footnote.reset.numbering.at.chapter.level" select="$footnote.reset.numbering.at.chapter.level"/>
<xsl:param name="process.footnotes" select="$process.footnotes"/>
<xsl:choose>
<xsl:when test="$process.footnotes = 1">
<xsl:when test="($process.footnotes = 1) or ancestor::h:table">
<xsl:apply-templates select="." mode="footnote.marker">
<xsl:with-param name="footnote.reset.numbering.at.chapter.level" select="$footnote.reset.numbering.at.chapter.level"/>
</xsl:apply-templates>
Expand Down Expand Up @@ -328,7 +346,7 @@
</xsl:apply-templates>
</xsl:variable>
<xsl:choose>
<xsl:when test="$process.footnotes = 1">
<xsl:when test="($process.footnotes = 1) or ancestor::h:table">
<!-- Same general handling as regular footnote markers, except footnoterefs don't get ids -->
<sup>
<a data-type="noteref">
Expand Down Expand Up @@ -366,16 +384,22 @@
<xsl:template match="h:span[@data-type='footnote']" mode="footnote.number">
<xsl:param name="footnote.reset.numbering.at.chapter.level" select="$footnote.reset.numbering.at.chapter.level"/>
<xsl:choose>
<xsl:when test="ancestor::h:table">
<!-- Count footnotes from this table -->
<xsl:number count="h:span[@data-type='footnote'][ancestor::h:table]" from="h:table" level="any" format="{$table.footnote.numeration.format}"/>
</xsl:when>
<xsl:when test="$footnote.reset.numbering.at.chapter.level = 1">
<!-- Count footnote only from most recent chapter-level element -->
<xsl:number count="h:span[@data-type='footnote']" level="any" from="h:section[parent::h:body or
parent::h:div[@data-type='part'] or
not(ancestor::h:section)]|
h:div[@data-type='part']"/>
<!-- Count non-table footnotes only from most recent chapter-level element -->
<xsl:number count="h:span[@data-type='footnote'][not(ancestor::h:table)]"
level="any" format="{$footnote.numeration.format}"
from="h:section[parent::h:body or
parent::h:div[@data-type='part'] or
not(ancestor::h:section)]|
h:div[@data-type='part']"/>
</xsl:when>
<xsl:otherwise>
<!-- Count footnotes from beginning of content -->
<xsl:number count="h:span[@data-type='footnote']" level="any"/>
<!-- Count non-table footnotes from beginning of content -->
<xsl:number count="h:span[@data-type='footnote'][not(ancestor::h:table)]" level="any" format="{$footnote.numeration.format}"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Expand All @@ -384,7 +408,7 @@
<!-- For standard, one-chunk output, we put all the footnotes at the end of the last chapter or appendix -->
<!-- (Note that if there are no chapters or appendixes in the book, footnotes will not be generated properly. This can be changed
if we determine that there are other main-book-div types that can hold footnotes at the end of a book) -->
<xsl:if test="self::h:section[@data-type='chapter' or @data-type='appendix'] and not(following::h:section[@data-type='chapter' or @data-type='appendix']) and count(//h:span[@data-type='footnote']) > 0">
<xsl:if test="self::h:section[@data-type='chapter' or @data-type='appendix'] and not(following::h:section[@data-type='chapter' or @data-type='appendix']) and count(//h:span[@data-type='footnote'][not(ancestor::h:table)]) > 0">
<!-- Footnotes should be put in an aside by default, but we call html.output.element to see if <aside> should be remapped to something else -->
<!-- Kludge-y way to get an aside element -->
<xsl:variable name="aside-element">
Expand All @@ -397,7 +421,7 @@
</xsl:variable>
<xsl:element name="{$footnote-element-name}" namespace="http://www.w3.org/1999/xhtml">
<xsl:attribute name="data-type">footnotes</xsl:attribute>
<xsl:apply-templates select="//h:span[@data-type='footnote']" mode="generate.footnote"/>
<xsl:apply-templates select="//h:span[@data-type='footnote'][not(ancestor::h:table)]" mode="generate.footnote"/>
</xsl:element>
</xsl:if>
</xsl:template>
Expand Down
6 changes: 6 additions & 0 deletions htmlbook-xsl/param.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,12 @@ toc:lower-roman
<!-- Reset footnote numbering at chapter level elements (children of part or body) -->
<xsl:param name="footnote.reset.numbering.at.chapter.level" select="1"/>

<!-- Numeration format for table footnotes -->
<xsl:param name="table.footnote.numeration.format" select="'a'"/>

<!-- Numeration format for non-table footnotes -->
<xsl:param name="footnote.numeration.format" select="'1'"/>

<!-- Admonition-specific params -->
<!-- Add title heading elements for different admonition types that do not already have headings in markup -->
<xsl:param name="add.title.heading.for.admonitions" select="0"/>
Expand Down
107 changes: 107 additions & 0 deletions htmlbook-xsl/xspec/elements.xspec
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,113 @@ sect5:1
</x:scenario>
</x:scenario>

<!-- Table footnote tests -->
<x:scenario label="When a table with footnotes is matched">
<x:context>
<table>
<caption>Four colors</caption>
<tbody>
<tr>
<td>Vermillion<span id="tf1" data-type="footnote">Reddish</span></td>
<td>Cerulean<span id="tf2" data-type="footnote">Bluish</span></td>
</tr>
<tr>
<td>Chartreuse<span id="tf3" data-type="footnote">Greenish</span></td>
<td>Fuschia<span id="tf4" data-type="footnote">Purplish</span></td>
</tr>
<tr>
<td>Teal<a data-type="footnoteref" href="#tf3"/></td>
<td>Eggplant<a data-type="footnoteref" href="#tf4"/></td>
</tr>
</tbody>
</table>
</x:context>

<x:expect label="Footnotes should be added to a tfoot section at the end of table">
<table>
<caption>...</caption>
<tbody>...</tbody>
<tfoot class="footnotes">
<tr>
<td>
<p data-type="footnote" id="tf1"><sup><a href="#tf1-marker">a</a></sup> Reddish</p>
<p data-type="footnote" id="tf2"><sup><a href="#tf2-marker">b</a></sup> Bluish</p>
<p data-type="footnote" id="tf3"><sup><a href="#tf3-marker">c</a></sup> Greenish</p>
<p data-type="footnote" id="tf4"><sup><a href="#tf4-marker">d</a></sup> Purplish</p>
</td>
</tr>
</tfoot>
</table>
</x:expect>

<!-- Same result regardless of whether process.footnotes is disabled or enabled -->
<x:scenario label="With process.footnotes disabled">
<x:context select="//h:span[@id='tf4']">
<x:param name="process.footnotes" select="0"/>
</x:context>
<x:expect label="The footnote callout should be converted to a superscripted hyperlink with a lower-alpha marker">
<sup><a data-type="noteref" id="tf4-marker" href="#tf4">d</a></sup>
</x:expect>
</x:scenario>

<x:scenario label="With process.footnotes enabled">
<x:context select="//h:span[@id='tf4']">
<x:param name="process.footnotes" select="1"/>
</x:context>
<x:expect label="The footnote callout should be converted to a superscripted hyperlink with a lower-alpha marker">
<sup><a data-type="noteref" id="tf4-marker" href="#tf4">d</a></sup>
</x:expect>
</x:scenario>

<x:scenario label="(footnoteref)">
<x:context select="(//h:a[@data-type='footnoteref'])[1]"/>
<x:expect label="The proper footnote callout should be generated with a lower-alpha marker">
<sup><a data-type="noteref" href="#tf3">c</a></sup>
</x:expect>
</x:scenario>
</x:scenario>

<x:scenario label="When a section is matched that has both footnotes and table footnotes">
<x:context>
<section data-type="chapter">
<h1>All about colors</h1>
<p>The following table<span data-type="footnote">Made with love</span> lists some colors</p>
<table>
<caption>Four colors</caption>
<tbody>
<tr>
<td>Vermillion<span id="tf1" data-type="footnote">Reddish</span></td>
<td>Cerulean<span id="tf2" data-type="footnote">Bluish</span></td>
</tr>
<tr>
<td>Chartreuse<span id="tf3" data-type="footnote">Greenish</span></td>
<td>Fuschia<span id="tf4" data-type="footnote">Purplish</span></td>
</tr>
</tbody>
</table>
<p>I hope you found this table accurate<span data-type="footnote">If not, please send errata</span></p>
</section>
</x:context>

<x:scenario label="With process.footnotes disabled">
<x:context>
<x:param name="process.footnotes" select="0"/>
</x:context>
<x:expect label="There should be 4 footnotes at end of table" test="count(//h:table//h:tfoot//*[@data-type='footnote']) = 4"/>
<x:expect label="There should be no footnotes at end of section" test="count(//h:section/h:aside//*[@data-type='footnote']) = 0"/>
</x:scenario>

<x:scenario label="With process.footnotes enabled">
<x:context>
<x:param name="process.footnotes" select="1"/>
</x:context>
<x:expect label="There should be 4 footnotes at end of table" test="count(//h:table//h:tfoot//*[@data-type='footnote']) = 4"/>
<x:expect label="There should be 2 footnotes at end of section" test="count(//h:section/h:aside//*[@data-type='footnote']) = 2"/>
<x:expect label="Footnotes at end of section should be numbered in sequence" test="every $footnote in (//h:p[@data-type='footnote'][ancestor::h:aside]) satisfies $footnote[count(preceding-sibling::h:p[@data-type='footnote']) + 1 = h:sup/h:a]"/>
</x:scenario>

</x:scenario>

<!-- Comment-toggle tests -->
<x:scenario label="When matching a block element with data-type='comment'">
<x:context>
Expand Down