| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 | ;;; ob-ruby.el --- org-babel functions for ruby evaluation;; Copyright (C) 2009 Eric Schulte;; Author: Eric Schulte;; 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:;; Org-Babel support for evaluating ruby source code.;;; Requirements:;; - ruby and irb executables :: http://www.ruby-lang.org/;; ;; - ruby-mode :: Can be installed through ELPA, or from;;   http://github.com/eschulte/rinari/raw/master/util/ruby-mode.el;;   ;; - inf-ruby mode :: Can be installed through ELPA, or from;;   http://github.com/eschulte/rinari/raw/master/util/inf-ruby.el;;; Code:(require 'ob)(require 'inf-ruby)(add-to-list 'org-babel-tangle-lang-exts '("ruby" . "rb"))(defun org-babel-expand-body:ruby (body params &optional processed-params)  "Expand BODY according to PARAMS, return the expanded body."  (let ((vars (second (or processed-params (org-babel-process-params params)))))    (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")))(defun org-babel-execute:ruby (body params)  "Execute a block of Ruby code with org-babel.  This function iscalled by `org-babel-execute-src-block'."  (message "executing Ruby source code block")  (let* ((processed-params (org-babel-process-params params))         (session (org-babel-ruby-initiate-session (first processed-params)))         (result-params (third processed-params))         (result-type (fourth processed-params))         (full-body (org-babel-expand-body:ruby                     body params processed-params))         (result (org-babel-ruby-evaluate session full-body result-type)))    (or (cdr (assoc :file params))        (org-babel-reassemble-table         result         (org-babel-pick-name (nth 4 processed-params)			      (cdr (assoc :colnames params)))         (org-babel-pick-name (nth 5 processed-params)			      (cdr (assoc :rownames params)))))))(defun org-babel-prep-session:ruby (session params)  "Prepare SESSION according to the header arguments specified in PARAMS."  ;; (message "params=%S" params) ;; debugging  (let* ((session (org-babel-ruby-initiate-session session))         (vars (org-babel-ref-variables params))         (var-lines (mapcar ;; define any variables                     (lambda (pair)                       (format "%s=%s"                               (car pair)                               (org-babel-ruby-var-to-ruby (cdr pair))))                     vars)))    (org-babel-comint-in-buffer session      (sit-for .5) (goto-char (point-max))      (mapc (lambda (var)              (insert var) (comint-send-input nil t)              (org-babel-comint-wait-for-output session)              (sit-for .1) (goto-char (point-max))) var-lines))    session))(defun org-babel-load-session:ruby (session body params)  "Load BODY into SESSION."  (save-window-excursion    (let ((buffer (org-babel-prep-session:ruby session params)))      (with-current-buffer buffer        (goto-char (process-mark (get-buffer-process (current-buffer))))        (insert (org-babel-chomp body)))      buffer)));; helper functions(defun org-babel-ruby-var-to-ruby (var)  "Convert an elisp var into a string of ruby source codespecifying a var of the same value."  (if (listp var)      (concat "[" (mapconcat #'org-babel-ruby-var-to-ruby var ", ") "]")    (format "%S" var)))(defun org-babel-ruby-table-or-string (results)  "If RESULTS look like a table, then convert them into anEmacs-lisp table, otherwise return the results as a string."  (message "converting %S" results)  (org-babel-read   (if (and (stringp results) (string-match "^\\[.+\\]$" results))       (org-babel-read        (concat "'"                (replace-regexp-in-string                 "\\[" "(" (replace-regexp-in-string                            "\\]" ")" (replace-regexp-in-string                                       ", " " " (replace-regexp-in-string                                                 "'" "\"" results))))))     results)))(defun org-babel-ruby-initiate-session (&optional session params)  "If there is not a current inferior-process-buffer in SESSIONthen create one.  Return the initialized session."  (unless (string= session "none")    (let ((session-buffer (save-window-excursion			    (run-ruby nil session) (current-buffer))))      (if (org-babel-comint-buffer-livep session-buffer)	  (progn (sit-for .25) session-buffer)        (sit-for .5)        (org-babel-ruby-initiate-session session)))))(defvar org-babel-ruby-last-value-eval "_"  "When evaluated by Ruby this returns the return value of the last statement.")(defvar org-babel-ruby-pp-last-value-eval "require 'pp'; pp(_)"  "When evaluated by Ruby this pretty prints value of the last statement.")(defvar org-babel-ruby-eoe-indicator ":org_babel_ruby_eoe"  "Used to indicate that evaluation is has completed.")(defvar org-babel-ruby-wrapper-method  "def main()%sendresults = main()File.open('%s', 'w'){ |f| f.write((results.class == String) ? results : results.inspect) }")(defvar org-babel-ruby-pp-wrapper-method  "require 'pp'def main()%sendresults = main()File.open('%s', 'w') do |f|  $stdout = f  pp resultsend")(defun org-babel-ruby-evaluate (buffer body &optional result-type)  "Pass BODY to the Ruby process in BUFFER.  If RESULT-TYPE equals'output then return a list of the outputs of the statements inBODY, if RESULT-TYPE equals 'value then return the value of thelast statement in BODY, as elisp."  (if (not session)      ;; external process evaluation      (save-excursion        (case result-type          (output           (with-temp-buffer             (insert body)             ;; (message "buffer=%s" (buffer-string)) ;; debugging             (org-babel-shell-command-on-region	      (point-min) (point-max) "ruby" 'current-buffer 'replace)             (buffer-string)))          (value           (let* ((tmp-file (make-temp-file "ruby-functional-results"))		  exit-code		  (stderr		   (with-temp-buffer		     (insert (format (if (member "pp" result-params)					 org-babel-ruby-pp-wrapper-method				       org-babel-ruby-wrapper-method)				     body tmp-file))		     (setq exit-code			   (org-babel-shell-command-on-region			    (point-min) (point-max) "ruby"			    nil 'replace (current-buffer)))		     (buffer-string))))	     (if (> exit-code 0) (org-babel-error-notify exit-code stderr))             (let ((raw (with-temp-buffer			  (insert-file-contents			   (org-babel-maybe-remote-file tmp-file))			  (buffer-string))))               (if (or (member "code" result-params)		       (member "pp" result-params))                   raw                 (org-babel-ruby-table-or-string raw)))))))    ;; comint session evaluation    (let* ((full-body	    (mapconcat	     #'org-babel-chomp	     (list body (if (member "pp" result-params)                            org-babel-ruby-pp-last-value-eval                          org-babel-ruby-last-value-eval)                   org-babel-ruby-eoe-indicator) "\n"))           (raw (org-babel-comint-with-output		    (buffer org-babel-ruby-eoe-indicator t full-body)                  (insert full-body) (comint-send-input nil t)))           (results (cdr (member			  org-babel-ruby-eoe-indicator			  (reverse (mapcar #'org-babel-ruby-read-string					   (mapcar #'org-babel-trim raw)))))))      (case result-type        (output (mapconcat #'identity (reverse (cdr results)) "\n"))        (value         (if (or (member "code" result-params) (member "pp" result-params))             (car results)           (org-babel-ruby-table-or-string (car results))))))))(defun org-babel-ruby-read-string (string)  "Strip \\\"s from around a ruby string."  (if (string-match "^\"\\([^\000]+\\)\"$" string)      (match-string 1 string)    string))(provide 'ob-ruby);;; ob-ruby.el ends here
 |