From d128662fa3dd3c50509214b320b035915ca2a5ff Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Thu, 16 Jul 2009 16:21:07 -0400 Subject: [PATCH] Eliminating duplicated code (take 2...). This proposal for code tidying uses multiple-value-bind to satisfy: 1. The various parsed/resolved components of the param list (session, vars, result-type) are available in the org-babel-execute:LANG functions. 2. Those functions don't duplicate the code for parsing the params list and resolving references 3. The functions still have the params list available to them, should they need to implement language-specific behaviour using it. If the org-babel-execute:LANG functions need to be called directly, then that would now have to be via (multiple-value-bind (session vars result-params result-type) (org-babel-process-params params) (funcall cmd body params)) as in org-babel-exp.el. (But is it actually necessary to by-pass org-babel-execute-src-block?) --- lisp/langs/org-babel-R.el | 19 +++++++------------ lisp/langs/org-babel-lisp.el | 5 ++--- lisp/langs/org-babel-python.el | 23 +++++++++-------------- lisp/langs/org-babel-ruby.el | 23 +++++++++-------------- lisp/langs/org-babel-sh.el | 11 +++-------- lisp/org-babel-exp.el | 6 +++++- lisp/org-babel.el | 28 ++++++++++++++++++++++------ 7 files changed, 57 insertions(+), 58 deletions(-) diff --git a/lisp/langs/org-babel-R.el b/lisp/langs/org-babel-R.el index c085f917c..82413380f 100644 --- a/lisp/langs/org-babel-R.el +++ b/lisp/langs/org-babel-R.el @@ -37,20 +37,15 @@ (defun org-babel-execute:R (body params) "Execute a block of R code with org-babel. This function is -called by `org-babel-execute-src-block'." +called by `org-babel-execute-src-block' via multiple-value-bind." (message "executing R source code block...") (save-window-excursion - (let* ((vars (org-babel-ref-variables params)) - (full-body (concat - (mapconcat ;; define any variables - (lambda (pair) - (org-babel-R-assign-elisp (car pair) (cdr pair))) - vars "\n") "\n" body "\n")) - (result-params (split-string (or (cdr (assoc :results params)) ""))) - (result-type (cond ((member "output" result-params) 'output) - ((member "value" result-params) 'value) - (t 'value))) - (session (org-babel-R-initiate-session (cdr (assoc :session params))))) + (let ((full-body (concat + (mapconcat ;; define any variables + (lambda (pair) + (org-babel-R-assign-elisp (car pair) (cdr pair))) + vars "\n") "\n" body "\n")) + (session (org-babel-R-initiate-session session))) (org-babel-R-evaluate session full-body result-type)))) (defun org-babel-prep-session:R (session params) diff --git a/lisp/langs/org-babel-lisp.el b/lisp/langs/org-babel-lisp.el index 7d7520e18..704b2eaaf 100644 --- a/lisp/langs/org-babel-lisp.el +++ b/lisp/langs/org-babel-lisp.el @@ -37,11 +37,10 @@ (defun org-babel-execute:emacs-lisp (body params) "Execute a block of emacs-lisp code with org-babel. This -function is called by `org-babel-execute-src-block'." +function is called by `org-babel-execute-src-block' via multiple-value-bind." (message "executing emacs-lisp code block...") (save-window-excursion - (let ((vars (org-babel-ref-variables params)) - (print-level nil) (print-length nil) results) + (let ((print-level nil) (print-length nil) results) (setq results (eval `(let ,(mapcar (lambda (var) `(,(car var) ',(cdr var))) vars) ,(read (concat "(progn " body ")"))))) diff --git a/lisp/langs/org-babel-python.el b/lisp/langs/org-babel-python.el index 981a3f545..8869b02df 100644 --- a/lisp/langs/org-babel-python.el +++ b/lisp/langs/org-babel-python.el @@ -38,21 +38,16 @@ (defun org-babel-execute:python (body params) "Execute a block of Python code with org-babel. This function is -called by `org-babel-execute-src-block'." +called by `org-babel-execute-src-block' via multiple-value-bind." (message "executing Python source code block") - (let* ((vars (org-babel-ref-variables params)) - (result-params (split-string (or (cdr (assoc :results params)) ""))) - (result-type (cond ((member "output" result-params) 'output) - ((member "value" result-params) 'value) - (t 'value))) - (full-body (concat - (mapconcat ;; define any variables - (lambda (pair) - (format "%s=%s" - (car pair) - (org-babel-python-var-to-python (cdr pair)))) - vars "\n") "\n" (org-babel-trim body) "\n")) ;; then the source block body - (session (org-babel-python-initiate-session (cdr (assoc :session params))))) + (let ((full-body (concat + (mapconcat ;; define any variables + (lambda (pair) + (format "%s=%s" + (car pair) + (org-babel-python-var-to-python (cdr pair)))) + vars "\n") "\n" (org-babel-trim body) "\n")) ;; then the source block body + (session (org-babel-python-initiate-session session))) (org-babel-python-evaluate session full-body result-type))) (defun org-babel-prep-session:python (session params) diff --git a/lisp/langs/org-babel-ruby.el b/lisp/langs/org-babel-ruby.el index 2d9f2cc04..c42ca812e 100644 --- a/lisp/langs/org-babel-ruby.el +++ b/lisp/langs/org-babel-ruby.el @@ -38,21 +38,16 @@ (defun org-babel-execute:ruby (body params) "Execute a block of Ruby code with org-babel. This function is -called by `org-babel-execute-src-block'." +called by `org-babel-execute-src-block' via multiple-value-bind." (message "executing Ruby source code block") - (let* ((vars (org-babel-ref-variables params)) - (result-params (split-string (or (cdr (assoc :results params)) ""))) - (result-type (cond ((member "output" result-params) 'output) - ((member "value" result-params) 'value) - (t 'value))) - (full-body (concat - (mapconcat ;; define any variables - (lambda (pair) - (format "%s=%s" - (car pair) - (org-babel-ruby-var-to-ruby (cdr pair)))) - vars "\n") "\n" body "\n")) ;; then the source block body - (session (org-babel-ruby-initiate-session (cdr (assoc :session params))))) + (let ((full-body (concat + (mapconcat ;; define any variables + (lambda (pair) + (format "%s=%s" + (car pair) + (org-babel-ruby-var-to-ruby (cdr pair)))) + vars "\n") "\n" body "\n")) ;; then the source block body + (session (org-babel-ruby-initiate-session session))) (org-babel-ruby-evaluate session full-body result-type))) (defun org-babel-prep-session:ruby (session params) diff --git a/lisp/langs/org-babel-sh.el b/lisp/langs/org-babel-sh.el index 1218dfffc..8bc54f7b5 100644 --- a/lisp/langs/org-babel-sh.el +++ b/lisp/langs/org-babel-sh.el @@ -38,21 +38,16 @@ (defun org-babel-execute:sh (body params) "Execute a block of Shell commands with org-babel. This -function is called by `org-babel-execute-src-block'." +function is called by `org-babel-execute-src-block' via multiple-value-bind." (message "executing Shell source code block") - (let* ((vars (org-babel-ref-variables params)) - (result-params (split-string (or (cdr (assoc :results params)) ""))) - (result-type (cond ((member "output" result-params) 'output) - ((member "value" result-params) 'value) - (t 'value))) - (full-body (concat + (let* ((full-body (concat (mapconcat ;; define any variables (lambda (pair) (format "%s=%s" (car pair) (org-babel-sh-var-to-sh (cdr pair)))) vars "\n") "\n" body "\n\n")) ;; then the source block body - (session (org-babel-sh-initiate-session (cdr (assoc :session params))))) + (session (org-babel-sh-initiate-session session))) (org-babel-sh-evaluate session full-body result-type))) (defun org-babel-prep-session:sh (session params) diff --git a/lisp/org-babel-exp.el b/lisp/org-babel-exp.el index 4ff6db900..abf7d487a 100644 --- a/lisp/org-babel-exp.el +++ b/lisp/org-babel-exp.el @@ -84,8 +84,12 @@ options and are taken from `org-babel-defualt-inline-header-args'." (if (string-match "\n$" body) "" "\n")))) (defun org-babel-exp-results (body lang params &optional inline) + ;; I expect there's a good reason why not, but would it be possible + ;; to use org-babel-execute-src-block here? [ded] (let* ((cmd (intern (concat "org-babel-execute:" lang))) - (result (funcall cmd body params)) + (result + (multiple-value-bind (session vars result-params result-type) + (org-babel-process-params params) (funcall cmd body params))) (result-as-org (org-babel-result-to-org-string result))) (if inline (format "=%s=" result) diff --git a/lisp/org-babel.el b/lisp/org-babel.el index 373b3f2dc..a01a46cfc 100644 --- a/lisp/org-babel.el +++ b/lisp/org-babel.el @@ -156,20 +156,22 @@ the header arguments specified at the source code block." (body (second info)) (params (org-babel-merge-params (third info) (org-babel-get-src-block-function-args) params)) - (result-params (split-string (or (cdr (assoc :results params)) ""))) - (result-type (cond ((member "output" result-params) 'output) - ((member "value" result-params) 'value) - (t 'value))) + (processed-params (org-babel-process-params params)) + (result-params (third processed-params)) + (result-type (fourth processed-params)) (cmd (intern (concat "org-babel-execute:" lang))) result) ;; (message (format "params=%S" params)) ;; debugging (unless (member lang org-babel-interpreters) (error "Language is not in `org-babel-interpreters': %s" lang)) (when arg (setq result-params (cons "silent" result-params))) - (setq result (org-babel-process-result (funcall cmd body params) result-type)) + (setq result + (org-babel-process-result + (multiple-value-bind (session vars result-params result-type) processed-params + (funcall cmd body params)) result-type)) (org-babel-insert-result result result-params) (case result-type (output nil) (value result)))) - + (defun org-babel-process-result (result result-type) "This doesn't do anything currently. @@ -330,6 +332,20 @@ of the following form. (language body header-arguments-alist)" (cons (intern (concat ":" arg)) nil))) (split-string (concat " " arg-string) "[ \f\t\n\r\v]+:" t))))) +(defun org-babel-process-params (params) + "Parse params and resolve references. + +Return a list (session vars result-params result-type). These are +made available to the org-babel-execute:LANG functions via +multiple-value-bind." + (let* ((session (cdr (assoc :session params))) + (vars (org-babel-ref-variables params)) + (result-params (split-string (or (cdr (assoc :results params)) ""))) + (result-type (cond ((member "output" result-params) 'output) + ((member "value" result-params) 'value) + (t 'value)))) + (list session vars result-params result-type))) + (defun org-babel-where-is-src-block-head () "Return the point at the beginning of the current source block. Specifically at the beginning of the #+BEGIN_SRC line.