<?xml version="1.0" encoding="utf-8"?>
<!--

 File Name:            sdocbook_html.xslt

 Simplified DocBook Stylesheet
 (for Simplified DocBook V1.0CR2)

 Copyright 2002 Fourthought Inc, USA.
 See  http://4suite.org/COPYRIGHT  for license and copyright information

 Simplified DocBook: The Definitive Guide
 http://www.docbook.org/tdg/simple/en/html/sdocbook.html

 TODO:
  - Support all of Simplified DocBook, not just the parts we use.
  - Maybe turn this into a proper customization layer for the
    official DocBook XSLT stylesheets

 DESIGN NOTES:
  - TEST ALL CHANGES in multiple browsers (e.g. IE and Mozilla).
  - Don't rely on the DTD to provide default attributes; chances
      are the source doc isn't referencing a DTD at all.
  - Do as much natural traversal down the source tree as possible.
  - Special traversal modes:
        HEAD = generating HTML <head> contents
        TOC = generating table of contents
  - Default traversal will visit all elements, doing nothing.
      To generate output, you need a template that matches one
      of these elements. The template can use apply-templates
      or can pick-and-choose from its contents. Don't forget to
      use apply-templates to continue on, unless you want the
      branch to be a dead end (which is sometimes desirable).
  - Rely on CSS for as much formatting as possible, except:
      monospace type w/literal whitespace: use <pre>
      required bold: use <strong>
      required italics: use <em>
    Default CSS stylesheet URI = 'sdocbook_html.css';
    Default 'draft' watermark image URI = 'draft.gif';
  - Create <div>s with appropriate CSS classes for all block-level
      elements where it makes sense. Be careful when traversing
      onward from one of these elements that you apply-templates
      to attributes as well as children (e.g. select="@*|node()")
      so that ids will be copied through.
  - If an element's content model does not include #PCDATA,
      don't apply-templates to all its children. Just do elements,
      or both elements and attributes if block-level. This is in
      part because (for now) we are letting the built-in template
      for text nodes handle text, copying it through.
  - It's already starting to get messy, I know.
