Browse Source

Merging master into results.

In order to get new tangle load-file function. Had to resolve org-babel.org conflict manually and didn't know the 'proper' way to do so, so there may be weirdness in that file.
Dan Davison 16 years ago
parent
commit
690ed664c6
3 changed files with 155 additions and 45 deletions
  1. 51 17
      lisp/org-babel-tangle.el
  2. 95 28
      org-babel.org
  3. 9 0
      test-tangle.org

+ 51 - 17
lisp/org-babel-tangle.el

@@ -38,13 +38,42 @@ language, and the cdr should be a list containing the extension
 and shebang(#!) line to use when writing out the language to
 file.")
 
-(defun org-babel-tangle ()
+(defun org-babel-load-file (file)
+  "Load the contents of the Emacs Lisp source code blocks in the
+org-mode formatted FILE.  This function will first export the
+source code using `org-babel-tangle' and then load the resulting
+file using `load-file'."
+  (let ((loadable-file (first (org-babel-tangle-file file "emacs-lisp"))))
+    (message "loading %s" loadable-file)
+    (unless (file-exists-p loadable-file)
+      (error "can't load file that doesn't exist"))
+    (load-file loadable-file)
+    (message "loaded %s" loadable-file)))
+
+(defun org-babel-tangle-file (file &optional lang)
+  "Extract the bodies of all source code blocks in FILE with
+`org-babel-tangle'.  Optional argument LANG can be used to limit
+the exported source code blocks by language."
+  (flet ((age (file)
+              (time-to-seconds
+               (time-subtract (current-time)
+                              (sixth (file-attributes file))))))
+    (let ((target-file (concat (file-name-sans-extension file) "."
+                               (second (assoc lang org-babel-tangle-langs)))))
+      (if (and lang (file-exists-p target-file) (> (age file) (age target-file)))
+          (list target-file)
+        (save-window-excursion (find-file file) (org-babel-tangle lang))))))
+
+(defun org-babel-tangle (&optional lang)
   "Extract the bodies of all source code blocks from the current
-file into their own source-specific files."
+file into their own source-specific files.  Optional argument
+LANG can be used to limit the exported source code blocks by
+language."
   (interactive)
   (save-excursion
     (let ((base-name (file-name-sans-extension (buffer-file-name)))
-          (block-counter 0))
+          (block-counter 0)
+          path-collector)
       (mapc ;; for every language create a file
        (lambda (by-lang)
          (let* ((lang (car by-lang))
@@ -54,6 +83,7 @@ file into their own source-specific files."
                 (she-bang (second lang-specs))
                 (by-session (cdr by-lang)))
            (flet ((to-file (filename specs)
+                           (add-to-list 'path-collector filename)
                            (with-temp-file filename
                              (funcall lang-f)
                              (when she-bang (insert (concat she-bang "\n")))
@@ -69,14 +99,17 @@ file into their own source-specific files."
                        by-session)
                (setq block-counter (+ block-counter (length (cdr (car by-session)))))
                (to-file (format "%s.%s" base-name ext) (cdr (car by-session)))))))
-       (org-babel-collect-blocks))
-      (message "tangled %d source-code blocks" block-counter))))
+       (org-babel-collect-blocks lang))
+      (message "tangled %d source-code blocks" block-counter)
+      path-collector)))
 
-(defun org-babel-collect-blocks ()
+(defun org-babel-collect-blocks (&optional lang)
   "Collect all source blocks in the current org-mode file.
 Return two nested association lists, first grouped by language,
 then by session, the contents will be source-code block
-specifications of the form used by `org-babel-spec-to-string'."
+specifications of the form used by `org-babel-spec-to-string'.
+Optional argument LANG can be used to limit the collected source
+code blocks by language."
   (let ((block-counter 0) blocks)
     (org-babel-map-source-blocks (buffer-file-name)
       (setq block-counter (+ 1 block-counter))
@@ -85,21 +118,22 @@ specifications of the form used by `org-babel-spec-to-string'."
              (source-name (intern (or (org-babel-get-src-block-name)
                                       (format "block-%d" block-counter))))
              (info (org-babel-get-src-block-info))
-             (lang (first info))
+             (src-lang (first info))
              (body (second info))
              (params (third info))
              (spec (list link source-name params body))
              (session (cdr (assoc :session params)))
              by-lang by-session)
-        ;; add the spec for this block to blocks under it's lang and session
-        (setq by-lang (cdr (assoc lang blocks)))
-        (setq blocks (delq (assoc lang blocks) blocks))
-        (setq by-session (cdr (assoc session by-lang)))
-        (setq by-lang (delq (assoc session by-lang) by-lang))
-        (setq blocks (cons ;; by-language
-                      (cons lang (cons ;; by-session
-                                  (cons session (cons spec by-session)) by-lang))
-                      blocks))))
+        (unless (and lang (not (string= lang src-lang))) ;; maybe limit by language
+          ;; add the spec for this block to blocks under it's language and session
+          (setq by-lang (cdr (assoc src-lang blocks)))
+          (setq blocks (delq (assoc src-lang blocks) blocks))
+          (setq by-session (cdr (assoc session by-lang)))
+          (setq by-lang (delq (assoc session by-lang) by-lang))
+          (setq blocks (cons ;; by-language
+                        (cons src-lang (cons ;; by-session
+                                        (cons session (cons spec by-session)) by-lang))
+                        blocks)))))
     ;; blocks should contain all source-blocks organized by language and session
     ;; (message "blocks=%S" blocks) ;; debugging
     blocks))

