axiom-developer
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Axiom-developer] Re: hyperdoc on windows


From: root
Subject: Re: [Axiom-developer] Re: hyperdoc on windows
Date: Fri, 21 Sep 2007 23:45:45 -0400

>> At the moment, due to the great work by Arthur Ralfs, I'm making
>> progress on the browser-based version. I now have some of the
>> hyperdoc pages converted and am working on using Arthur's code
>> to evaluate and return math output directly to the browser.
>> Axiom's output in mathML in firefox is very pretty.
>
>I haven't been able to run Arthur's code in Windows :-(. It will be good
>if you can put your modifications to the interface in a repository (git or 
>svn),
>so others (maybe me :-) can work on top of Arthur's work.

The axiom silver version (git or svn) has most of Arthur's code for
mathML output already. I've attached his pamphlet file so you can try it.

To try it, put it someplace like /home/silver
 o cd /home/silver
 o check out and build the latest silver branch:
  - svn co https://axiom.svn.sourceforge.net/svnroot/axiom axiom
  - cd axiom
  - export AXIOM=`pwd`/mnt/linux
  - export PATH=$AXIOM/bin:$PATH
  - make
 o cd /home/silver/axiom
 o save the axserver.pamphlet file (attached)
 o export PATH=$AXIOM/bin/lib:$PATH
 o notangle -R"Server Lisp" axserver.pamphlet > http.lisp
 o notangle axserver.pamphlet > axserver.spad
 o notangle -R"Axiom xml" axserver.pamphlet > axiom.xml
 o axiom -nox
 o -> )set mes auto off
 o -> )set output mathml on
 o -> )lisp (load "http.lisp")
 o -> )compile axserver
 o -> axServer(8085,mutliServ$AXSERV)
 o start firefox
 o go to URL http://127.0.0.1:8085/home/silver/axiom/axiom.xml
 o type an axiom expression in the input box
 o hit enter

The http.lisp file provides low level routines used in the spad code.
The axiom.xml provides the web page and form.
The axserver.spad provides the axServer function
The latest svn axiom image incorporates the mathML patches


Once I have a demonstration page (I'm working on the path
  Basic Commands -> Calculus -> Differentiate -> (axiom response)
I'll be able to convert the whole of hyperdoc to firefox and we
should have a portable front end.

I'm using AJAX so the Axiom output appears on the same page as the
original browser input line. That way the user can experiment without
leaving the differentiate page.

The plan is to look at a "pamphlet" page that has an input/output
interaction containing history. I hope to have a button that can
generate a "pamphlet" from the working page (a different kind of
notebook idea). Different worksheets can be on different tabs.
I'm debating about putting each tab in its own axiom frame.

If I can figure a way to make the page "live" we might yet get the
"drag-and-drop" a pamphlet idea working in the near future.




It would be good to get this working in Doyen. I think that Arthur's
approach using mathML is much prettier than using the current method.




Since you've gotten GCL to run on windows you might consider what it
would take to get Arthur's mathML code into the wh-sandbox build.  (I
believe you used wh-sandbox). Once that code is incorporated you can
follow the same path to get Arthur's example to work. The key steps 
would be:

 o incorporate Arthur's mathML extension into the algebra build
   (see attached patch 20070811.01.tpd.patch which won't apply
    directly to wh-sandbox but contains all the important changes)
 o get http.lisp from axserver.pamphlet working on GCL/windows
 o get the above example to work

I'm not sure how to port the http.lisp file to windows but Camm might
be able to help and Waldek has been doing a lot of work in that
direction. If Arthur's code above could be made to work then all of
the other effort I'm doing should instantly port to platforms running
Firefox. 




>> Once I get this to work, firefox can be a standard replacement for
>> hyperdoc, the pages will be in html, and you can change colors
>> to whatever you'd like. In addition, you'll be able to write your
>> own pages for class.
>
>I think it will be good to add Martin's code to Arthur's work to browse
>the databases:
>
>http://wiki.axiom-developer.org/SandBoxHyperDocReplacement

I already demonstrated getting database accesses working here:

  http://daly.axiom-developer.org/asq.php

so it will be pretty trivial to do database lookups as part of
the Firefox version of hyperdoc. Was there other functionality
that I missed?


Let me know if you have any questions.

Tim



================================================================
=== axserver.pamphlet
================================================================
\documentclass{article}
\usepackage{axiom}
\begin{document}
\title{\$SPAD/src/algebra axserver.spad}
\author{Arthur C. Ralfs}
\maketitle
\begin{abstract}
The AxiomServer package is designed to provide a web interface
to axiom.
\end{abstract}
\eject
\tableofcontents
\eject
\section{Preface}

\section{Lisp preliminaries}

Extract the lisp to a file named, say, http.lisp with the
command

notangle -RServer\ Lisp axserver.pamphlet > http.lisp

<<Server Lisp>>=
;; file: http.lisp

(defvar |StandardOutput| *standard-output*)

