aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1993-07-07 22:15:20 +0000
committerRichard M. Stallman1993-07-07 22:15:20 +0000
commitdaa6abb8d5bef4099000108ccd4f0550615c906e (patch)
tree9792bdf65a5cf83c9035970e726c01f8a0534a7b
parent1e377362bec4b8dd4005044af1bc7506669c49a5 (diff)
downloademacs-daa6abb8d5bef4099000108ccd4f0550615c906e.tar.gz
emacs-daa6abb8d5bef4099000108ccd4f0550615c906e.zip
Fix typo re `texinfo-sequential-node-update.'
Ensure that no commands depend on the value of case-fold-search. Rewrite messages. Avoid using `mark-whole-buffer'. (texinfo-start-menu-description): New function to insert title as description in a menu. (texinfo-make-menu-list): Remove automatic title insertion. (texinfo-master-menu): Error message if file contains too few nodes for a master menu. Handle the case where no master menu was inserted. (texinfo-insert-master-menu-list): Only attempt to insert detailed master menu if there is one. Insert a master menu only after `Top' node and before next node. (texinfo-check-for-node-name): Offer section title as prompt. (texinfo-copy-next-section-title): Copy title correctly. Handle failure to find @node. (texinfo-copy-menu): Error message if menu empty. (texinfo-pointer-name): Find only those section commands that are accompanied by `@node' lines. (texinfo-section-types-regexp): Look for subh and subs, not just sub. (texinfo-make-one-menu): Copy node-name correctly for message. (texinfo-copy-menu-title): Copy title as it should rather than node line. (texinfo-find-higher-level-node): Stop search at limit. Special handling for `top' and `chapter' levels. (texinfo-copy-menu-title): Rewrite to handle outer include files. (texinfo-multi-file-update): Update all nodes properly (and sooner); rewrite doc string and interactive. Copy title properly. (texinfo-all-menus-update): Fixed typo that caused the function to create a master menu when it shouldn't. Update pre-existing master menu, if there is one. (texinfo-incorporate-descriptions): Use a regexp search to look for both kinds of menu item. (texinfo-menu-indent-description): Likewise. (texinfo-incorporate-menu-entry-names): New function. (texinfo-insert-menu): Handle both kinds of menu item. (texinfo-multi-files-insert-main-menu): Likewise. (texinfo-update-node): Pass t as second arg to push-mark. (texinfo-sequential-node-update): Likewise. (texinfo-insert-node-lines): Bind `title' at a higher level. Don't find previous @node if it's close. Take region to process as arguments. (texinfo-multiple-files-update): Handle prefix arg better within `interactive'. Canonicalize the blank lines.
-rw-r--r--lisp/textmodes/texnfo-upd.el1212
1 files changed, 757 insertions, 455 deletions
diff --git a/lisp/textmodes/texnfo-upd.el b/lisp/textmodes/texnfo-upd.el
index dae1d6aa8c7..67bd142a428 100644
--- a/lisp/textmodes/texnfo-upd.el
+++ b/lisp/textmodes/texnfo-upd.el
@@ -1,9 +1,8 @@
1;;; texnfo-upd.el --- a utility for updating nodes and menus in Texinfo files. 1;;; Texinfo mode utilities for updating nodes and menus in Texinfo files.
2;;; Copyright 1989, 1990, 1991, 1992 Free Software Foundation
2 3
3;;;; Copyright 1989, 1990, 1992 Free Software Foundation 4;; Author: Robert J. Chassell
4 5;; Maintainer: bug-texinfo@prep.ai.mit.edu
5;; Author: Bob Chassell <bob@gnu.ai.mit.edu>
6;; Version: 2.00
7;; Keywords: maint, tex, docs 6;; Keywords: maint, tex, docs
8 7
9;; This file is part of GNU Emacs. 8;; This file is part of GNU Emacs.
@@ -23,11 +22,10 @@
23;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 22;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 23
25;;; Commentary: 24;;; Commentary:
26
27;;;; Summary
28 25
29; (Much of the following commentary ought eventually be incorporated 26;;; Known bug: update commands fail to ignore @ignore.
30; into the Texinfo Manual.) 27
28;;; Summary: how to use the updating commands
31 29
32; The node and menu updating functions automatically 30; The node and menu updating functions automatically
33 31
@@ -35,13 +33,10 @@
35; * insert the `Next', `Previous' and `Up' pointers of a node, 33; * insert the `Next', `Previous' and `Up' pointers of a node,
36; * insert or update the menu for a section, 34; * insert or update the menu for a section,
37; * create a master menu for a Texinfo source file. 35; * create a master menu for a Texinfo source file.
38 36;
39; Passed an argument, the `texinfo-update-node' and 37; Passed an argument, the `texinfo-update-node' and
40; `texinfo-make-menu' functions do their jobs in the region. 38; `texinfo-make-menu' functions do their jobs in the region.
41 39;
42; These functions replace doing these jobs by hand.
43; You may find them helpful.
44
45; In brief, the functions for creating or updating nodes and menus, are: 40; In brief, the functions for creating or updating nodes and menus, are:
46; 41;
47; texinfo-update-node (&optional region-p) 42; texinfo-update-node (&optional region-p)
@@ -81,8 +76,7 @@
81; be the first node in the file. 76; be the first node in the file.
82 77
83 78
84;;;; The updating functions in detail 79;;; The update node functions described in detail
85; --------------------------------
86 80
87; The `texinfo-update-node' function without an argument inserts 81; The `texinfo-update-node' function without an argument inserts
88; the correct next, previous and up pointers for the node in which 82; the correct next, previous and up pointers for the node in which
@@ -98,10 +92,14 @@
98; The `texinfo-every-node-update' function runs `texinfo-update-node' 92; The `texinfo-every-node-update' function runs `texinfo-update-node'
99; on the whole buffer. 93; on the whole buffer.
100 94
101; The `texinfo-update-node' function inserts the immediately following 95; The `texinfo-sequential-node-update' function inserts the
102; and preceding node into the `Next' or `Previous' pointers regardless 96; immediately following and preceding node into the `Next' or
103; of their hierarchical level. This is only useful for certain kinds 97; `Previous' pointers regardless of their hierarchical level. This is
104; of text, like a novel, which you go through sequentially. 98; only useful for certain kinds of text, like a novel, which you go
99; through sequentially.
100
101
102;;; The menu making functions described in detail
105 103
106; The `texinfo-make-menu' function without an argument creates or 104; The `texinfo-make-menu' function without an argument creates or
107; updates a menu for the section encompassing the node that follows 105; updates a menu for the section encompassing the node that follows
@@ -146,9 +144,10 @@
146; Since node names should be more concise than section or chapter 144; Since node names should be more concise than section or chapter
147; titles, node names so inserted will need to be edited manually. 145; titles, node names so inserted will need to be edited manually.
148 146
149;;; Code:
150 147
151;;;; Menu Making Functions 148;;; Code:
149
150;;; The menu making functions
152 151
153(defun texinfo-make-menu (&optional region-p) 152(defun texinfo-make-menu (&optional region-p)
154 "Without any prefix argument, make or update a menu. 153 "Without any prefix argument, make or update a menu.
@@ -168,7 +167,7 @@ are inserted as descriptions."
168 (texinfo-make-one-menu level) 167 (texinfo-make-one-menu level)
169 (message "Done...updated the menu. You may save the buffer.")) 168 (message "Done...updated the menu. You may save the buffer."))
170 ;; else 169 ;; else
171 (message "Making or updating menus... ") 170 (message "Making or updating menus in %s... " (buffer-name))
172 (let ((beginning (region-beginning)) 171 (let ((beginning (region-beginning))
173 (region-end (region-end)) 172 (region-end (region-end))
174 (level (progn ; find section type following point 173 (level (progn ; find section type following point
@@ -207,40 +206,62 @@ at the level specified by LEVEL. Point is left at the end of menu."
207 (first (texinfo-menu-first-node beginning end)) 206 (first (texinfo-menu-first-node beginning end))
208 (node-name (progn 207 (node-name (progn
209 (goto-char beginning) 208 (goto-char beginning)
209 (beginning-of-line)
210 (texinfo-copy-node-name))) 210 (texinfo-copy-node-name)))
211 (new-menu-list (texinfo-make-menu-list beginning end level))) 211 (new-menu-list (texinfo-make-menu-list beginning end level)))
212 (if (texinfo-old-menu-p beginning first) 212 (if (texinfo-old-menu-p beginning first)
213 (progn 213 (progn
214 (texinfo-incorporate-descriptions new-menu-list) 214 (texinfo-incorporate-descriptions new-menu-list)
215 (texinfo-incorporate-menu-entry-names new-menu-list)
215 (texinfo-delete-old-menu beginning first))) 216 (texinfo-delete-old-menu beginning first)))
216 (texinfo-insert-menu new-menu-list node-name))) 217 (texinfo-insert-menu new-menu-list node-name)))
217 218
218(defun texinfo-all-menus-update (&optional update-all-nodes-p) 219(defun texinfo-all-menus-update (&optional update-all-nodes-p)
219 "Update every regular menu in a Texinfo file. 220 "Update every regular menu in a Texinfo file.
220You must remove the detailed part of a pre-existing master menu before 221Update pre-existing master menu, if there is one.
221running this command, lest it be partly duplicated.
222 222
223If called with a non-nil argument, this function first updates all the 223If called with a non-nil argument, this function first updates all the
224nodes in the buffer before updating the menus." 224nodes in the buffer before updating the menus."
225 (interactive "P") 225 (interactive "P")
226 (save-excursion 226 (let ((case-fold-search t)
227 (mark-whole-buffer) 227 master-menu-p)
228 (message "Checking for a master menu... ")
229 (save-excursion 228 (save-excursion
230 (if (re-search-forward texinfo-master-menu-header nil t) 229 (push-mark (point-max) t)
231 (error 230 (goto-char (point-min))
232 "Please remove existing master menu, lest it be partly duplicated!"))) 231 (message "Checking for a master menu in %s ... "(buffer-name))
233 232 (save-excursion
234 (if update-all-nodes-p 233 (if (re-search-forward texinfo-master-menu-header nil t)
235 (progn 234 ;; Remove detailed master menu listing
236 (message "First updating all nodes... ") 235 (progn
237 (sleep-for 2) 236 (setq master-menu-p t)
238 (mark-whole-buffer) 237 (goto-char (match-beginning 0))
239 (texinfo-update-node t))) 238 (let ((end-of-detailed-menu-descriptions
240 239 (save-excursion ; beginning of end menu line
241 (message "Updating all menus... ") 240 (goto-char (texinfo-menu-end))
242 (sleep-for 2) 241 (beginning-of-line) (forward-char -1)
243 (texinfo-make-menu t) 242 (point))))
243 (delete-region (point) end-of-detailed-menu-descriptions)))))
244
245 (if update-all-nodes-p
246 (progn
247 (message "Updating all nodes in %s ... " (buffer-name))
248 (sleep-for 2)
249 (push-mark (point-max) t)
250 (goto-char (point-min))
251 (texinfo-update-node t)))
252
253 (message "Updating all menus in %s ... " (buffer-name))
254 (sleep-for 2)
255 (push-mark (point-max) t)
256 (goto-char (point-min))
257 (texinfo-make-menu t)
258
259 (if master-menu-p
260 (progn
261 (message "Updating the master menu in %s... " (buffer-name))
262 (sleep-for 2)
263 (texinfo-master-menu nil))))
264
244 (message "Done...updated all the menus. You may save the buffer."))) 265 (message "Done...updated all the menus. You may save the buffer.")))
245 266
246(defun texinfo-find-lower-level-node (level region-end) 267(defun texinfo-find-lower-level-node (level region-end)
@@ -250,21 +271,21 @@ and to the end of the menu region for the level.
250 271
251Return t if the node is found, else nil. Leave point at the beginning 272Return t if the node is found, else nil. Leave point at the beginning
252of the node if one is found; else do not move point." 273of the node if one is found; else do not move point."
253 274 (let ((case-fold-search t))
254 (if (and (< (point) region-end) 275 (if (and (< (point) region-end)
255 (re-search-forward 276 (re-search-forward
256 (concat 277 (concat
257 "\\(^@node\\).*\n" ; match node line 278 "\\(^@node\\).*\n" ; match node line
258 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any 279 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any
259 "\\|" ; or 280 "\\|" ; or
260 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any 281 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any
261 (eval (cdr (assoc level texinfo-update-menu-lower-regexps)))) 282 (eval (cdr (assoc level texinfo-update-menu-lower-regexps))))
262 ;; the next higher level node marks the end of this 283 ;; the next higher level node marks the end of this
263 ;; section, and no lower level node will be found beyond 284 ;; section, and no lower level node will be found beyond
264 ;; this position even if region-end is farther off 285 ;; this position even if region-end is farther off
265 (texinfo-update-menu-region-end level) 286 (texinfo-update-menu-region-end level)
266 t)) 287 t))
267 (goto-char (match-beginning 1)))) 288 (goto-char (match-beginning 1)))))
268 289
269(defun texinfo-find-higher-level-node (level region-end) 290(defun texinfo-find-higher-level-node (level region-end)
270 "Search forward from point for node at any higher level than argument LEVEL. 291 "Search forward from point for node at any higher level than argument LEVEL.
@@ -272,22 +293,24 @@ Search is limited to the end of the marked region, REGION-END.
272 293
273Return t if the node is found, else nil. Leave point at the beginning 294Return t if the node is found, else nil. Leave point at the beginning
274of the node if one is found; else do not move point." 295of the node if one is found; else do not move point."
275 296 (let ((case-fold-search t))
276 (if (and (< (point) region-end) 297 (cond
277 (re-search-forward 298 ((or (string-equal "top" level) (string-equal "chapter" level))
278 (concat 299 (if (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" region-end t)
279 "\\(^@node\\).*\n" ; match node line 300 (progn (beginning-of-line) t)))
280 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any 301 (t
281 "\\|" ; or 302 (if (re-search-forward
282 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any 303 (concat
283 (eval ; (won't ever find a `top' node) 304 "\\(^@node\\).*\n" ; match node line
284 (cdr (assoc level texinfo-update-menu-higher-regexps)))) 305 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any
285 nil 306 "\\|" ; or
286 t)) 307 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any
287 (goto-char (match-beginning 1)))) 308 (eval (cdr (assoc level texinfo-update-menu-higher-regexps))))
309 region-end t)
310 (progn (beginning-of-line) t))))))
288 311
289 312
290;;;; Making the list of new menu entries 313;;; Making the list of new menu entries
291 314
292(defun texinfo-make-menu-list (beginning end level) 315(defun texinfo-make-menu-list (beginning end level)
293 "Make a list of node names and their descriptions. 316 "Make a list of node names and their descriptions.
@@ -306,14 +329,16 @@ element consists only of the node name."
306 (setq new-menu-list 329 (setq new-menu-list
307 (cons (cons 330 (cons (cons
308 (texinfo-copy-node-name) 331 (texinfo-copy-node-name)
309 (texinfo-copy-section-title)) 332 (prog1 "" (forward-line 1)))
333 ;; Use following to insert section titles automatically.
334 ;; (texinfo-copy-section-title))
310 new-menu-list))) 335 new-menu-list)))
311 (reverse new-menu-list))) 336 (reverse new-menu-list)))
312 337
313(defun texinfo-menu-locate-entry-p (level search-end) 338(defun texinfo-menu-locate-entry-p (level search-end)
314 "Find a node that will be part of menu for this section. 339 "Find a node that will be part of menu for this section.
315First argument is a string such as \"section\" specifying the general 340First argument is a string such as \"section\" specifying the general
316hierarchical level of the menu; second argument is a postion 341hierarchical level of the menu; second argument is a position
317specifying the end of the search. 342specifying the end of the search.
318 343
319The function returns t if the node is found, else nil. It searches 344The function returns t if the node is found, else nil. It searches
@@ -321,17 +346,18 @@ forward from point, and leaves point at the beginning of the node.
321 346
322The function finds entries of the same type. Thus `subsections' and 347The function finds entries of the same type. Thus `subsections' and
323`unnumberedsubsecs' will appear in the same menu." 348`unnumberedsubsecs' will appear in the same menu."
324 (if (re-search-forward 349 (let ((case-fold-search t))
325 (concat 350 (if (re-search-forward
326 "\\(^@node\\).*\n" ; match node line 351 (concat
327 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any 352 "\\(^@node\\).*\n" ; match node line
328 "\\|" ; or 353 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any
329 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any 354 "\\|" ; or
330 (eval 355 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any
331 (cdr (assoc level texinfo-update-menu-same-level-regexps)))) 356 (eval
332 search-end 357 (cdr (assoc level texinfo-update-menu-same-level-regexps))))
333 t) 358 search-end
334 (goto-char (match-beginning 1)))) 359 t)
360 (goto-char (match-beginning 1)))))
335 361
336(defun texinfo-copy-node-name () 362(defun texinfo-copy-node-name ()
337 "Return the node name as a string. 363 "Return the node name as a string.
@@ -374,7 +400,7 @@ must have been done by `texinfo-menu-locate-entry-p'."
374 (progn (end-of-line) (point)))) 400 (progn (end-of-line) (point))))
375 401
376 402
377;;;; Handling the old menu 403;;; Handling the old menu
378 404
379(defun texinfo-old-menu-p (beginning first) 405(defun texinfo-old-menu-p (beginning first)
380 "Move point to the beginning of the menu for this section, if any. 406 "Move point to the beginning of the menu for this section, if any.
@@ -397,24 +423,31 @@ end of the section, and leaves point there where a menu ought to be."
397 423
398Point must be at beginning of old menu. 424Point must be at beginning of old menu.
399 425
400If the node-name of the new menu entry cannot be found in the old 426If the node-name of the new menu is found in the old menu, insert the
401menu, use the new section title for the description, but if the 427old description into the new entry.
402node-name of the new menu is found in the old menu, replace the
403section title with the old description, whatever it may be.
404 428
405For this function, the new menu is a list made up of lists of dotted 429For this function, the new menu is a list made up of lists of dotted
406pairs in which the first element of the pair is the node name and the 430pairs in which the first element of the pair is the node name and the
407second element the description. The new menu is changed destructively. 431second element the description. The new menu is changed destructively.
408The old menu is the menu as it appears in the texinfo file." 432The old menu is the menu as it appears in the texinfo file."
409 433
410 (let ((new-menu-list-pointer new-menu-list) 434 (let ((new-menu-list-pointer new-menu-list)
411 (end-of-menu (texinfo-menu-end))) 435 (end-of-menu (texinfo-menu-end)))
412 (while new-menu-list 436 (while new-menu-list
413 (save-excursion ; keep point at beginning of menu 437 (save-excursion ; keep point at beginning of menu
414 (if (search-forward 438 (if (re-search-forward
415 (concat "\* " ; so only menu entries are found 439 ;; Existing nodes can have the form
416 (car (car new-menu-list)) 440 ;; * NODE NAME:: DESCRIPTION
417 ":") ; so only complete entries are found 441 ;; or
442 ;; * MENU ITEM: NODE NAME. DESCRIPTION.
443 ;;
444 ;; Recognize both when looking for the description.
445 (concat "\\* \\(" ; so only menu entries are found
446 (car (car new-menu-list)) "::"
447 "\\|"
448 ".*: " (car (car new-menu-list)) "[.,\t\n]"
449 "\\)"
450 ) ; so only complete entries are found
418 end-of-menu 451 end-of-menu
419 t) 452 t)
420 (setcdr (car new-menu-list) 453 (setcdr (car new-menu-list)
@@ -422,6 +455,47 @@ The old menu is the menu as it appears in the texinfo file."
422 (setq new-menu-list (cdr new-menu-list))) 455 (setq new-menu-list (cdr new-menu-list)))
423 (setq new-menu-list new-menu-list-pointer))) 456 (setq new-menu-list new-menu-list-pointer)))
424 457
458(defun texinfo-incorporate-menu-entry-names (new-menu-list)
459 "Copy any old menu entry names to the new menu.
460
461Point must be at beginning of old menu.
462
463If the node-name of the new menu entry cannot be found in the old
464menu, do nothing.
465
466For this function, the new menu is a list made up of lists of dotted
467pairs in which the first element of the pair is the node name and the
468second element is the description (or nil).
469
470If we find an existing menu entry name, we change the first element of
471the pair to be another dotted pair in which the car is the menu entry
472name and the cdr is the node name.
473
474NEW-MENU-LIST is changed destructively. The old menu is the menu as it
475appears in the texinfo file."
476
477 (let ((new-menu-list-pointer new-menu-list)
478 (end-of-menu (texinfo-menu-end)))
479 (while new-menu-list
480 (save-excursion ; keep point at beginning of menu
481 (if (re-search-forward
482 ;; Existing nodes can have the form
483 ;; * NODE NAME:: DESCRIPTION
484 ;; or
485 ;; * MENU ITEM: NODE NAME. DESCRIPTION.
486 ;;
487 ;; We're interested in the second case.
488 (concat "\\* " ; so only menu entries are found
489 "\\(.*\\): " (car (car new-menu-list)) "[.,\t\n]")
490 end-of-menu
491 t)
492 (setcar
493 (car new-menu-list) ; replace the node name
494 (cons (buffer-substring (match-beginning 1) (match-end 1))
495 (car (car new-menu-list)))))
496 (setq new-menu-list (cdr new-menu-list))))
497 (setq new-menu-list new-menu-list-pointer)))
498
425(defun texinfo-menu-copy-old-description (end-of-menu) 499(defun texinfo-menu-copy-old-description (end-of-menu)
426 "Return description field of old menu line as string. 500 "Return description field of old menu line as string.
427Point must be located just after the node name. Point left before description. 501Point must be located just after the node name. Point left before description.
@@ -429,6 +503,7 @@ Single argument, END-OF-MENU, is position limiting search."
429 (skip-chars-forward "[:.,\t\n ]+") 503 (skip-chars-forward "[:.,\t\n ]+")
430 ;; don't copy a carriage return at line beginning with asterisk! 504 ;; don't copy a carriage return at line beginning with asterisk!
431 ;; do copy a description that begins with an `@'! 505 ;; do copy a description that begins with an `@'!
506 ;; !! Known bug: does not copy descriptions starting with ^|\{?* etc.
432 (if (and (looking-at "\\(\\w+\\|@\\)") 507 (if (and (looking-at "\\(\\w+\\|@\\)")
433 (not (looking-at "\\(^\\* \\|^@end menu\\)"))) 508 (not (looking-at "\\(^\\* \\|^@end menu\\)")))
434 (buffer-substring 509 (buffer-substring
@@ -461,7 +536,7 @@ node within the section."
461 (point)))) 536 (point))))
462 537
463 538
464;;;; Inserting new menu 539;;; Inserting new menu
465 540
466;; try 32, but perhaps 24 is better 541;; try 32, but perhaps 24 is better
467(defvar texinfo-column-for-description 32 542(defvar texinfo-column-for-description 32
@@ -475,30 +550,124 @@ texinfo-column-for-description.
475MENU-LIST has form: 550MENU-LIST has form:
476 551
477 \(\(\"node-name1\" . \"description\"\) 552 \(\(\"node-name1\" . \"description\"\)
478 \(\"node-name\" . \"description\"\) ... \) 553 \(\"node-name2\" . \"description\"\) ... \)
479 554
480However, there does not need to be a description field." 555However, the description field might be nil.
556
557Also, the node-name field might itself be a dotted pair (call it P) of
558strings instead of just a string. In that case, the car of P
559is the menu entry name, and the cdr of P is the node name."
481 560
482 (insert "@menu\n") 561 (insert "@menu\n")
483 (while menu-list 562 (while menu-list
484 (if (cdr (car menu-list)) ; menu-list has description entry 563 ;; Every menu entry starts with a star and a space.
564 (insert "* ")
565
566 ;; Insert the node name (and menu entry name, if present).
567 (let ((node-part (car (car menu-list))))
568 (if (stringp node-part)
569 ;; "Double colon" entry line; menu entry and node name are the same,
570 (insert (format "%s::" node-part))
571 ;; "Single colon" entry line; menu entry and node name are different.
572 (insert (format "%s: %s." (car node-part) (cdr node-part)))))
573
574 ;; Insert the description, if present.
575 (if (cdr (car menu-list))
485 (progn 576 (progn
486 (insert 577 ;; Move to right place.
487 (format "* %s::" (car (car menu-list)))) ; node-name entry 578 (indent-to texinfo-column-for-description 2)
488 (indent-to texinfo-column-for-description 2) 579 ;; Insert description.
489 (insert 580 (insert (format "%s" (cdr (car menu-list))))))
490 (format "%s\n" (cdr (car menu-list))))) ; description entry 581
491 ;; else menu-list lacks description entry 582 (insert "\n") ; end this menu entry
492 (insert
493 (format "* %s::\n" (car (car menu-list))))) ; node-name entry
494 (setq menu-list (cdr menu-list))) 583 (setq menu-list (cdr menu-list)))
495 (insert "@end menu") 584 (insert "@end menu")
496 (message 585 (message
497 "Updated \"%s\" level menu following node: %s ... " 586 "Updated \"%s\" level menu following node: %s ... " level node-name))
498 level node-name))
499 587
500 588
501;;;; Handling description indentation 589;;; Starting menu descriptions by inserting titles
590
591(defun texinfo-start-menu-description ()
592 "In this menu entry, insert the node's section title as a description.
593Position point at beginning of description ready for editing.
594Do not insert a title if the line contains an existing description.
595
596You will need to edit the inserted text since a useful description
597complements the node name rather than repeats it as a title does."
598
599 (interactive)
600 (let (beginning end node-name title)
601 (save-excursion
602 (beginning-of-line)
603 (if (search-forward "* " (save-excursion (end-of-line) (point)) t)
604 (progn (skip-chars-forward " \t")
605 (setq beginning (point)))
606 (error "This is not a line in a menu!"))
607
608 (cond
609 ;; "Double colon" entry line; menu entry and node name are the same,
610 ((search-forward "::" (save-excursion (end-of-line) (point)) t)
611 (if (looking-at "[ \t]*[^ \t\n]+")
612 (error "Descriptive text already exists."))
613 (skip-chars-backward ": \t")
614 (setq node-name (buffer-substring beginning (point))))
615
616 ;; "Single colon" entry line; menu entry and node name are different.
617 ((search-forward ":" (save-excursion (end-of-line) (point)) t)
618 (skip-chars-forward " \t")
619 (setq beginning (point))
620 ;; Menu entry line ends in a period, comma, or tab.
621 (if (re-search-forward "[.,\t]"
622 (save-excursion (forward-line 1) (point)) t)
623 (progn
624 (if (looking-at "[ \t]*[^ \t\n]+")
625 (error "Descriptive text already exists."))
626 (skip-chars-backward "., \t")
627 (setq node-name (buffer-substring beginning (point))))
628 ;; Menu entry line ends in a return.
629 (re-search-forward ".*\n"
630 (save-excursion (forward-line 1) (point)) t)
631 (skip-chars-backward " \t\n")
632 (setq node-name (buffer-substring beginning (point)))
633 (if (= 0 (length node-name))
634 (error "No node name on this line.")
635 (insert "."))))
636 (t (error "No node name on this line.")))
637 ;; Search for node that matches node name, and copy the section title.
638 (if (re-search-forward
639 (concat
640 "^@node[ \t]+"
641 node-name
642 ".*\n" ; match node line
643 "\\("
644 "\\(\\(^@c \\|^@comment\\).*\n\\)" ; match comment line, if any
645 "\\|" ; or
646 "\\(^@ifinfo[ ]*\n\\)" ; ifinfo line, if any
647 "\\)?")
648 nil t)
649 (progn
650 (setq title
651 (buffer-substring
652 ;; skip over section type
653 (progn (forward-word 1)
654 ;; and over spaces
655 (skip-chars-forward " \t")
656 (point))
657 (progn (end-of-line)
658 (skip-chars-backward " \t")
659 (point)))))
660 (error "Cannot find node to match node name in menu entry.")))
661 ;; Return point to the menu and insert the title.
662 (end-of-line)
663 (delete-region
664 (point)
665 (save-excursion (skip-chars-backward " \t") (point)))
666 (indent-to texinfo-column-for-description 2)
667 (save-excursion (insert title))))
668
669
670;;; Handling description indentation
502 671
503; Since the make-menu functions indent descriptions, these functions 672; Since the make-menu functions indent descriptions, these functions
504; are useful primarily for indenting a single menu specially. 673; are useful primarily for indenting a single menu specially.
@@ -540,7 +709,10 @@ second and subsequent lines of a multi-line description."
540 (goto-char (texinfo-menu-end)) 709 (goto-char (texinfo-menu-end))
541 (beginning-of-line) 710 (beginning-of-line)
542 (point))) 711 (point)))
543 (if (search-forward "::" (texinfo-menu-end) t) 712
713 (if (re-search-forward "\\* \\(.*::\\|.*: [^.,\t\n]+[.,\t]\\)"
714 (texinfo-menu-end)
715 t)
544 (progn 716 (progn
545 (let ((beginning-white-space (point))) 717 (let ((beginning-white-space (point)))
546 (skip-chars-forward " \t") ; skip over spaces 718 (skip-chars-forward " \t") ; skip over spaces
@@ -554,7 +726,7 @@ second and subsequent lines of a multi-line description."
554 (setq beginning-of-next-line (point))))) 726 (setq beginning-of-next-line (point)))))
555 727
556 728
557;;;; Making the master menu 729;;; Making the master menu
558 730
559(defun texinfo-master-menu (update-all-nodes-menus-p) 731(defun texinfo-master-menu (update-all-nodes-menus-p)
560 "Make a master menu for a whole Texinfo file. 732 "Make a master menu for a whole Texinfo file.
@@ -570,7 +742,7 @@ menus in the buffer (incorporating descriptions from pre-existing
570menus) before it constructs the master menu. 742menus) before it constructs the master menu.
571 743
572The function removes the detailed part of an already existing master 744The function removes the detailed part of an already existing master
573menu. This action depends on the pre-existing master menu using the 745menu. This action depends on the pre-exisitng master menu using the
574standard `texinfo-master-menu-header'. 746standard `texinfo-master-menu-header'.
575 747
576The master menu has the following format, which is adapted from the 748The master menu has the following format, which is adapted from the
@@ -588,66 +760,76 @@ recommendation in the Texinfo Manual:
588 760
589Each of the menus in the detailed node listing is introduced by the 761Each of the menus in the detailed node listing is introduced by the
590title of the section containing the menu." 762title of the section containing the menu."
591 763
592 (interactive "P") 764 (interactive "P")
593 (widen) 765 (let ((case-fold-search t))
594 (goto-char (point-min)) 766 (widen)
595 767 (goto-char (point-min))
596 ;; Move point to location after `top'. 768
597 (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t)) 769 ;; Move point to location after `top'.
598 (error "This buffer needs a Top node!")) 770 (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t))
599 771 (error "This buffer needs a Top node!"))
600 (let ((first-chapter 772
601 (save-excursion (re-search-forward "^@node") (point)))) 773 (let ((first-chapter
602 (if (re-search-forward texinfo-master-menu-header first-chapter t) 774 (save-excursion
603 ;; Remove detailed master menu listing 775 (or (re-search-forward "^@node" nil t)
776 (error "Too few nodes for a master menu!"))
777 (point))))
778 (if (re-search-forward texinfo-master-menu-header first-chapter t)
779 ;; Remove detailed master menu listing
780 (progn
781 (goto-char (match-beginning 0))
782 (let ((end-of-detailed-menu-descriptions
783 (save-excursion ; beginning of end menu line
784 (goto-char (texinfo-menu-end))
785 (beginning-of-line) (forward-char -1)
786 (point))))
787 (delete-region (point) end-of-detailed-menu-descriptions)))))
788
789 (if update-all-nodes-menus-p
604 (progn 790 (progn
605 (goto-char (match-beginning 0)) 791 (message "Making a master menu in %s ...first updating all nodes... "
606 (let ((end-of-detailed-menu-descriptions 792 (buffer-name))
607 (save-excursion ; beginning of end menu line 793 (sleep-for 2)
608 (goto-char (texinfo-menu-end)) 794 (push-mark (point-max) t)
609 (beginning-of-line) (forward-char -1) 795 (goto-char (point-min))
610 (point)))) 796 (texinfo-update-node t)
611 (delete-region (point) end-of-detailed-menu-descriptions))))) 797
612 798 (message "Updating all menus in %s ... " (buffer-name))
613 (if update-all-nodes-menus-p 799 (sleep-for 2)
614 (progn 800 (push-mark (point-max) t)
615 (message "Making a master menu...first updating all nodes... ") 801 (goto-char (point-min))
616 (sleep-for 2) 802 (texinfo-make-menu t)))
617 (mark-whole-buffer) 803
618 (texinfo-update-node t) 804 (message "Now making the master menu in %s... " (buffer-name))
619 805 (sleep-for 2)
620 (message "Updating all menus... ")
621 (sleep-for 2)
622 (mark-whole-buffer)
623 (texinfo-make-menu t)))
624
625 (message "Now making the master menu... ")
626 (sleep-for 2)
627 (goto-char (point-min))
628 (texinfo-insert-master-menu-list
629 (texinfo-master-menu-list))
630
631 ;; Remove extra newlines that texinfo-insert-master-menu-list
632 ;; may have inserted.
633
634 (save-excursion
635 (goto-char (point-min)) 806 (goto-char (point-min))
807 (texinfo-insert-master-menu-list
808 (texinfo-master-menu-list))
636 809
637 (re-search-forward texinfo-master-menu-header) 810 ;; Remove extra newlines that texinfo-insert-master-menu-list
638 (goto-char (match-beginning 0)) 811 ;; may have inserted.
639 (insert "\n")
640 (delete-blank-lines)
641 812
642 (re-search-backward "^@menu") 813 (save-excursion
643 (forward-line -1) 814 (goto-char (point-min))
644 (delete-blank-lines) 815
816 (if (re-search-forward texinfo-master-menu-header nil t)
817 (progn
818 (goto-char (match-beginning 0))
819 (insert "\n")
820 (delete-blank-lines)
821 (goto-char (point-min))))
822
823 (re-search-forward "^@menu")
824 (forward-line -1)
825 (delete-blank-lines)
826
827 (re-search-forward "^@end menu")
828 (forward-line 1)
829 (delete-blank-lines))
645 830
646 (re-search-forward "^@end menu") 831 (message
647 (forward-line 1) 832 "Done...completed making master menu. You may save the buffer.")))
648 (delete-blank-lines))
649
650 (message "Done...completed making master menu. You may save the buffer."))
651 833
652(defun texinfo-master-menu-list () 834(defun texinfo-master-menu-list ()
653 "Return a list of menu entries and header lines for the master menu. 835 "Return a list of menu entries and header lines for the master menu.
@@ -675,51 +857,60 @@ However, there does not need to be a title field."
675(defun texinfo-insert-master-menu-list (master-menu-list) 857(defun texinfo-insert-master-menu-list (master-menu-list)
676 "Format and insert the master menu in the current buffer." 858 "Format and insert the master menu in the current buffer."
677 (goto-char (point-min)) 859 (goto-char (point-min))
678 (re-search-forward "^@menu") 860 ;; Insert a master menu only after `Top' node and before next node
861 ;; \(or include file if there is no next node\).
862 (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t))
863 (error "This buffer needs a Top node!"))
864 (let ((first-chapter
865 (save-excursion (re-search-forward "^@node\\|^@include") (point))))
866 (if (not (re-search-forward "^@menu" first-chapter t))
867 (error
868 "Buffer lacks ordinary `Top' menu in which to insert master.")))
679 (beginning-of-line) 869 (beginning-of-line)
680 (delete-region (point) ; buffer must have ordinary top menu 870 (delete-region ; buffer must have ordinary top menu
681 (save-excursion 871 (point)
682 (re-search-forward "^@end menu") 872 (save-excursion (re-search-forward "^@end menu") (point)))
683 (point)))
684
685 (save-excursion ; leave point at beginning of menu
686 ;; Handle top of menu
687 (insert "\n@menu\n")
688 ;; Insert chapter menu entries
689 (setq this-very-menu-list (reverse (car (car master-menu-list))))
690 ;;; Tell user what is going on.
691 (message "Inserting chapter menu entry: %s ... " this-very-menu-list)
692 (while this-very-menu-list
693 (insert "* " (car this-very-menu-list) "\n")
694 (setq this-very-menu-list (cdr this-very-menu-list)))
695
696 (setq master-menu-list (cdr master-menu-list))
697
698 (insert texinfo-master-menu-header)
699 873
700 ;; Now, insert all the other menus 874 (save-excursion ; leave point at beginning of menu
701 875 ;; Handle top of menu
702 ;; The menu master-menu-list has a form like this: 876 (insert "\n@menu\n")
703 ;; ((("beta" "alpha") "title-A") 877 ;; Insert chapter menu entries
704 ;; (("delta" "gamma") "title-B"))
705
706 (while master-menu-list
707
708 (message
709 "Inserting menu for %s .... " (car (cdr (car master-menu-list))))
710 ;; insert title of menu section
711 (insert "\n" (car (cdr (car master-menu-list))) "\n\n")
712
713 ;; insert each menu entry
714 (setq this-very-menu-list (reverse (car (car master-menu-list)))) 878 (setq this-very-menu-list (reverse (car (car master-menu-list))))
879 ;; Tell user what is going on.
880 (message "Inserting chapter menu entry: %s ... " this-very-menu-list)
715 (while this-very-menu-list 881 (while this-very-menu-list
716 (insert "* " (car this-very-menu-list) "\n") 882 (insert "* " (car this-very-menu-list) "\n")
717 (setq this-very-menu-list (cdr this-very-menu-list))) 883 (setq this-very-menu-list (cdr this-very-menu-list)))
718 884
719 (setq master-menu-list (cdr master-menu-list))) 885 (setq master-menu-list (cdr master-menu-list))
720 886
721 ;; Finish menu 887 ;; Only insert detailed master menu if there is one....
722 (insert "@end menu\n\n"))) 888 (if (car (car master-menu-list))
889 (insert texinfo-master-menu-header))
890
891 ;; Now, insert all the other menus
892
893 ;; The menu master-menu-list has a form like this:
894 ;; ((("beta" "alpha") "title-A")
895 ;; (("delta" "gamma") "title-B"))
896
897 (while master-menu-list
898
899 (message
900 "Inserting menu for %s .... " (car (cdr (car master-menu-list))))
901 ;; insert title of menu section
902 (insert "\n" (car (cdr (car master-menu-list))) "\n\n")
903
904 ;; insert each menu entry
905 (setq this-very-menu-list (reverse (car (car master-menu-list))))
906 (while this-very-menu-list
907 (insert "* " (car this-very-menu-list) "\n")
908 (setq this-very-menu-list (cdr this-very-menu-list)))
909
910 (setq master-menu-list (cdr master-menu-list)))
911
912 ;; Finish menu
913 (insert "@end menu\n\n")))
723 914
724(defvar texinfo-master-menu-header 915(defvar texinfo-master-menu-header
725 "\n --- The Detailed Node Listing ---\n" 916 "\n --- The Detailed Node Listing ---\n"
@@ -736,21 +927,24 @@ If a menu is not found, do not move point and return nil."
736 "Return the title of the section preceding the menu as a string. 927 "Return the title of the section preceding the menu as a string.
737If such a title cannot be found, return an empty string. Do not move 928If such a title cannot be found, return an empty string. Do not move
738point." 929point."
739 (save-excursion 930 (let ((case-fold-search t))
740 (if (re-search-backward 931 (save-excursion
741 (concat 932 (if (re-search-backward
742 "\\(^@node\\).*\n" ; match node line 933 (concat
743 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any 934 "\\(^@top"
744 "\\|" ; or 935 "\\|" ; or
745 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any 936 texinfo-section-types-regexp ; all other section types
746 (eval 937 "\\)")
747 (cdr 938 nil
748 (assoc (texinfo-hierarchic-level) 939 t)
749 texinfo-update-menu-higher-regexps)))) 940 (progn
750 nil 941 (beginning-of-line)
751 t) 942 (forward-word 1) ; skip over section type
752 (texinfo-copy-section-title) 943 (skip-chars-forward " \t") ; and over spaces
753 " "))) 944 (buffer-substring
945 (point)
946 (progn (end-of-line) (point))))
947 ""))))
754 948
755(defun texinfo-copy-menu () 949(defun texinfo-copy-menu ()
756 "Return the entries of an existing menu as a list. 950 "Return the entries of an existing menu as a list.
@@ -761,7 +955,9 @@ and leave point on the line before the `@end menu' line."
761 (last-entry (save-excursion ; position of beginning of 955 (last-entry (save-excursion ; position of beginning of
762 ; last `* ' entry 956 ; last `* ' entry
763 (goto-char end-of-menu) 957 (goto-char end-of-menu)
764 (re-search-backward "^\* ") ; handle multi-line desc. 958 ;; handle multi-line description
959 (if (not (re-search-backward "^\* " nil t))
960 (error "No entries in menu."))
765 (point)))) 961 (point))))
766 (while (< (point) last-entry) 962 (while (< (point) last-entry)
767 (if (re-search-forward "^\* " end-of-menu t) 963 (if (re-search-forward "^\* " end-of-menu t)
@@ -778,7 +974,7 @@ and leave point on the line before the `@end menu' line."
778 this-menu-list)) 974 this-menu-list))
779 975
780 976
781;;;; Determining the hierarchical level in the texinfo file 977;;; Determining the hierarchical level in the texinfo file
782 978
783(defun texinfo-specific-section-type () 979(defun texinfo-specific-section-type ()
784 "Return the specific type of next section, as a string. 980 "Return the specific type of next section, as a string.
@@ -787,60 +983,67 @@ For example, \"unnumberedsubsec\". Return \"top\" for top node.
787Searches forward for a section. Hence, point must be before the 983Searches forward for a section. Hence, point must be before the
788section whose type will be found. Does not move point. Signal an 984section whose type will be found. Does not move point. Signal an
789error if the node is not the top node and a section is not found." 985error if the node is not the top node and a section is not found."
790 (save-excursion 986 (let ((case-fold-search t))
791 (cond 987 (save-excursion
792 ((re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" 988 (cond
793 (save-excursion 989 ((re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)"
794 (end-of-line) 990;;; Following search limit by cph but causes a bug
795 (point)) 991;;; (save-excursion
796 t) 992;;; (end-of-line)
797 "top") 993;;; (point))
798 ((re-search-forward texinfo-section-types-regexp nil t) 994 nil
799 (buffer-substring (progn (beginning-of-line) ; copy its name 995 t)
800 (1+ (point))) 996 "top")
801 (progn (forward-word 1) 997 ((re-search-forward texinfo-section-types-regexp nil t)
802 (point)))) 998 (buffer-substring (progn (beginning-of-line) ; copy its name
803 (t 999 (1+ (point)))
804 (error 1000 (progn (forward-word 1)
805 "texinfo-specific-section-type: Chapter or section not found."))))) 1001 (point))))
1002 (t
1003 (error
1004 "texinfo-specific-section-type: Chapter or section not found."))))))
806 1005
807(defun texinfo-hierarchic-level () 1006(defun texinfo-hierarchic-level ()
808 "Return the general hierarchal level of the next node in a texinfo file. 1007 "Return the general hierarchal level of the next node in a texinfo file.
809Thus, a subheading or appendixsubsec is of type subsection." 1008Thus, a subheading or appendixsubsec is of type subsection."
810 (cdr (assoc 1009 (let ((case-fold-search t))
811 (texinfo-specific-section-type) 1010 (cdr (assoc
812 texinfo-section-to-generic-alist))) 1011 (texinfo-specific-section-type)
1012 texinfo-section-to-generic-alist))))
813 1013
814 1014
815;;;; Locating the major positions 1015;;; Locating the major positions
816 1016
817(defun texinfo-update-menu-region-beginning (level) 1017(defun texinfo-update-menu-region-beginning (level)
818 "Locate beginning of higher level section this section is within. 1018 "Locate beginning of higher level section this section is within.
819Return position of the beginning of the node line; do not move point. 1019Return position of the beginning of the node line; do not move point.
820Thus, if this level is subsection, searches backwards for section node. 1020Thus, if this level is subsection, searches backwards for section node.
821Only argument is a string of the general type of section." 1021Only argument is a string of the general type of section."
822 1022 (let ((case-fold-search t))
823 (cond 1023 ;; !! Known bug: if section immediately follows top node, this
824 ((or (string-equal "top" level) 1024 ;; returns the beginning of the buffer as the beginning of the
825 (string-equal "chapter" level)) 1025 ;; higher level section.
826 (save-excursion 1026 (cond
827 (goto-char (point-min)) 1027 ((or (string-equal "top" level)
828 (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t) 1028 (string-equal "chapter" level))
829 (beginning-of-line) 1029 (save-excursion
830 (point))) 1030 (goto-char (point-min))
831 (t 1031 (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t)
832 (save-excursion 1032 (beginning-of-line)
833 (re-search-backward 1033 (point)))
834 (concat 1034 (t
835 "\\(^@node\\).*\n" ; match node line 1035 (save-excursion
836 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any 1036 (re-search-backward
837 "\\|" ; or 1037 (concat
838 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any 1038 "\\(^@node\\).*\n" ; match node line
839 (eval 1039 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any
840 (cdr (assoc level texinfo-update-menu-higher-regexps)))) 1040 "\\|" ; or
841 nil 1041 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any
842 'goto-beginning) 1042 (eval
843 (point))))) 1043 (cdr (assoc level texinfo-update-menu-higher-regexps))))
1044 nil
1045 'goto-beginning)
1046 (point))))))
844 1047
845(defun texinfo-update-menu-region-end (level) 1048(defun texinfo-update-menu-region-end (level)
846 "Locate end of higher level section this section is within. 1049 "Locate end of higher level section this section is within.
@@ -848,20 +1051,21 @@ Return position; do not move point. Thus, if this level is a
848subsection, find the node for the section this subsection is within. 1051subsection, find the node for the section this subsection is within.
849If level is top or chapter, returns end of file. Only argument is a 1052If level is top or chapter, returns end of file. Only argument is a
850string of the general type of section." 1053string of the general type of section."
851 1054 (let ((case-fold-search t))
852 (save-excursion 1055 (save-excursion
853 (if (re-search-forward 1056 (if (re-search-forward
854 (concat 1057 (concat
855 "\\(^@node\\).*\n" ; match node line 1058 "\\(^@node\\).*\n" ; match node line
856 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any 1059 "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any
857 "\\|" ; or 1060 "\\|" ; or
858 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any 1061 "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any
859 (eval 1062 (eval
860 (cdr (assoc level texinfo-update-menu-higher-regexps)))) 1063 ;; Never finds end of level above chapter so goes to end.
861 nil 1064 (cdr (assoc level texinfo-update-menu-higher-regexps))))
862 'goto-end) 1065 nil
863 (match-beginning 1) 1066 'goto-end)
864 (point-max)))) 1067 (match-beginning 1)
1068 (point-max)))))
865 1069
866(defun texinfo-menu-first-node (beginning end) 1070(defun texinfo-menu-first-node (beginning end)
867 "Locate first node of the section the menu will be placed in. 1071 "Locate first node of the section the menu will be placed in.
@@ -880,7 +1084,7 @@ end of that region; it limits the search."
880 (point))) 1084 (point)))
881 1085
882 1086
883;;;; Alists and regular expressions for defining hierarchical levels 1087;;; Alists and regular expressions for defining hierarchical levels
884 1088
885(defvar texinfo-section-to-generic-alist 1089(defvar texinfo-section-to-generic-alist
886 '(("top" . "top") 1090 '(("top" . "top")
@@ -909,8 +1113,9 @@ end of that region; it limits the search."
909The keys are strings specifying specific types of section; the values 1113The keys are strings specifying specific types of section; the values
910are strings of their corresponding general types.") 1114are strings of their corresponding general types.")
911 1115
1116;; We used to look for just sub, but that found @subtitle.
912(defvar texinfo-section-types-regexp 1117(defvar texinfo-section-types-regexp
913 "^@\\(chapter \\|sect\\|sub\\|unnum\\|major\\|chapheading \\|heading \\|appendix\\)" 1118 "^@\\(chapter \\|sect\\|subs\\|subh\\|unnum\\|major\\|chapheading \\|heading \\|appendix\\)"
914 "Regexp matching chapter, section, other headings (but not the top node).") 1119 "Regexp matching chapter, section, other headings (but not the top node).")
915 1120
916(defvar texinfo-chapter-level-regexp 1121(defvar texinfo-chapter-level-regexp
@@ -1010,7 +1215,7 @@ The keys are strings specifying the general hierarchical level in the
1010document; the values are regular expressions.") 1215document; the values are regular expressions.")
1011 1216
1012 1217
1013;;;; Updating a Node 1218;;; Updating a node
1014 1219
1015(defun texinfo-update-node (&optional region-p) 1220(defun texinfo-update-node (&optional region-p)
1016 "Without any prefix argument, update the node in which point is located. 1221 "Without any prefix argument, update the node in which point is located.
@@ -1031,7 +1236,7 @@ keybindings, are:
1031 texinfo-indent-menu-description (column &optional region-p) 1236 texinfo-indent-menu-description (column &optional region-p)
1032 1237
1033The `texinfo-column-for-description' variable specifies the column to 1238The `texinfo-column-for-description' variable specifies the column to
1034which menu descriptions are indented. Its default value is 24." 1239which menu descriptions are indented. Its default value is 32."
1035 1240
1036 (interactive "P") 1241 (interactive "P")
1037 (if (not region-p) 1242 (if (not region-p)
@@ -1049,7 +1254,7 @@ which menu descriptions are indented. Its default value is 24."
1049 (save-restriction 1254 (save-restriction
1050 (narrow-to-region beginning end) 1255 (narrow-to-region beginning end)
1051 (goto-char beginning) 1256 (goto-char beginning)
1052 (push-mark) 1257 (push-mark (point) t)
1053 (while (re-search-forward "^@node" (point-max) t) 1258 (while (re-search-forward "^@node" (point-max) t)
1054 (beginning-of-line) 1259 (beginning-of-line)
1055 (texinfo-update-the-node)) 1260 (texinfo-update-the-node))
@@ -1059,7 +1264,8 @@ which menu descriptions are indented. Its default value is 24."
1059 "Update every node in a Texinfo file." 1264 "Update every node in a Texinfo file."
1060 (interactive) 1265 (interactive)
1061 (save-excursion 1266 (save-excursion
1062 (mark-whole-buffer) 1267 (push-mark (point-max) t)
1268 (goto-char (point-min))
1063 (texinfo-update-node t) 1269 (texinfo-update-node t)
1064 (message "Done...updated every node. You may save the buffer."))) 1270 (message "Done...updated every node. You may save the buffer.")))
1065 1271
@@ -1111,12 +1317,17 @@ left at the end of the node line."
1111 "Determine whether the node has a node name. Prompt for one if not. 1317 "Determine whether the node has a node name. Prompt for one if not.
1112Point must be at beginning of node line. Does not move point." 1318Point must be at beginning of node line. Does not move point."
1113 (save-excursion 1319 (save-excursion
1114 (forward-word 1) ; skip over node command 1320 (let ((initial (texinfo-copy-next-section-title)))
1115 (skip-chars-forward " \t") ; and over spaces 1321 ;; This is not clean. Use `interactive' to read the arg.
1116 (if (not (looking-at "[^,\t\n ]+")) ; regexp based on what info looks for 1322 (forward-word 1) ; skip over node command
1117 ; alternatively, use "[a-zA-Z]+" 1323 (skip-chars-forward " \t") ; and over spaces
1118 (let ((node-name (read-from-minibuffer "Node name: "))) 1324 (if (not (looking-at "[^,\t\n ]+")) ; regexp based on what Info looks for
1119 (insert " " node-name))))) 1325 ; alternatively, use "[a-zA-Z]+"
1326 (let ((node-name
1327 (read-from-minibuffer
1328 "Node name (use no @, commas, colons, or apostrophes): "
1329 initial)))
1330 (insert " " node-name))))))
1120 1331
1121(defun texinfo-delete-existing-pointers () 1332(defun texinfo-delete-existing-pointers ()
1122 "Delete `Next', `Previous', and `Up' pointers. 1333 "Delete `Next', `Previous', and `Up' pointers.
@@ -1144,42 +1355,71 @@ the Texinfo file; when looking for the `Up' pointer, the section found
1144will be at some level higher in the Texinfo file. The fourth argument 1355will be at some level higher in the Texinfo file. The fourth argument
1145\(one of 'next, 'previous, or 'up\) specifies whether to find the 1356\(one of 'next, 'previous, or 'up\) specifies whether to find the
1146`Next', `Previous', or `Up' pointer." 1357`Next', `Previous', or `Up' pointer."
1147 1358 (let ((case-fold-search t))
1148 (cond ((eq direction 'next) 1359 (cond ((eq direction 'next)
1149 (forward-line 3) ; skip over current node 1360 (forward-line 3) ; skip over current node
1150 (if (re-search-forward 1361 ;; Search for section commands accompanied by node lines;
1151 (eval 1362 ;; ignore section commands in the middle of nodes.
1152 (cdr (assoc level texinfo-update-menu-same-level-regexps))) 1363 (if (re-search-forward
1153 end 1364 ;; A `Top' node is never a next pointer, so won't find it.
1154 t) 1365 (concat
1155 'normal 1366 ;; Match node line.
1156 'no-pointer)) 1367 "\\(^@node\\).*\n"
1157 ((eq direction 'previous) 1368 ;; Match comment or ifinfo line, if any
1158 (if (re-search-backward 1369 "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?"
1159 (concat 1370 (eval
1160 "\\(" 1371 (cdr (assoc level texinfo-update-menu-same-level-regexps))))
1161 (eval 1372 end
1162 (cdr (assoc level texinfo-update-menu-same-level-regexps))) 1373 t)
1163 "\\|" 1374 'normal
1164 (eval 1375 'no-pointer))
1165 (cdr (assoc level texinfo-update-menu-higher-regexps))) 1376 ((eq direction 'previous)
1166 "\\)") 1377 (if (re-search-backward
1167 beginning 1378 (concat
1168 t) 1379 "\\("
1169 'normal 1380 ;; Match node line.
1170 'no-pointer)) 1381 "\\(^@node\\).*\n"
1171 ((eq direction 'up) 1382 ;; Match comment or ifinfo line, if any
1172 (if (re-search-backward 1383 "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?"
1173 (eval (cdr (assoc level texinfo-update-menu-higher-regexps))) 1384 (eval
1174 (save-excursion 1385 (cdr (assoc level texinfo-update-menu-same-level-regexps)))
1175 (goto-char beginning) 1386 "\\|"
1176 (beginning-of-line) 1387 ;; Match node line.
1177 (point)) 1388 "\\(^@node\\).*\n"
1178 t) 1389 ;; Match comment or ifinfo line, if any
1179 'normal 1390 "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?"
1180 'no-pointer)) 1391 (eval
1181 (t 1392 (cdr (assoc level texinfo-update-menu-higher-regexps)))
1182 (error "texinfo-find-pointer: lack proper arguments")))) 1393 "\\|"
1394 ;; Handle `Top' node specially.
1395 "^@node [ \t]*top[ \t]*\\(,\\|$\\)"
1396 "\\)")
1397 beginning
1398 t)
1399 'normal
1400 'no-pointer))
1401 ((eq direction 'up)
1402 (if (re-search-backward
1403 (concat
1404 "\\("
1405 ;; Match node line.
1406 "\\(^@node\\).*\n"
1407 ;; Match comment or ifinfo line, if any
1408 "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?"
1409 (eval (cdr (assoc level texinfo-update-menu-higher-regexps)))
1410 "\\|"
1411 ;; Handle `Top' node specially.
1412 "^@node [ \t]*top[ \t]*\\(,\\|$\\)"
1413 "\\)")
1414 (save-excursion
1415 (goto-char beginning)
1416 (beginning-of-line)
1417 (point))
1418 t)
1419 'normal
1420 'no-pointer))
1421 (t
1422 (error "texinfo-find-pointer: lack proper arguments")))))
1183 1423
1184(defun texinfo-pointer-name (kind) 1424(defun texinfo-pointer-name (kind)
1185 "Return the node name preceding the section command. 1425 "Return the node name preceding the section command.
@@ -1221,7 +1461,7 @@ towards which the pointer is directed, one of `next, `previous, or
1221 (delete-region (point) (save-excursion (end-of-line) (point)))) 1461 (delete-region (point) (save-excursion (end-of-line) (point))))
1222 1462
1223 1463
1224;;;; Updating nodes sequentially 1464;;; Updating nodes sequentially
1225; These sequential update functions insert `Next' or `Previous' 1465; These sequential update functions insert `Next' or `Previous'
1226; pointers that point to the following or preceding nodes even if they 1466; pointers that point to the following or preceding nodes even if they
1227; are at higher or lower hierarchical levels. This means that if a 1467; are at higher or lower hierarchical levels. This means that if a
@@ -1264,7 +1504,7 @@ Info `g*' command is inadequate."
1264 (save-restriction 1504 (save-restriction
1265 (narrow-to-region beginning end) 1505 (narrow-to-region beginning end)
1266 (goto-char beginning) 1506 (goto-char beginning)
1267 (push-mark) 1507 (push-mark (point) t)
1268 (while (re-search-forward "^@node" (point-max) t) 1508 (while (re-search-forward "^@node" (point-max) t)
1269 (beginning-of-line) 1509 (beginning-of-line)
1270 (texinfo-sequentially-update-the-node)) 1510 (texinfo-sequentially-update-the-node))
@@ -1306,31 +1546,31 @@ same hierarchical level in the Texinfo file, or, in the case of the up
1306pointer, some level higher. The second argument (one of 'next, 1546pointer, some level higher. The second argument (one of 'next,
1307'previous, or 'up) specifies whether to find the `Next', `Previous', 1547'previous, or 'up) specifies whether to find the `Next', `Previous',
1308or `Up' pointer." 1548or `Up' pointer."
1309 1549 (let ((case-fold-search t))
1310 (cond ((eq direction 'next) 1550 (cond ((eq direction 'next)
1311 (forward-line 3) ; skip over current node 1551 (forward-line 3) ; skip over current node
1312 (if (re-search-forward 1552 (if (re-search-forward
1313 texinfo-section-types-regexp 1553 texinfo-section-types-regexp
1314 (point-max) 1554 (point-max)
1315 t) 1555 t)
1316 'normal 1556 'normal
1317 'no-pointer)) 1557 'no-pointer))
1318 ((eq direction 'previous) 1558 ((eq direction 'previous)
1319 (if (re-search-backward 1559 (if (re-search-backward
1320 texinfo-section-types-regexp 1560 texinfo-section-types-regexp
1321 (point-min) 1561 (point-min)
1322 t) 1562 t)
1323 'normal 1563 'normal
1324 'no-pointer)) 1564 'no-pointer))
1325 ((eq direction 'up) 1565 ((eq direction 'up)
1326 (if (re-search-backward 1566 (if (re-search-backward
1327 (eval (cdr (assoc level texinfo-update-menu-higher-regexps))) 1567 (eval (cdr (assoc level texinfo-update-menu-higher-regexps)))
1328 beginning 1568 beginning
1329 t) 1569 t)
1330 'normal 1570 'normal
1331 'no-pointer)) 1571 'no-pointer))
1332 (t 1572 (t
1333 (error "texinfo-sequential-find-pointer: lack proper arguments")))) 1573 (error "texinfo-sequential-find-pointer: lack proper arguments")))))
1334 1574
1335(defun texinfo-sequentially-insert-pointer (level direction) 1575(defun texinfo-sequentially-insert-pointer (level direction)
1336 "Insert the `Next', `Previous' or `Up' node name at point. 1576 "Insert the `Next', `Previous' or `Up' node name at point.
@@ -1348,67 +1588,82 @@ string such as \"section\". The second argument is direction, one of
1348 (texinfo-sequentially-find-pointer level direction))))) 1588 (texinfo-sequentially-find-pointer level direction)))))
1349 1589
1350 1590
1351;;;; Inserting `@node' lines 1591;;; Inserting `@node' lines
1352; The `texinfo-insert-node-lines' function inserts `@node' lines as needed 1592; The `texinfo-insert-node-lines' function inserts `@node' lines as needed
1353; before the `@chapter', `@section', and such like lines of a region 1593; before the `@chapter', `@section', and such like lines of a region
1354; in a Texinfo file. 1594; in a Texinfo file.
1355 1595
1356(defun texinfo-insert-node-lines (&optional title-p) 1596(defun texinfo-insert-node-lines (beginning end &optional title-p)
1357 "Insert missing `@node' lines in region of Texinfo file. 1597 "Insert missing `@node' lines in region of Texinfo file.
1358Non-nil argument (prefix, if interactive) means also to insert the 1598Non-nil argument (prefix, if interactive) means also to insert the
1359section titles as node names; and also to insert the section titles as 1599section titles as node names; and also to insert the section titles as
1360node names in pre-existing @node lines that lack names." 1600node names in pre-existing @node lines that lack names."
1361 (interactive "P") 1601 (interactive "r\nP")
1362 (save-excursion 1602
1363 (let ((begin-region (region-beginning)) 1603 ;; Use marker; after inserting node lines, leave point at end of
1364 (end-region (region-end))) 1604 ;; region and mark at beginning.
1365 (goto-char begin-region) 1605
1366 (while (< (point) end-region) 1606 (let (beginning-marker end-marker title last-section-position)
1367 (re-search-forward texinfo-section-types-regexp nil 'end) 1607
1368 ;; copy title, since most often, we will need it 1608 ;; Save current position on mark ring and set mark to end.
1369 (let ((title 1609 (push-mark end t)
1370 (progn 1610 (setq end-marker (mark-marker))
1371 (beginning-of-line) 1611
1372 (forward-word 1) 1612 (goto-char beginning)
1373 (skip-chars-forward " \t") 1613 (while (re-search-forward
1374 (buffer-substring 1614 texinfo-section-types-regexp
1375 (point) 1615 end-marker
1376 (save-excursion (end-of-line) (point)))))) 1616 'end)
1377 ;; insert a node if necessary 1617 ;; Copy title if desired.
1378 (if (re-search-backward 1618 (if title-p
1379 "^@node" 1619 (progn
1380 (save-excursion 1620 (beginning-of-line)
1381 (forward-line -3) 1621 (forward-word 1)
1382 (point)) 1622 (skip-chars-forward " \t")
1383 t) 1623 (setq title (buffer-substring
1384 ;; @node present, and point at beginning of that line 1624 (point)
1385 (forward-word 1) 1625 (save-excursion (end-of-line) (point))))))
1386 ;; else @node missing, insert one 1626 ;; Insert node line if necessary.
1387 (progn 1627 (if (re-search-backward
1388 (beginning-of-line) ; beginning of `@section' line 1628 "^@node"
1389 (insert "@node\n") 1629 ;; Avoid finding previous node line if node lines are close.
1390 (backward-char 1))) ; leave point just after `@node' 1630 (or last-section-position
1391 ;; insert a title if warranted 1631 (save-excursion (forward-line -2) (point))) t)
1392 (if title-p 1632 ;; @node is present, and point at beginning of that line
1393 (progn 1633 (forward-word 1) ; Leave point just after @node.
1394 (skip-chars-forward " \t") 1634 ;; Else @node missing; insert one.
1395 ;; use regexp based on what info looks for 1635 (beginning-of-line) ; Beginning of `@section' line.
1396 ;; (alternatively, use "[a-zA-Z]+") 1636 (insert "@node\n")
1397 (if (not (looking-at "[^,\t\n ]+")) 1637 (backward-char 1)) ; Leave point just after `@node'.
1398 (progn 1638 ;; Insert title if desired.
1399 (beginning-of-line) 1639 (if title-p
1400 (forward-word 1) 1640 (progn
1401 (insert " " title) 1641 (skip-chars-forward " \t")
1402 (message "Inserted title %s ... " title))))) 1642 ;; Use regexp based on what info looks for
1403 ;; in any case, go forward beyond current section title 1643 ;; (alternatively, use "[a-zA-Z]+");
1404 (forward-line 3))))) 1644 ;; this means we only insert a title if none exists.
1405 (if title-p 1645 (if (not (looking-at "[^,\t\n ]+"))
1646 (progn
1647 (beginning-of-line)
1648 (forward-word 1)
1649 (insert " " title)
1650 (message "Inserted title %s ... " title)))))
1651 ;; Go forward beyond current section title.
1652 (re-search-forward texinfo-section-types-regexp
1653 (save-excursion (forward-line 3) (point)) t)
1654 (setq last-section-position (point))
1655 (forward-line 1))
1656
1657 ;; Leave point at end of region, mark at beginning.
1658 (set-mark beginning)
1659
1660 (if title-p
1406 (message 1661 (message
1407 "Done inserting node lines and titles. You may save the buffer.") 1662 "Done inserting node lines and titles. You may save the buffer.")
1408 (message "Done inserting node lines. You may save the buffer."))) 1663 (message "Done inserting node lines. You may save the buffer."))))
1409 1664
1410 1665
1411;;;; Update and create menus for multi-file Texinfo sources 1666;;; Update and create menus for multi-file Texinfo sources
1412 1667
1413;; 1. M-x texinfo-multiple-files-update 1668;; 1. M-x texinfo-multiple-files-update
1414;; 1669;;
@@ -1437,7 +1692,7 @@ node names in pre-existing @node lines that lack names."
1437;;; Hence, you may need a file for indices. 1692;;; Hence, you may need a file for indices.
1438 1693
1439 1694
1440;;;; Auxiliary functions for multiple file updating 1695;;; Auxiliary functions for multiple file updating
1441 1696
1442(defun texinfo-multi-file-included-list (outer-file) 1697(defun texinfo-multi-file-included-list (outer-file)
1443 "Return a list of the included files in OUTER-FILE." 1698 "Return a list of the included files in OUTER-FILE."
@@ -1465,25 +1720,27 @@ same place. If there is no title, returns an empty string."
1465 1720
1466 (save-excursion 1721 (save-excursion
1467 (end-of-line) 1722 (end-of-line)
1468 (let ((section-end (or 1723 (let ((node-end (or
1469 (save-excursion 1724 (save-excursion
1470 (re-search-forward "\\(^@node\\)" nil t) 1725 (if (re-search-forward "\\(^@node\\)" nil t)
1471 (match-beginning 0)) 1726 (match-beginning 0)))
1472 (point-max)))) 1727 (point-max))))
1473 (if (re-search-forward texinfo-section-types-regexp section-end t) 1728 (if (re-search-forward texinfo-section-types-regexp node-end t)
1474 ;; copy title 1729 (progn
1475 (let ((title 1730 (beginning-of-line)
1476 (buffer-substring 1731 ;; copy title
1477 (progn (forward-word 1) ; skip over section type 1732 (let ((title
1478 (skip-chars-forward " \t") ; and over spaces 1733 (buffer-substring
1479 (point)) 1734 (progn (forward-word 1) ; skip over section type
1480 (progn (end-of-line) (point))))) 1735 (skip-chars-forward " \t") ; and over spaces
1481 title) 1736 (point))
1737 (progn (end-of-line) (point)))))
1738 title))
1482 "")))) 1739 ""))))
1483 1740
1484(defun texinfo-multi-file-update (files &optional update-everything) 1741(defun texinfo-multi-file-update (files &optional update-everything)
1485 "Update first node pointers in each file in FILES. 1742 "Update first node pointers in each file in FILES.
1486Return a list of the node names and the title immediate following them. 1743Return a list of the node names.
1487 1744
1488The first file in the list is an outer file; the remaining are 1745The first file in the list is an outer file; the remaining are
1489files included in the outer file with `@include' commands. 1746files included in the outer file with `@include' commands.
@@ -1502,16 +1759,20 @@ Requirements:
1502 * each highest hierarchical level node must be of the same type. 1759 * each highest hierarchical level node must be of the same type.
1503 1760
1504Thus, normally, each included file contains one, and only one, 1761Thus, normally, each included file contains one, and only one,
1505chapter. 1762chapter."
1506
1507The menu-list has the form:
1508
1509 \(\(\"node-name1\" . \"title1\"\)
1510 \(\"node-name2\" . \"title2\"\) ... \)
1511 1763
1512However, there does not need to be a title field." 1764; The menu-list has the form:
1765;
1766; \(\(\"node-name1\" . \"title1\"\)
1767; \(\"node-name2\" . \"title2\"\) ... \)
1768;
1769; However, there does not need to be a title field and this function
1770; does not fill it; however a comment tells you how to do so.
1771; You would use the title field if you wanted to insert titles in the
1772; description slot of a menu as a description.
1513 1773
1514 (let (menu-list) 1774 (let ((case-fold-search t)
1775 menu-list)
1515 1776
1516 ;; Find the name of the first node of the first included file. 1777 ;; Find the name of the first node of the first included file.
1517 (switch-to-buffer (find-file-noselect (car (cdr files)))) 1778 (switch-to-buffer (find-file-noselect (car (cdr files))))
@@ -1526,9 +1787,11 @@ However, there does not need to be a title field."
1526 (setq menu-list 1787 (setq menu-list
1527 (cons (cons 1788 (cons (cons
1528 next-node-name 1789 next-node-name
1529 (texinfo-copy-next-section-title)) 1790 (prog1 "" (forward-line 1)))
1791 ;; Use following to insert section titles automatically.
1792 ;; (texinfo-copy-next-section-title)
1530 menu-list)) 1793 menu-list))
1531 1794
1532 ;; Go to outer file 1795 ;; Go to outer file
1533 (switch-to-buffer (find-file-noselect (car files))) 1796 (switch-to-buffer (find-file-noselect (car files)))
1534 (goto-char (point-min)) 1797 (goto-char (point-min))
@@ -1560,7 +1823,9 @@ However, there does not need to be a title field."
1560 (setq menu-list 1823 (setq menu-list
1561 (cons (cons 1824 (cons (cons
1562 next-node-name 1825 next-node-name
1563 (texinfo-copy-next-section-title)) 1826 (prog1 "" (forward-line 1)))
1827 ;; Use following to insert section titles automatically.
1828 ;; (texinfo-copy-next-section-title)
1564 menu-list))) 1829 menu-list)))
1565 1830
1566 ;; Go to node to be updated. 1831 ;; Go to node to be updated.
@@ -1569,6 +1834,11 @@ However, there does not need to be a title field."
1569 (if (not (re-search-forward "^@node" nil t)) 1834 (if (not (re-search-forward "^@node" nil t))
1570 (error "No `@node' line found in %s !" (buffer-name))) 1835 (error "No `@node' line found in %s !" (buffer-name)))
1571 (beginning-of-line) 1836 (beginning-of-line)
1837
1838 ;; Update other menus and nodes if requested.
1839 (if update-everything (texinfo-all-menus-update t))
1840
1841 (beginning-of-line)
1572 (texinfo-delete-existing-pointers) 1842 (texinfo-delete-existing-pointers)
1573 (end-of-line) 1843 (end-of-line)
1574 (insert ", " next-node-name ", " previous-node-name ", " up-node-name) 1844 (insert ", " next-node-name ", " previous-node-name ", " up-node-name)
@@ -1576,9 +1846,6 @@ However, there does not need to be a title field."
1576 (beginning-of-line) 1846 (beginning-of-line)
1577 (setq previous-node-name (texinfo-copy-node-name)) 1847 (setq previous-node-name (texinfo-copy-node-name))
1578 1848
1579 ;; Update other menus and nodes if requested.
1580 (if update-everything (texinfo-all-menus-update t))
1581
1582 (setq files (cdr files))) 1849 (setq files (cdr files)))
1583 (nreverse menu-list))) 1850 (nreverse menu-list)))
1584 1851
@@ -1589,20 +1856,29 @@ texinfo-column-for-description."
1589 1856
1590 (insert "@menu\n") 1857 (insert "@menu\n")
1591 (while menu-list 1858 (while menu-list
1592 (if (cdr (car menu-list)) ; menu-list has description entry 1859 ;; Every menu entry starts with a star and a space.
1860 (insert "* ")
1861
1862 ;; Insert the node name (and menu entry name, if present).
1863 (let ((node-part (car (car menu-list))))
1864 (if (stringp node-part)
1865 ;; "Double colon" entry line; menu entry and node name are the same,
1866 (insert (format "%s::" node-part))
1867 ;; "Single colon" entry line; menu entry and node name are different.
1868 (insert (format "%s: %s." (car node-part) (cdr node-part)))))
1869
1870 ;; Insert the description, if present.
1871 (if (cdr (car menu-list))
1593 (progn 1872 (progn
1594 (insert 1873 ;; Move to right place.
1595 (format "* %s::" (car (car menu-list)))) ; node-name entry 1874 (indent-to texinfo-column-for-description 2)
1596 (indent-to texinfo-column-for-description 2) 1875 ;; Insert description.
1597 (insert 1876 (insert (format "%s" (cdr (car menu-list))))))
1598 (format "%s\n" (cdr (car menu-list))))) ; description entry 1877
1599 ;; else menu-list lacks description entry 1878 (insert "\n") ; end this menu entry
1600 (insert
1601 (format "* %s::\n" (car (car menu-list))))) ; node-name entry
1602 (setq menu-list (cdr menu-list))) 1879 (setq menu-list (cdr menu-list)))
1603 (insert "@end menu")) 1880 (insert "@end menu"))
1604 1881
1605
1606(defun texinfo-multi-file-master-menu-list (files-list) 1882(defun texinfo-multi-file-master-menu-list (files-list)
1607 "Return master menu list from files in FILES-LIST. 1883 "Return master menu list from files in FILES-LIST.
1608Menu entries in each file collected using `texinfo-master-menu-list'. 1884Menu entries in each file collected using `texinfo-master-menu-list'.
@@ -1621,24 +1897,27 @@ be the files included within it. A main menu must already exist."
1621 master-menu-list))) 1897 master-menu-list)))
1622 1898
1623 1899
1624;;;; The multiple-file update function 1900;;; The multiple-file update function
1625 1901
1626(defun texinfo-multiple-files-update 1902(defun texinfo-multiple-files-update
1627 (outer-file &optional update-everything make-master-menu) 1903 (outer-file &optional update-everything make-master-menu)
1628 "Update first node pointers in each file included in OUTER-FILE; 1904 "Update first node pointers in each file included in OUTER-FILE;
1629create or update main menu in the outer file that refers to such nodes. 1905create or update the `Top' level node pointers and the main menu in
1630This does not create or update menus or pointers within the included files. 1906the outer file that refers to such nodes. This does not create or
1907update menus or pointers within the included files.
1631 1908
1632With optional MAKE-MASTER-MENU argument (prefix arg, if interactive), 1909With optional MAKE-MASTER-MENU argument (prefix arg, if interactive),
1633insert a master menu in OUTER-FILE. This does not create or update 1910insert a master menu in OUTER-FILE in addition to creating or updating
1634menus or pointers within the included files. 1911pointers in the first @node line in each included file and creating or
1912updating the `Top' level node pointers of the outer file. This does
1913not create or update other menus and pointers within the included
1914files.
1635 1915
1636With optional UPDATE-EVERYTHING argument (numeric prefix arg, if 1916With optional UPDATE-EVERYTHING argument (numeric prefix arg, if
1637interactive), update all the menus and all the `Next', `Previous', and 1917interactive), update all the menus and all the `Next', `Previous', and
1638`Up' pointers of all the files included in OUTER-FILE before inserting 1918`Up' pointers of all the files included in OUTER-FILE before inserting
1639a master menu in OUTER-FILE. 1919a master menu in OUTER-FILE. Also, update the `Top' level node
1640 1920pointers of OUTER-FILE.
1641The command also updates the `Top' level node pointers of OUTER-FILE.
1642 1921
1643Notes: 1922Notes:
1644 1923
@@ -1658,12 +1937,18 @@ Requirements:
1658 1937
1659Thus, normally, each included file contains one, and only one, 1938Thus, normally, each included file contains one, and only one,
1660chapter." 1939chapter."
1661 1940
1662 (interactive "fName of outer `include' file: ") 1941 (interactive (cons
1663 1942 (read-string
1664 (cond (current-prefix-arg 1943 "Name of outer `include' file: "
1665 (setq make-master-menu (listp current-prefix-arg)) 1944 (buffer-file-name))
1666 (setq update-everything (numberp current-prefix-arg)))) 1945 (cond ((not current-prefix-arg)
1946 '(nil nil))
1947 ((listp current-prefix-arg)
1948 '(t nil)) ; make-master-menu
1949 ((numberp current-prefix-arg)
1950 '(t t)) ; update-everything
1951 )))
1667 1952
1668 (let* ((included-file-list (texinfo-multi-file-included-list outer-file)) 1953 (let* ((included-file-list (texinfo-multi-file-included-list outer-file))
1669 (files included-file-list) 1954 (files included-file-list)
@@ -1720,10 +2005,27 @@ chapter."
1720 2005
1721 ;; Create a master menu and insert it 2006 ;; Create a master menu and insert it
1722 (texinfo-insert-master-menu-list 2007 (texinfo-insert-master-menu-list
1723 (texinfo-multi-file-master-menu-list 2008 (texinfo-multi-file-master-menu-list
1724 included-file-list))))) 2009 included-file-list)))))
2010
2011 ;; Remove unwanted extra lines.
2012 (save-excursion
2013 (goto-char (point-min))
2014
2015 (re-search-forward "^@menu")
2016 (forward-line -1)
2017 (insert "\n") ; Ensure at least one blank line.
2018 (delete-blank-lines)
2019
2020 (re-search-forward "^@end menu")
2021 (forward-line 1)
2022 (insert "\n") ; Ensure at least one blank line.
2023 (delete-blank-lines))
2024
1725 (message "Multiple files updated.")) 2025 (message "Multiple files updated."))
1726 2026
2027
2028;;; Place `provide' at end of file.
1727(provide 'texnfo-upd) 2029(provide 'texnfo-upd)
1728 2030
1729;;; texnfo-upd.el ends here 2031;;; texnfo-upd.el ends here