Add 2012 to FSF copyright years for Emacs files (do not merge to trunk)
[bpt/emacs.git] / lisp / textmodes / makeinfo.el
index 718d96e..0c0f5ad 100644 (file)
@@ -1,16 +1,18 @@
 ;;; makeinfo.el --- run makeinfo conveniently
 
-;; Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+;; Copyright (C) 1991, 1993, 2001, 2002, 2003, 2004,
+;;   2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 
-;; Author: Robert J. Chassell      
+;; Author: Robert J. Chassell
 ;; Maintainer: FSF
+;; Keywords: docs convenience
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -18,9 +20,7 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 ;;; Variables used by `makeinfo'
 
 (require 'compile)
+(require 'info)
+
+(defvar tex-end-of-header)
+(defvar tex-start-of-header)
+
 
 (defgroup makeinfo nil
-  "Run makeinfo conveniently"
+  "Run makeinfo conveniently."
   :group 'docs)
 
 
@@ -59,7 +64,7 @@ The name of the file is appended to this string, separated by a space."
   :group 'makeinfo)
 
 (defcustom makeinfo-options "--fill-column=70"
-  "*String containing options for running `makeinfo'.  
+  "*String containing options for running `makeinfo'.
 Do not include `--footnote-style' or `--paragraph-indent';
 the proper way to specify those is with the Texinfo commands
 `@footnotestyle` and `@paragraphindent'."
@@ -77,6 +82,9 @@ the proper way to specify those is with the Texinfo commands
 (defvar makeinfo-output-file-name nil
   "Info file name used for text output by `makeinfo'.")
 
+(defvar makeinfo-output-node-name nil
+  "Node name to visit in output file, for `makeinfo-buffer'.")
+
 \f
 ;;; The `makeinfo' function definitions
 
@@ -86,7 +94,7 @@ the proper way to specify those is with the Texinfo commands
 This command does not offer the `next-error' feature since it would
 apply to a temporary file, not the original; use the `makeinfo-buffer'
 command to gain use of `next-error'."
