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
b...@sagehill.net

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.
<?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>
---------------------------------------------------------------------
To unsubscribe, e-mail: docbook-apps-unsubscr...@lists.oasis-open.org
For additional commands, e-mail: docbook-apps-h...@lists.oasis-open.org

Reply via email to