Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
;;; eev-prepared.el -- eev modules that use temporary dirs and prepared shells.

;; Copyright (C) 2012 Free Software Foundation, Inc.
;; This file is (not yet?) part of GNU eev.
;; GNU eev 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 of the License, or
;; (at your option) any later version.
;; GNU eev is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
;; Author:     Eduardo Ochs <eduardoochs@gmail.com>
;; Maintainer: Eduardo Ochs <eduardoochs@gmail.com>
;; Version:    2012nov02
;; Keywords:   e-scripts
;; Latest version: <http://angg.twu.net/eev-current/eev-prepared.el>
;;       htmlized: <http://angg.twu.net/eev-current/eev-prepared.el.html>
;;       See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
;;                 <http://angg.twu.net/eev-intros/find-eev-intro.html>
;;                                                (find-eev-intro)

;;; Commentary:
;; See: (find-eev "eev-env.el")
;;      (find-prepared-intro)

(require 'eev-env)

(ee-setenv "EEVTMPDIR" "$HOME/.eev")	; ee.sh and other temp scripts
(ee-setenv "EEVRCDIR"  "$EEVDIR/rcfiles")
(ee-setenv "EE"        "$EEVTMPDIR/ee.sh")
(ee-setenv "EEG"       "$EEVTMPDIR/ee.eeg")
(ee-setenv "EEGDB"     "$EEVTMPDIR/ee.gdb")
(ee-setenv "EETEX"     "$EEVTMPDIR/ee.tex")
(ee-setenv "EEC"       "$EEVTMPDIR/ee.c")
(ee-setenv "EETMPC"    "$EEVTMPDIR/tmp.c")
(ee-setenv "EEAOUT"    "$EEVTMPDIR/ee.aout")

(defvar ee-eevtmpdir    (ee-expand "$EEVTMPDIR/")
  "The directory where the temporary script files are put.")

(defvar ee-eevrcdir     (ee-expand "$EEVRCDIR/")
  "The directory where some auxiliary rcfiles for eev are to be found.")

(defvar ee-file         (ee-expand "$EE")
  "The temporary script file used by `eev'.")
(defvar ee-file-tex     (ee-expand "$EETEX")
  "The temporary script file used by `eelatex'.")
(defvar ee-file-gdb     (ee-expand "$EEGDB")
  "The temporary script file used by `eegdb'.")
(defvar ee-file-generic (ee-expand "$EEG"))

(defvar eelatex-eevscript
  "cd $EEVTMPDIR/; latex tmp.tex && xdvi tmp.dvi &" "See `eelatex'.")

(code-c-d "eevtmp" "$EEVTMPDIR/"       :anchor)  ; (find-eevtmpfile "")
(code-c-d "eevrc"  "$EEVRCDIR/"        :anchor)  ; (find-eevrcfile "")
(code-c-d "eevex"  "$EEVDIR/examples/" :anchor)  ; (find-eevexfile "")

;; (defvar ee-eevdir       (ee-expand "$EEVDIR/")
;;   "The directory where the elisp files for eev live.")
;; (code-c-d "eev"    "$EEVDIR/"          :anchor)  ; (find-eev "")

;;;  __  __                             
;;; |  \/  |    __  __    ___  _____   __
;;; | |\/| | __ \ \/ /   / _ \/ _ \ \ / /
;;; | |  | ||__| >  <   |  __/  __/\ V / 
;;; |_|  |_|    /_/\_\   \___|\___| \_/  
;;; eev and friends (or: saving regions as temporary scripts)

(defun ee-se-to-string (s e)
  "Convert the pair (S E) to a string.
If S is a number then return the contents of the current buffer
between the positions S and E; if S is a string then return S and
ignore E. See `write-region' - it uses the same convention for
interpreting \"(S E)\"-pairs as this function."
  (cond ((numberp s) (buffer-substring-no-properties s e))
        ((stringp s) s)))

(defun octal-to-num (str)
  "Convert STR - a sequence of octal digits - to a number."
  (let ((lastv (- (string-to-char (substring str -1)) ?0))
	(rest (substring str 0 -1)))
    (if (string= "" rest) lastv (+ lastv (* 8 (octal-to-num rest))))))

(defun ee-write-string (str &optional altfile fmode)
  "Write STR to ALTFILE, or to ee-file if ALTFILE is nil.
FMODE should be either nil or a string containing a sequence of
octal digits; if it is not nil then do the equivalent of a
\"chmod FMODE file\"."
  (let ((fname (substitute-in-file-name (or altfile ee-file))))
    (write-region str nil fname)	; a standard kludge
    (if fmode (set-file-modes fname (octal-to-num fmode)))))

(defun ee-write (s e pre post &optional altfile fmode)
  "Write PRE+(ee-se-to-string S E)+POST to ALTFILE, or to `ee-file'.
PRE and POST must be strings. See `ee-se-to-string' and
  (ee-write-string (concat pre (ee-se-to-string s e) post)
		   altfile fmode))

(defun ee-se-to-string-with-nl (s e)
  "Same as `ee-se-to-string', but force the result to end with a newline."
  (let ((str (ee-se-to-string s e)))
    (if (string-match "[^\n]\\'" str) (concat str "\n") str)))

(defun ee-write-with-nl (s e pre post &optional altfile fmode)
  "Same as `ee-write', but using `ee-se-to-string-with-nl'."
  (ee-write-string (concat pre (ee-se-to-string-with-nl s e) post)
		   altfile fmode))

(defun eev (s &optional e altfile)
  "Save the region in `ee-file', or in ALTFILE if it is non-nil.
If S is a string write then write the string instead. See `ee-write'.
This function is mostly used to send blocks of commands to shells via
a temporary script file. The shells do not receive the commands
immediately - we need to tell them to execute the commands stored in
the temporary script.\n
For example, if we mark the block below and type `M-x eev',\n
  # A hyperlink: (find-efunction 'eev)
  echo $[1+2]
  # Temporary scripts can change the
  # directory and the environment.
  cd /tmp/\n
and then go to a prepared shell and run `ee', we see something like
  /home/edrx$ ee
  # A hyperlink: (find-efunction 'eev)
  echo $[1+2]
  # Temporary scripts can change the
  # directory and the environment.
  cd /tmp/
  /tmp$ \n
Note that this only works in \"prepared shells\", where `ee' has been
defined as a shell function in the correct way; the relevant code for
.bashrc or .zshrc is this:\n
  export EEVTMPDIR ;: ${EEVTMPDIR:=~/.eev}
  export EE        ;: ${EE:=$EEVTMPDIR/ee.sh}
  function ee () { set -v; . $EE$*; set +v; }\n
See: (find-eevfile \"INSTALL\")
and: (find-eevfile \"eev-rctool\")"
  (interactive "r")
  (ee-write-with-nl s e "" "" altfile)
  (format "eev: wrote %s" (or altfile ee-file)))

(defun eevs (s &optional e suffix)
  "Like `eev', but with a suffix; write the region to `ee-file'+SUFFIX.
For example, if $EE is \"~/.eev/ee.sh\" and SUFFIX is \"0\" then
write the region to the file \"~/.eev/ee.sh0\". The shell
function \"ee\" concatenates its first argument to the value of
$EE, so running \"ee 0\" on a prepared shell executes the
temporary script \"~/.eev/ee.sh0\" instead of \"~/.eev/ee.sh\".
If S is a string write then write the string instead. See `ee-write'."
  (interactive "r\nsSuffix: ")
  (eev s e (concat ee-file suffix)))

(defun eelatex (s &optional e)
  "Save the region to `ee-file-tex', then save `eelatex-eevscript' to `ee-file'.
An example: run `M-x eelatex' on the line below,

  Hello! $\\frac{42}{\\sqrt{5}}$

then go to a prepared shell and run \"ee\". A temporary LaTeX
file will be processed by \"latex\" and the resulting dvi file
will be shown on the screen.
If S is a string write then write the string instead. See `eev'."
  (interactive "r")
  (ee-write s e "" "" ee-file-tex)
  (eev eelatex-eevscript nil)
  (format "eelatex: wrote %s and %s" ee-file-tex ee-file))

(defun eegdb (s &optional e)
  "Save the region to the temporary GDB script file given by `ee-file-gdb'.
After that if your GDB init file was prepared adequately then
running \"ee\" on a GDB prompt will make GDB execute the commands
in the temporary GDB script.
If S is a string write then write the string instead. See `eev'."
  (interactive "r")
  (ee-write s e "" "" ee-file-gdb)
  (format "eegdb: wrote %s" ee-file-gdb))

;; Obsolete, or almost? Used by: (find-eevfile "eeg4")
(defun eeg (s &optional e)
  (interactive "r")
  (ee-write s e "" "" ee-file-generic)
  (format "eeg: wrote %s" ee-file-gdb))

(defun eeeval (s &optional e)
"Like `eev', but instead of saving the region execute it immediately as Lisp.
This function is very similar to `eval-region'."
  (interactive "r")
  (eval (read (concat "(progn " (ee-se-to-string s e) "\n)"))))

(defun ee-default-directory ()
  "Return `default-directory' usually, but behave specially in some modes.
If the current buffer is a w3m buffer that is visiting a local
file (i.e., if the url is like \"file://...\") then extract the
directory from the url instead of returning the value of
This function is used by `eecd'."
  (if (eq major-mode 'w3-mode)
      (let ((url (url-view-url 0)))
	(if (string-match "^file:\\(.*/\\)[^/]*$" url)
	    (match-string 1 url)
	  (error "Current url is %S, which is not a local file" url)))

;; 2005jan10, incompatible change: added "dir"
(defun eecd (&optional dir command)
  "Save to $EE a \"cd\" command to `cd' to the current directory.
If DIR is not nil then use DIR; otherwise run `ee-default-directory'.
If COMMAND is not nil then save \"cd DIR; COMMAND\" instead of just
\"cd DIR\".\n
See `eev' for more about $EE and the temporary script file."
  (eev (concat "cd " (file-name-directory
		      (or dir (ee-default-directory)))
	       "\n" (or command ""))))

(provide 'eev-prepared)

;; Local Variables:
;; coding:            raw-text-unix
;; ee-anchor-format:  "«%s»"
;; ee-anchor-format:  "defun %s "
;; no-byte-compile:   t
;; End: