diff --git a/contrib/babel/library-of-babel.org b/contrib/babel/library-of-babel.org index 441d1f4fa..ded879220 100644 --- a/contrib/babel/library-of-babel.org +++ b/contrib/babel/library-of-babel.org @@ -35,6 +35,32 @@ The raw Org-mode text of this file can be downloaded at [[repofile:contrib/babel/library-of-babel.org][library-of-babel.org]] +* File I/O +** reading and writing files +Read the contents of the file at =path= into a string. +#+srcname: read +#+begin_src emacs-lisp :var path="" + (with-temp-filebuffer path + (buffer-substring (point-min) (point-max))) +#+end_src + +Read the lines of the file at =path= into a list. +#+srcname: read-lines +#+begin_src emacs-lisp :var path="" + (split-string + (with-temp-filebuffer path + (buffer-substring (point-min) (point-max)))) +#+end_src + +Write =data= to a file at =path=. If =data= is a list, then write it +as a table in traditional Org-mode table syntax. +#+srcname: write +#+begin_src emacs-lisp :var data="" :var path="" + (with-temp-file path + (org-babel-insert-result data)) + nil +#+end_src + * Plotting code ** R diff --git a/contrib/babel/lisp/langs/org-babel-ruby.el b/contrib/babel/lisp/langs/org-babel-ruby.el index 4919850cb..ca7ce29df 100644 --- a/contrib/babel/lisp/langs/org-babel-ruby.el +++ b/contrib/babel/lisp/langs/org-babel-ruby.el @@ -65,13 +65,15 @@ called by `org-babel-execute-src-block'." (result-params (third processed-params)) (result-type (fourth processed-params)) (full-body (org-babel-expand-body:ruby - body params processed-params)) ;; then the source block body + body params processed-params)) (result (org-babel-ruby-evaluate session full-body result-type))) (or (cdr (assoc :file params)) (org-babel-reassemble-table result - (org-babel-pick-name (nth 4 processed-params) (cdr (assoc :colnames params))) - (org-babel-pick-name (nth 5 processed-params) (cdr (assoc :rownames params))))))) + (org-babel-pick-name (nth 4 processed-params) + (cdr (assoc :colnames params))) + (org-babel-pick-name (nth 5 processed-params) + (cdr (assoc :rownames params))))))) (defun org-babel-prep-session:ruby (session params) "Prepare SESSION according to the header arguments specified in PARAMS." @@ -129,9 +131,10 @@ Emacs-lisp table, otherwise return the results as a string." "If there is not a current inferior-process-buffer in SESSION then create. Return the initialized session." (unless (string= session "none") - (let ((session-buffer (save-window-excursion (run-ruby nil session) (current-buffer)))) + (let ((session-buffer (save-window-excursion + (run-ruby nil session) (current-buffer)))) (if (org-babel-comint-buffer-livep session-buffer) - session-buffer + (progn (sit-for .25) session-buffer) (sit-for .5) (org-babel-ruby-initiate-session session))))) @@ -175,24 +178,30 @@ last statement in BODY, as elisp." (with-temp-buffer (insert body) ;; (message "buffer=%s" (buffer-string)) ;; debugging - (org-babel-shell-command-on-region (point-min) (point-max) "ruby" 'current-buffer 'replace) + (org-babel-shell-command-on-region + (point-min) (point-max) "ruby" 'current-buffer 'replace) (buffer-string))) (value - (let* ((tmp-file (make-temp-file "ruby-functional-results")) exit-code + (let* ((tmp-file (make-temp-file "ruby-functional-results")) + exit-code (stderr (with-temp-buffer (insert (format (if (member "pp" result-params) org-babel-ruby-pp-wrapper-method - org-babel-ruby-wrapper-method) body tmp-file)) - ;; (message "buffer=%s" (buffer-string)) ;; debugging + org-babel-ruby-wrapper-method) + body tmp-file)) (setq exit-code - (org-babel-shell-command-on-region (point-min) (point-max) "ruby" nil 'replace (current-buffer))) + (org-babel-shell-command-on-region + (point-min) (point-max) "ruby" + nil 'replace (current-buffer))) (buffer-string)))) (if (> exit-code 0) (org-babel-error-notify exit-code stderr)) (let ((raw (with-temp-buffer - (insert-file-contents (org-babel-maybe-remote-file tmp-file)) + (insert-file-contents + (org-babel-maybe-remote-file tmp-file)) (buffer-string)))) - (if (or (member "code" result-params) (member "pp" result-params)) + (if (or (member "code" result-params) + (member "pp" result-params)) raw (org-babel-ruby-table-or-string raw))))))) ;; comint session evaluation @@ -203,11 +212,13 @@ last statement in BODY, as elisp." org-babel-ruby-pp-last-value-eval org-babel-ruby-last-value-eval) org-babel-ruby-eoe-indicator) "\n")) - (raw (org-babel-comint-with-output buffer org-babel-ruby-eoe-indicator t + (raw (org-babel-comint-with-output + buffer org-babel-ruby-eoe-indicator t (insert full-body) (comint-send-input nil t))) - (results (cdr (member org-babel-ruby-eoe-indicator - (reverse (mapcar #'org-babel-ruby-read-string - (mapcar #'org-babel-trim raw))))))) + (results (cdr (member + org-babel-ruby-eoe-indicator + (reverse (mapcar #'org-babel-ruby-read-string + (mapcar #'org-babel-trim raw))))))) (case result-type (output (mapconcat #'identity (reverse (cdr results)) "\n")) (value diff --git a/contrib/babel/lisp/org-babel-comint.el b/contrib/babel/lisp/org-babel-comint.el index e693a4034..0189c9a2e 100644 --- a/contrib/babel/lisp/org-babel-comint.el +++ b/contrib/babel/lisp/org-babel-comint.el @@ -52,38 +52,53 @@ body inside the protection of `save-window-excursion' and (set-buffer ,buffer) ,@body))) -(defmacro org-babel-comint-with-output (buffer eoe-indicator remove-echo &rest body) +(defmacro org-babel-comint-with-output + (buffer eoe-indicator remove-echo &rest body) "Evaluate BODY in BUFFER, wait until EOE-INDICATOR appears in output, then return all process output. This ensures that the filter is removed in case of an error or user `keyboard-quit' during execution of body." (declare (indent 3)) `(org-babel-comint-in-buffer ,buffer - (let ((string-buffer "")) + (let ((string-buffer "") dangling-text) (flet ((my-filt (text) (setq string-buffer (concat string-buffer text)))) ;; setup filter (add-hook 'comint-output-filter-functions 'my-filt) (unwind-protect (progn - ;; pass FULL-BODY to process + ;; got located, and save dangling text (goto-char (process-mark (get-buffer-process (current-buffer)))) + (let ((start (point)) + (end (point-max))) + (setq dangling-text (buffer-substring start end)) + (delete-region start end)) + ;; pass FULL-BODY to process ,@body ;; wait for end-of-evaluation indicator (while (progn (goto-char comint-last-input-end) (not (save-excursion - (and (re-search-forward comint-prompt-regexp nil t) - (re-search-forward (regexp-quote ,eoe-indicator) nil t))))) + (and (re-search-forward + comint-prompt-regexp nil t) + (re-search-forward + (regexp-quote ,eoe-indicator) nil t))))) (accept-process-output (get-buffer-process (current-buffer))) - ;; ;; thought this would allow async background running, but I was wrong... - ;; (run-with-timer .5 .5 'accept-process-output (get-buffer-process (current-buffer))) - )) + ;; thought the following this would allow async + ;; background running, but I was wrong... + ;; (run-with-timer .5 .5 'accept-process-output + ;; (get-buffer-process (current-buffer))) + ) + ;; replace cut dangling text + (goto-char (process-mark (get-buffer-process (current-buffer)))) + (insert dangling-text)) ;; remove filter (remove-hook 'comint-output-filter-functions 'my-filt))) ;; remove echo'd FULL-BODY from input (if (and ,remove-echo (string-match - (replace-regexp-in-string "\n" "\r\n" (regexp-quote ,full-body)) string-buffer)) + (replace-regexp-in-string + "\n" "[\r\n]+" (regexp-quote ,full-body)) + string-buffer)) (setq raw (substring string-buffer (match-end 0)))) (split-string string-buffer comint-prompt-regexp)))) diff --git a/contrib/babel/lisp/org-babel-exp.el b/contrib/babel/lisp/org-babel-exp.el index 2764412cb..e27915493 100644 --- a/contrib/babel/lisp/org-babel-exp.el +++ b/contrib/babel/lisp/org-babel-exp.el @@ -121,18 +121,25 @@ options are taken from `org-babel-default-header-args'." (defun org-babel-exp-do-export (info type) "Return a string containing the exported content of the current code block respecting the value of the :exports header argument." - (case (intern (or (cdr (assoc :exports (third info))) "code")) - ('none "") - ('code (org-babel-exp-code info type)) - ('results (org-babel-exp-results info type)) - ('both (concat (org-babel-exp-code info type) - "\n\n" - (org-babel-exp-results info type))))) + (flet ((silently () (let ((session (cdr (assoc :session (third info))))) + (when (and session + (not (equal "none" session)) + (not (assoc :noeval (third info)))) + (org-babel-exp-results info type 'silent)))) + (clean () (org-babel-remove-result info))) + (case (intern (or (cdr (assoc :exports (third info))) "code")) + ('none (silently) (clean) "") + ('code (silently) (clean) (org-babel-exp-code info type)) + ('results (org-babel-exp-results info type)) + ('both (concat (org-babel-exp-code info type) + "\n\n" + (org-babel-exp-results info type)))))) (defun org-babel-exp-code (info type) "Return the code the current code block in a manner suitable for exportation by org-mode. This function is called by -`org-babel-exp-do-export'." +`org-babel-exp-do-export'. The code block will not be +evaluated." (let ((lang (first info)) (body (second info)) (switches (fourth info)) @@ -165,10 +172,12 @@ for exportation by org-mode. This function is called by call-line)) ((t (format ": %s\n" call-line))))))))) -(defun org-babel-exp-results (info type) +(defun org-babel-exp-results (info type &optional silent) "Return the results of the current code block in a manner suitable for exportation by org-mode. This function is called by -`org-babel-exp-do-export'." +`org-babel-exp-do-export'. The code block will be evaluated. +Optional argument SILENT can be used to inhibit insertion of +results into the buffer." (let ((lang (first info)) (body (second info)) (params @@ -189,28 +198,31 @@ suitable for exportation by org-mode. This function is called by (let ((raw (org-babel-execute-src-block nil info '((:results . "silent")))) (result-params (split-string (cdr (assoc :results params))))) - (cond ;; respect the value of the :results header argument - ((member "file" result-params) - (org-babel-result-to-file raw)) - ((or (member "raw" result-params) (member "org" result-params)) - (format "%s" raw)) - ((member "code" result-params) - (format "src_%s{%s}" lang raw)) - (t - (if (stringp raw) - (if (= 0 (length raw)) "=(no results)=" - (format "=%s=" raw)) - (format "=%S=" raw)))))) + (unless silent + (cond ;; respect the value of the :results header argument + ((member "file" result-params) + (org-babel-result-to-file raw)) + ((or (member "raw" result-params) (member "org" result-params)) + (format "%s" raw)) + ((member "code" result-params) + (format "src_%s{%s}" lang raw)) + (t + (if (stringp raw) + (if (= 0 (length raw)) "=(no results)=" + (format "=%s=" raw)) + (format "=%S=" raw))))))) ('block (org-babel-execute-src-block - nil nil (org-babel-merge-params params '((:results . "replace")))) + nil nil (org-babel-merge-params + params `((:results . ,(if silent "silent" "replace"))))) "") ('lob (save-excursion (re-search-backward org-babel-lob-one-liner-regexp nil t) (org-babel-execute-src-block - nil (list lang body (org-babel-merge-params - params '((:results . "replace"))))) ""))))) + nil (list lang body + (org-babel-merge-params + params `((:results . ,(if silent "silent" "replace")))))) ""))))) (provide 'org-babel-exp) ;;; org-babel-exp.el ends here diff --git a/contrib/babel/lisp/org-babel-tangle.el b/contrib/babel/lisp/org-babel-tangle.el index 9d8749d64..30bb8fc92 100644 --- a/contrib/babel/lisp/org-babel-tangle.el +++ b/contrib/babel/lisp/org-babel-tangle.el @@ -255,7 +255,8 @@ form "no") (fifth spec))))) (insert-comment (format "[[%s][%s]]" (org-link-escape link) source-name)) - (insert (format "\n%s\n" (org-babel-chomp body))) + (insert (format "\n%s\n" (replace-regexp-in-string + "^," "" (org-babel-chomp body)))) (insert-comment (format "%s ends here" source-name))))) (provide 'org-babel-tangle) diff --git a/contrib/babel/lisp/org-babel.el b/contrib/babel/lisp/org-babel.el index b6e50d1b4..bb31161c2 100644 --- a/contrib/babel/lisp/org-babel.el +++ b/contrib/babel/lisp/org-babel.el @@ -46,7 +46,9 @@ then run `org-babel-execute-src-block'." then run `org-babel-expand-src-block'." (interactive) (let ((info (org-babel-get-src-block-info))) - (if info (progn (org-babel-expand-src-block current-prefix-arg info) t) nil))) + (if info + (progn (org-babel-expand-src-block current-prefix-arg info) t) + nil))) (defadvice org-edit-special (around org-babel-prep-session-for-edit activate) "Prepare the current source block's session according to it's @@ -75,7 +77,9 @@ to `org-open-at-point'." then run `org-babel-load-in-session'." (interactive) (let ((info (org-babel-get-src-block-info))) - (if info (progn (org-babel-load-in-session current-prefix-arg info) t) nil))) + (if info + (progn (org-babel-load-in-session current-prefix-arg info) t) + nil))) (add-hook 'org-metaup-hook 'org-babel-load-in-session-maybe) @@ -89,7 +93,8 @@ then run `org-babel-pop-to-session'." (add-hook 'org-metadown-hook 'org-babel-pop-to-session-maybe) (defconst org-babel-header-arg-names - '(cache cmdline colnames dir exports file noweb results session tangle var) + '(cache cmdline colnames dir exports file noweb results + session tangle var noeval) "Common header arguments used by org-babel. Note that individual languages may define their own language specific header arguments as well.") @@ -384,10 +389,11 @@ the current buffer." "Call `org-babel-execute-src-block' on every source block in the current subtree." (interactive "P") - (save-excursion - (org-narrow-to-subtree) - (org-babel-execute-buffer) - (widen))) + (save-restriction + (save-excursion + (org-narrow-to-subtree) + (org-babel-execute-buffer) + (widen)))) (defun org-babel-get-src-block-info (&optional header-vars-only) "Get information of the current source block. @@ -965,7 +971,7 @@ code ---- the results are extracted in the syntax of the source (listp (cdr (car result))))) result (list result)) '(:fmt (lambda (cell) (format "%s" cell)))) "\n")) - (goto-char beg) (org-cycle)) + (goto-char beg) (org-table-align)) ((member "file" result-params) (insert result)) ((member "html" result-params)