ob-lob.el 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. (declare-function org-babel-in-example-or-verbatim "ob-exp" nil)
  24. (defvar org-babel-library-of-babel nil
  25. "Library of source-code blocks.
  26. This is an association list. Populate the library by adding
  27. files to `org-babel-lob-files'.")
  28. (defcustom org-babel-lob-files '()
  29. "Files used to populate the `org-babel-library-of-babel'.
  30. To add files to this list use the `org-babel-lob-ingest' command."
  31. :group 'org-babel
  32. :type 'list)
  33. (defvar org-babel-default-lob-header-args '((:exports . "results"))
  34. "Default header arguments to use when exporting #+lob/call lines.")
  35. ;;;###autoload
  36. (defun org-babel-lob-ingest (&optional file)
  37. "Add all named source-blocks defined in FILE to
  38. `org-babel-library-of-babel'."
  39. (interactive "fFile: ")
  40. (let ((lob-ingest-count 0))
  41. (org-babel-map-src-blocks file
  42. (let* ((info (org-babel-get-src-block-info 'light))
  43. (source-name (nth 4 info)))
  44. (when source-name
  45. (setq source-name (intern source-name)
  46. org-babel-library-of-babel
  47. (cons (cons source-name info)
  48. (assq-delete-all source-name org-babel-library-of-babel))
  49. lob-ingest-count (1+ lob-ingest-count)))))
  50. (message "%d src block%s added to Library of Babel"
  51. lob-ingest-count (if (> lob-ingest-count 1) "s" ""))
  52. lob-ingest-count))
  53. (defconst org-babel-block-lob-one-liner-regexp
  54. (concat
  55. "^\\([ \t]*\\)#\\+call:[ \t]+\\([^\(\)\n]+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)"
  56. "\(\\([^\n]*\\)\)\\(\\[.+\\]\\|\\)[ \t]*\\(\\([^\n]*\\)\\)?")
  57. "Regexp to match non-inline calls to predefined source block functions.")
  58. (defconst org-babel-inline-lob-one-liner-regexp
  59. (concat
  60. "\\([^\n]*\\)call_\\([^\(\)\n]+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)"
  61. "\(\\([^\n]*\\)\)\\(\\[\\(.*?\\)\\]\\)?")
  62. "Regexp to match inline calls to predefined source block functions.")
  63. (defconst org-babel-lob-one-liner-regexp
  64. (concat "\\(" org-babel-block-lob-one-liner-regexp
  65. "\\|" org-babel-inline-lob-one-liner-regexp "\\)")
  66. "Regexp to match calls to predefined source block functions.")
  67. ;; functions for executing lob one-liners
  68. ;;;###autoload
  69. (defmacro org-babel-map-call-lines (file &rest body)
  70. "Evaluate BODY forms on each call line in FILE.
  71. If FILE is nil evaluate BODY forms on source blocks in current
  72. buffer."
  73. (declare (indent 1))
  74. (let ((tempvar (make-symbol "file")))
  75. `(let* ((,tempvar ,file)
  76. (visited-p (or (null ,tempvar)
  77. (get-file-buffer (expand-file-name ,tempvar))))
  78. (point (point)) to-be-removed)
  79. (save-window-excursion
  80. (when ,tempvar (find-file ,tempvar))
  81. (setq to-be-removed (current-buffer))
  82. (goto-char (point-min))
  83. (while (re-search-forward org-babel-lob-one-liner-regexp nil t)
  84. (goto-char (match-beginning 1))
  85. (save-match-data ,@body)
  86. (goto-char (match-end 0))))
  87. (unless visited-p (kill-buffer to-be-removed))
  88. (goto-char point))))
  89. (def-edebug-spec org-babel-map-call-lines (form body))
  90. ;;;###autoload
  91. (defun org-babel-lob-execute-maybe ()
  92. "Execute a Library of Babel source block, if appropriate.
  93. Detect if this is context for a Library Of Babel source block and
  94. if so then run the appropriate source block from the Library."
  95. (interactive)
  96. (let ((info (org-babel-lob-get-info)))
  97. (if (and (nth 0 info) (not (org-babel-in-example-or-verbatim)))
  98. (progn (org-babel-lob-execute info) t)
  99. nil)))
  100. ;;;###autoload
  101. (defun org-babel-lob-get-info ()
  102. "Return a Library of Babel function call as a string."
  103. (flet ((nonempty (a b)
  104. (let ((it (match-string a)))
  105. (if (= (length it) 0) (match-string b) it))))
  106. (let ((case-fold-search t))
  107. (save-excursion
  108. (beginning-of-line 1)
  109. (when (looking-at org-babel-lob-one-liner-regexp)
  110. (append
  111. (mapcar #'org-babel-clean-text-properties
  112. (list
  113. (format "%s%s(%s)%s"
  114. (nonempty 3 12)
  115. (if (not (= 0 (length (nonempty 5 13))))
  116. (concat "[" (nonempty 5 13) "]") "")
  117. (or (nonempty 7 16) "")
  118. (or (nonempty 8 19) ""))
  119. (nonempty 9 18)))
  120. (list (length (if (= (length (match-string 12)) 0)
  121. (match-string 2) (match-string 11))))))))))
  122. (defun org-babel-lob-execute (info)
  123. "Execute the lob call specified by INFO."
  124. (let ((params (org-babel-process-params
  125. (org-babel-merge-params
  126. org-babel-default-header-args
  127. (org-babel-params-from-properties)
  128. (org-babel-parse-header-arguments
  129. (org-babel-clean-text-properties
  130. (concat ":var results="
  131. (mapconcat #'identity (butlast info) " "))))))))
  132. (org-babel-execute-src-block
  133. nil (list "emacs-lisp" "results" params nil nil (nth 2 info)))))
  134. (provide 'ob-lob)
  135. ;;; ob-lob.el ends here