Hi Eric, Please find attached a new patch that contains the same changes of the ob-shell.el exporter as before, but also contains unit tests for checking that it works. Let me know if you need some changes in there, and how the google-wide copyright issues comes along. My information came from Chris DiBona (our master of open-source licenses), is this helps to find the relevant documents. Thanks, Pascal On Sat, Mar 29, 2014 at 8:37 PM, Eric Schulte wrote: > Thanks for making these changes. Once they're in and Bastien figures > out how the google-wide copyright attribution works we should be good to > go. > > Thanks! > > Pascal Fleury writes: > > > Hi Eric, see comments inline. > > > > > > On Thu, Mar 27, 2014 at 6:43 PM, Eric Schulte >wrote: > > > >> Hi Pascal, > >> > >> This looks like a good patch. If I could make three changes/requests. > >> > >> > > Thanks, I am happy to see it makes sense. > > > > > >> 1. This patch should also work for "begin_src bash" code blocks. After > >> a very quick glance it doesn't appear to. > >> > >> I have actually tried this with the latest org-mode release (8.2.5h) and > > it did plainly not accept 'begin_src bash'. Maybe that's new with the > > ob-shell.el (I noticed it has been renamed :-) > > > > > >> 2. Could you include one or two tests ensuring that this patch does what > >> it intends with bash code blocks, and does not affect code blocks > >> executed with bin/sh? > >> > > > > Will do, seeing it has some traction. > > > > > >> > >> 3. Large contributions like this require some FSF paperwork. Please see > >> the following page for information on requirements to contribute. > >> > >> > > I checked internally, and apparently, Google has already such a signed > > document. It would run on the same document, as I am a google employee. > > > > > >> http://orgmode.org/worg/org-contribute.html > >> > >> Thanks, and I look forward to seeing this merged into Org-mode! > >> Eric > >> > >> Pascal Fleury writes: > >> > >> > 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 > >> > > >> > 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) > >> > >> -- > >> Eric Schulte > >> https://cs.unm.edu/~eschulte > >> PGP: 0x614CA05D > >> > > -- > Eric Schulte > https://cs.unm.edu/~eschulte > PGP: 0x614CA05D > >