~ericmoritz/+junk/emacs.d

« back to all changes in this revision

Viewing changes to src/org-6.34c/contrib/babel/lisp/langs/org-babel-sh.el

  • Committer: Eric Moritz
  • Date: 2010-03-08 17:33:56 UTC
  • Revision ID: eric@eric-moritzs-macbook-pro.local-20100308173356-lfvzvmyp2kzm7l5y
Added a src folder to hold versions of packages that I use

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
;;; org-babel-sh.el --- org-babel functions for shell evaluation
 
2
 
 
3
;; Copyright (C) 2009 Eric Schulte
 
4
 
 
5
;; Author: Eric Schulte
 
6
;; Keywords: literate programming, reproducible research
 
7
;; Homepage: http://orgmode.org
 
8
;; Version: 0.01
 
9
 
 
10
;;; License:
 
11
 
 
12
;; This program is free software; you can redistribute it and/or modify
 
13
;; it under the terms of the GNU General Public License as published by
 
14
;; the Free Software Foundation; either version 3, or (at your option)
 
15
;; any later version.
 
16
;;
 
17
;; This program is distributed in the hope that it will be useful,
 
18
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
;; GNU General Public License for more details.
 
21
;;
 
22
;; You should have received a copy of the GNU General Public License
 
23
;; along with GNU Emacs; see the file COPYING.  If not, write to the
 
24
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
25
;; Boston, MA 02110-1301, USA.
 
26
 
 
27
;;; Commentary:
 
28
 
 
29
;; Org-Babel support for evaluating shell source code.
 
30
 
 
31
;;; Code:
 
