]> code.delx.au - gnu-emacs/blobdiff - lisp/textmodes/texnfo-upd.el
Merge from emacs-24; up to 117689
[gnu-emacs] / lisp / textmodes / texnfo-upd.el
index 868be0d4fa6762671de5f116be3a9fffd2ddd9aa..839d7a96b5dec58d4c5e34f7fec3924a32ade200 100644 (file)
@@ -1,7 +1,6 @@
 ;;; texnfo-upd.el --- utilities for updating nodes and menus in Texinfo files
 
-;; Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+;; Copyright (C) 1989-1992, 2001-2014 Free Software Foundation, Inc.
 
 ;; Author: Robert J. Chassell
 ;; Maintainer: bug-texinfo@gnu.org
@@ -24,7 +23,9 @@
 
 ;;; Commentary:
 
-;; Known bug: update commands fail to ignore @ignore.
+;; Known bug: update commands fail to ignore @ignore, and fail to DTRT
+;; with the @if... directives (so expect trouble when the manual uses
+;; different @node lines or @menu items in @iftex and in @ifnottex).
 
 ;; Summary: how to use the updating commands
 
 ;; With a prefix argument, the `texinfo-update-node' and
 ;; `texinfo-make-menu' functions do their jobs in the region.
 ;;
+;; Important note: We do NOT recommend use of these commands to update
+;; the `Next', `Previous' and `Up' pointers on @node lines.  Most
+;; manuals, including those whose Texinfo files adhere to the structure
+;; described below, don't need these pointers, because makeinfo will
+;; generate them automatically (see the node "makeinfo Pointer
+;; Creation" in the Texinfo manual).  By contrast, due to known bugs
+;; described above, texinfo-update-node etc. could produce incorrect
+;; pointers, and thus make a perfectly valid Texinfo file into an
+;; invalid one.  You _have_ been warned!
+;;
 ;; In brief, the functions for creating or updating nodes and menus, are:
 ;;
 ;;     texinfo-update-node (&optional beginning end)
 ;; It does not matter whether the  `@node' line has pre-existing
 ;; `Next', `Previous', or `Up' pointers in it.  They are removed.
 
+;; Warning: Since the pre-existing pointers are replaced with the ones
+;; computed by `texinfo-update-node', and since this function has
+;; known bugs with the more advanced Texinfo features (see above), it
+;; could produce an invalid Texinfo file.  You are well advised not to
+;; use this function, except if you know what you are doing and
+;; exercise extreme caution.  Keep in mind that most manuals do not
+;; need the `Next', `Previous', and `Up' pointers to be present on the
+;; @node lines; makeinfo will automatically generate them when it
+;; produces the Info or HTML versions of the manual.
+
 ;; The `texinfo-every-node-update' function runs `texinfo-update-node'
 ;; on the whole buffer.
 
 ;; on the whole buffer.
 
 ;; The `texinfo-master-menu' function creates an extended menu located
-;; after the top node.  (The file must have a top node.)  The function
-;; first updates all the regular menus in the buffer (incorporating the
-;; descriptions from pre-existing menus), and then constructs a master
-;; menu that includes every entry from every other menu.  (However, the
-;; function cannot update an already existing master menu; if one
-;; exists, it must be removed before calling the function.)
+;; after the top node.  (The file must have a top node.)  This
+;; function works only on Texinfo files all of whose menus are
+;; present in a single file; use `texinfo-multiple-files-update' for
+;; multi-file manuals.  The function constructs a master menu that
+;; includes every entry from every other menu.  Use this command to
+;; create or update the @detailmenu menu after you've created or
+;; updated all the menus in the file, including the menu in the Top
+;; node, using the `texinfo-make-menu' or the `texinfo-all-menus-update'
+;; command.
 
 ;; The `texinfo-indent-menu-description' function indents every
 ;; description in the menu following point, to the specified column.
 ;; as node names in pre-existing `@node' lines that lack names.
 ;;
 ;; Since node names should be more concise than section or chapter
-;; titles, node names so inserted will need to be edited manually.
+;; titles, you will usually want to manually edit node names so inserted.
 
 \f
 ;;; Code:
@@ -179,7 +203,7 @@ It comes after the chapter-level menu entries.")
     (3 . (concat "\\(^@\\)\\(" texinfo-section-level-regexp "\\)\\>[ \t]*"))
     (4 . (concat "\\(^@\\)\\(" texinfo-subsection-level-regexp "\\)\\>[ \t]+"))
     (5 . (concat "\\(^@\\)\\(" texinfo-subsubsection-level-regexp "\\)\\>[ \t]+")))
