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 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} + + + +]> + + + + + + MathML Test + + + + + + +\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. + +<>= +)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 tags. + +@ +\subsection{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 ","&",""]$(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 := + ["cos","cot","csc","log","sec","sin","tan", + "cosh","coth","csch","sech","sinh","tanh", + "arccos","arcsin","arctan","erf","","$",""] + +@ +\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 + +<>= + -- 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: ... + 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 + + 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 "" + displayElt(s) + sayTeX$Lisp "" + s + + coerceL(expr : E): S == + s : S := postcondition formatMml(precondition expr, minPrec) + sayTeX$Lisp "" + sayTeX$Lisp s + sayTeX$Lisp "" + s + + display(mathml : S): Void == + sayTeX$Lisp "" + sayTeX$Lisp mathml + sayTeX$Lisp "" + 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)$Lisp@Boolean) 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 + +<>= + + 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. "" + enE:I -- marks end of element, e.g. " ... " + 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 " ... " + -- 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 [""] + 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. + +<>= + + 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)$Lisp@Boolean) 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 := "" + rrow : S := "" + -- 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 := "+-" + 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,"-",str.uend] + if pos < len-18 then + str := postcondition(str) + str + + + + stringify expr == (object2String$Lisp expr)@S + + + + group str == + concat ["",str,""] + + addBraces str == + concat ["{",str,"}"] + + addBrackets str == + concat ["[",str,"]"] + + parenthesize str == + concat ["(",str,")"] + + precondition expr == + outputTran$Lisp expr + + formatSpecial(op : S, args : L E, prec : I) : S == + arg : E + prescript : Boolean := false + op = "theMap" => "theMap(...)" + op = "AGGLST" => + formatNary(",",args,prec) + op = "AGGSET" => + formatNary(";",args,prec) + op = "TAG" => + group concat [formatMml(first args,prec), + "", + formatMml(second args,prec)] + --RightArrow + op = "VCONCAT" => + group concat("", + concat(concat([concat("",concat(formatMml(u, minPrec),"")) + for u in args]::L S), + "")) + op = "CONCATB" => + formatNary(" ",args,prec) + op = "CONCAT" => + formatNary("",args,minPrec) + op = "QUOTE" => + group concat("'",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 ["",formatMml(first args,minPrec),"¯"] + --OverBar + op = "ROOT" => + null args => "" + tmp : S := group formatMml(first args, minPrec) + null rest args => concat ["",tmp,""] + group concat + ["",tmp,"",formatMml(first rest args, minPrec),""] + op = "SEGMENT" => + tmp : S := concat [formatMml(first args, minPrec),".."] + 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 ["",formatMml(first args, minPrec), + formatSpecial("AGGLST",rest args,minPrec),""] + -- 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 + ""base""formatMml(first args, minPrec)"" + else if #args = 2 then + -- it would be nice to substitue ′ for , in the case of + -- an ordinary derivative, it looks a lot better. + ""base""formatMml(first args,minPrec)""formatMml(first rest args, minPrec)"" + else if #args = 3 then + ""base""formatMml(first args,minPrec)""formatMml(first rest args,minPrec)""formatMml(first rest rest args,minPrec)"" + else if #args = 4 then + ""base""formatMml(first args,minPrec)""formatMml(first rest args,minPrec)""formatMml(first rest rest args,minPrec)""formatMml(first rest rest rest args,minPrec)"" + else + "Problem with multiscript object" + op = "SC" => + -- need to handle indentation someday + null args => "" + tmp := formatNaryNoGroup("", args, minPrec) + group concat ["",tmp,""] + 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 ["not done yet for: ",op,""] + + 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" => "Mistake in formatSub: no SUB" + stringify first rest rest atomE ^= "CONCAT" => "Mistake in formatSub: no CONCAT" + -- 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 := ""tmpS"" + else + s : S := ""string(ndiffs)""tmpS"" + -- 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""tmpS"" + else + s := s""tmpS""string(j)"" + i := i + 1 + s := s"(" + i := 1 + while i < #posLS+1 repeat + tmpS := stringify args.i + s := s""tmpS"" + if i < #posLS then s := s"," + i := i+1 + s := s")" + + 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" => "Mistake in formatSub: no SUB" + stringify first rest rest atomE ^= "CONCAT" => "Mistake in formatSub: no CONCAT" + -- 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 := ""funcS"" + i := 1 + while i < #numLS+1 repeat + s := s","numLS.i"" + i := i + 1 + s := s"(" + i := 1 + while i < #posLS+1 repeat + tmpS := stringify args.i + s := s""tmpS"" + if i < #posLS then s := s"," + i := i+1 + s := s")" + + 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" => "Mistake in formatSuperSub: no SUPERSUB" + #args ^= 1 => "Mistake in SuperSub: #args <> 1" + 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 := ""funcS"" + j : I := 0 + while j < i repeat + s := s"" + j := j + 1 + s := s"("bvarS")" + + 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" => "Mistake in formatSuperSub: no SUPERSUB" + #args ^= 1 => "Mistake in SuperSub: #args <> 1" + 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 := ""string(ndiffs)""funcS""bvarS""string(ndiffs)"("bvarS")" + + 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" => "" + -- Sum + op = "SIGMA2" => "" + -- Sum + op = "PI" => "" + -- Product + op = "PI2" => "" + -- Product +-- op = "INTSIGN" => "" + -- Integral, int + op = "INDEFINTEGRAL" => "" + -- Integral, int + "????" + hold := formatMml(first args,minPrec) + args := rest args + if op ^= "INDEFINTEGRAL" then + if hold ^= "" then + s := concat ["",s,group hold] + else + s := concat ["",s,group " "] + if not null rest args then + hold := formatMml(first args,minPrec) + if hold ^= "" then + s := concat [s,group hold,""] + else + s := concat [s,group " ",""] + 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 ["" integrand "" bvarS ""] + + 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 ["" lowlim "" highlim "" integrand "" bvarS ""] + + + formatMatrix(args : L E) : S == + -- format for args is [[ROW ...],[ROW ...],[ROW ...]] + -- generate string for formatting columns (centered) + group addBrackets concat + ["",formatNaryNoGroup("",args,minPrec), + ""] + + formatFunction(op : S, args : L E, prec : I) : S == + group concat ["",op,"",parenthesize formatNary(",",args,minPrec)] + + formatNullary(op : S) == + op = "NOTHING" => "" + group concat ["",op,"()"] + + formatUnary(op : S, arg : E, prec : I) == + p : I := position(op,unaryOps) + p < 1 => error "unknown unary op" + opPrec := unaryPrecs.p + s : S := concat ["",op,"",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 ["",s1,"",op,"",s2,""] + op = "**" => s := concat ["",s1,"",s2,""] + op = "/" => s := concat ["",s1,"",s2,""] + op = "OVER" => s := concat ["",s1,"",s2,""] + op = "+->" => s := concat ["",s1,"",op,"",s2,""] + s := concat ["",s1,"",op,"",s2,""] + 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) "+" formatZag(rest args)] + op := + op = "," => "," --originally , \: + op = ";" => ";" --originally ; \: should figure these out + op = "*" => "" + -- InvisibleTimes + op = " " => "" + op = "ROW" => "" + op = "+" => "+" + op = "-" => "-" + 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 => ""formatMml(first rest tmpZag,minPrec)""formatMml(first rest rest tmpZag,minPrec)"+"formatZag(rest args)"" + ""formatMml(first rest tmpZag,minPrec)formatMml(first rest rest tmpZag,minPrec)"" + + 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 => ""formatMml(first rest tmpZag,minPrec)""formatMml(first rest rest tmpZag,minPrec)"+"formatZag(rest args)"" + ""formatMml(first rest tmpZag,minPrec)formatMml(first rest rest tmpZag,minPrec)"" + + formatMml(expr : E,prec : I) == + i,len : Integer + intSplitLen : Integer := 20 + ATOM(expr)$Lisp@Boolean => + 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 ["",str,""] + nstr := + empty? str => nstr + concat [nstr," ",str] + concat ["",elt(nstr,segment(2)$US),""] + else str := concat ["",str,""] + str = "%pi" => "π" + -- pi + str = "%e" => "" + -- ExponentialE + str = "%i" => "" + -- 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("",str.u),"") + len > 0 and str.1 = char "%" => concat(concat("",str),"") + len > 1 and digit? str.1 => concat ["",str,""] -- should handle floats + -- presumably this is a literal string + len > 0 and str.1 = char "_"" => + concat(concat("",str),"") + 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("",str),"") + -- if we get to here does that mean it's a variable? + concat ["",str,""] + 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} +<>= +<> +<> +<> +<> +<> +<> + +@ +\section{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. +@ +<<*>>= +<> +<> +@ +\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 "y2+2xy+x2" +--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 +--Ry2+2xy+x2 +--R +--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 +--Ry2+2xy+x2 +--R +--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 +--Rxxx +--R +--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 +--Rxxx +--R +--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 +--R147+53 +--R +--R +--R Type: AlgebraicNumber +--E 8 + +--S 9 of 21 +set [1,2,3] +--R +--R (9) {1,2,3} +--R +--R{1,2,3} +--R +--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 +--R{0,40: 1,47: 2,42: 3,38: 4} +--R +--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 +--Rax-a36x3+a5120x5-a75040x7+a9362880x9-a1139916800x11+O(x12) +--R +--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 +--R[yj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xiyj+xi] +--R +--R +--R Type: Matrix Polynomial Integer +--E 12 + +--S 13 of 21 +y:=operator 'y +--R +--R (13) y +--R +--Ry +--R +--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 +--R4yx3z(x,z) +--R +--R +--R Type: Expression Integer +--E 14 +)clear all + +--S 15 of 21 +y:=operator 'y +--R +--R +--R (1) y +--R +--Ry +--R +--R +--R Type: BasicOperator +--E 15 + +--S 16 of 21 +D(y x,x,2) +--R +--R ,, +--R (2) y (x) +--R +--R +--R2yx2(x) +--R +--R +--R Type: Expression Integer +--E 16 + +--S 17 of 21 +x:=series 'x +--R +--R +--R (3) x +--R +--Rx +--R +--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 +--Rsin(1)+cos(1)x-sin(1)2x2-cos(1)6x3+sin(1)24x4+cos(1)120x5-sin(1)720x6-cos(1)5040x7+sin(1)40320x8+cos(1)362880x9-sin(1)3628800x10+O(x11) +--R +--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 +--R(y-1)(-1)+12-112(y-1)+124(y-1)2-19720(y-1)3+3160(y-1)4-86360480(y-1)5+27524192(y-1)6-339533628800(y-1)7+81831036800(y-1)8-3250433479001600(y-1)9+O((y-1)10) +--R +--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 +--R1.0+z+0.5z2+0.1666666666 6666666667z3+0.0416666666 6666666666 7z4+0.0083333333 3333333333 34z5+0.0013888888 8888888888 89z6+0.0001984126 9841269841 27z7+0.0000248015 8730158730 1587z8+0.0000027557 3192239858 90653z9+0.2755731922 3985890653 E -6z10+O(z11) +--R +--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 +--R3+17+115+11+125+11+17+14 +--R +--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 + 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} +<>= +<> +<> +@ +\subsection{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() == + 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 ",'%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]) <> <> <> +<> <> <> <> 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. <> <> <> +<> )) @ \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 + 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} +<>= + (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 ------------------------