config

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

ob-table.el (5398B)


      1 ;;; ob-table.el --- Support for Calling Babel Functions from Tables -*- lexical-binding: t; -*-
      2 
      3 ;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
      4 
      5 ;; Author: Eric Schulte
      6 ;; Keywords: literate programming, reproducible research
      7 ;; URL: https://orgmode.org
      8 
      9 ;; This file is part of GNU Emacs.
     10 
     11 ;; GNU Emacs is free software: you can redistribute it and/or modify
     12 ;; it under the terms of the GNU General Public License as published by
     13 ;; the Free Software Foundation, either version 3 of the License, or
     14 ;; (at your option) any later version.
     15 
     16 ;; GNU Emacs is distributed in the hope that it will be useful,
     17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 ;; GNU General Public License for more details.
     20 
     21 ;; You should have received a copy of the GNU General Public License
     22 ;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
     23 
     24 ;;; Commentary:
     25 
     26 ;; Should allow calling functions from Org tables using the function
     27 ;; `org-sbe' as so...
     28 
     29 ;; #+begin_src emacs-lisp :results silent
     30 ;;   (defun fibbd (n) (if (< n 2) 1 (+ (fibbd (- n 1)) (fibbd (- n 2)))))
     31 ;; #+end_src
     32 
     33 ;; #+name: fibbd
     34 ;; #+begin_src emacs-lisp :var n=2 :results silent
     35 ;; (fibbd n)
     36 ;; #+end_src
     37 
     38 ;; | original | fibbd  |
     39 ;; |----------+--------|
     40 ;; |        0 |        |
     41 ;; |        1 |        |
     42 ;; |        2 |        |
     43 ;; |        3 |        |
     44 ;; |        4 |        |
     45 ;; |        5 |        |
     46 ;; |        6 |        |
     47 ;; |        7 |        |
     48 ;; |        8 |        |
     49 ;; |        9 |        |
     50 ;; #+TBLFM: $2='(org-sbe "fibbd" (n $1))
     51 
     52 ;; NOTE: The quotation marks around the function name, 'fibbd' here,
     53 ;; are optional.
     54 
     55 ;;; Code:
     56 
     57 (require 'org-macs)
     58 (org-assert-version)
     59 
     60 (require 'ob-core)
     61 (require 'org-macs)
     62 
     63 (defun org-babel-table-truncate-at-newline (string)
     64   "Replace newline character with ellipses.
     65 If STRING ends in a newline character, then remove the newline
     66 character and replace it with ellipses."
     67   (if (and (stringp string) (string-match "[\n\r]\\(.\\)?" string))
     68       (concat (substring string 0 (match-beginning 0))
     69 	      (when (match-string 1 string) "..."))
     70     string))
     71 
     72 (defmacro org-sbe (source-block &rest variables)
     73   "Return the results of calling SOURCE-BLOCK with VARIABLES.
     74 
     75 Each element of VARIABLES should be a list of two elements: the
     76 first element is the name of the variable and second element is a
     77 string of its value.
     78 
     79 So this `org-sbe' construct
     80 
     81  (org-sbe \"source-block\" (n $2) (m 3))
     82 
     83 is the equivalent of the following source code block:
     84 
     85  #+begin_src emacs-lisp :var results=source-block(n=val_at_col_2, m=3) \\
     86      :results silent
     87  results
     88  #+end_src
     89 
     90 The quotation marks around the function name, `source-block', are
     91 optional.
     92 
     93 By default, string variable names are interpreted as references to
     94 source-code blocks, to force interpretation of a cell's value as a
     95 string, prefix the identifier a \"$\" (e.g., \"$$2\" instead of \"$2\"
     96 or \"$@2$2\" instead of \"@2$2\").  \"$\" will also force interpreting
     97 string value literally: $\"value\" will refer to a string, not a
     98 source block name.
     99 
    100 It is also possible to pass header arguments to the code block.  In
    101 this case a table cell should hold the string value of the header
    102 argument which can then be passed before all variables as shown in the
    103 example below.
    104 
    105 | 1 | 2 | :file nothing.png | nothing.png |
    106 #+TBLFM: @1$4=\\='(org-sbe test-sbe $3 (x $1) (y $2))"
    107   (declare (debug (form form)))
    108   (let* ((header-args (if (stringp (car variables)) (car variables) ""))
    109 	 (variables (if (stringp (car variables)) (cdr variables) variables)))
    110     (let* (quote
    111 	   (variables
    112 	    (mapcar
    113 	     (lambda (var)
    114 	       ;; ensure that all cells prefixed with $'s are strings
    115 	       (cons (car var)
    116 		     (delq nil (mapcar
    117 			      (lambda (el)
    118 				(if (eq '$ el)
    119 				    (prog1 nil (setq quote t))
    120 				  (prog1
    121 				      (cond
    122 				       (quote (format "%S" el))
    123 				       ((stringp el) (org-no-properties el))
    124 				       (t el))
    125 				    (setq quote nil))))
    126 			      (cdr var)))))
    127 	     variables)))
    128       (unless (stringp source-block)
    129 	(setq source-block (symbol-name source-block)))
    130       `(let ((result
    131               (if ,(and source-block (> (length source-block) 0))
    132                   (let ((params
    133                          ',(org-babel-parse-header-arguments
    134                             (concat
    135                              ":var results="
    136                              source-block
    137                              "[" header-args "]"
    138                              "("
    139                              (mapconcat
    140                               (lambda (var-spec)
    141                                 (if (> (length (cdr var-spec)) 1)
    142                                     (format "%S='%S"
    143                                             (car var-spec)
    144                                             (mapcar #'read (cdr var-spec)))
    145                                   (format "%S=%s"
    146                                           (car var-spec) (cadr var-spec))))
    147                               variables ", ")
    148                              ")"))))
    149                     (org-babel-execute-src-block
    150                      nil (list "emacs-lisp" "results" params)
    151                      '((:results . "silent"))))
    152                 "")))
    153          (org-trim (if (stringp result) result (format "%S" result)))))))
    154 
    155 (provide 'ob-table)
    156 
    157 ;;; ob-table.el ends here