]> code.delx.au - gnu-emacs/blobdiff - lisp/org/ob-table.el
Update copyright year to 2014 by running admin/update-copyright.
[gnu-emacs] / lisp / org / ob-table.el
index f15065508293c96f824314a6141ac6f73fca4c48..f7c5526d4381a503000768d94fc273b12b039424 100644 (file)
@@ -1,11 +1,10 @@
 ;;; ob-table.el --- support for calling org-babel functions from tables
 
-;; Copyright (C) 2009, 2010  Free Software Foundation, Inc.
+;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
 
 ;; Author: Eric Schulte
 ;; Keywords: literate programming, reproducible research
 ;; Homepage: http://orgmode.org
-;; Version: 7.01
 
 ;; This file is part of GNU Emacs.
 
@@ -31,7 +30,7 @@
 ;;   (defun fibbd (n) (if (< n 2) 1 (+ (fibbd (- n 1)) (fibbd (- n 2)))))
 ;; #+end_src
 
-;; #+srcname: fibbd
+;; #+name: fibbd
 ;; #+begin_src emacs-lisp :var n=2 :results silent
 ;; (fibbd n)
 ;; #+end_src
 ;; #+TBLFM: $2='(sbe 'fibbd (n $1))
 
 ;;; Code:
-(require 'ob)
+(require 'ob-core)
 
 (defun org-babel-table-truncate-at-newline (string)
   "Replace newline character with ellipses.
 If STRING ends in a newline character, then remove the newline
 character and replace it with ellipses."
-  (if (and (stringp string) (string-match "[\n\r]" string))
-      (concat (substring string 0 (match-beginning 0)) "...")
-    string))
+  (if (and (stringp string) (string-match "[\n\r]\\(.\\)?" string))
+      (concat (substring string 0 (match-beginning 0))
+             (if (match-string 1 string) "...")) string))
 
-(defmacro sbe (source-block &rest variables)
+(defmacro sbe (source-block &rest variables) ;FIXME: Namespace prefix!
   "Return the results of calling SOURCE-BLOCK with VARIABLES.
 Each element of VARIABLES should be a two
 element list, whose first element is the name of the variable and
@@ -76,34 +75,67 @@ results
 
 NOTE: by default string variable names are interpreted as
 references to source-code blocks, to force interpretation of a
-cell's value as a string, prefix the identifier with two \"$\"s
-rather than a single \"$\" (i.e. \"$$2\" instead of \"$2\" in the
-example above."
-  (let ((variables (mapcar
-                    (lambda (var)
-                      (if (and (= 3 (length var)) (eq (nth 1 var) '$))
-                          (list (car var) (format "\"%s\"" (last var)))
-                        var))
-                    variables)))
-    (unless (stringp source-block) (setq source-block (symbol-name source-block)))
-    (org-babel-table-truncate-at-newline ;; org-table cells can't be multi-line
-     (if (and source-block (> (length source-block) 0))
-         (let ((params
-                (eval `(org-babel-parse-header-arguments
-                        (concat ":var results="
-                                ,source-block
-                                "("
-                                (mapconcat (lambda (var-spec)
-                                             (format "%S=%s" (nth 0 var-spec) (nth 1 var-spec)))
-                                           ',variables ", ")
-                                ")")))))
-           (org-babel-execute-src-block
-            nil (list "emacs-lisp" "results"
-                      (org-babel-merge-params '((:results . "silent")) params))))
-       ""))))
+cell's value as a string, prefix the identifier a \"$\" (e.g.,
+\"$$2\" instead of \"$2\" or \"$@2$2\" instead of \"@2$2\").
+
+NOTE: it is also possible to pass header arguments to the code
+block.  In this case a table cell should hold the string value of
+the header argument which can then be passed before all variables
+as shown in the example below.
+
+| 1 | 2 | :file nothing.png | nothing.png |
+#+TBLFM: @1$4='(sbe test-sbe $3 (x $1) (y $2))"
+  (declare (debug (form form)))
+  (let* ((header-args (if (stringp (car variables)) (car variables) ""))
+        (variables (if (stringp (car variables)) (cdr variables) variables)))
+    (let* (quote
+          (variables
+           (mapcar
+            (lambda (var)
+              ;; ensure that all cells prefixed with $'s are strings
+              (cons (car var)
+                    (delq nil (mapcar
+                               (lambda (el)
+                                 (if (eq '$ el)
+                                     (prog1 nil (setq quote t))
+                                   (prog1
+                                       (cond
+                                        (quote (format "\"%s\"" el))
+                                        ((stringp el) (org-no-properties el))
+                                        (t el))
+                                     (setq quote nil))))
+                               (cdr var)))))
+            variables)))
+      (unless (stringp source-block)
+       (setq source-block (symbol-name source-block)))
+      (let ((result
+             (if (and source-block (> (length source-block) 0))
+                 (let ((params
+                        ;; FIXME: Why `eval'?!?!?
+                        (eval `(org-babel-parse-header-arguments
+                                (concat
+                                 ":var results="
+                                 ,source-block
+                                 "[" ,header-args "]"
+                                 "("
+                                 (mapconcat
+                                  (lambda (var-spec)
+                                    (if (> (length (cdr var-spec)) 1)
+                                        (format "%S='%S"
+                                                (car var-spec)
+                                                (mapcar #'read (cdr var-spec)))
+                                      (format "%S=%s"
+                                              (car var-spec) (cadr var-spec))))
+                                  ',variables ", ")
+                                 ")")))))
+                   (org-babel-execute-src-block
+                    nil (list "emacs-lisp" "results" params)
+                    '((:results . "silent"))))
+               "")))
+        (org-babel-trim (if (stringp result) result (format "%S" result)))))))
 
 (provide 'ob-table)
 
-;; arch-tag: 4234cc7c-4fc8-4e92-abb0-2892de1a493b
+
 
 ;;; ob-table.el ends here