X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/99a33b77e15b9a075024701d060d912b2fd87caf..7095596ac3ece75b7fb98be7a47e4715a54842c2:/lisp/info-xref.el diff --git a/lisp/info-xref.el b/lisp/info-xref.el index 41da9d12c9..cafc0e4b06 100644 --- a/lisp/info-xref.el +++ b/lisp/info-xref.el @@ -1,6 +1,6 @@ ;;; info-xref.el --- check external references in an Info document -;; Copyright (C) 2003-2011 Free Software Foundation, Inc. +;; Copyright (C) 2003-2016 Free Software Foundation, Inc. ;; Author: Kevin Ryde ;; Keywords: docs @@ -45,8 +45,25 @@ ;;; 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 @@ -153,13 +170,13 @@ overall good/bad count summary inserted at the very end." 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'." + "Emit a `format-message'-ed message FMT+ARGS to the `info-xref-output-buffer'." (with-current-buffer info-xref-output-buffer (save-excursion (goto-char (point-max)) (let ((inhibit-read-only t)) (insert info-xref-output-heading - (apply 'format fmt args) + (apply #'format-message fmt args) "\n"))) (setq info-xref-output-heading "") ;; all this info-xref can be pretty slow, display now so the user sees @@ -205,7 +222,8 @@ buffer's line and column of point." (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) @@ -239,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))))))) @@ -313,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 @@ -368,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))))) @@ -413,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) @@ -421,7 +454,7 @@ and can take a long time." (cond ((symbolp load) (condition-case cause (require load) (error - (info-xref-output "Symbol `%s': cannot require '%s: %s" + (info-xref-output "Symbol `%s': cannot require `%s': %s" symbol load cause)))) ;; skip if previously loaded ((assoc load load-history)) @@ -447,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"