config

Personal configuration.
git clone git://code.dwrz.net/config
Log | Files | Refs

ob-lob.el (6512B)


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