<?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: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 MathML objects.
define AldorToMathMLCat(UCH:UniCodeCharacter):Category == OutputType with {
  <xsl:apply-templates select="tokens/nullary" mode="Category"/>
  <xsl:apply-templates select="tokens/nullary2" mode="Category"/>
  <xsl:apply-templates select="tokens/container" mode="Category"/>
  <xsl:apply-templates select="tokens/container2" mode="Category"/>
}

  <!-- now construct the domain -->
+++ This domain contains constructors for the basic MathML objects.
extend MathMLCont(UCH:UniCodeCharacter):AldorToMathMLCat(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;

  defURLString:DOMString(UCH) := ["definitionURL"];
  encodingString:DOMString(UCH) := ["encoding"];

  <xsl:apply-templates select="tokens/nullary" mode="addbody"/>
  <xsl:apply-templates select="tokens/nullary2" mode="addbody"/>
  <xsl:apply-templates select="tokens/container" mode="addbody"/>
  <xsl:apply-templates select="tokens/container2" mode="addbody"/>
}
</xsl:template>

  <xsl:template match="tokens/nullary" mode="Category">
    <xsl:variable name="tok" select="."/>
    <xsl:choose>
      <!-- special cases -->
      <xsl:when test="$tok='and' or $tok='or' or $tok='rem' or
$tok='not' or $tok='in'">
  _<xsl:value-of select="."/> : () -> %;
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="."/> : () -> %;
      </xsl:otherwise>
    </xsl:choose>
      ++ a nullary function to construct the <xsl:value-of select="."/> element
  </xsl:template>

  <xsl:template match="tokens/nullary2" mode="Category">
    <xsl:variable name="tok" select="."/>
    <xsl:choose>
      <!-- special cases -->
      <xsl:when test="$tok='and' or $tok='or' or $tok='rem' or
$tok='not' or $tok='in'">
  _<xsl:value-of select="."/> : () -> %;
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="."/> : (DOMString(UCH),DOMString(UCH)) -> %;
      </xsl:otherwise>
    </xsl:choose>
      ++ a binary function to construct the <xsl:value-of select="."/> element
      ++ the first argument is the value of the {\em definitionURL} attribute
      ++ the second argument is the value of the {\em encoding} attribute
  </xsl:template>

  <xsl:template match="tokens/container" mode="Category">
    <xsl:value-of select="."/> : List(%) -> %;
      ++ a unary function to construct an element which has an arbitrary number
      ++ of children. The single argument should be a list of the children
  </xsl:template>

  <xsl:template match="tokens/container2" mode="Category">
    <!-- make a signature for functions for each different selection
         of attributes -->
    <xsl:call-template name="makesig">
      <xsl:with-param name="num" select="count(attr)"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="makesig">
    <xsl:param name="num"/>
    <xsl:value-of select="tok"
      /> : (<xsl:for-each
select="attr[position()&lt;$num]">DOMString(UCH),</xsl:for-each
    ><xsl:if test="attr[$num&gt;0]">DOMString(UCH)</xsl:if><xsl:if
test="numchilds&gt;0 and attr[$num&gt;0]">,</xsl:if>

<xsl:call-template name="contentargs2">
    <xsl:with-param name="numkids" select="numchilds"/>
  </xsl:call-template><xsl:if test="cdata"><xsl:if test="numchilds or attr[$num&gt;0]">,</xsl:if>DOMString(UCH)</xsl:if>) -> %;
      ++ a function to construct an element which has <xsl:value-of select="$num"/>
      ++ attributes. The arguments should be the attribute values
      ++ followed by the element content
    <xsl:if test="$num&gt;0">
      <xsl:call-template name="makesig">
        <xsl:with-param name="num" select="$num - 1"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

  <xsl:template name="contentargs2">
    <xsl:param name="numkids"/>
    <xsl:if test="$numkids&gt;0">%<xsl:if test="$numkids&gt;1">,</xsl:if>
    <xsl:call-template name="contentargs2">
      <xsl:with-param name="numkids" select="$numkids - 1"/>
    </xsl:call-template>
    </xsl:if>
  </xsl:template>

  <xsl:template match="tokens/nullary" mode="addbody">
    <xsl:variable name="tok" select="."/>
    <xsl:value-of select="."/>String:DOMString(UCH) := ["<xsl:value-of
select="."/>"];
  <xsl:choose>
      <xsl:when test="$tok='and' or $tok='or' or $tok='rem' or $tok='not' or $tok='in'">_<xsl:value-of select="."/>
      </xsl:when>
      <xsl:otherwise><xsl:value-of select="."/>
      </xsl:otherwise>
    </xsl:choose>():% == {
      import from NamedNodeMap(UCH),NodeList(UCH);
      per createElement(<xsl:value-of select="."/>String,new(0),new())
  }

  </xsl:template>

  <!-- template for nullary functions taking definitionURLs and encoding
       attributes -->
  <xsl:template match="tokens/nullary2" mode="addbody">
  <xsl:value-of select="."/>(str1:DOMString(UCH),str2:DOMString(UCH)):% == {
    nnm:NamedNodeMap(UCH) := new(0);
    setNamedItem(nnm,cast createAttribute(defURLString,str1));
    setNamedItem(nnm,cast createAttribute(encodingString,str2));
    per createElement(<xsl:value-of select="."/>String,nnm,new());
  }
    
  </xsl:template>

  <!-- template for functions which take one List argument -->
  <xsl:template match="tokens/container" mode="addbody">
    <xsl:value-of select="."/>String := ["<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:template>

  <xsl:template match="tokens/container2" mode="addbody">
    <!-- do once for each number of attributes (recursion) -->
    <xsl:call-template name="makefn">
      <xsl:with-param name="num" select="count(attr)"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="makefn">
    <xsl:param name="num"/>
    <xsl:for-each select="attr[position()&lt;=$num]">
      <xsl:value-of select="."/>String:DOMString(UCH) := ["<xsl:value-of select="."/>"];
    </xsl:for-each>
    <xsl:value-of select="tok"/>String:DOMString(UCH) := ["<xsl:value-of select="tok"/>"];
  <xsl:value-of select="tok"
/>(<xsl:for-each select="attr[position()&lt;=$num]">
      <xsl:value-of select="."/>:DOMString(UCH)<xsl:if
      test="position()&lt;$num or ../numchilds&gt;0">,</xsl:if>
    </xsl:for-each>
      <!-- now put arguments for the content -->
     <xsl:call-template name="contentargs">
        <xsl:with-param name="numkids" select="numchilds"/>
      </xsl:call-template><xsl:if test="cdata"><xsl:if
      test="attr[position()&lt;=$num] or
      numchilds">,</xsl:if>cont:DOMString(UCH)</xsl:if>):% == { <!-- 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="numchilds"/>
    </xsl:call-template>
    <xsl:if test="cdata">
      addChild(cast createTextNode cont,children);
    </xsl:if>
    per createElement(<xsl:value-of select="tok"/>String,nnm,children);
  }

  <xsl:if test="$num&gt;0"> <!-- do recursive call -->
    <xsl:call-template name="makefn">
      <xsl:with-param name="num" select="$num - 1"/>
    </xsl:call-template>
  </xsl:if>
  </xsl:template>

  <xsl:template name="contentargs">
    <xsl:param name="numkids"/>
    <xsl:if test="$numkids&gt;0">child<xsl:value-of select="$numkids"/>:%<xsl:if test="$numkids&gt;1">,</xsl:if>
    <xsl:call-template name="contentargs">
      <xsl:with-param name="numkids" select="$numkids - 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 child<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>

