Merge branch 'maint'
[org-mode/org-tableheadings.git] / lisp / ob-lob.el
blob739849f559a4ebdf2cd0e4b3185eedada815f0c2
1 ;;; ob-lob.el --- functions supporting the Library of Babel
3 ;; Copyright (C) 2009-2016 Free Software Foundation, Inc.
5 ;; Authors: 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-core)
29 (require 'ob-table)
31 (declare-function org-babel-in-example-or-verbatim "ob-exp" nil)
32 (declare-function org-element-context "org-element" (&optional element))
33 (declare-function org-element-property "org-element" (property element))
34 (declare-function org-element-type "org-element" (element))
36 (defvar org-babel-library-of-babel nil
37 "Library of source-code blocks.
38 This is an association list. Populate the library by adding
39 files to `org-babel-lob-files'.")
41 (defcustom org-babel-lob-files nil
42 "Files used to populate the `org-babel-library-of-babel'.
43 To add files to this list use the `org-babel-lob-ingest' command."
44 :group 'org-babel
45 :version "24.1"
46 :type '(repeat file))
48 (defvar org-babel-default-lob-header-args '((:exports . "results"))
49 "Default header arguments to use when exporting #+lob/call lines.")
51 (defun org-babel-lob-ingest (&optional file)
52 "Add all named source blocks defined in FILE to `org-babel-library-of-babel'."
53 (interactive "fFile: ")
54 (let ((lob-ingest-count 0))
55 (org-babel-map-src-blocks file
56 (let* ((info (org-babel-get-src-block-info 'light))
57 (source-name (nth 4 info)))
58 (when source-name
59 (setq source-name (intern source-name)
60 org-babel-library-of-babel
61 (cons (cons source-name info)
62 (assq-delete-all source-name org-babel-library-of-babel))
63 lob-ingest-count (1+ lob-ingest-count)))))
64 (message "%d src block%s added to Library of Babel"
65 lob-ingest-count (if (> lob-ingest-count 1) "s" ""))
66 lob-ingest-count))
68 (defconst org-babel-block-lob-one-liner-regexp
69 (concat
70 "^\\([ \t]*?\\)#\\+call:[ \t]+\\([^()\n]+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)"
71 "(\\([^\n]*?\\))\\(\\[.+\\]\\|\\)[ \t]*\\(\\([^\n]*\\)\\)?")
72 "Regexp to match non-inline calls to predefined source block functions.")
74 (defconst org-babel-inline-lob-one-liner-regexp
75 (concat
76 "\\([^\n]*?\\)call_\\([^()[:space:]\n]+?\\)\\(\\[\\(.*?\\)\\]\\|\\(\\)\\)"
77 "(\\(.*?\\))\\(\\[\\(.*?\\)\\]\\)?")
78 "Regexp to match inline calls to predefined source block functions.")
80 (defconst org-babel-lob-one-liner-regexp
81 (concat "\\(" org-babel-block-lob-one-liner-regexp
82 "\\|" org-babel-inline-lob-one-liner-regexp "\\)")
83 "Regexp to match calls to predefined source block functions.")
85 ;; functions for executing lob one-liners
87 ;;;###autoload
88 (defun org-babel-lob-execute-maybe ()
89 "Execute a Library of Babel source block, if appropriate.
90 Detect if this is context for a Library Of Babel source block and
91 if so then run the appropriate source block from the Library."
92 (interactive)
93 (let ((info (org-babel-lob-get-info)))
94 (if (and (nth 0 info) (not (org-babel-in-example-or-verbatim)))
95 (progn (org-babel-lob-execute info) t)
96 nil)))
98 ;;;###autoload
99 (defun org-babel-lob-get-info ()
100 "Return a Library of Babel function call as a string."
101 (when (save-excursion
102 (beginning-of-line)
103 (let ((case-fold-search t))
104 (looking-at org-babel-lob-one-liner-regexp)))
105 (let ((context (save-match-data (org-element-context))))
106 (when (memq (org-element-type context) '(babel-call inline-babel-call))
107 (list (format "%s%s(%s)"
108 (org-element-property :call context)
109 (let ((in (org-element-property :inside-header context)))
110 (if in (format "[%s]" in) ""))
111 (or (org-element-property :arguments context) ""))
112 (org-element-property :end-header context)
113 (length (if (= (length (match-string 12)) 0)
114 (match-string-no-properties 2)
115 (match-string-no-properties 11)))
116 (org-element-property :name context))))))
118 (defvar org-babel-default-header-args:emacs-lisp) ; Defined in ob-emacs-lisp.el
119 (defun org-babel-lob-execute (info)
120 "Execute the lob call specified by INFO."
121 (let* ((mkinfo (lambda (p)
122 (list "emacs-lisp" "results" p nil
123 (nth 3 info) ;; name
124 (nth 2 info))))
125 (pre-params (apply #'org-babel-merge-params
126 org-babel-default-header-args
127 org-babel-default-header-args:emacs-lisp
128 (append
129 (org-babel-params-from-properties)
130 (list
131 (org-babel-parse-header-arguments
132 (org-no-properties
133 (concat
134 ":var results="
135 (mapconcat #'identity (butlast info 2)
136 " "))))))))
137 (pre-info (funcall mkinfo pre-params))
138 (cache-p (and (cdr (assoc :cache pre-params))
139 (string= "yes" (cdr (assoc :cache pre-params)))))
140 (new-hash (when cache-p
141 (org-babel-sha1-hash
142 ;; Do *not* pre-process params for call line
143 ;; hash evaluation, since for a call line :var
144 ;; extension *is* execution.
145 (let* ((params (nth 2 pre-info))
146 (sha1-nth2 (list
147 (cons
148 (cons :c-var (cdr (assoc :var params)))
149 (assq-delete-all :var (copy-tree params)))))
150 (sha1-info (copy-tree pre-info)))
151 (prog1 sha1-info
152 (setcar (cddr sha1-info) sha1-nth2))))))
153 (old-hash (when cache-p (org-babel-current-result-hash pre-info)))
154 (org-babel-current-src-block-location (point-marker)))
155 (if (and cache-p (equal new-hash old-hash))
156 (save-excursion (goto-char (org-babel-where-is-src-block-result
157 nil pre-info))
158 (forward-line 1)
159 (message "%S" (org-babel-read-result)))
160 (prog1 (let* ((proc-params (org-babel-process-params pre-params))
161 org-confirm-babel-evaluate)
162 (org-babel-execute-src-block nil (funcall mkinfo proc-params)))
163 ;; update the hash
164 (when new-hash
165 (org-babel-set-current-result-hash new-hash pre-info))))))
167 (provide 'ob-lob)
169 ;; Local variables:
170 ;; generated-autoload-file: "org-loaddefs.el"
171 ;; End:
173 ;;; ob-lob.el ends here