<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:bnf="http://www.thaiopensource.com/relaxng/bnf"
                xmlns:rng="http://relaxng.org/ns/structure/1.0"
                exclude-result-prefixes="bnf rng"
                version="1.0">

<xsl:include href="spec.xsl"/>

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

<xsl:template mode="bnf" match="bnf:define"/>

<xsl:template mode="bnf" match="bnf:rule|bnf:token">
<p>
  <xsl:choose>
    <xsl:when test="self::bnf:rule">
       <i><a name="nt-{@name}"><xsl:value-of select="@name"/></a></i>
    </xsl:when>
    <xsl:otherwise>
       <b><i><a name="t-{@name}"><xsl:value-of select="@name"/></a></i></b>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:if test="bnf:arg">
     <xsl:text>(</xsl:text>
     <xsl:for-each select="bnf:arg">
	<xsl:if test="position() != 1">, </xsl:if>
	<i><xsl:value-of select="@name"/></i>
     </xsl:for-each>
     <xsl:text>)</xsl:text>
  </xsl:if>
  <xsl:text>&#160;&#160;::=</xsl:text>

  <xsl:apply-templates select="bnf:case" mode="bnf"/>
</p>
</xsl:template>

<xsl:template mode="bnf" match="bnf:case">
  <br/>
  <xsl:text>&#160;&#160;&#160;&#160;</xsl:text>
  <xsl:if test="position() != 1">
    <xsl:text>|&#160;&#160;</xsl:text>
  </xsl:if>
  <xsl:apply-templates mode="bnf" select="*[not(self::bnf:constraint)][1]"/>
  <xsl:for-each select="bnf:constraint">
    <br/>
    <xsl:text>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</xsl:text>
    <b>Constraint: </b>
    <a href="#constraint-{@name}"><xsl:value-of select="@name"/></a>
  </xsl:for-each>
  <xsl:if test="*[not(self::bnf:constraint)][2]">
     <br/>
     <xsl:text>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{ </xsl:text>
     <xsl:apply-templates mode="bnf" select="*[2]"/>
     <xsl:text> }</xsl:text>
  </xsl:if>
</xsl:template>

<xsl:template mode="bnf" match="bnf:literal">
  <xsl:text>"</xsl:text>
  <code><xsl:value-of select="."/></code>
  <xsl:text>"</xsl:text>
</xsl:template>

<xsl:template mode="bnf" match="bnf:sequence">
  <xsl:for-each select="*">
    <xsl:if test="position() != 1">
       <xsl:text>&#160;&#160;</xsl:text>
    </xsl:if>
    <xsl:apply-templates mode="bnf" select="."/>
  </xsl:for-each>
</xsl:template>

<xsl:template mode="bnf" match="bnf:except">
  <xsl:apply-templates mode="bnf" select="*[1]"/>
  <xsl:text> - </xsl:text>
  <xsl:apply-templates mode="bnf" select="*[2]"/>
</xsl:template>

<xsl:template match="bnf:empty" mode="bnf"><i>&#x3B5;</i></xsl:template>

<xsl:template match="bnf:char" mode="bnf">
  <code><xsl:value-of select="."/></code>
</xsl:template>

<xsl:template match="bnf:hexChar" mode="bnf">
  <xsl:text>&amp;#x</xsl:text>
  <xsl:value-of select="."/>
  <xsl:text>;</xsl:text>
</xsl:template>

<xsl:template mode="bnf" match="bnf:nt|bnf:xnt|bnf:t">
  <xsl:if test="@context">
    <i><xsl:value-of select="@context"/></i>
    <b><i>.</i></b>
  </xsl:if>
  <xsl:choose>
    <xsl:when test="self::bnf:nt">
      <i><a href="#nt-{@name}" class="nt"><xsl:value-of select="@name"/></a></i>
    </xsl:when>
    <xsl:when test="self::bnf:t">
      <b><i><a href="#t-{@name}" class="nt"><xsl:value-of select="@name"/></a></i></b>
    </xsl:when>
    <xsl:otherwise>
      <i><xsl:value-of select="@name"/></i>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:if test="*">
    <xsl:text>(</xsl:text>
    <xsl:for-each select="*">
       <xsl:if test="position() != 1">, </xsl:if>
       <xsl:apply-templates mode="bnf" select="."/>
    </xsl:for-each>
    <xsl:text>)</xsl:text>
  </xsl:if>
  <xsl:if test="@as">
    <sub><i><xsl:value-of select="@as"/></i></sub>
  </xsl:if>
</xsl:template>

<xsl:template mode="bnf" match="bnf:ref">
  <i><xsl:value-of select="@name"/></i>
</xsl:template>

<xsl:template mode="bnf" match="bnf:concat">
  <xsl:text>(</xsl:text>
  <xsl:for-each select="*">
     <xsl:if test="position() != 1">, </xsl:if>
     <xsl:apply-templates mode="bnf" select="."/>
  </xsl:for-each>
  <xsl:text>)</xsl:text>
</xsl:template>

<xsl:template mode="bnf" match="bnf:function">
  <xsl:call-template name="function">
    <xsl:with-param name="name" select="@name"/>
  </xsl:call-template>
</xsl:template>

