Commit | Line | Data |
---|---|---|
3ab2c837 BG |
1 | ;;; ob-maxima.el --- org-babel functions for maxima evaluation |
2 | ||
ba318903 | 3 | ;; Copyright (C) 2009-2014 Free Software Foundation, Inc. |
3ab2c837 | 4 | |
09ade3a3 | 5 | ;; Author: Eric S Fraga |
dfd98937 | 6 | ;; Eric Schulte |
3ab2c837 BG |
7 | ;; Keywords: literate programming, reproducible research, maxima |
8 | ;; Homepage: http://orgmode.org | |
3ab2c837 | 9 | |
09ade3a3 | 10 | ;; This file is part of GNU Emacs. |
3ab2c837 | 11 | |
09ade3a3 | 12 | ;; GNU Emacs is free software: you can redistribute it and/or modify |
3ab2c837 | 13 | ;; it under the terms of the GNU General Public License as published by |
09ade3a3 GM |
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, | |
3ab2c837 BG |
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. | |
09ade3a3 | 21 | |
3ab2c837 | 22 | ;; You should have received a copy of the GNU General Public License |
09ade3a3 | 23 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
3ab2c837 BG |
24 | |
25 | ;;; Commentary: | |
26 | ||
27 | ;; Org-Babel support for evaluating maxima entries. | |
28 | ;; | |
29 | ;; This differs from most standard languages in that | |
30 | ;; | |
31 | ;; 1) there is no such thing as a "session" in maxima | |
32 | ;; | |
e66ba1df | 33 | ;; 2) we are adding the "cmdline" header argument |
3ab2c837 BG |
34 | |
35 | ;;; Code: | |
36 | (require 'ob) | |
37 | ||
e66ba1df BG |
38 | (defvar org-babel-tangle-lang-exts) |
39 | (add-to-list 'org-babel-tangle-lang-exts '("maxima" . "max")) | |
40 | ||
3ab2c837 BG |
41 | (defvar org-babel-default-header-args:maxima '()) |
42 | ||
153ae947 BG |
43 | (defcustom org-babel-maxima-command |
44 | (if (boundp 'maxima-command) maxima-command "maxima") | |
45 | "Command used to call maxima on the shell." | |
3c8b09ca BG |
46 | :group 'org-babel |
47 | :type 'string) | |
153ae947 | 48 | |
3ab2c837 BG |
49 | (defun org-babel-maxima-expand (body params) |
50 | "Expand a block of Maxima code according to its header arguments." | |
e66ba1df | 51 | (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))) |
8223b1d2 BG |
52 | (mapconcat 'identity |
53 | (list | |
54 | ;; graphic output | |
55 | (let ((graphic-file (org-babel-maxima-graphical-output-file params))) | |
56 | (if graphic-file | |
57 | (format | |
58 | "set_plot_option ([gnuplot_term, png]); set_plot_option ([gnuplot_out_file, %S]);" | |
59 | graphic-file) | |
60 | "")) | |
61 | ;; variables | |
62 | (mapconcat 'org-babel-maxima-var-to-maxima vars "\n") | |
63 | ;; body | |
64 | body | |
65 | "gnuplot_close ()$") | |
66 | "\n"))) | |
3ab2c837 BG |
67 | |
68 | (defun org-babel-execute:maxima (body params) | |
666ffc7e SM |
69 | "Execute a block of Maxima entries with org-babel. |
70 | This function is called by `org-babel-execute-src-block'." | |
3ab2c837 | 71 | (message "executing Maxima source code block") |
d660637a BG |
72 | (let ((result-params (split-string (or (cdr (assoc :results params)) ""))) |
73 | (result | |
8223b1d2 | 74 | (let* ((cmdline (or (cdr (assoc :cmdline params)) "")) |
e66ba1df | 75 | (in-file (org-babel-temp-file "maxima-" ".max")) |
153ae947 BG |
76 | (cmd (format "%s --very-quiet -r 'batchload(%S)$' %s" |
77 | org-babel-maxima-command in-file cmdline))) | |
e66ba1df BG |
78 | (with-temp-file in-file (insert (org-babel-maxima-expand body params))) |
79 | (message cmd) | |
666ffc7e SM |
80 | ;; " | grep -v batch | grep -v 'replaced' | sed '/^$/d' " |
81 | (let ((raw (org-babel-eval cmd ""))) | |
82 | (mapconcat | |
83 | #'identity | |
84 | (delq nil | |
85 | (mapcar (lambda (line) | |
86 | (unless (or (string-match "batch" line) | |
87 | (string-match "^rat: replaced .*$" line) | |
88 | (string-match "^;;; Loading #P" line) | |
89 | (= 0 (length line))) | |
90 | line)) | |
91 | (split-string raw "[\r\n]"))) "\n"))))) | |
e66ba1df BG |
92 | (if (org-babel-maxima-graphical-output-file params) |
93 | nil | |
271672fa BG |
94 | (org-babel-result-cond result-params |
95 | result | |
e66ba1df BG |
96 | (let ((tmp-file (org-babel-temp-file "maxima-res-"))) |
97 | (with-temp-file tmp-file (insert result)) | |
98 | (org-babel-import-elisp-from-file tmp-file)))))) | |
99 | ||
3ab2c837 BG |
100 | |
101 | (defun org-babel-prep-session:maxima (session params) | |
102 | (error "Maxima does not support sessions")) | |
103 | ||
e66ba1df BG |
104 | (defun org-babel-maxima-var-to-maxima (pair) |
105 | "Convert an elisp val into a string of maxima code specifying a var | |
106 | of the same value." | |
107 | (let ((var (car pair)) | |
108 | (val (cdr pair))) | |
109 | (when (symbolp val) | |
110 | (setq val (symbol-name val)) | |
111 | (when (= (length val) 1) | |
112 | (setq val (string-to-char val)))) | |
8223b1d2 BG |
113 | (format "%S: %s$" var |
114 | (org-babel-maxima-elisp-to-maxima val)))) | |
e66ba1df BG |
115 | |
116 | (defun org-babel-maxima-graphical-output-file (params) | |
117 | "Name of file to which maxima should send graphical output." | |
118 | (and (member "graphics" (cdr (assq :result-params params))) | |
119 | (cdr (assq :file params)))) | |
120 | ||
121 | (defun org-babel-maxima-elisp-to-maxima (val) | |
122 | "Return a string of maxima code which evaluates to VAL." | |
123 | (if (listp val) | |
124 | (concat "[" (mapconcat #'org-babel-maxima-elisp-to-maxima val ", ") "]") | |
125 | (format "%s" val))) | |
126 | ||
127 | ||
3ab2c837 BG |
128 | (provide 'ob-maxima) |
129 | ||
5b409b39 | 130 | |
3ab2c837 BG |
131 | |
132 | ;;; ob-maxima.el ends here |