+(defun Info-history ()
+ "Go to a node with a menu of visited nodes."
+ (interactive)
+ (let ((curr-file Info-current-file)
+ (curr-node Info-current-node)
+ p)
+ (with-current-buffer (get-buffer-create " *info-history*")
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (goto-char (point-min))
+ (insert "\n\^_\nFile: history, Node: Top, Up: (dir)\n\n")
+ (insert "Recently Visited Nodes\n**********************\n\n")
+ (insert "* Menu:\n\n")
+ (let ((hl (delete '("history" "Top") Info-history-list)))
+ (while hl
+ (let ((file (nth 0 (car hl)))
+ (node (nth 1 (car hl))))
+ (if (and (string-equal file curr-file)
+ (string-equal node curr-node))
+ (setq p (point)))
+ (insert "* " node ": (" (file-name-nondirectory file)
+ ")" node ".\n"))
+ (setq hl (cdr hl))))))
+ (Info-find-node "history" "Top")
+ (goto-char (or p (point-min)))))
+
+(defun Info-toc ()
+ "Go to a node with table of contents of the current Info file.
+Table of contents is created from the tree structure of menus."
+ (interactive)
+ (let ((curr-file (substring-no-properties Info-current-file))
+ (curr-node (substring-no-properties Info-current-node))
+ p)
+ (with-current-buffer (get-buffer-create " *info-toc*")
+ (let ((inhibit-read-only t)
+ (node-list (Info-build-toc curr-file)))
+ (erase-buffer)
+ (goto-char (point-min))
+ (insert "\n\^_\nFile: toc, Node: Top, Up: (dir)\n\n")
+ (insert "Table of Contents\n*****************\n\n")
+ (insert "*Note Top: (" curr-file ")Top.\n")
+ (Info-insert-toc
+ (nth 2 (assoc "Top" node-list)) ; get Top nodes
+ node-list 0 curr-file))
+ (if (not (bobp))
+ (let ((Info-hide-note-references 'hide)
+ (Info-fontify-visited-nodes nil))
+ (Info-mode)
+ (setq Info-current-file "toc" Info-current-node "Top")
+ (goto-char (point-min))
+ (narrow-to-region (or (re-search-forward "\n[\^_\f]\n" nil t)
+ (point-min))
+ (point-max))
+ (Info-fontify-node)
+ (widen)))
+ (goto-char (point-min))
+ (if (setq p (search-forward (concat "*Note " curr-node ":") nil t))
+ (setq p (- p (length curr-node) 2))))
+ (Info-find-node "toc" "Top")
+ (goto-char (or p (point-min)))))
+
+(defun Info-insert-toc (nodes node-list level curr-file)
+ "Insert table of contents with references to nodes."
+ (let ((section "Top"))
+ (while nodes
+ (let ((node (assoc (car nodes) node-list)))
+ (unless (member (nth 1 node) (list nil section))
+ (insert (setq section (nth 1 node)) "\n"))
+ (insert (make-string level ?\t))
+ (insert "*Note " (car nodes) ": (" curr-file ")" (car nodes) ".\n")
+ (Info-insert-toc (nth 2 node) node-list (1+ level) curr-file)
+ (setq nodes (cdr nodes))))))
+
+(defun Info-build-toc (file)
+ "Build table of contents from menus of Info FILE and its subfiles."
+ (with-temp-buffer
+ (let* ((file (and (stringp file) (Info-find-file file)))
+ (default-directory (or (and (stringp file)
+ (file-name-directory file))
+ default-directory))
+ (main-file (and (stringp file) file))
+ (sections '(("Top" "Top")))
+ nodes subfiles)
+ (while (or main-file subfiles)
+ (or main-file (message "Searching subfile %s..." (car subfiles)))
+ (erase-buffer)
+ (info-insert-file-contents (or main-file (car subfiles)))
+ (goto-char (point-min))
+ (while (and (search-forward "\n\^_\nFile:" nil 'move)
+ (search-forward "Node: " nil 'move))
+ (let ((nodename (substring-no-properties (Info-following-node-name)))
+ (bound (- (or (save-excursion (search-forward "\n\^_" nil t))
+ (point-max)) 2))
+ (section "Top")
+ menu-items)
+ (when (and (not (Info-index-node nodename file))
+ (re-search-forward "^\\* Menu:" bound t))
+ (forward-line 1)
+ (beginning-of-line)
+ (setq bound (or (and (equal nodename "Top")
+ (save-excursion
+ (re-search-forward
+ "^[ \t-]*The Detailed Node Listing" nil t)))
+ bound))
+ (while (< (point) bound)
+ (cond
+ ;; Menu item line
+ ((looking-at "^\\* +[^:]+:")
+ (beginning-of-line)
+ (forward-char 2)
+ (let ((menu-node-name (substring-no-properties
+ (Info-extract-menu-node-name))))
+ (setq menu-items (cons menu-node-name menu-items))
+ (if (equal nodename "Top")
+ (setq sections
+ (cons (list menu-node-name section) sections)))))
+ ;; Other non-empty strings in the Top node are section names
+ ((and (equal nodename "Top")
+ (looking-at "^\\([^ \t\n*=.-][^:\n]*\\)"))
+ (setq section (match-string-no-properties 1))))
+ (forward-line 1)
+ (beginning-of-line)))
+ (setq nodes (cons (list nodename
+ (cadr (assoc nodename sections))
+ (nreverse menu-items))
+ nodes))
+ (goto-char bound)))
+ (if main-file
+ (save-excursion
+ (goto-char (point-min))
+ (if (search-forward "\n\^_\nIndirect:" nil t)
+ (let ((bound (save-excursion (search-forward "\n\^_" nil t))))
+ (while (re-search-forward "^\\(.*\\): [0-9]+$" bound t)
+ (setq subfiles (cons (match-string-no-properties 1)
+ subfiles)))))
+ (setq subfiles (nreverse subfiles)
+ main-file nil))
+ (setq subfiles (cdr subfiles))))
+ (message "")
+ (nreverse nodes))))
+\f
+(defun Info-follow-reference (footnotename &optional fork)