-  "*Regexps for searching for same level sections in a Texinfo file.
+  "Regexps for searching for same level sections in a Texinfo file.
 The keys are strings specifying the general hierarchical level in the
 document; the values are regular expressions.")
 
@@ -207,7 +231,7 @@ document; the values are regular expressions.")
       "\\|"
       texinfo-chapter-level-regexp
       "\\)\\>[ \t]*\\)")))
-  "*Regexps for searching for higher level sections in a Texinfo file.
+  "Regexps for searching for higher level sections in a Texinfo file.
 The keys are strings specifying the general hierarchical level in the
 document; the values are regular expressions.")
 
@@ -246,7 +270,7 @@ document; the values are regular expressions.")
       "\\)\\>[ \t]+\\)"))
     ;; There's nothing below 5, use a bogus regexp that can't match.
     (5 . "a\\(^\\)"))
-  "*Regexps for searching for lower level sections in a Texinfo file.
+  "Regexps for searching for lower level sections in a Texinfo file.
 The keys are strings specifying the general hierarchical level in the
 document; the values are regular expressions.")
 
@@ -331,8 +355,13 @@ at the level specified by LEVEL.  Point is left at the end of menu."
   "Update every regular menu in a Texinfo file.
 Update pre-existing master menu, if there is one.
 
