Article View: gnu.emacs.bug
Article #100072informat.el
From: Hallvard B Furuseth
Date: Fri, 26 Jan 1990 11:20
Date: Fri, 26 Jan 1990 11:20
720 lines
26146 bytes
26146 bytes
Here is the informat.el to be used with info.el in my previous article.
Hallvard Furuseth
hallvard@ifi.uio.no
;; Info support functions package for Emacs
;; Copyright (C) 1986 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY. No author or distributor
;; accepts responsibility to anyone for the consequences of using it
;; or for whether it serves any particular purpose or works at all,
;; unless he says so in writing. Refer to the GNU Emacs General Public
;; License for full details.
;; Everyone is granted permission to copy, modify and redistribute
;; GNU Emacs, but only under the conditions described in the
;; GNU Emacs General Public License. A copy of this license is
;; supposed to have been given to you along with GNU Emacs so you
;; can know your rights and responsibilities. It should be in a
;; file named COPYING. Among other things, the copyright notice
;; and this notice must be preserved on all copies.
(require 'info)
(defvar Info-validate-ambiguous-menus "\\<Index$"
"Regexp matching node names which may contain ambiguous menu items.")
(defun Info-foreach-node (iFn-tolerance iFn-func)
;; Step through all nodes, accepting subfile-lengths TOLERANCE chars wrong
;; before correcting Info-subfiles, and call (FUNC nodename beg-of-node).
;; Returns a corrected copy of Info-subfiles.
;; Uses hopeless variable names to avoid name clashes.
(Info-find-tag-table)
(let* ((case-fold-search t)
(iFn-regexp "node:[ \t]*\\([^,\n\t]\\)*[,\t\n]")
(iFn-char-offset 0) iFn-start iFn-substart iFn-sflist
(Info-subfiles (if (consp Info-subfiles)
(copy-alist Info-subfiles)
Info-subfiles))
(iFn-subfiles Info-subfiles))
(while iFn-subfiles
(widen)
(or (cond ((atom iFn-subfiles)
(goto-char (point-min))
nil)
((assoc (car (car iFn-subfiles)) iFn-sflist))
(t
(setq iFn-sflist (cons (car (car iFn-subfiles))
iFn-sflist))
(Info-visit-subfile (car (car iFn-subfiles)))
(forward-char -1)
nil))
(progn
(setq iFn-substart (point))
(or iFn-start
(setq iFn-start iFn-substart))
(setq iFn-char-offset (+ iFn-char-offset
(- iFn-start iFn-substart)))
(if (consp iFn-subfiles)
(let ((realpos (+ (point) iFn-char-offset))
(subfpos (cdr (car iFn-subfiles))))
(if (and (<= subfpos realpos)
(<= realpos (+ subfpos iFn-tolerance)))
(setq iFn-char-offset (- subfpos (point)))
(setcdr (car iFn-subfiles) realpos))
(forward-char -1)))
(while (search-forward "\n\^_" nil 'move)
(forward-line 1)
(let ((iFn-beg (point)))
(forward-line 1)
(if (re-search-backward iFn-regexp iFn-beg 'move)
(funcall iFn-func
(buffer-substring (match-beginning 1)
(progn
(goto-char (match-end 1))
(skip-chars-backward " \t")
(point)))
(progn (goto-char iFn-beg)
(+ iFn-beg iFn-char-offset))))))
;; Back up over ^_ terminating the subfile
(re-search-backward "^\^_\f?\n*\\'" nil t)
(setq iFn-char-offset (+ iFn-char-offset
(- (point) iFn-start)))))
(setq iFn-subfiles (cdr-safe iFn-subfiles)))
Info-subfiles))
(defun Info-tagify ()
"Enter info-mode and create or update Info-file tag table in current buffer."
(interactive)
(info-mode t)
;; Save and restore node and position in Info file.
(let (list
(Info-next-hist (Info-next-hist)))
(unwind-protect
(let* ((subfiles (Info-foreach-node 0
(function (lambda (name beg)
(setq list (cons (list name beg)
list))))))
(marker Info-tag-table-marker))
(if list
(save-excursion
(if (marker-buffer marker)
(set-buffer (marker-buffer marker)))
(goto-char (point-max))
(forward-line -8)
(if (search-forward "\^_\nEnd tag table\n" nil 'move)
(progn
(search-backward "\nTag table:\n"
(save-excursion
(search-backward "\n\^_" nil nil 2)
(point)))
(beginning-of-line)))
(let ((buffer-read-only nil)
(del-pos (point)))
;; Protect the tag table (keep either new or old table).
;; Really, only the "(Indirect)" line *needs* protection.
(unwind-protect
(progn (or (bolp)
(insert ?\n))
(insert "\^_\f\nTag table:\n")
(if (consp subfiles)
(insert "(Indirect)\n"))
(set-marker marker (point))
(setq list (nreverse list))
(while list
(insert "Node: " (car (car list)) ?\177)
(princ (car (cdr (car list))) (current-buffer))
(insert ?\n)
(setq list (cdr list)))
(insert "\^_\nEnd tag table\n")
(setq del-pos (point-max)))
(delete-region (point) del-pos))
(if (consp subfiles)
(progn
(search-backward "\n\^_\nIndirect:")
(forward-line 3)
;; Insert corrected subfile list, which MUST be correct
;; Be sure to delete either the new or the old list.
(setq del-pos (point))
(unwind-protect
(progn (Info-insert-subfiles subfiles)
(save-excursion
(search-forward "\n\^_")
(setq del-pos (1- (point)))))
(delete-region (point) del-pos))))))
(message "No nodes in file; did not tagify."))
(setq Info-subfiles subfiles))
(Info-back))
(consp list)))
(defun Info-split ()
"Split an info file into an indirect file plus bounded-size subfiles.
Each subfile will be up to 50000 characters plus one node.
To use this command, first visit a large Info file that has a tag table.
The buffer is modified into a (small) indirect info file
which should be saved in place of the original visited file.
The subfiles are written in the same directory the original file is in,
with names generated by appending `-' and a number to the original file name.
The indirect file still functions as an Info file, but it contains
just the tag table and a directory of subfiles."
(interactive)
(if (< (buffer-size) 70000)
(error "This is too small to be worth splitting"))
(and Info-tag-table-marker
(not (eq (current-buffer) (marker-buffer Info-tag-table-marker)))
(error "This is already an indirect Info file"))
(widen)
(goto-char (point-min))
(search-forward "\^_")
(forward-char -1)
(let ((start (point))
(chars-deleted 0)
subfiles
(subfile-number 1)
(case-fold-search t)
(filename (file-name-sans-versions buffer-file-name)))
(goto-char (point-max))
(forward-line -8)
(setq buffer-read-only nil)
(or (search-forward "\^_\nEnd tag table\n" nil t)
(error "Tag table required; use M-x Info-tagify"))
(search-backward "\nTag table:\n")
(if (looking-at "\nTag table:\n\^_")
(error "Tag table is just a skeleton; use M-x Info-tagify"))
(if (looking-at "\nTag table:\n(Indirect)\n")
(error "This is already an indirect Info file"))
;; This buffer will no longer be used as the tag table's buffer.
(if Info-tag-table-marker
(Info-kill-tag-table))
(beginning-of-line)
(forward-char 1)
(save-restriction
(narrow-to-region (point-min) (point))
(goto-char (point-min))
(while (< (1+ (point)) (point-max))
(goto-char (min (+ (point) 50000) (point-max)))
(Info-node-end "\n\^_")
(setq subfiles (cons (cons (concat (file-name-nondirectory filename)
(format "-%d" subfile-number))
(+ start chars-deleted))
subfiles))
;; Include the final ^_ (WHY???), and
;; put a newline at end of split file, to make Unix happier.
(forward-char 1)
(insert "\n")
(write-region (point-min) (point)
(concat filename (format "-%d" subfile-number)))
(delete-region (1- (point)) (point))
;; Back up over the final ^_.
(forward-char -1)
(setq chars-deleted (+ chars-deleted
(- (point) start)))
(delete-region start (point))
(setq subfile-number (1+ subfile-number))))
(goto-char start)
(insert "\^_\nIndirect:\n")
(Info-insert-subfiles (nreverse subfiles))
(forward-char -1)
(search-forward "\nTag Table:\n")
(insert "(Indirect)\n")))
(defun Info-insert-subfiles (subfiles)
(while subfiles
(insert (car (car subfiles)) ": "
(int-to-string (cdr (car subfiles))) "\n")
(setq subfiles (cdr subfiles))))
(defun Info-node-end (&optional end-regexp)
(or end-regexp
(setq end-regexp "\n[\^_\f]"))
(while (cond ((not (re-search-forward end-regexp nil 'move))
nil)
((looking-at "[\n\^_\f]*execute: ")
(goto-char (match-end 0))
t)
(t
(beginning-of-line)
nil))))
(defun Info-file-basename (filename)
(Info-strip-filename (file-name-nondirectory filename)))
(defun Info-validate ()
"Enter info-mode and check current buffer for validity as an Info file.
Check that every node pointer points to an existing node."
(interactive)
(or (Info-validate-subfiles)
(error "Subfile list of %s is corrupted, you must correct it by hand."
(file-name-nondirectory
(or Info-current-file buffer-file-name))))
(info-mode t)
(let ((Info-next-hist (Info-next-hist)))
(unwind-protect
(let ((allnodes (list '("*")))
(case-fold-search t)
(tags-losing nil)
(lossages ())
subfiles)
(widen)
(setq subfiles
(Info-foreach-node 999
(function
(lambda (name beg)
(setq name (downcase name))
(if (string-match " " name)
(Info-validate-lossage
name "Warning: Adjacent spaces in node name" nil))
(if (assoc name allnodes)
(Info-validate-lossage name "Duplicate node name" nil)
(setq allnodes
(cons (list name
(let ((temp
(Info-extract-pointer
"prev[ious]*" t (point))))
(if temp
(downcase temp)))
beg)
allnodes)))))))
(Info-foreach-node 999
(function
(lambda (thisnode beg)
(setq thisnode (downcase thisnode))
(save-restriction
(narrow-to-region (point)
(progn
(re-search-forward "\n[\^_\f]" nil 'move)
(point)))
(goto-char (point-min))
(end-of-line)
(and (search-backward "next:" nil t)
(setq next (Info-validate-node-name "invalid Next"))
(assoc next allnodes)
(if (equal (car (cdr (assoc next allnodes)))
thisnode)
;; allow multiple `next' pointers to one node
(let ((tem lossages))
(while tem
(if (and (equal (car (cdr (car tem)))
"should have Previous")
(equal (car (car tem))
next))
(setq lossages (delq (car tem) lossages)))
(setq tem (cdr tem))))
(Info-validate-lossage next "should have Previous"
thisnode)))
(end-of-line)
(if (re-search-backward "prev[ious]*:" nil t)
(Info-validate-node-name "invalid Previous"))
(end-of-line)
(if (search-backward "up:" nil t)
(Info-validate-node-name "invalid Up"))
(if (search-forward "\n* Menu:" nil t)
(let ((no-sel (string-match
Info-validate-ambiguous-menus thisnode))
selections sel-item sel-node)
(while (re-search-forward "\n\\* " nil t)
(setq sel-item (buffer-substring
(point)
(save-excursion
(skip-chars-forward "^:")
(point)))
sel-node (Info-validate-node-name
(concat "invalid menu item " sel-item)
(Info-extract-menu-node-name)))
(or no-sel
(Info-validate-selection
sel-item sel-node "ambiguous menu item")))))
(goto-char (point-min))
(let (selections sel-item sel-node)
(while
(re-search-forward "\\*note[ \n\t]+\\([^:]*\\):" nil t)
(goto-char (match-beginning 1))
(setq sel-item (buffer-substring (point) (match-end 1))
sel-node (Info-reference-name
(Info-extract-menu-node-name
"Bad format cross-reference" "^.,\t")))
(Info-validate-selection
sel-item
(Info-validate-node-name
(concat "invalid reference " sel-item)
(substring sel-node
(if (= (aref sel-node 0) ?\ ) 1 0)
(if (string-match " \\'" sel-node) -1)))
"ambiguous reference")))))))
(setq tags-losing (not (and (equal subfiles Info-subfiles)
(Info-validate-tags-table))))
(if (or lossages tags-losing)
(save-excursion
(with-output-to-temp-buffer " *problems in info file*"
(setq lossages (nreverse lossages))
(while lossages
(princ "In node \"")
(princ (car (car lossages)))
(princ "\", ")
(let ((tem (nth 1 (car lossages))))
(cond ((string-match "\n" tem)
(princ (substring tem 0 (match-beginning 0)))
(princ "..."))
(t
(princ tem))))
(if (nth 2 (car lossages))
(progn
(princ ": ")
(let ((tem (nth 2 (car lossages))))
(cond ((string-match "\n" tem)
(princ (substring tem
0 (match-beginning 0)))
(princ "..."))
(t
(princ tem))))))
(terpri)
(setq lossages (cdr lossages)))
(if tags-losing
(princ "\nTags table must be recomputed\n"))))
;; Here if info file is valid.
;; If we already made a list of problems, clear it out.
(if (get-buffer " *problems in info file*")
(save-excursion;; avoid bug in kill-buffer (emacs-18.55)
(kill-buffer " *problems in info file*")))
(message "File appears valid")))
(Info-back))))
(defun Info-validate-node-name (kind &optional name)
(if name
nil
(goto-char (match-end 0))
(skip-chars-forward " \t")
(if (= (following-char) ?\()
nil
(setq name
(buffer-substring
(point)
(progn
(skip-chars-forward "^,\t\n")
(skip-chars-backward " ")
(point))))))
(if (null name)
nil
(setq name (downcase name))
(or (and (> (length name) 0) (= (aref name 0) ?\())
(assoc name allnodes)
(Info-validate-lossage thisnode kind name)))
name)
(defun Info-validate-selection (sel-item sel-node errmsg)
(setq sel-item (downcase sel-item))
(let ((sel-cons (assoc sel-item selections)))
(cond ((not sel-cons)
(setq selections (cons (cons sel-item sel-node)
selections)))
((not (equal sel-node (cdr sel-cons)))
(Info-validate-lossage thisnode errmsg sel-item)
(setcdr sel-cons nil)))))
(defun Info-validate-subfiles ()
;; This function is somewhat paranoid; most of it may be unnecessary.
(let (subfiles indirect)
(cond ((save-excursion
(and Info-tag-table-marker
(marker-buffer Info-tag-table-marker)
(set-buffer (marker-buffer Info-tag-table-marker)))
(goto-char (point-min))
(and (search-forward "\^_\nEnd tag table\n" nil t)
(progn (search-backward "\nTag table:\n")
(looking-at "\nTag table:\n(Indirect)\n"))
(progn
(setq indirect t)
(search-backward "\n\^_\nIndirect:")
(forward-line 3)
(while (looking-at "\\([^:\^_\f\n\t ]+\\): [0-9]+\n")
(goto-char (1+ (match-end 1)))
(setq subfiles
(cons (cons (buffer-substring (match-beginning 1)
(match-end 1))
(read (current-buffer)))
subfiles))
(or (file-readable-p (car (car subfiles)))
(error "Subfile %s not found" (car (car subfiles)))))
(not (looking-at "\^_")))))
nil)
((not indirect))
;; SUBFILES is now the reversed subfile list
((equal subfiles
(sort (copy-sequence subfiles)
(function (lambda (x y)
(> (cdr x) (cdr y))))))
;; If Info-subfiles is set, make sure it is correct.
(if Info-subfiles
(setq Info-subfiles (nreverse subfiles)))
t))))
(defun Info-validate-tags-table ()
(save-excursion
(let ((subposlist (nconc (if (consp Info-subfiles)
(mapcar 'cdr Info-subfiles))
(list (lsh -1 -1)))))
(if (marker-buffer Info-tag-table-marker)
(set-buffer (marker-buffer Info-tag-table-marker)))
(goto-char (point-min))
(not (if (search-forward "\^_\nEnd tag table\n" nil t)
(catch 'losing
(setq allnodes (nreverse allnodes))
(let* ((tagnodes ())
(allnodes (cdr allnodes)) ; Skip the "*".
tem)
(search-backward "\nTag table:\n")
(goto-char (match-end 0))
(if (looking-at "(Indirect)\n")
(goto-char (match-end 0)))
(while (looking-at ".*Node: \\(.*\\)\177\\([0-9]+\\)$")
(goto-char (match-beginning 2))
(setq tagnodes (cons (cons (downcase (buffer-substring
(match-beginning 1)
(match-end 1)))
(read (current-buffer)))
tagnodes)))
(forward-line 1)
(or (and (looking-at "End tag table\n")
(= (length allnodes) (length tagnodes)))
(throw 'losing 'z))
(setq tagnodes (sort tagnodes (function
(lambda (t1 t2)
(< (cdr t1) (cdr t2))))))
(while allnodes
(or (equal (car (car allnodes)) (car (car tagnodes)))
(throw 'losing 'x))
(setq tem (nth 2 (car allnodes)))
(while (<= (car subposlist) (cdr (car tagnodes)))
(or (<= (car subposlist) tem)
(throw 'losing 'w))
(setq subposlist (cdr subposlist)))
(if (<= (car subposlist) tem)
(throw 'losing 'w))
(setq tem (- tem (cdr (car tagnodes))))
(if (or (< tem -1000) (< 1000 tem))
(throw 'losing 'y))
(setq allnodes (cdr allnodes)
tagnodes (cdr tagnodes)))
nil)))))))
(defun Info-validate-lossage (&rest elt-list)
(setq lossages (cons elt-list lossages)))
(defun batch-info-validate ()
"Runs Info-validate on the files remaining on the command line.
Must be used only with -batch, and kills emacs on completion.
Each file will be processed even if an error occurred previously.
For example, invoke \"emacs -batch -f batch-info-validate $info/ ~/*.info\""
(if (not noninteractive)
(error "batch-info-validate may only be used -batch."))
(let ((version-control t)
(auto-save-default nil)
(find-file-run-dired nil)
(kept-old-versions 259259)
(kept-new-versions 259259)
;; Try to avoid autoloading non-.el files (such as autoloading
;; .../info/texinfo when encountering .../info/whatever.texinfo)
(auto-mode-alist (list '("" . info-mode))))
(let ((error 0)
file
(files ()) allfiles)
(while command-line-args-left
(setq file (expand-file-name (car command-line-args-left)))
(cond ((not (file-exists-p file))
(message ">> %s does not exist!" file)
(setq error 1
command-line-args-left (cdr command-line-args-left)))
((file-directory-p file)
(setq command-line-args-left
(nconc (delq nil
(mapcar (function
(lambda (f)
(if (or (auto-save-file-name-p f)
(backup-file-name-p f))
nil
f)))
(directory-files file t "^[^.]")))
(cdr command-line-args-left))))
(t
(setq files (cons file files)
command-line-args-left (cdr command-line-args-left)))))
(setq allfiles (mapcar 'list files))
(while files
(setq file (car files)
files (cdr files))
(if (and (string-match "-[0-9]+\\'" file)
(assoc (substring file 0 (match-beginning 0)) allfiles))
(princ (format " Skipping subfile %s\n" file))
(condition-case err
(let ((tagified nil)
(lose nil)
(loss-name " *problems in info file*"))
(if buffer-file-name (if Info-tag-table-marker
(Info-KILL)
(kill-buffer (current-buffer))))
(if (get-buffer loss-name)
(kill-buffer loss-name))
(find-file file)
(buffer-flush-undo (current-buffer))
(set-buffer-modified-p nil)
(info-mode)
(Info-find-tag-table)
(cond ((marker-position Info-tag-table-marker)
(message "%s already tagified" file))
((< (point-max) 30000)
(message "%s too small to bother tagifying" file))
(t
(message "Tagifying %s..." file)
(if (setq tagified (Info-tagify))
(message "Tagifying %s...done" file))))
(message "Checking validity of info file %s..." file)
(Info-validate)
(if (not (get-buffer loss-name))
nil ;(message "Checking validity of info file %s... OK" file)
(message "----------------------------------------------------------------------")
(message ">> PROBLEMS IN INFO FILE %s" file)
(save-excursion
(set-buffer loss-name)
(princ (buffer-string)))
(message "----------------------------------------------------------------------")
(setq error 1 lose t))
(and tagified (not lose)
(progn (message "Saving modified %s" file)
(Info-SAVE))))
(error (message ">> Error: %s" (prin1-to-string err))))
(terpri)))
(kill-emacs error))))
(defun Info-create-node (nodename)
"Create node NODENAME after current node (in current Info file)."
(let ((nodedesc (Info-newnode-desc nodename)))
;; Prepare to insert node
(widen)
(setq Info-current-node "*")
(if (save-excursion (goto-char (point-min))
(looking-at "\\s *\\'"))
;; Insert header if the file only contains whitespace
(progn (erase-buffer)
(insert "Info file: "
(file-name-nondirectory Info-current-file)
",\t-*-Info-*-\ncreated with Info-edit, "
(current-time-string) " edit by: " (user-login-name)))
;; Find end of current node in not-empty file
(end-of-line)
(if (re-search-backward "\n\^_.*\n.*Node:" nil 'move)
(forward-line 2))
(Info-node-end))
;; Insert node
(let ((beg (point)) pos)
(unwind-protect
(progn (or (bolp)
(insert ?\n))
(insert (if (looking-at "\^_?\f")
"\^_\f\n"
"\^_\n"))
(setq pos (point))
(insert "File: " (Info-file-basename Info-current-file)
", Node: " nodename)
(if nodedesc
;; Insert pointers
(let ((nodedesc (nthcdr 2 nodedesc))
(pointers '("Prev" "Up" "Next")))
(if (eq (car nodedesc) 'Info-up)
(setcar nodedesc (nth 1 nodedesc)))
(while nodedesc
(if (stringp (car nodedesc))
(insert ", " (car pointers) ": " (car nodedesc)))
(setq pointers (cdr pointers)
nodedesc (cdr nodedesc)))))
(insert ?\n)
(setq beg (point)))
;; Delete the node if it was not fully inserted.
(delete-region beg (point)))
(if (marker-position Info-tag-table-marker)
;; Update tag table.
(save-excursion
(if Info-current-subfile
;; Find the subfile
(let ((rest-subfiles Info-subfiles))
(while (and rest-subfiles
(not (string-equal Info-current-subfile
(car (car rest-subfiles)))))
(setq rest-subfiles (cdr rest-subfiles)))
(setq pos (+ pos (- (cdr (car rest-subfiles))
(progn (goto-char (point-min))
(search-forward "\n\^_")
(point)))))
(and (setq rest-subfiles (cdr rest-subfiles))
(>= pos (car rest-subfiles))
(setq pos (1- (car rest-subfiles))))))
(set-buffer (marker-buffer Info-tag-table-marker))
(goto-char (point-max))
;; Put new tag in front, to override any old tags.
(re-search-backward "\nTag table:\n\\((Indirect)\n\\)?")
(goto-char (match-end 0))
(insert (format "Node: %s\^?%d\n" nodename pos))))
nodename)))
;; Use Info-node-desc to suggest (File Node Prev Up Next) for nodename.
(defun Info-newnode-desc (nodename)
(if Info-node-desc
(let* ((nodedesc Info-node-desc)
(lastfile (car nodedesc))
(nodefile Info-current-file)
d-lastfile d-nodefile
(d-nodename (downcase nodename)))
;; I don't want a partly modified Info-node-desc
(setq Info-node-desc nil)
;; Make nodenames of nodedesc relative to new file instead of old file.
(if lastfile (setq lastfile (Info-file-basename lastfile)
d-lastfile (downcase lastfile)))
(if nodefile (setq nodefile (Info-file-basename nodefile)
d-nodefile (downcase nodefile)))
(if (equal d-lastfile d-nodefile)
(setq lastfile nil d-lastfile nil))
(setcdr nodedesc
(mapcar
(function
(lambda (node)
(if (symbolp node)
node
(setq node (Info-split-node-name node lastfile ""))
(and (car node)
(equal d-nodefile
(downcase (Info-file-basename (car node))))
(setcar node nil))
(if (car node)
(concat "(" (car node) ")" (nth 1 node))
(nth 1 node)))))
(cdr nodedesc)))
;; If correct nodename and Up != nodename, return nodedesc.
(and (equal d-nodename (and (nth 1 nodedesc)
(downcase (nth 1 nodedesc))))
(not (equal d-nodename (and (nth 3 nodedesc)
(downcase (nth 3 nodedesc)))))
(let ((list nodedesc))
;; If Next or Prev == nodename, or other file, remove that ptr.
(while (setq list (nthcdr 2 list))
(and (stringp (car list))
(or (= (aref (car list) 0) ?\()
(string-equal d-nodename (downcase (car list))))
(setcar list nil)))
nodedesc)))))
;;; Local Variables: ***
;;; eval:(put 'Info-foreach-node 'lisp-indent-hook 1) ***
;;; End: ***
Technical Details
Message-ID:
<9001261120.AA00691@nikud.uio.no>Path:
arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!zephyr.ens.tek.com!uw-beaver!mit-eddie!snorkelwacker!tut.cis.ohio-state.edu!IFI.UIO.NO!hallvardShow Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fb2f1,c64c55822126b740,start X-Google-Attributes: gidfb2f1,public X-Google-ArrivalTime: 1990-01-26 03:20:53 PST Path: arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!zephyr.ens.tek.com!uw-beaver!mit-eddie!snorkelwacker!tut.cis.ohio-state.edu!IFI.UIO.NO!hallvard From: hallvard@IFI.UIO.NO (Hallvard B Furuseth) Newsgroups: gnu.emacs.bug Subject: informat.el Message-ID: <9001261120.AA00691@nikud.uio.no> Date: 26 Jan 90 11:20:53 GMT Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 720 Posted: Fri Jan 26 12:20:53 1990