Re: Endnotes in PDF?

Bob Stayton <[email protected]> Tue, 21 Dec 2021 14:40:42 -0800
Newsgroups gmane.text.docbook.apps
Message-ID <[email protected]>
Hi,

I used the same style of endnotes in a book that I wrote with DocBook, 
so I have attached the stylesheet module that I wrote to do that.  You 
might need to make some adjustments to fit it into your customization layer.

Bob Stayton
[email protected]

On 12/21/2021 7:02 AM, M. Downing Roberts wrote:
> I'm trying to use DocBook and FOP to generate endnotes at the end of 
> my book. I.e., I'd like the footnote elements to be rendered as 
> endnotes, not footnotes.
>
> If possible, I'd like them grouped by chapter (but at the end of the 
> book, not at the end of each chapter).
>
> I've searched a lot, and only found a discussion here:
>
> http://www.sagehill.net/docbookxsl/Endnotes.html
>
> ...but it's too vague. Too many loose ends. I can't get it to work at all.
>
> Any suggestions??
>
> Thanks!
>
> M.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
endnotes.bobs.xsl (text/xml, 12.5 KB)
<?xml version="1.0"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY lowercase "'abcdefghijklmnopqrstuvwxyz'">
<!ENTITY uppercase "'ABCDEFGHIJKLMNOPQRSTUVWXYZ'">
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format"
                version="1.0" >

<xsl:output indent="no"/>

<xsl:attribute-set name="endnote.title.properties">
  <xsl:attribute name="font-family">&FGHeavy;</xsl:attribute>
  <xsl:attribute name="font-size">10pt</xsl:attribute>
  <xsl:attribute name="line-height">11pt</xsl:attribute>
  <xsl:attribute name="text-align">start</xsl:attribute>
  <xsl:attribute name="space-before">12pt</xsl:attribute>
  <xsl:attribute name="space-after">4pt</xsl:attribute>
  <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
</xsl:attribute-set>

<xsl:attribute-set name="endnote.listblock.properties">
  <xsl:attribute name="font-size">9.0pt</xsl:attribute>
  <xsl:attribute name="line-height">10pt</xsl:attribute>
  <xsl:attribute name="space-before">4pt</xsl:attribute>
  <xsl:attribute name="provisional-distance-between-starts">18pt</xsl:attribute>
  <xsl:attribute name="provisional-label-separation">3pt</xsl:attribute>
</xsl:attribute-set>

<xsl:attribute-set name="endnote.listlabel.properties">
  <xsl:attribute name="text-align">end</xsl:attribute>
  <xsl:attribute name="end-indent">label-end()</xsl:attribute>
</xsl:attribute-set>

<xsl:attribute-set name="endnote.listbody.properties">
  <xsl:attribute name="text-align">start</xsl:attribute>
  <xsl:attribute name="start-indent">body-start()</xsl:attribute>
</xsl:attribute-set>

