<?xml version='1.0' encoding='UTF-8'?><!-- -*- indent-tabs-mode: nil -*- -->
<!--
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option) any
later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.

You should have received a copy of the GNU Lesser General Public License
along with this program; see the file COPYING.LGPL.  If not, see <http://www.gnu.org/licenses/>.
-->


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:set="http://exslt.org/sets"
                xmlns:str="http://exslt.org/strings"
                xmlns="http://www.w3.org/1999/xhtml"
                exclude-result-prefixes="db set str"
                version="1.0">

<!--!!==========================================================================
DocBook to HTML - Command Synopses
@revision[version=1.0 date=2011-05-16 status=final]

This module contains templates to process DocBook command synopsis elements.
-->


<!-- == Matched Templates == -->

<!-- = arg = -->
<xsl:template match="arg | db:arg">
  <xsl:param name="sepchar">
    <xsl:choose>
      <xsl:when test="ancestor::cmdsynopsis[1][@sepchar]">
        <xsl:value-of select="ancestor::cmdsynopsis[1]/@sepchar"/>
      </xsl:when>
      <xsl:when test="ancestor::db:cmdsynopsis[1][@sepchar]">
        <xsl:value-of select="ancestor::db:cmdsynopsis[1]/@sepchar"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text> </xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:param>
  <xsl:param name="choice">
    <xsl:choose>
      <xsl:when test="@choice">
        <xsl:value-of select="@choice"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="'opt'"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:param>
  <xsl:param name="rep">
    <xsl:choose>
      <xsl:when test="@rep">
        <xsl:value-of select="@rep"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="'norepeat'"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:param>

  <span class="arg-punc">
    <xsl:choose>
      <xsl:when test="$choice = 'plain'"/>
      <xsl:when test="$choice = 'req'">
        <xsl:text>{</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>[</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <span>
      <xsl:call-template name="html.class.attr">
        <xsl:with-param name="class" select="'arg'"/>
      </xsl:call-template>
      <xsl:for-each select="node()">
        <xsl:choose>
          <xsl:when test="self::sbr or self::db:sbr">
            <xsl:text>&#x000A;</xsl:text>
            <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode"
                                 select="ancestor::cmdsynopsis[1] |
                                         ancestor::db:cmdsynopsis[1]">
              <xsl:with-param name="sbr" select="."/>
              <xsl:with-param name="sepchar" select="$sepchar"/>
            </xsl:apply-templates>
          </xsl:when>
          <xsl:otherwise>
            <xsl:apply-templates select=".">
              <xsl:with-param name="sepchar" select="$sepchar"/>
            </xsl:apply-templates>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </span>
    <xsl:if test="$rep = 'repeat'">
      <xsl:text>...</xsl:text>
    </xsl:if>
    <xsl:choose>
      <xsl:when test="$choice = 'plain'"/>
      <xsl:when test="$choice = 'req'">
        <xsl:text>}</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>]</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </span>
</xsl:template>

<!-- = cmdsynopsis = -->
<xsl:template match="cmdsynopsis | db:cmdsynopsis">
  <xsl:param name="sepchar">
    <xsl:choose>
      <xsl:when test="@sepchar">
        <xsl:value-of select="@sepchar"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text> </xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:param>
  <xsl:variable name="if"><xsl:call-template name="db.profile.test"/></xsl:variable>
  <xsl:if test="$if != ''">
  <div>
    <xsl:call-template name="html.class.attr">
      <xsl:with-param name="class" select="'synopsis cmdsynopsis'"/>
    </xsl:call-template>
    <xsl:call-template name="html.lang.attrs"/>
    <xsl:call-template name="db2html.anchor"/>
    <pre class="contents cmdsynopsis">
      <xsl:for-each select="command    | arg    | group    | sbr |
                            db:command | db:arg | db:group | db:sbr">
        <xsl:choose>
          <xsl:when test="position() = 1"/>
          <xsl:when test="self::sbr">
            <xsl:text>&#x000A;</xsl:text>
            <xsl:value-of select="str:padding(string-length(preceding-sibling::command[1]), ' ')"/>
          </xsl:when>
          <xsl:when test="self::db:sbr">
            <xsl:text>&#x000A;</xsl:text>
            <xsl:value-of select="str:padding(string-length(preceding-sibling::db:command[1]), ' ')"/>
          </xsl:when>
          <xsl:when test="self::command or self::db:command">
            <xsl:text>&#x000A;</xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$sepchar"/>
          </xsl:otherwise>
        </xsl:choose>
        <xsl:apply-templates select=".">
          <xsl:with-param name="sepchar" select="$sepchar"/>
        </xsl:apply-templates>
      </xsl:for-each>
      <xsl:apply-templates select="synopfragment | db:synopfragment">
        <xsl:with-param name="sepchar" select="$sepchar"/>
      </xsl:apply-templates>
    </pre>
  </div>
  </xsl:if>