+Only single-file manuals are supported by this function.  For
+multi-file manuals, use `texinfo-multiple-files-update'.
+
 If called with a non-nil argument, this function first updates all the
-nodes in the buffer before updating the menus.
+nodes in the buffer before updating the menus.  Do NOT invoke this
+command with an argument if your Texinfo file uses @node lines without
+the `Next', `Previous', and `Up' pointers!
 
 Indents the first line of descriptions, and leaves trailing whitespace
 in a menu that lacks descriptions, so descriptions will format well.
@@ -349,9 +378,7 @@ section titles are often too short to explain a node well."
        (when (search-forward texinfo-master-menu-header nil t)
          ;; Check if @detailmenu kludge is used;
          ;; if so, leave point before @detailmenu.
-         (search-backward "\n@detailmenu"
-                          (save-excursion (forward-line -3) (point))
-                          t)
+         (search-backward "\n@detailmenu" (line-beginning-position -2) t)
          ;; Remove detailed master menu listing
          (setq master-menu-p t)
          (goto-char (match-beginning 0))
@@ -627,9 +654,7 @@ Single argument, END-OF-MENU, is position limiting search."
        (point)
        (save-excursion
         (re-search-forward "\\(^\\* \\|^@ignore\\|^@end menu\\)" end-of-menu t)
-        (forward-line -1)
-        (end-of-line)                  ; go to end of last description line
-        (point)))
+        (line-end-position 0)))        ; end of last description line
     ""))
 
 (defun texinfo-menu-end ()
@@ -657,7 +682,7 @@ node within the section."
 
 ;; try 32, but perhaps 24 is better
 (defvar texinfo-column-for-description 32
-  "*Column at which descriptions start in a Texinfo menu.")
+  "Column at which descriptions start in a Texinfo menu.")
 
 (defun texinfo-insert-menu (menu-list node-name)
   "Insert formatted menu at point.
@@ -692,7 +717,7 @@ is the menu entry name, and the cdr of P is the node name."
        (insert (format "%s: %s." (car node-part) (cdr node-part)))))
 
     ;; Insert the description, if present.
-    (when (cdr menu)
+    (when (> (length (cdr menu)) 0)
       ;; Move to right place.
       (indent-to texinfo-column-for-description 2)
       ;; Insert description.
@@ -719,34 +744,32 @@ complements the node name rather than repeats it as a title does."
   (let (beginning end node-name title)
     (save-excursion
       (beginning-of-line)
-      (if (search-forward "* " (save-excursion (end-of-line) (point)) t)
+      (if (search-forward "* " (line-end-position) t)
          (progn (skip-chars-forward " \t")
                 (setq beginning (point)))
        (error "This is not a line in a menu"))
 
       (cond
        ;; "Double colon" entry line; menu entry and node name are the same,
-       ((search-forward "::" (save-excursion (end-of-line) (point)) t)
+       ((search-forward "::" (line-end-position) t)
        (if (looking-at "[ \t]*[^ \t\n]+")
            (error "Descriptive text already exists"))
        (skip-chars-backward ": \t")
        (setq node-name (buffer-substring beginning (point))))
 
        ;; "Single colon" entry line; menu entry and node name are different.
-       ((search-forward ":" (save-excursion (end-of-line) (point)) t)
+       ((search-forward ":" (line-end-position) t)
        (skip-chars-forward " \t")
        (setq beginning (point))
        ;; Menu entry line ends in a period, comma, or tab.
-       (if (re-search-forward "[.,\t]"
-                              (save-excursion (forward-line 1) (point)) t)
+       (if (re-search-forward "[.,\t]" (line-beginning-position 2) t)
            (progn
              (if (looking-at "[ \t]*[^ \t\n]+")
                  (error "Descriptive text already exists"))
              (skip-chars-backward "., \t")
              (setq node-name (buffer-substring beginning (point))))
          ;; Menu entry line ends in a return.
-         (re-search-forward ".*\n"
-                            (save-excursion (forward-line 1) (point)) t)
+         (re-search-forward ".*\n" (line-beginning-position 2) t)
          (skip-chars-backward " \t\n")
          (setq node-name (buffer-substring beginning (point)))
          (if (= 0 (length node-name))
@@ -850,20 +873,35 @@ second and subsequent lines of a multi-line description."
 
 (defun texinfo-master-menu (update-all-nodes-menus-p)
   "Make a master menu for a whole Texinfo file.
-Non-nil argument (prefix, if interactive) means first update all
-existing nodes and menus.  Remove pre-existing master menu, if there is one.
-
-This function creates a master menu that follows the top node.  The
-master menu includes every entry from all the other menus.  It
-replaces any existing ordinary menu that follows the top node.
-
-If called with a non-nil argument, this function first updates all the
-menus in the buffer (incorporating descriptions from pre-existing
-menus) before it constructs the master menu.
-
-The function removes the detailed part of an already existing master
-menu.  This action depends on the pre-existing master menu using the
-standard `texinfo-master-menu-header'.
+Remove pre-existing master menu, if there is one.
+
+This function supports only single-file manuals.  For multi-file
+manuals, use `texinfo-multiple-files-update'.
+
+This function creates or updates the @detailmenu section of a
+master menu that follows the Top node.  It replaces any existing
+detailed menu that follows the top node.  The detailed menu
+includes every entry from all the other menus.  By default, the
+existing menus, including the menu in the Top node, are not
+updated according to the buffer contents, so all the menus should
+be updated first using `texinfo-make-menu' or
+`texinfo-all-menus-update', which see.  Alternatively, invoke
+this function with a prefix argument, see below.
+
+Non-nil, non-numeric argument (C-u prefix, if interactive) means
+first update all existing menus in the buffer (incorporating
+descriptions from pre-existing menus) before it constructs the
+master menu.  If the argument is numeric (e.g., \"C-u 2\"),
+update all existing nodes as well, by calling
+\`texinfo-update-node' on the entire file.  Warning: do NOT
+invoke with a numeric argument if your Texinfo file uses @node
+lines without the `Next', `Previous', `Up' pointers, as the
+result could be an invalid Texinfo file!
+
+The function removes and recreates the detailed part of an already
+existing master menu.  This action assumes that the pre-existing
+master menu uses the standard `texinfo-master-menu-header' for the
+detailed menu.
 
 The master menu has the following format, which is adapted from the
 recommendation in the Texinfo Manual:
