comparison lisp/textmodes/texnfo-upd.el @ 24175:ec6c3e69f89a

(texinfo-make-menu): Make region-end a marker.
author Karl Heuer <kwzh@gnu.org>
date Mon, 25 Jan 1999 17:04:23 +0000
parents c9d093e48f15
children 6b85141508e0
comparison
equal deleted inserted replaced
24174:4cd52e40cf31 24175:ec6c3e69f89a
176 (interactive 176 (interactive
177 (if prefix-arg 177 (if prefix-arg
178 (list (point) (mark)))) 178 (list (point) (mark))))
179 (if (null beginning) 179 (if (null beginning)
180 (let ((level (texinfo-hierarchic-level))) 180 (let ((level (texinfo-hierarchic-level)))
181 (texinfo-make-one-menu level) 181 (texinfo-make-one-menu level)
182 (message "Menu updated")) 182 (message "Menu updated"))
183 ;; else 183 ;; else
184 (message "Making or updating menus in %s... " (buffer-name)) 184 (message "Making or updating menus in %s... " (buffer-name))
185 (save-excursion 185 (save-excursion
186 (goto-char (min beginning end)) 186 (goto-char (min beginning end))
187 ;; find section type following point 187 ;; find section type following point
188 (let ((level (texinfo-hierarchic-level)) 188 (let ((level (texinfo-hierarchic-level))
189 (region-end (max beginning end))) 189 (region-end-marker (make-marker)))
190 (save-restriction 190 (set-marker region-end-marker (max beginning end))
191 (widen) 191 (save-restriction
192 192 (widen)
193 (while (texinfo-find-lower-level-node level region-end) 193
194 (setq level (texinfo-hierarchic-level)) ; new, lower level 194 (while (texinfo-find-lower-level-node
195 (texinfo-make-one-menu level)) 195 level (marker-position region-end-marker))
196 196 (setq level (texinfo-hierarchic-level)) ; new, lower level
197 (while (and (< (point) region-end) 197 (texinfo-make-one-menu level))
198 (texinfo-find-higher-level-node level region-end)) 198
199 (setq level (texinfo-hierarchic-level)) 199 (while (and (< (point) (marker-position region-end-marker))
200 (texinfo-find-higher-level-node
201 level (marker-position region-end-marker)))
202 (setq level (texinfo-hierarchic-level))
200 ;; Don't allow texinfo-find-higher-level-node 203 ;; Don't allow texinfo-find-higher-level-node
201 ;; to find the same node again. 204 ;; to find the same node again.
202 (forward-line 1) 205 (forward-line 1)
203 (while (texinfo-find-lower-level-node level region-end) 206 (while (texinfo-find-lower-level-node
204 (setq level (texinfo-hierarchic-level)) ; new, lower level 207 level (marker-position region-end-marker))
205 (texinfo-make-one-menu level)))))) 208 (setq level (texinfo-hierarchic-level)) ; new, lower level
209 (texinfo-make-one-menu level))))))
206 (message "Making or updating menus in %s...done" (buffer-name)))) 210 (message "Making or updating menus in %s...done" (buffer-name))))
207 211
208 (defun texinfo-make-one-menu (level) 212 (defun texinfo-make-one-menu (level)
209 "Make a menu of all the appropriate nodes in this section. 213 "Make a menu of all the appropriate nodes in this section.
210 `Appropriate nodes' are those associated with sections that are 214 `Appropriate nodes' are those associated with sections that are
217 (end-of-line) 221 (end-of-line)
218 (point))) 222 (point)))
219 (end (texinfo-update-menu-region-end level)) 223 (end (texinfo-update-menu-region-end level))
220 (first (texinfo-menu-first-node beginning end)) 224 (first (texinfo-menu-first-node beginning end))
221 (node-name (progn 225 (node-name (progn
222 (goto-char beginning) 226 (goto-char beginning)
223 (beginning-of-line) 227 (beginning-of-line)
224 (texinfo-copy-node-name))) 228 (texinfo-copy-node-name)))
225 (new-menu-list (texinfo-make-menu-list beginning end level))) 229 (new-menu-list (texinfo-make-menu-list beginning end level)))
226 (if (texinfo-old-menu-p beginning first) 230 (if (texinfo-old-menu-p beginning first)
227 (progn 231 (progn
228 (texinfo-incorporate-descriptions new-menu-list) 232 (texinfo-incorporate-descriptions new-menu-list)
229 (texinfo-incorporate-menu-entry-names new-menu-list) 233 (texinfo-incorporate-menu-entry-names new-menu-list)
230 (texinfo-delete-old-menu beginning first))) 234 (texinfo-delete-old-menu beginning first)))
231 (texinfo-insert-menu new-menu-list node-name))) 235 (texinfo-insert-menu new-menu-list node-name)))
232 236
233 (defun texinfo-all-menus-update (&optional update-all-nodes-p) 237 (defun texinfo-all-menus-update (&optional update-all-nodes-p)
234 "Update every regular menu in a Texinfo file. 238 "Update every regular menu in a Texinfo file.
235 Update pre-existing master menu, if there is one. 239 Update pre-existing master menu, if there is one.
236 240
237 If called with a non-nil argument, this function first updates all the 241 If called with a non-nil argument, this function first updates all the
238 nodes in the buffer before updating the menus." 242 nodes in the buffer before updating the menus."
239 (interactive "P") 243 (interactive "P")
240 (let ((case-fold-search t) 244 (let ((case-fold-search t)
241 master-menu-p) 245 master-menu-p)
242 (save-excursion 246 (save-excursion
243 (push-mark (point-max) t) 247 (push-mark (point-max) t)
244 (goto-char (point-min)) 248 (goto-char (point-min))
245 (message "Checking for a master menu in %s ... "(buffer-name)) 249 (message "Checking for a master menu in %s ... "(buffer-name))
246 (save-excursion 250 (save-excursion
247 (if (search-forward texinfo-master-menu-header nil t) 251 (if (search-forward texinfo-master-menu-header nil t)
248 (progn 252 (progn
249 ;; Check if @detailmenu kludge is used; 253 ;; Check if @detailmenu kludge is used;
250 ;; if so, leave point before @detailmenu. 254 ;; if so, leave point before @detailmenu.
251 (search-backward "\n@detailmenu" 255 (search-backward "\n@detailmenu"
252 (save-excursion (forward-line -3) (point)) 256 (save-excursion (forward-line -3) (point))
253 t) 257 t)
254 ;; Remove detailed master menu listing 258 ;; Remove detailed master menu listing
255 (setq master-menu-p t) 259 (setq master-menu-p t)
256 (goto-char (match-beginning 0)) 260 (goto-char (match-beginning 0))
257 (let ((end-of-detailed-menu-descriptions 261 (let ((end-of-detailed-menu-descriptions
258 (save-excursion ; beginning of end menu line 262 (save-excursion ; beginning of end menu line
259 (goto-char (texinfo-menu-end)) 263 (goto-char (texinfo-menu-end))
260 (beginning-of-line) (forward-char -1) 264 (beginning-of-line) (forward-char -1)
261 (point)))) 265 (point))))
262 (delete-region (point) end-of-detailed-menu-descriptions))))) 266 (delete-region (point) end-of-detailed-menu-descriptions)))))
263 267
264 (if update-all-nodes-p 268 (if update-all-nodes-p
265 (progn 269 (progn
266 (message "Updating all nodes in %s ... " (buffer-name)) 270 (message "Updating all nodes in %s ... " (buffer-name))
267 (sleep-for 2) 271 (sleep-for 2)
268 (texinfo-update-node (point-min) (point-max)))) 272 (texinfo-update-node (point-min) (point-max))))
269 273
270 (message "Updating all menus in %s ... " (buffer-name)) 274 (message "Updating all menus in %s ... " (buffer-name))
271 (sleep-for 2) 275 (sleep-for 2)
272 (texinfo-make-menu (point-max) (point-min)) 276 (texinfo-make-menu (point-max) (point-min))
273 277
274 (if master-menu-p 278 (if master-menu-p
275 (progn 279 (progn
276 (message "Updating the master menu in %s... " (buffer-name)) 280 (message "Updating the master menu in %s... " (buffer-name))
277 (sleep-for 2) 281 (sleep-for 2)
278 (texinfo-master-menu nil)))) 282 (texinfo-master-menu nil))))
279 283
280 (message "Done...updated all the menus. You may save the buffer."))) 284 (message "Done...updated all the menus. You may save the buffer.")))
281 285
282 (defun texinfo-find-lower-level-node (level region-end) 286 (defun texinfo-find-lower-level-node (level region-end)
283 "Search forward from point for node at any level lower than LEVEL. 287 "Search forward from point for node at any level lower than LEVEL.
286 290
287 Return t if the node is found, else nil. Leave point at the beginning 291 Return t if the node is found, else nil. Leave point at the beginning
288 of the node if one is found; else do not move point." 292 of the node if one is found; else do not move point."
289 (let ((case-fold-search t)) 293 (let ((case-fold-search t))
290 (if (and (< (point) region-end) 294 (if (and (< (point) region-end)
291 (re-search-forward 295 (re-search-forward
292 (concat 296 (concat
293 "\\(^@node\\).*\n" ; match node line 297 "\\(^@node\\).*\n" ; match node line
294 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any 298 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any
295 "\\|" ; or 299 "\\|" ; or
296 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any 300 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any
297 (eval (cdr (assoc level texinfo-update-menu-lower-regexps)))) 301 (eval (cdr (assoc level texinfo-update-menu-lower-regexps))))
298 ;; the next higher level node marks the end of this 302 ;; the next higher level node marks the end of this
299 ;; section, and no lower level node will be found beyond 303 ;; section, and no lower level node will be found beyond
300 ;; this position even if region-end is farther off 304 ;; this position even if region-end is farther off
301 (texinfo-update-menu-region-end level) 305 (texinfo-update-menu-region-end level)
302 t)) 306 t))
303 (goto-char (match-beginning 1))))) 307 (goto-char (match-beginning 1)))))
304 308
305 (defun texinfo-find-higher-level-node (level region-end) 309 (defun texinfo-find-higher-level-node (level region-end)
306 "Search forward from point for node at any higher level than argument LEVEL. 310 "Search forward from point for node at any higher level than argument LEVEL.
307 Search is limited to the end of the marked region, REGION-END. 311 Search is limited to the end of the marked region, REGION-END.
308 312
314 318
315 (let ((case-fold-search t)) 319 (let ((case-fold-search t))
316 (cond 320 (cond
317 ((or (string-equal "top" level) (string-equal "chapter" level)) 321 ((or (string-equal "top" level) (string-equal "chapter" level))
318 (if (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" region-end t) 322 (if (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" region-end t)
319 (progn (beginning-of-line) t))) 323 (progn (beginning-of-line) t)))
320 (t 324 (t
321 (if (re-search-forward 325 (if (re-search-forward
322 (concat 326 (concat
323 "\\(^@node\\).*\n" ; match node line 327 "\\(^@node\\).*\n" ; match node line
324 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any 328 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any
325 "\\|" ; or 329 "\\|" ; or
326 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any 330 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any
327 (eval (cdr (assoc level texinfo-update-menu-higher-regexps)))) 331 (eval (cdr (assoc level texinfo-update-menu-higher-regexps))))
328 region-end t) 332 region-end t)
329 (progn (beginning-of-line) t)))))) 333 (progn (beginning-of-line) t))))))
330 334
331 335
332 ;;; Making the list of new menu entries 336 ;;; Making the list of new menu entries
333 337
334 (defun texinfo-make-menu-list (beginning end level) 338 (defun texinfo-make-menu-list (beginning end level)
344 element consists only of the node name." 348 element consists only of the node name."
345 (goto-char beginning) 349 (goto-char beginning)
346 (let (new-menu-list) 350 (let (new-menu-list)
347 (while (texinfo-menu-locate-entry-p level end) 351 (while (texinfo-menu-locate-entry-p level end)
348 (setq new-menu-list 352 (setq new-menu-list
349 (cons (cons 353 (cons (cons
350 (texinfo-copy-node-name) 354 (texinfo-copy-node-name)
351 (prog1 "" (forward-line 1))) 355 (prog1 "" (forward-line 1)))
352 ;; Use following to insert section titles automatically. 356 ;; Use following to insert section titles automatically.
353 ;; (texinfo-copy-section-title)) 357 ;; (texinfo-copy-section-title))
354 new-menu-list))) 358 new-menu-list)))
355 (reverse new-menu-list))) 359 (reverse new-menu-list)))
356 360
357 (defun texinfo-menu-locate-entry-p (level search-end) 361 (defun texinfo-menu-locate-entry-p (level search-end)
358 "Find a node that will be part of menu for this section. 362 "Find a node that will be part of menu for this section.
359 First argument is a string such as \"section\" specifying the general 363 First argument is a string such as \"section\" specifying the general
365 369
366 The function finds entries of the same type. Thus `subsections' and 370 The function finds entries of the same type. Thus `subsections' and
367 `unnumberedsubsecs' will appear in the same menu." 371 `unnumberedsubsecs' will appear in the same menu."
368 (let ((case-fold-search t)) 372 (let ((case-fold-search t))
369 (if (re-search-forward 373 (if (re-search-forward
370 (concat 374 (concat
371 "\\(^@node\\).*\n" ; match node line 375 "\\(^@node\\).*\n" ; match node line
372 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any 376 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any
373 "\\|" ; or 377 "\\|" ; or
374 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any 378 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any
375 (eval 379 (eval
376 (cdr (assoc level texinfo-update-menu-same-level-regexps)))) 380 (cdr (assoc level texinfo-update-menu-same-level-regexps))))
377 search-end 381 search-end
378 t) 382 t)
379 (goto-char (match-beginning 1))))) 383 (goto-char (match-beginning 1)))))
380 384
381 (defun texinfo-copy-node-name () 385 (defun texinfo-copy-node-name ()
382 "Return the node name as a string. 386 "Return the node name as a string.
383 387
384 Start with point at the beginning of the node line; copy the text 388 Start with point at the beginning of the node line; copy the text
387 line. If there is no node name, returns an empty string." 391 line. If there is no node name, returns an empty string."
388 392
389 (save-excursion 393 (save-excursion
390 (buffer-substring 394 (buffer-substring
391 (progn (forward-word 1) ; skip over node command 395 (progn (forward-word 1) ; skip over node command
392 (skip-chars-forward " \t") ; and over spaces 396 (skip-chars-forward " \t") ; and over spaces
393 (point)) 397 (point))
394 (if (search-forward 398 (if (search-forward
395 "," 399 ","
396 (save-excursion (end-of-line) (point)) t) ; bound search 400 (save-excursion (end-of-line) (point)) t) ; bound search
397 (1- (point)) 401 (1- (point))
398 (end-of-line) (point))))) 402 (end-of-line) (point)))))
399 403
400 (defun texinfo-copy-section-title () 404 (defun texinfo-copy-section-title ()
401 "Return the title of the section as a string. 405 "Return the title of the section as a string.
402 The title is used as a description line in the menu when one does not 406 The title is used as a description line in the menu when one does not
412 416
413 (goto-char (match-beginning 7)) ; match section name 417 (goto-char (match-beginning 7)) ; match section name
414 418
415 (buffer-substring 419 (buffer-substring
416 (progn (forward-word 1) ; skip over section type 420 (progn (forward-word 1) ; skip over section type
417 (skip-chars-forward " \t") ; and over spaces 421 (skip-chars-forward " \t") ; and over spaces
418 (point)) 422 (point))
419 (progn (end-of-line) (point)))) 423 (progn (end-of-line) (point))))
420 424
421 425
422 ;;; Handling the old menu 426 ;;; Handling the old menu
423 427
449 pairs in which the first element of the pair is the node name and the 453 pairs in which the first element of the pair is the node name and the
450 second element the description. The new menu is changed destructively. 454 second element the description. The new menu is changed destructively.
451 The old menu is the menu as it appears in the Texinfo file." 455 The old menu is the menu as it appears in the Texinfo file."
452 456
453 (let ((new-menu-list-pointer new-menu-list) 457 (let ((new-menu-list-pointer new-menu-list)
454 (end-of-menu (texinfo-menu-end))) 458 (end-of-menu (texinfo-menu-end)))
455 (while new-menu-list 459 (while new-menu-list
456 (save-excursion ; keep point at beginning of menu 460 (save-excursion ; keep point at beginning of menu
457 (if (re-search-forward 461 (if (re-search-forward
458 ;; Existing nodes can have the form 462 ;; Existing nodes can have the form
459 ;; * NODE NAME:: DESCRIPTION 463 ;; * NODE NAME:: DESCRIPTION
460 ;; or 464 ;; or
461 ;; * MENU ITEM: NODE NAME. DESCRIPTION. 465 ;; * MENU ITEM: NODE NAME. DESCRIPTION.
462 ;; 466 ;;
463 ;; Recognize both when looking for the description. 467 ;; Recognize both when looking for the description.
464 (concat "\\* \\(" ; so only menu entries are found 468 (concat "\\* \\(" ; so only menu entries are found
465 (regexp-quote (car (car new-menu-list))) "::" 469 (regexp-quote (car (car new-menu-list))) "::"
466 "\\|" 470 "\\|"
467 ".*: " (regexp-quote (car (car new-menu-list))) "[.,\t\n]" 471 ".*: " (regexp-quote (car (car new-menu-list))) "[.,\t\n]"
468 "\\)" 472 "\\)"
469 ) ; so only complete entries are found 473 ) ; so only complete entries are found
470 end-of-menu 474 end-of-menu
471 t) 475 t)
472 (setcdr (car new-menu-list) 476 (setcdr (car new-menu-list)
473 (texinfo-menu-copy-old-description end-of-menu)))) 477 (texinfo-menu-copy-old-description end-of-menu))))
474 (setq new-menu-list (cdr new-menu-list))) 478 (setq new-menu-list (cdr new-menu-list)))
475 (setq new-menu-list new-menu-list-pointer))) 479 (setq new-menu-list new-menu-list-pointer)))
476 480
477 (defun texinfo-incorporate-menu-entry-names (new-menu-list) 481 (defun texinfo-incorporate-menu-entry-names (new-menu-list)
478 "Copy any old menu entry names to the new menu. 482 "Copy any old menu entry names to the new menu.
492 496
493 NEW-MENU-LIST is changed destructively. The old menu is the menu as it 497 NEW-MENU-LIST is changed destructively. The old menu is the menu as it
494 appears in the texinfo file." 498 appears in the texinfo file."
495 499
496 (let ((new-menu-list-pointer new-menu-list) 500 (let ((new-menu-list-pointer new-menu-list)
497 (end-of-menu (texinfo-menu-end))) 501 (end-of-menu (texinfo-menu-end)))
498 (while new-menu-list 502 (while new-menu-list
499 (save-excursion ; keep point at beginning of menu 503 (save-excursion ; keep point at beginning of menu
500 (if (re-search-forward 504 (if (re-search-forward
501 ;; Existing nodes can have the form 505 ;; Existing nodes can have the form
502 ;; * NODE NAME:: DESCRIPTION 506 ;; * NODE NAME:: DESCRIPTION
503 ;; or 507 ;; or
504 ;; * MENU ITEM: NODE NAME. DESCRIPTION. 508 ;; * MENU ITEM: NODE NAME. DESCRIPTION.
505 ;; 509 ;;
506 ;; We're interested in the second case. 510 ;; We're interested in the second case.
507 (concat "\\* " ; so only menu entries are found 511 (concat "\\* " ; so only menu entries are found
508 "\\(.*\\): " (regexp-quote (car (car new-menu-list))) 512 "\\(.*\\): " (regexp-quote (car (car new-menu-list)))
509 "[.,\t\n]") 513 "[.,\t\n]")
510 end-of-menu 514 end-of-menu
511 t) 515 t)
512 (setcar 516 (setcar
513 (car new-menu-list) ; replace the node name 517 (car new-menu-list) ; replace the node name
514 (cons (buffer-substring (match-beginning 1) (match-end 1)) 518 (cons (buffer-substring (match-beginning 1) (match-end 1))
515 (car (car new-menu-list))))) 519 (car (car new-menu-list)))))
516 (setq new-menu-list (cdr new-menu-list)))) 520 (setq new-menu-list (cdr new-menu-list))))
517 (setq new-menu-list new-menu-list-pointer))) 521 (setq new-menu-list new-menu-list-pointer)))
518 522
519 (defun texinfo-menu-copy-old-description (end-of-menu) 523 (defun texinfo-menu-copy-old-description (end-of-menu)
520 "Return description field of old menu line as string. 524 "Return description field of old menu line as string.
523 (skip-chars-forward "[:.,\t\n ]+") 527 (skip-chars-forward "[:.,\t\n ]+")
524 ;; don't copy a carriage return at line beginning with asterisk! 528 ;; don't copy a carriage return at line beginning with asterisk!
525 ;; do copy a description that begins with an `@'! 529 ;; do copy a description that begins with an `@'!
526 ;; !! Known bug: does not copy descriptions starting with ^|\{?* etc. 530 ;; !! Known bug: does not copy descriptions starting with ^|\{?* etc.
527 (if (and (looking-at "\\(\\w+\\|@\\)") 531 (if (and (looking-at "\\(\\w+\\|@\\)")
528 (not (looking-at "\\(^\\* \\|^@end menu\\)"))) 532 (not (looking-at "\\(^\\* \\|^@end menu\\)")))
529 (buffer-substring 533 (buffer-substring
530 (point) 534 (point)
531 (save-excursion 535 (save-excursion
532 (re-search-forward "\\(^\\* \\|^@end menu\\)" end-of-menu t) 536 (re-search-forward "\\(^\\* \\|^@end menu\\)" end-of-menu t)
533 (forward-line -1) 537 (forward-line -1)
534 (end-of-line) ; go to end of last description line 538 (end-of-line) ; go to end of last description line
535 (point))) 539 (point)))
536 "")) 540 ""))
537 541
538 (defun texinfo-menu-end () 542 (defun texinfo-menu-end ()
539 "Return position of end of menu, but don't move point. 543 "Return position of end of menu, but don't move point.
540 Signal an error if not end of menu." 544 Signal an error if not end of menu."
541 (save-excursion 545 (save-excursion
542 (if (re-search-forward "^@end menu" nil t) 546 (if (re-search-forward "^@end menu" nil t)
543 (point) 547 (point)
544 (error "Menu does not have an end.")))) 548 (error "Menu does not have an end."))))
545 549
546 (defun texinfo-delete-old-menu (beginning first) 550 (defun texinfo-delete-old-menu (beginning first)
547 "Delete the old menu. Point must be in or after menu. 551 "Delete the old menu. Point must be in or after menu.
548 First argument is position of the beginning of the section in which 552 First argument is position of the beginning of the section in which
549 the menu will be located; second argument is the position of the first 553 the menu will be located; second argument is the position of the first
550 node within the section." 554 node within the section."
551 ;; No third arg to search, so error if search fails. 555 ;; No third arg to search, so error if search fails.
552 (re-search-backward "^@menu" beginning) 556 (re-search-backward "^@menu" beginning)
553 (delete-region (point) 557 (delete-region (point)
554 (save-excursion 558 (save-excursion
555 (re-search-forward "^@end menu" first) 559 (re-search-forward "^@end menu" first)
556 (point)))) 560 (point))))
557 561
558 562
559 ;;; Inserting new menu 563 ;;; Inserting new menu
560 564
561 ;; try 32, but perhaps 24 is better 565 ;; try 32, but perhaps 24 is better
584 (insert "* ") 588 (insert "* ")
585 589
586 ;; Insert the node name (and menu entry name, if present). 590 ;; Insert the node name (and menu entry name, if present).
587 (let ((node-part (car (car menu-list)))) 591 (let ((node-part (car (car menu-list))))
588 (if (stringp node-part) 592 (if (stringp node-part)
589 ;; "Double colon" entry line; menu entry and node name are the same, 593 ;; "Double colon" entry line; menu entry and node name are the same,
590 (insert (format "%s::" node-part)) 594 (insert (format "%s::" node-part))
591 ;; "Single colon" entry line; menu entry and node name are different. 595 ;; "Single colon" entry line; menu entry and node name are different.
592 (insert (format "%s: %s." (car node-part) (cdr node-part))))) 596 (insert (format "%s: %s." (car node-part) (cdr node-part)))))
593 597
594 ;; Insert the description, if present. 598 ;; Insert the description, if present.
595 (if (cdr (car menu-list)) 599 (if (cdr (car menu-list))
596 (progn 600 (progn
597 ;; Move to right place. 601 ;; Move to right place.
598 (indent-to texinfo-column-for-description 2) 602 (indent-to texinfo-column-for-description 2)
599 ;; Insert description. 603 ;; Insert description.
600 (insert (format "%s" (cdr (car menu-list)))))) 604 (insert (format "%s" (cdr (car menu-list))))))
601 605
602 (insert "\n") ; end this menu entry 606 (insert "\n") ; end this menu entry
603 (setq menu-list (cdr menu-list))) 607 (setq menu-list (cdr menu-list)))
604 (insert "@end menu") 608 (insert "@end menu")
605 (message 609 (message
619 (interactive) 623 (interactive)
620 (let (beginning end node-name title) 624 (let (beginning end node-name title)
621 (save-excursion 625 (save-excursion
622 (beginning-of-line) 626 (beginning-of-line)
623 (if (search-forward "* " (save-excursion (end-of-line) (point)) t) 627 (if (search-forward "* " (save-excursion (end-of-line) (point)) t)
624 (progn (skip-chars-forward " \t") 628 (progn (skip-chars-forward " \t")
625 (setq beginning (point))) 629 (setq beginning (point)))
626 (error "This is not a line in a menu!")) 630 (error "This is not a line in a menu!"))
627 631
628 (cond 632 (cond
629 ;; "Double colon" entry line; menu entry and node name are the same, 633 ;; "Double colon" entry line; menu entry and node name are the same,
630 ((search-forward "::" (save-excursion (end-of-line) (point)) t) 634 ((search-forward "::" (save-excursion (end-of-line) (point)) t)
631 (if (looking-at "[ \t]*[^ \t\n]+") 635 (if (looking-at "[ \t]*[^ \t\n]+")
632 (error "Descriptive text already exists.")) 636 (error "Descriptive text already exists."))
633 (skip-chars-backward ": \t") 637 (skip-chars-backward ": \t")
634 (setq node-name (buffer-substring beginning (point)))) 638 (setq node-name (buffer-substring beginning (point))))
635 639
636 ;; "Single colon" entry line; menu entry and node name are different. 640 ;; "Single colon" entry line; menu entry and node name are different.
637 ((search-forward ":" (save-excursion (end-of-line) (point)) t) 641 ((search-forward ":" (save-excursion (end-of-line) (point)) t)
638 (skip-chars-forward " \t") 642 (skip-chars-forward " \t")
639 (setq beginning (point)) 643 (setq beginning (point))
640 ;; Menu entry line ends in a period, comma, or tab. 644 ;; Menu entry line ends in a period, comma, or tab.
641 (if (re-search-forward "[.,\t]" 645 (if (re-search-forward "[.,\t]"
642 (save-excursion (forward-line 1) (point)) t) 646 (save-excursion (forward-line 1) (point)) t)
643 (progn 647 (progn
644 (if (looking-at "[ \t]*[^ \t\n]+") 648 (if (looking-at "[ \t]*[^ \t\n]+")
645 (error "Descriptive text already exists.")) 649 (error "Descriptive text already exists."))
646 (skip-chars-backward "., \t") 650 (skip-chars-backward "., \t")
647 (setq node-name (buffer-substring beginning (point)))) 651 (setq node-name (buffer-substring beginning (point))))
648 ;; Menu entry line ends in a return. 652 ;; Menu entry line ends in a return.
649 (re-search-forward ".*\n" 653 (re-search-forward ".*\n"
650 (save-excursion (forward-line 1) (point)) t) 654 (save-excursion (forward-line 1) (point)) t)
651 (skip-chars-backward " \t\n") 655 (skip-chars-backward " \t\n")
652 (setq node-name (buffer-substring beginning (point))) 656 (setq node-name (buffer-substring beginning (point)))
653 (if (= 0 (length node-name)) 657 (if (= 0 (length node-name))
654 (error "No node name on this line.") 658 (error "No node name on this line.")
655 (insert ".")))) 659 (insert "."))))
656 (t (error "No node name on this line."))) 660 (t (error "No node name on this line.")))
657 ;; Search for node that matches node name, and copy the section title. 661 ;; Search for node that matches node name, and copy the section title.
658 (if (re-search-forward 662 (if (re-search-forward
659 (concat 663 (concat
660 "^@node[ \t]+" 664 "^@node[ \t]+"
661 (regexp-quote node-name) 665 (regexp-quote node-name)
662 ".*\n" ; match node line 666 ".*\n" ; match node line
663 "\\(" 667 "\\("
664 "\\(\\(^@c \\|^@comment\\).*\n\\)" ; match comment line, if any 668 "\\(\\(^@c \\|^@comment\\).*\n\\)" ; match comment line, if any
665 "\\|" ; or 669 "\\|" ; or
666 "\\(^@ifinfo[ ]*\n\\)" ; ifinfo line, if any 670 "\\(^@ifinfo[ ]*\n\\)" ; ifinfo line, if any
667 "\\)?") 671 "\\)?")
668 nil t) 672 nil t)
669 (progn 673 (progn
670 (setq title 674 (setq title
671 (buffer-substring 675 (buffer-substring
672 ;; skip over section type 676 ;; skip over section type
673 (progn (forward-word 1) 677 (progn (forward-word 1)
674 ;; and over spaces 678 ;; and over spaces
675 (skip-chars-forward " \t") 679 (skip-chars-forward " \t")
676 (point)) 680 (point))
677 (progn (end-of-line) 681 (progn (end-of-line)
678 (skip-chars-backward " \t") 682 (skip-chars-backward " \t")
679 (point))))) 683 (point)))))
680 (error "Cannot find node to match node name in menu entry."))) 684 (error "Cannot find node to match node name in menu entry.")))
681 ;; Return point to the menu and insert the title. 685 ;; Return point to the menu and insert the title.
682 (end-of-line) 686 (end-of-line)
683 (delete-region 687 (delete-region
684 (point) 688 (point)
685 (save-excursion (skip-chars-backward " \t") (point))) 689 (save-excursion (skip-chars-backward " \t") (point)))
702 "nIndent menu descriptions to (column number): \nP") 706 "nIndent menu descriptions to (column number): \nP")
703 (save-excursion 707 (save-excursion
704 (save-restriction 708 (save-restriction
705 (widen) 709 (widen)
706 (if (not region-p) 710 (if (not region-p)
707 (progn 711 (progn
708 (re-search-forward "^@menu") 712 (re-search-forward "^@menu")
709 (texinfo-menu-indent-description column) 713 (texinfo-menu-indent-description column)
710 (message 714 (message
711 "Indented descriptions in menu. You may save the buffer.")) 715 "Indented descriptions in menu. You may save the buffer."))
712 ;;else 716 ;;else
713 (message "Indenting every menu description in region... ") 717 (message "Indenting every menu description in region... ")
714 (goto-char (region-beginning)) 718 (goto-char (region-beginning))
715 (while (and (< (point) (region-end)) 719 (while (and (< (point) (region-end))
716 (texinfo-locate-menu-p)) 720 (texinfo-locate-menu-p))
717 (forward-line 1) 721 (forward-line 1)
718 (texinfo-menu-indent-description column)) 722 (texinfo-menu-indent-description column))
719 (message "Indenting done. You may save the buffer."))))) 723 (message "Indenting done. You may save the buffer.")))))
720 724
721 (defun texinfo-menu-indent-description (to-column-number) 725 (defun texinfo-menu-indent-description (to-column-number)
722 "Indent the Texinfo file menu description to TO-COLUMN-NUMBER. 726 "Indent the Texinfo file menu description to TO-COLUMN-NUMBER.
723 Start with point just after the word `menu' in the `@menu' line and 727 Start with point just after the word `menu' in the `@menu' line and
724 leave point on the line before the `@end menu' line. Does not indent 728 leave point on the line before the `@end menu' line. Does not indent
725 second and subsequent lines of a multi-line description." 729 second and subsequent lines of a multi-line description."
726 (let* ((beginning-of-next-line (point))) 730 (let* ((beginning-of-next-line (point)))
727 (while (< beginning-of-next-line 731 (while (< beginning-of-next-line
728 (save-excursion ; beginning of end menu line 732 (save-excursion ; beginning of end menu line
729 (goto-char (texinfo-menu-end)) 733 (goto-char (texinfo-menu-end))
730 (beginning-of-line) 734 (beginning-of-line)
731 (point))) 735 (point)))
732 736
733 (if (re-search-forward "\\* \\(.*::\\|.*: [^.,\t\n]+[.,\t]\\)" 737 (if (re-search-forward "\\* \\(.*::\\|.*: [^.,\t\n]+[.,\t]\\)"
734 (texinfo-menu-end) 738 (texinfo-menu-end)
735 t) 739 t)
736 (progn 740 (progn
737 (let ((beginning-white-space (point))) 741 (let ((beginning-white-space (point)))
738 (skip-chars-forward " \t") ; skip over spaces 742 (skip-chars-forward " \t") ; skip over spaces
739 (if (looking-at "\\(@\\|\\w\\)+") ; if there is text 743 (if (looking-at "\\(@\\|\\w\\)+") ; if there is text
740 (progn 744 (progn
741 ;; remove pre-existing indentation 745 ;; remove pre-existing indentation
742 (delete-region beginning-white-space (point)) 746 (delete-region beginning-white-space (point))
743 (indent-to-column to-column-number)))))) 747 (indent-to-column to-column-number))))))
744 ;; position point at beginning of next line 748 ;; position point at beginning of next line
745 (forward-line 1) 749 (forward-line 1)
746 (setq beginning-of-next-line (point))))) 750 (setq beginning-of-next-line (point)))))
747 751
748 752
786 (widen) 790 (widen)
787 (goto-char (point-min)) 791 (goto-char (point-min))
788 792
789 ;; Move point to location after `top'. 793 ;; Move point to location after `top'.
790 (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t)) 794 (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t))
791 (error "This buffer needs a Top node!")) 795 (error "This buffer needs a Top node!"))
792 796
793 (let ((first-chapter 797 (let ((first-chapter
794 (save-excursion 798 (save-excursion
795 (or (re-search-forward "^@node" nil t) 799 (or (re-search-forward "^@node" nil t)
796 (error "Too few nodes for a master menu!")) 800 (error "Too few nodes for a master menu!"))
797 (point)))) 801 (point))))
798 (if (search-forward texinfo-master-menu-header first-chapter t) 802 (if (search-forward texinfo-master-menu-header first-chapter t)
799 (progn 803 (progn
800 ;; Check if @detailmenu kludge is used; 804 ;; Check if @detailmenu kludge is used;
801 ;; if so, leave point before @detailmenu. 805 ;; if so, leave point before @detailmenu.
802 (search-backward "\n@detailmenu" 806 (search-backward "\n@detailmenu"
803 (save-excursion (forward-line -3) (point)) 807 (save-excursion (forward-line -3) (point))
804 t) 808 t)
805 ;; Remove detailed master menu listing 809 ;; Remove detailed master menu listing
806 (goto-char (match-beginning 0)) 810 (goto-char (match-beginning 0))
807 (let ((end-of-detailed-menu-descriptions 811 (let ((end-of-detailed-menu-descriptions
808 (save-excursion ; beginning of end menu line 812 (save-excursion ; beginning of end menu line
809 (goto-char (texinfo-menu-end)) 813 (goto-char (texinfo-menu-end))
810 (beginning-of-line) (forward-char -1) 814 (beginning-of-line) (forward-char -1)
811 (point)))) 815 (point))))
812 (delete-region (point) end-of-detailed-menu-descriptions))))) 816 (delete-region (point) end-of-detailed-menu-descriptions)))))
813 817
814 (if update-all-nodes-menus-p 818 (if update-all-nodes-menus-p
815 (progn 819 (progn
816 (message "Making a master menu in %s ...first updating all nodes... " 820 (message "Making a master menu in %s ...first updating all nodes... "
817 (buffer-name)) 821 (buffer-name))
818 (sleep-for 2) 822 (sleep-for 2)
819 (texinfo-update-node (point-min) (point-max)) 823 (texinfo-update-node (point-min) (point-max))
820 824
821 (message "Updating all menus in %s ... " (buffer-name)) 825 (message "Updating all menus in %s ... " (buffer-name))
822 (sleep-for 2) 826 (sleep-for 2)
823 (texinfo-make-menu (point-min) (point-max)))) 827 (texinfo-make-menu (point-min) (point-max))))
824 828
825 (message "Now making the master menu in %s... " (buffer-name)) 829 (message "Now making the master menu in %s... " (buffer-name))
826 (sleep-for 2) 830 (sleep-for 2)
827 (goto-char (point-min)) 831 (goto-char (point-min))
828 (texinfo-insert-master-menu-list 832 (texinfo-insert-master-menu-list
833 837
834 (save-excursion 838 (save-excursion
835 (goto-char (point-min)) 839 (goto-char (point-min))
836 840
837 (if (search-forward texinfo-master-menu-header nil t) 841 (if (search-forward texinfo-master-menu-header nil t)
838 (progn 842 (progn
839 (goto-char (match-beginning 0)) 843 (goto-char (match-beginning 0))
840 ;; Check if @detailmenu kludge is used; 844 ;; Check if @detailmenu kludge is used;
841 ;; if so, leave point before @detailmenu. 845 ;; if so, leave point before @detailmenu.
842 (search-backward "\n@detailmenu" 846 (search-backward "\n@detailmenu"
843 (save-excursion (forward-line -3) (point)) 847 (save-excursion (forward-line -3) (point))
844 t) 848 t)
845 (insert "\n") 849 (insert "\n")
846 (delete-blank-lines) 850 (delete-blank-lines)
847 (goto-char (point-min)))) 851 (goto-char (point-min))))
848 852
849 (re-search-forward "^@menu") 853 (re-search-forward "^@menu")
850 (forward-line -1) 854 (forward-line -1)
851 (delete-blank-lines) 855 (delete-blank-lines)
852 856
872 However, there does not need to be a title field." 876 However, there does not need to be a title field."
873 877
874 (let (master-menu-list) 878 (let (master-menu-list)
875 (while (texinfo-locate-menu-p) 879 (while (texinfo-locate-menu-p)
876 (setq master-menu-list 880 (setq master-menu-list
877 (cons (list 881 (cons (list
878 (texinfo-copy-menu) 882 (texinfo-copy-menu)
879 (texinfo-copy-menu-title)) 883 (texinfo-copy-menu-title))
880 master-menu-list))) 884 master-menu-list)))
881 (reverse master-menu-list))) 885 (reverse master-menu-list)))
882 886
883 (defun texinfo-insert-master-menu-list (master-menu-list) 887 (defun texinfo-insert-master-menu-list (master-menu-list)
884 "Format and insert the master menu in the current buffer." 888 "Format and insert the master menu in the current buffer."
885 (goto-char (point-min)) 889 (goto-char (point-min))
886 ;; Insert a master menu only after `Top' node and before next node 890 ;; Insert a master menu only after `Top' node and before next node
887 ;; \(or include file if there is no next node\). 891 ;; \(or include file if there is no next node\).
888 (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t)) 892 (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t))
889 (error "This buffer needs a Top node!")) 893 (error "This buffer needs a Top node!"))
890 (let ((first-chapter 894 (let ((first-chapter
891 (save-excursion (re-search-forward "^@node\\|^@include") (point)))) 895 (save-excursion (re-search-forward "^@node\\|^@include") (point))))
892 (if (not (re-search-forward "^@menu" first-chapter t)) 896 (if (not (re-search-forward "^@menu" first-chapter t))
893 (error 897 (error
894 "Buffer lacks ordinary `Top' menu in which to insert master."))) 898 "Buffer lacks ordinary `Top' menu in which to insert master.")))
895 (beginning-of-line) 899 (beginning-of-line)
896 (delete-region ; buffer must have ordinary top menu 900 (delete-region ; buffer must have ordinary top menu
897 (point) 901 (point)
898 (save-excursion (re-search-forward "^@end menu") (point))) 902 (save-excursion (re-search-forward "^@end menu") (point)))
899 903
906 ;; Insert chapter menu entries 910 ;; Insert chapter menu entries
907 (setq this-very-menu-list (reverse (car (car master-menu-list)))) 911 (setq this-very-menu-list (reverse (car (car master-menu-list))))
908 ;; Tell user what is going on. 912 ;; Tell user what is going on.
909 (message "Inserting chapter menu entry: %s ... " this-very-menu-list) 913 (message "Inserting chapter menu entry: %s ... " this-very-menu-list)
910 (while this-very-menu-list 914 (while this-very-menu-list
911 (insert "* " (car this-very-menu-list) "\n") 915 (insert "* " (car this-very-menu-list) "\n")
912 (setq this-very-menu-list (cdr this-very-menu-list))) 916 (setq this-very-menu-list (cdr this-very-menu-list)))
913 917
914 (setq master-menu-list (cdr master-menu-list)) 918 (setq master-menu-list (cdr master-menu-list))
915 919
916 ;; Only insert detailed master menu if there is one.... 920 ;; Only insert detailed master menu if there is one....
917 (if (car (car master-menu-list)) 921 (if (car (car master-menu-list))
918 (progn (setq master-menu-inserted-p t) 922 (progn (setq master-menu-inserted-p t)
919 (insert (concat "\n@detailmenu\n" 923 (insert (concat "\n@detailmenu\n"
920 texinfo-master-menu-header)))) 924 texinfo-master-menu-header))))
921 925
922 ;; @detailmenu added 5 Sept 1996 to `texinfo-master-menu-header' 926 ;; @detailmenu added 5 Sept 1996 to `texinfo-master-menu-header'
923 ;; at Karl Berry's request to avert a bug in `makeinfo'; 927 ;; at Karl Berry's request to avert a bug in `makeinfo';
924 ;; all agree this is a bad kludge and should eventually be removed. 928 ;; all agree this is a bad kludge and should eventually be removed.
933 ;; ((("beta" "alpha") "title-A") 937 ;; ((("beta" "alpha") "title-A")
934 ;; (("delta" "gamma") "title-B")) 938 ;; (("delta" "gamma") "title-B"))
935 939
936 (while master-menu-list 940 (while master-menu-list
937 941
938 (message 942 (message
939 "Inserting menu for %s .... " (car (cdr (car master-menu-list)))) 943 "Inserting menu for %s .... " (car (cdr (car master-menu-list))))
940 ;; insert title of menu section 944 ;; insert title of menu section
941 (insert "\n" (car (cdr (car master-menu-list))) "\n\n") 945 (insert "\n" (car (cdr (car master-menu-list))) "\n\n")
942 946
943 ;; insert each menu entry 947 ;; insert each menu entry
944 (setq this-very-menu-list (reverse (car (car master-menu-list)))) 948 (setq this-very-menu-list (reverse (car (car master-menu-list))))
945 (while this-very-menu-list 949 (while this-very-menu-list
946 (insert "* " (car this-very-menu-list) "\n") 950 (insert "* " (car this-very-menu-list) "\n")
947 (setq this-very-menu-list (cdr this-very-menu-list))) 951 (setq this-very-menu-list (cdr this-very-menu-list)))
948 952
949 (setq master-menu-list (cdr master-menu-list))) 953 (setq master-menu-list (cdr master-menu-list)))
950 954
951 ;; Finish menu 955 ;; Finish menu
952 956
953 ;; @detailmenu (see note above) 957 ;; @detailmenu (see note above)
954 ;; Only insert @end detailmenu if a master menu was inserted. 958 ;; Only insert @end detailmenu if a master menu was inserted.
955 (if master-menu-inserted-p 959 (if master-menu-inserted-p
956 (insert "\n@end detailmenu")) 960 (insert "\n@end detailmenu"))
957 (insert "\n@end menu\n\n")))) 961 (insert "\n@end menu\n\n"))))
958 962
959 (defun texinfo-locate-menu-p () 963 (defun texinfo-locate-menu-p ()
960 "Find the next menu in the texinfo file. 964 "Find the next menu in the texinfo file.
961 If found, leave point after word `menu' on the `@menu' line, and return t. 965 If found, leave point after word `menu' on the `@menu' line, and return t.
967 If such a title cannot be found, return an empty string. Do not move 971 If such a title cannot be found, return an empty string. Do not move
968 point." 972 point."
969 (let ((case-fold-search t)) 973 (let ((case-fold-search t))
970 (save-excursion 974 (save-excursion
971 (if (re-search-backward 975 (if (re-search-backward
972 (concat 976 (concat
973 "\\(^@top" 977 "\\(^@top"
974 "\\|" ; or 978 "\\|" ; or
975 texinfo-section-types-regexp ; all other section types 979 texinfo-section-types-regexp ; all other section types
976 "\\)") 980 "\\)")
977 nil 981 nil
978 t) 982 t)
979 (progn 983 (progn
980 (beginning-of-line) 984 (beginning-of-line)
981 (forward-word 1) ; skip over section type 985 (forward-word 1) ; skip over section type
982 (skip-chars-forward " \t") ; and over spaces 986 (skip-chars-forward " \t") ; and over spaces
983 (buffer-substring 987 (buffer-substring
984 (point) 988 (point)
985 (progn (end-of-line) (point)))) 989 (progn (end-of-line) (point))))
986 "")))) 990 ""))))
987 991
988 (defun texinfo-copy-menu () 992 (defun texinfo-copy-menu ()
989 "Return the entries of an existing menu as a list. 993 "Return the entries of an existing menu as a list.
990 Start with point just after the word `menu' in the `@menu' line 994 Start with point just after the word `menu' in the `@menu' line
991 and leave point on the line before the `@end menu' line." 995 and leave point on the line before the `@end menu' line."
992 (let* (this-menu-list 996 (let* (this-menu-list
993 (end-of-menu (texinfo-menu-end)) ; position of end of `@end menu' 997 (end-of-menu (texinfo-menu-end)) ; position of end of `@end menu'
994 (last-entry (save-excursion ; position of beginning of 998 (last-entry (save-excursion ; position of beginning of
995 ; last `* ' entry 999 ; last `* ' entry
996 (goto-char end-of-menu) 1000 (goto-char end-of-menu)
997 ;; handle multi-line description 1001 ;; handle multi-line description
998 (if (not (re-search-backward "^\\* " nil t)) 1002 (if (not (re-search-backward "^\\* " nil t))
999 (error "No entries in menu.")) 1003 (error "No entries in menu."))
1000 (point)))) 1004 (point))))
1001 (while (< (point) last-entry) 1005 (while (< (point) last-entry)
1002 (if (re-search-forward "^\\* " end-of-menu t) 1006 (if (re-search-forward "^\\* " end-of-menu t)
1003 (progn 1007 (progn
1004 (setq this-menu-list 1008 (setq this-menu-list
1005 (cons 1009 (cons
1006 (buffer-substring 1010 (buffer-substring
1007 (point) 1011 (point)
1008 ;; copy multi-line descriptions 1012 ;; copy multi-line descriptions
1009 (save-excursion 1013 (save-excursion
1010 (re-search-forward "\\(^\\* \\|^@e\\)" nil t) 1014 (re-search-forward "\\(^\\* \\|^@e\\)" nil t)
1011 (- (point) 3))) 1015 (- (point) 3)))
1012 this-menu-list))))) 1016 this-menu-list)))))
1013 this-menu-list)) 1017 this-menu-list))
1014 1018
1015 1019
1016 ;;; Determining the hierarchical level in the texinfo file 1020 ;;; Determining the hierarchical level in the texinfo file
1017 1021
1028 ((re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" 1032 ((re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)"
1029 ;;; Following search limit by cph but causes a bug 1033 ;;; Following search limit by cph but causes a bug
1030 ;;; (save-excursion 1034 ;;; (save-excursion
1031 ;;; (end-of-line) 1035 ;;; (end-of-line)
1032 ;;; (point)) 1036 ;;; (point))
1033 nil 1037 nil
1034 t) 1038 t)
1035 "top") 1039 "top")
1036 ((re-search-forward texinfo-section-types-regexp nil t) 1040 ((re-search-forward texinfo-section-types-regexp nil t)
1037 (buffer-substring-no-properties 1041 (buffer-substring-no-properties
1038 (progn (beginning-of-line) ; copy its name 1042 (progn (beginning-of-line) ; copy its name
1039 (1+ (point))) 1043 (1+ (point)))
1040 (progn (forward-word 1) 1044 (progn (forward-word 1)
1041 (point)))) 1045 (point))))
1042 (t 1046 (t
1043 (error 1047 (error
1044 "texinfo-specific-section-type: Chapter or section not found.")))))) 1048 "texinfo-specific-section-type: Chapter or section not found."))))))
1045 1049
1046 (defun texinfo-hierarchic-level () 1050 (defun texinfo-hierarchic-level ()
1047 "Return the general hierarchal level of the next node in a texinfo file. 1051 "Return the general hierarchal level of the next node in a texinfo file.
1048 Thus, a subheading or appendixsubsec is of type subsection." 1052 Thus, a subheading or appendixsubsec is of type subsection."
1049 (let ((case-fold-search t)) 1053 (let ((case-fold-search t))
1050 (cdr (assoc 1054 (cdr (assoc
1051 (texinfo-specific-section-type) 1055 (texinfo-specific-section-type)
1052 texinfo-section-to-generic-alist)))) 1056 texinfo-section-to-generic-alist))))
1053 1057
1054 1058
1055 ;;; Locating the major positions 1059 ;;; Locating the major positions
1056 1060
1057 (defun texinfo-update-menu-region-beginning (level) 1061 (defun texinfo-update-menu-region-beginning (level)
1063 ;; !! Known bug: if section immediately follows top node, this 1067 ;; !! Known bug: if section immediately follows top node, this
1064 ;; returns the beginning of the buffer as the beginning of the 1068 ;; returns the beginning of the buffer as the beginning of the
1065 ;; higher level section. 1069 ;; higher level section.
1066 (cond 1070 (cond
1067 ((or (string-equal "top" level) 1071 ((or (string-equal "top" level)
1068 (string-equal "chapter" level)) 1072 (string-equal "chapter" level))
1069 (save-excursion 1073 (save-excursion
1070 (goto-char (point-min)) 1074 (goto-char (point-min))
1071 (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t) 1075 (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t)
1072 (beginning-of-line) 1076 (beginning-of-line)
1073 (point))) 1077 (point)))
1074 (t 1078 (t
1075 (save-excursion 1079 (save-excursion
1076 (re-search-backward 1080 (re-search-backward
1077 (concat 1081 (concat
1078 "\\(^@node\\).*\n" ; match node line 1082 "\\(^@node\\).*\n" ; match node line
1079 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any 1083 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any
1080 "\\|" ; or 1084 "\\|" ; or
1081 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any 1085 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any
1082 (eval 1086 (eval
1083 (cdr (assoc level texinfo-update-menu-higher-regexps)))) 1087 (cdr (assoc level texinfo-update-menu-higher-regexps))))
1084 nil 1088 nil
1085 'goto-beginning) 1089 'goto-beginning)
1086 (point)))))) 1090 (point))))))
1087 1091
1088 (defun texinfo-update-menu-region-end (level) 1092 (defun texinfo-update-menu-region-end (level)
1089 "Locate end of higher level section this section is within. 1093 "Locate end of higher level section this section is within.
1090 Return position; do not move point. Thus, if this level is a 1094 Return position; do not move point. Thus, if this level is a
1091 subsection, find the node for the section this subsection is within. 1095 subsection, find the node for the section this subsection is within.
1092 If level is top or chapter, returns end of file. Only argument is a 1096 If level is top or chapter, returns end of file. Only argument is a
1093 string of the general type of section." 1097 string of the general type of section."
1094 (let ((case-fold-search t)) 1098 (let ((case-fold-search t))
1095 (save-excursion 1099 (save-excursion
1096 (if (re-search-forward 1100 (if (re-search-forward
1097 (concat 1101 (concat
1098 "\\(^@node\\).*\n" ; match node line 1102 "\\(^@node\\).*\n" ; match node line
1099 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any 1103 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any
1100 "\\|" ; or 1104 "\\|" ; or
1101 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any 1105 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any
1102 (eval 1106 (eval
1103 ;; Never finds end of level above chapter so goes to end. 1107 ;; Never finds end of level above chapter so goes to end.
1104 (cdr (assoc level texinfo-update-menu-higher-regexps)))) 1108 (cdr (assoc level texinfo-update-menu-higher-regexps))))
1105 nil 1109 nil
1106 'goto-end) 1110 'goto-end)
1107 (match-beginning 1) 1111 (match-beginning 1)
1108 (point-max))))) 1112 (point-max)))))
1109 1113
1110 (defun texinfo-menu-first-node (beginning end) 1114 (defun texinfo-menu-first-node (beginning end)
1111 "Locate first node of the section the menu will be placed in. 1115 "Locate first node of the section the menu will be placed in.
1112 Return position; do not move point. 1116 Return position; do not move point.
1113 The menu will be located just before this position. 1117 The menu will be located just before this position.
1282 (if prefix-arg 1286 (if prefix-arg
1283 (list (point) (mark)))) 1287 (list (point) (mark))))
1284 (if (null beginning) 1288 (if (null beginning)
1285 ;; Update a single node. 1289 ;; Update a single node.
1286 (let ((auto-fill-function nil) (auto-fill-hook nil)) 1290 (let ((auto-fill-function nil) (auto-fill-hook nil))
1287 (if (not (re-search-backward "^@node" (point-min) t)) 1291 (if (not (re-search-backward "^@node" (point-min) t))
1288 (error "Node line not found before this position")) 1292 (error "Node line not found before this position"))
1289 (texinfo-update-the-node) 1293 (texinfo-update-the-node)
1290 (message "Done...updated the node. You may save the buffer.")) 1294 (message "Done...updated the node. You may save the buffer."))
1291 ;; else 1295 ;; else
1292 (let ((auto-fill-function nil) 1296 (let ((auto-fill-function nil)
1293 (auto-fill-hook nil)) 1297 (auto-fill-hook nil))
1294 (save-excursion 1298 (save-excursion
1295 (save-restriction 1299 (save-restriction
1316 (texinfo-delete-existing-pointers) 1320 (texinfo-delete-existing-pointers)
1317 (message "Updating node: %s ... " (texinfo-copy-node-name)) 1321 (message "Updating node: %s ... " (texinfo-copy-node-name))
1318 (save-restriction 1322 (save-restriction
1319 (widen) 1323 (widen)
1320 (let* 1324 (let*
1321 ((case-fold-search t) 1325 ((case-fold-search t)
1322 (level (texinfo-hierarchic-level)) 1326 (level (texinfo-hierarchic-level))
1323 (beginning (texinfo-update-menu-region-beginning level)) 1327 (beginning (texinfo-update-menu-region-beginning level))
1324 (end (texinfo-update-menu-region-end level))) 1328 (end (texinfo-update-menu-region-end level)))
1325 (if (string-equal level "top") 1329 (if (string-equal level "top")
1326 (texinfo-top-pointer-case) 1330 (texinfo-top-pointer-case)
1327 ;; else 1331 ;; else
1328 (texinfo-insert-pointer beginning end level 'next) 1332 (texinfo-insert-pointer beginning end level 'next)
1329 (texinfo-insert-pointer beginning end level 'previous) 1333 (texinfo-insert-pointer beginning end level 'previous)
1330 (texinfo-insert-pointer beginning end level 'up) 1334 (texinfo-insert-pointer beginning end level 'up)
1331 (texinfo-clean-up-node-line))))) 1335 (texinfo-clean-up-node-line)))))
1332 1336
1333 (defun texinfo-top-pointer-case () 1337 (defun texinfo-top-pointer-case ()
1334 "Insert pointers in the Top node. This is a special case. 1338 "Insert pointers in the Top node. This is a special case.
1335 1339
1336 The `Next' pointer is a pointer to a chapter or section at a lower 1340 The `Next' pointer is a pointer to a chapter or section at a lower
1338 to `(dir)'. Point must be at the beginning of the node line, and is 1342 to `(dir)'. Point must be at the beginning of the node line, and is
1339 left at the end of the node line." 1343 left at the end of the node line."
1340 1344
1341 (texinfo-clean-up-node-line) 1345 (texinfo-clean-up-node-line)
1342 (insert ", " 1346 (insert ", "
1343 (save-excursion 1347 (save-excursion
1344 ;; There may be an @chapter or other such command between 1348 ;; There may be an @chapter or other such command between
1345 ;; the top node line and the next node line, as a title 1349 ;; the top node line and the next node line, as a title
1346 ;; for an `ifinfo' section. This @chapter command must 1350 ;; for an `ifinfo' section. This @chapter command must
1347 ;; must be skipped. So the procedure is to search for 1351 ;; must be skipped. So the procedure is to search for
1348 ;; the next `@node' line, and then copy its name. 1352 ;; the next `@node' line, and then copy its name.
1349 (if (re-search-forward "^@node" nil t) 1353 (if (re-search-forward "^@node" nil t)
1350 (progn 1354 (progn
1351 (beginning-of-line) 1355 (beginning-of-line)
1352 (texinfo-copy-node-name)) 1356 (texinfo-copy-node-name))
1353 " ")) 1357 " "))
1354 ", (dir), (dir)")) 1358 ", (dir), (dir)"))
1355 1359
1356 (defun texinfo-check-for-node-name () 1360 (defun texinfo-check-for-node-name ()
1357 "Determine whether the node has a node name. Prompt for one if not. 1361 "Determine whether the node has a node name. Prompt for one if not.
1358 Point must be at beginning of node line. Does not move point." 1362 Point must be at beginning of node line. Does not move point."
1359 (save-excursion 1363 (save-excursion
1360 (let ((initial (texinfo-copy-next-section-title))) 1364 (let ((initial (texinfo-copy-next-section-title)))
1361 ;; This is not clean. Use `interactive' to read the arg. 1365 ;; This is not clean. Use `interactive' to read the arg.
1362 (forward-word 1) ; skip over node command 1366 (forward-word 1) ; skip over node command
1363 (skip-chars-forward " \t") ; and over spaces 1367 (skip-chars-forward " \t") ; and over spaces
1364 (if (not (looking-at "[^,\t\n ]+")) ; regexp based on what Info looks for 1368 (if (not (looking-at "[^,\t\n ]+")) ; regexp based on what Info looks for
1365 ; alternatively, use "[a-zA-Z]+" 1369 ; alternatively, use "[a-zA-Z]+"
1366 (let ((node-name 1370 (let ((node-name
1367 (read-from-minibuffer 1371 (read-from-minibuffer
1368 "Node name (use no @, commas, colons, or apostrophes): " 1372 "Node name (use no @, commas, colons, or apostrophes): "
1369 initial))) 1373 initial)))
1370 (insert " " node-name)))))) 1374 (insert " " node-name))))))
1371 1375
1372 (defun texinfo-delete-existing-pointers () 1376 (defun texinfo-delete-existing-pointers ()
1373 "Delete `Next', `Previous', and `Up' pointers. 1377 "Delete `Next', `Previous', and `Up' pointers.
1374 Starts from the current position of the cursor, and searches forward 1378 Starts from the current position of the cursor, and searches forward
1375 on the line for a comma and if one is found, deletes the rest of the 1379 on the line for a comma and if one is found, deletes the rest of the
1376 line, including the comma. Leaves point at beginning of line." 1380 line, including the comma. Leaves point at beginning of line."
1377 (let ((eol-point (save-excursion (end-of-line) (point)))) 1381 (let ((eol-point (save-excursion (end-of-line) (point))))
1378 (if (search-forward "," eol-point t) 1382 (if (search-forward "," eol-point t)
1379 (delete-region (1- (point)) eol-point))) 1383 (delete-region (1- (point)) eol-point)))
1380 (beginning-of-line)) 1384 (beginning-of-line))
1381 1385
1382 (defun texinfo-find-pointer (beginning end level direction) 1386 (defun texinfo-find-pointer (beginning end level direction)
1383 "Move point to section associated with next, previous, or up pointer. 1387 "Move point to section associated with next, previous, or up pointer.
1384 Return type of pointer (either `normal' or `no-pointer'). 1388 Return type of pointer (either `normal' or `no-pointer').
1394 will be at some level higher in the Texinfo file. The fourth argument 1398 will be at some level higher in the Texinfo file. The fourth argument
1395 \(one of 'next, 'previous, or 'up\) specifies whether to find the 1399 \(one of 'next, 'previous, or 'up\) specifies whether to find the
1396 `Next', `Previous', or `Up' pointer." 1400 `Next', `Previous', or `Up' pointer."
1397 (let ((case-fold-search t)) 1401 (let ((case-fold-search t))
1398 (cond ((eq direction 'next) 1402 (cond ((eq direction 'next)
1399 (forward-line 3) ; skip over current node 1403 (forward-line 3) ; skip over current node
1400 ;; Search for section commands accompanied by node lines; 1404 ;; Search for section commands accompanied by node lines;
1401 ;; ignore section commands in the middle of nodes. 1405 ;; ignore section commands in the middle of nodes.
1402 (if (re-search-forward 1406 (if (re-search-forward
1403 ;; A `Top' node is never a next pointer, so won't find it. 1407 ;; A `Top' node is never a next pointer, so won't find it.
1404 (concat 1408 (concat
1405 ;; Match node line. 1409 ;; Match node line.
1406 "\\(^@node\\).*\n" 1410 "\\(^@node\\).*\n"
1407 ;; Match comment or ifinfo line, if any 1411 ;; Match comment or ifinfo line, if any
1408 "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?" 1412 "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?"
1409 (eval 1413 (eval
1410 (cdr (assoc level texinfo-update-menu-same-level-regexps)))) 1414 (cdr (assoc level texinfo-update-menu-same-level-regexps))))
1411 end 1415 end
1412 t) 1416 t)
1413 'normal 1417 'normal
1414 'no-pointer)) 1418 'no-pointer))
1415 ((eq direction 'previous) 1419 ((eq direction 'previous)
1416 (if (re-search-backward 1420 (if (re-search-backward
1417 (concat 1421 (concat
1418 "\\(" 1422 "\\("
1419 ;; Match node line. 1423 ;; Match node line.
1420 "\\(^@node\\).*\n" 1424 "\\(^@node\\).*\n"
1421 ;; Match comment or ifinfo line, if any 1425 ;; Match comment or ifinfo line, if any
1422 "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?" 1426 "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?"
1423 (eval 1427 (eval
1424 (cdr (assoc level texinfo-update-menu-same-level-regexps))) 1428 (cdr (assoc level texinfo-update-menu-same-level-regexps)))
1425 "\\|" 1429 "\\|"
1426 ;; Match node line. 1430 ;; Match node line.
1427 "\\(^@node\\).*\n" 1431 "\\(^@node\\).*\n"
1428 ;; Match comment or ifinfo line, if any 1432 ;; Match comment or ifinfo line, if any
1429 "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?" 1433 "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?"
1430 (eval 1434 (eval
1431 (cdr (assoc level texinfo-update-menu-higher-regexps))) 1435 (cdr (assoc level texinfo-update-menu-higher-regexps)))
1432 "\\|" 1436 "\\|"
1433 ;; Handle `Top' node specially. 1437 ;; Handle `Top' node specially.
1434 "^@node [ \t]*top[ \t]*\\(,\\|$\\)" 1438 "^@node [ \t]*top[ \t]*\\(,\\|$\\)"
1435 "\\)") 1439 "\\)")
1436 beginning 1440 beginning
1437 t) 1441 t)
1438 'normal 1442 'normal
1439 'no-pointer)) 1443 'no-pointer))
1440 ((eq direction 'up) 1444 ((eq direction 'up)
1441 (if (re-search-backward 1445 (if (re-search-backward
1442 (concat 1446 (concat
1443 "\\(" 1447 "\\("
1444 ;; Match node line. 1448 ;; Match node line.
1445 "\\(^@node\\).*\n" 1449 "\\(^@node\\).*\n"
1446 ;; Match comment or ifinfo line, if any 1450 ;; Match comment or ifinfo line, if any
1447 "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?" 1451 "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?"
1448 (eval (cdr (assoc level texinfo-update-menu-higher-regexps))) 1452 (eval (cdr (assoc level texinfo-update-menu-higher-regexps)))
1449 "\\|" 1453 "\\|"
1450 ;; Handle `Top' node specially. 1454 ;; Handle `Top' node specially.
1451 "^@node [ \t]*top[ \t]*\\(,\\|$\\)" 1455 "^@node [ \t]*top[ \t]*\\(,\\|$\\)"
1452 "\\)") 1456 "\\)")
1453 (save-excursion 1457 (save-excursion
1454 (goto-char beginning) 1458 (goto-char beginning)
1455 (beginning-of-line) 1459 (beginning-of-line)
1456 (point)) 1460 (point))
1457 t) 1461 t)
1458 'normal 1462 'normal
1459 'no-pointer)) 1463 'no-pointer))
1460 (t 1464 (t
1461 (error "texinfo-find-pointer: lack proper arguments"))))) 1465 (error "texinfo-find-pointer: lack proper arguments")))))
1462 1466
1463 (defun texinfo-pointer-name (kind) 1467 (defun texinfo-pointer-name (kind)
1464 "Return the node name preceding the section command. 1468 "Return the node name preceding the section command.
1465 The argument is the kind of section, either `normal' or `no-pointer'." 1469 The argument is the kind of section, either `normal' or `no-pointer'."
1466 (let (name) 1470 (let (name)
1467 (cond ((eq kind 'normal) 1471 (cond ((eq kind 'normal)
1468 (end-of-line) ; this handles prev node top case 1472 (end-of-line) ; this handles prev node top case
1469 (re-search-backward ; when point is already 1473 (re-search-backward ; when point is already
1470 "^@node" ; at the beginning of @node line 1474 "^@node" ; at the beginning of @node line
1471 (save-excursion (forward-line -3)) 1475 (save-excursion (forward-line -3))
1472 t) 1476 t)
1473 (setq name (texinfo-copy-node-name))) 1477 (setq name (texinfo-copy-node-name)))
1474 ((eq kind 'no-pointer) 1478 ((eq kind 'no-pointer)
1475 ;; Don't need to put a blank in the pointer slot, 1479 ;; Don't need to put a blank in the pointer slot,
1476 ;; since insert "' " always has a space 1480 ;; since insert "' " always has a space
1477 (setq name " "))) ; put a blank in the pointer slot 1481 (setq name " "))) ; put a blank in the pointer slot
1478 name)) 1482 name))
1479 1483
1480 (defun texinfo-insert-pointer (beginning end level direction) 1484 (defun texinfo-insert-pointer (beginning end level direction)
1481 "Insert the `Next', `Previous' or `Up' node name at point. 1485 "Insert the `Next', `Previous' or `Up' node name at point.
1530 1534
1531 (interactive "P") 1535 (interactive "P")
1532 (if (not region-p) 1536 (if (not region-p)
1533 ;; update a single node 1537 ;; update a single node
1534 (let ((auto-fill-function nil) (auto-fill-hook nil)) 1538 (let ((auto-fill-function nil) (auto-fill-hook nil))
1535 (if (not (re-search-backward "^@node" (point-min) t)) 1539 (if (not (re-search-backward "^@node" (point-min) t))
1536 (error "Node line not found before this position.")) 1540 (error "Node line not found before this position."))
1537 (texinfo-sequentially-update-the-node) 1541 (texinfo-sequentially-update-the-node)
1538 (message 1542 (message
1539 "Done...sequentially updated the node . You may save the buffer.")) 1543 "Done...sequentially updated the node . You may save the buffer."))
1540 ;; else 1544 ;; else
1541 (let ((auto-fill-function nil) 1545 (let ((auto-fill-function nil)
1542 (auto-fill-hook nil) 1546 (auto-fill-hook nil)
1543 (beginning (region-beginning)) 1547 (beginning (region-beginning))
1544 (end (region-end))) 1548 (end (region-end)))
1545 (if (= end beginning) 1549 (if (= end beginning)
1546 (error "Please mark a region!")) 1550 (error "Please mark a region!"))
1547 (save-restriction 1551 (save-restriction
1548 (narrow-to-region beginning end) 1552 (narrow-to-region beginning end)
1549 (goto-char beginning) 1553 (goto-char beginning)
1550 (push-mark (point) t) 1554 (push-mark (point) t)
1551 (while (re-search-forward "^@node" (point-max) t) 1555 (while (re-search-forward "^@node" (point-max) t)
1552 (beginning-of-line) 1556 (beginning-of-line)
1553 (texinfo-sequentially-update-the-node)) 1557 (texinfo-sequentially-update-the-node))
1554 (message 1558 (message
1555 "Done...updated the nodes in sequence. You may save the buffer."))))) 1559 "Done...updated the nodes in sequence. You may save the buffer.")))))
1556 1560
1557 (defun texinfo-sequentially-update-the-node () 1561 (defun texinfo-sequentially-update-the-node ()
1558 "Update one node such that the pointers are sequential. 1562 "Update one node such that the pointers are sequential.
1559 A `Next' or `Previous' pointer points to any preceding or following node, 1563 A `Next' or `Previous' pointer points to any preceding or following node,
1560 regardless of its hierarchical level." 1564 regardless of its hierarchical level."
1561 1565
1562 (texinfo-check-for-node-name) 1566 (texinfo-check-for-node-name)
1563 (texinfo-delete-existing-pointers) 1567 (texinfo-delete-existing-pointers)
1564 (message 1568 (message
1565 "Sequentially updating node: %s ... " (texinfo-copy-node-name)) 1569 "Sequentially updating node: %s ... " (texinfo-copy-node-name))
1566 (save-restriction 1570 (save-restriction
1567 (widen) 1571 (widen)
1568 (let* 1572 (let*
1569 ((case-fold-search t) 1573 ((case-fold-search t)
1570 (level (texinfo-hierarchic-level))) 1574 (level (texinfo-hierarchic-level)))
1571 (if (string-equal level "top") 1575 (if (string-equal level "top")
1572 (texinfo-top-pointer-case) 1576 (texinfo-top-pointer-case)
1573 ;; else 1577 ;; else
1574 (texinfo-sequentially-insert-pointer level 'next) 1578 (texinfo-sequentially-insert-pointer level 'next)
1575 (texinfo-sequentially-insert-pointer level 'previous) 1579 (texinfo-sequentially-insert-pointer level 'previous)
1576 (texinfo-sequentially-insert-pointer level 'up) 1580 (texinfo-sequentially-insert-pointer level 'up)
1577 (texinfo-clean-up-node-line))))) 1581 (texinfo-clean-up-node-line)))))
1578 1582
1579 (defun texinfo-sequentially-find-pointer (level direction) 1583 (defun texinfo-sequentially-find-pointer (level direction)
1580 "Find next or previous pointer sequentially in Texinfo file, or up pointer. 1584 "Find next or previous pointer sequentially in Texinfo file, or up pointer.
1581 Move point to section associated with the pointer. Find point even if 1585 Move point to section associated with the pointer. Find point even if
1582 it is in a different section. 1586 it is in a different section.
1589 pointer, some level higher. The second argument (one of `next', 1593 pointer, some level higher. The second argument (one of `next',
1590 `previous', or `up') specifies whether to find the `Next', `Previous', 1594 `previous', or `up') specifies whether to find the `Next', `Previous',
1591 or `Up' pointer." 1595 or `Up' pointer."
1592 (let ((case-fold-search t)) 1596 (let ((case-fold-search t))
1593 (cond ((eq direction 'next) 1597 (cond ((eq direction 'next)
1594 (forward-line 3) ; skip over current node 1598 (forward-line 3) ; skip over current node
1595 (if (re-search-forward 1599 (if (re-search-forward
1596 texinfo-section-types-regexp 1600 texinfo-section-types-regexp
1597 (point-max) 1601 (point-max)
1598 t) 1602 t)
1599 'normal 1603 'normal
1600 'no-pointer)) 1604 'no-pointer))
1601 ((eq direction 'previous) 1605 ((eq direction 'previous)
1602 (if (re-search-backward 1606 (if (re-search-backward
1603 texinfo-section-types-regexp 1607 texinfo-section-types-regexp
1604 (point-min) 1608 (point-min)
1605 t) 1609 t)
1606 'normal 1610 'normal
1607 'no-pointer)) 1611 'no-pointer))
1608 ((eq direction 'up) 1612 ((eq direction 'up)
1609 (if (re-search-backward 1613 (if (re-search-backward
1610 (eval (cdr (assoc level texinfo-update-menu-higher-regexps))) 1614 (eval (cdr (assoc level texinfo-update-menu-higher-regexps)))
1611 beginning 1615 beginning
1612 t) 1616 t)
1613 'normal 1617 'normal
1614 'no-pointer)) 1618 'no-pointer))
1615 (t 1619 (t
1616 (error "texinfo-sequential-find-pointer: lack proper arguments"))))) 1620 (error "texinfo-sequential-find-pointer: lack proper arguments")))))
1617 1621
1618 (defun texinfo-sequentially-insert-pointer (level direction) 1622 (defun texinfo-sequentially-insert-pointer (level direction)
1619 "Insert the `Next', `Previous' or `Up' node name at point. 1623 "Insert the `Next', `Previous' or `Up' node name at point.
1620 Move point forward. 1624 Move point forward.
1621 1625
1652 (push-mark end t) 1656 (push-mark end t)
1653 (setq end-marker (mark-marker)) 1657 (setq end-marker (mark-marker))
1654 1658
1655 (goto-char beginning) 1659 (goto-char beginning)
1656 (while (re-search-forward 1660 (while (re-search-forward
1657 texinfo-section-types-regexp 1661 texinfo-section-types-regexp
1658 end-marker 1662 end-marker
1659 'end) 1663 'end)
1660 ;; Copy title if desired. 1664 ;; Copy title if desired.
1661 (if title-p 1665 (if title-p
1662 (progn 1666 (progn
1663 (beginning-of-line) 1667 (beginning-of-line)
1664 (forward-word 1) 1668 (forward-word 1)
1665 (skip-chars-forward " \t") 1669 (skip-chars-forward " \t")
1666 (setq title (buffer-substring 1670 (setq title (buffer-substring
1667 (point) 1671 (point)
1668 (save-excursion (end-of-line) (point)))))) 1672 (save-excursion (end-of-line) (point))))))
1669 ;; Insert node line if necessary. 1673 ;; Insert node line if necessary.
1670 (if (re-search-backward 1674 (if (re-search-backward
1671 "^@node" 1675 "^@node"
1672 ;; Avoid finding previous node line if node lines are close. 1676 ;; Avoid finding previous node line if node lines are close.
1673 (or last-section-position 1677 (or last-section-position
1674 (save-excursion (forward-line -2) (point))) t) 1678 (save-excursion (forward-line -2) (point))) t)
1675 ;; @node is present, and point at beginning of that line 1679 ;; @node is present, and point at beginning of that line
1676 (forward-word 1) ; Leave point just after @node. 1680 (forward-word 1) ; Leave point just after @node.
1677 ;; Else @node missing; insert one. 1681 ;; Else @node missing; insert one.
1678 (beginning-of-line) ; Beginning of `@section' line. 1682 (beginning-of-line) ; Beginning of `@section' line.
1679 (insert "@node\n") 1683 (insert "@node\n")
1680 (backward-char 1)) ; Leave point just after `@node'. 1684 (backward-char 1)) ; Leave point just after `@node'.
1681 ;; Insert title if desired. 1685 ;; Insert title if desired.
1682 (if title-p 1686 (if title-p
1683 (progn 1687 (progn
1684 (skip-chars-forward " \t") 1688 (skip-chars-forward " \t")
1685 ;; Use regexp based on what info looks for 1689 ;; Use regexp based on what info looks for
1686 ;; (alternatively, use "[a-zA-Z]+"); 1690 ;; (alternatively, use "[a-zA-Z]+");
1687 ;; this means we only insert a title if none exists. 1691 ;; this means we only insert a title if none exists.
1688 (if (not (looking-at "[^,\t\n ]+")) 1692 (if (not (looking-at "[^,\t\n ]+"))
1689 (progn 1693 (progn
1690 (beginning-of-line) 1694 (beginning-of-line)
1691 (forward-word 1) 1695 (forward-word 1)
1692 (insert " " title) 1696 (insert " " title)
1693 (message "Inserted title %s ... " title))))) 1697 (message "Inserted title %s ... " title)))))
1694 ;; Go forward beyond current section title. 1698 ;; Go forward beyond current section title.
1695 (re-search-forward texinfo-section-types-regexp 1699 (re-search-forward texinfo-section-types-regexp
1696 (save-excursion (forward-line 3) (point)) t) 1700 (save-excursion (forward-line 3) (point)) t)
1697 (setq last-section-position (point)) 1701 (setq last-section-position (point))
1698 (forward-line 1)) 1702 (forward-line 1))
1699 1703
1700 ;; Leave point at end of region, mark at beginning. 1704 ;; Leave point at end of region, mark at beginning.
1701 (set-mark beginning) 1705 (set-mark beginning)
1738 ;;; Auxiliary functions for multiple file updating 1742 ;;; Auxiliary functions for multiple file updating
1739 1743
1740 (defun texinfo-multi-file-included-list (outer-file) 1744 (defun texinfo-multi-file-included-list (outer-file)
1741 "Return a list of the included files in OUTER-FILE." 1745 "Return a list of the included files in OUTER-FILE."
1742 (let ((included-file-list (list outer-file)) 1746 (let ((included-file-list (list outer-file))
1743 start) 1747 start)
1744 (save-excursion 1748 (save-excursion
1745 (switch-to-buffer (find-file-noselect outer-file)) 1749 (switch-to-buffer (find-file-noselect outer-file))
1746 (widen) 1750 (widen)
1747 (goto-char (point-min)) 1751 (goto-char (point-min))
1748 (while (re-search-forward "^@include" nil t) 1752 (while (re-search-forward "^@include" nil t)
1749 (skip-chars-forward " \t") 1753 (skip-chars-forward " \t")
1750 (setq start (point)) 1754 (setq start (point))
1751 (end-of-line) 1755 (end-of-line)
1752 (skip-chars-backward " \t") 1756 (skip-chars-backward " \t")
1753 (setq included-file-list 1757 (setq included-file-list
1754 (cons (buffer-substring start (point)) 1758 (cons (buffer-substring start (point))
1755 included-file-list))) 1759 included-file-list)))
1756 (nreverse included-file-list)))) 1760 (nreverse included-file-list))))
1757 1761
1758 (defun texinfo-copy-next-section-title () 1762 (defun texinfo-copy-next-section-title ()
1759 "Return the name of the immediately following section as a string. 1763 "Return the name of the immediately following section as a string.
1760 1764
1762 same place. If there is no title, returns an empty string." 1766 same place. If there is no title, returns an empty string."
1763 1767
1764 (save-excursion 1768 (save-excursion
1765 (end-of-line) 1769 (end-of-line)
1766 (let ((node-end (or 1770 (let ((node-end (or
1767 (save-excursion 1771 (save-excursion
1768 (if (re-search-forward "\\(^@node\\)" nil t) 1772 (if (re-search-forward "\\(^@node\\)" nil t)
1769 (match-beginning 0))) 1773 (match-beginning 0)))
1770 (point-max)))) 1774 (point-max))))
1771 (if (re-search-forward texinfo-section-types-regexp node-end t) 1775 (if (re-search-forward texinfo-section-types-regexp node-end t)
1772 (progn 1776 (progn
1773 (beginning-of-line) 1777 (beginning-of-line)
1774 ;; copy title 1778 ;; copy title
1775 (let ((title 1779 (let ((title
1776 (buffer-substring 1780 (buffer-substring
1777 (progn (forward-word 1) ; skip over section type 1781 (progn (forward-word 1) ; skip over section type
1778 (skip-chars-forward " \t") ; and over spaces 1782 (skip-chars-forward " \t") ; and over spaces
1779 (point)) 1783 (point))
1780 (progn (end-of-line) (point))))) 1784 (progn (end-of-line) (point)))))
1781 title)) 1785 title))
1782 "")))) 1786 ""))))
1783 1787
1784 (defun texinfo-multi-file-update (files &optional update-everything) 1788 (defun texinfo-multi-file-update (files &optional update-everything)
1785 "Update first node pointers in each file in FILES. 1789 "Update first node pointers in each file in FILES.
1786 Return a list of the node names. 1790 Return a list of the node names.
1787 1791
1812 ;; does not fill it; however a comment tells you how to do so. 1816 ;; does not fill it; however a comment tells you how to do so.
1813 ;; You would use the title field if you wanted to insert titles in the 1817 ;; You would use the title field if you wanted to insert titles in the
1814 ;; description slot of a menu as a description. 1818 ;; description slot of a menu as a description.
1815 1819
1816 (let ((case-fold-search t) 1820 (let ((case-fold-search t)
1817 menu-list) 1821 menu-list)
1818 1822
1819 ;; Find the name of the first node of the first included file. 1823 ;; Find the name of the first node of the first included file.
1820 (switch-to-buffer (find-file-noselect (car (cdr files)))) 1824 (switch-to-buffer (find-file-noselect (car (cdr files))))
1821 (widen) 1825 (widen)
1822 (goto-char (point-min)) 1826 (goto-char (point-min))
1823 (if (not (re-search-forward "^@node" nil t)) 1827 (if (not (re-search-forward "^@node" nil t))
1824 (error "No `@node' line found in %s !" (buffer-name))) 1828 (error "No `@node' line found in %s !" (buffer-name)))
1825 (beginning-of-line) 1829 (beginning-of-line)
1826 (texinfo-check-for-node-name) 1830 (texinfo-check-for-node-name)
1827 (setq next-node-name (texinfo-copy-node-name)) 1831 (setq next-node-name (texinfo-copy-node-name))
1828 1832
1829 (setq menu-list 1833 (setq menu-list
1830 (cons (cons 1834 (cons (cons
1831 next-node-name 1835 next-node-name
1832 (prog1 "" (forward-line 1))) 1836 (prog1 "" (forward-line 1)))
1833 ;; Use following to insert section titles automatically. 1837 ;; Use following to insert section titles automatically.
1834 ;; (texinfo-copy-next-section-title) 1838 ;; (texinfo-copy-next-section-title)
1835 menu-list)) 1839 menu-list))
1836 1840
1837 ;; Go to outer file 1841 ;; Go to outer file
1838 (switch-to-buffer (find-file-noselect (car files))) 1842 (switch-to-buffer (find-file-noselect (car files)))
1839 (goto-char (point-min)) 1843 (goto-char (point-min))
1840 (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t)) 1844 (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t))
1841 (error "This buffer needs a Top node!")) 1845 (error "This buffer needs a Top node!"))
1842 (beginning-of-line) 1846 (beginning-of-line)
1843 (texinfo-delete-existing-pointers) 1847 (texinfo-delete-existing-pointers)
1844 (end-of-line) 1848 (end-of-line)
1845 (insert ", " next-node-name ", (dir), (dir)") 1849 (insert ", " next-node-name ", (dir), (dir)")
1846 (beginning-of-line) 1850 (beginning-of-line)
1848 (setq files (cdr files)) 1852 (setq files (cdr files))
1849 1853
1850 (while files 1854 (while files
1851 1855
1852 (if (not (cdr files)) 1856 (if (not (cdr files))
1853 ;; No next file 1857 ;; No next file
1854 (setq next-node-name "") 1858 (setq next-node-name "")
1855 ;; Else, 1859 ;; Else,
1856 ;; find the name of the first node in the next file. 1860 ;; find the name of the first node in the next file.
1857 (switch-to-buffer (find-file-noselect (car (cdr files)))) 1861 (switch-to-buffer (find-file-noselect (car (cdr files))))
1858 (widen) 1862 (widen)
1859 (goto-char (point-min)) 1863 (goto-char (point-min))
1860 (if (not (re-search-forward "^@node" nil t)) 1864 (if (not (re-search-forward "^@node" nil t))
1861 (error "No `@node' line found in %s !" (buffer-name))) 1865 (error "No `@node' line found in %s !" (buffer-name)))
1862 (beginning-of-line) 1866 (beginning-of-line)
1863 (texinfo-check-for-node-name) 1867 (texinfo-check-for-node-name)
1864 (setq next-node-name (texinfo-copy-node-name)) 1868 (setq next-node-name (texinfo-copy-node-name))
1865 (setq menu-list 1869 (setq menu-list
1866 (cons (cons 1870 (cons (cons
1867 next-node-name 1871 next-node-name
1868 (prog1 "" (forward-line 1))) 1872 (prog1 "" (forward-line 1)))
1869 ;; Use following to insert section titles automatically. 1873 ;; Use following to insert section titles automatically.
1870 ;; (texinfo-copy-next-section-title) 1874 ;; (texinfo-copy-next-section-title)
1871 menu-list))) 1875 menu-list)))
1872 1876
1873 ;; Go to node to be updated. 1877 ;; Go to node to be updated.
1874 (switch-to-buffer (find-file-noselect (car files))) 1878 (switch-to-buffer (find-file-noselect (car files)))
1875 (goto-char (point-min)) 1879 (goto-char (point-min))
1876 (if (not (re-search-forward "^@node" nil t)) 1880 (if (not (re-search-forward "^@node" nil t))
1877 (error "No `@node' line found in %s !" (buffer-name))) 1881 (error "No `@node' line found in %s !" (buffer-name)))
1878 (beginning-of-line) 1882 (beginning-of-line)
1879 1883
1880 ;; Update other menus and nodes if requested. 1884 ;; Update other menus and nodes if requested.
1881 (if update-everything (texinfo-all-menus-update t)) 1885 (if update-everything (texinfo-all-menus-update t))
1882 1886
1902 (insert "* ") 1906 (insert "* ")
1903 1907
1904 ;; Insert the node name (and menu entry name, if present). 1908 ;; Insert the node name (and menu entry name, if present).
1905 (let ((node-part (car (car menu-list)))) 1909 (let ((node-part (car (car menu-list))))
1906 (if (stringp node-part) 1910 (if (stringp node-part)
1907 ;; "Double colon" entry line; menu entry and node name are the same, 1911 ;; "Double colon" entry line; menu entry and node name are the same,
1908 (insert (format "%s::" node-part)) 1912 (insert (format "%s::" node-part))
1909 ;; "Single colon" entry line; menu entry and node name are different. 1913 ;; "Single colon" entry line; menu entry and node name are different.
1910 (insert (format "%s: %s." (car node-part) (cdr node-part))))) 1914 (insert (format "%s: %s." (car node-part) (cdr node-part)))))
1911 1915
1912 ;; Insert the description, if present. 1916 ;; Insert the description, if present.
1913 (if (cdr (car menu-list)) 1917 (if (cdr (car menu-list))
1914 (progn 1918 (progn
1915 ;; Move to right place. 1919 ;; Move to right place.
1916 (indent-to texinfo-column-for-description 2) 1920 (indent-to texinfo-column-for-description 2)
1917 ;; Insert description. 1921 ;; Insert description.
1918 (insert (format "%s" (cdr (car menu-list)))))) 1922 (insert (format "%s" (cdr (car menu-list))))))
1919 1923
1920 (insert "\n") ; end this menu entry 1924 (insert "\n") ; end this menu entry
1921 (setq menu-list (cdr menu-list))) 1925 (setq menu-list (cdr menu-list)))
1922 (insert "@end menu")) 1926 (insert "@end menu"))
1923 1927
1928 The first file in FILES-LIST must be the outer file; the others must 1932 The first file in FILES-LIST must be the outer file; the others must
1929 be the files included within it. A main menu must already exist." 1933 be the files included within it. A main menu must already exist."
1930 (save-excursion 1934 (save-excursion
1931 (let (master-menu-list) 1935 (let (master-menu-list)
1932 (while files-list 1936 (while files-list
1933 (switch-to-buffer (find-file-noselect (car files-list))) 1937 (switch-to-buffer (find-file-noselect (car files-list)))
1934 (message "Working on: %s " (current-buffer)) 1938 (message "Working on: %s " (current-buffer))
1935 (goto-char (point-min)) 1939 (goto-char (point-min))
1936 (setq master-menu-list 1940 (setq master-menu-list
1937 (append master-menu-list (texinfo-master-menu-list))) 1941 (append master-menu-list (texinfo-master-menu-list)))
1938 (setq files-list (cdr files-list))) 1942 (setq files-list (cdr files-list)))
1939 master-menu-list))) 1943 master-menu-list)))
1940 1944
1941 1945
1942 ;;; The multiple-file update function 1946 ;;; The multiple-file update function
1943 1947
1979 1983
1980 Thus, normally, each included file contains one, and only one, 1984 Thus, normally, each included file contains one, and only one,
1981 chapter." 1985 chapter."
1982 1986
1983 (interactive (cons 1987 (interactive (cons
1984 (read-string 1988 (read-string
1985 "Name of outer `include' file: " 1989 "Name of outer `include' file: "
1986 (buffer-file-name)) 1990 (buffer-file-name))
1987 (cond ((not current-prefix-arg) 1991 (cond ((not current-prefix-arg)
1988 '(nil nil)) 1992 '(nil nil))
1989 ((listp current-prefix-arg) 1993 ((listp current-prefix-arg)
1990 '(t nil)) ; make-master-menu 1994 '(t nil)) ; make-master-menu
1991 ((numberp current-prefix-arg) 1995 ((numberp current-prefix-arg)
1992 '(t t)) ; update-everything 1996 '(t t)) ; update-everything
1993 ))) 1997 )))
1994 1998
1995 (let* ((included-file-list (texinfo-multi-file-included-list outer-file)) 1999 (let* ((included-file-list (texinfo-multi-file-included-list outer-file))
1996 (files included-file-list) 2000 (files included-file-list)
1997 main-menu-list 2001 main-menu-list
1998 next-node-name 2002 next-node-name
1999 previous-node-name 2003 previous-node-name
2000 (up-node-name "Top")) 2004 (up-node-name "Top"))
2001 2005
2002 ;;; Update the pointers 2006 ;;; Update the pointers
2003 ;;; and collect the names of the nodes and titles 2007 ;;; and collect the names of the nodes and titles
2004 (setq main-menu-list (texinfo-multi-file-update files update-everything)) 2008 (setq main-menu-list (texinfo-multi-file-update files update-everything))
2005 2009
2008 ;; Go to outer file 2012 ;; Go to outer file
2009 (switch-to-buffer (find-file-noselect (car included-file-list))) 2013 (switch-to-buffer (find-file-noselect (car included-file-list)))
2010 (if (texinfo-old-menu-p 2014 (if (texinfo-old-menu-p
2011 (point-min) 2015 (point-min)
2012 (save-excursion 2016 (save-excursion
2013 (re-search-forward "^@include") 2017 (re-search-forward "^@include")
2014 (beginning-of-line) 2018 (beginning-of-line)
2015 (point))) 2019 (point)))
2016 2020
2017 ;; If found, leave point after word `menu' on the `@menu' line. 2021 ;; If found, leave point after word `menu' on the `@menu' line.
2018 (progn 2022 (progn
2019 (texinfo-incorporate-descriptions main-menu-list) 2023 (texinfo-incorporate-descriptions main-menu-list)
2020 ;; Delete existing menu. 2024 ;; Delete existing menu.
2021 (beginning-of-line) 2025 (beginning-of-line)
2022 (delete-region 2026 (delete-region
2023 (point) 2027 (point)
2024 (save-excursion (re-search-forward "^@end menu") (point))) 2028 (save-excursion (re-search-forward "^@end menu") (point)))
2025 ;; Insert main menu 2029 ;; Insert main menu
2026 (texinfo-multi-files-insert-main-menu main-menu-list)) 2030 (texinfo-multi-files-insert-main-menu main-menu-list))
2027 2031
2028 ;; Else no current menu; insert it before `@include' 2032 ;; Else no current menu; insert it before `@include'
2029 (texinfo-multi-files-insert-main-menu main-menu-list)) 2033 (texinfo-multi-files-insert-main-menu main-menu-list))
2030 2034
2031 ;;; Insert master menu 2035 ;;; Insert master menu
2032 2036
2033 (if make-master-menu 2037 (if make-master-menu
2034 (progn 2038 (progn
2035 ;; First, removing detailed part of any pre-existing master menu 2039 ;; First, removing detailed part of any pre-existing master menu
2036 (goto-char (point-min)) 2040 (goto-char (point-min))
2037 (if (search-forward texinfo-master-menu-header nil t) 2041 (if (search-forward texinfo-master-menu-header nil t)
2038 (progn 2042 (progn
2039 (goto-char (match-beginning 0)) 2043 (goto-char (match-beginning 0))
2040 ;; Check if @detailmenu kludge is used; 2044 ;; Check if @detailmenu kludge is used;
2041 ;; if so, leave point before @detailmenu. 2045 ;; if so, leave point before @detailmenu.
2042 (search-backward "\n@detailmenu" 2046 (search-backward "\n@detailmenu"
2043 (save-excursion (forward-line -3) (point)) 2047 (save-excursion (forward-line -3) (point))
2044 t) 2048 t)
2045 ;; Remove detailed master menu listing 2049 ;; Remove detailed master menu listing
2046 (let ((end-of-detailed-menu-descriptions 2050 (let ((end-of-detailed-menu-descriptions
2047 (save-excursion ; beginning of end menu line 2051 (save-excursion ; beginning of end menu line
2048 (goto-char (texinfo-menu-end)) 2052 (goto-char (texinfo-menu-end))
2049 (beginning-of-line) (forward-char -1) 2053 (beginning-of-line) (forward-char -1)
2050 (point)))) 2054 (point))))
2051 (delete-region (point) end-of-detailed-menu-descriptions)))) 2055 (delete-region (point) end-of-detailed-menu-descriptions))))
2052 2056
2053 ;; Create a master menu and insert it 2057 ;; Create a master menu and insert it
2054 (texinfo-insert-master-menu-list 2058 (texinfo-insert-master-menu-list
2055 (texinfo-multi-file-master-menu-list 2059 (texinfo-multi-file-master-menu-list
2056 included-file-list))))) 2060 included-file-list)))))
2057 2061
2058 ;; Remove unwanted extra lines. 2062 ;; Remove unwanted extra lines.
2059 (save-excursion 2063 (save-excursion
2060 (goto-char (point-min)) 2064 (goto-char (point-min))
2061 2065