</xsl:template>

<!-- = group = -->
<xsl:template match="group | db:group">
  <xsl:param name="sepchar">
    <xsl:choose>
      <xsl:when test="ancestor::cmdsynopsis[1][@sepchar]">
        <xsl:value-of select="ancestor::cmdsynopsis[1]/@sepchar"/>
      </xsl:when>
      <xsl:when test="ancestor::db:cmdsynopsis[1][@sepchar]">
        <xsl:value-of select="ancestor::db:cmdsynopsis[1]/@sepchar"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text> </xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:param>
  <xsl:param name="choice">
    <xsl:choose>
      <xsl:when test="@choice">
        <xsl:value-of select="@choice"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="'opt'"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:param>
  <xsl:param name="rep">
    <xsl:choose>
      <xsl:when test="@rep">
        <xsl:value-of select="@rep"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="'norepeat'"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:param>
  <xsl:variable name="padding">
    <xsl:if test="sbr or db:sbr">
      <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode"
                           select="ancestor::cmdsynopsis[1] |
                                   ancestor::db:cmdsynopsis[1]">
        <xsl:with-param name="sbr" select="sbr[1] | db:sbr[1]"/>
        <xsl:with-param name="sepchar" select="$sepchar"/>
      </xsl:apply-templates>
    </xsl:if>
  </xsl:variable>

  <span class="group-punc">
    <xsl:choose>
      <xsl:when test="$choice = 'plain'">
        <xsl:text>(</xsl:text>
      </xsl:when>
      <xsl:when test="$choice = 'req'">
        <xsl:text>{</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>[</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <span>
      <xsl:call-template name="html.class.attr">
        <xsl:with-param name="class" select="'group'"/>
      </xsl:call-template>
      <xsl:for-each select="*">
        <xsl:choose>
          <xsl:when test="self::sbr or self::db:sbr">
            <xsl:text>&#x000A;</xsl:text>
            <xsl:value-of select="$padding"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:apply-templates select=".">
              <xsl:with-param name="sepchar" select="$sepchar"/>
            </xsl:apply-templates>
            <xsl:if test="position() != last()">
              <xsl:value-of select="concat($sepchar, '|', $sepchar)"/>
            </xsl:if>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </span>
    <xsl:choose>
      <xsl:when test="$choice = 'plain'">
        <xsl:text>)</xsl:text>
      </xsl:when>
      <xsl:when test="$choice = 'req'">
        <xsl:text>}</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>]</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:if test="$rep = 'repeat'">
      <xsl:text>...</xsl:text>
    </xsl:if>
  </span>
</xsl:template>

