]> code.delx.au - gnu-emacs/blobdiff - lisp/info-xref.el
Less 'make' chatter in batch mode
[gnu-emacs] / lisp / info-xref.el
index a92d9d89da62c8fb395271e59c4d6e717863059e..3e871a1a3fc88fd303a3d0cc5772460bf1457957 100644 (file)
@@ -1,7 +1,6 @@
 ;;; info-xref.el --- check external references in an Info document
 
-;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 2003-2015 Free Software Foundation, Inc.
 
 ;; Author: Kevin Ryde <user42@zip.com.au>
 ;; Keywords: docs
 ;;; Code:
 
 (require 'info)
-(eval-when-compile
-  (require 'cl)) ;; for `incf'
+(eval-when-compile (require 'cl-lib))   ; for `cl-incf'
+
+(defgroup info-xref nil
+  "Check external cross-references in Info documents."
+  :group 'docs)                         ; FIXME right parent?
+
+;; Should this even be an option?
+(defcustom info-xref-case-fold nil
+  "Non-nil means node checks should ignore case.
+When following cross-references, the Emacs Info reader first tries a
+case-sensitive match, then if that fails a case-insensitive one.
+The standalone Info reader does not do this, nor does this work
+for links in the html versions of Texinfo manuals.  Therefore
+to ensure your cross-references work on the widest range of platforms,
+you should set this variable to nil."
+  :group 'info-xref
+  :type 'boolean
+  :version "24.4")
+
 
 ;;-----------------------------------------------------------------------------
 ;; vaguely generic
@@ -152,7 +168,7 @@ overall good/bad count summary inserted at the very end."
      (unless info-xref-in-progress
        (info-xref-output "done, %d good, %d bad, %d unavailable"
                          info-xref-good info-xref-bad info-xref-unavail))))
-  
+
 (defun info-xref-output (fmt &rest args)
   "Emit a `format'-ed message FMT+ARGS to the `info-xref-output-buffer'."
   (with-current-buffer info-xref-output-buffer
@@ -201,12 +217,13 @@ buffer's line and column of point."
     (save-excursion
       (save-window-excursion
         (prog1
-            (condition-case err
+            (condition-case nil
                 (progn
                   (Info-goto-node node
                                   (when (get-buffer "*info*")
                                     (set-buffer "*info*")
-                                    "xref - temporary"))
+                                    "xref - temporary")
+                                  (not info-xref-case-fold))
                   t)
               (error nil))
           (unless (equal (current-buffer) oldbuf)
@@ -240,11 +257,11 @@ buffer's line and column of point."
 
         ;; if the file exists, try the node
         (cond ((not (cdr (assoc file info-xref-xfile-alist)))
-               (incf info-xref-unavail))
+               (cl-incf info-xref-unavail))
               ((info-xref-goto-node-p node)
-               (incf info-xref-good))
+               (cl-incf info-xref-good))
               (t
-               (incf info-xref-bad)
+               (cl-incf info-xref-bad)
                (info-xref-output-error "no such node: %s" node)))))))
 
 
@@ -314,7 +331,7 @@ should be harmless."
   (interactive)
   (info-xref-check-list (info-xref-all-info-files)))
 
-;; An alternative for geting only top-level files here would be to simply
+;; An alternative for getting only top-level files here would be to simply
 ;; return all files and have info-xref-check-list not follow "Indirect:".
 ;; The current way seems better because it (potentially) gets the proper
 ;; top-level filename into the error messages, and suppresses duplicate "not
@@ -369,13 +386,28 @@ in the path."
                     (forward-line)))
               (info-xref-check-buffer))))))))
 
+(defconst info-xref-node-re "\\(?1:\\(([^)]*)\\)[^.,]+\\)"
+  "Regexp with subexp 1 matching (manual)node.")
+
+;; "@xref{node,crossref,manual}." produces:
+;; texinfo 4 or 5:
+;; *Note crossref: (manual)node.
+;; "@xref{node,,manual}." produces:
+;; texinfo 4:
+;; *Note node: (manual)node.
+;; texinfo 5:
+;; *Note (manual)node::.
+(defconst info-xref-note-re
+  (concat "\\*[Nn]ote[ \n\t]+\\(?:"
+          "[^:]*:[ \n\t]+" info-xref-node-re "\\|"
+          info-xref-node-re "::\\)[.,]")
+  "Regexp matching a \"*note...\" link.")
+
 (defun info-xref-check-buffer ()
   "Check external references in the info file in the current buffer.
 This should be the raw file contents, not `Info-mode'."
   (goto-char (point-min))
-  (while (re-search-forward
-          "\\*[Nn]ote[ \n\t]+[^:]*:[ \n\t]+\\(\\(([^)]*)\\)[^.,]+\\)[.,]"
-          nil t)
+  (while (re-search-forward info-xref-note-re nil t)
     (save-excursion
       (goto-char (match-beginning 1)) ;; start of nodename as error position
       (info-xref-check-node (match-string 1)))))
@@ -414,7 +446,7 @@ and can take a long time."
    (unless (boundp 'viper-mode)
      (setq viper-mode nil))  ;; avoid viper.el ask about viperizing
    (unless (boundp 'gnus-registry-install)
-     (setq gnus-registry-install nil))  ;; avoid gnus-registery.el querying
+     (setq gnus-registry-install nil))  ;; avoid gnus-registry.el querying
 
    (mapatoms
     (lambda (symbol)
@@ -448,8 +480,8 @@ and can take a long time."
           (if (eq :tag (cadr link))
               (setq link (cddr link)))
           (if (info-xref-goto-node-p (cadr link))
-              (incf info-xref-good)
-            (incf info-xref-bad)
+              (cl-incf info-xref-good)
+            (cl-incf info-xref-bad)
             ;; symbol-file gives nil for preloaded variables, would need
             ;; to copy what describe-variable does to show the right place
             (info-xref-output "Symbol `%s' (file %s): cannot goto node: %s"
@@ -479,20 +511,22 @@ in the files, the Lisp code checked doesn't have to be loaded,
 and links can be in the file commentary or elsewhere too.  Even
 .elc files can usually be checked successfully if you don't have
 the sources handy."
-
   (interactive
-   (let* ((default       (and buffer-file-name
+   (let* ((default (and buffer-file-name
                               (file-relative-name buffer-file-name)))
-          (prompt        (if default
-                             (format "Filename with wildcards (%s): "
-                                     default)
-                           "Filename with wildcards: "))
-          (pattern       (read-file-name prompt nil default))
-          (filename-list (file-expand-wildcards pattern
-                                                t))) ;; absolute filenames
-     (eval-and-compile
-       (require 'cl)) ;; for `remove-if'
-     (setq filename-list (remove-if 'info-xref-lock-file-p filename-list))
+          (prompt (if default
+                      (format "Filename with wildcards (%s): "
+                              default)
+                    "Filename with wildcards: "))
+          (pattern (read-file-name prompt nil default))
+          ;; absolute filenames
+          (filename-list (file-expand-wildcards pattern t))
+          newlist)
+     (setq filename-list
+           (dolist (file filename-list (nreverse newlist))
+             (or (info-xref-lock-file-p file)
+                 (file-directory-p file)
+                 (push file newlist))))
      (unless filename-list
        (error "No files: %S" pattern))
      (list filename-list)))