The book stylesheet

The following is an explanation of some of the mappings in the Demonstrations/DITA/book stylesheet.

$headfoot//booktitlealt

The booktitle element can contain other elements such as booktitlealt. Since it inherits from title, the map/title mapping assigns the content of this element to the BookTitle variable, which is used to display the left page header (see the 1 column page layout and the booktitle header/foot mapping).

The $headfoot//booktitlealt mapping suppresses the booktitlealt element when it is used in the context of a fixed block, so only the main title appears in the page header.

map

Some processing needs to be done at different times depending on the input data. For example, consider the appropriate time to generate the cover page. For a simple map it can be done as soon as the title content is known. For a bookmap it should be deferred until the bookmeta element has been processed, since it contains information that may appear on the cover.

The map mapping (which will be used for both map and bookmap because of inheritance) contains the following:

<set var="MapContent" copy="element"/>

<!-- Test whether the bookmeta element is present -->
<xmlproc source="MapContent" var="HasMeta" select="count(//bookmeta[1])"/>

This creates an XML fragment from the map or bookmap and sets the HasMeta variable to either 0 or 1 according to whether a bookmeta element is present. The map/title mapping uses this variable to decide whether to generate the cover page immediately or to let the bookmeta mapping do it.

The map mapping also looks for a frontmatter element. If one is found it sets the page numbering style to roman numerals.

bookmeta

This mapping demonstrates the use of “pull” processing for an element. The mapping scans and suppresses the element, and creates an XML fragment from it.

Only the required information is extracted for later use; everything else is ignored.

topicref

This is the most complex mapping in the stylesheet, and plays an important role in defining the structure of the document. The following explain parts of its pre-content.

<stack var="TopicLevel" value="{TopicLevel}+1"/>
<stack var="TopicContext" string="{TopicContext}"/>

The use of the stack command is important, since topicref elements can be nested. Using stack instead of set restores the previous value of the variable when the end tag of this element is processed. The value of TopicContext may be altered by what follows; this command makes sure that the former value will be restored.

<!-- set the navigation title -->
<set var="Topicref" copy="element"/>
<xmlproc source="Topicref" var="Navtitle" select="topicmeta/navtitle/node()"/>
<if var="Navtitle" target="">
    <set var="Navtitle" string="{@navtitle}"/>
</if>

The DITA 1.2 specification says that a navtitle element should be used in preference to the attribute value, so the above attempts to find a navtitle element and extract its content. If this produces an empty result, the attribute value is used.

<case var="@class" test="matches" target="* bookmap/chapter *">
    <set var="TopicContext" string="C"/>

    <if var="@href" target="#IMPLIED">
        <!-- dummy topic for chapter -->
        <NewTopic level="C1"/>
        <Title level="C1">{Navtitle}</Title>
    </if>
</case>

This is one of the cases in the switch statement; at most one of these will be executed. The above is executed if a chapter element, or something that inherits from it, is being processed. The test for #IMPLIED is the correct way to test for a missing attribute in TopLeaf. If there is no topic specified for this chapter, a title is generated using the value for Navtitle created above, since the topic/title mapping will not be triggered in this case.

<switch>
<case var="@processing-role" target="resource-only">
    <!-- ignore objects included as resources -->
</case>
<case var="@href" target="#IMPLIED">
    <!-- ignore if there is no referenced object -->
</case>
<case>
    <read file="{document-folder}/{@href}" use-fragment="yes"/>
</case>
</switch>

The final part reads the referenced topic unless it is not directly part of the document content.

The TopicContext and TopicLevel variables are used in the topic and topic/title mappings to apply an appropriate style.

topic//topic

If a file contains multiple nested topics, this mapping is used for the inner topics. It increments the level counter so the topic title will be rendered with the appropriate style. The topic mapping is the one used for the top-level topic in a file.

xref

This mapping creates a link using the value of the dita.fullref attribute. This attribute is not present in the data — it is added internally by TopLeaf.

The page number is added to the link content by calling the %AddPage custom mapping. This extracts the page number from the entry in the xref file that corresponds to the link target. It relies on the following:

  • The automatic page number references described in “Page numbers”.

  • The xref file is read in the $document mapping.

  • The tl:xref mapping assigns the xref content to the Xref variable as an XML fragment.

figurelist

This also relies on the xref content being read into the Xref variable.

<xmlproc source="Xref" var="FigureCount"
  select="count(tlx:xrefline[@class='%FigureRef'])"/>

The command above sets the FigureCount variable to the number of xref entries generated by the %FigureRef custom marker. If the value of this variable is greater than zero, the code below it sends the entries to the input stream to produce the list of figures.