<!-- = synopfragment = -->
<xsl:template match="synopfragment | db:synopfragment">
  <xsl:param name="sepchar">
    <xsl:choose>
      <xsl:when test="ancestor::cmdsynopsis[1][@sepchar]">
        <xsl:value-of select="ancestor::cmdsynopsis[1]/@sepchar"/>
      </xsl:when>
      <xsl:when test="ancestor::db:cmdsynopsis[1][@sepchar]">
        <xsl:value-of select="ancestor::db:cmdsynopsis[1]/@sepchar"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text> </xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:param>
  <div>
    <xsl:call-template name="html.class.attr">
      <xsl:with-param name="class" select="'synopfragment'"/>
    </xsl:call-template>
    <xsl:call-template name="db2html.anchor"/>
    <xsl:variable name="count" select="count(preceding-sibling::synopfragment) +
                                       count(preceding-sibling::db:synopfragment)"/>
    <xsl:variable name="countlast" select="count(preceding-sibling::synopfragment) +
                                           count(following-sibling::synopfragment) +
                                           count(preceding-sibling::db:synopfragment) +
                                           count(following-sibling::db:synopfragment)"/>
    <span class="co">
      <xsl:text> </xsl:text>
      <xsl:value-of select="$count + 1"/>
      <xsl:text> </xsl:text>
    </span>
    <xsl:value-of select="str:padding(string-length($countlast + 1) -
                                      string-length($count + 1) + 1, ' ')"/>
    <xsl:for-each select="*">
      <xsl:value-of select="$sepchar"/>
      <xsl:apply-templates select=".">
        <xsl:with-param name="sepchar" select="$sepchar"/>
      </xsl:apply-templates>
    </xsl:for-each>
  </div>
</xsl:template>

<!-- = synopfragmentref = -->
<xsl:template match="synopfragmentref | db:synopfragmentref">
  <xsl:for-each select="key('db.id.key', @linkend)[1]">
    <xsl:if test="self::synopfragment or self::db:synopfragment">
      <xsl:variable name="count" select="count(preceding-sibling::synopfragment) +
                                         count(preceding-sibling::db:synopfragment)"/>
      <span class="co">
        <xsl:text> </xsl:text>
        <xsl:value-of select="$count + 1"/>
        <xsl:text> </xsl:text>
      </span>
    </xsl:if>
  </xsl:for-each>
</xsl:template>


<!--%%==========================================================================
db2html.cmdsynopsis.sbr.padding.mode
Output padding for elements leading up to an `sbr` element.
@revision[version=1.0 date=2011-05-16 status=final]

[xsl:params]
$sbr: The `sbr` element to pad up to
$sepchar: The value of the `sepchar` attribute on the enclosing `cmdsynopsis`

When processed in this mode, elements output whitespace to the length of the
textual output they would normally produce.  This allows options to be aligned
when explicit line breaks are inserted with `sbr` elements.

To create the padding for a given `sbr` element, this mode is called on the
enclosing `cmdsynopsis` element, passing the `sbr` element.  When processed
in this mode, elements should only output padding for content the leads up to
the `sbr` element passed in the $sbr parameter.  When processing children
that don't contain the given `sbr` element, the $sbr parameter should be
set to `false()` for those children.  This avoids additional descendant
selectors, which are generally expensive to perform.
-->
<xsl:template mode="db2html.cmdsynopsis.sbr.padding.mode" match="node()">
  <xsl:value-of select="str:padding(string-length(.), ' ')"/>
</xsl:template>

<!-- = cmdsynopsis % db2html.cmdsynopsis.sbr.padding.mode = -->
<xsl:template mode="db2html.cmdsynopsis.sbr.padding.mode"
              match="cmdsynopsis | db:cmdsynopsis">
  <xsl:param name="sbr"/>
  <xsl:param name="sepchar"/>
  <xsl:variable name="child"
                select="*[$sbr and set:has-same-node(.|.//sbr|.//db:sbr, $sbr)][1]"/>
  <xsl:choose>
    <xsl:when test="$child/self::synopfragment |
                    $child/self::db:synopfragment">
      <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode" select="$child">
        <xsl:with-param name="sbr" select="$sbr"/>
        <xsl:with-param name="sepchar" select="$sepchar"/>
      </xsl:apply-templates>
    </xsl:when>
    <xsl:otherwise>
      <!-- Output padding for the preceding command -->
      <xsl:variable name="cmd" select="$child/preceding-sibling::command[1] |
                                       $child/preceding-sibling::db:command[1]"/>
      <xsl:value-of select="str:padding(string-length($cmd), ' ')"/>
      <xsl:value-of select="str:padding(string-length($sepchar), ' ')"/>
      <!-- Process all children that are between $cmd and $child, but 
           after any sbr elements between $cmd and $child -->
      <xsl:for-each select="$cmd/following-sibling::*
                              [set:has-same-node(following-sibling::*, $child)]
                              [not(set:has-same-node(. | following-sibling::sbr,
                                                     $child/preceding-sibling::sbr)) and
                               not(set:has-same-node(. | following-sibling::db:sbr,
                                                         $child/preceding-sibling::db:sbr))]">
        <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode" select=".">
          <xsl:with-param name="sbr" select="false()"/>
          <xsl:with-param name="sepchar" select="$sepchar"/>
        </xsl:apply-templates>
        <xsl:value-of select="str:padding(string-length($sepchar), ' ')"/>
      </xsl:for-each>
      <!-- And process $child itself -->
      <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode" select="$child">
        <xsl:with-param name="sbr" select="$sbr"/>
        <xsl:with-param name="sepchar" select="$sepchar"/>
      </xsl:apply-templates>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- = arg % db2html.cmdsynopsis.sbr.padding.mode = -->
