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
 and shebang(#!) line to use when writing out the language to
 file.")
 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
   "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)
   (interactive)
   (save-excursion
   (save-excursion
     (let ((base-name (file-name-sans-extension (buffer-file-name)))
     (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
       (mapc ;; for every language create a file
        (lambda (by-lang)
        (lambda (by-lang)
          (let* ((lang (car by-lang))
          (let* ((lang (car by-lang))
@@ -54,6 +83,7 @@ file into their own source-specific files."
                 (she-bang (second lang-specs))
                 (she-bang (second lang-specs))
                 (by-session (cdr by-lang)))
                 (by-session (cdr by-lang)))
            (flet ((to-file (filename specs)
            (flet ((to-file (filename specs)
+                           (add-to-list 'path-collector filename)
                            (with-temp-file filename
                            (with-temp-file filename
                              (funcall lang-f)
                              (funcall lang-f)
                              (when she-bang (insert (concat she-bang "\n")))
                              (when she-bang (insert (concat she-bang "\n")))
@@ -69,14 +99,17 @@ file into their own source-specific files."
                        by-session)
                        by-session)
                (setq block-counter (+ block-counter (length (cdr (car by-session)))))
                (setq block-counter (+ block-counter (length (cdr (car by-session)))))
                (to-file (format "%s.%s" base-name ext) (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.
   "Collect all source blocks in the current org-mode file.
 Return two nested association lists, first grouped by language,
 Return two nested association lists, first grouped by language,
 then by session, the contents will be source-code block
 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)
   (let ((block-counter 0) blocks)
     (org-babel-map-source-blocks (buffer-file-name)
     (org-babel-map-source-blocks (buffer-file-name)
       (setq block-counter (+ 1 block-counter))
       (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)
              (source-name (intern (or (org-babel-get-src-block-name)
                                       (format "block-%d" block-counter))))
                                       (format "block-%d" block-counter))))
              (info (org-babel-get-src-block-info))
              (info (org-babel-get-src-block-info))
-             (lang (first info))
+             (src-lang (first info))
              (body (second info))
              (body (second info))
              (params (third info))
              (params (third info))
              (spec (list link source-name params body))
              (spec (list link source-name params body))
              (session (cdr (assoc :session params)))
              (session (cdr (assoc :session params)))
              by-lang by-session)
              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
     ;; blocks should contain all source-blocks organized by language and session
     ;; (message "blocks=%S" blocks) ;; debugging
     ;; (message "blocks=%S" blocks) ;; debugging
     blocks))
     blocks))

+ 95 - 28
org-babel.org

@@ -1,5 +1,5 @@
 #+TITLE: org-babel --- facilitating communication between programming languages and people
 #+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
 #+OPTIONS: H:3 num:nil toc:t
 #+STARTUP: oddeven hideblocks
 #+STARTUP: oddeven hideblocks
 
 
@@ -25,11 +25,10 @@ In this document:
 - The [[* Sandbox][Sandbox]] :: demonstrates much of the early/basic functionality
 - The [[* Sandbox][Sandbox]] :: demonstrates much of the early/basic functionality
      through commented source-code blocks.
      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
 and easily-shortcut-callable source-code blocks for handling common
 tasks.
 tasks.
 
 
-
 * Introduction
 * Introduction
 
 
 Org-Babel enables *communication* between programming languages and
 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.
 and the results to be collected in the same table.
 
 
 *** Emacs initialization files stored in Org-Mode buffers
 *** 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
 ** features
@@ -191,7 +199,8 @@ would then be [[#sandbox][the sandbox]].
 #+end_src
 #+end_src
 
 
 
 
-* Tasks [28/43]
+
+* Tasks [28/44]
 ** TODO support for working with =*Org Edit Src Example*= buffers [2/4]
 ** 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
 *** 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
 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
 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
 =file= =:results= headers we could drop the results to a temp buffer
 and pop open that 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
 ** TODO Finalise behaviour regarding vector/scalar output
 *** DONE Stop spaces causing vector output
 *** DONE Stop spaces causing vector output
@@ -823,8 +843,41 @@ $0
 [[file:snippets/org-mode/sb][sb -- snippet]]
 [[file:snippets/org-mode/sb][sb -- snippet]]
 
 
 waiting for guidance from those more familiar with yasnippets
 waiting for guidance from those more familiar with yasnippets
-
 ** DONE LoB: allow output in buffer
 ** 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
 ** 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
    I've had an initial stab at that in org-babel-find-named-block
    (library-of-babel branch).
    (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]])
 (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
 ** 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
    I think Carsten has recently altered the core so that #+ can have
    preceding whitespace, at least for literal/code examples. org-babel
    preceding whitespace, at least for literal/code examples. org-babel
    should support this.
    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
 ** TODO non-orgtbl formatted lists
 for example
 for example
@@ -1939,10 +1983,11 @@ for example
 
 
 #+resname: this-doesn't-match-orgtbl
 #+resname: this-doesn't-match-orgtbl
 
 
+
 ** TODO collapsing consecutive newlines in string output
 ** TODO collapsing consecutive newlines in string output
 
 
 #+srcname: multi-line-string-output
 #+srcname: multi-line-string-output
-#+begin_src ruby :results replace
+#+begin_src ruby :results output
 "the first line ends here
 "the first line ends here
 
 
 
 
@@ -1951,15 +1996,35 @@ for example
 even a third"
 even a third"
 #+end_src
 #+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
 ** TODO cursor movement when evaluating source blocks
    E.g. the pie chart example. Despite the save-window-excursion in
    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
    org-babel-execute:R. (I never learned how to do this properly: org-R
    jumps all over the place...)
    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?
 ** TODO are the org-babel-trim s necessary?
    at the end of e.g. org-babel-R-evaluate, org-babel-python-evaluate, but
    at the end of e.g. org-babel-R-evaluate, org-babel-python-evaluate, but
@@ -2045,6 +2110,15 @@ even a third"
 | 6 | .1666 |
 | 6 | .1666 |
 
 
 #+lob: R-plot(data=XX)
 #+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
 ** 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
    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.
    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]
 table[0]
 #+end_src
 #+end_src
 
 
-#+resname:
-: [1, 2, 3]
-
-
-
-
-| 1 | 2 | 3 |
 
 
 #+begin_src ruby :var table=sandbox :results replace
 #+begin_src ruby :var table=sandbox :results replace
 table
 table

+ 9 - 0
test-tangle.org

@@ -76,3 +76,12 @@ end
 #+begin_src ruby :session special
 #+begin_src ruby :session special
 plus_two(holder)
 plus_two(holder)
 #+end_src
 #+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