Function: Info-find-node-2

Info-find-node-2 is a byte-compiled function defined in info.el.gz.

Signature

(Info-find-node-2 FILENAME NODENAME &optional NO-GOING-BACK STRICT-CASE)

Source Code

;; Defined in /usr/src/emacs/lisp/info.el.gz
(defun Info-find-node-2 (filename nodename &optional no-going-back strict-case)
  (buffer-disable-undo (current-buffer))
  (or (derived-mode-p 'Info-mode)
      (Info-mode))
  (widen)
  (setq Info-current-node nil)
  (unwind-protect
      (let ((case-fold-search t)
	    (virtual-fun (Info-virtual-fun 'find-node
					   (or filename Info-current-file)
					   nodename))
	    anchorpos)
	(cond
	 ((functionp virtual-fun)
	  (let ((filename (or filename Info-current-file)))
	    (setq buffer-read-only nil)
	    (setq Info-current-file filename
		  Info-current-subfile nil
		  Info-current-file-completions nil
		  buffer-file-name nil)
	    (erase-buffer)
	    (Info-virtual-call virtual-fun filename nodename no-going-back)
	    (set-marker Info-tag-table-marker nil)
	    (setq buffer-read-only t)
	    (set-buffer-modified-p nil)
	    (setq Info-current-node-virtual t)))
	 ((not (and
		;; Reread a file when moving from a virtual node.
		(not Info-current-node-virtual)
		(or (null filename)
		    (equal Info-current-file filename))))
	  ;; Switch files if necessary
	  (let ((inhibit-read-only t))
	    (when Info-current-node-virtual
	      ;; When moving from a virtual node.
	      (setq Info-current-node-virtual nil)
	      (if (null filename)
		  (setq filename Info-current-file)))
	    (setq Info-current-file nil
		  Info-current-subfile nil
		  Info-current-file-completions nil
		  buffer-file-name nil)
	    (erase-buffer)
            ;; Erase any memory of the previous coding-system, so that
            ;; info-insert-file-contents sets the buffer's encoding to
            ;; what the Info file specifies.
            (set-buffer-file-coding-system 'undecided t)
	    (info-insert-file-contents filename nil)
	    (setq default-directory (file-name-directory filename))
	    (set-buffer-modified-p nil)
	    (setq Info-file-supports-index-cookies
		 (Info-file-supports-index-cookies filename))

	    ;; See whether file has a tag table.  Record the location if yes.
            (Info--record-tag-table nodename)
	    (setq Info-current-file filename)
	    )))

        ;; Use string-equal, not equal, to ignore text props.
        (if (string-equal nodename "*")
            (progn (setq Info-current-node nodename)
                   (Info-set-mode-line))
          ;; Possibilities:
          ;;
          ;; 1. Anchor found in tag table
          ;; 2. Anchor *not* in tag table
          ;;
          ;; 3. Node found in tag table
          ;; 4. Node *not* found in tag table, but found in file
          ;; 5. Node *not* in tag table, and *not* in file
          ;;
          ;; *Or* the same, but in an indirect subfile.

          ;; Search file for a suitable node.
	  (let ((guesspos (point-min))
		(regexp (concat "\\(Node:\\|Ref:\\) *\\("
				(if (stringp nodename)
				    (regexp-quote nodename)
				  "")
				"\\) *[,\t\n\177]")))

	    (catch 'foo

	      ;; First, search a tag table, if any
	      (when (marker-position Info-tag-table-marker)
		(let* ((m Info-tag-table-marker)
		       (found (Info-find-in-tag-table m regexp strict-case)))

		  (when found
		    ;; FOUND is (ANCHOR POS MODE).
		    (let ((filepos (nth 1 found))) ;File position in bytes.

                      ;; If this is an indirect file, determine which
                      ;; file really holds this node and read it in.
                      (unless (eq (nth 2 found) 'Info-mode)
                        ;; Note that the current buffer must be the
                        ;; *info* buffer on entry to
                        ;; Info-read-subfile.  Thus the hackery above.
                        (setq filepos (Info-read-subfile filepos)))

                      (setq guesspos
                            (filepos-to-bufferpos filepos 'approximate)))

		    ;; Handle anchor
		    (when (nth 0 found)
		      (goto-char (setq anchorpos guesspos))
		      (throw 'foo t)))))

	      ;; Else we may have a node, which we search for:
	      (goto-char (max (point-min) (- guesspos 1000)))

	      ;; Now search from our advised position (or from beg of
	      ;; buffer) to find the actual node.  First, check
	      ;; whether the node is right where we are, in case the
	      ;; buffer begins with a node.
	      (let ((pos (Info-find-node-in-buffer regexp strict-case)))
		(when pos
		  (goto-char pos)
		  (throw 'foo t)))

              ;; If the Texinfo source had an @ifnottex block of text
              ;; before the Top node, makeinfo 5.0 and 5.1 mistakenly
              ;; omitted that block's size from the starting position
              ;; of the 1st subfile, which makes GUESSPOS overshoot
              ;; the correct position by the length of that text.  So
              ;; we try again with a larger slop.
              (goto-char (max (point-min) (- guesspos 10000)))
	      (let ((pos (Info-find-node-in-buffer regexp strict-case)))
		(when pos
		  (goto-char pos)
		  (throw 'foo t)))

              (when (string-match "\\([^.]+\\)\\." nodename)
                (let (Info-point-loc)
                  (Info-find-node-2
                   filename (match-string 1 nodename) no-going-back))
                (widen)
                (throw 'foo t))

              ;; No such anchor in tag table or node in tag table or file
              (user-error "No such node or anchor: %s" nodename))

	    (Info-select-node)
	    (goto-char (point-min))
	    (forward-line 1)		       ; skip header line
	    ;; (when (> Info-breadcrumbs-depth 0) ; skip breadcrumbs line
	    ;;   (forward-line 1))

	    (cond (anchorpos
                   (let ((new-history (list Info-current-file
                                            (substring-no-properties nodename))))
                     ;; Add anchors to the history too
                     (setq Info-history-list
                           (cons new-history
                                 (remove new-history Info-history-list))))
                   (goto-char anchorpos))
                  ((numberp Info-point-loc)
                   (forward-line (- Info-point-loc 2))
                   (setq Info-point-loc nil))
		  ((stringp Info-point-loc)
		   (Info-find-index-name Info-point-loc)
		   (setq Info-point-loc nil))))))
    ;; If we did not finish finding the specified node,
    ;; go back to the previous one or to the Top node.
    (unless (or Info-current-node no-going-back)
      (if Info-history
	  (let ((hist (car Info-history)))
	    (setq Info-history (cdr Info-history))
	    (Info-find-node (nth 0 hist) (nth 1 hist) t t)
	    (goto-char (nth 2 hist)))
	(Info-find-node Info-current-file "Top" t t)))))