<xsl:template name="function">
  <xsl:param name="name"/>
  <xsl:value-of select="$name"/>
  <xsl:text>(</xsl:text>
  <xsl:for-each select="*">
     <xsl:if test="position() != 1">, </xsl:if>
     <xsl:apply-templates mode="bnf" select="."/>
  </xsl:for-each>
  <xsl:text>)</xsl:text>
</xsl:template>

<xsl:template mode="bnf" match="bnf:element[@name]">
<code>&lt;<xsl:value-of select="@name"/></code>
<xsl:for-each select="bnf:attributes/*">
  <code><xsl:text> </xsl:text></code>
  <xsl:apply-templates mode="bnf" select="."/>
</xsl:for-each>
<xsl:choose>
  <xsl:when test="*[not(self::bnf:attributes)]">
     <code>&gt;</code>
     <xsl:text> </xsl:text>
     <xsl:for-each select="*[not(self::bnf:attributes)]">
	<xsl:if test="position() != 1"><xsl:text> </xsl:text></xsl:if>
	<xsl:apply-templates mode="bnf" select="."/>
     </xsl:for-each>
     <xsl:text> </xsl:text>
     <code>&lt;/<xsl:value-of select="@name"/>&gt;</code>
  </xsl:when>
  <xsl:otherwise>
    <code>/&gt;</code>
  </xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template mode="bnf" match="bnf:attribute[@name]">
  <code><xsl:value-of select="@name"/>=</code>
  <xsl:apply-templates mode="bnf" select="*"/>
</xsl:template>

<xsl:template mode="bnf" match="bnf:emptySequence">( )</xsl:template>

<xsl:template mode="bnf" match="bnf:emptySet">{ }</xsl:template>

<xsl:template mode="bnf" match="bnf:prefix|bnf:localPart|bnf:qName|bnf:union|bnf:attribute|bnf:element|bnf:name">
  <xsl:call-template name="function">
    <xsl:with-param name="name" select="local-name()"/>
  </xsl:call-template>
</xsl:template>

<xsl:template mode="bnf" match="bnf:string">
  <xsl:text>"</xsl:text>
  <code><xsl:value-of select="."/></code>
  <xsl:text>"</xsl:text>
</xsl:template>

<xsl:template mode="bnf" match="bnf:true|bnf:false|bnf:inherit|bnf:context">
  <b><xsl:value-of select="local-name()"/></b>
</xsl:template>

<xsl:template mode="bnf" match="bnf:ifelse">
  <xsl:apply-templates mode="bnf" select="*[1]"/>
  <xsl:text> ? </xsl:text>
  <xsl:apply-templates mode="bnf" select="*[2]"/>
  <xsl:text> : </xsl:text>
  <xsl:apply-templates mode="bnf" select="*[3]"/>
</xsl:template>

<xsl:template mode="bnf" match="bnf:charClass|bnf:charClassExcept">
  <xsl:text>[</xsl:text>
  <xsl:if test="self::bnf:charClassExcept">^</xsl:if>
  <xsl:apply-templates mode="bnf" select="*"/>
  <xsl:text>]</xsl:text>
  <xsl:if test="@as">
    <sub><i><xsl:value-of select="@as"/></i></sub>
  </xsl:if>
</xsl:template>

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

<xsl:template mode="bnf" match="bnf:add">
  <xsl:apply-templates mode="bnf" select="*[1]"/>
  <xsl:text> + </xsl:text>
  <xsl:apply-templates mode="bnf" select="*[2]"/>
</xsl:template>

<xsl:template mode="bnf" match="bnf:multiply">
  <xsl:text>(</xsl:text>
  <xsl:apply-templates mode="bnf" select="*[1]"/>
  <xsl:text> * </xsl:text>
  <xsl:apply-templates mode="bnf" select="*[2]"/>
  <xsl:text>)</xsl:text>
</xsl:template>

<xsl:template match="bnf:number" mode="bnf">
  <xsl:value-of select="."/>
</xsl:template>

<xsl:template match="constraint">
<div class="constraint">
  <h4 class="title">
    <xsl:text>Constraint: </xsl:text>
     <a name="constraint-{@name}"><xsl:value-of select="@name"/></a>
  </h4>
  <xsl:apply-templates/>
</div>
</xsl:template>

<xsl:template match="rng:value[contains(.,'&quot;')]">
  <xsl:text>'</xsl:text>
  <code><xsl:value-of select="."/></code>
  <xsl:text>'</xsl:text>
</xsl:template>

<xsl:template match="rng:value">
  <xsl:text>"</xsl:text>
  <code><xsl:value-of select="."/></code>
  <xsl:text>"</xsl:text>
</xsl:template>

<xsl:template match="rng:data[rng:except]">
  <xsl:param name="conn-cur" select="$rng:conn-none"/>
  <xsl:if test="$conn-cur!=$rng:conn-top">(</xsl:if>
  <i><xsl:value-of select="@type"/></i>
  <xsl:text> - </xsl:text>
  <xsl:call-template name="rng:pattern">
    <xsl:with-param name="conn-new" select="$rng:conn-or"/>
    <xsl:with-param name="conn-cur" select="$rng:conn-none"/>
    <xsl:with-param name="sub" select="rng:except/*"/>
  </xsl:call-template>
  <xsl:if test="$conn-cur!=$rng:conn-top">)</xsl:if>
</xsl:template>

</xsl:stylesheet>
