Annotation of GNUtools/emacs/lisp/informat.el, revision 1.1

1.1     ! root        1: ;; Info support functions package for Emacs
        !             2: ;; Copyright (C) 1986 Free Software Foundation, Inc.
        !             3: 
        !             4: ;; This file is part of GNU Emacs.
        !             5: 
        !             6: ;; GNU Emacs is free software; you can redistribute it and/or modify
        !             7: ;; it under the terms of the GNU General Public License as published by
        !             8: ;; the Free Software Foundation; either version 1, or (at your option)
        !             9: ;; any later version.
        !            10: 
        !            11: ;; GNU Emacs is distributed in the hope that it will be useful,
        !            12: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: ;; GNU General Public License for more details.
        !            15: 
        !            16: ;; You should have received a copy of the GNU General Public License
        !            17: ;; along with GNU Emacs; see the file COPYING.  If not, write to
        !            18: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
        !            19: 
        !            20: (require 'info)
        !            21: 
        !            22: (defun Info-tagify ()
        !            23:   "Create or update Info-file tag table in current buffer."
        !            24:   (interactive)
        !            25:   ;; Save and restore point and restrictions.
        !            26:   ;; save-restrictions would not work
        !            27:   ;; because it records the old max relative to the end.
        !            28:   ;; We record it relative to the beginning.
        !            29:   (let ((omin (point-min))
        !            30:        (omax (point-max))
        !            31:        (nomax (= (point-max) (1+ (buffer-size))))
        !            32:        (opoint (point)))
        !            33:     (unwind-protect
        !            34:        (progn
        !            35:          (widen)
        !            36:          (goto-char (point-min))
        !            37:          (if (search-forward "\^_\nIndirect:\n" nil t)
        !            38:              (message "Cannot tagify split info file")
        !            39:            (let ((regexp "Node:[ \t]*\\([^,\n\t]\\)*[,\t\n]")
        !            40:                  (case-fold-search t)
        !            41:                  list)
        !            42:              (while (search-forward "\n\^_" nil t)
        !            43:                (forward-line 1)
        !            44:                (let ((beg (point)))
        !            45:                  (forward-line 1)
        !            46:                  (if (re-search-backward regexp beg t)
        !            47:                      (setq list
        !            48:                            (cons (list (buffer-substring
        !            49:                                          (match-beginning 1)
        !            50:                                          (match-end 1))
        !            51:                                        beg)
        !            52:                                  list)))))
        !            53:              (goto-char (point-max))
        !            54:              (forward-line -8)
        !            55:              (let ((buffer-read-only nil))
        !            56:                (if (search-forward "\^_\nEnd tag table\n" nil t)
        !            57:                    (let ((end (point)))
        !            58:                      (search-backward "\nTag table:\n")
        !            59:                      (beginning-of-line)
        !            60:                      (delete-region (point) end)))
        !            61:                (goto-char (point-max))
        !            62:                (insert "\^_\f\nTag table:\n")
        !            63:                (move-marker Info-tag-table-marker (point))
        !            64:                (setq list (nreverse list))
        !            65:                (while list
        !            66:                  (insert "Node: " (car (car list)) ?\177)
        !            67:                  (princ (car (cdr (car list))) (current-buffer))
        !            68:                  (insert ?\n)
        !            69:                  (setq list (cdr list)))
        !            70:                (insert "\^_\nEnd tag table\n")))))
        !            71:       (goto-char opoint)
        !            72:       (narrow-to-region omin (if nomax (1+ (buffer-size))
        !            73:                               (min omax (point-max)))))))
        !            74: 
        !            75: (defun Info-split ()
        !            76:   "Split an info file into an indirect file plus bounded-size subfiles.
        !            77: Each subfile will be up to 50000 characters plus one node.
        !            78: 
        !            79: To use this command, first visit a large Info file that has a tag table.
        !            80: The buffer is modified into a (small) indirect info file
        !            81: which should be saved in place of the original visited file.
        !            82: 
        !            83: The subfiles are written in the same directory the original file is in,
        !            84: with names generated by appending `-' and a number to the original file name.
        !            85: 
        !            86: The indirect file still functions as an Info file, but it contains
        !            87: just the tag table and a directory of subfiles."
        !            88:   (interactive)
        !            89:   (if (< (buffer-size) 70000)
        !            90:       (error "This is too small to be worth splitting"))
        !            91:   (goto-char (point-min))
        !            92:   (search-forward "\^_")
        !            93:   (forward-char -1)
        !            94:   (let ((start (point))
        !            95:        (chars-deleted 0)
        !            96:        subfiles
        !            97:        (subfile-number 1)
        !            98:        (case-fold-search t)
        !            99:        (filename (file-name-sans-versions buffer-file-name)))
        !           100:     (goto-char (point-max))
        !           101:     (forward-line -8)
        !           102:     (setq buffer-read-only nil)
        !           103:     (or (search-forward "\^_\nEnd tag table\n" nil t)
        !           104:        (error "Tag table required; use M-x Info-tagify"))
        !           105:     (search-backward "\nTag table:\n")
        !           106:     (if (looking-at "\nTag table:\n\^_")
        !           107:        (error "Tag table is just a skeleton; use M-x Info-tagify"))
        !           108:     (beginning-of-line)
        !           109:     (forward-char 1)
        !           110:     (save-restriction
        !           111:       (narrow-to-region (point-min) (point))
        !           112:       (goto-char (point-min))
        !           113:       (while (< (1+ (point)) (point-max))
        !           114:        (goto-char (min (+ (point) 50000) (point-max)))
        !           115:        (search-forward "\^_" nil 'move)
        !           116:        (setq subfiles
        !           117:              (cons (list (+ start chars-deleted)
        !           118:                          (concat (file-name-nondirectory filename)
        !           119:                                  (format "-%d" subfile-number)))
        !           120:                    subfiles))
        !           121:        ;; Put a newline at end of split file, to make Unix happier.
        !           122:        (insert "\n")
        !           123:        (write-region (point-min) (point)
        !           124:                      (concat filename (format "-%d" subfile-number)))
        !           125:        (delete-region (1- (point)) (point))
        !           126:        ;; Back up over the final ^_.
        !           127:        (forward-char -1)
        !           128:        (setq chars-deleted (+ chars-deleted (- (point) start)))
        !           129:        (delete-region start (point))
        !           130:        (setq subfile-number (1+ subfile-number))))
        !           131:     (while subfiles
        !           132:       (goto-char start)
        !           133:       (insert (nth 1 (car subfiles))
        !           134:              (format ": %d" (car (car subfiles)))
        !           135:              "\n")
        !           136:       (setq subfiles (cdr subfiles)))
        !           137:     (goto-char start)
        !           138:     (insert "\^_\nIndirect:\n")
        !           139:     (search-forward "\nTag Table:\n")
        !           140:     (insert "(Indirect)\n")))
        !           141: 
        !           142: (defun Info-validate ()
        !           143:   "Check current buffer for validity as an Info file.
        !           144: Check that every node pointer points to an existing node."
        !           145:   (interactive)
        !           146:   (save-excursion
        !           147:     (save-restriction
        !           148:       (widen)
        !           149:       (goto-char (point-min))
        !           150:       (if (search-forward "\nTag table:\n(Indirect)\n" nil t)
        !           151:          (error "Don't yet know how to validate indirect info files: \"%s\""
        !           152:                 (buffer-name (current-buffer))))
        !           153:       (goto-char (point-min))
        !           154:       (let ((allnodes '(("*")))
        !           155:            (regexp "Node:[ \t]*\\([^,\n\t]*\\)[,\t\n]")
        !           156:            (case-fold-search t)
        !           157:            (tags-losing nil)
        !           158:            (lossages ()))
        !           159:        (while (search-forward "\n\^_" nil t)
        !           160:          (forward-line 1)
        !           161:          (let ((beg (point)))
        !           162:            (forward-line 1)
        !           163:            (if (re-search-backward regexp beg t)
        !           164:                (let ((name (downcase
        !           165:                              (buffer-substring
        !           166:                                (match-beginning 1)
        !           167:                                (progn
        !           168:                                  (goto-char (match-end 1))
        !           169:                                  (skip-chars-backward " \t")
        !           170:                                  (point))))))
        !           171:                  (if (assoc name allnodes)
        !           172:                      (setq lossages
        !           173:                            (cons (list name "Duplicate node-name" nil)
        !           174:                                  lossages))
        !           175:                      (setq allnodes
        !           176:                            (cons (list name
        !           177:                                        (progn
        !           178:                                          (end-of-line)
        !           179:                                          (and (re-search-backward
        !           180:                                                "prev[ious]*:" beg t)
        !           181:                                               (progn
        !           182:                                                 (goto-char (match-end 0))
        !           183:                                                 (downcase
        !           184:                                                   (Info-following-node-name)))))
        !           185:                                        beg)
        !           186:                                  allnodes)))))))
        !           187:        (goto-char (point-min))
        !           188:        (while (search-forward "\n\^_" nil t)
        !           189:          (forward-line 1)
        !           190:          (let ((beg (point))
        !           191:                thisnode next)
        !           192:            (forward-line 1)
        !           193:            (if (re-search-backward regexp beg t)
        !           194:                (save-restriction
        !           195:                  (search-forward "\n\^_" nil 'move)
        !           196:                  (narrow-to-region beg (point))
        !           197:                  (setq thisnode (downcase
        !           198:                                   (buffer-substring
        !           199:                                     (match-beginning 1)
        !           200:                                     (progn
        !           201:                                       (goto-char (match-end 1))
        !           202:                                       (skip-chars-backward " \t")
        !           203:                                       (point)))))
        !           204:                  (end-of-line)
        !           205:                  (and (search-backward "next:" nil t)
        !           206:                       (setq next (Info-validate-node-name "invalid Next"))
        !           207:                       (assoc next allnodes)
        !           208:                       (if (equal (car (cdr (assoc next allnodes)))
        !           209:                                  thisnode)
        !           210:                           ;; allow multiple `next' pointers to one node
        !           211:                           (let ((tem lossages))
        !           212:                             (while tem
        !           213:                               (if (and (equal (car (cdr (car tem)))
        !           214:                                               "should have Previous")
        !           215:                                        (equal (car (car tem))
        !           216:                                               next))
        !           217:                                   (setq lossages (delq (car tem) lossages)))
        !           218:                               (setq tem (cdr tem))))
        !           219:                         (setq lossages
        !           220:                               (cons (list next
        !           221:                                           "should have Previous"
        !           222:                                           thisnode)
        !           223:                                     lossages))))
        !           224:                  (end-of-line)
        !           225:                  (if (re-search-backward "prev[ious]*:" nil t)
        !           226:                      (Info-validate-node-name "invalid Previous"))
        !           227:                  (end-of-line)
        !           228:                  (if (search-backward "up:" nil t)
        !           229:                      (Info-validate-node-name "invalid Up"))
        !           230:                  (if (re-search-forward "\n* Menu:" nil t)
        !           231:                      (while (re-search-forward "\n\\* " nil t)
        !           232:                        (Info-validate-node-name
        !           233:                          (concat "invalid menu item "
        !           234:                                  (buffer-substring (point)
        !           235:                                                    (save-excursion
        !           236:                                                      (skip-chars-forward "^:")
        !           237:                                                      (point))))
        !           238:                          (Info-extract-menu-node-name))))
        !           239:                  (goto-char (point-min))
        !           240:                  (while (re-search-forward "\\*note[ \n]*[^:\t]*:" nil t)
        !           241:                    (goto-char (+ (match-beginning 0) 5))
        !           242:                    (skip-chars-forward " \n")
        !           243:                    (Info-validate-node-name
        !           244:                     (concat "invalid reference "
        !           245:                             (buffer-substring (point)
        !           246:                                               (save-excursion
        !           247:                                                 (skip-chars-forward "^:")
        !           248:                                                 (point))))
        !           249:                     (Info-extract-menu-node-name "Bad format cross-reference")))))))
        !           250:        (setq tags-losing (not (Info-validate-tags-table)))
        !           251:        (if (or lossages tags-losing)
        !           252:            (with-output-to-temp-buffer " *problems in info file*"
        !           253:              (while lossages
        !           254:                (princ "In node \"")
        !           255:                (princ (car (car lossages)))
        !           256:                (princ "\", ")
        !           257:                (let ((tem (nth 1 (car lossages))))
        !           258:                  (cond ((string-match "\n" tem)
        !           259:                         (princ (substring tem 0 (match-beginning 0)))
        !           260:                         (princ "..."))
        !           261:                        (t
        !           262:                         (princ tem))))
        !           263:                (if (nth 2 (car lossages))
        !           264:                    (progn
        !           265:                      (princ ": ")
        !           266:                      (let ((tem (nth 2 (car lossages))))
        !           267:                        (cond ((string-match "\n" tem)
        !           268:                               (princ (substring tem 0 (match-beginning 0)))
        !           269:                               (princ "..."))
        !           270:                              (t
        !           271:                               (princ tem))))))
        !           272:                (terpri)
        !           273:                (setq lossages (cdr lossages)))
        !           274:              (if tags-losing (princ "\nTags table must be recomputed\n")))
        !           275:          ;; Here if info file is valid.
        !           276:          ;; If we already made a list of problems, clear it out.
        !           277:          (save-excursion
        !           278:            (if (get-buffer " *problems in info file*")
        !           279:                (progn
        !           280:                  (set-buffer " *problems in info file*")
        !           281:                  (kill-buffer (current-buffer)))))
        !           282:          (message "File appears valid"))))))
        !           283: 
        !           284: (defun Info-validate-node-name (kind &optional name)
        !           285:   (if name
        !           286:       nil
        !           287:     (goto-char (match-end 0))
        !           288:     (skip-chars-forward " \t")
        !           289:     (if (= (following-char) ?\()
        !           290:        nil
        !           291:       (setq name
        !           292:            (buffer-substring
        !           293:             (point)
        !           294:             (progn
        !           295:              (skip-chars-forward "^,\t\n")
        !           296:              (skip-chars-backward " ")
        !           297:              (point))))))
        !           298:   (if (null name)
        !           299:       nil
        !           300:     (setq name (downcase name))
        !           301:     (or (and (> (length name) 0) (= (aref name 0) ?\())
        !           302:        (assoc name allnodes)
        !           303:        (setq lossages
        !           304:              (cons (list thisnode kind name) lossages))))
        !           305:   name)
        !           306: 
        !           307: (defun Info-validate-tags-table ()
        !           308:   (goto-char (point-min))
        !           309:   (if (not (search-forward "\^_\nEnd tag table\n" nil t))
        !           310:       t
        !           311:     (not (catch 'losing
        !           312:           (let* ((end (match-beginning 0))
        !           313:                  (start (progn (search-backward "\nTag table:\n")
        !           314:                                (1- (match-end 0))))
        !           315:                  tem)
        !           316:             (setq tem allnodes)
        !           317:             (while tem
        !           318:               (goto-char start)
        !           319:               (or (equal (car (car tem)) "*")
        !           320:                   (search-forward (concat "Node: "
        !           321:                                           (car (car tem))
        !           322:                                           "\177")
        !           323:                                   end t)
        !           324:                   (throw 'losing 'x))
        !           325:               (setq tem (cdr tem)))
        !           326:             (goto-char (1+ start))
        !           327:             (while (looking-at ".*Node: \\(.*\\)\177\\([0-9]+\\)$")
        !           328:               (setq tem (downcase (buffer-substring
        !           329:                                     (match-beginning 1)
        !           330:                                     (match-end 1))))
        !           331:               (setq tem (assoc tem allnodes))
        !           332:               (if (or (not tem)
        !           333:                       (< 1000 (progn
        !           334:                                 (goto-char (match-beginning 2))
        !           335:                                 (setq tem (- (car (cdr (cdr tem)))
        !           336:                                              (read (current-buffer))))
        !           337:                                 (if (> tem 0) tem (- tem)))))
        !           338:                   (throw 'losing 'y)))
        !           339:             (forward-line 1))
        !           340:           (or (looking-at "End tag table\n")
        !           341:               (throw 'losing 'z))
        !           342:           nil))))
        !           343: 
        !           344: (defun batch-info-validate ()
        !           345:   "Runs  Info-validate  on the files remaining on the command line.
        !           346: Must be used only with -batch, and kills emacs on completion.
        !           347: Each file will be processed even if an error occurred previously.
        !           348: For example, invoke \"emacs -batch -f batch-info-validate $info/ ~/*.info\""
        !           349:   (if (not noninteractive)
        !           350:       (error "batch-info-validate may only be used -batch."))
        !           351:   (let ((version-control t)
        !           352:        (auto-save-default nil)
        !           353:        (find-file-run-dired nil)
        !           354:        (kept-old-versions 259259)
        !           355:        (kept-new-versions 259259))
        !           356:     (let ((error 0)
        !           357:          file
        !           358:          (files ()))
        !           359:       (while command-line-args-left
        !           360:        (setq file (expand-file-name (car command-line-args-left)))
        !           361:        (cond ((not (file-exists-p file))
        !           362:               (message ">> %s does not exist!" file)
        !           363:               (setq error 1
        !           364:                     command-line-args-left (cdr command-line-args-left))) 
        !           365:              ((file-directory-p file)
        !           366:               (setq command-line-args-left (nconc (directory-files file)
        !           367:                                              (cdr command-line-args-left))))
        !           368:              (t
        !           369:               (setq files (cons file files)
        !           370:                     command-line-args-left (cdr command-line-args-left)))))
        !           371:       (while files
        !           372:        (setq file (car files)
        !           373:              files (cdr files))
        !           374:        (let ((lose nil))
        !           375:          (condition-case err
        !           376:              (progn
        !           377:                (if buffer-file-name (kill-buffer (current-buffer)))
        !           378:                (find-file file)
        !           379:                (buffer-flush-undo (current-buffer))
        !           380:                (set-buffer-modified-p nil)
        !           381:                (fundamental-mode)
        !           382:                (let ((case-fold-search nil))
        !           383:                  (goto-char (point-max))
        !           384:                  (cond ((search-backward "\n\^_\^L\nTag table:\n" nil t)
        !           385:                         (message "%s already tagified" file))
        !           386:                        ((< (point-max) 30000)
        !           387:                         (message "%s too small to bother tagifying" file))
        !           388:                        (t
        !           389:                         (message "Tagifying %s..." file)
        !           390:                         (Info-tagify)
        !           391:                         (message "Tagifying %s...done" file))))
        !           392:                (let ((loss-name " *problems in info file*"))
        !           393:                  (message "Checking validity of info file %s..." file)
        !           394:                  (if (get-buffer loss-name)
        !           395:                      (kill-buffer loss-name))
        !           396:                  (Info-validate)
        !           397:                  (if (not (get-buffer loss-name))
        !           398:                      nil ;(message "Checking validity of info file %s... OK" file)
        !           399:                    (message "----------------------------------------------------------------------")
        !           400:                    (message ">> PROBLEMS IN INFO FILE %s" file)
        !           401:                    (save-excursion
        !           402:                      (set-buffer loss-name)
        !           403:                      (princ (buffer-substring (point-min) (point-max))))
        !           404:                    (message "----------------------------------------------------------------------")
        !           405:                    (setq error 1 lose t)))
        !           406:                (if (and (buffer-modified-p)
        !           407:                         (not lose))
        !           408:                    (progn (message "Saving modified %s" file)
        !           409:                           (save-buffer))))
        !           410:            (error (message ">> Error: %s" (prin1-to-string err))))))
        !           411:       (kill-emacs error))))

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.