; GPL'ed as under the GNU license.. ; -- Deepak Goel (deego@glue.umd.edu) ;9/5/00 ; This helps me do automated actions everytime a particular file gets updated.. ; Most of the functions here are oriented towards a display-ed screen.. ; O GENERAL USER: PLEASE CHANGE THE LOADED-PROFILE FILE TO ; generalprofile.el below. You will need to download this ; generalprofile.el, edit it to your needs, and also download ; timerfunctions.el. Please have an emacs installed on your system, ; pref. emacs20. ;;;==================================================== (defmacro bind (a &optional value) "Like setq but only If a not already bound. Copied from .emacs.macros. Basically, is like defvar." (list 'if (list 'not (list 'boundp (list 'quote a))) (list 'setq a value)) ) ;USER OPTIONS BEGIN ;;;==================================================== (require 'cl) (load-file "timerfunctions.el") ; *file* ==> file without extension ; *ext* ==> extension of file, default: .tex.e ; there are also defaults for *view-command* and *command* ;PROFILES ARE SET HERE: (load "deegoprofile.el") (setq *overrule-error* nil) (bind *overrule-error* nil) (bind *ext* ".tex.e") (bind *view-command* (concat "gv -scale 2 " *file* ".ps &")) ; FOR ME: (bind *command* (concat "elat " *file*)) (bind *directory* "~/more/tex") (bind *file* "myarticle") ;;;==================================================== ;;;==================================================== (setq *repeattime* 4) (setq *initialtime* 4) (setq *viewp* t) (setq *includeruntime* nil) ;;;==================================================== ;USER OPTIONS END ; overrule-error => show gv even if error-found.. ;;;==================================================== (setq *begintime* (cadr (current-time))) (defun last-modified-time-my (file) "Gets file's last modified-time." (sixth (file-attributes file))) ; this ensures initial processing.. (setq *last-modified-time* nil) ;(setq *last-modified-time* (ignore-errors (last-modified-time-my *file*))) ; (defun elatstart () ; "Automatically elatexes *file* whenever needed. The main function ; here.. Does so by running elatrun whenever it finds it idle.. Does not ; work for more than a day continuously. ; " ; (interactive) ; (cd *directory*) ; (run-with-idle-timer *initialtime* "repeat" 'elatrestartrun) ; ) ; ;;;==================================================== ; (defun elatrestartrun () ; "Internal." ; (setq *begintime* (cadr (current-time))) ; (elatrun) ; ) ; ;;;==================================================== ; (defun elatrun () ; "Whenever emacs is idle for *initialtime* sec., this function is ; called by elatstart. This function then runs elat on the file. Then, ; sets a one-time-timer to run itself for time + repeat seconds in case ; emacs remains idle.... which ; will do the same and so on.., so that as long as emacs is idle, ; elatrun will run every repeat seconds. Does not work for more than a ; day continuosly because i am using \(cadr \(current-time\)\). ; WHEN I SAY IT WILL REPEAT EVERY *repeattime* SECONDS, I MEAN THAT THE ; TIME TO RUN ELAT IS *NOT* COUNTED TOWARDS THAT. IN FACT, I GO TO GREAT ; LENGTHS TO ENSURE THAT---SEE KEEPTRACK BELOW.. ; " ; (let ((keeptrack (cadr (current-time)))) ; (cd *directory*) ; (elat) ; (setq *begintime* (+ *begintime* (- (cadr (current-time)) keeptrack))) ; (run-with-idle-timer (+ *repeattime* (- (cadr (current-time)) ; *begintime*)) ; ; the one below is no good---doesn't even respect the users' options. ; ; (run-at-time nil *repeattime* 'elat) ; ; (run-at-time nil *repeattime* 'elatwhenidle) ; ) ;;;###autoload (defun elatstart () (tf-run-with-idle-timer *initialtime* t *repeattime* t *includeruntime* 'elat) ) ;;;==================================================== (global-set-key "\C-cv" 'elatview) (defun elatview () "Ghostview command." (interactive) (shell-command (concat "cd " *directory*)) (shell-command *view-command*)) (global-set-key "\C-ce" 'elat) (defun elatwhenidle () (run-with-idle-timer 5 nil 'elat)) (defun elat () "One instance of processing. Bound to C-cC-e. This command elats the file if the file has been modified. It shows the processing-results, searching for errors, if any. The last time's precessing results are backuped into a buffer called Previous Shell Command Output." (interactive) (cd *directory*) (let* ((newtime (last-modified-time-my (concat *file* *ext*))) (modifiedp (not (equal *last-modified-time* newtime)))) (setq *last-modified-time* newtime) (if modifiedp (progn (get-buffer-create "*Shell Command Output*") (get-buffer-create "*Previous Shell Command Output*") (kill-region (point-min) (point-max)) (insert-buffer "*Shell Command Output*") (switch-to-buffer "*Shell Command Output*") (kill-region (point-min) (point-max)) (shell-command "echo Running elat now.") (shell-command (concat "cd " *directory*)) (shell-command *command*) (switch-to-buffer "*Shell Command Output*") (goto-char (point-min)) (search-forward "about the first error" nil t) (let (error-found) (if (or (search-forward "Error" nil "go-to-end-otherwise") (progn (goto-char (point-min)) (search-forward "Undefined control sequence" nil "go-to-end-otherwise")) (progn (goto-char (point-min)) (search-forward "Emergency stop" nil "go-to-end-otherwise"))) ; (ignore-errors (bold-region ; (- (point) 7) ; (point)))) (setq error-found t)) (if error-found (progn (insert "[[[<---**ERROR**DETECTED**DURING**RUN**!!***]]]") (ding t) (ding t) (ding t) (ding t) (ding t) )) ; else gv.. (if *viewp* (if (or *overrule-error* (not error-found)) (progn (ignore-errors (delete-process "*Async Shell Command*")) (elatview ))))) (switch-to-buffer "*Shell Command Output*") (insert (current-time-my)) (line-to-top-of-window) ; (shell-command "echo Done") ))) ) ;;;==================================================== ;;;==================================================== ; The following might be useful in a batch mode.. ; (defun do-upon-revert (file sittime action &optional skip-initial) ; "NOT CURRENTLY IN USE. ; If a file exists and has been modified, perform action. ; The action is performed by default the first time this function is ; launched, unless skip-initial is non-nil. Any action is ; performed only if the file exists. Is basically a generalization of ; auto-revert-buffer, and helps me auto-process my latex documents. This ; process is more suited for background batch type jobs, and will not be ; used here any more. The problem with background jobs, however, is that ; the sit-for won't work, so I had better comment it out.. But that ; would mean continuous CPU wastage.." ; (let ((aatime (last-modified-time-my file)) bbtime modifiedp) ; (if (and aatime (not skip-initial)) (eval action)) ; (while (> 1 0) ; (sit-for sittime) ; (setq bbtime (last-modified-time-my file)) ; (setq modifiedp (equal aatime bbtime)) ; (setq aatime bbtime) ; (if (and modifiedp aatime) ; (eval action))))) ; LocalWords: timerfunctions