Commit | Line | Data |
---|---|---|
86fbb8ca CD |
1 | ;;; ob-table.el --- support for calling org-babel functions from tables |
2 | ||
ba318903 | 3 | ;; Copyright (C) 2009-2014 Free Software Foundation, Inc. |
86fbb8ca CD |
4 | |
5 | ;; Author: Eric Schulte | |
6 | ;; Keywords: literate programming, reproducible research | |
7 | ;; Homepage: http://orgmode.org | |
86fbb8ca CD |
8 | |
9 | ;; This file is part of GNU Emacs. | |
10 | ||
11 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
12 | ;; it under the terms of the GNU General Public License as published by | |
13 | ;; the Free Software Foundation, either version 3 of the License, or | |
14 | ;; (at your option) any later version. | |
15 | ||
16 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | ;; GNU General Public License for more details. | |
20 | ||
21 | ;; You should have received a copy of the GNU General Public License | |
22 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
23 | ||
24 | ;;; Commentary: | |
25 | ||
26 | ;; Should allow calling functions from org-mode tables using the | |
30cb51f1 | 27 | ;; function `org-sbe' as so... |
86fbb8ca CD |
28 | |
29 | ;; #+begin_src emacs-lisp :results silent | |
30 | ;; (defun fibbd (n) (if (< n 2) 1 (+ (fibbd (- n 1)) (fibbd (- n 2))))) | |
31 | ;; #+end_src | |
32 | ||
e66ba1df | 33 | ;; #+name: fibbd |
86fbb8ca CD |
34 | ;; #+begin_src emacs-lisp :var n=2 :results silent |
35 | ;; (fibbd n) | |
36 | ;; #+end_src | |
37 | ||
38 | ;; | original | fibbd | | |
39 | ;; |----------+--------| | |
40 | ;; | 0 | | | |
41 | ;; | 1 | | | |
42 | ;; | 2 | | | |
43 | ;; | 3 | | | |
44 | ;; | 4 | | | |
45 | ;; | 5 | | | |
46 | ;; | 6 | | | |
47 | ;; | 7 | | | |
48 | ;; | 8 | | | |
49 | ;; | 9 | | | |
30cb51f1 | 50 | ;; #+TBLFM: $2='(org-sbe 'fibbd (n $1)) |
86fbb8ca CD |
51 | |
52 | ;;; Code: | |
271672fa | 53 | (require 'ob-core) |
86fbb8ca CD |
54 | |
55 | (defun org-babel-table-truncate-at-newline (string) | |
56 | "Replace newline character with ellipses. | |
57 | If STRING ends in a newline character, then remove the newline | |
58 | character and replace it with ellipses." | |
acedf35c CD |
59 | (if (and (stringp string) (string-match "[\n\r]\\(.\\)?" string)) |
60 | (concat (substring string 0 (match-beginning 0)) | |
61 | (if (match-string 1 string) "...")) string)) | |
86fbb8ca | 62 | |
30cb51f1 | 63 | (defmacro org-sbe (source-block &rest variables) |
86fbb8ca CD |
64 | "Return the results of calling SOURCE-BLOCK with VARIABLES. |
65 | Each element of VARIABLES should be a two | |
66 | element list, whose first element is the name of the variable and | |
67 | second element is a string of its value. The following call to | |
30cb51f1 | 68 | `org-sbe' would be equivalent to the following source code block. |
86fbb8ca | 69 | |
30cb51f1 | 70 | (org-sbe 'source-block (n $2) (m 3)) |
86fbb8ca CD |
71 | |
72 | #+begin_src emacs-lisp :var results=source-block(n=val_at_col_2, m=3) :results silent | |
73 | results | |
74 | #+end_src | |
75 | ||
76 | NOTE: by default string variable names are interpreted as | |
77 | references to source-code blocks, to force interpretation of a | |
153ae947 BG |
78 | cell's value as a string, prefix the identifier a \"$\" (e.g., |
79 | \"$$2\" instead of \"$2\" or \"$@2$2\" instead of \"@2$2\"). | |
e66ba1df BG |
80 | |
81 | NOTE: it is also possible to pass header arguments to the code | |
82 | block. In this case a table cell should hold the string value of | |
83 | the header argument which can then be passed before all variables | |
84 | as shown in the example below. | |
85 | ||
86 | | 1 | 2 | :file nothing.png | nothing.png | | |
30cb51f1 | 87 | #+TBLFM: @1$4='(org-sbe test-sbe $3 (x $1) (y $2))" |
666ffc7e | 88 | (declare (debug (form form))) |
e66ba1df BG |
89 | (let* ((header-args (if (stringp (car variables)) (car variables) "")) |
90 | (variables (if (stringp (car variables)) (cdr variables) variables))) | |
91 | (let* (quote | |
92 | (variables | |
93 | (mapcar | |
94 | (lambda (var) | |
95 | ;; ensure that all cells prefixed with $'s are strings | |
96 | (cons (car var) | |
97 | (delq nil (mapcar | |
98 | (lambda (el) | |
99 | (if (eq '$ el) | |
153ae947 | 100 | (prog1 nil (setq quote t)) |
271672fa BG |
101 | (prog1 |
102 | (cond | |
103 | (quote (format "\"%s\"" el)) | |
104 | ((stringp el) (org-no-properties el)) | |
105 | (t el)) | |
e66ba1df BG |
106 | (setq quote nil)))) |
107 | (cdr var))))) | |
108 | variables))) | |
109 | (unless (stringp source-block) | |
110 | (setq source-block (symbol-name source-block))) | |
666ffc7e SM |
111 | (let ((result |
112 | (if (and source-block (> (length source-block) 0)) | |
113 | (let ((params | |
114 | ;; FIXME: Why `eval'?!?!? | |
115 | (eval `(org-babel-parse-header-arguments | |
116 | (concat | |
117 | ":var results=" | |
118 | ,source-block | |
119 | "[" ,header-args "]" | |
120 | "(" | |
121 | (mapconcat | |
122 | (lambda (var-spec) | |
123 | (if (> (length (cdr var-spec)) 1) | |
124 | (format "%S='%S" | |
125 | (car var-spec) | |
126 | (mapcar #'read (cdr var-spec))) | |
127 | (format "%S=%s" | |
128 | (car var-spec) (cadr var-spec)))) | |
129 | ',variables ", ") | |
130 | ")"))))) | |
131 | (org-babel-execute-src-block | |
132 | nil (list "emacs-lisp" "results" params) | |
133 | '((:results . "silent")))) | |
134 | ""))) | |
135 | (org-babel-trim (if (stringp result) result (format "%S" result))))))) | |
86fbb8ca CD |
136 | |
137 | (provide 'ob-table) | |
138 | ||
5b409b39 | 139 | |
86fbb8ca CD |
140 | |
141 | ;;; ob-table.el ends here |