From 715998c1070fa0b3cbea30b9cd7d04120da75de5 Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Mon, 23 Feb 2009 16:07:07 -0800 Subject: [PATCH] adding R support for litorgy --- litorgy/litorgy-R.el | 118 +++++++++++++++++++++++++++++++++++++++++++ litorgy/litorgy.el | 14 ++++- rorg.org | 11 ++++ 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 litorgy/litorgy-R.el diff --git a/litorgy/litorgy-R.el b/litorgy/litorgy-R.el new file mode 100644 index 000000000..fbae80400 --- /dev/null +++ b/litorgy/litorgy-R.el @@ -0,0 +1,118 @@ +;;; litorgy-R.el --- litorgy functions for R code evaluation + +;; Copyright (C) 2009 Eric Schulte, Dan Davison, Austin F. Frank + +;; Author: Eric Schulte, Dan Davison, Austin F. Frank +;; Keywords: literate programming, reproducible research +;; Homepage: http://orgmode.org +;; Version: 0.01 + +;;; License: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; Litorgy support for evaluating R code + +;;; Code: +(require 'litorgy) + +(litorgy-add-interpreter "R") + +(defun litorgy-execute:R (body params) + "Execute a block of R code with litorgy. This function is +called by `litorgy-execute-src-block'." + (let (results) + (message "executing R code block...") + (litorgy-initiate-R-buffer) + (mapc (lambda (line) (litorgy-R-input-command line)) (butlast (split-string body "[\r\n]"))) + (litorgy-R-last-output) + ;; ;; using litorgy-R-region-to-string + ;; (with-temp-buffer + ;; (insert body) + ;; (setq results (litorgy-R-region-to-string (point-min) (point-max))) + ;; (message "finished executing R code block") + ;; results) + )) + +;; Maybe the following be replaced with a method using `ess-execute', +;; I went with the following functions because I wrote them and they +;; are what I know +;; +;; (not the best reasons for making design decisions) + +(defvar litorgy-R-buffer nil + "Holds the buffer for the current R process") + +(defun litorgy-initiate-R-buffer () + "If there is not a current R process then create one." + (unless (and (buffer-live-p litorgy-R-buffer) (get-buffer litorgy-R-buffer)) + (save-excursion + (R) + (setf litorgy-R-buffer (current-buffer)) + (litorgy-R-wait-for-output) + (litorgy-R-input-command "")))) + +(defun litorgy-R-command-to-string (command) + "Send a command to R, and return the results as a string." + (litorgy-R-input-command command) + (litorgy-R-last-output)) + +(defun litorgy-R-input-command (command) + "Pass COMMAND to the R process running in `litorgy-R-buffer'." + (save-excursion + (save-match-data + (set-buffer litorgy-R-buffer) + (goto-char (process-mark (get-buffer-process (current-buffer)))) + (insert command) + (comint-send-input) + (litorgy-R-wait-for-output)))) + +(defun litorgy-R-region-to-string (start end) + "Send a region to R, and return the results as a string." + (interactive "r") + (comint-send-region (get-buffer-process litorgy-R-buffer) start end) + (litorgy-R-wait-for-output) + (litorgy-R-last-output)) + +(defun litorgy-R-wait-for-output () + "Wait until output arrives" + (save-excursion + (save-match-data + (set-buffer litorgy-R-buffer) + (while (progn + (goto-char comint-last-input-end) + (not (re-search-forward comint-prompt-regexp nil t))) + (accept-process-output (get-buffer-process (current-buffer))))))) + +(defun litorgy-R-last-output () + "Return the last R output as a string" + (save-excursion + (save-match-data + (set-buffer litorgy-R-buffer) + (goto-char (process-mark (get-buffer-process (current-buffer)))) + (forward-line 0) + (let ((raw (buffer-substring comint-last-input-end (- (point) 1)))) + (if (string-match "\n" raw) + raw + (and (string-match "\\[[[:digit:]+]\\] *\\(.*\\)$" raw) + (message raw) + (message (match-string 1 raw)) + (match-string 1 raw))))))) + +(provide 'litorgy-R) +;;; litorgy-R.el ends here diff --git a/litorgy/litorgy.el b/litorgy/litorgy.el index a2d1236eb..61a7fb7ac 100644 --- a/litorgy/litorgy.el +++ b/litorgy/litorgy.el @@ -56,6 +56,13 @@ so then run `litorgy-execute-src-block'." "\\([ \t]+\\([^\n]+\\)\\)?\n" ;; match header arguments "\\([^\000]+?\\)#\\+end_src"))) +(defun litorgy-add-interpreter (interpreter) + "Add INTERPRETER to `litorgy-interpreters' and update +`litorgy-src-block-regexp' appropriately." + (unless (member interpreter litorgy-interpreters) + (setq litorgy-interpreters (cons interpreter litorgy-interpreters)) + (litorgy-set-interpreters 'litorgy-interpreters litorgy-interpreters))) + (defcustom litorgy-interpreters '() "Interpreters allows for evaluation tags. This is a list of program names (as strings) that can evaluate code and @@ -66,7 +73,12 @@ emacs-lisp Evaluate Emacs Lisp code and display the result sh Pass command to the shell and display the result perl The perl interpreter python The python interpreter -ruby The ruby interpreter" +ruby The ruby interpreter + +The source block regexp `litorgy-src-block-regexp' is updated +when a new interpreter is added to this list through the +customize interface. To add interpreters to this variable from +lisp code use the `litorgy-add-interpreter' function." :group 'litorgy :set 'litorgy-set-interpreters :type '(set :greedy t diff --git a/rorg.org b/rorg.org index ebeb8d0f8..ed56f7185 100644 --- a/rorg.org +++ b/rorg.org @@ -87,6 +87,8 @@ The main objectives of this project are... AIUI The following can all be viewed as implementations of org-eval-buffer for R code: + + (see this question again posed in [[file:litorgy/litorgy-R.el::Maybe%20the%20following%20be%20replaced%20with%20a%20method%20using%20ess%20execute][litorgy-R.el]]) ***** org-eval-light This is the beginnings of a general evaluation mechanism, that @@ -591,6 +593,15 @@ print "Hello world!" #+end_src +** litorgy-R + +#+begin_src R :replace t +a <- 9 +b <- 18 +a + b +#+end_src + + ** free variables First assign the variable with some sort of interpreted line