Difficulty: ★★☆ (medium)
Keywords: table of contents, TOC, authors, proceedings

Problem

You have a document which is written by different authors (like in proceedings) and want to include the author names in the table of contents.

Solution

You need to customize the toc.line template. Proceed as follows:

  1. Make sure your chapters, appendices, sections, etc. contain at least one author, like in the following example:

    <sect1>
      <title>How to Become a Linux Mascott</title>
      <info>
        <author>
          <personname>
            <firstname>Tux</firstname>
            <surname>Penguin</surname>
          </personname>
        </author>
      </info>
      <!-- ... -->
    </sect1>
  2. Create a customization layer first as shown in Section 2.3, “Writing Customization Layers”.

  3. Add the following line to your customization layer:

    <xsl:include href="autotoc.xsl"/>
  4. Create a new file autotoc.xsl in the same directory, with the following contents:

    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns="http://www.w3.org/1999/xhtml">
      
      <xsl:template name="toc.line">
        <xsl:param name="toc-context" select="."/>
        <xsl:param name="depth" select="1"/>
        <xsl:param name="depth.from.context" select="8"/>
    
        <xsl:variable name="author" select="*/author|*/authorgroup/author"/>
    
        <xsl:if test="$author">
          <span class="author">
            <xsl:call-template name="person.name.list">
              <xsl:with-param name="person.list" select="$author"/>
            </xsl:call-template>
            <xsl:text>: </xsl:text>
          </span>
        </xsl:if>
        <span class="{local-name(.)}">
          <xsl:if test="$autotoc.label.in.hyperlink = 0">
            <xsl:variable name="label">
              <xsl:apply-templates select="." mode="label.markup"/>
            </xsl:variable>
            <xsl:copy-of select="$label"/>
            <xsl:if test="$label != ''">
              <xsl:value-of select="$autotoc.label.separator"/>
            </xsl:if>
          </xsl:if>
    
          <a>
            <xsl:attribute name="href">
              <xsl:call-template name="href.target">
                <xsl:with-param name="context" select="$toc-context"/>
                <xsl:with-param name="toc-context" select="$toc-context"/>
              </xsl:call-template>
            </xsl:attribute>
    
            <xsl:if test="not($autotoc.label.in.hyperlink = 0)">
              <xsl:variable name="label">
                <xsl:apply-templates select="." mode="label.markup"/>
              </xsl:variable>
              <xsl:copy-of select="$label"/>
              <xsl:if test="$label != ''">
                <xsl:value-of select="$autotoc.label.separator"/>
              </xsl:if>
            </xsl:if>
    
            <xsl:apply-templates select="." mode="titleabbrev.markup"/>
          </a>
        </span>
      </xsl:template>
    </xsl:stylesheet>

    1

    Collects all author nodes regardless if they appear in info or authorgroup

    2

    Checks, if author nodes were found

    3

    Calls person.name.list and pass the nodes from 1

    4

    Contains the original code from autotoc.xsl and creates the title entry for the table of contents

  5. Rebuild your document with your customization layer.

When you process the above section with the customization layer, you will receive the following line:

Tux Penguin: How to Become a Linux Mascott

Or in HTML notation:

<span class="author">Tux Penguin: </span>
<span class="section">
  <a href="...">How to Become a Linux Mascott</a>
</span>

Depending on the parameter section.autolabel the title can be prefixed with a number.

Discussion

The previous stylesheet works also for one or more authors. It does not matter if the author elements appear as a direct child of info or authorgroup. The following code produces the same string:

<info>
  <author>
    <personname>
      <firstname>Tux</firstname>
      <surname>Penguin</surname>
    </personname>
  </author>
  <author>
    <personname>
      <firstname>Wilber</firstname>
      <surname>Gimp</surname>
    </personname>
  </author>
</info>
<info>
  <authorgroup>
    <author>
      <personname>
        <firstname>Tux</firstname>
        <surname>Penguin</surname>
      </personname>
    </author>
    <author>
      <personname>
        <firstname>Wilber</firstname>
        <surname>Gimp</surname>
      </personname>
    </author>
  </authorgroup>
</info>

Even if you mix author and authorgroup you will get the correct string output.

You can also use elements other than author. To detect editor, extend the variable author as follows:

<xsl:variable name="author"
      select="*/author|*/editor|*/authorgroup/author|*/authorgroup/editor"/>

See Also


Project@GitHubIssue#10