diff --git a/books/bookvol10.3.pamphlet b/books/bookvol10.3.pamphlet index d80c974..d31717e 100644 --- a/books/bookvol10.3.pamphlet +++ b/books/bookvol10.3.pamphlet @@ -53695,6 +53695,1221 @@ HexadecimalExpansion(): Exports == Implementation where @ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{package HTMLFORM HTMLFormat} +Here I have put some information about 'how to use' and 'the benefits of' +this HTML formatter. Also some information for programmers if they want +to extend this package. + +If you want information about creating output formatters in general then, +rather than duplicating content here I refer you to mathml.spad.pamphlet +containing the MathMLFormat domain by Arthur C. Ralfs. This contains useful +information for writers of output formatters. + +\subsection{Overview} + +This package allows users to cut and paste output from the Axiom +command line to a HTML page. This output is enabled by typing: + +\begin{verbatim} +)set output html on +\end{verbatim} + +After this the command line will output html (in addition to other formats +that are enabled) and this html code can then be copied and pasted into a +HTML document. + +The HTML produced is well formed XML, that is, all tags have equivalent +closing tags. + +\subsection{Why output to HTML?} + +In some ways HTMLFormat is a compromise between the standard text output and +specialised formats like MathMLFormat. The potential quality is never +going to be as good as output to a specialised maths renderer but on +the other hand it is a lot better than the clunky fixed width font +text output. The quality is not the only issue though, the direct output +in any format is unlikely to be exactly what the user wants, so possibly +more important than quality is the ability to edit the output. + +HTMLFormat has advantages that the other output formats don't, for instance, +\begin{itemize} +\item It works with any browser without the need for plugins (as far as I know +most computers should have the required fonts) +\item Users can easily annotate and add comments using colour, bold, underline +and so on. +\item Annotations can easily be done with whatever html editor or text editor +you are familiar with. +\item Edits to the output will cause the width of columns and so on to be +automatically adjusted, no need to try to insert spaces to get the +superscripts to line up again! +\item It is very easy to customise output so, for instance, we can fit a lot of +information in a compact space on the page. +\end{itemize} + +\section{Using the formatter} +We can cause the command line interpreter to output in html by typing +the following: + +\begin{verbatim} +)set output html on +\end{verbatim} + +After this the command line will output html (in addition to other formats +that are enabled) and this html code can then be copied and pasted into an +existing HTML document. + +If you do not already have an html page to copy the output to then you can +create one with a text editor and entering the following: + +\begin{verbatim} + + + + Enter Your Title Here + + + Copy and paste the output from command line here. + + +\end{verbatim} + +Or using any program that will export to html such as OpenOffice.org +writer. + +\section{Form of the output} +\begin{verbatim} +HTMLFormat does not try to interpret syntax, for instance in an example like: +(1) -> integral(x^x,x) +it just takes what OutputForm provides and does not try to replace +%A with the bound variable x. +\end{verbatim} + +\section{Matrix Formatting} +A big requirement for me is to fit big matrices on ordinary web pages. + +At the moment the default output for a matrix is a grid, however it easy to +modify this for a single matrix, or a whole page or whole site by using css +(cascading style sheets). For instance we can get a more conventional looking +matrix by adding the following style to the top of the page after the +tag: + +\begin{verbatim} + +\end{verbatim} + +There are many other possibilities, for instance we can generate a matrix +with bars either side to indicate a determinant. All we have to do is +change the css for the site, page or individual element. + +\section{Programmers Guide} +This package converts from OutputForm, which is a hierarchical tree structure, +to html which uses tags arranged in a hierarchical tree structure. So the +package converts from one tree (graph) structure to another. + +This conversion is done in two stages using an intermediate Tree String +structure. This Tree String structure represents HTML where: +\begin{itemize} +\item leafs represents unstructured text +\item string in leafs contains the text +\item non-leafs represents xml elements +\item string in non-leafs represents xml attributes +\end{itemize} + +This is created by traversing OutputForm while building up the Tree String +structure. + +The second stage is to convert the Tree Structure to text. All text output +is done using: +\begin{verbatim} +sayTeX$Lisp +\end{verbatim} +I have not produced and output to String as I don't know a way to append +to a long string efficiently and I don't know how to insert carriage- +returns into a String. + +\subsection{Future Developments} +There would be some benefits in creating a XMLFormat category which would +contain common elements for all xml formatted outputs such as HTMLFormat, +MathMLFormat, SVGFormat and X3DFormat. However programming effort might +be better spent creating a version of OutputForm which has better syntax +information. + +<>= +)set break resume +)sys rm -f HTMLFormat.output +)spool HTMLFormat.output +)set message test on +)set message auto off +)clear all + +--S 1 of 9 +)show HTMLFormat +--R HTMLFormat is a domain constructor +--R Abbreviation for HTMLFormat is HTMLFORM +--R This constructor is exposed in this frame. +--R Issue )edit bookvol10.3.pamphlet to see algebra source code for HTMLFORM +--R +--R------------------------------- Operations -------------------------------- +--R ?=? : (%,%) -> Boolean coerce : OutputForm -> String +--R coerce : % -> OutputForm coerceL : OutputForm -> String +--R coerceS : OutputForm -> String display : String -> Void +--R exprex : OutputForm -> String hash : % -> SingleInteger +--R latex : % -> String ?~=? : (%,%) -> Boolean +--R +--E 1 + +--S 2 of 9 +coerce("3+4"::OutputForm)$HTMLFORM +--R +--R"3+4" +--R +--R (1) " " +--R Type: String +--E 2 + +--S 3 of 9 +coerce("sqrt(3+4)"::OutputForm)$HTMLFORM +--R +--R"sqrt(3+4)" +--R +--R (2) " " +--R Type: String +--E 3 + +--S 4 of 9 +coerce(sqrt(3+4)::OutputForm)$HTMLFORM +--R +--R√7 +--R +--R (3) " " +--R Type: String +--E 4 + +--S 5 of 9 +coerce(sqrt(3+x)::OutputForm)$HTMLFORM +--R +--R +--R +--R +--R +--R +--R
+--R√ +--R +--Rx+3 +--R
+--R +--R (4) " " +--R Type: String +--E 5 + +--S 6 of 9 +coerceS(sqrt(3+x)::OutputForm)$HTMLFORM +--R +--R +--R +--R +--R +--R +--R
+--R√ +--R +--Rx+3 +--R
+--R +--R (5) " " +--R Type: String +--E 6 + +--S 7 of 9 +coerceL(sqrt(3+x)::OutputForm)$HTMLFORM +--R +--R +--R +--R +--R +--R +--R
+--R√ +--R +--Rx+3 +--R
+--R +--R (6) " " +--R Type: String +--E 7 + +--S 8 of 9 +exprex(sqrt(3+x)::OutputForm)$HTMLFORM +--R +--R +--R (7) "{{ROOT}{{+}{x}{3}}}" +--R Type: String +--E 8 + +--S 9 of 9 +display(coerce(sqrt(3+x)::OutputForm)$HTMLFORM)$HTMLFORM +--R +--R +--R +--R +--R +--R +--R
+--R√ +--R +--Rx+3 +--R
+--R +--R Type: Void +--E 9 +)spool +)lisp (bye) +@ +<>= +==================================================================== +HTMLFormat examples +==================================================================== + +coerce("3+4"::OutputForm)$HTMLFORM + "3+4" + +coerce("sqrt(3+4)"::OutputForm)$HTMLFORM + "sqrt(3+4)" + +coerce(sqrt(3+4)::OutputForm)$HTMLFORM + √7 + +coerce(sqrt(3+x)::OutputForm)$HTMLFORM + + + + + +
+ √ + + x+3 +
+ +coerceS(sqrt(3+x)::OutputForm)$HTMLFORM + + + + + +
+ √ + + x+3 +
+ +coerceL(sqrt(3+x)::OutputForm)$HTMLFORM + + + + + +
+ √ + + x+3 +
+ +exprex(sqrt(3+x)::OutputForm)$HTMLFORM + "{{ROOT}{{+}{x}{3}}}" + +display(coerce(sqrt(3+x)::OutputForm)$HTMLFORM)$HTMLFORM + + + + + +
+ √ + + x+3 +
+ +See Also: +o )show HTMLFormat + +@ + +\pagehead{HTMLFormat}{HTMLFORM} +\pagepic{ps/v103htmlformat.eps}{HTMLFORM}{1.00} +{\bf See}\\ +\pagefrom{SetCategory}{SETCAT} + +{\bf Exports:}\\ +\begin{tabular}{lllll} +\cross{HTMLFORM}{?=?} & +\cross{HTMLFORM}{?~=?} & +\cross{HTMLFORM}{coerce} & +\cross{HTMLFORM}{coerceL} & +\cross{HTMLFORM}{coerceS} \\ +\cross{HTMLFORM}{display} & +\cross{HTMLFORM}{exprex} & +\cross{HTMLFORM}{hash} & +\cross{HTMLFORM}{latex} & +\end{tabular} + +<>= +)abbrev domain HTMLFORM HTMLFormat +++ Author: Martin J Baker, Arthur C. Ralfs, Robert S. Sutor +++ Date: January 2010 +++ Description: +++ HtmlFormat provides a coercion from OutputForm to html. +HTMLFormat(): public == private where + E ==> OutputForm + I ==> Integer + L ==> List + S ==> String + + public == SetCategory with + coerce: E -> S + ++ coerce(o) changes o in the standard output format to html format. + ++ + ++X coerce(sqrt(3+x)::OutputForm)$HTMLFORM + coerceS: E -> S + ++ coerceS(o) changes o in the standard output format to html + ++ format and displays formatted result. + ++ + ++X coerceS(sqrt(3+x)::OutputForm)$HTMLFORM + coerceL: E -> S + ++ coerceL(o) changes o in the standard output format to html + ++ format and displays result as one long string. + ++ + ++X coerceL(sqrt(3+x)::OutputForm)$HTMLFORM + exprex: E -> S + ++ exprex(o) coverts \spadtype{OutputForm} to \spadtype{String} + ++ + ++X exprex(sqrt(3+x)::OutputForm)$HTMLFORM + display: S -> Void + ++ display(o) prints the string returned by coerce. + ++ + ++X display(coerce(sqrt(3+x)::OutputForm)$HTMLFORM)$HTMLFORM + + private == add + import OutputForm + import Character + import Integer + import List OutputForm + import List String + + expr: E + prec,opPrec: I + str: S + blank : S := " \ " + + maxPrec : I := 1000000 + minPrec : I := 0 + + unaryOps : L S := ["-"]$(L S) + unaryPrecs : L I := [700]$(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,600,600]$(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", "SLASH"] + + -- the next two lists provide translations for some strings for + -- which HTML has some special character codes. + specialStrings : L S := + ["cos", "cot", "csc", "log", "sec", "sin", "tan", _ + "cosh", "coth", "csch", "sech", "sinh", "tanh", _ + "acos","asin","atan","erf","...","$","infinity","Gamma", _ + "%pi","%e","%i"] + specialStringsInHTML : L S := + ["cos","cot","csc","log","sec","sin","tan", _ + "cosh","coth","csch","sech","sinh","tanh", _ + "arccos","arcsin","arctan","erf","…","$","∞",_ + "Г","π","ⅇ","ⅈ"] + + debug := false + + atomize:E -> L E + + formatBinary:(S,L E, I) -> Tree S + + formatFunction:(Tree S,L E, I) -> Tree S + + formatMatrix:L E -> Tree S + + formatNary:(S,L E, I) -> Tree S + + formatNaryNoGroup:(S,L E, I) -> Tree S + + formatNullary:S -> Tree S + + formatPlex:(S,L E, I) -> Tree S + + formatSpecial:(S,L E, I) -> Tree S + + formatUnary:(S, E, I) -> Tree S + + formatHtml:(E,I) -> Tree S + + precondition:E -> E + -- this function is applied to the OutputForm expression before + -- doing anything else. + + outputTree:Tree S -> Void + -- This function traverses the tree and linierises it into a string. + -- To get the formatting we use a nested set of tables. It also checks + -- for +- and removes the +. it may also need to remove the outer + -- set of brackets. + + stringify:E -> S + + coerce(expr : E): S == + outputTree formatHtml(precondition expr, minPrec) + " " + + coerceS(expr : E): S == + outputTree formatHtml(precondition expr, minPrec) + " " + + coerceL(expr : E): S == + outputTree formatHtml(precondition expr, minPrec) + " " + + display(html : S): Void == + sayTeX$Lisp html + void()$Void + + newNode(tag:S,node: Tree S): (Tree S) == + t := tree(S,[node]) + setvalue!(t,tag) + t + + newNodes(tag:S,nodes: L Tree S): (Tree S) == + t := tree(S,nodes) + setvalue!(t,tag) + t + + -- returns true if this can be represented without a table + notTable?(node: Tree S): Boolean == + empty?(node) => true + leaf?(node) => true + prefix?("table",value(node))$String => false + c := children(node) + for a in c repeat + if not notTable?(a) then return false + true + + -- this retuns a string representation of OutputForm arguments + -- it is used when debug is true to trace the calling of functions + -- in this package + argsToString(args : L E): S == + sop : S := exprex first args + args := rest args + s : S := concat ["{",sop] + for a in args repeat + s1 : S := exprex a + s := concat [s,s1] + s := concat [s,"}"] + + 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 + (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 + s : S := concat ["{",sop] + if nargs > 0 then + for a in args repeat + s1 : S := exprex a + s := concat [s,s1] + s := concat [s,"}"] + + 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 + + -- output html test using tables and + -- remove unnecessary '+' at end of first string + -- when second string starts with '-' + outputTree(t: Tree S): Void == + endWithPlus:Boolean := false -- if the last string ends with '+' + -- and the next string starts with '-' then the '+' needs to be + -- removed + if empty?(t) then + --if debug then sayTeX$Lisp "outputTree empty" + return void()$Void + if leaf?(t) then + --if debug then sayTeX$Lisp concat("outputTree leaf:",value(t)) + sayTeX$Lisp value(t) + return void()$Void + tagName := copy value(t) + tagPos := position(char(" "),tagName,1)$String + if tagPos > 1 then + tagName := split(tagName,char(" ")).1 + --sayTeX$Lisp "outputTree: tagPos="string(tagPos)" "tagName + if value(t) ~= "" then sayTeX$Lisp concat ["<",value(t),">"] + c := children(t) + enableGrid:Boolean := (#c > 1) and not notTable?(t) + if enableGrid then + if tagName = "table" then enableGrid := false + if tagName = "tr" then enableGrid := false + b:List Boolean := [leaf?(c1) for c1 in c] + -- if all children are strings then no need to wrap in table + allString: Boolean := true + for c1 in c repeat if not leaf?(c1) then allString := false + if allString then + s:String := "" + for c1 in c repeat s := concat(s,value(c1)) + sayTeX$Lisp s + if value(t) ~= "" then sayTeX$Lisp concat [""] + return void()$Void + if enableGrid then + sayTeX$Lisp "" + sayTeX$Lisp "" + for c1 in c repeat + if enableGrid then sayTeX$Lisp "" + if enableGrid then + sayTeX$Lisp "" + sayTeX$Lisp "
" + outputTree(c1) + if enableGrid then sayTeX$Lisp "
" + if value(t) ~= "" then sayTeX$Lisp concat [""] + void()$Void + + stringify expr == (mathObject2String$Lisp expr)@S + + precondition expr == + outputTran$Lisp expr + + -- I dont know what SC is so put it in a table for now + formatSC(args : L E, prec : I) : Tree S == + if debug then sayTeX$Lisp "formatSC: "concat [" args=",_ + argsToString(args)," prec=",string(prec)$S] + null args => tree("") + cells:L Tree S := [_ + newNode("td id='sc' style='border-bottom-style:solid'",_ + formatHtml(a,prec)) for a in args] + row:Tree S := newNodes("tr id='sc'",cells) + newNode("table border='0' id='sc'",row) + + -- to build an overbar we put it in a single column, + -- single row table and set the top border to solid + buildOverbar(content : Tree S) : Tree S == + if debug then sayTeX$Lisp "buildOverbar" + cell:Tree S := _ + newNode("td id='overbar' style='border-top-style:solid'",content) + row:Tree S := newNode("tr id='overbar'",cell) + newNode("table border='0' id='overbar'",row) + + -- to build an square root we put it in a double column, + -- single row table and set the top border of the second column to + -- solid + buildRoot(content : Tree S) : Tree S == + if debug then sayTeX$Lisp "buildRoot" + if leaf?(content) then + -- root of a single term so no need for overbar + return newNodes("",[tree("√"),content]) + cell1:Tree S := newNode("td id='root'",tree("√")) + cell2:Tree S := _ + newNode("td id='root' style='border-top-style:solid'",content) + row:Tree S := newNodes("tr id='root'",[cell1,cell2]) + newNode("table border='0' id='root'",row) + + -- to build an 'n'th root we put it in a double column, + -- single row table and set the top border of the second column to + -- solid + buildNRoot(content : Tree S,nth: Tree S) : Tree S == + if debug then sayTeX$Lisp "buildNRoot" + power:Tree S := newNode("sup",nth) + if leaf?(content) then + -- root of a single term so no need for overbar + return newNodes("",[power,tree("√"),content]) + cell1:Tree S := newNodes("td id='nroot'",[power,tree("√")]) + cell2:Tree S := _ + newNode("td id='nroot' style='border-top-style:solid'",content) + row:Tree S := newNodes("tr id='nroot'",[cell1,cell2]) + newNode("table border='0' id='nroot'",row) + + -- formatSpecial handles "theMap","AGGLST","AGGSET","TAG","SLASH", + -- "VCONCAT", "CONCATB","CONCAT","QUOTE","BRACKET","BRACE","PAREN", + -- "OVERBAR","ROOT", "SEGMENT","SC","MATRIX","ZAG" + -- note "SUB" and "SUPERSUB" are handled directly by formatHtml + formatSpecial(op : S, args : L E, prec : I) : Tree S == + if debug then sayTeX$Lisp _ + "formatSpecial: " concat ["op=",op," args=",argsToString(args),_ + " prec=",string(prec)$S] + arg : E + prescript : Boolean := false + op = "theMap" => tree("theMap(...)") + op = "AGGLST" => + formatNary(",",args,prec) + op = "AGGSET" => + formatNary(";",args,prec) + op = "TAG" => + newNodes("",[formatHtml(first args,prec),tree("→"),_ + formatHtml(second args,prec)]) + --RightArrow + op = "SLASH" => + newNodes("",[formatHtml(first args, prec),tree("/"),_ + formatHtml(second args,prec)]) + op = "VCONCAT" => + newNodes("table",[newNode("td",formatHtml(u, minPrec))_ + for u in args]::L Tree S) + op = "CONCATB" => + formatNary(" ",args,prec) + op = "CONCAT" => + formatNary("",args,minPrec) + op = "QUOTE" => + newNodes("",[tree("'"),formatHtml(first args, minPrec)]) + op = "BRACKET" => + newNodes("",[tree("["),formatHtml(first args, minPrec),tree("]")]) + op = "BRACE" => + newNodes("",[tree("{"),formatHtml(first args, minPrec),tree("}")]) + op = "PAREN" => + newNodes("",[tree("("),formatHtml(first args, minPrec),tree(")")]) + op = "OVERBAR" => + null args => tree("") + buildOverbar(formatHtml(first args,minPrec)) + op = "ROOT" and #args < 1 => tree("") + op = "ROOT" and #args = 1 => _ + buildRoot(formatHtml(first args, minPrec)) + op = "ROOT" and #args > 1 => _ + buildNRoot(formatHtml(first args, minPrec),_ + formatHtml(second args, minPrec)) + op = "SEGMENT" => + -- '..' indicates a range in a list for example + tmp : Tree S := newNodes("",[formatHtml(first args, minPrec),_ + tree("..")]) + null rest args => tmp + newNodes("",[tmp,formatHtml(first rest args, minPrec)]) + op = "SC" => formatSC(args,minPrec) + 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 "+" + newNodes("",[tree(" \zag{"),formatHtml(first args, minPrec), + tree("}{"), + formatHtml(first rest args,minPrec),tree("}")]) + tree("formatSpecial not implemented:"op) + + formatSuperSub(expr : E, args : L E, opPrec : I) : Tree S == + -- This one produces ordinary derivatives with differential notation, + -- it needs a little more work yet. + -- first have to divine the semantics, add cases as needed + if debug then sayTeX$Lisp _ + "formatSuperSub: " concat ["expr=",stringify expr," args=",_ + argsToString(args)," prec=",string(opPrec)$S] + atomE : L E := atomize(expr) + op : S := stringify first atomE + op ~= "SUPERSUB" => tree("Mistake in formatSuperSub: no SUPERSUB") + #args ~= 1 => tree("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"," + res:Tree S := newNodes("",_ + [tree("ⅆ"string(ndiffs)""funcS"ⅆ"),_ + formatHtml(first args,minPrec),tree(""string(ndiffs)"⁡"),_ + formatHtml(first args,minPrec),tree(")")]) + res + + -- build structure such as integral as a table + buildPlex3(main:Tree S,supsc:Tree S,op:Tree S,subsc:Tree S) : Tree S == + if debug then sayTeX$Lisp "buildPlex" + ssup:Tree S := newNode("td id='plex'",supsc) + sop:Tree S := newNode("td id='plex'",op) + ssub:Tree S := newNode("td id='plex'",subsc) + m:Tree S := newNode("td rowspan='3' id='plex'",main) + rows:(List Tree S) := [newNodes("tr id='plex'",[ssup,m]),_ + newNode("tr id='plex'",sop),newNode("tr id='plex'",ssub)] + newNodes("table border='0' id='plex'",rows) + + -- build structure such as integral as a table + buildPlex2(main : Tree S,supsc : Tree S,op : Tree S) : Tree S == + if debug then sayTeX$Lisp "buildPlex" + ssup:Tree S := newNode("td id='plex'",supsc) + sop:Tree S := newNode("td id='plex'",op) + m:Tree S := newNode("td rowspan='2' id='plex'",main) + rows:(List Tree S) := [newNodes("tr id='plex'",[sop,m]),_ + newNode("tr id='plex'",ssup)] + newNodes("table border='0' id='plex'",rows) + + -- format an integral + -- args.1 = "NOTHING" + -- args.2 = bound variable + -- args.3 = body, thing being integrated + -- + -- axiom replaces the bound variable with somthing like + -- %A and puts the original variable used + -- in the input command as a superscript on the integral sign. + formatIntSign(args : L E, opPrec : I) : Tree 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 ... + if debug then sayTeX$Lisp "formatIntSign: " concat [" args=",_ + argsToString(args)," prec=",string(opPrec)$S] + (stringify first args) = "NOTHING" => + buildPlex2(formatHtml(args.3,opPrec),tree("∫"),_ + formatHtml(args.2,opPrec)) -- could use ∫ or ∫ + buildPlex3(formatHtml(first args,opPrec),formatHtml(args.3,opPrec),_ + tree("∫"),formatHtml(args.2,opPrec)) + + -- plex ops are "SIGMA","SIGMA2","PI","PI2","INTSIGN","INDEFINTEGRAL" + -- expects 2 or 3 args + formatPlex(op : S, args : L E, prec : I) : Tree S == + if debug then sayTeX$Lisp "formatPlex: " concat ["op=",op," args=",_ + argsToString(args)," prec=",string(prec)$S] + checkarg:Boolean := false + 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 : Tree S := + op = "SIGMA" => + checkarg := true + tree("∑") + -- Sum + op = "SIGMA2" => + checkarg := true + tree("∑") + -- Sum + op = "PI" => + checkarg := true + tree("∏") + -- Product + op = "PI2" => + checkarg := true + tree("∏") + -- Product + op = "INTSIGN" => tree("∫") + -- Integral, int + op = "INDEFINTEGRAL" => tree("∫") + -- Integral, int + tree("formatPlex: unexpected op:"op) + -- if opPrec < prec then perhaps we should parenthesize? + -- but we need to be careful we don't get loads of unnecessary + -- brackets + if n=2 then return buildPlex2(formatHtml(first args,minPrec),_ + formatHtml(args.2,minPrec),s) + buildPlex3(formatHtml(first args,minPrec),formatHtml(args.2,minPrec),_ + s,formatHtml(args.3,minPrec)) + + -- an example is: op=ROW arg={{ROW}{1}{2}} + formatMatrixRow(op : S, arg : E, prec : I,y:I,h:I) : L Tree S == + if debug then sayTeX$Lisp "formatMatrixRow: " concat ["op=",op,_ + " args=",stringify arg," prec=",string(prec)$S] + ATOM(arg)$Lisp@Boolean => [_ + tree("formatMatrixRow does not contain row")] + l : L E := (arg pretend L E) + op : S := stringify first l + args : L E := rest l + --sayTeX$Lisp "formatMatrixRow op="op" args="argsToString(args) + w:I := #args + cells:(List Tree S) := empty() + for x in 1..w repeat + --sayTeX$Lisp "formatMatrixRow: x="string(x)$S" width="string(w)$S + attrib:S := "td id='mat'" + if x=1 then attrib := "td id='matl'" + if x=w then attrib := "td id='matr'" + if y=1 then attrib := "td id='matt'" + if y=h then attrib := "td id='matb'" + if x=1 and y=1 then attrib := "td id='matlt'" + if x=1 and y=h then attrib := "td id='matlb'" + if x=w and y=1 then attrib := "td id='matrt'" + if x=w and y=h then attrib := "td id='matrb'" + cells := append(cells,[newNode(attrib,formatHtml(args.(x),prec))]) + cells + + -- an example is: op=MATRIX args={{ROW}{1}{2}}{{ROW}{3}{4}} + formatMatrixContent(op : S, args : L E, prec : I) : L Tree S == + if debug then sayTeX$Lisp "formatMatrixContent: " concat ["op=",op,_ + " args=",argsToString(args)," prec=",string(prec)$S] + y:I := 0 + rows:(List Tree S) := [newNodes("tr id='mat'",_ + formatMatrixRow("ROW",e,prec,y:=y+1,#args)) for e in args] + rows + + formatMatrix(args : L E) : Tree S == + -- format for args is [[ROW ...],[ROW ...],[ROW ...]] + -- generate string for formatting columns (centered) + if debug then sayTeX$Lisp "formatMatrix: " concat ["args=",_ + argsToString(args)] + newNodes("table border='1' id='mat'",_ + formatMatrixContent("MATRIX",args,minPrec)) + + -- output arguments in column table + buildColumnTable(elements : List Tree S) : Tree S == + if debug then sayTeX$Lisp "buildColumnTable" + cells:(List Tree S) := [newNode("td id='col'",j) for j in elements] + rows:(List Tree S) := [newNode("tr id='col'",i) for i in cells] + newNodes("table border='0' id='col'",rows) + + -- build superscript structure as either sup tag or + -- if it contains anything that won't go into a + -- sup tag then build it as a table + buildSuperscript(main : Tree S,super : Tree S) : Tree S == + if debug then sayTeX$Lisp "buildSuperscript" + notTable?(super) => newNodes("",[main,newNode("sup",super)]) + m:Tree S := newNode("td rowspan='2' id='sup'",main) + su:Tree S := newNode("td id='sup'",super) + e:Tree S := newNode("td id='sup'",tree(" ")) + rows:(List Tree S) := [newNodes("tr id='sup'",[m,su]),_ + newNode("tr id='sup'",e)] + newNodes("table border='0' id='sup'",rows) + + -- build subscript structure as either sub tag or + -- if it contains anything that won't go into a + -- sub tag then build it as a table + buildSubscript(main : Tree S,subsc : Tree S) : Tree S == + if debug then sayTeX$Lisp "buildSubscript" + notTable?(subsc) => newNodes("",[main,newNode("sub",subsc)]) + m:Tree S := newNode("td rowspan='2' id='sub'",main) + su:Tree S := newNode("td id='sub'",subsc) + e:Tree S := newNode("td id='sub'",tree(" ")) + rows:(List Tree S) := [newNodes("tr id='sub'",[m,e]),_ + newNode("tr id='sub'",su)] + newNodes("table border='0' id='sub'",rows) + + formatSub(expr : E, args : L E, opPrec : I) : Tree S == + -- format subscript + -- this function expects expr to start with SUB + -- it expects first args to be the operator or value that + -- the subscript is applied to + -- and the rest args to be the subscript + if debug then sayTeX$Lisp "formatSub: " concat ["expr=",_ + stringify expr," args=",argsToString(args)," prec=",_ + string(opPrec)$S] + atomE : L E := atomize(expr) + if empty?(atomE) then + if debug then sayTeX$Lisp "formatSub: expr=empty" + return tree("formatSub: expr=empty") + op : S := stringify first atomE + op ~= "SUB" => + if debug then sayTeX$Lisp "formatSub: expr~=SUB" + tree("formatSub: expr~=SUB") + -- assume args.1 is the expression and args.2 is its subscript + if #args < 2 then + if debug then sayTeX$Lisp concat("formatSub: num args=",_ + string(#args)$String)$String + return tree(concat("formatSub: num args=",_ + string(#args)$String)$String) + if #args > 2 then + if debug then sayTeX$Lisp concat("formatSub: num args=",_ + string(#args)$String)$String + return buildSubscript(formatHtml(first args,opPrec),_ + newNodes("",[formatHtml(e,opPrec) for e in rest args])) + buildSubscript(formatHtml(first args,opPrec),_ + formatHtml(args.2,opPrec)) + + formatFunction(op : Tree S, args : L E, prec : I) : Tree S == + if debug then sayTeX$Lisp "formatFunction: " concat ["args=",_ + argsToString(args)," prec=",string(prec)$S] + newNodes("",[op,tree("("),formatNary(",",args,minPrec),tree(")")]) + + formatNullary(op : S) : Tree S == + if debug then sayTeX$Lisp "formatNullary: " concat ["op=",op] + op = "NOTHING" => empty()$Tree(S) + tree(op"()") + + -- implement operation with single argument + -- an example is minus '-' + -- prec is precidence of operator, used to force brackets where + -- more tightly bound operation is next to less tightly bound operation + formatUnary(op : S, arg : E, prec : I) : Tree S == + if debug then sayTeX$Lisp "formatUnary: " concat ["op=",op," arg=",_ + stringify arg," prec=",string(prec)$S] + p : I := position(op,unaryOps) + p < 1 => error "unknown unary op" + opPrec := unaryPrecs.p + s : Tree S := newNodes("",[tree(op),formatHtml(arg,opPrec)]) + opPrec < prec => newNodes("",[tree("("),s,tree(")")]) + s + + -- output division with numerator above the denominator + -- implemented as a table + buildOver(top : Tree S,bottom : Tree S) : Tree S == + if debug then sayTeX$Lisp "buildOver" + topCell:Tree S := newNode("td",top) + bottomCell:Tree S := newNode("td style='border-top-style:solid'",_ + bottom) + rows:(List Tree S) := [newNode("tr id='col'",topCell),_ + newNode("tr id='col'",bottomCell)] + newNodes("table border='0' id='col'",rows) + + -- op may be: "|","^","/","OVER","+->" + -- note: "+" and "*" are n-ary ops + formatBinary(op : S, args : L E, prec : I) : Tree S == + if debug then sayTeX$Lisp "formatBinary: " concat ["op=",op,_ + " args=",argsToString(args)," prec=",string(prec)$S] + p : I := position(op,binaryOps) + p < 1 => error "unknown binary op" + opPrec := binaryPrecs.p + -- if base op is product or sum need to add parentheses + if ATOM(first args)$Lisp@Boolean then + opa:S := stringify first args + else + la : L E := (first args pretend L E) + opa : S := stringify first la + if (opa = "SIGMA" or opa = "SIGMA2" or opa = "PI" or opa = "PI2")_ + and op = "^" then + s1 : Tree S := newNodes("",[tree("("),formatHtml(first args,_ + opPrec),tree(")")]) + else + s1 : Tree S := formatHtml(first args, opPrec) + s2 : Tree S := formatHtml(first rest args, opPrec) + op = "|" => newNodes("",[s1,tree(op),s2]) + op = "^" => buildSuperscript(s1,s2) + op = "/" => newNodes("",[s1,tree(op),s2]) + op = "OVER" => buildOver(s1,s2) + op = "+->" => newNodes("",[s1,tree("|—›"),s2]) + newNodes("",[s1,tree(op),s2]) + + -- build a zag from a table with a right part and a + -- upper and lower left part + buildZag(top:Tree S,lowerLeft:Tree S,lowerRight:Tree S) : Tree S == + if debug then sayTeX$Lisp "buildZag" + cellTop:Tree S := _ + newNode("td colspan='2' id='zag' style='border-bottom-style:solid'",_ + top) + cellLowerLeft:Tree S := newNodes("td id='zag'",[lowerLeft,tree("+")]) + cellLowerRight:Tree S := newNode("td id='zag'",lowerRight) + row1:Tree S := newNodes("tr id='zag'",[cellTop]) + row2:Tree S := newNodes("tr id='zag'",[cellLowerLeft,cellLowerRight]) + newNodes("table border='0' id='zag'",[row1,row2]) + + formatZag(args : L E,nestLevel:I) : Tree S == + -- args will be a list of things like this {{ZAG}{1}{7}}, the ZAG + -- must be there, the '1' and '7' could conceivably be more complex + -- expressions + -- + -- ex 1. continuedFraction(314159/100000) + -- {{+}{3}{{ZAG}{1}{7}}{{ZAG}{1}{15}}{{ZAG}{1}{1}}{{ZAG}{1}{25}} + -- {{ZAG}{1}{1}}{{ZAG}{1}{7}}{{ZAG}{1}{4}}} + -- this is the preconditioned output form + -- including "op", the args list would be the rest of this + -- i.e op = '+' and args = {{3}{{ZAG}{1}{7}}{{ZAG}{1}{15}} + -- {{ZAG}{1}{1}}{{ZAG}{1}{25}}{{ZAG}{1}{1}}{{ZAG}{1}{7}}{{ZAG}{1}{4}}} + -- + -- ex 2. continuedFraction(14159/100000) + -- this one doesn't have the leading integer + -- {{+}{{ZAG}{1}{7}}{{ZAG}{1}{15}}{{ZAG}{1}{1}}{{ZAG}{1}{25}} + -- {{ZAG}{1}{1}}{{ZAG}{1}{7}}{{ZAG}{1}{4}}} + -- + -- ex 3. continuedFraction(3,repeating [1], repeating [3,6]) + -- {{+}{3}{{ZAG}{1}{3}}{{ZAG}{1}{6}}{{ZAG}{1}{3}}{{ZAG}{1}{6}} + -- {{ZAG}{1}{3}}{{ZAG}{1}{6}}{{ZAG}{1}{3}}{{ZAG}{1}{6}} + -- {{ZAG}{1}{3}}{{ZAG}{1}{6}}{...}} + -- + -- In each of these examples the args list consists of the terms + -- following the '+' op + -- so the first arg 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 contains "ZAG". + -- Note that since the resulting tables are nested we need + -- to handle the whole continued fraction at once, i.e. we can't + -- just look for, e.g., {{ZAG}{1}{6}} + -- + -- we will assume that the font starts at 16px and reduce it by 4 + -- outer zag + -- next zag + -- next zag + -- next zag + -- lowest zag + if debug then sayTeX$Lisp "formatZag: " concat ["args=",_ + argsToString(args)] + tmpZag : L E := first args pretend L E + fontAttrib : S := + nestLevel < 2 => "span style='font-size:16px'" + nestLevel = 2 => "span style='font-size:14px'" + nestLevel = 3 => "span style='font-size:12px'" + nestLevel = 4 => "span style='font-size:10px'" + "span style='font-size:9px'" + -- may want to test that tmpZag contains 'ZAG' + #args > 1 => + newNode(fontAttrib,buildZag(formatHtml(first rest tmpZag,minPrec),_ + formatHtml(first rest rest tmpZag,minPrec),_ + formatZag(rest args,nestLevel+1))) + (first args = "...":: E)@Boolean => tree("…") + op:S := stringify first args + position("ZAG",op,1) > 0 => + newNode(fontAttrib,buildOver(formatHtml(first rest tmpZag,minPrec),_ + formatHtml(first rest rest tmpZag,minPrec))) + tree("formatZag: Last argument in ZAG construct unknown operator: "op) + + -- returns true if this term starts with a minus '-' sign + -- this is used so that we can suppress any plus '+' in front + -- of the - so we dont get terms like +- + neg?(arg : E) : Boolean == + if debug then sayTeX$Lisp "neg?: " concat ["arg=",argsToString([arg])] + ATOM(arg)$Lisp@Boolean => false + l : L E := (arg pretend L E) + op : S := stringify first l + op = "-" => true + false + + formatNary(op : S, args : L E, prec : I) : Tree S == + if debug then sayTeX$Lisp "formatNary: " concat ["op=",op," args=",_ + argsToString(args)," prec=",string(prec)$S] + formatNaryNoGroup(op, args, prec) + + -- possible op values are: + -- ",",";","*"," ","ROW","+","-" + -- an example is content of matrix which gives: + -- {{ROW}{1}{2}}{{ROW}{3}{4}} + -- or AGGLST which gives op=, args={{1}{2}} + -- + -- need to: + -- format ZAG + -- check for +- + -- add brackets for sigma or pi or root ("SIGMA","SIGMA2","PI","PI2") + formatNaryNoGroup(op : S, args : L E, prec : I) : Tree S == + if debug then sayTeX$Lisp "formatNaryNoGroup: " concat ["op=",op,_ + " args=",argsToString(args)," prec=",string(prec)$S] + checkargs:Boolean := false + null args => empty()$Tree(S) + p : I := position(op,naryOps) + p < 1 => error "unknown nary op" + -- need to test for "ZAG" case and divert it here + (#args > 1) and (position("ZAG",stringify first rest args,1) > 0) => + tmpS : S := stringify first args + position("ZAG",tmpS,1) > 0 => formatZag(args,1) + newNodes("",[formatHtml(first args,minPrec),tree("+"),_ + formatZag(rest args,1)]) + -- At least for the ops "*","+","-" we need to test to see if a + -- sigma or pi is one of their arguments because we might need + -- parentheses as indicated + -- by the problem with summation(operator(f)(i),i=1..n)+1 versus + -- summation(operator(f)(i)+1,i=1..n) having identical displays as of + -- 2007-12-21 + l := empty()$Tree(S) + opPrec := naryPrecs.p + -- if checkargs is true check each arg except last one to see if it's + -- a sigma or pi and if so add parentheses. Other op's may have to be + -- checked for in future + count:I := 1 + tags : (L Tree S) + if opPrec < prec then tags := [tree("("),formatHtml(args.1,opPrec)] + if opPrec >= prec then tags := [formatHtml(args.1,opPrec)] + for a in rest args repeat + if op ~= "+" or not neg?(a) then tags := append(tags,[tree(op)]) + tags := append(tags,[formatHtml(a,opPrec)]) + if opPrec < prec then tags := append(tags,[tree(")")]) + newNodes("",tags) + + -- expr is a tree structure + -- prec is the precision of integers + -- formatHtml returns a string for this node in the tree structure + -- and calls recursivly to evaluate sub expressions + formatHtml(arg : E,prec : I) : Tree S == + if debug then sayTeX$Lisp "formatHtml: " concat ["arg=",_ + argsToString([arg])," prec=",string(prec)$S] + i,len : Integer + intSplitLen : Integer := 20 + ATOM(arg)$Lisp@Boolean => + if debug then sayTeX$Lisp "formatHtml atom: " concat ["expr=",_ + stringify arg," prec=",string(prec)$S] + str := stringify arg + (i := position(str,specialStrings)) > 0 => + tree(specialStringsInHTML.i) + tree(str) + l : L E := (arg pretend L E) + null l => tree(blank) + op : S := stringify first l + args : L E := rest l + nargs : I := #args + -- 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) + -- special cases + -- specialOps are: + -- MATRIX, BRACKET, BRACE, CONCATB, VCONCAT + -- AGGLST, CONCAT, OVERBAR, ROOT, SUB, TAG + -- SUPERSUB, ZAG, AGGSET, SC, PAREN + -- SEGMENT, QUOTE, theMap, SLASH + member?(op, specialOps) => formatSpecial(op,args,prec) + -- specialOps are: + -- SIGMA, SIGMA2, PI, PI2, INTSIGN, INDEFINTEGRAL + member?(op, plexOps) => formatPlex(op,args,prec) + -- nullary case: function with no aguments + 0 = nargs => formatNullary op + -- unary case: function with one agument such as '-' + (1 = nargs) and member?(op, unaryOps) => + formatUnary(op, first args, prec) + -- binary case + -- binary ops include special processing for | ^ / OVER and +-> + (2 = nargs) and member?(op, binaryOps) => + formatBinary(op, args, prec) + -- nary case: including '+' and '*' + member?(op,naryNGOps) => formatNaryNoGroup(op,args, prec) + member?(op,naryOps) => formatNary(op,args, prec) + + op1 := formatHtml(first l,minPrec) + formatFunction(op1,args,prec) + +@ +<>= +"HTMLFORM" [color="#88FF44",href="bookvol10.3.pdf#nameddest=HTMLFORM"] +"STRING" [color="#4488FF",href="bookvol10.2.pdf#nameddest=STRING"] +"HTMLFORM" -> "STRING" + +@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{domain HDP HomogeneousDirectProduct} <>= @@ -149471,6 +150686,7 @@ Note that this code is not included in the generated catdef.spad file. <> <> <> +<> <> <> <> diff --git a/books/bookvol5.pamphlet b/books/bookvol5.pamphlet index 954e3af..ee58d0f 100644 --- a/books/bookvol5.pamphlet +++ b/books/bookvol5.pamphlet @@ -1019,7 +1019,7 @@ the Bill Burge's parser. <>= (defun |ncIntLoop| () (let ((curinstream *standard-output*) - (curoutstream *standard-input*)) + (curoutstream *standard-input*)) (declare (special curinstream curoutstream)) (|intloop|))) @@ -1346,16 +1346,16 @@ This function performs those setup commands. \calls{init-memory-config}{set-hole-size} <>= (defun init-memory-config (&key - (cons 500) - (fixnum 200) - (symbol 500) - (package 8) - (array 400) - (string 500) - (cfun 100) - (cpages 3000) - (rpages 1000) - (hole 2000) ) + (cons 500) + (fixnum 200) + (symbol 500) + (package 8) + (array 400) + (string 500) + (cfun 100) + (cpages 3000) + (rpages 1000) + (hole 2000) ) ;; initialize AKCL memory allocation parameters #+:AKCL (progn @@ -1625,7 +1625,7 @@ $current-directory = "/research/test/" (setq $library-directory-list (mapcar #'make-absolute-filename $relative-library-directory-list)) (setq |$defaultMsgDatabaseName| - (pathname (make-absolute-filename "/doc/msgs/s2-us.msgs"))) + (pathname (make-absolute-filename "/doc/msgs/s2-us.msgs"))) (setq |$msgDatabaseName| ()) (setq $current-directory $spadroot)) @@ -14273,33 +14273,33 @@ the text in the buffer. In the description of the keys below, ^n means Control-n, or holding the CONTROL key down while pressing "n". Errors will ring the terminal bell. -^A/^E : Move cursor to beginning/end of the line. +^A/^E : Move cursor to beginning/end of the line. ^F/^B : Move cursor forward/backward one character. -^D : Delete the character under the cursor. +^D : Delete the character under the cursor. ^H, DEL : Delete the character to the left of the cursor. -^K : Kill from the cursor to the end of line. -^L : Redraw current line. -^O : Toggle overwrite/insert mode. Initially in insert mode. Text - added in overwrite mode (including yanks) overwrite - existing text, while insert mode does not overwrite. +^K : Kill from the cursor to the end of line. +^L : Redraw current line. +^O : Toggle overwrite/insert mode. Initially in insert mode. Text + added in overwrite mode (including yanks) overwrite + existing text, while insert mode does not overwrite. ^P/^N : Move to previous/next item on history list. ^R/^S : Perform incremental reverse/forward search for string on - the history list. Typing normal characters adds to the current - search string and searches for a match. Typing ^R/^S marks - the start of a new search, and moves on to the next match. - Typing ^H or DEL deletes the last character from the search - string, and searches from the starting location of the last search. - Therefore, repeated DEL's appear to unwind to the match nearest - the point at which the last ^R or ^S was typed. If DEL is - repeated until the search string is empty the search location - begins from the start of the history list. Typing ESC or - any other editing character accepts the current match and - loads it into the buffer, terminating the search. -^T : Toggle the characters under and to the left of the cursor. -^Y : Yank previously killed text back at current location. Note that - this will overwrite or insert, depending on the current mode. + the history list. Typing normal characters adds to the current + search string and searches for a match. Typing ^R/^S marks + the start of a new search, and moves on to the next match. + Typing ^H or DEL deletes the last character from the search + string, and searches from the starting location of the last search. + Therefore, repeated DEL's appear to unwind to the match nearest + the point at which the last ^R or ^S was typed. If DEL is + repeated until the search string is empty the search location + begins from the start of the history list. Typing ESC or + any other editing character accepts the current match and + loads it into the buffer, terminating the search. +^T : Toggle the characters under and to the left of the cursor. +^Y : Yank previously killed text back at current location. Note that + this will overwrite or insert, depending on the current mode. ^U : Show help (this text). -TAB : Perform command completion based on word to the left of the cursor. +TAB : Perform command completion based on word to the left of the cursor. Words are deemed to contain only the alphanumeric and the % ! ? _ characters. NL, CR : returns current buffer to the program. @@ -15557,44 +15557,43 @@ See:\\ (eval-when (eval load) (setq |$systemCommands| '( - (|abbreviations| . |compiler| ) - (|boot| . |development|) + (|abbreviations| . |compiler| ) + (|boot| . |development|) (|browse| . |development|) - (|cd| . |interpreter|) - (|clear| . |interpreter|) - (|close| . |interpreter|) - (|compiler| . |compiler| ) - (|copyright| . |interpreter|) - (|credits| . |interpreter|) - (|describe| . |interpreter|) - (|display| . |interpreter|) - (|edit| . |interpreter|) - (|fin| . |development|) - (|frame| . |interpreter|) - (|help| . |interpreter|) - (|history| . |interpreter|) -;; (|input| . |interpreter|) - (|lisp| . |development|) - (|library| . |interpreter|) - (|load| . |interpreter|) - (|ltrace| . |interpreter|) - (|pquit| . |interpreter|) - (|quit| . |interpreter|) - (|read| . |interpreter|) - (|savesystem| . |interpreter|) - (|set| . |interpreter|) - (|show| . |interpreter|) - (|spool| . |interpreter|) - (|summary| . |interpreter|) - (|synonym| . |interpreter|) - (|system| . |interpreter|) - (|trace| . |interpreter|) - (|trademark| . |interpreter|) - (|undo| . |interpreter|) - (|what| . |interpreter|) - (|with| . |interpreter|) - (|workfiles| . |development|) - (|zsystemdevelopment| . |interpreter|) + (|cd| . |interpreter|) + (|clear| . |interpreter|) + (|close| . |interpreter|) + (|compiler| . |compiler| ) + (|copyright| . |interpreter|) + (|credits| . |interpreter|) + (|describe| . |interpreter|) + (|display| . |interpreter|) + (|edit| . |interpreter|) + (|fin| . |development|) + (|frame| . |interpreter|) + (|help| . |interpreter|) + (|history| . |interpreter|) + (|lisp| . |development|) + (|library| . |interpreter|) + (|load| . |interpreter|) + (|ltrace| . |interpreter|) + (|pquit| . |interpreter|) + (|quit| . |interpreter|) + (|read| . |interpreter|) + (|savesystem| . |interpreter|) + (|set| . |interpreter|) + (|show| . |interpreter|) + (|spool| . |interpreter|) + (|summary| . |interpreter|) + (|synonym| . |interpreter|) + (|system| . |interpreter|) + (|trace| . |interpreter|) + (|trademark| . |interpreter|) + (|undo| . |interpreter|) + (|what| . |interpreter|) + (|with| . |interpreter|) + (|workfiles| . |development|) + (|zsystemdevelopment| . |interpreter|) ))) @ @@ -16923,55 +16922,55 @@ of synonyms which are in common use. (eval-when (eval load) (setq |$InitialCommandSynonymAlist| '( - (|?| . "what commands") - (|ap| . "what things") - (|apr| . "what things") + (|?| . "what commands") + (|ap| . "what things") + (|apr| . "what things") (|apropos| . "what things") - (|cache| . "set functions cache") - (|cl| . "clear") - (|cls| . "zsystemdevelopment )cls") - (|cms| . "system") - (|co| . "compiler") - (|d| . "display") - (|dep| . "display dependents") + (|cache| . "set functions cache") + (|cl| . "clear") + (|cls| . "zsystemdevelopment )cls") + (|cms| . "system") + (|co| . "compiler") + (|d| . "display") + (|dep| . "display dependents") (|dependents| . "display dependents") - (|e| . "edit") + (|e| . "edit") (|expose| . "set expose add constructor") - (|fc| . "zsystemdevelopment )c") - (|fd| . "zsystemdevelopment )d") - (|fdt| . "zsystemdevelopment )dt") - (|fct| . "zsystemdevelopment )ct") - (|fctl| . "zsystemdevelopment )ctl") - (|fe| . "zsystemdevelopment )e") - (|fec| . "zsystemdevelopment )ec") - (|fect| . "zsystemdevelopment )ect") - (|fns| . "exec spadfn") + (|fc| . "zsystemdevelopment )c") + (|fd| . "zsystemdevelopment )d") + (|fdt| . "zsystemdevelopment )dt") + (|fct| . "zsystemdevelopment )ct") + (|fctl| . "zsystemdevelopment )ctl") + (|fe| . "zsystemdevelopment )e") + (|fec| . "zsystemdevelopment )ec") + (|fect| . "zsystemdevelopment )ect") + (|fns| . "exec spadfn") (|fortran| . "set output fortran") - (|h| . "help") - (|hd| . "system hypertex &") - (|kclam| . "boot clearClams ( )") + (|h| . "help") + (|hd| . "system hypertex &") + (|kclam| . "boot clearClams ( )") (|killcaches| . "boot clearConstructorAndLisplibCaches ( )") - (|patch| . "zsystemdevelopment )patch") - (|pause| . "zsystemdevelopment )pause") + (|patch| . "zsystemdevelopment )patch") + (|pause| . "zsystemdevelopment )pause") (|prompt| . "set message prompt") (|recurrence| . "set functions recurrence") (|restore| . "history )restore") - (|save| . "history )save") + (|save| . "history )save") (|startGraphics| . "system $AXIOM/lib/viewman &") (|startNAGLink| . "system $AXIOM/lib/nagman &") (|stopGraphics| . "lisp (|sockSendSignal| 2 15)") (|stopNAGLink| . "lisp (|sockSendSignal| 8 15)") - (|time| . "set message time") - (|type| . "set message type") + (|time| . "set message time") + (|type| . "set message type") (|unexpose| . "set expose drop constructor") - (|up| . "zsystemdevelopment )update") + (|up| . "zsystemdevelopment )update") (|version| . "lisp (axiomVersion)") - (|w| . "what") - (|wc| . "what categories") - (|wd| . "what domains") + (|w| . "what") + (|wc| . "what categories") + (|wd| . "what domains") (|who| . "lisp (pprint credits)") - (|wp| . "what packages") - (|ws| . "what synonyms") + (|wp| . "what packages") + (|ws| . "what synonyms") ))) @ @@ -22941,7 +22940,7 @@ o )history (declare (special /editfile)) (setq /editfile l) (cond - (q (/rq)) + (q (/rq)) (t (/rf)) ) (flag |boot-NewKEY| 'key) (|terminateSystemCommand|) @@ -23556,7 +23555,7 @@ args arguments for compiling AXIOM code |setOutputLibrary| NIL |htSetOutputLibrary| - ) + ) @ \section{Variables Used} \section{Functions} @@ -23996,6 +23995,7 @@ otherwise the new algebra won't be loaded by the interpreter when needed. (|HallBasis| . HB) (|Heap| . HEAP) (|HexadecimalExpansion| . HEXADEC) + (|HTMLFormat| . HTMLFORM) (|IdealDecompositionPackage| . IDECOMP) (|IndexCard| . ICARD) (|InfClsPt| . ICP) @@ -27691,8 +27691,9 @@ algebra display output in algebraic form On:CONSOLE characters choose special output character set plain fortran create output in FORTRAN format Off:CONSOLE fraction how fractions are formatted vertical +html create output in HTML style Off:CONSOLE length line length of output displays 77 -mathml create output in MathML style Off:CONSOLE +mathml create output in MathML style Off:CONSOLE openmath create output in OpenMath style Off:CONSOLE script display output in SCRIPT formula format Off:CONSOLE scripts show subscripts,... linearly off @@ -27713,6 +27714,7 @@ is defined within the output structure. <> <> <> +<> <> <> <> @@ -28548,6 +28550,210 @@ The current setting is: Off:CONSOLE @ +\subsection{html} +\begin{verbatim} +----------------------- The html Option ------------------------ + + Description: create output in html style + + )set output html is used to tell AXIOM to turn html-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 html + where arg can be one of + on turn html printing on + off turn html printing off (default state) + console send html output to screen (default state) + fp<.fe> send html output to file with file prefix fp + and file extension .fe. If not given, + .fe defaults to .html. + +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.html, +issue the two commands + + )set output html on + )set output html 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} +\defdollar{htmlFormat} +<>= +(defvar |$htmlFormat| nil "create output in HTML format") + +@ +\defdollar{htmlOutputFile} +<>= +(defvar |$htmlOutputFile| "CONSOLE" + "where HTML output goes (enter {\em console} or a pathname)") + +@ +<>= + (|html| + "create output in HTML style" + |interpreter| + FUNCTION + |setOutputHtml| + (("create output in HTML format" + LITERALS + |$htmlFormat| + (|off| |on|) + |off|) + (|break| |$htmlFormat|) + ("where HTML output goes (enter {\em console} or a pathname)" + FILENAME + |$htmlOutputFile| + |chkOutputFileName| + "console")) + NIL) + +@ + +\defun{setOutputHtml}{setOutputHtml} +\calls{setOutputHtml}{defiostream} +\calls{setOutputHtml}{concat} +\calls{setOutputHtml}{describeSetOutputHtml} +\calls{setOutputHtml}{pairp} +\calls{setOutputHtml}{qcdr} +\calls{setOutputHtml}{qcar} +\calls{setOutputHtml}{member} +\calls{setOutputHtml}{upcase} +\calls{setOutputHtml}{sayKeyedMsg} +\calls{setOutputHtml}{shut} +\calls{setOutputHtml}{pathnameType} +\calls{setOutputHtml}{pathnameDirectory} +\calls{setOutputHtml}{pathnameName} +\callsdollar{setOutputHtml}{filep} +\calls{setOutputHtml}{make-outstream} +\calls{setOutputHtml}{object2String} +\usesdollar{setOutputHtml}{htmlOutputStream} +\usesdollar{setOutputHtml}{htmlOutputFile} +\usesdollar{setOutputHtml}{htmlFormat} +\usesdollar{setOutputHtml}{filep} +<>= +(defun |setOutputHtml| (arg) + (let (label tmp1 tmp2 ptype fn ft fm filename teststream) + (declare (special |$htmlOutputStream| |$htmlOutputFile| |$htmlFormat| + $filep)) + (cond + ((eq arg '|%initialize%|) + (setq |$htmlOutputStream| + (defiostream '((mode . output) (device . console)) 255 0)) + (setq |$htmlOutputFile| "CONSOLE") + (setq |$htmlFormat| nil)) + ((eq arg '|%display%|) + (if |$htmlFormat| + (setq label "On:") + (setq label "Off:")) + (concat label |$htmlOutputFile|)) + ((or (null arg) (eq arg '|%describe%|) (eq (car arg) '?)) + (|describeSetOutputHtml|)) + (t + (cond + ((and (pairp arg) + (eq (qcdr arg) nil) + (progn (setq fn (qcar arg)) t) + (|member| fn '(y n ye yes no o on of off console + |y| |n| |ye| |yes| |no| |o| |on| |of| |off| |console|))) + '|ok|) + (t (setq arg (list fn '|smml|)))) + (cond + ((and (pairp arg) + (eq (qcdr arg) nil) + (progn (setq fn (qcar arg)) t)) + (cond + ((|member| (upcase fn) '(y n ye o of)) + (|sayKeyedMsg| 's2iv0002 '(|HTML| |html|))) + ((|member| (upcase fn) '(no off)) (setq |$htmlFormat| nil)) + ((|member| (upcase fn) '(yes on)) (setq |$htmlFormat| t)) + ((eq (upcase fn) 'console) + (shut |$htmlOutputStream|) + (setq |$htmlOutputStream| + (defiostream '((mode . output) (device . console)) 255 0)) + (setq |$htmlOutputFile| "CONSOLE")))) + ((or + (and (pairp arg) + (progn + (setq fn (qcar arg)) + (setq tmp1 (qcdr arg)) + (and (pairp tmp1) + (eq (qcdr tmp1) nil) + (progn (setq ft (qcar tmp1)) t)))) + (and (pairp arg) + (progn (setq fn (qcar arg)) + (setq tmp1 (qcdr arg)) + (and (pairp tmp1) + (progn + (setq ft (qcar tmp1)) + (setq tmp2 (qcdr tmp1)) + (and (pairp tmp2) + (eq (qcdr tmp2) nil) + (progn + (setq fm (qcar tmp2)) + t))))))) + (when (setq ptype (|pathnameType| fn)) + (setq fn + (concat (|pathnameDirectory| fn) (|pathnameName| fn))) + (setq ft ptype)) + (unless fm (setq fm 'a)) + (setq filename ($filep fn ft fm)) + (cond + ((null filename) (|sayKeyedMsg| 's2iv0003 (list fn ft fm))) + ((setq teststream (make-outstream filename 255 0)) + (shut |$htmlOutputStream|) + (setq |$htmlOutputStream| teststream) + (setq |$htmlOutputFile| (|object2String| filename)) + (|sayKeyedMsg| 's2iv0004 (list "HTML" |$htmlOutputFile|))) + (t (|sayKeyedMsg| 's2iv0003 (list fn ft fm))))) + (t + (|sayKeyedMsg| 's2iv0005 nil) + (|describeSetOutputHtml|))))))) + +@ + +\defun{describeSetOutputHtml}{describeSetOutputHtml} +\calls{describeSetOutputHtml}{sayBrightly} +\calls{describeSetOutputHtml}{setOutputHtml} +<>= +(defun |describeSetOutputHtml| () + (|sayBrightly| (LIST + '|%b| ")set output html" + '|%d| "is used to tell AXIOM to turn HTML-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 html " + '|%l| " where arg can be one of" + '|%l| " on turn HTML printing on" + '|%l| " off turn HTML printing off (default state)" + '|%l| " console send HTML output to screen (default state)" + '|%l| " fp<.fe> send HTML 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| "HTML output to the file" + '|%b| "polymer.smml," + '|%d| "issue the two commands" + '|%l| + '|%l| " )set output html on" + '|%l| " )set output html 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| (|setOutputHtml| '|%display%|) + '|%d|))) + +@ + \subsection{openmath} \begin{verbatim} ----------------------- The openmath Option ------------------------ @@ -34770,43 +34976,43 @@ o )library (file-closed nil) (/editfile *spad-input-file*) (|$noSubsumption| |$noSubsumption|) in-stream out-stream) (declare (special echo-meta /editfile *comp370-apply* *eof* - file-closed xcape |$noSubsumption| |$InteractiveFrame| + file-closed xcape |$noSubsumption| |$InteractiveFrame| |$InteractiveMode| |$InitialDomainsInScope|)) ;; only rebind |$InteractiveFrame| if compiling (progv (if (not |$InteractiveMode|) '(|$InteractiveFrame|)) - (if (not |$InteractiveMode|) - (list (|addBinding| '|$DomainsInScope| - `((fluid . |true|) - (|special| . ,(copy-tree |$InitialDomainsInScope|))) - (|addBinding| '|$Information| nil + (if (not |$InteractiveMode|) + (list (|addBinding| '|$DomainsInScope| + `((fluid . |true|) + (|special| . ,(copy-tree |$InitialDomainsInScope|))) + (|addBinding| '|$Information| nil (|makeInitialModemapFrame|))))) (init-boot/spad-reader) (unwind-protect (progn (setq in-stream (if *spad-input-file* - (open *spad-input-file* :direction :input) - *standard-input*)) + (open *spad-input-file* :direction :input) + *standard-input*)) (initialize-preparse in-stream) (setq out-stream (if *spad-output-file* - (open *spad-output-file* :direction :output) - *standard-output*)) + (open *spad-output-file* :direction :output) + *standard-output*)) (when *spad-output-file* - (format out-stream "~&;;; -*- Mode:Lisp; Package:Boot -*-~%~%") - (print-package "BOOT")) + (format out-stream "~&;;; -*- Mode:Lisp; Package:Boot -*-~%~%") + (print-package "BOOT")) (setq curoutstream out-stream) (loop (if (or *eof* file-closed) (return nil)) (catch 'spad_reader - (if (setq boot-line-stack (preparse in-stream)) - (let ((line (cdar boot-line-stack))) - (declare (special line)) - (|PARSE-NewExpr|) - (let ((parseout (pop-stack-1)) ) - (when parseout - (let ((*standard-output* out-stream)) - (s-process parseout)) - (format out-stream "~&"))) - ))) + (if (setq boot-line-stack (preparse in-stream)) + (let ((line (cdar boot-line-stack))) + (declare (special line)) + (|PARSE-NewExpr|) + (let ((parseout (pop-stack-1)) ) + (when parseout + (let ((*standard-output* out-stream)) + (s-process parseout)) + (format out-stream "~&"))) + ))) (ioclear in-stream out-stream))) (if *spad-input-file* (shut in-stream)) (if *spad-output-file* (shut out-stream))) @@ -35278,7 +35484,7 @@ gets the index into the EBCDIC table, and returns the appropriate character. :direction :input))))) (if (and (numberp char-position) (> char-position 0)) (file-position strm char-position)) - strm)))) + strm)))) @ @@ -35975,17 +36181,17 @@ Format of an entry in interp.daase: (constructor-name operationalist constructormodemap - modemaps -- this should not be needed. eliminate it. - object -- the name of the object file to load for this con. + modemaps -- this should not be needed. eliminate it. + object -- the name of the object file to load for this con. constructorcategory -- note that this info is the cadar of the - constructormodemap for domains and packages so it is stored - as NIL for them. it is valid for categories. - niladic -- t or nil directly + constructormodemap for domains and packages so it is stored + as NIL for them. it is valid for categories. + niladic -- t or nil directly unused - cosig -- kept directly - constructorkind -- kept directly - defaultdomain -- a short list, for %i - ancestors -- used to compute new category updates + cosig -- kept directly + constructorkind -- kept directly + defaultdomain -- a short list, for %i + ancestors -- used to compute new category updates ) \end{verbatim} \calls{interpOpen}{unsqueeze} @@ -36380,7 +36586,7 @@ Format of an entry in browse.daase: (when (setq struct (get constructor 'database)) (setq data (database-dependents struct)))) (otherwise (warn "~%(GETDATABASE ~a ~a) failed~%" constructor key))) - (when (numberp data) ;fetch the real data + (when (numberp data) ;fetch the real data (when *miss* (format t "getdatabase miss: ~20a ~a~%" constructor key)) (file-position stream data) (setq data (unsqueeze (read stream))) @@ -36409,19 +36615,19 @@ Format of an entry in browse.daase: (case key ; fixup the special cases (sourcefile (when (and data (string= (directory-namestring data) "") - (string= (pathname-type data) "spad")) + (string= (pathname-type data) "spad")) (setq data (concatenate 'string $spadroot "/../../src/algebra/" data)))) (asharp? ; is this asharp code? (if (consp data) (setq data (cdr data)) (setq data nil))) - (object ; fix up system object pathname + (object ; fix up system object pathname (if (consp data) (setq data - (if (string= (directory-namestring (car data)) "") - (concatenate 'string $spadroot "/algebra/" (car data) ".o") - (car data))) + (if (string= (directory-namestring (car data)) "") + (concatenate 'string $spadroot "/algebra/" (car data) ".o") + (car data))) (when (and data (string= (directory-namestring data) "")) (setq data (concatenate 'string $spadroot "/algebra/" data ".o"))))))) data)) @@ -36494,7 +36700,7 @@ The localdatabase function tries to find files in the order of: (mapcan #'(lambda (f) (when (string-equal (pathname-type f) "nrlib") (list (concatenate 'string (namestring f) "/" - vmlisp::*index-filename*)))) allfiles)))) + vmlisp::*index-filename*)))) allfiles)))) (let (thisdir nrlibs object only dir key (|$forceDatabaseUpdate| t) noexpose) (declare (special |$forceDatabaseUpdate| vmlisp::*index-filename* |$ConstructorCache|)) @@ -36506,7 +36712,7 @@ The localdatabase function tries to find files in the order of: (when dir (setq nrlibs (processDir dir thisdir))) (dolist (file filelist) (let ((filename (pathname-name file)) - (namedir (directory-namestring file))) + (namedir (directory-namestring file))) (unless namedir (setq thisdir (concatenate 'string thisdir "/"))) (cond ((setq file (probe-file @@ -36563,7 +36769,7 @@ The localdatabase function tries to find files in the order of: (setq *allconstructors* (adjoin key *allconstructors*)) (setf (get key 'database) dbstruct) ; store the struct, side-effect it... (setf (database-constructorform dbstruct) constructorform) - (setq *allOperations* nil) ; force this to recompute + (setq *allOperations* nil) ; force this to recompute (setf (database-object dbstruct) object) (setq abbrev (intern (pathname-name (first (last (pathname-directory object)))))) @@ -36779,36 +36985,36 @@ constructor abbreviation to pamphlet file name. (dolist (con (|allConstructors|)) (let (dbstruct) (when (setq dbstruct (get con 'database)) - (setf (database-cosig dbstruct) - (cons nil (mapcar #'|categoryForm?| - (cddar (database-constructormodemap dbstruct))))) - (when (and (|categoryForm?| con) - (= (length (setq d (|domainsOf| (list con) NIL NIL))) 1)) - (setq d (caar d)) - (when (= (length d) (length (|getConstructorForm| con))) - (format t " ~a has a default domain of ~a~%" con (car d)) - (setf (database-defaultdomain dbstruct) (car d))))))) - ; note: genCategoryTable creates *ancestors-hash*. write-interpdb - ; does gethash calls into it rather than doing a getdatabase call. + (setf (database-cosig dbstruct) + (cons nil (mapcar #'|categoryForm?| + (cddar (database-constructormodemap dbstruct))))) + (when (and (|categoryForm?| con) + (= (length (setq d (|domainsOf| (list con) NIL NIL))) 1)) + (setq d (caar d)) + (when (= (length d) (length (|getConstructorForm| con))) + (format t " ~a has a default domain of ~a~%" con (car d)) + (setf (database-defaultdomain dbstruct) (car d))))))) + ; note: genCategoryTable creates *ancestors-hash*. write-interpdb + ; does gethash calls into it rather than doing a getdatabase call. (write-interpdb) (write-warmdata) (when (probe-file (final-name "compress")) - (delete-file (final-name "compress"))) + (delete-file (final-name "compress"))) (rename-file "compress.build" (final-name "compress")) (when (probe-file (final-name "interp")) - (delete-file (final-name "interp"))) + (delete-file (final-name "interp"))) (rename-file "interp.build" (final-name "interp")) (when (probe-file (final-name "operation")) - (delete-file (final-name "operation"))) + (delete-file (final-name "operation"))) (rename-file "operation.build" (final-name "operation")) (when (probe-file (final-name "browse")) - (delete-file (final-name "browse"))) + (delete-file (final-name "browse"))) (rename-file "browse.build" - (final-name "browse")) + (final-name "browse")) (when (probe-file (final-name "category")) - (delete-file (final-name "category"))) + (delete-file (final-name "category"))) (rename-file "category.build" - (final-name "category"))))) + (final-name "category"))))) @ @@ -36868,12 +37074,12 @@ short negative numbers. <>= (defvar *attributes* '(|nil| |infinite| |arbitraryExponent| |approximate| |complex| - |shallowMutable| |canonical| |noetherian| |central| - |partiallyOrderedSet| |arbitraryPrecision| |canonicalsClosed| - |noZeroDivisors| |rightUnitary| |leftUnitary| - |additiveValuation| |unitsKnown| |canonicalUnitNormal| - |multiplicativeValuation| |finiteAggregate| |shallowlyMutable| - |commutative|) "The list of known algebra attributes") + |shallowMutable| |canonical| |noetherian| |central| + |partiallyOrderedSet| |arbitraryPrecision| |canonicalsClosed| + |noZeroDivisors| |rightUnitary| |leftUnitary| + |additiveValuation| |unitsKnown| |canonicalUnitNormal| + |multiplicativeValuation| |finiteAggregate| |shallowlyMutable| + |commutative|) "The list of known algebra attributes") @ @@ -36893,7 +37099,7 @@ short negative numbers. (finish-output out) (setq masterpos (file-position out)) (setq compresslist - (append (|allConstructors|) (|allOperations|) *attributes*)) + (append (|allConstructors|) (|allOperations|) *attributes*)) (push "algebra" compresslist) (push "failed" compresslist) (push 'signature compresslist) @@ -36961,12 +37167,12 @@ using integers as indexes into the compression vector. (defun unsqueeze (expr) (declare (special *compressvector*)) (cond ((atom expr) - (cond ((and (numberp expr) (<= expr 0)) - (svref *compressVector* (- expr))) - (t expr))) - (t (rplaca expr (unsqueeze (car expr))) - (rplacd expr (unsqueeze (cdr expr))) - expr))) + (cond ((and (numberp expr) (<= expr 0)) + (svref *compressVector* (- expr))) + (t expr))) + (t (rplaca expr (unsqueeze (car expr))) + (rplacd expr (unsqueeze (cdr expr))) + expr))) @ @@ -36976,17 +37182,17 @@ using integers as indexes into the compression vector. (constructor-name operationalist constructormodemap - modemaps -- this should not be needed. eliminate it. - object -- the name of the object file to load for this con. + modemaps -- this should not be needed. eliminate it. + object -- the name of the object file to load for this con. constructorcategory -- note that this info is the cadar of the - constructormodemap for domains and packages so it is stored - as NIL for them. it is valid for categories. - niladic -- t or nil directly + constructormodemap for domains and packages so it is stored + as NIL for them. it is valid for categories. + niladic -- t or nil directly unused - cosig -- kept directly - constructorkind -- kept directly - defaultdomain -- a short list, for %i - ancestors -- used to compute new category updates + cosig -- kept directly + constructorkind -- kept directly + defaultdomain -- a short list, for %i + ancestors -- used to compute new category updates ) \end{verbatim} @@ -36997,8 +37203,8 @@ Here I'll try to outline the interp database write procedure "build interp.daase from hash tables" (declare (special $spadroot *ancestors-hash*)) (let (opalistpos modemapspos cmodemappos master masterpos obj *print-pretty* - concategory categorypos kind niladic cosig abbrev defaultdomain - ancestors ancestorspos out) + concategory categorypos kind niladic cosig abbrev defaultdomain + ancestors ancestorspos out) (declare (special *print-pretty*)) (print "building interp.daase") @@ -37187,8 +37393,8 @@ Here I'll try to outline the interp database write procedure "build interp.daase from hash tables" (declare (special $spadroot *ancestors-hash*)) (let (opalistpos modemapspos cmodemappos master masterpos obj *print-pretty* - concategory categorypos kind niladic cosig abbrev defaultdomain - ancestors ancestorspos out) + concategory categorypos kind niladic cosig abbrev defaultdomain + ancestors ancestorspos out) (declare (special *print-pretty*)) (print "building interp.daase") (setq out (open "interp.build" :direction :output)) @@ -37866,9 +38072,9 @@ semantics survive. (defun bvec-greater (bv1 bv2) (let ((pos (mismatch bv1 bv2))) (cond ((or (null pos) (>= pos (length bv1))) nil) - ((< pos (length bv2)) (> (bit bv1 pos) (bit bv2 pos))) - ((find 1 bv1 :start pos) t) - (t nil)))) + ((< pos (length bv2)) (> (bit bv1 pos) (bit bv2 pos))) + ((find 1 bv1 :start pos) t) + (t nil)))) @ @@ -39969,6 +40175,7 @@ This needs to work off the internal exposure list, not the file. <> <> <> +<> <> <> <> @@ -41035,6 +41242,7 @@ This needs to work off the internal exposure list, not the file. <> <> <> +<> <> <> <> diff --git a/books/bookvol7.1.pamphlet b/books/bookvol7.1.pamphlet index b18f78b..37294f3 100644 --- a/books/bookvol7.1.pamphlet +++ b/books/bookvol7.1.pamphlet @@ -79058,6 +79058,8 @@ that the correct output is shown in the text. \menudownlink{{4.5. TeX Format}}{ugInOutTeXPage} \menudownlink{{4.6. IBM Script Formula Format}}{ugInOutScriptPage} \menudownlink{{4.7. FORTRAN Format}}{ugInOutFortranPage} + \menudownlink{{4.8. HTML Format}}{ugInOutHTMLPage} + \menudownlink{{4.9. MathML Format}}{ugInOutMathMLPage} \endmenu \endscroll \autobuttons @@ -79204,6 +79206,8 @@ The names are \item[fortran] for FORTRAN output. \item[algebra] for monospace two-dimensional mathematical output. \item[tex] for \texht{\TeX}{TeX} output. +\item[html] for HTML output. +\item[mathml] for MathML output. \item[script] for IBM Script Formula Format output. \enditems \indent{0} @@ -80063,6 +80067,46 @@ Look at the code generated for the matrix again. \end{paste}\end{patch} @ +\pagehead{ugInOutHTMLPage}{ug04.ht}{HTML Format} +<>= +\begin{page}{ugInOutHTMLPage}{4.8. HTML Format} +\beginscroll + +Axiom can produce HTML output for your expressions. +The output is produced by the HTMLFormat domain. + +To turn on HTML output formatting, issue this. + +)set output html on + +To turn HTML output formatting off, issue + +)set output html off + +\endscroll +\autobuttons +\end{page} + +\pagehead{ugInOutMathMLPage}{ug04.ht}{MathML Format} +<>= +\begin{page}{ugInOutMathMLPage}{4.9. MathML Format} +\beginscroll + +Axiom can produce MathML output for your expressions. +The output is produced by the MathMLFormat domain. + +To turn on MathML output formatting, issue this. + +)set output mathml on + +To turn MathML output formatting off, issue + +)set output mathml off + +\endscroll +\autobuttons +\end{page} + \chapter{Users Guide Chapter 5 (ug05.ht)} \pagehead{ugLangPage}{ug05.ht} {Introduction to the Axiom Interactive Language} diff --git a/books/ps/v103htmlformat.eps b/books/ps/v103htmlformat.eps new file mode 100644 index 0000000..a582746 --- /dev/null +++ b/books/ps/v103htmlformat.eps @@ -0,0 +1,266 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: Graphviz version 2.20.2 (Mon Mar 30 10:09:11 UTC 2009) +%%For: (root) root +%%Title: pic +%%Pages: 1 +%%BoundingBox: 36 36 140 152 +%%EndComments +save +%%BeginProlog +/DotDict 200 dict def +DotDict begin + +/setupLatin1 { +mark +/EncodingVector 256 array def + EncodingVector 0 + +ISOLatin1Encoding 0 255 getinterval putinterval +EncodingVector 45 /hyphen put + +% Set up ISO Latin 1 character encoding +/starnetISO { + dup dup findfont dup length dict begin + { 1 index /FID ne { def }{ pop pop } ifelse + } forall + /Encoding EncodingVector def + currentdict end definefont +} def +/Times-Roman starnetISO def +/Times-Italic starnetISO def +/Times-Bold starnetISO def +/Times-BoldItalic starnetISO def +/Helvetica starnetISO def +/Helvetica-Oblique starnetISO def +/Helvetica-Bold starnetISO def +/Helvetica-BoldOblique starnetISO def +/Courier starnetISO def +/Courier-Oblique starnetISO def +/Courier-Bold starnetISO def +/Courier-BoldOblique starnetISO def +cleartomark +} bind def + +%%BeginResource: procset graphviz 0 0 +/coord-font-family /Times-Roman def +/default-font-family /Times-Roman def +/coordfont coord-font-family findfont 8 scalefont def + +/InvScaleFactor 1.0 def +/set_scale { + dup 1 exch div /InvScaleFactor exch def + scale +} bind def + +% styles +/solid { [] 0 setdash } bind def +/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def +/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def +/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def +/bold { 2 setlinewidth } bind def +/filled { } bind def +/unfilled { } bind def +/rounded { } bind def +/diagonals { } bind def + +% hooks for setting color +/nodecolor { sethsbcolor } bind def +/edgecolor { sethsbcolor } bind def +/graphcolor { sethsbcolor } bind def +/nopcolor {pop pop pop} bind def + +/beginpage { % i j npages + /npages exch def + /j exch def + /i exch def + /str 10 string def + npages 1 gt { + gsave + coordfont setfont + 0 0 moveto + (\() show i str cvs show (,) show j str cvs show (\)) show + grestore + } if +} bind def + +/set_font { + findfont exch + scalefont setfont +} def + +% draw text fitted to its expected width +/alignedtext { % width text + /text exch def + /width exch def + gsave + width 0 gt { + [] 0 setdash + text stringwidth pop width exch sub text length div 0 text ashow + } if + grestore +} def + +/boxprim { % xcorner ycorner xsize ysize + 4 2 roll + moveto + 2 copy + exch 0 rlineto + 0 exch rlineto + pop neg 0 rlineto + closepath +} bind def + +/ellipse_path { + /ry exch def + /rx exch def + /y exch def + /x exch def + matrix currentmatrix + newpath + x y translate + rx ry scale + 0 0 1 0 360 arc + setmatrix +} bind def + +/endpage { showpage } bind def +/showpage { } def + +/layercolorseq + [ % layer color sequence - darkest to lightest + [0 0 0] + [.2 .8 .8] + [.4 .8 .8] + [.6 .8 .8] + [.8 .8 .8] + ] +def + +/layerlen layercolorseq length def + +/setlayer {/maxlayer exch def /curlayer exch def + layercolorseq curlayer 1 sub layerlen mod get + aload pop sethsbcolor + /nodecolor {nopcolor} def + /edgecolor {nopcolor} def + /graphcolor {nopcolor} def +} bind def + +/onlayer { curlayer ne {invis} if } def + +/onlayers { + /myupper exch def + /mylower exch def + curlayer mylower lt + curlayer myupper gt + or + {invis} if +} def + +/curlayer 0 def + +%%EndResource +%%EndProlog +%%BeginSetup +14 default-font-family set_font +1 setmiterlimit +% /arrowlength 10 def +% /arrowwidth 5 def + +% make sure pdfmark is harmless for PS-interpreters other than Distiller +/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse +% make '<<' and '>>' safe on PS Level 1 devices +/languagelevel where {pop languagelevel}{1} ifelse +2 lt { + userdict (<<) cvn ([) cvn load put + userdict (>>) cvn ([) cvn load put +} if + +%%EndSetup +setupLatin1 +%%Page: 1 1 +%%PageBoundingBox: 36 36 140 152 +%%PageOrientation: Portrait +0 0 1 beginpage +gsave +36 36 104 116 boxprim clip newpath +1 1 set_scale 0 rotate 40 40 translate +% HTMLFORM +gsave +[ /Rect [ 0 72 96 108 ] + /Border [ 0 0 0 ] + /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=HTMLFORM) >> + /Subtype /Link +/ANN pdfmark +0.273 0.733 1.000 nodecolor +newpath 96 108 moveto +0 108 lineto +0 72 lineto +96 72 lineto +closepath fill +1 setlinewidth +filled +0.273 0.733 1.000 nodecolor +newpath 96 108 moveto +0 108 lineto +0 72 lineto +96 72 lineto +closepath stroke +0.000 0.000 0.000 nodecolor +14 /Times-Roman set_font +7.5 85.9 moveto 81 (HTMLFORM) alignedtext +grestore +% STRING +gsave +[ /Rect [ 13 0 83 36 ] + /Border [ 0 0 0 ] + /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=STRING) >> + /Subtype /Link +/ANN pdfmark +0.606 0.733 1.000 nodecolor +newpath 83 36 moveto +13 36 lineto +13 0 lineto +83 0 lineto +closepath fill +1 setlinewidth +filled +0.606 0.733 1.000 nodecolor +newpath 83 36 moveto +13 36 lineto +13 0 lineto +83 0 lineto +closepath stroke +0.000 0.000 0.000 nodecolor +14 /Times-Roman set_font +21 13.9 moveto 54 (STRING) alignedtext +grestore +% HTMLFORM->STRING +gsave +1 setlinewidth +0.000 0.000 0.000 edgecolor +newpath 48 72 moveto +48 64 48 55 48 46 curveto +stroke +0.000 0.000 0.000 edgecolor +newpath 51.5 46 moveto +48 36 lineto +44.5 46 lineto +closepath fill +1 setlinewidth +solid +0.000 0.000 0.000 edgecolor +newpath 51.5 46 moveto +48 36 lineto +44.5 46 lineto +closepath stroke +grestore +endpage +showpage +grestore +%%PageTrailer +%%EndPage: 1 +%%Trailer +end +restore +%%EOF diff --git a/changelog b/changelog index 5c5221a..4552868 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,11 @@ +20100706 myb src/axiom-website/patches.html 20100706.01.myb.patch +20100706 myb src/interp/vmlisp.lisp HTMLFormat support code +20100706 myb src/interp/i-output.lisp HTMLFormat support code +20100706 myb src/algebra/Makefile test and help for HTMLFormat +20100706 myb books/bookvol7.1 document HTMLFormat +20100706 myb books/bookvol5 expose HTMLFormat, add support code +20100706 myb books/bookvol10.3 add HTMLFormat +20100706 myb books/ps/v103htmlformat.eps added 20100705 wxh src/axiom-website/patches.html 20100705.01.wxh.patch 20100705 wxh src/algebra/Makefile test and help ComplexDoubleFloatMatrix 20100705 wxh books/bookvol5 expose ComplexDoubleFloatMatrix, add macros diff --git a/src/algebra/Makefile.pamphlet b/src/algebra/Makefile.pamphlet index 3269146..0f325cf 100644 --- a/src/algebra/Makefile.pamphlet +++ b/src/algebra/Makefile.pamphlet @@ -5377,7 +5377,8 @@ LAYER11=\ ${OUT}/GALFACTU.o ${OUT}/GALPOLYU.o ${OUT}/GB.o ${OUT}/GBEUCLID.o \ ${OUT}/GBF.o ${OUT}/GBINTERN.o ${OUT}/GHENSEL.o ${OUT}/GMODPOL.o \ ${OUT}/GOSPER.o ${OUT}/GRIMAGE.o ${OUT}/GROEBSOL.o ${OUT}/HDMP.o \ - ${OUT}/HDP.o ${OUT}/HEXADEC.o ${OUT}/HEUGCD.o ${OUT}/IBPTOOLS.o \ + ${OUT}/HDP.o ${OUT}/HEXADEC.o ${OUT}/HEUGCD.o ${OUT}/HTMLFORM.o \ + ${OUT}/IBPTOOLS.o \ ${OUT}/IFF.o ${OUT}/IBITS.o ${OUT}/ICARD.o ${OUT}/ICDEN.o \ ${OUT}/IDECOMP.o ${OUT}/IIARRAY2.o ${OUT}/IMATLIN.o ${OUT}/IMATQF.o \ ${OUT}/INMODGCD.o ${OUT}/INNMFACT.o ${OUT}/INPSIGN.o ${OUT}/INTERGB.o \ @@ -6871,6 +6872,21 @@ LAYER11=\ /*"HEUGCD" -> {"ORDSET-"; "ABELSG-"; "SGROUP-"; "SETCAT-"; "RETRACT-"}*/ /*"HEUGCD" -> "BASTYPE-"*/ +"HTMLFORM" [color="#88FF44",href="bookvol10.3.pdf#nameddest=HTMLFORM"] +"HTMLFORM" -> "STRING" +/*"HTMLFORM" -> {"SETCAT"; "BASTYPE"; "KOERCE"; "INT"; "NNI"; "STRICAT"}*/ +/*"HTMLFORM" -> {"SRAGG"; "A1AGG"; "FLAGG"; "LNAGG"; "IXAGG"; "HOAGG"; "AGG"}*/ +/*"HTMLFORM" -> {"TYPE"; "EVALAB"; "IEVALAB"; "ELTAGG"; "ELTAB"; "CLAGG"}*/ +/*"HTMLFORM" -> {"KONVERT"; "ORDSET"; "OM"; "RCAGG"; "BOOLEAN"; "CHAR"}*/ +/*"HTMLFORM" -> {"SINT"; "OUTFORM"; "LIST"; "PRIMARR"; "A1AGG-"; "ISTRING"}*/ +/*"HTMLFORM" -> {"SRAGG-"; "ILIST"; "LSAGG"; "STAGG"; "URAGG"; "ELAGG"}*/ +/*"HTMLFORM" -> {"LSAGG-"; "ORDFIN"; "FINITE"; "STAGG-"; "FLAGG-"; "LNAGG-"}*/ +/*"HTMLFORM" -> {"IXAGG-"; "CLAGG-"; "HOAGG-"; "ORDSET-"; "AGG-"; "ELTAGG-"}*/ +/*"HTMLFORM" -> {"SETCAT-"; "BASTYPE-"; "ELAGG-"; "URAGG-"; "INS-"; "PI"}*/ +/*"HTMLFORM" -> {"EUCDOM-"; "UFD-"; "GCDDOM-"; "INTDOM-"; "ALGEBRA-"}*/ +/*"HTMLFORM" -> {"DIFRING-"; "ORDRING-"; "MODULE-"; "RING-"; "ABELGRP-"}*/ +/*"HTMLFORM" -> {"ABELMON-"; "MONOID-"; "ABELSG-"; "SGROUP-"; "RETRACT-"}*/ + "IBPTOOLS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=IBPTOOLS"] /*"IBPTOOLS" -> {"RING"; "RNG"; "ABELGRP"; "CABMON"; "ABELMON"; "ABELSG"}*/ /*"IBPTOOLS" -> {"SETCAT"; "BASTYPE"; "KOERCE"; "SGROUP"; "MONOID"}*/ @@ -17530,6 +17546,7 @@ SPADHELP=\ ${HELP}/HashTable.help \ ${HELP}/Heap.help \ ${HELP}/HexadecimalExpansion.help \ + ${HELP}/HTMLFormat.help \ ${HELP}/HomogeneousAggregate.help \ ${HELP}/HomogeneousDirectProduct.help \ ${HELP}/HomogeneousDistributedMultivariatePolynomial.help \ @@ -18221,6 +18238,7 @@ REGRESS= \ HashTable.regress \ Heap.regress \ HexadecimalExpansion.regress \ + HTMLFormat.regress \ HomogeneousAggregate.regress \ HomogeneousDirectProduct.regress \ HomogeneousDistributedMultivariatePolynomial.regress \ @@ -21862,6 +21880,18 @@ ${HELP}/HexadecimalExpansion.help: ${BOOKS}/bookvol10.3.pamphlet ${BOOKS}/bookvol10.3.pamphlet >${INPUT}/HexadecimalExpansion.input @echo "HexadecimalExpansion (HEXADEC)" >>${HELPFILE} +${HELP}/HTMLFormat.help: ${BOOKS}/bookvol10.3.pamphlet + @echo 5000 create HTMLFormat.help from \ + ${BOOKS}/bookvol10.3.pamphlet + @${TANGLE} -R"HTMLFormat.help" \ + ${BOOKS}/bookvol10.3.pamphlet \ + >${HELP}/HTMLFormat.help + @cp ${HELP}/HTMLFormat.help ${HELP}/HTMLFORM.help + @${TANGLE} -R"HTMLFormat.input" \ + ${BOOKS}/bookvol10.3.pamphlet \ + >${INPUT}/HTMLFormat.input + @echo "HTMLFormat (HTMLFORM)" >>${HELPFILE} + ${HELP}/HomogeneousAggregate.help: ${BOOKS}/bookvol10.2.pamphlet @echo 5000 create HomogeneousAggregate.help from \ ${BOOKS}/bookvol10.2.pamphlet diff --git a/src/axiom-website/patches.html b/src/axiom-website/patches.html index 370e5e3..d5ef5a5 100644 --- a/src/axiom-website/patches.html +++ b/src/axiom-website/patches.html @@ -2982,5 +2982,7 @@ src/input/Makefile add TESTSET=notests
books/bookvol10.3 add DoubleFloatMatrix
20100705.01.wxh.patch books/bookvol10.3 add ComplexDoubleFloatMatrix
+20100706.01.myb.patch +books/bookvol10.3 add HTMLFormat
diff --git a/src/interp/i-output.lisp.pamphlet b/src/interp/i-output.lisp.pamphlet index baac0a3..e2875b4 100644 --- a/src/interp/i-output.lisp.pamphlet +++ b/src/interp/i-output.lisp.pamphlet @@ -4156,6 +4156,20 @@ NIL (FORCE-OUTPUT |$mathmlOutputStream|) NIL)))) +(defun |htmlFormat| (expr) + "Output the expression using HTML format" + (let (ht htrep formatFn displayFn) + (declare (special |$htmlOutputStream| |$OutputForm|)) + (setq ht '(|HTMLFormat|)) + (setq htrep '(|String|)) + (setq formatFn + (|getFunctionFromDomain| '|coerce| ht (cons |$OutputForm| nil))) + (setq displayFn (|getFunctionFromDomain| '|display| ht (cons htrep nil))) + (spadcall (spadcall expr formatFn) displayFn) + (terpri |$htmlOutputStream|) + (force-output |$htmlOutputStream|) + nil)) + ;output(expr,domain) == ; if isWrapped expr then expr := unwrap expr ; isMapExpr expr => @@ -4194,17 +4208,19 @@ NIL (PROG (T$ |x| |printfun| |textwrit| |ISTMP#1| S) (DECLARE (SPECIAL |$mathmlFormat| |$texFormat| |$algebraFormat| |$fortranOutputStream| |$collectOutput| - |$fortranFormat| |$formulaFormat| |$OutputForm|)) + |$fortranFormat| |$formulaFormat| |$OutputForm| + |$htmlFormat|)) (RETURN (PROGN (COND ((|isWrapped| |expr|) (SPADLET |expr| (|unwrap| |expr|)))) (COND ((|isMapExpr| |expr|) - (COND (|$formulaFormat| (|formulaFormat| |expr|))) - (COND (|$texFormat| (|texFormat| |expr|))) - (COND (|$algebraFormat| (|mathprintWithNumber| |expr|))) - (COND (|$mathmlFormat| (|mathmlFormat| |expr|)) ('T NIL))) + (when |$formulaFormat| (|formulaFormat| |expr|)) + (when |$texFormat| (|texFormat| |expr|)) + (when |$algebraFormat| (|mathprintWithNumber| |expr|)) + (when |$htmlFormat| (|htmlFormat| |expr|)) + (when |$mathmlFormat| (|mathmlFormat| |expr|))) ((OR (|categoryForm?| |domain|) (|member| |domain| '((|Mode|) (|Domain|) (|SubDomain| (|Domain|))))) @@ -4227,9 +4243,10 @@ NIL ((NULL |$collectOutput|) (TERPRI |$fortranOutputStream|))) (FORCE-OUTPUT |$fortranOutputStream|))) - (COND (|$algebraFormat| (|mathprintWithNumber| |x|))) - (COND (|$texFormat| (|texFormat| |x|))) - (COND (|$mathmlFormat| (|mathmlFormat| |x|)) ('T NIL))) + (when |$algebraFormat| (|mathprintWithNumber| |x|)) + (when |$texFormat| (|texFormat| |x|)) + (when |$htmlFormat| (|htmlFormat| |x|)) + (when |$mathmlFormat| (|mathmlFormat| |x|))) ((AND (FUNCTIONP (|opOf| |domain|)) (NULL (SYMBOLP (|opOf| |domain|))) (SPADLET |printfun| diff --git a/src/interp/vmlisp.lisp.pamphlet b/src/interp/vmlisp.lisp.pamphlet index a0822d5..24030f5 100644 --- a/src/interp/vmlisp.lisp.pamphlet +++ b/src/interp/vmlisp.lisp.pamphlet @@ -5698,6 +5698,9 @@ now the function is defined but does nothing. (defvar |$specialCaseKeyList| nil "checked in optCall") (defvar |$formulaFormat| nil "if true produce script formula output") (defvar |$texFormat| nil "if true produce tex output") +(defvar |$mathmlFormat| nil "if true produce mathml output") +(defvar |$htmlFormat| nil "if true produce html output") +(defvar |$texFormat| nil "if true produce tex output") (defvar |$fortranFormat| nil "if true produce fortran output") (defvar |$algebraFormat| t "produce 2-d algebra output") (defvar |$kernelWarn| NIL "")