dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

ob-lob.el (6473B)


      1 ;;; ob-lob.el --- Functions Supporting the Library of Babel -*- lexical-binding: t; -*-
      2 
      3 ;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
      4 
      5 ;; Authors: Eric Schulte
      6 ;;	 Dan Davison
      7 ;; Keywords: literate programming, reproducible research
      8 ;; URL: https://orgmode.org
      9 
     10 ;; This file is part of GNU Emacs.
     11 
     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.
     16 
     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.
     21 
     22 ;; You should have received a copy of the GNU General Public License
     23 ;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
     24 
     25 ;;; Code:
     26 
     27 (require 'org-macs)
     28 (org-assert-version)
     29 
     30 (require 'cl-lib)
     31 (require 'ob-core)
     32 (require 'ob-table)
     33 
     34 (declare-function org-babel-ref-split-args "ob-ref" (arg-string))
     35 (declare-function org-element-at-point "org-element" (&optional pom cached-only))
     36 (declare-function org-element-context "org-element" (&optional element))
     37 (declare-function org-element-property "org-element" (property element))
     38 (declare-function org-element-type "org-element" (element))
     39 
     40 (defvar org-babel-library-of-babel nil
     41   "Library of source-code blocks.
     42 This is an association list.  Populate the library by calling
     43 `org-babel-lob-ingest' on files containing source blocks.")
     44 
     45 (defvar org-babel-default-lob-header-args '((:exports . "results"))
     46   "Default header arguments to use when exporting Babel calls.
     47 By default, a Babel call inherits its arguments from the source
     48 block being called.  Header arguments defined in this variable
     49 take precedence over these.  It is useful for properties that
     50 should not be inherited from a source block.")
     51 
     52 (defun org-babel-lob-ingest (&optional file)
     53   "Add all named source blocks defined in FILE to `org-babel-library-of-babel'."
     54   (interactive "fFile: ")
     55   (let ((lob-ingest-count 0))
     56     (org-babel-map-src-blocks file
     57       (let* ((info (org-babel-get-src-block-info 'no-eval))
     58 	     (source-name (nth 4 info)))
     59 	(when source-name
     60 	  (setf (nth 1 info)
     61 		(if (org-babel-noweb-p (nth 2 info) :eval)
     62 		    (org-babel-expand-noweb-references info)
     63 		  (nth 1 info)))
     64 	  (let ((source (intern source-name)))
     65 	    (setq org-babel-library-of-babel
     66 		  (cons (cons source info)
     67 			(assq-delete-all source org-babel-library-of-babel))))
     68 	  (cl-incf lob-ingest-count))))
     69     (message "%d source block%s added to Library of Babel"
     70 	     lob-ingest-count (if (> lob-ingest-count 1) "s" ""))
     71     lob-ingest-count))
     72 
     73 ;; Functions for executing lob one-liners.
     74 
     75 ;;;###autoload
     76 (defun org-babel-lob-execute-maybe ()
     77   "Execute a Library of Babel source block, if appropriate.
     78 Detect if this is context for a Library Of Babel source block and
     79 if so then run the appropriate source block from the Library."
     80   (interactive)
     81   (let* ((datum (org-element-context))
     82          (info (org-babel-lob-get-info datum)))
     83     (when info
     84       (org-babel-execute-src-block nil info nil (org-element-type datum))
     85       t)))
     86 
     87 (defun org-babel-lob--src-info (ref)
     88   "Return internal representation for Babel data referenced as REF.
     89 REF is a string.  This function looks into the current document
     90 for a Babel call or source block.  If none is found, it looks
     91 after REF in the Library of Babel."
     92   (let ((name ref)
     93 	(file nil))
     94     ;; Extract the remote file, if specified in the reference.
     95     (when (string-match "\\`\\(.+\\):\\(.+\\)\\'" ref)
     96       (setq file (match-string 1 ref))
     97       (setq name (match-string 2 ref)))
     98     ;; During export, look into the pristine copy of the document
     99     ;; being exported instead of the current one, which could miss
    100     ;; some data.
    101     (with-current-buffer (cond (file (find-file-noselect file t))
    102 			       (org-babel-exp-reference-buffer)
    103 			       (t (current-buffer)))
    104       (org-with-point-at 1
    105 	(catch :found
    106 	  (let ((case-fold-search t)
    107 		(regexp (org-babel-named-data-regexp-for-name name)))
    108 	    (while (re-search-forward regexp nil t)
    109 	      (let ((element (org-element-at-point)))
    110 		(when (equal name (org-element-property :name element))
    111 		  (throw :found
    112 			 (pcase (org-element-type element)
    113 			   (`src-block (org-babel-get-src-block-info t element))
    114 			   (`babel-call (org-babel-lob-get-info element))
    115 			   ;; Non-executable data found.  Since names
    116 			   ;; are supposed to be unique throughout
    117 			   ;; a document, bail out.
    118 			   (_ nil))))))
    119 	    (cdr (assoc-string ref org-babel-library-of-babel))))))))
    120 
    121 ;;;###autoload
    122 (defun org-babel-lob-get-info (&optional datum no-eval)
    123   "Return internal representation for Library of Babel function call.
    124 
    125 Consider DATUM, when provided, or element at point otherwise.
    126 
    127 When optional argument NO-EVAL is non-nil, Babel does not resolve
    128 remote variable references; a process which could likely result
    129 in the execution of other code blocks, and do not evaluate Lisp
    130 values in parameters.
    131 
    132 Return nil when not on an appropriate location.  Otherwise return
    133 a list compatible with `org-babel-get-src-block-info', which
    134 see."
    135   (let* ((context (or datum (org-element-context)))
    136 	 (type (org-element-type context))
    137 	 (reference (org-element-property :call context)))
    138     (when (memq type '(babel-call inline-babel-call))
    139       (pcase (org-babel-lob--src-info reference)
    140 	(`(,language ,body ,header ,_ ,_ ,_ ,coderef)
    141 	 (let ((begin (org-element-property (if (eq type 'inline-babel-call)
    142 						:begin
    143 					      :post-affiliated)
    144 					    context)))
    145 	   (list language
    146 		 body
    147 		 (apply #'org-babel-merge-params
    148 			header
    149 			org-babel-default-lob-header-args
    150 			(append
    151 			 (org-with-point-at begin
    152 			   (org-babel-params-from-properties language no-eval))
    153 			 (list
    154 			  (org-babel-parse-header-arguments
    155 			   (org-element-property :inside-header context) no-eval)
    156 			  (let ((args (org-element-property :arguments context)))
    157 			    (and args
    158 				 (mapcar (lambda (ref) (cons :var ref))
    159 					 (org-babel-ref-split-args args))))
    160 			  (org-babel-parse-header-arguments
    161 			   (org-element-property :end-header context) no-eval))))
    162 		 nil
    163 		 (org-element-property :name context)
    164 		 begin
    165 		 coderef)))
    166 	(_ nil)))))
    167 
    168 (provide 'ob-lob)
    169 
    170 ;; Local variables:
    171 ;; generated-autoload-file: "org-loaddefs.el"
    172 ;; End:
    173 
    174 ;;; ob-lob.el ends here