<!-- replace bibliography with end notes -->
<xsl:template match="bibliography[@role = 'endnotes']">
  <xsl:param name="node" select="."/>

  <xsl:variable name="id">
    <xsl:call-template name="object.id"/>
  </xsl:variable>

  <xsl:variable name="title">
    <xsl:apply-templates select="." mode="object.title.markup"/>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="not(parent::*) or parent::part or parent::book">
      <xsl:variable name="master-reference">
        <xsl:call-template name="select.pagemaster"/>
      </xsl:variable>

      <fo:page-sequence hyphenate="{$hyphenate}"
                        master-reference="{$master-reference}">
        <xsl:attribute name="language">
          <xsl:call-template name="l10n.language"/>
        </xsl:attribute>
        <xsl:attribute name="format">
          <xsl:call-template name="page.number.format">
            <xsl:with-param name="master-reference" select="$master-reference"/>
          </xsl:call-template>
        </xsl:attribute>
        <xsl:attribute name="initial-page-number">
          <xsl:call-template name="initial.page.number">
            <xsl:with-param name="master-reference" select="$master-reference"/>
          </xsl:call-template>
        </xsl:attribute>
        <xsl:attribute name="force-page-count">
          <xsl:call-template name="force.page.count">
            <xsl:with-param name="master-reference" select="$master-reference"/>
          </xsl:call-template>
        </xsl:attribute>
        <xsl:attribute name="hyphenation-character">
          <xsl:call-template name="gentext">
            <xsl:with-param name="key" select="'hyphenation-character'"/>
          </xsl:call-template>
        </xsl:attribute>
        <xsl:attribute name="hyphenation-push-character-count">
          <xsl:call-template name="gentext">
            <xsl:with-param name="key" select="'hyphenation-push-character-count'"/>
          </xsl:call-template>
        </xsl:attribute>
        <xsl:attribute name="hyphenation-remain-character-count">
          <xsl:call-template name="gentext">
            <xsl:with-param name="key" select="'hyphenation-remain-character-count'"/>
          </xsl:call-template>
        </xsl:attribute>

        <xsl:apply-templates select="." mode="running.head.mode">
          <xsl:with-param name="master-reference" select="$master-reference"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="." mode="running.foot.mode">
          <xsl:with-param name="master-reference" select="$master-reference"/>
        </xsl:apply-templates>

        <fo:flow flow-name="xsl-region-body">
          <xsl:call-template name="set.flow.properties">
            <xsl:with-param name="element" select="local-name(.)"/>
            <xsl:with-param name="master-reference" select="$master-reference"/>
          </xsl:call-template>


          <fo:block id="{$id}">
            <xsl:call-template name="bibliography.titlepage"/>
          </fo:block>

          <xsl:call-template name="book.endnotes"/>

        </fo:flow>
      </fo:page-sequence>
    </xsl:when>
    <xsl:otherwise>
      <fo:block id="{$id}"
                hyphenate="true"
                break-before="page"
                space-before.minimum="1em"
                space-before.optimum="1.5em"
                space-before.maximum="2em">
        <xsl:call-template name="bibliography.titlepage"/>
      </fo:block>
      <xsl:apply-templates>
        <xsl:sort select="translate(abbrev, &lowercase;, &uppercase;)"/>
      </xsl:apply-templates>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- handle table title footnotes like regular footnotes -->
<xsl:template name="book.endnotes">
  <xsl:variable name="footnotes" select="//footnote"/>
  <xsl:variable name="table.footnotes"
                select=".//tgroup//footnote"/>

  <xsl:if test="count($footnotes)>count($table.footnotes)">
      <xsl:apply-templates select="//chapter|//appendix|//preface" mode="chapter.endnotes"/>
  </xsl:if>
</xsl:template>

<xsl:template match="chapter|appendix|preface" mode="chapter.endnotes">
  <xsl:variable name="footnotes"
                select=".//footnote[not(ancestor::tgroup)]"/>
  <xsl:if test="$footnotes">
    <fo:block xsl:use-attribute-sets="endnote.title.properties">
      <xsl:call-template name="gentext">
        <xsl:with-param name="key" select="local-name(.)"/>
      </xsl:call-template>
      <xsl:text> </xsl:text>
      <xsl:apply-templates select="." mode="label.markup"/>
      <xsl:text>: </xsl:text>
      <xsl:apply-templates select="." mode="title.markup"/>
    </fo:block>
    <xsl:apply-templates select="$footnotes" mode="process.footnote.mode"/>
      
  </xsl:if>
</xsl:template>