@@ -904,9 +942,7 @@ section titles are often too short to explain a node well."
          (progn
            ;; Check if @detailmenu kludge is used;
            ;; if so, leave point before @detailmenu.
-           (search-backward "\n@detailmenu"
-                            (save-excursion (forward-line -3) (point))
-                            t)
+           (search-backward "\n@detailmenu" (line-beginning-position -2) t)
            ;; Remove detailed master menu listing
            (goto-char (match-beginning 0))
            (let ((end-of-detailed-menu-descriptions
@@ -918,10 +954,11 @@ section titles are often too short to explain a node well."
 
     (if update-all-nodes-menus-p
        (progn
-         (message "Making a master menu in %s ...first updating all nodes... "
-                  (buffer-name))
-         (texinfo-update-node (point-min) (point-max))
-
+         (when (numberp update-all-nodes-menus-p)
+           (message
+            "Making a master menu in %s ...first updating all nodes... "
+            (buffer-name))
+           (texinfo-update-node (point-min) (point-max)))
          (message "Updating all menus in %s ... " (buffer-name))
          (texinfo-make-menu (point-min) (point-max))))
 
@@ -941,9 +978,7 @@ section titles are often too short to explain a node well."
            (goto-char (match-beginning 0))
            ;; Check if @detailmenu kludge is used;
            ;; if so, leave point before @detailmenu.
-           (search-backward "\n@detailmenu"
-                            (save-excursion (forward-line -3) (point))
-                            t)
+           (search-backward "\n@detailmenu" (line-beginning-position -2) t)
            (insert "\n")
            (delete-blank-lines)
            (goto-char (point-min))))
@@ -989,7 +1024,7 @@ However, there does not need to be a title field."
   (let ((first-chapter
         (save-excursion (re-search-forward "^@node\\|^@include") (point))))
     (unless (re-search-forward "^@menu" first-chapter t)
-      (error "Buffer lacks ordinary `Top' menu in which to insert master")))
+      (error "Buffer lacks a menu in its first node; create it, then run me again")))
   (beginning-of-line)
   (delete-region      ; buffer must have ordinary top menu
    (point)
@@ -1110,27 +1145,43 @@ For example, \"unnumberedsubsec\".  Return \"top\" for top node.
 Searches forward for a section.  Hence, point must be before the
 section whose type will be found.  Does not move point.  Signal an
 error if the node is not the top node and a section is not found."
-  (let ((case-fold-search t))
-    (save-excursion
-      (cond
-       ((re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)"
-                          ;; Following search limit by cph but causes a bug
-                          ;;(line-end-position)
-                          nil
-                          t)
-       "top")
-       ((re-search-forward texinfo-section-types-regexp nil t)
-       (buffer-substring-no-properties
-        (progn (beginning-of-line) ; copy its name
-               (1+ (point)))
-        (progn (forward-word 1)
-               (point))))
-       (t
-       (error
-        "texinfo-specific-section-type: Chapter or section not found"))))))
+  (let* ((case-fold-search t)
+        ;; The Texinfo manual has a second Top node inside @verbatim
+        ;; near the end, which dupes us into thinking we are at top
+        ;; level, no matter where we are when invoked.  We don't
+        ;; really grok @verbatim, so we cheat: only consider us to be
+        ;; at top level if the position of the Top node we found is
+        ;; before any other sectioning command.
+        (top-pos (save-excursion
+                   (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)"
+                                      ;; Following search limit causes a bug
+                                      ;;(line-end-position)
+                                      nil
+                                      t)))
+        (sec-pos (save-excursion
+                   (re-search-forward texinfo-section-types-regexp nil t)))
+        sec-name)
+    (if sec-pos
+       (save-excursion
+         (goto-char sec-pos)
+         (setq sec-name (buffer-substring-no-properties
+                         (progn (beginning-of-line) ; copy its name
+                                (1+ (point)))
+                         (progn (forward-word 1)
+                                (point))))))
+    (cond
+     ((or sec-pos top-pos)
+      (if (and top-pos sec-pos)
+         (if (< top-pos sec-pos)
+             "top"
+           sec-name)
+       (or sec-name "top")))
+     (t
+      (error
+       "texinfo-specific-section-type: Chapter or section not found")))))
 
 (defun texinfo-hierarchic-level ()
-  "Return the general hierarchal level of the next node in a texinfo file.
+  "Return the general hierarchical level of the next node in a texinfo file.
 Thus, a subheading or appendixsubsec is of type subsection."
   (let ((case-fold-search t))
     (cadr (assoc
@@ -1154,8 +1205,7 @@ Only argument is a string of the general type of section."
       (save-excursion
        (goto-char (point-min))
        (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t)
-       (beginning-of-line)
-       (point)))
+       (line-beginning-position)))
      (t
       (save-excursion
        (re-search-backward
@@ -1206,13 +1256,11 @@ The menu will be located just before this position.
 First argument is the position of the beginning of the section in
 which the menu will be located; second argument is the position of the
 end of that region; it limits the search."
-
   (save-excursion
     (goto-char beginning)
     (forward-line 1)
     (re-search-forward "^@node" end t)
-    (beginning-of-line)
-    (point)))
+    (line-beginning-position)))
 
 \f
 ;;; Updating a node
@@ -1221,6 +1269,11 @@ end of that region; it limits the search."
   "Without any prefix argument, update the node in which point is located.
 Interactively, a prefix argument means to operate on the region.
 
+Warning: do NOT use this function if your Texinfo file uses @node
+lines without the `Next', `Previous', `Up' pointers, because the
+result could be an invalid Texinfo file due to known deficiencies
+in this command: it does not support @ignore and @if* directives.
+
 The functions for creating or updating nodes and menus, and their
 keybindings, are:
 
@@ -1260,7 +1313,12 @@ which menu descriptions are indented. Its default value is 32."
          (message "Done...nodes updated in region.  You may save the buffer."))))))
 
 (defun texinfo-every-node-update ()
-  "Update every node in a Texinfo file."
+  "Update every node in a Texinfo file.
+
+Warning: do NOT use this function if your Texinfo file uses @node
+lines without the `Next', `Previous', `Up' pointers, because the
+result could be an invalid Texinfo file due to known deficiencies
+in this command: it does not support @ignore and @if* directives."
   (interactive)
   (save-excursion
     (texinfo-update-node (point-min) (point-max))
@@ -1331,7 +1389,7 @@ Point must be at beginning of node line.  Does not move point."
 Starts from the current position of the cursor, and searches forward
 on the line for a comma and if one is found, deletes the rest of the
 line, including the comma.  Leaves point at beginning of line."
-  (let ((eol-point (save-excursion (end-of-line) (point))))
+  (let ((eol-point (line-end-position)))
     (if (search-forward "," eol-point t)
        (delete-region (1- (point)) eol-point)))
   (beginning-of-line))
@@ -1437,8 +1495,7 @@ will be at some level higher in the Texinfo file.  The fourth argument
                 "\\)")
                (save-excursion
                  (goto-char beginning)
-                 (beginning-of-line)
-                 (point))
+                 (line-beginning-position))
                t)
               'normal
             'no-pointer))
