Literate DocBook XML Stylesheets

Part of Literate Programming in XML

Norman Walsh

$Id: ldocbook.xweb,v 1.4 2002/01/06 19:27:56 nwalsh Exp $

05 Oct 2001


Table of Contents

1. The Stylesheets
1.1. The HTML Stylesheet
1.2. The Chunking HTML Stylesheet
1.3. The FO Stylesheet
1.4. Initialization
1.4.1. Parameters
1.4.2. Localization
2. Process HTML Fragments
2.1. Fragment Labels
2.2. Fragment Titles
3. Process FO Fragments
4. Process HTML Fragment References
4.1. Fragment Cross-Reference Text
5. Process FO Fragment References
5.1. Fragment Cross-Reference Text

The ldocbook.xsl stylesheet transforms an XWEB documentation file (a “woven” XWEB document) into HTML documentation.

This stylesheet assumes that fragments appear inside DocBook section elements. Some additional customization of the §2.1.1. Fragment Labels and §2.2.1. Fragment Titles will be required to support a different organization.

1. The Stylesheets

This document describes both the HTML and XSL Formatting Objects versions of the stylesheet.

1.1. The HTML Stylesheet

The stylesheet performs some initialization and establishes templates for the Literate Programming elements that can appear in the documentation. Most of the documentation elements will be DocBook elements handled by the imported stylesheet.

§1.1.1

  1| <xsl:stylesheet xmlns:fo="http://www.w3.org/1999/XSL/Format"
   |                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:verb="com.nwalsh.saxon.Verbatim"
   |                 exclude-result-prefixes="verb src"
   |                 version="1.0">
  5|   <xsl:import xmlns:fo="http://www.w3.org/1999/XSL/Format"
   |               xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:verb="com.nwalsh.saxon.Verbatim"
   |               href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
   | 
   |   §1.4.1. Initialization
 10|   §2.1. Process HTML Fragments
   |   §4.1. Process HTML Fragment References
   | </xsl:stylesheet>

1.2. The Chunking HTML Stylesheet

The stylesheet performs some initialization and establishes templates for the Literate Programming elements that can appear in the documentation. Most of the documentation elements will be DocBook elements handled by the imported stylesheet.

§1.2.1

  1| <xsl:stylesheet xmlns:fo="http://www.w3.org/1999/XSL/Format"
   |                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:verb="com.nwalsh.saxon.Verbatim"
   |                 exclude-result-prefixes="verb src"
   |                 version="1.0">
  5|   <xsl:import xmlns:fo="http://www.w3.org/1999/XSL/Format"
   |               xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:verb="com.nwalsh.saxon.Verbatim"
   |               href="http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl"/>
   | 
   |   §1.4.1. Initialization
 10|   §2.1. Process HTML Fragments
   |   §4.1. Process HTML Fragment References
   | </xsl:stylesheet>

1.3. The FO Stylesheet

The stylesheet performs some initialization and establishes templates for the Literate Programming elements that can appear in the documentation. Most of the documentation elements will be DocBook elements handled by the imported stylesheet.

§1.3.1

  1| <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   |                 xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:verb="com.nwalsh.saxon.Verbatim"
   |                 exclude-result-prefixes="verb src fo"
   |                 version="1.0">
  5| 
   |   <xsl:import xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   |               xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:verb="com.nwalsh.saxon.Verbatim"
   |               href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
   | 
 10|   <xsl:param xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   |              xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:verb="com.nwalsh.saxon.Verbatim"
   |              name="page.margin.outer"
   |              select="'1in'"/>
   |   <xsl:param xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 15|              xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:verb="com.nwalsh.saxon.Verbatim"
   |              name="title.margin.left"
   |              select="'-0pt'"/>
   | 
   |   §1.4.1. Initialization
 20|   §3.1. Process FO Fragments
   |   §5.1. Process FO Fragment References
   | </xsl:stylesheet>

1.4. Initialization

The stylesheet initializes the processor by loading its version information (stored in a separate file because it is shared by several stylesheets), importing the base DocBook stylesheet, setting some parameters, and setting up some internationalized text.

§1.4.1: §1.1.1, §1.2.1, §1.3.1

  1|   <xsl:include href="../VERSION"/>
   | 
   |   <xsl:template match="revhistory"
   |                 mode="titlepage.mode"/>
  5| 
   |   §1.4.1.1. Parameters
   |   §1.4.2.1. Localization

1.4.1. Parameters

In DocBook Literate Programming documentation, we always number sections and verbatim environments.

§1.4.1.1: §1.4.1

  1| <xsl:param name="section.autolabel"
   |            select="1"/>
   | <xsl:param name="linenumbering.everyNth"
   |            select="5"/>
  5| <xsl:param name="linenumbering.separator"
   |            select="'| '"/>

1.4.2. Localization

