~ubuntu-branches/debian/squeeze/maxima/squeeze

« back to all changes in this revision

Viewing changes to interfaces/emacs/emaxima/emaxima.lisp

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2006-10-18 14:52:42 UTC
  • mto: (1.1.5 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20061018145242-vzyrm5hmxr8kiosf
ImportĀ upstreamĀ versionĀ 5.10.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
(in-package "MAXIMA")
 
1
;; This is mostly from texmacs-maxima-5.9.2.lisp
 
2
;;    Small changes to mactex.lisp for interfacing with TeXmacs
 
3
;;    Andrey Grozin, 2001-2005
 
4
 
 
5
(in-package :maxima)
2
6
 
3
7
(declare-top
4
8
         (special lop rop $gcprint $inchar)
5
9
         (*expr tex-lbp tex-rbp))
6
10
 
7
 
(DEFUN MAIN-PROMPT ()
8
 
  (FORMAT () "(~A~D) "
9
 
    (STRIPDOLLAR $INCHAR) $LINENUM))
10
 
 
11
 
;(DEFUN BREAK-PROMPT ()
12
 
;  (declare (special $prompt))
13
 
;  (format nil "~A" (STRIPDOLLAR $PROMPT)))
14
 
 
15
 
(defun break-dbm-loop (at)
16
 
  (let* (
17
 
         (*quit-tags* (cons (cons *break-level* *quit-tag*) *quit-tags*))
18
 
         (*break-level* (if (not at) *break-level* (cons t *break-level*)))
19
 
         (*quit-tag* (cons nil nil))
20
 
         (*break-env* *break-env*)
21
 
         (*mread-prompt* "")
22
 
         (*diff-bindlist* nil)
23
 
         (*diff-mspeclist* nil)
24
 
         val
25
 
         )
26
 
    (declare (special *mread-prompt* ))
27
 
    (and (consp at) (set-env at))
28
 
    (cond ((null at)
29
 
           ($frame 0 nil)))
30
 
    (catch 'step-continue
31
 
      (catch *quit-tag*
32
 
        (unwind-protect
33
 
            (do () (())
34
 
                (format *debug-io*
35
 
                    "~&~@[(~a:~a) ~]"  (unless (stringp at) "dbm")
36
 
                    (length *quit-tags*))
37
 
                (setq val
38
 
                      (catch 'macsyma-quit
39
 
                        (let ((res (dbm-read *debug-io*  nil *top-eof* t)))
40
 
                          (declare (special *mread-prompt*))
41
 
                          (cond ((and (consp res) (keywordp (car res)))
42
 
                                 (let ((value (break-call (car res)
43
 
                                                          (cdr res) 'break-command)))
44
 
                                   (cond ((eq value :resume) (return)))
45
 
                                   ))
46
 
                                (t
47
 
                                 (setq $__ (nth 2 res))
48
 
                                 (setq $% (meval* $__))
49
 
                                 (SETQ $_ $__)
50
 
                                 (displa $%)
51
 
                                 ))
52
 
                          nil
53
 
                          )))
54
 
                (and (eql val 'top)
55
 
                     (throw-macsyma-top))
56
 
                      )
57
 
         (restore-bindings)
58
 
        )))))
59
 
 
60
 
;(setq $display2d 'true)
61
 
 
62
 
;; TeX-printing
63
 
;; (c) copyright 1987, Richard J. Fateman
64
 
;; Small changes for interfacing with TeXmacs: Andrey Grozin, 2001
65
 
;; Yet more small changes for interfacing with imaxima: Jesper Harder 2001
66
 
;; Even more small changes for emaxima: Jay Belanger 2003
67
 
 
68
 
 
69
 
(defun tex (x l r lop rop)
70
 
        ;; x is the expression of interest; l is the list of strings to its
71
 
        ;; left, r to its right. lop and rop are the operators on the left
72
 
        ;; and right of x in the tree, and will determine if parens must
73
 
        ;; be inserted
74
 
        (setq x (nformat x))
75
 
        (cond ((atom x) (tex-atom x l r))
76
 
              ((or (<= (tex-lbp (caar x)) (tex-rbp lop)) (> (tex-lbp rop) (tex-rbp (caar x))))
77
 
               (tex-paren x l r))
78
 
              ;; special check needed because macsyma notates arrays peculiarly
79
 
              ((memq 'array (cdar x)) (tex-array x l r))
80
 
              ;; dispatch for object-oriented tex-ifiying
81
 
              ((get (caar x) 'tex) (funcall (get (caar x) 'tex) x l r))
82
 
              (t (tex-function x l r nil))))
83
 
 
84
 
(defun tex-atom (x l r) ;; atoms: note: can we lose by leaving out {}s ?
85
 
  (append l 
86
 
          (list (cond ((numberp x) (texnumformat x))
87
 
                      ((and (symbolp x) (get x 'texword)))
88
 
                      ((stringp x) (texstring x))
89
 
                      ((characterp x) (texchar x))
90
 
                      (t (tex-stripdollar x))))
91
 
          
92
 
          r))
93
 
 
94
 
(defun texstring (x)
95
 
  (cond ((equal x "") "")
96
 
        ((eql (elt x 0) #\\) x)
97
 
;;     (t (concatenate 'string "\\mbox{{}" x "{}}")))) ;; jah: 
98
 
        (t (concatenate 'string "\\verb| " x " |"))))
99
 
 
100
 
(defun texchar (x)
101
 
  (if (eql x #\|) "\\verb/|/"
102
 
    (concatenate 'string "\\verb|" (string x) "|"))) ;; jah: \mbox{\verb} is illegal
103
 
 
104
 
(defun myquote (str)
105
 
  (let ((var "") (charlist
106
 
                  '((#\{ . "\\left\\{\\right.")
107
 
                    (#\} . "\\left\\}\\right.")
108
 
                    (#\# . "\\#")
109
 
                    (#\$ . "\\$")
110
 
                    (#\% . "\\%")
111
 
                    (#\& . "\\&")
112
 
                    (#\_ . "\\_"))))
113
 
    (dotimes (i (length str))
114
 
      (let ((chari (elt str i)))
115
 
        (setq var (concatenate 'string var 
116
 
                               (or (cdr (assoc chari charlist))
117
 
                                   (string chari))))))
118
 
  var))
 
11
(defun main-prompt ()
 
12
  (format () "(~A~D) "
 
13
    (print-invert-case (stripdollar $inchar)) $linenum))
119
14
 
120
15
(defun tex-stripdollar (sym)
121
16
  (or (symbolp sym) (return-from tex-stripdollar sym))
122
 
  (let* ((name (symbol-name sym))
123
 
      (pname (if (memq (elt name 0) '(#\$ #\&)) (subseq name 1) name))
124
 
      (l (length pname)))
125
 
    (cond
126
 
     ((eql l 1) (myquote pname))
127
 
     (t (concatenate 'string "\\mathrm{" (myquote pname) "}")))))
128
 
 
129
 
(defun strcat (&rest args)
130
 
  (apply #'concatenate 'string (mapcar #'string args)))
131
 
 
132
 
;; 10/14/87 RJF  convert 1.2e20 to 1.2 \cdot 10^{20}
133
 
;; 03/30/01 RLT  make that 1.2 \times 10^{20}
134
 
(defun texnumformat(atom)
135
 
  (let (r firstpart exponent)
136
 
    (cond ((integerp atom)
137
 
           atom)
138
 
          (t
139
 
           (setq r (explode atom))
140
 
           (setq exponent (member 'e r :test #'string-equal));; is it ddd.ddde+EE
141
 
           (cond ((null exponent)
142
 
                   ;; it is not. go with it as given
143
 
                  atom)
144
 
                 (t
145
 
                  (setq firstpart
146
 
                        (nreverse (cdr (member 'e (reverse r) :test #'string-equal))))
147
 
                  (strcat (apply #'strcat firstpart )
148
 
                          " \\times 10^{"
149
 
                          (apply #'strcat (cdr exponent))
150
 
                          "}")))))))
151
 
 
152
 
(defun tex-paren (x l r) 
153
 
  (tex x (append l '("\\left(")) (cons "\\right)" r) 'mparen 'mparen))
154
 
 
155
 
(defun tex-array (x l r)
156
 
  (let ((f))
157
 
       (if (eq 'mqapply (caar x))
158
 
           (setq f (cadr x) 
159
 
                 x (cdr x))
160
 
           (setq f (caar x)))
161
 
       (if (atom (cadr x))
162
 
           ;; subscript is an atom -- don't use \isubscript
163
 
           (progn
164
 
             (setq l (tex (texword f) l nil lop 'mfunction)
165
 
                   r (nconc (tex-list (cdr x) nil (list "}") ",") r))
166
 
             (nconc l (list "_{") r))
167
 
         (setq l (tex (texword f) (append l (list "\\isubscript{"))  nil lop 'mfunction)
168
 
               r (nconc (tex-list (cdr x) nil (list "}") ",") r))
169
 
         (nconc  l (list "}{") r ))))
170
 
 
171
 
;; we could patch this so sin x rather than sin(x), but instead we made sin a prefix
172
 
;; operator
173
 
 
174
 
(defun tex-function (x l r op) op
175
 
        (setq l (tex (texword (caar x)) l nil 'mparen 'mparen)
176
 
              r (tex (cons '(mprogn) (cdr x)) nil r 'mparen 'mparen))
177
 
        (nconc l r))
178
 
 
179
 
;; set up a list , separated by symbols (, * ...)  and then tack on the
180
 
;; ending item (e.g. "]" or perhaps ")"
181
 
 
182
 
(defun tex-list (x l r sym)
183
 
  (if (null x) r
184
 
      (do ((nl))
185
 
          ((null (cdr x))
186
 
           (setq nl (nconc nl (tex (car x)  l r 'mparen 'mparen)))
187
 
           nl)
188
 
;;        (setq nl (nconc nl (tex (car x)  l (list sym) 'mparen 'mparen))
189
 
          (setq nl (nconc nl (tex (car x)  l (list (concatenate 'string sym "\\linebreak[0]")) 'mparen 'mparen))
190
 
                  x (cdr x)
191
 
                  l nil))))
192
 
 
193
 
(defun tex-prefix (x l r)
194
 
  (tex (cadr x) (append l (texsym (caar x))) r (caar x) rop))
195
 
 
196
 
(defun tex-infix (x l r)
197
 
  ;; check for 2 args
198
 
  (if (or (null (cddr x)) (cdddr x)) (wna-err (caar x)))
199
 
  (setq l (tex (cadr x) l nil lop (caar x)))
200
 
  (tex (caddr x) (append l (texsym (caar x))) r (caar x) rop))
201
 
  
202
 
(defun tex-postfix (x l r)
203
 
  (tex (cadr x) l (append (texsym (caar x)) r) lop (caar x)))
204
 
 
205
 
(defun tex-nary (x l r)
206
 
  (let* ((op (caar x)) (sym (texsym op)) (y (cdr x)) (ext-lop lop) (ext-rop rop))
207
 
    (cond ((null y)       (tex-function x l r t)) ; this should not happen
208
 
          ((null (cdr y)) (tex-function x l r t)) ; this should not happen, too
209
 
          (t (do ((nl) (lop ext-lop op) (rop op (if (null (cdr y)) ext-rop op)))
210
 
                 ((null (cdr y)) (setq nl (nconc nl (tex (car y)  l r lop rop))) nl)
211
 
                 (setq nl (nconc nl (tex (car y)  l (list sym)   lop rop))
212
 
                       y (cdr y) 
213
 
                       l nil))))))
214
 
 
215
 
(defun tex-nofix (x l r) (tex (caar x) l r (caar x) rop))
216
 
 
217
 
(defun tex-matchfix (x l r)
218
 
  (setq l (append l (car (texsym (caar x))))
219
 
        ;; car of texsym of a matchfix operator is the lead op
220
 
        r (append (cdr (texsym (caar x))) r) 
221
 
        ;; cdr is the trailing op
222
 
        x (tex-list (cdr x) nil r ","))
223
 
  (append l x))
224
 
 
225
 
(defun texsym (x) (or (get x 'texsym) (get x 'strsym)(get x 'dissym)
226
 
                      (stripdollar x)))
227
 
 
228
 
(defun texword (x)(or (get x 'texword) (stripdollar x)))
229
 
 
230
 
(defprop bigfloat tex-bigfloat tex)
231
 
 
232
 
(defun tex-bigfloat (x l r) (fpformat x))
233
 
 
234
 
(defprop mprog "\\mathbf{block}\\;" texword)
235
 
(defprop %erf "\\mathrm{erf}" texword)
236
 
(defprop $erf "\\mathrm{erf}" texword) ;; etc for multicharacter names
237
 
(defprop $true  "\\mathbf{true}"  texword)
238
 
(defprop $false "\\mathbf{false}" texword)
239
 
 
240
 
(defprop mprogn tex-matchfix tex) ;; mprogn is (<progstmnt>, ...)
241
 
(defprop mprogn (("\\left(") "\\right)") texsym)
242
 
 
243
 
(defprop mlist tex-matchfix tex)
244
 
(defprop mlist (("\\left[ ")" \\right] ") texsym)
245
 
 
246
 
;;absolute value
247
 
(defprop mabs tex-matchfix tex)
248
 
(defprop mabs (("\\left| ")"\\right| ") texsym)
249
 
 
250
 
(defprop mqapply tex-mqapply tex)
251
 
 
252
 
(defun tex-mqapply (x l r)
253
 
  (setq l (tex (cadr x) l (list "(" ) lop 'mfunction)
254
 
        r (tex-list (cddr x) nil (cons ")" r) ","))
255
 
  (append l r));; fixed 9/24/87 RJF
256
 
 
257
 
(defprop $%i "i" texword)
258
 
(defprop $%pi "\\pi" texword)
259
 
(defprop $%e "e" texword)
260
 
(defprop $inf "\\infty " texword)
261
 
(defprop $minf " -\\infty " texword)
262
 
(defprop %laplace "\\mathcal{L}" texword) ;; jah
263
 
(defprop $alpha "\\alpha" texword)
264
 
(defprop $beta "\\beta" texword)
265
 
(defprop $gamma "\\gamma" texword)
266
 
(defprop %gamma "\\Gamma" texword)
267
 
(defprop $%gamma "\\gamma" texword)
268
 
(defprop $delta "\\delta" texword)
269
 
(defprop $epsilon "\\varepsilon" texword)
270
 
(defprop $zeta "\\zeta" texword)
271
 
(defprop $eta "\\eta" texword)
272
 
(defprop $theta "\\vartheta" texword)
273
 
(defprop $iota "\\iota" texword)
274
 
(defprop $kappa "\\varkappa" texword)
275
 
;(defprop $lambda "\\lambda" texword)
276
 
(defprop $mu "\\mu" texword)
277
 
(defprop $nu "\\nu" texword)
278
 
(defprop $xi "\\xi" texword)
279
 
(defprop $pi "\\pi" texword)
280
 
(defprop $rho "\\rho" texword)
281
 
(defprop $sigma "\\sigma" texword)
282
 
(defprop $tau "\\tau" texword)
283
 
(defprop $upsilon "\\upsilon" texword)
284
 
(defprop $phi "\\varphi" texword)
285
 
(defprop $chi "\\chi" texword)
286
 
(defprop $psi "\\psi" texword)
287
 
(defprop $omega "\\omega" texword)
288
 
 
289
 
(defprop mquote tex-prefix tex)
290
 
(defprop mquote ("'") texsym)
291
 
(defprop mquote 201. tex-rbp)
292
 
 
293
 
(defprop msetq tex-infix tex)
294
 
(defprop msetq (":") texsym)
295
 
(defprop msetq 180. tex-rbp)
296
 
(defprop msetq 20. tex-rbp)
297
 
 
298
 
(defprop mset tex-infix tex)
299
 
(defprop mset ("::") texsym)
300
 
(defprop mset 180. tex-lbp)
301
 
(defprop mset 20. tex-rbp)
302
 
 
303
 
(defprop mdefine tex-infix tex)
304
 
(defprop mdefine (":=") texsym)
305
 
(defprop mdefine 180. tex-lbp)
306
 
(defprop mdefine 20. tex-rbp)
307
 
 
308
 
(defprop mdefmacro tex-infix tex)
309
 
(defprop mdefmacro ("::=") texsym)
310
 
(defprop mdefmacro 180. tex-lbp)
311
 
(defprop mdefmacro 20. tex-rbp)
312
 
 
313
 
(defprop marrow tex-infix tex)
314
 
(defprop marrow ("\\rightarrow ") texsym)
315
 
(defprop marrow 25 tex-lbp)
316
 
(defprop marrow 25 tex-rbp)
317
 
 
318
 
(defprop mfactorial tex-postfix tex)
319
 
(defprop mfactorial ("!") texsym)
320
 
(defprop mfactorial 160. tex-lbp)
321
 
 
322
 
(defprop mexpt tex-mexpt tex)
323
 
(defprop mexpt 140. tex-lbp)
324
 
(defprop mexpt 139. tex-rbp)
325
 
 
326
 
;; insert left-angle-brackets for mncexpt. a^<n> is how a^^n looks.
 
17
  (let* ((name (quote-% (print-invert-case sym)))
 
18
      (name1 (if (memq (elt name 0) '(#\$ #\&)) (subseq name 1) name))
 
19
      (l (length name1)))
 
20
    (if (eql l 1) name1 (concatenate 'string "\\mathrm{" name1 "}"))))
 
21
 
 
22
 
 
23
;; Also, we should output f(x)^2, not f^2(x)
 
24
 
327
25
(defun tex-mexpt (x l r)
328
 
  (let((nc (eq (caar x) 'mncexpt))); true if a^^b rather than a^b
329
 
     ;; here is where we have to check for f(x)^b to be displayed
330
 
     ;; as f^b(x), as is the case for sin(x)^2 .
331
 
     ;; which should be sin^2 x rather than (sin x)^2 or (sin(x))^2. 
332
 
     ;; yet we must not display (a+b)^2 as +^2(a,b)...
333
 
     ;; or (sin(x))^(-1) as sin^(-1)x, which would be arcsine x
334
 
    (cond ;; this whole clause
335
 
     ;; should be deleted if this hack is unwanted and/or the
336
 
           ;; time it takes is of concern.
337
 
           ;; it shouldn't be too expensive.
338
 
           ((and (eq (caar x) 'mexpt) ; don't do this hack for mncexpt
339
 
                 (let* 
340
 
                  ((fx (cadr x)); this is f(x)
341
 
                   (f (and (not (atom fx)) (atom (caar fx)) (caar fx))) ; this is f [or nil]
342
 
                   (bascdr (and f (cdr fx))) ; this is (x) [maybe (x,y..), or nil]
343
 
                   (expon (caddr x)) ;; this is the exponent
344
 
                   (doit (and 
345
 
                          f ; there is such a function
346
 
                          (memq (getchar f 1) '(% $)) ;; insist it is a % or $ function
347
 
                          (not (memq f '(%sum %lsum %product %derivative 
348
 
                                              %integrate %limit))) ;; what else? what a hack...
349
 
                          (or (and (atom expon) (not (numberp expon))) ; f(x)^y is ok
350
 
                              (and (atom expon) (numberp expon) (> expon 0))))))
351
 
                              ; f(x)^3 is ok, but not f(x)^-1, which could 
352
 
                              ; inverse of f, if written f^-1 x
353
 
                              ; what else? f(x)^(1/2) is sqrt(f(x)), ??
354
 
                  (cond (doit
355
 
                         (setq l (append (tex f l nil lop 'mexpt)
356
 
                                        (tex expon (list "^{")
357
 
                                             (cons " }" nil) 'mparen 'mparen)))
358
 
                         (if (and (null (cdr bascdr))
359
 
                                  (eq (get f 'tex) 'tex-prefix))
360
 
                             (setq r (tex (car bascdr) nil r f 'mparen))
361
 
                           (setq r (tex (cons '(mprogn) bascdr) nil r 'mparen 'mparen)))
362
 
                         (append l r))
363
 
                        (t nil))))) ; won't doit. fall through
364
 
           (t
365
 
            (if (atom (caddr x))
366
 
                ;; Don't use \iexpt when exponent is an atom
367
 
                (progn
368
 
                  (setq l (tex (cadr x) l nil lop (caar x))
369
 
                        r (if (mmminusp (setq x (nformat (caddr x))))
370
 
                              ;; the change in base-line makes parens unnecessary
371
 
                              (if nc
372
 
                                  (tex (cadr x) '("^ {-\\langle ")(cons "\\rangle }" r) 'mparen 'mparen)
373
 
                                (tex (cadr x) '("^ {- ")(cons " }" r) 'mparen 'mparen))
374
 
                            (if nc
375
 
                                (tex x (list "^{\\langle ")(cons "\\rangle}" r) 'mparen 'mparen)
376
 
                              (tex x (list "^{")(cons "}" r) 'mparen 'mparen))))
377
 
                  (append l r))
378
 
              (setq l (tex (cadr x) (append l (list "\\iexpt{")) nil lop (caar x))
379
 
                  r (if (mmminusp (setq x (nformat (caddr x))))
380
 
                        ;; the change in base-line makes parens unnecessary
381
 
                        (if nc
382
 
                            (tex (cadr x) '("{-\\langle ")(cons "\\rangle }" r) 'mparen 'mparen)
383
 
                          (tex (cadr x) '("{- ")(cons " }" r) 'mparen 'mparen))
384
 
                      (if nc
385
 
                          (tex x (list "{\\langle ")(cons "\\rangle}" r) 'mparen 'mparen)
386
 
                        (tex x (list "{") (cons "}" r) 'mparen 'mparen))))
387
 
                 (append l (list "}") r))))))
388
 
 
389
 
(defprop mncexpt tex-mexpt tex)
390
 
 
391
 
(defprop mncexpt 135. tex-lbp)
392
 
(defprop mncexpt 134. tex-rbp)
393
 
 
394
 
(defprop mnctimes tex-nary tex)
395
 
(defprop mnctimes "\\cdot " texsym)
396
 
(defprop mnctimes 110. tex-lbp)
397
 
(defprop mnctimes 109. tex-rbp)
398
 
 
399
 
(defprop mtimes tex-nary tex)
400
 
(defprop mtimes "\\*" texsym)
401
 
(defprop mtimes 120. tex-lbp)
402
 
(defprop mtimes 120. tex-rbp)
403
 
 
404
 
(defprop %sqrt tex-sqrt tex)
405
 
 
406
 
(defun tex-sqrt(x l r)
407
 
  ;; format as \\sqrt { } assuming implicit parens for sqr grouping
408
 
  (tex (cadr x) (append l  '("\\sqrt{")) (append '("}") r) 'mparen 'mparen))
409
 
 
410
 
;; macsyma doesn't know about cube (or nth) roots,
411
 
;; but if it did, this is what it would look like.
412
 
(defprop $cubrt tex-cubrt tex)
413
 
 
414
 
(defun tex-cubrt (x l r)
415
 
  (tex (cadr x) (append l  '("\\root 3 \\of{")) (append '("}") r) 'mparen 'mparen))
416
 
 
417
 
(defprop mquotient tex-mquotient tex)
418
 
(defprop mquotient ("\\over") texsym)
419
 
(defprop mquotient 122. tex-lbp) ;;dunno about this
420
 
(defprop mquotient 123. tex-rbp) 
421
 
 
422
 
(defun tex-mquotient (x l r)
423
 
  (if (or (null (cddr x)) (cdddr x)) (wna-err (caar x)))
424
 
  (cond ((and (atom (cadr x)) (atom (caddr x)))
425
 
         ;; both denom and numerator are atoms
426
 
         (setq l (tex (cadr x) (append l '("\\frac{")) nil nil nil) ;;fixme
427
 
               r (tex (caddr x) (list "}{") (append '("}")r) 'mparen 'mparen)))
428
 
        ((atom (cadr x))
429
 
         ;; numerator is an atom
430
 
         (setq l (tex (cadr x) (append l '("\\frac{")) nil 'mparen 'mparen)
431
 
               r (tex (caddr x) (list "}{") (append '("}")r) 'mparen 'mparen)))
432
 
        ((atom (caddr x))
433
 
         ;; denom is an atom
434
 
         (setq l (tex (cadr x) (append l '("\\frac{")) nil 'mparen 'mparen)
435
 
               r (tex (caddr x) (list "}{") (append '("}")r) 'mparen 'mparen)))
436
 
        (t
437
 
         ;; neither are atoms
438
 
         (setq l (tex (cadr x) (append l '("\\frac{")) nil 'mparen 'mparen)
439
 
               r (tex (caddr x) (list "}{") (append '("}")r) 'mparen 'mparen))))
440
 
  (append l r))
441
 
 
442
 
(defprop $matrix tex-matrix tex)
443
 
 
444
 
(defun tex-matrix(x l r) ;;matrix looks like ((mmatrix)((mlist) a b) ...)
445
 
  (append l `("\\pmatrix{")
446
 
         (mapcan #'(lambda(y)
447
 
                          (tex-list (cdr y) nil (list "\\cr ") "&")) 
448
 
                 (cdr x))
449
 
         '("}") r))
450
 
 
451
 
;; macsyma sum or prod is over integer range, not  low <= index <= high
452
 
;; TeX is lots more flexible .. but
453
 
 
454
 
(defprop %sum tex-sum tex)
455
 
(defprop %lsum tex-lsum tex)
456
 
(defprop %product tex-sum tex)
457
 
 
458
 
;; easily extended to union, intersect, otherops
459
 
 
460
 
(defun tex-lsum(x l r)
461
 
  (let ((op (cond ((eq (caar x) '%lsum) "\\sum_{")
462
 
                  ;; extend here
463
 
                  ))
464
 
        ;; gotta be one of those above 
465
 
        (s1 (tex (cadr x) nil nil 'mparen rop));; summand
466
 
        (index ;; "index = lowerlimit"
467
 
               (tex `((min simp) , (caddr x), (cadddr x))  nil nil 'mparen 'mparen)))
468
 
       (append l `( ,op ,@index "}}{" ,@s1 "}") r)))
469
 
 
470
 
(defun tex-sum(x l r)
471
 
  (let ((op (cond ((eq (caar x) '%sum) "\\sum_{")
472
 
                  ((eq (caar x) '%product) "\\prod_{")
473
 
                  ;; extend here
474
 
                  ))
475
 
        ;; gotta be one of those above 
476
 
        (s1 (tex (cadr x) nil nil 'mparen rop));; summand
477
 
        (index ;; "index = lowerlimit"
478
 
               (tex `((mequal simp) ,(caddr x),(cadddr x)) nil nil 'mparen 'mparen))
479
 
        (toplim (tex (car(cddddr x)) nil nil 'mparen 'mparen)))
480
 
       (append l `( ,op ,@index "}^{" ,@toplim "}{" ,@s1 "}") r)))
481
 
 
482
 
(defprop %integrate tex-int tex)
483
 
(defun tex-int (x l r)
484
 
  (let ((s1 (tex (cadr x) nil nil 'mparen 'mparen));;integrand delims / & d
485
 
        (var (tex (caddr x) nil nil 'mparen rop))) ;; variable
486
 
       (cond((= (length x) 3)
487
 
             (append l `("\\int {" ,@s1 "}{\\;d" ,@var "}") r))
488
 
            (t ;; presumably length 5
489
 
               (let ((low (tex (nth 3 x) nil nil 'mparen 'mparen))
490
 
                     ;; 1st item is 0
491
 
                     (hi (tex (nth 4 x) nil nil 'mparen 'mparen)))
492
 
                    (append l `("\\int_{" ,@low "}^{" ,@hi "}{" ,@s1 "\\;d" ,@var "}") r))))))
493
 
 
494
 
(defprop %limit tex-limit tex)
495
 
 
496
 
(defun tex-limit(x l r) ;; ignoring direction, last optional arg to limit
497
 
  (let ((s1 (tex (cadr x) nil nil 'mparen rop));; limitfunction
498
 
        (subfun ;; the thing underneath "limit"
499
 
         (subst "\\rightarrow " '=
500
 
                (tex `((mequal simp) ,(caddr x),(cadddr x))
501
 
                     nil nil 'mparen 'mparen))))
502
 
       (append l `("\\lim_{" ,@subfun "}{" ,@s1 "}") r)))
503
 
 
504
 
(defprop %at tex-at tex)
505
 
 
506
 
;; e.g.  at(diff(f(x)),x=a)
507
 
(defun tex-at (x l r)
508
 
  (let ((s1 (tex (cadr x) nil nil lop rop))
509
 
        (sub (tex (caddr x) nil nil 'mparen 'mparen)))
510
 
       (append l '("\\left.") s1  '("\\right|_{") sub '("}") r)))
511
 
 
512
 
(defprop mbox tex-mbox tex)
513
 
 
514
 
(defun tex-mbox (x l r)
515
 
  (append l '("\\boxed{") (tex (cadr x) nil nil 'mparen 'mparen) '("}") r))
516
 
 
517
 
(defprop mlabox tex-mlabox tex)
518
 
 
519
 
(defun tex-mlabox (x l r)
520
 
   (append l '("\\stackrel{") (tex (caddr x) nil nil 'mparen 'mparen)
521
 
           '("}{\\boxed{") (tex (cadr x) nil nil 'mparen 'mparen) '("}}") r)) ; jh
522
 
 
523
 
;;binomial coefficients
524
 
 
525
 
(defprop %binomial tex-choose tex)
526
 
           
 
26
  (let((nc (eq (caar x) 'mncexpt)))     ; true if a^^b rather than a^b
 
27
    (setq l (if (and (numberp (cadr x)) (numneedsparen (cadr x)))
 
28
                (tex (cadr x) (cons "\\left(" l) '("\\right)") lop (caar x))
 
29
                (tex (cadr x) l nil lop (caar x)))
 
30
          r (if (mmminusp (setq x (nformat (caddr x))))
 
31
                ;; the change in base-line makes parens unnecessary
 
32
                (if nc
 
33
                    (tex (cadr x) '("^ {-\\langle ")(cons "\\rangle }" r) 'mparen 'mparen)
 
34
                    (tex (cadr x) '("^ {- ")(cons " }" r) 'mparen 'mparen))
 
35
                (if nc
 
36
                    (tex x (list "^{\\langle ")(cons "\\rangle}" r) 'mparen 'mparen)
 
37
                    (if (and (integerp x) (< x 10))
 
38
                        (tex x (list "^")(cons "" r) 'mparen 'mparen)
 
39
                        (tex x (list "^{")(cons "}" r) 'mparen 'mparen)))))
 
40
    (append l r)))
 
41
 
 
42
;; binomial coefficients
 
43
 
527
44
(defun tex-choose (x l r)
528
 
  `(,@l 
529
 
    "{" 
 
45
  `(,@l
 
46
    "\\binom{"
530
47
    ,@(tex (cadr x) nil nil 'mparen 'mparen)
531
 
    "\\choose "
 
48
    "}{"
532
49
    ,@(tex (caddr x) nil nil 'mparen 'mparen)
533
50
    "}"
534
51
    ,@r))
535
52
 
536
 
 
537
 
(defprop rat tex-rat tex) 
538
 
(defprop rat 120. tex-lbp)
539
 
(defprop rat 121. tex-rbp)
540
 
(defun tex-rat(x l r) (tex-mquotient x l r))
541
 
 
542
 
(defprop mplus tex-mplus tex)
543
 
(defprop mplus 100. tex-lbp)
544
 
(defprop mplus 100. tex-rbp)
545
 
 
546
 
(defun tex-mplus (x l r)
547
 
 ;(declare (fixnum w))
548
 
 (cond ((memq 'trunc (car x))(setq r (cons "+\\cdots " r))))
549
 
 (cond ((null (cddr x))
550
 
        (if (null (cdr x))
551
 
            (tex-function x l r t)
552
 
            (tex (cadr x) (cons "+" l) r 'mplus rop)))
553
 
       (t (setq l (tex (cadr x) l nil lop 'mplus) 
554
 
                x (cddr x))
555
 
          (do ((nl l)  (dissym))
556
 
              ((null (cdr x))
557
 
               (if (mmminusp (car x)) (setq l (cadar x) dissym (list "-"))
558
 
                   (setq l (car x) dissym (list "+")))
559
 
               (setq r (tex l dissym r 'mplus rop))
560
 
               (append nl r))
561
 
              (if (mmminusp (car x)) (setq l (cadar x) dissym (list "-"))
562
 
                  (setq l (car x) dissym (list "+")))
563
 
              (setq nl (append nl (tex l dissym nil 'mplus 'mplus))
564
 
                    x (cdr x))))))
565
 
 
566
 
(defprop mminus tex-prefix tex)
567
 
(defprop mminus ("-") texsym)
568
 
(defprop mminus 100. tex-rbp)
569
 
(defprop mminus 100. tex-lbp)
570
 
 
571
 
(defprop min tex-infix tex)
572
 
(defprop min ("\\in{") texsym)
573
 
(defprop min 80. tex-lbp)
574
 
(defprop min 80. tex-rbp)
575
 
 
576
 
(defprop mequal tex-infix tex)
577
 
(defprop mequal (=) texsym)
578
 
(defprop mequal 80. tex-lbp)
579
 
(defprop mequal 80. tex-rbp)
580
 
 
581
 
(defprop mnotequal tex-infix tex)
582
 
(defprop mnotequal 80. tex-lbp)
583
 
(defprop mnotequal 80. tex-rbp)
584
 
 
585
 
(defprop mgreaterp tex-infix tex)
586
 
(defprop mgreaterp (>) texsym)
587
 
(defprop mgreaterp 80. tex-lbp)
588
 
(defprop mgreaterp 80. tex-rbp)
589
 
 
590
 
(defprop mgeqp tex-infix tex)
591
 
(defprop mgeqp ("\\geq") texsym)
592
 
(defprop mgeqp 80. tex-lbp)
593
 
(defprop mgeqp 80. tex-rbp)
594
 
 
595
 
(defprop mlessp tex-infix tex)
596
 
(defprop mlessp (<) texsym)
597
 
(defprop mlessp 80. tex-lbp)
598
 
(defprop mlessp 80. tex-rbp)
599
 
 
600
 
(defprop mleqp tex-infix tex)
601
 
(defprop mleqp ("\\leq") texsym)
602
 
(defprop mleqp 80. tex-lbp)
603
 
(defprop mleqp 80. tex-rbp)
604
 
 
605
 
(defprop mnot tex-prefix tex)
606
 
(defprop mnot ("\\not ") texsym)
607
 
(defprop mnot 70. tex-rbp)
608
 
 
609
 
(defprop mand tex-nary tex)
610
 
(defprop mand ("\\and") texsym)
611
 
(defprop mand 60. tex-lbp)
612
 
(defprop mand 60. tex-rbp)
613
 
 
614
 
(defprop mor tex-nary tex)
615
 
(defprop mor ("\\or") texsym)
616
 
 
617
 
;; make sin(x) display as sin x , but sin(x+y) as sin(x+y)
618
 
;; etc
619
 
 
620
 
(defun tex-setup (x)
621
 
  (let((a (car x))
622
 
       (b (cadr x)))
623
 
      (setf (get a 'tex) 'tex-prefix)
624
 
      (setf (get a 'texword) b)  ;This means "sin" will always be roman
625
 
      (setf (get a 'texsym) (list b))
626
 
      (setf (get a 'tex-rbp) 130)))
627
 
 
628
 
(mapc #'tex-setup 
629
 
  '( (%sin "\\sin ")
630
 
     (%cos "\\cos ")
631
 
     (%tan "\\tan ")
632
 
     (%cot "\\cot ")
633
 
     (%sec "\\sec ")
634
 
     (%csc "\\csc ")
635
 
     (%asin "\\arcsin ")
636
 
     (%acos "\\arccos ")
637
 
     (%atan "\\arctan ")
638
 
     (%acot "\\operatorname{arccot}")
639
 
     (%asec "\\operatorname{arcsec}")
640
 
     (%acsc "\\operatorname{arccsc}")
641
 
     (%sinh "\\sinh ")
642
 
     (%cosh "\\cosh ")
643
 
     (%tanh "\\tanh ")
644
 
     (%coth "\\coth ")
645
 
     (%sech "\\operatorname{sech}")          
646
 
     (%csch "\\operatorname{csch}")
647
 
     (%asinh "\\operatorname{arcsinh}")
648
 
     (%acosh "\\operatorname{arccosh}")
649
 
     (%atanh "\\operatorname{arctanh}")
650
 
     (%acoth "\\operatorname{arccoth}")
651
 
     (%asech "\\operatorname{arcsech}")
652
 
     (%acsch "\\operatorname{arccsch}")
653
 
     (%determinant "\\det ")     
654
 
     (%ln "\\ln ")
655
 
     (%log "\\log ")
656
 
    ;; (%erf "{\\rm erf}") this would tend to set erf(x) as erf x. Unusual
657
 
     ;(%laplace "{\\cal L}")
658
 
     )) ;; etc
659
 
 
660
 
(defprop mor tex-nary tex)
661
 
(defprop mor 50. tex-lbp)
662
 
(defprop mor 50. tex-rbp)
663
 
 
664
 
(defprop mcond tex-mcond tex)
665
 
(defprop mcond 25. tex-lbp)
666
 
(defprop mcond 25. tex-rbp)
667
 
(defprop %derivative tex-derivative tex)
668
 
(defun tex-derivative (x l r)
669
 
  (tex (tex-d x '$|d|) l r lop rop ))
670
 
 
671
 
(defun tex-d(x dsym) ;dsym should be $d or "$d\\partial"
672
 
  ;; format the macsyma derivative form so it looks
673
 
  ;; sort of like a quotient times the deriva-dand.
674
 
  (let*
675
 
   ((arg (cadr x)) ;; the function being differentiated
676
 
    (difflist (cddr x)) ;; list of derivs e.g. (x 1 y 2)
677
 
    (ords (odds difflist 0)) ;; e.g. (1 2)
678
 
    (vars (odds difflist 1)) ;; e.g. (x y)
679
 
    (numer `((mexpt) ,dsym ((mplus) ,@ords))) ; d^n numerator
680
 
    (denom (cons '(mtimes)
681
 
                 (mapcan #'(lambda(b e)
682
 
                                  `(,dsym ,(simplifya `((mexpt) ,b ,e) nil)))
683
 
                         vars ords))))
684
 
   `((mtimes)
685
 
     ((mquotient) ,(simplifya numer nil) ,denom)
686
 
     ,arg)))
687
 
 
688
 
(defun odds(n c) 
689
 
  ;; if c=1, get the odd terms  (first, third...)
690
 
  (cond ((null n) nil) 
691
 
        ((= c 1)(cons (car n)(odds (cdr n) 0)))
692
 
        ((= c 0)(odds (cdr n) 1))))
693
 
 
694
 
(defun tex-mcond (x l r)
695
 
  (append l
696
 
    (tex (cadr x) '("\\mathbf{if}\\;")
697
 
      '("\\;\\mathbf{then}\\;") 'mparen 'mparen)
698
 
    (if (eql (fifth x) '$false)
699
 
      (tex (caddr x) nil r 'mcond rop)
700
 
      (append (tex (caddr x) nil nil 'mparen 'mparen)
701
 
        (tex (fifth x) '("\\;\\mathbf{else}\\;") r 'mcond rop)))))
702
 
 
703
 
(defprop mdo tex-mdo tex)
704
 
(defprop mdo 30. tex-lbp)
705
 
(defprop mdo 30. tex-rbp)
706
 
(defprop mdoin tex-mdoin tex)
707
 
(defprop mdoin 30. tex-rbp)
708
 
 
709
 
(defun tex-lbp(x)(cond((get x 'tex-lbp))(t(lbp x))))
710
 
(defun tex-rbp(x)(cond((get x 'tex-rbp))(t(lbp x))))
711
 
 
712
 
;; these aren't quite right
713
 
 
714
 
(defun tex-mdo (x l r)
715
 
  (tex-list (texmdo x) l r "\\;"))
716
 
 
717
 
(defun tex-mdoin (x l r)
718
 
  (tex-list (texmdoin x) l r "\\;"))
719
 
 
720
 
(defun texmdo (x)
721
 
   (nconc (cond ((second x) `("\\mathbf{for}" ,(second x))))
722
 
         (cond ((equal 1 (third x)) nil)
723
 
               ((third x)  `("\\mathbf{from}" ,(third x))))
724
 
         (cond ((equal 1 (fourth x)) nil)
725
 
               ((fourth x) `("\\mathbf{step}" ,(fourth x)))
726
 
               ((fifth x)  `("\\mathbf{next}" ,(fifth x))))
727
 
         (cond ((sixth x)  `("\\mathbf{thru}" ,(sixth x))))
728
 
         (cond ((null (seventh x)) nil)
729
 
               ((eq 'mnot (caar (seventh x)))
730
 
                `("\\mathbf{while}" ,(cadr (seventh x))))
731
 
               (t `("\\mathbf{unless}" ,(seventh x))))
732
 
         `("\\mathbf{do}" ,(eighth x))))
733
 
 
734
 
(defun texmdoin (x)
735
 
  (nconc `("\\mathbf{for}" ,(second x) "\\mathbf{in}" ,(third x))
736
 
         (cond ((sixth x) `("\\mathbf{thru}" ,(sixth x))))
737
 
         (cond ((null (seventh x)) nil)
738
 
               ((eq 'mnot (caar (seventh x)))
739
 
                `("\\mathbf{while}" ,(cadr (seventh x))))
740
 
               (t `("\\mathbf{unless}" ,(seventh x))))
741
 
         `("\\mathbf{do}" ,(eighth x))))
742
 
 
743
 
 
744
 
;; Undone and trickier:
745
 
;; handle reserved symbols stuff, just in case someone
746
 
;; has a macsyma variable named (yuck!!) \over  or has a name with 
747
 
;; {} in it.
748
 
;; Maybe do some special hacking for standard notations for 
749
 
;; hypergeometric fns, alternative summation notations  0<=n<=inf, etc.
750
 
 
751
 
;;Undone and really pretty hard: line breaking
752
 
 
753
 
(defprop mtext tex-mtext tex)
754
 
(defprop text-string tex-mtext tex)
755
 
(defprop mlable tex-mlable tex)
756
 
(defprop spaceout tex-spaceout tex)
757
 
 
758
 
(defun tex-mtext (x l r) (tex-list (cdr x) l r ""))
 
53
;; Integrals, sums, products
 
54
 
 
55
(defun tex-int (x l r)
 
56
  (let ((s1 (tex (cadr x) nil nil 'mparen 'mparen)) ;;integrand delims / & d
 
57
        (var (tex (caddr x) nil nil 'mparen rop))) ;; variable
 
58
    (cond((= (length x) 3)
 
59
          (append l `("\\int {" ,@s1 "}{\\;d" ,@var "}\\big.") r))
 
60
         (t ;; presumably length 5
 
61
          (let ((low (tex (nth 3 x) nil nil 'mparen 'mparen))
 
62
                ;; 1st item is 0
 
63
                (hi (tex (nth 4 x) nil nil 'mparen 'mparen)))
 
64
            (append l `("\\int_{" ,@low "}^{" ,@hi "}{" ,@s1 "\\;d" ,@var "}\\big.") r))))))
 
65
 
 
66
(defun tex-sum(x l r)
 
67
  (let ((op (cond ((eq (caar x) '%sum) "\\sum_{")
 
68
                  ((eq (caar x) '%product) "\\prod_{")
 
69
                  ;; extend here
 
70
                  ))
 
71
        ;; gotta be one of those above
 
72
        (s1 (tex (cadr x) nil nil 'mparen rop)) ;; summand
 
73
        (index ;; "index = lowerlimit"
 
74
         (tex `((mequal simp) ,(caddr x),(cadddr x)) nil nil 'mparen 'mparen))
 
75
        (toplim (tex (car(cddddr x)) nil nil 'mparen 'mparen)))
 
76
    (append l `( ,op ,@index "}^{" ,@toplim "}{" ,@s1 "}\\big.") r)))
 
77
 
 
78
(defun tex-lsum(x l r)
 
79
  (let ((op (cond ((eq (caar x) '%lsum) "\\sum_{")
 
80
                  ;; extend here
 
81
                  ))
 
82
        ;; gotta be one of those above 
 
83
        (s1 (tex (cadr x) nil nil 'mparen rop)) ;; summand
 
84
        (index ;; "index = lowerlimit"
 
85
         (tex `((min simp) , (caddr x), (cadddr x))  nil nil 'mparen 'mparen)))
 
86
    (append l `( ,op ,@index "}}{" ,@s1 "}\\big.") r)))
 
87
 
 
88
;; This is a hack for math input of integrals, sums, products
 
89
 
 
90
(defmfun $tmint (a b f x) ($integrate f x a b))
 
91
 
 
92
(defmspec $tmsum (l) (setq l (cdr l))
 
93
  (if (= (length l) 3)
 
94
      (dosum (caddr l) (cadar l) (meval (caddar l)) (meval (cadr l)) t)
 
95
      (wna-err '$tmsum)))
 
96
 
 
97
(defmspec $tmlsum (l) (setq l (cdr l))
 
98
  (or (= (length l) 2) (wna-err '$tmlsum))
 
99
  (let ((form (cadr l))
 
100
        (ind (cadar l))
 
101
        (lis (meval (caddar l)))
 
102
        (ans 0))
 
103
       (or (symbolp ind) (merror "Second argument not a variable ~M" ind))
 
104
       (cond (($listp lis)
 
105
              (loop for v in (cdr lis)
 
106
                    with lind = (cons ind nil)
 
107
                    for w = (cons v nil)
 
108
                    do
 
109
                    (setq ans (add* ans  (mbinding (lind w) (meval form)))))
 
110
                   ans)
 
111
           (t `((%lsum) ,form ,ind ,lis)))))
 
112
 
 
113
(defmspec $tmprod (l) (setq l (cdr l))
 
114
  (if (= (length l) 3)
 
115
      (dosum (caddr l) (cadar l) (meval (caddar l)) (meval (cadr l)) nil)
 
116
      (wna-err '$tmprod)))
759
117
 
760
118
(defun tex-mlable (x l r)
761
119
  (tex (caddr x)
762
120
    (append l
763
121
      (if (cadr x)
764
 
          (list (format nil "(~A) " (stripdollar (cadr x))))
 
122
          (list (format nil "(~A) " 
 
123
                        (print-invert-case (stripdollar (cadr x)))))
765
124
        nil))
766
125
    r 'mparen 'mparen))
767
126
 
768
 
(defun tex-spaceout (x l r)
769
 
  (append l (list "\\verb|" (make-string (cadr x) :initial-element #\space) "|") r))
770
 
 
771
 
; jh: verb & mbox
772
127
(defun qndispla (form)
773
128
  (let (($display2d nil))
774
129
    (displa form)))
775
130
 
776
131
(defun latex (x)
777
 
;;  (princ x)  ;; uncomment to debug.
778
132
  (mapc #'princ
779
133
        (if (and (listp x) (cdr x)
780
134
                 (equal (string-right-trim '(#\Space) (cadr x)) "Is"))
781
 
           (qndispla x)      ;(tex x '("") '("") 'mparen 'mparen)
 
135
           (qndispla x)
782
136
          (tex x '("") '("
783
137
") 'mparen 'mparen))))
784
138
 
787
141
    (if (eq $display2d '$emaxima)
788
142
        (latex form)
789
143
      (funcall old-displa form))))
790