now passing arguments to source-blocks when the source-block is used to initialize a header-argument variable

before this is useful need to implement params merging in
  litorgy-execute-src-block, see the TODO infile
This commit is contained in:
Eric Schulte 2009-05-09 09:34:55 -07:00
parent c85ec77932
commit 728869fef8
3 changed files with 83 additions and 76 deletions

View File

@ -69,54 +69,59 @@ return nil."
(if (string-match "\"\\(.+\\)\"" ref) (read ref) ;; string
nil)))) ;; reference
(defun litorgy-ref-parse (reference)
"Parse the assignment REFERENCE of a variable specified in a
header argument. If the assignment has a literal value return
that value, otherwise interpret REFERENCE as a reference to an
external resource returning a list with two elements. The first
element of the list will be the name of the variable, and the
second will be an emacs-lisp representation of the value of the
variable."
(defun litorgy-ref-parse (assignment)
"Parse a variable ASSIGNMENT in a header argument. If the
right hand side of the assignment has a literal value return that
value, otherwise interpret as a reference to an external resource
and find it's value using `litorgy-ref-resolve-reference'.
Return a list with two elements. The first element of the list
will be the name of the variable, and the second will be an
emacs-lisp representation of the value of the variable."
(if (string-match "\\(.+\\)=\\(.+\\)" assignment)
(let ((var (match-string 1 assignment))
(ref (match-string 2 assignment)))
(cons (intern var)
(or (litorgy-ref-literal ref)
(litorgy-ref-resolve-reference ref))))))
(defun litorgy-ref-resolve-reference (ref)
"Resolve the reference and return it's value"
(save-excursion
(if (string-match "\\(.+\\)=\\(.+\\)" reference)
(let* ((var (match-string 1 reference))
(ref (match-string 2 reference))
(lit (litorgy-ref-literal ref))
direction type)
(when (string-match "\\(.+\\):\\(.+\\)" reference)
(find-file (match-string 1 reference))
(setf ref (match-string 2 reference)))
(cons (intern var)
(or lit
(progn
(cond ;; follow the reference in the current file
((string= ref "previous") (setq direction -1))
((string= ref "next") (setq direction 1))
(t
(goto-char (point-min))
(setq direction 1)
(unless (let ((regexp (concat "^#\\+\\(TBL\\|SRC\\)NAME:[ \t]*"
(regexp-quote ref) "[ \t]*$")))
(or (re-search-forward regexp nil t)
(re-search-backward regexp nil t)))
;; ;; TODO: allow searching for names in other buffers
;; (setq id-loc (org-id-find ref 'marker)
;; buffer (marker-buffer id-loc)
;; loc (marker-position id-loc))
;; (move-marker id-loc nil)
(error (format "reference '%s' not found in this buffer" ref)))))
(while (not (setq type (litorgy-ref-at-ref-p)))
(forward-line direction)
(beginning-of-line)
(if (or (= (point) (point-min)) (= (point) (point-max)))
(error "reference not found")))
(case type
('table
(mapcar (lambda (row)
(mapcar #'litorgy-read row))
(org-table-to-lisp)))
('source-block
(litorgy-execute-src-block t))))))))))
(let (direction type args)
(when (string-match "\\(.+\\):\\(.+\\)" ref)
(find-file (match-string 1 ref))
(setf ref (match-string 2 ref)))
(cond ;; follow the reference in the current file
((string= ref "previous") (setq direction -1))
((string= ref "next") (setq direction 1))
(t
(goto-char (point-min))
(setq direction 1)
(unless (let ((regexp (concat "^#\\+\\(TBL\\|SRC\\)NAME:[ \t]*"
(regexp-quote ref) "[ \t]*$")))
(or (re-search-forward regexp nil t)
(re-search-backward regexp nil t)))
;; ;; TODO: allow searching for names in other buffers
;; (setq id-loc (org-id-find ref 'marker)
;; buffer (marker-buffer id-loc)
;; loc (marker-position id-loc))
;; (move-marker id-loc nil)
(error (format "reference '%s' not found in this buffer" ref)))))
(while (not (setq type (litorgy-ref-at-ref-p)))
(forward-line direction)
(beginning-of-line)
(if (or (= (point) (point-min)) (= (point) (point-max)))
(error "reference not found")))
(case type
('table
(mapcar (lambda (row)
(mapcar #'litorgy-read row))
(org-table-to-lisp)))
('source-block
;; assign any arguments to pass to source block
(when (string-match "\(\\(.+\\)\)" ref)
(setq args (mapcar (lambda (ref) (cons :var ref)) (split-string ref ",[ \f\t\n\r\v]*"))))
(litorgy-execute-src-block t nil args))))))
(defun litorgy-ref-at-ref-p ()
"Return the type of reference located at point or nil of none

View File

@ -96,7 +96,7 @@ lisp code use the `litorgy-add-interpreter' function."
(const "ruby")))
;;; functions
(defun litorgy-execute-src-block (&optional arg info)
(defun litorgy-execute-src-block (&optional arg info params)
"Execute the current source code block, and dump the results
into the buffer immediately following the block. Results are
commented by `org-toggle-fixed-width-section'. With optional
@ -105,7 +105,10 @@ results in raw elisp (this is useful for automated execution of a
source block).
Optionally supply a value for INFO in the form returned by
`litorgy-get-src-block-info'."
`litorgy-get-src-block-info'.
Optionally supply a value for PARAMS which will be merged with
the header arguments specified at the source code block." ; TODO implement!!
(interactive "P")
(let* ((info (or info (litorgy-get-src-block-info)))
(lang (first info))
@ -167,18 +170,7 @@ of the following form. (language body header-arguments-alist)"
(mapcar
(lambda (arg) (if (string-match "\\([^ \f\t\n\r\v]+\\)[ \f\t\n\r\v]*\\([^ \f\t\n\r\v]+.*\\)" arg)
(cons (intern (concat ":" (match-string 1 arg))) (match-string 2 arg))))
(let (matches holder)
(mapcar (lambda (part)
(if (string= (substring part -1) "(")
(setq holder part)
(if holder
(progn
(setq matches (cons (concat holder " :" part) matches))
(setq holder nil))
(setq matches (cons part matches)))))
(split-string (concat " " arg-string) "[ \f\t\n\r\v]+:" t))
(message (format "%S" matches))
matches))))
(split-string (concat " " arg-string) "[ \f\t\n\r\v]+:" t))))
(defun litorgy-insert-result (result &optional insert)
"Insert RESULT into the current buffer after the end of the

View File

@ -3,7 +3,7 @@
#+SEQ_TODO: TODO OPEN PROPOSED | DONE RESOLVED REJECTED
#+STARTUP: oddeven
* Tasks [6/14]
* Tasks [7/14]
** TODO test for litorgy
since we are accumulating this nice collection of source-code blocks
@ -19,17 +19,6 @@ I have the feeling that this should be possible using only litorgical
functions with minimal or no additional elisp. It would be very cool
for litorgy to be able to test itself.
** TODO re-implement helper functions from org-R
Much of the power of org-R seems to be in it's helper functions for
the quick graphing of tables. Should we try to re-implement these
functions on top of litorgy?
I'm thinking this may be useful both to add features to litorgy-R and
also to potentially suggest extensions of the framework. For example
one that comes to mind is the ability to treat a source-code block
like a function which accepts arguments and returns results. Actually
this can be it's own TODO (see [[* source blocks as functions][source blocks as functions]]).
** TODO source blocks as functions
Allow source code blocks to be called like functions, with arguments
@ -52,6 +41,9 @@ Sweave? Would/Should we just mimic the behavior of Sweave with the
addition of support for poping up graphics during live evaluation of a
source code block.
I think the best way to approach this would be to start with an
example R source-code block and then work up from there.
** TODO ability to select which of multiple sessions is being used
Increasingly it is looking like we're going to want to run all
source code blocks in comint buffer (sessions). Which will have
@ -108,7 +100,18 @@ source code block.
posterity. Same for a shell session either in a *shell* buffer, or
pasted from another terminal emulator. And python of course.
** TODO folding of code blocks? [1/2]
** PROPOSED re-implement helper functions from org-R
Much of the power of org-R seems to be in it's helper functions for
the quick graphing of tables. Should we try to re-implement these
functions on top of litorgy?
I'm thinking this may be useful both to add features to litorgy-R and
also to potentially suggest extensions of the framework. For example
one that comes to mind is the ability to treat a source-code block
like a function which accepts arguments and returns results. Actually
this can be it's own TODO (see [[* source blocks as functions][source blocks as functions]]).
** DONE folding of code blocks? [2/2]
[DED] In similar way to using outline-minor-mode for folding function
bodies, can we fold code blocks? #+begin whatever statements are
pretty ugly, and in any case when you're thinking about the overall
@ -119,9 +122,13 @@ source code block.
now be fold-able in the same manner as headlines (by pressing TAB
on the first line).
*** TODO folding of results
*** REJECTED folding of results
So, lets do a three-stage tab cycle... First fold the src block,
then fold the results, then unfold.
There's no way to tell if the results are a table or not w/o
actually executing the block which would be too expensive of an
operation.
** DONE inline source code blocks [2/2]
Like the =\R{ code }= blocks
@ -286,6 +293,9 @@ recognition of ruby arrays as such.
* Sandbox
:PROPERTIES:
:CUSTOM_ID: sandbox
:END:
This is a place for code examples
** litorgy.el beginning functionality
@ -624,7 +634,7 @@ inline source code blocks) [[file:test-export.org]]
: 15
#+begin_src emacs-lisp :var result=triple(:n => 8)
#+begin_src emacs-lisp :var result=triple(n=8)
result
#+end_src