diff options
Diffstat (limited to 'texinfo/emacs/makeinfo.el')
-rw-r--r-- | texinfo/emacs/makeinfo.el | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/texinfo/emacs/makeinfo.el b/texinfo/emacs/makeinfo.el new file mode 100644 index 00000000000..a649d522156 --- /dev/null +++ b/texinfo/emacs/makeinfo.el @@ -0,0 +1,247 @@ +;;; makeinfo.el --- run makeinfo conveniently + +;; Copyright (C) 1991, 1993 Free Software Foundation, Inc. + +;; Author: Robert J. Chassell +;; Maintainer: FSF + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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, or (at your option) +;; any later version. + +;; GNU Emacs 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., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; The Texinfo mode `makeinfo' related commands are: + +;; makeinfo-region to run makeinfo on the current region. +;; makeinfo-buffer to run makeinfo on the current buffer, or +;; with optional prefix arg, on current region +;; kill-compilation to kill currently running makeinfo job +;; makeinfo-recenter-makeinfo-buffer to redisplay *compilation* buffer + +;;; Keybindings (defined in `texinfo.el') + +;; makeinfo bindings +; (define-key texinfo-mode-map "\C-c\C-m\C-r" 'makeinfo-region) +; (define-key texinfo-mode-map "\C-c\C-m\C-b" 'makeinfo-buffer) +; (define-key texinfo-mode-map "\C-c\C-m\C-k" 'kill-compilation) +; (define-key texinfo-mode-map "\C-c\C-m\C-l" +; 'makeinfo-recenter-compilation-buffer) + +;;; Code: + +;;; Variables used by `makeinfo' + +(require 'compile) + +(defvar makeinfo-run-command "makeinfo" + "*Command used to run `makeinfo' subjob. +The name of the file is appended to this string, separated by a space.") + +(defvar makeinfo-options "--fill-column=70" + "*String containing options for running `makeinfo'. +Do not include `--footnote-style' or `--paragraph-indent'; +the proper way to specify those is with the Texinfo commands +`@footnotestyle` and `@paragraphindent'.") + +(require 'texinfo) + +(defvar makeinfo-compilation-process nil + "Process that runs `makeinfo'. Should start out nil.") + +(defvar makeinfo-temp-file nil + "Temporary file name used for text being sent as input to `makeinfo'.") + +(defvar makeinfo-output-file-name nil + "Info file name used for text output by `makeinfo'.") + + +;;; The `makeinfo' function definitions + +(defun makeinfo-region (region-beginning region-end) + "Make Info file from region of current Texinfo file, and switch to it. + +This command does not offer the `next-error' feature since it would +apply to a temporary file, not the original; use the `makeinfo-buffer' +command to gain use of `next-error'." + + (interactive "r") + (let (filename-or-header + filename-or-header-beginning + filename-or-header-end) + ;; Cannot use `let' for makeinfo-temp-file or + ;; makeinfo-output-file-name since `makeinfo-compilation-sentinel' + ;; needs them. + + (setq makeinfo-temp-file + (concat + (make-temp-name + (substring (buffer-file-name) + 0 + (or (string-match "\\.tex" (buffer-file-name)) + (length (buffer-file-name))))) + ".texinfo")) + + (save-excursion + (save-restriction + (widen) + (goto-char (point-min)) + (let ((search-end (save-excursion (forward-line 100) (point)))) + ;; Find and record the Info filename, + ;; or else explain that a filename is needed. + (if (re-search-forward + "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*" + search-end t) + (setq makeinfo-output-file-name + (buffer-substring (match-beginning 1) (match-end 1))) + (error + "The texinfo file needs a line saying: @setfilename <name>")) + + ;; Find header and specify its beginning and end. + (goto-char (point-min)) + (if (and + (prog1 + (search-forward tex-start-of-header search-end t) + (beginning-of-line) + ;; Mark beginning of header. + (setq filename-or-header-beginning (point))) + (prog1 + (search-forward tex-end-of-header nil t) + (beginning-of-line) + ;; Mark end of header + (setq filename-or-header-end (point)))) + + ;; Insert the header into the temporary file. + (write-region + (min filename-or-header-beginning region-beginning) + filename-or-header-end + makeinfo-temp-file nil nil) + + ;; Else no header; insert @filename line into temporary file. + (goto-char (point-min)) + (search-forward "@setfilename" search-end t) + (beginning-of-line) + (setq filename-or-header-beginning (point)) + (forward-line 1) + (setq filename-or-header-end (point)) + (write-region + (min filename-or-header-beginning region-beginning) + filename-or-header-end + makeinfo-temp-file nil nil)) + + ;; Insert the region into the file. + (write-region + (max region-beginning filename-or-header-end) + region-end + makeinfo-temp-file t nil) + + ;; Run the `makeinfo-compile' command in the *compilation* buffer + (save-excursion + (makeinfo-compile + (concat makeinfo-run-command + " " + makeinfo-options + " " + makeinfo-temp-file) + "Use `makeinfo-buffer' to gain use of the `next-error' command" + nil))))))) + +;;; Actually run makeinfo. COMMAND is the command to run. +;;; ERROR-MESSAGE is what to say when next-error can't find another error. +;;; If PARSE-ERRORS is non-nil, do try to parse error messages. +(defun makeinfo-compile (command error-message parse-errors) + (let ((buffer + (compile-internal command error-message nil + (and (not parse-errors) + ;; If we do want to parse errors, pass nil. + ;; Otherwise, use this function, which won't + ;; ever find any errors. + '(lambda (&rest ignore) + (setq compilation-error-list nil)))))) + (set-process-sentinel (get-buffer-process buffer) + 'makeinfo-compilation-sentinel))) + +;; Delete makeinfo-temp-file after processing is finished, +;; and visit Info file. +;; This function is called when the compilation process changes state. +;; Based on `compilation-sentinel' in compile.el +(defun makeinfo-compilation-sentinel (proc msg) + (compilation-sentinel proc msg) + (if (and makeinfo-temp-file (file-exists-p makeinfo-temp-file)) + (delete-file makeinfo-temp-file)) + ;; Always use the version on disk. + (if (get-file-buffer makeinfo-output-file-name) + (progn (set-buffer makeinfo-output-file-name) + (revert-buffer t t)) + (find-file makeinfo-output-file-name)) + (goto-char (point-min))) + +(defun makeinfo-buffer () + "Make Info file from current buffer. + +Use the \\[next-error] command to move to the next error +\(if there are errors\)." + + (interactive) + (cond ((null buffer-file-name) + (error "Buffer not visiting any file")) + ((buffer-modified-p) + (if (y-or-n-p "Buffer modified; do you want to save it? ") + (save-buffer)))) + + ;; Find and record the Info filename, + ;; or else explain that a filename is needed. + (save-excursion + (goto-char (point-min)) + (let ((search-end (save-excursion (forward-line 100) (point)))) + (if (re-search-forward + "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*" + search-end t) + (setq makeinfo-output-file-name + (buffer-substring (match-beginning 1) (match-end 1))) + (error + "The texinfo file needs a line saying: @setfilename <name>")))) + + (save-excursion + (makeinfo-compile + (concat makeinfo-run-command " " makeinfo-options + " " buffer-file-name) + "No more errors." + t))) + +(defun makeinfo-recenter-compilation-buffer (linenum) + "Redisplay `*compilation*' buffer so most recent output can be seen. +The last line of the buffer is displayed on +line LINE of the window, or centered if LINE is nil." + (interactive "P") + (let ((makeinfo-buffer (get-buffer "*compilation*")) + (old-buffer (current-buffer))) + (if (null makeinfo-buffer) + (message "No *compilation* buffer") + (pop-to-buffer makeinfo-buffer) + (bury-buffer makeinfo-buffer) + (goto-char (point-max)) + (recenter (if linenum + (prefix-numeric-value linenum) + (/ (window-height) 2))) + (pop-to-buffer old-buffer) + ))) + +;;; Place `provide' at end of file. +(provide 'makeinfo) + +;;; makeinfo.el ends here + |