ob-lob.el 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. ;;; ob-lob.el --- functions supporting the Library of Babel
  2. ;; Copyright (C) 2009-2011 Free Software Foundation, Inc.
  3. ;; Author: Eric Schulte
  4. ;; Dan Davison
  5. ;; Keywords: literate programming, reproducible research
  6. ;; Homepage: http://orgmode.org
  7. ;; This file is part of GNU Emacs.
  8. ;; GNU Emacs is free software: you can redistribute it and/or modify
  9. ;; it under the terms of the GNU General Public License as published by
  10. ;; the Free Software Foundation, either version 3 of the License, or
  11. ;; (at your option) any later version.
  12. ;; GNU Emacs is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;; GNU General Public License for more details.
  16. ;; You should have received a copy of the GNU General Public License
  17. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  18. ;;; Code:
  19. (eval-when-compile
  20. (require 'cl))
  21. (require 'ob)
  22. (require 'ob-table)
  23. (defvar org-babel-library-of-babel nil
  24. "Library of source-code blocks.
  25. This is an association list. Populate the library by adding
  26. files to `org-babel-lob-files'.")
  27. (defcustom org-babel-lob-files '()
  28. "Files used to populate the `org-babel-library-of-babel'.
  29. To add files to this list use the `org-babel-lob-ingest' command."
  30. :group 'org-babel
  31. :type 'list)
  32. (defvar org-babel-default-lob-header-args '((:exports . "results"))
  33. "Default header arguments to use when exporting #+lob/call lines.")
  34. ;;;###autoload
  35. (defun org-babel-lob-ingest (&optional file)
  36. "Add all named source-blocks defined in FILE to
  37. `org-babel-library-of-babel'."
  38. (interactive "fFile: ")
  39. (let ((lob-ingest-count 0))
  40. (org-babel-map-src-blocks file
  41. (let* ((info (org-babel-get-src-block-info 'light))
  42. (source-name (nth 4 info)))
  43. (when source-name
  44. (setq source-name (intern source-name)
  45. org-babel-library-of-babel
  46. (cons (cons source-name info)
  47. (assq-delete-all source-name org-babel-library-of-babel))
  48. lob-ingest-count (1+ lob-ingest-count)))))
  49. (message "%d src block%s added to Library of Babel"
  50. lob-ingest-count (if (> lob-ingest-count 1) "s" ""))
  51. lob-ingest-count))
  52. (defconst org-babel-block-lob-one-liner-regexp
  53. (concat
  54. "^\\([ \t]*\\)#\\+call:[ \t]+\\([^\(\)\n]+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)"
  55. "\(\\([^\n]*\\)\)\\(\\[.+\\]\\|\\)[ \t]*\\(\\([^\n]*\\)\\)?")
  56. "Regexp to match non-inline calls to predefined source block functions.")
  57. (defconst org-babel-inline-lob-one-liner-regexp
  58. (concat
  59. "\\([^\n]*\\)call_\\([^\(\)\n]+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)"
  60. "\(\\([^\n]*\\)\)\\(\\[\\(.*?\\)\\]\\)?")
  61. "Regexp to match inline calls to predefined source block functions.")
  62. (defconst org-babel-lob-one-liner-regexp
  63. (concat "\\(" org-babel-block-lob-one-liner-regexp
  64. "\\|" org-babel-inline-lob-one-liner-regexp "\\)")
  65. "Regexp to match calls to predefined source block functions.")
  66. ;; functions for executing lob one-liners
  67. ;;;###autoload
  68. (defmacro org-babel-map-call-lines (file &rest body)
  69. "Evaluate BODY forms on each call line in FILE.
  70. If FILE is nil evaluate BODY forms on source blocks in current
  71. buffer."
  72. (declare (indent 1))
  73. (let ((tempvar (make-symbol "file")))
  74. `(let* ((,tempvar ,file)
  75. (visited-p (or (null ,tempvar)
  76. (get-file-buffer (expand-file-name ,tempvar))))
  77. (point (point)) to-be-removed)
  78. (save-window-excursion
  79. (when ,tempvar (find-file ,tempvar))
  80. (setq to-be-removed (current-buffer))
  81. (goto-char (point-min))
  82. (while (re-search-forward org-babel-lob-one-liner-regexp nil t)
  83. (goto-char (match-beginning 1))
  84. (save-match-data ,@body)
  85. (goto-char (match-end 0))))
  86. (unless visited-p (kill-buffer to-be-removed))
  87. (goto-char point))))
  88. (def-edebug-spec org-babel-map-call-lines (form body))
  89. ;;;###autoload
  90. (defun org-babel-lob-execute-maybe ()
  91. "Execute a Library of Babel source block, if appropriate.
  92. Detect if this is context for a Library Of Babel source block and
  93. if so then run the appropriate source block from the Library."
  94. (interactive)
  95. (let ((info (org-babel-lob-get-info)))
  96. (if (and (nth 0 info) (not (org-babel-in-example-or-verbatim)))
  97. (progn (org-babel-lob-execute info) t)
  98. nil)))
  99. ;;;###autoload
  100. (defun org-babel-lob-get-info ()
  101. "Return a Library of Babel function call as a string."
  102. (flet ((nonempty (a b)
  103. (let ((it (match-string a)))
  104. (if (= (length it) 0) (match-string b) it))))
  105. (let ((case-fold-search t))
  106. (save-excursion
  107. (beginning-of-line 1)
  108. (when (looking-at org-babel-lob-one-liner-regexp)
  109. (append
  110. (mapcar #'org-babel-clean-text-properties
  111. (list
  112. (format "%s%s(%s)%s"
  113. (nonempty 3 12)
  114. (if (not (= 0 (length (nonempty 5 13))))
  115. (concat "[" (nonempty 5 13) "]") "")
  116. (or (nonempty 7 16) "")
  117. (or (nonempty 8 19) ""))
  118. (nonempty 9 18)))
  119. (list (length (if (= (length (match-string 12)) 0)
  120. (match-string 2) (match-string 11))))))))))
  121. (defun org-babel-lob-execute (info)
  122. "Execute the lob call specified by INFO."
  123. (let ((params (org-babel-process-params
  124. (org-babel-merge-params
  125. org-babel-default-header-args
  126. (org-babel-params-from-properties)
  127. (org-babel-parse-header-arguments
  128. (org-babel-clean-text-properties
  129. (concat ":var results="
  130. (mapconcat #'identity (butlast info) " "))))))))
  131. (org-babel-execute-src-block
  132. nil (list "emacs-lisp" "results" params nil nil (nth 2 info)))))
  133. (provide 'ob-lob)
  134. ;;; ob-lob.el ends here