<xsl:template mode="db2html.cmdsynopsis.sbr.padding.mode" match="arg | db:arg">
  <xsl:param name="sbr"/>
  <xsl:param name="sepchar"/>
  <xsl:if test="@choice != 'plain'">
    <xsl:text> </xsl:text>
  </xsl:if>
  <xsl:choose>
    <xsl:when test="not($sbr)">
      <!-- The sbr is outside this element.  The total width an arg is whatever
           comes before an sbr plus whatever comes after an sbr plus possible
           punctuation spacing. -->
      <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode"
                           select="node()[not(preceding-sibling::sbr) and
                                          not(preceding-sibling::db:sbr)]">
        <xsl:with-param name="sbr" select="$sbr"/>
        <xsl:with-param name="sepchar" select="$sepchar"/>
      </xsl:apply-templates>
      <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode"
                           select="(sbr | db:sbr)[last()]/following-sibling::node()">
        <xsl:with-param name="sbr" select="$sbr"/>
        <xsl:with-param name="sepchar" select="$sepchar"/>
      </xsl:apply-templates>
      <xsl:if test="@choice != 'plain'">
        <xsl:text> </xsl:text>
      </xsl:if>
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="child" select="*[set:has-same-node(.|.//sbr|.//db:sbr,
                                           $sbr)][1]"/>
      <!-- Process all children that are before $child, but after
           any sbr elements before $child.  Process any children
           before the initial sbr before $child, if it exists. -->
      <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode"
                           select="$child/preceding-sibling::sbr[last()]/preceding-sibling::node()
                                   | $child/preceding-sibling::db:sbr[last()]/preceding-sibling::node()
                                   | ($child/preceding-sibling::node())
                                       [not(set:has-same-node(. | following-sibling::sbr,
                                                              $child/preceding-sibling::sbr)) and
                                        not(set:has-same-node(. | following-sibling::db:sbr,
                                                              $child/preceding-sibling::db:sbr))]">
        <xsl:with-param name="sbr" select="false()"/>
        <xsl:with-param name="sepchar" select="$sepchar"/>
      </xsl:apply-templates>
      <!-- And process $child itself -->
      <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode" select="$child">
        <xsl:with-param name="sbr" select="$sbr"/>
        <xsl:with-param name="sepchar" select="$sepchar"/>
      </xsl:apply-templates>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- = group % db2html.cmdsynopsis.sbr.padding.mode = -->
