<!DOCTYPE xsl:stylesheet PUBLIC 'http://www.w3.org/1999/XSL/Transform'
      'http://www.w3.org/People/cmsmcq/lib/xslt10.dtd' [

<!--*

/* ast_dot.xsl:  stylesheet for translating from an XML dump of
 * an abstract syntax tree into Graphviz dot notation.
 */

/* Copyright (c) 2008 World Wide Web Consortium, 
 * (Massachusetts Institute of Technology, European Research 
 * Consortium for Informatics and Mathematics, Keio University). 
 * All Rights Reserved. This work is distributed under the 
 * W3C(TM) Software License [1] 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.
 *
 * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
 */

/* This file is part of Xerophily, a parser for XSD regular expressions. */

*-->

<!ATTLIST xsl:stylesheet 
  xmlns:xsl CDATA "http://www.w3.org/1999/XSL/Transform" 
  xmlns:xsd CDATA "http://www.w3.org/2001/XMLSchema" 
  xmlns:h   CDATA "http://www.w3.org/1999/xhtml"
>
<!ENTITY mdash  "&#x2014;" ><!--=em dash-->

<!ENTITY nl '&#xA;'>
<!ENTITY NL '&#xA;&#xA;'>

<!ENTITY x-top-level-atts "
  xmlns:saxon CDATA #FIXED 'http://icl.com/saxon'
">

<!ENTITY % non-xsl-instructions "| saxon:output">

<!--* I assume saxon:output gets same content as xsl:template *-->
<!--* content model should be %template; *-->
<!ELEMENT saxon:output  (#PCDATA
  | xsl:apply-templates
  | xsl:call-template
  | xsl:apply-imports
  | xsl:for-each
  | xsl:value-of
  | xsl:copy-of
  | xsl:number
  | xsl:choose
  | xsl:if
  | xsl:text
  | xsl:copy
  | xsl:variable
  | xsl:message
  | xsl:fallback
  | xsl:processing-instruction
  | xsl:comment
  | xsl:element
  | xsl:attribute
  | saxon:output)*
>
<!--* I have added only the file attribute; saxon:output has more *-->
<!ATTLIST saxon:output
  file CDATA #REQUIRED
  method NMTOKEN #IMPLIED
  version NMTOKEN #IMPLIED
  encoding CDATA #IMPLIED
  omit-xml-declaration (yes|no) #IMPLIED
  standalone (yes|no) #IMPLIED
  doctype-public CDATA #IMPLIED
  doctype-system CDATA #IMPLIED
  cdata-section-elements NMTOKENS #IMPLIED
  indent (yes|no) #IMPLIED
  media-type CDATA #IMPLIED
>

]>
<xsl:stylesheet 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
 xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
 xmlns:h="http://www.w3.org/1999/xhtml"
 xmlns:saxon = 'http://icl.com/saxon'
 extension-element-prefixes="saxon"
 version="1.0">

 <xsl:output method="text"/>

 <xsl:template match="xsd:schema">
  <xsl:text>// Whole lotta diagraphs, made by ast_dot.xsl &NL;</xsl:text>
  <xsl:apply-templates/>
 </xsl:template>

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

 <xsl:template match="*" mode="ast">
  <!--* 
  <xsl:message>Unrecognized <xsl:value-of select="name()"/></xsl:message>
  <xsl:message><xsl:copy-of select="."/></xsl:message>
  *-->
  <xsl:variable name="self">
   <xsl:apply-templates select="." mode="make-nodename"/>
  </xsl:variable>
  <!--* <xsl:message>Element <xsl:value-of select="name()"/> is node <xsl:value-of select="'hi'"/></xsl:message> *-->
  <xsl:value-of select="$self"/>
  <xsl:text>[ label="</xsl:text>
  <xsl:value-of select="name()"/>
  <xsl:text>"];&nl;</xsl:text>
  <xsl:call-template name="do-parent-arc">
   <xsl:with-param name="self" select="$self"/>
  </xsl:call-template>
  <xsl:apply-templates mode="ast"/>
 </xsl:template>

 <xsl:template match="xsd:documentation | h:*"/>

 <xsl:template match="xsd:annotation|xsd:appinfo|xsd:restriction">
  <xsl:apply-templates/>
 </xsl:template>

 <xsl:template match="xsd:simpleType">
  <xsl:apply-templates/>
 </xsl:template>

 <xsl:template match="xsd:pattern">
  <xsl:apply-templates/>
 </xsl:template>

 <xsl:template match="ast">
  <xsl:variable name="astname">   
   <xsl:value-of select="ancestor::xsd:simpleType[@name][1]/@name"/>
  </xsl:variable>
  <xsl:variable name="astnum">   
   <xsl:number level="any" count="ast" from="xsd:simpleType"/>
  </xsl:variable>
  <xsl:variable name="self">
   <xsl:apply-templates select="." mode="make-nodename"/>
  </xsl:variable>
  <xsl:message>Writing <xsl:value-of select="concat('ast.',$astname,'.',$astnum,'.dot ...')"/></xsl:message> 
  <saxon:output href="{concat('ast.',$astname,'.',$astnum,'.dot')}">
   <xsl:text>digraph </xsl:text>
   <xsl:value-of select="translate($astname,'-.','__')"/>
   <xsl:text> { &NL;</xsl:text>
   <xsl:text>// pattern [label="</xsl:text>
   <xsl:value-of select="@value"/>
   <xsl:text>"];&nl;</xsl:text>
   <xsl:value-of select="$self"/>
   <xsl:text>[label="grammars: </xsl:text>
   <xsl:value-of select="@grammar"/>
   <xsl:text>"];&nl;</xsl:text>
   <xsl:apply-templates mode="ast"/>
   <xsl:text> }&NL;</xsl:text>
  </saxon:output>
 </xsl:template>

 <xsl:template match="no_parse" mode="ast">
  <xsl:text>no_parse; &nl;</xsl:text>
 </xsl:template>
 
 <xsl:template name="make-nodename" mode="make-nodename" match="*">
  <xsl:variable name="tumbler">
   <xsl:choose>
    <xsl:when test="self::ast">0</xsl:when>
    <xsl:otherwise>
     <xsl:number level="any" count="*" from="ast" format="1"/>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:variable>
  <!--* <xsl:message>Tumbler is <xsl:value-of select="$tumbler"/></xsl:message> *-->
  <xsl:value-of select="concat('n',$tumbler)"/>
 </xsl:template>

 <xsl:template name="do-parent-arc">
  <xsl:param name="self">
   <xsl:apply-templates select="." mode="make-nodename"/>
  </xsl:param>
  <xsl:param name="parent">
   <xsl:apply-templates select=".." mode="make-nodename"/>
  </xsl:param>
  <xsl:value-of select="$parent"/>
  <xsl:text> -> </xsl:text>
  <xsl:value-of select="$self"/>
  <xsl:text>;&nl;</xsl:text>
 </xsl:template>

 <xsl:template match="seq">
  <xsl:variable name="self">
   <xsl:apply-templates select="." mode="make-nodename"/>
  </xsl:variable>
  <xsl:value-of select="$self"/>
  <xsl:text>[ label="</xsl:text>
  <xsl:value-of select="name()"/>
  <xsl:text>"];&nl;</xsl:text>
  <xsl:apply-templates mode="ast"/>

 </xsl:template>

<!--*
 <xsl:template match="count[@min='1' and @max='1']" mode="ast">
  <xsl:variable name="self">
   <xsl:apply-templates select="." mode="make-nodename"/>
  </xsl:variable>
  <xsl:value-of select="$self"/>
  <xsl:text>[ label="1-1"];&nl;</xsl:text>
  <xsl:apply-templates mode="ast"/>
 </xsl:template>
 <xsl:template match="count[@min='1' and @max='unbounded']" mode="ast">
  <xsl:variable name="self">
   <xsl:apply-templates select="." mode="make-nodename"/>
  </xsl:variable>
  <xsl:value-of select="$self"/>
  <xsl:text>[ label="1-*"];&nl;</xsl:text>
  <xsl:apply-templates mode="ast"/>
 </xsl:template>
 <xsl:template match="count[@min='0' and @max='unbounded']" mode="ast">
  <xsl:variable name="self">
   <xsl:apply-templates select="." mode="make-nodename"/>
  </xsl:variable>
  <xsl:value-of select="$self"/>
  <xsl:text>[ label="0-*"];&nl;</xsl:text>
  <xsl:apply-templates mode="ast"/>
 </xsl:template>
*-->
 <xsl:template match="count" mode="ast">
  <xsl:variable name="self">
   <xsl:apply-templates select="." mode="make-nodename"/>
  </xsl:variable>
  <xsl:value-of select="$self"/>
  <xsl:text>[ label="</xsl:text>
  <xsl:value-of select="@min"/>
  <xsl:text>-</xsl:text>
  <xsl:choose>
   <xsl:when test="@max='unbounded'">
    <xsl:text>*</xsl:text>
   </xsl:when>
   <xsl:otherwise>
    <xsl:value-of select="@max"/>
   </xsl:otherwise>
  </xsl:choose>
  <xsl:text>"];&nl;</xsl:text>

  <xsl:call-template name="do-parent-arc">
   <xsl:with-param name="self" select="$self"/>
  </xsl:call-template>
  <xsl:apply-templates mode="ast"/>
 </xsl:template>

 <xsl:template match="charClass[any_of[simple_range and count(*) = 1] and count(*) = 1]" mode="ast">
  <xsl:variable name="self">
   <xsl:apply-templates select="." mode="make-nodename"/>
  </xsl:variable>
  <xsl:value-of select="$self"/>
  <xsl:text>[ label="[</xsl:text>
  <xsl:value-of select="./any_of/simple_range/@from"/>
  <xsl:text>-</xsl:text>
  <xsl:value-of select="./any_of/simple_range//@to"/>
  <xsl:text>]"];&nl;</xsl:text>
  <xsl:call-template name="do-parent-arc">
   <xsl:with-param name="self" select="$self"/>
  </xsl:call-template>
  <!--* <xsl:apply-templates mode="ast"/> *-->
 </xsl:template>

 <xsl:template match="simple_range" mode="ast">
  <xsl:variable name="self">
   <xsl:apply-templates select="." mode="make-nodename"/>
  </xsl:variable>
  <xsl:value-of select="$self"/>
  <xsl:text>[ label="'</xsl:text>
  <xsl:value-of select="./@from"/>
  <xsl:text>' - '</xsl:text>
  <xsl:value-of select="./@to"/>
  <xsl:text>'"];&nl;</xsl:text>
  <xsl:call-template name="do-parent-arc">
   <xsl:with-param name="self" select="$self"/>
  </xsl:call-template>
  <!--* <xsl:apply-templates mode="ast"/> *-->
 </xsl:template>

 <xsl:template match="mce" mode="ast">
  <xsl:variable name="self">
   <xsl:apply-templates select="." mode="make-nodename"/>
  </xsl:variable>
  <xsl:value-of select="$self"/>
  <xsl:text>[ label="MCE: </xsl:text>
  <xsl:value-of select="@kw"/>
  <xsl:text>"];&nl;</xsl:text>
  <xsl:call-template name="do-parent-arc">
   <xsl:with-param name="self" select="$self"/>
  </xsl:call-template>
  <xsl:apply-templates mode="ast"/>
 </xsl:template>
 <xsl:template match="sce" mode="ast">
  <xsl:variable name="self">
   <xsl:apply-templates select="." mode="make-nodename"/>
  </xsl:variable>
  <xsl:value-of select="$self"/>
  <xsl:text>[ label="SCE: </xsl:text>
  <xsl:value-of select="."/>
  <xsl:text>"];&nl;</xsl:text>
  <xsl:call-template name="do-parent-arc">
   <xsl:with-param name="self" select="$self"/>
  </xsl:call-template>
  <xsl:apply-templates mode="ast"/>
 </xsl:template>

 <xsl:template match="c" mode="ast">
  <xsl:variable name="self">
   <xsl:apply-templates select="." mode="make-nodename"/>
  </xsl:variable>
  <xsl:value-of select="$self"/>
  <xsl:text>[ label="'</xsl:text>
  <xsl:value-of select="."/>
  <xsl:text>'"];&nl;</xsl:text>
  <xsl:call-template name="do-parent-arc">
   <xsl:with-param name="self" select="$self"/>
  </xsl:call-template>
  <xsl:apply-templates mode="ast"/>
 </xsl:template>

 <xsl:template match="text()"/>
 <xsl:template match="text()" mode="ast"/>
 
</xsl:stylesheet>
<!-- Keep this comment at the end of the file
Local variables:
mode: xml
sgml-default-dtd-file:"/Library/SGML/Public/Emacs/xslt.ced"
sgml-omittag:t
sgml-shorttag:t
sgml-indent-data:t
sgml-indent-step:1
End:
-->