@@ -1453,7 +1510,7 @@ The argument is the kind of section, either `normal' or `no-pointer'."
           (end-of-line)                ; this handles prev node top case
           (re-search-backward          ; when point is already
            "^@node"                    ; at the beginning of @node line
-           (save-excursion (forward-line -3))
+           (line-beginning-position -2)
            t)
           (setq name (texinfo-copy-node-name)))
          ((eq kind 'no-pointer)
@@ -1483,7 +1540,7 @@ towards which the pointer is directed, one of `next', `previous', or `up'."
   "Remove extra commas, if any, at end of node line."
   (end-of-line)
   (skip-chars-backward ", ")
-  (delete-region (point) (save-excursion (end-of-line) (point))))
+  (delete-region (point) (line-end-position)))
 
 \f
 ;;; Updating nodes sequentially
@@ -1647,13 +1704,14 @@ node names in pre-existing `@node' lines that lack names."
            (skip-chars-forward " \t")
            (setq title (buffer-substring
                         (point)
-                        (save-excursion (end-of-line) (point))))))
+                        (line-end-position)))))
       ;; Insert node line if necessary.
       (if (re-search-backward
           "^@node"
           ;; Avoid finding previous node line if node lines are close.
           (or last-section-position
-              (save-excursion (forward-line -2) (point))) t)
+              (line-beginning-position -1))
+          t)
          ;;  @node is present, and point at beginning of that line
          (forward-word 1)          ; Leave point just after @node.
        ;; Else @node missing; insert one.
@@ -1675,7 +1733,7 @@ node names in pre-existing `@node' lines that lack names."
                  (message "Inserted title %s ... " title)))))
       ;; Go forward beyond current section title.
       (re-search-forward texinfo-section-types-regexp
-                        (save-excursion (forward-line 3) (point)) t)
+                        (line-beginning-position 4) t)
       (setq last-section-position (point))
       (forward-line 1))
 
