Add support for external html docs
[maxima.git] / interfaces / emacs / emaxima / emaxima.el
blobbaccfb237f5f45515882e6c91f0e800c3bd78352
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)
8 ;; Authors: Dan Dill
9 ;; Jay Belanger
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.
17 ;;
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.
22 ;;
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
31 ;;; Commentary:
33 ;; See the file EMintro.ps for a quick introduction.
35 (require 'maxima)
36 (provide 'emaxima)
38 ;;;; The variables that the user may wish to change
40 (defgroup emaxima nil
41 "Maxima mode"
42 :prefix "emaxima-"
43 :tag "EMaxima")
45 (defcustom emaxima-use-tex 'auctex
46 "Possible modes to use within EMaxima.
47 Possible choices are 'auctex, 'tex or nil"
48 :group 'emaxima
49 :type '(choice :menu-tag "TeX style"
50 :tag "TeX style"
51 (const auctex)
52 (const tex)
53 (const nil)))
55 (defcustom emaxima-use-emaxima-indent nil
56 "Use Maxima indent when in cells.
57 Only works with AUCTeX."
58 :group 'emaxima
59 :type 'boolean)
61 (defcustom emaxima-tex-lisp-file (locate-library "emaxima.lisp" t)
62 "The file to be loaded that allows TeX output."
63 :group 'emaxima
64 :type '(file))
66 (defcustom emaxima-output-marker "---"
67 "The string to separate the input from the output."
68 :group 'emaxima
69 :type 'string)
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
74 package assembly."
75 :group 'emaxima
76 :type '(boolean))
78 (defcustom emaxima-preview-after-update-all t
79 "If non-nil and preview-latex is available, preview after update-all"
80 :group 'emaxima
81 :type 'boolean)
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."
88 :group 'emaxima
89 :type '(integer))
91 (defcustom emaxima-temp-dir "/tmp/"
92 "Directory for temporary files.
93 Specify \"\" to use the directory of the EMaxima document buffer."
94 :group 'emaxima
95 :type '(directory))
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"
156 (interactive "*P")
157 (cond
158 ((emaxima-cell-p)
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"
168 (interactive "*P")
169 (cond
170 ((emaxima-cell-p)
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"
181 (interactive)
182 (save-excursion
183 (goto-line 1)
184 (beginning-of-line)
185 (if (looking-at ".*-\\*-EMaxima-\\*-")
187 (open-line 1)
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 ()
197 (maxima-start)
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 ()
203 (maxima-start)
204 (when emaxima-tex-lisp-file
205 (maxima-single-string-wait "block(display2d:origdisplay, linenum:linenum-1)$")))
207 (defun emaxima-indent-line ()
208 (interactive)
209 (if (emaxima-cell-p)
210 (maxima-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."
217 (let ((found nil))
218 (save-excursion
219 (if (re-search-backward emaxima-any-cell-begin-regexp
220 (point-min) t) ; \beginmaxima
221 (setq found (point))))
222 (save-excursion
223 (if (and found
224 (re-search-backward emaxima-any-cell-end-regexp
225 found t)) ; Intervening \endmaxima
226 (setq found nil)))
227 (save-excursion
228 (if (and found
229 (re-search-forward emaxima-any-cell-end-regexp
230 (point-max) t)) ;\endmaxima
231 (setq found (point))
232 (setq found nil))) ; No \endmaxima
233 (save-excursion
234 (if (and found
235 (re-search-forward emaxima-any-cell-begin-regexp
236 found t)) ; Intervening \beginmaxima
237 (setq found nil)))
238 (if found t nil)))
240 (defun emaxima-standard-cell-p ()
241 "Non-nil if point is in a standard cell."
242 (and
243 (emaxima-cell-p)
244 (save-excursion
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."
250 (and
251 (emaxima-cell-p)
252 (save-excursion
253 (re-search-backward emaxima-any-cell-begin-regexp)
254 (looking-at emaxima-session-cell-begin-regexp))))
256 (defun emaxima-package-cell-p ()
257 (and
258 (emaxima-standard-cell-p)
259 (save-excursion
260 (re-search-backward emaxima-standard-cell-begin-regexp)
261 (goto-char (match-end 0))
262 (and
263 (looking-at "\\[")
264 (not (looking-at "\\[\\]"))))))
266 ;;; Create the cells.
267 (defun emaxima-new-standard-cell ()
268 "Insert cell in buffer."
269 (if (not (bolp))
270 (progn
271 (open-line 1)
272 (forward-line 1)))
273 (insert "\\begin{maxima}[]\n\n\\end{maxima}")
274 (unless (looking-at " *$")
275 (insert "\n")
276 (forward-line -1))
277 (beginning-of-line)
278 (previous-line 1))
280 (defun emaxima-new-session-cell ()
281 "Insert cell in buffer."
282 (if (not (bolp))
283 (progn
284 (open-line 1)
285 (forward-line 1)))
286 (insert "\\begin{maximasession}\n\n\\end{maximasession}")
287 (unless (looking-at " *$")
288 (insert "\n")
289 (forward-line -1))
290 (beginning-of-line)
291 (previous-line 1))
293 (defun emaxima-create-standard-cell ()
294 "Insert standard cell in buffer."
295 (interactive)
296 (if (not (emaxima-cell-p))
297 (emaxima-new-standard-cell)
298 (if (emaxima-standard-cell-p)
299 (error "Currently in cell.")
300 (save-excursion
301 (re-search-backward emaxima-session-cell-begin-regexp)
302 (re-search-forward "maximasession")
303 (replace-match "maxima")
304 (search-forward "}")
305 (insert "[]")
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."
312 (interactive)
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.")
319 (save-excursion
320 (re-search-backward emaxima-standard-cell-begin-regexp)
321 (re-search-forward "maxima")
322 (replace-match "maximasession")
323 (search-forward "}")
324 (if (looking-at "\\[\\]")
325 (delete-char 2))
326 (re-search-forward emaxima-standard-cell-end-regexp)
327 (search-backward "maxima")
328 (replace-match "maximasession"))))))
330 (defun emaxima-toggle-starred-cell ()
331 (interactive)
332 "Toggle whether or not the current cell is starred."
333 (if (not (emaxima-cell-p))
334 (error "Not in cell.")
335 (save-excursion
336 (re-search-backward emaxima-any-cell-begin-regexp)
337 (re-search-forward "maxima\\(?:session\\)?")
338 (if (looking-at "\\*")
339 (delete-char 1)
340 (insert "*"))
341 (re-search-forward emaxima-any-cell-end-regexp)
342 (beginning-of-line)
343 (re-search-forward "maxima\\(?:session\\)?")
344 (if (looking-at "\\*")
345 (delete-char 1)
346 (insert "*")))))
348 (defun emaxima-starred-cell-p ()
349 "Non-nil if point is in starred cell."
350 (if (not (emaxima-cell-p))
352 (save-excursion
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."
359 (interactive)
360 (cond
361 ((emaxima-standard-cell-p)
362 (save-excursion
363 (let ((initstring)
364 (package))
365 (re-search-backward emaxima-standard-cell-begin-regexp)
366 (goto-char (match-end 0))
367 (if (looking-at "\\[\\(.*\\)\\]")
368 (progn
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"))))
378 ;;; Cell positions
380 (defun emaxima-cell-start ()
381 "Return position of start of cell containing point."
382 (save-excursion
383 (if (not (looking-at emaxima-any-cell-begin-regexp))
384 (re-search-backward emaxima-any-cell-begin-regexp))
385 (forward-line 1)
386 (point)))
388 (defun emaxima-cell-end ()
389 "Return position of end of cell containing point."
390 (save-excursion
391 (re-search-forward emaxima-any-cell-end-regexp)
392 (forward-line -1)
393 (end-of-line)
394 (point)))
396 (defun emaxima-previous-cell-start ()
397 "Get start of preceding cell. If none, return current position."
398 (let ((cur-pos (point))
399 (start nil))
400 (save-excursion
401 (if (not (re-search-backward emaxima-any-cell-end-regexp (point-min) t))
402 cur-pos
403 (if (emaxima-cell-p)
404 (progn
405 (re-search-backward emaxima-any-cell-begin-regexp)
406 (forward-line 1)
407 (point))
408 cur-pos)))))
410 (defun emaxima-next-cell-start (&optional arg)
411 "Get start of next cell. If none, return current position."
412 (let ((cur-pos (point))
413 (start nil)
414 (re (if arg
415 emaxima-any-cell-begin-regexp
416 emaxima-any-non-nu-cell-begin-regexp)))
417 (save-excursion
418 (if (re-search-forward re (point-max) t)
419 (progn
420 (if (not (emaxima-cell-p))
421 cur-pos)
422 (forward-line 1)
423 (point))
424 cur-pos))))
426 ;;; Cell motion
428 (defun emaxima-forward-cell (&optional arg)
429 "Move to next cell."
430 (interactive)
431 (let ((cur-pos (point))
432 (cell-pos (point-max))
433 new-pos)
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))
440 nil; No more cells
441 (goto-char cell-pos))))
443 (defun emaxima-backward-cell ()
444 "Move to previous cell."
445 (interactive)
446 (let ((cur-pos (point))
447 (cell-pos (point-min))
448 new-pos)
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))
455 nil ; No more cells
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*."
464 (save-excursion
465 (goto-char (emaxima-cell-start))
466 (if (re-search-forward "^\\\\maximaoutput"
467 (emaxima-cell-end) t)
468 (progn
469 (forward-line -1)
470 (end-of-line)
471 (point))
472 nil)))
474 (defun emaxima-empty-output-p ()
475 "Check if there is not output or only empty lines in output."
476 (save-excursion
477 (goto-char (emaxima-cell-start))
478 (if (re-search-forward "^\\\\maximaoutput"
479 (emaxima-cell-end) t)
480 (progn
481 (forward-line 1)
482 (while (looking-at "[ \t]*$")
483 (forward-line 1))
484 (looking-at "\\\\end{maxima"))
485 nil)))
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."
491 (interactive)
492 (let ((out-start (emaxima-output-p)))
493 (if out-start
494 (delete-region out-start (emaxima-cell-end))
495 t)))
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))))
506 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)."
511 (interactive "P")
512 (if arg
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.
539 (interactive)
540 (let ((home-buffer (current-buffer))
541 files parts file part
542 ref-count
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"))
546 (save-excursion
547 (goto-char (emaxima-cell-start))
548 (forward-line -1)
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
555 (progn
556 (message "Getting filenames...")
557 (setq files (emaxima-get-filenames))
558 (message ""))
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
564 (progn
565 (message "Getting partnames")
566 (setq parts (emaxima-get-partnames file files))
567 (message "")))
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)))
575 (unwind-protect
576 (save-excursion
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
607 without asking."
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
613 ;; `FILE'.
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.
624 (interactive)
625 (let ((home-buffer (current-buffer))
626 files parts prompt
627 tmp-buffer tmp-alist file-buffer)
628 (if (not file)
629 ;; If file has not been specified, prompt
630 (progn
631 ;; Get default file from cell label, if any
632 (save-excursion
633 (goto-char (emaxima-cell-start))
634 (forward-line -1)
635 (if (looking-at emaxima-package-cell-regexp)
636 (progn
637 (setq emaxima-error-point (point))
638 (unwind-protect ; In case filename errors
639 (if emaxima-abbreviations-allowed
640 ;; This can take some seconds
641 (progn
642 (message "Getting filenames...")
643 (if (not (setq files (emaxima-get-filenames)))
644 (error
645 "No complete package filenames found"))
646 (message "")))
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"))))
652 (if (not overwrite)
653 (if (file-exists-p file)
654 (progn
655 (setq prompt (concat
656 "Package file `"
657 file
658 "' exists. Overwrite it ? "))
659 (if (not (y-or-n-p prompt))
660 (error "Package assembly cancelled")))))
661 (if (get-buffer file)
662 (kill-buffer file))
663 (if emaxima-abbreviations-allowed
664 ;; This can take several seconds for a document with many cells
665 (progn
666 (message "Getting partnames...")
667 (setq parts (emaxima-get-partnames file files))
668 (message "")))
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
674 (progn
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)
682 (write-file file)
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)
694 ; file
695 (switch-to-buffer-other-window file)))
697 (defun emaxima-reference-count (buffer)
698 "Return the number of references in BUFFER."
699 (let ((count 0)
700 (home-buffer (current-buffer)))
701 (save-excursion
702 (set-buffer 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))
707 count))
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))
716 end)
717 (save-excursion
718 (goto-char start)
719 (beginning-of-line)
720 (while (looking-at "^ *$") (forward-line 1))
721 (setq start (point))
722 (if (not (setq end (emaxima-output-p)))
723 (progn
724 (goto-char (emaxima-cell-end))
725 (while (looking-at "^ *$") (forward-line -1))
726 (end-of-line)
727 (setq end (point)))
728 (progn
729 (goto-char end)
730 (while (looking-at "^ *$") (forward-line -1))
731 (end-of-line)
732 (setq end (point))))
733 (set-buffer (get-buffer-create buffer))
734 (goto-char (point-max))
735 (insert-buffer-substring home-buffer start end)
736 (insert "\n")))))
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
756 (progn
757 ;; Scan buffer to construct buffers for all `file:part'
758 (save-excursion
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))
768 (cond
769 ((not this-file)
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))
777 (cond
778 ((not this-part)
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 "")
792 (setq key file)
793 (setq key (concat file ":" this-part)))
795 (assoc key emaxima-buffer-alist) ; buffer already created
796 (emaxima-replace-assoc
797 emaxima-buffer-alist
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
803 ) ; cond on partname
804 ) ; t on right filename (package)
805 ) ; cond on filename
806 ) ; if a marked cell
807 ) ; while still cells to process
808 (set-buffer home-buffer)
809 ) ; save excursion
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))
824 path-to-here
825 ref-indent ref-key ref-buffer
826 (key-buffer (cdr (assoc key emaxima-buffer-alist)))
827 file part
828 re-found)
829 (or key-buffer (error "No cell `%s'" key))
830 (set-buffer key-buffer)
831 (goto-char (point-min))
832 (if noinit
834 (setq noinit t)
835 (setq emaxima-dereference-path (list key)))
836 (setq path-to-here emaxima-dereference-path)
837 (while (re-search-forward "^ *\t*<[^:].*:[^>].*>$" (point-max) t)
838 (setq re-found 1)
839 (beginning-of-line)
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
849 (progn
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))
858 indent-end)
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)
865 ref-found))
867 (defun emaxima-dereference-error (path)
868 "Report package self-reference error, in PATH"
869 (let ((cell (car path))
870 (home-buffer (current-buffer))
871 to-cell from-cell)
872 (setq to-cell cell)
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."
893 (let (start end)
894 (save-excursion
895 (beginning-of-line)
896 (setq start (point))
897 (search-forward "<")
898 (untabify start (point))
899 (setq end (point))
900 (beginning-of-line)
901 (tabify (point) end)
902 (- end start 1))))
904 (defun emaxima-insert-complete-name ()
905 "Insert complete name in buffer for cell.
906 Return t if successful, else nil."
907 (interactive)
908 (let ((here (point))
909 start end name text files parts)
910 (save-excursion
911 (beginning-of-line)
912 (cond
913 ((and ; partname
915 (re-search-forward
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"))
923 (message "")
924 (search-backward "[") ;; Look here
925 (forward-char 1)
926 (setq start (point))
927 (search-forward ":")
928 (forward-char -1)
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))
935 (message "")
936 (forward-char 1)
937 (setq start (point)) ; New start, for partname deletion
938 (setq text (buffer-substring (point) here))
939 (if (not (setq name (emaxima-complete-name
940 (concat text "...")
941 parts)))
942 (error "No matching package partname found"))
943 (cond
944 ((equal t name) ; Text is complete
945 (setq name text))
946 ((equal t (try-completion name parts)))
947 (t ; Else, get completion
948 (setq name
949 (completing-read
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
954 ((and ; filename
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"))
963 (message "")
964 (re-search-backward "\\[\\|<") ;;xxx
965 (forward-char 1)
966 (setq start (point))
967 (setq text (buffer-substring start here))
968 (if (not (setq name (emaxima-complete-name
969 (concat text "...") ; completion form
970 files)))
971 (error "No matching package filename found"))
972 (cond
973 ((equal t name) ; Text is complete
974 (setq name text))
975 ((equal t (try-completion name files)))
976 (t ; Else, get completion
977 (setq name
978 (completing-read
979 "Filename (<space> to see filenames): "
980 files nil t name))
981 (if (equal "" name) (error ""))))
982 (delete-region start here)
983 (insert (concat name ":")))
985 ;;(error "Nothing to complete")
986 nil))) ; save-excursion
987 (if (not name)
989 (goto-char (+ (point) (length name) 1))
990 t)))
992 (defun emaxima-get-filenames ()
993 "Return alist of package filenames for cells."
994 (let (file files)
995 (save-excursion
996 (goto-char (point-min))
997 (while (emaxima-forward-cell)
998 (forward-line -1)
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
1002 (if files
1003 (if (assoc file files)
1004 nil ; already only
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
1009 ) ; save-excursion
1010 files))
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
1018 is returned.
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
1023 (if (and
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)))
1029 (cond
1030 ((equal t name)
1031 (setq name try-name))
1032 ((and
1033 exact
1034 (not (equal t (try-completion name alist))))
1035 (setq name nil)))) ; Not an exact match, so error
1036 name))
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))
1043 (unwind-protect
1044 (save-excursion
1045 (goto-char (point-min))
1046 (while (emaxima-forward-cell)
1047 (setq cell-end (emaxima-cell-end))
1048 (forward-line -1)
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
1055 (while (and
1056 (<= (point) cell-end)
1058 (re-search-forward
1059 (concat emaxima-standard-cell-begin-regexp
1060 "\\[[^:].*:.*\\]") cell-end t)
1061 (re-search-forward
1062 "^ *\t*<[^:].*:.*>" cell-end t)))
1063 (beginning-of-line) ; We have a filename-partname reference
1064 (if (not (setq file (emaxima-get-filename files)))
1065 (progn
1066 (setq emaxima-error-point (point))
1067 (error "Ambiguous filename")))
1068 (if (not (equal cell-file file))
1069 (progn
1070 (setq emaxima-error-point (point))
1071 (error "Reference must match cell filename: `%s'"
1072 cell-file)))
1073 (setq part (emaxima-get-partname))
1074 (if (not part)
1075 nil ; Need full (unabbreviated) parts only, for alist
1076 (if parts ; Update alist
1077 (if (or
1078 (equal part "")
1079 (emaxima-string-mem part parts))
1080 nil; already on list
1081 (setq parts (append (list part) parts)))
1082 ; Add to alist
1083 (if (not (equal part ""))
1084 (setq parts (list part)))) ; Create alist
1085 ) ; if an unabbreviated part
1086 (forward-line 1)
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
1091 ); save-excursion
1092 (goto-char emaxima-error-point) ; unwind-protect form
1093 ) ; unwind-protect
1094 (setq parts (mapcar 'list parts)) ; Make list into an alist
1095 parts))
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 "\\.\\.\\.")
1103 beg text)
1104 (save-excursion
1105 (beginning-of-line)
1106 (setq beg (point))
1107 (end-of-line)
1108 (setq text (buffer-substring beg (point)))
1109 (string-match match-re text)
1110 (setq text
1111 (substring text (+ 1 (match-beginning 1)) (+ -1 (match-end 2)))))
1112 (if alist
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))
1118 (error
1119 "Set emaxima-abbreviations-allowed (M-x set-variable) to use abbreviations"))
1120 text))))
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 "\\.\\.\\.")
1128 beg text)
1129 (save-excursion
1130 (beginning-of-line)
1131 (setq beg (point))
1132 (end-of-line)
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))))
1136 (if alist
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))
1142 (error
1143 "Set emaxima-abbreviations-allowed (M-x set-variable) to use abbreviations"))
1144 text))))
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."
1148 (let (try
1149 (found nil))
1150 (while (and (setq try (car list)) (not found))
1151 (setq list (cdr list))
1152 (if (equal element try)
1153 (setq found t)))
1154 found))
1156 (defun emaxima-reference-p ()
1157 "Return t if cell contains a cell reference, else return nil."
1158 (save-excursion
1159 (goto-char (emaxima-cell-start))
1160 (if (re-search-forward "^ *\t*<[^:].*:[^>].*>$" (emaxima-cell-end) t)
1162 nil)))
1164 ;;; Cell evaluation
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)
1174 (save-excursion
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)))
1179 (save-excursion
1180 (goto-char (emaxima-cell-start))
1181 ;; Now I want to skip over any blank lines at the beginning of the cell
1182 (beginning-of-line)
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)))
1187 (progn
1188 (goto-char (emaxima-cell-end))
1189 (while (looking-at "^ *$") (forward-line -1))
1190 (end-of-line)
1191 (setq end (point)))
1192 (progn
1193 (goto-char end)
1194 (while (looking-at "^ *$") (forward-line -1))
1195 (end-of-line)
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)))
1205 (progn
1206 (insert "\\ps\n")
1207 (insert (emaxima-fix-tex-output string) "\n" ))
1208 (if strip
1209 (setq string (maxima-strip-string-end string)))
1210 (insert "\\p\n")
1211 (insert string)
1212 (insert " \\\\\n")))
1214 (defun emaxima-insert-last-output-tex ()
1215 (let ((mb)
1216 (me)
1217 (ie)
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))
1222 (when (> mb 0)
1223 (emaxima-insert-preoutput (substring out 0 mb)))
1224 (insert "\\t")
1225 (insert (substring out (+ mb 3) (- me 1)))
1226 (insert ". ")
1227 (setq out (maxima-strip-string-beginning (substring out me)))
1228 (string-match
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))))
1233 (insert " \\\\\n")
1234 (setq out (maxima-strip-string-beginning (substring out ie))))
1235 (if (string-match (concat "(" maxima-outchar "[0-9]+)") out)
1236 (progn
1237 (setq mb (match-beginning 0))
1238 (setq me (match-end 0))
1239 (when (> mb 0)
1240 (emaxima-insert-preoutput (substring out 0 mb) t))
1241 (insert "\\o")
1242 (insert (substring out (+ mb 3 ) (- me 1)))
1243 ; (insert (substring out (+ mb (1+ (length maxima-outchar))) (- me 1)))
1244 (insert ". ")
1245 (insert (emaxima-fix-tex-output
1246 (maxima-strip-string (substring out me))))
1247 (insert " \\\\\n"))
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)))
1253 (me)
1254 (mb)
1255 (ie))
1256 (while (string-match (concat "(" maxima-linechar "[0-9]+)") out)
1257 (setq mb (match-beginning 0))
1258 (setq me (match-end 0))
1259 (when (> mb 0)
1260 (emaxima-insert-preoutput (substring out 0 mb)))
1261 (insert "\\t")
1262 (insert (substring out (+ mb 3) (- me 1)))
1263 (insert ". ")
1264 (setq out (maxima-strip-string-beginning (substring out me)))
1265 (string-match
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))))
1270 (insert " \\\\\n")
1271 (setq out (substring out ie)))
1272 (if (string-match (concat "(" maxima-outchar "[0-9]+)") out)
1273 (progn
1274 (setq mb (match-beginning 0))
1275 (setq me (match-end 0))
1276 (when (> mb 0)
1277 (emaxima-insert-preoutput (substring out 0 mb) t))
1278 (setq out (maxima-strip-string-beginning (substring out me)))
1279 (insert "\\m")
1280 (insert " ")
1281 (insert (emaxima-fix-tex-output out));(substring out me))
1282 (insert " \\\\\n"))
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*"))
1290 (prompt))
1291 (if (null maxima-buffer)
1292 (message "No Maxima output buffer")
1293 (set-buffer maxima-buffer)
1294 (save-excursion
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))
1299 (setq prompt
1300 (buffer-substring-no-properties
1301 (match-beginning 0) (- (match-end 0) 1))))
1302 (set-buffer old-buffer)
1303 prompt)))
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))
1310 (end))
1311 (save-excursion
1312 (set-buffer tmpbuf)
1313 (maxima-remove-kill-buffer-hooks)
1314 (insert string)
1315 (goto-char (point-min))
1316 (search-forward ":lisp")
1317 (forward-sexp)
1318 (setq end (- (point) 1)))
1319 (kill-buffer tmpbuf)
1320 end))
1322 (defun emaxima-get-form-end (string)
1323 (let* ((tmpfile (maxima-make-temp-name))
1324 (tmpbuf (get-buffer-create tmpfile))
1325 (end))
1326 (save-excursion
1327 (set-buffer tmpbuf)
1328 (maxima-remove-kill-buffer-hooks)
1329 (insert string)
1330 (goto-char (point-min))
1331 (maxima-goto-end-of-form)
1332 (setq end (- (point) 1)))
1333 (kill-buffer tmpbuf)
1334 end))
1336 (defun emaxima-update-cell ()
1337 "Send the current cell's contents to Maxima, and return the results."
1338 (cond
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."
1348 (cond
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)
1359 (let ((end)
1360 (cell (emaxima-get-cell-contents)))
1361 (goto-char (emaxima-cell-end))
1362 (forward-line 1)
1363 (insert "\\maximaoutput\n")
1364 (while (or
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)
1374 (insert mlon))))))
1376 (defun emaxima-tex-update-standard-cell ()
1377 "Send the current cell's contents to Maxima, and return the results."
1378 (emaxima-delete-output)
1379 (let ((end)
1380 (cell (emaxima-get-cell-contents)))
1381 (goto-char (emaxima-cell-end))
1382 (forward-line 1)
1383 (insert "\\maximaoutput*\n")
1384 (while (or
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)))
1391 (emaxima-tex-on))
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."
1398 (save-excursion
1399 (emaxima-delete-output)
1400 (let ((end)
1401 (cell (emaxima-get-cell-contents)))
1402 (goto-char (emaxima-cell-end))
1403 (forward-line 1)
1404 (insert "\\maximaoutput\n")
1405 (while (or
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))
1413 (insert " ")
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))
1420 (insert "\n"))
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)
1428 (save-excursion
1429 (emaxima-delete-output)
1430 (let ((end)
1431 (out)
1432 (cell (emaxima-get-cell-contents)))
1433 (goto-char (emaxima-cell-end))
1434 (forward-line 1)
1435 (insert "\\maximaoutput*\n")
1436 (while (or
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)))
1443 (emaxima-tex-on))
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)))
1449 (insert "\\i")
1450 (insert (substring (emaxima-last-input-prompt)
1451 3 -1))
1452 ; (1+ (length maxima-inchar)) -1))
1453 (insert ". ")
1454 ; (insert (maxima-replace-in-string "\\$" "\\\\$" (substring cell 0 end)))
1455 (insert (substring cell 0 end))
1456 (insert " \\\\")
1457 (unless (string= "\n" (substring cell (- end 1) end))
1458 (insert "\n"))
1459 ; (insert "\n")
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."
1468 (interactive "P")
1469 (maxima-start)
1470 (let ((ask))
1471 (if arg
1472 (setq ask t)
1473 (setq ask nil))
1474 (save-excursion
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))
1481 (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."
1487 (interactive "P")
1488 (maxima-start)
1489 (if (not emaxima-tex-lisp-file)
1490 (error "File `emaxima.lisp' not found in Emacs load path.")
1491 (emaxima-tex-on))
1492 (let ((ask))
1493 (if arg
1494 (setq ask t)
1495 (setq ask nil))
1496 (save-excursion
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))))
1501 (emaxima-tex-off)
1502 (if (and emaxima-preview-after-update-all
1503 (fboundp 'preview-buffer))
1504 (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."
1509 (interactive "P")
1510 (maxima-start)
1511 (let ((ask))
1512 (if arg
1513 (setq ask t)
1514 (setq ask nil))
1515 (save-excursion
1516 (goto-char (point-min))
1517 (while (emaxima-forward-cell)
1518 (if (and
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))
1524 (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."
1530 (interactive "P")
1531 (maxima-start)
1532 (if (not emaxima-tex-lisp-file)
1533 (error "File `emaxima.lisp' not found in Emacs load path.")
1534 (emaxima-tex-on))
1535 (let ((ask))
1536 (if arg
1537 (setq ask t)
1538 (setq ask nil))
1539 (save-excursion
1540 (goto-char (point-min))
1541 (while (emaxima-forward-cell)
1542 (if (and
1543 (emaxima-session-cell-p)
1544 (or ask (y-or-n-p "Update this cell? ")))
1545 (emaxima-tex-update-session-cell))))
1546 (emaxima-tex-off)
1547 (if (and emaxima-preview-after-update-all
1548 (fboundp 'preview-buffer))
1549 (preview-buffer))))
1551 (defun emaxima-update-single-cell ()
1552 "Send the current cell's contents to Maxima, and return the results."
1553 (interactive)
1554 (maxima-start)
1555 (save-excursion
1556 (cond
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."
1570 (interactive)
1571 (maxima-start)
1572 (if (not emaxima-tex-lisp-file)
1573 (error "File `emaxima.lisp' not found in Emacs load path.")
1574 (save-excursion
1575 (cond
1576 ((emaxima-standard-cell-p)
1577 (emaxima-tex-on)
1578 (emaxima-tex-update-standard-cell)
1579 (emaxima-tex-off)
1580 (if (emaxima-empty-output-p)
1581 (emaxima-delete-output)))
1582 ((emaxima-session-cell-p)
1583 (emaxima-tex-on)
1584 (emaxima-tex-update-session-cell)
1585 (emaxima-tex-off)
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."
1594 (interactive)
1595 (if (not emaxima-tex-lisp-file)
1596 (error "File `emaxima.lisp' not found in Emacs load path.")
1597 (maxima-start)
1598 (emaxima-tex-on)
1599 (maxima-single-string-wait
1600 (buffer-substring-no-properties
1601 (maxima-line-beginning-position) (maxima-line-end-position)))
1602 (beginning-of-line)
1603 (insert "% ")
1604 (end-of-line)
1605 (newline)
1606 (emaxima-insert-last-output-tex-noprompt)
1607 (emaxima-tex-off)))
1609 (defun emaxima-replace-line ()
1610 "Sends the current line to Maxima, and then replaces it with the Maxima
1611 output."
1612 (interactive)
1613 (maxima-start)
1614 (maxima-single-string-wait
1615 (buffer-substring-no-properties
1616 (maxima-line-beginning-position) (maxima-line-end-position)))
1617 (beginning-of-line)
1618 (insert "% ")
1619 (end-of-line)
1620 (newline)
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))
1630 (end))
1631 (save-excursion
1632 (set-buffer tmpbuf)
1633 (maxima-remove-kill-buffer-hooks)
1634 (insert string)
1635 ;; Replace beginning \maxima with \begin{verbatim}
1636 (goto-char (point-min))
1637 (kill-line)
1638 (insert "\\begin{verbatim}")
1639 ;; Take care of the output
1640 (if (re-search-forward "^\\\\maximaoutput" nil t)
1641 (progn
1642 (beginning-of-line)
1643 (if (not (looking-at "\\\\maximaoutput\\*"))
1644 (progn
1645 (kill-line)
1646 (insert "\\end{verbatim}\n")
1647 (insert emaxima-output-marker "\n")
1648 (insert "\\begin{verbatim}")
1649 (re-search-forward emaxima-standard-cell-end-regexp)
1650 (beginning-of-line)
1651 (kill-line)
1652 (insert "\\end{verbatim}\n")
1653 (insert "%% End of cell\n"))
1654 ;; Else, in a TeX cell
1655 (kill-line)
1656 (insert "\\end{verbatim}\n")
1657 (insert emaxima-output-marker "\\\\")
1658 (let ((pt (point)))
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))
1663 (insert "\\[")
1664 (search-forward "\\\\")
1665 (delete-char -2)
1666 (insert "\\]"))
1667 ;; Next, get rid of the \Es
1668 (goto-char pt)
1669 (while (re-search-forward "^\\\\t[^N]" nil t)
1670 (delete-region (line-beginning-position) (point))
1671 (insert "\\[ \%t")
1672 (search-forward ".")
1673 (delete-char -1)
1674 (insert "=")
1675 (search-forward "\\\\")
1676 (delete-char -2)
1677 (insert "\\]"))
1678 ;; Next, get rid of the \ms
1679 (goto-char pt)
1680 (while (re-search-forward "^\\\\m" nil t)
1681 (delete-region (line-beginning-position) (point))
1682 (insert "\\[")
1683 (search-forward "\\\\")
1684 (delete-char -2)
1685 (insert "\\]"))
1686 ;; Finally, get rid of the \ps
1687 (goto-char pt)
1688 (while (re-search-forward "^\\\\p" nil t)
1689 (delete-region (line-beginning-position) (point))
1690 (insert "\\begin{verbatim}")
1691 (search-forward "\\\\")
1692 (delete-char -2)
1693 (insert "\n\\end{verbatim}"))
1694 (re-search-forward emaxima-standard-cell-end-regexp)
1695 (beginning-of-line)
1696 (kill-line)
1697 (insert "%% End of cell\n"))))
1698 ;; No output
1699 (re-search-forward emaxima-standard-cell-end-regexp)
1700 (beginning-of-line)
1701 (kill-line)
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)
1706 string))
1708 (defun emaxima-tex-up-session-cell (string)
1709 (let* ((tmpfile (maxima-make-temp-name))
1710 (tmpbuf (get-buffer-create tmpfile))
1711 (end))
1712 (save-excursion
1713 (set-buffer tmpbuf)
1714 (maxima-remove-kill-buffer-hooks)
1715 ; (make-local-hook 'kill-buffer-hook)
1716 ; (setq kill-buffer-hook nil)
1717 (insert string)
1718 (goto-char (point-min))
1719 ;; Take care of the output
1720 (if (re-search-forward "^\\\\maximaoutput" nil t)
1721 (progn
1722 (beginning-of-line)
1723 (delete-region (point-min) (point))
1724 (if (not (looking-at "\\\\maximaoutput\\*"))
1725 (progn
1726 (kill-line)
1727 (insert "\\begin{verbatim}")
1728 (re-search-forward emaxima-session-cell-end-regexp)
1729 (beginning-of-line)
1730 (kill-line)
1731 (insert "\\end{verbatim}\n")
1732 (insert "%% End of cell"))
1733 ;; Else, in a TeX cell
1734 (kill-line)
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")
1740 (insert "(%i")
1741 (search-forward ".")
1742 (delete-char -1)
1743 (insert ")")
1744 (search-forward "\\\\")
1745 (delete-char -2)
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 ".")
1753 (delete-char -1)
1754 (insert ")+\n\\[")
1755 (search-forward "\\\\")
1756 (delete-char -2)
1757 (insert "\\]"))
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 ".")
1764 (delete-char -1)
1765 (insert ")+\n\\[")
1766 (search-forward "\\\\")
1767 (delete-char -2)
1768 (insert "\\]"))
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 "\\\\")
1775 (delete-char -2)
1776 (insert "\n\\end{verbatim}"))
1777 (re-search-forward emaxima-session-cell-end-regexp)
1778 (beginning-of-line)
1779 (kill-line)
1780 (insert "%% End of cell\n")))
1781 ;; No output
1782 (erase-buffer)
1783 (insert "%% End of cell\n"))
1784 (setq string (buffer-substring-no-properties (point-min) (point-max))))
1785 (kill-buffer tmpbuf)
1786 string))
1788 (defun emaxima-tex-up-starred-cell (string)
1789 (let* ((tmpfile (maxima-make-temp-name))
1790 (tmpbuf (get-buffer-create tmpfile))
1791 (end))
1792 (save-excursion
1793 (set-buffer tmpbuf)
1794 (maxima-remove-kill-buffer-hooks)
1795 (insert string)
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)
1803 string))
1805 (defun emaxima-replace-cells-by-latex ()
1806 (interactive)
1807 (let ((cell)
1808 (beg)
1809 (end))
1810 (save-excursion
1811 (goto-char (point-min))
1812 (while (emaxima-forward-cell)
1813 (if (get-char-property (point) 'preview-state)
1814 (preview-clearout-at-point))
1815 (forward-line -1)
1816 (setq beg (point))
1817 (cond
1818 ((emaxima-starred-cell-p)
1819 (re-search-forward emaxima-any-cell-end-regexp)
1820 (setq end (point))
1821 (setq cell (buffer-substring-no-properties beg end))
1822 (comment-region beg end)
1823 (forward-line 1)
1824 (insert (emaxima-tex-up-starred-cell cell)))
1825 ((emaxima-session-cell-p)
1826 (re-search-forward emaxima-any-cell-end-regexp)
1827 (setq end (point))
1828 (setq cell (buffer-substring-no-properties beg end))
1829 (comment-region beg end)
1830 (forward-line 1)
1831 (insert (emaxima-tex-up-session-cell cell)))
1833 (re-search-forward emaxima-any-cell-end-regexp)
1834 (setq end (point))
1835 (setq cell (buffer-substring-no-properties beg end))
1836 (comment-region beg end)
1837 (forward-line 1)
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."
1843 (interactive)
1844 (if (not (emaxima-cell-p))
1845 (error "Not in an Emaxima cell")
1846 (if (emaxima-starred-cell-p)
1847 (message "Starred cell")
1848 (let ((beg))
1849 (goto-char (emaxima-cell-start))
1850 (forward-line -1)
1851 (setq beg (point))
1852 (search-forward emaxima-any-cell-end-regexp)
1853 (forward-line 1)
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."
1860 (interactive)
1861 (while (emaxima-forward-cell)
1862 (emaxima-preview-cell)))
1864 ;; First, find out what kind of TeX mode is being used.
1866 (cond
1867 ((eq emaxima-use-tex 'auctex)
1868 (require 'tex-site)
1869 ;; I don't think this is the best thing to do...
1870 (load "latex")
1871 (defun texmode () (latex-mode)))
1872 ((eq emaxima-use-tex 'tex)
1873 (require 'tex-mode)
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"
1883 ;; limit t)
1884 ;; (let ((beg (match-end 0)) end)
1885 ;; (if (search-forward "\\endmaxima"
1886 ;; limit 'move)
1887 ;; (setq end (match-beginning 0))
1888 ;; (setq end (point)))
1889 ;; (store-match-data (list beg end))
1890 ;; t)))
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
1903 information.)
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
1912 without prompting)
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)
1998 ;;; Now, the menu.
1999 (easy-menu-define emaxima-menu emaxima-mode-map
2000 "EMaxima mode menu"
2001 '("EMaxima"
2002 ("Cells"
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
2008 (emaxima-cell-p)]
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])
2018 ("Update"
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]
2022 "---"
2023 ["TeX update line" emaxima-replace-line-with-tex (not (emaxima-cell-p))]
2024 ["TeX update all cells" emaxima-tex-update-all-cells])
2025 ("Process"
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)])
2030 ("Misc"
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])
2035 ("Web"
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))])
2040 ("Help"
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