org-babel-exp-lob-one-liners should not parse the entire buffer.
[org-mode.git] / lisp / ob-lob.el
blobd2ebb17b30f89f2d4857f84a86bd5c847efb763c
1 ;;; ob-lob.el --- functions supporting the Library of Babel
3 ;; Copyright (C) 2009-2011 Free Software Foundation, Inc.
5 ;; Author: Eric Schulte
6 ;; Dan Davison
7 ;; Keywords: literate programming, reproducible research
8 ;; Homepage: http://orgmode.org
10 ;; This file is part of GNU Emacs.
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.
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.
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/>.
25 ;;; Code:
26 (eval-when-compile
27 (require 'cl))
28 (require 'ob)
29 (require 'ob-table)
31 (declare-function org-babel-in-example-or-verbatim "ob-exp" nil)
33 (defvar org-babel-library-of-babel nil
34 "Library of source-code blocks.
35 This is an association list. Populate the library by adding
36 files to `org-babel-lob-files'.")
38 (defcustom org-babel-lob-files '()
39 "Files used to populate the `org-babel-library-of-babel'.
40 To add files to this list use the `org-babel-lob-ingest' command."
41 :group 'org-babel
42 :type 'list)
44 (defvar org-babel-default-lob-header-args '((:exports . "results"))
45 "Default header arguments to use when exporting #+lob/call lines.")
47 ;;;###autoload
48 (defun org-babel-lob-ingest (&optional file)
49 "Add all named source-blocks defined in FILE to
50 `org-babel-library-of-babel'."
51 (interactive "fFile: ")
52 (let ((lob-ingest-count 0))
53 (org-babel-map-src-blocks file
54 (let* ((info (org-babel-get-src-block-info 'light))
55 (source-name (nth 4 info)))
56 (when source-name
57 (setq source-name (intern source-name)
58 org-babel-library-of-babel
59 (cons (cons source-name info)
60 (assq-delete-all source-name org-babel-library-of-babel))
61 lob-ingest-count (1+ lob-ingest-count)))))
62 (message "%d src block%s added to Library of Babel"
63 lob-ingest-count (if (> lob-ingest-count 1) "s" ""))
64 lob-ingest-count))
66 (defconst org-babel-block-lob-one-liner-regexp
67 (concat
68 "^\\([ \t]*\\)#\\+call:[ \t]+\\([^\(\)\n]+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)"
69 "\(\\([^\n]*\\)\)\\(\\[.+\\]\\|\\)[ \t]*\\(\\([^\n]*\\)\\)?")
70 "Regexp to match non-inline calls to predefined source block functions.")
72 (defconst org-babel-inline-lob-one-liner-regexp
73 (concat
74 "\\([^\n]*\\)call_\\([^\(\)\n]+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)"
75 "\(\\([^\n]*\\)\)\\(\\[\\(.*?\\)\\]\\)?")
76 "Regexp to match inline calls to predefined source block functions.")
78 (defconst org-babel-lob-one-liner-regexp
79 (concat "\\(" org-babel-block-lob-one-liner-regexp
80 "\\|" org-babel-inline-lob-one-liner-regexp "\\)")
81 "Regexp to match calls to predefined source block functions.")
83 ;; functions for executing lob one-liners
85 ;;;###autoload
86 (defmacro org-babel-map-call-lines (file &rest body)
87 "Evaluate BODY forms on each call line in FILE.
88 If FILE is nil evaluate BODY forms on source blocks in current
89 buffer."
90 (declare (indent 1))
91 (let ((tempvar (make-symbol "file")))
92 `(let* ((,tempvar ,file)
93 (visited-p (or (null ,tempvar)
94 (get-file-buffer (expand-file-name ,tempvar))))
95 (point (point)) to-be-removed)
96 (save-window-excursion
97 (when ,tempvar (find-file ,tempvar))
98 (setq to-be-removed (current-buffer))
99 (goto-char (point-min))
100 (while (re-search-forward org-babel-lob-one-liner-regexp nil t)
101 (goto-char (match-beginning 1))
102 (save-match-data ,@body)
103 (goto-char (match-end 0))))
104 (unless visited-p (kill-buffer to-be-removed))
105 (goto-char point))))
106 (def-edebug-spec org-babel-map-call-lines (form body))
108 ;;;###autoload
109 (defun org-babel-lob-execute-maybe ()
110 "Execute a Library of Babel source block, if appropriate.
111 Detect if this is context for a Library Of Babel source block and
112 if so then run the appropriate source block from the Library."
113 (interactive)
114 (let ((info (org-babel-lob-get-info)))
115 (if (and (nth 0 info) (not (org-babel-in-example-or-verbatim)))
116 (progn (org-babel-lob-execute info) t)
117 nil)))
119 ;;;###autoload
120 (defun org-babel-lob-get-info ()
121 "Return a Library of Babel function call as a string."
122 (flet ((nonempty (a b)
123 (let ((it (match-string a)))
124 (if (= (length it) 0) (match-string b) it))))
125 (let ((case-fold-search t))
126 (save-excursion
127 (beginning-of-line 1)
128 (when (looking-at org-babel-lob-one-liner-regexp)
129 (append
130 (mapcar #'org-babel-clean-text-properties
131 (list
132 (format "%s%s(%s)%s"
133 (nonempty 3 12)
134 (if (not (= 0 (length (nonempty 5 13))))
135 (concat "[" (nonempty 5 13) "]") "")
136 (or (nonempty 7 16) "")
137 (or (nonempty 8 19) ""))
138 (nonempty 9 18)))
139 (list (length (if (= (length (match-string 12)) 0)
140 (match-string 2) (match-string 11))))))))))
142 (defun org-babel-lob-execute (info)
143 "Execute the lob call specified by INFO."
144 (let ((params (org-babel-process-params
145 (org-babel-merge-params
146 org-babel-default-header-args
147 (org-babel-params-from-properties)
148 (org-babel-parse-header-arguments
149 (org-babel-clean-text-properties
150 (concat ":var results="
151 (mapconcat #'identity (butlast info) " "))))))))
152 (org-babel-execute-src-block
153 nil (list "emacs-lisp" "results" params nil nil (nth 2 info)))))
155 (provide 'ob-lob)
159 ;;; ob-lob.el ends here