@@ -1948,7 +2006,11 @@ With optional UPDATE-EVERYTHING argument (numeric prefix arg, if
 interactive), update all the menus and all the `Next', `Previous', and
 `Up' pointers of all the files included in OUTER-FILE before inserting
 a master menu in OUTER-FILE.  Also, update the `Top' level node
-pointers of OUTER-FILE.
+pointers of OUTER-FILE.  Do NOT invoke this command with a numeric prefix
+arg, if your files use @node lines without the `Next', `Previous', `Up'
+pointers, because this could produce invalid Texinfo files due to known
+deficiencies in `texinfo-update-node': it does not support the @ignore
+and @if... directives.
 
 Notes:
 
@@ -1993,9 +2055,7 @@ chapter."
         (point-min)
         (save-excursion
           (re-search-forward "^@include")
-          (beginning-of-line)
-          (point)))
-
+          (line-beginning-position)))
        ;; If found, leave point after word `menu' on the `@menu' line.
        (progn
          (texinfo-incorporate-descriptions main-menu-list)
@@ -2021,9 +2081,7 @@ chapter."
                (goto-char (match-beginning 0))
                ;; Check if @detailmenu kludge is used;
                ;; if so, leave point before @detailmenu.
-               (search-backward "\n@detailmenu"
-                                (save-excursion (forward-line -3) (point))
-                                t)
+               (search-backward "\n@detailmenu" (line-beginning-position -2) t)
                ;; Remove detailed master menu listing
                (let ((end-of-detailed-menu-descriptions
                       (save-excursion  ; beginning of end menu line
@@ -2057,5 +2115,4 @@ chapter."
 ;; Place `provide' at end of file.
 (provide 'texnfo-upd)
 
-;; arch-tag: d21613a5-c32f-43f4-8af4-bfb1e7455842
 ;;; texnfo-upd.el ends here