Commit | Line | Data |
---|---|---|
86fbb8ca CD |
1 | ;;; ob-asymptote.el --- org-babel functions for asymptote evaluation |
2 | ||
73b0cd50 | 3 | ;; Copyright (C) 2009-2011 Free Software Foundation, Inc. |
86fbb8ca CD |
4 | |
5 | ;; Author: Eric Schulte | |
6 | ;; Keywords: literate programming, reproducible research | |
7 | ;; Homepage: http://orgmode.org | |
acedf35c | 8 | ;; Version: 7.4 |
86fbb8ca CD |
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 <http://www.gnu.org/licenses/>. | |
24 | ||
25 | ;;; Commentary: | |
26 | ||
27 | ;; Org-Babel support for evaluating asymptote source code. | |
28 | ;; | |
29 | ;; This differs from most standard languages in that | |
30 | ;; | |
31 | ;; 1) there is no such thing as a "session" in asymptote | |
32 | ;; | |
33 | ;; 2) we are generally only going to return results of type "file" | |
34 | ;; | |
35 | ;; 3) we are adding the "file" and "cmdline" header arguments, if file | |
36 | ;; is omitted then the -V option is passed to the asy command for | |
37 | ;; interactive viewing | |
38 | ||
39 | ;;; Requirements: | |
40 | ||
41 | ;; - The asymptote program :: http://asymptote.sourceforge.net/ | |
42 | ;; | |
43 | ;; - asy-mode :: Major mode for editing asymptote files | |
44 | ||
45 | ;;; Code: | |
46 | (require 'ob) | |
47 | (eval-when-compile (require 'cl)) | |
48 | ||
49 | (declare-function orgtbl-to-generic "org-table" (table params)) | |
50 | (declare-function org-combine-plists "org" (&rest plists)) | |
51 | ||
52 | (add-to-list 'org-babel-tangle-lang-exts '("asymptote" . "asy")) | |
53 | ||
54 | (defvar org-babel-default-header-args:asymptote | |
55 | '((:results . "file") (:exports . "results")) | |
56 | "Default arguments when evaluating an Asymptote source block.") | |
57 | ||
86fbb8ca CD |
58 | (defun org-babel-execute:asymptote (body params) |
59 | "Execute a block of Asymptote code. | |
60 | This function is called by `org-babel-execute-src-block'." | |
afe98dfa | 61 | (let* ((result-params (split-string (or (cdr (assoc :results params)) ""))) |
86fbb8ca CD |
62 | (out-file (cdr (assoc :file params))) |
63 | (format (or (and out-file | |
64 | (string-match ".+\\.\\(.+\\)" out-file) | |
65 | (match-string 1 out-file)) | |
66 | "pdf")) | |
67 | (cmdline (cdr (assoc :cmdline params))) | |
afe98dfa CD |
68 | (in-file (org-babel-temp-file "asymptote-")) |
69 | (cmd | |
70 | (concat "asy " | |
71 | (if out-file | |
72 | (concat | |
73 | "-globalwrite -f " format | |
74 | " -o " (org-babel-process-file-name out-file)) | |
75 | "-V") | |
76 | " " cmdline | |
77 | " " (org-babel-process-file-name in-file)))) | |
86fbb8ca | 78 | (with-temp-file in-file |
afe98dfa CD |
79 | (insert (org-babel-expand-body:generic |
80 | body params | |
81 | (org-babel-variable-assignments:asymptote params)))) | |
86fbb8ca CD |
82 | (message cmd) (shell-command cmd) |
83 | out-file)) | |
84 | ||
85 | (defun org-babel-prep-session:asymptote (session params) | |
86 | "Return an error if the :session header argument is set. | |
87 | Asymptote does not support sessions" | |
88 | (error "Asymptote does not support sessions")) | |
89 | ||
afe98dfa CD |
90 | (defun org-babel-variable-assignments:asymptote (params) |
91 | "Return list of asymptote statements assigning the block's variables" | |
92 | (mapcar #'org-babel-asymptote-var-to-asymptote | |
93 | (mapcar #'cdr (org-babel-get-header params :var)))) | |
94 | ||
86fbb8ca CD |
95 | (defun org-babel-asymptote-var-to-asymptote (pair) |
96 | "Convert an elisp value into an Asymptote variable. | |
97 | The elisp value PAIR is converted into Asymptote code specifying | |
98 | a variable of the same value." | |
99 | (let ((var (car pair)) | |
100 | (val (if (symbolp (cdr pair)) | |
101 | (symbol-name (cdr pair)) | |
102 | (cdr pair)))) | |
103 | (cond | |
104 | ((integerp val) | |
105 | (format "int %S=%S;" var val)) | |
106 | ((floatp val) | |
107 | (format "real %S=%S;" var val)) | |
108 | ((stringp val) | |
109 | (format "string %S=\"%s\";" var val)) | |
110 | ((listp val) | |
111 | (let* ((dimension-2-p (not (null (cdr val)))) | |
112 | (dim (if dimension-2-p "[][]" "[]")) | |
113 | (type (org-babel-asymptote-define-type val)) | |
114 | (array (org-babel-asymptote-table-to-array | |
115 | val | |
116 | (if dimension-2-p '(:lstart "{" :lend "}," :llend "}"))))) | |
117 | (format "%S%s %S=%s;" type dim var array)))))) | |
118 | ||
119 | (defun org-babel-asymptote-table-to-array (table params) | |
120 | "Convert values of an elisp table into a string of an asymptote array. | |
121 | Empty cells are ignored." | |
122 | (labels ((atom-to-string (table) | |
123 | (cond | |
124 | ((null table) '()) | |
125 | ((not (listp (car table))) | |
126 | (cons (if (and (stringp (car table)) | |
127 | (not (string= (car table) ""))) | |
128 | (format "\"%s\"" (car table)) | |
129 | (format "%s" (car table))) | |
130 | (atom-to-string (cdr table)))) | |
131 | (t | |
132 | (cons (atom-to-string (car table)) | |
133 | (atom-to-string (cdr table)))))) | |
134 | ;; Remove any empty row | |
135 | (fix-empty-lines (table) | |
136 | (delq nil (mapcar (lambda (l) (delq "" l)) table)))) | |
137 | (orgtbl-to-generic | |
138 | (fix-empty-lines (atom-to-string table)) | |
139 | (org-combine-plists '(:hline nil :sep "," :tstart "{" :tend "}") params)))) | |
140 | ||
141 | (defun org-babel-asymptote-define-type (data) | |
142 | "Determine type of DATA. | |
143 | DATA is a list. Type symbol is returned as 'symbol. The type is | |
144 | usually the type of the first atom encountered, except for arrays | |
145 | of int, where every cell must be of int type." | |
146 | (labels ((anything-but-int (el) | |
147 | (cond | |
148 | ((null el) nil) | |
149 | ((not (listp (car el))) | |
150 | (cond | |
151 | ((floatp (car el)) 'real) | |
152 | ((stringp (car el)) 'string) | |
153 | (t | |
154 | (anything-but-int (cdr el))))) | |
155 | (t | |
156 | (or (anything-but-int (car el)) | |
157 | (anything-but-int (cdr el))))))) | |
158 | (or (anything-but-int data) 'int))) | |
159 | ||
160 | (provide 'ob-asymptote) | |
161 | ||
86fbb8ca CD |
162 | |
163 | ;;; ob-asymptote.el ends here |