+ 95 - 28
org-babel.org

@@ -1,5 +1,5 @@
 #+TITLE: org-babel --- facilitating communication between programming languages and people
-#+SEQ_TODO: TODO PROPOSED STARTED | DONE DEFERRED REJECTED
+#+SEQ_TODO: PROPOSED TODO STARTED | DONE DEFERRED REJECTED
 #+OPTIONS: H:3 num:nil toc:t
 #+STARTUP: oddeven hideblocks
 
@@ -25,11 +25,10 @@ In this document:
 - The [[* Sandbox][Sandbox]] :: demonstrates much of the early/basic functionality
      through commented source-code blocks.
 
-Also see the [[file:library-of-babel.org][Library of Babel]] an extensible collection of ready-made
+Also see the [[file:library-of-babel.org][Library of Babel]], an extensible collection of ready-made
 and easily-shortcut-callable source-code blocks for handling common
 tasks.
 
-
 * Introduction
 
 Org-Babel enables *communication* between programming languages and
@@ -139,7 +138,16 @@ table, allowing the test suite to be run be evaluation of the table
 and the results to be collected in the same table.
 
 *** Emacs initialization files stored in Org-Mode buffers
-Once org-babel-tangle is completed this could be a very compelling use case.
+Using `org-babel-tangle' it is possible to embed your Emacs
+initialization into org-mode files.  This allows for folding,
+note-taking, todo's etc... embedded with the source-code of your Emacs
+initialization, and through org-mode's publishing features aids in
+sharing your customizations with others.
+
+It may be worthwhile to create a fork of Phil Hagelberg's
+[[http://github.com/technomancy/emacs-starter-kit/tree/master][emacs-starter-kit]] which uses literate org-mode files for all of the
+actual elisp customization.  These org-mode files could then be
+exported to html and used to populate the repositories wiki on [[http://github.com/][github]].
 
 
 ** features
@@ -191,7 +199,8 @@ would then be [[#sandbox][the sandbox]].
 #+end_src
 
 
-* Tasks [28/43]
+
+* Tasks [28/44]
 ** TODO support for working with =*Org Edit Src Example*= buffers [2/4]
 *** TODO optionally evaluate header references when we switch to =*Org Edit Src*= buffer
 That seems to imply that the header references need to be evaluated
@@ -323,6 +332,17 @@ languages which almost always produce graphical output should set
 results in the buffer.  Then if there is a combination of =silent= and
 =file= =:results= headers we could drop the results to a temp buffer
 and pop open that buffer...
+** TODO =\C-c \C-o= to open results of source block
+by adding a =defadvice= to =org-open-at-point= we can use the common
+=\C-c \C-o= keybinding to open the results of a source-code block.
+This would be especially useful for source-code blocks which generate
+graphical results and insert a file link as the results in the
+org-mode buffer.  (see [[* figure out how to handle graphic output][TODO figure out how to handle graphic output]]).
+This could also act reasonably with other results types...
+
+- file :: use org-open-at-point to open the file
+- scalar :: open results unquoted in a new buffer
+- tabular :: export the table to a new buffer and open that buffer
 
 ** TODO Finalise behaviour regarding vector/scalar output
 *** DONE Stop spaces causing vector output
@@ -823,8 +843,41 @@ $0
 [[file:snippets/org-mode/sb][sb -- snippet]]
 
 waiting for guidance from those more familiar with yasnippets
-
 ** DONE LoB: allow output in buffer
+** DONE singe-function tangling and loading elisp from literate org-mode file [3/3]
+
+This function should tangle the org-mode file for elisp, and then call
+`load-file' on the resulting tangled file.
+
+#+srcname: test-loading-embedded-emacs-lisp
+#+begin_src emacs-lisp :results replace
+  (setq test-tangle-advert nil)
+  (setq test-tangle-loading nil)
+  (setq results (list :before test-tangle-loading test-tangle-advert))
+  (org-babel-load-file "test-tangle.org")
+  (setq results (list (list :after test-tangle-loading test-tangle-advert) results))
+  (delete-file "test-tangle.el")
+  (reverse results)
+#+end_src
+
+#+resname: test-loading-embedded-emacs-lisp
+| :before | nil                 | nil                                                              |
+| :after  | "org-babel tangles" | "use org-babel-tangle for all your emacs initialization files!!" |
+
+*** DONE add optional language limiter to org-babel-tangle
+This should check to see if there is any need to re-export
+
+*** DONE ensure that org-babel-tangle returns the path to the tangled file(s)
+
+#+srcname: test-return-value-of-org-babel-tangle
+#+begin_src emacs-lisp :results replace
+  (mapcar #'file-name-nondirectory (org-babel-tangle-file "test-tangle.org" "emacs-lisp"))
+#+end_src
+
+#+resname:
+| "test-tangle.el" |
+
+*** DONE only tangle the file if it's actually necessary
 ** DONE add a function to jump to a source-block by name
    I've had an initial stab at that in org-babel-find-named-block
    (library-of-babel branch).
@@ -1914,20 +1967,11 @@ This could probably be added to [[file:lisp/org-babel-script.el][org-babel-scrip
 (see [[* file result types][file result types]])
 
 
-* Bugs [17/28]
+* Bugs [18/23]
 ** TODO Allow source blocks to be recognised when #+ are not first characters on the line
    I think Carsten has recently altered the core so that #+ can have
    preceding whitespace, at least for literal/code examples. org-babel
    should support this.
-** PROPOSED make :results replace the default?
-   I'm tending to think that appending results to pre-existing results
-   creates mess, and that the cleaner `replace' option should be the
-   default. E.g. when a source block creates an image, we would want
-   that to be updated, rather than have a new one be added.
-** PROPOSED external shell execution can't isolate return values
-I have no idea how to do this as of yet.  The result is that when
-shell functions are run w/o a session there is no difference between
-the =output= and =value= result arguments.
 
 ** TODO non-orgtbl formatted lists
 for example
@@ -1939,10 +1983,11 @@ for example
 
 #+resname: this-doesn't-match-orgtbl
 
+
 ** TODO collapsing consecutive newlines in string output
 
 #+srcname: multi-line-string-output
-#+begin_src ruby :results replace
+#+begin_src ruby :results output
 "the first line ends here
 
 
@@ -1951,15 +1996,35 @@ for example
 even a third"
 #+end_src
 
-#+resname:
-: the first line ends here
-: 	     and this is the second one
-: 	return even a third
+#+resname: multi-line-string-output
+
 
 ** TODO cursor movement when evaluating source blocks
    E.g. the pie chart example. Despite the save-window-excursion in
    org-babel-execute:R. (I never learned how to do this properly: org-R
    jumps all over the place...)
+   
+** PROPOSED external shell execution can't isolate return values
+I have no idea how to do this as of yet.  The result is that when
+shell functions are run w/o a session there is no difference between
+the =output= and =value= result arguments.
+
+Yea, I don't know how to do this either.  I searched extensively on
+how to isolate the *last* output of a series of shell commands (see
+[[* last command for
+ shells][last command for shells]]).  The results of the search were basically
+that it was not possible (or at least not accomplish-able with a
+reasonable amount of effort).
+
+That fact combined with the tenancy to all ways use standard out in
+shell scripts led me to treat these two options (=output= and =value=)
+as identical in shell evaluation.  Not ideal but maybe good enough for
+the moment.
+
+In the `results' branch I've changed this so that they're not quite
+identical: output results in raw stdout contents, whereas value
+converts it to elisp, perhaps to a table if it looks tabular. This is
+the same for the other languages. [Dan]
 
 ** TODO are the org-babel-trim s necessary?
    at the end of e.g. org-babel-R-evaluate, org-babel-python-evaluate, but
@@ -2045,6 +2110,15 @@ even a third"
 | 6 | .1666 |
 
 #+lob: R-plot(data=XX)
+
+** DONE make :results replace the default?
+   I'm tending to think that appending results to pre-existing results
+   creates mess, and that the cleaner `replace' option should be the
+   default. E.g. when a source block creates an image, we would want
+   that to be updated, rather than have a new one be added.
+   
+   I agree.
+
 ** DONE ruby evaluation not working under ubuntu emacs 23
    With emacs 23.0.91.1 on ubuntu, for C-h f run-ruby I have the
    following, which seems to conflict with [[file:lisp/langs/org-babel-ruby.el::let%20session%20buffer%20save%20window%20excursion%20run%20ruby%20nil%20session%20current%20buffer][this line]] in org-babel-ruby.el.
@@ -2775,13 +2849,6 @@ table.first.join(" - ")
 table[0]
 #+end_src
 
-#+resname:
-: [1, 2, 3]
-
-
-
-
-| 1 | 2 | 3 |
 
 #+begin_src ruby :var table=sandbox :results replace
 table

+ 9 - 0
test-tangle.org

@@ -76,3 +76,12 @@ end
 #+begin_src ruby :session special
 plus_two(holder)
 #+end_src
+
+
+** Emacs Lisp initialization stuff
+
+#+srcname: lets-set-some-variables
+#+begin_src emacs-lisp 
+  (setq test-tangle-loading "org-babel tangles")
+  (setq test-tangle-advert "use org-babel-tangle for all your emacs initialization files!!")
+#+end_src