babel: remove all language file reference to define language variables
[org-mode.git] / lisp / babel / langs / ob-gnuplot.el
blobe114663779ee48a91d26d3f1be2b98fc274ad608
1 ;;; ob-gnuplot.el --- org-babel functions for gnuplot evaluation
3 ;; Copyright (C) 2009 Eric Schulte
5 ;; Author: Eric Schulte
6 ;; Keywords: literate programming, reproducible research
7 ;; Homepage: http://orgmode.org
8 ;; Version: 0.01
10 ;;; License:
12 ;; This program 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, or (at your option)
15 ;; any later version.
17 ;; This program 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.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
27 ;;; Commentary:
29 ;; Org-Babel support for evaluating gnuplot source code.
31 ;; This differs from most standard languages in that
33 ;; 1) we are generally only going to return results of type "file"
35 ;; 2) we are adding the "file" and "cmdline" header arguments
37 ;;; Requirements:
39 ;; - gnuplot :: http://www.gnuplot.info/
40 ;;
41 ;; - gnuplot-mode :: http://cars9.uchicago.edu/~ravel/software/gnuplot-mode.html
43 ;;; Code:
44 (require 'ob)
45 (require 'gnuplot)
47 (defvar org-babel-default-header-args:gnuplot
48 '((:results . "file") (:exports . "results") (:session . nil))
49 "Default arguments to use when evaluating a gnuplot source block.")
51 (defvar org-babel-gnuplot-timestamp-fmt nil)
53 (defun org-babel-gnuplot-process-vars (params)
54 "Extract variables from PARAMS and process the variables
55 dumping all vectors into files and returning an association list
56 of variable names and the related value to be used in the gnuplot
57 code."
58 (mapcar
59 (lambda (pair)
60 (cons
61 (car pair) ;; variable name
62 (if (listp (cdr pair)) ;; variable value
63 (org-babel-gnuplot-table-to-data
64 (cdr pair) (make-temp-file "org-babel-gnuplot") params)
65 (cdr pair))))
66 (org-babel-ref-variables params)))
68 (defun org-babel-expand-body:gnuplot (body params &optional processed-params)
69 "Expand BODY according to PARAMS, return the expanded body."
70 (save-window-excursion
71 (let* ((vars (org-babel-gnuplot-process-vars params))
72 (out-file (cdr (assoc :file params)))
73 (term (or (cdr (assoc :term params))
74 (when out-file (file-name-extension out-file))))
75 (cmdline (cdr (assoc :cmdline params)))
76 (title (plist-get params :title))
77 (lines (plist-get params :line))
78 (sets (plist-get params :set))
79 (x-labels (plist-get params :xlabels))
80 (y-labels (plist-get params :ylabels))
81 (timefmt (plist-get params :timefmt))
82 (time-ind (or (plist-get params :timeind)
83 (when timefmt 1)))
84 output)
85 (flet ((add-to-body (text)
86 (setq body (concat text "\n" body))))
87 ;; append header argument settings to body
88 (when title (add-to-body (format "set title '%s'" title))) ;; title
89 (when lines (mapc (lambda (el) (add-to-body el)) lines)) ;; line
90 (when sets
91 (mapc (lambda (el) (add-to-body (format "set %s" el))) sets))
92 (when x-labels
93 (add-to-body
94 (format "set xtics (%s)"
95 (mapconcat (lambda (pair)
96 (format "\"%s\" %d" (cdr pair) (car pair)))
97 x-labels ", "))))
98 (when y-labels
99 (add-to-body
100 (format "set ytics (%s)"
101 (mapconcat (lambda (pair)
102 (format "\"%s\" %d" (cdr pair) (car pair)))
103 y-labels ", "))))
104 (when time-ind
105 (add-to-body "set xdata time")
106 (add-to-body (concat "set timefmt \""
107 (or timefmt
108 "%Y-%m-%d-%H:%M:%S") "\"")))
109 (when out-file (add-to-body (format "set output \"%s\"" out-file)))
110 (when term (add-to-body (format "set term %s" term)))
111 ;; insert variables into code body: this should happen last
112 ;; placing the variables at the *top* of the code in case their
113 ;; values are used later
114 (add-to-body (mapconcat
115 (lambda (pair) (format "%s = \"%s\"" (car pair) (cdr pair)))
116 vars "\n"))
117 ;; replace any variable names preceded by '$' with the actual
118 ;; value of the variable
119 (mapc (lambda (pair)
120 (setq body (replace-regexp-in-string
121 (format "\\$%s" (car pair)) (cdr pair) body)))
122 vars))
123 body)))
125 (defun org-babel-execute:gnuplot (body params)
126 "Execute a block of Gnuplot code with org-babel. This function is
127 called by `org-babel-execute-src-block'."
128 (message "executing Gnuplot source code block")
129 (let ((session (cdr (assoc :session params)))
130 (result-type (cdr (assoc :results params)))
131 (out-file (cdr (assoc :file params)))
132 (body (org-babel-expand-body:gnuplot body params)))
133 (save-window-excursion
134 ;; evaluate the code body with gnuplot
135 (if (string= session "none")
136 (let ((script-file (make-temp-file "org-babel-gnuplot-script")))
137 (with-temp-file script-file
138 (insert (concat body "\n")))
139 (message "gnuplot \"%s\"" script-file)
140 (setq output
141 (shell-command-to-string (format "gnuplot \"%s\"" script-file)))
142 (message output))
143 (with-temp-buffer
144 (insert (concat body "\n"))
145 (gnuplot-mode)
146 (gnuplot-send-buffer-to-gnuplot)))
147 (if (member "output" (split-string result-type))
148 output
149 out-file))))
151 (defun org-babel-prep-session:gnuplot (session params)
152 "Prepare SESSION according to the header arguments specified in PARAMS."
153 (let* ((session (org-babel-gnuplot-initiate-session session))
154 (vars (org-babel-ref-variables params))
155 (var-lines (mapcar
156 (lambda (pair) (format "%s = \"%s\"" (car pair) (cdr pair)))
157 vars)))
158 (message "%S" session)
159 (org-babel-comint-in-buffer session
160 (mapc (lambda (var-line)
161 (insert var-line) (comint-send-input nil t)
162 (org-babel-comint-wait-for-output session)
163 (sit-for .1) (goto-char (point-max))) var-lines))
164 session))
166 (defun org-babel-load-session:gnuplot (session body params)
167 "Load BODY into SESSION."
168 (save-window-excursion
169 (let ((buffer (org-babel-prep-session:gnuplot session params)))
170 (with-current-buffer buffer
171 (goto-char (process-mark (get-buffer-process (current-buffer))))
172 (insert (org-babel-chomp body)))
173 buffer)))
175 (defun org-babel-gnuplot-initiate-session (&optional session params)
176 "If there is not a current inferior-process-buffer in SESSION
177 then create one. Return the initialized session. The current
178 `gnuplot-mode' doesn't provide support for multiple sessions."
179 (unless (string= session "none")
180 (save-window-excursion (gnuplot-send-string-to-gnuplot "" "line")
181 gnuplot-buffer)))
183 (defun org-babel-gnuplot-quote-timestamp-field (s)
184 "Convert field S from timestamp to Unix time and export to gnuplot."
185 (format-time-string org-babel-gnuplot-timestamp-fmt (org-time-string-to-time s)))
187 (defun org-babel-gnuplot-quote-tsv-field (s)
188 "Quote field S for export to gnuplot."
189 (unless (stringp s)
190 (setq s (format "%s" s)))
191 (if (string-match org-table-number-regexp s) s
192 (if (string-match org-ts-regexp3 s)
193 (org-babel-gnuplot-quote-timestamp-field s)
194 (concat "\"" (mapconcat 'identity (split-string s "\"") "\"\"") "\""))))
196 (defun org-babel-gnuplot-table-to-data (table data-file params)
197 "Export TABLE to DATA-FILE in a format readable by gnuplot.
198 Pass PARAMS through to `orgtbl-to-generic' when exporting TABLE."
199 (with-temp-file data-file
200 (make-local-variable 'org-babel-gnuplot-timestamp-fmt)
201 (setq org-babel-gnuplot-timestamp-fmt (or
202 (plist-get params :timefmt)
203 "%Y-%m-%d-%H:%M:%S"))
204 (insert (orgtbl-to-generic
205 table
206 (org-combine-plists
207 '(:sep "\t" :fmt org-babel-gnuplot-quote-tsv-field)
208 params))))
209 data-file)
211 (provide 'ob-gnuplot)
212 ;;; ob-gnuplot.el ends here