diff options
author | Eric Schulte <schulte.eric@gmail.com> | 2010-07-14 11:01:57 -0700 |
---|---|---|
committer | Eric Schulte <schulte.eric@gmail.com> | 2010-07-14 11:01:57 -0700 |
commit | 32b7a76d41052bbd33e4b1ae2710a667065cc98d (patch) | |
tree | 5095656cc4b3586aaeeede919053088990a25770 | |
parent | e6a274824d18761f26ed2bfd2a1eaa77aef1d42a (diff) | |
download | org-mode-32b7a76d41052bbd33e4b1ae2710a667065cc98d.tar.gz |
babel: cleaned up code and improved documentation of indexing into variables
* lisp/ob-ref.el (org-babel-ref-index-list): slight code cleanup, also
now allowing an empty index to mean the entire range
* doc/org.texi (var): updated the documentation of Babel index
referencing to include working examples covering the full range of
index behavior
-rw-r--r-- | doc/org.texi | 112 | ||||
-rw-r--r-- | lisp/ob-ref.el | 40 |
2 files changed, 100 insertions, 52 deletions
diff --git a/doc/org.texi b/doc/org.texi index ded3c37..c7287d3 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -11445,19 +11445,14 @@ The following header arguments are defined: @node var, results, Specific header arguments, Specific header arguments @subsubsection @code{:var} -The @code{:var} header argument is used to pass arguments to -code blocks. The specifics of how arguments are included -in a code block vary by language; these are -addressed in the language-specific documentation. However, the -syntax used to specify arguments is the same across all -languages. The values passed to arguments can be -@itemize @bullet -@item literal values -@item values from org-mode tables -@item the results of other code blocks -@end itemize - -These values can be indexed in a manner similar to arrays---see the argument +The @code{:var} header argument is used to pass arguments to code blocks. +The specifics of how arguments are included in a code block vary by language; +these are addressed in the language-specific documentation. However, the +syntax used to specify arguments is the same across all languages. The +values passed to arguments can be literal values, values from org-mode +tables, or the results of other code blocks. + +These values can be indexed in a manner similar to arrays---see the ``indexable variable values'' heading below. The following syntax is used to pass arguments to code blocks using the @@ -11540,43 +11535,88 @@ following the source name. @end example @subsubheading Indexable variable values -It is possible to assign a portion of a value to a variable in a source -block. The following example assigns the second and third rows of the table +It is possible to reference portions of variable values by ``indexing'' into +the variables. Indexes are 0 based with negative values counting back from +the end. If an index is separated by ``,''s then each subsequent section +will index into the next deepest nesting or dimension of the value. The +following example assigns the last cell of the first row the table @code{example-table} to the variable @code{data}: @example -:var data=example-table[1:2] -@end example +#+results: example-table +| 1 | a | +| 2 | b | +| 3 | c | +| 4 | d | -Note: ranges are indexed using the @code{:} operator. +#+begin_src emacs-lisp :var data=example-table[0,-1] + data +#+end_src -Note: indices are 0 based. +#+results: +: a +@end example -The following example assigns the second column of the first row of -@code{example-table} to @code{data}: +Ranges of variable values can be referenced using two integer separated by a +@code{:}, in which case the entire inclusive range is referenced. For +example the following assigns the entire first column of @code{example-table} +to @code{data}. @example -:var data=example-table[0,1] +#+results: example-table +| 1 | a | +| 2 | b | +| 3 | c | +| 4 | d | + +#+begin_src emacs-lisp :var data=example-table[1:2] + data +#+end_src + +#+results: +| 2 | b | +| 3 | c | @end example -It is possible to index into the results of code blocks as well as -tables. Any number of dimensions can be indexed. Dimensions are separated -from one another by commas. +Additionally an empty index, or the single character @code{*} are both +interpreted to mean the entire range and as such are equivalent to +@code{0:-1}, as shown in the following example in which the entire first +column is referenced. + +@example +#+results: example-table +| 1 | a | +| 2 | b | +| 3 | c | +| 4 | d | + +#+begin_src emacs-lisp :var data=example-table[,0] + data +#+end_src + +#+results: +| 1 | 2 | 3 | 4 | +@end example -For more information on indexing behavior see the documentation for the -@code{org-babel-ref-index-list} function, provided below. +It is possible to index into the results of code blocks as well as tables. +Any number of dimensions can be indexed. Dimensions are separated from one +another by commas, as shown in the following example. -@deffn -org-babel-ref-index-list is a Lisp function in `org-babel-ref.el'. +@example +#+source: 3D +#+begin_src emacs-lisp + '(((1 2 3) (4 5 6) (7 8 9)) + ((10 11 12) (13 14 15) (16 17 18)) + ((19 20 21) (22 23 24) (25 26 27))) +#+end_src -(org-babel-ref-index-list index lis) +#+begin_src emacs-lisp :var data=3D[1,,1] + data +#+end_src -Return the subset of LIS indexed by INDEX. If INDEX is -separated by ,s then each PORTION is assumed to index into the -next deepest nesting or dimension. A valid PORTION can consist -of either an integer index, or two integers separated by a : in -which case the entire range is returned. -@end deffn +#+results: +| 11 | 14 | 17 | +@end example @node results, file, var, Specific header arguments @subsubsection @code{:results} diff --git a/lisp/ob-ref.el b/lisp/ob-ref.el index 148dafb..4ed70be 100644 --- a/lisp/ob-ref.el +++ b/lisp/ob-ref.el @@ -177,28 +177,36 @@ return nil." (defun org-babel-ref-index-list (index lis) "Return the subset of LIS indexed by INDEX. -If INDEX is separated by ,s then each PORTION is assumed to index -into the next deepest nesting or dimension. A valid PORTION can -consist of either an integer index, or two integers separated by -a : in which case the entire range is returned." - (if (string-match "^,?\\([^,]+\\)" index) - (let ((length (length lis)) + +Indices are 0 based and negative indices count from the end of +LIS, so 0 references the first element of LIS and -1 references +the last. If INDEX is separated by \",\"s then each \"portion\" +is assumed to index into the next deepest nesting or dimension. + +A valid \"portion\" can consist of either an integer index, two +integers separated by a \":\" in which case the entire range is +returned, or an empty string or \"*\" both of which are +interpreted to mean the entire range and as such are equivalent +to \"0:-1\"." + (if (and (> (length index) 0) (string-match "^\\([^,]*\\),?" index)) + (let ((ind-re "\\(\\([-[:digit:]]+\\):\\([-[:digit:]]+\\)\\|\*\\)") + (length (length lis)) (portion (match-string 1 index)) (remainder (substring index (match-end 0)))) (flet ((wrap (num) (if (< num 0) (+ length num) num)) - (open (lis) (if (and (listp lis) (= (length lis) 1)) (car lis) lis))) + (open (ls) (if (and (listp ls) (= (length ls) 1)) (car ls) ls))) (open (mapcar (lambda (sub-lis) (org-babel-ref-index-list remainder sub-lis)) - (if (string-match "\\(\\([-[:digit:]]+\\):\\([-[:digit:]]+\\)\\|\*\\)" - portion) - (mapcar (lambda (n) (nth n lis)) - (apply 'number-sequence - (if (match-string 2 portion) - (list - (wrap (string-to-number (match-string 2 portion))) - (wrap (string-to-number (match-string 3 portion)))) - (list (wrap 0) (wrap -1))))) + (if (or (= 0 (length portion)) (string-match ind-re portion)) + (mapcar + (lambda (n) (nth n lis)) + (apply 'number-sequence + (if (and (> (length portion) 0) (match-string 2 portion)) + (list + (wrap (string-to-number (match-string 2 portion))) + (wrap (string-to-number (match-string 3 portion)))) + (list (wrap 0) (wrap -1))))) (list (nth (wrap (string-to-number portion)) lis))))))) lis)) |