(defvar  |NewLine| '#\NewLine)

;; some regexp stuff

(defun |StringMatch| (s1 s2)
  (si::string-match s1 s2)
  )



(defun |ListMatches| (&rest args)
  (si::list-matches args)
  )

(defun |MatchBeginning| (i)
  (si::match-beginning i)
  )

(defun |MatchEnd| (i)
  (si::match-end i)
  )

;; the socket stuff


(defun |SiSock| (p spadfn)
;;  (format t "SiSocket-1")
  (si::socket p :server
              (function
               (lambda (w) (SPADCALL w spadfn) )
               )
              :daemon nil)
  )

(defun |SiListen| (s) 
;;  (format t "SiListen-1")
  (si::listen s)
  )
(defun |SiAccept| (s) (si::accept s))
(defun |SiCopyStream| (q s) (si::copy-stream q s))

;; Camm Maguire's modified demo server

(defun foo (s)
  (setq get "" pathvar "")
  (do ((c (read-char s) (read-char s)))
      ((eq c '#\Space))
      (setq get (concat get (string c)))
      )
  (write-line "get: ")
  (write-line get)
  (do ((c (read-char s) (read-char s nil 'the-end)))
      ((eq c '#\Space))
      (setq pathvar (concat pathvar (string c)))
      )
  (write-line "pathvar: ")
  (write-line pathvar)
  (when pathvar
    (if (pathname-name (pathname pathvar))
        (with-open-file (q pathvar) (si::copy-stream q s))
      (dolist (l (directory pathvar)) (format s "~a~%" (namestring l)))
      )
    )
  (close s)
  )
 

(defun bar (p fn) 
  (let ((s (si::socket p :server fn))) 
        (tagbody l 
                (when (si::listen s) 
                        (let ((w (si::accept s))) 
                                (foo w))) 
                (sleep 3) 
                (go l))))

;;(bar 8080 #'foo)

@

\section{Axiom Server}

Extract the AxiomServer package with the command

notangle axserver.pamphlet > axserver.spad

<<package AXSERV AxiomServer>>=

)abbrev package AXSERV AxiomServer
AxiomServer: public == private where

  public == with

    axServer: (Integer, SExpression->Void) -> Void
    multiServ: SExpression -> Void
    fileserver: SExpression -> Void
    axget: SExpression -> Void
    axpost: SExpression -> Void


  private == add

    getFile: (SExpression,String) -> Void
    getCommand: (SExpression,String) -> Void
    lastStep: () -> String
    lastType: () -> String
    formatMessages: String -> String
    formatMessages1: String -> String


    axServer(port:Integer,serverfunc:SExpression->Void):Void ==
      WriteLine("socketServer")$Lisp
      s := SiSock(port,serverfunc)$Lisp
      -- To listen for just one connection and then close the socket
      -- uncomment i := 0.
      i:Integer := 1
      while (i > 0) repeat
        if not null?(SiListen(s)$Lisp)$SExpression then
          w := SiAccept(s)$Lisp
          serverfunc(w)
--        i := 0

    multiServ(s:SExpression):Void ==
          WriteLine("multiServ")$Lisp
          headers:String := ""
          char:String
          -- read in the http headers
          while (char := 
STRING(READ_-CHAR_-NO_-HANG(s,NIL$Lisp,'EOF)$Lisp)$Lisp) ^= "EOF" repeat
              headers := concat [headers,char]
          sayTeX$Lisp headers
          StringMatch("([^ ]*)", headers)$Lisp
          u:UniversalSegment(Integer)
          u := 
segment(MatchBeginning(1)$Lisp+1,MatchEnd(1)$Lisp)$UniversalSegment(Integer)
          reqtype:String := headers.u
          sayTeX$Lisp  concat ["request type: ",reqtype]
          if  reqtype = "GET" then
              StringMatch("GET ([^ ]*)",headers)$Lisp
              u:UniversalSegment(Integer)
              u := 
segment(MatchBeginning(1)$Lisp+1,MatchEnd(1)$Lisp)$UniversalSegment(Integer)
              getFile(s,headers.u)
          if reqtype = "POST" then
              StringMatch("command=(.*)$",headers)$Lisp
              u:UniversalSegment(Integer)
              u := 
segment(MatchBeginning(1)$Lisp+1,MatchEnd(1)$Lisp)$UniversalSegment(Integer)
              getCommand(s,headers.u)

    getFile(s:SExpression,pathvar:String):Void ==
        WriteLine("getFile")$Lisp
        if not null? PATHNAME_-NAME(PATHNAME(pathvar)$Lisp)$Lisp then
        -- display contents of file
            q:=OPEN(pathvar)$Lisp
        else
            q:=MAKE_-STRING_-INPUT_-STREAM("Problem with file path")$Lisp
        file:String := ""
        while (char := STRING(READ_-CHAR_-NO_-HANG(q,NIL$Lisp,'EOF)$Lisp)$Lisp) 
^= "EOF" repeat
            file := concat [file,char]
        CLOSE(q)$Lisp
        file := concat ["Content-Length: 
",string(#file),STRING(NewLine$Lisp)$Lisp,STRING(NewLine$Lisp)$Lisp,file]
        file := concat ["Connection: close",STRING(NewLine$Lisp)$Lisp,file]
        file := concat ["Content-Type: 
application/xhtml+xml",STRING(NewLine$Lisp)$Lisp,file]
        file := concat ["HTTP/1.1 200 OK",STRING(NewLine$Lisp)$Lisp,file]
        f:=MAKE_-STRING_-INPUT_-STREAM(file)$Lisp
        SiCopyStream(f,s)$Lisp
        CLOSE(f)$Lisp
        CLOSE(s)$Lisp

    getCommand(s:SExpression,command:String):Void ==
        WriteLine$Lisp concat ["getCommand: ",command]
        SETQ(tmpmathml$Lisp, MAKE_-STRING_-OUTPUT_-STREAM()$Lisp)$Lisp
        SETQ(tmpalgebra$Lisp, MAKE_-STRING_-OUTPUT_-STREAM()$Lisp)$Lisp
        SETQ(savemathml$Lisp, _$texOutputStream$Lisp)$Lisp
        SETQ(savealgebra$Lisp, _$algebraOutputStream$Lisp)$Lisp
        SETQ(_$texOutputStream$Lisp,tmpmathml$Lisp)$Lisp
        SETQ(_$algebraOutputStream$Lisp,tmpalgebra$Lisp)$Lisp
--      parseAndInterpret$Lisp command
--      parseAndEvalStr$Lisp command
-- The previous two commands don't exit nicely when a syntactically incorrect 
command is
-- given to them.  They somehow need to be wrapped in CATCH statements but I 
haven't 
-- figured out how to do this.  parseAndEvalToStringEqNum  uses the following 
CATCH
-- statements to call parseAndEvalStr but when I try these they don't work.  I 
get a
-- "NIL is not a valid identifier to use in AXIOM" message. Using 
parseAndEvalToStringEqNum
-- works and doesn't crash on a syntax error.
--        v := CATCH('SPAD__READER, CATCH('top__level, parseAndEvalStr$Lisp 
command)$Lisp)$Lisp
--        v = 'restart => ['"error"]
        ans := string parseAndEvalToStringEqNum$Lisp command
        
SETQ(resultmathml$Lisp,GET_-OUTPUT_-STREAM_-STRING(_$texOutputStream$Lisp)$Lisp)$Lisp
        
SETQ(resultalgebra$Lisp,GET_-OUTPUT_-STREAM_-STRING(_$algebraOutputStream$Lisp)$Lisp)$Lisp
        SETQ(_$texOutputStream$Lisp,savemathml$Lisp)$Lisp
        SETQ(_$algebraOutputStream$Lisp,savealgebra$Lisp)$Lisp
        CLOSE(tmpmathml$Lisp)$Lisp
        CLOSE(tmpalgebra$Lisp)$Lisp
        -- Since strings returned from axiom are going to be displayed in html I
        -- should really check for the characters &,<,> and replace them with
        -- &amp;,&lt;,&gt;.  At present I only check for ampersands in 
formatMessages.
        mathml:String := string(resultmathml$Lisp)
        algebra:String := string(resultalgebra$Lisp)
        algebra := formatMessages(algebra)
        -- At this point mathml contains the mathml for the output but does not
        -- include step number or type information.  We should also save the 
command.
        -- I get the type and step number from the $internalHistoryTable
        axans:String := concat ["<div><div class=_"command_">Input: 
",command,"</div><div class=_"stepnum_">Step number: ",lastStep(),"</div><div 
class=_"algebra_">",algebra,"</div><div class=_"mathml_">",mathml,"</div><div 
class=_"type_">Type: ",lastType(),"</div></div>"]
        WriteLine$Lisp concat ["mathml answer: ",mathml]
        WriteLine$Lisp concat ["algebra answer: ",algebra]
        q:=MAKE_-STRING_-INPUT_-STREAM(axans)$Lisp
        SiCopyStream(q,s)$Lisp
        CLOSE(q)$Lisp
        CLOSE(s)$Lisp


    lastType():String ==
--  The last history entry is the first item in the $internalHistoryTable list 
so 
--  car(_$internalHistoryTable$Lisp) selects it.  Here's an example:
--  (3 (x+y)**3 (% (value (Polynomial (Integer)) WRAPPED 1 y (3 0 . 1) (2 1 x 
(1 0 . 3)) (1 1 x (2 0 . 3)) (0 1 x (3 0 . 1)))))
--  This corresponds to the input "(x+y)**3" being issued as the third command 
after
--  starting axiom.  The following line selects the type information.
        string 
car(cdr(car(cdr(car(cdr(cdr(car(_$internalHistoryTable$Lisp)$Lisp)$Lisp)$Lisp)$Lisp)$Lisp)$Lisp)$Lisp)$Lisp


    lastStep():String ==
        string car(car(_$internalHistoryTable$Lisp)$Lisp)$Lisp
        

    formatMessages(str:String):String ==
        WriteLine("formatMessages")$Lisp
        -- I need to replace any ampersands with &amp; and may also need to
        -- replace < and > with &lt; and &gt;
        strlist:List String
        WriteLine(str)$Lisp
        strlist := split(str,char "&")
        str := ""
        for s in strlist repeat
            str := concat [str,s,"&amp;"]
        strlen:Integer := #str
        str := str.(1..(#str - 5))
        WriteLine(str)$Lisp
        -- Here I split the string into lines and put each line in a "div".
        strlist := split(str, char string NewlineChar$Lisp)
        str := ""
        WriteLine("formatMessages1")$Lisp
        WriteLine(concat strlist)$Lisp
        for s in strlist repeat
            WriteLine(s)$Lisp
            str := concat [str,"<div>",s,"</div>"]
        str
@
        
\section{Axiom javascript}

The javascript is currently included in a "script" element in the
Axiom xml page.

<<axiom javascript>>=

function init() {
}


function makeRequest() {
//    The following instantiation of the XMLHttpRequest object is for
//    browsers other than IE.  IE requires something different.
    http_request = new XMLHttpRequest();         
    var command = document.getElementById('comm').value;
    http_request.open('POST', '127.0.0.1:8085', true);
    http_request.onreadystatechange = handleResponse;
//    http_request.setRequestHeader('Content-Type', 
'application/x-www-form-urlencoded');
//    http_request.send("command="+encodeURIComponent(command));
    http_request.setRequestHeader('Content-Type', 'text/plain');
    http_request.send("command="+command);
}

function handleResponse() {
    if (http_request.readyState == 4) {
        if (http_request.status == 200) {
// stick response in div=mathBox
            var mathString = http_request.responseText;
            var mathRange = document.createRange();
            var mathBox = 
document.createElementNS('http://www.w3.org/1999/xhtml','div');
            mathRange.selectNodeContents(mathBox);
            var mathFragment = mathRange.createContextualFragment(mathString);
            mathBox.appendChild(mathFragment);
// set id on mathBox
//          var stepNum = mathBox.firstChild.firstChild.data;
//          mathBox.setAttribute('id', 'step'+stepNum);
//          mathBox.setAttribute('class', 'mathbox');
// remove old mathbox
            
document.getElementById('mathAns').removeChild(document.getElementById('mathAns').firstChild)

// insert everything into the document

            document.getElementById('mathAns').appendChild(mathBox);

// delete linenum box
//            mathBox.removeChild(mathBox.firstChild);

        } else
        {
            alert('There was a problem with the request.'+ 
http_request.statusText);
        }
    }
}

@

\section{Axiom xml}

Extract the Axiom xml interface page with the commmand

notangle -RAxiom\ xml axserver.pamphlet > axiom.xml

or in fact make the file name whatever you like instead of
"axiom.xml".

<<Axiom xml>>=
<?xml version="1.0" encoding="UTF-8"?>
<!--
<<license-xml>>
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN" 
"http://www.w3.org/Math/DTD/mathml2/xhtml-math11-f.dtd"; [
<!ENTITY mathml "http://www.w3.org/1998/Math/MathML";>
<!ENTITY InvisibleTimes " ">
]>

<html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:xlink="http://www.w3.org/1999/xlink";>

<head>
<title>Axiom Interface</title>
<script type="text/javascript">
<<axiom javascript>>
</script>

</head>

<body id="body">

  <form id="commreq" action="javascript:makeRequest();">
    <p>
      Enter command: <input type="text" id="comm" name="command" size="80"/>
      <input type="submit" value="submit command"/>
    </p>
  </form>

<div id="mathAns"><div></div></div>



</body>

</html>

@

\section{Running Axiom Server}

Put the extracted files in a suitable directory, like the one you
started Axiom from, and issue the commands:

)set output mathml on

)lisp (load "http.lisp")

)compile axserver

axServer(8085,mutliServ$AXSERV)


Of course you need a mathml enabled build of axiom to do this.
You may also want to issue the command

)set messages autoload off

before starting the Axiom server.


\section{License}
<<license>>=
--Copyright (c) 2007 Arthur C. Ralfs
--All rights reserved.
--
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
--
--    - Redistributions of source code must retain the above copyright
--      notice, this list of conditions and the following disclaimer.
--
--    - Redistributions in binary form must reproduce the above copyright
--      notice, this list of conditions and the following disclaimer in
--      the documentation and/or other materials provided with the
--      distribution.
--
--    - Neither the name of Arthur C. Ralfs nor the
--      names of its contributors may be used to endorse or promote products
--      derived from this software without specific prior written permission.
--
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


@

<<license-xml>>=
  Copyright (c) 2007 Arthur C. Ralfs
  All rights reserved.
  
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:
  
      - Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
  
      - Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in
        the documentation and/or other materials provided with the
        distribution.
  
      - Neither the name of Arthur C. Ralfs nor the
        names of its contributors may be used to endorse or promote products
        derived from this software without specific prior written permission.
  
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


@

<<*>>=
<<license>>
<<package AXSERV AxiomServer>>

@

\eject
\begin{thebibliography}{99}
\bibitem{1} nothing
\end{thebibliography}
\end{document}


=========================================================================
=== 20070811.01.tpd.patch 
=========================================================================
diff --git a/changelog b/changelog
index 7cbe49b..e3d84c9 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,13 @@
+20070811 tpd src/input/Makefile add mathml.input
+20070811 tpd src/input/mathml.input write test cases
+20070810 tpd readme add Arthur C. Ralfs
+20070810 tpd src/interp/setq.lisp add Arthur C. Ralfs
+20070810 tpd src/algebra/Makefile add mathml.spad
+20070810 acr src/algebra/exposed.lsp add (|MathMLFormat| . MMLFORM)
+20070810 acr src/interp/i-output.boot added mathml patch
+20070810 acr scr/interp/setvars.boot add mathml patch
+20070810 acr scr/interp/setvart.boot add mathml patch
+20070810 acr Arthur C. Ralfs <address@hidden>
 20070810 tpd src/interp/metameta.lisp removed (unused)
 20070810 tpd src/interp/ccl-depsys.lsp remove metameta
 20070810 tpd src/interp/parsing.lisp remove metameta
diff --git a/readme b/readme
index 112fa70..578fc37 100644
--- a/readme
+++ b/readme
@@ -221,9 +221,10 @@ at the axiom command prompt will prettyprint the list.
 "Michel Petitot         Didier Pinchon         Ayal Pinkus"
 "Jose Alfredo Portes"
 "Claude Quitte"
-"Norman Ramsey          Michael Richardson     Renaud Rioboo"
-"Jean Rivlin            Nicolas Robidoux       Simon Robinson"
-"Raymond Rogers         Michael Rothstein      Martin Rubey"
+"Arthur C. Ralfs        Norman Ramsey          Michael Richardson"
+"Renaud Rioboo          Jean Rivlin            Nicolas Robidoux"
+"Simon Robinson         Raymond Rogers         Michael Rothstein"
+"Martin Rubey"
 "Philip Santas          Alfred Scheerhorn      William Schelter"
 "Gerhard Schneider      Martin Schoenert       Marshall Schor"
 "Frithjof Schulze       Fritz Schwarz          Nick Simicich"
diff --git a/src/algebra/Makefile.pamphlet b/src/algebra/Makefile.pamphlet
index 987ea71..9172e69 100644
--- a/src/algebra/Makefile.pamphlet
+++ b/src/algebra/Makefile.pamphlet
@@ -743,7 +743,8 @@ view3d.spad.pamphlet (VIEW3D)
 
 LAYER17=\
   ${OUT}/CCLASS.o  ${OUT}/FSAGG2.o  ${OUT}/GALFACT.o ${OUT}/IALGFACT.o \
-  ${OUT}/IBACHIN.o ${OUT}/NORMMA.o  ${OUT}/ODERED.o  ${OUT}/OMSAGG.o   \
+  ${OUT}/IBACHIN.o ${OUT}/MMLFORM.o \
+  ${OUT}/NORMMA.o  ${OUT}/ODERED.o  ${OUT}/OMSAGG.o   \
   ${OUT}/PERM.o    ${OUT}/PERMGRP.o ${OUT}/PRIMES.o  ${OUT}/PWFFINTB.o \
   ${OUT}/RDIST.o   ${OUT}/SAE.o     ${OUT}/SAEFACT.o ${OUT}/SAERFFC.o  \
   ${OUT}/SGCF.o    ${OUT}/TBAGG.o   ${OUT}/TBAGG-.o  ${OUT}/VIEW3D.o  \
@@ -1249,7 +1250,8 @@ SPADFILES= \
  ${OUTSRC}/list.spad ${OUTSRC}/lmdict.spad ${OUTSRC}/lodof.spad \
  ${OUTSRC}/lodop.spad ${OUTSRC}/lodo.spad \
  ${OUTSRC}/manip.spad ${OUTSRC}/mappkg.spad ${OUTSRC}/matcat.spad \
- ${OUTSRC}/matfuns.spad ${OUTSRC}/matrix.spad ${OUTSRC}/matstor.spad \
+ ${OUTSRC}/matfuns.spad ${OUTSRC}/mathml.spad \
+ ${OUTSRC}/matrix.spad ${OUTSRC}/matstor.spad \
  ${OUTSRC}/mesh.spad ${OUTSRC}/mfinfact.spad ${OUTSRC}/misc.spad \
  ${OUTSRC}/mkfunc.spad ${OUTSRC}/mkrecord.spad \
  ${OUTSRC}/mlift.spad ${OUTSRC}/moddfact.spad ${OUTSRC}/modgcd.spad \
@@ -1409,7 +1411,8 @@ DOCFILES= \
  ${DOC}/list.spad.dvi ${DOC}/lmdict.spad.dvi ${DOC}/lodof.spad.dvi \
  ${DOC}/lodop.spad.dvi ${DOC}/lodo.spad.dvi \
  ${DOC}/manip.spad.dvi ${DOC}/mappkg.spad.dvi ${DOC}/matcat.spad.dvi \
- ${DOC}/matfuns.spad.dvi ${DOC}/matrix.spad.dvi ${DOC}/matstor.spad.dvi \
+ ${DOC}/matfuns.spad.dvi ${DOC}/mathml.spad.dvi \
+ ${DOC}/matrix.spad.dvi ${DOC}/matstor.spad.dvi \
  ${DOC}/mesh.spad.dvi ${DOC}/mfinfact.spad.dvi ${DOC}/misc.spad.dvi \
  ${DOC}/mkfunc.spad.dvi ${DOC}/mkrecord.spad.dvi ${DOC}/mlift.spad.jhd.dvi \
  ${DOC}/mlift.spad.dvi ${DOC}/moddfact.spad.dvi ${DOC}/modgcd.spad.dvi \
diff --git a/src/algebra/exposed.lsp.pamphlet b/src/algebra/exposed.lsp.pamphlet
index 498b79a..c893d91 100644
--- a/src/algebra/exposed.lsp.pamphlet
+++ b/src/algebra/exposed.lsp.pamphlet
@@ -207,6 +207,7 @@
   (|MappingPackage1| . MAPPKG1)
   (|MappingPackage2| . MAPPKG2)
   (|MappingPackage3| . MAPPKG3)
+  (|MathMLFormat| . MMLFORM)
   (|Matrix| . MATRIX)
   (|MatrixCategoryFunctions2| . MATCAT2)
   (|MatrixCommonDenominator| . MCDEN)
diff --git a/src/algebra/mathml.spad.pamphlet b/src/algebra/mathml.spad.pamphlet
new file mode 100644
index 0000000..c589e78
--- /dev/null
+++ b/src/algebra/mathml.spad.pamphlet
@@ -0,0 +1,1376 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra mathml.spad}
+\author{Arthur C. Ralfs}
+\maketitle
+\begin{abstract}
+MathMLFormat is a package to produce presentation mathematical
+markup language from OutputForm.
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{Preface}
+
+Both this code and documentation are still under development and
+I don't pretend they are anywhere close to perfect or even finished.
+However the code does work and I hope it might be useful to somebody
+both for it's ability to output MathML from Axiom and as an example
+of how to write a new output form.
+
+\section{Introduction to Mathematical Markup Language}
+
+MathML exists in two forms: presentation and content.
+At this time (2007-02-11) the package only has a presentation
+package.  A content package is in the
+works however it is more difficult.  Unfortunately Axiom does
+not make its semantics easliy available.  The \spadtype{OutputForm}
+domain mediates between the individual Axiom domains and the
+user visible output but \spadtype{OutputForm} does not provide full
+semantic information.  From my currently incomplete understanding
+of Axiom it appears that remedying this would entail going back
+to the individual domains and rewriting a lot of code.
+However some semantics are conveyed directly by \spadtype{OutputForm} and other
+things can be deduced from \spadtype{OutputForm} or form the original
+user command.
+
+\section{Displaying MathML}
+
+The MathML string produced by ")set output mathml on" can be pasted
+directly into an appropriate xhtml page and then viewed in Firefox
+or some other MathML aware browser. The boiler plate code needed for
+a test page, testmathml.xml, is:
+
+\begin{verbatim}
+<?xml version="1.0" ?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN"
+                      "http://www.w3.org/Math/DTD/mathml2/xhtml-math11-f.dtd"; [
+<!ENTITY mathml "http://www.w3.org/1998/Math/MathML";>
+]>
+
+<html xmlns="http://www.w3.org/1999/xhtml";
+      xmlns:xlink="http://www.w3.org/1999/xlink"; >
+
+
+  <head>
+    <title>MathML Test </title>
+  </head>
+
+  <body>
+
+  </body>
+</html>
+\end{verbatim}
+
+
+Paste the MathML string into the body element and it should display
+nicely in Firefox.
+
+\section{Test Cases}
+
+Here's a list of test cases that currently format correctly:
+
+1. (x+y)**2
+
+2. integrate(x**x,x)
+
+3. integral(x**x,x)
+
+4. (5 + sqrt 63 + sqrt 847)**(1/3)
+
+5. set $[$1,2,3$]$
+
+6. multiset $[$x rem 5 for x in primes(2,1000)$]$
+
+7. series(sin(a*x),x=0)
+
+8. matrix $[$ $[$x**i + y**j for i in 1..10$]$ for j in 1..10$]$
+
+9. y := operator 'y
+   a. D(y(x,z),$[$x,x,z,x$]$)
+   b. D(y x,x,2)
+
+10. x := series 'x
+    a. sin(1+x)
+
+11. series(1/log(y),y=1)
+
+12. y:UTS(FLOAT,'z,0) := exp(z)
+
+13. a. c := continuedFraction(314159/100000)
+    b. c := continuedFraction(314159/100000)
+
+The \spadtype{TexFormat} domain has the capability to format an object with
+subscripts, superscripts, presubscripts and presuperscripts however
+I don't know of any Axiom command that produces such an object. In
+fact at present I see the case of "SUPERSUB" being used for putting
+primes in the superscript position to denote ordinary differentiation.
+I also only see the "SUB" case being only used to denote partial
+derivatives.
+
+\section{)set output mathml on}
+
+
+Making mathml appear as output during a normal Axiom session
+by invoking ")set output mathml on" proved to be a bit tedious
+and seems to be undocumented.  I document my experience here
+in case in proves useful to somebody else trying to get a new
+output format from Axiom.
+
+In \spadtype{MathMLFormat} the functions 
+\spadfun{coerce(expr : OutputForm) : String} and
+\spadfun{display(s : String) : Void} provide the desired mathml output.
+Note that this package was constructed by close examination of
+Robert Sutor's \spadtype{TexFormat} domain and much remains from that source.
+To have mathml displayed as output we need to get Axiom to 
+call display(coerce(expr)) at the appropriate place.  Here's what
+I did to get that to happen. Note that my starting point here was
+an attempt by Andrey Grozin to do the same.  To figure things out
+I searched through files for "tex" to see what was done for the
+\spadtype{TexFormat} domain, and used grep to find which files had mention of
+\spadtype{TexFormat}.
+
+\subsection{File src/interp/setvars.boot.pamphlet}
+
+
+  Create an output mathml section by analogy to the tex section.
+Remember to add the code chunk "outputmathmlCode" at the end.
+
+setvars.boot is a bootstrap file which means that it has to be
+precompiled into lisp code and then that code has to be inserted
+back into setvars.boot. To do this extract the boot code by running
+"notangle" on it.  I did this from the "tmp" directory.
+From inside axiom run ")lisp (boottran::boottocl "tmp/setvars.boot")
+which put "setvars.clisp" into "int/interp/setvars.clisp".  Then
+replace the lisp in "setvars.boot.pamphlet" with that in the newly
+generated "setvars.clisp".
+
+The relevant code chunks appearing in "setvars.boot.pamphlet" are:
+\begin{verbatim}
+    outputmathmlCode
+    setOutputMathml
+    describeSetOutputMathml
+\end{verbatim}
+and the relevant variables are:
+\begin{verbatim}
+    setOutputMathml
+    $mathmlOutputStream
+    $mathmlOutputFile
+    $mathmlFormat
+    describeSetOutputMathml
+\end{verbatim}
+
+\subsection{File setvart.boot.pamphlet}
+
+
+Create an output mathml section in "setvart.boot.pamphlet" again
+patterned after the tex section.  I changed the default file 
+extension from ".stex" to ".smml".
+
+To the "section{output}" table I added the line
+\begin{verbatim}
+   mathml                 created output in MathML style       Off:CONSOLE
+\end{verbatim}
+Added the code chunk "outputmathml" to the code chunk "output"
+in "section{output}".
+
+Relevant code chunks:
+\begin{verbatim}
+        outputmathml
+\end{verbatim}
+Relevant variables:
+\begin{verbatim}
+        setOutputMathml
+        $mathmlFormat
+        $mathmlOutputFile
+\end{verbatim}
+
+Note when copying the tex stuff I changed occurrences of "tex"
+to "mathml", "Tex" to "Mathml" and "TeX" to "MathML".
+
+\subsection{File src/algebra/Makefile.pamphlet}
+
+
+The file "src/algebra/tex.spad.pamphlet" contains
+the domain \spadtype{TexFormat} (TEX) and the package 
+\spadtype{TexFormat1} (TEX1).
+However the sole function of \spadtype{TexFormat1} is to \spadfun{coerce}
+objects from a domain into \spadtype{OutputForm} and then apply 
+\spadtype{TexFormat}
+to them.  It is to save programmers the trouble of doing
+the coercion themselves from inside spad code.  It does
+not appear to be used for the main purpose of delivering
+Axiom output in TeX format.  In order to keep the mathml
+package as simple as possible, and because I didn't see much
+use for this, I didn't copy the \spadtype{TexFormat1} package.  So
+no analog of the TEX1 entries in "Makefile.pamphlet" were
+needed.  One curiosity I don't understand is why TEX1
+appears in layer 4 when it seems to depend on TEX which
+appears in layer 14.
+
+Initially I added "\${OUT}/MMLFORM.o" to layer 14 and
+"mathml.spad.pamphlet" to completed spad files in layer 14.
+When trying to compile the build failed at MMLFORM.  It left
+"MMLFORM.erlib" in "int/algebra" instead of "MMLFORM.NRLIB"
+which confused me at first because mathml.spad compiled
+under a running axiom.  By examining the file "obj/tmp/trace"
+I saw that a new dependency had been introduced, compared
+to TexFormat, with the function eltName depending on the
+domain FSAGG in layer 16.  So the lines had to be moved 
+from layer 14 to layer 17.
+
+Added appropriate lines to "SPADFILES" and "DOCFILES".
+
+\subsection{File src/algebra/exposed.lsp.pamphlet}
+
+Add the line "($\vert{}$MathMLFormat$\vert$ . MMLFORM)"
+
+\subsection{File src/algebra/Lattice.pamphlet}
+
+I don't see that this file is used anywhere but I made
+the appropriate changes anyway by searching for "TEX" and
+mimicing everthing for MMLFORM.
+
+\subsection{File src/doc/axiom.bib.pamphlet}
+
+Added mathml.spad subsection to "src/doc/axiom.bib.pamphlet".
+
+\subsection{File interp/i-output.boot.pamphlet}
+
+
+This is where the \spadfun{coerce} and \spadfun{display} functions 
+from MathMLFormat
+actually get called.  The following was added:
+
+\begin{verbatim}
+mathmlFormat expr ==
+  mml := '(MathMLFormat)
+  mmlrep := '(String)
+  formatFn := getFunctionFromDomain("coerce",mml,[$OutputForm])
+  displayFn := getFunctionFromDomain("display",mml,[mmlrep])
+  SPADCALL(SPADCALL(expr,formatFn),displayFn)
+  TERPRI $mathmlOutputStream
+  FORCE_-OUTPUT $mathmlOutputStream
+  NIL
+\end{verbatim}
+
+Note that compared to the texFormat function there are a couple
+of differences.  Since \spadtype{MathMLFormat} is currently a package rather
+than a domain there is the "mmlrep" variable whereas in texFormat
+the argument of the "display" function is an instance of the 
+domain.  Also the \spadfun{coerce} function here only has one argument,
+namely "\$OutputForm".
+
+Also for the function "output(expr,domain)" add lines for mathml,
+e.g. "if \$mathmlFormat then mathmlFormat expr".
+
+After these changes Axiom compiled with mathml enabled under
+)set output.
+
+\section{package MMLFORM MathMLFormat}
+
+\subsection{Public Declarations}
+
+The declarations
+\begin{verbatim}
+  E      ==> OutputForm
+  I      ==> Integer
+  L      ==> List
+  S      ==> String
+  US     ==> UniversalSegment(Integer)
+\end{verbatim}
+provide abbreviations for domains used heavily in the code.
+The publicly exposed functions are:
+
+    \spadfun{coerce: E -$>$ S}  This function is the main one for converting
+and expression in domain OutputForm into a MathML string.
+
+    \spadfun{coerceS: E -$>$ S}  This function is for use from the command 
line.
+It converts an OutputForm expression into a MathML string and does
+some formatting so that the output is not one long line.  If you take
+the output from this function, stick it in an emacs buffer in
+nxml-mode and then indent according to mode, you'll get something that's
+nicer to look at than comes from coerce. Note that coerceS returns
+the same value as coerce but invokes a display function as well so that
+the result will be printed twice in different formats.  The need for this
+is that the output from coerce is automatically formatted with line breaks
+by Axiom's output routine that are not in the right place.
+
+    \spadfun{coerceL: E -$>$ S}  Similar to coerceS except that the displayed 
result
+is the MathML string in one long line.  These functions can be used,
+for instance, to get the MathML for the previous result by typing
+coerceL(%)\$MMLFORM.
+
+    \spadfun{exprex: E -$>$ S}  Converts \spadtype{OutputForm} to 
+\spadtype{String} with
+the structure preserved with braces.  This is useful in developing this
+package. Actually this is not quite accurate.  The function
+\spadfun{precondition} is first applied to the \spadtype{OutputForm}
+expression before \spadfun{exprex}.   Raw \spadtype{OutputForm} and the nature
+of the \spadfun{precondition} function is still obscure to me at the time of
+this writing (2007-02-14), however I probably need to understand it to make
+sure I'm not missing any semantics.  The spad function \spadfun{precondition}
+is just a wrapper for the lisp function outputTran\$Lisp, which I guess is
+compiled from boot.
+
+    \spadfun{display: S -$>$ Void}  This one prints the string returned by 
coerce as one
+long line, adding "math" tags: $<$math ...$>$ ... $<$/math$>$.  Thus the output
+from this can be stuck directly into an appropriate html/xhtml page and will
+be displayed nicely by a MathML aware browser.
+
+    \spadfun{displayF: S -$>$ Void}  This function doesn't exist 
+yet but it would be nice
+to have a humanly readable formatted output as well.  The basics do exist in
+the coerceS function however the formatting still needs some work to be 
+really good.
+
+<<public declarations>>=
+)abbrev domain MMLFORM MathMLFormat
+++ Author: Arthur C. Ralfs
+++ Date: January 2007
+++ This package is based on the TeXFormat domain by Robert S. Sutor
+++ without which I wouldn't have known where to start.
+++ Basic Operations: coerce, coerceS, coerceL, exprex, display
+++ Description:
+++    \spadtype{MathMLFormat} provides a coercion from \spadtype{OutputForm}
+++    to MathML format.
+
+MathMLFormat(): public == private where
+  E      ==> OutputForm
+  I      ==> Integer
+  L      ==> List
+  S      ==> String
+  US     ==> UniversalSegment(Integer)
+
+  public == SetCategory with
+    coerce:    E -> S
+      ++ coerceS(o) changes o in the standard output format to MathML
+      ++ format.
+    coerceS:   E -> S
+      ++ coerceS(o) changes o in the standard output format to MathML
+      ++ format and displays formatted result.
+    coerceL:   E -> S
+      ++ coerceS(o) changes o in the standard output format to MathML
+      ++ format and displays result as one long string.
+    exprex:    E -> S
+      ++ coverts \spadtype{OutputForm} to \spadtype{String} with the
+      ++ structure preserved with braces.  Actually this is not quite
+      ++ accurate.  The function \spadfun{precondition} is first 
+      ++ applied to the
+      ++ \spadtype{OutputForm} expression before \spadfun{exprex}.  
+      ++ The raw \spadtype{OutputForm} and
+      ++ the nature of the \spadfun{precondition} function is 
+      ++ still obscure to me
+      ++ at the time of this writing (2007-02-14).
+    display:   S -> Void
+      ++ prints the string returned by coerce, adding <math ...> tags.
+
+@
+\subsection{Private Constant Declarations}
+<<private constant declarations>>=
+  private == add
+    import OutputForm
+    import Character
+    import Integer
+    import List OutputForm
+    import List String
+
+    -- local variables declarations and definitions
+
+    expr: E
+    prec,opPrec: I
+    str:  S
+    blank         : S := " \  "
+
+    maxPrec       : I   := 1000000
+    minPrec       : I   := 0
+
+    unaryOps      : L S := ["-","^"]$(L S)
+    unaryPrecs    : L I := [700,260]$(L I)
+
+    -- the precedence of / in the following is relatively low because
+    -- the bar obviates the need for parentheses.
+    binaryOps     : L S := ["+->","|","**","/","<",">","=","OVER"]$(L S)
+    binaryPrecs   : L I := [0,0,900, 700,400,400,400,   700]$(L I)
+
+    naryOps       : L S := ["-","+","*",blank,",",";"," ","ROW","",
+       " \cr ","&","</mtd></mtr><mtr><mtd>"]$(L S)
+    naryPrecs     : L I := [700,700,800,  800,110,110,  0,    0, 0,
+             0,  0,   0]$(L I)
+    naryNGOps     : L S := ["ROW","&"]$(L S)
+
+    plexOps       : L S := 
["SIGMA","SIGMA2","PI","PI2","INTSIGN","INDEFINTEGRAL"]$(L S)
+    plexPrecs     : L I := [    700, 800,     700, 800 , 700,      700]$(L I)
+
+    specialOps    : L S := ["MATRIX","BRACKET","BRACE","CONCATB","VCONCAT",  _
+                            "AGGLST","CONCAT","OVERBAR","ROOT","SUB","TAG", _
+                            "SUPERSUB","ZAG","AGGSET","SC","PAREN", _
+                            "SEGMENT","QUOTE","theMap" ]
+
+    -- the next two lists provide translations for some strings for
+    -- which MML provides special macros.
+
+    specialStrings : L S :=
+      ["cos", "cot", "csc", "log", "sec", "sin", "tan",
+        "cosh", "coth", "csch", "sech", "sinh", "tanh",
+          "acos","asin","atan","erf","...","$","infinity"]
+    specialStringsInMML : L S :=
+      
["<mo>cos</mo>","<mo>cot</mo>","<mo>csc</mo>","<mo>log</mo>","<mo>sec</mo>","<mo>sin</mo>","<mo>tan</mo>",
+        
"<mo>cosh</mo>","<mo>coth</mo>","<mo>csch</mo>","<mo>sech</mo>","<mo>sinh</mo>","<mo>tanh</mo>",
+          
"<mo>arccos</mo>","<mo>arcsin</mo>","<mo>arctan</mo>","<mo>erf</mo>","<mo>&#x2026;</mo>","<mo>$</mo>","<mo>&#x221E;</mo>"]
+
+@
+\subsection{Private Function Declarations}
+
+These are the local functions:
+
+    addBraces:S -$>$ S
+
+    addBrackets:S -$>$ S
+
+    atomize:E -$>$ L E
+
+    displayElt:S -$>$ Void
+      function for recursively displaying mathml nicely formatted
+
+    eltLimit:(S,I,S) -$>$ I
+      demarcates end postion of mathml element with name:S starting at
+      position i:I in mathml string s:S and returns end of end tag as
+      i:I position in mathml string, i.e. find start and end of
+      substring:  $<$name ...$>$...$<$/name$>$
+
+    eltName:(I,S) -$>$ S
+      find name of mathml element starting at position i:I in string s:S
+
+    group:S -$>$ S
+
+    formatBinary:(S,L E, I) -$>$ S
+
+    formatFunction:(S,L E, I) -$>$ S
+
+    formatMatrix:L E -$>$ S
+
+    formatNary:(S,L E, I) -$>$ S
+
+    formatNaryNoGroup:(S,L E, I) -$>$ S
+
+    formatNullary:S -$>$ S
+
+    formatPlex:(S,L E, I) -$>$ S
+
+    formatSpecial:(S,L E, I) -$>$ S
+
+    formatUnary:(S,  E, I) -$>$ S
+
+    formatMml:(E,I) -$>$ S
+
+    newWithNum:I -$>$ \$
+      this is a relic from tex.spad and is not used here so far.  I'll
+      probably remove it.
+
+    parenthesize:S -$>$ S
+
+    precondition:E -$>$ E
+      this function is applied to the OutputForm expression before
+      doing anything else.
+
+    postcondition:S -$>$ S
+      this function is applied after all other OutputForm -$>$ MathML
+      transformations.  In the TexFormat domain the ungroup function
+      first peels off the outermost set of braces however I have 
+      replaced braces with $<$mrow$>$s here and sometimes the outermost set
+      of $<$mrow$>$s is necessary to get proper display in Firefox.  
+      For instance with getting the correct size of brackets on a matrix 
+      the whole expression needs to be enclosed in a mrow element.  
+      It also checks for $+-$ and removes the $+$.
+
+    stringify:E -$>$ S
+
+    tagEnd:(S,I,S) -$>$ I
+      finds closing "$>$" of start or end tag for mathML element for formatting
+      MathML string for human readability.  No analog in TexFormat.
+
+    ungroup:S -$>$ S
+
+<<private function declarations>>=
+    -- local function signatures
+
+    addBraces:      S -> S
+    addBrackets:    S -> S
+    atomize:        E -> L E
+    displayElt:     S -> Void
+      ++ function for recursively displaying mathml nicely formatted
+    eltLimit:       (S,I,S) -> I
+      ++ demarcates end postion of mathml element with name:S starting at
+      ++ position i:I in mathml string s:S and returns end of end tag as
+      ++  i:I position in mathml string, i.e. find start and end of
+      ++  substring:  <name ...>...</name>
+    eltName:        (I,S) -> S
+      ++ find name of mathml element starting at position i:I in string s:S
+    group:          S -> S
+    formatBinary:   (S,L E, I) -> S
+    formatFunction: (S,L E, I) -> S
+    formatIntSign:  (L E, I) -> S
+    formatMatrix:   L E -> S
+    formatNary:     (S,L E, I) -> S
+    formatNaryNoGroup: (S,L E, I) -> S
+    formatNullary:  S -> S
+    formatPlex:     (S,L E, I) -> S
+    formatSpecial:  (S,L E, I) -> S
+    formatSub:      (E, L E, I) -> S
+    formatSuperSub: (E, L E, I) -> S
+    formatSuperSub1: (E, L E, I) -> S
+    formatUnary:    (S,  E, I) -> S
+    formatMml:      (E,I) -> S
+    formatZag:      L E -> S
+    formatZag1:     L E -> S
+    newWithNum:     I -> $
+    parenthesize:   S -> S
+    precondition:   E -> E
+    postcondition:  S -> S
+    stringify:      E -> S
+    tagEnd:         (S,I,S) -> I
+      ++  finds closing ">" of start or end tag for mathML element
+    ungroup:        S -> S
+
+@
+\subsection{Public Function Definitions}
+
+Note that I use the function sayTeX\$Lisp much as I would printf in a
+C program.  I've noticed in grepping the code that there are other "say"
+functions, sayBrightly and sayMessage for instance, but I have no idea
+what the difference is between them at this point.  sayTeX\$Lisp does the
+job so for the time being I'll use that until I learn more.
+
+The functions coerceS and coerceL should probably be changed to display
+functions, {\it i.e.}\/ \spadfun{displayS} and \spadfun{display L}, 
+returning Void.  I really only need the one coerce function.
+
+<<public function definitions>>=
+    -- public function definitions
+
+    coerce(expr : E): S ==
+      s : S := postcondition formatMml(precondition expr, minPrec)
+      s
+
+    coerceS(expr : E): S ==
+      s : S := postcondition formatMml(precondition expr, minPrec)
+      sayTeX$Lisp "<math xmlns=_"http://www.w3.org/1998/Math/MathML_"; 
mathsize=_"big_" display=_"block_">"
+      displayElt(s)
+      sayTeX$Lisp "</math>"
+      s
+
+    coerceL(expr : E): S ==
+      s : S := postcondition formatMml(precondition expr, minPrec)
+      sayTeX$Lisp "<math xmlns=_"http://www.w3.org/1998/Math/MathML_"; 
mathsize=_"big_" display=_"block_">"
+      sayTeX$Lisp s
+      sayTeX$Lisp "</math>"
+      s
+
+    display(mathml : S): Void ==
+      sayTeX$Lisp "<math xmlns=_"http://www.w3.org/1998/Math/MathML_"; 
mathsize=_"big_" display=_"block_">"
+      sayTeX$Lisp mathml
+      sayTeX$Lisp "</math>"
+      void()$Void
+
+      
+
+    exprex(expr : E): S ==
+      -- This breaks down an expression into atoms and returns it as
+      -- a string.  It's for developmental purposes to help understand
+      -- the expressions.
+      a : E
+      expr := precondition expr
+--      sayTeX$Lisp "0: "stringify expr
+      (ATOM(expr)address@hidden) or (stringify expr = "NOTHING") => 
+        concat ["{",stringify expr,"}"]      
+      le : L E := (expr pretend L E)
+      op := first le
+      sop : S := exprex op
+      args : L E := rest le
+      nargs : I := #args
+--      sayTeX$Lisp concat ["1: ",stringify first le," : ",string(nargs)$S]
+      s : S := concat ["{",sop]
+      if nargs > 0  then
+        for a in args repeat
+--       sayTeX$Lisp concat ["2: ",stringify a]
+         s1 : S := exprex a
+         s := concat [s,s1]
+      s := concat [s,"}"]
+
+@
+\subsection{Private Function Definitions}
+
+\subsubsection{Display Functions}
+
+    displayElt(mathml:S):Void
+
+    eltName(pos:I,mathml:S):S
+
+    eltLimit(name:S,pos:I,mathml:S):I
+
+    tagEnd(name:S,pos:I,mathml:S):I
+
+<<display functions>>=
+
+    displayElt(mathML:S): Void ==
+      -- Takes a string of syntactically complete mathML
+      -- and formats it for display.
+--      sayTeX$Lisp "****displayElt1****"
+--      sayTeX$Lisp mathML
+      enT:I -- marks end of tag, e.g. "<name>"
+      enE:I -- marks end of element, e.g. "<name> ... </name>"
+      end:I -- marks end of mathML string
+      u:US
+      end := #mathML
+      length:I := 60
+--      sayTeX$Lisp "****displayElt1.1****"
+      name:S := eltName(1,mathML)
+--      sayTeX$Lisp name
+--      sayTeX$Lisp concat("****displayElt1.2****",name)
+      enE := eltLimit(name,2+#name,mathML)
+--      sayTeX$Lisp "****displayElt2****"
+      if enE < length then
+--        sayTeX$Lisp "****displayElt3****"
+        u := segment(1,enE)$US
+       sayTeX$Lisp mathML.u
+      else
+--        sayTeX$Lisp "****displayElt4****"
+        enT := tagEnd(name,1,mathML)
+       u := segment(1,enT)$US
+       sayTeX$Lisp mathML.u
+       u := segment(enT+1,enE-#name-3)$US
+       displayElt(mathML.u)
+       u := segment(enE-#name-2,enE)$US
+       sayTeX$Lisp mathML.u
+      if end > enE then
+--        sayTeX$Lisp "****displayElt5****"
+        u := segment(enE+1,end)$US
+        displayElt(mathML.u)
+
+      void()$Void
+
+    eltName(pos:I,mathML:S): S ==
+      -- Assuming pos is the position of "<" for a start tag of a mathML
+      -- element finds and returns the element's name.
+      i:I := pos+1
+      --sayTeX$Lisp "eltName:mathmML string: "mathML
+      while member?(mathML.i,lowerCase()$CharacterClass)$CharacterClass repeat
+         i := i+1
+      u:US := segment(pos+1,i-1)
+      name:S := mathML.u
+
+    eltLimit(name:S,pos:I,mathML:S): I ==
+      -- Finds the end of a mathML element like "<name ...> ... </name>"
+      -- where pos is the position of the space after name in the start tag
+      -- although it could point to the closing ">".  Returns the position
+      -- of the ">" in the end tag.
+      pI:I := pos
+      startI:I
+      endI:I
+      startS:S := concat ["<",name]
+      endS:S := concat ["</",name,">"]
+      level:I := 1
+      --sayTeX$Lisp "eltLimit: element name: "name
+      while (level > 0) repeat
+        startI := position(startS,mathML,pI)$String
+
+       endI := position(endS,mathML,pI)$String
+
+       if (startI = 0) then
+         level := level-1
+          --sayTeX$Lisp "****eltLimit 1******"
+         pI := tagEnd(name,endI,mathML)
+       else
+         if (startI < endI) then
+           level := level+1
+           pI := tagEnd(name,startI,mathML)
+         else
+           level := level-1
+           pI := tagEnd(name,endI,mathML)
+      pI
+
+
+    tagEnd(name:S,pos:I,mathML:S):I ==
+      -- Finds the closing ">" for either a start or end tag of a mathML
+      -- element, so the return value is the position of ">" in mathML.
+      pI:I := pos
+      while  (mathML.pI ^= char ">") repeat
+        pI := pI+1
+      u:US := segment(pos,pI)$US
+      --sayTeX$Lisp "tagEnd: "mathML.u
+      pI
+
+@
+\subsubsection{Formatting Functions}
+
+Still need to format \verb+\zag+ in formatSpecial!
+
+In formatPlex the case op = "INTSIGN" is now passed off to
+formatIntSign which is a change from the TexFormat domain.
+This is done here for presentation mark up to replace the
+ugly bound variable that Axiom delivers.  For content mark up
+this has to be done anyway.  
+
+The formatPlex function also allows for op = "INDEFINTEGRAL".
+However I don't know what Axiom command gives rise to this case.
+The INTSIGN case already allows for both definite and indefinite
+integrals.
+
+In the function formatSpecial various cases are handled including
+SUB and SUPERSUB.  These cases are now caught in formatMml and so
+the code in formatSpecial doesn't get executed.  The only cases
+I know of using these are partial derivatives for SUB and ordinary
+derivatives or SUPERSUB however in TexFormat the capability is there
+to handle multiscripts, i.e. an object with subscripts, superscripts,
+pre-subscripts and pre-superscripts but I am so far unaware of any
+Axiom command that produces such a multiscripted object.
+
+Another question is how to represent derivatives.  At present I have
+differential notation for partials and prime notation for ordinary 
+derivatives, 
+but it would be nice to allow for different derivative notations in 
+different circumstances, maybe some options to )set output mathml on.
+
+Ordinary derivatives are formatted in formatSuperSub and there are
+2 versions, formatSuperSub and formatSuperSub1, which at this point
+have to be switched by swapping names.
+
+<<formatting functions>>=
+
+    atomize(expr : E): L E ==
+      -- This breaks down an expression into a flat list of atomic expressions.
+      -- expr should be preconditioned.
+      le : L E := nil()
+      a : E
+      letmp : L E
+      (ATOM(expr)address@hidden) or (stringify expr = "NOTHING") => 
+        le := append(le,list(expr))
+      letmp := expr pretend L E
+      for a in letmp repeat
+        le := append(le,atomize a)
+      le
+       
+
+    ungroup(str: S): S ==
+      len : I := #str
+      len < 14 => str
+      lrow : S :=  "<mrow>"
+      rrow : S :=  "</mrow>"
+      -- drop leading and trailing mrows
+      u1 : US := segment(1,6)$US
+      u2 : US := segment(len-6,len)$US
+      if (str.u1 =$S lrow) and (str.u2 =$S rrow) then
+        u : US := segment(7,len-7)$US
+        str := str.u
+      str
+
+    postcondition(str: S): S ==
+--      str := ungroup str
+      len : I := #str
+      plusminus : S := "<mo>+</mo><mo>-</mo>"
+      pos : I := position(plusminus,str,1)
+      if pos > 0 then
+        ustart:US := segment(1,pos-1)$US
+       uend:US := segment(pos+20,len)$US
+        str := concat [str.ustart,"<mo>-</mo>",str.uend]
+       if pos < len-18 then
+         str := postcondition(str)
+      str
+
+
+
+    stringify expr == (object2String$Lisp expr)@S
+
+
+
+    group str ==
+      concat ["<mrow>",str,"</mrow>"]
+
+    addBraces str ==
+      concat ["<mo>{</mo>",str,"<mo>}</mo>"]
+
+    addBrackets str ==
+      concat ["<mo>[</mo>",str,"<mo>]</mo>"]
+
+    parenthesize str ==
+      concat ["<mo>(</mo>",str,"<mo>)</mo>"]
+
+    precondition expr ==
+      outputTran$Lisp expr
+
+    formatSpecial(op : S, args : L E, prec : I) : S ==
+      arg : E
+      prescript : Boolean := false
+      op = "theMap" => "<mtext>theMap(...)</mtext>"
+      op = "AGGLST" =>
+        formatNary(",",args,prec)
+      op = "AGGSET" =>
+        formatNary(";",args,prec)
+      op = "TAG" =>
+        group concat [formatMml(first args,prec),
+                      "<mo>&#x02192;</mo>",
+                        formatMml(second args,prec)]
+                        --RightArrow
+      op = "VCONCAT" =>
+        group concat("<mtable><mtr>",
+                     concat(concat([concat("<mtd>",concat(formatMml(u, 
minPrec),"</mtd>"))
+                                    for u in args]::L S),
+                            "</mtr></mtable>"))
+      op = "CONCATB" =>
+        formatNary(" ",args,prec)
+      op = "CONCAT" =>
+        formatNary("",args,minPrec)
+      op = "QUOTE" =>
+        group concat("<mo>'</mo>",formatMml(first args, minPrec))
+      op = "BRACKET" =>
+        group addBrackets ungroup formatMml(first args, minPrec)
+      op = "BRACE" =>
+        group addBraces ungroup formatMml(first args, minPrec)
+      op = "PAREN" =>
+        group parenthesize ungroup formatMml(first args, minPrec)
+      op = "OVERBAR" =>
+        null args => ""
+        group concat ["<mover accent='true'><mrow>",formatMml(first 
args,minPrec),"</mrow><mo stretchy='true'>&#x000AF;</mo></mover>"]
+        --OverBar
+      op = "ROOT" =>
+        null args => ""
+        tmp : S := group formatMml(first args, minPrec)
+        null rest args => concat ["<msqrt>",tmp,"</msqrt>"]
+        group concat
+         ["<mroot><mrow>",tmp,"</mrow>",formatMml(first rest args, 
minPrec),"</mroot>"]
+      op = "SEGMENT" =>
+        tmp : S := concat [formatMml(first args, minPrec),"<mo>..</mo>"]
+        group
+          null rest args =>  tmp
+          concat [tmp,formatMml(first rest args, minPrec)]
+      -- SUB should now be diverted in formatMml although I'll leave
+      -- the code here for now.
+      op = "SUB" =>
+        group concat ["<msub>",formatMml(first args, minPrec),
+          formatSpecial("AGGLST",rest args,minPrec),"</msub>"]
+      -- SUPERSUB should now be diverted in formatMml although I'll leave
+      -- the code here for now.
+      op = "SUPERSUB" =>
+        base:S := formatMml(first args, minPrec)
+       args := rest args
+       if #args = 1 then
+         "<msub><mrow>"base"</mrow><mrow>"formatMml(first args, 
minPrec)"</mrow></msub>"
+       else if #args = 2 then
+       -- it would be nice to substitue &#x2032; for , in the case of
+       -- an ordinary derivative, it looks a lot better.
+         "<msubsup><mrow>"base"</mrow><mrow>"formatMml(first 
args,minPrec)"</mrow><mrow>"formatMml(first rest args, 
minPrec)"</mrow></msubsup>"
+       else if #args = 3 then
+         "<mmultiscripts><mrow>"base"</mrow><mrow>"formatMml(first 
args,minPrec)"</mrow><mrow>"formatMml(first rest 
args,minPrec)"</mrow><mprescripts/><mrow>"formatMml(first rest rest 
args,minPrec)"</mrow><none/></mmultiscripts>"
+       else if #args = 4 then
+         "<mmultiscripts><mrow>"base"</mrow><mrow>"formatMml(first 
args,minPrec)"</mrow><mrow>"formatMml(first rest 
args,minPrec)"</mrow><mprescripts/><mrow>"formatMml(first rest rest 
args,minPrec)"</mrow><mrow>"formatMml(first rest rest rest 
args,minPrec)"</mrow></mmultiscripts>"
+       else
+         "<mtext>Problem with multiscript object</mtext>"
+      op = "SC" =>
+        -- need to handle indentation someday
+        null args => ""
+        tmp := formatNaryNoGroup("</mtd></mtr><mtr><mtd>", args, minPrec)
+        group concat ["<mtable><mtr><mtd>",tmp,"</mtd></mtr></mtable>"]
+      op = "MATRIX" => formatMatrix rest args
+      op = "ZAG" =>
+-- 
{{+}{3}{{ZAG}{1}{7}}{{ZAG}{1}{15}}{{ZAG}{1}{1}}{{ZAG}{1}{25}}{{ZAG}{1}{1}}{{ZAG}{1}{7}}{{ZAG}{1}{4}}}
+-- to format continued fraction traditionally need to intercept it at the
+-- formatNary of the "+"
+        concat [" \zag{",formatMml(first args, minPrec),"}{",
+          formatMml(first rest args,minPrec),"}"]
+      concat ["<mtext>not done yet for: ",op,"</mtext>"]
+
+    formatSub(expr : E, args : L E, opPrec : I) : S ==
+      -- This one produces differential notation partial derivatives.
+      -- At this time this is only to handle partial derivatives.
+      -- If the SUB case handles anything else I'm not aware of it.
+      -- This an example of the 4th partial of y(x,z) w.r.t. x,x,z,x
+      -- 
{{{SUB}{y}{{CONCAT}{{CONCAT}{{CONCAT}{{CONCAT}{,}{1}}{{CONCAT}{,}{1}}}{{CONCAT}{,}{2}}}{{CONCAT}{,}{1}}}}{x}{z}}
+      atomE : L E := atomize(expr)      
+      op : S := stringify first atomE
+      op ^= "SUB" => "<mtext>Mistake in formatSub: no SUB</mtext>"
+      stringify first rest rest atomE ^= "CONCAT" => "<mtext>Mistake in 
formatSub: no CONCAT</mtext>"
+      -- expecting form for atomE like
+      --[{SUB}{func}{CONCAT}...{CONCAT}{,}{n}{CONCAT}{,}{n}...{CONCAT}{,}{n}],
+      --counting the first CONCATs before the comma gives the number of
+      --derivatives
+      ndiffs : I := 0
+      tmpLE : L E := rest rest atomE
+      while stringify first tmpLE = "CONCAT" repeat
+        ndiffs := ndiffs+1
+       tmpLE := rest tmpLE
+      numLS : L S := nil
+      i : I := 1
+      while i < ndiffs repeat
+        numLS := append(numLS,list(stringify first rest tmpLE))
+       tmpLE := rest rest rest tmpLE
+       i := i+1
+      numLS := append(numLS,list(stringify first rest tmpLE))
+      -- numLS contains the numbers of the bound variables as strings
+      -- for the differentiations, thus for the differentiation [x,x,z,x]
+      -- for y(x,z) numLS = ["1","1","2","1"]
+      posLS : L S := nil
+      i := 0
+ --     sayTeX$Lisp "formatSub: nargs = "string(#args)
+      while i < #args repeat
+        posLS := append(posLS,list(string(i+1)))
+       i := i+1
+      -- posLS contains the positions of the bound variables in args
+      -- as a list of strings, e.g. for the above example ["1","2"]
+      tmpS: S := stringify atomE.2
+      if ndiffs = 1 then
+        s : S := "<mfrac><mo>&#x02202;</mo><mi>"tmpS"</mi><mrow>"
+      else        
+        s : S := 
"<mfrac><mrow><msup><mo>&#x02202;</mo><mn>"string(ndiffs)"</mn></msup><mi>"tmpS"</mi></mrow><mrow>"
+      -- need to find the order of the differentiation w.r.t. the i-th
+      -- variable
+      i := 1
+      j : I
+      k : I
+      tmpS: S
+      while i < #posLS+1 repeat
+       j := 0
+       k := 1
+       while k < #numLS + 1 repeat
+         if numLS.k = string i then j := j + 1
+         k := k+1
+        if j > 0 then
+         tmpS := stringify args.i
+         if j = 1 then
+           s := s"<mo>&#x02202;</mo><mi>"tmpS"</mi>"
+         else
+           s := 
s"<mo>&#x02202;</mo><msup><mi>"tmpS"</mi><mn>"string(j)"</mn></msup>"
+        i := i + 1
+      s := s"</mrow></mfrac><mo>(</mo>"
+      i := 1
+      while i < #posLS+1 repeat
+        tmpS := stringify args.i
+       s := s"<mi>"tmpS"</mi>"
+       if i < #posLS then s := s"<mo>,</mo>"
+       i := i+1
+      s := s"<mo>)</mo>"
+
+    formatSub1(expr : E, args : L E, opPrec : I) : S ==
+      -- This one produces partial derivatives notated by ",n" as
+      -- subscripts.
+      -- At this time this is only to handle partial derivatives.
+      -- If the SUB case handles anything else I'm not aware of it.
+      -- This an example of the 4th partial of y(x,z) w.r.t. x,x,z,x
+      -- {{{SUB}{y}{{CONCAT}{{CONCAT}{{CONCAT}{{CONCAT}{,}{1}}
+      -- {{CONCAT}{,}{1}}}{{CONCAT}{,}{2}}}{{CONCAT}{,}{1}}}}{x}{z}},
+      -- here expr is everything in the first set of braces and 
+      -- args is {{x}{z}}
+      atomE : L E := atomize(expr)      
+      op : S := stringify first atomE
+      op ^= "SUB" => "<mtext>Mistake in formatSub: no SUB</mtext>"
+      stringify first rest rest atomE ^= "CONCAT" => "<mtext>Mistake in 
formatSub: no CONCAT</mtext>"
+      -- expecting form for atomE like
+      --[{SUB}{func}{CONCAT}...{CONCAT}{,}{n}{CONCAT}{,}{n}...{CONCAT}{,}{n}],
+      --counting the first CONCATs before the comma gives the number of
+      --derivatives
+      ndiffs : I := 0
+      tmpLE : L E := rest rest atomE
+      while stringify first tmpLE = "CONCAT" repeat
+        ndiffs := ndiffs+1
+       tmpLE := rest tmpLE
+      numLS : L S := nil
+      i : I := 1
+      while i < ndiffs repeat
+        numLS := append(numLS,list(stringify first rest tmpLE))
+       tmpLE := rest rest rest tmpLE
+       i := i+1
+      numLS := append(numLS,list(stringify first rest tmpLE))
+      -- numLS contains the numbers of the bound variables as strings
+      -- for the differentiations, thus for the differentiation [x,x,z,x]
+      -- for y(x,z) numLS = ["1","1","2","1"]
+      posLS : L S := nil
+      i := 0
+ --     sayTeX$Lisp "formatSub: nargs = "string(#args)
+      while i < #args repeat
+        posLS := append(posLS,list(string(i+1)))
+       i := i+1
+      -- posLS contains the positions of the bound variables in args
+      -- as a list of strings, e.g. for the above example ["1","2"]
+      funcS: S := stringify atomE.2
+      s : S := "<msub><mi>"funcS"</mi><mrow>"
+      i := 1
+      while i < #numLS+1 repeat
+        s := s"<mo>,</mo><mn>"numLS.i"</mn>"
+       i := i + 1
+      s := s"</mrow></msub><mo>(</mo>"
+      i := 1
+      while i < #posLS+1 repeat
+        tmpS := stringify args.i
+       s := s"<mi>"tmpS"</mi>"
+       if i < #posLS then s := s"<mo>,</mo>"
+       i := i+1
+      s := s"<mo>)</mo>"
+
+    formatSuperSub1(expr : E, args : L E, opPrec : I) : S ==
+      -- this produces differential notation ordinary derivatives.
+      -- first have to divine the semantics, add cases as needed
+      atomE : L E := atomize(expr)      
+      op : S := stringify first atomE
+      op ^= "SUPERSUB" => "<mtext>Mistake in formatSuperSub: no 
SUPERSUB</mtext>"
+      #args ^= 1 => "<mtext>Mistake in SuperSub: #args <> 1</mtext>"
+      var : E := first args
+      -- should be looking at something like {{SUPERSUB}{var}{ }{,,...,}} for
+      -- example here's the second derivative of y w.r.t. x
+      -- {{{SUPERSUB}{y}{ }{,,}}{x}}, expr is the first {} and args is the
+      -- {x}
+      funcS : S := stringify first rest atomE
+      bvarS : S := stringify first args
+      -- count the number of commas
+      commaS : S := stringify first rest rest rest atomE
+      commaTest : S := ","
+      i : I := 0
+      while position(commaTest,commaS,1) > 0 repeat
+        i := i+1
+       commaTest := commaTest","
+      s : S := "<msup><mi>"funcS"</mi><mrow>"
+      j : I := 0
+      while j < i repeat
+        s := s"<mo>&#x02032;</mo>"
+       j := j + 1
+      s := 
s"</mrow></msup><mo>&#x02061;</mo><mo>(</mo><mi>"bvarS"</mi><mo>)</mo>"
+
+    formatSuperSub(expr : E, args : L E, opPrec : I) : S ==
+      -- This one produces ordinary derivatives with prime notation.
+      -- first have to divine the semantics, add cases as needed
+      atomE : L E := atomize(expr)      
+      op : S := stringify first atomE
+      op ^= "SUPERSUB" => "<mtext>Mistake in formatSuperSub: no 
SUPERSUB</mtext>"
+      #args ^= 1 => "<mtext>Mistake in SuperSub: #args <> 1</mtext>"
+      var : E := first args
+      -- should be looking at something like {{SUPERSUB}{var}{ }{,,...,}} for
+      -- example here's the second derivative of y w.r.t. x
+      -- {{{SUPERSUB}{y}{ }{,,}}{x}}, expr is the first {} and args is the
+      -- {x}
+      funcS : S := stringify first rest atomE
+      bvarS : S := stringify first args
+      -- count the number of commas
+      commaS : S := stringify first rest rest rest atomE
+      commaTest : S := ","
+      ndiffs : I := 0
+      while position(commaTest,commaS,1) > 0 repeat
+        ndiffs := ndiffs+1
+       commaTest := commaTest","
+      s : S := 
"<mfrac><mrow><msup><mo>&#x02146;</mo><mn>"string(ndiffs)"</mn></msup><mi>"funcS"</mi></mrow><mrow><mo>&#x02146;</mo><msup><mi>"bvarS"</mi><mn>"string(ndiffs)"</mn></msup></mrow></mfrac><mo>&#x02061;</mo><mo>(</mo><mi>"bvarS"</mi><mo>)</mo>"
+
+    formatPlex(op : S, args : L E, prec : I) : S ==
+      hold : S
+      p : I := position(op,plexOps)
+      p < 1 => error "unknown plex op"
+      op = "INTSIGN" => formatIntSign(args,minPrec)
+      opPrec := plexPrecs.p
+      n : I := #args
+      (n ^= 2) and (n ^= 3) => error "wrong number of arguments for plex"
+      s : S :=
+        op = "SIGMA"   => "<mo>&#x02211;</mo>"
+       -- Sum
+        op = "SIGMA2"   => "<mo>&#x02211;</mo>"
+       -- Sum
+        op = "PI"      => "<mo>&#x0220F;</mo>"
+       -- Product
+        op = "PI2"     => "<mo>&#x0220F;</mo>"
+       -- Product
+--        op = "INTSIGN" => "<mo>&#x0222B;</mo>"
+       -- Integral, int
+        op = "INDEFINTEGRAL" => "<mo>&#x0222B;</mo>"
+       -- Integral, int
+        "????"
+      hold := formatMml(first args,minPrec)
+      args := rest args
+      if op ^= "INDEFINTEGRAL" then
+        if hold ^= "" then
+          s := concat ["<munderover>",s,group hold]
+       else
+         s := concat ["<munderover>",s,group " "]
+        if not null rest args then
+          hold := formatMml(first args,minPrec)
+         if hold ^= "" then
+            s := concat [s,group hold,"</munderover>"]
+         else
+           s := concat [s,group " ","</munderover>"]
+          args := rest args
+        s := concat [s,formatMml(first args,minPrec)]
+      else
+        hold := group concat [hold,formatMml(first args,minPrec)]
+        s := concat [s,hold]
+--      if opPrec < prec then s := parenthesize s
+-- getting ugly parentheses on fractions
+      group s
+
+    formatIntSign(args : L E, opPrec : I) : S ==
+      -- the original OutputForm expression looks something like this:
+      -- {{INTSIGN}{NOTHING or lower limit?}
+      -- {bvar or upper limit?}{{*}{integrand}{{CONCAT}{d}{axiom var}}}}
+      -- the args list passed here consists of the rest of this list, i.e.
+      -- starting at the NOTHING or ...
+      (stringify first args) = "NOTHING" =>
+        -- the bound variable is the second one in the argument list
+       bvar : E := first rest args
+       bvarS : S := stringify bvar
+       tmpS : S
+       i : I := 0
+       u1 : US
+       u2 : US
+       -- this next one atomizes the integrand plus differential
+       atomE : L E := atomize(first rest rest args)
+       -- pick out the bound variable used by axiom
+       varRS : S := stringify last(atomE)
+       tmpLE : L E := ((first rest rest args) pretend L E)
+        integrand : S := formatMml(first rest tmpLE,minPrec)
+       -- replace the bound variable, i.e. axiom uses someting of the form
+       -- %A for the bound variable and puts the original variable used
+       -- in the input command as a superscript on the integral sign.
+       -- I'm assuming that the axiom variable is 2 characters.
+       while (i := position(varRS,integrand,i+1)) > 0 repeat
+         u1 := segment(1,i-1)$US
+         u2 := segment(i+2,#integrand)$US
+         integrand := concat [integrand.u1,bvarS,integrand.u2]
+       concat ["<mrow><mo>&#x0222B;</mo>" integrand "<mo>&#x02146;</mo><mi>" 
bvarS "</mi></mrow>"]
+
+      lowlim : S := stringify first args
+      highlim : S := stringify first rest args
+      bvar : E := last atomize(first rest rest args)
+      bvarS : S := stringify bvar
+      tmpLE : L E := ((first rest rest args) pretend L E)
+      integrand : S := formatMml(first rest tmpLE,minPrec)
+      concat ["<mrow><munderover><mo>&#x0222B;</mo><mi>" lowlim "</mi><mi>" 
highlim "</mi></munderover>" integrand "<mo>&#x02146;</mo><mi>" bvarS 
"</mi></mrow>"] 
+
+
+    formatMatrix(args : L E) : S ==
+      -- format for args is [[ROW ...],[ROW ...],[ROW ...]]
+      -- generate string for formatting columns (centered)
+      group addBrackets concat
+        
["<mtable><mtr><mtd>",formatNaryNoGroup("</mtd></mtr><mtr><mtd>",args,minPrec),
+          "</mtd></mtr></mtable>"]
+
+    formatFunction(op : S, args : L E, prec : I) : S ==
+      group concat ["<mo>",op,"</mo>",parenthesize 
formatNary(",",args,minPrec)]
+
+    formatNullary(op : S) ==
+      op = "NOTHING" => ""
+      group concat ["<mo>",op,"</mo><mo>(</mo><mo>)</mo>"]
+
+    formatUnary(op : S, arg : E, prec : I) ==
+      p : I := position(op,unaryOps)
+      p < 1 => error "unknown unary op"
+      opPrec := unaryPrecs.p
+      s : S := concat ["<mo>",op,"</mo>",formatMml(arg,opPrec)]
+      opPrec < prec => group parenthesize s
+      op = "-" => s
+      group s
+
+    formatBinary(op : S, args : L E, prec : I) : S ==
+      p : I := position(op,binaryOps)
+      p < 1 => error "unknown binary op"
+      opPrec := binaryPrecs.p
+      s1 : S := formatMml(first args, opPrec)
+      s2 : S := formatMml(first rest args, opPrec)
+      op :=
+        op = "|"     =>  s := concat 
["<mrow>",s1,"</mrow><mo>",op,"</mo><mrow>",s2,"</mrow>"]
+        op = "**"    =>  s := concat 
["<msup><mrow>",s1,"</mrow><mrow>",s2,"</mrow></msup>"]
+        op = "/"     =>  s := concat 
["<mfrac><mrow>",s1,"</mrow><mrow>",s2,"</mrow></mfrac>"]
+        op = "OVER"  =>  s := concat 
["<mfrac><mrow>",s1,"</mrow><mrow>",s2,"</mrow></mfrac>"]
+        op = "+->"   =>  s := concat 
["<mrow>",s1,"</mrow><mo>",op,"</mo><mrow>",s2,"</mrow>"]
+        s := concat ["<mrow>",s1,"</mrow><mo>",op,"</mo><mrow>",s2,"</mrow>"]
+      group
+        op = "OVER" => s
+--        opPrec < prec => parenthesize s
+-- ugly parentheses?
+        s
+
+    formatNary(op : S, args : L E, prec : I) : S ==
+      group formatNaryNoGroup(op, args, prec)
+
+    formatNaryNoGroup(op : S, args : L E, prec : I) : S ==
+      null args => ""
+      p : I := position(op,naryOps)
+      p < 1 => error "unknown nary op"
+      -- need to test for "ZAG" case and divert it here, here's an
+      -- example including "op", the args list would be the rest of this
+      -- {{+}{3}{{ZAG}{1}{7}}{{ZAG}{1}{15}}{{ZAG}{1}{1}}{{ZAG}{1}{25}}
+      -- {{ZAG}{1}{1}}{{ZAG}{1}{7}}{{ZAG}{1}{4}}}
+      -- The first arg, the "3" in this case, could be a "ZAG" or something
+      -- else, but the second arg looks like it has to be "ZAG", so maybe
+      -- test for #args > 1 and args.2 is "ZAG".
+      -- This test should work so long as axiom doesn't try to evaluate
+      -- the second half of the "and" when the first half is false.
+      (#args > 1) and (position("ZAG",stringify first rest args,1) > 0) =>
+          tmpS : S := stringify first args
+          position("ZAG",tmpS,1) > 0 => formatZag(args)
+--        position("ZAG",tmpS,1) > 0 => formatZag1(args)
+          concat [formatMml(first args,minPrec) "<mo>+</mo>" formatZag(rest 
args)]
+      op :=
+        op = ","     => "<mo>,</mo>" --originally , \:
+        op = ";"     => "<mo>;</mo>" --originally ; \: should figure these out
+        op = "*"     => "<mo>&#x02062;</mo>"
+       -- InvisibleTimes
+        op = " "     => "<mspace width='0.5em'/>"
+        op = "ROW"   => "</mtd><mtd>"
+       op = "+"     => "<mo>+</mo>"
+       op = "-"     => "<mo>-</mo>"
+        op
+      l : L S := nil
+      opPrec := naryPrecs.p
+      for a in args repeat
+        l := concat(op,concat(formatMml(a,opPrec),l)$L(S))$L(S)
+      s : S := concat reverse rest l
+      opPrec < prec => parenthesize s
+      s
+
+    formatZag(args : L E) : S ==
+    -- {{ZAG}{1}{7}}
+      tmpZag : L E := first args pretend L E
+      #args > 1 => "<mfrac>"formatMml(first rest 
tmpZag,minPrec)"<mrow><mn>"formatMml(first rest rest 
tmpZag,minPrec)"</mn><mo>+</mo>"formatZag(rest args)"</mrow></mfrac>"
+      "<mfrac>"formatMml(first rest tmpZag,minPrec)formatMml(first rest rest 
tmpZag,minPrec)"</mfrac>"
+      
+    formatZag1(args : L E) : S ==
+    -- make alternative ZAG format without diminishing fonts, maybe
+    -- use a table
+    -- {{ZAG}{1}{7}}
+      tmpZag : L E := first args pretend L E
+      #args > 1 => "<mfrac>"formatMml(first rest 
tmpZag,minPrec)"<mrow><mn>"formatMml(first rest rest 
tmpZag,minPrec)"</mn><mo>+</mo>"formatZag(rest args)"</mrow></mfrac>"
+      "<mfrac>"formatMml(first rest tmpZag,minPrec)formatMml(first rest rest 
tmpZag,minPrec)"</mfrac>"
+
+    formatMml(expr : E,prec : I) ==
+      i,len : Integer
+      intSplitLen : Integer := 20
+      ATOM(expr)address@hidden =>
+        str := stringify expr
+        len := #str
+       -- this bit seems to deal with integers
+        FIXP$Lisp expr =>
+          i := expr pretend Integer
+          if (i < 0) or (i > 9)
+            then
+              group
+                 nstr : String := ""
+                 -- insert some blanks into the string, if too long
+                 while ((len := #str) > intSplitLen) repeat
+                   nstr := concat [nstr," ",
+                     elt(str,segment(1,intSplitLen)$US)]
+                   str := elt(str,segment(intSplitLen+1)$US)
+                 empty? nstr => concat ["<mn>",str,"</mn>"]
+                 nstr :=
+                   empty? str => nstr
+                   concat [nstr," ",str]
+                 concat ["<mn>",elt(nstr,segment(2)$US),"</mn>"]
+            else str := concat ["<mn>",str,"</mn>"]
+        str = "%pi" => "<mi>&#x003C0;</mi>"
+       -- pi
+        str = "%e"  => "<mi>&#x02147;</mi>"
+       -- ExponentialE
+        str = "%i"  => "<mi>&#x02148;</mi>"
+       -- ImaginaryI
+       -- what sort of atom starts with %%? need an example
+        len > 1 and str.1 = char "%" and str.2 = char "%" =>
+          u : US := segment(3,len)$US
+          concat(concat("<mi>",str.u),"</mi>")
+        len > 0 and str.1 = char "%" => concat(concat("<mi>",str),"</mi>")
+        len > 1 and digit? str.1 => concat ["<mn>",str,"</mn>"] -- should 
handle floats
+       -- presumably this is a literal string
+        len > 0 and str.1 = char "_"" =>
+          concat(concat("<mtext>",str),"</mtext>")
+        len = 1 and str.1 = char " " => " "
+        (i := position(str,specialStrings)) > 0 =>
+          specialStringsInMML.i
+        (i := position(char " ",str)) > 0 =>
+          -- We want to preserve spacing, so use a roman font.
+         -- What's this for?  Leave the \rm in for now so I can see
+         -- where it arises.  Removed 2007-02-14
+          concat(concat("<mtext>",str),"</mtext>")
+       -- if we get to here does that mean it's a variable?
+        concat ["<mi>",str,"</mi>"]
+      l : L E := (expr pretend L E)
+      null l => blank
+      op : S := stringify first l
+      args : L E := rest l
+      nargs : I := #args
+
+      -- special cases
+      member?(op, specialOps) => formatSpecial(op,args,prec)
+      member?(op, plexOps)    => formatPlex(op,args,prec)
+
+      -- nullary case
+      0 = nargs => formatNullary op
+
+      -- unary case
+      (1 = nargs) and member?(op, unaryOps) =>
+        formatUnary(op, first args, prec)
+
+      -- binary case
+      (2 = nargs) and member?(op, binaryOps) =>
+        formatBinary(op, args, prec)
+
+      -- nary case
+      member?(op,naryNGOps) => formatNaryNoGroup(op,args, prec)
+      member?(op,naryOps) => formatNary(op,args, prec)
+      -- need to test here in case first l is SUPERSUB case and then
+      -- pass first l and args to formatSuperSub.
+      position("SUPERSUB",op,1) > 0 =>
+        formatSuperSub(first l,args,minPrec)
+      -- now test for SUB
+      position("SUB",op,1) > 0 =>
+        formatSub(first l,args,minPrec)
+
+      op := formatMml(first l,minPrec)
+      formatFunction(op,args,prec)
+
+@
+\section{Mathematical Markup Language Form}
+<<package MMLFORM MathMLForm>>=
+<<public declarations>>
+<<private constant declarations>>
+<<private function declarations>>
+<<public function definitions>>
+<<display functions>>
+<<formatting functions>>
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+--    - Redistributions of source code must retain the above copyright
+--      notice, this list of conditions and the following disclaimer.
+--
+--    - Redistributions in binary form must reproduce the above copyright
+--      notice, this list of conditions and the following disclaimer in
+--      the documentation and/or other materials provided with the
+--      distribution.
+--
+--    - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+--      names of its contributors may be used to endorse or promote products
+--      derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+<<package MMLFORM MathMLForm>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/input/Makefile.pamphlet b/src/input/Makefile.pamphlet
index 474b899..621d8ed 100644
--- a/src/input/Makefile.pamphlet
+++ b/src/input/Makefile.pamphlet
@@ -329,7 +329,8 @@ REGRES= algaggr.regress algbrbf.regress  algfacob.regress 
alist.regress  \
     lodo2.regress     lodo3.regress    lodof.regress    lodo.regress \
     lpoly.regress     lupfact.regress  lword.regress    macbug.regress \
     macros.regress    magma.regress    mapleok.regress  mappkg1.regress \
-    matbug.regress    matrix1.regress  matrix22.regress matrix.regress \
+    matbug.regress    mathml.regress   \
+    matrix1.regress  matrix22.regress matrix.regress \
     mfinfact.regress  mkfunc.regress   mpoly.regress    mset2.regress \
     mset.regress      multfact.regress multiple.regress ndftip.regress \
     negfloats.regress nepip.regress    newlodo.regress  newton.regress \
@@ -551,6 +552,7 @@ FILES= ${OUT}/algaggr.input  ${OUT}/algbrbf.input    
${OUT}/algfacob.input \
        ${OUT}/lupfact.input  ${OUT}/lword.input      ${OUT}/macbug.input \
        ${OUT}/macros.input   ${OUT}/marcbench.input  ${OUT}/magma.input \
        ${OUT}/mapleok.input  ${OUT}/mappkg1.input    ${OUT}/matbug.input \
+       ${OUT}/mathml.input \
        ${OUT}/matrix22.input ${OUT}/matrix.input     ${OUT}/matrix1.input \
        ${OUT}/mfinfact.input ${OUT}/mkfunc.input     ${OUT}/mountain.input \
        ${OUT}/mpoly.input    ${OUT}/mset.input       ${OUT}/mset2.input \
@@ -816,6 +818,7 @@ DOCFILES= \
   ${DOC}/macros.input.dvi      ${DOC}/magma.input.dvi      \
   ${DOC}/mapleok.input.dvi     ${DOC}/mappkg1.input.dvi    \
   ${DOC}/marcbench.input.dvi   ${DOC}/matbug.input.dvi     \
+  ${DOC}/mathml.input.dvi      \
   ${DOC}/matops.as.dvi         ${DOC}/matrix1.input.dvi    \
   ${DOC}/matrix22.input.dvi    ${DOC}/matrix.input.dvi     \
   ${DOC}/matrox.input.dvi      ${DOC}/mfinfact.input.dvi   \
diff --git a/src/input/mathml.input.pamphlet b/src/input/mathml.input.pamphlet
new file mode 100644
index 0000000..461f32c
--- /dev/null
+++ b/src/input/mathml.input.pamphlet
@@ -0,0 +1,349 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/input mathml.input}
+\author{Arthur Ralfs}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+<<*>>=
+)spool mathml.output
+)set message test on
+)set message auto off
+)clear all
+ 
+--S 1 of 21
+(x+y)**2
+--R 
+--R
+--R         2           2
+--R   (1)  y  + 2x y + x
+--R                                                     Type: Polynomial 
Integer
+--E 1
+
+--S 2 of 21
+coerce(%)$MMLFORM
+--R 
+--R
+--R   (2)
+--R  
"<mrow><mrow><msup><mrow><mi>y</mi></mrow><mrow><mn>2</mn></mrow></msup></mro
+--R  
w><mo>+</mo><mrow><mn>2</mn><mo>&#x02062;</mo><mi>x</mi><mo>&#x02062;</mo><mi
+--R  
>y</mi></mrow><mo>+</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>2</mn></
+--R  mrow></msup></mrow></mrow>"
+--R                                                                 Type: 
String
+--E 2
+
+--S 3 of 21
+(x+y)**2
+--R 
+--R
+--R         2           2
+--R   (3)  y  + 2x y + x
+--R                                                     Type: Polynomial 
Integer
+--E 3
+
+--S 4 of 21
+display(coerce(%)$MMLFORM)$MMLFORM
+--R 
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mrow><mrow><msup><mrow><mi>y</mi></mrow><mrow><mn>2</mn></mrow></msup></mrow><mo>+</mo><mrow><mn>2</mn><mo>&#x02062;</mo><mi>x</mi><mo>&#x02062;</mo><mi>y</mi></mrow><mo>+</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>2</mn></mrow></msup></mrow></mrow>
+--R</math>
+--R                                                                   Type: 
Void
+--E 4
+
+)set output mathml on
+
+--S 5 of 21
+(x+y)**2
+--R
+--R         2           2
+--R   (5)  y  + 2x y + x
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mrow><mrow><msup><mrow><mi>y</mi></mrow><mrow><mn>2</mn></mrow></msup></mrow><mo>+</mo><mrow><mn>2</mn><mo>&#x02062;</mo><mi>x</mi><mo>&#x02062;</mo><mi>y</mi></mrow><mo>+</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>2</mn></mrow></msup></mrow></mrow>
+--R</math>
+--R
+--R                                                     Type: Polynomial 
Integer
+--E 5
+
+--S 6 of 21
+integrate(x**x,x)
+--R
+--R           x
+--R         ++    %I
+--R   (6)   |   %I  d%I
+--R        ++
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mrow><mo>&#x0222B;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mi>x</mi></mrow></msup></mrow><mo>&#x02146;</mo><mi>x</mi></mrow>
+--R</math>
+--R
+--R                                          Type: Union(Expression 
Integer,...)
+--E 6
+
+--S 7 of 21
+integral(x**x,x)
+--R
+--R           x
+--R         ++    %I
+--R   (7)   |   %I  d%I
+--R        ++
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mrow><mo>&#x0222B;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mi>x</mi></mrow></msup></mrow><mo>&#x02146;</mo><mi>x</mi></mrow>
+--R</math>
+--R
+--R                                                     Type: Expression 
Integer
+--E 7
+
+--S 8 of 21
+(5+sqrt 63 + sqrt 847)**(1/3)
+--R
+--R         +----------+
+--R        3|   +-+
+--R   (8)  \|14\|7  + 5
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mrow><mroot><mrow><mrow><mrow><mrow><mrow><mn>14</mn></mrow><mo>&#x02062;</mo><msqrt><mrow><mn>7</mn></mrow></msqrt></mrow><mo>+</mo><mn>5</mn></mrow></mrow></mrow><mn>3</mn></mroot></mrow>
+--R</math>
+--R
+--R                                                        Type: 
AlgebraicNumber
+--E 8
+
+--S 9 of 21
+set [1,2,3]
+--R
+--R   (9)  {1,2,3}
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mrow><mo>{</mo><mn>1</mn><mo>,</mo><mn>2</mn><mo>,</mo><mn>3</mn><mo>}</mo></mrow>
+--R</math>
+--R
+--R                                                    Type: Set 
PositiveInteger
+--E 9
+
+--S 10 of 21
+multiset [x rem 5 for x in primes(2,1000)]
+--R
+--R   (10)  {0,40: 1,47: 2,42: 3,38: 4}
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mrow><mo>{</mo><mn>0</mn><mo>,</mo><mrow><mrow><mn>40</mn></mrow><mtext>: 
</mtext><mn>1</mn></mrow><mo>,</mo><mrow><mrow><mn>47</mn></mrow><mtext>: 
</mtext><mn>2</mn></mrow><mo>,</mo><mrow><mrow><mn>42</mn></mrow><mtext>: 
</mtext><mn>3</mn></mrow><mo>,</mo><mrow><mrow><mn>38</mn></mrow><mtext>: 
</mtext><mn>4</mn></mrow><mo>}</mo></mrow>
+--R</math>
+--R
+--R                                                       Type: Multiset 
Integer
+--E 10
+
+--S 11 of 21
+series(sin(a*x),x=0)
+--R
+--R                3        5        7          9            11
+--R               a   3    a   5    a    7     a     9      a      11      12
+--R   (11)  a x - -- x  + --- x  - ---- x  + ------ x  - -------- x   + O(x  )
+--R                6      120      5040      362880      39916800
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mrow><mrow><mi>a</mi><mo>&#x02062;</mo><mi>x</mi></mrow><mo>-</mo><mrow><mrow><mfrac><mrow><mrow><msup><mrow><mi>a</mi></mrow><mrow><mn>3</mn></mrow></msup></mrow></mrow><mrow><mn>6</mn></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>3</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mrow><mfrac><mrow><mrow><msup><mrow><mi>a</mi></mrow><mrow><mn>5</mn></mrow></msup></mrow></mrow><mrow><mrow><mn>120</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>5</mn></mrow></msup></mrow></mrow><mo>-</mo><mrow><mrow><mfrac><mrow><mrow><msup><mrow><mi>a</mi></mrow><mrow><mn>7</mn></mrow></msup></mrow></mrow><mrow><mrow><mn>5040</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>7</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mrow><mfrac><mrow><mrow><msup><mrow><mi>a</mi></mrow><mrow><mn>9</mn></mrow></msup></mrow></mrow><mrow><mrow><mn>362880</mn></mrow></!
 
mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>9</mn></mrow></msup></mrow></mrow><mo>-</mo><mrow><mrow><mfrac><mrow><mrow><msup><mrow><mi>a</mi></mrow><mrow><mrow><mn>11</mn></mrow></mrow></msup></mrow></mrow><mrow><mrow><mn>39916800</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mrow><mn>11</mn></mrow></mrow></msup></mrow></mrow><mo>+</mo><mrow><mo><mi>O</mi></mo><mo>(</mo><mrow><mrow><msup><mrow><mi>x</mi></mrow><mrow><mrow><mn>12</mn></mrow></mrow></msup></mrow></mrow><mo>)</mo></mrow></mrow>
+--R</math>
+--R
+--R                        Type: UnivariatePuiseuxSeries(Expression 
Integer,x,0)
+--E 11
+
+--S 12 of 21
+matrix [[xi+yj for i in 1..10] for j in 1..10]
+--R
+--R   (12)
+--R   [
+--R     [yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + 
xi,
+--R      yj + xi, yj + xi]
+--R     ,
+--R
+--R     [yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + 
xi,
+--R      yj + xi, yj + xi]
+--R     ,
+--R
+--R     [yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + 
xi,
+--R      yj + xi, yj + xi]
+--R     ,
+--R
+--R     [yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + 
xi,
+--R      yj + xi, yj + xi]
+--R     ,
+--R
+--R     [yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + 
xi,
+--R      yj + xi, yj + xi]
+--R     ,
+--R
+--R     [yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + 
xi,
+--R      yj + xi, yj + xi]
+--R     ,
+--R
+--R     [yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + 
xi,
+--R      yj + xi, yj + xi]
+--R     ,
+--R
+--R     [yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + 
xi,
+--R      yj + xi, yj + xi]
+--R     ,
+--R
+--R     [yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + 
xi,
+--R      yj + xi, yj + xi]
+--R     ,
+--R
+--R     [yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + xi, yj + 
xi,
+--R      yj + xi, yj + xi]
+--R     ]
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mrow><mo>[</mo><mtable><mtr><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow!
 ></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><m!
 row><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><m!
i>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+<!
 
/mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></m!
 td></mtr><mtr><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mro!
w></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj<!
 
/mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd><mtd><mrow><mi>yj</mi><mo>+</mo><mi>xi</mi></mrow></mtd></mtr></mtable><mo>]</mo></mrow>
+--R</math>
+--R
+--R                                              Type: Matrix Polynomial 
Integer
+--E 12
+
+--S 13 of 21
+y:=operator 'y
+--R
+--R   (13)  y
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mi>y</mi>
+--R</math>
+--R
+--R                                                          Type: 
BasicOperator
+--E 13
+
+--S 14 of 21
+D(y(x,z),[x,x,z,x])
+--R
+--R   (14)  y        (x,z)
+--R          ,1,1,2,1
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mfrac><mrow><msup><mo>&#x02202;</mo><mn>4</mn></msup><mi>y</mi></mrow><mrow><mo>&#x02202;</mo><msup><mi>x</mi><mn>3</mn></msup><mo>&#x02202;</mo><mi>z</mi></mrow></mfrac><mo>(</mo><mi>x</mi><mo>,</mo><mi>z</mi><mo>)</mo>
+--R</math>
+--R
+--R                                                     Type: Expression 
Integer
+--E 14
+)clear all
+
+--S 15 of 21
+y:=operator 'y
+--R 
+--R
+--R   (1)  y
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mi>y</mi>
+--R</math>
+--R
+--R                                                          Type: 
BasicOperator
+--E 15
+
+--S 16 of 21
+D(y x,x,2)
+--R
+--R         ,,
+--R   (2)  y  (x)
+--R
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mfrac><mrow><msup><mo>&#x02146;</mo><mn>2</mn></msup><mi>y</mi></mrow><mrow><mo>&#x02146;</mo><msup><mi>x</mi><mn>2</mn></msup></mrow></mfrac><mo>&#x02061;</mo><mo>(</mo><mi>x</mi><mo>)</mo>
+--R</math>
+--R
+--R                                                     Type: Expression 
Integer
+--E 16
+
+--S 17 of 21
+x:=series 'x
+--R 
+--R
+--R   (3)  x
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mi>x</mi>
+--R</math>
+--R
+--R                        Type: UnivariatePuiseuxSeries(Expression 
Integer,x,0)
+--E 17
+
+--S 18 of 21
+sin(1+x)
+--R
+--R   (4)
+--R                        sin(1)  2   cos(1)  3   sin(1)  4   cos(1)  5
+--R     sin(1) + cos(1)x - ------ x  - ------ x  + ------ x  + ------ x
+--R                           2           6          24          120
+--R   + 
+--R       sin(1)  6   cos(1)  7   sin(1)  8   cos(1)  9    sin(1)  10      11
+--R     - ------ x  - ------ x  + ------ x  + ------ x  - ------- x   + O(x  )
+--R         720        5040        40320      362880      3628800
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mrow><mrow><mo><mo>sin</mo></mo><mo>(</mo><mrow><mn>1</mn></mrow><mo>)</mo></mrow><mo>+</mo><mrow><mrow><mo><mo>cos</mo></mo><mo>(</mo><mrow><mn>1</mn></mrow><mo>)</mo></mrow><mo>&#x02062;</mo><mi>x</mi></mrow><mo>-</mo><mrow><mrow><mfrac><mrow><mrow><mo><mo>sin</mo></mo><mo>(</mo><mrow><mn>1</mn></mrow><mo>)</mo></mrow></mrow><mrow><mn>2</mn></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>2</mn></mrow></msup></mrow></mrow><mo>-</mo><mrow><mrow><mfrac><mrow><mrow><mo><mo>cos</mo></mo><mo>(</mo><mrow><mn>1</mn></mrow><mo>)</mo></mrow></mrow><mrow><mn>6</mn></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>3</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mrow><mfrac><mrow><mrow><mo><mo>sin</mo></mo><mo>(</mo><mrow><mn>1</mn></mrow><mo>)</mo></mrow></mrow><mrow><mrow><mn>24</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>4</mn></mrow></msup></mrow></mro!
 
w><mo>+</mo><mrow><mrow><mfrac><mrow><mrow><mo><mo>cos</mo></mo><mo>(</mo><mrow><mn>1</mn></mrow><mo>)</mo></mrow></mrow><mrow><mrow><mn>120</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>5</mn></mrow></msup></mrow></mrow><mo>-</mo><mrow><mrow><mfrac><mrow><mrow><mo><mo>sin</mo></mo><mo>(</mo><mrow><mn>1</mn></mrow><mo>)</mo></mrow></mrow><mrow><mrow><mn>720</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>6</mn></mrow></msup></mrow></mrow><mo>-</mo><mrow><mrow><mfrac><mrow><mrow><mo><mo>cos</mo></mo><mo>(</mo><mrow><mn>1</mn></mrow><mo>)</mo></mrow></mrow><mrow><mrow><mn>5040</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>7</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mrow><mfrac><mrow><mrow><mo><mo>sin</mo></mo><mo>(</mo><mrow><mn>1</mn></mrow><mo>)</mo></mrow></mrow><mrow><mrow><mn>40320</mn></mrow></mrow></mfrac></mrow><mo>!
 &#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>8</!
mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mrow><mfrac><mrow><mrow><mo><mo>cos</mo></mo><mo>(</mo><mrow><mn>1</mn></mrow><mo>)</mo></mrow></mrow><mrow><mrow><mn>362880</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mn>9</mn></mrow></msup></mrow></mrow><mo>-</mo><mrow><mrow><mfrac><mrow><mrow><mo><mo>sin</mo></mo><mo>(</mo><mrow><mn>1</mn></mrow><mo>)</mo></mrow></mrow><mrow><mrow><mn>3628800</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mi>x</mi></mrow><mrow><mrow><mn>10</mn></mrow></mrow></msup></mrow></mrow><mo>+</mo><mrow><mo><mi>O</mi></mo><mo>(</mo><mrow><mrow><msup><mrow><mi>x</mi></mrow><mrow><mrow><mn>11</mn></mrow></mrow></msup></mrow></mrow><mo>)</mo></mrow></mrow>
+--R</math>
+--R
+--R                        Type: UnivariatePuiseuxSeries(Expression 
Integer,x,0)
+--E 18
+
+)clear all
+
+--S 19 of 21
+series(1/log(y),y=1)
+--R
+--R   (1)
+--R            - 1   1    1            1        2    19        3    3         4
+--R     (y - 1)    + - - -- (y - 1) + -- (y - 1)  - --- (y - 1)  + --- (y - 1)
+--R                  2   12           24            720            160
+--R   + 
+--R        863         5    275         6    33953         7     8183         8
+--R     - ----- (y - 1)  + ----- (y - 1)  - ------- (y - 1)  + ------- (y - 1)
+--R       60480            24192            3628800            1036800
+--R   + 
+--R        3250433         9            10
+--R     - --------- (y - 1)  + O((y - 1)  )
+--R       479001600
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mrow><mrow><msup><mrow><mrow><mo>(</mo><mi>y</mi><mo>-</mo><mn>1</mn><mo>)</mo></mrow></mrow><mrow><mrow><mo>(</mo><mo>-</mo><mn>1</mn><mo>)</mo></mrow></mrow></msup></mrow><mo>+</mo><mrow><mfrac><mrow><mn>1</mn></mrow><mrow><mn>2</mn></mrow></mfrac></mrow><mo>-</mo><mrow><mrow><mfrac><mrow><mn>1</mn></mrow><mrow><mrow><mn>12</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><mo>(</mo><mi>y</mi><mo>-</mo><mn>1</mn><mo>)</mo></mrow></mrow><mo>+</mo><mrow><mrow><mfrac><mrow><mn>1</mn></mrow><mrow><mrow><mn>24</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mrow><mo>(</mo><mi>y</mi><mo>-</mo><mn>1</mn><mo>)</mo></mrow></mrow><mrow><mn>2</mn></mrow></msup></mrow></mrow><mo>-</mo><mrow><mrow><mfrac><mrow><mrow><mn>19</mn></mrow></mrow><mrow><mrow><mn>720</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mrow><mo>(</mo><mi>y</mi><mo>-</mo><mn>1</mn><mo>)</mo></mrow></mrow><mrow><mn>3</mn></mrow></msup></mrow></mrow><mo>+</mo><m!
 
row><mrow><mfrac><mrow><mn>3</mn></mrow><mrow><mrow><mn>160</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mrow><mo>(</mo><mi>y</mi><mo>-</mo><mn>1</mn><mo>)</mo></mrow></mrow><mrow><mn>4</mn></mrow></msup></mrow></mrow><mo>-</mo><mrow><mrow><mfrac><mrow><mrow><mn>863</mn></mrow></mrow><mrow><mrow><mn>60480</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mrow><mo>(</mo><mi>y</mi><mo>-</mo><mn>1</mn><mo>)</mo></mrow></mrow><mrow><mn>5</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mrow><mfrac><mrow><mrow><mn>275</mn></mrow></mrow><mrow><mrow><mn>24192</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mrow><mo>(</mo><mi>y</mi><mo>-</mo><mn>1</mn><mo>)</mo></mrow></mrow><mrow><mn>6</mn></mrow></msup></mrow></mrow><mo>-</mo><mrow><mrow><mfrac><mrow><mrow><mn>33953</mn></mrow></mrow><mrow><mrow><mn>3628800</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mrow><mo>(</mo><mi>y</mi><mo>-</mo><mn!
 >1</mn><mo>)</mo></mrow></mrow><mrow><mn>7</mn></mrow></msup><!
/mrow></mrow><mo>+</mo><mrow><mrow><mfrac><mrow><mrow><mn>8183</mn></mrow></mrow><mrow><mrow><mn>1036800</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mrow><mo>(</mo><mi>y</mi><mo>-</mo><mn>1</mn><mo>)</mo></mrow></mrow><mrow><mn>8</mn></mrow></msup></mrow></mrow><mo>-</mo><mrow><mrow><mfrac><mrow><mrow><mn>3250433</mn></mrow></mrow><mrow><mrow><mn>479001600</mn></mrow></mrow></mfrac></mrow><mo>&#x02062;</mo><mrow><msup><mrow><mrow><mo>(</mo><mi>y</mi><mo>-</mo><mn>1</mn><mo>)</mo></mrow></mrow><mrow><mn>9</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mo><mi>O</mi></mo><mo>(</mo><mrow><mrow><msup><mrow><mrow><mo>(</mo><mi>y</mi><mo>-</mo><mn>1</mn><mo>)</mo></mrow></mrow><mrow><mrow><mn>10</mn></mrow></mrow></msup></mrow></mrow><mo>)</mo></mrow></mrow>
+--R</math>
+--R
+--R                        Type: UnivariatePuiseuxSeries(Expression 
Integer,y,1)
+--E 19
+
+)clear all
+
+--S 20 of 21
+y:UTS(FLOAT,'z,0):=exp(z)
+--R
+--R   (1)
+--R                    2                            3
+--R     1.0 + z + 0.5 z  + 0.1666666666 6666666667 z
+--R   + 
+--R                                4                               5
+--R     0.0416666666 6666666666 7 z  + 0.0083333333 3333333333 34 z
+--R   + 
+--R                                 6                               7
+--R     0.0013888888 8888888888 89 z  + 0.0001984126 9841269841 27 z
+--R   + 
+--R                                   8                                  9
+--R     0.0000248015 8730158730 1587 z  + 0.0000027557 3192239858 90653 z
+--R   + 
+--R                                   10      11
+--R     0.2755731922 3985890653 E -6 z   + O(z  )
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mrow><mn>1.0</mn><mo>+</mo><mi>z</mi><mo>+</mo><mrow><mn>0.5</mn><mo>&#x02062;</mo><mrow><msup><mrow><mi>z</mi></mrow><mrow><mn>2</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mn>0.1666666666
 
6666666667</mn><mo>&#x02062;</mo><mrow><msup><mrow><mi>z</mi></mrow><mrow><mn>3</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mn>0.0416666666
 6666666666 
7</mn><mo>&#x02062;</mo><mrow><msup><mrow><mi>z</mi></mrow><mrow><mn>4</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mn>0.0083333333
 3333333333 
34</mn><mo>&#x02062;</mo><mrow><msup><mrow><mi>z</mi></mrow><mrow><mn>5</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mn>0.0013888888
 8888888888 
89</mn><mo>&#x02062;</mo><mrow><msup><mrow><mi>z</mi></mrow><mrow><mn>6</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mn>0.0001984126
 9841269841 
27</mn><mo>&#x02062;</mo><mrow><msup><mrow><mi>z</mi></mrow><mrow><mn>7</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mn>0.0000248015
 8730158730 1587</mn><mo>&#x02062;</mo><mrow><msup><mr!
 
ow><mi>z</mi></mrow><mrow><mn>8</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mn>0.0000027557
 3192239858 
90653</mn><mo>&#x02062;</mo><mrow><msup><mrow><mi>z</mi></mrow><mrow><mn>9</mn></mrow></msup></mrow></mrow><mo>+</mo><mrow><mn>0.2755731922
 3985890653 E 
-6</mn><mo>&#x02062;</mo><mrow><msup><mrow><mi>z</mi></mrow><mrow><mrow><mn>10</mn></mrow></mrow></msup></mrow></mrow><mo>+</mo><mrow><mo><mi>O</mi></mo><mo>(</mo><mrow><mrow><msup><mrow><mi>z</mi></mrow><mrow><mrow><mn>11</mn></mrow></mrow></msup></mrow></mrow><mo>)</mo></mrow></mrow>
+--R</math>
+--R
+--R                                    Type: 
UnivariateTaylorSeries(Float,z,0.0)
+--E 20
+
+--S 21 of 21
+c:=continuedFraction(314159/100000)
+--R
+--R              1 |     1  |     1 |     1  |     1 |     1 |     1 |
+--R   (2)  3 + +---+ + +----+ + +---+ + +----+ + +---+ + +---+ + +---+
+--R            | 7     | 15     | 1     | 25     | 1     | 7     | 4
+--R<math xmlns="http://www.w3.org/1998/Math/MathML"; mathsize="big" 
display="block">
+--R<mrow><mn>3</mn><mo>+</mo><mfrac><mn>1</mn><mrow><mn><mn>7</mn></mn><mo>+</mo><mfrac><mn>1</mn><mrow><mn><mrow><mn>15</mn></mrow></mn><mo>+</mo><mfrac><mn>1</mn><mrow><mn><mn>1</mn></mn><mo>+</mo><mfrac><mn>1</mn><mrow><mn><mrow><mn>25</mn></mrow></mn><mo>+</mo><mfrac><mn>1</mn><mrow><mn><mn>1</mn></mn><mo>+</mo><mfrac><mn>1</mn><mrow><mn><mn>7</mn></mn><mo>+</mo><mfrac><mn>1</mn><mn>4</mn></mfrac></mrow></mfrac></mrow></mfrac></mrow></mfrac></mrow></mfrac></mrow></mfrac></mrow></mfrac></mrow>
+--R</math>
+--R
+--R                                              Type: ContinuedFraction 
Integer
+--E 21
+)spool
+)lisp (bye)
+ 
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/interp/i-output.boot.pamphlet 
b/src/interp/i-output.boot.pamphlet
index 10cd956..a1a84ab 100644
--- a/src/interp/i-output.boot.pamphlet
+++ b/src/interp/i-output.boot.pamphlet
@@ -1380,12 +1380,24 @@ texFormat1 expr ==
   FORCE_-OUTPUT $texOutputStream
   NIL
 
+mathmlFormat expr ==
+  mml := '(MathMLFormat)
+  mmlrep := '(String)
+  formatFn := getFunctionFromDomain("coerce",mml,[$OutputForm])
+  displayFn := getFunctionFromDomain("display",mml,[mmlrep])
+  SPADCALL(SPADCALL(expr,formatFn),displayFn)
+  TERPRI $mathmlOutputStream
+  FORCE_-OUTPUT $mathmlOutputStream
+  NIL
+
+
 output(expr,domain) ==
   if isWrapped expr then expr := unwrap expr
   isMapExpr expr =>
     if $formulaFormat then formulaFormat expr
     if $texFormat     then texFormat expr
     if $algebraFormat then mathprintWithNumber expr
+    if $mathmlFormat  then mathmlFormat expr
   categoryForm? domain or domain in '((Mode) (Domain) (SubDomain (Domain))) =>
     if $algebraFormat then
       mathprintWithNumber outputDomainConstructor expr
@@ -1401,6 +1413,7 @@ output(expr,domain) ==
     if $algebraFormat then
       mathprintWithNumber x
     if $texFormat     then texFormat x
+    if $mathmlFormat  then mathmlFormat x
   (FUNCTIONP(opOf domain)) and
     (printfun := compiledLookup("<<",'(TextWriter TextWriter $), evalDomain 
domain))
        and (textwrit := compiledLookup("print", '($), TextWriter())) =>
diff --git a/src/interp/setq.lisp.pamphlet b/src/interp/setq.lisp.pamphlet
index 6f23778..25155d8 100644
--- a/src/interp/setq.lisp.pamphlet
+++ b/src/interp/setq.lisp.pamphlet
@@ -777,9 +777,10 @@
 "Michel Petitot         Didier Pinchon         Ayal Pinkus"
 "Jose Alfredo Portes"
 "Claude Quitte"
-"Norman Ramsey          Michael Richardson     Renaud Rioboo"
-"Jean Rivlin            Nicolas Robidoux       Simon Robinson"
-"Raymond Rogers         Michael Rothstein      Martin Rubey"
+"Arthur C. Ralfs        Norman Ramsey          Michael Richardson"
+"Renaud Rioboo          Jean Rivlin            Nicolas Robidoux"
+"Simon Robinson         Raymond Rogers         Michael Rothstein"
+"Martin Rubey"
 "Philip Santas          Alfred Scheerhorn      William Schelter"
 "Gerhard Schneider      Martin Schoenert       Marshall Schor"
 "Frithjof Schulze       Fritz Schwarz          Nick Simicich"
diff --git a/src/interp/setvars.boot.pamphlet b/src/interp/setvars.boot.pamphlet
index 864ced0..b052e85 100644
--- a/src/interp/setvars.boot.pamphlet
+++ b/src/interp/setvars.boot.pamphlet
@@ -1382,6 +1382,125 @@ describeSetOutputFortran() ==
   '"The current setting is: ",'%b,setOutputFortran "%display%",'%d)
 
 @
+\section{output mathml}
+See the section mathml in setvart.boot.pamphlet\cite{1}
+\begin{verbatim}
+----------------------- The mathml Option ------------------------
+
+ Description: create output in MathML style
+
+ )set output mathml is used to tell AXIOM to turn MathML-style output
+printing on and off, and where to place the output.  By default,
+the destination for the output is the screen but printing is 
+turned off.
+
+Syntax:   )set output mathml <arg>
+    where arg can be one of
+  on          turn MathML printing on
+  off         turn MathML printing off (default state)
+  console     send MathML output to screen (default state)
+  fp<.fe>     send MathML output to file with file prefix fp
+              and file extension .fe. If not given, 
+              .fe defaults to .stex.
+
+If you wish to send the output to a file, you must issue 
+this command twice: once with on and once with the file name. 
+For example, to send MathML output to the file polymer.stex, 
+issue the two commands
+
+  )set output mathml on
+  )set output mathml polymer
+
+The output is placed in the directory from which you invoked 
+AXIOM or the one you set with the )cd system command.
+The current setting is:  Off:CONSOLE 
+\end{verbatim}
+<<outputmathmlCode>>=
+<<setOutputMathml>>
+<<describeSetOutputMathml>>
+@
+\subsection{setOutputMathml}
+<<setOutputMathml>>=
+setOutputMathml arg ==
+  arg = "%initialize%" =>
+    $mathmlOutputStream :=
+      DEFIOSTREAM('((MODE . OUTPUT) (DEVICE . CONSOLE)),255,0)
+    $mathmlOutputFile := '"CONSOLE"
+    $mathmlFormat := NIL
+
+  arg = "%display%" =>
+    if $mathmlFormat then label := '"On:" else label := '"Off:"
+    STRCONC(label,$mathmlOutputFile)
+
+  (null arg) or (arg = "%describe%") or (first arg = '_?) =>
+    describeSetOutputMathml()
+
+  -- try to figure out what the argument is
+
+  if arg is [fn] and
+    fn in '(Y N YE YES NO O ON OF OFF CONSOLE y n ye yes no o on of off 
console)
+      then 'ok
+      else arg := [fn,'smml]
+
+  arg is [fn] =>
+    UPCASE(fn) in '(Y N YE O OF) =>
+      sayKeyedMsg("S2IV0002",'(MathML mathml))
+    UPCASE(fn) in '(NO OFF)  => $mathmlFormat := NIL
+    UPCASE(fn) in '(YES ON) => $mathmlFormat := true
+    UPCASE(fn) = 'CONSOLE =>
+      SHUT $mathmlOutputStream
+      $mathmlOutputStream :=
+        DEFIOSTREAM('((MODE . OUTPUT) (DEVICE . CONSOLE)),255,0)
+      $mathmlOutputFile := '"CONSOLE"
+
+  (arg is [fn,ft]) or (arg is [fn,ft,fm]) => -- aha, a file
+    if (ptype := pathnameType fn) then
+      fn := STRCONC(pathnameDirectory fn,pathnameName fn)
+      ft := ptype
+    if null fm then fm := 'A
+    filename := $FILEP(fn,ft,fm)
+    null filename =>
+      sayKeyedMsg("S2IV0003",[fn,ft,fm])
+    (testStream := MAKE_-OUTSTREAM(filename,255,0)) =>
+      SHUT $mathmlOutputStream
+      $mathmlOutputStream := testStream
+      $mathmlOutputFile := object2String filename
+      sayKeyedMsg("S2IV0004",['"MathML",$mathmlOutputFile])
+    sayKeyedMsg("S2IV0003",[fn,ft,fm])
+
+  sayKeyedMsg("S2IV0005",NIL)
+  describeSetOutputMathml()
+
+@
+\subsection{describeSetOutputMathml}
+<<describeSetOutputMathml>>=
+describeSetOutputMathml() ==
+  sayBrightly LIST ('%b,'")set output mathml",'%d,_
+   '"is used to tell AXIOM to turn MathML-style output",'%l,_
+   '"printing on and off, and where to place the output.  By default, 
the",'%l,_
+   '"destination for the output is the screen but printing is turned 
off.",'%l,_
+   '%l,_
+   '"Syntax:   )set output mathml <arg>",'%l,_
+  '"    where arg can be one of",'%l,_
+  '"  on          turn MathML printing on",'%l,_
+  '"  off         turn MathML printing off (default state)",'%l,_
+  '"  console     send MathML output to screen (default state)",'%l,_
+  '"  fp<.fe>     send MathML output to file with file prefix fp and 
file",'%l,_
+  '"              extension .fe. If not given, .fe defaults to .stex.",'%l,
+  '%l,_
+  '"If you wish to send the output to a file, you must issue this 
command",'%l,_
+  '"twice: once with",'%b,'"on",'%d,'"and once with the file name. For 
example, to send",'%l,_
+  '"MathML output to the file",'%b,'"polymer.smml,",'%d,'"issue the two 
commands",'%l,_
+  '%l,_
+  '"  )set output mathml on",'%l,_
+  '"  )set output mathml polymer",'%l,_
+  '%l,_
+  '"The output is placed in the directory from which you invoked AXIOM 
or",'%l,_
+  '"the one you set with the )cd system command.",'%l,_
+  '"The current setting is: ",'%b,setOutputMathml "%display%",'%d)
+
+
+@
 \section{output openmath}
 See the subsection output openmath in setvart.boot.pamphlet\cite{1}
 \begin{verbatim}
@@ -1821,6 +1940,7 @@ describeSetStreamsCalculate() == 
sayKeyedMsg("S2IV0001",[$streamCount])
 <<outputalgebraCode>>
 <<outputcharactersCode>>
 <<outputfortranCode>>
+<<outputmathmlCode>>
 <<outputopenmathCode>>
 <<outputscriptCode>>
 <<outputtexCode>>
diff --git a/src/interp/setvart.boot.pamphlet b/src/interp/setvart.boot.pamphlet
index 92e8825..bfa2f14 100644
--- a/src/interp/setvart.boot.pamphlet
+++ b/src/interp/setvart.boot.pamphlet
@@ -1673,6 +1673,7 @@ length      line length of output displays           77
 scripts     show subscripts,... linearly             off 
 showeditor  view output of )show in editor           off 
 tex         create output in TeX style               Off:CONSOLE 
+mathml     create output in MathML style            Off:CONSOLE 
 \end{verbatim}
 Since the output option has a bunch of sub-options each suboption 
 is defined within the output structure.
@@ -1694,6 +1695,7 @@ is defined within the output structure.
 <<outputscripts>>
 <<outputshoweditor>>
 <<outputtex>>
+<<outputmathml>>
  ))
 @
 \subsection{abbreviate}
@@ -1901,6 +1903,58 @@ The current setting is:  Off:CONSOLE
       (10 245)
       77)
 @
+\subsection{mathml}
+\begin{verbatim}
+----------------------- The mathml Option ------------------------
+
+ Description: create output in MathML style
+
+ )set output mathml is used to tell AXIOM to turn MathML-style output
+printing on and off, and where to place the output.  By default,
+the destination for the output is the screen but printing is 
+turned off.
+
+Syntax:   )set output mathml <arg>
+    where arg can be one of
+  on          turn MathML printing on
+  off         turn MathML printing off (default state)
+  console     send MathML output to screen (default state)
+  fp<.fe>     send MathML output to file with file prefix fp
+              and file extension .fe. If not given, 
+              .fe defaults to .smml.
+
+If you wish to send the output to a file, you must issue 
+this command twice: once with on and once with the file name. 
+For example, to send MathML output to the file polymer.smml, 
+issue the two commands
+
+  )set output mathml on
+  )set output mathml polymer
+
+The output is placed in the directory from which you invoked 
+AXIOM or the one you set with the )cd system command.
+The current setting is:  Off:CONSOLE 
+\end{verbatim}
+<<outputmathml>>=
+     (mathml
+      "create output in MathML style"
+      interpreter
+      FUNCTION
+      setOutputMathml
+      (("create output in MathML format"
+        LITERALS
+        $mathmlFormat
+        (off on)
+        off)
+       (break $mathmlFormat)
+       ("where MathML output goes (enter {\em console} or a pathname)"
+        FILENAME
+        $mathmlOutputFile
+        chkOutputFileName
+        "console"))
+      NIL)
+
+@
 \subsection{openmath}
 \begin{verbatim}
 ----------------------- The openmath Option ------------------------




reply via email to

[Prev in Thread] Current Thread [Next in Thread]