diff options
Diffstat (limited to 'lisp/org/ob-sh.el')
-rw-r--r-- | lisp/org/ob-sh.el | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/lisp/org/ob-sh.el b/lisp/org/ob-sh.el index 6ca52b1f361..9349a842a60 100644 --- a/lisp/org/ob-sh.el +++ b/lisp/org/ob-sh.el @@ -1,11 +1,11 @@ ;;; ob-sh.el --- org-babel functions for shell evaluation -;; Copyright (C) 2009-2011 Free Software Foundation, Inc. +;; Copyright (C) 2009, 2010 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.4 +;; Version: 7.7 ;; This file is part of GNU Emacs. @@ -28,6 +28,7 @@ ;;; Code: (require 'ob) +(require 'ob-ref) (require 'ob-comint) (require 'ob-eval) (require 'shell) @@ -45,16 +46,25 @@ "Command used to invoke a shell. This will be passed to `shell-command-on-region'") +(defcustom org-babel-sh-var-quote-fmt + "$(cat <<'BABEL_TABLE'\n%s\nBABEL_TABLE\n)" + "Format string used to escape variables when passed to shell scripts." + :group 'org-babel + :type 'string) + (defun org-babel-execute:sh (body params) "Execute a block of Shell commands with Babel. This function is called by `org-babel-execute-src-block'." (let* ((session (org-babel-sh-initiate-session (cdr (assoc :session params)))) - (result-params (cdr (assoc :result-params params))) + (result-params (cdr (assoc :result-params params))) + (stdin ((lambda (stdin) (when stdin (org-babel-sh-var-to-string + (org-babel-ref-resolve stdin)))) + (cdr (assoc :stdin params)))) (full-body (org-babel-expand-body:generic body params (org-babel-variable-assignments:sh params)))) (org-babel-reassemble-table - (org-babel-sh-evaluate session full-body result-params) + (org-babel-sh-evaluate session full-body result-params stdin) (org-babel-pick-name (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name @@ -95,20 +105,17 @@ This function is called by `org-babel-execute-src-block'." "Convert an elisp value to a shell variable. Convert an elisp var into a string of shell commands specifying a var of the same value." - (if (listp var) - (flet ((deep-string (el) - (if (listp el) - (mapcar #'deep-string el) - (org-babel-sh-var-to-sh el sep)))) - (format "$(cat <<'BABEL_TABLE'\n%s\nBABEL_TABLE\n)" - (orgtbl-to-generic - (deep-string (if (listp (car var)) var (list var))) - (list :sep (or sep "\t"))))) - (if (stringp var) - (if (string-match "[\n\r]" var) - (format "$(cat <<BABEL_STRING\n%s\nBABEL_STRING\n)" var) - (format "%s" var)) - (format "%S" var)))) + (format org-babel-sh-var-quote-fmt (org-babel-sh-var-to-string var sep))) + +(defun org-babel-sh-var-to-string (var &optional sep) + "Convert an elisp value to a string." + (flet ((echo-var (v) (if (stringp v) v (format "%S" v)))) + (cond + ((and (listp var) (listp (car var))) + (orgtbl-to-generic var (list :sep (or sep "\t") :fmt #'echo-var))) + ((listp var) + (mapconcat #'echo-var var "\n")) + (t (echo-var var))))) (defun org-babel-sh-table-or-results (results) "Convert RESULTS to an appropriate elisp value. @@ -128,7 +135,7 @@ Emacs-lisp table, otherwise return the results as a string." (defvar org-babel-sh-eoe-output "org_babel_sh_eoe" "String to indicate that evaluation has completed.") -(defun org-babel-sh-evaluate (session body &optional result-params) +(defun org-babel-sh-evaluate (session body &optional result-params stdin) "Pass BODY to the Shell process in BUFFER. If RESULT-TYPE equals 'output then return a list of the outputs of the statements in BODY, if RESULT-TYPE equals 'value then @@ -136,13 +143,25 @@ return the value of the last statement in BODY." ((lambda (results) (when results (if (or (member "scalar" result-params) + (member "verbatim" result-params) (member "output" result-params)) results (let ((tmp-file (org-babel-temp-file "sh-"))) (with-temp-file tmp-file (insert results)) (org-babel-import-elisp-from-file tmp-file))))) - (if (not session) - (org-babel-eval org-babel-sh-command (org-babel-trim body)) + (cond + (stdin ; external shell script w/STDIN + (let ((script-file (org-babel-temp-file "sh-script-")) + (stdin-file (org-babel-temp-file "sh-stdin-"))) + (with-temp-file script-file (insert body)) + (with-temp-file stdin-file (insert stdin)) + (with-temp-buffer + (call-process-shell-command + (format "%s %s" org-babel-sh-command script-file) + stdin-file + (current-buffer)) + (buffer-string)))) + (session ; session evaluation (mapconcat #'org-babel-sh-strip-weird-long-prompt (mapcar @@ -152,11 +171,19 @@ return the value of the last statement in BODY." (session org-babel-sh-eoe-output t body) (mapc (lambda (line) - (insert line) (comint-send-input nil t) (sleep-for 0.25)) + (insert line) + (comint-send-input nil t) + (while (save-excursion + (goto-char comint-last-input-end) + (not (re-search-forward + comint-prompt-regexp nil t))) + (accept-process-output (get-buffer-process (current-buffer))))) (append (split-string (org-babel-trim body) "\n") (list org-babel-sh-eoe-indicator)))) - 2)) "\n")))) + 2)) "\n")) + ('otherwise ; external shell script + (org-babel-eval org-babel-sh-command (org-babel-trim body)))))) (defun org-babel-sh-strip-weird-long-prompt (string) "Remove prompt cruft from a string of shell output." @@ -166,5 +193,6 @@ return the value of the last statement in BODY." (provide 'ob-sh) +;; arch-tag: 416dd531-c230-4b0a-a5bf-8d948f990f2d ;;; ob-sh.el ends here |