;;;; oml-mode-process.el --- Process an o:XML program ;; oml-mode is a copy of xslide modified by Martin Klang to do o:XML ;; Copyright (C) 1998, 1999 Tony Graham ;; Author: Tony Graham ;;; This file is not part of GNU Emacs. ;; 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 2 ;; of the License, 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 this program; if not, write to the Free Software ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ;;;; Commentary: ;; Copied almost wholesale from psgml.el by Lennart Staflin ;;;; Variables: (defcustom oml-offer-save t "*If non-nil, ask about saving modified buffers before \\[oml-process] is run." :type '(choice (const :tag "Yes" t) (const :tag "No" nil)) :group 'oml-process) (defcustom oml-process-command (list ;; XT Windows executable "xt %i %s %o" ;; XT Java "java com.jclark.oml.Driver %i %s %o" ;; Instant Saxon "saxon -o %o %i %s" ;; Instant Saxon using xml-program PI "saxon -o %o %i" ;; Saxon "java com.icl.saxon.StyleSheet -o %o %i %s" ;; Saxon using xml-program PI "java com.icl.saxon.StyleSheet -o %o %i") "*The shell command to process an o:XML document. This is a `format' control string that by default should contain three `%s' conversion specifications: the first will be replaced by the value of oml-process-input-file \(or the empty string, if nil\); the second will be replaced by oml-process-program-file \(or the empty string, if nil\); the third will be replaced by oml-process-output-file \(or the empty string, if nil\). If `oml-process-files' is non-nil, the format string should contain one `%s' conversion specification for each element of its result. If oml-process-command is a list, then every element should be a string. The strings will be tried in order and %-sequences in the string will be replaced according to the list below, if the string contains %-sequences with no replacement value the next string will be tried. %b means the visited file of the current buffer %i means the value of oml-process-input-file %s means the value of oml-process-program-file %o means the value of oml-process-output-file " :type '(repeat :tag "Commands" string) :group 'oml-process) (defvar oml-process-files nil "If non-nil, a function of no arguments that returns a list of file names. These file names will serve as the arguments to the `oml-process-command' format control string instead of the defaults.") (defcustom oml-process-error-regexps '(("file:\\([^:]+\\):\\([0-9]+\\):\\([0-9]+\\):" 1 2 3) ("file:/\\(\\([A-Za-z]:\\)?[^:]+\\):\\([0-9]+\\):\\(\\([0-9]+\\):\\)?" 1 3 5) ("on line \\([0-9]+\\) of file:\\([^:]+\\):\\([0-9]+\\)" 3 1 2)) "Alist of regexps to recognize error messages from `oml-process'. See `compilation-error-regexp-alist'." :type '(repeat :tag "Regexps" (list (regexp :tag "Regexp") (integer :tag "File index") (integer :tag "Line index") (choice :tag "Column index" (integer) (const :tag "None" nil)))) :group 'oml-process) (defvar oml-xml-source nil "*If non-nil, this is the name of the XML source file.") (put 'oml-xml-source 'oml-type 'string) (defvar oml-oml-result nil "*If non-nil, this is the name of the o:XML result file.") (put 'oml-oml-result 'oml-type 'string) (defvar oml-process-command-history nil "The minibuffer history list for `oml-process''s COMMAND argument.") ;;(make-variable-buffer-local 'oml-process-command-history) (eval-and-compile (autoload 'compile-internal "compile" "")) (defun oml-subst-expand-char (c parts) (cdr-safe (assq (downcase c) parts))) (defun oml-subst-expand (s parts) (loop for i from 0 to (1- (length s)) as c = (aref s i) concat (if (eq c ?%) (or (oml-subst-expand-char (aref s (incf i)) parts) (return nil)) (char-to-string (aref s i))))) (defun oml-populate-process-command-history () (cond ((consp oml-process-command) (let ((process-subst (list (cons ?b (and (buffer-file-name) (file-name-nondirectory (buffer-file-name)))) (cons ?i oml-process-input-file) (cons ?s oml-process-program-file) (cons ?o oml-process-output-file)))) (setq oml-process-command-history (append (mapcar (lambda (x) (oml-subst-expand x process-subst)) oml-process-command) oml-process-command-history)))) ;; (loop for template in oml-process-command ;; append ;; (oml-subst-expand template process-subst) ;; into ;; oml-process-command-history))) (t (apply 'format oml-process-command (if oml-process-files (funcall oml-process-files) (list (or oml-xml-source "") (let ((name (buffer-file-name))) (if name (file-name-nondirectory name) "")) (or oml-oml-result ""))))))) (defvar oml-process-input-file nil "Filename of input file for `oml-process' command") (defvar oml-process-input-history nil "The minibuffer history list for `oml-get-process-parameters''s INPUT argument.") (defvar oml-process-program-file nil "Filename of program file for `oml-process' command") (defvar oml-process-program-history nil "The minibuffer history list for `oml-get-process-parameters''s STYLESHEET argument.") (defvar oml-process-output-file nil "Filename of output file for `oml-process' command") (defvar oml-process-output-history nil "The minibuffer history list for `oml-get-process-parameters''s OUTPUT argument.") (defun oml-get-process-parameters () "Get and set the parameters for the `oml-process' command" (interactive) (setq oml-process-input-file (oml-read-from-minibuffer "Input file: " (concat (file-name-sans-extension (file-name-nondirectory (buffer-file-name))) ".xml") 'oml-process-input-history)) (setq oml-process-program-file (oml-read-from-minibuffer "Stylesheet file: " (file-name-nondirectory (buffer-file-name)) 'oml-process-program-history)) (setq oml-process-output-file (oml-read-from-minibuffer "Output file: " (concat (file-name-sans-extension (file-name-nondirectory oml-process-input-file)) ".html") 'oml-process-output-history))) (defun oml-process (command) "Process an o:XML program. Runs COMMAND, a shell command, in a separate process asynchronously with output going to the buffer *o:XML process*. You can then use the command \\[next-error] to find the next error message and move to the line in the o:XML document that caused it. The first time that the program is run and whenever you provide a prefix argument, e.g. \\[universal-argument] \\[oml-process], prompts for input filename, program file, and output filename. Those values are used with the templates in `oml-process-command' to populate this command's command history with the command lines to run several o:XML processors using those values. Use M-p and M-n to step through the predefined commands, edit a command if necessary, or enter a new command line. The next time that this command is run, the previously executed command is used as the default." (interactive (list (progn (if (or current-prefix-arg (null oml-process-command-history)) (progn (oml-get-process-parameters) (oml-populate-process-command-history))) (read-from-minibuffer "Process command: " (car oml-process-command-history) nil nil 'oml-process-command-history)))) (if oml-offer-save (save-some-buffers nil nil)) (compile-internal command "No more errors" "o:XML process" nil oml-process-error-regexps)) (provide 'oml-mode-process)