Function: Info-toc-build

Info-toc-build is a byte-compiled function defined in info.el.gz.

Signature

(Info-toc-build FILE)

Documentation

Build table of contents from menus of Info FILE and its subfiles.

Source Code

;; Defined in /usr/src/emacs/lisp/info.el.gz
(defun Info-toc-build (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)
        (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))
		 (upnode (and (re-search-forward
			       (concat "Up:" (Info-following-node-name-re))
			       bound t)
			      (match-string-no-properties 1)))
		 (section "Top")
		 menu-items)
	    (when (and upnode (string-search "(" upnode)) (setq upnode nil))
            (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 upnode
                                    (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))))
      (nreverse nodes))))