<xsl:template match="footnote">
  <xsl:variable name="id">
    <xsl:call-template name="object.id">
      <xsl:with-param name="conditional" select="0"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="ancestor::tgroup">
      <xsl:call-template name="format.footnote.mark">
        <xsl:with-param name="mark">
          <xsl:apply-templates select="." mode="footnote.number"/>
        </xsl:with-param>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
        <fo:inline id="{$id}" keep-with-previous.within-line="always">
          <fo:basic-link internal-destination="{concat('ftn.',$id)}">
            <xsl:call-template name="format.footnote.mark">
              <xsl:with-param name="mark">
                <xsl:apply-templates select="." mode="footnote.number"/>
              </xsl:with-param>
            </xsl:call-template>
          </fo:basic-link>
        </fo:inline>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="footnote" name="process.footnote" mode="process.footnote.mode">

  <xsl:variable name="id">
    <xsl:text>ftn.</xsl:text>
    <xsl:call-template name="object.id">
      <xsl:with-param name="conditional" select="0"/>
    </xsl:call-template>
  </xsl:variable>

  <fo:list-block id="{$id}" xsl:use-attribute-sets="endnote.listblock.properties">
    <fo:list-item>
      <fo:list-item-label xsl:use-attribute-sets="endnote.listlabel.properties">
        <xsl:variable name="href">
          <xsl:call-template name="object.id">
            <xsl:with-param name="object" select="."/>
          </xsl:call-template>
        </xsl:variable>
      
        <fo:block>
          <fo:basic-link internal-destination="{$href}">
            <xsl:apply-templates select="." mode="footnote.number"/>
            <xsl:text>.</xsl:text>
          </fo:basic-link>
        </fo:block>
      </fo:list-item-label>
      <fo:list-item-body xsl:use-attribute-sets="endnote.listbody.properties">

        <xsl:variable name="biblioref">
          <xsl:call-template name="biblioref">
            <xsl:with-param name="string" select="normalize-space(para[1])"/>
          </xsl:call-template>
        </xsl:variable>
      
        <xsl:variable name="marker" select="concat('[', $biblioref, ']')"/>
        <xsl:variable name="lookup" select="key('abbrev', $biblioref)"/>
      
        <fo:block>
          <xsl:choose>
            <xsl:when test="local-name($lookup) = 'bibliomixed'">
              <xsl:apply-templates select="$lookup/node()" mode="bibliomixed.mode"/>
              <xsl:text> </xsl:text>
              <xsl:apply-templates select="para[1]/node()"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:apply-templates/>
            </xsl:otherwise>
          </xsl:choose>
        </fo:block>
      </fo:list-item-body>
    </fo:list-item>
  </fo:list-block>

</xsl:template>

<xsl:template match="footnote/para[1]
                     |footnote/simpara[1]
                     |footnote/formalpara[1]"
              priority="2">
  <!-- this only works if the first thing in a footnote is a para, -->
  <!-- which is ok, because it usually is. -->
  <fo:block>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template name="biblioentry.label"/>

<!-- return the abbrev used in a biblioreference -->
<xsl:template name="biblioref">
  <xsl:param name="string" select="normalize-space(.)"/>
  <xsl:if test="starts-with($string, '['  )">
    <xsl:variable name="var1" select="substring($string, 2)"/>
    <xsl:variable name="var2" select="substring-before($var1, ']' )"/>
    <xsl:value-of select="$var2"/>
  </xsl:if>
</xsl:template>

<!-- match on first text node of first para -->
<xsl:template match="footnote/para[1]/text()[1]|footnote/simpara[1]/text()[1]" 
              priority="2">
  <xsl:choose>
    <xsl:when test="starts-with(., '[') and contains(., ']')">
      <xsl:value-of select="substring-after(., ']')"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="."/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="title" mode="bibliomixed.mode">
  <fo:inline font-style="italic">
    <xsl:apply-templates mode="bibliomixed.mode"/>
  </fo:inline>
</xsl:template>

<!-- restart numbering in chapters -->
<xsl:template match="footnote" mode="footnote.number">
  <xsl:choose>
    <xsl:when test="string-length(@label) != 0">
      <xsl:value-of select="@label"/>
    </xsl:when>
    <xsl:when test="ancestor::tgroup">
      <xsl:variable name="tfnum">
        <xsl:number level="any" from="tgroup" format="1"/>
      </xsl:variable>

      <xsl:choose>
        <xsl:when test="string-length($table.footnote.number.symbols) &gt;= $tfnum">
          <xsl:value-of select="substring($table.footnote.number.symbols, $tfnum, 1)"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:number level="any" from="tgroup"
                      format="{$table.footnote.number.format}"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
    <xsl:otherwise>
      <xsl:number level="any" from="chapter|appendix" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- consecutive numbers for figures -->
<xsl:template match="figure|table|example" mode="label.markup">
  <xsl:variable name="pchap"
                select="(ancestor::chapter
                        |ancestor::appendix
                        |ancestor::article[ancestor::book])[last()]"/>

  <xsl:variable name="prefix"/>

  <xsl:choose>
    <xsl:when test="@label">
      <xsl:value-of select="@label"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:choose>
        <xsl:when test="$prefix != ''">
            <xsl:apply-templates select="$pchap" mode="label.markup"/>
            <xsl:apply-templates select="$pchap" mode="intralabel.punctuation"/>
          <xsl:number format="1" from="chapter|appendix" level="any"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:number format="1" from="book|article" level="any"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


</xsl:stylesheet>