EasyPG 1.07 Released
[packages] / xemacs-packages / auctex / tex-buf.el
1 ;;; tex-buf.el --- External commands for AUCTeX.
2
3 ;; Copyright (C) 1991-1999, 2001-2017 Free Software Foundation, Inc.
4
5 ;; Maintainer: auctex-devel@gnu.org
6 ;; Keywords: tex, wp
7
8 ;; This file is part of AUCTeX.
9
10 ;; AUCTeX is free software; you can redistribute it and/or modify it
11 ;; under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14
15 ;; AUCTeX is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ;; General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with AUCTeX; see the file COPYING.  If not, write to the Free
22 ;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 ;; 02110-1301, USA.
24
25 ;;; Commentary:
26
27 ;; This file provides support for external commands.
28
29 ;;; Code:
30
31 (require 'tex)
32 (require 'latex)
33 (require 'comint)
34
35 ;;; Customization:
36
37 (defcustom TeX-process-asynchronous (not (eq system-type 'ms-dos))
38   "*Use asynchronous processes."
39   :group 'TeX-command
40   :type 'boolean)
41
42 (defcustom TeX-shell
43   (if (memq system-type '(ms-dos emx windows-nt))
44       shell-file-name
45     "/bin/sh")
46   "Name of shell used to parse TeX commands."
47   :group 'TeX-command
48   :type 'file)
49
50 (defcustom TeX-shell-command-option
51   (cond ((memq system-type '(ms-dos emx windows-nt) )
52          (cond ((boundp 'shell-command-option)
53                 shell-command-option)
54                ((boundp 'shell-command-switch)
55                 shell-command-switch)
56                (t
57                 "/c")))
58         (t                              ;Unix & EMX (Emacs 19 port to OS/2)
59          "-c"))
60   "Shell argument indicating that next argument is the command."
61   :group 'TeX-command
62   :type 'string)
63
64 ;;; Interactive Commands
65 ;;
66 ;; The general idea is, that there is one process and process buffer
67 ;; associated with each master file, and one process and process buffer
68 ;; for running TeX on a region.   Thus, if you have N master files, you
69 ;; can run N + 1 processes simultaneously.
70 ;;
71 ;; Some user commands operates on ``the'' process.  The following
72 ;; algorithm determine what ``the'' process is.
73 ;;
74 ;; IF   last process started was on a region
75 ;; THEN ``the'' process is the region process
76 ;; ELSE ``the'' process is the master file (of the current buffer) process
77
78 (defun TeX-save-document (name)
79   "Save all files belonging to the current document.
80 Return non-nil if document needs to be re-TeX'ed."
81   (interactive (list (TeX-master-file)))
82   (if (string-equal name "")
83       (setq name (TeX-master-file)))
84
85   (TeX-check-files (concat name "." (TeX-output-extension))
86                    (cons name (TeX-style-list))
87                    TeX-file-extensions))
88
89 (defun TeX-command-master (&optional override-confirm)
90   "Run command on the current document.
91
92 If a prefix argument OVERRIDE-CONFIRM is given, confirmation will
93 depend on it being positive instead of the entry in `TeX-command-list'."
94   (interactive "P")
95   (TeX-command (TeX-command-query (TeX-master-file nil nil t))
96                'TeX-master-file override-confirm))
97
98 (defvar TeX-command-region-begin nil)
99 (defvar TeX-command-region-end nil)
100 ;; Used for marking the last region.
101
102 (make-variable-buffer-local 'TeX-command-region-begin)
103 (make-variable-buffer-local 'TeX-command-region-end)
104
105 (defun TeX-current-offset (&optional pos)
106   "Calculate line offset of POS, or of point if POS is nil."
107   (save-restriction
108     (widen)
109     (save-excursion
110       (let ((inhibit-point-motion-hooks t)
111             (inhibit-field-text-motion t))
112         (if pos (goto-char pos))
113         (+ (count-lines (point-min) (point))
114            (if (bolp) 0 -1))))))
115
116 (defun TeX-pin-region (begin end)
117   "Pin the TeX region specified by BEGIN and END.
118 If BEGIN is nil, the region is unpinned.
119
120 In interactive use, a positive prefix arg will pin the region,
121 a non-positive one will unpin it.  Without a prefix arg, if
122 a region is actively marked, it will get pinned.  If not, a
123 pinned region will get unpinned and vice versa."
124   (interactive
125    (if
126        (if current-prefix-arg
127            (> (prefix-numeric-value current-prefix-arg) 0)
128          (or (TeX-active-mark)
129              (null TeX-command-region-begin)))
130        (list (region-beginning) (region-end))
131      '(nil nil)))
132   (if begin
133       (progn
134         (unless (markerp TeX-command-region-begin)
135           (setq TeX-command-region-begin (make-marker))
136           (setq TeX-command-region-end (make-marker)))
137         (set-marker TeX-command-region-begin begin)
138         (set-marker TeX-command-region-end end)
139         (message "TeX region pinned."))
140     (when (markerp TeX-command-region-begin)
141       (set-marker TeX-command-region-begin nil)
142       (set-marker TeX-command-region-end nil))
143     (setq TeX-command-region-begin nil)
144     (setq TeX-command-region-end nil)
145     (message "TeX region unpinned.")))
146
147 (defun TeX-region-update ()
148   "Update the TeX-region file."
149   ;; Note that TeX-command-region-begin is not a marker when called
150   ;; from TeX-command-buffer.
151   (and (or (null TeX-command-region-begin)
152            (markerp TeX-command-region-begin))
153        (TeX-active-mark)
154        (TeX-pin-region (region-beginning) (region-end)))
155   (let ((begin (or TeX-command-region-begin (region-beginning)))
156         (end (or TeX-command-region-end (region-end))))
157     (TeX-region-create (TeX-region-file TeX-default-extension)
158                        (buffer-substring begin end)
159                        (file-name-nondirectory (buffer-file-name))
160                        (TeX-current-offset begin))))
161
162 (defun TeX-command-region (&optional override-confirm)
163   "Run TeX on the current region.
164
165 Query the user for a command to run on the temporary file specified by
166 the variable `TeX-region'.  If there is an explicitly active region,
167 it is stored for later commands.  If not, a previously stored region
168 \(can be also be set with `TeX-pin-region') overrides the current region,
169 if present.
170
171 If a prefix argument OVERRIDE-CONFIRM is given, prompting will
172 ignore the prompting flag from `TeX-command-list' and instead
173 will prompt iff the prefix is positive.
174
175 If the master file for the document has a header, it is written to the
176 temporary file before the region itself.  The document's header is all
177 text before `TeX-header-end'.
178
179 If the master file for the document has a trailer, it is written to
180 the temporary file after the region itself.  The document's trailer is
181 all text after `TeX-trailer-start'."
182   (interactive "P")
183   (TeX-region-update)
184   ;; In the next line, `TeX-region-file' should be called with nil
185   ;; `nondirectory' argument, otherwise `TeX-comand-default' called
186   ;; within `TeX-command-query' won't work in included files not
187   ;; placed in `TeX-master-directory'.
188   (TeX-command (TeX-command-query (TeX-region-file)) 'TeX-region-file
189                override-confirm))
190
191 (defun TeX-command-buffer (&optional override-confirm)
192   "Run TeX on the current buffer.
193
194 Query the user for a command to run on the temporary file specified by
195 the variable `TeX-region'.  The region file will be recreated from the
196 visible part of the buffer.
197
198 If a prefix argument OVERRIDE-CONFIRM is given, confirmation will
199 depend on it being positive instead of the entry in `TeX-command-list'."
200   (interactive "P")
201   (let ((TeX-command-region-begin (point-min))
202         (TeX-command-region-end (point-max)))
203     (TeX-command-region override-confirm)))
204
205 (unless (featurep 'xemacs)
206   ;; This variable is not defined in XEmacs because XEmacs' version of
207   ;; `pop-to-buffer' doesn't support the optional NORECORD argument.  In
208   ;; XEmacs, the third arg is ON-FRAME (Emacs: NORECORD).
209   (defcustom TeX-record-buffer nil
210     "Whether to record buffer names of generated TeX buffers.
211 When non-nil, these buffers are put at the front of the list of
212 recently selected ones."
213     :group 'TeX-command
214     :type 'boolean))
215
216 (defun TeX-pop-to-buffer (buffer &optional other-window norecord)
217   "Compatibility wrapper for `pop-to-buffer'.
218
219 Select buffer BUFFER in some window, preferably a different one.
220 BUFFER may be a buffer, a string (a buffer name), or nil.
221 If BUFFER is a string which is not the name of an existing buffer,
222 then this function creates a buffer with that name.
223 If BUFFER is nil, then it chooses some other buffer.
224 If `pop-up-windows' is non-nil, windows can be split to do this.
225 If optional second arg OTHER-WINDOW is non-nil, insist on finding another
226 window even if BUFFER is already visible in the selected window,
227 and ignore `same-window-regexps' and `same-window-buffer-names'.
228 This function returns the buffer it switched to.
229 This uses the function `display-buffer' as a subroutine; see the documentation
230 of `display-buffer' for additional customization information.
231
232 Optional third arg NORECORD non-nil means do not put this buffer
233 at the front of the list of recently selected ones.
234
235 NORECORD is ignored in XEmacs."
236   ;; Make sure not to use third arg in XEmacs.  In XEmacs, the third arg is
237   ;; ON-FRAME (Emacs: NORECORD), so we set it to nil.
238   (pop-to-buffer buffer other-window (and norecord
239                                           (boundp 'TeX-record-buffer)
240                                           TeX-record-buffer)))
241
242 (defun TeX-recenter-output-buffer (line)
243   "Redisplay buffer of TeX job output so that most recent output can be seen.
244 The last line of the buffer is displayed on line LINE of the window, or
245 at bottom if LINE is nil."
246   (interactive "P")
247   (let ((buffer (TeX-active-buffer)))
248     (if buffer
249         (let ((old-buffer (current-buffer)))
250           (TeX-pop-to-buffer buffer t t)
251           (bury-buffer buffer)
252           (goto-char (point-max))
253           (recenter (if line
254                         (prefix-numeric-value line)
255                       (/ (window-height) 2)))
256           (TeX-pop-to-buffer old-buffer nil t))
257       (message "No process for this document."))))
258
259 (defun TeX-kill-job ()
260   "Kill the currently running TeX job."
261   (interactive)
262   (let ((process (TeX-active-process)))
263     (if process
264         (kill-process process)
265       ;; Should test for TeX background process here.
266       (error "No TeX process to kill"))))
267
268 ;; FIXME: The vars below are defined in this file, but they're defined too
269 ;; far down (i.e. further down than their first use), so we have to pre-declare
270 ;; them here to explain it to the compiler.
271 ;; We should move those vars's definitions earlier instead!
272 (defvar TeX-current-process-region-p)
273 (defvar TeX-save-query)
274 (defvar TeX-parse-function)
275 (defvar TeX-sentinel-function)
276 (defvar TeX-sentinel-default-function)
277 (defvar compilation-in-progress)
278 (defvar TeX-current-page)
279 (defvar TeX-error-overview-open-after-TeX-run)
280 (defvar TeX-error-list)
281 (defvar TeX-parse-all-errors)
282 (defvar TeX-command-buffer)
283 (defvar TeX-region)
284
285 (defun TeX-home-buffer ()
286   "Go to the buffer where you last issued a TeX command.
287 If there is no such buffer, or you already are in that buffer, find
288 the master file."
289   (interactive)
290   (if (or (null TeX-command-buffer)
291           (null (buffer-name TeX-command-buffer))
292           (eq TeX-command-buffer (current-buffer)))
293       (find-file (TeX-master-file TeX-default-extension))
294     (switch-to-buffer TeX-command-buffer)))
295
296 (defvar TeX-error-last-visited -1
297   "Index of the last visited error listed in `TeX-error-list'.
298
299 This variable is intended to be set only in output buffer so it
300 will be shared among all files of the same document.")
301 (make-variable-buffer-local 'TeX-error-last-visited)
302
303 (defun TeX-get-parse-function ()
304   "Get the parse function for the current buffer."
305   (with-current-buffer TeX-command-buffer
306     (TeX-process-get-variable (TeX-active-master) 'TeX-parse-function)))
307
308 (defun TeX-next-error (&optional arg reparse)
309   "Find the next error in the TeX output buffer.
310
311 A prefix ARG specifies how many error messages to move;
312 negative means move back to previous error messages, if possible.
313
314 If REPARSE is non-nil, reparse the error message buffer.
315
316 \\[universal-argument] as a prefix means reparse the error
317 message buffer and start at the first error."
318   (interactive "P")
319   (if (or (null (TeX-active-buffer))
320           (eq 'compilation-mode (with-current-buffer TeX-command-buffer
321                                   major-mode)))
322       (if (featurep 'xemacs)
323           (next-error arg)
324         (next-error arg reparse))
325
326     ;; Force reparsing when the function is called with a universal-argument.
327     (if (consp arg) (setq reparse t arg nil))
328
329     (funcall (TeX-get-parse-function) arg reparse)))
330
331 (defun TeX-previous-error (arg)
332   "Find the previous error in the TeX output buffer.
333
334 Prefix arg N says how many error messages to move backward (or
335 forward, if negative).
336
337 This works only with TeX commands and if the
338 `TeX-parse-all-errors' variable is non-nil."
339   (interactive "p")
340   (if (or (null (TeX-active-buffer))
341           (eq 'compilation-mode (with-current-buffer TeX-command-buffer
342                                   major-mode)))
343       (previous-error arg)
344
345     (let ((parse-function (TeX-get-parse-function)))
346       (if (and TeX-parse-all-errors (equal parse-function #'TeX-parse-TeX))
347           ;; When `TeX-parse-all-errors' is non-nil and the parsing function is
348           ;; `TeX-parse-TeX' we can move backward in the errors.
349           (TeX-parse-TeX (- arg) nil)
350         ;; XXX: moving backward in the errors hasn't yet been implemented for
351         ;; other parsing functions.
352         (error "Jumping to previous error not supported")))))
353
354 ;;; Command Query
355
356 (defvar TeX-error-overview-frame nil
357   "The frame of the error overview.")
358
359 (defconst TeX-error-overview-buffer-name "*TeX errors*"
360   "Name of the buffer in which to show error list.")
361
362 (defvar LaTeX-idx-md5-alist nil
363   "Alist of MD5 hashes of idx file.
364
365 Car is the idx file, cdr is its md5 hash.")
366
367 (defvar LaTeX-idx-changed-alist nil
368   "Whether the idx files changed.
369
370 Car is the idx file, cdr is whether idx changed after LaTeX
371 run.")
372
373 (defcustom TeX-check-engine t
374   "Whether AUCTeX should check the correct engine has been set before running LaTeX commands."
375   :group 'TeX-command
376   :type 'boolean)
377
378 (defvar TeX-check-engine-list '(default luatex omega xetex)
379   "List of engines required by the loaded TeX packages.
380
381 Do not set this variable directly, use
382 `TeX-check-engine-add-engines' to specify required engines.")
383 (make-variable-buffer-local 'TeX-check-engine-list)
384
385 (defun TeX-check-engine-add-engines (&rest engines)
386   "Add ENGINES to list of required engines.
387
388 Set `TeX-check-engine-list' to the intersection between the list
389 itself and the list of provided engines.
390
391 See for example style/fontspec.el"
392   (let ((list TeX-check-engine-list)
393         (res nil))
394     (setq TeX-check-engine-list
395           ;; The following is based on the definition of `cl-intersection' of
396           ;; GNU Emacs.
397           (and list engines
398                (if (equal list engines) list
399                  (or (>= (length list) (length engines))
400                      (setq list (prog1 engines (setq engines list))))
401                  (while engines
402                    (if (memq (car engines) list)
403                        (push (car engines) res))
404                    (pop engines))
405                  res)))))
406
407 (defun TeX-check-engine (name)
408   "Check the correct engine has been set.
409
410 Look into `TeX-check-engine-list' for the required engines.
411
412 NAME is the command to be run.  Actually do the check only if the
413 variable `TeX-check-engine' is non-nil and LaTeX is the command
414 to be run."
415   (and
416    (string= name "LaTeX")
417    TeX-check-engine
418    TeX-check-engine-list
419    (null (memq TeX-engine TeX-check-engine-list))
420    (memq TeX-engine '(default luatex omega xetex))
421    ;; The set engine is not listed in `TeX-check-engine-list'.  We check only
422    ;; builtin engines because we can't take care of custom ones.  Do nothing if
423    ;; there is no allowed engine, we don't know what to do in that case.
424    (let ((length (length TeX-check-engine-list))
425          (name-alist '((default . "TeX")
426                        (luatex  . "LuaTeX")
427                        (omega   . "Omega")
428                        (xetex   . "XeTeX")))
429          (completion-ignore-case t)
430          (engine nil))
431      (when
432          (cond
433           ;; There is exactly one allowed engine.
434           ((= length 1)
435            (setq engine (car TeX-check-engine-list))
436            (y-or-n-p (format "%s is required to build this document.
437 Do you want to use this engine?" (cdr (assoc engine name-alist)))))
438           ;; More than one engine is allowed.
439           ((> length 1)
440            (if (y-or-n-p (format "It appears %s are required to build this document.
441 Do you want to select one of these engines?"
442                                  (mapconcat
443                                   (lambda (elt) (cdr (assoc elt name-alist)))
444                                   TeX-check-engine-list ", ")))
445                (setq engine
446                      (car (rassoc
447                            (completing-read
448                             (format
449                              "Choose between %s: "
450                              (mapconcat
451                               (lambda (elt) (cdr (assoc elt name-alist)))
452                               TeX-check-engine-list ", "))
453                             (mapcar
454                              (lambda (elt) (cdr (assoc elt name-alist)))
455                              TeX-check-engine-list))
456                            name-alist)))
457              ;; Don't keep asking.  If user doesn't want to change engine,
458              ;; probably has a good reason.  In order to do so, without adding
459              ;; yet another variable we just hack `TeX-check-engine-list' and
460              ;; make it nil.
461              (setq TeX-check-engine-list nil))))
462        (TeX-engine-set engine)
463        (when (and (fboundp 'add-file-local-variable)
464                   (y-or-n-p "Do you want to remember the choice?"))
465          (add-file-local-variable 'TeX-engine engine)
466          (save-buffer))))))
467
468 (defcustom TeX-check-TeX t
469   "Whether AUCTeX should check if a working TeX distribution is present."
470   :group 'TeX-command
471   :type 'boolean)
472
473 (defcustom TeX-check-TeX-command-not-found 127
474   "Numerical code returned by shell for a command not found error."
475   :group 'TeX-command
476   :type 'integer)
477
478 (defun TeX-command (name file &optional override-confirm)
479   "Run command NAME on the file returned by calling FILE.
480
481 FILE is the symbol of a function returning a file name.  The
482 function has one optional argument, the extension to use on the
483 file.
484
485 Use the information in `TeX-command-list' to determine how to run
486 the command.
487
488 If OVERRIDE-CONFIRM is a prefix argument, confirmation will be
489 asked if it is positive, and suppressed if it is not.
490
491 Run function `TeX-check-engine' to check the correct engine has
492 been set."
493   (TeX-check-engine name)
494
495   (cond ((eq file #'TeX-region-file)
496          (setq TeX-current-process-region-p t))
497         ((eq file #'TeX-master-file)
498          (setq TeX-current-process-region-p nil)))
499
500   ;; When we're operating on a region, we need to update the position
501   ;; of point in the region file so that forward search works.
502   (if (string= name "View") (TeX-region-update-point))
503
504   (let ((command (TeX-command-expand (nth 1 (assoc name TeX-command-list))
505                                      file))
506         (hook (nth 2 (assoc name TeX-command-list)))
507         (confirm (if override-confirm
508                      (> (prefix-numeric-value override-confirm) 0)
509                    (nth 3 (assoc name TeX-command-list)))))
510
511     ;; Verify the expanded command
512     (if confirm
513         (setq command
514               (read-from-minibuffer (concat name " command: ") command
515                                     nil nil)))
516
517     ;; Kill the frame and buffer associated to the error overview before running
518     ;; the command, but keep them if the command to be run is View.
519     (unless (string= name "View")
520       (if (frame-live-p TeX-error-overview-frame)
521           (delete-frame TeX-error-overview-frame))
522       (if (get-buffer TeX-error-overview-buffer-name)
523           (kill-buffer TeX-error-overview-buffer-name)))
524
525     ;; Before running some commands, check that AUCTeX is able to find "tex"
526     ;; program.
527     (and TeX-check-TeX
528          (member name '("TeX" "LaTeX" "AmSTeX" "ConTeXt" "ConTeXt Full"))
529          (= TeX-check-TeX-command-not-found
530             (call-process TeX-shell nil nil nil
531                           TeX-shell-command-option TeX-command))
532          (error (format "ERROR: AUCTeX cannot find a working TeX distribution.
533 Make sure you have one and that TeX binaries are in PATH environment variable%s"
534                         (if (eq system-type 'darwin)
535                             ".
536 If you are using OS X El Capitan or later
537 remember to add /Library/TeX/texbin/ to your PATH"
538                           ""))))
539
540     ;; Now start the process
541     (setq file (funcall file))
542     (TeX-process-set-variable file 'TeX-command-next TeX-command-Show)
543     (funcall hook name command file)))
544
545 (defvar TeX-command-text)               ;Dynamically scoped.
546 (defvar TeX-command-pos)                ;Dynamically scoped.
547
548 (defun TeX-command-expand (command file &optional list)
549   "Expand COMMAND for FILE as described in LIST.
550 LIST default to `TeX-expand-list'.  As a special exception,
551 `%%' can be used to produce a single `%' sign in the output
552 without further expansion."
553   (defvar TeX-command-pos)
554   (let (pat
555         pos ;;FIXME: Should this be dynamically scoped?
556         entry TeX-command-text TeX-command-pos
557         ;; FIXME: This variable appears to be unused!
558         (file `(lambda (&rest args)
559                  (shell-quote-argument
560                   (concat (and (stringp TeX-command-pos) TeX-command-pos)
561                           (apply #',file args)
562                           (and (stringp TeX-command-pos) TeX-command-pos)))))
563         expansion-res case-fold-search string expansion arguments)
564     ;; Because I can't figure out WTH they're trying to do with `file'
565     ;; up there (it's not used anywhere in the function), Imma just
566     ;; gonna jam this here to shutup the byte-compiler. --SY.
567     (setq file file)
568     (setq list (cons
569                 (list "%%" (lambda nil
570                              (setq pos (1+ pos))
571                              "%"))
572                 (or list (TeX-expand-list)))
573           pat (regexp-opt (mapcar #'car list)))
574     (while (setq pos (string-match pat command pos))
575       (setq string (match-string 0 command)
576             entry (assoc string list)
577             expansion (car (cdr entry)) ;Second element
578             arguments (cdr (cdr entry)) ;Remaining elements
579             string (save-match-data
580                      ;; Note regarding the special casing of `file':
581                      ;; `file' is prevented from being evaluated as a
582                      ;; function because inside of AUCTeX it only has
583                      ;; a meaning as a variable.  This makes sure that
584                      ;; a function definition made by an external
585                      ;; package (e.g. icicles) is not picked up.
586                      (cond ((and (not (eq expansion 'file))
587                                  (functionp expansion))
588                             (apply expansion arguments))
589                            ((boundp expansion)
590                             (setq expansion-res
591                                   (apply (symbol-value expansion) arguments))
592                             (when (eq expansion 'file)
593                               ;; Advance past the file name in order to
594                               ;; prevent expanding any substring of it.
595                               (setq pos (+ pos (length expansion-res))))
596                             expansion-res)
597                            (t
598                             (error "Nonexpansion %s" expansion)))))
599       (if (stringp string)
600           (setq command
601                 (replace-match string t t command)))))
602   command)
603
604 (defun TeX-check-files (derived originals extensions)
605   "Check if DERIVED is newer than any of the ORIGINALS.
606 Try each original with each member of EXTENSIONS, in all directories
607 in `TeX-check-path'.  Returns true if any of the ORIGINALS with any of the
608 EXTENSIONS are newer than DERIVED.  Will prompt to save the buffer of any
609 ORIGINALS which are modified but not saved yet."
610   (let (existingoriginals
611         found
612         (extensions (TeX-delete-duplicate-strings extensions))
613         (buffers (buffer-list)))
614     (dolist (path (TeX-delete-duplicate-strings
615                    (mapcar (lambda (dir)
616                              (expand-file-name (file-name-as-directory dir)))
617                            (append
618                             TeX-check-path
619                             ;; In `TeX-command-default', this function is used to
620                             ;; check whether bibliography databases are newer
621                             ;; than generated *.bbl files, but bibliography
622                             ;; database are relative to `TeX-master-directory'
623                             ;; and the test can be run also from included files
624                             ;; that are in directories different from
625                             ;; `TeX-master-directory'.
626                             (list (TeX-master-directory))))))
627       (dolist (orig originals)
628         (dolist (ext extensions)
629           (let ((filepath (concat path orig "." ext)))
630             (if (or (file-exists-p filepath)
631                     (get-file-buffer filepath))
632                 (setq existingoriginals (cons filepath existingoriginals)))))))
633     (while buffers
634       (let* ((buffer (car buffers))
635              (name (buffer-file-name buffer)))
636         (setq buffers (cdr buffers))
637         (if (and name (member name existingoriginals))
638             (progn
639               (and (buffer-modified-p buffer)
640                    (or (not TeX-save-query)
641                        (y-or-n-p (concat "Save file "
642                                          (buffer-file-name buffer)
643                                          "? ")))
644                    (with-current-buffer buffer (save-buffer)))))))
645     (dolist (eo existingoriginals)
646       (if (file-newer-than-file-p eo derived)
647           (setq found t)))
648     found))
649
650 (defcustom TeX-command-sequence-max-runs-same-command 4
651   "Maximum number of runs of the same command."
652   :type 'integer
653   :group 'TeX-command)
654
655 (defcustom TeX-command-sequence-max-runs 12
656   "Maximum number of total runs."
657   :type 'integer
658   :group 'TeX-command)
659
660 (defvar TeX-command-sequence-count-same-command 1
661   "Counter for the runs of the same command in `TeX-command-sequence'.")
662
663 (defvar TeX-command-sequence-count 1
664   "Counter for the total runs of `TeX-command-sequence'.")
665
666 (defvar TeX-command-sequence-last-command nil
667   "Last command run in `TeX-command-sequence'.")
668
669 (defvar TeX-command-sequence-sentinel nil
670   "Sentinel for `TeX-command-sequence'.")
671
672 (defvar TeX-command-sequence-file-function nil
673   "File function for `TeX-command-sequence'.")
674
675 (defvar TeX-command-sequence-command nil
676   "Command argument for `TeX-command-sequence'.
677
678 It is set in `TeX-command-sequence' and used in
679 `TeX-command-sequence-sentinel' to call again
680 `TeX-command-sequence' with the appropriate command argument.")
681
682 (defun TeX-command-sequence (command &optional reset file-fn)
683   "Run a sequence of TeX commands defined by COMMAND.
684
685 The COMMAND argument may be
686
687   * nil: no command will be run in this case
688
689   * a string with a command from `TeX-command-list'
690
691   * a non-nil list of strings, which are commands from
692     `TeX-command-list'; the car of the list is used as command to
693     be executed in the first run of `TeX-command-sequence', the
694     cdr of the list will be passed to the function in the next
695     run, etc.
696
697   * a function name, returning a string which is command from
698     `TeX-command-list'; it will be funcall'd (without arguments!)
699     and used again in the next run of `TeX-command-sequence'.
700
701   * with any other value the function `TeX-command-default' is
702     used to determine the command to run, until a stopping
703     condition is met.
704
705 This function runs at most
706 `TeX-command-sequence-max-runs-same-command' times the same
707 command in a row, and `TeX-command-sequence-max-runs' times in
708 total in any case.  It ends when `TeX-command-Show' is the
709 command to be run.
710
711 A non-nil value for the optional argument RESET means this is the
712 first run of the function and some variables need to be reset.
713
714 FILE-FN is a function of zero arguments returning the current
715 filename.  Valid choices are `TeX-master-file' (default if
716 omitted) and `TeX-region-file'."
717   (setq TeX-command-sequence-file-function (or file-fn #'TeX-master-file))
718   (if (null command)
719       (message "No command to run.")
720     (let (cmd process)
721       (cond
722        ((stringp command)
723         (setq cmd command
724               TeX-command-sequence-command nil))
725        ((listp command)
726         (setq cmd (pop command)
727               TeX-command-sequence-command command))
728        ((functionp command)
729         (setq cmd (funcall command)
730               TeX-command-sequence-command command))
731        (t
732         (setq cmd (TeX-command-default
733                    ;; File function should be called with nil `nondirectory'
734                    ;; argument, otherwise `TeX-command-sequence' won't work in
735                    ;; included files not placed in `TeX-master-directory'.  In
736                    ;; addition, `TeX-master-file' is called with the third
737                    ;; argument (`ask') set to t, so that the master file is
738                    ;; properly set.  This is also what `TeX-command-master'
739                    ;; does.
740                    (funcall TeX-command-sequence-file-function nil nil t))
741               TeX-command-sequence-command t)))
742       (TeX-command cmd TeX-command-sequence-file-function 0)
743       (when reset
744         (setq TeX-command-sequence-count-same-command 1
745               TeX-command-sequence-count 1
746               TeX-command-sequence-last-command nil))
747       (cond
748        ;; Stop when the same command has been run
749        ;; `TeX-command-sequence-max-runs-same-command' times in a row.
750        ((>= TeX-command-sequence-count-same-command
751             TeX-command-sequence-max-runs-same-command)
752         (message "Stopping after running %S %d times in a row."
753                  TeX-command-sequence-last-command
754                  TeX-command-sequence-count-same-command))
755        ;; Stop when there have been `TeX-command-sequence-max-runs' total
756        ;; compilations.
757        ((>= TeX-command-sequence-count TeX-command-sequence-max-runs)
758         (message "Stopping after %d compilations." TeX-command-sequence-count))
759        ;; The command just run is `TeX-command-Show'.
760        ((equal command TeX-command-Show))
761        ;; In any other case continue: increase counters (when needed), update
762        ;; `TeX-command-sequence-last-command' and run the sentinel.
763        (t
764         (if (equal cmd TeX-command-sequence-last-command)
765             (setq TeX-command-sequence-count-same-command
766                   (1+ TeX-command-sequence-count-same-command))
767           (setq TeX-command-sequence-count-same-command 1))
768         (setq TeX-command-sequence-count (1+ TeX-command-sequence-count)
769               TeX-command-sequence-last-command cmd)
770         (and (setq process (get-buffer-process (current-buffer)))
771              (setq TeX-command-sequence-sentinel (process-sentinel process))
772              (set-process-sentinel process
773                                    #'TeX-command-sequence-sentinel)))))))
774
775 (defcustom TeX-save-query t
776   "*If non-nil, ask user for permission to save files before starting TeX."
777   :group 'TeX-command
778   :type 'boolean)
779
780 (defvar TeX-command-history nil)
781
782 (defun TeX-command-default (name)
783   "Guess the next command to be run on NAME."
784   (let ((command-next nil))
785     (cond (;; name might be absolute or relative, so expand it for
786            ;; comparison.
787            (if (string-equal (expand-file-name name)
788                              (expand-file-name (TeX-region-file)))
789                (TeX-check-files (concat name "." (TeX-output-extension))
790                                 ;; Each original will be checked for all dirs
791                                 ;; in `TeX-check-path' so this needs to be just
792                                 ;; a filename without directory.
793                                 (list (file-name-nondirectory name))
794                                 TeX-file-extensions)
795              (TeX-save-document (TeX-master-file)))
796            TeX-command-default)
797           ((and (memq major-mode '(doctex-mode latex-mode))
798                 ;; Want to know if bib file is newer than .bbl
799                 ;; We don't care whether the bib files are open in emacs
800                 (TeX-check-files (concat name ".bbl")
801                                  (mapcar #'car
802                                          (LaTeX-bibliography-list))
803                                  (append BibTeX-file-extensions
804                                          TeX-Biber-file-extensions)))
805            ;; We should check for bst files here as well.
806            (if LaTeX-using-Biber TeX-command-Biber TeX-command-BibTeX))
807           ((and
808             ;; Rationale: makeindex should be run when final document is almost
809             ;; complete (see
810             ;; http://tex.blogoverflow.com/2012/09/dont-forget-to-run-makeindex/),
811             ;; otherwise, after following latex runs, index pages may change due
812             ;; to changes in final document, resulting in extra makeindex and
813             ;; latex runs.
814             (member
815              (setq command-next
816                    (TeX-process-get-variable
817                     name
818                     'TeX-command-next
819                     (or (and TeX-PDF-mode (TeX-PDF-from-DVI))
820                         TeX-command-Show)))
821              (list "Dvips" "Dvipdfmx" TeX-command-Show))
822             (cdr (assoc (expand-file-name (concat name ".idx"))
823                         LaTeX-idx-changed-alist)))
824            "Index")
825           (command-next)
826           (TeX-command-Show))))
827
828 (defun TeX-command-query (name)
829   "Query the user for what TeX command to use."
830   (let* ((default (TeX-command-default name))
831          (completion-ignore-case t)
832          (answer (or TeX-command-force
833                      (completing-read
834                       (concat "Command (default " default "): ")
835                       (TeX-mode-specific-command-list major-mode) nil t
836                       nil 'TeX-command-history default))))
837     ;; If the answer is "latex" it will not be expanded to "LaTeX"
838     (setq answer (car-safe (TeX-assoc answer TeX-command-list)))
839     (if (and answer
840              (not (string-equal answer "")))
841         answer
842       default)))
843
844 (defvar TeX-command-next nil
845   "The default command next time `TeX-command' is invoked.")
846
847  (make-variable-buffer-local 'TeX-command-next)
848
849 (defun TeX-printer-query (&optional queue)
850   "Query the user for a printer name.
851 QUEUE is non-nil when we are checking for the printer queue."
852   (let (command element printer)
853     (if queue
854         (unless (setq element 2 command TeX-queue-command)
855           (error "Need to customize `TeX-queue-command'"))
856       (unless (setq element 1 command TeX-print-command)
857           (error "Need to customize `TeX-print-command'")))
858     (while (progn
859              (setq printer (if TeX-printer-list
860                                (let ((completion-ignore-case t))
861                                  (completing-read
862                                   (format "Printer%s: "
863                                           (if TeX-printer-default
864                                               (format " (default %s)" TeX-printer-default) ""))
865                                   TeX-printer-list))
866                              ""))
867              (setq printer (or (car-safe (TeX-assoc printer TeX-printer-list))
868                                printer))
869              (not (if (or (null printer) (string-equal "" printer))
870                       (setq printer TeX-printer-default)
871                     (setq TeX-printer-default printer)))))
872
873     (let ((expansion (let ((entry (assoc printer TeX-printer-list)))
874                        (or (nth element entry)
875                            command))))
876       (if (string-match "%p" printer)
877           (error "Don't use %s in printer names" "%p"))
878       (while (string-match "%p" expansion)
879         (setq expansion (replace-match printer t t expansion 0)))
880       expansion)))
881
882 (defun TeX-style-check (styles)
883   "Check STYLES compared to the current style options."
884   (let ((files (TeX-style-list)))
885     (while (and styles
886                 (not (TeX-member (car (car styles)) files 'string-match)))
887       (setq styles (cdr styles))))
888   (if styles
889       (nth 1 (car styles))
890     ""))
891
892 (defun TeX-output-extension ()
893   "Get the extension of the current TeX output file."
894   (if (listp TeX-output-extension)
895       (car TeX-output-extension)
896     (or (TeX-process-get-variable (TeX-active-master)
897                                   'TeX-output-extension
898                                   TeX-output-extension)
899         TeX-output-extension)))
900
901 (defun TeX-view-mouse (event)
902   "Start `TeX-view' at mouse position."
903   (interactive "e")
904   (with-current-buffer (window-buffer (posn-window (event-start event)))
905     (goto-char (posn-point (event-start event)))
906     (TeX-view)))
907
908 (defun TeX-region-update-point ()
909   "Syncs the location of point in the region file with the current file.
910
911 Thereafter, point in the region file is on the same text as in
912 the current buffer.
913
914 Do nothing in case the last command hasn't operated on the region
915 or `TeX-source-correlate-mode' is disabled."
916   (when (and TeX-current-process-region-p TeX-source-correlate-mode)
917     (let ((region-buf (get-file-buffer (TeX-region-file t)))
918           (orig-line (TeX-current-offset))
919           (pos-in-line (- (point) (max (line-beginning-position)
920                                        (or TeX-command-region-begin
921                                            (region-beginning))))))
922       (when region-buf
923         (with-current-buffer region-buf
924           (goto-char (point-min))
925           (when (re-search-forward "!offset(\\(-?[0-9]+\\)" nil t)
926             (let ((offset (string-to-number (match-string 1))))
927               (goto-char (point-min))
928               (forward-line (- orig-line offset))
929               (forward-char pos-in-line))))))))
930
931 (defun TeX-view ()
932   "Start a viewer without confirmation.
933 The viewer is started either on region or master file,
934 depending on the last command issued."
935   (interactive)
936   (let ((output-file (TeX-active-master (TeX-output-extension))))
937     (if (file-exists-p output-file)
938         (TeX-command "View" 'TeX-active-master 0)
939       (message "Output file %S does not exist." output-file))))
940
941 (defun TeX-output-style-check (styles)
942   "Check STYLES compared to the current view output file extension and
943 the current style options."
944   (let ((ext  (TeX-output-extension))
945         (files (TeX-style-list)))
946     (while (and
947             styles
948             (or
949              (not (string-match (car (car styles)) ext))
950              (let ((style (nth 1 (car styles))))
951                (cond
952                 ((listp style)
953                  (while
954                      (and style
955                           (TeX-member (car style) files 'string-match))
956                    (setq style (cdr style)))
957                  style)
958                 ((not (TeX-member style files 'string-match)))))))
959       (setq styles (cdr styles)))
960     (if styles
961         (nth 2 (car styles))
962       "%v")))
963
964 ;;; Command Hooks
965
966 (defvar TeX-after-compilation-finished-functions nil
967   "Hook being run after TeX/LaTeX/ConTeXt finished successfully.
968 The functions in this hook are run with the DVI/PDF output file
969 given as argument.  Using this hook can be useful for updating
970 the viewer automatically after re-compilation of the document.
971
972 If you use an emacs-internal viewer such as `doc-view-mode' or
973 `pdf-view-mode', add `TeX-revert-document-buffer' to this hook.")
974
975 (make-obsolete-variable 'TeX-after-TeX-LaTeX-command-finished-hook
976                         'TeX-after-compilation-finished-functions
977                         "11.89")
978
979 (defun TeX-revert-document-buffer (file)
980   "Revert the buffer visiting FILE.
981 This function is intended to be used in
982 `TeX-after-compilation-finished-functions' for users that view
983 their compiled document with an emacs viewer such as
984 `doc-view-mode' or `pdf-view-mode'.  (Note that this function
985 just calls `revert-buffer' in the respective buffer and thus
986 requires that the corresponding mode defines a sensible
987 `revert-buffer-function'.)"
988   (let ((buf (find-buffer-visiting file)))
989     (when buf
990       (with-current-buffer buf
991         (revert-buffer nil t t)))))
992
993 (defvar TeX-after-start-process-function
994   #'TeX-adjust-process-coding-system
995   "Function to adjust coding system of an asynchronous process.
996 Called with one argument PROCESS.")
997
998 (defun TeX-adjust-process-coding-system (process)
999   "Adjust coding system of PROCESS to suitable value.
1000 Usually coding system is the same as the TeX file with eol format
1001 adjusted to OS default value.  Take care of Japanese TeX, which
1002 requires special treatment."
1003   (when (featurep 'mule)
1004     (if (and (boundp 'japanese-TeX-mode)
1005              (fboundp 'japanese-TeX-set-process-coding-system)
1006              (with-current-buffer TeX-command-buffer
1007                japanese-TeX-mode))
1008         (japanese-TeX-set-process-coding-system process)
1009       (let ((cs (with-current-buffer TeX-command-buffer
1010                   buffer-file-coding-system)))
1011         ;; The value of `buffer-file-coding-system' is sometimes
1012         ;; undecided-{unix,dos,mac}.  That happens when the file
1013         ;; contains no multibyte chars and only end of line format is
1014         ;; determined.  Emacs lisp reference recommends not to use
1015         ;; undecided-* for process coding system, so it might seem
1016         ;; reasonable to change undecided-* to some fixed coding
1017         ;; system like this:
1018         ;; (if (eq 'undecided (coding-sytem-type cs))
1019         ;;     (setq cs 'utf-8))
1020         ;; However, that can lose when the following conditions are
1021         ;; met:
1022         ;; (1) The document is divided into multiple files.
1023         ;; (2) The command buffer contains no multibyte chars.
1024         ;; (3) The other files contain mutlibyte chars and saved in
1025         ;;     a coding system other than the coding system chosen
1026         ;;     above.
1027         ;; So we leave undecided-* unchanged here.  Although
1028         ;; undecided-* is not quite safe for the coding system for
1029         ;; encoding, i.e., keyboard input to the TeX process, we
1030         ;; expect that this does not raise serious problems because it
1031         ;; is pretty rare that TeX process needs keyboard input of
1032         ;; multibyte chars.
1033
1034         ;; Eol format of TeX files can differ from OS default. TeX
1035         ;; binaries accept all type of eol format in the given files
1036         ;; and output messages according to OS default.  So we set eol
1037         ;; format to OS default value.
1038         (setq cs (coding-system-change-eol-conversion
1039                   cs
1040                   ;; The eol of macosX is LF, not CR.  So we choose
1041                   ;; other than `unix' only for w32 system.
1042                   ;; FIXME: what should we do for cygwin?
1043                   (if (eq system-type 'windows-nt) 'dos 'unix)))
1044         (set-process-coding-system process cs cs)))))
1045
1046 (defcustom TeX-show-compilation nil
1047   "*If non-nil, show output of TeX compilation in other window."
1048   :group 'TeX-command
1049   :type 'boolean)
1050
1051 (defun TeX-run-command (name command file)
1052   "Create a process for NAME using COMMAND to process FILE.
1053 Return the new process."
1054   (let ((default TeX-command-default)
1055         (buffer (TeX-process-buffer-name file))
1056         (dir (TeX-master-directory))
1057         (command-buff (current-buffer)))
1058     (TeX-process-check file)            ; Check that no process is running
1059     (setq-default TeX-command-buffer command-buff)
1060     (get-buffer-create buffer)
1061     (set-buffer buffer)
1062     (buffer-disable-undo)
1063     (erase-buffer)
1064     (set (make-local-variable 'line-number-display-limit) 0)
1065     (setq TeX-output-extension nil)
1066     (set (make-local-variable 'TeX-command-buffer) command-buff)
1067     (if dir (cd dir))
1068     (insert "Running `" name "' on `" file "' with ``" command "''\n")
1069     (TeX-output-mode)
1070     (if TeX-show-compilation
1071         (display-buffer buffer)
1072       (message "Type `%s' to display results of compilation."
1073                (substitute-command-keys
1074                 "\\<TeX-mode-map>\\[TeX-recenter-output-buffer]")))
1075     (setq TeX-parse-function #'TeX-parse-command)
1076     (setq TeX-command-default default)
1077     (setq TeX-sentinel-function
1078           (lambda (_process name)
1079             (message (concat name ": done."))))
1080     (if TeX-process-asynchronous
1081         (let ((process (start-process name buffer TeX-shell
1082                                       TeX-shell-command-option command)))
1083           (if TeX-after-start-process-function
1084               (funcall TeX-after-start-process-function process))
1085           (TeX-command-mode-line process)
1086           (set-process-filter process #'TeX-command-filter)
1087           (set-process-sentinel process #'TeX-command-sentinel)
1088           (set-marker (process-mark process) (point-max))
1089           (setq compilation-in-progress (cons process compilation-in-progress))
1090           process)
1091       (setq mode-line-process ": run")
1092       (set-buffer-modified-p (buffer-modified-p))
1093       (sit-for 0)                               ; redisplay
1094       (call-process TeX-shell nil buffer nil
1095                     TeX-shell-command-option command))))
1096
1097 (defun TeX-run-set-command (name command)
1098   "Remember TeX command to use to NAME and set corresponding output extension."
1099   (setq TeX-command-default name
1100         TeX-output-extension
1101         (if (and (null (TeX-PDF-from-DVI)) TeX-PDF-mode) "pdf" "dvi"))
1102   (let ((case-fold-search t)
1103         (lst TeX-command-output-list))
1104     (while lst
1105       (if (string-match (car (car lst)) command)
1106           (setq TeX-output-extension (car (cdr (car lst)))
1107                 lst nil)
1108         (setq lst (cdr lst))))))
1109
1110 (defun TeX-run-format (name command file)
1111   "Create a process for NAME using COMMAND to format FILE with TeX."
1112   (TeX-run-set-command name command)
1113   (let ((buffer (TeX-process-buffer-name file))
1114         (process (TeX-run-command name command file)))
1115     ;; Hook to TeX debugger.
1116     (with-current-buffer buffer
1117       (TeX-parse-reset)
1118       (setq TeX-parse-function #'TeX-parse-TeX)
1119       (setq TeX-sentinel-function #'TeX-TeX-sentinel)
1120       (if TeX-process-asynchronous
1121           (progn
1122             ;; Updating the mode line.
1123             (setq TeX-current-page "[0]")
1124             (TeX-format-mode-line process)
1125             (set-process-filter process #'TeX-format-filter)))
1126       process)))
1127
1128 (defvar TeX-error-report-switches nil
1129   "Reports presence of errors after `TeX-run-TeX'.
1130 To test whether the current buffer has a compile error from last
1131 run of `TeX-run-TeX', use
1132   (TeX-error-report-has-errors-p)")
1133
1134 (defun TeX-error-report-has-errors-p ()
1135   "Return non-nil if current buffer has compile errors from last TeX run."
1136   (plist-get TeX-error-report-switches (intern (TeX-master-file))))
1137
1138 (defun TeX-run-TeX (name command file)
1139   "Create a process for NAME using COMMAND to format FILE with TeX."
1140
1141   ;; Save information in TeX-error-report-switches
1142   ;; Initialize error to nil (no error) for current master.
1143   ;; Presence of error is reported inside `TeX-TeX-sentinel-check'
1144   (let ((current-master (TeX-master-file))
1145         (idx-file nil) (element nil))
1146     ;; the current master file is saved because error routines are
1147     ;; parsed in other buffers;
1148     (setq TeX-error-report-switches
1149           (plist-put TeX-error-report-switches
1150                      'TeX-current-master current-master))
1151     ;; reset error to nil (no error)
1152     (setq TeX-error-report-switches
1153           (plist-put TeX-error-report-switches
1154                      (intern current-master) nil))
1155
1156     ;; Store md5 hash of the index file before running LaTeX.
1157     (and (memq major-mode '(doctex-mode latex-mode))
1158          (prog1 (file-exists-p
1159                  (setq idx-file (expand-file-name (concat file ".idx"))))
1160            ;; In order to avoid confusion and pollution of
1161            ;; `LaTeX-idx-md5-alist', remove from this alist all md5 hashes of
1162            ;; the current index file.  Note `assq-delete-all' doesn't work with
1163            ;; string keys and has problems with non-list elements in Emacs 21
1164            ;; (see file tex-site.el).
1165            (while (setq element (assoc idx-file LaTeX-idx-md5-alist))
1166              (setq LaTeX-idx-md5-alist (delq element LaTeX-idx-md5-alist))))
1167          (with-temp-buffer
1168            (insert-file-contents idx-file)
1169            (push (cons idx-file (md5 (current-buffer))) LaTeX-idx-md5-alist))))
1170
1171   ;; can we assume that TeX-sentinel-function will not be changed
1172   ;; during (TeX-run-format ..)? --pg
1173   ;; rather use let* ? --pg
1174
1175   (if TeX-interactive-mode
1176       (TeX-run-interactive name command file)
1177     (let* ((sentinel-function TeX-sentinel-default-function)
1178            (process (TeX-run-format name command file)))
1179       (setq TeX-sentinel-function sentinel-function)
1180       (if TeX-process-asynchronous
1181           process
1182         (TeX-synchronous-sentinel name file process)))))
1183
1184 ;; backward compatibilty
1185
1186 (defalias 'TeX-run-LaTeX 'TeX-run-TeX)
1187
1188
1189 (defun TeX-run-BibTeX (name command file)
1190   "Create a process for NAME using COMMAND to format FILE with BibTeX."
1191   (let ((process (TeX-run-command name command file)))
1192     (setq TeX-sentinel-function #'TeX-BibTeX-sentinel)
1193     (if TeX-process-asynchronous
1194         process
1195       (TeX-synchronous-sentinel name file process))))
1196
1197 (defun TeX-run-Biber (name command file)
1198   "Create a process for NAME using COMMAND to format FILE with Biber."
1199   (let ((process (TeX-run-command name command file)))
1200     (setq TeX-sentinel-function #'TeX-Biber-sentinel)
1201     (if TeX-process-asynchronous
1202         process
1203       (TeX-synchronous-sentinel name file process))))
1204
1205 (defun TeX-run-dvips (name command file)
1206   "Create a process for NAME using COMMAND to convert FILE with dvips."
1207   (let ((process (TeX-run-command name command file)))
1208     (setq TeX-sentinel-function #'TeX-dvips-sentinel)
1209     (if TeX-process-asynchronous
1210         process
1211       (TeX-synchronous-sentinel name file process))))
1212
1213 (defun TeX-run-dvipdfmx (name command file)
1214   "Create a process for NAME using COMMAND to convert FILE with dvipdfmx."
1215   (let ((process (TeX-run-command name command file)))
1216     (setq TeX-sentinel-function #'TeX-dvipdfmx-sentinel)
1217     (if TeX-process-asynchronous
1218         process
1219       (TeX-synchronous-sentinel name file process))))
1220
1221 (defun TeX-run-ps2pdf (name command file)
1222   "Create a process for NAME using COMMAND to convert FILE with ps2pdf."
1223   (let ((process (TeX-run-command name command file)))
1224     (setq TeX-sentinel-function #'TeX-ps2pdf-sentinel)
1225     (if TeX-process-asynchronous
1226         process
1227       (TeX-synchronous-sentinel name file process))))
1228
1229 (defun TeX-run-index (name command file)
1230   "Create a process for NAME using COMMAND to compile the index file."
1231   (let ((process (TeX-run-command name command file))
1232         (element nil))
1233     (setq TeX-sentinel-function #'TeX-index-sentinel)
1234     ;; Same cleaning as that for `LaTeX-idx-md5-alist' in `TeX-run-TeX'.
1235     (while (setq element
1236                  ;; `file' has been determined in `TeX-command-buffer', while
1237                  ;; this function has `TeX-master-directory' as
1238                  ;; `default-directory', then we have to expand `file' file-name
1239                  ;; in the same directory of `TeX-command-buffer'.
1240                  (assoc (with-current-buffer TeX-command-buffer
1241                             (expand-file-name (concat file ".idx")))
1242                         LaTeX-idx-changed-alist))
1243       (setq LaTeX-idx-changed-alist (delq element LaTeX-idx-changed-alist)))
1244     (if TeX-process-asynchronous
1245         process
1246       (TeX-synchronous-sentinel name file process))))
1247
1248 (defun TeX-run-compile (_name command _file)
1249   "Ignore first and third argument, start compile with second argument."
1250   (let ((default-directory (TeX-master-directory)))
1251     (setq TeX-command-buffer (compile command))))
1252
1253 (defun TeX-run-shell (_name command _file)
1254   "Ignore first and third argument, start shell-command with second argument."
1255   (let ((default-directory (TeX-master-directory)))
1256     (shell-command command)
1257     (if (eq system-type 'ms-dos)
1258         (redraw-display))))
1259
1260 (defun TeX-run-discard (_name command _file)
1261   "Start COMMAND as process, discarding its output.
1262 NAME and FILE are ignored."
1263   (let ((default-directory (TeX-master-directory)))
1264     (call-process TeX-shell
1265                   nil 0 nil
1266                   TeX-shell-command-option
1267                   command)))
1268
1269 (defun TeX-run-discard-foreground (_name command _file)
1270   "Call process with second argument in the foreground, discarding its output.
1271 With support for MS-DOS, especially when dviout is used with PC-9801 series."
1272   (if (and (boundp 'dos-machine-type) (eq dos-machine-type 'pc98)) ;if PC-9801
1273       (send-string-to-terminal "\e[2J")) ; clear screen
1274   (call-process TeX-shell (if (eq system-type 'ms-dos) "con") nil nil
1275                 TeX-shell-command-option command)
1276   (if (eq system-type 'ms-dos)
1277       (redraw-display)))
1278 (defalias 'TeX-run-dviout 'TeX-run-discard-foreground)
1279
1280 (defun TeX-run-background (name command _file)
1281   "Start process with second argument, show output when and if it arrives."
1282   (let ((dir (TeX-master-directory)))
1283     (set-buffer (get-buffer-create "*TeX background*"))
1284     (if dir (cd dir))
1285     (erase-buffer)
1286     (let ((process (start-process (concat name " background")
1287                                   nil TeX-shell
1288                                   TeX-shell-command-option command)))
1289       (if TeX-after-start-process-function
1290           (funcall TeX-after-start-process-function process))
1291       (set-process-filter process #'TeX-background-filter)
1292       (process-kill-without-query process))))
1293
1294 (defun TeX-run-silent (name command _file)
1295   "Start process with second argument."
1296   (let ((dir (TeX-master-directory)))
1297     (set-buffer (get-buffer-create "*TeX silent*"))
1298     (if dir (cd dir))
1299     (erase-buffer)
1300     (let ((process (start-process (concat name " silent")
1301                                   (current-buffer) TeX-shell
1302                                   TeX-shell-command-option command)))
1303       (if TeX-after-start-process-function
1304           (funcall TeX-after-start-process-function process))
1305       (process-kill-without-query process))))
1306
1307 (defun TeX-run-interactive (name command file)
1308   "Run TeX interactively.
1309 Run command in a buffer (in comint-shell-mode) so that it accepts user
1310 interaction. If you return to the file buffer after the TeX run,
1311 Error parsing on \\[next-error] should work with a bit of luck."
1312   (TeX-run-set-command name command)
1313   (require 'comint)
1314   (let ((default TeX-command-default)
1315         (buffer (TeX-process-buffer-name file))
1316         (process nil)
1317         (dir (TeX-master-directory))
1318         (command-buff (current-buffer))
1319         (sentinel-function TeX-sentinel-default-function)) ; inherit from major mode
1320     (TeX-process-check file)            ; Check that no process is running
1321     (setq-default TeX-command-buffer command-buff)
1322     (with-output-to-temp-buffer buffer)
1323     (set-buffer buffer)
1324     (set (make-local-variable 'TeX-command-buffer) command-buff)
1325     (setq buffer-read-only nil)
1326     (if dir (cd dir))
1327     (insert "Running `" name "' on `" file "' with ``" command "''\n")
1328     (comint-exec buffer name TeX-shell nil
1329                  (list TeX-shell-command-option command))
1330     (comint-mode)
1331     (add-hook 'comint-output-filter-functions #'TeX-interactive-goto-prompt)
1332     (setq mode-name name)
1333     (setq TeX-command-default default)
1334     (setq process (get-buffer-process buffer))
1335     (if TeX-after-start-process-function
1336         (funcall TeX-after-start-process-function process))
1337     (TeX-command-mode-line process)
1338     (set-process-sentinel process #'TeX-command-sentinel)
1339     (set-marker (process-mark process) (point-max))
1340     (setq compilation-in-progress (cons process compilation-in-progress))
1341     (TeX-parse-reset)
1342     (setq TeX-parse-function #'TeX-parse-TeX)
1343     ;; use the sentinel-function that the major mode sets, not the LaTeX one
1344     (setq TeX-sentinel-function sentinel-function)))
1345
1346 (defun TeX-run-function (_name command _file)
1347   "Execute Lisp function or function call given as the string COMMAND.
1348 Parameters NAME and FILE are ignored."
1349   (let ((fun (car (read-from-string command))))
1350     (if (functionp fun) (funcall fun) (eval fun))))
1351
1352 (defun TeX-run-discard-or-function (name command file)
1353   "Start COMMAND as process or execute it as a Lisp function.
1354 If run as a process, the output is discarded.  COMMAND is
1355 expected to be a string.  NAME and FILE are ignored."
1356   (if (functionp (car (read-from-string command)))
1357       (TeX-run-function name command file)
1358     (TeX-run-discard name command file)))
1359
1360 (defun TeX-run-ispell-on-document (_command _ignored _name)
1361   "Run ispell on all open files belonging to the current document.
1362 This function is *obsolete* and only here for compatibility
1363 reasons.  Use `TeX-run-function' instead."
1364   (interactive)
1365   (TeX-ispell-document ""))
1366
1367
1368 ;;; Command Sentinels
1369
1370 (defun TeX-synchronous-sentinel (name file result)
1371   "Process TeX command output buffer after the process dies."
1372   (let ((buffer (TeX-process-buffer (file-name-nondirectory file))))
1373     (with-current-buffer buffer
1374
1375       ;; Append post-mortem information to the buffer
1376       (goto-char (point-max))
1377       (insert "\n" mode-name (if (and result (zerop result))
1378                                  " finished" " exited") " at "
1379               (substring (current-time-string) 0 -5))
1380       (setq mode-line-process ": exit")
1381
1382       ;; Do command specific actions.
1383       (setq TeX-command-next TeX-command-Show)
1384       (goto-char (point-min))
1385       (apply TeX-sentinel-function nil name nil)
1386
1387       ;; Force mode line redisplay soon
1388       (set-buffer-modified-p (buffer-modified-p)))))
1389
1390 (defun TeX-command-sentinel (process msg)
1391   "Process TeX command output buffer after the process dies."
1392   ;; Set `TeX-transient-master' here because `preview-parse-messages'
1393   ;; may open files and thereby trigger master file questions which we
1394   ;; don't want and need because we already know the master.  Use
1395   ;; `TeX-master-file' instead of `TeX-active-master' to determine the
1396   ;; master because the region file should never be the master.
1397   (let* ((TeX-transient-master (TeX-master-file))
1398          (buffer (process-buffer process))
1399          (name (process-name process)))
1400     (cond ((null (buffer-name buffer))  ; buffer killed
1401            (set-process-buffer process nil)
1402            (set-process-sentinel process nil))
1403           ((memq (process-status process) '(signal exit))
1404            (with-current-buffer buffer
1405
1406              ;; Append post-mortem information to the buffer
1407              (goto-char (point-max))
1408              (insert-before-markers "\n" mode-name " " msg)
1409              (forward-char -1)
1410              (insert " at "
1411                      (substring (current-time-string) 0 -5))
1412              (forward-char 1)
1413
1414              ;; Do command specific actions.
1415              (TeX-command-mode-line process)
1416              (setq TeX-command-next TeX-command-Show)
1417              (goto-char (point-min))
1418              (apply TeX-sentinel-function process name nil)
1419
1420
1421              ;; If buffer and mode line will show that the process
1422              ;; is dead, we can delete it now.  Otherwise it
1423              ;; will stay around until M-x list-processes.
1424              (delete-process process)
1425
1426              ;; Force mode line redisplay soon
1427              (set-buffer-modified-p (buffer-modified-p))))))
1428   (setq compilation-in-progress (delq process compilation-in-progress)))
1429
1430
1431 (defvar TeX-sentinel-function (lambda (_process _name) nil)
1432   "Hook to cleanup TeX command buffer after temination of PROCESS.
1433 NAME is the name of the process.")
1434
1435 (make-variable-buffer-local 'TeX-sentinel-function)
1436
1437
1438 (defvar TeX-sentinel-default-function (lambda (_process _name) nil)
1439   "Default for `TeX-sentinel-function'.  To be set in major mode.
1440 Hook to cleanup TeX command buffer after temination of PROCESS.
1441 NAME is the name of the process.")
1442
1443 (make-variable-buffer-local 'TeX-sentinel-default-function)
1444
1445 (defun TeX-TeX-sentinel (process name)
1446   "Cleanup TeX output buffer after running TeX.
1447
1448 Parse the output buffer to collect errors and warnings if the
1449 variable `TeX-parse-all-errors' is non-nil.
1450
1451 Open the error overview if
1452 `TeX-error-overview-open-after-TeX-run' is non-nil and there are
1453 errors or warnings to show."
1454   (if (TeX-TeX-sentinel-check process name)
1455       (progn
1456         (if TeX-parse-all-errors
1457             (TeX-parse-all-errors))
1458         (if (and TeX-error-overview-open-after-TeX-run
1459                  (TeX-error-overview-make-entries
1460                   (TeX-master-directory) (TeX-active-buffer)))
1461             (TeX-error-overview)))
1462     (message (concat name ": formatted " (TeX-current-pages)))
1463     (let (dvi2pdf)
1464         (if (with-current-buffer TeX-command-buffer
1465            (and TeX-PDF-mode (setq dvi2pdf (TeX-PDF-from-DVI))))
1466          (setq TeX-command-next dvi2pdf)
1467        (setq TeX-command-next TeX-command-Show)))))
1468
1469 (defun TeX-current-pages ()
1470   "Return string indicating the number of pages formatted."
1471   (cond ((null TeX-current-page)
1472          "some pages")
1473         ((string-match "[^0-9]1[^0-9]" TeX-current-page)
1474          (concat TeX-current-page " page"))
1475         (t
1476          (concat TeX-current-page " pages"))))
1477
1478 (defun TeX-TeX-sentinel-check (process name)
1479   "Cleanup TeX output buffer after running TeX.
1480 Return nil ifs no errors were found."
1481   (save-excursion
1482     (goto-char (point-max))
1483     (cond
1484      ((and (string-match "ConTeXt" name) (boundp 'ConTeXt-Mark-version)
1485            (with-current-buffer TeX-command-buffer
1486              (string= ConTeXt-Mark-version "IV")))
1487       (when (re-search-backward " > result saved in file: \\(.*?\\), " nil t)
1488         (let ((output-file (TeX-match-buffer 1)))
1489           ;; Shave off quotation marks if present.
1490           (when (string-match "\\`\"\\(.*\\)\"\\'" output-file)
1491             (setq output-file (match-string 1 output-file)))
1492           (setq TeX-output-extension
1493                 (if (string-match "\\.\\([^.]*\\)$" output-file)
1494                     (match-string 1 output-file)
1495                   "dvi")))
1496         (if (re-search-forward ", \\([0-9]+\\) shipped pages, " nil t)
1497             (setq TeX-current-page (concat "{" (TeX-match-buffer 1) "}")))))
1498      (t
1499       (if (re-search-backward "^Output written on \\(.*?\\) (\\([0-9]+\\) page"
1500                               nil t)
1501           (let ((output-file (TeX-match-buffer 1)))
1502             (setq TeX-current-page (concat "{" (TeX-match-buffer 2) "}"))
1503             ;; Shave off quotation marks if present.
1504             (when (string-match "\\`\"\\(.*\\)\"\\'" output-file)
1505               (setq output-file (match-string 1 output-file)))
1506             (setq TeX-output-extension
1507                   (if (string-match "\\.\\([^.]*\\)$" output-file)
1508                       (match-string 1 output-file)
1509                     "dvi")))))))
1510   (if process (TeX-format-mode-line process))
1511   (if (re-search-forward "^\\(!\\|.*:[0-9]+:\\) " nil t)
1512       (progn
1513         (message "%s errors in `%s'. Use %s to display." name (buffer-name)
1514                  (substitute-command-keys
1515                   "\\<TeX-mode-map>\\[TeX-next-error]"))
1516         (setq TeX-command-next TeX-command-default)
1517         ;; error reported to TeX-error-report-switches
1518         (setq TeX-error-report-switches
1519               (plist-put TeX-error-report-switches
1520                          (intern (plist-get TeX-error-report-switches
1521                                             'TeX-current-master))
1522                          t))
1523         t)
1524     (let (dvi2pdf)
1525         (if (with-current-buffer TeX-command-buffer
1526            (and TeX-PDF-mode (setq dvi2pdf (TeX-PDF-from-DVI))))
1527          (setq TeX-command-next dvi2pdf)
1528        (setq TeX-command-next TeX-command-Show)))
1529     nil))
1530
1531 ;; This regexp should catch warnings of the type
1532 ;;   LaTeX Warning: ...
1533 ;;   LaTeX Font Warning: ...
1534 ;;   Package xyz123 Warning: ...
1535 ;;   Class xyz123 Warning: ...
1536 (defvar LaTeX-warnings-regexp
1537   "\\(?:LaTeX\\|Class\\|Package\\|\*\\) [-A-Za-z0-9]* ?[Ww]arning:"
1538   "Regexp matching LaTeX warnings.")
1539
1540 (defun TeX-LaTeX-sentinel-has-warnings ()
1541   "Return non-nil, if the output buffer contains warnings.
1542 Warnings can be indicated by LaTeX or packages."
1543   (save-excursion
1544     (goto-char (point-min))
1545     (re-search-forward (concat "^" LaTeX-warnings-regexp) nil t)))
1546
1547 (defun TeX-LaTeX-sentinel-has-bad-boxes ()
1548   "Return non-nil, if LaTeX output indicates overfull or underfull boxes."
1549   (save-excursion
1550     (goto-char (point-min))
1551     (re-search-forward "^\\(Ov\\|Und\\)erfull \\\\" nil t)))
1552
1553 ;; should go into latex.el? --pg
1554 (defun TeX-LaTeX-sentinel (process name)
1555   "Cleanup TeX output buffer after running LaTeX.
1556
1557 Parse the output buffer to collect errors and warnings if the
1558 variable `TeX-parse-all-errors' is non-nil.
1559
1560 Open the error overview if
1561 `TeX-error-overview-open-after-TeX-run' is non-nil and there are
1562 errors or warnings to show."
1563   (if TeX-parse-all-errors
1564       (TeX-parse-all-errors))
1565   (if (and TeX-error-overview-open-after-TeX-run
1566            (TeX-error-overview-make-entries
1567             (TeX-master-directory) (TeX-active-buffer)))
1568       (TeX-error-overview))
1569   (cond ((TeX-TeX-sentinel-check process name))
1570         ((and (save-excursion
1571                 (re-search-forward
1572                  "^Package biblatex Warning: Please (re)run Biber on the file"
1573                  nil t))
1574               (with-current-buffer TeX-command-buffer
1575                 (and (LaTeX-bibliography-list)
1576                      (TeX-check-files (TeX-master-file "bbl")
1577                                       (TeX-style-list)
1578                                       (append TeX-file-extensions
1579                                               BibTeX-file-extensions
1580                                               TeX-Biber-file-extensions)))))
1581          (message "%s%s" "You should run Biber to get citations right, "
1582                   (TeX-current-pages))
1583          (setq TeX-command-next (with-current-buffer TeX-command-buffer
1584                                   TeX-command-Biber)))
1585         ((and (save-excursion
1586                 (re-search-forward
1587                  "^\\(?:LaTeX\\|Package natbib\\) Warning: Citation" nil t))
1588               (with-current-buffer TeX-command-buffer
1589                 (and (LaTeX-bibliography-list)
1590                      (TeX-check-files (TeX-master-file "bbl")
1591                                       (TeX-style-list)
1592                                       (append TeX-file-extensions
1593                                               BibTeX-file-extensions
1594                                               TeX-Biber-file-extensions)))))
1595          (message "%s%s" "You should run BibTeX to get citations right, "
1596                   (TeX-current-pages))
1597          (setq TeX-command-next (with-current-buffer TeX-command-buffer
1598                                   TeX-command-BibTeX)))
1599         ((re-search-forward "Package biblatex Warning: Please rerun LaTeX" nil t)
1600          (message "%s%s" "You should run LaTeX again, " (TeX-current-pages))
1601          (setq TeX-command-next TeX-command-default))
1602         ((re-search-forward "^(biblatex)\\W+Page breaks have changed" nil t)
1603          (message "%s%s" "You should run LaTeX again - page breaks have changed, "
1604                   (TeX-current-pages))
1605          (setq TeX-command-next TeX-command-default))
1606         ((re-search-forward "^\\(?:LaTeX Warning: Label(s)\\|\
1607 Package natbib Warning: Citation(s)\\)" nil t)
1608          (message "%s%s" "You should run LaTeX again to get references right, "
1609                   (TeX-current-pages))
1610          (setq TeX-command-next TeX-command-default))
1611         ((re-search-forward
1612           "^\\(?:(rerunfilecheck)\\|Package hyperref Warning:\\)\\W+\
1613 Rerun to get outlines right" nil t)
1614          (message "%s%s" "You should run LaTeX again to get outlines right, "
1615                   (TeX-current-pages))
1616          (setq TeX-command-next TeX-command-default))
1617         ((re-search-forward "^LaTeX Warning: Reference" nil t)
1618          (message "%s%s%s" name ": there were unresolved references, "
1619                   (TeX-current-pages))
1620          (let (dvi2pdf)
1621            (if (with-current-buffer TeX-command-buffer
1622                  (and TeX-PDF-mode (setq dvi2pdf (TeX-PDF-from-DVI))))
1623                (setq TeX-command-next dvi2pdf)
1624              (setq TeX-command-next TeX-command-Show))))
1625         ((re-search-forward "^\\(?:LaTeX Warning: Citation\\|\
1626 Package natbib Warning:.*undefined citations\\)" nil t)
1627          (message "%s%s%s" name ": there were unresolved citations, "
1628                   (TeX-current-pages))
1629          (let (dvi2pdf)
1630            (if (with-current-buffer TeX-command-buffer
1631                  (and TeX-PDF-mode (setq dvi2pdf (TeX-PDF-from-DVI))))
1632                (setq TeX-command-next dvi2pdf)
1633              (setq TeX-command-next TeX-command-Show))))
1634         ((re-search-forward "Package longtable Warning: Table widths have \
1635 changed\\. Rerun LaTeX\\." nil t)
1636          (message
1637           "%s" "You should run LaTeX again to get table formatting right")
1638          (setq TeX-command-next TeX-command-default))
1639         ((re-search-forward "^hf-TikZ Warning: Mark '.*' changed\\. \
1640 Rerun to get mark in right position\\." nil t)
1641          (message
1642           "%s" "You should run LaTeX again to get TikZ marks in right position")
1643          (setq TeX-command-next TeX-command-default))
1644         ((re-search-forward "^\* xsim warning: \"rerun\"" nil t)
1645          (message
1646           "%s" "You should run LaTeX again to synchronize exercise properties")
1647          (setq TeX-command-next TeX-command-default))
1648         ((re-search-forward
1649           "^\\(\\*\\* \\)?J?I?p?\\(La\\|Sli\\)TeX\\(2e\\)? \
1650 \\(Version\\|ver\\.\\|<[0-9/-]*\\(?:u[^>]*\\)?>\\)" nil t)
1651          (let* ((warnings (and TeX-debug-warnings
1652                                (TeX-LaTeX-sentinel-has-warnings)))
1653                 (bad-boxes (and TeX-debug-bad-boxes
1654                                 (TeX-LaTeX-sentinel-has-bad-boxes)))
1655                 (add-info (when (or warnings bad-boxes)
1656                             (concat " (with "
1657                                     (when warnings "warnings")
1658                                     (when (and warnings bad-boxes) " and ")
1659                                     (when bad-boxes "bad boxes")
1660                                     ")"))))
1661            (message "%s" (concat name ": successfully formatted "
1662                                  (TeX-current-pages) add-info)))
1663          (let (dvi2pdf)
1664            (if (with-current-buffer TeX-command-buffer
1665                  (and TeX-PDF-mode (setq dvi2pdf (TeX-PDF-from-DVI))))
1666                (setq TeX-command-next dvi2pdf)
1667              (setq TeX-command-next TeX-command-Show))))
1668         (t
1669          (message "%s%s%s" name ": problems after " (TeX-current-pages))
1670          (setq TeX-command-next TeX-command-default)))
1671
1672   ;; Check whether the idx file changed.
1673   (let ((idx-file nil) (master nil))
1674     (and (file-exists-p
1675           (setq idx-file
1676                 (concat
1677                  (setq master
1678                        (with-current-buffer TeX-command-buffer
1679                          (expand-file-name (TeX-active-master)))) ".idx")))
1680          ;; imakeidx package automatically runs makeindex, thus, we need to be
1681          ;; sure .ind file isn't newer than .idx.
1682          (TeX-check-files (concat master ".ind")
1683                           (list (file-name-nondirectory master)) '("idx"))
1684          (with-temp-buffer
1685            (insert-file-contents idx-file)
1686            (not (equal
1687                  ;; Compare old md5 hash of the idx file with the new one.
1688                  (cdr (assoc idx-file LaTeX-idx-md5-alist))
1689                  (md5 (current-buffer)))))
1690          (push (cons idx-file t) LaTeX-idx-changed-alist)))
1691
1692   (unless (TeX-error-report-has-errors-p)
1693     (run-hook-with-args 'TeX-after-compilation-finished-functions
1694                         (with-current-buffer TeX-command-buffer
1695                           (expand-file-name
1696                            (TeX-active-master (TeX-output-extension)))))))
1697
1698 ;; should go into latex.el? --pg
1699 (defun TeX-BibTeX-sentinel (_process _name)
1700   "Cleanup TeX output buffer after running BibTeX."
1701   (goto-char (point-max))
1702   (cond
1703    ;; Check whether BibTeX reports any warnings or errors.
1704    ((re-search-backward (concat
1705                          "^(There \\(?:was\\|were\\) \\([0-9]+\\) "
1706                          "\\(warnings?\\|error messages?\\))")
1707                         nil t)
1708     ;; Tell the user their number so that she sees whether the
1709     ;; situation is getting better or worse.
1710     (message (concat "BibTeX finished with %s %s. "
1711                      "Type `%s' to display output.")
1712              (match-string 1) (match-string 2)
1713              (substitute-command-keys
1714               "\\<TeX-mode-map>\\[TeX-recenter-output-buffer]")))
1715    (t
1716     (message (concat "BibTeX finished successfully. "
1717                      "Run LaTeX again to get citations right."))))
1718   ;; In any case, run the default next command.
1719   (setq TeX-command-next TeX-command-default))
1720
1721 (defun TeX-Biber-sentinel (_process _name)
1722   "Cleanup TeX output buffer after running Biber."
1723   (goto-char (point-max))
1724   (cond
1725    ((re-search-backward "^INFO - \\(WARNINGS\\|ERRORS\\): \\([0-9]+\\)" nil t)
1726     (message (concat "Biber finished with %s %s. "
1727                      "Type `%s' to display output.")
1728              (match-string 2) (downcase (match-string 1))
1729              (substitute-command-keys
1730               "\\<TeX-mode-map>\\[TeX-recenter-output-buffer]"))
1731     (setq TeX-command-next TeX-command-default))
1732    ((re-search-backward "^FATAL" nil t)
1733     (message (concat "Biber had a fatal error and did not finish! "
1734                      "Type `%s' to display output.")
1735              (substitute-command-keys
1736               "\\<TeX-mode-map>\\[TeX-recenter-output-buffer]"))
1737     (setq TeX-command-next TeX-command-Biber))
1738    (t
1739     (message (concat "Biber finished successfully. "
1740                      "Run LaTeX again to get citations right."))
1741     (setq TeX-command-next TeX-command-default))))
1742
1743 (defun TeX-dvips-sentinel (_process _name)
1744   "Cleanup TeX output buffer after running dvips."
1745   (goto-char (point-max))
1746   (cond
1747    ((search-backward "TeX Output exited abnormally" nil t)
1748     (message "Dvips failed.  Type `%s' to display output."
1749              (substitute-command-keys
1750               "\\<TeX-mode-map>\\[TeX-recenter-output-buffer]")))
1751    (t
1752     (if (with-current-buffer TeX-command-buffer
1753           (and (equal (TeX-PDF-from-DVI) "Dvips") TeX-PDF-mode))
1754         (setq TeX-output-extension "ps"
1755               TeX-command-next "Ps2pdf"))
1756     (message "Dvips finished successfully. "))))
1757
1758 (defun TeX-dvipdfmx-sentinel (_process _name)
1759   "Cleanup TeX output buffer after running dvipdfmx."
1760   (goto-char (point-max))
1761   (cond
1762    ((search-backward "TeX Output exited abnormally" nil t)
1763     (message "Dvipdfmx failed.  Type `%s' to display output."
1764              (substitute-command-keys
1765               "\\<TeX-mode-map>\\[TeX-recenter-output-buffer]")))
1766    (t
1767     (if (with-current-buffer TeX-command-buffer
1768           (and (equal (TeX-PDF-from-DVI) "Dvipdfmx") TeX-PDF-mode))
1769         (setq TeX-output-extension "pdf"
1770               TeX-command-next TeX-command-Show))
1771     (message "Dvipdfmx finished successfully. "))))
1772
1773 (defun TeX-ps2pdf-sentinel (_process _name)
1774   "Cleanup TeX output buffer after running ps2pdf."
1775   (goto-char (point-max))
1776   (cond
1777    ((search-backward "TeX Output exited abnormally" nil t)
1778     (message "ps2pdf failed.  Type `%s' to display output."
1779              (substitute-command-keys
1780               "\\<TeX-mode-map>\\[TeX-recenter-output-buffer]")))
1781    (t
1782     (if (with-current-buffer TeX-command-buffer
1783           (and (equal (TeX-PDF-from-DVI) "Dvips") TeX-PDF-mode))
1784         (setq TeX-command-next TeX-command-Show
1785               TeX-output-extension "pdf"))
1786     (message "ps2pdf finished successfully. "))))
1787
1788 (defun TeX-index-sentinel (_process _name)
1789   "Cleanup TeX output buffer after compiling index."
1790   (goto-char (point-max))
1791   (cond
1792    ((search-backward "TeX Output exited abnormally" nil t)
1793     (message "Index failed.  Type `%s' to display output."
1794              (substitute-command-keys
1795               "\\<TeX-mode-map>\\[TeX-recenter-output-buffer]")))
1796    (t
1797     (setq TeX-command-next TeX-command-default)
1798     (message (concat "Index finished successfully. "
1799                      "Run LaTeX again to get index right.")))))
1800
1801 (defun TeX-command-sequence-sentinel (process string)
1802   "Call the appropriate sentinel for the current process.
1803
1804 If there are no errors, call back `TeX-command-sequence' using
1805 `TeX-command-sequence-command' as command argument, unless this
1806 variable is nil."
1807   (with-current-buffer (process-buffer process)
1808     (funcall TeX-command-sequence-sentinel process string)
1809     (if (string-match "\\(finished\\|exited\\)" string)
1810         (with-current-buffer TeX-command-buffer
1811           (unless
1812               (or
1813                (TeX-error-report-has-errors-p)
1814                (null TeX-command-sequence-command))
1815             (TeX-command-sequence TeX-command-sequence-command nil
1816                                   TeX-command-sequence-file-function))))))
1817
1818 ;;; Process Control
1819
1820
1821 ;; This variable is shared with `compile.el'.
1822 ;; FIXME: Then it should not be defvar'd here!
1823 (defvar compilation-in-progress nil
1824   "List of compilation processes now running.")
1825
1826 (or (assq 'compilation-in-progress minor-mode-alist)
1827     (setq minor-mode-alist (cons '(compilation-in-progress " Compiling")
1828                                  minor-mode-alist)))
1829
1830 (defun TeX-process-get-variable (name symbol &optional default)
1831   "Return the value in the process buffer for NAME of SYMBOL.
1832
1833 Return DEFAULT if the process buffer does not exist or SYMBOL is not
1834 defined."
1835   (let ((buffer (TeX-process-buffer name)))
1836     (if (and buffer
1837              (local-variable-p symbol buffer))
1838         (with-current-buffer buffer
1839           (symbol-value symbol))
1840       default)))
1841
1842 (defun TeX-process-set-variable (name symbol value)
1843   "Set the variable SYMBOL in the process buffer to VALUE.
1844 Return nil iff no process buffer exist."
1845   (let ((buffer (TeX-process-buffer name)))
1846     (if buffer
1847         (with-current-buffer buffer
1848           (set symbol value)
1849           t)
1850       nil)))
1851
1852 (defun TeX-process-check (name)
1853   "Check if a process for the TeX document NAME already exist.
1854 If so, give the user the choice of aborting the process or the current
1855 command."
1856   (let (process)
1857     (while (and (setq process (TeX-process name))
1858                 (eq (process-status process) 'run))
1859       (cond
1860        ((yes-or-no-p (concat "Process `"
1861                              (process-name process)
1862                              "' for document `"
1863                              name
1864                              "' running, kill it? "))
1865         (delete-process process))
1866        ((eq (process-status process) 'run)
1867            (error "Cannot have two processes for the same document"))))))
1868
1869 (defun TeX-process-buffer-name (name)
1870   "Return name of AUCTeX buffer associated with the document NAME."
1871   (concat "*" (abbreviate-file-name (expand-file-name name)) " output*"))
1872
1873 (defun TeX-process-buffer (name)
1874   "Return the AUCTeX buffer associated with the document NAME."
1875   (get-buffer (TeX-process-buffer-name name)))
1876
1877 (defun TeX-process (name)
1878   "Return AUCTeX process associated with the document NAME."
1879   (and TeX-process-asynchronous
1880        (get-buffer-process (TeX-process-buffer name))))
1881
1882 ;;; Process Filters
1883
1884 (defun TeX-command-mode-line (process)
1885   "Format the mode line for a buffer containing output from PROCESS."
1886     (setq mode-line-process (concat ": "
1887                                     (symbol-name (process-status process))))
1888     (set-buffer-modified-p (buffer-modified-p)))
1889
1890 (defun TeX-command-filter (process string)
1891   "Filter to process normal output."
1892   (with-current-buffer (process-buffer process)
1893     (save-excursion
1894       (goto-char (process-mark process))
1895       (insert-before-markers string)
1896       (set-marker (process-mark process) (point)))))
1897
1898 (defvar TeX-current-page nil
1899   "The page number currently being formatted, enclosed in brackets.")
1900
1901  (make-variable-buffer-local 'TeX-current-page)
1902
1903 (defun TeX-format-mode-line (process)
1904   "Format the mode line for a buffer containing TeX output from PROCESS."
1905     (setq mode-line-process (concat " " TeX-current-page ": "
1906                                     (symbol-name (process-status process))))
1907     (set-buffer-modified-p (buffer-modified-p)))
1908
1909 (defun TeX-format-filter (process string)
1910   "Filter to process TeX output."
1911   (with-current-buffer (process-buffer process)
1912     (let (str pos end (pt (marker-position (process-mark process))))
1913       (save-excursion
1914         (goto-char pt)
1915         (insert-before-markers string)
1916         (set-marker (process-mark process) (point))
1917         ;; Remove line breaks at columns 79 and 80
1918         (while (> (point) pt)
1919           (end-of-line 0)
1920           (when (and (memq (- (point) (line-beginning-position)) '(79 80))
1921                      ;; Heuristic: Don't delete the linebreak if the next line
1922                      ;; is empty or starts with an opening parenthesis, or if
1923                      ;; point is located after a period and in the next line no
1924                      ;; word char follows.
1925                      (not (memq (char-after (1+ (point))) '(?\n ?\()))
1926                      (not (and (eq (char-before) ?.)
1927                                (char-after (1+ (point)))
1928                                (not (eq ?w (char-syntax (char-after (1+ (point)))))))))
1929             (delete-char 1)))
1930         (goto-char (marker-position (process-mark process)))
1931         ;; Determine current page
1932         (while (and pt
1933                     (skip-chars-backward "^]" pt)
1934                     (> (point) pt))
1935           (setq end (point))
1936           (backward-char)
1937           (skip-chars-backward "-0-9\n." (max (point-min) (- pt 128)))
1938           (when (and (eq ?\[ (char-before))
1939                      (not (eq ?\] (char-after)))
1940                      (progn
1941                        (setq str (buffer-substring (1- (point)) end)
1942                              pos nil)
1943                        (while (setq pos (string-match "\n" str pos))
1944                          (setq str (replace-match "" t t str)))
1945                        (string-match
1946                         "\\`\\[-?[0-9]+\\(\\.-?[0-9]+\\)\\{0,9\\}\\]\\'"
1947                         str)))
1948             (setq TeX-current-page str
1949                   pt nil)
1950             (TeX-format-mode-line process)))))))
1951
1952 (defvar TeX-parse-function nil
1953   "Function to call to parse content of TeX output buffer.")
1954 (make-variable-buffer-local 'TeX-parse-function)
1955
1956 (defun TeX-background-filter (_process string)
1957   "Filter to process background output."
1958   (let ((old-window (selected-window))
1959         (pop-up-windows t))
1960     (TeX-pop-to-buffer "*TeX background*" nil t)
1961     (goto-char (point-max))
1962     (insert string)
1963     (select-window old-window)))
1964
1965 ;; Copy and adaption of `comint-postoutput-scroll-to-bottom' from CVS
1966 ;; Emacs of 2005-04-24.
1967 (defun TeX-interactive-goto-prompt (string)
1968   "Move point to prompt of an interactive TeX run."
1969   (let* ((selected (selected-window))
1970          (current (current-buffer))
1971          (process (get-buffer-process current)))
1972     (unwind-protect
1973         (when process
1974           (walk-windows
1975            (lambda (window)
1976              (when (eq (window-buffer window) current)
1977                (select-window window)
1978                (when (and (< (point) (process-mark process))
1979                           (string-match "^\\? $" string))
1980                  (goto-char (process-mark process)))
1981                (select-window selected)))
1982            nil t))
1983       (set-buffer current))))
1984
1985
1986 ;;; Active Process
1987
1988 (defvar TeX-current-process-region-p nil
1989   "This variable is set to t iff the last TeX command is on a region.")
1990
1991 (defun TeX-active-process ()
1992   "Return the active process for the current buffer."
1993   (TeX-process (TeX-active-master)))
1994
1995 (defun TeX-active-buffer ()
1996   "Return the buffer of the active process for this buffer."
1997   (and TeX-command-buffer
1998        (with-current-buffer TeX-command-buffer
1999          (TeX-process-buffer (TeX-active-master)))))
2000
2001 (defun TeX-active-master (&optional extension nondirectory)
2002   "The master file currently being compiled.
2003
2004 If optional argument EXTENSION is non-nil, add that file extension to
2005 the name.  Special value t means use `TeX-default-extension'.
2006
2007 If optional second argument NONDIRECTORY is non-nil, do not include
2008 the directory."
2009   (if TeX-current-process-region-p
2010       (TeX-region-file extension nondirectory)
2011     (TeX-master-file extension nondirectory)))
2012
2013 (defvar TeX-command-buffer nil
2014   "The buffer from where the last TeX command was issued.")
2015
2016 ;;; Region File
2017
2018 (defcustom TeX-region-extra ""
2019   "*String to insert in the region file between the header and the text."
2020   :group 'TeX-command
2021   :type 'string)
2022
2023 ;; This was "{\\makeatletter\\gdef\\AucTeX@cite#1[#2]#3{[#3#1#2]}\
2024 ;;           \\gdef\\cite{\\@ifnextchar[{\\AucTeX@cite{, }}\
2025 ;;           {\\AucTeX@cite{}[]}}}\n"
2026 ;; However, that string is inappropriate for plain TeX and ConTeXt.
2027 ;; This needs reconsideration.
2028
2029
2030 (defvar TeX-region-hook nil
2031   "List of hooks to run before the region file is saved.
2032 The hooks are run in the region buffer, you may use the variable
2033 `master-buffer' to access the buffer of the master file and
2034 `orig-buffer' to access the buffer where \\[TeX-command-region] or
2035 \\[TeX-command-buffer] is invoked from.")
2036
2037 (defun TeX-quote-filename (file)
2038   "Convert file name into a form acceptable to TeX."
2039   (let (pos)
2040     (while (setq pos (string-match "\\\\" file pos))
2041       (setq file (replace-match "/" t t file 0)
2042             pos (1+ pos)))
2043     (while (setq pos (string-match "[~#]" file pos))
2044       (setq file (replace-match "\\\\string\\&" t nil file 0)
2045             pos (+ pos 8))))
2046   file)
2047
2048 (defvar font-lock-mode-enable-list)
2049 (defvar font-lock-auto-fontify)
2050 (defvar font-lock-defaults-alist)
2051
2052 (defvar TeX-region-orig-buffer nil
2053   "The original buffer in which the TeX-region was created.")
2054 (make-variable-buffer-local 'TeX-region-orig-buffer)
2055
2056 (defun TeX-region-create (file region original offset)
2057   "Create a new file named FILE with the string REGION.
2058 The region is taken from ORIGINAL starting at line OFFSET.
2059
2060 The current buffer and master file is searched, in order to ensure
2061 that the TeX header and trailer information is also included.
2062
2063 The OFFSET is used to provide the debugger with information about the
2064 original file."
2065   (let* (;; We shift buffer a lot, so we must keep track of the buffer
2066          ;; local variables.
2067          (header-end TeX-header-end)
2068          (trailer-start TeX-trailer-start)
2069
2070          ;; We seach for header and trailer in the master file.
2071          (orig-buffer (current-buffer))
2072          (master-name (TeX-master-file TeX-default-extension))
2073          (master-buffer (find-file-noselect master-name))
2074
2075          ;; Attempt to disable font lock.
2076          (font-lock-defaults-alist nil)
2077          (font-lock-defaults nil)
2078          (font-lock-maximum-size 0)
2079          (font-lock-mode-hook nil)
2080          (font-lock-auto-fontify nil)
2081          (font-lock-mode-enable-list nil)
2082          ;; And insert them into the FILE buffer.
2083          (file-buffer (let (;; Don't query for master file
2084                             (TeX-transient-master t)
2085                             ;; Don't choose a special mode (and call its hooks)
2086                             (auto-mode-alist nil)
2087                             (magic-mode-alist nil)
2088                             (enable-local-variables nil)
2089                             ;; Don't run any f-f hooks
2090                             (find-file-hook nil))
2091                         (find-file-noselect file)))
2092          ;; But remember original content.
2093          original-content
2094
2095          ;; We search for the header from the master file, if it is
2096          ;; not present in the region.
2097          (header (if (string-match header-end region)
2098                      ""
2099                    (save-excursion
2100                      (save-restriction
2101                        (set-buffer master-buffer)
2102                        (save-excursion
2103                          (save-restriction
2104                            (widen)
2105                            (goto-char (point-min))
2106                            ;; NOTE: We use the local value of
2107                            ;; TeX-header-end from the master file.
2108                            (if (not (re-search-forward TeX-header-end nil t))
2109                                ""
2110                              (re-search-forward "[\r\n]" nil t)
2111                              (buffer-substring (point-min) (point)))))))))
2112          (header-offset 0)
2113          ;; We search for the trailer from the master file, if it is
2114          ;; not present in the region.
2115          (trailer-offset 0)
2116          (trailer (if (string-match trailer-start region)
2117                       ""
2118                     (save-excursion
2119                       (save-restriction
2120                         (set-buffer master-buffer)
2121                         (save-excursion
2122                           (save-restriction
2123                             (widen)
2124                             (goto-char (point-max))
2125                             ;; NOTE: We use the local value of
2126                             ;; TeX-trailer-start from the master file.
2127                             (if (not (re-search-backward TeX-trailer-start nil t))
2128                                 ""
2129                               ;;(beginning-of-line 1)
2130                               (re-search-backward "[\r\n]" nil t)
2131                               (setq trailer-offset (TeX-current-offset))
2132                               (buffer-substring (point) (point-max))))))))))
2133     ;; file name should be relative to master
2134     (setq original (TeX-quote-filename (file-relative-name
2135                                         original (TeX-master-directory)))
2136           master-name (TeX-quote-filename master-name))
2137     (with-current-buffer file-buffer
2138       (setq buffer-read-only t
2139             buffer-undo-list t)
2140       (setq original-content (buffer-string))
2141       (let ((inhibit-read-only t))
2142         (erase-buffer)
2143         (when (boundp 'buffer-file-coding-system)
2144           (setq buffer-file-coding-system
2145                 (with-current-buffer master-buffer buffer-file-coding-system)))
2146         (insert "\\message{ !name(" master-name ")}"
2147                 header
2148                 TeX-region-extra
2149                 "\n\\message{ !name(" original ") !offset(")
2150         (setq header-offset (- offset
2151                                (1+ (TeX-current-offset))))
2152         (insert (int-to-string header-offset)
2153                 ") }\n"
2154                 region
2155                 "\n\\message{ !name("  master-name ") !offset(")
2156         (insert (int-to-string (- trailer-offset
2157                                   (1+ (TeX-current-offset))))
2158                 ") }\n"
2159                 trailer)
2160         (setq TeX-region-orig-buffer orig-buffer)
2161         (run-hooks 'TeX-region-hook)
2162         (if (string-equal (buffer-string) original-content)
2163             (set-buffer-modified-p nil)
2164           (save-buffer 0))))))
2165
2166 (defun TeX-region-file (&optional extension nondirectory _ignore)
2167   "Return TeX-region file name with EXTENSION.
2168 If optional second argument NONDIRECTORY is non-nil, do not include
2169 the directory.
2170
2171 The compatibility argument IGNORE is ignored."
2172   ;; The third argument `_ignore' is kept for symmetry with `TeX-master-file's
2173   ;; third argument `ask'.  For example, it's used in `TeX-command-sequence',
2174   ;; where we don't know which function has to be called.  Keep this in mind
2175   ;; should you want to use another argument here.
2176   (concat (if nondirectory "" (TeX-master-directory))
2177           (cond ((eq extension t)
2178                  (concat TeX-region "." TeX-default-extension))
2179                 (extension
2180                  (concat TeX-region "." extension))
2181                 (t
2182                  TeX-region))))
2183
2184 (defcustom TeX-region "_region_"
2185   "*Base name of temporary file for `TeX-command-region' and `TeX-command-buffer'."
2186   :group 'TeX-command
2187   :type 'string)
2188
2189 (defvar LaTeX-command-section-level nil
2190   "The section level used for `LaTeX-command-section'.
2191 Will be initialized to `LaTeX-largest-level' buffer-locally.")
2192 (make-variable-buffer-local 'LaTeX-command-section-level)
2193
2194 (defun LaTeX-command-section-level ()
2195   "Return the value of `LaTeX-command-section-level'.
2196 Initialize it to `LaTeX-largest-level' if needed."
2197   (unless LaTeX-command-section-level
2198     (setq LaTeX-command-section-level LaTeX-largest-level))
2199   LaTeX-command-section-level)
2200
2201
2202 (defun LaTeX-command-section-change-level (arg)
2203   "Change `LaTeX-command-section-level' by ARG.
2204 `LaTeX-command-section-level' is the sectioning level used to
2205 determine the current section by `LaTeX-command-section'.
2206 The levels are defined by `LaTeX-section-list'."
2207   (interactive "p")
2208   (let ((old-level (car (rassoc (list (LaTeX-command-section-level))
2209                                 LaTeX-section-list))))
2210     (setq LaTeX-command-section-level (+ LaTeX-command-section-level arg))
2211     (cond
2212      ((> LaTeX-command-section-level 6)
2213       (setq LaTeX-command-section-level 6)
2214       (message "Cannot shrink LaTeX-command-section-level below subparagraph."))
2215      ((< LaTeX-command-section-level 0)
2216       (setq LaTeX-command-section-level 0)
2217       (message "Cannot enlarge LaTeX-command-section-level above part."))
2218      (t (message "Changed level from %s to %s."
2219                  old-level (car (rassoc (list LaTeX-command-section-level)
2220                                         LaTeX-section-list)))))))
2221
2222 (defun LaTeX-command-section-boundaries ()
2223   "Return the boundaries of the current section as (start . end).
2224 The section is determined by `LaTeX-command-section-level'."
2225   (let* ((case-fold-search nil)
2226          (rx (concat "\\\\" (regexp-opt
2227                              (mapcar
2228                               (lambda (level)
2229                                 (car (rassoc (list level) LaTeX-section-list)))
2230                               (let (r)
2231                                 (dotimes (i (1+ (LaTeX-command-section-level)))
2232                                   (push i r))
2233                                 r)))
2234                      "{")))
2235     (cons (save-excursion
2236             (re-search-backward rx nil t)
2237             (point))
2238           (save-excursion
2239             (re-search-forward (concat rx "\\|\\\\end{document}") nil t)
2240             (forward-line 0)
2241             (point)))))
2242
2243 (defun LaTeX-command-section (&optional override-confirm)
2244   "Run a command on the current section.
2245
2246 What makes the current section is defined by
2247 `LaTeX-command-section-level' which can be enlarged or shrunken
2248 with `LaTeX-command-section-change-level'.
2249
2250 Query the user for a command to run on the temporary file
2251 specified by the variable `TeX-region'.  The region file will be
2252 recreated from current section.
2253
2254 If a prefix argument OVERRIDE-CONFIRM is given, confirmation will
2255 depend on it being positive instead of the entry in
2256 `TeX-command-list'."
2257   (interactive "P")
2258   (if (eq major-mode 'latex-mode)
2259       (let* ((bounds (LaTeX-command-section-boundaries))
2260              (TeX-command-region-begin (car bounds))
2261              (TeX-command-region-end (cdr bounds)))
2262         (TeX-command-region override-confirm))
2263     (error "LaTeX-command-section can only be run on LaTeX documents")))
2264
2265 (defun TeX-command-run-all-region ()
2266   "Compile the current region until an error occurs or it is finished."
2267   (interactive)
2268   (TeX-region-update)
2269   (TeX-command-sequence t t #'TeX-region-file))
2270
2271 (defun LaTeX-command-run-all-section ()
2272   "Compile the current section until an error occurs or it is finished."
2273   (interactive)
2274   (if (eq major-mode 'latex-mode)
2275       (let* ((bounds (LaTeX-command-section-boundaries))
2276              (TeX-command-region-begin (car bounds))
2277              (TeX-command-region-end (cdr bounds)))
2278         (TeX-region-update)
2279         (TeX-command-sequence t t #'TeX-region-file))
2280     (error "LaTeX-command-run-all-section can only be run on LaTeX documents")))
2281
2282 (defun TeX-command-run-all (arg)
2283   "Compile the current document until an error occurs or it is finished.
2284 With a prefix ARG (`\\[universal-argument] \\[TeX-command-run-all]'),
2285 compile the current region instead, e.g, call
2286 `TeX-command-run-all-region'.  With multiple prefix
2287 arguments (`\\[universal-argument] \\[universal-argument] \\[TeX-command-run-all]'),
2288 compile the current section instead, e.g. call
2289 `LaTeX-command-run-all-section'."
2290   (interactive "P")
2291   (cond
2292    ((null arg)       (TeX-command-sequence t t))
2293    ((= 4 (car arg))  (TeX-command-run-all-region))
2294    (t                (LaTeX-command-run-all-section))))
2295
2296 ;;; Parsing
2297
2298 ;;; - Global Parser Variables
2299
2300 (defvar TeX-error-point nil
2301   "How far we have parsed until now.")
2302
2303 (make-variable-buffer-local 'TeX-error-point)
2304
2305 (defvar TeX-error-file nil
2306   "Stack of files in which errors have occurred.")
2307
2308 (make-variable-buffer-local 'TeX-error-file)
2309
2310 (defvar TeX-error-offset nil
2311   "Add this to any line numbers from TeX.  Stack like `TeX-error-file'.")
2312
2313 (make-variable-buffer-local 'TeX-error-offset)
2314
2315 (defun TeX-parse-reset (&optional reparse)
2316   "Reset all variables used for parsing TeX output.
2317 If optional argument REPARSE is non-nil, reparse the output log."
2318   (setq TeX-error-point (point-min)
2319         TeX-error-offset nil
2320         TeX-error-file nil
2321         TeX-error-list nil
2322         TeX-error-last-visited -1)
2323   (if reparse
2324       (TeX-parse-all-errors)))
2325
2326 ;;; - Parsers Hooks
2327
2328 ;; All this parsers hooks should have the same arguments even though they will
2329 ;; be ignored, because `TeX-next-error' can call any of these functions.
2330 (defun TeX-parse-command (_arg _reparse)
2331   "We can't parse anything but TeX."
2332   (error "I cannot parse %s output, sorry"
2333          (if (TeX-active-process)
2334              (process-name (TeX-active-process))
2335            "this")))
2336
2337 (defun TeX-error-list-skip-warning-p (type ignore)
2338   "Decide if a warning of `TeX-error-list' should be skipped.
2339
2340 TYPE is one of the types listed in `TeX-error-list', IGNORE
2341 is the flag to choose if the warning should be skipped."
2342   ;; The warning should be skipped if it...
2343   (or
2344    ;; ...is a warning and we want to ignore all warnings, or...
2345    (and (null TeX-debug-warnings)
2346         (equal type 'warning))
2347    ;; ...is a bad-box and we want to ignore all bad-boxes, or...
2348    (and (null TeX-debug-bad-boxes)
2349         (equal type 'bad-box))
2350    ;; ...is a warning to be ignored.
2351    (and TeX-suppress-ignored-warnings
2352         ignore)))
2353
2354 (defun TeX-parse-TeX (arg reparse)
2355   "Find the next error produced by running TeX.
2356
2357 ARG specifies how many error messages to move, when possible;
2358 negative means move back to previous error messages.
2359
2360 If REPARSE is non-nil, reparse the output log.
2361
2362 If the file occurs in an included file, the file is loaded (if not
2363 already in an Emacs buffer) and the cursor is placed at the error."
2364   (let ((old-buffer (current-buffer))
2365         (default-major-mode major-mode)
2366         max-index item)
2367
2368     ;; Switch to the output buffer.
2369     (with-current-buffer (TeX-active-buffer)
2370       (if reparse
2371           (TeX-parse-reset reparse))
2372       (if TeX-parse-all-errors
2373           (progn
2374             (setq arg (or arg 1)
2375                   max-index (length TeX-error-list))
2376             ;; This loop is needed to skip ignored warnings, when
2377             ;; `TeX-suppress-ignored-warnings' is non-nil and there are ignore
2378             ;; warnings.
2379             (while (null (zerop arg))
2380               (setq TeX-error-last-visited
2381                     ;; Increase or decrese `TeX-error-last-visited' depending on
2382                     ;; the sign of `arg'.  Note: `signum' is a function from
2383                     ;; `cl' library, do not be tempted to use it.
2384                     (if (> arg 0)
2385                         (1+ TeX-error-last-visited)
2386                       (1- TeX-error-last-visited))
2387                     item (if (natnump TeX-error-last-visited)
2388                              (nth TeX-error-last-visited TeX-error-list)
2389                            ;; XEmacs doesn't support `nth' with a negative index.
2390                            nil))
2391               ;; Increase or decrease `arg' only if the warning isn't to be
2392               ;; skipped.
2393               (unless (TeX-error-list-skip-warning-p (nth 0 item) (nth 10 item))
2394                 ;; Note: `signum' is a function from `cl' library, do not be
2395                 ;; tempted to use it.
2396                 (setq arg (if (> arg 0)
2397                               (1- arg)
2398                             (1+ arg)))))
2399             (if (< TeX-error-last-visited -1)
2400                 (setq TeX-error-last-visited -1))
2401             (cond ((or (null item)
2402                        (< TeX-error-last-visited 0))
2403                    (if (> TeX-error-last-visited max-index)
2404                        (setq TeX-error-last-visited max-index))
2405                    (message "No more errors.")
2406                    (beep)
2407                    (TeX-pop-to-buffer old-buffer))
2408                   (t
2409                    (apply #'TeX-find-display-help item))))
2410
2411         (goto-char TeX-error-point)
2412         (TeX-parse-error old-buffer)))))
2413
2414 ;;; - Parsing (La)TeX
2415
2416 (defvar TeX-translate-location-hook nil
2417   "List of functions to be called before showing an error or warning.
2418
2419 You might want to examine and modify the free variables `file',
2420 `offset', `line', `string', `error', and `context' from this hook.")
2421
2422 ;; `ignore' flag should be the always the last one in the list of information
2423 ;; for each error/warning, because it can be set within `TeX-warning' by a
2424 ;; custom function taking as argument all information present in
2425 ;; `TeX-error-list' but `ignore', see `TeX-ignore-warnings'.
2426 (defvar TeX-error-list nil
2427   "List of warnings and errors.
2428
2429 Each element of the list is a list of information for a specific
2430 error or warning.  This is the structure of each element:
2431  *  0: type (error, warning, bad-box)
2432  *  1: file
2433  *  2: line
2434  *  3: message of the error or warning
2435  *  4: offset
2436  *  5: context, to be displayed in the help window
2437  *  6: string to search in the buffer, in order to find location
2438        of the error or warning
2439  *  7: for warnings referring to multiple lines (e.g. bad boxes),
2440        the last line mentioned in the warning message
2441  *  8: t if it is a bad-box, nil otherwise
2442  *  9: value of `TeX-error-point'
2443  * 10: whether the warning should be ignored
2444
2445 This variable is intended to be set only in output buffer so it
2446 will be shared among all files of the same document.")
2447 (make-variable-buffer-local 'TeX-error-list)
2448
2449 (defcustom TeX-parse-all-errors t
2450   "Whether to automatically collect all warning and errors after running TeX.
2451
2452 If t, it makes it possible to use `TeX-previous-error' with TeX
2453 commands."
2454   :group 'TeX-command
2455   :type 'boolean)
2456
2457 (defun TeX-parse-all-errors ()
2458   "Parse TeX output buffer to collect all warnings and errors."
2459   ;; Reset error list.
2460   (setq TeX-error-list nil)
2461   (save-excursion
2462     (goto-char (point-min))
2463     (while (TeX-parse-error nil t)))
2464   ;; Reset last visited error.
2465   (setq TeX-error-last-visited -1))
2466
2467 (defun TeX-parse-error (old &optional store)
2468   "Goto next error.  Pop to OLD buffer if no more errors are found.
2469
2470 If the optional argument STORE is non-nil, the function will
2471 store the found warning or error in `TeX-error-list' instead of
2472 displaying the issue.
2473
2474 Return non-nil if an error or warning is found."
2475   (let ((regexp
2476          (concat
2477           ;; TeX error
2478           "^\\(!\\|\\(.*?\\):[0-9]+:\\) \\|"
2479           ;; New file
2480           "(\n?\\([^\n())]+\\)\\|"
2481           ;; End of file.
2482           "\\()\\)\\|"
2483           ;; Hook to change line numbers
2484           " !\\(?:offset(\\([---0-9]+\\))\\|"
2485           ;; Hook to change file name
2486           "name(\\([^)]+\\))\\)\\|"
2487           ;; Start of LaTeX bad box
2488           "^\\(\\(?:Overfull\\|Underfull\\|Tight\\|Loose\\) "
2489           ;;   Horizontal bad box
2490           "\\(?:\\\\hbox.* at lines? [0-9]+\\(?:--[0-9]+\\)?$\\|"
2491           ;;   Vertical bad box.  See also `TeX-warning'.
2492           "\\\\vbox ([ a-z0-9]+) has occurred while \\\\output is active \\[[^]]+\\]\\)\\)\\|"
2493           ;; LaTeX warning
2494           "^\\(" LaTeX-warnings-regexp ".*\\)"))
2495         (error-found nil))
2496     (while
2497         (cond
2498          ((null
2499            (re-search-forward regexp nil t))
2500           ;; No more errors.
2501           (unless store
2502             (message "No more errors.")
2503             (beep)
2504             (TeX-pop-to-buffer old))
2505           nil)
2506          ;; TeX error
2507          ((match-beginning 1)
2508           (when (match-beginning 2)
2509             (unless TeX-error-file
2510               (push nil TeX-error-file)
2511               (push nil TeX-error-offset))
2512             (unless (car TeX-error-offset)
2513               (rplaca TeX-error-file (TeX-match-buffer 2))))
2514           (setq error-found t)
2515           (if (looking-at "Preview ")
2516               t
2517             (TeX-error store)
2518             nil))
2519          ;; LaTeX bad box
2520          ((match-beginning 7)
2521           ;; In `TeX-error-list' we collect all warnings, also if they're going
2522           ;; to be actually skipped.
2523           (if (or store TeX-debug-bad-boxes)
2524               (progn
2525                 (setq error-found t)
2526                 (TeX-warning (TeX-match-buffer 7) (match-beginning 7) t store)
2527                 nil)
2528             (re-search-forward "\r?\n\
2529 \\(?:.\\{79\\}\r?\n\
2530 \\)*.*\r?$")
2531             t))
2532          ;; LaTeX warning
2533          ((match-beginning 8)
2534           ;; In `TeX-error-list' we collect all warnings, also if they're going
2535           ;; to be actually skipped.
2536           (if (or store TeX-debug-warnings)
2537               (progn
2538                 (setq error-found t)
2539                 (TeX-warning (TeX-match-buffer 8) (match-beginning 8) nil store)
2540                 nil)
2541             t))
2542
2543          ;; New file -- Push on stack
2544          ((match-beginning 3)
2545           (let ((file (TeX-match-buffer 3))
2546                 (end (match-end 3)))
2547             ;; Strip quotation marks and remove newlines if necessary
2548             (when (or (eq (string-to-char file) ?\")
2549                       (string-match "[ \t\n]" file))
2550               (setq file (mapconcat #'identity (split-string file "[\"\n]+") "")))
2551             ;; Polish `file' string
2552             (setq file
2553                   (let ((string file))
2554                     ;; Trim whitespaces at the front.  XXX: XEmacs doesn't
2555                     ;; support character classes in regexps, like "[:space:]".
2556                     (setq string
2557                           (if (string-match "\\'[ \t\n\r]*" string)
2558                               (replace-match "" t t string)
2559                             string))
2560                     ;; Sometimes `file' is something like
2561                     ;;     "./path/to/file.tex [9] [10 <./path/to/file>] "
2562                     ;; where "[9]" and "[10 <./path/to/file>]" are pages of the
2563                     ;; output file, with path to an included file.  Remove these
2564                     ;; numbers together with whitespaces at the end of the
2565                     ;; string.
2566                     (if (string-match "\\( *\\(\\[[^]]+\\]\\)? *\\)*\\'" string)
2567                         (replace-match "" t t string)
2568                       string)))
2569             (push file TeX-error-file)
2570             (push nil TeX-error-offset)
2571             (goto-char end))
2572           t)
2573
2574          ;; End of file -- Pop from stack
2575          ((match-beginning 4)
2576           (when (> (length TeX-error-file) 0)
2577             (pop TeX-error-file)
2578             (pop TeX-error-offset))
2579           (goto-char (match-end 4))
2580           t)
2581
2582          ;; Hook to change line numbers
2583          ((match-beginning 5)
2584           (setq TeX-error-offset
2585                 (list (string-to-number (TeX-match-buffer 5))))
2586           t)
2587
2588          ;; Hook to change file name
2589          ((match-beginning 6)
2590           (setq TeX-error-file
2591                 (list (TeX-match-buffer 6)))
2592           t)))
2593     error-found))
2594
2595 (defun TeX-find-display-help (type file line error offset context string
2596                                    line-end _bad-box error-point _ignore)
2597   "Find the error and display the help.
2598
2599 For a description of arguments, see `TeX-error-list'.  IGNORE
2600 value is not used here."
2601   ;; Go back to TeX-buffer
2602   (let ((runbuf (TeX-active-buffer))
2603         (master (with-current-buffer TeX-command-buffer
2604                   (expand-file-name (TeX-master-file))))
2605         (command-buffer TeX-command-buffer)
2606         error-file-buffer start)
2607     (run-hooks 'TeX-translate-location-hook)
2608
2609     (if file
2610         (progn
2611           (setq error-file-buffer
2612                 (find-file
2613                  (expand-file-name file (file-name-directory master))))
2614           ;; Set the value of `TeX-command-buffer' in the next file with an
2615           ;; error to be displayed to the value it has in the current buffer.
2616           (with-current-buffer error-file-buffer
2617             (set (make-local-variable 'TeX-command-buffer) command-buffer))
2618
2619           ;; Find the location of the error or warning.
2620           (when line
2621             (goto-char (point-min))
2622             (forward-line (+ offset line -1))
2623             (cond
2624              ;; Error.
2625              ((equal type 'error)
2626               (if (not (string= string " "))
2627                   (search-forward string nil t)))
2628              ;; Warning or bad box.
2629              (t
2630               (beginning-of-line 0)
2631               (setq start (point))
2632               (goto-char (point-min))
2633               (forward-line (+ offset line-end -1))
2634               (end-of-line)
2635               (when string
2636                 (search-backward string start t)
2637                 (search-forward string nil t))))))
2638       ;; When the file cannot be determined stay here but issue a warning.
2639       (message (concat "Could not determine file for "
2640                        (cond ((equal type 'error) "error")
2641                              (t "warning"))))
2642       (beep))
2643
2644     ;; Display the help.
2645     (cond ((eq TeX-display-help 'expert)
2646            (TeX-pop-to-buffer runbuf nil t)
2647            (goto-char error-point)
2648            (TeX-pop-to-buffer error-file-buffer nil t))
2649           (TeX-display-help
2650            (TeX-help-error
2651             error
2652             (if (equal type 'warning) (concat "\n" context) context)
2653             runbuf type))
2654           (t
2655            (message (concat "! " error))))))
2656
2657 (defun TeX-error (&optional store)
2658   "Display an error.
2659
2660 If optional argument STORE is non-nil, store the error
2661 information in `TeX-error-list' instead of displaying the error."
2662
2663   (let* ( ;; We need the error message to show the user.
2664          (error (progn
2665                   (re-search-forward "\\(.*\\)")
2666                   (TeX-match-buffer 1)))
2667
2668          ;; And the context for the help window.
2669          (context-start (point))
2670          context-available
2671
2672          ;; And the line number to position the cursor.
2673          (line (cond
2674                 ;; regular style
2675                 ((re-search-forward "l\\.\\([0-9]+\\)" nil t)
2676                  (setq context-available t)
2677                  (string-to-number (TeX-match-buffer 1)))
2678                 ;; file:line:error style
2679                 ((save-excursion
2680                    (re-search-backward ":\\([0-9]+\\): "
2681                                        (line-beginning-position) t))
2682                  (string-to-number (TeX-match-buffer 1)))
2683                 ;; nothing found
2684                 (t 1)))
2685
2686          ;; And a string of the context to search for.
2687          (string (progn
2688                    (beginning-of-line)
2689                    (re-search-forward " \\(\\([^ \t]*$\\)\\|\\($\\)\\)")
2690                    (TeX-match-buffer 1)))
2691
2692          ;; And we have now found to the end of the context.
2693          (context (if context-available
2694                       (buffer-substring context-start (progn (forward-line 1)
2695                                                              (end-of-line)
2696                                                              (point)))
2697                     ;; There is no real context available, so we
2698                     ;; simply show the line with the error message.
2699                     (buffer-substring (1- (line-beginning-position))
2700                                       context-start)))
2701          ;; We may use these in another buffer.
2702          (offset (or (car TeX-error-offset) 0))
2703          (file (car TeX-error-file))
2704          info-list)
2705
2706     ;; Remember where we was.
2707     (setq TeX-error-point (point)
2708           info-list (list 'error file line error offset context string nil nil
2709                           TeX-error-point nil))
2710     (if store
2711         ;; Store the error information.
2712         (add-to-list 'TeX-error-list info-list t)
2713       ;; Find the error point and display the help.
2714       (apply #'TeX-find-display-help info-list))))
2715
2716 (defun TeX-warning (warning warning-start bad-box &optional store)
2717   "Display a warning for WARNING.
2718
2719 WARNING-START is the position where WARNING starts.  If BAD-BOX
2720 is non-nil, the warning refers to a bad-box, otherwise it is a
2721 generic warning.
2722
2723 If optional argument STORE is non-nil, store the warning
2724 information in `TeX-error-list' instead of displaying the
2725 warning."
2726
2727   (let* ( ;; line-string: match 1 is beginning line, match 2 is end line
2728          (line-string (if bad-box
2729                           "at lines? \\([0-9]*\\)\\(?:--\\([0-9]*\\)\\)?"
2730                         "on input line \\([0-9]*\\)\\."))
2731          ;; word-string: match 1 is the word
2732          (word-string (if bad-box "[][\\W() ---]\\(\\w+\\)[][\\W() ---]*$"
2733                         ;; Match "ref" in both "Reference `ref' on page NN
2734                         ;; undefined" and "Citation 'ref' on page NN undefined".
2735                         "\\(?:`\\|'\\)\\([-a-zA-Z0-9:]+\\)'"))
2736
2737          ;; Get error-line (warning).  Don't search before `warning-start' to
2738          ;; avoid catching completely unrelated line numbers.
2739          (line (when (save-excursion (re-search-backward line-string
2740                                                          warning-start t))
2741                  (string-to-number (TeX-match-buffer 1))))
2742          ;; If this is a bad box and the warning ends with "...at lines MM--NN"
2743          ;; we can use "NN" as `line-end', in any other case (including bad
2744          ;; boxes ending with "...at line NN") just use `line'.
2745          (line-end (if (and bad-box (match-beginning 2))
2746                        (string-to-number (TeX-match-buffer 2))
2747                      line))
2748
2749          ;; Find the context
2750          (context-start (progn (cond
2751                                 ((and bad-box (string-match "\\\\hbox" warning))
2752                                  ;; Horizontal bad box
2753                                  (end-of-line))
2754                                 (bad-box
2755                                  ;; Vertical bad box (by exclusion), don't move
2756                                  ;; point.  In the output buffer, unlike in the
2757                                  ;; actual *.log file, these warnings do not end
2758                                  ;; with "...is active []", but in the same line
2759                                  ;; there may be something else, including a new
2760                                  ;; file opened.  Thus, point shouldn't move
2761                                  ;; from the end of the actual bad box warning.
2762                                  ;; This is why the corresponding regexp in
2763                                  ;; `TeX-parse-error' doesn't match everything
2764                                  ;; until the end of the line.
2765                                  nil)
2766                                 (t
2767                                  ;; Generic warning.
2768                                  (beginning-of-line)))
2769                                (point)))
2770
2771          (context (cond ((string-match LaTeX-warnings-regexp warning)
2772                          ;; The warnings matching `LaTeX-warnings-regexp' are
2773                          ;; emitted by \GenericWarning macro, or macros based on
2774                          ;; it (\ClassWarning, \PackageWarning, etc).  After
2775                          ;; such warnings there is an empty line, just look for
2776                          ;; it to find the end.
2777                          (beginning-of-line)
2778                          (while (null (eolp))
2779                            (forward-line 1))
2780                          (buffer-substring context-start (progn (end-of-line)
2781                                                                 (point))))
2782
2783                         ((and bad-box (string-match "\\\\vbox" warning))
2784                          ;; Vertical bad boxes don't provide any additional
2785                          ;; information.  In this case, reuse the `warning' as
2786                          ;; `context' and don't move point, so that we avoid
2787                          ;; eating the next line that may contain another
2788                          ;; warning.  See also comment for `context-start'.
2789                          (concat "\n" warning))
2790
2791                         (t
2792                          ;; Horizontal bad boxes.
2793                          (forward-line 1)
2794                          (end-of-line)
2795                          (while (equal (current-column) 79)
2796                            (forward-line 1)
2797                            (end-of-line))
2798                          (buffer-substring context-start (point)))))
2799
2800          ;; This is where we want to be.
2801          (error-point (point))
2802
2803          ;; Now find the error word.
2804          (string (when (save-excursion
2805                          (re-search-backward word-string context-start t))
2806                    (TeX-match-buffer 1)))
2807
2808          ;; We might use these in another file.
2809          (offset (or (car TeX-error-offset) 0))
2810          (file (car TeX-error-file))
2811          info-list ignore)
2812
2813     ;; Second chance to get line number right.  If `line' is nil, check whether
2814     ;; the reference to the line number is in `context'.  For example, this is
2815     ;; the case for warnings emitted with \ClassWarning and \PackageWarning.
2816     ;; XXX: maybe it suffices to evaluate `line' after `context' above, but I
2817     ;; don't know if there are cases in which it's important to get `line'
2818     ;; before `context'.
2819     (and (null line)
2820          (string-match line-string context)
2821          (setq line-end
2822                (setq line (and (match-beginning 1)
2823                                (string-to-number (match-string 1 context))))))
2824
2825     ;; This is where we start next time.
2826     (goto-char error-point)
2827     (setq TeX-error-point (point))
2828
2829     ;; Explanation of what follows: we add the warning to `TeX-error-list' even
2830     ;; if it has to be ignored, with a flag specifying whether it is ignored.
2831     ;; We do so in order to be able to change between "ignore" and "dont-ignore"
2832     ;; behavior by just looking to the flag, without the need to reparse the
2833     ;; output log.
2834
2835     ;; Store the list of information about the warning.
2836     (setq info-list (list (if bad-box 'bad-box 'warning) file line warning
2837                           offset context string line-end bad-box
2838                           TeX-error-point)
2839           ;; Decide whether it should be ignored.
2840           ignore (and TeX-ignore-warnings
2841                       (cond
2842                        ((stringp TeX-ignore-warnings)
2843                         (string-match TeX-ignore-warnings warning))
2844                        ((fboundp TeX-ignore-warnings)
2845                         (apply TeX-ignore-warnings info-list))))
2846           ;; Update `info-list'.
2847           info-list (append info-list (list ignore)))
2848
2849     (if store
2850         ;; Store the warning information.
2851         (add-to-list 'TeX-error-list info-list t)
2852       ;; Find the warning point and display the help.
2853       (apply #'TeX-find-display-help info-list))))
2854
2855 ;;; Error Messages
2856
2857 (defcustom TeX-error-description-list
2858   '(("\\(?:Package Preview Error\\|Preview\\):.*" .
2859      "The `auctex' option to `preview' should not be applied manually.
2860 If you see this error message outside of a preview run, either
2861 you did something too clever, or AUCTeX something too stupid.")
2862
2863     ("Bad \\\\line or \\\\vector argument.*" .
2864      "The first argument of a \\line or \\vector command, which specifies the
2865 slope, is illegal\.")
2866
2867     ("Bad math environment delimiter.*" .
2868      "TeX has found either a math-mode-starting command such as \\[ or \\(
2869 when it is already in math mode, or else a math-mode-ending command
2870 such as \\) or \\] while in LR or paragraph mode.  The problem is caused
2871 by either unmatched math mode delimiters or unbalanced braces\.")
2872
2873     ("Bad use of \\\\\\\\.*" .
2874      "A \\\\ command appears between paragraphs, where it makes no sense. This
2875 error message occurs when the \\\\ is used in a centering or flushing
2876 environment or else in the scope of a centering or flushing
2877 declaration.")
2878
2879     ("\\\\begin{[^ ]*} ended by \\\\end{[^ ]*}." .
2880      "LaTeX has found an \\end command that doesn't match the corresponding
2881 \\begin command. You probably misspelled the environment name in the
2882 \\end command, have an extra \\begin, or else forgot an \\end.")
2883
2884     ("Can be used only in preamble." .
2885      "LaTeX has encountered, after the \\begin{document}, one of the
2886 following commands that should appear only in the preamble:
2887 \\documentclass, \\nofiles, \\includeonly, \\makeindex, or
2888 \\makeglossary.  The error is also caused by an extra \\begin{document}
2889 command.")
2890
2891     ("Command name [^ ]* already used.*" .
2892      "You are using \\newcommand, \\newenvironment, \\newlength, \\newsavebox,
2893 or \\newtheorem to define a command or environment name that is
2894 already defined, or \\newcounter to define a counter that already
2895 exists. (Defining an environment named gnu automatically defines the
2896 command \\gnu.) You'll have to choose a new name or, in the case of
2897 \\newcommand or \\newenvironment, switch to the \\renew ...  command.")
2898
2899     ("Counter too large." .
2900      "1. Some object that is numbered with letters, probably an item in a
2901 enumerated list, has received a number greater than 26. Either you're
2902 making a very long list or you've been resetting counter values.
2903
2904 2. Footnotes are being ``numbered'' with letters or footnote symbols
2905 and LaTeX has run out of letters or symbols. This is probably caused
2906 by too many \\thanks commands.")
2907
2908     ("Environment [^ ]* undefined." .
2909      "LaTeX has encountered a \\begin command for a nonexistent environment.
2910 You probably misspelled the environment name. ")
2911
2912     ("Float(s) lost." .
2913      "You put a figure or table environment or a \\marginpar command inside a
2914 parbox---either one made with a minipage environment or \\parbox
2915 command, or one constructed by LaTeX in making a footnote, figure,
2916 etc. This is an outputting error, and the offending environment or
2917 command may be quite a way back from the point where LaTeX discovered
2918 the problem. One or more figures, tables, and/or marginal notes have
2919 been lost, but not necessarily the one that caused the error.")
2920
2921     ("Illegal character in array arg." .
2922      "There is an illegal character in the argument of an array or tabular
2923 environment, or in the second argument of a \\multicolumn command.")
2924
2925     ("Missing \\\\begin{document}." .
2926      "LaTeX produced printed output before encountering a \\begin{document}
2927 command. Either you forgot the \\begin{document} command or there is
2928 something wrong in the preamble. The problem may be a stray character
2929 or an error in a declaration---for example, omitting the braces around
2930 an argument or forgetting the \\ in a command name.")
2931
2932     ("Missing p-arg in array arg.*" .
2933      "There is a p that is not followed by an expression in braces in the
2934 argument of an array or tabular environment, or in the second argument
2935 of a \\multicolumn command.")
2936
2937     ("Missing @-exp in array arg." .
2938      "There is an @ character not followed by an @-expression in the
2939 argument of an array or tabular environment, or in the second argument
2940 of a \\multicolumn command.")
2941
2942     ("No such counter." .
2943      "You have specified a nonexistent counter in a \\setcounter or
2944 \\addtocounter command. This is probably caused by a simple typing
2945 error.  However, if the error occurred while a file with the extension
2946 aux is being read, then you probably used a \\newcounter command
2947 outside the preamble.")
2948
2949     ("Not in outer par mode." .
2950      "You had a figure or table environment or a \\marginpar command in math
2951 mode or inside a parbox.")
2952
2953     ("\\\\pushtabs and \\\\poptabs don't match." .
2954      "LaTeX found a \\poptabs with no matching \\pushtabs, or has come to the
2955 \\end{tabbing} command with one or more unmatched \\pushtabs commands.")
2956
2957     ("Something's wrong--perhaps a missing \\\\item." .
2958      "The most probable cause is an omitted \\item command in a list-making
2959 environment. It is also caused by forgetting the argument of a
2960 thebibliography environment.")
2961
2962     ("Tab overflow." .
2963      "A \\= command has exceeded the maximum number of tab stops that LaTeX
2964 permits.")
2965
2966     ("There's no line here to end." .
2967      "A \\newline or \\\\ command appears between paragraphs, where it makes no
2968 sense. If you're trying to ``leave a blank line'', use a \\vspace
2969 command.")
2970
2971     ("This may be a LaTeX bug." .
2972      "LaTeX has become thoroughly confused. This is probably due to a
2973 previously detected error, but it is possible that you have found an
2974 error in LaTeX itself. If this is the first error message produced by
2975 the input file and you can't find anything wrong, save the file and
2976 contact the person listed in your Local Guide.")
2977
2978     ("Too deeply nested." .
2979      "There are too many list-making environments nested within one another.
2980 How many levels of nesting are permitted may depend upon what computer
2981 you are using, but at least four levels are provided, which should be
2982 enough.")
2983
2984     ("Too many unprocessed floats." .
2985      "While this error can result from having too many \\marginpar commands
2986 on a page, a more likely cause is forcing LaTeX to save more figures
2987 and tables than it has room for.  When typesetting its continuous
2988 scroll, LaTeX saves figures and tables separately and inserts them as
2989 it cuts off pages. This error occurs when LaTeX finds too many figure
2990 and/or table environments before it is time to cut off a page, a
2991 problem that is solved by moving some of the environments farther
2992 towards the end of the input file. The error can also be caused by a
2993 ``logjam''---a figure or table that cannot be printed causing others
2994 to pile up behind it, since LaTeX will not print figures or tables out
2995 of order. The jam can be started by a figure or table that either is
2996 too large to fit on a page or won't fit where its optional placement
2997 argument says it must go. This is likely to happen if the argument
2998 does not contain a p option.")
2999
3000     ("Undefined tab position." .
3001      "A \\>, \\+, \\-, or \\< command is trying to go to a nonexistent tab
3002 position---one not defined by a \\= command.")
3003
3004     ("\\\\< in mid line." .
3005      "A \\< command appears in the middle of a line in a tabbing environment.
3006 This command should come only at the beginning of a line.")
3007
3008     ("Double subscript." .
3009      "There are two subscripts in a row in a mathematical
3010 formula---something like x_{2}_{3}, which makes no sense.")
3011
3012     ("Double superscript." .
3013      "There are two superscripts in a row in a mathematical
3014 formula---something like x^{2}^{3}, which makes no sense.")
3015
3016     ("Extra alignment tab has been changed to \\\\cr." .
3017      "There are too many separate items (column entries) in a single row of
3018 an array or tabular environment. In other words, there were too many &
3019 's before the end of the row. You probably forgot the \\\\ at the end of
3020 the preceding row.")
3021
3022     ("Extra \\}, or forgotten \\$." .
3023      "The braces or math mode delimiters don't match properly. You probably
3024 forgot a {, \\[, \\(, or $.")
3025
3026     ("Font [^ ]* not loaded: Not enough room left." .
3027      "The document uses more fonts than TeX has room for. If different parts
3028 of the document use different fonts, then you can get around the
3029 problem by processing it in parts.")
3030
3031     ("I can't find file `.*'." .
3032      "TeX can't find a file that it needs. If the name of the missing file
3033 has the extension tex, then it is looking for an input file that you
3034 specified---either your main file or another file inserted with an
3035 \\input or \\include command. If the missing file has the extension sty
3036 , then you have specified a nonexistent document style or style
3037 option.")
3038
3039     ("Illegal parameter number in definition of .*" .
3040      "This is probably caused by a \\newcommand, \\renewcommand,
3041 \\newenvironment, or \\renewenvironment command in which a # is used
3042 incorrectly.  A # character, except as part of the command name \\#,
3043 can be used only to indicate an argument parameter, as in #2, which
3044 denotes the second argument. This error is also caused by nesting one
3045 of the above four commands inside another, or by putting a parameter
3046 like #2 in the last argument of a \\newenvironment or \\renewenvironment
3047 command.")
3048
3049     ("Illegal unit of measure ([^ ]* inserted)." .
3050      "If you just got a
3051
3052       ! Missing number, treated as zero.
3053
3054 error, then this is part of the same problem.  If not, it means that
3055 LaTeX was expecting a length as an argument and found a number
3056 instead.  The most common cause of this error is writing 0 instead of
3057 something like 0in for a length of zero, in which case typing return
3058 should result in correct output. However, the error can also be caused
3059 by omitting a command argument.")
3060
3061     ("Misplaced alignment tab character \\&." .
3062      "The special character &, which should be used only to separate items
3063 in an array or tabular environment, appeared in ordinary text. You
3064 probably meant to type \\&.")
3065
3066     ("Missing control sequence inserted." .
3067      "This is probably caused by a \\newcommand, \\renewcommand, \\newlength,
3068 or \\newsavebox command whose first argument is not a command name.")
3069
3070     ("Missing number, treated as zero." .
3071      "This is usually caused by a LaTeX command expecting but not finding
3072 either a number or a length as an argument. You may have omitted an
3073 argument, or a square bracket in the text may have been mistaken for
3074 the beginning of an optional argument. This error is also caused by
3075 putting \\protect in front of either a length command or a command such
3076 as \\value that produces a number.")
3077
3078     ("Missing [{}] inserted." .
3079      "TeX has become confused. The position indicated by the error locator
3080 is probably beyond the point where the incorrect input is.")
3081
3082     ("Missing \\$ inserted." .
3083      "TeX probably found a command that can be used only in math mode when
3084 it wasn't in math mode.  Remember that unless stated otherwise, all
3085 all the commands of Section 3.3 in LaTeX Book (Lamport) can be used
3086 only in math mode. TeX is not in math mode when it begins processing
3087 the argument of a box-making command, even if that command is inside a
3088 math environment. This error also occurs if TeX encounters a blank
3089 line when it is in math mode.")
3090
3091     ("Not a letter." .
3092      "Something appears in the argument of a \\hyphenation command that
3093 doesn't belong there.")
3094
3095     ("Paragraph ended before [^ ]* was complete." .
3096      "A blank line occurred in a command argument that shouldn't contain
3097 one. You probably forgot the right brace at the end of an argument.")
3098
3099     ("\\\\[^ ]*font [^ ]* is undefined .*" .
3100      "These errors occur when an uncommon font is used in math mode---for
3101 example, if you use a \\sc command in a formula inside a footnote,
3102 calling for a footnote-sized small caps font.  This problem is solved
3103 by using a \\load command.")
3104
3105     ("Font .* not found." .
3106      "You requested a family/series/shape/size combination that is totally
3107 unknown.  There are two cases in which this error can occur:
3108   1) You used the \\size macro to select a size that is not available.
3109   2) If you did not do that, go to your local `wizard' and
3110      complain fiercely that the font selection tables are corrupted!")
3111
3112     ("TeX capacity exceeded, sorry .*" .
3113      "TeX has just run out of space and aborted its execution. Before you
3114 panic, remember that the least likely cause of this error is TeX not
3115 having the capacity to process your document.  It was probably an
3116 error in your input file that caused TeX to run out of room. The
3117 following discussion explains how to decide whether you've really
3118 exceeded TeX's capacity and, if so, what to do. If the problem is an
3119 error in the input, you may have to use the divide and conquer method
3120 described previously to locate it. LaTeX seldom runs out of space on a
3121 short input file, so if running it on the last few pages before the
3122 error indicator's position still produces the error, then there's
3123 almost certainly something wrong in the input file.
3124
3125 The end of the error indicator tells what kind of space TeX ran out
3126 of. The more common ones are listed below, with an explanation of
3127 their probable causes.
3128
3129 buffer size
3130 ===========
3131 Can be caused by too long a piece of text as the argument
3132 of a sectioning, \\caption, \\addcontentsline, or \\addtocontents
3133 command. This error will probably occur when the \\end{document} is
3134 being processed, but it could happen when a \\tableofcontents,
3135 \\listoffigures, or \\listoftables command is executed. To solve this
3136 problem, use a shorter optional argument. Even if you're producing a
3137 table of contents or a list of figures or tables, such a long entry
3138 won't help the reader.
3139
3140 exception dictionary
3141 ====================
3142 You have used \\hyphenation commands to give TeX
3143 more hyphenation information than it has room for. Remove some of the
3144 less frequently used words from the \\hyphenation commands and insert
3145 \\- commands instead.
3146
3147 hash size
3148 =========
3149 Your input file defines too many command names and/or uses
3150 too many cross-ref- erencing labels.
3151
3152 input stack size
3153 ================
3154 This is probably caused by an error in a command
3155 definition. For example, the following command makes a circular
3156 definition, defining \\gnu in terms of itself:
3157
3158           \\newcommand{\\gnu}{a \\gnu} % This is wrong!
3159
3160 When TeX encounters this \\gnu command, it will keep chasing its tail
3161 trying to figure out what \\gnu should produce, and eventually run out
3162 of ``input stack''.
3163
3164 main memory size
3165 ================
3166 This is one kind of space that TeX can run out of when processing a
3167 short file. There are three ways you can run TeX out of main memory
3168 space: (1) defining a lot of very long, complicated commands, (2)
3169 making an index or glossary and having too many \\index or \\glossary
3170 commands on a single page, and (3) creating so complicated a page of
3171 output that TeX can't hold all the information needed to generate it.
3172 The solution to the first two problems is obvious: define fewer
3173 commands or use fewer \\index and \\glossary commands. The third problem
3174 is nastier. It can be caused by large tabbing, tabular, array, and
3175 picture environments. TeX's space may also be filled up with figures
3176 and tables waiting for a place to go.  To find out if you've really
3177 exceeded TeX's capacity in this way, put a \\clearpage command in your
3178 input file right before the place where TeX ran out of room and try
3179 running it again. If it doesn't run out of room with the \\clearpage
3180 command there, then you did exceed TeX's capacity.  If it still runs
3181 out of room, then there's probably an error in your file.  If TeX is
3182 really out of room, you must give it some help. Remember that TeX
3183 processes a complete paragraph before deciding whether to cut the
3184 page. Inserting a \\newpage command in the middle of the paragraph,
3185 where TeX should break the page, may save the day by letting TeX write
3186 the current page before processing the rest of the paragraph. (A
3187 \\pagebreak command won't help.) If the problem is caused by
3188 accumulated figures and tables, you can try to prevent them from
3189 accumulating---either by moving them further towards the end of the
3190 document or by trying to get them to come out sooner.  If you are
3191 still writing the document, simply add a \\clearpage command and forget
3192 about the problem until you're ready to produce the final version.
3193 Changes to the input file are likely to make the problem go away.
3194
3195 pool size
3196 =========
3197 You probably used too many cross-ref-erencing \\labels and/or defined
3198 too many new command names. More precisely, the labels and command
3199 names that you define have too many characters, so this problem can be
3200 solved by using shorter names. However, the error can also be caused
3201 by omitting the right brace that ends the argument of either a counter
3202 command such as \\setcounter, or a \\newenvironment or \\newtheorem
3203 command.
3204
3205 save size
3206 =========
3207 This occurs when commands, environments, and the scopes of
3208 declarations are nested too deeply---for example, by having the
3209 argument of a \\multiput command contain a picture environment that in
3210 turn has a \\footnotesize declaration whose scope contains a \\multiput
3211 command containing a ....")
3212
3213     ("Text line contains an invalid character." .
3214      "The input contains some strange character that it shouldn't. A mistake
3215 when creating the file probably caused your text editor to insert this
3216 character. Exactly what could have happened depends upon what text
3217 editor you used. If examining the input file doesn't reveal the
3218 offending character, consult the Local Guide for suggestions.")
3219
3220     ("Undefined control sequence."   .
3221      "TeX encountered an unknown command name. You probably misspelled the
3222 name. If this message occurs when a LaTeX command is being processed,
3223 the command is probably in the wrong place---for example, the error
3224 can be produced by an \\item command that's not inside a list-making
3225 environment. The error can also be caused by a missing \\documentclass
3226 command.")
3227
3228     ("Use of [^ ]* doesn't match its definition." .
3229      "It's probably one of the picture-drawing commands, and you have used
3230 the wrong syntax for specifying an argument. If it's \\@array that
3231 doesn't match its definition, then there is something wrong in an
3232 @-expression in the argument of an array or tabular
3233 environment---perhaps a fragile command that is not \\protect'ed.")
3234
3235     ("You can't use `macro parameter character \\#' in [^ ]* mode." .
3236      "The special character # has appeared in ordinary text. You probably
3237 meant to type \\#.")
3238
3239     ("Overfull \\\\hbox .*" .
3240      "Because it couldn't find a good place for a line break, TeX put more
3241 on this line than it should.")
3242
3243     ("Overfull \\\\vbox .*" .
3244      "Because it couldn't find a good place for a page break, TeX put more
3245 on the page than it should. ")
3246
3247     ("Underfull \\\\hbox .*" .
3248      "Check your output for extra vertical space.  If you find some, it was
3249 probably caused by a problem with a \\\\ or \\newline command---for
3250 example, two \\\\ commands in succession. This warning can also be
3251 caused by using the sloppypar environment or \\sloppy declaration, or
3252 by inserting a \\linebreak command.")
3253
3254     ("Underfull \\\\vbox .*" .
3255      "TeX could not find a good place to break the page, so it produced a
3256 page without enough text on it. ")
3257
3258     ;; New list items should be placed here
3259     ;;
3260     ;; ("err-regexp" . "context")
3261     ;;
3262     ;; the err-regexp item should match anything
3263
3264     (".*" . "No help available"))       ; end definition
3265   "A list of the form (\"err-regexp\" . \"context\") used by function
3266 `TeX-help-error' to display help-text on an error message or warning.
3267 err-regexp should be a regular expression matching the error message
3268 given from TeX/LaTeX, and context should be some lines describing that
3269 error."
3270   :group 'TeX-output
3271   :type '(repeat (cons :tag "Entry"
3272                        (regexp :tag "Match")
3273                        (string :format "Description:\n%v"))))
3274
3275 ;;; - Help
3276
3277 (defgroup TeX-error-description-faces nil
3278   "Faces used in error descriptions."
3279   :prefix "TeX-error-description-"
3280   :group 'TeX-output)
3281
3282 (defface TeX-error-description-error
3283   (if (and (featurep 'emacs)
3284            (>= emacs-major-version 22))
3285       ;; This is the same as `error' face in latest GNU Emacs versions.
3286       '((((class color) (min-colors 88) (background light))
3287          :foreground "Red1" :weight bold)
3288         (((class color) (min-colors 88) (background dark))
3289          :foreground "Pink" :weight bold)
3290         (((class color) (min-colors 16) (background light))
3291          :foreground "Red1" :weight bold)
3292         (((class color) (min-colors 16) (background dark))
3293          :foreground "Pink" :weight bold)
3294         (((class color) (min-colors 8))
3295          :foreground "red" :weight bold)
3296         (t (:inverse-video t :weight bold)))
3297     '((((type tty)) (:foreground "red" :bold t))
3298       (((class color)) (:forground "Red1" :bold t))
3299       (t (:inverse-video t :bold t))))
3300   "Face for \"Error\" string in error descriptions.")
3301
3302 (defface TeX-error-description-warning
3303   (if (and (featurep 'emacs)
3304            (>= emacs-major-version 22))
3305       ;; This is the same as `warning' face in latest GNU Emacs versions.
3306       '((((class color) (min-colors 16)) :foreground "DarkOrange" :weight bold)
3307         (((class color)) :foreground "yellow" :weight bold))
3308     '((((type tty)) (:foreground "yellow" :bold t))
3309       (((class color)) (:foregound "DarkOrange" :bold t))))
3310   "Face for \"Warning\" string in error descriptions.")
3311
3312 (defface TeX-error-description-tex-said
3313   (if (and (featurep 'emacs)
3314            (>= emacs-major-version 22))
3315       ;; This is the same as `font-lock-function-name-face' face in latest GNU
3316       ;; Emacs versions.
3317       '((((class color) (min-colors 88) (background light))
3318          :foreground "Blue1")
3319         (((class color) (min-colors 88) (background dark))
3320          :foreground "LightSkyBlue")
3321         (((class color) (min-colors 16) (background light))
3322          :foreground "Blue")
3323         (((class color) (min-colors 16) (background dark))
3324          :foreground "LightSkyBlue")
3325         (((class color) (min-colors 8))
3326          :foreground "blue" :weight bold)
3327         (t (:inverse-video t :weight bold)))
3328     '((((type tty)) (:foreground "blue" :bold t))
3329       (((class color)) (:foreground "Blue1" :bold t))
3330       (t (:inverse-video t :bold t))))
3331   "Face for \"TeX said\" string in error descriptions.")
3332
3333 (defface TeX-error-description-help
3334   '((t (:inherit TeX-error-description-tex-said)))
3335   "Face for \"Help\" string in error descriptions.")
3336
3337 (defun TeX-help-error (error output runbuffer type)
3338   "Print ERROR in context OUTPUT from RUNBUFFER in another window.
3339 TYPE is a symbol specifing if ERROR is a real error, a warning or
3340 a bad box."
3341
3342   (let ((old-buffer (current-buffer))
3343         (log-file (with-current-buffer runbuffer
3344                     (with-current-buffer TeX-command-buffer
3345                       (expand-file-name (TeX-active-master "log")))))
3346         (TeX-error-pointer 0))
3347
3348     ;; Find help text entry.
3349     (while (not (string-match (car (nth TeX-error-pointer
3350                                         TeX-error-description-list))
3351                               error))
3352       (setq TeX-error-pointer (+ TeX-error-pointer 1)))
3353
3354     (TeX-pop-to-buffer (get-buffer-create "*TeX Help*") nil t)
3355     (let ((inhibit-read-only t))
3356       (erase-buffer)
3357       (insert
3358        (cond
3359         ((equal type 'error)
3360          (propertize "ERROR" 'font-lock-face 'TeX-error-description-error))
3361         ((equal type 'warning)
3362          (propertize "WARNING" 'font-lock-face 'TeX-error-description-warning))
3363         ((equal type 'bad-box)
3364          (propertize "BAD BOX" 'font-lock-face 'TeX-error-description-warning)))
3365        ": " error
3366        (propertize "\n\n--- TeX said ---" 'font-lock-face
3367                    'TeX-error-description-tex-said)
3368        output
3369        (propertize "\n--- HELP ---\n" 'font-lock-face
3370                    'TeX-error-description-help)
3371        (let ((help (cdr (nth TeX-error-pointer
3372                              TeX-error-description-list))))
3373          (save-excursion
3374            (if (and (= (1+ TeX-error-pointer)
3375                        (length TeX-error-description-list))
3376                     (let* ((log-buffer (find-buffer-visiting log-file)))
3377                       (if log-buffer
3378                           (progn
3379                             (set-buffer log-buffer)
3380                             (revert-buffer t t))
3381                         (setq log-buffer
3382                               (find-file-noselect log-file))
3383                         (set-buffer log-buffer))
3384                       (auto-save-mode nil)
3385                       (setq buffer-read-only t)
3386                       (goto-char (point-min))
3387                       (search-forward error nil t 1))
3388                     (re-search-forward "^l\\." nil t)
3389                     (re-search-forward "^ [^\n]+$" nil t))
3390                (let ((start (1+ (point))))
3391                  (forward-char 1)
3392                  (re-search-forward "^$")
3393                  (concat "From the .log file...\n\n"
3394                          (buffer-substring start (point))))
3395              help)))))
3396     (goto-char (point-min))
3397     (TeX-special-mode)
3398     (TeX-pop-to-buffer old-buffer nil t)))
3399
3400 ;;; Error Overview
3401
3402 (defvar TeX-error-overview-active-buffer nil
3403   "The active buffer for the current error overview.")
3404
3405 (defvar TeX-error-overview-orig-frame nil
3406   "Frame from which the error overview has been launched.")
3407
3408 (defvar TeX-error-overview-orig-window nil
3409   "Window from which the error overview has been launched.")
3410
3411 (defcustom TeX-error-overview-setup nil
3412   "The frame setup of the error overview.
3413
3414 The possible value is: `separate-frame' (error oveview in a
3415 separate frame); with a nil value the current frame is used.
3416
3417 If the display does not support multi frame, the current frame
3418 will be used regardless of the value of this variable."
3419   :group 'TeX-output
3420   :type '(choice
3421           (const :tag "Error overview in separate frame" separate-frame)
3422           (const :tag "Use current frame" nil)))
3423
3424 (defun TeX-error-overview-setup ()
3425   "Return the frame setup of the error overview for the current display."
3426   (and (display-multi-frame-p) TeX-error-overview-setup))
3427
3428 (defun TeX-error-overview-goto-source (&optional button)
3429   "Go to the error point in the source.
3430 If optional argument BUTTON is non-nil, go to source associated
3431 to the selected error."
3432   (interactive)
3433   (let ((index (if button (button-get button 'id) (tabulated-list-get-id)))
3434         item window)
3435     (if index
3436         (progn
3437           ;; Select the source frame/window, if still live.
3438           (if (TeX-error-overview-setup)
3439               (if (frame-live-p TeX-error-overview-orig-frame)
3440                   (select-frame TeX-error-overview-orig-frame)
3441                 (error "You have deleted a vital frame---\
3442 please restart TeX error overview"))
3443             (if (window-live-p TeX-error-overview-orig-window)
3444                 (select-window TeX-error-overview-orig-window)
3445               (error "You have deleted a vital window---\
3446 please restart TeX error overview")))
3447           ;; Get the error details.
3448           (with-current-buffer TeX-error-overview-active-buffer
3449             (setq item (nth index TeX-error-list)
3450                   TeX-error-last-visited index))
3451           ;; Find the error and display the help.
3452           (with-current-buffer TeX-command-buffer
3453             ;; For consistency with `TeX-parse-TeX', use the major mode of
3454             ;; `TeX-command-buffer' when visiting the error point.
3455             (let ((default-major-mode major-mode))
3456               ;; Find the error and display the help.
3457               (apply #'TeX-find-display-help item)))
3458           ;; Return to the error overview.
3459           (if (TeX-error-overview-setup)
3460               (select-frame TeX-error-overview-frame)
3461             (if (setq window
3462                       (get-buffer-window TeX-error-overview-buffer-name))
3463                 ;; If error overview window is visible just select it.
3464                 (select-window window)
3465               ;; Otherwise, split the help window and display the error overview
3466               ;; near to it.  This should be the only reason for the error
3467               ;; overview window not being still visible after the beginning of
3468               ;; the function.
3469               (select-window
3470                (get-buffer-window (cond
3471                                    ((eq TeX-display-help 'expert)
3472                                     TeX-error-overview-active-buffer)
3473                                    (TeX-display-help  "*TeX Help*"))))
3474               (if (window-splittable-p (selected-window) t)
3475                   (split-window-horizontally)
3476                 (split-window-vertically))
3477               (switch-to-buffer TeX-error-overview-buffer-name))))
3478       (message "No more errors.")
3479       (beep))))
3480
3481 (defun TeX-error-overview-make-entries (&optional master-dir active-buffer)
3482   "Generate the list of errors to be printed using `tabulated-list-entries'.
3483 Write file names relative to MASTER-DIR when they are not absolute.
3484
3485 ACTIVE-BUFFER is used as buffer from which to extract the list of
3486 errors.  If nil, defaults to `TeX-error-overview-active-buffer'."
3487   (with-current-buffer (or active-buffer TeX-error-overview-active-buffer)
3488     (let ((id 0)
3489           type file line msg entries)
3490       (mapc
3491        (lambda (entry)
3492          (setq type (nth 0 entry)
3493                file (nth 1 entry)
3494                line (nth 2 entry)
3495                msg  (nth 3 entry))
3496          ;; Add the entry only if it isn't to be skipped.
3497          (unless (TeX-error-list-skip-warning-p type (nth 10 entry))
3498            (push
3499             (list
3500              ;; ID.
3501              id
3502              (vector
3503               ;; File.
3504               (if (stringp file)
3505                   (if (file-name-absolute-p file)
3506                       file
3507                     (file-relative-name file master-dir))
3508                 "")
3509               ;; Line.
3510               (if (numberp line)
3511                   (number-to-string line)
3512                 "")
3513               ;; Type.
3514               (cond
3515                ((equal type 'error)
3516                 (propertize "Error" 'font-lock-face 'TeX-error-description-error))
3517                ((equal type 'warning)
3518                 (propertize "Warning" 'font-lock-face
3519                             'TeX-error-description-warning))
3520                ((equal type 'bad-box)
3521                 (propertize "Bad box" 'font-lock-face
3522                             'TeX-error-description-warning))
3523                (t
3524                 ""))
3525               ;; Message.
3526               (list (if (stringp msg)
3527                         ;; Sometimes, the message can be longer than one line,
3528                         ;; but print here only the first one.
3529                         (progn
3530                           (string-match "^.*" msg)
3531                           (match-string 0 msg))
3532                       "")
3533                     'face 'link
3534                     'follow-link t
3535                     'id id
3536                     'action 'TeX-error-overview-goto-source)))
3537             entries))
3538          ;; Increase the `id' counter in any case.
3539          (setq id (1+ id)))
3540        TeX-error-list)
3541       (reverse entries))))
3542
3543 (defun TeX-error-overview-next-error (&optional arg)
3544   "Move to the next line and find the associated error.
3545
3546 A prefix ARG specifies how many error messages to move; negative
3547 means move back to previous error messages."
3548   (interactive "p")
3549   (if (= (forward-line arg) 0)
3550       (TeX-error-overview-goto-source)
3551     ;; If there are lines left to move we are at the beginning or at the end of
3552     ;; the buffer and there are no more errors.
3553     (message "No more errors.")
3554     (beep)))
3555
3556 (defun TeX-error-overview-previous-error (&optional arg)
3557   "Move to the previous line and find the associated error.
3558
3559 Prefix arg N says how many error messages to move backward (or
3560 forward, if negative)."
3561   (interactive "p")
3562   (TeX-error-overview-next-error (- arg)))
3563
3564 (defun TeX-error-overview-jump-to-source ()
3565   "Display the help and move point to the error source."
3566   (interactive)
3567   (TeX-error-overview-goto-source)
3568   (pop-to-buffer
3569    (save-window-excursion
3570      (select-window TeX-error-overview-orig-window)
3571      (current-buffer))))
3572
3573 (defun TeX-error-overview-goto-log ()
3574   "Display the current error in log buffer."
3575   (interactive)
3576   (let ((TeX-display-help 'expert))
3577     (TeX-error-overview-goto-source)))
3578
3579 (defun TeX-error-overview-toggle-debug-bad-boxes ()
3580   "Run `TeX-toggle-debug-bad-boxes' and update entries list."
3581   (interactive)
3582   (TeX-toggle-debug-bad-boxes)
3583   (setq tabulated-list-entries
3584         (TeX-error-overview-make-entries
3585          (with-current-buffer TeX-command-buffer (TeX-master-directory))))
3586   (tabulated-list-init-header)
3587   (tabulated-list-print))
3588
3589 (defun TeX-error-overview-toggle-debug-warnings ()
3590   "Run `TeX-toggle-debug-warnings' and update entries list."
3591   (interactive)
3592   (TeX-toggle-debug-warnings)
3593   (setq tabulated-list-entries
3594         (TeX-error-overview-make-entries
3595          (with-current-buffer TeX-command-buffer (TeX-master-directory))))
3596   (tabulated-list-init-header)
3597   (tabulated-list-print))
3598
3599 (defun TeX-error-overview-toggle-suppress-ignored-warnings ()
3600   "Toggle visibility of ignored warnings and update entries list."
3601   (interactive)
3602   (TeX-toggle-suppress-ignored-warnings)
3603   (setq tabulated-list-entries
3604         (TeX-error-overview-make-entries
3605          (with-current-buffer TeX-command-buffer (TeX-master-directory))))
3606   (tabulated-list-init-header)
3607   (tabulated-list-print))
3608
3609 (defun TeX-error-overview-quit ()
3610   "Delete the window or the frame of the error overview."
3611   (interactive)
3612   (if (TeX-error-overview-setup)
3613       (delete-frame TeX-error-overview-frame)
3614     (delete-window))
3615   (setq TeX-error-overview-orig-frame nil))
3616
3617 (defvar TeX-error-overview-mode-map
3618   (let ((map (make-sparse-keymap)))
3619     (define-key map "b"    'TeX-error-overview-toggle-debug-bad-boxes)
3620     (define-key map "j"    'TeX-error-overview-jump-to-source)
3621     (define-key map "l"    'TeX-error-overview-goto-log)
3622     (define-key map "n"    'TeX-error-overview-next-error)
3623     (define-key map "p"    'TeX-error-overview-previous-error)
3624     (define-key map "q"    'TeX-error-overview-quit)
3625     (define-key map "w"    'TeX-error-overview-toggle-debug-warnings)
3626     (define-key map "x"    'TeX-error-overview-toggle-suppress-ignored-warnings)
3627     (define-key map "\C-m" 'TeX-error-overview-goto-source)
3628     map)
3629   "Local keymap for `TeX-error-overview-mode' buffers.")
3630
3631 (easy-menu-define TeX-error-overview-menu
3632   TeX-error-overview-mode-map
3633   "Menu used in TeX error overview mode."
3634   (TeX-menu-with-help
3635    '("TeX errors"
3636      ["Next error" TeX-error-overview-next-error
3637       :help "Jump to the next error"]
3638      ["Previous error" TeX-error-overview-previous-error
3639       :help "Jump to the previous error"]
3640      ["Go to source" TeX-error-overview-goto-source
3641       :help "Show the error in the source"]
3642      ["Jump to source" TeX-error-overview-jump-to-source
3643       :help "Move point to the error in the source"]
3644      ["Go to log" TeX-error-overview-goto-log
3645       :help "Show the error in the log buffer"]
3646      "-"
3647      ["Debug Bad Boxes" TeX-error-overview-toggle-debug-bad-boxes
3648       :style toggle :selected TeX-debug-bad-boxes
3649       :help "Show overfull and underfull boxes"]
3650      ["Debug Warnings" TeX-error-overview-toggle-debug-warnings
3651       :style toggle :selected TeX-debug-warnings
3652       :help "Show warnings"]
3653      ["Ignore Unimportant Warnings"
3654       TeX-error-overview-toggle-suppress-ignored-warnings
3655       :style toggle :selected TeX-suppress-ignored-warnings
3656       :help "Hide specified warnings"]
3657      "-"
3658      ["Quit" TeX-error-overview-quit
3659       :help "Quit"])))
3660
3661 (defvar TeX-error-overview-list-entries nil
3662   "List of errors to be used in the error overview.")
3663
3664 (define-derived-mode TeX-error-overview-mode tabulated-list-mode
3665                      "TeX errors"
3666   "Major mode for listing TeX errors."
3667   (setq tabulated-list-format [("File" 25 nil)
3668                                ("Line" 4 nil :right-align t)
3669                                ("Type" 7 nil)
3670                                ("Message" 0 nil)]
3671         tabulated-list-padding 1
3672         tabulated-list-entries TeX-error-overview-list-entries)
3673   (tabulated-list-init-header)
3674   (tabulated-list-print)
3675   (easy-menu-add TeX-error-overview-menu TeX-error-overview-mode-map))
3676
3677 (defcustom TeX-error-overview-frame-parameters
3678   '((name . "TeX errors")
3679     (title . "TeX errors")
3680     (height . 10)
3681     (width . 80)
3682     (top . (- 0))
3683     (left . (- 0))
3684     (unsplittable . t)
3685     (minibuffer . nil)
3686     (vertical-scroll-bars . t)
3687     (tool-bar-lines . 0))
3688   "Parameters of the error overview frame."
3689   :group 'TeX-output
3690   :type 'alist
3691   :options '((name string) (title string) (height integer) (width integer)
3692              (top integer) (left integer) (unsplittable boolean)
3693              (minibuffer boolean) (vertical-scroll-bars boolean)
3694              (tool-bar-lines integer)))
3695
3696 (defcustom TeX-error-overview-open-after-TeX-run nil
3697   "Whether to open automatically the error overview after running TeX."
3698   :group 'TeX-output
3699   :type 'boolean)
3700
3701 (defun TeX-error-overview ()
3702   "Show an overview of the errors occurred in the last TeX run."
3703   (interactive)
3704   ;; Check requirements before start.
3705   (if (fboundp 'tabulated-list-mode)
3706       (if (setq TeX-error-overview-active-buffer (TeX-active-buffer))
3707           ;; `TeX-error-overview-list-entries' is going to be used only as value
3708           ;; of `tabulated-list-entries' in `TeX-error-overview-mode'.  In
3709           ;; principle, we don't need `TeX-error-overview-list-entries', but
3710           ;; `tabulated-list-entries' is buffer-local and we need the list of
3711           ;; entries before creating the error overview buffer in order to
3712           ;; decide whether we need to show anything.
3713           (if (setq TeX-error-overview-list-entries
3714                     (TeX-error-overview-make-entries
3715                      (TeX-master-directory)))
3716               (progn
3717                 (setq TeX-error-overview-orig-window (selected-window)
3718                       TeX-error-overview-orig-frame
3719                       (window-frame TeX-error-overview-orig-window))
3720                 ;; Create the error overview buffer.  This is
3721                 ;; automatically killed before running TeX commands, so if
3722                 ;; exists it is up-to-date and doesn't need to be
3723                 ;; re-created.
3724                 (unless (get-buffer TeX-error-overview-buffer-name)
3725                   (with-current-buffer
3726                       (get-buffer-create TeX-error-overview-buffer-name)
3727                     (TeX-error-overview-mode)))
3728                 ;; Move point to the line associated to the last visited
3729                 ;; error.
3730                 (with-current-buffer TeX-error-overview-buffer-name
3731                   (goto-char (point-min))
3732                   (forward-line (with-current-buffer
3733                                     TeX-error-overview-active-buffer
3734                                   TeX-error-last-visited))
3735                   ;; Create a new frame for the error overview or display the
3736                   ;; buffer in the same frame, depending on the setup.
3737                   (if (TeX-error-overview-setup)
3738                       (if (frame-live-p TeX-error-overview-frame)
3739                           ;; Do not create a duplicate frame if there is
3740                           ;; already one, just select it.
3741                           (select-frame-set-input-focus
3742                            TeX-error-overview-frame)
3743                         ;; Create a new frame and store its name.
3744                         (select-frame
3745                          (setq TeX-error-overview-frame
3746                                (make-frame
3747                                 TeX-error-overview-frame-parameters)))
3748                         (set-window-buffer (selected-window)
3749                                            TeX-error-overview-buffer-name)
3750                         (set-window-dedicated-p (selected-window) t))
3751                     (TeX-pop-to-buffer TeX-error-overview-buffer-name))))
3752             (error (concat "No error or warning to show"
3753                            ;; Suggest to display warnings and bad boxes with the
3754                            ;; appropriate key-bindings if there are such
3755                            ;; messages in the output buffer.  Rationale of the
3756                            ;; test: `TeX-error-overview-list-entries' is nil,
3757                            ;; but if `TeX-error-list' is not nil it means that
3758                            ;; there are hidden warnings/bad boxes.
3759                            (when (TeX-process-get-variable (TeX-active-master)
3760                                                            'TeX-error-list)
3761                              (format ".  Type `%s' and `%s' to display \
3762 warnings and bad boxes"
3763                                      (substitute-command-keys
3764                                       "\\<TeX-mode-map>\\[TeX-toggle-debug-warnings]")
3765                                      (substitute-command-keys
3766                                       "\\<TeX-mode-map>\\[TeX-toggle-debug-bad-boxes]"))))))
3767         (error "No process for this document"))
3768     (error "Error overview is available only in Emacs 24 or later")))
3769
3770 ;;; Output mode
3771
3772 (defalias 'TeX-special-mode
3773   (if (fboundp 'special-mode)
3774       (progn
3775         (defvaralias 'TeX-special-mode-map 'special-mode-map)
3776         #'special-mode)
3777     (defvar TeX-special-mode-map
3778       (let ((map (make-sparse-keymap)))
3779         (suppress-keymap map)
3780         (define-key map "q" (if (fboundp 'quit-window)
3781                                 'quit-window
3782                               'bury-buffer))
3783         (define-key map " " (if (fboundp 'scroll-up-command)
3784                                 'scroll-up-command
3785                               'scroll-up))
3786         (define-key map [backspace] (if (fboundp 'scroll-down-command)
3787                                         'scroll-down-command
3788                                       'scroll-down))
3789         (define-key map "\C-?" (if (fboundp 'scroll-down-command)
3790                                    'scroll-down-command
3791                                  'scroll-down))
3792         (define-key map "?" 'describe-mode)
3793         (define-key map "h" 'describe-mode)
3794         (define-key map ">" 'end-of-buffer)
3795         (define-key map "<" 'beginning-of-buffer)
3796         (define-key map "g" 'revert-buffer)
3797         map)
3798       "Keymap for `TeX-special-mode-map'.")
3799     (lambda ()
3800       "Placeholder mode for Emacsen which don't have `special-mode'.")))
3801
3802 (defvar TeX-output-mode-map
3803   (let ((map (make-sparse-keymap)))
3804     (set-keymap-parent map TeX-special-mode-map)
3805     (define-key map "n" 'TeX-next-error)
3806     (define-key map "p" 'TeX-previous-error)
3807     (define-key map "b" 'TeX-toggle-debug-bad-boxes)
3808     (define-key map "w" 'TeX-toggle-debug-warnings)
3809     (define-key map "i" (lambda ()
3810                           (interactive)
3811                           (with-current-buffer TeX-command-buffer
3812                             (TeX-interactive-mode (if TeX-interactive-mode -1 1)))))
3813     (define-key map "s" (lambda ()
3814                           (interactive)
3815                           (with-current-buffer TeX-command-buffer
3816                             (TeX-source-correlate-mode (if TeX-source-correlate-mode -1 1)))))
3817     map)
3818   "Keymap for `TeX-output-mode'.")
3819
3820 (define-derived-mode TeX-output-mode TeX-special-mode "TeX Output"
3821   "Major mode for viewing TeX output.
3822 \\{TeX-output-mode-map} "
3823   :syntax-table nil
3824   (set (make-local-variable 'revert-buffer-function)
3825        #'TeX-output-revert-buffer)
3826   ;; special-mode makes it read-only which prevents input from TeX.
3827   (setq buffer-read-only nil))
3828
3829 (defun TeX-output-revert-buffer (_ignore-auto _noconfirm)
3830   "Rerun the TeX command which of which this buffer was the output."
3831   (goto-char (point-min))
3832   (if (looking-at "Running `\\(.*\\)' on `\\(.*\\)' with ``\\(.*\\)''$")
3833       (let ((name (match-string 1))
3834             (file (match-string 2)))
3835         (with-current-buffer TeX-command-buffer
3836           (TeX-command name (if (string-match TeX-region file)
3837                                 #'TeX-region-file
3838                               #'TeX-master-file))))
3839     (error "Unable to find what command to run")))
3840
3841 (provide 'tex-buf)
3842
3843 ;;; tex-buf.el ends here