Browse Source

org-babel: export of functional-style source blocks

A "functional-style" source block is one in which the name is followed
immediately by a parenthesised argument. An example is the following
"function", which generates n uniform random numbers:

\#+srcname: rand(n)
\#+begin_src R
runif(n)
\#+end_src

With these changes, such source blocks are passed over to the export
machinery in the following form:

\#+begin_src org-babel-lob
<function-def-keyword> rand(n):
\#+end_src
\#+begin_src R <switches>
<indent>runif(n)
\#+end_src

where <function-def-keyword> is the value of
org-babel-function-def-export-keyword, which defaults to "function",
<switches> are the src block switches that belonged to the original
block, and <indent> is the whitespace indent of the function body, the
width of which is determined by org-babel-function-def-export-indent.
org-babel-lob is a simple major mode responsible for fontification of
the blocks corresponding to the function definition line (as opposed
to the function body).
Dan Davison 15 years ago
parent
commit
c84903f1b3
2 changed files with 44 additions and 4 deletions
  1. 42 3
      contrib/babel/lisp/org-babel-exp.el
  2. 2 1
      contrib/babel/lisp/org-babel-lob.el

+ 42 - 3
contrib/babel/lisp/org-babel-exp.el

@@ -35,6 +35,27 @@
 (add-to-list 'org-export-interblocks '(src org-babel-exp-inline-src-blocks))
 (add-to-list 'org-export-interblocks '(src org-babel-exp-inline-src-blocks))
 (add-to-list 'org-export-interblocks '(lob org-babel-exp-lob-one-liners))
 (add-to-list 'org-export-interblocks '(lob org-babel-exp-lob-one-liners))
 
 
+(defvar org-babel-function-def-export-keyword "function"
+  "When exporting a source block function, this keyword will
+appear in the exported version in the place of #+srcname:. A
+source block is considered to be a source block function if the
+srcname is present and is followed by a parenthesised argument
+list. The parentheses may be empty or contain whitespace. An
+example is the following which generates n random
+(uniform) numbers.
+
+#+srcname: rand(n)
+#+begin_src R
+  runif(n)
+#+end_src
+")
+
+(defvar org-babel-function-def-export-indent 4
+  "When exporting a source block function, the block contents
+will be indented by this many characters. See
+`org-babel-function-def-export-name' for the definition of a
+source block function.")
+
 (defun org-babel-exp-src-blocks (body &rest headers)
 (defun org-babel-exp-src-blocks (body &rest headers)
   "Process src block for export.  Depending on the 'export'
   "Process src block for export.  Depending on the 'export'
 headers argument in replace the source code block with...
 headers argument in replace the source code block with...
@@ -107,11 +128,29 @@ options are taken from `org-babel-default-header-args'."
 (defun org-babel-exp-code (info type)
 (defun org-babel-exp-code (info type)
   (let ((lang (first info))
   (let ((lang (first info))
 	(body (second info))
 	(body (second info))
-	(switches (fourth info)))
+	(switches (fourth info))
+	(name (fifth info))
+	(args (sixth info))
+	(function-def-line ""))
     (case type
     (case type
       ('inline (format "=%s=" (second info)))
       ('inline (format "=%s=" (second info)))
-      ('block (format "#+BEGIN_SRC %s %s\n%s%s#+END_SRC" lang switches body
-		      (if (string-match "\n$" body) "" "\n")))
+      ('block
+	  (when args
+	    (unless (string-match "-i\\>" switches)
+	      (setq switches (concat switches " -i")))
+	    (setq body (with-temp-buffer
+			 (insert body)
+			 (indent-code-rigidly (point-min) (point-max) org-babel-function-def-export-indent)
+			 (buffer-string)))
+	    (setq args (mapconcat #'identity
+				  (delq nil (mapcar (lambda (el) (and (length (cdr el)) (cdr el))) args))
+				  ", "))
+	    (setq function-def-line
+		  (format "#+BEGIN_SRC org-babel-lob\n%s %s(%s):\n#+END_SRC\n"
+			  org-babel-function-def-export-keyword name args)))
+        (concat function-def-line
+                (format "#+BEGIN_SRC %s %s\n%s%s#+END_SRC" lang switches body
+                        (if (string-match "\n$" body) "" "\n"))))
       ('lob (save-excursion
       ('lob (save-excursion
 	      (re-search-backward org-babel-lob-one-liner-regexp)
 	      (re-search-backward org-babel-lob-one-liner-regexp)
 	      (format "#+BEGIN_SRC org-babel-lob\n%s\n#+END_SRC"
 	      (format "#+BEGIN_SRC org-babel-lob\n%s\n#+END_SRC"

+ 2 - 1
contrib/babel/lisp/org-babel-lob.el

@@ -31,6 +31,7 @@
 ;;; Code:
 ;;; Code:
 (require 'org-babel)
 (require 'org-babel)
 (require 'org-babel-table)
 (require 'org-babel-table)
+(require 'org-babel-exp)
 
 
 (defvar org-babel-library-of-babel nil
 (defvar org-babel-library-of-babel nil
   "Library of source-code blocks.  This is an association list.
   "Library of source-code blocks.  This is an association list.
@@ -94,7 +95,7 @@ the word 'call'."
     (org-babel-execute-src-block nil (list "emacs-lisp" "results" params))))
     (org-babel-execute-src-block nil (list "emacs-lisp" "results" params))))
 
 
 (define-generic-mode org-babel-lob-mode
 (define-generic-mode org-babel-lob-mode
-  '("#") nil nil nil nil
+  '("#") (list org-babel-function-def-export-keyword) nil nil nil
   "Major mode for fontification of library of babel lines on export")
   "Major mode for fontification of library of babel lines on export")
 
 
 (provide 'org-babel-lob)
 (provide 'org-babel-lob)