(texinfo-mode-map): Add C-c C-e bindings for texinfmt.el.
[bpt/emacs.git] / lisp / textmodes / makeinfo.el
1 ;;;; makeinfo.el -- run makeinfo conveniently.
2 ;;; Copyright (C) 1991, 1993 Free Software Foundation, Inc.
3
4 ;;; Author: Robert J. Chassell
5 ;;; Maintainer: FSF
6
7 ;;; This file is part of GNU Emacs.
8
9 ;; GNU Emacs is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22
23 ;;; Commentary:
24
25 ;;; The Texinfo mode `makeinfo' related commands are:
26
27 ;; makeinfo-region to run makeinfo on the current region.
28 ;; makeinfo-buffer to run makeinfo on the current buffer, or
29 ;; with optional prefix arg, on current region
30 ;; kill-compilation to kill currently running makeinfo job
31 ;; makeinfo-recenter-makeinfo-buffer to redisplay *compilation* buffer
32
33 ;;; Keybindings (defined in `texinfo.el')
34
35 ;; makeinfo bindings
36 ; (define-key texinfo-mode-map "\C-c\C-m\C-r" 'makeinfo-region)
37 ; (define-key texinfo-mode-map "\C-c\C-m\C-b" 'makeinfo-buffer)
38 ; (define-key texinfo-mode-map "\C-c\C-m\C-k" 'kill-compilation)
39 ; (define-key texinfo-mode-map "\C-c\C-m\C-l"
40 ; 'makeinfo-recenter-compilation-buffer)
41 \f
42 ;;; Code:
43
44 ;;; Variables used by `makeinfo'
45
46 (require 'compile)
47
48 (defvar makeinfo-run-command "makeinfo"
49 "*Command used to run `makeinfo' subjob.
50 The name of the file is appended to this string, separated by a space.")
51
52 (defvar makeinfo-options "--fill-column=70"
53 "*String containing options for running `makeinfo'.
54 Do not include `--footnote-style' or `--paragraph-indent';
55 the proper way to specify those is with the Texinfo commands
56 `@footnotestyle` and `@paragraphindent'.")
57
58 (require 'texinfo)
59
60 (defvar makeinfo-compilation-process nil
61 "Process that runs `makeinfo'. Should start out nil.")
62
63 (defvar makeinfo-temp-file nil
64 "Temporary file name used for text being sent as input to `makeinfo'.")
65
66 (defvar makeinfo-output-file-name nil
67 "Info file name used for text output by `makeinfo'.")
68
69 \f
70 ;;; The `makeinfo' function definitions
71
72 (defun makeinfo-region (region-beginning region-end)
73 "Make Info file from region of current Texinfo file, and switch to it.
74
75 This command does not offer the `next-error' feature since it would
76 apply to a temporary file, not the original; use the `makeinfo-buffer'
77 command to gain use of `next-error'."
78
79 (interactive "r")
80 (let (filename-or-header
81 filename-or-header-beginning
82 filename-or-header-end)
83 ;; Cannot use `let' for makeinfo-temp-file or
84 ;; makeinfo-output-file-name since `makeinfo-compilation-sentinel'
85 ;; needs them.
86
87 (setq makeinfo-temp-file
88 (concat
89 (make-temp-name
90 (substring (buffer-file-name)
91 0
92 (or (string-match "\\.tex" (buffer-file-name))
93 (length (buffer-file-name)))))
94 ".texinfo"))
95
96 (save-excursion
97 (save-restriction
98 (widen)
99 (goto-char (point-min))
100 (let ((search-end (save-excursion (forward-line 100) (point))))
101 ;; Find and record the Info filename,
102 ;; or else explain that a filename is needed.
103 (if (re-search-forward
104 "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*"
105 search-end t)
106 (setq makeinfo-output-file-name
107 (buffer-substring (match-beginning 1) (match-end 1)))
108 (error
109 "The texinfo file needs a line saying: @setfilename <name>"))
110
111 ;; Find header and specify its beginning and end.
112 (goto-char (point-min))
113 (if (and
114 (prog1
115 (search-forward texinfo-start-of-header search-end t)
116 (beginning-of-line)
117 ;; Mark beginning of header.
118 (setq filename-or-header-beginning (point)))
119 (prog1
120 (search-forward texinfo-end-of-header nil t)
121 (beginning-of-line)
122 ;; Mark end of header
123 (setq filename-or-header-end (point))))
124
125 ;; Insert the header into the temporary file.
126 (write-region
127 (min filename-or-header-beginning region-beginning)
128 filename-or-header-end
129 makeinfo-temp-file nil nil)
130
131 ;; Else no header; insert @filename line into temporary file.
132 (goto-char (point-min))
133 (search-forward "@setfilename" search-end t)
134 (beginning-of-line)
135 (setq filename-or-header-beginning (point))
136 (forward-line 1)
137 (setq filename-or-header-end (point))
138 (write-region
139 (min filename-or-header-beginning region-beginning)
140 filename-or-header-end
141 makeinfo-temp-file nil nil))
142
143 ;; Insert the region into the file.
144 (write-region
145 (max region-beginning filename-or-header-end)
146 region-end
147 makeinfo-temp-file t nil)
148
149 ;; Run the `makeinfo-compile' command in the *compilation* buffer
150 (save-excursion
151 (makeinfo-compile
152 (concat makeinfo-run-command
153 " "
154 makeinfo-options
155 " "
156 makeinfo-temp-file)
157 "Use `makeinfo-buffer' to gain use of the `next-error' command"
158 nil)))))))
159
160 ;;; Actually run makeinfo. COMMAND is the command to run.
161 ;;; ERROR-MESSAGE is what to say when next-error can't find another error.
162 ;;; If PARSE-ERRORS is non-nil, do try to parse error messages.
163 (defun makeinfo-compile (command error-message parse-errors)
164 (let ((buffer
165 (compile-internal command error-message nil
166 (and (not parse-errors)
167 ;; If we do want to parse errors, pass nil.
168 ;; Otherwise, use this function, which won't
169 ;; ever find any errors.
170 '(lambda (&rest ignore)
171 (setq compilation-error-list nil))))))
172 (set-process-sentinel (get-buffer-process buffer)
173 'makeinfo-compilation-sentinel)))
174
175 ;; Delete makeinfo-temp-file after processing is finished,
176 ;; and visit Info file.
177 ;; This function is called when the compilation process changes state.
178 ;; Based on `compilation-sentinel' in compile.el
179 (defun makeinfo-compilation-sentinel (proc msg)
180 (compilation-sentinel proc msg)
181 (if (and makeinfo-temp-file (file-exists-p makeinfo-temp-file))
182 (delete-file makeinfo-temp-file))
183 ;; Always use the version on disk.
184 (if (get-file-buffer makeinfo-output-file-name)
185 (progn (set-buffer makeinfo-output-file-name)
186 (revert-buffer t t))
187 (find-file makeinfo-output-file-name))
188 (goto-char (point-min)))
189
190 (defun makeinfo-buffer ()
191 "Make Info file from current buffer.
192
193 Use the \\[next-error] command to move to the next error
194 \(if there are errors\)."
195
196 (interactive)
197 (cond ((null buffer-file-name)
198 (error "Buffer not visiting any file"))
199 ((buffer-modified-p)
200 (if (y-or-n-p "Buffer modified; do you want to save it? ")
201 (save-buffer))))
202
203 ;; Find and record the Info filename,
204 ;; or else explain that a filename is needed.
205 (save-excursion
206 (goto-char (point-min))
207 (let ((search-end (save-excursion (forward-line 100) (point))))
208 (if (re-search-forward
209 "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*"
210 search-end t)
211 (setq makeinfo-output-file-name
212 (buffer-substring (match-beginning 1) (match-end 1)))
213 (error
214 "The texinfo file needs a line saying: @setfilename <name>"))))
215
216 (save-excursion
217 (makeinfo-compile
218 (concat makeinfo-run-command " " makeinfo-options
219 " " buffer-file-name)
220 "No more errors."
221 t)))
222
223 (defun makeinfo-recenter-compilation-buffer (linenum)
224 "Redisplay `*compilation*' buffer so most recent output can be seen.
225 The last line of the buffer is displayed on
226 line LINE of the window, or centered if LINE is nil."
227 (interactive "P")
228 (let ((makeinfo-buffer (get-buffer "*compilation*"))
229 (old-buffer (current-buffer)))
230 (if (null makeinfo-buffer)
231 (message "No *compilation* buffer")
232 (pop-to-buffer makeinfo-buffer)
233 (bury-buffer makeinfo-buffer)
234 (goto-char (point-max))
235 (recenter (if linenum
236 (prefix-numeric-value linenum)
237 (/ (window-height) 2)))
238 (pop-to-buffer old-buffer)
239 )))
240
241 ;;; Place `provide' at end of file.
242 (provide 'makeinfo)
243
244 ;;; makeinfo.el ends here
245