org-mode/contrib/babel/lisp/org-babel-lob.el

102 lines
3.7 KiB
EmacsLisp
Raw Normal View History

;;; org-babel-lob.el --- The Library of Babel: off-the-shelf functions for data analysis and plotting using org-babel
2009-10-29 19:03:43 -04:00
;; Copyright (C) 2009 Eric Schulte, Dan Davison
2009-10-29 19:03:43 -04:00
;; Author: Eric Schulte, Dan Davison
;; Keywords: literate programming, reproducible research
;; Homepage: http://orgmode.org
;; Version: 0.01
;;; License:
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;; Commentary:
;; See org-babel.org in the parent directory for more information
;;; Code:
(require 'org-babel)
(require 'org-babel-table)
(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 '()
"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
:type 'list)
(defun org-babel-lob-ingest (&optional file)
"Add all source-blocks defined in FILE to `org-babel-library-of-babel'."
(interactive "f")
(org-babel-map-source-blocks file
(let* ((info (org-babel-get-src-block-info))
(source-name (intern (fifth info))))
(when source-name
(setq org-babel-library-of-babel
(cons (cons source-name info)
(assq-delete-all source-name org-babel-library-of-babel)))))))
;; functions for executing lob one-liners
(defvar org-babel-lob-one-liner-regexp "^[ \t]*#\\+lob:[ \t]+\\([^\(\)\n]+\\)\(\\([^\n]*\\)\)[ \t]*\\([^\n]*\\)")
(defun org-babel-lob-execute-maybe ()
"Detect if this is context for a org-babel Library Of Babel
src-block and if so then run the appropriate source block from
the Library."
(interactive)
(let ((info (org-babel-lob-get-info)))
(if (first info) (progn (org-babel-lob-execute info) t) nil)))
(add-hook 'org-ctrl-c-ctrl-c-hook 'org-babel-lob-execute-maybe)
(defun org-babel-lob-get-info ()
Enabling LoB to put results in buffer, and slowly moving towards more unified concept of function calls. Previously LoB calls were not able to produce results in the buffer. These changes go some way to allowing them to do that. [There are still some bugs to deal with]. That meant changing org-babel.el so that there is a notion of the `source block name' for a LoB line, in order to construct a #+resname (currently I've made the name the same as the function call). I'm also slowly moving towards unifying the notion of `function calls' a bit more: I've changed the org-babel-lob-one-liner-regexp so that instead of a monolithic match it now matches first the function name, and second the function arguments in parentheses. org-babel-lob-get-info makes that match, and although it still concatenates them and returns the string, the two elements can be accessed immediately afterwards using match-string. So that situation is very similar to org-babel-get-src-block-name, whose job (in this branch) is also to parse the function *name* and the function *arguments*. In a few places in the code (esp. function names), I think the word `info' should be replaced with `call' or `function call', which I believe more accurately indicates what the `info' is: a function definition, together with bound arguments/references. The function call syntax, i.e. function-name(arg1=ref1), originally introduced for references (and thereby in LoB), and which I'm proposing we use throughout, raises the question of default arguments, and those being over-ridden by supplied arguments, as in e.g. python, and R.
2009-07-10 22:59:10 -04:00
"Return the function call supplied on the current Library of
Babel line as a string.
This function is analogous to org-babel-get-src-block-name. For
both functions, after they are called, (match-string 1) matches
the function name, and (match-string 2) matches the function
arguments inside the parentheses. I think perhaps these functions
should be renamed to bring out this similarity, perhaps involving
the word 'call'."
(let ((case-fold-search t))
(save-excursion
(move-beginning-of-line 1)
(if (looking-at org-babel-lob-one-liner-regexp)
(mapcar #'org-babel-clean-text-properties
(list (format "%s(%s)" (match-string 1) (match-string 2))
(match-string 3)))))))
(defun org-babel-lob-execute (info)
Enabling LoB to put results in buffer, and slowly moving towards more unified concept of function calls. Previously LoB calls were not able to produce results in the buffer. These changes go some way to allowing them to do that. [There are still some bugs to deal with]. That meant changing org-babel.el so that there is a notion of the `source block name' for a LoB line, in order to construct a #+resname (currently I've made the name the same as the function call). I'm also slowly moving towards unifying the notion of `function calls' a bit more: I've changed the org-babel-lob-one-liner-regexp so that instead of a monolithic match it now matches first the function name, and second the function arguments in parentheses. org-babel-lob-get-info makes that match, and although it still concatenates them and returns the string, the two elements can be accessed immediately afterwards using match-string. So that situation is very similar to org-babel-get-src-block-name, whose job (in this branch) is also to parse the function *name* and the function *arguments*. In a few places in the code (esp. function names), I think the word `info' should be replaced with `call' or `function call', which I believe more accurately indicates what the `info' is: a function definition, together with bound arguments/references. The function call syntax, i.e. function-name(arg1=ref1), originally introduced for references (and thereby in LoB), and which I'm proposing we use throughout, raises the question of default arguments, and those being over-ridden by supplied arguments, as in e.g. python, and R.
2009-07-10 22:59:10 -04:00
(let ((params (org-babel-merge-params
org-babel-default-header-args
(org-babel-parse-header-arguments
(org-babel-clean-text-properties
(concat ":var results=" (mapconcat #'identity info " ")))))))
Enabling LoB to put results in buffer, and slowly moving towards more unified concept of function calls. Previously LoB calls were not able to produce results in the buffer. These changes go some way to allowing them to do that. [There are still some bugs to deal with]. That meant changing org-babel.el so that there is a notion of the `source block name' for a LoB line, in order to construct a #+resname (currently I've made the name the same as the function call). I'm also slowly moving towards unifying the notion of `function calls' a bit more: I've changed the org-babel-lob-one-liner-regexp so that instead of a monolithic match it now matches first the function name, and second the function arguments in parentheses. org-babel-lob-get-info makes that match, and although it still concatenates them and returns the string, the two elements can be accessed immediately afterwards using match-string. So that situation is very similar to org-babel-get-src-block-name, whose job (in this branch) is also to parse the function *name* and the function *arguments*. In a few places in the code (esp. function names), I think the word `info' should be replaced with `call' or `function call', which I believe more accurately indicates what the `info' is: a function definition, together with bound arguments/references. The function call syntax, i.e. function-name(arg1=ref1), originally introduced for references (and thereby in LoB), and which I'm proposing we use throughout, raises the question of default arguments, and those being over-ridden by supplied arguments, as in e.g. python, and R.
2009-07-10 22:59:10 -04:00
(org-babel-execute-src-block nil (list "emacs-lisp" "results" params))))
(define-generic-mode org-babel-lob-mode
'("#") nil nil nil nil
"Major mode for fontification of library of babel lines on export")
(provide 'org-babel-lob)
;;; org-babel-lob.el ends here