1. tex handles strings ungracefully:
(C2) tex("a+b");
$$&a+b$$
Here is a version of tex-atom that (I think) does a better
job with strings
(defun tex-atom (x l r) ;; atoms: note: can we lose by leaving out {}s ?
(append l
(list (cond ((numberp x) (texnumformat x))
((and (symbolp x) (get x 'texword)))
((mstringp x)
(concatenate
'string "\\\\'\\\\'" (string-left-trim "&" x) "\\\\'\\\\'"))
(t (tex-stripdollar x)))) r))
--------------------------------------------------------------------
2. In mactex, why is the defprop for $lambda is commented
out? Additionally, to tex Maxima lambda forms, I think
there should be a defprop for lambda. Without these
defprops:
(C1) tex(lambda);
$$LAMBDA$$
(C2) tex(lambda([x],x^2));
$$LAMBDA\left(\left[ x \right] ,x^2\right)$$
After appending the defprops
(defprop $lambda "\\lambda" texword)
(defprop lambda "\\lambda" texword)
to mactex.lisp, we get
(C4) tex(lambda);
$$
\lambda
$$
(C5) tex(lambda([x],x^2));
$$
\lambda\left(\left[ x \right] ,x^2\right)
$$
-------------------------------------------------------------------
3. mactex has some support for tex-ing function
definitions, loops, and if then else statements, but the
code is "short-circuited":
(C52) tex(f(x) := x^2);
|
f(x):=x^2;|
(C53) tex(f(x) := if x < 1 then 0 else 42);
|
f(x):=IF x < 1 THEN 0 ELSE 42;|
After removing the short-circuit, we get
(C55) tex(f(x) := x^2);
$$
f\left(x\right):=x^2
$$
(C56) tex(f(x) := if x < 1 then 0 else 42);
$$
f\left(x\right):=\mathbf{if}\>x<1\>\mathbf{then}\>0
\>\mathbf{else}\>42
$$
Possibly, the support for tex-ing such things is limited,
so it was short-circuited. If you want to experiment, here
is version of tex1 that will get you started.
(defun tex1 (mexplabel &optional filename ) ;; mexplabel, and optional filename
(prog (mexp texport $gcprint ccol x y itsalabel)
;; $gcprint = nil turns gc messages off
(setq ccol 1)
(cond ((null mexplabel)
(displa " No eqn given to TeX")
(return nil)))
;; collect the file-name, if any, and open a port if needed
(setq texport (cond((null filename) *standard-output* ); t= output to terminal
(t
(open (stripdollar filename)
:direction :output
:if-exists :append))))
;; go back and analyze the first arg more thoroughly now.
;; do a normal evaluation of the expression in macsyma
(setq mexp (meval mexplabel))
(cond ((memq mexplabel $labels); leave it if it is a label
(setq mexplabel (concat "(" (stripdollar mexplabel) ")"))
(setq itsalabel t))
(t (setq mexplabel nil)));flush it otherwise
;; maybe it is a function?
(cond((symbolp (setq x mexp)) ;;exclude strings, numbers
(setq x ($verbify x))
(cond ((setq y (mget x 'mexpr))
(setq mexp (list '(mdefine) (cons (list x) (cdadr y)) (caddr y))))
((setq y (mget x 'mmacro))
(setq mexp (list '(mdefmacro) (cons (list x) (cdadr y)) (caddr y))))
((setq y (mget x 'aexpr))
(setq mexp (list '(mdefine) (cons (list x 'array) (cdadr y)) (caddr y)))))))
(cond ;((and (null(atom mexp)) ;; commented out by BLW
;(memq (caar mexp) '(mdefine mdefmacro)))
;(format texport "|~%" ) ;delimit with |marks
;(cond (mexplabel (format texport "~a " mexplabel)))
;(format texport "~%")
;(myprinc "$$")
;(format texport "~% ")
;(mapc #'myprinc
; (tex mexp nil nil 'mparen 'mparen))
;(format texport "~%")
;(myprinc "$$"))
;(mgrind mexp texport) ;write expression as string
;(format texport ";|~%"))
((and
itsalabel ;; but is it a user-command-label?
(eq (getchar $inchar 2) (getchar mexplabel 2)))
;; aha, this is a C-line: do the grinding:
(format texport "~%|~a " mexplabel) ;delimit with |marks
(mgrind mexp texport) ;write expression as string
(format texport ";|~%"))
(t ; display the expression for TeX now:
(myprinc "$$")
(format texport "~% ");; put $$ on a separate line and indent (BLW)
(mapc #'myprinc
;;initially the left and right contexts are
;; empty lists, and there are implicit parens
;; around the whole expression
(tex mexp nil nil 'mparen 'mparen))
(cond (mexplabel
(format texport "\\leqno{\\tt ~a}" mexplabel)))
(format texport "~%$$")))
(cond (filename(terpri texport); and drain port if not terminal
(close texport)))
(return mexplabel)))
-------------------------------------------------------------
4. Maxima doesn't "know" the derivative of signum. This
can be fixed by appending the defprop
(defprop %signum ((x) 0) grad)
to your maxima-init.lisp file. Or, depending on your personality,
append
(defprop %signum ((x) (($dirac_delta) x)) grad)
Maxima, however, doesn't know anything about dirac_delta.
Additionally, if you pefer diff(abs(x),x) ==> signum(x),
append
(meval '(($gradef) ((mabs) x) ((%signum) x)))
to your maxima-init.lisp file or
gradef(abs(x), signum(x));
to your maxima-init.mac file.
(If your Maxima is more than a few days old, it doesn't
support maxima-init.lisp or maxima-init.mac files.)
----------------------------------------------------------------
Barton