<xsl:template mode="db2html.cmdsynopsis.sbr.padding.mode" match="group |
                                                                 db:group">
  <xsl:param name="sbr"/>
  <xsl:param name="sepchar"/>
  <xsl:text> </xsl:text>
  <xsl:choose>
    <xsl:when test="not($sbr)">
      <!-- The sbr is outside this element.  The total width a group is
           calculated by taking all children after the last sbr (or all
           children if there is no sbr), adding their widths, and adding
           width for joining punctuation for all but one of them.  Add
           to this punctuation spacing for the group as a whole. -->
      <xsl:for-each select="*[not(following-sibling::sbr) and not(self::sbr) and
                              not(following-sibling::db:sbr) and not(self::db:sbr)]">
        <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode" select=".">
          <xsl:with-param name="sbr" select="$sbr"/>
          <xsl:with-param name="sepchar" select="$sepchar"/>
        </xsl:apply-templates>
        <xsl:if test="position() != 1">
          <xsl:value-of select="str:padding(2 * string-length($sepchar) + 1, ' ')"/>
        </xsl:if>
      </xsl:for-each>
      <xsl:text> </xsl:text>
    </xsl:when>
    <xsl:when test="set:has-same-node(., $sbr/..)"/>
    <xsl:otherwise>
      <xsl:variable name="child" select="*[set:has-same-node(.|.//sbr|.//db:sbr, $sbr)][1]"/>
      <!-- Process all children that are before $child, but after
           any sbr elements before $child. Add joining punctuation
           padding for all but one of them. -->
      <xsl:for-each select="($child/preceding-sibling::*)
                              [not(set:has-same-node(. | following-sibling::sbr,
                                                     $child/preceding-sibling::sbr)) and
                               not(set:has-same-node(. | following-sibling::db:sbr,
                                                     $child/preceding-sibling::db:sbr))]">
        <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode" select=".">
          <xsl:with-param name="sbr" select="false()"/>
          <xsl:with-param name="sepchar" select="$sepchar"/>
        </xsl:apply-templates>
        <xsl:if test="position() != 1">
          <xsl:value-of select="str:padding(2 * string-length($sepchar) + 1, ' ')"/>
        </xsl:if>
      </xsl:for-each>
      <!-- And process $child itself -->
      <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode" select="$child">
        <xsl:with-param name="sbr" select="$sbr"/>
        <xsl:with-param name="sepchar" select="$sepchar"/>
      </xsl:apply-templates>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- = synopfragment % db2html.cmdsynopsis.sbr.padding.mode = -->
<xsl:template mode="db2html.cmdsynopsis.sbr.padding.mode"
              match="synopfragment | db:synopfragment">
  <xsl:param name="sbr"/>
  <xsl:param name="sepchar"/>
  <xsl:variable name="countlast" select="count(preceding-sibling::synopfragment) +
                                         count(following-sibling::synopfragment) +
                                         count(preceding-sibling::db:synopfragment) +
                                         count(following-sibling::db:synopfragment)"/>
  <xsl:value-of select="str:padding(string-length($countlast + 1) + 3, ' ')"/>
  <xsl:value-of select="str:padding(string-length($sepchar), ' ')"/>
  <xsl:variable name="child" select="*[set:has-same-node(.|.//sbr|.//db:sbr, $sbr)][1]"/>
  <!-- Process all children that are before $child, but 
       after any sbr elements before $child -->
  <xsl:for-each select="$child/preceding-sibling::*
                          [not(set:has-same-node(. | following-sibling::sbr,
                                                 $child/preceding-sibling::sbr)) and
                           not(set:has-same-node(. | following-sibling::db:sbr,
                                                 $child/preceding-sibling::db:sbr))]">
    <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode" select=".">
      <xsl:with-param name="sbr" select="false()"/>
      <xsl:with-param name="sepchar" select="$sepchar"/>
    </xsl:apply-templates>
    <xsl:value-of select="str:padding(string-length($sepchar), ' ')"/>
  </xsl:for-each>
  <!-- And process $child itself -->
  <xsl:apply-templates mode="db2html.cmdsynopsis.sbr.padding.mode" select="$child">
    <xsl:with-param name="sbr" select="$sbr"/>
    <xsl:with-param name="sepchar" select="$sepchar"/>
  </xsl:apply-templates>
</xsl:template>

<!-- = synopfragmentref % db2html.cmdsynopsis.sbr.padding.mode = -->
<xsl:template mode="db2html.cmdsynopsis.sbr.padding.mode"
              match="synopfragmentref | db:synopfragmentref">
  <xsl:variable name="node" select="key('db.id.key', @linkend)"/>
  <xsl:variable name="count" select="count($node/preceding-sibling::synopfragment) +
                                     count($node/preceding-sibling::db:synopfragment) + 1"/>
  <xsl:value-of select="str:padding(string-length($count) + 2, ' ')"/>
</xsl:template>

</xsl:stylesheet>
