Function: Info-follow-reference

Info-follow-reference is an interactive and byte-compiled function defined in info.el.gz.

Signature

(Info-follow-reference FOOTNOTENAME &optional FORK)

Documentation

Follow cross reference named FOOTNOTENAME to the node it refers to.

FOOTNOTENAME may be an abbreviation of the reference name. If FORK is non-nil (interactively with a prefix arg), show the node in a new Info buffer. If FORK is a string, it is the name to use for the new buffer.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/info.el.gz
(defun Info-follow-reference (footnotename &optional fork)
  "Follow cross reference named FOOTNOTENAME to the node it refers to.
FOOTNOTENAME may be an abbreviation of the reference name.
If FORK is non-nil (interactively with a prefix arg), show the node in
a new Info buffer.  If FORK is a string, it is the name to use for the
new buffer."
  (interactive
   (let ((completion-ignore-case t)
	 (case-fold-search t)
	 completions default alt-default (start-point (point)) str i bol eol)
     (save-excursion
       ;; Store end and beginning of line.
       (setq eol (line-end-position)
             bol (line-beginning-position))
       (goto-char (point-min))
       (while (re-search-forward "\\*note[ \n\t]+\\([^:]*\\):" nil t)
	 (setq str (match-string-no-properties 1))
	 ;; See if this one should be the default.
	 (and (null default)
	      (<= (match-beginning 0) start-point)
	      (<= start-point (point))
	      (setq default t))
	 ;; See if this one should be the alternate default.
	 (and (null alt-default)
	      (and (<= bol (match-beginning 0))
		   (<= (point) eol))
	      (setq alt-default t))
	 (setq i 0)
	 (while (setq i (string-match "[ \n\t]+" str i))
	   (setq str (concat (substring str 0 i) " "
			     (substring str (match-end 0))))
	   (setq i (1+ i)))
	 ;; Record as a completion and perhaps as default.
	 (if (eq default t) (setq default str))
	 (if (eq alt-default t) (setq alt-default str))
	 ;; Don't add this string if it's a duplicate.
	 (or (assoc-string str completions t)
	     (push str completions)))
       (setq completions (nreverse completions)))
     ;; If no good default was found, try an alternate.
     (or default
	 (setq default alt-default))
     ;; If only one cross-reference found, then make it default.
     (if (eq (length completions) 1)
         (setq default (car completions)))
     (if completions
         (let ((input (completing-read (format-prompt "Follow reference named"
                                                      default)
                                       completions nil t)))
	   (list (if (equal input "")
		     default input)
                 current-prefix-arg))
       (user-error "No cross-references in this node")))
   Info-mode)

  (unless footnotename
    (error "No reference was specified"))

  (let (target i (str (concat "\\*note " (regexp-quote footnotename)))
	       (case-fold-search t))
    (while (setq i (string-search " " str i))
      (setq str (concat (substring str 0 i) "[ \t\n]+" (substring str (1+ i))))
      (setq i (+ i 6)))
    (save-excursion
      ;; Move point to the beginning of reference if point is on reference
      (or (looking-at "\\*note[ \n\t]+")
          (and (looking-back "\\*note[ \n\t]+"
                             (save-excursion (skip-chars-backward " \n\t")
                                             (line-beginning-position)))
               (goto-char (match-beginning 0)))
          (if (and (save-excursion
                     (goto-char (+ (point) 5)) ; skip a possible *note
                     (re-search-backward "\\*note[ \n\t]+" nil t)
                     (looking-at str))
                   (<= (point) (match-end 0)))
              (goto-char (match-beginning 0))))
      ;; Go to the reference closest to point
      (let ((next-ref (save-excursion (and (re-search-forward str nil t)
                                           (+ (match-beginning 0) 5))))
            (prev-ref (save-excursion (and (re-search-backward str nil t)
                                           (+ (match-beginning 0) 5)))))
        (goto-char (cond ((and next-ref prev-ref)
                          (if (< (abs (- next-ref (point)))
                                 (abs (- prev-ref (point))))
                              next-ref prev-ref))
                         ((or next-ref prev-ref))
                         ((user-error "No cross-reference named %s"
                                      footnotename))))
        (setq target (Info-extract-menu-node-name t))))
    (while (setq i (string-match "[ \t\n]+" target i))
      (setq target (concat (substring target 0 i) " "
			   (substring target (match-end 0))))
      (setq i (+ i 1)))
    (Info-goto-node target fork)))