32
(require 'org-babel)
 
33
(require 'shell)
 
34
 
 
35
(org-babel-add-interpreter "sh")
 
36
 
 
37
(add-to-list 'org-babel-tangle-langs '("sh" "sh" "#!/usr/bin/env sh"))
 
38
 
 
39
(defun org-babel-execute:sh (body params)
 
40
  "Execute a block of Shell commands with org-babel.  This
 
41
function is called by `org-babel-execute-src-block'."
 
42
  (message "executing Shell source code block")
 
43
  (let* ((processed-params (org-babel-process-params params))
 
44
         (session (org-babel-sh-initiate-session (first processed-params)))
 
45
         (vars (second processed-params))
 
46
         (result-type (fourth processed-params))
 
47
         (full-body (concat
 
48
                     (mapconcat ;; define any variables
 
49
                      (lambda (pair)
 
50
                        (format "%s=%s"
 
51
                                (car pair)
 
52
                                (org-babel-sh-var-to-sh (cdr pair))))
 
53
                      vars "\n") "\n" body "\n\n"))) ;; then the source block body
 
54
    (org-babel-sh-evaluate session full-body result-type)))
 
55
 
 
56
(defun org-babel-prep-session:sh (session params)
 
57
  "Prepare SESSION according to the header arguments specified in PARAMS."
 
58
  (let* ((session (org-babel-sh-initiate-session session))
 
59
         (vars (org-babel-ref-variables params))
 
60
         (var-lines (mapcar ;; define any variables
 
61
                     (lambda (pair)
 
62
                       (format "%s=%s"
 
63
                               (car pair)
 
64
                               (org-babel-sh-var-to-sh (cdr pair))))
 
65
                     vars)))
 
66
    (org-babel-comint-in-buffer session
 
67
      (mapc (lambda (var)
 
68
              (insert var) (comint-send-input nil t)
 
69
              (org-babel-comint-wait-for-output session)) var-lines))
 
70
    session))
 
71
 
 
72
(defun org-babel-load-session:sh (session body params)
 
73
  "Load BODY into SESSION."
 
74
  (save-window-excursion
 
75
    (let ((buffer (org-babel-prep-session:sh session params)))
 
76
      (with-current-buffer buffer
 
77
        (goto-char (process-mark (get-buffer-process (current-buffer))))
 
78
        (insert (org-babel-chomp body)))
 
79
      buffer)))
 
80
 
 
81
;; helper functions
 
82
 
 
83
(defun org-babel-sh-var-to-sh (var)
 
84
  "Convert an elisp var into a string of shell commands
 
85
specifying a var of the same value."
 
86
  (if (listp var)
 
87
      (concat "[" (mapconcat #'org-babel-sh-var-to-sh var ", ") "]")
 
88
    (format "%S" var)))
 
89
 
 
90
(defun org-babel-sh-table-or-results (results)
 
91
  "If the results look like a table, then convert them into an
 
92
Emacs-lisp table, otherwise return the results as a string."
 
93
  (org-babel-read
 
94
   (if (string-match "^\\[.+\\]$" results)
 
95
       (org-babel-read
 
96
        (replace-regexp-in-string
 
97
         "\\[" "(" (replace-regexp-in-string
 
98
                    "\\]" ")" (replace-regexp-in-string
 
99
                               ", " " " (replace-regexp-in-string
 
100
                                         "'" "\"" results)))))
 
101
     results)))
 
102
 
 
103
(defun org-babel-sh-initiate-session (&optional session)
 
104
  (unless (string= session "none")
 
105
    (save-window-excursion
 
106
      (or (org-babel-comint-buffer-livep session)
 
107
          (progn (shell session) (get-buffer (current-buffer)))))))
 
108
 
 
109
(defvar org-babel-sh-eoe-indicator "echo 'org_babel_sh_eoe'"
 
110
  "Used to indicate that evaluation is has completed.")
 
111
(defvar org-babel-sh-eoe-output "org_babel_sh_eoe"
 
112
  "Used to indicate that evaluation is has completed.")
 
113
 
 
114
(defun org-babel-sh-evaluate (session body &optional result-type)
 
115
  "Pass BODY to the Shell process in BUFFER.  If RESULT-TYPE equals
 
116
'output then return a list of the outputs of the statements in
 
117
BODY, if RESULT-TYPE equals 'value then return the value of the
 
118
last statement in BODY."
 
119
  (if (not session)
 
120
      ;; external process evaluation
 
121
      (save-window-excursion
 
122
        (with-temp-buffer
 
123
          (insert body)
 
124
          ;; (message "buffer=%s" (buffer-string)) ;; debugging
 
125
          (shell-command-on-region (point-min) (point-max) "sh" 'replace)
 
126
          (case result-type
 
127
            (output (buffer-string))
 
128
            (value ;; TODO: figure out how to return non-output values from shell scripts
 
129
             (let ((tmp-file (make-temp-file "org-babel-sh"))
 
130
                   (results (buffer-string)))
 
131
               (with-temp-file tmp-file (insert results))
 
132
               (org-babel-import-elisp-from-file tmp-file))))))
 
133
    ;; comint session evaluation
 
134
    (flet ((strip-empty (lst)
 
135
                        (delq nil (mapcar (lambda (el) (unless (= (length el) 0) el)) lst))))
 
136
      (let ((tmp-file (make-temp-file "org-babel-sh"))
 
137
            (results
 
138
             (cdr (member
 
139
                   org-babel-sh-eoe-output
 
140
                   (strip-empty
 
141
                    (reverse
 
142
                     (mapcar #'org-babel-sh-strip-weird-long-prompt
 
143
                             (mapcar #'org-babel-trim
 
144
                                     (org-babel-comint-with-output
 
145
                                         session org-babel-sh-eoe-output t
 
146
                                       (mapc (lambda (line) (insert line) (comint-send-input))
 
147
                                             (strip-empty (split-string body "\n")))
 
148
                                       (insert org-babel-sh-eoe-indicator)
 
149
                                       (comint-send-input))))))))))
 
150
        ;; (message (replace-regexp-in-string
 
151
        ;;           "%" "%%" (format "processed-results=%S" results))) ;; debugging
 
152
        (or (and results
 
153
                 (case result-type
 
154
                   (output (org-babel-trim (mapconcat #'org-babel-trim
 
155
                                                      (reverse results) "\n")))
 
156
                   (value (with-temp-file tmp-file
 
157
                            (insert (car results)) (insert "\n"))
 
158
                          (org-babel-import-elisp-from-file tmp-file))))
 
159
            "")))))
 
160
 
 
161
(defun org-babel-sh-strip-weird-long-prompt (string)
 
162
  (while (string-match "^% +[\r\n$]+ *" string)
 
163
    (setq string (substring string (match-end 0))))
 
164
  string)
 
165
 
 
166
(provide 'org-babel-sh)
 
167
;;; org-babel-sh.el ends here