1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;; The data in this file contains enhancments. ;;;;;
5 ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;;
6 ;;; All rights reserved ;;;;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11 (defvar $manual_demo
"manual.demo")
13 (defmspec $example
(l)
14 (declare (special *need-prompt
*))
15 (let ((example (second l
)))
16 (when (symbolp example
)
17 ;; Coerce a symbol to be a string.
18 ;; Remove the first character if it is a dollar sign.
19 (setq example
(coerce (exploden (stripdollar example
)) 'string
)))
20 (unless (stringp example
)
22 (intl:gettext
"example: argument must be a symbol or a string; found: ~M") example
))
23 ;; Downcase the string. $example is not case sensitive.
24 (setq example
(string-downcase example
))
25 (with-open-file (st ($file_search1 $manual_demo
'((mlist) $file_search_demo
)))
26 (prog (tem all c-tag d-tag
)
28 (setq tem
(read-char st nil
))
29 (unless tem
(go notfound
))
30 (unless (eql tem
#\
&) (go again
))
31 (setq tem
(read-char st nil
))
32 (unless (eql tem
#\
&) (go again
))
33 ;; so we are just after having read &&
35 (setq tem
(read st nil nil
))
36 (unless tem
(go notfound
))
37 ;; Coerce the topic in tem to be a string.
38 (setq tem
(coerce (exploden tem
) 'string
))
39 (cond ((string= tem example
)
43 ;; at this stage we read maxima forms and print and eval
44 ;; until a peek sees '&' as the first character of next expression,
45 ;; but at first skip over whitespaces.
47 (when (member (setq tem
(peek-char nil st nil
))
48 '(#\tab
#\space
#\newline
#\linefeed
#\return
#\page
))
49 ;; Found whitespace. Read char and look for next char.
50 ;; The && label can be positioned anywhere before the next topic.
51 (setq tem
(read-char st nil
))
53 (cond ((or (null tem
) (eql tem
#\
&))
54 (setf *need-prompt
* t
)
56 (setq tem
(dbm-read st nil nil
))
58 (setq c-tag
(makelabel $inchar
))
59 (unless $nolabels
(setf (symbol-value c-tag
) (nth 2 tem
)))
61 (displa `((mlabel) ,c-tag
,(nth 2 tem
))))
62 (setq $%
(meval* (nth 2 tem
)))
63 (setq d-tag
(makelabel $outchar
))
64 (unless $nolabels
(setf (symbol-value d-tag
) $%
))
65 (when (eq (caar tem
) 'displayinput
)
66 (displa `((mlabel) ,d-tag
,$%
)))
70 (setf *need-prompt
* t
)
72 (return `((mlist) ,@(nreverse all
)))
74 (mtell (intl:gettext
"example: ~M not found. 'example();' returns the list of known examples.~%") example
)
77 (defun mread-noprompt (&rest read-args
)
78 (let ((*mread-prompt
* "") (*prompt-on-read-hang
*))
79 (declare (special *mread-prompt
* *prompt-on-read-hang
*))
80 (unless read-args
(setq read-args
(list #+(or sbcl cmu
) *standard-input
*
81 #-
(or sbcl cmu
) *query-io
*)))
82 (caddr (apply #'mread read-args
))))
84 ;; Some list creation utilities.
86 (defmspec $create_list
(l)
87 (cons '(mlist) (apply #'create-list1
(cadr l
) (cddr l
))))
89 (defun create-list1 (form &rest l
&aux lis var1 top
)
90 (cond ((null l
) (list (meval* form
)))
95 (unless (symbolp var1
) (merror (intl:gettext
"create_list: expected a symbol; found: ~A") var1
))
96 (setq lis
(meval* lis
))
97 (mbinding ((list var1
))
98 (cond ((and (numberp lis
)
100 (setq top
(car l
) l
(cdr l
))
101 (setq top
(meval* top
))
103 (loop for i from lis to top
106 (apply #'create-list1 form l
)))
108 (loop for v in
(cdr lis
)
111 (apply #'create-list1 form l
)))
112 (t (merror (intl:gettext
"create_list: unexpected arguments."))))))))
114 ;; The documentation is now in INFO format and can be printed using
115 ;; tex, or viewed using info or gnu emacs or using a web browser. All
116 ;; versions of maxima have a builtin info retrieval mechanism.
118 (defmspec $describe
(x)
119 (let ((topic ($sconcat
(cadr x
)))
120 (exact-p (or (null (caddr x
)) (eq (caddr x
) '$exact
))))
122 (cl-info::info-exact topic
)
123 (cl-info::info-inexact topic
))))
125 ; The old implementation
127 ; (cons '(mlist) (apropos-list s :maxima)))
129 ;;; Utility function for apropos to filter a list LST with a function FN
130 ;;; it is semiliar to remove-if-not, but take the return value of the function
131 ;;; and build up a new list with this values.
132 ;;; e.g. (filter #'(lambda(x) (if (oddp x) (inc x)) '(1 2 3 4 5)) --> (2 4 6)
134 (defun filter (fn lst
)
137 (let ((val (funcall fn x
)))
138 (if val
(push val acc
))))
141 (defmspec $apropos
(s)
143 (setq s
(car (margs s
)))
145 ;; A list of all Maxima names which contain the string S.
146 (setq acc
(append acc
(apropos-list (stripdollar s
) :maxima
)))
147 ;; Filter the names which are Maxima User symbols starting
148 ;; with % or $ and remove duplicates.
152 (filter #'(lambda (x)
153 (cond ((char= (get-first-char x
) #\$
) x
)
154 ((char= (get-first-char x
) #\%
)
155 ;; Change to a verb, when present.
156 (if (setq y
(get x
'noun
))
163 (intl:gettext
"apropos: argument must be a string; found: ~M") s
)))))