<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

<--
 Copyright (C) 2003 	Bill Naylor

 This library 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.1 of the License, or (at your option) any later version.

 This library 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 library; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 You may contact the author at e-mail: bill@mcs.vuw.ac.nz -->

  <xsl:output method="text"/>
  <xsl:strip-space elements="container"/>

  <xsl:template match="/">
#include "aldor"

#library XMLLib "libxml.al"
import from XMLLib;

import from String,Character;

    <!-- first make the Category -->
+++ this code is automatically created using XSLT
+++ This category contains function signatures for constructor functions for
+++ the basic Presentation MathML objects.
define AldorToMathMLPresCat(UCH:UniCodeCharacter):Category == OutputType with {
  <xsl:apply-templates select="tokens/token" mode="Category"/>
  <xsl:apply-templates select="tokens/container" mode="Category"/>
}

  <!-- now construct the domain -->
+++ This domain contains constructors for the basic Presentation MathML objects.
extend MathMLPres(UCH:UniCodeCharacter):AldorToMathMLPresCat(UCH) == add {
  Rep ==> Element(UCH);
  import from Rep,Document(UCH),DOMString(UCH),MachineInteger,Attr(UCH),NodeList(UCH),Text(UCH);

  (tw:TextWriter) &lt;&lt; (om:%):TextWriter == tw&lt;&lt;rep om;

  retract(el:Element(UCH)):% == per el;

  cast(om:%):Element(UCH) == rep om;

  <xsl:apply-templates select="tokens/token" mode="domain"/>
  <xsl:apply-templates select="tokens/container" mode="domain"/>

}
</xsl:template>

<!-- signatures for tokens -->
<xsl:template match="tokens/token" mode="Category">
  <xsl:value-of select="."/>: DOMString(UCH) -> %;
</xsl:template>

<!-- signatures for containers -->
<xsl:template match="tokens/container" mode="Category">
  <xsl:choose>
    <xsl:when test="text()">
      <xsl:value-of select="."/>: List(%) -> %;
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="tag"/>: (<xsl:call-template name="args"
mode="Category">
      <xsl:with-param name="numArgs" select="num"/>
    </xsl:call-template>) -> %;

    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- construct the range part of the signature for containers with
specific number of arguments -->
<xsl:template name="args" mode="Category">
  <xsl:param name="numArgs"/>%<xsl:if 
  test="$numArgs &gt; 1">,<xsl:call-template name="args" mode="Category">
      <xsl:with-param name="numArgs" select="$numArgs - 1"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

<!-- construct functions for tokens -->
<xsl:template match="tokens/token" mode="domain">
   <xsl:value-of select="."/>String:DOMString(UCH) := ["<xsl:value-of select="."/>"];
  <xsl:value-of select="."/>(content:DOMString(UCH)):% == {
      nnm:NamedNodeMap(UCH) := new(0);
      children:NodeList(UCH) := new();
      addChild(cast createTextNode content,children);
      per createElement(<xsl:value-of select="."/>String,nnm,children);
}
</xsl:template>

<!-- functions for containers -->
<xsl:template match="tokens/container" mode="domain">
  <xsl:choose>
    <xsl:when test="text()">
   <xsl:value-of select="."/>String:DOMString(UCH) := ["<xsl:value-of select="."/>"];
      <xsl:value-of select="."/>(l:List(%)):% == {
    import from NamedNodeMap(UCH);
    nl:NodeList(UCH) := new();
    for i in l repeat addChild(cast rep i,nl);
    per createElement(<xsl:value-of select="."/>String,new(0),nl)
  }

    </xsl:when>
    <xsl:otherwise>
   <xsl:value-of select="tag"/>String:DOMString(UCH) := ["<xsl:value-of select="tag"/>"];
      <xsl:value-of select="tag"/>(<xsl:call-template name="args"
mode="domain">
      <xsl:with-param name="numArgs" select="num"/>
    </xsl:call-template>):% == { <!-- body of function -->
      nnm:NamedNodeMap(UCH) := new(0);
    <xsl:for-each select="attr[position()&lt;=$num]">
      setNamedItem(nnm,cast createAttribute(<xsl:value-of
      select="."/>String,<xsl:value-of select="."/>));
    </xsl:for-each>
    children:NodeList(UCH) := new();
    <xsl:call-template name="addchildren">
      <xsl:with-param name="numkids" select="num"/>
    </xsl:call-template>
    per createElement(<xsl:value-of select="tag"/>String,nnm,children)
  }

    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- construct the argument list for container functions with
specific number of arguments -->
<xsl:template name="args" mode="domain">
  <xsl:param name="numArgs"/>arg<xsl:value-of select="$numArgs"/>:%<xsl:if 
  test="$numArgs &gt; 1">,<xsl:call-template name="args" mode="domain">
      <xsl:with-param name="numArgs" select="$numArgs - 1"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

  <xsl:template name="addchildren">
    <xsl:param name="numkids"/>
    <xsl:if test="$numkids &gt; 0">
      addChild(cast rep arg<xsl:value-of select="$numkids"/>,children);
      <xsl:call-template name="addchildren">
        <xsl:with-param name="numkids" select="$numkids - 1"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>