Localized text in the DocBook stylesheets makes use of an external document to determine the nature of, among other things, element titles and cross references.

Cross references to src:fragments are not supported in the stock stylesheets (since there is no such element in DocBook).

In order to make cross references work properly, we must provide an appropriate localization for src:fragment titles. We do this by pointing the local.l10n.xml at ourselves (at the stylesheet document).

In our local localization document, we add an l:i18n element to provide the necessary context.

If you want to support DocBook Literate Programming in other languages, this section will have to be updated.

§1.4.2.1: §1.4.1

  1| <xsl:param name="local.l10n.xml"
   |            select="document('')"/>
   | 
   | <l:i18n>
  5|   <l:l10n language="en">
   |    <l:context name="title">
   |       <l:template name="fragment"
   |                   text="%t"/>
   |     </l:context>
 10|   </l:l10n>
   | </l:i18n>

2. Process HTML Fragments

Fragments are output as verbatim environments with numbered lines, if possible. A table is used to make the listings stand out.

§2.1: §1.1.1, §1.2.1

  1| <xsl:template match="src:fragment">
   |   <xsl:param name="suppress-numbers"
   |              select="'0'"/>
   |   <xsl:param name="linenumbering"
  5|              select="'numbered'"/>
   | 
   |   <xsl:variable name="section"
   |                 select="ancestor::section[1]"/>
   |   <xsl:variable name="id"
 10|                 select="@id"/>
   |   <xsl:variable name="referents"
   |                 select="//src:fragment[.//src:fragref[@linkend=$id]]"/>
   | 
   |   <div class="src-fragment">
 15|   <a name="{@id}"/>
   |   <table border="1"
   |          width="100%">
   |     <tr>
   |       <td>
 20|         <p>
   |           <b>
   |             <xsl:apply-templates select="."
   |                                  mode="label.markup"/>
   |           </b>
 25|           <xsl:if test="$referents">
   |             <xsl:text>: </xsl:text>
   |             <xsl:for-each select="$referents">
   |               <xsl:if test="position() > 1">, </xsl:if>
   |               <a>
 30|                 <xsl:attribute name="href">
   |                   <xsl:call-template name="href.target">
   |                     <xsl:with-param name="object"
   |                                     select="."/>
   |                   </xsl:call-template>
 35|                 </xsl:attribute>
   |                 <xsl:apply-templates select="."
   |                                      mode="label.markup"/>
   |               </a>
   |             </xsl:for-each>
 40|           </xsl:if>
   |         </p>
   |       </td>
   |     </tr>
   |     <tr>
 45|       <td>
   |         <xsl:choose>
   |           <xsl:when test="$suppress-numbers = '0'                           and $linenumbering = 'numbered'                           and $use.extensions != '0'                           and $linenumbering.extension != '0'">
   |             <xsl:variable name="rtf">
   |               <xsl:apply-templates/>
 50|             </xsl:variable>
   |             <pre class="{name(.)}">
   |               <xsl:copy-of select="verb:numberLines($rtf)"/>
   |             </pre>
   |           </xsl:when>
 55|           <xsl:otherwise>
   |             <pre class="{name(.)}">
   |               <xsl:apply-templates/>
   |             </pre>
   |           </xsl:otherwise>
 60|         </xsl:choose>
   |       </td>
   |     </tr>
   |   </table>
   |   </div>
 65| </xsl:template>
   | 
   | §2.1.1. Fragment Labels
   | §2.2.1. Fragment Titles

Fragment labels and titles must also be supported.

2.1. Fragment Labels

A fragment label consists of a section mark followed by the label of the current section and the number of the fragment within that section.

§2.1.1: §2.1, §3.1

  1| <xsl:template match="src:fragment"
   |               mode="label.markup">
   |   <xsl:variable name="section"
   |                 select="ancestor::section[1]"/>
  5| 
   |   <xsl:text>§</xsl:text>
   | 
   |   <xsl:choose>
   |     <xsl:when test="$section">
 10|       <xsl:variable name="section.label">
   |         <xsl:apply-templates select="$section"
   |                              mode="label.markup"/>
   |       </xsl:variable>
   |       <xsl:choose>
 15|         <xsl:when test="string($section.label) = ''">
   |           <xsl:number from="section"/>
   |         </xsl:when>
   |         <xsl:otherwise>
   |           <xsl:copy-of select="$section.label"/>
 20|           <xsl:text>.</xsl:text>
   |           <xsl:number from="section"/>
   |         </xsl:otherwise>
   |       </xsl:choose>
   |     </xsl:when>
 25|     <xsl:otherwise>
   |       <xsl:number from="/"/>
   |     </xsl:otherwise>
   |   </xsl:choose>
   | </xsl:template>

2.2. Fragment Titles

A fragment title is the title of the section that contains it.

