summaryrefslogtreecommitdiff
path: root/lisp/ob-lob.el
diff options
context:
space:
mode:
authorSébastien Delafond <sdelafond@gmail.com>2016-11-07 10:41:54 +0100
committerSébastien Delafond <sdelafond@gmail.com>2016-11-07 10:41:54 +0100
commitec84430cf4e09ba25ec675debdf802bc28111e06 (patch)
tree9c64bc8a0cd5e8cac82aa5fdf369d40529f140f8 /lisp/ob-lob.el
parent84539dca3aa301ecfe48858eceef1ced0505388b (diff)
Imported Upstream version 9.0
Diffstat (limited to 'lisp/ob-lob.el')
-rw-r--r--lisp/ob-lob.el194
1 files changed, 83 insertions, 111 deletions
diff --git a/lisp/ob-lob.el b/lisp/ob-lob.el
index cf5cb4e..1c4123b 100644
--- a/lisp/ob-lob.el
+++ b/lisp/ob-lob.el
@@ -1,4 +1,4 @@
-;;; ob-lob.el --- functions supporting the Library of Babel
+;;; ob-lob.el --- Functions Supporting the Library of Babel -*- lexical-binding: t; -*-
;; Copyright (C) 2009-2016 Free Software Foundation, Inc.
@@ -23,27 +23,27 @@
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Code:
-(eval-when-compile
- (require 'cl))
+(require 'cl-lib)
(require 'ob-core)
(require 'ob-table)
-(declare-function org-babel-in-example-or-verbatim "ob-exp" nil)
+(declare-function org-babel-ref-split-args "ob-ref" (arg-string))
+(declare-function org-element-at-point "org-element" ())
+(declare-function org-element-context "org-element" (&optional element))
+(declare-function org-element-property "org-element" (property element))
+(declare-function org-element-type "org-element" (element))
(defvar org-babel-library-of-babel nil
"Library of source-code blocks.
-This is an association list. Populate the library by adding
-files to `org-babel-lob-files'.")
-
-(defcustom org-babel-lob-files nil
- "Files used to populate the `org-babel-library-of-babel'.
-To add files to this list use the `org-babel-lob-ingest' command."
- :group 'org-babel
- :version "24.1"
- :type '(repeat file))
+This is an association list. Populate the library by calling
+`org-babel-lob-ingest' on files containing source blocks.")
(defvar org-babel-default-lob-header-args '((:exports . "results"))
- "Default header arguments to use when exporting #+lob/call lines.")
+ "Default header arguments to use when exporting Babel calls.
+By default, a Babel call inherits its arguments from the source
+block being called. Header arguments defined in this variable
+take precedence over these. It is useful for properties that
+should not be inherited from a source block.")
(defun org-babel-lob-ingest (&optional file)
"Add all named source blocks defined in FILE to `org-babel-library-of-babel'."
@@ -62,24 +62,7 @@ To add files to this list use the `org-babel-lob-ingest' command."
lob-ingest-count (if (> lob-ingest-count 1) "s" ""))
lob-ingest-count))
-(defconst org-babel-block-lob-one-liner-regexp
- (concat
- "^\\([ \t]*?\\)#\\+call:[ \t]+\\([^()\n]+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)"
- "(\\([^\n]*?\\))\\(\\[.+\\]\\|\\)[ \t]*\\(\\([^\n]*\\)\\)?")
- "Regexp to match non-inline calls to predefined source block functions.")
-
-(defconst org-babel-inline-lob-one-liner-regexp
- (concat
- "\\([^\n]*?\\)call_\\([^()[:space:]\n]+?\\)\\(\\[\\(.*?\\)\\]\\|\\(\\)\\)"
- "(\\(.*?\\))\\(\\[\\(.*?\\)\\]\\)?")
- "Regexp to match inline calls to predefined source block functions.")
-
-(defconst org-babel-lob-one-liner-regexp
- (concat "\\(" org-babel-block-lob-one-liner-regexp
- "\\|" org-babel-inline-lob-one-liner-regexp "\\)")
- "Regexp to match calls to predefined source block functions.")
-
-;; functions for executing lob one-liners
+;; Functions for executing lob one-liners.
;;;###autoload
(defun org-babel-lob-execute-maybe ()
@@ -88,87 +71,76 @@ Detect if this is context for a Library Of Babel source block and
if so then run the appropriate source block from the Library."
(interactive)
(let ((info (org-babel-lob-get-info)))
- (if (and (nth 0 info) (not (org-babel-in-example-or-verbatim)))
- (progn (org-babel-lob-execute info) t)
- nil)))
+ (when info
+ (org-babel-execute-src-block nil info)
+ t)))
+
+(defun org-babel-lob--src-info (name)
+ "Return internal representation for Babel data named NAME.
+NAME is a string. This function looks into the current document
+for a Babel call or source block. If none is found, it looks
+after NAME in the Library of Babel. Eventually, if that also
+fails, it returns nil."
+ ;; During export, look into the pristine copy of the document being
+ ;; exported instead of the current one, which could miss some data.
+ (with-current-buffer (or org-babel-exp-reference-buffer (current-buffer))
+ (org-with-wide-buffer
+ (goto-char (point-min))
+ (catch :found
+ (let ((case-fold-search t)
+ (regexp (org-babel-named-data-regexp-for-name name)))
+ (while (re-search-forward regexp nil t)
+ (let ((element (org-element-at-point)))
+ (when (equal name (org-element-property :name element))
+ (throw :found
+ (pcase (org-element-type element)
+ (`src-block (org-babel-get-src-block-info t element))
+ (`babel-call (org-babel-lob-get-info element))
+ ;; Non-executable data found. Since names are
+ ;; supposed to be unique throughout a document,
+ ;; bail out.
+ (_ nil))))))
+ ;; No element named NAME in buffer. Try Library of Babel.
+ (cdr (assoc-string name org-babel-library-of-babel)))))))
;;;###autoload
-(defun org-babel-lob-get-info ()
- "Return a Library of Babel function call as a string."
- (let ((case-fold-search t)
- (nonempty (lambda (a b)
- (let ((it (match-string a)))
- (if (= (length it) 0) (match-string b) it)))))
- (save-excursion
- (beginning-of-line 1)
- (when (looking-at org-babel-lob-one-liner-regexp)
- (append
- (mapcar #'org-no-properties
- (list
- (format "%s%s(%s)%s"
- (funcall nonempty 3 12)
- (if (not (= 0 (length (funcall nonempty 5 14))))
- (concat "[" (funcall nonempty 5 14) "]") "")
- (or (funcall nonempty 7 16) "")
- (or (funcall nonempty 8 19) ""))
- (funcall nonempty 9 18)))
- (list (length (if (= (length (match-string 12)) 0)
- (match-string 2) (match-string 11)))
- (save-excursion
- (forward-line -1)
- (save-match-data
- (and (looking-at (concat org-babel-src-name-regexp
- "\\([^\n]*\\)$"))
- (org-no-properties (match-string 1)))))))))))
-
-(defvar org-babel-default-header-args:emacs-lisp) ; Defined in ob-emacs-lisp.el
-(defun org-babel-lob-execute (info)
- "Execute the lob call specified by INFO."
- (let* ((mkinfo (lambda (p)
- (list "emacs-lisp" "results" p nil
- (nth 3 info) ;; name
- (nth 2 info))))
- (pre-params (apply #'org-babel-merge-params
- org-babel-default-header-args
- org-babel-default-header-args:emacs-lisp
- (append
- (org-babel-params-from-properties)
- (list
- (org-babel-parse-header-arguments
- (org-no-properties
- (concat
- ":var results="
- (mapconcat #'identity (butlast info 2)
- " "))))))))
- (pre-info (funcall mkinfo pre-params))
- (cache-p (and (cdr (assoc :cache pre-params))
- (string= "yes" (cdr (assoc :cache pre-params)))))
- (new-hash (when cache-p
- (org-babel-sha1-hash
- ;; Do *not* pre-process params for call line
- ;; hash evaluation, since for a call line :var
- ;; extension *is* execution.
- (let* ((params (nth 2 pre-info))
- (sha1-nth2 (list
- (cons
- (cons :c-var (cdr (assoc :var params)))
- (assq-delete-all :var (copy-tree params)))))
- (sha1-info (copy-tree pre-info)))
- (prog1 sha1-info
- (setcar (cddr sha1-info) sha1-nth2))))))
- (old-hash (when cache-p (org-babel-current-result-hash pre-info)))
- (org-babel-current-src-block-location (point-marker)))
- (if (and cache-p (equal new-hash old-hash))
- (save-excursion (goto-char (org-babel-where-is-src-block-result
- nil pre-info))
- (forward-line 1)
- (message "%S" (org-babel-read-result)))
- (prog1 (let* ((proc-params (org-babel-process-params pre-params))
- org-confirm-babel-evaluate)
- (org-babel-execute-src-block nil (funcall mkinfo proc-params)))
- ;; update the hash
- (when new-hash
- (org-babel-set-current-result-hash new-hash pre-info))))))
+(defun org-babel-lob-get-info (&optional datum)
+ "Return internal representation for Library of Babel function call.
+Consider DATUM, when provided, or element at point. Return nil
+when not on an appropriate location. Otherwise return a list
+compatible with `org-babel-get-src-block-info', which see."
+ (let* ((context (or datum (org-element-context)))
+ (type (org-element-type context)))
+ (when (memq type '(babel-call inline-babel-call))
+ (pcase (org-babel-lob--src-info (org-element-property :call context))
+ (`(,language ,body ,header ,_ ,_ ,_ ,coderef)
+ (let ((begin (org-element-property (if (eq type 'inline-babel-call)
+ :begin
+ :post-affiliated)
+ context)))
+ (list language
+ body
+ (apply #'org-babel-merge-params
+ header
+ org-babel-default-lob-header-args
+ (append
+ (org-with-wide-buffer
+ (goto-char begin)
+ (org-babel-params-from-properties language))
+ (list
+ (org-babel-parse-header-arguments
+ (org-element-property :inside-header context))
+ (let ((args (org-element-property :arguments context)))
+ (and args
+ (mapcar (lambda (ref) (cons :var ref))
+ (org-babel-ref-split-args args))))
+ (org-babel-parse-header-arguments
+ (org-element-property :end-header context)))))
+ nil
+ (org-element-property :name context)
+ begin
+ coderef)))
+ (_ nil)))))
(provide 'ob-lob)