summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Schulte <schulte.eric@gmail.com>2010-07-14 11:01:57 -0700
committerEric Schulte <schulte.eric@gmail.com>2010-07-14 11:01:57 -0700
commit32b7a76d41052bbd33e4b1ae2710a667065cc98d (patch)
tree5095656cc4b3586aaeeede919053088990a25770
parente6a274824d18761f26ed2bfd2a1eaa77aef1d42a (diff)
downloadorg-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.texi112
-rw-r--r--lisp/ob-ref.el40
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))