§2.2.1: §2.1, §3.1

  1| <xsl:template match="src:fragment"
   |               mode="title.markup">
   |   <xsl:variable name="section"
   |                 select="ancestor::section[1]"/>
  5| 
   |   <xsl:if test="$section">
   |     <xsl:apply-templates select="$section"
   |                          mode="title.markup"/>
   |   </xsl:if>
 10| </xsl:template>

3. Process FO Fragments

Fragments are output as verbatim environments with numbered lines, if possible.

§3.1: §1.3.1

  1| <xsl:template match="src:fragment">
   |   <xsl:param name="suppress-numbers"
   |              select="'0'"/>
   |   <xsl:param name="linenumbering"
  5|              select="'numbered'"/>
   | 
   |   <xsl:variable name="section"
   |                 select="ancestor::section[1]"/>
   |   <xsl:variable name="id"
 10|                 select="@id"/>
   |   <xsl:variable name="referents"
   |                 select="//src:fragment[.//src:fragref[@linkend=$id]]"/>
   | 
   |   <fo:block xsl:use-attribute-sets="formal.object.properties"
 15|             keep-together="always"
   |             border-style="solid"
   |             border-width="0pt"
   |             border-before-width="0.25pt"
   |             border-after-width="0.25pt">
 20|     <fo:block id="{@id}"
   |               border-width="0pt"
   |               border-style="solid"
   |               border-after-width="0.25pt">
   |       <fo:inline font-weight="bold">
 25|         <xsl:apply-templates select="."
   |                              mode="label.markup"/>
   |       </fo:inline>
   |       <fo:inline>
   |         <xsl:if test="$referents">
 30|           <xsl:text>: </xsl:text>
   |           <xsl:for-each select="$referents">
   |             <xsl:if test="position() > 1">, </xsl:if>
   |             <xsl:apply-templates select="."
   |                                  mode="label.markup"/>
 35|           </xsl:for-each>
   |         </xsl:if>
   |       </fo:inline>
   |     </fo:block>
   | 
 40|     <fo:block wrap-option="no-wrap"
   |               text-align="start"
   |               white-space-collapse="false"
   |               linefeed-treatment="preserve"
   |               xsl:use-attribute-sets="monospace.verbatim.properties">
 45|       <xsl:variable name="rtf">
   |         <xsl:apply-templates/>
   |       </xsl:variable>
   | 
   |       <xsl:choose>
 50|         <xsl:when test="$suppress-numbers = '0'                         and $linenumbering = 'numbered'                         and $use.extensions != '0'                         and $linenumbering.extension != '0'">
   |           <xsl:call-template name="number.rtf.lines">
   |             <xsl:with-param name="rtf"
   |                             select="$rtf"/>
   |           </xsl:call-template>
 55|         </xsl:when>
   |         <xsl:otherwise>
   |           <xsl:copy-of select="$rtf"/>
   |         </xsl:otherwise>
   |       </xsl:choose>
 60|     </fo:block>
   |   </fo:block>
   | </xsl:template>
   | 
   | §2.1.1. Fragment Labels
 65| §2.2.1. Fragment Titles

4. Process HTML Fragment References

A fragment reference has exactly the same semantics as a DocBook xref.

§4.1: §1.1.1, §1.2.1

  1| <xsl:template match="src:fragref">
  2|   <xsl:call-template name="xref"/>
  3| </xsl:template>
  4| §4.1.1. Fragment Cross-Reference Text

4.1. Fragment Cross-Reference Text

Cross references to fragments produce the fragment label and title.

§4.1.1: §4.1

  1| <xsl:template match="src:fragment"
   |               mode="xref-to">
   |   <xsl:variable name="section"
   |                 select="ancestor::section[1]"/>
  5| 
   |   <i>
   |     <xsl:apply-templates select="."
   |                          mode="label.markup"/>
   |     <xsl:text>. </xsl:text>
 10|     <xsl:apply-templates select="."
   |                          mode="title.markup"/>
   |   </i>
   | </xsl:template>

5. Process FO Fragment References

A fragment reference has exactly the same semantics as a DocBook xref.

§5.1: §1.3.1

  1| <xsl:template match="src:fragref">
  2|   <xsl:call-template name="xref"/>
  3| </xsl:template>
  4| §5.1.1. Fragment Cross-Reference Text

5.1. Fragment Cross-Reference Text

Cross references to fragments produce the fragment label and title.

§5.1.1: §5.1

  1| <xsl:template match="src:fragment"
   |               mode="xref-to">
   |   <xsl:variable name="section"
   |                 select="ancestor::section[1]"/>
  5| 
   |   <fo:inline font-style="italic">
   |     <xsl:apply-templates select="."
   |                          mode="label.markup"/>
   |     <xsl:text>. </xsl:text>
 10|     <xsl:apply-templates select="."
   |                          mode="title.markup"/>
   |   </fo:inline>
   | </xsl:template>