;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Maple2Html-mode ;; ;; Date: Sept. 17 1996 ;; Author: Carlos C. Rodriguez. carlos@math.albany.edu ;; ;; Summary: ;; Major mode for interacting with an inferior maple process for ;; creating web pages in html. It works in combination with the ;; perl program: maple2html (a.k.a. m2h). ;; The perl program is executed automatically every time the ;; buffer is saved. See the man page for m2h for information on what ;; this program does. ;; ;; Latest version and related information will be available at ;; ;; http://omega.albany.edu:8008/maple2html ;; ;; Installation: Save this file with name maple2html.el in a directory ;; appearing in your load-path variable. ;; Edit the next variables with the locations of ;; maple in your system. ;; this MUST HAVE the correct location of the maple executable ;; in your system, (defvar inferior-maple-program "/usr/local/bin/maple" "The command to run maple on a file.") ;; you may not need to change this, (defvar maple-args "-q" "Arguments passed to maple, it could be useful to set it to -q") ;; You May NEED this constant also (defconst local-maple-dir "/usr/local/maple/" "Maple Home directory") ;; You only need this if you are planning to run mint, (defvar mint-command (concat local-maple-dir "bin/mint") "The command to run mint on a file. The name of the file will be appended to this string, separated by <.") ;; Then if you want to run this mode, on a clean ;; buffer do: ;; ;; M-x load-file maple2html.el RET ;; ;; Tips and documentation on how to use this mode ;; can be obtained after loading (e.g. with the ;; command above) by typing: ;; ;; C-x m ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; LOCAL math.albany.edu info ;; ;; NOTE: If you have access to the /math disk then ;; you don't need to save a copy of this file. ;; By typing in a shell: ;; ;; /math/ppl/cr569/m2h4me ;; ;; this script is also at: ;; ;; http://omega.albany.edu:8008/m2h4me ;; ;; your account will be automatically set up ;; for using maple2html. If you prefer to do ;; it by hand then... (m2h4me does this for you ;; and also modifies your .mapleinit and .mailcap ;; for on the fly execution of maple from the web), ;; ;; .. If you insist on doing it by hand add the following ;; to the end of your $HOME/.cshrc file ;; ;; setenv EMACSLOADPATH .:/math/ppl/cr569/lisp ;; setenv PATH $PATH:/math/ppl/cr569/bin ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; begin adding to your $HOME/.emacs. Don't forget to delete the ;;'s ;; ;;(autoload 'run-maple2html-mode "maple2html" "Maple2Html major mode." t) ;;(or (assoc "\\.m2h$" auto-mode-alist) ;; (setq auto-mode-alist (cons '("\\.m2h$" . run-maple2html-mode) ;; auto-mode-alist))) ;;(or (assoc "-m2h$" auto-mode-alist) ;; (setq auto-mode-alist (cons '("-m2h$" . run-maple2html-mode) ;; auto-mode-alist))) ;; ;;;; end adding to $HOME/.emacs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; For automatic maple execution from the web on the fly ;; you need two do two things: ;; ;; 1) Add the following lines to your $HOME/.mailcap ;; ;; application/maple; maple.pl %s ;; application/x-maple; maple.pl %s ;; ;; 2) Add the following to your $HOME/.mapleinit ;; ;; x11 := proc() ;; plotsetup(x11); ;; plots[display](args[1]); ;; end: ;; ;; gif := proc() ;; plotsetup(gif,plotoutput = args[2]); ;; plots[display](args[1]); ;; end: ;; ;; read(`/home1or2/facORgrad/uid/.webmaple`); ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; REPLACE /home1or2/facORgrad/uid with the result of the ;;;; command "echo $HOME" i.e. your home in the system ;;;; in my case this is something like /home2/faculty/carlos ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; ;; Legalese: This is GNU software. ;; You can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; ;; GNU software is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ;; ;; ;; Code ;; Maple2Html mode a modification of Interactive maple mode. ;; (defun m2h-add-text () "Add text/html to the buffer" (interactive) (beginning-of-line) (open-line 1) (insert "# ")) (defun m2h-add-title (title) "Add or modify a title." (interactive "sTitle: ") (save-excursion (goto-char (point-min)) (if (looking-at "TITLE: ") (save-excursion (kill-line) t)) ;; Plop the new title in its place. (insert "TITLE: ") (insert title) (kill-line nil) (insert "\n"))) (defun m2h-pickup-from-last.el () "To be used when re-editing an m2h file. This function does the following: 1) Goes to the end and posibly cleans up the maple header. 2) It reads the .mpl file into the session." (interactive) (save-excursion (beginning-of-buffer) (re-search-forward "|[\\]^") (beginning-of-line) (let ((beg (point))) (re-search-forward "> [ \t\n ]*$") (beginning-of-line) (delete-region beg (point)))) (end-of-buffer) (m2h-read-maple-file)) ; (if (y-or-n-p "Do you want to kill the output from the read command?") ; (message "ready to kill") ; (message "OK won't kill it"))) (defun m2h-delete-previous-maple-output () "Deletes from the buffer from the beginning of the line to the previous maple prompt." (interactive) (save-excursion (beginning-of-line) (let ((end (point))) (comint-previous-prompt 1) (delete-region (point) end)))) ;;; lifted from maple.el (require 'comint) (provide 'maple) (provide 'maple2html) (require 'maple2html) ;;; Customization: This is where help files are located. ;;; Edit here, or set in default.el perhaps? ;;; However since maple-describe-function is currently borken anyway ;;; you can ignore it for now ... (defconst local-maple-dir "/usr/local/maple/" "Maple Home directory") (defvar maple-lib-directory (concat local-maple-dir "lib") "Maple library") (defvar maple-mode-syntax-table nil "Syntax table in use in maple-mode buffers.") (if maple-mode-syntax-table () (let ((table (make-syntax-table))) (modify-syntax-entry ?\\ "\\" table) (modify-syntax-entry ?\{ "(}" table) (modify-syntax-entry ?\[ "(]" table) (modify-syntax-entry ?\( "()" table) (modify-syntax-entry ?\} "){" table) (modify-syntax-entry ?\] ")[" table) (modify-syntax-entry ?\) ")(" table) (modify-syntax-entry ?* "." table) (modify-syntax-entry ?+ "." table) (modify-syntax-entry ?- "." table) (modify-syntax-entry ?/ "." table) (modify-syntax-entry ?= "." table) (modify-syntax-entry ?< "." table) (modify-syntax-entry ?> "." table) (modify-syntax-entry ?\' "\"" table) (modify-syntax-entry ?\` "\"" table) (modify-syntax-entry ?\" "." table) (modify-syntax-entry ?# "<" table) ; (modify-syntax-entry ?\n ">" table) ; (modify-syntax-entry ?\f ">" table) (setq maple-mode-syntax-table table))) (defvar maple-mode-map nil "Keymap used in Maple mode.") (if maple-mode-map () (let ((map (make-sparse-keymap))) (define-key map "\C-m" 'maple-newline) (define-key map "\C-?" 'maple-untab) (define-key map "\C-i" 'maple-tab) (define-key map "\C-c\C-i" 'backward-delete-char-untabify) (define-key map "\C-c\C-h" 'maple-help) (define-key map "\C-c<" 'maple-backward-to-same-indent) (define-key map "\C-c>" 'maple-forward-to-same-indent) (define-key map "\C-c#" 'maple-inline-comment) (define-key map "\C-ce" 'maple-else) (define-key map "\C-cf" 'maple-for) (define-key map "\C-ch" 'maple-header) (define-key map "\C-ci" 'maple-if) (define-key map "\C-cl" 'maple-local) (define-key map "\C-cm" 'maple-modify) (define-key map "\C-cp" 'maple-procedure) (define-key map "\C-cw" 'maple-while) (define-key map "\C-c\C-r" 'maple-region) (define-key map "\C-c\C-b" 'maple-buffer) (define-key map "\C-c\C-m" 'mint-buffer) (define-key map "\C-c\C-l" 'comint-show-output) (define-key map "\C-c\C-z" 'suspend-emacs) (define-key map "\C-c\C-s" 'switch-to-maple) (setq maple-mode-map map))) (defvar maple-indent 3 "*This variable gives the indentation in Maple-Mode") (defun maple-mode () "This is a mode intended to support program development in Maple. All control constructs of Maple can be reached by typing Control-C followed by the first character of the construct. Use \\[maple-region] to run Maple on the current region under a special subshell. \\[maple-buffer] does the whole buffer. Control-c f for Control-c e else Control-c i if Control-c l local Control-c w while Control-c p proc Control-c # comment Control-c h header Control-c m modify Control-c ( paired parens Control-c Control-z suspend-emacs C-c < and C-c > move backward and forward respectively to the next line having the same (or lesser) level of indentation. maple-indent controls the number of spaces for each indentation. \\{maple-mode-map} " (interactive) (kill-all-local-variables) (maple-define-common-keys maple-mode-map) (use-local-map maple-mode-map) (setq major-mode 'maple-mode) (setq mode-name "Maple") (make-local-variable 'comment-column) (setq comment-column 41) (make-local-variable 'end-comment-column) (setq end-comment-column 72) (set-syntax-table maple-mode-syntax-table) (make-local-variable 'paragraph-start) (setq paragraph-start (concat "^$\\|" page-delimiter)) (make-local-variable 'paragraph-separate) (setq paragraph-separate paragraph-start) (make-local-variable 'paragraph-ignore-fill-prefix) (setq paragraph-ignore-fill-prefix t) ; (make-local-variable 'indent-line-function) ; (setq indent-line-function 'c-indent-line) (make-local-variable 'require-final-newline) (setq require-final-newline t) (make-local-variable 'comment-start) (setq comment-start "#") (make-local-variable 'comment-end) (setq comment-end "\n") (make-local-variable 'comment-column) (setq comment-column 41) ; (make-local-variable 'comment-start-skip) ; (setq comment-start-skip "/\\*+ *") (make-local-variable 'comment-indent-hook) (setq comment-indent-hook 'c-comment-indent) (make-local-variable 'parse-sexp-ignore-comments) (setq parse-sexp-ignore-comments t) (run-hooks 'maple-mode-hook)) (defun maple-newline () "Insert a newline and indent following line like previous line." (interactive) (let ((hpos (current-indentation))) (newline) (indent-to hpos))) (defun maple-tab () "Indent to next tab stop." (interactive) (if (< (current-indentation) (- (point) (save-excursion (beginning-of-line)(point)))) (insert "\t") (back-to-indentation) (indent-to (* (1+ (/ (current-indentation) maple-indent)) maple-indent)))) (defun maple-tabsize (s) "changes spacing used for indentation. Reads spacing from minibuffer." (interactive "new indentation spacing: ") (setq maple-indent s)) (defun maple-untab () "Delete backwards to previous tab stop." (interactive) (backward-delete-char 1)) (defun maple-go-to-this-indent (step indent-level) "Move point repeatedly by lines till the current line has given indent-level or less, or the start/end of the buffer is hit. Ignore blank lines and comments." (while (and (zerop (forward-line step)) (or (looking-at "^[ ]*$") (looking-at "^[ ]*#") (looking-at "^<<[A-Za-z0-9_]+>>") (looking-at "^[A-Za-z0-9_]+:") (> (current-indentation) indent-level))) nil)) (defun maple-backward-to-same-indent () "Move point backwards to nearest line with same indentation or less. If not found, point is left at top of buffer." (interactive) (maple-go-to-this-indent -1 (current-indentation)) (back-to-indentation)) (defun maple-forward-to-same-indent () "Move point forwards to nearest line with same indentation or less. If not found, point is left at start of last line in buffer." (interactive) (maple-go-to-this-indent 1 (current-indentation)) (back-to-indentation)) (defun maple-for () "Build skeleton for-loop statment, prompting for the loop parameters." (interactive) (let ((for (read-string "var: "))) (if (string-equal for "") (let ((to (read-string "to: "))) (if (not (string-equal to "")) (insert " to " to))) (insert "for " for) (let ((in (read-string "in: "))) (if (not (string-equal in "")) (insert " in " in) (let ((from (read-string "from: "))) (if (not (string-equal from "")) (insert " from " from))) (let ((by (read-string "by: "))) (if (not (string-equal by "")) (insert " by " by))) (let ((to (read-string "to: "))) (if (not (string-equal to "")) (insert " to " to))))))) (let ((while (read-string "while: "))) (if (not (string-equal while "")) (insert " while " while))) (insert " do") (maple-newline) (maple-newline) (insert "od;") (end-of-line 0) (maple-tab)) (defun maple-while () "Build skeleton while-loop statment, prompting for the loop parameters." (interactive) (insert "while " (read-string "cond: ")) (insert " do") (maple-newline) (maple-newline) (insert "od;") (end-of-line 0) (maple-tab)) (defun maple-header () "Insert a comment block containing the module title, author, etc." (interactive) (if (eq (point) (point-min)) nil (set-mark (point)) (goto-line 1)) (insert "\n\n") (previous-line 2) (insert "##-*-maple-*-") (insert "##\n## Title: \t") (insert (read-string "Title: ")) (insert "\n## Created:\t") (insert (current-time-string)) (insert "\n## Author: \t") (insert (user-full-name)) (insert (concat "\n##\t\t<" (user-login-name) "@" (system-name) ">\n")) (insert "##\n## Description: ") (end-of-line nil)) (defun maple-modify () "Insert a comment block containing the modification, author, etc." (interactive) (set-mark (point)) (goto-line 1) (while (char-equal (char-after (point)) 35) (forward-line 1)) (insert "##\n## Modified: \t") (insert (current-time-string)) (insert "\n## Author: \t") (insert (user-full-name)) (insert "\n## Modification: ") (insert (read-string "Modification: ")) (insert "\n##\n")) (defun maple-if () "Insert skeleton if statment, prompting for ." (interactive) (insert "if " (read-string "cond: ") " then") (maple-newline) (maple-newline) (insert "fi;") (end-of-line 0) (maple-tab)) (defun maple-else () "Add an elif clause to an if statement, prompting for the condition. When no condition is given, put an else." (interactive) (maple-untab) (let ((condition (read-string "elif: "))) (if (not (string-equal condition "")) (insert "elif " condition " then") (insert "else"))) (maple-newline) (maple-tab)) (defun maple-local () "Add a new local variable, inserting the word local if necessary." (interactive) (save-excursion (set-mark (point)) (while (or (> (current-indentation) 0) (looking-at "#") (looking-at "end") (looking-at "option")) (forward-line -1)) (let ((first-time)) (if (looking-at "local") (setq first-time nil) (forward-line 1) (insert "local ;\n") (forward-line -1) (setq first-time t)) (search-forward ";") (backward-char) (let ((newvar (read-string "New variable: "))) (if first-time (insert newvar) (insert ", " newvar)))))) (defun maple-procedure () (interactive) (let ((name (read-string "Name: " )) args) (insert name ":=proc (") (insert (read-string "Arguments: ") ")") (let ((options (read-string "Options: "))) (if (not (string-equal options "")) (progn (maple-newline) (insert "options " options ";")))) (maple-newline) (maple-newline) (insert "end: # ") (insert name) (end-of-line 0) (maple-tab))) (defun maple-paired-parens () "Insert a pair of round parentheses, placing point between them." (interactive) (insert "()") (backward-char)) (defun maple-inline-comment () "Start a comment after the end of the line, indented at least COMMENT-COLUMN. If starting after END-COMMENT-COLUMN, start a new line." (interactive) (end-of-line) (if (> (current-column) end-comment-column) (newline)) (if (< (current-column) comment-column) (indent-to comment-column)) (insert "# ")) (defun maple-display-comment () "Inserts 3 comment lines, making a display comment." (interactive) (insert "#\n# \n#") (end-of-line 0)) (defun maple-help () "Like describe-function in lisp-mode, tries to guess which function is interesting for the user and prompts for confirmation, then displays help. This could be much better if we called Maple to find the file, but I do not see how it could be as fast. A rather unsuccessful attempt has been made to make this work for help queries of the form \"index,library\". For an explanation of why this does not always work, see the file maple.el, comments to the function maple-help-file-name." (interactive) (save-excursion (let ((orig (point)) eow bow) (forward-word -1) (setq bow (point)) (forward-word 1) (setq eow (point)) (let* ((posfuncname (buffer-substring bow eow)) (funcname (read-string (if (string-equal posfuncname "") "Help about: " (concat "Help about [" posfuncname "]: "))))) (and (string-equal funcname "") (setq funcname posfuncname)) (let ((help-file-name (maple-help-file-name funcname))) (or help-file-name (error "Cannot find help for this function")) (with-output-to-temp-buffer "*Maple Help*" (buffer-flush-undo standard-output) (save-excursion (set-buffer standard-output) (insert-file-contents help-file-name)))))))) ;;; Assuming maple-lib-directory is "/usr/local/maple/lib", ;;; help(foo) looks at /usr/local/maple/lib/help/text/foo and ;;; help(foo,bar) looks at /usr/local/maple/lib/help/foo/text/bar. ;;; Except the latter IS NOT ALWAYS TRUE! For example, ;;; help(index,expressions) ;;; looks at /usr/local/maple/lib/help/index/text/expr. ;;; TO DO: Try to trick emacsclient to do the dirty work for us: ;;; let PAGER be emacsclient -maplehelp or something like it... (defun maple-help-file-name (topic) (let ((fname (cond ((string-match "^\\s-*\\(\\w+\\)\\s-*$" topic) (concat maple-lib-directory "/help/text/" (substring topic (match-beginning 1) (match-end 1)))) ((string-match "^\\s-*\\(\\w+\\)\\s-*,\\s-*\\(\\w+\\)\\s-*$" topic) (concat maple-lib-directory "/help/" (substring topic (match-beginning 1) (match-end 1)) "/text/" (substring topic (match-beginning 2) (match-end 2)))) (t nil)))) (and fname (file-exists-p fname) fname))) ;;; Invoking Maple in an inferior shell. (defun maple-define-common-keys (keymap) "Define the keys that we want defined both in maple-mode and in the maple-shell." (define-key keymap "\C-c\C-k" 'maple-kill-job)) ;; Lifted from comint-maple.el ;; (defun full-copy-sparse-keymap (km) "Recursively copy the sparse keymap KM" (cond ((consp km) (cons (full-copy-sparse-keymap (car km)) (full-copy-sparse-keymap (cdr km)))) (t km))) ;; end of lift (defvar run-maple2html-map nil "Keymap for the maple shell. A shell-mode-map with a few additions") (cond ((not run-maple2html-map) (setq run-maple2html-map (full-copy-sparse-keymap comint-mode-map)) (define-key run-maple2html-map "\C-c\C-s" 'comint-snarf-input) (define-key run-maple2html-map "\M-t" 'm2h-add-title) (define-key run-maple2html-map "\C-RET" 'do-display-math) )) (defvar maple-temp-directory "/tmp/" "*Directory in which to create temporary files.") (defvar zap-file nil "Temporary file name used for text being sent as input to Maple.") (defvar run-maple2html-mode-hook '() "*Hook for customising run-maple2html mode") ;;;; the mode is defined HERE (defun run-maple2html-mode () "Major mode for interacting with an inferior maple process for creating web pages in html. It works in combination with the perl program: maple2html or m2h. The perl program is executed automatically every time the buffer is saved. See the man page for m2h for information on what this program does. Variable inferior-maple-program controls which maple is run. Useful tips: 1) After creating an m2h file for the first time (usually with): C-x C-f foo-m2h RET maple will start running and you will see the header maple header. 2) To get rid of the header and to add a title for the file do: ESC-T This is the title of foo RET to change the title from anywhere in the buffer just do: ESC-t 3) with the point after the maple prompt >, do: ESC-i enter any foo bar text/html you want. you can also do this by hand by starting a line with the pound char #. 4) You can link an image (usually a gif file) by just starting a line with the char ! followed by the file containing the image like !foo.gif 5) RELOADING: ESC-= ... ESC-d If you visit an m2h file that already exists then maple will start running and the maple header will be displayed at the end of the file. To RELOAD the state that maple was in at the time this file was last saved and to get rid of the new maple header you need to do two things. First: ESC-= after maple finishes with the loading of the definitions etc... (this may take some time if you are visiting a file with lots of commands) do: ESC-d and all the output generated by the loading will be erased. At this point you find yourself at the same state you were when you last saved this file. 6) To erase the last (above) maple command and its output just do: ESC-d this deletes from the beginning of the line the point is on to the previous maple prompt >. 7) Maple commands must follow the maple prompt > and they are sent to maple to process with: ESC-RET 8) Plain RETurn can be used to split a large maple command into several lines. This is specially useful when entering maple procedures. When you are finished editing the commands and you are ready for maple to proccess them issue the ESC-RET. 9) Maple commands previously issued are remembered with ESC-p There are lots of other useful keys in this mode, just look at the bindings below. \\{run-maple2html-map} Customisation: Entry to this mode runs the hooks on comint-mode-hook and run-maple2html-mode-hook (in that order). switch-to-maple switches the current buffer to the Lisp process buffer. maple-eval-region sends the current region to the Lisp process. maple-eval-region-and-go switches to the Lisp process buffer after sending its text. If you accidentally suspend your process, use \\[comint-continue-subjob] to continue it." (interactive) (comint-mode) (setq m2h-buffer (buffer-name)) (make-m2h-comint m2h-buffer inferior-maple-program) (make-variable-buffer-local 'after-save-hook) (setq after-save-hook 'maple2html-execute) (setq comint-prompt-regexp "^\\(> \\)+ *") (setq major-mode 'run-maple2html-mode) (setq mode-name "Maple2Html Interaction") (setq mode-line-process '(": %s")) (use-local-map run-maple2html-map) (setq comint-input-sentinel 'ignore) (setq comint-get-old-input 'maple-get-old-input) (make-variable-buffer-local 'comint-process-echoes) (setq comint-process-echoes 1) (make-variable-buffer-local 'm2h-do-read-maple-file) (setq m2h-do-read-maple-file t) (add-hook 'comint-output-filter-functions 'kick-ctrl-m) (run-hooks 'run-maple2html-mode-hook)) ;(add-hook 'run-maple2html-mode-hook 'm2h-read-maple-file) (defun kick-ctrl-m (string) (save-excursion (beginning-of-line) (while (search-forward " " nil t) (replace-match "" nil t)))) (defun m2h-read-maple-file () "Reads the maple file filename.mpl at the beginning" (interactive) (setq m2h-maple-file (concat m2h-buffer ".mpl")) (if (and m2h-do-read-maple-file (file-exists-p m2h-maple-file)) (let (set-mark (point)) (insert-string (concat "read `" m2h-maple-file "`;")) (comint-send-input)) (insert "No .mpl file to be read"))) (defun maple2html-execute () "Basic function for calling maple2html." (interactive) (call-process "m2h" nil nil nil m2h-buffer)) (defun run-maple2html (m2h-buffer) "Run an inferior maple process, input and output via buffer m2h-buffer. If a process already running, switch to that buffer. Take program name from the variable inferior-maple-program. \(Type \\[describe-mode] in the process buffer for a list of commands.)" (interactive "BEnter name: ") (cond ((not (comint-check-proc m2h-buffer)) (set-buffer (make-m2h-comint m2h-buffer inferior-maple-program)) (run-maple2html-mode))) (setq run-maple2html-buffer m2h-buffer) ;;; ;; Get rid of the pesky echo! ;; ;; (setq comint-process-echoes 't) ;; ;;; (switch-to-buffer m2h-buffer)) (defun m2h-ask4-title-and-clean (title) "clean up the maple header and ask for title" (interactive "sEnter title: ") (save-excursion (let ((beg (goto-char (point-min))) (end (- (re-search-forward "^ ?> ") 2))) (delete-region beg end)) (goto-char (point-min)) (insert (concat "TITLE: " title "\n")))) (fset 'm2h 'run-maple2html) (defun switch-to-maple (eob-p) "Switch to the inferior maple process buffer. With argument, positions cursor at end of buffer." (interactive "P") (if (get-buffer run-maple2html-buffer) (switch-to-buffer run-maple2html-buffer) (error "No current process buffer. See variable run-maple2html-buffer.")) (cond (eob-p (push-mark) (goto-char (point-max))))) (defun maple-region-and-go (start end) "Send the current region to the inferior maple, and switch to the process buffer." (interactive "r") (maple-region start end) (switch-to-maple t)) (defun maple-region (start end) "Send the current region to the inferior maple process." (interactive "r") (run-maple2html) (comint-send-region (run-maple2html-proc) start end) (comint-send-string (run-maple2html-proc) "\n")) (defun run-maple2html-proc () "Returns the current run-maple2html process. See variable run-maple2html-buffer." (let ((proc (get-buffer-process (if (eq major-mode 'inferior-maple-mode) (current-buffer) run-maple2html-buffer)))) (or proc (error "No current process. See variable run-maple2html-buffer")))) (defun maple-buffer () "Send entire buffer to maple process." (interactive) (run-maple2html) (maple-region (point-min) (point-max))) (defun maple-pushop () (interactive) (insert-string "pushop(\");") (comint-send-input)) (defun maple-nextop () (interactive) (insert-string "nextop();") (comint-send-input)) (defun maple-lastop () (interactive) (insert-string "lastop();") (comint-send-input)) (defun maple-popop () (interactive) (insert-string "popop();") (comint-send-input)) (defun maple-simplify () (interactive) (insert-string "simplify(\");") (comint-send-input)) (defun maple-factor () (interactive) (insert-string "factor(\");") (comint-send-input)) (defun maple-expand () (interactive) (insert-string "expand(\");") (comint-send-input)) (defun maple-collect () (interactive) (insert-string "collect(\",indets(\"));") (comint-send-input)) ;;; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ;;; Here come my own additions (hanche 1990-11-19): (defvar maple-get-old-input-full t "If true, maple-get-old-input will search forward as well as backwards to find an expression to send to maple; otherwise, the forward extent is only as far as the end of the current line") (defun maple-get-old-input () "Suitable value for comint-get-old-input in maple process mode: Search backwards for a prompt, and send everything from the prompt to the end of the current line. If the variable maple-get-old-input-full is true, include a search forward for a line ending with a colon or semicolon" (interactive) (save-excursion (or (and maple-get-old-input-full (progn (beginning-of-line) (re-search-forward "[:;]\\s *$" (point-max) t))) (end-of-line)) (let ((here (point))) (if (not (re-search-backward comint-prompt-regexp (point-min) t)) (error "Could not find a prompt before point") (buffer-substring (match-end 0) here))))) (defun comint-snarf-input () "Snarf input and copy to end of buffer just like comint-send-input does, but do not submit the input to the process. See the documentation for comint-send-input for the hairy details." (interactive) (let ((proc (get-buffer-process (current-buffer)))) (if (not proc) (error "Current buffer has no process") (let* ((pmark (process-mark proc)) (pmark-val (marker-position pmark))) (if (>= (point) pmark-val) () (let ((copy (funcall comint-get-old-input))) (goto-char pmark) (insert copy))))))) (defun comint-set-process-filter (filter) "Make FILTER the process filter for the process running in the current buffer." (let ((proc (get-buffer-process (current-buffer)))) (if proc (set-process-filter proc filter) (error "This buffer has no process")))) ;;; The following is for test purposes. When done, build into the code ;;; for run-maple2html itself? ;(setq run-maple2html-mode-hook ; (function (lambda () ; (comint-set-process-filter 'maple-process-filter)))) (add-hook 'run-maple2html-mode-hook '(lambda () (comint-set-process-filter 'maple-process-filter))) ; (defvar debug-strings-log nil "*Strings from the Maple process") (defun maple-process-filter (proc string) ;; (setq debug-strings-log (cons string debug-strings-log)) (let ((cbuf (current-buffer)) (save-match-data (match-data)) (proc-marker (process-mark proc)) (user-marker (point-marker))) (unwind-protect (progn (set-buffer (process-buffer proc)) (if (fboundp 'comint-proc-prefilter) (setq string (comint-proc-prefilter string))) (goto-char proc-marker) (insert string) (let ((here (point-marker))) ;; Remove all kinds of extra prompt pieces. ; (goto-char proc-marker) ; (beginning-of-line) ; (if (looking-at "^\\(\\(> \\)+\\).") ; (delete-region (match-beginning 1) (match-end 1))) (if (= proc-marker user-marker) (goto-char here) (goto-char user-marker)) (set-marker proc-marker here) ; Delete unneded markers in the buffer: (set-marker user-marker nil) (set-marker here nil))) ;; safely exit the filter (set-buffer cbuf) (store-match-data save-match-data)))) (defun comint-proc-prefilter (string) "Delete null characters from process output." (save-excursion (set-buffer (get-buffer-create "* tmp *")) (insert string) (beginning-of-buffer) (replace-string "\0" "") (prog1 (buffer-string) (kill-buffer (current-buffer))))) (define-key run-maple2html-map "\C-m" 'maple-newline) (define-key run-maple2html-map "\C-\M-m" 'comint-send-input) (defun maple-debug-goto-proc-marker () (interactive) (let* ((proc (get-buffer-process (current-buffer))) (marker (process-mark proc))) (goto-char marker))) (define-key run-maple2html-map "\M-m" 'maple2html-execute) (define-key run-maple2html-map "\M-d" 'm2h-delete-previous-maple-output) (define-key run-maple2html-map "\M-=" 'm2h-pickup-from-last.el) (define-key run-maple2html-map "\M-r" 'm2h-read-maple-file) (define-key run-maple2html-map "\M-t" 'm2h-add-title) (define-key run-maple2html-map "\M-T" 'm2h-ask4-title-and-clean) (define-key run-maple2html-map "\M-i" 'm2h-add-text) ;;;lifted from comint.el (defun comint-check-proc (buffer) "Return t if there is a living process associated w/buffer BUFFER. Living means the status is `open', `run', or `stop'. BUFFER can be either a buffer or the name of one." (let ((proc (get-buffer-process buffer))) (and proc (memq (process-status proc) '(open run stop))))) ;; Note that this guy, unlike shell.el's make-shell, barfs if you pass it () ;; for the second argument (program). ;;;###autoload (defun make-m2h-comint (name program &optional startfile &rest switches) "Make a comint process NAME in a buffer, running PROGRAM. The name of the buffer is NOT made by surrounding NAME with `*'s. PROGRAM should be either a string denoting an executable program to create via `start-process', or a cons pair of the form (HOST . SERVICE) denoting a TCP connection to be opened via `open-network-stream'. If there is already a running process in that buffer, it is not restarted. Optional third arg STARTFILE is the name of a file to send the contents of to the process. If PROGRAM is a string, any more args are arguments to PROGRAM." (or (fboundp 'start-process) (error "Multi-processing is not supported for this system")) (let ((buffer (get-buffer-create name ))) ;; If no process, or nuked process, crank up a new one and put buffer in ;; comint mode. Otherwise, leave buffer and existing process alone. (cond ((not (comint-check-proc buffer)) (save-excursion (set-buffer buffer) (comint-mode)) ; Install local vars, mode, keymap, ... (comint-exec buffer name program startfile switches))) buffer))