-->

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  exclude-result-prefixes="dc"
>

  <!-- metadata -->
  <dc:Creator>Fourthought, Inc</dc:Creator>
  <dc:Title>Simplified DocBook Stylesheet</dc:Title>

  <!-- generate full HTML doc with table of contents? -->
  <xsl:param name="top-level-html" select="true()"/>

  <!-- if generating full HTML doc, URI of CSS file to link to -->
  <xsl:param name="css-file" select="'sdocbook_html.css'"/>

  <!-- show revision history? -->
  <xsl:param name="show-rev-history"/>

  <!-- show revision remarks? -->
  <xsl:param name="show-rev-remarks"/>

  <!-- number each <section>? -->
  <xsl:param name="number-sections" select="'yes'"/>

  <!-- max depth of table of contents -->
  <xsl:param name="toc-depth" select="3"/>

  <!-- generate HTML for each <section> even if it has no title? -->
  <!-- not yet supported -->
  <xsl:param name="mark-untitled-sections" select="'yes'"/>

  <!-- a DOCTYPE with a system ID puts browsers in standards-compliance mode -->
  <xsl:output method="html" encoding="iso-8859-1" indent="yes"
    doctype-system="http://www.w3.org/TR/html4/loose.dtd"
    doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>

  <!-- ================================================================== -->

  <xsl:template match="/">
    <xsl:choose>
      <xsl:when test="$top-level-html=1">
        <html>
          <head>
            <xsl:apply-templates mode="HEAD"/>
            <xsl:if test='$css-file'>
              <link rel='stylesheet' href='{$css-file}' type='text/css'/>
            </xsl:if>
          </head>
          <body>
            <xsl:apply-templates/>
          </body>
        </html>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- default behavior for all modes: traverse elements only -->
  <xsl:template match="*" mode="HEAD">
    <xsl:apply-templates select="*" mode="HEAD"/>
  </xsl:template>

  <xsl:template match="*" mode="TOC">
    <xsl:apply-templates select="*" mode="TOC"/>
  </xsl:template>

  <xsl:template match="*">
    <xsl:comment>
      <xsl:text>Unknown element '</xsl:text>
      <xsl:value-of select="name()"/>
      <xsl:text>'</xsl:text>
      <xsl:if test="namespace-uri()">
        <xsl:value-of select="concat(' (namespace: ',namespace-uri(),')')"/>
      </xsl:if>
    </xsl:comment>
    <xsl:message terminate="no">
      <xsl:text>Unknown element '</xsl:text>
      <xsl:value-of select="name()"/>
      <xsl:text>'</xsl:text>
      <xsl:if test="namespace-uri()">
        <xsl:value-of select="concat(' (namespace: ',namespace-uri(),')')"/>
      </xsl:if>
      <xsl:text> - Please add a template for it to the stylesheet!</xsl:text>
    </xsl:message>
    <xsl:apply-templates select="*"/>
  </xsl:template>

  <!-- abort if it doesn't look like Simplified DocBook -->
  <xsl:template match="/*[name()!='article']">
    <xsl:message terminate="yes">The source tree does not appear to be a Simplified DocBook document.&#10;'article' (in no namespace) must be the document element.&#10;</xsl:message>
  </xsl:template>

  <!-- attempt to copy id attributes verbatim -->
  <xsl:template match="@id">
    <xsl:copy/>
  </xsl:template>

  <!-- ignore other attributes -->
  <xsl:template match="@*" priority="-1"/>

  <!-- ================================================================== -->
  <!--
     article ::=
     ((title,subtitle?,titleabbrev?)?,articleinfo?,
      (((itemizedlist|orderedlist|variablelist|note|literallayout|
         programlisting|para|blockquote|mediaobject|informaltable|example|
         figure|table|sidebar|abstract|authorblurb|epigraph)+,section*)|
       section+),
      ((appendix)|bibliography)*)

     attributes:
       class :: = faq|journalarticle|productsheet|
               specification|techreport|whitepaper
       status :: = CDATA (e.g., draft|final)
   -->

  <xsl:template match="article[@status='draft']" mode="HEAD">
    <xsl:apply-templates select="*" mode="HEAD"/>
    <style type="text/css">
      <xsl:comment>&#10;body { background: #EEE fixed url('draft.gif') }&#10;</xsl:comment>
    </style>
  </xsl:template>

  <xsl:template match="article" mode="TOC">
    <div class="toc">
      <h2>Table Of Contents</h2>
      <xsl:apply-templates select="section" mode="TOC"/>
      <xsl:if test="appendix">
        <h3 style="margin-left: 0.6em">
          <xsl:choose>
            <xsl:when test="appendix[2]">Appendices</xsl:when>
            <xsl:when test="appendix">Appendix</xsl:when>
          </xsl:choose>
        </h3>
        <xsl:apply-templates select="appendix" mode="TOC"/>
      </xsl:if>
    </div>
  </xsl:template>

  <xsl:template match="article">
    <xsl:if test="title|articleinfo">
      <div class="articleinfo">
        <xsl:apply-templates select="title|articleinfo"/>
      </div>
    </xsl:if>
    <xsl:if test="section and $top-level-html=1">
      <xsl:apply-templates select="." mode="TOC"/>
    </xsl:if>
    <hr/>
    <div class="article">
      <xsl:apply-templates select="@*|*[name()!='title' and name()!='articleinfo']"/>
    </div>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    title ::=
    (#PCDATA|footnoteref|xref|abbrev|acronym|citetitle|emphasis|
     footnote|phrase|quote|trademark|link|ulink|command|
     computeroutput|email|filename|literal|option|replaceable|
     systemitem|userinput|author|corpauthor|othercredit|revhistory|
     inlinemediaobject)*

    ...but we will assume the text content of the element is all we need.

    These elements contain title:
    abstract, appendix, article, articleinfo, authorblurb, bibliodiv,
    bibliography, bibliomixed, bibliomset, blockquote, example, figure,
    itemizedlist, legalnotice, note, objectinfo, orderedlist, section,
    sectioninfo, sidebar, table, variablelist.

  -->

  <!-- ignore most titles -->
  <xsl:template match="title" priority="-1"/>

  <xsl:template match="article/title" mode="HEAD">
    <xsl:call-template name="HEAD-article-title"/>
  </xsl:template>

  <xsl:template match="articleinfo/title" mode="HEAD">
    <xsl:choose>
      <xsl:when test="not(/article/title)">
        <xsl:call-template name="HEAD-article-title"/>
      </xsl:when>
      <xsl:when test="/article/title and /article/title != .">
        <xsl:message terminate="no">DocBook error: article/title and articleinfo/title differ. Ignoring articleinfo/title.</xsl:message>
      </xsl:when>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="HEAD-article-title">
    <title>
      <xsl:value-of select="normalize-space()"/>
    </title>
  </xsl:template>

  <xsl:template match="article/title">
    <xsl:call-template name="article-title"/>
  </xsl:template>

  <xsl:template match="articleinfo/title">
    <xsl:if test="not(/article/title)">
        <xsl:call-template name="article-title"/>
    </xsl:if>
  </xsl:template>

  <xsl:template name="article-title">
    <div class="article-title">
      <h1 class="title">
        <xsl:apply-templates select="@*|node()"/>
      </h1>
      <xsl:if test="subtitle">
        <h2 class="subtitle">
          <xsl:value-of select="normalize-space(following-sibling::subtitle)"/>
        </h2>
      </xsl:if>
    </div>
  </xsl:template>

  <!-- ================================================================== -->

  <!--
    articleinfo ::=
    ((mediaobject|legalnotice|subjectset|keywordset|abbrev|abstract|
      author|authorgroup|bibliomisc|copyright|corpauthor|date|edition|
      editor|issuenum|othercredit|pubdate|publishername|releaseinfo|
      revhistory|subtitle|title|titleabbrev|volumenum|citetitle|
      honorific|firstname|surname|lineage|othername|affiliation|
      authorblurb)+)
  -->
  <xsl:template match="articleinfo" mode="HEAD">
    <xsl:if test="author|authorgroup/author">
      <meta name="author">
        <xsl:attribute name="content">
          <xsl:apply-templates select="author|authorgroup/author" mode="HEAD"/>
        </xsl:attribute>
      </meta>
    </xsl:if>
    <xsl:apply-templates select="*[not(starts-with(local-name(),'author'))]" mode="HEAD"/>
  </xsl:template>

  <xsl:template match="articleinfo" mode="TOC"/>

  <xsl:template match="articleinfo">
    <xsl:if test="author|authorgroup/author|othercredit|authorgroup/othercredit|revhistory">
      <dl>
        <xsl:apply-templates select="revhistory"/>
        <xsl:if test="author|authorgroup/author">
          <dt>
            <xsl:text>Principal author</xsl:text>
            <xsl:if test="count(author|authorgroup/author) &gt; 1">s</xsl:if>
            <xsl:text>: </xsl:text>
          </dt>
          <xsl:apply-templates select="author|authorgroup/author">
            <xsl:with-param name="include-orgname" select="true()"/>
          </xsl:apply-templates>
        </xsl:if>
        <xsl:if test="othercredit|authorgroup/othercredit">
          <dt>
            <xsl:choose>
              <xsl:when test="author|authorgroup/author">Add'l contributors: </xsl:when>
              <xsl:otherwise>Contributors: </xsl:otherwise>
            </xsl:choose>
          </dt>
          <xsl:apply-templates select="othercredit|authorgroup/othercredit">
            <xsl:with-param name="include-orgname" select="true()"/>
          </xsl:apply-templates>
        </xsl:if>
      </dl>
    </xsl:if>
    <xsl:apply-templates select="*[local-name()!='revhistory' and not(starts-with(local-name(),'author') or starts-with(local-name(),'othercredit'))]"/>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    revhistory ::= (revision+)
    revision ::=
    (revnumber,date,authorinitials*,
     (revremark|revdescription)?)
  -->
  <xsl:template match="revhistory">
    <dt>This version:</dt>
    <dd>
      <!-- we will assume newest/current revision is last -->
      <xsl:call-template name="create-rev-string">
        <xsl:with-param name="rev" select="revision[last()]"/>
      </xsl:call-template>
    </dd>
    <xsl:if test="$show-rev-history and revision[2]">
      <dt>Previous versions:</dt>
      <xsl:for-each select="revision[position()!=last()]">
        <xsl:sort order="descending"/>
        <dd>
          <xsl:call-template name="create-rev-string">
            <xsl:with-param name="rev" select="."/>
          </xsl:call-template>
        </dd>
      </xsl:for-each>
    </xsl:if>
  </xsl:template>

  <xsl:template name="create-rev-string">
    <xsl:param name="rev" select="/.."/>
    <xsl:variable name="rev-number" select="normalize-space($rev/revnumber)"/>
    <xsl:variable name="rev-date" select="normalize-space($rev/date)"/>
    <xsl:choose>
      <xsl:when test="$rev-number and $rev-date">
        <xsl:value-of select="concat('Revision ',$rev-number,' (',$rev-date,')')"/>
      </xsl:when>
      <xsl:when test="$rev-number">
        <xsl:value-of select="concat('Revision ',$rev-number)"/>
      </xsl:when>
      <xsl:when test="$rev-date">
        <xsl:value-of select="concat($rev-date,' Revision')"/>
        <xsl:variable name="rev-within-date" select="count($rev/../revision[date=$rev-date])"/>
        <xsl:if test="$rev-within-date -1">
          <xsl:value-of select="concat(' (Update #',$rev-within-date,')')"/>
        </xsl:if>
      </xsl:when>
      <xsl:otherwise>Unknown revision number</xsl:otherwise>
    </xsl:choose>
    <xsl:if test="$show-rev-remarks and normalize-space($rev/revremark)">
      <xsl:text>: </xsl:text>
      <span class="revremark">
        <xsl:value-of select="$rev/revremark"/>
      </span>
    </xsl:if>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    author ::= ((honorific|firstname|surname|lineage|othername|
                 affiliation|authorblurb)+)
    othercredit ::= ((honorific|firstname|surname|lineage|othername|
                      affiliation|authorblurb)+)
  -->

  <xsl:template match="author|othercredit" mode="HEAD">
    <xsl:param name="include-orgname"/>
    <xsl:call-template name="list-authors">
      <xsl:with-param name="include-orgname" select="$include-orgname"/>
      <xsl:with-param name="separator" select="', '"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="author|othercredit">
    <xsl:param name="include-orgname"/>
    <dd>
      <xsl:call-template name="list-authors">
        <xsl:with-param name="include-orgname" select="$include-orgname"/>
        <xsl:with-param name="separator"/>
      </xsl:call-template>
    </dd>
  </xsl:template>

  <xsl:template name="list-authors">
    <xsl:param name="include-orgname"/>
    <xsl:param name="separator" select="'; '"/>
    <xsl:param name="wrapper"/>
    <xsl:if test="normalize-space(honorific)">
      <xsl:value-of select="concat(honorific,' ')"/>
    </xsl:if>
    <xsl:if test="normalize-space(firstname)">
      <xsl:value-of select="concat(firstname,' ')"/>
    </xsl:if>
    <xsl:if test="normalize-space(othername[@role='middle'])">
      <xsl:value-of select="concat(othername[@role='middle'],' ')"/>
    </xsl:if>
    <xsl:value-of select="surname"/>
    <xsl:if test="normalize-space(lineage)">
      <xsl:value-of select="concat(' ',lineage)"/>
    </xsl:if>
    <xsl:if test="$include-orgname and normalize-space(affiliation/orgname)">
      <xsl:text> </xsl:text>
      <span class="orgname">
        <xsl:value-of select="concat('(',affiliation/orgname,')')"/>
      </span>
    </xsl:if>
    <xsl:if test="position() != last()">
      <xsl:copy-of select="$separator"/>
    </xsl:if>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    keywordset ::= (keyword+)
    keyword ::= (#PCDATA)
  -->
  <xsl:template match="articleinfo/keywordset" mode="HEAD">
    <meta name="keywords">
      <xsl:attribute name="content">
        <xsl:for-each select="keyword">
          <xsl:value-of select="translate(.,',',';')"/>
          <xsl:if test="position()!=last()">, </xsl:if>
        </xsl:for-each>
      </xsl:attribute>
    </meta>
  </xsl:template>

  <xsl:template match="articleinfo/keywordset"/>

  <!-- ================================================================== -->
  <!--
    abstract ::= (title?,(para)+)
  -->

  <xsl:template match="articleinfo/abstract|article/abstract" mode="HEAD">
    <meta name="description" content="{normalize-space(para)}"/>
  </xsl:template>

  <xsl:template match="articleinfo/abstract|article/abstract">
    <div class="abstract">
      <xsl:apply-templates select="@*"/>
      <h2>
        <xsl:choose>
          <xsl:when test="title">
            <xsl:value-of select="title"/>
          </xsl:when>
          <xsl:otherwise>Abstract</xsl:otherwise>
        </xsl:choose>
      </h2>
      <xsl:apply-templates select="para"/>
    </div>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    para ::=
    (#PCDATA|footnoteref|xref|abbrev|acronym|citetitle|emphasis|
     footnote|phrase|quote|trademark|link|ulink|command|
     computeroutput|email|filename|literal|option|replaceable|
     systemitem|userinput|inlinemediaobject)*
  -->
  <xsl:template match="para">
    <p>
      <xsl:apply-templates select="@*|node()"/>
    </p>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    trademark ::=
    (#PCDATA|link|ulink|command|computeroutput|email|filename|literal|
     option|replaceable|systemitem|userinput|inlinemediaobject|
     emphasis)*

    attributes: class = (copyright|registered|service|trade); default: trade
  -->
   <xsl:template match="trademark">
    <xsl:if test="@class='copyright'">&#169;&#160;</xsl:if>
    <xsl:apply-templates/>
    <xsl:choose>
      <xsl:when test="@class='registered'"><sup style="font-size: 75%; vertical-align: top">&#174;</sup></xsl:when>
      <xsl:when test="@class='service'"><sup style="font-size: 75%; vertical-align: top">&#8480;</sup></xsl:when>
      <xsl:when test="@class='copyright'"/> <!-- avoids falling into otherwise clause -->
      <xsl:otherwise><sup style="font-size: 75%; vertical-align: top">&#8482;</sup></xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    link ::=
    (#PCDATA|footnoteref|xref|abbrev|acronym|citetitle|emphasis|
     footnote|phrase|quote|trademark|link|ulink|command|
     computeroutput|email|filename|literal|option|replaceable|
     systemitem|userinput|inlinemediaobject)*

    attributes: linkend=IDREF (required; points to some 'id' attr)
                endterm=IDREF (points to 'id' attr of element with text
                to use for link text, if no content provided in this one)
                type=CDATA (app-specific customization)
  -->
  <xsl:key name="element-by-id" match="*" use="@id"/>
  <xsl:template match="link">
    <xsl:choose>
      <!-- we have something to link to -->
      <xsl:when test="key('element-by-id',@linkend)">
        <a href="#{@linkend}">
          <xsl:choose>
            <xsl:when test="normalize-space()">
              <xsl:value-of select="."/>
            </xsl:when>
            <xsl:when test="normalize-space(key('element-by-id',@endterm))">
              <xsl:value-of select="key('element-by-id',@endterm)"/>
            </xsl:when>
            <xsl:otherwise>[ link ]</xsl:otherwise>
          </xsl:choose>
        </a>
      </xsl:when>
      <xsl:otherwise>
        <xsl:message terminate="no">'link' element referenced unknown id '<xsl:value-of select="@linkend"/>'.</xsl:message>
        <xsl:comment>this text was supposed to be linked; see processor message for details</xsl:comment>
        <xsl:apply-templates/>
        <xsl:comment>end linked text</xsl:comment>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    ulink ::=
    (#PCDATA|footnoteref|xref|abbrev|acronym|citetitle|emphasis|
     footnote|phrase|quote|trademark|link|ulink|command|
     computeroutput|email|filename|literal|option|replaceable|
     systemitem|userinput|inlinemediaobject)*

    attributes: url=CDATA; type=CDATA
  -->
  <xsl:template match="ulink[@url]">
    <a href="{@url}">
      <xsl:apply-templates select="@*"/>
      <xsl:if test="@type='off-site'">
        <xsl:attribute name="target">_new</xsl:attribute>
      </xsl:if>
      <xsl:choose>
        <xsl:when test="normalize-space()">
          <xsl:apply-templates/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:attribute name="style">font-family: "Andale Mono","Lucida Console",monospace</xsl:attribute>
          <xsl:value-of select="@url"/>
        </xsl:otherwise>
      </xsl:choose>
    </a>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    section ::=
    (sectioninfo?,
     (title,subtitle?,titleabbrev?),
     (((itemizedlist|orderedlist|variablelist|note|literallayout|
        programlisting|para|blockquote|mediaobject|informaltable|
        example|figure|table|sidebar|abstract|authorblurb|epigraph)+,
       section*)|
      section+))

    appendix ::=
    ((title,subtitle?,titleabbrev?),
     (((itemizedlist|orderedlist|variablelist|note|literallayout|
        programlisting|para|blockquote|mediaobject|informaltable|
        example|figure|table|sidebar|abstract|authorblurb|epigraph)+,
       section*)|
      section+))

    attributes: status=CDATA (e.g., draft|final)
                label=CDATA (identifier string if auto-generated one not OK)
  -->
  <xsl:template match="section|appendix" mode="TOC">
    <xsl:if test="count(ancestor::section) &lt; $toc-depth">
      <p style="display: inline; padding-left: {count(ancestor::section)+1}em">
        <xsl:if test="$number-sections and local-name()='section'">
          <xsl:number level="multiple" format="1.1 "/>
        </xsl:if>
        <xsl:if test="$number-sections and local-name()='appendix'">
          <xsl:number level="multiple" format="A.1 "/>
        </xsl:if>
        <a>
          <xsl:choose>
            <xsl:when test="normalize-space(@label)">
              <xsl:attribute name="href">
                <xsl:value-of select="concat('#',translate(normalize-space(@label),' ','-'))"/>
              </xsl:attribute>
            </xsl:when>
            <xsl:otherwise>
              <xsl:attribute name="href">
                <xsl:value-of select="concat('#',generate-id())"/>
              </xsl:attribute>
            </xsl:otherwise>
          </xsl:choose>
          <xsl:choose>
            <xsl:when test="title">
              <xsl:value-of select="title"/>
            </xsl:when>
            <xsl:when test="@label">
              <xsl:value-of select="@label"/>
            </xsl:when>
            <xsl:otherwise>untitled section</xsl:otherwise>
          </xsl:choose>
        </a>
        <br/>
      </p>
      <xsl:apply-templates select="section" mode="TOC"/>
    </xsl:if>
  </xsl:template>

  <xsl:template match="section|appendix">
    <div class="{local-name()}">
      <xsl:apply-templates select="@*"/>
      <xsl:variable name="section-depth" select="count(ancestor::section|ancestor::appendix)+1"/>
      <xsl:variable name="heading-level">
        <xsl:choose>
          <xsl:when test="$section-depth &gt; 6">6</xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$section-depth"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      <a>
        <xsl:choose>
          <xsl:when test="normalize-space(@label)">
            <xsl:attribute name="name">
              <xsl:value-of select="translate(normalize-space(@label),' ','-')"/>
            </xsl:attribute>
          </xsl:when>
          <xsl:otherwise>
            <xsl:attribute name="name">
              <xsl:value-of select="generate-id()"/>
            </xsl:attribute>
          </xsl:otherwise>
        </xsl:choose>
        <xsl:element name="h{$heading-level}">
          <xsl:if test="title/@id">
            <xsl:copy-of select="title/@id"/>
          </xsl:if>
          <xsl:if test="$heading-level=1">
            <xsl:attribute name="class">section-title</xsl:attribute>
          </xsl:if>
          <xsl:if test="$number-sections">
            <span class="section-number">
              <xsl:if test="local-name()='section'">
                <xsl:number level="multiple" format="1.1 "/>
              </xsl:if>
              <xsl:if test="local-name()='appendix'">
                <xsl:number level="multiple" format="A.1 "/>
              </xsl:if>
            </span>
          </xsl:if>
          <xsl:choose>
            <xsl:when test="title">
              <xsl:value-of select="title"/>
              <xsl:if test="subtitle">
                <br/>
                <span class="section-subtitle">
                  <xsl:value-of select="subtitle"/>
                </span>
              </xsl:if>
            </xsl:when>
            <xsl:when test="@label">
              <xsl:value-of select="@label"/>
            </xsl:when>
            <xsl:otherwise>untitled section</xsl:otherwise>
          </xsl:choose>
        </xsl:element>
      </a>
      <xsl:apply-templates select="*"/>
    </div>
  </xsl:template>

  <!-- easier than excluding these from the apply-templates above -->
  <xsl:template match="section/title|section/subtitle|appendix/title|appendix/subtitle"/>
  <xsl:template match="titleabbrev"/>
  <xsl:template match="sectioninfo"/>

  <!-- ================================================================== -->
  <!--
    itemizedlist ::= ((title,titleabbrev?)?,listitem+)
      attributes: mark=CDATA (keyword for item marker type, e.g., bullet)
                  spacing=compact|normal (vertical spacing)
  -->
  <xsl:template match="itemizedlist">
    <ul>
      <xsl:apply-templates select="@*"/>
      <xsl:attribute name="style">
        <xsl:choose>
          <xsl:when test="@mark='circle'">list-style-type: circle;</xsl:when>
          <xsl:when test="@mark='square'">list-style-type: square;</xsl:when>
          <xsl:otherwise>list-style-type: disc;</xsl:otherwise>
        </xsl:choose>
        <xsl:choose>
          <xsl:when test="@spacing='compact'">list-style-position: inside;</xsl:when>
          <xsl:otherwise>list-style-position: outside;</xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <xsl:apply-templates select="listitem"/>
    </ul>
  </xsl:template>

  <xsl:template match="itemizedlist/@spacing[.='compact']|orderedlist/@spacing[.='compact']">
    <!-- expected to be added to the <ul> or <ol> -->
    <xsl:attribute name="class">compact</xsl:attribute>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    orderedlist ::= ((title,titleabbrev?)?,listitem+)
      attributes: spacing=compact|normal (vertical spacing)
                  continuation=continues|restarts (default: restarts)
                  numeration=arabic|loweralpha|lowerroman|upperalpha|
                             upperroman (arabic assumed but no default)
                  inheritnum=ignore|inherit (default: ignore)
  -->
  <xsl:template match="orderedlist">
    <ol>
      <xsl:apply-templates select="@*"/>
      <xsl:attribute name="style">
        <xsl:choose>
          <xsl:when test="@numeration='loweralpha'">list-style-type: lower-alpha;</xsl:when>
          <xsl:when test="@numeration='upperalpha'">list-style-type: upper-alpha;</xsl:when>
          <xsl:when test="@numeration='lowerroman'">list-style-type: lower-roman;</xsl:when>
          <xsl:when test="@numeration='upperroman'">list-style-type: upper-roman;</xsl:when>
          <xsl:otherwise>list-style-type: decimal;</xsl:otherwise>
        </xsl:choose>
        <xsl:choose>
          <xsl:when test="@spacing='compact'">list-style-position: inside;</xsl:when>
          <xsl:otherwise>list-style-position: outside;</xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <xsl:apply-templates select="listitem"/>
    </ol>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    listitem ::=
    ((itemizedlist|orderedlist|variablelist|note|literallayout|
      programlisting|para|blockquote|mediaobject|informaltable|
      example|figure|table|sidebar|abstract|authorblurb|epigraph)+)
  -->
  <xsl:template match="listitem">
    <li>
      <xsl:if test="parent::*/@spacing='compact'">
        <xsl:attribute name="style">margin-top: 0; margin-bottom: 0</xsl:attribute>
      </xsl:if>
      <!-- to support orderedlist with continuation='continues', figure
           out a way here to create a 'value' attribute on the first
           listitem, with the right number to start on. -->
      <xsl:apply-templates select="*"/>
    </li>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    emphasis ::=
    (#PCDATA|footnoteref|xref|abbrev|acronym|citetitle|emphasis|
     footnote|phrase|quote|trademark|link|ulink|command|
     computeroutput|email|filename|literal|option|replaceable|
     systemitem|userinput|inlinemediaobject)*
  -->
  <xsl:template match="emphasis">
    <xsl:choose>
      <xsl:when test="@role='bold' or @role='strong'">
        <strong>
          <xsl:apply-templates/>
        </strong>
      </xsl:when>
      <xsl:otherwise>
        <em>
          <xsl:apply-templates/>
        </em>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    programlisting ::=
    (#PCDATA|footnoteref|xref|abbrev|acronym|citetitle|emphasis|
     footnote|phrase|quote|trademark|link|ulink|command|
     computeroutput|email|filename|literal|option|replaceable|
     systemitem|userinput|inlinemediaobject|lineannotation)*
      attributes: linenumbering=numbered|unnumbered
                  width=CDATA
  -->
  <xsl:template match="programlisting">
    <div>
      <xsl:apply-templates select="@*"/>
      <xsl:attribute name="class">
        <xsl:choose>
          <xsl:when test="@role='sample.IO'">screen</xsl:when>
          <xsl:otherwise>programlisting</xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <!-- pre necessary because CSS1's white-space:pre can be ignored -->
      <pre>
        <xsl:apply-templates select="@*|node()"/>
      </pre>
    </div>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    computeroutput ::=
    (#PCDATA|link|ulink|command|computeroutput|email|filename|literal|
     option|replaceable|systemitem|userinput|inlinemediaobject)*
      attributes: moreinfo=none|refentry (default: none)
  -->
  <xsl:template match="computeroutput">
    <span class="computeroutput">
      <xsl:apply-templates/>
    </span>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    userinput ::=
    (#PCDATA|link|ulink|command|computeroutput|email|filename|literal|
     option|replaceable|systemitem|userinput|inlinemediaobject)*
     attributes: moreinfo=none|refentry (default: none)
  -->
  <xsl:template match="userinput">
    <span class="userinput">
      <xsl:apply-templates/>
    </span>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    literal ::=
    (#PCDATA|link|ulink|command|computeroutput|email|filename|literal|
     option|replaceable|systemitem|userinput|inlinemediaobject)*
     attributes: moreinfo=none|refentry (default: none)
  -->
  <xsl:template match="literal">
    <span class="literal">
      <xsl:apply-templates/>
    </span>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    legalnotice ::=
    (title?,
     (itemizedlist|orderedlist|variablelist|note|literallayout|
      programlisting|para|blockquote)+)
  -->
  <xsl:template match="legalnotice">
    <div class="legalnotice">
      <xsl:apply-templates select="@*|*[local-name()!='title']"/>
    </div>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    figure ::=
    ((title,titleabbrev?),
     (literallayout|programlisting|blockquote|mediaobject|
      informaltable|link|ulink)+)
      attributes: float (default: "0")
                  pgwide
                  label
  -->
  <xsl:template match="figure">
    <div class="figure">
      <xsl:apply-templates select="@*"/>
      <xsl:choose>
        <!-- do HTML/CSS allow for pgwide support? -->
        <xsl:when test="@float!='0'">
          <xsl:attribute name="style">display: inline</xsl:attribute>
        </xsl:when>
        <xsl:otherwise>
          <xsl:attribute name="style">display: block; float: none</xsl:attribute>
        </xsl:otherwise>
      </xsl:choose>
      <a>
        <xsl:choose>
          <xsl:when test="normalize-space(@label)">
            <xsl:attribute name="name">
              <xsl:value-of select="translate(@label,' ','-')"/>
            </xsl:attribute>
          </xsl:when>
          <xsl:otherwise>
            <xsl:attribute name="name">
              <xsl:value-of select="generate-id()"/>
            </xsl:attribute>
          </xsl:otherwise>
        </xsl:choose>
        <p class="figure-title">
          <span style="font-weight: bold">
            <xsl:text>Figure </xsl:text>
            <xsl:number level="any" format="1.1 "/>
          </span>
          <xsl:text> &#8212; </xsl:text>
          <xsl:value-of select="title"/>
        </p>
      </a>
      <xsl:apply-templates select="*[local-name()!='title']"/>
    </div>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    mediaobject ::=
    (objectinfo?,
     (videoobject|audioobject|imageobject),
     (videoobject|audioobject|imageobject|textobject)*,
     caption?)
    "If possible, the processing system should use the content of the
    first object within the MediaObject. If the first object cannot be
    used, the remaining objects should be considered in the order that
    they occur."
  -->
  <xsl:template match="mediaobject">
    <!-- for now we only support imageobject -->
    <xsl:apply-templates select="imageobject[1]"/>
  </xsl:template>

  <!-- ================================================================== -->
  <!--
    imageobject ::=
    (objectinfo?,imagedata)

    imagedata ::=
    EMPTY
    attributes: fileref
                width
                depth
                scale
                scalefit
                format=BMP|GIF|JPEG|PNG|etc. (see the docs)
                align=center|left|right
                entityref
                srccredit
  -->
  <xsl:template match="imageobject">
    <xsl:if test="imagedata/@fileref">
      <xsl:variable name="data" select="imagedata[1]"/>
      <xsl:if test="$data/@fileref">
        <xsl:choose>
          <xsl:when test="$data/@align='center'">
            <div style="text-align: center">
              <img src="{$data/@fileref}">
                <xsl:apply-templates select="@id"/> <!-- add ID, if any -->
                <xsl:apply-templates select="$data/@*"/>
              </img>
            </div>
          </xsl:when>
          <xsl:otherwise>
            <img src="{$data/@fileref}">
              <xsl:apply-templates select="@id"/>
              <xsl:apply-templates select="$data/@*"/>
            </img>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:if>
    </xsl:if>
  </xsl:template>

  <xsl:template match="imagedata/@width">
    <xsl:attribute name="width">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="imagedata/@depth">
    <xsl:attribute name="height">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="imagedata/@align[.!='center']">
    <xsl:attribute name="align">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>

  <!-- FIXME: support other attributes -->

  <!-- ================================================================== -->

</xsl:stylesheet>
