1 ;; emaxima.el Mode for interaction with Maxima from TeX buffer
2 ;; Written 2/12/1991 by Dan Dill dan@chem.bu.edu
3 ;; Modified for Maxima by Jay Belanger
5 ;; Copyright (C) 1991, 1993 Dan Dill (dan@chem.bu.edu)
6 ;; 1999-2007 Jay Belanger (belanger@truman.edu)
11 ;; Keywords: maxima, emaxima
13 ;; This program is free software; you can redistribute it and/or
14 ;; modify it under the terms of the GNU General Public License as
15 ;; published by the Free Software Foundation; either version 2 of
16 ;; the License, or (at your option) any later version.
18 ;; This program is distributed in the hope that it will be
19 ;; useful, but WITHOUT ANY WARRANTY; without even the implied
20 ;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21 ;; PURPOSE. See the GNU General Public License for more details.
23 ;; You should have received a copy of the GNU General Public
24 ;; License along with this program; if not, write to the Free
25 ;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28 ;; You will need, in addition to this file,
29 ;; maxima.el, maxima-font-lock.el and emaxima.sty
33 ;; See the file EMintro.ps for a quick introduction.
38 ;;;; The variables that the user may wish to change
45 (defcustom emaxima-use-tex
'auctex
46 "Possible modes to use within EMaxima.
47 Possible choices are 'auctex, 'tex or nil"
49 :type
'(choice :menu-tag
"TeX style"
55 (defcustom emaxima-use-emaxima-indent nil
56 "Use Maxima indent when in cells.
57 Only works with AUCTeX."
61 (defcustom emaxima-tex-lisp-file
(locate-library "emaxima.lisp" t
)
62 "The file to be loaded that allows TeX output."
66 (defcustom emaxima-output-marker
"---"
67 "The string to separate the input from the output."
71 (defcustom emaxima-abbreviations-allowed t
72 "If non-nil, then `...' abbreviations are allowed in cell labels
73 and references. Note that enabling this options will slow cell and
78 (defcustom emaxima-preview-after-update-all t
79 "If non-nil and preview-latex is available, preview after update-all"
83 (defcustom emaxima-max-references
5
84 "Number of references in a cell below which cell references are fetched
85 as needed, scanning the entire document for each reference. At or above this
86 number, all cells in a document for the given filename are precollated in a
87 single scan of the document."
91 (defcustom emaxima-temp-dir
"/tmp/"
92 "Directory for temporary files.
93 Specify \"\" to use the directory of the EMaxima document buffer."
97 ;;; Other variables and constants
99 (defvar emaxima-zap-file nil
100 "Temporary file name used for text being sent as input to Maxima.")
102 (defvar emaxima-dereference-path nil
103 "List of buffers referenced in cell assembly.
104 Used by `emaxima-dereference-buffer' to detect self-reference.")
106 (defvar emaxima-zap-file-prefix nil
107 "Global variable used as prefix to make unique buffer names for cell
108 and package assembly.")
110 (defvar emaxima-error-point nil
111 "Buffer position where error detected.")
113 (defvar emaxima-buffer-alist nil
114 "Alist of temporary buffers associate with cells `file:part'.
115 The buffers are used in package and cell assembly.")
117 (defvar emaxima-source-buffer nil
118 "Buffer from which emaxima-collate-cells works.")
120 (defconst emaxima-standard-cell-begin-regexp
121 "\\\\begin{maxima\\(?:\\(?:\\*\\|nu\\*?\\)?}\\)"
122 "A regexp matching the beginning of a standard cell.")
124 (defconst emaxima-standard-cell-end-regexp
125 "\\\\end{maxima\\(?:\\(?:\\*\\|nu\\*?\\)?}\\)"
126 "A regexp matching the end of a standard cell.")
128 (defconst emaxima-session-cell-begin-regexp
129 "\\\\begin{maximasession\\(?:\\(?:\\*\\|nu\\*?\\)?}\\)"
130 "A regexp matching the beginning of a session cell.")
132 (defconst emaxima-session-cell-end-regexp
133 "\\\\end{maximasession\\(?:\\(?:\\*\\|nu\\*?\\)?}\\)"
134 "A regexp matching the end of a session cell.")
136 (defconst emaxima-any-cell-begin-regexp
137 "\\\\begin{maxima\\(?:\\(?:\\*\\|nu\\*?\\|session\\(?:\\*\\|nu\\*?\\)?\\)?}\\)"
138 "A regexp matching the beginning of any cell.")
140 (defconst emaxima-any-non-nu-cell-begin-regexp
141 "\\\\begin{maxima\\(?:\\(?:\\*\\|session\\*?\\)?}\\)"
142 "A regexp matching the beginning of any cell.")
144 (defconst emaxima-any-cell-end-regexp
145 "\\\\end{maxima\\(?:\\(?:\\*\\|nu\\*?\\|session\\(?:\\*\\|nu\\*?\\)?\\)?}\\)"
146 "A regexp matching the end of any cell.")
148 (defconst emaxima-package-cell-regexp
149 (concat emaxima-standard-cell-begin-regexp
"\\[.*:.*\\]")
150 "A regexp matching the beginning of a standard cell.")
152 ;;; Some utility functions
154 (defun emaxima-insert-quote (arg)
155 "Insert a quote as appropriate"
159 (self-insert-command (prefix-numeric-value arg
)))
160 ((eq emaxima-use-tex
'auctex
)
161 (TeX-insert-quote arg
))
162 ((eq emaxima-use-tex
'tex
)
163 (tex-insert-quote arg
))
164 (t (self-insert-command (prefix-numeric-value arg
)))))
166 (defun emaxima-insert-dollar (arg)
167 "Insert a dollar sign as appropriate"
171 (self-insert-command (prefix-numeric-value arg
)))
172 ((eq emaxima-use-tex
'auctex
)
173 (TeX-insert-dollar arg
))
174 ((eq emaxima-use-tex
'tex
)
175 (skeleton-pair-insert-maybe arg
))
176 (t (self-insert-command (prefix-numeric-value arg
)))))
178 (defun emaxima-mark-file-as-emaxima ()
179 "Mark the file as an EMaxima buffer.
180 The next time the file is loaded, it will then be in EMaxima mode"
185 (if (looking-at ".*-\\*-EMaxima-\\*-")
188 (insert "%-*-EMaxima-*-"))))
190 (defun emaxima-load-tex-library ()
191 (when emaxima-tex-lisp-file
192 (maxima-single-string-wait
193 (concat "block(load(\""
194 emaxima-tex-lisp-file
195 "\"), linenum:linenum-1)$"))))
196 (defun emaxima-tex-on ()
198 (when emaxima-tex-lisp-file
199 (maxima-single-string-wait
200 "block(origdisplay:display2d, display2d:emaxima, linenum:linenum-1)$")))
202 (defun emaxima-tex-off ()
204 (when emaxima-tex-lisp-file
205 (maxima-single-string-wait "block(display2d:origdisplay, linenum:linenum-1)$")))
207 (defun emaxima-indent-line ()
211 (LaTeX-indent-line)))
213 ;;; Which type of cell, if any, is the point in.
215 (defun emaxima-cell-p ()
216 "Non-nil if point is in a Emaxima cell."
219 (if (re-search-backward emaxima-any-cell-begin-regexp
220 (point-min) t
) ; \beginmaxima
221 (setq found
(point))))
224 (re-search-backward emaxima-any-cell-end-regexp
225 found t
)) ; Intervening \endmaxima
229 (re-search-forward emaxima-any-cell-end-regexp
230 (point-max) t
)) ;\endmaxima
232 (setq found nil
))) ; No \endmaxima
235 (re-search-forward emaxima-any-cell-begin-regexp
236 found t
)) ; Intervening \beginmaxima
240 (defun emaxima-standard-cell-p ()
241 "Non-nil if point is in a standard cell."
245 (re-search-backward emaxima-any-cell-begin-regexp
)
246 (looking-at emaxima-standard-cell-begin-regexp
))))
248 (defun emaxima-session-cell-p ()
249 "Non-nil if point is in a session cell."
253 (re-search-backward emaxima-any-cell-begin-regexp
)
254 (looking-at emaxima-session-cell-begin-regexp
))))
256 (defun emaxima-package-cell-p ()
258 (emaxima-standard-cell-p)
260 (re-search-backward emaxima-standard-cell-begin-regexp
)
261 (goto-char (match-end 0))
264 (not (looking-at "\\[\\]"))))))
266 ;;; Create the cells.
267 (defun emaxima-new-standard-cell ()
268 "Insert cell in buffer."
273 (insert "\\begin{maxima}[]\n\n\\end{maxima}")
274 (unless (looking-at " *$")
280 (defun emaxima-new-session-cell ()
281 "Insert cell in buffer."
286 (insert "\\begin{maximasession}\n\n\\end{maximasession}")
287 (unless (looking-at " *$")
293 (defun emaxima-create-standard-cell ()
294 "Insert standard cell in buffer."
296 (if (not (emaxima-cell-p))
297 (emaxima-new-standard-cell)
298 (if (emaxima-standard-cell-p)
299 (error "Currently in cell.")
301 (re-search-backward emaxima-session-cell-begin-regexp
)
302 (re-search-forward "maximasession")
303 (replace-match "maxima")
306 (re-search-forward emaxima-session-cell-end-regexp
)
307 (search-backward "maximasession")
308 (replace-match "maxima")))))
310 (defun emaxima-create-session-cell ()
311 "Insert session cell in buffer."
313 (if (not (emaxima-cell-p))
314 (emaxima-new-session-cell)
315 (if (emaxima-package-cell-p)
316 (error "Currently in package cell.")
317 (if (emaxima-session-cell-p)
318 (error "Currently in session cell.")
320 (re-search-backward emaxima-standard-cell-begin-regexp
)
321 (re-search-forward "maxima")
322 (replace-match "maximasession")
324 (if (looking-at "\\[\\]")
326 (re-search-forward emaxima-standard-cell-end-regexp
)
327 (search-backward "maxima")
328 (replace-match "maximasession"))))))
330 (defun emaxima-toggle-starred-cell ()
332 "Toggle whether or not the current cell is starred."
333 (if (not (emaxima-cell-p))
334 (error "Not in cell.")
336 (re-search-backward emaxima-any-cell-begin-regexp
)
337 (re-search-forward "maxima\\(?:session\\)?")
338 (if (looking-at "\\*")
341 (re-search-forward emaxima-any-cell-end-regexp
)
343 (re-search-forward "maxima\\(?:session\\)?")
344 (if (looking-at "\\*")
348 (defun emaxima-starred-cell-p ()
349 "Non-nil if point is in starred cell."
350 (if (not (emaxima-cell-p))
353 (re-search-backward emaxima-any-cell-begin-regexp
)
354 (re-search-forward "maxima\\(?:session\\)?")
355 (looking-at "\\*"))))
357 (defun emaxima-package-part ()
358 "Insert package marker for cell."
361 ((emaxima-standard-cell-p)
365 (re-search-backward emaxima-standard-cell-begin-regexp
)
366 (goto-char (match-end 0))
367 (if (looking-at "\\[\\(.*\\)\\]")
369 (setq initstring
(match-string 1))
370 (delete-region (match-beginning 0) (match-end 0)))
371 (setq initstring
""))
372 (setq package
(read-string "Package: " initstring
))
373 (unless (string= package
"")
374 (insert (concat "[" package
"]"))))))
376 (message "Not in (standard) Maxima cell"))))
380 (defun emaxima-cell-start ()
381 "Return position of start of cell containing point."
383 (if (not (looking-at emaxima-any-cell-begin-regexp
))
384 (re-search-backward emaxima-any-cell-begin-regexp
))
388 (defun emaxima-cell-end ()
389 "Return position of end of cell containing point."
391 (re-search-forward emaxima-any-cell-end-regexp
)
396 (defun emaxima-previous-cell-start ()
397 "Get start of preceding cell. If none, return current position."
398 (let ((cur-pos (point))
401 (if (not (re-search-backward emaxima-any-cell-end-regexp
(point-min) t
))
405 (re-search-backward emaxima-any-cell-begin-regexp
)
410 (defun emaxima-next-cell-start (&optional arg
)
411 "Get start of next cell. If none, return current position."
412 (let ((cur-pos (point))
415 emaxima-any-cell-begin-regexp
416 emaxima-any-non-nu-cell-begin-regexp
)))
418 (if (re-search-forward re
(point-max) t
)
420 (if (not (emaxima-cell-p))
428 (defun emaxima-forward-cell (&optional arg
)
431 (let ((cur-pos (point))
432 (cell-pos (point-max))
434 (setq new-pos
(emaxima-next-cell-start arg
))
435 (if (not (equal new-pos cur-pos
))
436 (if (> new-pos cell-pos
)
438 (setq cell-pos new-pos
)))
439 (if (equal cell-pos
(point-max))
441 (goto-char cell-pos
))))
443 (defun emaxima-backward-cell ()
444 "Move to previous cell."
446 (let ((cur-pos (point))
447 (cell-pos (point-min))
449 (setq new-pos
(emaxima-previous-cell-start))
450 (if (not (equal new-pos cur-pos
))
451 (if (< new-pos cell-pos
)
453 (setq cell-pos new-pos
)))
454 (if (equal cell-pos
(point-min))
456 (goto-char cell-pos
))))
458 ;;; Output related functions
460 (defun emaxima-output-p ()
461 "Return start of output text if present, else return nil. Assumes
462 point in cell. Output assumed to follow input, separated by a
463 \maximaoutput or \maximaoutput*."
465 (goto-char (emaxima-cell-start))
466 (if (re-search-forward "^\\\\maximaoutput"
467 (emaxima-cell-end) t
)
474 (defun emaxima-empty-output-p ()
475 "Check if there is not output or only empty lines in output."
477 (goto-char (emaxima-cell-start))
478 (if (re-search-forward "^\\\\maximaoutput"
479 (emaxima-cell-end) t
)
482 (while (looking-at "[ \t]*$")
484 (looking-at "\\\\end{maxima"))
487 (defun emaxima-delete-output ()
488 "Delete current output (if any). Assumes point in cell.
489 Output assumed to follow input, separated by a emaxima-output-marker line.
490 Input *may* contain blank lines."
492 (let ((out-start (emaxima-output-p)))
494 (delete-region out-start
(emaxima-cell-end))
498 ;;; @@ EMaxima functions for package assembly
500 (defun emaxima-replace-assoc (alist key val
)
501 "Replace ALIST KEY VALUE, if KEY present, else add KEY VALUE.
502 Return modified alist."
503 (if (assoc key alist
)
504 (setcdr (assoc key alist
) val
)
505 (setcdr alist
(cons (cons key val
) (cdr alist
))))
508 (defun emaxima-assemble (arg)
509 "Assemble package (see emaxima-assemble-package), or, with C-u prefix,
510 assemble references within a cell (see emaxima-assemble-cell)."
513 (emaxima-assemble-package)
514 (emaxima-assemble-cell)))
516 (defun emaxima-assemble-cell (&optional delete
)
517 "Assemble references in cell to file with unique name. The buffer used to
518 write the file is not deleted, unless optional DELETE is non-nil.
519 Return the filename."
521 ;; Here is how this function works:
523 ;; The text of the cell is written to a buffer with key `file:part'. Then
524 ;; the number of references in the cell is counted. If the number of
525 ;; references in the cell is less than emaxima-max-references, then the cell
526 ;; references are resolved by successive calls to emaxima-dereference-buffer
527 ;; which collates the text for cell references as needed, using
528 ;; emaxima-collate-cells. If the number of references is equal to or
529 ;; greater than emaxima-max-references, then all cells in the document
530 ;; correpsonding to the current cell type and filename are collated into
531 ;; buffers, using emaxima-collate-cells, and then the all cell references
532 ;; are are resolved by successive calls to emaxima-dereference-buffer.
534 ;; The global `emaxima-buffer-alist' associates buffer names with keys.
535 ;; Buffer names are unique. The names of all buffers are constructed with
536 ;; `maxima-make-temp-name' and are unique. All buffers except possibly the
537 ;; cell-buffer are deleted on exit.
540 (let ((home-buffer (current-buffer))
541 files parts file part
543 cell-key cell-buffer tmp-alist tmp-buffer
)
544 (if (not (emaxima-cell-p)) (error "Not in a cell"))
545 (if (not (emaxima-reference-p)) (error "Cell contains no references"))
547 (goto-char (emaxima-cell-start))
549 (if (not (looking-at emaxima-package-cell-regexp
))
550 (error "Cell is not a package"))
551 (setq emaxima-error-point
(point))
552 (if emaxima-abbreviations-allowed
553 (unwind-protect ; In case filename errors
554 ;; This can take some seconds
556 (message "Getting filenames...")
557 (setq files
(emaxima-get-filenames))
559 (goto-char emaxima-error-point
)))
560 (setq file
(emaxima-get-filename files
))
561 (if (not file
) (error "Ambiguous filename"))
562 (if emaxima-abbreviations-allowed
563 ;; This can take several seconds for a document with many cells
565 (message "Getting partnames")
566 (setq parts
(emaxima-get-partnames file files
))
568 (setq part
(emaxima-get-partname parts
))
569 (if (not part
) (error "Ambiguous partname"))) ; save-excursion
570 (setq cell-key
(concat file
":"))
571 (if (not (equal part
"")) (setq cell-key
(concat cell-key part
)))
572 (message "Assembling `%s' ..." cell-key
) ; (sleep-for 1)
573 (setq cell-buffer
(maxima-make-temp-name))
574 (setq emaxima-buffer-alist
(list (cons cell-key cell-buffer
)))
577 (emaxima-append-cell-to-buffer cell-buffer
)
578 (setq emaxima-source-buffer
(current-buffer)) ; Collate from here
579 (if (< (emaxima-reference-count cell-buffer
) emaxima-max-references
)
580 ;; Build reference buffers as needed
581 (while (emaxima-dereference-buffer cell-key files parts nil
))
582 ;; Prebuild all reference buffers
583 (emaxima-collate-cells file part files parts nil
)
584 (while (emaxima-dereference-buffer cell-key files parts nil
)))
585 (set-buffer cell-buffer
)
586 (write-file (concat emaxima-temp-dir cell-buffer
))
587 (set-buffer home-buffer
))
588 ;; unwind-protect forms: deleted cell buffers
589 (setq tmp-alist emaxima-buffer-alist
)
590 (while (setq tmp-buffer
(cdr (car tmp-alist
)))
591 (setq tmp-alist
(cdr tmp-alist
))
592 (condition-case nil
; In case buffer not actually created
593 (if (and (not delete
) (equal tmp-buffer cell-buffer
))
594 nil
; Don't delete the assembly buffer
595 (kill-buffer tmp-buffer
))
596 (error nil
)))) ; unwind-protect
597 (message "`%s' assembled in file `%s%s'"
598 cell-key emaxima-temp-dir cell-buffer
)
599 (concat emaxima-temp-dir cell-buffer
)))
601 (defun emaxima-assemble-package (&optional file overwrite
)
602 "Assemble text into a package buffer and write that buffer to a file.
603 The buffer is *not* deleted. Return the filename.
604 Optional arguments (useful for batch processing):
605 FILE package filename;
606 OVERWRITE, if not nil package filename buffer will be overwritten
608 ;; Here is how this function works:
610 ;; The entire buffer is scanned for marked cells matching TYPE and FILE and
611 ;; these are collated by `file' and `part' into buffers with keys
612 ;; `file:part' and, for `part' = "" (a package cell), into a buffer with key
615 ;; Once the cell buffers have been created, then all cell references in the
616 ;; package buffer, with key `FILE', are replaced by the contents of the
617 ;; corresponding buffers with keys `file:part', by successive calls to
618 ;; emaxima-dereference-buffer.
620 ;; The global `emaxima-buffer-alist' associates buffer names with keys.
621 ;; Buffer names are unique. The names of all buffers are constructed with
622 ;; `maxima-make-temp-name' and are unique. All buffers
623 ;; except the package buffer `FILE' are deleted on exit.
625 (let ((home-buffer (current-buffer))
627 tmp-buffer tmp-alist file-buffer
)
629 ;; If file has not been specified, prompt
631 ;; Get default file from cell label, if any
633 (goto-char (emaxima-cell-start))
635 (if (looking-at emaxima-package-cell-regexp
)
637 (setq emaxima-error-point
(point))
638 (unwind-protect ; In case filename errors
639 (if emaxima-abbreviations-allowed
640 ;; This can take some seconds
642 (message "Getting filenames...")
643 (if (not (setq files
(emaxima-get-filenames)))
645 "No complete package filenames found"))
647 (goto-char emaxima-error-point
))
648 (setq file
(emaxima-get-filename files
)))))
649 (setq file
(read-from-minibuffer "Package file: " file
))
650 (if (or (not file
) (equal file
""))
651 (error "No file specified"))))
653 (if (file-exists-p file
)
658 "' exists. Overwrite it ? "))
659 (if (not (y-or-n-p prompt
))
660 (error "Package assembly cancelled")))))
661 (if (get-buffer file
)
663 (if emaxima-abbreviations-allowed
664 ;; This can take several seconds for a document with many cells
666 (message "Getting partnames...")
667 (setq parts
(emaxima-get-partnames file files
))
669 (message "Assembling package `%s' ..." file
) ;(sleep-for 1)
670 ;; Set where assembly will occur
671 (setq file-buffer
(maxima-make-temp-name))
672 (setq emaxima-buffer-alist
(list (cons file file-buffer
)))
673 (unwind-protect ; So buffer can be deleted even if errors or abort
675 (setq emaxima-source-buffer
(current-buffer)) ; Collate from here
676 (emaxima-collate-cells file nil files parts nil
)
677 (or (get-buffer (cdr (assoc file emaxima-buffer-alist
)))
678 (error "No `%s' cell `%s:' found" file file
))
679 ;; OK, here we go: Recursively dereference the cell buffer:
680 (while (emaxima-dereference-buffer file files parts
))
681 (set-buffer file-buffer
)
683 (set-buffer home-buffer
))
684 ;; unwind-protect tail: Delete part files
685 (setq tmp-alist emaxima-buffer-alist
)
686 (while (setq tmp-buffer
(cdr (car tmp-alist
)))
687 (setq tmp-alist
(cdr tmp-alist
))
688 (condition-case nil
; In case buffer not actually created
689 (if (equal tmp-buffer file-buffer
)
690 nil
; Don't delete the package buffer
691 (kill-buffer tmp-buffer
))
692 (error nil
)))) ; unwind-protect
693 (message "Package `%s' assembled" file
)
695 (switch-to-buffer-other-window file
)))
697 (defun emaxima-reference-count (buffer)
698 "Return the number of references in BUFFER."
700 (home-buffer (current-buffer)))
703 (goto-char (point-min))
704 (while (re-search-forward "^ *\t*<[^:].*:[^>].*>$" (point-max) t
)
705 (setq count
(+ count
1)))
706 (set-buffer home-buffer
))
709 (defun emaxima-append-cell-to-buffer (buffer)
710 "Append text of cell containing point to BUFFER.
711 Create BUFFER if it does not exist."
712 (if (not (emaxima-cell-p))
713 (error "Not in a cell.")
714 (let ((home-buffer (current-buffer))
715 (start (emaxima-cell-start))
720 (while (looking-at "^ *$") (forward-line 1))
722 (if (not (setq end
(emaxima-output-p)))
724 (goto-char (emaxima-cell-end))
725 (while (looking-at "^ *$") (forward-line -
1))
730 (while (looking-at "^ *$") (forward-line -
1))
733 (set-buffer (get-buffer-create buffer
))
734 (goto-char (point-max))
735 (insert-buffer-substring home-buffer start end
)
738 (defun emaxima-collate-cells (file part files parts
&optional single
)
740 "Assemble cells marked with filename FILE in buffers with keys
741 `file:part' or, for part = null string (package cells), with key `file'. The
742 names of all buffers are constructed with `maxima-make-temp-name' and are
743 unique. If PART is non-nil then do not collate cells with keys `FILE:PART'
744 and `FILE' (package cells). Use FILES and PARTS for name completion \(see
745 `emaxima-get-filename' and `emaxima-get-partname'\). If optional SINGLE is
746 non-nil, then collate just cells `FILE:PART' (PART must be non-nil).
748 The global `emaxima-buffer-alist' associates buffer names with keys. It must
749 be initialized, typically with the buffer for key `FILE' or `FILE:PART',
750 according to whether PART is nil or not."
752 (let ((home-buffer (current-buffer))
753 this-part this-file key
)
754 (unwind-protect ; For error location
755 (setq emaxima-error-point
(point)) ; Go here if no error
757 ;; Scan buffer to construct buffers for all `file:part'
759 (set-buffer emaxima-source-buffer
) ; Collate from here
760 (goto-char (point-min))
761 (while (emaxima-forward-cell)
762 ;; We have a cell of the right type
763 (forward-line -
1) ; Move to \begin{...
764 (if (not (looking-at emaxima-package-cell-regexp
))
765 (forward-line 1) ; So we go to next cell next time through
766 ;; We have a marked cell
767 (setq this-file
(emaxima-get-filename files
))
770 (setq emaxima-error-point
(point))
771 (error "Ambiguous filename"))
772 ((not (equal file this-file
))
773 (forward-line 1)) ; So we go to next cell next time through
775 ;; We have a cell of the right package filename
776 (setq this-part
(emaxima-get-partname parts
))
779 (setq emaxima-error-point
(point))
780 (error "Ambiguous partname"))
781 ((and single
(not (equal this-part part
)))
782 (forward-line 1));Do only `file:part' for SINGLE non-nil
783 ((and part
(equal this-part
""))
784 (forward-line 1));Cell assembly,
785 ;ignore package cell `FILE:'
786 ((and (not single
) (equal this-part part
))
787 (forward-line 1));Cell assembly, ignore cell `FILE:PART'
789 ;; We have a cell with a valid partname
790 (forward-line 1) ; Move into cell
791 (if (equal this-part
"")
793 (setq key
(concat file
":" this-part
)))
795 (assoc key emaxima-buffer-alist
) ; buffer already created
796 (emaxima-replace-assoc
798 key
(maxima-make-temp-name)))
799 ;; Append cell contents to its buffer
800 (emaxima-append-cell-to-buffer
801 (cdr (assoc key emaxima-buffer-alist
)))
802 ) ; t on valid partname
804 ) ; t on right filename (package)
807 ) ; while still cells to process
808 (set-buffer home-buffer
)
810 ) ; progn of unwind-protect body
811 ;; unwind-protect tail: Delete part files
812 (goto-char emaxima-error-point
))))
814 (defun emaxima-dereference-buffer (key files parts
&optional noinit
)
815 "Resolve all references in buffer corresponding to KEY in alist
816 emaxima-buffer-alist, using FILES and PARTS for name completion. If optional
817 NOINIT is nil, initialize global variable `emaxima-dereference-path' with KEY.
818 If NOINIT is non-nil, add KEY to `emaxima-dereference-path'.
819 then references are collated in buffers and added to emaxima-buffer-alist if
820 necessary. Use `emaxima-dereference-path' to check for self-reference and
821 report error if detected,"
822 (let ((ref-found nil
)
823 (home-buffer (current-buffer))
825 ref-indent ref-key ref-buffer
826 (key-buffer (cdr (assoc key emaxima-buffer-alist
)))
829 (or key-buffer
(error "No cell `%s'" key
))
830 (set-buffer key-buffer
)
831 (goto-char (point-min))
835 (setq emaxima-dereference-path
(list key
)))
836 (setq path-to-here emaxima-dereference-path
)
837 (while (re-search-forward "^ *\t*<[^:].*:[^>].*>$" (point-max) t
)
840 (setq ref-indent
(emaxima-get-reference-indentation))
841 (setq file
(emaxima-get-filename files
))
842 (setq part
(emaxima-get-partname parts
))
843 (setq ref-key
(concat file
":" part
))
844 (if (emaxima-string-mem ref-key path-to-here
)
845 (emaxima-dereference-error (cons ref-key path-to-here
)))
846 (setq emaxima-dereference-path
(cons ref-key path-to-here
))
847 (if (not (assoc ref-key emaxima-buffer-alist
))
848 ;; Construct buffer on the fly
850 (setq ref-buffer
(maxima-make-temp-name))
851 (emaxima-replace-assoc emaxima-buffer-alist ref-key ref-buffer
)
852 (emaxima-collate-cells file part files parts t
))
853 (setq ref-buffer
(cdr (assoc ref-key emaxima-buffer-alist
))))
854 (while (emaxima-dereference-buffer ref-key files parts noinit
))
855 (kill-line 1) ; Remove reference line
856 (insert-buffer ref-buffer
)
857 (let ((indent-start (point))
859 (exchange-point-and-mark)
860 (setq indent-end
(point))
861 (exchange-point-and-mark)
862 (if ref-indent
(indent-rigidly indent-start indent-end ref-indent
))))
863 (setq emaxima-dereference-path path-to-here
)
864 (set-buffer home-buffer
)
867 (defun emaxima-dereference-error (path)
868 "Report package self-reference error, in PATH"
869 (let ((cell (car path
))
870 (home-buffer (current-buffer))
873 (with-output-to-temp-buffer "*Help*" (message ""))
874 (pop-to-buffer "*Help*")
875 (insert "Self-reference detected assembling EMaxima cell\n\n")
876 (insert (concat "\t\t" to-cell
"\n\n"))
877 (insert "Here is how the self-reference happened:\n\n")
878 (setq path
(reverse path
))
879 (setq from-cell
(car path
))
880 (insert (concat "\t" from-cell
"\n"))
881 (while (setq path
(cdr path
))
882 (setq to-cell
(car path
))
883 (if (equal cell to-cell
)
884 (insert (concat " !!! ->\t -->\t" to-cell
"\n"))
885 (insert (concat "\t -->\t" to-cell
"\n")))
886 (setq from-cell to-cell
))
887 (pop-to-buffer home-buffer
)
888 (error "Self-reference detected")))
890 (defun emaxima-get-reference-indentation ()
891 "Return indentation of reference on current line.
892 Line assumed tabified."
898 (untabify start
(point))
904 (defun emaxima-insert-complete-name ()
905 "Insert complete name in buffer for cell.
906 Return t if successful, else nil."
909 start end name text files parts
)
916 (concat emaxima-standard-cell-begin-regexp
"\\[.*:[^\t]*") here t
)
917 (re-search-forward "^[ \t]*<.*:[^\t]*" here t
))
918 (equal here
(point)))
919 ;; This can take a second or two
920 (message "Getting filenames...")
921 (if (not (setq files
(emaxima-get-filenames)))
922 (error "No package filenames in document"))
924 (search-backward "[") ;; Look here
929 (setq text
(buffer-substring start
(point)))
930 (if (not (setq name
(emaxima-complete-name text files
)))
931 (error "No matching package filename found"))
932 ;; This can take several seconds for a document with many cells
933 (message "Getting partnames")
934 (setq parts
(emaxima-get-partnames name files
))
937 (setq start
(point)) ; New start, for partname deletion
938 (setq text
(buffer-substring (point) here
))
939 (if (not (setq name
(emaxima-complete-name
942 (error "No matching package partname found"))
944 ((equal t name
) ; Text is complete
946 ((equal t
(try-completion name parts
)))
947 (t ; Else, get completion
950 "Partname (<space> to see partnames): "
951 parts nil t name
)))) ; cond: what kind of partname completion was done
952 (delete-region start here
)
953 (insert (concat name
"]"))) ; End of partname completion
955 (or (re-search-forward
956 (concat emaxima-standard-cell-begin-regexp
"\\[[^ \t]*" here t
))
957 (re-search-forward "^[ \t]*<[^ \t]*" here t
))
958 (equal here
(point)))
959 ;; This can take a second or two
960 (message "Getting filenames...")
961 (if (not (setq files
(emaxima-get-filenames)))
962 (error "No package filenames in document"))
964 (re-search-backward "\\[\\|<") ;;xxx
967 (setq text
(buffer-substring start here
))
968 (if (not (setq name
(emaxima-complete-name
969 (concat text
"...") ; completion form
971 (error "No matching package filename found"))
973 ((equal t name
) ; Text is complete
975 ((equal t
(try-completion name files
)))
976 (t ; Else, get completion
979 "Filename (<space> to see filenames): "
981 (if (equal "" name
) (error ""))))
982 (delete-region start here
)
983 (insert (concat name
":")))
985 ;;(error "Nothing to complete")
986 nil
))) ; save-excursion
989 (goto-char (+ (point) (length name
) 1))
992 (defun emaxima-get-filenames ()
993 "Return alist of package filenames for cells."
996 (goto-char (point-min))
997 (while (emaxima-forward-cell)
999 (if (not (looking-at emaxima-package-cell-regexp
))
1000 (forward-line 1) ; Cell not marked. Get set for next one
1001 (if (setq file
(emaxima-get-filename)) ; Only unabbreviated names
1003 (if (assoc file files
)
1005 (setq files
(cons (list file
) files
))) ; Add to alist
1006 (setq files
(list (list file
))))) ; Start alist
1007 (forward-line 1)) ; if a marked cell
1008 ) ; while cell to look at
1012 (defun emaxima-complete-name (text alist
&optional exact
)
1013 "Get full name corresponding to TEXT.
1014 If text is a string ending in `...',
1015 then the substring preceding the `...' is used with try-completion on ALIST.
1016 An exact match is required if optional EXACT is t.
1017 If text is just `...' and alist is length 1, then the car of its single element
1019 Otherwise nil is returned."
1020 (let (name try-name
)
1021 (if (not (string-match "\\(\\.\\.\\.$\\)" text
))
1022 (setq name text
) ; don't do completion on full names
1024 (eq 0 (match-beginning 1)) ; just "..."
1025 (eq 1 (length alist
))) ; a single package filename
1026 (setq name
(car (car alist
)))
1027 (setq try-name
(substring text
0 (match-beginning 1)))
1028 (setq name
(try-completion try-name alist
)))
1031 (setq name try-name
))
1034 (not (equal t
(try-completion name alist
))))
1035 (setq name nil
)))) ; Not an exact match, so error
1038 (defun emaxima-get-partnames (file files
)
1039 "Return alist of partnames for package FILE, using FILES for
1040 filename completion."
1041 (let (cell-end cell-file part parts
)
1042 (setq emaxima-error-point
(point))
1045 (goto-char (point-min))
1046 (while (emaxima-forward-cell)
1047 (setq cell-end
(emaxima-cell-end))
1049 (if (not (looking-at
1050 (concat emaxima-standard-cell-begin-regexp
"\\[[^:].*:.*\\]")))
1051 (forward-line 1) ; Not a marked cell
1052 (setq cell-file
(emaxima-get-filename files
))
1053 (if (not (equal file cell-file
))
1054 (forward-line 1) ; Wrong file
1056 (<= (point) cell-end
)
1059 (concat emaxima-standard-cell-begin-regexp
1060 "\\[[^:].*:.*\\]") cell-end t
)
1062 "^ *\t*<[^:].*:.*>" cell-end t
)))
1063 (beginning-of-line) ; We have a filename-partname reference
1064 (if (not (setq file
(emaxima-get-filename files
)))
1066 (setq emaxima-error-point
(point))
1067 (error "Ambiguous filename")))
1068 (if (not (equal cell-file file
))
1070 (setq emaxima-error-point
(point))
1071 (error "Reference must match cell filename: `%s'"
1073 (setq part
(emaxima-get-partname))
1075 nil
; Need full (unabbreviated) parts only, for alist
1076 (if parts
; Update alist
1079 (emaxima-string-mem part parts
))
1080 nil
; already on list
1081 (setq parts
(append (list part
) parts
)))
1083 (if (not (equal part
""))
1084 (setq parts
(list part
)))) ; Create alist
1085 ) ; if an unabbreviated part
1087 ) ; while references to process in this cell
1088 ) ; if a marked cell of this FILE
1089 ) ; if a marked cell
1090 ) ; while cells to process
1092 (goto-char emaxima-error-point
) ; unwind-protect form
1094 (setq parts
(mapcar 'list parts
)) ; Make list into an alist
1097 (defun emaxima-get-filename (&optional alist
)
1098 "Get filename in package reference on current line.
1099 If optional ALIST is supplied, use it for name completion.
1100 Return nil if no name or error in name."
1101 (let ((match-re "\\(\\[\\|<\\)[^:]*\\(:\\)")
1102 (abbrev-re "\\.\\.\\.")
1108 (setq text
(buffer-substring beg
(point)))
1109 (string-match match-re text
)
1111 (substring text
(+ 1 (match-beginning 1)) (+ -
1 (match-end 2)))))
1113 (emaxima-complete-name text alist t
)
1114 (if (string-match abbrev-re text
)
1115 (if emaxima-abbreviations-allowed
1117 (setq emaxima-error-point
(point))
1119 "Set emaxima-abbreviations-allowed (M-x set-variable) to use abbreviations"))
1122 (defun emaxima-get-partname (&optional alist
)
1123 "Get partname in package reference on current line.
1124 If optional ALIST is supplied, use it for name completion.
1125 Return nil if no name or error in name."
1126 (let ((match-re "\\(:\\)\\([^]>]*\\)")
1127 (abbrev-re "\\.\\.\\.")
1133 (setq text
(buffer-substring beg
(point)))
1134 (string-match match-re text
)
1135 (setq text
(substring text
(+ 1 (match-beginning 1)) (match-end 2))))
1137 (emaxima-complete-name text alist t
)
1138 (if (string-match abbrev-re text
)
1139 (if emaxima-abbreviations-allowed
1141 (setq emaxima-error-point
(point))
1143 "Set emaxima-abbreviations-allowed (M-x set-variable) to use abbreviations"))
1146 (defun emaxima-string-mem (element list
) ; memq doesn't work for strings
1147 "Returns t if string ELEMENT is in LIST of strings, else returns nil."
1150 (while (and (setq try
(car list
)) (not found
))
1151 (setq list
(cdr list
))
1152 (if (equal element try
)
1156 (defun emaxima-reference-p ()
1157 "Return t if cell contains a cell reference, else return nil."
1159 (goto-char (emaxima-cell-start))
1160 (if (re-search-forward "^ *\t*<[^:].*:[^>].*>$" (emaxima-cell-end) t
)
1165 ;;; Get information about the cell input and output
1167 (defun emaxima-get-cell-contents ()
1168 "Return the cell contents as a string."
1169 (if (not (emaxima-cell-p))
1170 (message "Not in Maxima cell"))
1171 (let ((home-buffer (current-buffer))
1172 assembled-file start end
)
1173 (if (emaxima-reference-p)
1175 (widen) ; So cell references will be found
1176 (set-buffer (find-file-noselect
1177 (emaxima-assemble-cell t
)))
1178 (buffer-substring-no-properties (point-min) (point-max)))
1180 (goto-char (emaxima-cell-start))
1181 ;; Now I want to skip over any blank lines at the beginning of the cell
1183 (while (looking-at "^ *$") (forward-line 1))
1184 (setq start
(point))
1185 ;; as well as at the end of the cell
1186 (if (not (setq end
(emaxima-output-p)))
1188 (goto-char (emaxima-cell-end))
1189 (while (looking-at "^ *$") (forward-line -
1))
1194 (while (looking-at "^ *$") (forward-line -
1))
1196 (setq end
(point)))))
1197 (buffer-substring-no-properties start end
))))
1199 (defun emaxima-fix-tex-output (string)
1200 (maxima-replace-in-string ":=" "\\\\mathbin{:=}" string
))
1202 (defun emaxima-insert-preoutput (string &optional strip
)
1203 (if (and (> (length string
) 1)
1204 (string= "$$" (substring string
0 2)))
1207 (insert (emaxima-fix-tex-output string
) "\n" ))
1209 (setq string
(maxima-strip-string-end string
)))
1212 (insert " \\\\\n")))
1214 (defun emaxima-insert-last-output-tex ()
1218 (out (maxima-strip-string (maxima-last-output))))
1219 (while (string-match (concat "(" maxima-linechar
"[0-9]+)") out
)
1220 (setq mb
(match-beginning 0))
1221 (setq me
(match-end 0))
1223 (emaxima-insert-preoutput (substring out
0 mb
)))
1225 (insert (substring out
(+ mb
3) (- me
1)))
1227 (setq out
(maxima-strip-string-beginning (substring out me
)))
1229 (concat "(\\(" maxima-outchar
"\\|" maxima-linechar
"\\)[0-9]+)") out
)
1230 (setq ie
(match-beginning 0))
1231 (insert (emaxima-fix-tex-output
1232 (maxima-strip-string-end (substring out
0 ie
))))
1234 (setq out
(maxima-strip-string-beginning (substring out ie
))))
1235 (if (string-match (concat "(" maxima-outchar
"[0-9]+)") out
)
1237 (setq mb
(match-beginning 0))
1238 (setq me
(match-end 0))
1240 (emaxima-insert-preoutput (substring out
0 mb
) t
))
1242 (insert (substring out
(+ mb
3 ) (- me
1)))
1243 ; (insert (substring out (+ mb (1+ (length maxima-outchar))) (- me 1)))
1245 (insert (emaxima-fix-tex-output
1246 (maxima-strip-string (substring out me
))))
1248 (when (not (string= out
""))
1249 (emaxima-insert-preoutput out
)))))
1251 (defun emaxima-insert-last-output-tex-noprompt ()
1252 (let ((out (maxima-strip-string (maxima-last-output)))
1256 (while (string-match (concat "(" maxima-linechar
"[0-9]+)") out
)
1257 (setq mb
(match-beginning 0))
1258 (setq me
(match-end 0))
1260 (emaxima-insert-preoutput (substring out
0 mb
)))
1262 (insert (substring out
(+ mb
3) (- me
1)))
1264 (setq out
(maxima-strip-string-beginning (substring out me
)))
1266 (concat "(\\(" maxima-outchar
"\\|" maxima-linechar
"\\)[0-9]+)") out
)
1267 (setq ie
(match-beginning 0))
1268 (insert (emaxima-fix-tex-output
1269 (maxima-strip-string-end (substring out
0 ie
))))
1271 (setq out
(substring out ie
)))
1272 (if (string-match (concat "(" maxima-outchar
"[0-9]+)") out
)
1274 (setq mb
(match-beginning 0))
1275 (setq me
(match-end 0))
1277 (emaxima-insert-preoutput (substring out
0 mb
) t
))
1278 (setq out
(maxima-strip-string-beginning (substring out me
)))
1281 (insert (emaxima-fix-tex-output out
));(substring out me))
1283 (when (not (string= out
""))
1284 (emaxima-insert-preoutput out
)))))
1286 (defun emaxima-last-input-prompt ()
1287 "Copy the last input-prompt from Maxima."
1288 (let ((old-buffer (current-buffer))
1289 (maxima-buffer (get-buffer "*maxima*"))
1291 (if (null maxima-buffer
)
1292 (message "No Maxima output buffer")
1293 (set-buffer maxima-buffer
)
1295 (goto-char (point-max))
1296 (if (not (inferior-maxima-running))
1297 (re-search-backward inferior-maxima-prompt
(point-min) nil
1)
1298 (re-search-backward inferior-maxima-prompt
(point-min) nil
2))
1300 (buffer-substring-no-properties
1301 (match-beginning 0) (- (match-end 0) 1))))
1302 (set-buffer old-buffer
)
1305 ;;; Update the different cell types
1307 (defun emaxima-get-lisp-end (string)
1308 (let* ((tmpfile (maxima-make-temp-name))
1309 (tmpbuf (get-buffer-create tmpfile
))
1313 (maxima-remove-kill-buffer-hooks)
1315 (goto-char (point-min))
1316 (search-forward ":lisp")
1318 (setq end
(- (point) 1)))
1319 (kill-buffer tmpbuf
)
1322 (defun emaxima-get-form-end (string)
1323 (let* ((tmpfile (maxima-make-temp-name))
1324 (tmpbuf (get-buffer-create tmpfile
))
1328 (maxima-remove-kill-buffer-hooks)
1330 (goto-char (point-min))
1331 (maxima-goto-end-of-form)
1332 (setq end
(- (point) 1)))
1333 (kill-buffer tmpbuf
)
1336 (defun emaxima-update-cell ()
1337 "Send the current cell's contents to Maxima, and return the results."
1339 ((emaxima-standard-cell-p)
1340 (emaxima-update-standard-cell))
1341 ((emaxima-session-cell-p)
1342 (emaxima-update-session-cell)))
1343 (if (emaxima-empty-output-p)
1344 (emaxima-delete-output)))
1346 (defun emaxima-tex-update-cell ()
1347 "Send the current cell's contents to Maxima, and return the results."
1349 ((emaxima-standard-cell-p)
1350 (emaxima-tex-update-standard-cell))
1351 ((emaxima-session-cell-p)
1352 (emaxima-tex-update-session-cell)))
1353 (if (emaxima-empty-output-p)
1354 (emaxima-delete-output)))
1356 (defun emaxima-update-standard-cell ()
1357 "Send the current cell's contents to Maxima, and return the results."
1358 (emaxima-delete-output)
1360 (cell (emaxima-get-cell-contents)))
1361 (goto-char (emaxima-cell-end))
1363 (insert "\\maximaoutput\n")
1365 (string-match "[$;]" cell
)
1366 (eq (string-match "[ \n]*:lisp" cell
) 0))
1367 (if (eq (string-match "[ \n]*:lisp" cell
) 0)
1368 (setq end
(emaxima-get-lisp-end cell
))
1369 (setq end
(emaxima-get-form-end cell
)))
1370 (maxima-single-string-wait (substring cell
0 end
))
1371 (setq cell
(substring cell end
))
1372 (let ((mlon (maxima-last-output-noprompt)))
1373 (unless (= (length (maxima-strip-string mlon
)) 0)
1376 (defun emaxima-tex-update-standard-cell ()
1377 "Send the current cell's contents to Maxima, and return the results."
1378 (emaxima-delete-output)
1380 (cell (emaxima-get-cell-contents)))
1381 (goto-char (emaxima-cell-end))
1383 (insert "\\maximaoutput*\n")
1385 (string-match "[$;]" cell
)
1386 (eq (string-match "[ \n]*:lisp" cell
) 0))
1387 (if (eq (string-match "[ \n]*:lisp" cell
) 0)
1388 (setq end
(emaxima-get-lisp-end cell
))
1389 (setq end
(emaxima-get-form-end cell
)))
1390 (if (and emaxima-tex-lisp-file
(not (inferior-maxima-running)))
1392 (maxima-single-string-wait (substring cell
0 end
))
1393 (setq cell
(substring cell end
))
1394 (emaxima-insert-last-output-tex-noprompt))))
1396 (defun emaxima-update-session-cell ()
1397 "Send the current cell's contents to Maxima, and return the results."
1399 (emaxima-delete-output)
1401 (cell (emaxima-get-cell-contents)))
1402 (goto-char (emaxima-cell-end))
1404 (insert "\\maximaoutput\n")
1406 (string-match "[$;]" cell
)
1407 (eq (string-match "[ \n]*:lisp" cell
) 0))
1408 (if (eq (string-match "[ \n]*:lisp" cell
) 0)
1409 (setq end
(emaxima-get-lisp-end cell
))
1410 (setq end
(emaxima-get-form-end cell
)))
1411 (maxima-single-string-wait (substring cell
0 end
))
1412 (insert (emaxima-last-input-prompt))
1414 (while (or (string= "\n" (substring cell
0 1))
1415 (string= " " (substring cell
0 1)))
1416 (setq cell
(substring cell
1))
1417 (setq end
(- end
1)))
1418 (insert (substring cell
0 end
))
1419 (unless (string= "\n" (substring cell
(- end
1) end
))
1421 (insert (maxima-last-output))
1422 (setq cell
(substring cell end
))))))
1424 (defun emaxima-tex-update-session-cell ()
1425 "Send the current cell's contents to Maxima, and return the results."
1426 (if (not emaxima-tex-lisp-file
)
1427 (emaxima-update-session-cell)
1429 (emaxima-delete-output)
1432 (cell (emaxima-get-cell-contents)))
1433 (goto-char (emaxima-cell-end))
1435 (insert "\\maximaoutput*\n")
1437 (string-match "[$;]" cell
)
1438 (eq (string-match "[ \n]*:lisp" cell
) 0))
1439 (if (eq (string-match "[ \n]*:lisp" cell
) 0)
1440 (setq end
(emaxima-get-lisp-end cell
))
1441 (setq end
(emaxima-get-form-end cell
)))
1442 (if (and emaxima-tex-lisp-file
(not (inferior-maxima-running)))
1444 (maxima-single-string-wait (substring cell
0 end
))
1445 (while (or (string= "\n" (substring cell
0 1))
1446 (string= " " (substring cell
0 1)))
1447 (setq cell
(substring cell
1))
1448 (setq end
(- end
1)))
1450 (insert (substring (emaxima-last-input-prompt)
1452 ; (1+ (length maxima-inchar)) -1))
1454 ; (insert (maxima-replace-in-string "\\$" "\\\\$" (substring cell 0 end)))
1455 (insert (substring cell
0 end
))
1457 (unless (string= "\n" (substring cell
(- end
1) end
))
1460 (emaxima-insert-last-output-tex)
1461 (setq cell
(substring cell end
)))))))
1463 ;;; Update the different groups
1465 (defun emaxima-update-all-cells (arg)
1466 "Optionally update all cells.
1467 With C-u prefix, update without confirmation at each cell."
1475 (goto-char (point-min))
1476 (while (emaxima-forward-cell t
)
1477 (if (or ask
(y-or-n-p "Update this cell? "))
1478 (emaxima-update-cell))))
1479 (if (and emaxima-preview-after-update-all
1480 (fboundp 'preview-buffer
))
1484 (defun emaxima-tex-update-all-cells (arg)
1485 "Optionally update all cells.
1486 With C-u prefix, update without confirmation at each cell."
1489 (if (not emaxima-tex-lisp-file
)
1490 (error "File `emaxima.lisp' not found in Emacs load path.")
1497 (goto-char (point-min))
1498 (while (emaxima-forward-cell)
1499 (if (or ask
(y-or-n-p "Update this cell? "))
1500 (emaxima-tex-update-cell))))
1502 (if (and emaxima-preview-after-update-all
1503 (fboundp 'preview-buffer
))
1506 (defun emaxima-update-session-cells (arg)
1507 "Optionally update all session cells.
1508 With C-u prefix, update without confirmation at each cell."
1516 (goto-char (point-min))
1517 (while (emaxima-forward-cell)
1519 (emaxima-session-cell-p)
1520 (or ask
(y-or-n-p "Update this cell? ")))
1521 (emaxima-update-session-cell))))
1522 (if (and emaxima-preview-after-update-all
1523 (fboundp 'preview-buffer
))
1527 (defun emaxima-tex-update-session-cells (arg)
1528 "Optionally update all cells.
1529 With C-u prefix, update without confirmation at each cell."
1532 (if (not emaxima-tex-lisp-file
)
1533 (error "File `emaxima.lisp' not found in Emacs load path.")
1540 (goto-char (point-min))
1541 (while (emaxima-forward-cell)
1543 (emaxima-session-cell-p)
1544 (or ask
(y-or-n-p "Update this cell? ")))
1545 (emaxima-tex-update-session-cell))))
1547 (if (and emaxima-preview-after-update-all
1548 (fboundp 'preview-buffer
))
1551 (defun emaxima-update-single-cell ()
1552 "Send the current cell's contents to Maxima, and return the results."
1557 ((emaxima-standard-cell-p)
1558 (emaxima-update-standard-cell)
1559 (if (emaxima-empty-output-p)
1560 (emaxima-delete-output)))
1561 ((emaxima-session-cell-p)
1562 (emaxima-update-session-cell)
1563 (if (emaxima-empty-output-p)
1564 (emaxima-delete-output)))
1566 (error "Not in a cell.")))))
1568 (defun emaxima-tex-update-single-cell ()
1569 "Send the current cell's contents to Maxima, and return the results."
1572 (if (not emaxima-tex-lisp-file
)
1573 (error "File `emaxima.lisp' not found in Emacs load path.")
1576 ((emaxima-standard-cell-p)
1578 (emaxima-tex-update-standard-cell)
1580 (if (emaxima-empty-output-p)
1581 (emaxima-delete-output)))
1582 ((emaxima-session-cell-p)
1584 (emaxima-tex-update-session-cell)
1586 (if (emaxima-empty-output-p)
1587 (emaxima-delete-output)))
1589 (error "Not in a cell."))))))
1591 (defun emaxima-replace-line-with-tex ()
1592 "Sends the current line to Maxima, and then replaces it with the Maxima
1593 output in TeX form."
1595 (if (not emaxima-tex-lisp-file
)
1596 (error "File `emaxima.lisp' not found in Emacs load path.")
1599 (maxima-single-string-wait
1600 (buffer-substring-no-properties
1601 (maxima-line-beginning-position) (maxima-line-end-position)))
1606 (emaxima-insert-last-output-tex-noprompt)
1609 (defun emaxima-replace-line ()
1610 "Sends the current line to Maxima, and then replaces it with the Maxima
1614 (maxima-single-string-wait
1615 (buffer-substring-no-properties
1616 (maxima-line-beginning-position) (maxima-line-end-position)))
1621 (insert (maxima-last-output-noprompt)))
1623 ;;; The following section adds a command which will comment out all the
1624 ;;; cells, and replace them by a more-or-less LaTeX equivalent.
1625 ;;; Very preliminary
1627 (defun emaxima-tex-up-standard-cell (string)
1628 (let* ((tmpfile (maxima-make-temp-name))
1629 (tmpbuf (get-buffer-create tmpfile
))
1633 (maxima-remove-kill-buffer-hooks)
1635 ;; Replace beginning \maxima with \begin{verbatim}
1636 (goto-char (point-min))
1638 (insert "\\begin{verbatim}")
1639 ;; Take care of the output
1640 (if (re-search-forward "^\\\\maximaoutput" nil t
)
1643 (if (not (looking-at "\\\\maximaoutput\\*"))
1646 (insert "\\end{verbatim}\n")
1647 (insert emaxima-output-marker
"\n")
1648 (insert "\\begin{verbatim}")
1649 (re-search-forward emaxima-standard-cell-end-regexp
)
1652 (insert "\\end{verbatim}\n")
1653 (insert "%% End of cell\n"))
1654 ;; Else, in a TeX cell
1656 (insert "\\end{verbatim}\n")
1657 (insert emaxima-output-marker
"\\\\")
1659 ;; First, for the standard cells
1660 ;; Get rid of the \os
1661 (while (re-search-forward "^\\\\o" nil t
)
1662 (delete-region (line-beginning-position) (point))
1664 (search-forward "\\\\")
1667 ;; Next, get rid of the \Es
1669 (while (re-search-forward "^\\\\t[^N]" nil t
)
1670 (delete-region (line-beginning-position) (point))
1672 (search-forward ".")
1675 (search-forward "\\\\")
1678 ;; Next, get rid of the \ms
1680 (while (re-search-forward "^\\\\m" nil t
)
1681 (delete-region (line-beginning-position) (point))
1683 (search-forward "\\\\")
1686 ;; Finally, get rid of the \ps
1688 (while (re-search-forward "^\\\\p" nil t
)
1689 (delete-region (line-beginning-position) (point))
1690 (insert "\\begin{verbatim}")
1691 (search-forward "\\\\")
1693 (insert "\n\\end{verbatim}"))
1694 (re-search-forward emaxima-standard-cell-end-regexp
)
1697 (insert "%% End of cell\n"))))
1699 (re-search-forward emaxima-standard-cell-end-regexp
)
1702 (insert "\\end{verbatim}\n")
1703 (insert "%% End of cell\n"))
1704 (setq string
(buffer-substring-no-properties (point-min) (point-max))))
1705 (kill-buffer tmpbuf
)
1708 (defun emaxima-tex-up-session-cell (string)
1709 (let* ((tmpfile (maxima-make-temp-name))
1710 (tmpbuf (get-buffer-create tmpfile
))
1714 (maxima-remove-kill-buffer-hooks)
1715 ; (make-local-hook 'kill-buffer-hook)
1716 ; (setq kill-buffer-hook nil)
1718 (goto-char (point-min))
1719 ;; Take care of the output
1720 (if (re-search-forward "^\\\\maximaoutput" nil t
)
1723 (delete-region (point-min) (point))
1724 (if (not (looking-at "\\\\maximaoutput\\*"))
1727 (insert "\\begin{verbatim}")
1728 (re-search-forward emaxima-session-cell-end-regexp
)
1731 (insert "\\end{verbatim}\n")
1732 (insert "%% End of cell"))
1733 ;; Else, in a TeX cell
1735 (insert "\\noindent\n")
1736 ;; First, take care of the Cs
1737 (while (re-search-forward "^\\\\i" nil t
)
1738 (delete-region (line-beginning-position) (point))
1739 (insert "\\begin{verbatim}\n")
1741 (search-forward ".")
1744 (search-forward "\\\\")
1746 (insert "\n\\end{verbatim}"))
1747 ;; Next, get rid of the \os
1748 (goto-char (point-min))
1749 (while (re-search-forward "^\\\\o" nil t
)
1750 (delete-region (line-beginning-position) (point))
1751 (insert "\\verb+(%o")
1752 (search-forward ".")
1755 (search-forward "\\\\")
1758 ;; Next, get rid of the \ts
1759 (goto-char (point-min))
1760 (while (re-search-forward "^\\\\t[^N]" nil t
)
1761 (delete-region (line-beginning-position) (point))
1762 (insert "\verb+(%t")
1763 (search-forward ".")
1766 (search-forward "\\\\")
1769 ;; Finally, get rid of the \ps
1770 (goto-char (point-min))
1771 (while (re-search-forward "^\\\\p" nil t
)
1772 (delete-region (line-beginning-position) (point))
1773 (insert "\\begin{verbatim}")
1774 (search-forward "\\\\")
1776 (insert "\n\\end{verbatim}"))
1777 (re-search-forward emaxima-session-cell-end-regexp
)
1780 (insert "%% End of cell\n")))
1783 (insert "%% End of cell\n"))
1784 (setq string
(buffer-substring-no-properties (point-min) (point-max))))
1785 (kill-buffer tmpbuf
)
1788 (defun emaxima-tex-up-starred-cell (string)
1789 (let* ((tmpfile (maxima-make-temp-name))
1790 (tmpbuf (get-buffer-create tmpfile
))
1794 (maxima-remove-kill-buffer-hooks)
1796 (goto-char (point-min))
1797 (re-search-forward emaxima-any-cell-begin-regexp
)
1798 (replace-match "\\begin{comment}")
1799 (re-search-forward emaxima-any-cell-end-regexp
)
1800 (replace-match "\\end{comment}")
1801 (setq string
(buffer-substring-no-properties (point-min) (point-max))))
1802 (kill-buffer tmpbuf
)
1805 (defun emaxima-replace-cells-by-latex ()
1811 (goto-char (point-min))
1812 (while (emaxima-forward-cell)
1813 (if (get-char-property (point) 'preview-state
)
1814 (preview-clearout-at-point))
1818 ((emaxima-starred-cell-p)
1819 (re-search-forward emaxima-any-cell-end-regexp
)
1821 (setq cell
(buffer-substring-no-properties beg end
))
1822 (comment-region beg end
)
1824 (insert (emaxima-tex-up-starred-cell cell
)))
1825 ((emaxima-session-cell-p)
1826 (re-search-forward emaxima-any-cell-end-regexp
)
1828 (setq cell
(buffer-substring-no-properties beg end
))
1829 (comment-region beg end
)
1831 (insert (emaxima-tex-up-session-cell cell
)))
1833 (re-search-forward emaxima-any-cell-end-regexp
)
1835 (setq cell
(buffer-substring-no-properties beg end
))
1836 (comment-region beg end
)
1838 (insert (emaxima-tex-up-standard-cell cell
))))))))
1840 ;;; Some preview abilities
1841 (defun emaxima-preview-cell ()
1842 "Previews the current cell in the emacs buffer."
1844 (if (not (emaxima-cell-p))
1845 (error "Not in an Emaxima cell")
1846 (if (emaxima-starred-cell-p)
1847 (message "Starred cell")
1849 (goto-char (emaxima-cell-start))
1852 (search-forward emaxima-any-cell-end-regexp
)
1854 (preview-region beg
(point))))))
1856 ;; The following doesn't work yet...
1858 (defun emaxima-preview-cells ()
1859 "Previews all cells in the emacs buffer."
1861 (while (emaxima-forward-cell)
1862 (emaxima-preview-cell)))
1864 ;; First, find out what kind of TeX mode is being used.
1867 ((eq emaxima-use-tex
'auctex
)
1869 ;; I don't think this is the best thing to do...
1871 (defun texmode () (latex-mode)))
1872 ((eq emaxima-use-tex
'tex
)
1874 (defun texmode () (tex-mode)))
1876 (autoload 'text-mode
"text-mode")
1877 (defun texmode () (text-mode))))
1879 ;; ;;; A function for font-locking
1880 ;; (defun emaxima-match-cells (limit)
1881 ;; "Used to fontify whatever's between \\beginmaxima and \\endmaxima."
1882 ;; (when (re-search-forward "\\\\beginmaxima"
1884 ;; (let ((beg (match-end 0)) end)
1885 ;; (if (search-forward "\\endmaxima"
1887 ;; (setq end (match-beginning 0))
1888 ;; (setq end (point)))
1889 ;; (store-match-data (list beg end))
1892 (define-derived-mode emaxima-mode texmode
"EMaxima"
1893 "This is a mode intended to allow the user to write documents that
1894 include Maxima code. The file can be LaTeXed to produce nice
1895 looking output (although that isn't necessary, of course), and so the
1896 mode is an extension of texmode (AucTeX).
1897 The units of Maxima code that are worked with are \"cells\", which are
1898 delimited by \"\\beginmaxima\" and \"\\endmaxima\". The cells can be evaluated
1899 individually, as a group, and the output can be returned as Maxima output
1900 or in TeX form. Evaluating a cell and returning the output is called
1901 \"updating\" the cell. This mode also supports some literate programming
1902 constructs. (See the file \"EMaximaIntro.tex\" for more
1904 The commands for working with cells are:
1905 \\[emaxima-create-standard-cell] create a cell
1906 \\[emaxima-update-all-cells] update all the cells
1907 \\[emaxima-tex-update-all-cells] update all the cells in TeX form
1908 \\[emaxima-forward-cell] go to the next cell
1909 \\[emaxima-backward-cell] go to the previous cell
1911 \(With a prefix, C-u \\[emaxima-update-all-cells] and C-u \\[emaxima-tex-update-all-cells] will update the cells
1913 Since the Maxima output can be returned to the EMaxima buffer,
1914 the buffer which runs the Maxima process is not shown.
1916 Single lines can be evaluated:
1917 \\[emaxima-replace-line] replace the current line with Maxima output
1918 \\[emaxima-replace-line-with-tex] replace the current line with Maxima output in TeX form.
1920 Within a cell, the following commands are available:\\<emaxima-maxima-map>
1921 \\[emaxima-delete-output] delete the cell's output
1922 \\[emaxima-update-cell] update a cell
1923 \\[emaxima-tex-update-cell] update a cell in TeX form
1924 \\[emaxima-assemble] assemble a cell which defines a package
1925 C-u \\[emaxima-assemble] assemble a cell with references
1927 Finally, the command \\[emaxima-mark-file-as-emaxima] will insert a
1928 %-*-EMaxima-*- at the beginning of the file (if there isn't one there
1929 already) so the file will begin in emaxima-mode next time it's opened.
1931 \\{emaxima-mode-map}
1933 (when (or (eq emaxima-use-tex
'auctex
) (eq emaxima-use-tex
'tex
))
1934 (make-local-variable 'ispell-parser
)
1935 (setq ispell-parser
'tex
)
1936 (make-local-variable 'ispell-tex-p
)
1937 (setq ispell-tex-p t
))
1938 (when (eq emaxima-use-tex
'auctex
)
1939 (make-local-variable 'TeX-auto-untabify
)
1940 (setq TeX-auto-untabify t
))
1941 (make-local-variable 'texmathp-tex-commands
)
1942 (setq texmathp-tex-commands
1943 '(("\\endmaxima" sw-off
)))
1944 (when (eq emaxima-use-tex
'auctex
)
1945 (require 'font-latex
)
1946 (when emaxima-use-emaxima-indent
1947 (make-local-variable 'indent-line-function
)
1948 (setq indent-line-function
'emaxima-indent-line
)))
1950 ;; (defvar emaxima-keywords
1951 ;; (append font-latex-keywords-2
1952 ;; '((emaxima-match-cells (0 font-lock-function-name-face t t))
1953 ;; ("\\(\\\\\\(beginmaxima\\(?:noshow\\|session\\)?\\|endmaxima\\(?:noshow\\|session\\)?\\|maxima\\(?:output\\|session\\|tex\\(?:output\\|session\\)\\)\\)\\)"
1954 ;; (0 font-lock-keyword-face t t))))
1955 ;; "Keywords for EMaxima font-locking.")
1956 ;; (make-local-variable 'font-lock-defaults)
1957 ;; (setq font-lock-defaults
1958 ;; '(emaxima-keywords
1959 ;; nil nil ((?\( . ".") (?\) . ".") (?$ . "\"")) nil
1960 ;; (font-lock-comment-start-regexp . "%")
1961 ;; (font-lock-mark-block-function . mark-paragraph)))
1963 (if (inferior-maxima-running)
1964 (emaxima-load-tex-library))
1965 (add-hook 'inferior-maxima-mode-hook
'emaxima-load-tex-library
)
1966 ; (if running-xemacs
1967 ; (add-hook 'inferior-maxima-mode-hook (lambda () (sit-for 1))))
1968 (run-hooks 'emaxima-mode-hook
))
1971 ;;; Now, add to the keymap
1972 (define-key emaxima-mode-map
"\"" 'emaxima-insert-quote
)
1973 (define-key emaxima-mode-map
"$" 'emaxima-insert-dollar
)
1974 (define-key emaxima-mode-map
"\C-c\C-u" nil
)
1975 (define-key emaxima-mode-map
"\C-c+" 'emaxima-forward-cell
)
1976 (define-key emaxima-mode-map
"\C-c-" 'emaxima-backward-cell
)
1977 (define-key emaxima-mode-map
"\C-c\C-ua" 'emaxima-update-all-cells
)
1978 (define-key emaxima-mode-map
"\C-c\C-uA" 'emaxima-tex-update-all-cells
)
1979 (define-key emaxima-mode-map
"\C-c\C-us" 'emaxima-update-session
)
1980 (define-key emaxima-mode-map
"\C-c\C-uS" 'emaxima-tex-update-session
)
1981 (define-key emaxima-mode-map
"\C-c\C-o" 'emaxima-create-standard-cell
)
1982 (define-key emaxima-mode-map
"\C-c\C-a" 'emaxima-create-session-cell
)
1983 (define-key emaxima-mode-map
"\C-c\C-n" 'emaxima-toggle-starred-cell
)
1984 (define-key emaxima-mode-map
"\C-c\C-ul" 'emaxima-replace-line
)
1985 (define-key emaxima-mode-map
"\C-c\C-uL" 'emaxima-replace-line-with-tex
)
1986 (define-key emaxima-mode-map
"\C-c\C-k" 'maxima-stop
)
1987 ;; And some emaxima keys that make sense in cells
1988 (define-key emaxima-mode-map
"\C-c\C-v" 'emaxima-send-cell
)
1989 (define-key emaxima-mode-map
"\C-c\C-uc" 'emaxima-update-single-cell
)
1990 (define-key emaxima-mode-map
"\C-c\C-uC" 'emaxima-tex-update-single-cell
)
1991 (define-key emaxima-mode-map
"\C-c\C-d" 'emaxima-delete-output
)
1992 (define-key emaxima-mode-map
"\C-c\C-x" 'emaxima-package-part
)
1993 (define-key emaxima-mode-map
"\C-c@" 'emaxima-assemble
)
1994 (define-key emaxima-mode-map
"\C-c\C-h" 'maxima-help
)
1995 (define-key emaxima-mode-map
"\C-c\C-i" 'maxima-info
)
1996 (define-key emaxima-mode-map
[(control c
) (control tab
)] 'emaxima-insert-complete-name
)
1999 (easy-menu-define emaxima-menu emaxima-mode-map
2003 ["Create cell" emaxima-create-standard-cell
2004 (not (emaxima-standard-cell-p))]
2005 ["Create session cell" emaxima-create-session-cell
2006 (not (emaxima-session-cell-p))]
2007 ["Toggle starred cell" emaxima-toggle-starred-cell
2009 ["Send cell" emaxima-send-cell
(emaxima-cell-p)]
2010 ["Update cell" emaxima-update-single-cell
(emaxima-cell-p)]
2011 ["TeX update cell" emaxima-tex-update-single-cell
(emaxima-cell-p)]
2012 ["Delete output" emaxima-delete-output
(emaxima-cell-p)]
2013 ["Mark as package part" emaxima-package-part
(emaxima-standard-cell-p)]
2014 ["Insert complete name" emaxima-insert-complete-name
2015 (emaxima-standard-cell-p)]
2016 ["Forward cell" emaxima-forward-cell
]
2017 ["Backwards cell" emaxima-backward-cell
])
2019 ["Update line" emaxima-replace-line
(not (emaxima-cell-p))]
2020 ["Update all cells" emaxima-update-all-cells
]
2021 ["Update session cells" emaxima-update-session
]
2023 ["TeX update line" emaxima-replace-line-with-tex
(not (emaxima-cell-p))]
2024 ["TeX update all cells" emaxima-tex-update-all-cells
])
2026 ["Start a Maxima process" maxima-start
2027 (not (processp inferior-maxima-process
))]
2028 ["Run Maxima on region" maxima-region
]
2029 ["Kill Maxima process" maxima-stop
(processp inferior-maxima-process
)])
2031 ["Indent region" maxima-indent-region
(emaxima-cell-p)]
2032 ["Short comment" maxima-short-comment
(emaxima-cell-p)]
2033 ["Long comment" maxima-long-comment
(emaxima-cell-p)]
2034 ["Mark file as EMaxima" emaxima-mark-file-as-emaxima
])
2036 ["Assemble cell" emaxima-assemble-cell
2037 (and (emaxima-cell-p) (emaxima-reference-p))]
2038 ["Assemble package" emaxima-assemble-package
2039 (and (emaxima-cell-p) (emaxima-reference-p))])
2041 ["Manual" maxima-info
]
2042 ["Describe" maxima-help
])))
2044 ;;; The next line is necessary for XEmacs
2045 (if (featurep 'xemacs
)
2046 (easy-menu-add emaxima-menu emaxima-mode-map
))
2048 ;;; emaxima.el ends here