mostly mactex



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