-  
+
   (interactive "r")
   (let (filename-or-header
         filename-or-header-beginning
@@ -99,11 +107,11 @@ command to gain use of `next-error'."
           (concat
            (make-temp-file
             (substring (buffer-file-name)
-                       0 
-                       (or (string-match "\\.tex" (buffer-file-name)) 
+                       0
+                       (or (string-match "\\.tex" (buffer-file-name))
                            (length (buffer-file-name)))))
            ".texinfo"))
-    
+
     (save-excursion
       (save-restriction
         (widen)
@@ -111,34 +119,34 @@ command to gain use of `next-error'."
         (let ((search-end (save-excursion (forward-line 100) (point))))
           ;; Find and record the Info filename,
           ;; or else explain that a filename is needed.
-          (if (re-search-forward 
+          (if (re-search-forward
                "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*"
                search-end t)
-              (setq makeinfo-output-file-name 
+              (setq makeinfo-output-file-name
                     (buffer-substring (match-beginning 1) (match-end 1)))
             (error
              "The texinfo file needs a line saying: @setfilename <name>"))
 
           ;; Find header and specify its beginning and end.
           (goto-char (point-min))
-          (if (and 
-               (prog1 
+          (if (and
+               (prog1
                    (search-forward tex-start-of-header search-end t)
                  (beginning-of-line)
                  ;; Mark beginning of header.
                  (setq filename-or-header-beginning (point)))
-               (prog1 
+               (prog1
                    (search-forward tex-end-of-header nil t)
                  (beginning-of-line)
                  ;; Mark end of header
                  (setq filename-or-header-end (point))))
-              
+
               ;; Insert the header into the temporary file.
               (write-region
                (min filename-or-header-beginning region-beginning)
                filename-or-header-end
                makeinfo-temp-file nil nil)
-            
+
             ;; Else no header; insert @filename line into temporary file.
             (goto-char (point-min))
             (search-forward "@setfilename" search-end t)
@@ -150,7 +158,7 @@ command to gain use of `next-error'."
              (min filename-or-header-beginning region-beginning)
              filename-or-header-end
              makeinfo-temp-file nil nil))
-          
+
           ;; Insert the region into the file.
           (write-region
            (max region-beginning filename-or-header-end)
@@ -163,73 +171,102 @@ command to gain use of `next-error'."
              (concat makeinfo-run-command
                      " "
                      makeinfo-options
-                     " " 
+                     " "
                      makeinfo-temp-file)
-             "Use `makeinfo-buffer' to gain use of the `next-error' command"
-            nil)))))))
-
-;;; Actually run makeinfo.  COMMAND is the command to run.
-;;; ERROR-MESSAGE is what to say when next-error can't find another error.
-;;; If PARSE-ERRORS is non-nil, do try to parse error messages.
-(defun makeinfo-compile (command error-message parse-errors)
-  (let ((buffer
-        (compile-internal command error-message nil
-                          (and (not parse-errors)
-                               ;; If we do want to parse errors, pass nil.
-                               ;; Otherwise, use this function, which won't
-                               ;; ever find any errors.
-                               (lambda (&rest ignore)
-                                 (setq compilation-error-list nil))))))
-    (set-process-sentinel (get-buffer-process buffer)
-                         'makeinfo-compilation-sentinel)))
+            t
+             'makeinfo-compilation-sentinel-region)))))))
+
+(defun makeinfo-next-error (arg reset)
+  "This function is used to disable `next-error' if the user has
+used `makeinfo-region'.  Since the compilation process is used on
+a temporary file in that case, calling `next-error' would give
+nonsensical results."
+  (error "Use `makeinfo-buffer' to gain use of the `next-error' command"))
+
+;; Actually run makeinfo.  COMMAND is the command to run.  If
+;; DISABLE-ERRORS is non-nil, disable `next-error' by setting
+;; `next-error-function' to `makeinfo-next-error' in the compilation
+;; buffer.
+(defun makeinfo-compile (command disable-errors sentinel)
+  (let ((buffer (compilation-start command)))
+    (with-current-buffer buffer
+      (setq next-error-function
+           (if disable-errors
+               'makeinfo-next-error
+             'compilation-next-error-function)))
+    (set-process-sentinel (get-buffer-process buffer) sentinel)))
 
 ;; Delete makeinfo-temp-file after processing is finished,
 ;; and visit Info file.
 ;; This function is called when the compilation process changes state.
 ;; Based on `compilation-sentinel' in compile.el
-(defun makeinfo-compilation-sentinel (proc msg)
+(defun makeinfo-compilation-sentinel-region (proc msg)
+  "Sentinel for `makeinfo-compile' run from `makeinfo-region'."
   (compilation-sentinel proc msg)
-  (if (and makeinfo-temp-file (file-exists-p makeinfo-temp-file))
-      (delete-file makeinfo-temp-file))
-  ;; Always use the version on disk.
-  (if (get-file-buffer makeinfo-output-file-name)
-      (progn (set-buffer makeinfo-output-file-name)
-            (revert-buffer t t))
-    (find-file makeinfo-output-file-name))
-  (goto-char (point-min)))
+  (when (memq (process-status proc) '(signal exit))
+    (if (file-exists-p makeinfo-temp-file)
+       (delete-file makeinfo-temp-file))
+    ;; Always use the version on disk.
+    (let ((buffer (get-file-buffer makeinfo-output-file-name)))
+      (if buffer
+         (with-current-buffer buffer
+           (revert-buffer t t))
+       (setq buffer (find-file-noselect makeinfo-output-file-name)))
+      (if (window-dedicated-p (selected-window))
+         (switch-to-buffer-other-window buffer)
+       (switch-to-buffer buffer)))
+    (goto-char (point-min))))
+
+(defun makeinfo-current-node ()
+  "Return the name of the node containing point, in a texinfo file."
+  (save-excursion
+    (end-of-line)           ; in case point is at the start of an @node line
+    (if (re-search-backward "^@node\\s-+\\([^,\n]+\\)" (point-min) t)
+        (match-string 1)
+      "Top")))
 
 (defun makeinfo-buffer ()
   "Make Info file from current buffer.
 
-Use the \\[next-error] command to move to the next error 
+Use the \\[next-error] command to move to the next error
 \(if there are errors\)."
+
   (interactive)
   (cond ((null buffer-file-name)
          (error "Buffer not visiting any file"))
         ((buffer-modified-p)
          (if (y-or-n-p "Buffer modified; do you want to save it? ")
              (save-buffer))))
-  
+
   ;; Find and record the Info filename,
   ;; or else explain that a filename is needed.
   (save-excursion
     (goto-char (point-min))
     (let ((search-end (save-excursion (forward-line 100) (point))))
-      (if (re-search-forward 
+      (if (re-search-forward
            "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*"
            search-end t)
-          (setq makeinfo-output-file-name 
-                (buffer-substring (match-beginning 1) (match-end 1)))
+          (setq makeinfo-output-file-name
+                (expand-file-name
+                 (buffer-substring (match-beginning 1) (match-end 1))))
         (error
          "The texinfo file needs a line saying: @setfilename <name>"))))
-  
+  (setq makeinfo-output-node-name (makeinfo-current-node))
+
   (save-excursion
     (makeinfo-compile
      (concat makeinfo-run-command " " makeinfo-options
-             " " buffer-file-name)
-     "No more errors."
-     t)))
+            " " buffer-file-name)
+     nil
+     'makeinfo-compilation-sentinel-buffer)))
+
+(defun makeinfo-compilation-sentinel-buffer (proc msg)
+  "Sentinel for `makeinfo-compile' run from `makeinfo-buffer'."
+  (compilation-sentinel proc msg)
+  (when (memq (process-status proc) '(signal exit))
+    (when (file-exists-p makeinfo-output-file-name)
+      (Info-revert-find-node
+       makeinfo-output-file-name makeinfo-output-node-name))))
 
 (defun makeinfo-recenter-compilation-buffer (linenum)
   "Redisplay `*compilation*' buffer so most recent output can be seen.
@@ -252,4 +289,5 @@ line LINE of the window, or centered if LINE is nil."
 ;;; Place `provide' at end of file.
 (provide 'makeinfo)
 
+;; arch-tag: 5f810713-3de2-4e20-8030-4bc3dd0d9604
 ;;; makeinfo.el ends here