dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

ob-maxima.el (4775B)


      1 ;;; ob-maxima.el --- Babel Functions for Maxima      -*- lexical-binding: t; -*-
      2 
      3 ;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
      4 
      5 ;; Author: Eric S Fraga
      6 ;;	Eric Schulte
      7 ;; Keywords: literate programming, reproducible research, maxima
      8 ;; URL: https://orgmode.org
      9 
     10 ;; This file is part of GNU Emacs.
     11 
     12 ;; GNU Emacs is free software: you can redistribute it and/or modify
     13 ;; it under the terms of the GNU General Public License as published by
     14 ;; the Free Software Foundation, either version 3 of the License, or
     15 ;; (at your option) any later version.
     16 
     17 ;; GNU Emacs is distributed in the hope that it will be useful,
     18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 ;; GNU General Public License for more details.
     21 
     22 ;; You should have received a copy of the GNU General Public License
     23 ;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
     24 
     25 ;;; Commentary:
     26 
     27 ;; Org-Babel support for evaluating maxima entries.
     28 ;;
     29 ;; This differs from most standard languages in that
     30 ;; 1) there is no such thing as a "session" in maxima
     31 ;; 2) we are adding the "cmdline" header argument
     32 
     33 ;;; Code:
     34 
     35 (require 'org-macs)
     36 (org-assert-version)
     37 
     38 (require 'ob)
     39 
     40 (defvar org-babel-tangle-lang-exts)
     41 (add-to-list 'org-babel-tangle-lang-exts '("maxima" . "max"))
     42 
     43 (defvar org-babel-default-header-args:maxima '())
     44 
     45 (defcustom org-babel-maxima-command
     46   (if (boundp 'maxima-command) maxima-command "maxima")
     47   "Command used to call maxima on the shell."
     48   :group 'org-babel
     49   :type 'string)
     50 
     51 (defun org-babel-maxima-expand (body params)
     52   "Expand a block of Maxima code according to its header arguments."
     53   (let ((vars (org-babel--get-vars params))
     54 	(epilogue (cdr (assq :epilogue params)))
     55 	(prologue (cdr (assq :prologue params))))
     56     (mapconcat 'identity
     57 	       (list
     58 		;; Any code from the specified prologue at the start.
     59 		prologue
     60 		;; graphic output
     61 		(let ((graphic-file (ignore-errors (org-babel-graphical-output-file params))))
     62 		  (if graphic-file
     63 		      (format
     64 		       "set_plot_option ([gnuplot_term, png]); set_plot_option ([gnuplot_out_file, %S]);"
     65 		       graphic-file)
     66 		    ""))
     67 		;; variables
     68 		(mapconcat 'org-babel-maxima-var-to-maxima vars "\n")
     69 		;; body
     70 		body
     71 		;; Any code from the specified epilogue at the end.
     72 		epilogue
     73 		"gnuplot_close ()$")
     74 	       "\n")))
     75 
     76 (defun org-babel-execute:maxima (body params)
     77   "Execute a block of Maxima entries with org-babel.
     78 This function is called by `org-babel-execute-src-block'."
     79   (message "Executing Maxima source code block")
     80   (let ((result-params (split-string (or (cdr (assq :results params)) "")))
     81 	(result
     82 	 (let* ((cmdline (or (cdr (assq :cmdline params)) ""))
     83 		(in-file (org-babel-temp-file "maxima-" ".max"))
     84 		(cmd (format "%s --very-quiet -r %s %s"
     85 			     org-babel-maxima-command
     86                              (shell-quote-argument
     87                               (format "batchload(%S)$" in-file))
     88                              cmdline)))
     89 	   (with-temp-file in-file (insert (org-babel-maxima-expand body params)))
     90 	   (message cmd)
     91            ;; " | grep -v batch | grep -v 'replaced' | sed '/^$/d' "
     92 	   (let ((raw (org-babel-eval cmd "")))
     93              (mapconcat
     94               #'identity
     95               (delq nil
     96                     (mapcar (lambda (line)
     97                               (unless (or (string-match "batch" line)
     98                                           (string-match "^rat: replaced .*$" line)
     99                                           (string-match "^;;; Loading #P" line)
    100                                           (= 0 (length line)))
    101                                 line))
    102                             (split-string raw "[\r\n]"))) "\n")))))
    103     (if (ignore-errors (org-babel-graphical-output-file params))
    104 	nil
    105       (org-babel-result-cond result-params
    106 	result
    107 	(let ((tmp-file (org-babel-temp-file "maxima-res-")))
    108 	  (with-temp-file tmp-file (insert result))
    109 	  (org-babel-import-elisp-from-file tmp-file))))))
    110 
    111 
    112 (defun org-babel-prep-session:maxima (_session _params)
    113   (error "Maxima does not support sessions"))
    114 
    115 (defun org-babel-maxima-var-to-maxima (pair)
    116   "Convert an elisp val into a string of maxima code specifying a var
    117 of the same value."
    118   (let ((var (car pair))
    119         (val (cdr pair)))
    120     (when (symbolp val)
    121       (setq val (symbol-name val))
    122       (when (= (length val) 1)
    123         (setq val (string-to-char val))))
    124     (format "%S: %s$" var
    125 	    (org-babel-maxima-elisp-to-maxima val))))
    126 
    127 (defun org-babel-maxima-elisp-to-maxima (val)
    128   "Return a string of maxima code which evaluates to VAL."
    129   (if (listp val)
    130       (concat "[" (mapconcat #'org-babel-maxima-elisp-to-maxima val ", ") "]")
    131     (format "%s" val)))
    132 
    133 (provide 'ob-maxima)
    134 
    135 ;;; ob-maxima.el ends here