comparison lisp/info.el @ 444:576fb035e263 r21-2-37

Import from CVS: tag r21-2-37
author cvs
date Mon, 13 Aug 2007 11:36:19 +0200
parents abe6d1db359e
children 1ccc32a20af4
comparison
equal deleted inserted replaced
443:a8296e22da4e 444:576fb035e263
426 :type '(choice (const :tag "never" never) 426 :type '(choice (const :tag "never" never)
427 (const :tag "always" always) 427 (const :tag "always" always)
428 (const :tag "conservative" conservative)) 428 (const :tag "conservative" conservative))
429 :group 'info) 429 :group 'info)
430 430
431 (defvar Info-emacs-info-file-name "xemacs.info" 431 (defconst Info-emacs-info-file-name "xemacs.info"
432 "The filename of the XEmacs info for 432 "The filename of the XEmacs info for `Info-goto-emacs-command-node'
433 `Info-goto-emacs-command-node' (`\\<help-mode-map>\\[Info-goto-emacs-command-node]')") 433 (`\\<help-mode-map>\\[Info-goto-emacs-command-node]')")
434 434
435 ;;;###autoload 435 ;;;###autoload
436 (defvar Info-directory-list nil 436 (defvar Info-directory-list nil
437 "List of directories to search for Info documentation files. 437 "List of directories to search for Info documentation files.
438 438
445 search path, make the needed modifications on the variable's value 445 search path, make the needed modifications on the variable's value
446 from .emacs. For instance: 446 from .emacs. For instance:
447 447
448 (setq Info-directory-list (cons \"~/info\" Info-directory-list))") 448 (setq Info-directory-list (cons \"~/info\" Info-directory-list))")
449 449
450 (defcustom Info-localdir-heading-regexp 450 ;; This could as well be hard-coded since ${srcdir}/info/dir is in CVS --dv
451 "^Locally installed XEmacs Packages:?" 451 (defconst Info-localdir-heading-regexp "^Local Packages:$"
452 "The menu part of localdir files will be inserted below this topic 452 "The menu part of localdir files will be inserted below this topic
453 heading." 453 heading.")
454 :type 'regexp
455 :group 'info)
456 454
457 (defface info-node '((t (:bold t :italic t))) 455 (defface info-node '((t (:bold t :italic t)))
458 "Face used for node links in info." 456 "Face used for node links in info."
459 :group 'info-faces) 457 :group 'info-faces)
460 458
461 (defface info-xref '((t (:bold t))) 459 (defface info-xref '((t (:bold t)))
462 "Face used for cross-references in info." 460 "Face used for cross-references in info."
463 :group 'info-faces) 461 :group 'info-faces)
464 462
465 ;; Is this right for NT? .zip, with -c for to stdout, right? 463 ;; This list is based on Karl Berry-s advice about extensions `info' itself
466 (defvar Info-suffix-list '( ("" . nil) 464 ;; might encounter. --dv
467 (".info" . nil) 465 (defcustom Info-suffix-list '(("" . nil)
468 (".info.bz2" . "bzip2 -dc %s") 466 (".info" . nil)
469 (".info.gz" . "gzip -dc %s") 467 (".gz" . "gzip -dc %s")
470 (".info-z" . "gzip -dc %s") 468 (".info.gz" . "gzip -dc %s")
471 (".info.Z" . "uncompress -c %s") 469 (".z" . "gzip -dc %s")
472 (".bz2" . "bzip2 -dc %s") 470 (".info.z" . "gzip -dc %s")
473 (".gz" . "gzip -dc %s") 471 (".bz2" . "bzip2 -dc %s")
474 (".Z" . "uncompress -c %s") 472 (".info.bz2" . "bzip2 -dc %s")
475 (".zip" . "unzip -c %s") ) 473 (".Z" . "uncompress -c %s")
476 "List of file name suffixes and associated decoding commands. 474 (".info.Z" . "uncompress -c %s")
475 (".zip" . "unzip -c %s")
476 (".info.zip" . "unzip -c %s")
477 (".y" . "cat %s | unyabba")
478 ("info.y" . "cat %s | unyabba")
479 ;; These ones are for MS-DOS filenames.
480 (".inf" . nil)
481 (".igz" . "gzip -dc %s")
482 (".inz" . "gzip -c %s"))
483 "*List of file name suffixes and associated decoding commands.
477 Each entry should be (SUFFIX . STRING); if STRING contains %s, that is 484 Each entry should be (SUFFIX . STRING); if STRING contains %s, that is
478 changed to name of the file to decode, otherwise the file is given to 485 changed to name of the file to decode, otherwise the file is given to
479 the command as standard input. If STRING is nil, no decoding is done.") 486 the command as standard input. If STRING is nil, no decoding is done."
480 487 :type '(repeat (cons (string :tag "suffix")
481 (defvar Info-footnote-tag "Note" 488 (choice :tag "command"
489 (const :tag "none" :value nil)
490 (string :tag ""))))
491 :group 'info)
492
493 (defcustom Info-footnote-tag "Note"
482 "*Symbol that identifies a footnote or cross-reference. 494 "*Symbol that identifies a footnote or cross-reference.
483 All \"*Note\" references will be changed to use this word instead.") 495 All \"*Note\" references will be changed to use this word instead."
496 :type 'string
497 :group 'info)
484 498
485 (defvar Info-current-file nil 499 (defvar Info-current-file nil
486 "Info file that Info is now looking at, or nil. 500 "Info file that Info is now looking at, or nil.
487 This is the name that was specified in Info, not the actual file name. 501 This is the name that was specified in Info, not the actual file name.
488 It doesn't contain directory names or file name extensions added by Info.") 502 It doesn't contain directory names or file name extensions added by Info.")
506 (defvar Info-current-annotation-completions nil 520 (defvar Info-current-annotation-completions nil
507 "Cached completion list for current annotation files.") 521 "Cached completion list for current annotation files.")
508 522
509 (defvar Info-index-alternatives nil 523 (defvar Info-index-alternatives nil
510 "List of possible matches for last Info-index command.") 524 "List of possible matches for last Info-index command.")
525
511 (defvar Info-index-first-alternative nil) 526 (defvar Info-index-first-alternative nil)
512 527
513 (defcustom Info-annotations-path 528 (defcustom Info-annotations-path
514 (list 529 (list
515 (paths-construct-path (list user-init-directory "info.notes")) 530 (paths-construct-path (list user-init-directory "info.notes"))
543 558
544 * Menu: The list of major topics begins on the next line. 559 * Menu: The list of major topics begins on the next line.
545 560
546 ") 561 ")
547 562
548 (defvar Info-no-description-string "[No description available]" 563 (defcustom Info-no-description-string "[No description available]"
549 "Description string for info files that have none") 564 "*Description string for info files that have none"
565 :type 'string
566 :group 'info)
550 567
551 ;;;###autoload 568 ;;;###autoload
552 (defun info (&optional file) 569 (defun info (&optional file)
553 "Enter Info, the documentation browser. 570 "Enter Info, the documentation browser.
554 Optional argument FILE specifies the file to examine; 571 Optional argument FILE specifies the file to examine;
608 ;; empty filename is simple case 625 ;; empty filename is simple case
609 ((null filename) 626 ((null filename)
610 (Info-find-file-node nil nodename no-going-back tryfile line)) 627 (Info-find-file-node nil nodename no-going-back tryfile line))
611 ;; Convert filename to lower case if not found as specified. 628 ;; Convert filename to lower case if not found as specified.
612 ;; Expand it, look harder... 629 ;; Expand it, look harder...
613 ((let (temp temp-downcase found 630 ((let ((fname (substitute-in-file-name filename))
614 (fname (substitute-in-file-name filename))) 631 temp found)
615 (let ((dirs (cond 632 (let ((dirs (cond
616 ((string-match "^\\./" fname) ; If specified name starts with `./' 633 ;; If specified name starts with `./', then just try
617 (list default-directory)) ; then just try current directory. 634 ;; current directory. No point in searching for an absolute
635 ;; file name
636 ((string-match "^\\./" fname)
637 (list default-directory))
618 ((file-name-absolute-p fname) 638 ((file-name-absolute-p fname)
619 '(nil)) ; No point in searching for an absolute file name 639 '(nil))
620 (Info-additional-search-directory-list 640 (Info-additional-search-directory-list
621 (append Info-directory-list 641 (append Info-directory-list
622 Info-additional-search-directory-list)) 642 Info-additional-search-directory-list))
623 (t Info-directory-list)))) 643 (t Info-directory-list))))
624 ;; Search the directory list for file FNAME. 644 ;; Search the directory list for file FNAME.
625 (while (and dirs (not found)) 645 (while (and dirs (not found))
626 (setq temp (expand-file-name fname (car dirs))) 646 (setq temp (expand-file-name fname (car dirs)))
627 (setq temp-downcase 647 (setq found (Info-suffixed-file temp))
628 (expand-file-name (downcase fname) (car dirs)))
629 (if (equal temp-downcase temp) (setq temp-downcase nil))
630 ;; Try several variants of specified name.
631 ;; Try downcasing, appending a suffix, or both.
632 (setq found (Info-suffixed-file temp temp-downcase))
633 (setq dirs (cdr dirs))) 648 (setq dirs (cdr dirs)))
634 (if found 649 (if found
635 (progn (setq filename (expand-file-name found)) 650 (progn (setq filename (expand-file-name found))
636 t)))) 651 t))))
637 (Info-find-file-node filename nodename no-going-back tryfile line)) 652 (Info-find-file-node filename nodename no-going-back tryfile line))
740 (let (foun found-mode (m Info-tag-table-marker)) 755 (let (foun found-mode (m Info-tag-table-marker))
741 (save-excursion 756 (save-excursion
742 (set-buffer (marker-buffer Info-tag-table-marker)) 757 (set-buffer (marker-buffer Info-tag-table-marker))
743 (goto-char m) 758 (goto-char m)
744 (setq foun (re-search-forward regexp nil t)) 759 (setq foun (re-search-forward regexp nil t))
745 (if foun 760 (if foun
746 (setq guesspos (read (current-buffer)))) 761 (setq guesspos (read (current-buffer))))
747 (setq found-mode major-mode)) 762 (setq found-mode major-mode))
748 (if foun 763 (if foun
749 ;; If this is an indirect file, 764 ;; If this is an indirect file,
750 ;; determine which file really holds this node 765 ;; determine which file really holds this node
751 ;; and read it in. 766 ;; and read it in.
752 (if (not (eq major-mode found-mode)) 767 (if (not (eq major-mode found-mode))
753 (setq guesspos 768 (setq guesspos
818 ;; constructed Info-dir-contents. 833 ;; constructed Info-dir-contents.
819 (defvar Info-dir-file-attributes nil) 834 (defvar Info-dir-file-attributes nil)
820 835
821 (defun Info-insert-dir () 836 (defun Info-insert-dir ()
822 "Construct the Info directory node by merging the files named 837 "Construct the Info directory node by merging the files named
823 \"dir\" or \"localdir\" from the directories in `Info-directory-list' 838 \"dir\" or \"localdir\" from the directories in `Info-directory-list'.
824 The \"dir\" files will take precedence in cases where both exist. It 839 The \"dir\" files will take precedence in cases where both exist. It
825 sets the *info* buffer's `default-directory' to the first directory we 840 sets the *info* buffer's `default-directory' to the first directory we
826 actually get any text from." 841 actually get any text from."
827 (if (and Info-dir-contents Info-dir-file-attributes 842 (if (and Info-dir-contents Info-dir-file-attributes
828 ;; Verify that none of the files we used has changed 843 ;; Verify that none of the files we used has changed
844 ;; Search the directory list for the directory file. 859 ;; Search the directory list for the directory file.
845 (while dirs 860 (while dirs
846 (let ((truename (file-truename (expand-file-name (car dirs))))) 861 (let ((truename (file-truename (expand-file-name (car dirs)))))
847 (or (member truename dirs-done) 862 (or (member truename dirs-done)
848 (member (directory-file-name truename) dirs-done) 863 (member (directory-file-name truename) dirs-done)
849 ;; Try several variants of specified name. 864 ;; Karl Berry recently added the ability all possibilities for
850 ;; Try upcasing, appending `.info', or both. 865 ;; extension as for normal info files. This code however is
851 (let* (buf 866 ;; still unsatisfactory: if one day, we find a compressed dir
852 file 867 ;; file (which looks possible), we should be able to handle it
853 (attrs 868 ;; (which means decompress and read it, update it, save and
854 (or 869 ;; recompress it). --dv
855 (progn (setq file (expand-file-name "dir" truename)) 870 (let ((trials '("dir" "DIR"
856 (file-attributes file)) 871 "dir.info" "DIR.INFO"
857 (progn (setq file (expand-file-name "DIR" truename)) 872 "dir.inf" "DIR.INF"
858 (file-attributes file)) 873 "localdir" "LOCALDIR"
859 (progn (setq file (expand-file-name "dir.info" truename)) 874 "localdir.info" "LOCALDIR.INFO"
860 (file-attributes file)) 875 "localdir.inf" "LOCALDIR.INF"))
861 (progn (setq file (expand-file-name "DIR.INFO" truename)) 876 buf file attrs)
862 (file-attributes file)) 877 (catch 'found
863 (progn (setq file (expand-file-name "localdir" truename)) 878 (while (setq file (pop trials))
864 (file-attributes file)) 879 (setq file (expand-file-name file truename))
865 (progn (setq file (expand-file-name "dir" truename)) 880 (and (setq attrs (file-attributes file))
866 nil) 881 (throw 'found t))))
867 ))) 882 (unless file
883 (setq file (expand-file-name "dir" truename)))
868 (setq dirs-done 884 (setq dirs-done
869 (cons truename 885 (cons truename
870 (cons (directory-file-name truename) 886 (cons (directory-file-name truename)
871 dirs-done))) 887 dirs-done)))
872 (Info-maybe-update-dir file) 888 (Info-maybe-update-dir file)
1018 (message "Composing main Info directory...done")) 1034 (message "Composing main Info directory...done"))
1019 (setq Info-dir-contents (buffer-string))) 1035 (setq Info-dir-contents (buffer-string)))
1020 (setq default-directory Info-dir-contents-directory) 1036 (setq default-directory Info-dir-contents-directory)
1021 (setq buffer-file-name (caar Info-dir-file-attributes))) 1037 (setq buffer-file-name (caar Info-dir-file-attributes)))
1022 1038
1039 (defmacro Info-directory-files (dir-file &optional all full nosort files-only)
1040 "Return a list of Info files living in the same directory as DIR-FILE.
1041 This list actually contains the files living in this directory, except for
1042 the dir file itself and the secondary info files (foo-1 foo-2 etc).
1043
1044 If the optional argument ALL is non nil, the secondary info files are also
1045 included in the list.
1046
1047 Please refer to the function `directory-files' for the meaning of the other
1048 optional arguments."
1049 `(let* ((dir (file-name-directory ,dir-file))
1050 (all-files (remove ,dir-file (directory-files dir ',full nil ',nosort
1051 ',files-only))))
1052 (setq all-files
1053 (if ,full
1054 (remove (concat dir ".")
1055 (remove (concat dir "..") all-files))
1056 (remove "."
1057 (remove ".." all-files))))
1058 (if ,all
1059 all-files
1060 (let ((suff-match
1061 (concat "-[0-9]+\\("
1062 ;; Extract all known compression suffixes from
1063 ;; Info-suffix-list. These suffixes can typically be
1064 ;; found in entries of the form `.info.something'.
1065 (let ((suff-list Info-suffix-list)
1066 suff regexp)
1067 (while (setq suff (pop suff-list))
1068 (and (string-match "^\\.info" (car suff))
1069 (setq regexp (concat regexp
1070 (regexp-quote
1071 (substring
1072 (car suff) 5))
1073 (and suff-list "\\|")))))
1074 regexp)
1075 "\\)?$"))
1076 info-files file)
1077 (while (setq file (pop all-files))
1078 (or (string-match suff-match file)
1079 (push file info-files)))
1080 (reverse info-files)
1081 ))
1082 ))
1083
1023 (defun Info-maybe-update-dir (file) 1084 (defun Info-maybe-update-dir (file)
1024 "Rebuild dir or localdir according to `Info-auto-generate-directory'." 1085 "Rebuild dir or localdir according to `Info-auto-generate-directory'."
1025 (unless (or (not (file-exists-p (file-name-directory file))) 1086 (unless (or (not (file-exists-p (file-name-directory file)))
1026 (null (directory-files (file-name-directory file) nil "\\.info"))) 1087 (null (Info-directory-files file 'all)))
1027 (if (not (find-buffer-visiting file)) 1088 (if (not (find-buffer-visiting file))
1028 (if (not (file-exists-p file)) 1089 (if (not (file-exists-p file))
1029 (if (or (eq Info-auto-generate-directory 'always) 1090 (if (or (eq Info-auto-generate-directory 'always)
1030 (eq Info-auto-generate-directory 'if-missing)) 1091 (eq Info-auto-generate-directory 'if-missing))
1031 (Info-build-dir-anew (file-name-directory file))) 1092 (Info-build-dir-anew (file-name-directory file)))
1040 (defun Info-dir-outdated-p (file) 1101 (defun Info-dir-outdated-p (file)
1041 "Return non-nil if dir or localdir is outdated. 1102 "Return non-nil if dir or localdir is outdated.
1042 dir or localdir are outdated when an info file in the same 1103 dir or localdir are outdated when an info file in the same
1043 directory has been modified more recently." 1104 directory has been modified more recently."
1044 (let ((dir-mod-time (nth 5 (file-attributes file))) 1105 (let ((dir-mod-time (nth 5 (file-attributes file)))
1045 f-mod-time 1106 f-mod-time newer)
1046 newer)
1047 (setq Info-dir-newer-info-files nil) 1107 (setq Info-dir-newer-info-files nil)
1048 (mapcar 1108 (mapcar
1049 #'(lambda (f) 1109 #'(lambda (f)
1050 (prog2 1110 (prog2
1051 (setq f-mod-time (nth 5 (file-attributes f))) 1111 (setq f-mod-time (nth 5 (file-attributes f)))
1052 (setq newer (or (> (car f-mod-time) (car dir-mod-time)) 1112 (setq newer (or (> (car f-mod-time) (car dir-mod-time))
1053 (and (= (car f-mod-time) (car dir-mod-time)) 1113 (and (= (car f-mod-time) (car dir-mod-time))
1054 (> (car (cdr f-mod-time)) (car (cdr dir-mod-time)))))) 1114 (> (car (cdr f-mod-time))
1055 (if (and (file-readable-p f) 1115 (car (cdr dir-mod-time))))))
1056 newer) 1116 (if (and (file-readable-p f) newer)
1057 (setq Info-dir-newer-info-files 1117 (setq Info-dir-newer-info-files
1058 (cons f Info-dir-newer-info-files))))) 1118 (cons f Info-dir-newer-info-files)))))
1059 (directory-files (file-name-directory file) 1119 (Info-directory-files file nil 'fullname 'nosort t))
1060 'fullname
1061 ".*\\.info\\(\\.gz\\|\\.bz2\\|\\.Z\\|-z\\|\\.zip\\)?$"
1062 'nosort
1063 t))
1064 Info-dir-newer-info-files)) 1120 Info-dir-newer-info-files))
1065 1121
1066 (defun Info-extract-dir-entry-from (file) 1122 (defun Info-extract-dir-entry-from (file)
1067 "Extract the dir entry from the info FILE. 1123 "Extract the dir entry from the info FILE.
1068 The dir entry is delimited by the markers `START-INFO-DIR-ENTRY' 1124 The dir entry is delimited by the markers `START-INFO-DIR-ENTRY'
1069 and `END-INFO-DIR-ENTRY'" 1125 and `END-INFO-DIR-ENTRY'."
1070 (save-excursion 1126 (save-excursion
1071 (set-buffer (get-buffer-create " *Info-tmp*")) 1127 (set-buffer (get-buffer-create " *Info-tmp*"))
1072 (when (file-readable-p file) 1128 (when (file-readable-p file)
1073 (insert-file-contents file nil nil nil t) 1129 (insert-file-contents file nil nil nil t)
1074 (goto-char (point-min)) 1130 (goto-char (point-min))
1078 (setq beg (point)) 1134 (setq beg (point))
1079 (unless (null (re-search-forward "^END-INFO-DIR-ENTRY" nil t)) 1135 (unless (null (re-search-forward "^END-INFO-DIR-ENTRY" nil t))
1080 (goto-char (match-beginning 0)) 1136 (goto-char (match-beginning 0))
1081 (car (Info-parse-dir-entries beg (point))))))))) 1137 (car (Info-parse-dir-entries beg (point)))))))))
1082 1138
1083 ;; Parse dir entries contained between BEG and END into a list of the form 1139 ;; Parse dir entries contained between START and END into a list of the form
1084 ;; (filename topic node (description-line-1 description-line-2 ...)) 1140 ;; (filename topic node (description-line-1 description-line-2 ...))
1085 (defun Info-parse-dir-entries (beg end) 1141 (defun Info-parse-dir-entries (start end)
1086 (let (entry entries) 1142 (let (entry entries)
1087 (save-excursion 1143 (save-excursion
1088 (save-restriction 1144 (save-restriction
1089 (narrow-to-region beg end) 1145 (narrow-to-region start end)
1090 (goto-char beg) 1146 (goto-char start)
1091 (while (re-search-forward "^\\* \\([^:]+\\):\\([ \t]*(\\([^)]*\\))\\w*\\.\\|:\\)" nil t) 1147 (while (re-search-forward
1148 "^\\* \\([^:]+\\):\\([ \t]*(\\([^)]*\\))\\w*\\.\\|:\\)" nil t)
1092 (setq entry (list (match-string 2) 1149 (setq entry (list (match-string 2)
1093 (match-string 1) 1150 (match-string 1)
1094 (downcase (or (match-string 3) 1151 (downcase (or (match-string 3)
1095 (match-string 1))))) 1152 (match-string 1)))))
1096 (setq entry 1153 (setq entry
1133 1190
1134 1191
1135 (defun Info-build-dir-anew (directory) 1192 (defun Info-build-dir-anew (directory)
1136 "Build info directory information for DIRECTORY. 1193 "Build info directory information for DIRECTORY.
1137 The generated directory listing may be saved to a `dir' according 1194 The generated directory listing may be saved to a `dir' according
1138 to the value of `Info-save-auto-generated-dir'" 1195 to the value of `Info-save-auto-generated-dir'."
1139 (save-excursion 1196 (save-excursion
1140 (let* ((dirfile (expand-file-name "dir" directory)) 1197 (let* ((dirfile (expand-file-name "dir" directory))
1141 (to-temp (or (null Info-save-auto-generated-dir) 1198 (to-temp (or (null Info-save-auto-generated-dir)
1142 (eq Info-save-auto-generated-dir 'never) 1199 (eq Info-save-auto-generated-dir 'never)
1143 (and (not (file-writable-p dirfile)) 1200 (and (not (file-writable-p dirfile))
1144 (message "File not writable %s. Using temporary." dirfile)))) 1201 (message "File not writable %s. Using temporary."
1145 (info-files 1202 dirfile))))
1146 (directory-files directory 1203 (info-files (Info-directory-files dirfile nil 'fullname nil t)))
1147 'fullname
1148 ".*\\.info\\(.gz\\|.Z\\|-z\\|.zip\\)?$"
1149 nil
1150 t)))
1151 (if to-temp 1204 (if to-temp
1152 (message "Creating temporary dir in %s..." directory) 1205 (message "Creating temporary dir in %s..." directory)
1153 (message "Creating %s..." dirfile)) 1206 (message "Creating %s..." dirfile))
1154 (set-buffer (find-file-noselect dirfile t)) 1207 (set-buffer (find-file-noselect dirfile t))
1155 (setq buffer-read-only nil) 1208 (setq buffer-read-only nil)
1156 (erase-buffer) 1209 (erase-buffer)
1157 (insert Info-dir-prologue 1210 (insert Info-dir-prologue "Info files in " directory ":\n\n")
1158 "Info files in " directory ":\n\n")
1159 (Info-dump-dir-entries 1211 (Info-dump-dir-entries
1160 (mapcar 1212 (mapcar
1161 #'(lambda (f) 1213 #'(lambda (f)
1162 (or (Info-extract-dir-entry-from f) 1214 (or (Info-extract-dir-entry-from f)
1163 (list 'dummy 1215 (list 'dummy
1164 (progn 1216 (progn (string-match "\\([^.]*\\)\\(\\..*\\)?$"
1165 (string-match "\\(.*\\)\\.info\\(.gz\\|.Z\\|-z\\|.zip\\)?$" 1217 (file-name-nondirectory f))
1166 (file-name-nondirectory f)) 1218 (capitalize
1167 (capitalize (match-string 1 (file-name-nondirectory f)))) 1219 (match-string 1 (file-name-nondirectory f))))
1168 ":" 1220 ":"
1169 (list Info-no-description-string)))) 1221 (list Info-no-description-string))))
1170 info-files)) 1222 info-files))
1171 (if to-temp 1223 (if to-temp
1172 (set-buffer-modified-p nil) 1224 (set-buffer-modified-p nil)
1180 "Build info directory information in the directory of dir FILE. 1232 "Build info directory information in the directory of dir FILE.
1181 Description of info files are merged from the info files in the 1233 Description of info files are merged from the info files in the
1182 directory and the contents of FILE with the description in info files 1234 directory and the contents of FILE with the description in info files
1183 taking precedence over descriptions in FILE. 1235 taking precedence over descriptions in FILE.
1184 The generated directory listing may be saved to a `dir' according to 1236 The generated directory listing may be saved to a `dir' according to
1185 the value of `Info-save-auto-generated-dir' " 1237 the value of `Info-save-auto-generated-dir'."
1186 (save-excursion 1238 (save-excursion
1187 (save-restriction 1239 (save-restriction
1188 (let (dir-section-contents dir-full-contents 1240 (let (dir-section-contents dir-full-contents
1189 dir-entry 1241 dir-entry
1190 file-dir-entry 1242 file-dir-entry
1196 (and (eq Info-save-auto-generated-dir 'always) 1248 (and (eq Info-save-auto-generated-dir 'always)
1197 (not (file-writable-p file)) 1249 (not (file-writable-p file))
1198 (message "File not writable %s. Using temporary." file)) 1250 (message "File not writable %s. Using temporary." file))
1199 (and (eq Info-save-auto-generated-dir 'conservative) 1251 (and (eq Info-save-auto-generated-dir 'conservative)
1200 (or (and (not (file-writable-p file)) 1252 (or (and (not (file-writable-p file))
1201 (message "File not writable %s. Using temporary." file)) 1253 (message
1254 "File not writable %s. Using temporary." file))
1202 (not (y-or-n-p 1255 (not (y-or-n-p
1203 (message "%s is outdated. Overwrite ? " 1256 (message "%s is outdated. Overwrite ? "
1204 file)))))))) 1257 file))))))))
1205 (set-buffer (find-file-noselect file t)) 1258 (set-buffer (find-file-noselect file t))
1206 (setq buffer-read-only nil) 1259 (setq buffer-read-only nil)
1214 (re-search-forward "^\\* Menu:.*$" nil t) 1267 (re-search-forward "^\\* Menu:.*$" nil t)
1215 (setq mark (and (re-search-forward "^\\* " nil t) 1268 (setq mark (and (re-search-forward "^\\* " nil t)
1216 (match-beginning 0)))) 1269 (match-beginning 0))))
1217 (throw 'done nil)) 1270 (throw 'done nil))
1218 (setq dir-full-contents (Info-parse-dir-entries mark (point-max))) 1271 (setq dir-full-contents (Info-parse-dir-entries mark (point-max)))
1219 (setq next-section (or (and (re-search-forward "^[^* \t].*:[ \t]*$" nil t) 1272 (setq next-section (or (and (re-search-forward "^[^* \t].*:[ \t]*$"
1273 nil t)
1220 (match-beginning 0)) 1274 (match-beginning 0))
1221 (point-max))) 1275 (point-max)))
1222 (while next-section 1276 (while next-section
1223 (narrow-to-region mark next-section) 1277 (narrow-to-region mark next-section)
1224 (setq dir-section-contents (nreverse (Info-parse-dir-entries (point-min) 1278 (setq dir-section-contents (nreverse (Info-parse-dir-entries
1225 (point-max)))) 1279 (point-min) (point-max))))
1226 (mapcar 1280 (mapcar
1227 #'(lambda (file) 1281 #'(lambda (file)
1228 (setq dir-entry (assoc (downcase 1282 (setq dir-entry (assoc (downcase
1229 (file-name-sans-extension 1283 (file-name-sans-extension
1230 (file-name-nondirectory file))) 1284 (file-name-nondirectory file)))
1231 dir-section-contents) 1285 dir-section-contents)
1232 file-dir-entry (Info-extract-dir-entry-from file)) 1286 file-dir-entry (Info-extract-dir-entry-from file))
1233 (if dir-entry 1287 (if dir-entry
1234 (if file-dir-entry 1288 (if file-dir-entry
1235 ;; A dir entry in the info file takes precedence over an 1289 ;; A dir entry in the info file takes precedence over
1236 ;; existing entry in the dir file 1290 ;; an existing entry in the dir file
1237 (setcdr dir-entry (cdr file-dir-entry))) 1291 (setcdr dir-entry (cdr file-dir-entry)))
1238 (unless (or not-first-section 1292 (unless (or not-first-section
1239 (assoc (downcase 1293 (assoc (downcase
1240 (file-name-sans-extension 1294 (file-name-sans-extension
1241 (file-name-nondirectory file))) 1295 (file-name-nondirectory file)))
1242 dir-full-contents)) 1296 dir-full-contents))
1243 (if file-dir-entry 1297 (if file-dir-entry
1244 (setq dir-section-contents (cons file-dir-entry 1298 (setq dir-section-contents
1245 dir-section-contents)) 1299 (cons file-dir-entry dir-section-contents))
1246 (setq dir-section-contents 1300 (setq dir-section-contents
1247 (cons (list 'dummy 1301 (cons (list 'dummy
1248 (capitalize (file-name-sans-extension 1302 (capitalize (file-name-sans-extension
1249 (file-name-nondirectory file))) 1303 (file-name-nondirectory
1304 file)))
1250 ":" 1305 ":"
1251 (list Info-no-description-string)) 1306 (list Info-no-description-string))
1252 dir-section-contents)))))) 1307 dir-section-contents))))))
1253 Info-dir-newer-info-files) 1308 Info-dir-newer-info-files)
1254 (delete-region (point-min) (point-max)) 1309 (delete-region (point-min) (point-max))
1257 (if (= next-section (point-max)) 1312 (if (= next-section (point-max))
1258 (setq next-section nil) 1313 (setq next-section nil)
1259 (or (setq mark (and (re-search-forward "^\\* " nil t) 1314 (or (setq mark (and (re-search-forward "^\\* " nil t)
1260 (match-beginning 0))) 1315 (match-beginning 0)))
1261 (throw 'done nil)) 1316 (throw 'done nil))
1262 (setq next-section (or (and (re-search-forward "^[^* \t].*:[ \t]*$" nil t) 1317 (setq next-section (or (and (re-search-forward
1318 "^[^* \t].*:[ \t]*$" nil t)
1263 (match-beginning 0)) 1319 (match-beginning 0))
1264 (point-max)))) 1320 (point-max))))
1265 (setq not-first-section t))) 1321 (setq not-first-section t)))
1266 (if to-temp 1322 (if to-temp
1267 (progn 1323 (progn
1270 (save-buffer) 1326 (save-buffer)
1271 (message "Rebuilding %s...done" file)))))) 1327 (message "Rebuilding %s...done" file))))))
1272 1328
1273 ;;;###autoload 1329 ;;;###autoload
1274 (defun Info-batch-rebuild-dir () 1330 (defun Info-batch-rebuild-dir ()
1275 "(Re)build info `dir' files in the directories remaining on the command line. 1331 "(Re)build `dir' files in the directories remaining on the command line.
1276 Use this from the command line, with `-batch'; 1332 Use this from the command line, with `-batch', it won't work in an
1277 it won't work in an interactive Emacs. 1333 interactive XEmacs.
1278 Each file is processed even if an error occurred previously. 1334
1279 For example, invoke \"xemacs -batch -f Info-batch-rebuild-dir /usr/local/info\"" 1335 Each file is processed even if an error occurred previously. For example,
1336 invoke \"xemacs -batch -f Info-batch-rebuild-dir /usr/local/info\"."
1280 ;; command-line-args-left is what is left of the command line (from 1337 ;; command-line-args-left is what is left of the command line (from
1281 ;; startup.el) 1338 ;; startup.el)
1282 (defvar command-line-args-left) ; Avoid 'free variable' warning 1339 (defvar command-line-args-left) ; Avoid 'free variable' warning
1283 (if (not noninteractive) 1340 (if (not noninteractive)
1284 (error "`Info-batch-rebuild-dir' is to be used only with -batch")) 1341 (error "`Info-batch-rebuild-dir' is to be used only with -batch"))
1287 (while command-line-args-left 1344 (while command-line-args-left
1288 (if (not (file-directory-p (car command-line-args-left))) 1345 (if (not (file-directory-p (car command-line-args-left)))
1289 (message "Warning: Skipped %s. Not a directory." 1346 (message "Warning: Skipped %s. Not a directory."
1290 (car command-line-args-left)) 1347 (car command-line-args-left))
1291 (setq dir (expand-file-name "dir" (car command-line-args-left))) 1348 (setq dir (expand-file-name "dir" (car command-line-args-left)))
1292 (setq localdir (expand-file-name "localdir" (car command-line-args-left))) 1349 (setq localdir (expand-file-name "localdir"
1350 (car command-line-args-left)))
1293 (cond 1351 (cond
1294 ((file-exists-p dir) 1352 ((file-exists-p dir)
1295 (Info-rebuild-dir dir)) 1353 (Info-rebuild-dir dir))
1296 ((file-exists-p localdir) 1354 ((file-exists-p localdir)
1297 (Info-rebuild-dir localdir)) 1355 (Info-rebuild-dir localdir))
1329 (search-forward "\n\^_") 1387 (search-forward "\n\^_")
1330 (forward-line 2) 1388 (forward-line 2)
1331 (catch 'foo 1389 (catch 'foo
1332 (while (not (looking-at "\^_")) 1390 (while (not (looking-at "\^_"))
1333 (if (not (eolp)) 1391 (if (not (eolp))
1334 (let ((beg (point)) 1392 (let ((start (point))
1335 thisfilepos thisfilename) 1393 thisfilepos thisfilename)
1336 (search-forward ": ") 1394 (search-forward ": ")
1337 (setq thisfilename (buffer-substring beg (- (point) 2))) 1395 (setq thisfilename (buffer-substring start (- (point) 2)))
1338 (setq thisfilepos (read (current-buffer))) 1396 (setq thisfilepos (read (current-buffer)))
1339 ;; read in version 19 stops at the end of number. 1397 ;; read in version 19 stops at the end of number.
1340 ;; Advance to the next line. 1398 ;; Advance to the next line.
1341 (if (eolp) 1399 (if (eolp)
1342 (forward-line 1)) 1400 (forward-line 1))
1351 (widen) 1409 (widen)
1352 (erase-buffer) 1410 (erase-buffer)
1353 (Info-insert-file-contents (Info-suffixed-file 1411 (Info-insert-file-contents (Info-suffixed-file
1354 (expand-file-name lastfilename 1412 (expand-file-name lastfilename
1355 (file-name-directory 1413 (file-name-directory
1356 Info-current-file))) 1414 Info-current-file))
1415 'exact)
1357 t) 1416 t)
1358 (set-buffer-modified-p nil) 1417 (set-buffer-modified-p nil)
1359 (setq Info-current-subfile lastfilename))) 1418 (setq Info-current-subfile lastfilename)))
1360 (goto-char (point-min)) 1419 (goto-char (point-min))
1361 (search-forward "\n\^_") 1420 (search-forward "\n\^_")
1362 (+ (- nodepos lastfilepos) (point)))) 1421 (+ (- nodepos lastfilepos) (point))))
1363 1422
1364 (defun Info-suffixed-file (name &optional name2) 1423 (defun Info-all-case-regexp (str)
1365 "Look for NAME with each of the `Info-suffix-list' extensions in 1424 (let ((regexp "")
1366 turn. Optional NAME2 is the name of a fallback info file to check 1425 (len (length str))
1367 for; usually a downcased version of NAME." 1426 (i 0)
1368 (let ((suff Info-suffix-list) 1427 c)
1369 (found nil) 1428 (while (< i len)
1370 file file2) 1429 (setq c (aref str i))
1371 (while (and suff (not found)) 1430 (cond ((or (and (>= c ?A) (<= c ?Z))
1372 (setq file (concat name (caar suff)) 1431 (and (>= c ?a) (<= c ?z)))
1373 file2 (and name2 (concat name2 (caar suff)))) 1432 (setq regexp (concat regexp
1374 (cond 1433 "["
1375 ((file-regular-p file) 1434 (char-to-string (downcase c))
1376 (setq found file)) 1435 "\\|"
1377 ((and file2 (file-regular-p file2)) 1436 (char-to-string (upcase c))
1378 (setq found file2)) 1437 "]")))
1379 (t 1438 (t
1380 (setq suff (cdr suff))))) 1439 (setq regexp (concat regexp (char-to-string c)))))
1381 (or found 1440 (setq i (1+ i)))
1382 (and name (when (file-regular-p name) 1441 regexp))
1383 name)) 1442
1384 (and name2 (when (file-regular-p name2) 1443 (defun Info-suffixed-file (name &optional exact)
1385 name2))))) 1444 "Look for an info file named NAME. This function tries to be smart in
1445 finding the file corresponding to NAME: if it doesn't exist, several
1446 variants are looked for, notably by appending suffixes from
1447 `Info-suffix-list' and by trying to change the characters case in NAME.
1448
1449 The optional argument EXACT prevents this function from trying different case
1450 versions of NAME. Only the suffixes are tried."
1451 (catch 'found
1452 ;; First, try NAME alone:
1453 (and (file-regular-p name) (throw 'found name))
1454 ;; Then, try different variants
1455 (let ((suff-match (concat "\\("
1456 (let ((suff-list Info-suffix-list)
1457 suff regexp)
1458 (while (setq suff (pop suff-list))
1459 (setq regexp
1460 (concat regexp
1461 (regexp-quote (car suff))
1462 (and suff-list "\\|"))))
1463 regexp)
1464 "\\)?$"))
1465 (dir (file-name-directory name))
1466 file files)
1467 (setq name (file-name-nondirectory name))
1468 (setq files
1469 (condition-case data ;; protect against invalid directory
1470 ;; First, try NAME[.<suffix>]
1471 (append
1472 (directory-files dir 'fullname
1473 (concat "^" (regexp-quote name) suff-match)
1474 nil t)
1475 (if exact
1476 nil
1477 ;; Then, try to match the name independantly of the
1478 ;; characters case.
1479 (directory-files dir 'fullname
1480 (Info-all-case-regexp
1481 (concat "^"
1482 (regexp-quote name)
1483 suff-match))
1484 nil t)))
1485 (t
1486 (display-warning 'info
1487 (format "directory `%s' error: %s" dir data))
1488 nil)))
1489 (while (setq file (pop files))
1490 (and (file-regular-p file)
1491 (throw 'found file)))
1492 )))
1386 1493
1387 (defun Info-insert-file-contents (file &optional visit) 1494 (defun Info-insert-file-contents (file &optional visit)
1388 (setq file (expand-file-name file default-directory)) 1495 (setq file (expand-file-name file default-directory))
1389 (let ((suff Info-suffix-list)) 1496 (let ((suff Info-suffix-list)
1390 (while (and suff (or (<= (length file) (length (car (car suff)))) 1497 len)
1391 (not (equal (substring file 1498 (while (and suff
1392 (- (length (car (car suff))))) 1499 (setq len (length (car (car suff))))
1393 (car (car suff)))))) 1500 (or (<= (length file) len)
1501 (not (or
1502 (equal (substring file (- len))
1503 (car (car suff)))
1504 (equal (substring file (- len))
1505 (upcase (car (car suff)))))
1506 )))
1394 (setq suff (cdr suff))) 1507 (setq suff (cdr suff)))
1395 (if (stringp (cdr (car suff))) 1508 (if (stringp (cdr (car suff)))
1396 (let ((command (if (string-match "%s" (cdr (car suff))) 1509 (let ((command (if (string-match "%s" (cdr (car suff)))
1397 (format (cdr (car suff)) file) 1510 (format (cdr (car suff)) file)
1398 (concat (cdr (car suff)) " < " file)))) 1511 (concat (cdr (car suff)) " < " file))))
1455 (list (cons modeline-buffer-id-left-extent "Info: ") 1568 (list (cons modeline-buffer-id-left-extent "Info: ")
1456 (cons modeline-buffer-id-right-extent 1569 (cons modeline-buffer-id-right-extent
1457 (concat 1570 (concat
1458 "(" 1571 "("
1459 (if Info-current-file 1572 (if Info-current-file
1460 (let ((name (file-name-nondirectory Info-current-file))) 1573 (let ((name (file-name-nondirectory
1461 (if (string-match "\\.info$" name) 1574 Info-current-file)))
1462 (substring name 0 -5) 1575 (if (string-match "^\\([^.]*\\)\\..*$" name)
1576 (match-string 1 name)
1463 name)) 1577 name))
1464 "") 1578 "")
1465 ")" 1579 ")"
1466 (or Info-current-node "")))))) 1580 (or Info-current-node ""))))))
1467 1581
1536 (defun Info-read-node-name-1 (string predicate code) 1650 (defun Info-read-node-name-1 (string predicate code)
1537 (let ((no-completion (and (> (length string) 0) (eq (aref string 0) ?\()))) 1651 (let ((no-completion (and (> (length string) 0) (eq (aref string 0) ?\())))
1538 (cond ((eq code nil) 1652 (cond ((eq code nil)
1539 (if no-completion 1653 (if no-completion
1540 string 1654 string
1541 (try-completion string Info-read-node-completion-table predicate))) 1655 (try-completion string Info-read-node-completion-table
1656 predicate)))
1542 ((eq code t) 1657 ((eq code t)
1543 (if no-completion 1658 (if no-completion
1544 nil 1659 nil
1545 (all-completions string Info-read-node-completion-table predicate))) 1660 (all-completions string Info-read-node-completion-table
1661 predicate)))
1546 ((eq code 'lambda) 1662 ((eq code 'lambda)
1547 (if no-completion 1663 (if no-completion
1548 t 1664 t
1549 (assoc string Info-read-node-completion-table)))))) 1665 (assoc string Info-read-node-completion-table))))))
1550 1666
1593 (match-end 1))) 1709 (match-end 1)))
1594 compl)))) 1710 compl))))
1595 (goto-char (point-min)) 1711 (goto-char (point-min))
1596 (while (search-forward "\n\^_" nil t) 1712 (while (search-forward "\n\^_" nil t)
1597 (forward-line 1) 1713 (forward-line 1)
1598 (let ((beg (point))) 1714 (let ((start (point)))
1599 (forward-line 1) 1715 (forward-line 1)
1600 (if (re-search-backward "Node: *\\([^,\n]*\\) *[,\n\t]" 1716 (if (re-search-backward "Node: *\\([^,\n]*\\) *[,\n\t]"
1601 beg t) 1717 start t)
1602 (setq compl 1718 (setq compl
1603 (cons (list (buffer-substring (match-beginning 1) 1719 (cons (list (buffer-substring (match-beginning 1)
1604 (match-end 1))) 1720 (match-end 1)))
1605 compl)))))))) 1721 compl))))))))
1606 (setq Info-current-file-completions compl)))) 1722 (setq Info-current-file-completions compl))))
1632 (if (null Info-current-subfile) 1748 (if (null Info-current-subfile)
1633 (progn (re-search-forward regexp) (setq found (point))) 1749 (progn (re-search-forward regexp) (setq found (point)))
1634 (condition-case nil 1750 (condition-case nil
1635 (progn (re-search-forward regexp) (setq found (point))) 1751 (progn (re-search-forward regexp) (setq found (point)))
1636 (search-failed nil))))) 1752 (search-failed nil)))))
1637 (if (not found) ;can only happen in subfile case -- else would have erred 1753 (if (not found)
1754 ;; can only happen in subfile case -- else would have erred
1638 (unwind-protect 1755 (unwind-protect
1639 (let ((list ())) 1756 (let ((list ()))
1640 (save-excursion 1757 (save-excursion
1641 (set-buffer (marker-buffer Info-tag-table-marker)) 1758 (set-buffer (marker-buffer Info-tag-table-marker))
1642 (goto-char (point-min)) 1759 (goto-char (point-min))
1650 (beginning-of-line) 1767 (beginning-of-line)
1651 (while (not (eobp)) 1768 (while (not (eobp))
1652 (re-search-forward "\\(^.*\\): [0-9]+$") 1769 (re-search-forward "\\(^.*\\): [0-9]+$")
1653 (goto-char (+ (match-end 1) 2)) 1770 (goto-char (+ (match-end 1) 2))
1654 (setq list (cons (cons (read (current-buffer)) 1771 (setq list (cons (cons (read (current-buffer))
1655 (buffer-substring (match-beginning 1) 1772 (buffer-substring
1656 (match-end 1))) 1773 (match-beginning 1)
1774 (match-end 1)))
1657 list)) 1775 list))
1658 (goto-char (1+ (match-end 0)))) 1776 (goto-char (1+ (match-end 0))))
1659 (setq list (nreverse list) 1777 (setq list (nreverse list)
1660 list (cdr list)))) 1778 list (cdr list))))
1661 (while list 1779 (while list
1877 (interactive "p") 1995 (interactive "p")
1878 (Info-next-reference (- n))) 1996 (Info-next-reference (- n)))
1879 1997
1880 (defun Info-extract-menu-node-name (&optional errmessage multi-line) 1998 (defun Info-extract-menu-node-name (&optional errmessage multi-line)
1881 (skip-chars-forward " \t\n") 1999 (skip-chars-forward " \t\n")
1882 (let ((beg (point)) 2000 (let ((start (point))
1883 str i) 2001 str i)
1884 (skip-chars-forward "^:") 2002 (skip-chars-forward "^:")
1885 (forward-char 1) 2003 (forward-char 1)
1886 (setq str 2004 (setq str
1887 (if (looking-at ":") 2005 (if (looking-at ":")
1888 (buffer-substring beg (1- (point))) 2006 (buffer-substring start (1- (point)))
1889 (skip-chars-forward " \t\n") 2007 (skip-chars-forward " \t\n")
1890 ;; Kludge. 2008 ;; Kludge.
1891 ;; Allow dots in node name not followed by whitespace. 2009 ;; Allow dots in node name not followed by whitespace.
1892 (re-search-forward 2010 (re-search-forward
1893 (concat "\\(([^)]+)[^." 2011 (concat "\\(([^)]+)[^."
2376 (setq bufs (cdr bufs)))) 2494 (setq bufs (cdr bufs))))
2377 (goto-char savept))))) 2495 (goto-char savept)))))
2378 2496
2379 (defvar Info-annotate-map nil 2497 (defvar Info-annotate-map nil
2380 "Local keymap used within `a' command of Info.") 2498 "Local keymap used within `a' command of Info.")
2499
2381 (if Info-annotate-map 2500 (if Info-annotate-map
2382 nil 2501 nil
2383 ;; (setq Info-annotate-map (nconc (make-sparse-keymap) text-mode-map)) 2502 ;; (setq Info-annotate-map (nconc (make-sparse-keymap) text-mode-map))
2384 (setq Info-annotate-map (copy-keymap text-mode-map)) 2503 (setq Info-annotate-map (copy-keymap text-mode-map))
2385 (define-key Info-annotate-map "\C-c\C-c" 'Info-cease-annotate)) 2504 (define-key Info-annotate-map "\C-c\C-c" 'Info-cease-annotate))
2691 ((>= x (- w bx)) (Info-next) t) 2810 ((>= x (- w bx)) (Info-next) t)
2692 (t nil))))) 2811 (t nil)))))
2693 2812
2694 (defvar Info-mode-map nil 2813 (defvar Info-mode-map nil
2695 "Keymap containing Info commands.") 2814 "Keymap containing Info commands.")
2815
2696 (if Info-mode-map 2816 (if Info-mode-map
2697 nil 2817 nil
2698 (setq Info-mode-map (make-sparse-keymap)) 2818 (setq Info-mode-map (make-sparse-keymap))
2699 (suppress-keymap Info-mode-map) 2819 (suppress-keymap Info-mode-map)
2700 (define-key Info-mode-map "." 'beginning-of-buffer) 2820 (define-key Info-mode-map "." 'beginning-of-buffer)
2853 (run-hooks 'Info-mode-hook) 2973 (run-hooks 'Info-mode-hook)
2854 (Info-set-mode-line)) 2974 (Info-set-mode-line))
2855 2975
2856 (defvar Info-edit-map nil 2976 (defvar Info-edit-map nil
2857 "Local keymap used within `e' command of Info.") 2977 "Local keymap used within `e' command of Info.")
2978
2858 (if Info-edit-map 2979 (if Info-edit-map
2859 nil 2980 nil
2860 ;; XEmacs: remove FSF stuff 2981 ;; XEmacs: remove FSF stuff
2861 (setq Info-edit-map (make-sparse-keymap)) 2982 (setq Info-edit-map (make-sparse-keymap))
2862 (set-keymap-name Info-edit-map 'Info-edit-map) 2983 (set-keymap-name Info-edit-map 'Info-edit-map)
2992 (progn 3113 (progn
2993 (goto-char (match-end 0)) 3114 (goto-char (match-end 0))
2994 (while 3115 (while
2995 (looking-at "[ \t]*[^:, \t\n]+:[ \t]+\\([^:,\t\n]+\\),?\n?") 3116 (looking-at "[ \t]*[^:, \t\n]+:[ \t]+\\([^:,\t\n]+\\),?\n?")
2996 (goto-char (match-end 0)) 3117 (goto-char (match-end 0))
2997 (Info-highlight-region (match-beginning 1) (match-end 1) 'info-xref)))) 3118 (Info-highlight-region (match-beginning 1) (match-end 1)
3119 'info-xref))))
2998 ;; Now get the xrefs in the body 3120 ;; Now get the xrefs in the body
2999 (goto-char (point-min)) 3121 (goto-char (point-min))
3000 (while (re-search-forward xref-regexp nil t) 3122 (while (re-search-forward xref-regexp nil t)
3001 (if (= (char-after (1- (match-beginning 0))) ?\") ; hack 3123 (if (= (char-after (1- (match-beginning 0))) ?\") ; hack
3002 nil 3124 nil
3003 (Info-highlight-region (match-beginning 1) (match-end 1) 'info-xref))) 3125 (Info-highlight-region (match-beginning 1) (match-end 1)
3126 'info-xref)))
3004 ;; then highlight the nodes in the menu. 3127 ;; then highlight the nodes in the menu.
3005 (goto-char (point-min)) 3128 (goto-char (point-min))
3006 (if (and (search-forward "\n* menu:" nil t)) 3129 (if (and (search-forward "\n* menu:" nil t))
3007 (while (re-search-forward 3130 (while (re-search-forward
3008 "^\\* \\([^:\t\n]*\\):?:[ \t\n]" nil t) 3131 "^\\* \\([^:\t\n]*\\):?:[ \t\n]" nil t)
3009 (Info-highlight-region (match-beginning 1) (match-end 1) 'info-node))) 3132 (Info-highlight-region (match-beginning 1) (match-end 1)
3133 'info-node)))
3010 (set-buffer-modified-p nil)))) 3134 (set-buffer-modified-p nil))))
3011 3135
3012 (defun Info-construct-menu (&optional event) 3136 (defun Info-construct-menu (&optional event)
3013 "Construct a menu of Info commands. 3137 "Construct a menu of Info commands.
3014 Adds an entry for the node at EVENT, or under point if EVENT is omitted. 3138 Adds an entry for the node at EVENT, or under point if EVENT is omitted.