emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Eric Schulte <schulte.eric@gmail.com>
To: Sebastien Vauban <wxhgmqzgwmuf@spammotel.com>
Cc: emacs-orgmode@gnu.org
Subject: Re: org babel support for tcl and awk
Date: Wed, 25 May 2011 09:57:14 -0600	[thread overview]
Message-ID: <87oc2qhixx.fsf@gmail.com> (raw)
In-Reply-To: <80aaeb2cae.fsf@somewhere.org> (Sebastien Vauban's message of "Wed, 25 May 2011 14:30:01 +0200")

[-- Attachment #1: Type: text/plain, Size: 945 bytes --]

> * 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.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: example.org --]
[-- Type: text/x-org, Size: 316 bytes --]

** 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 |

[-- Attachment #3: Type: text/plain, Size: 17 bytes --]


Cheers -- Eric


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0001-sh-allow-passing-references-through-STDIN-of-a-shell.patch --]
[-- Type: text/x-diff, Size: 4709 bytes --]

From 03aa327d7950176e50ebb779c3f153bb9192dea5 Mon Sep 17 00:00:00 2001
From: Eric Schulte <schulte.eric@gmail.com>
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


[-- Attachment #5: Type: text/plain, Size: 74 bytes --]


>
> Best regards,
>   Seb

-- 
Eric Schulte
http://cs.unm.edu/~eschulte/

  reply	other threads:[~2011-05-25 15:57 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-24  9:31 org babel support for tcl and awk orgmode
2011-05-24 12:51 ` Eric Schulte
2011-05-24 17:53   ` Eric S Fraga
2011-05-24 19:03     ` Eric Schulte
2011-05-24 19:55       ` Sebastien Vauban
2011-05-24 23:51         ` Eric Schulte
2011-05-25 12:30           ` Sebastien Vauban
2011-05-25 15:57             ` Eric Schulte [this message]
2011-05-26 11:18               ` Sebastien Vauban
2011-05-26 13:37                 ` Eric Schulte
2011-05-26 13:03       ` Eric Schulte
2011-05-26 15:15         ` Eric S Fraga
2011-05-24 18:57   ` orgmode

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87oc2qhixx.fsf@gmail.com \
    --to=schulte.eric@gmail.com \
    --cc=emacs-orgmode@gnu.org \
    --cc=wxhgmqzgwmuf@spammotel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).