From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Schulte Subject: Re: org babel support for tcl and awk Date: Wed, 25 May 2011 09:57:14 -0600 Message-ID: <87oc2qhixx.fsf@gmail.com> References: <20110524113109.fo2dcd0mwno0c4w4@webmail.dds.nl> <8739k46z2p.fsf@gmail.com> <874o4kvvcb.fsf@ucl.ac.uk> <87vcwz9b02.fsf@gmail.com> <80boyr50w4.fsf@somewhere.org> <87lixvd5ei.fsf@gmail.com> <80aaeb2cae.fsf@somewhere.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([140.186.70.92]:49581) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QPGSZ-0007rJ-QM for emacs-orgmode@gnu.org; Wed, 25 May 2011 11:57:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QPGSY-0007Ks-JI for emacs-orgmode@gnu.org; Wed, 25 May 2011 11:57:23 -0400 Received: from mail-px0-f171.google.com ([209.85.212.171]:59762) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QPGSX-0007Kc-VZ for emacs-orgmode@gnu.org; Wed, 25 May 2011 11:57:22 -0400 Received: by pxi7 with SMTP id 7so5235517pxi.30 for ; Wed, 25 May 2011 08:57:20 -0700 (PDT) In-Reply-To: <80aaeb2cae.fsf@somewhere.org> (Sebastien Vauban's message of "Wed, 25 May 2011 14:30:01 +0200") List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Sebastien Vauban Cc: emacs-orgmode@gnu.org --=-=-= Content-Type: text/plain > * Conclusions > > As you can see, I did not really mean any concurrent execution. Simply being > able to execute parts of code in-situ, in the Org buffer, to document (and > test) what I'm writing. > > And to be able to assemble all the parts in one single script file, by the > means of literate programming. > I see, you want to be able to construct a large pipe chain STDOUT>STDIN, but you don't care if the parts of the chain (e.g., the code block) execute in serial or concurrently (as they do in the shell). The attached patch (can be applied with "git am") implements this behavior as I understand it. The result is a new :stdin header argument with which org-mode references can be passed to shell scripts as standard input. Given the technique used in this patch, I'll probably re-write part of ob-awk.el. The following Org-mode snippet demonstrates it's use, please let me know if this works for your use-case described above. --=-=-= Content-Type: text/x-org Content-Disposition: inline; filename=example.org ** passing values through to STDIN of shell code blocks #+results: square-table | 1 | 2 | 3 | | 4 | 5 | 6 | | 7 | 8 | 9 | #+source: first-col #+begin_src sh :stdin square-table awk '{print $1}' #+end_src #+begin_src sh :stdin first-col sed 's/4/middle/g' #+end_src #+results: | 1 | | middle | | 7 | --=-=-= Content-Type: text/plain Cheers -- Eric --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-sh-allow-passing-references-through-STDIN-of-a-shell.patch >From 03aa327d7950176e50ebb779c3f153bb9192dea5 Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Wed, 25 May 2011 09:50:36 -0600 Subject: [PATCH] sh: allow passing references through STDIN of a shell script * lisp/ob-sh.el (ob-ref): Uses ob-ref to resolve the value of the :stdin header argument. (org-babel-execute:sh): Use the :stdin header argument. (org-babel-sh-var-to-sh): Split the bulk of this function off into a new sub-function. (org-babel-sh-var-to-string): New function for converting elisp values to strings that make sense for parsing with sh. (org-babel-sh-evaluate): Adding "stdin" option to session and external evaluation options. --- lisp/ob-sh.el | 44 ++++++++++++++++++++++++++++++++------------ 1 files changed, 32 insertions(+), 12 deletions(-) diff --git a/lisp/ob-sh.el b/lisp/ob-sh.el index 128924d..10c08d4 100644 --- a/lisp/ob-sh.el +++ b/lisp/ob-sh.el @@ -28,6 +28,7 @@ ;;; Code: (require 'ob) +(require 'ob-ref) (require 'ob-comint) (require 'ob-eval) (require 'shell) @@ -57,10 +58,13 @@ 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))) + (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 @@ -101,14 +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." + (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)))) - ((lambda (var) (format org-babel-sh-var-quote-fmt var)) - (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)))))) + (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 @@ -141,8 +148,19 @@ return the value of the last statement in BODY." (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 @@ -156,7 +174,9 @@ return the value of the last statement in BODY." (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." -- 1.7.4.1 --=-=-= Content-Type: text/plain > > Best regards, > Seb -- Eric Schulte http://cs.unm.edu/~eschulte/ --=-=-=--