ob-lob.el 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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-lob-call-aliases '("lob" "call")
  53. "Aliases to call a source block function.
  54. If you change the value of this variable then your files may
  55. become unusable by other org-babel users, and vice versa.")
  56. (defconst org-babel-block-lob-one-liner-regexp
  57. (concat
  58. "^\\([ \t]*\\)#\\+\\(?:"
  59. (mapconcat #'regexp-quote org-babel-lob-call-aliases "\\|")
  60. "\\):[ \t]+\\([^\(\)\n]+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)"
  61. "\(\\([^\n]*\\)\)\\(\\[.+\\]\\|\\)[ \t]*\\(\\([^\n]*\\)\\)?")
  62. "Regexp to match non-inline calls to predefined source block functions.")
  63. (defconst org-babel-inline-lob-one-liner-regexp
  64. (concat
  65. "\\([^\n]*\\)\\(?:"
  66. (mapconcat #'regexp-quote org-babel-lob-call-aliases "\\|")
  67. "\\)_\\([^\(\)\n]+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)"
  68. "\(\\([^\n]*\\)\)\\(\\[\\(.*?\\)\\]\\)?")
  69. "Regexp to match inline calls to predefined source block functions.")
  70. (defconst org-babel-lob-one-liner-regexp
  71. (concat "\\(" org-babel-block-lob-one-liner-regexp
  72. "\\|" org-babel-inline-lob-one-liner-regexp "\\)")
  73. "Regexp to match calls to predefined source block functions.")
  74. ;; functions for executing lob one-liners
  75. ;;;###autoload
  76. (defmacro org-babel-map-call-lines (file &rest body)
  77. "Evaluate BODY forms on each call line in FILE.
  78. If FILE is nil evaluate BODY forms on source blocks in current
  79. buffer."
  80. (declare (indent 1))
  81. (let ((tempvar (make-symbol "file")))
  82. `(let* ((,tempvar ,file)
  83. (visited-p (or (null ,tempvar)
  84. (get-file-buffer (expand-file-name ,tempvar))))
  85. (point (point)) to-be-removed)
  86. (save-window-excursion
  87. (when ,tempvar (find-file ,tempvar))
  88. (setq to-be-removed (current-buffer))
  89. (goto-char (point-min))
  90. (while (re-search-forward org-babel-lob-one-liner-regexp nil t)
  91. (goto-char (match-beginning 1))
  92. (save-match-data ,@body)
  93. (goto-char (match-end 0))))
  94. (unless visited-p (kill-buffer to-be-removed))
  95. (goto-char point))))
  96. (def-edebug-spec org-babel-map-call-lines (form body))
  97. ;;;###autoload
  98. (defun org-babel-lob-execute-maybe ()
  99. "Execute a Library of Babel source block, if appropriate.
  100. Detect if this is context for a Library Of Babel source block and
  101. if so then run the appropriate source block from the Library."
  102. (interactive)
  103. (let ((info (org-babel-lob-get-info)))
  104. (if (and (nth 0 info) (not (org-babel-in-example-or-verbatim)))
  105. (progn (org-babel-lob-execute info) t)
  106. nil)))
  107. ;;;###autoload
  108. (defun org-babel-lob-get-info ()
  109. "Return a Library of Babel function call as a string."
  110. (flet ((nonempty (a b)
  111. (let ((it (match-string a)))
  112. (if (= (length it) 0) (match-string b) it))))
  113. (let ((case-fold-search t))
  114. (save-excursion
  115. (beginning-of-line 1)
  116. (when (looking-at org-babel-lob-one-liner-regexp)
  117. (append
  118. (mapcar #'org-babel-clean-text-properties
  119. (list
  120. (format "%s%s(%s)%s"
  121. (nonempty 3 12)
  122. (if (not (= 0 (length (nonempty 5 13))))
  123. (concat "[" (nonempty 5 13) "]") "")
  124. (or (nonempty 7 16) "")
  125. (or (nonempty 8 19) ""))
  126. (nonempty 9 18)))
  127. (list (length (if (= (length (match-string 12)) 0)
  128. (match-string 2) (match-string 11))))))))))
  129. (defun org-babel-lob-execute (info)
  130. "Execute the lob call specified by INFO."
  131. (let ((params (org-babel-process-params
  132. (org-babel-merge-params
  133. org-babel-default-header-args
  134. (org-babel-params-from-properties)
  135. (org-babel-parse-header-arguments
  136. (org-babel-clean-text-properties
  137. (concat ":var results="
  138. (mapconcat #'identity (butlast info) " "))))))))
  139. (org-babel-execute-src-block
  140. nil (list "emacs-lisp" "results" params nil nil (nth 2 info)))))
  141. (provide 'ob-lob)
  142. ;;; ob-lob.el ends here