comparison lisp/info.el @ 1971:b540866e8a79

(Info-insert-dir): Make menu items in Top node pointing each of the other nodes. (Info-insert-dir): New function. (Info-find-node): Use Info-insert-dir to visit dir file.
author Richard M. Stallman <rms@gnu.org>
date Mon, 01 Mar 1993 09:25:44 +0000
parents 04fb1d3d6992
children 0582c70595f1
comparison
equal deleted inserted replaced
1970:64a07c3362f1 1971:b540866e8a79
103 ;; Convert filename to lower case if not found as specified. 103 ;; Convert filename to lower case if not found as specified.
104 ;; Expand it. 104 ;; Expand it.
105 (if filename 105 (if filename
106 (let (temp temp-downcase found) 106 (let (temp temp-downcase found)
107 (setq filename (substitute-in-file-name filename)) 107 (setq filename (substitute-in-file-name filename))
108 (let ((dirs (if (string-match "^\\./" filename) 108 (if (string= (downcase (file-name-nondirectory filename)) "dir")
109 ;; If specified name starts with `./' 109 (setq found t)
110 ;; then just try current directory. 110 (let ((dirs (if (string-match "^\\./" filename)
111 '("./") 111 ;; If specified name starts with `./'
112 Info-directory-list))) 112 ;; then just try current directory.
113 ;; Search the directory list for file FILENAME. 113 '("./")
114 (while (and dirs (not found)) 114 Info-directory-list)))
115 (setq temp (expand-file-name filename (car dirs))) 115 ;; Search the directory list for file FILENAME.
116 (setq temp-downcase 116 (while (and dirs (not found))
117 (expand-file-name (downcase filename) (car dirs))) 117 (setq temp (expand-file-name filename (car dirs)))
118 ;; Try several variants of specified name. 118 (setq temp-downcase
119 ;; Try downcasing, appending `.info', or both. 119 (expand-file-name (downcase filename) (car dirs)))
120 (cond ((file-exists-p temp) 120 ;; Try several variants of specified name.
121 (setq found temp)) 121 ;; Try downcasing, appending `.info', or both.
122 ((file-exists-p temp-downcase) 122 (cond ((file-exists-p temp)
123 (setq found temp-downcase)) 123 (setq found temp))
124 ((file-exists-p (concat temp ".info")) 124 ((file-exists-p temp-downcase)
125 (setq found (concat temp ".info"))) 125 (setq found temp-downcase))
126 ((file-exists-p (concat temp-downcase ".info")) 126 ((file-exists-p (concat temp ".info"))
127 (setq found (concat temp-downcase ".info")))) 127 (setq found (concat temp ".info")))
128 (setq dirs (cdr dirs)))) 128 ((file-exists-p (concat temp-downcase ".info"))
129 (setq found (concat temp-downcase ".info"))))
130 (setq dirs (cdr dirs)))))
129 (if found 131 (if found
130 (setq filename found) 132 (setq filename found)
131 (error "Info file %s does not exist" filename)))) 133 (error "Info file %s does not exist" filename))))
132 ;; Record the node we are leaving. 134 ;; Record the node we are leaving.
133 (if (and Info-current-file (not no-going-back)) 135 (if (and Info-current-file (not no-going-back))
149 (let ((buffer-read-only nil)) 151 (let ((buffer-read-only nil))
150 (setq Info-current-file nil 152 (setq Info-current-file nil
151 Info-current-subfile nil 153 Info-current-subfile nil
152 buffer-file-name nil) 154 buffer-file-name nil)
153 (erase-buffer) 155 (erase-buffer)
154 (insert-file-contents filename t) 156 (setq default-directory Info-directory)
157 (if (eq filename t)
158 (Info-insert-dir)
159 (insert-file-contents filename t)
160 (setq default-directory (file-name-directory filename)))
155 (set-buffer-modified-p nil) 161 (set-buffer-modified-p nil)
156 (setq default-directory (file-name-directory filename))
157 ;; See whether file has a tag table. Record the location if yes. 162 ;; See whether file has a tag table. Record the location if yes.
158 (set-marker Info-tag-table-marker nil) 163 (set-marker Info-tag-table-marker nil)
159 (goto-char (point-max)) 164 (goto-char (point-max))
160 (forward-line -8) 165 (forward-line -8)
161 (or (equal nodename "*") 166 (or (equal nodename "*")
179 (insert-buffer-substring buf) 184 (insert-buffer-substring buf)
180 (set-marker Info-tag-table-marker 185 (set-marker Info-tag-table-marker
181 (match-end 0)))) 186 (match-end 0))))
182 (set-marker Info-tag-table-marker pos)))) 187 (set-marker Info-tag-table-marker pos))))
183 (setq Info-current-file 188 (setq Info-current-file
184 (file-name-sans-versions buffer-file-name)))) 189 (if (eq filename t) "dir"
190 (file-name-sans-versions buffer-file-name)))))
185 (if (equal nodename "*") 191 (if (equal nodename "*")
186 (progn (setq Info-current-node nodename) 192 (progn (setq Info-current-node nodename)
187 (Info-set-mode-line)) 193 (Info-set-mode-line))
188 ;; Search file for a suitable node. 194 ;; Search file for a suitable node.
189 (let ((guesspos (point-min)) 195 (let ((guesspos (point-min))
223 (let ((hist (car Info-history))) 229 (let ((hist (car Info-history)))
224 (setq Info-history (cdr Info-history)) 230 (setq Info-history (cdr Info-history))
225 (Info-find-node (nth 0 hist) (nth 1 hist) t) 231 (Info-find-node (nth 0 hist) (nth 1 hist) t)
226 (goto-char (nth 2 hist))))) 232 (goto-char (nth 2 hist)))))
227 (goto-char (point-min))) 233 (goto-char (point-min)))
234
235 ;; Record the contents of the (virtual) dir file,
236 ;; once we have merged it for the first time,
237 ;; so we can save time subsequently.
238 (defvar Info-dir-contents nil)
239
240 ;; Construct the Info directory node by merging the files named `dir'
241 ;; from various directories.
242 (defun Info-insert-dir ()
243 (if Info-dir-contents
244 (insert Info-dir-contents)
245 (let ((dirs Info-directory-list)
246 buffers buffer others nodes)
247 ;; Search the directory list for file FILENAME.
248 (while dirs
249 (setq temp (expand-file-name "dir" (car dirs)))
250 ;; Try several variants of specified name.
251 ;; Try downcasing, appending `.info', or both.
252 (cond ((file-exists-p temp)
253 (setq buffers (cons (find-file-noselect temp) buffers)))
254 ((file-exists-p (concat temp ".info"))
255 (setq buffers (cons (find-file-noselect (concat temp ".info"))
256 buffers))))
257 (setq dirs (cdr dirs)))
258 ;; Distinguish the dir file that comes with Emacs
259 ;; from all the others.
260 (setq buffer (car buffers)
261 others (cdr buffers))
262 ;; Insert the entire original dir file as a start.
263 (insert-buffer buffer)
264 ;; Look at each of the other buffers one by one.
265 (while others
266 (let ((other (car others)))
267 ;; In each, find all the menus.
268 (save-excursion
269 (set-buffer other)
270 (goto-char (point-min))
271 ;; Find each menu, and add an elt to NODES for it.
272 (while (re-search-forward "^\\* Menu:" nil t)
273 (let (beg nodename end)
274 (forward-line 1)
275 (setq beg (point))
276 (search-backward "\n")
277 (search-forward "Node: ")
278 (setq nodename (Info-following-node-name))
279 (search-forward "\n" nil 'move)
280 (beginning-of-line)
281 (setq end (point))
282 (setq nodes (cons (list nodename other beg end) nodes))))))
283 (setq others (cdr others)))
284 ;; Add to the main menu a menu item for each other node.
285 (re-search-forward "^\\* Menu:")
286 (forward-line 1)
287 (let ((menu-items '("top"))
288 (nodes nodes)
289 (case-fold-search t)
290 (end (save-excursion (search-forward "" nil t) (point))))
291 (while nodes
292 (let ((nodename (car (car nodes))))
293 (or (member (downcase nodename) menu-items)
294 (re-search-forward (concat "^\\* " (regexp-quote nodename) ":")
295 end t)
296 (progn
297 (insert "* " nodename "\n")
298 (setq menu-items (cons nodename menu-item)))))
299 (setq nodes (cdr nodes))))
300 ;; Now take each node of each of the other buffers
301 ;; and merge it into the main buffer.
302 (while nodes
303 (let ((nodename (car (car nodes))))
304 (goto-char (point-min))
305 ;; Find the like-named node in the main buffer.
306 (if (re-search-forward (concat "\n.*\n.*Node: "
307 (regexp-quote nodename)
308 "[,\n\t]")
309 nil t)
310 (progn
311 (search-forward "\n" nil 'move)
312 (beginning-of-line))
313 ;; If none exists, add one.
314 (goto-char (point-max))
315 (insert "\nFile: dir\tnode: " nodename "\n\n* Menu:\n\n"))
316 ;; Merge the text from the other buffer's menu
317 ;; into the menu in the like-named node in the main buffer.
318 (apply 'insert-buffer-substring (cdr (car nodes)))
319 (insert "\n"))
320 (setq nodes (cdr nodes)))
321 ;; Kill all the buffers we just made.
322 (while buffers
323 (kill-buffer (car buffers))
324 (setq buffers (cdr buffers))))
325 (setq Info-dir-contents (buffer-string))))
228 326
229 (defun Info-read-subfile (nodepos) 327 (defun Info-read-subfile (nodepos)
230 (set-buffer (marker-buffer Info-tag-table-marker)) 328 (set-buffer (marker-buffer Info-tag-table-marker))
231 (goto-char (point-min)) 329 (goto-char (point-min))
232 (search-forward "\n\^_") 330 (search-forward "\n\^_")
410 (Info-following-node-name)) 508 (Info-following-node-name))
411 (if (eq errorname t) 509 (if (eq errorname t)
412 nil 510 nil
413 (error (concat "Node has no " (capitalize (or errorname name)))))))) 511 (error (concat "Node has no " (capitalize (or errorname name))))))))
414 512
513 ;; Return the node name in the buffer following point.
514 ;; ALLOWEDCHARS, if non-nil, goes within [...] to make a regexp
515 ;; saying which chas may appear in the node name.
415 (defun Info-following-node-name (&optional allowedchars) 516 (defun Info-following-node-name (&optional allowedchars)
416 (skip-chars-forward " \t") 517 (skip-chars-forward " \t")
417 (buffer-substring 518 (buffer-substring
418 (point) 519 (point)
419 (progn 520 (progn