Просмотр исходного кода

org-babel: variable values are now indexable

  it is now possible to only assign a portion of a value to a variable
  in a source block.  So for example the following will only assign
  the second and third lines of the table 'example-table' to the
  variable 'data'

  :var data=example-table[1:2]

  and the following will only assign the second column of the first row

  :var data=example-table[0,1]

  note that all indices are 0 based

  it is possible to index into the results of source-code blocks as
  well as tables.  any number of dimensions can be indexed as long as
  they are separated by ','s and ranges can be indexed using the ':'
  operator.  for more information on indexing behavior see
  `org-babel-ref-index-list'
Eric Schulte 15 лет назад
Родитель
Сommit
1d2bab1fb8
1 измененных файлов с 32 добавлено и 2 удалено
  1. 32 2
      contrib/babel/lisp/org-babel-ref.el

+ 32 - 2
contrib/babel/lisp/org-babel-ref.el

@@ -96,7 +96,12 @@ return nil."
   "Resolve the reference and return its value"
   (save-excursion
     (let ((case-fold-search t)
-          type args new-refere new-referent result lob-info split-file split-ref)
+          type args new-refere new-referent result lob-info split-file split-ref
+          index index-row index-col)
+      ;; if ref is indexed grab the indices
+      (when (string-match "\\[\\(.+\\)\\]" ref)
+        (setq index (match-string 1 ref))
+        (setq ref (substring ref 0 (match-beginning 0))))
       ;; assign any arguments to pass to source block
       (when (string-match "^\\(.+?\\)\(\\(.*\\)\)$" ref)
         (setq new-refere (match-string 1 ref))
@@ -147,7 +152,32 @@ return nil."
 	      ('table (org-babel-read-table))
 	      ('source-block (org-babel-execute-src-block t nil params))
 	      ('lob (org-babel-execute-src-block t lob-info params))))
-      (if (symbolp result) (format "%S" result) result))))
+      (if (symbolp result)
+          (format "%S" result)
+        (if (and index (listp result))
+            (org-babel-ref-index-list index result)
+          result)))))
+
+(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))
+            (portion (match-string 1 index))
+            (remainder (substring index (match-end 0))))
+        (flet ((wrap (num) (if (< num 0) (+ length num) num)))
+          (mapcar
+           (lambda (sub-lis) (org-babel-ref-index-list remainder sub-lis))
+           (if (string-match "\\([-[:digit:]]+\\):\\([-[:digit:]]+\\)" portion)
+               (mapcar (lambda (n) (nth n lis))
+                       (number-sequence
+                        (wrap (string-to-number (match-string 1 portion)))
+                        (wrap (string-to-number (match-string 2 portion)))))
+             (list (nth (wrap (string-to-number portion)) lis))))))
+    lis))
 
 (defun org-babel-ref-split-args (arg-string)
   "Split ARG-STRING into top-level arguments of balanced parenthesis."