From: Pascal Fleury <fleury@google.com>
To: emacs-orgmode@gnu.org
Subject: Export arrays for 'sh' code blocks when using bash
Date: Thu, 27 Mar 2014 11:26:55 +0100 [thread overview]
Message-ID: <CACc7+8asJQLQ3j=hCC-72quQTMt54E9dA=Wft6SrfP_pxyXkEQ@mail.gmail.com> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 2084 bytes --]
Hello,
I'dl like to propose a patch for inclusion into org-mode (ob-shell.el in
particular).
*TL;DR:* use arrays and associative arrays when exporting variables to bash
in 'sh' code blocks.
*Details:*
When variables are defined in a 'sh' code block, they are exported as
strings. when the variable itself is an array or a table, then we simply
get a shell variable that contains the list of all values in a
non-structured form. E.g.
#+NAME: my_list
| one |
| two |
| three |
#+NAME: experiment
| name | first_attempt |
| date | [2014-03-27 Thu] |
| user | fleury |
#+BEGIN_SRC sh :var scalar="some value" :var array=my_list :var table=config
echo ${scalar} # -> prints 'some value'
echo ${array} # -> prints 'one two three'
echo ${table} # -> prints 'first attempt [2014-03-27 Thu] fleury'
#+END_SRC
This will print simple strings. Also, there is no easy way to access the
date of the experiment, for example. Now bash has things like arrays and
associative arrays, but the current ob-shell.el does not use these.
Probably because their syntax is bash-specific, and ob-shell.el is
shell-agnostic.
My patch (attached) changes this in the case you have
(setq org-babel-sh-command "bash")
in your emacs config somewhere. If any other value is used, it continues to
export them as we do today (I don't know enough about other shells).
In that case, it will export the list as an array, the table as an
associative array, and the scalar as it does already. So the 'sh' code
block could then use
#+BEGIN_SRC sh :var scalar="some value" :var array=my_list :var table=config
echo ${scalar}
echo ${array[1]} # -> prints "two"
echo ${table[user]} # -> prints "fleury"
#+END_SRC
In the case we have a bigger table, then the first row is used as key, the
others are represented as a string with all the values (as it is for array
currently). bash does not have multi-dimensional arrays, so it needs to be
a string.
This makes writing shell snippets much easier in my experience, and there
I'd like to propose this fix for the org-mode community at large.
--paf
[-- Attachment #1.2: Type: text/html, Size: 3882 bytes --]
[-- Attachment #2: orgmode-bash.patch --]
[-- Type: text/x-patch, Size: 2036 bytes --]
diff --git a/lisp/ob-shell.el b/lisp/ob-shell.el
index 3ede701..0a691e2 100644
--- a/lisp/ob-shell.el
+++ b/lisp/ob-shell.el
@@ -106,6 +106,30 @@ This function is called by `org-babel-execute-src-block'."
;; helper functions
+(defun org-babel-variable-assignments:bash_array (varname values &optional sep hline)
+ "Returns a list of statements declaring the values as a bash array."
+ (format "declare -a %s=( \"%s\" )"
+ varname
+ (mapconcat 'identity
+ (mapcar
+ (lambda (value) (org-babel-sh-var-to-sh value sep hline))
+ values)
+ "\" \"")))
+
+(defun org-babel-variable-assignments:bash_associative (varname values &optional sep hline)
+ "Returns a list of statements declaring the values as bash associative array."
+ (format "declare -A %s\n%s"
+ varname
+ (mapconcat 'identity
+ (mapcar
+ (lambda (items)
+ (format "%s[\"%s\"]=%s"
+ varname
+ (org-babel-sh-var-to-sh (car items) sep hline)
+ (org-babel-sh-var-to-sh (cdr items) sep hline)))
+ values)
+ "\n")))
+
(defun org-babel-variable-assignments:sh (params)
"Return list of shell statements assigning the block's variables."
(let ((sep (cdr (assoc :separator params)))
@@ -114,9 +138,17 @@ This function is called by `org-babel-execute-src-block'."
"hline"))))
(mapcar
(lambda (pair)
- (format "%s=%s"
- (car pair)
- (org-babel-sh-var-to-sh (cdr pair) sep hline)))
+ (if (and (string= org-babel-sh-command "bash") (listp (cdr pair)))
+ (if (listp (car (cdr pair)))
+ (org-babel-variable-assignments:bash_associative
+ (car pair) (cdr pair) sep hline)
+ (org-babel-variable-assignments:bash_array
+ (car pair) (cdr pair) sep) hline)
+ (format "%s=%s"
+ (car pair)
+ (org-babel-sh-var-to-sh (cdr pair) sep hline))
+ )
+ )
(mapcar #'cdr (org-babel-get-header params :var)))))
(defun org-babel-sh-var-to-sh (var &optional sep hline)
next reply other threads:[~2014-03-27 10:27 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-27 10:26 Pascal Fleury [this message]
2014-03-27 17:43 ` Export arrays for 'sh' code blocks when using bash Eric Schulte
2014-03-27 22:52 ` Pascal Fleury
2014-03-29 19:37 ` Eric Schulte
2014-04-06 23:25 ` Pascal Fleury
2014-04-11 2:38 ` Eric Schulte
2014-04-11 9:33 ` Bastien
2014-04-14 8:48 ` Pascal Fleury
2014-04-15 3:35 ` Eric Schulte
2014-04-15 11:15 ` Pascal Fleury
2014-04-22 14:47 ` Skip Collins
2014-04-22 15:37 ` Bastien
2014-04-22 17:19 ` Skip Collins
2014-04-22 20:59 ` Bastien
2014-04-22 21:04 ` Skip Collins
2014-04-22 21:09 ` Skip Collins
2014-04-22 21:22 ` Bastien
2014-04-23 13:51 ` Skip Collins
2014-04-23 14:13 ` Pascal Fleury
2014-04-23 16:31 ` Skip Collins
2014-04-24 1:23 ` Eric Schulte
2014-04-24 7:44 ` Pascal Fleury
2014-04-22 21:15 ` Bastien
2014-04-15 3:37 ` Eric Schulte
2014-04-15 15:37 ` Nick Dokos
2014-04-17 6:31 ` Bastien
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CACc7+8asJQLQ3j=hCC-72quQTMt54E9dA=Wft6SrfP_pxyXkEQ@mail.gmail.com' \
--to=fleury@google.com \
--cc=emacs-orgmode@gnu.org \
/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 external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.