diff options
author | Marc Espie <espie@cvs.openbsd.org> | 1999-01-11 16:47:46 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 1999-01-11 16:47:46 +0000 |
commit | ea1b3cac0d2dc5e4e744131301e8c1b114bff412 (patch) | |
tree | 622e18348a1c52a0bcfd25e3e26c0cf5608fcdcb /gnu | |
parent | 2ef2bfcba8bee0f75f48338554ad5a393e70104e (diff) |
As of 3.12, emacs files are no longer shipped with texinfo.
Refer to the emacs distribution for up-to-date versions of those.
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/usr.bin/texinfo/emacs/Makefile.am | 21 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/emacs/Makefile.in | 94 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/emacs/README | 17 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/emacs/elisp-comp | 5 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/emacs/info.el | 1702 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/emacs/informat.el | 425 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/emacs/makeinfo.el | 245 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/emacs/new-useful-setqs | 180 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/emacs/texinfmt.el | 3067 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/emacs/texinfo.el | 757 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/emacs/texnfo-upd.el | 2046 |
11 files changed, 0 insertions, 8559 deletions
diff --git a/gnu/usr.bin/texinfo/emacs/Makefile.am b/gnu/usr.bin/texinfo/emacs/Makefile.am deleted file mode 100644 index 5907f0874f4..00000000000 --- a/gnu/usr.bin/texinfo/emacs/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -## Makefile.am for texinfo/emacs. -## $Id: Makefile.am,v 1.1 1997/08/01 21:59:44 kstailey Exp $ -## Run automake in .. to produce Makefile.in from this. - -# Do not byte compile our Elisp files by default. -ELCFILES = - -# Do not install our Elisp files by default, either. -noinst_LISP = info.el informat.el makeinfo.el \ - texinfmt.el texinfo.el texnfo-upd.el - -EXTRA_DIST = README elisp-comp new-useful-setqs $(noinst_LISP) - -install-data-local: - @echo "WARNING: You must (compile and) install the Emacs Lisp files" - @echo "WARNING: manually. See ./emacs/README for some considerations." - -# For some reason these do not get defined. -distclean-lisp: -clean-lisp: -mostlyclean-lisp: diff --git a/gnu/usr.bin/texinfo/emacs/Makefile.in b/gnu/usr.bin/texinfo/emacs/Makefile.in deleted file mode 100644 index 045b8bc0698..00000000000 --- a/gnu/usr.bin/texinfo/emacs/Makefile.in +++ /dev/null @@ -1,94 +0,0 @@ -# Makefile for Texinfo/emacs. -*- Indented-Text -*- -# Copyright (C) 1995 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -# Author: Brian J. Fox (bfox@ai.mit.edu) -# -#### Start of system configuration section. #### - -RM = rm -f -CP = cp - -srcdir = @srcdir@ -VPATH = $(srcdir) -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = $(exec_prefix)/bin -# Prefix for each installed program, normally empty or `g'. -binprefix = -libdir = $(prefix)/lib -# Prefix for each installed man page, normally empty or `g'. -manprefix = -mandir = $(prefix)/man/man1 -manext = 1 -infodir = $(prefix)/info -lispdir = $(libdir)/emacs/site-lisp - -#### End of system configuration section. #### - -ELISP_SRCS = info.el makeinfo.el texinfo.el texnfo-upd.el \ - texnfo-tex.el texinfmt.el informat.el detexinfo.el -ELISP_OBJS = info.elc makeinfo.elc texinfo.elc texnfo-upd.elc \ - texnfo-tex.elc texinfmt.elc informat.elc detexinfo.elc - -.SUFFIXES: .el .elc - -.el.elc: - $(srcdir)/elisp-comp $< - -all: $(ELISP_OBJS) -sub-all: all - -# install: $(ELISP_OBJS) -# @(echo "(print (car load-path))" >/tmp/elc.$$$$; \ -# lispdir=`emacs -batch -q -l /tmp/elc.$$$$ -nw | grep site-lisp`; \ -# rm /tmp/elc.$$$$; \ -# if [ "$$lispdir" != "" ]; then \ -# lispdir=`echo $$lispdir | sed -e 's/"//g'`; \ -# echo "Installing .elc files in $$lispdir."; \ -# $(CP) $(ELISP_OBJS) $$lispdir; \ -# else \ -# echo "To install the elisp files, please copy *.elc to the"; \ -# echo "emacs site-lisp directory."; \ -# fi) - -install: $(ELISP_OBJS) - for file in $(ELISP_OBJS); do \ - $(INSTALL_DATA) $$file $(lispdir); \ - done - -uninstall: $(ELISP_OBJS) - cd $(lispdir) && rm -f $(ELISP_OBJS) - -informat.elc: info.elc -makeinfo.elc: texinfo.elc -texinfmt.elc: texinfo.elc -texinfmt.elc: texnfo-upd.elc - -Makefile: $(srcdir)/Makefile.in ../config.status - cd ..; sh config.status - -realclean distclean: clean - $(RM) -f Makefile *.log - -clean: FORCE - $(RM) -f *.elc - -FORCE: - diff --git a/gnu/usr.bin/texinfo/emacs/README b/gnu/usr.bin/texinfo/emacs/README deleted file mode 100644 index 23053166c3f..00000000000 --- a/gnu/usr.bin/texinfo/emacs/README +++ /dev/null @@ -1,17 +0,0 @@ -This directory contains Emacs Lisp sources related to Texinfo. - -M-x texinfo-format-buffer is no longer the standard way to make .info -files, and may or may not work. Use makeinfo instead. See the -`makeinfo advantages' in the manual for why. - -The files here may or may not be newer than the versions in the latest -Emacs distribution -- there is only one master source, so it simply -depends on what was released later. Use whatever works better for you. - -They are not compiled or installed by default, because of the above, and -also due to the wide variations in sites' Emacs installations. - -Even if you do install them, you may not want to compile them if your -site is running multiple versions of Emacs, since .elc files are not -portable between all Emacs releases. If you do want to compile them, -just run the ./elisp-comp shell script. diff --git a/gnu/usr.bin/texinfo/emacs/elisp-comp b/gnu/usr.bin/texinfo/emacs/elisp-comp deleted file mode 100644 index 8f27d7bde8f..00000000000 --- a/gnu/usr.bin/texinfo/emacs/elisp-comp +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -setpath=/tmp/elc.$$ -echo "(setq load-path (cons nil load-path))" > $setpath -emacs -batch -l $setpath -f batch-byte-compile $* -rm -f $setpath diff --git a/gnu/usr.bin/texinfo/emacs/info.el b/gnu/usr.bin/texinfo/emacs/info.el deleted file mode 100644 index 46c53a86ed8..00000000000 --- a/gnu/usr.bin/texinfo/emacs/info.el +++ /dev/null @@ -1,1702 +0,0 @@ -;;; info.el --- info package for Emacs. - -;; Copyright (C) 1985, 1986, 1992, 1993, 1994 Free Software Foundation, Inc. - -;; Maintainer: FSF -;; Keywords: help - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - -;;; Commentary: - -;;; Note that nowadays we expect info files to be made using makeinfo. - -;;; Code: - -(defvar Info-history nil - "List of info nodes user has visited. -Each element of list is a list (FILENAME NODENAME BUFFERPOS).") - -(defvar Info-enable-edit nil - "*Non-nil means the \\<Info-mode-map>\\[Info-edit] command in Info can edit the current node. -This is convenient if you want to write info files by hand. -However, we recommend that you not do this. -It is better to write a Texinfo file and generate the Info file from that, -because that gives you a printed manual as well.") - -(defvar Info-enable-active-nodes t - "Non-nil allows Info to execute Lisp code associated with nodes. -The Lisp code is executed when the node is selected.") - -(defvar Info-default-directory-list nil - "List of default directories to search for Info documentation files. -This value is used as the default for `Info-directory-list'. It is set -in paths.el.") - -(defvar Info-fontify t - "*Non-nil enables highlighting and fonts in Info nodes.") - -(defvar Info-fontify-maximum-menu-size 30000 - "*Maximum size of menu to fontify if `Info-fontify' is non-nil.") - -(defvar Info-directory-list - (let ((path (getenv "INFOPATH")) - ;; This is for older Emacs versions - ;; which might get this info.el from the Texinfo distribution. - (path-separator (if (boundp 'path-separator) path-separator - (if (eq system-type 'ms-dos) ";" ":"))) - (sibling (if installation-directory - (expand-file-name "info/" installation-directory)))) - (if path - (let ((list nil) - idx) - (while (> (length path) 0) - (setq idx (or (string-match path-separator path) (length path)) - list (cons (substring path 0 idx) list) - path (substring path (min (1+ idx) - (length path))))) - (nreverse list)) - (if (or (null sibling) - (member sibling Info-default-directory-list) - (not (file-exists-p sibling)) - ;; On DOS/NT, we use movable executables always, - ;; and we must always find the Info dir at run time. - (if (or (eq system-type 'ms-dos) (eq system-type 'windows-nt)) - nil - ;; Use invocation-directory for Info only if we used it for - ;; exec-directory also. - (not (string= exec-directory - (expand-file-name "lib-src/" - installation-directory))))) - Info-default-directory-list - (reverse (cons sibling (cdr (reverse Info-default-directory-list))))))) - "List of directories to search for Info documentation files. -nil means not yet initialized. In this case, Info uses the environment -variable INFOPATH to initialize it, or `Info-default-directory-list' -if there is no INFOPATH variable in the environment. -The last element of `Info-default-directory-list' is the directory -where Emacs installs the Info files that come with it. - -If you run the Emacs executable from the `src' directory in the Emacs -source tree, the `info' directory in the source tree is used as the last -element, in place of the installation Info directory. This is useful -when you run a version of Emacs without installing it.") - -(defvar Info-additional-directory-list nil - "List of additional directories to search for Info documentation files. -These directories are not searched for merging the `dir' file.") - -(defvar Info-current-file nil - "Info file that Info is now looking at, or nil.") - -(defvar Info-current-subfile nil - "Info subfile that is actually in the *info* buffer now, -or nil if current info file is not split into subfiles.") - -(defvar Info-current-node nil - "Name of node that Info is now looking at, or nil.") - -(defvar Info-tag-table-marker (make-marker) - "Marker pointing at beginning of current Info file's tag table. -Marker points nowhere if file has no tag table.") - -(defvar Info-current-file-completions nil - "Cached completion list for current Info file.") - -(defvar Info-index-alternatives nil - "List of possible matches for last Info-index command.") - -(defvar Info-standalone nil - "Non-nil if Emacs was started solely as an Info browser.") - -(defvar Info-suffix-list '( (".info.Z" . "uncompress") - (".info.Y" . "unyabba") - (".info.gz" . "gunzip") - (".info.z" . "gunzip") - (".info" . nil) - (".Z" . "uncompress") - (".Y" . "unyabba") - (".gz" . "gunzip") - (".z" . "gunzip") - ("" . nil)) - "List of file name suffixes and associated decoding commands. -Each entry should be (SUFFIX . STRING); the file is given to -the command as standard input. If STRING is nil, no decoding is done. -Because the SUFFIXes are tried in order, the empty string should -be last in the list.") - -(defun info-insert-file-contents (filename &optional visit) - "Insert the contents of an info file in the current buffer. -Do the right thing if the file has been compressed or zipped." - (let ((tail Info-suffix-list) - fullname decoder) - (if (file-exists-p filename) - (progn - (while (and tail - (not (string-match - (concat (regexp-quote (car (car tail))) "$") - filename))) - (setq tail (cdr tail))) - (setq fullname filename - decoder (cdr (car tail)))) - (while (and tail - (not (file-exists-p (concat filename (car (car tail)))))) - (setq tail (cdr tail))) - (setq fullname (concat filename (car (car tail))) - decoder (cdr (car tail))) - (or tail - (error "Can't find %s or any compressed version of it!" filename))) - ;; check for conflict with jka-compr - (if (and (featurep 'jka-compr) - (jka-compr-installed-p) - (jka-compr-get-compression-info fullname)) - (setq decoder nil)) - (insert-file-contents fullname visit) - (if decoder - (let ((buffer-read-only nil) - (default-directory (or (file-name-directory fullname) - default-directory))) - (shell-command-on-region (point-min) (point-max) decoder t))))) - -;;;###autoload (add-hook 'same-window-buffer-names "*info*") - -;;;###autoload -(defun info (&optional file) - "Enter Info, the documentation browser. -Optional argument FILE specifies the file to examine; -the default is the top-level directory of Info. - -In interactive use, a prefix argument directs this command -to read a file name from the minibuffer." - (interactive (if current-prefix-arg - (list (read-file-name "Info file name: " nil nil t)))) - (if file - (Info-goto-node (concat "(" file ")")) - (if (get-buffer "*info*") - (pop-to-buffer "*info*") - (Info-directory)))) - -;;;###autoload -(defun info-standalone () - "Run Emacs as a standalone Info reader. -Usage: emacs -f info-standalone [filename] -In standalone mode, \\<Info-mode-map>\\[Info-exit] exits Emacs itself." - (setq Info-standalone t) - (if (and command-line-args-left - (not (string-match "^-" (car command-line-args-left)))) - (condition-case err - (progn - (info (car command-line-args-left)) - (setq command-line-args-left (cdr command-line-args-left))) - (error (send-string-to-terminal - (format "%s\n" (if (eq (car-safe err) 'error) - (nth 1 err) err))) - (save-buffers-kill-emacs))) - (info))) - -;; Go to an info node specified as separate filename and nodename. -;; no-going-back is non-nil if recovering from an error in this function; -;; it says do not attempt further (recursive) error recovery. -(defun Info-find-node (filename nodename &optional no-going-back) - ;; Convert filename to lower case if not found as specified. - ;; Expand it. - (if filename - (let (temp temp-downcase found) - (setq filename (substitute-in-file-name filename)) - (if (string= (downcase (file-name-nondirectory filename)) "dir") - (setq found t) - (let ((dirs (if (string-match "^\\./" filename) - ;; If specified name starts with `./' - ;; then just try current directory. - '("./") - (if (file-name-absolute-p filename) - ;; No point in searching for an - ;; absolute file name - '(nil) - (if Info-additional-directory-list - (append Info-directory-list - Info-additional-directory-list) - Info-directory-list))))) - ;; Search the directory list for file FILENAME. - (while (and dirs (not found)) - (setq temp (expand-file-name filename (car dirs))) - (setq temp-downcase - (expand-file-name (downcase filename) (car dirs))) - ;; Try several variants of specified name. - (let ((suffix-list Info-suffix-list)) - (while (and suffix-list (not found)) - (cond ((file-exists-p - (concat temp (car (car suffix-list)))) - (setq found temp)) - ((file-exists-p - (concat temp-downcase (car (car suffix-list)))) - (setq found temp-downcase))) - (setq suffix-list (cdr suffix-list)))) - (setq dirs (cdr dirs))))) - (if found - (setq filename found) - (error "Info file %s does not exist" filename)))) - ;; Record the node we are leaving. - (if (and Info-current-file (not no-going-back)) - (setq Info-history - (cons (list Info-current-file Info-current-node (point)) - Info-history))) - ;; Go into info buffer. - (switch-to-buffer "*info*") - (buffer-disable-undo (current-buffer)) - (or (eq major-mode 'Info-mode) - (Info-mode)) - (widen) - (setq Info-current-node nil) - (unwind-protect - (progn - ;; Switch files if necessary - (or (null filename) - (equal Info-current-file filename) - (let ((buffer-read-only nil)) - (setq Info-current-file nil - Info-current-subfile nil - Info-current-file-completions nil - Info-index-alternatives nil - buffer-file-name nil) - (erase-buffer) - (if (eq filename t) - (Info-insert-dir) - (info-insert-file-contents filename t) - (setq default-directory (file-name-directory filename))) - (set-buffer-modified-p nil) - ;; See whether file has a tag table. Record the location if yes. - (set-marker Info-tag-table-marker nil) - (goto-char (point-max)) - (forward-line -8) - ;; Use string-equal, not equal, to ignore text props. - (or (string-equal nodename "*") - (not (search-forward "\^_\nEnd tag table\n" nil t)) - (let (pos) - ;; We have a tag table. Find its beginning. - ;; Is this an indirect file? - (search-backward "\nTag table:\n") - (setq pos (point)) - (if (save-excursion - (forward-line 2) - (looking-at "(Indirect)\n")) - ;; It is indirect. Copy it to another buffer - ;; and record that the tag table is in that buffer. - (save-excursion - (let ((buf (current-buffer))) - (set-buffer (get-buffer-create " *info tag table*")) - (buffer-disable-undo (current-buffer)) - (setq case-fold-search t) - (erase-buffer) - (insert-buffer-substring buf) - (set-marker Info-tag-table-marker - (match-end 0)))) - (set-marker Info-tag-table-marker pos)))) - (setq Info-current-file - (if (eq filename t) "dir" - (file-name-sans-versions buffer-file-name))))) - ;; Use string-equal, not equal, to ignore text props. - (if (string-equal nodename "*") - (progn (setq Info-current-node nodename) - (Info-set-mode-line)) - ;; Search file for a suitable node. - (let ((guesspos (point-min)) - (regexp (concat "Node: *" (regexp-quote nodename) " *[,\t\n\177]"))) - ;; First get advice from tag table if file has one. - ;; Also, if this is an indirect info file, - ;; read the proper subfile into this buffer. - (if (marker-position Info-tag-table-marker) - (save-excursion - (set-buffer (marker-buffer Info-tag-table-marker)) - (goto-char Info-tag-table-marker) - (if (re-search-forward regexp nil t) - (progn - (setq guesspos (read (current-buffer))) - ;; If this is an indirect file, - ;; determine which file really holds this node - ;; and read it in. - (if (not (eq (current-buffer) (get-buffer "*info*"))) - (setq guesspos - (Info-read-subfile guesspos)))) - (error "No such node: \"%s\"" nodename)))) - (goto-char (max (point-min) (- guesspos 1000))) - ;; Now search from our advised position (or from beg of buffer) - ;; to find the actual node. - (catch 'foo - (while (search-forward "\n\^_" nil t) - (forward-line 1) - (let ((beg (point))) - (forward-line 1) - (if (re-search-backward regexp beg t) - (throw 'foo t)))) - (error "No such node: %s" nodename))) - (Info-select-node))) - ;; If we did not finish finding the specified node, - ;; go back to the previous one. - (or Info-current-node no-going-back (null Info-history) - (let ((hist (car Info-history))) - (setq Info-history (cdr Info-history)) - (Info-find-node (nth 0 hist) (nth 1 hist) t) - (goto-char (nth 2 hist))))) - (goto-char (point-min))) - -;; Cache the contents of the (virtual) dir file, once we have merged -;; it for the first time, so we can save time subsequently. -(defvar Info-dir-contents nil) - -;; Cache for the directory we decided to use for the default-directory -;; of the merged dir text. -(defvar Info-dir-contents-directory nil) - -;; Record the file attributes of all the files from which we -;; constructed Info-dir-contents. -(defvar Info-dir-file-attributes nil) - -;; Construct the Info directory node by merging the files named `dir' -;; from various directories. Set the *info* buffer's -;; default-directory to the first directory we actually get any text -;; from. -(defun Info-insert-dir () - (if (and Info-dir-contents Info-dir-file-attributes - ;; Verify that none of the files we used has changed - ;; since we used it. - (eval (cons 'and - (mapcar '(lambda (elt) - (let ((curr (file-attributes (car elt)))) - ;; Don't compare the access time. - (if curr (setcar (nthcdr 4 curr) 0)) - (setcar (nthcdr 4 (cdr elt)) 0) - (equal (cdr elt) curr))) - Info-dir-file-attributes)))) - (insert Info-dir-contents) - (let ((dirs Info-directory-list) - buffers buffer others nodes dirs-done) - - (setq Info-dir-file-attributes nil) - - ;; Search the directory list for the directory file. - (while dirs - (let ((truename (file-truename (expand-file-name (car dirs))))) - (or (member truename dirs-done) - (member (directory-file-name truename) dirs-done) - ;; Try several variants of specified name. - ;; Try upcasing, appending `.info', or both. - (let* (file - (attrs - (or - (progn (setq file (expand-file-name "dir" truename)) - (file-attributes file)) - (progn (setq file (expand-file-name "DIR" truename)) - (file-attributes file)) - (progn (setq file (expand-file-name "dir.info" truename)) - (file-attributes file)) - (progn (setq file (expand-file-name "DIR.INFO" truename)) - (file-attributes file))))) - (setq dirs-done - (cons truename - (cons (directory-file-name truename) - dirs-done))) - (if attrs - (save-excursion - (or buffers - (message "Composing main Info directory...")) - (set-buffer (generate-new-buffer "info dir")) - (insert-file-contents file) - (setq buffers (cons (current-buffer) buffers) - Info-dir-file-attributes - (cons (cons file attrs) - Info-dir-file-attributes)))))) - (setq dirs (cdr dirs)))) - - (or buffers - (error "Can't find the info directory node")) - ;; Distinguish the dir file that comes with Emacs from all the - ;; others. Yes, that is really what this is supposed to do. - ;; If it doesn't work, fix it. - (setq buffer (car buffers) - others (cdr buffers)) - - ;; Insert the entire original dir file as a start; use its - ;; default directory as the default directory for the whole - ;; concatenation. - (insert-buffer buffer) - (setq Info-dir-contents-directory (save-excursion - (set-buffer buffer) - default-directory)) - - ;; Look at each of the other buffers one by one. - (while others - (let ((other (car others))) - ;; In each, find all the menus. - (save-excursion - (set-buffer other) - (goto-char (point-min)) - ;; Find each menu, and add an elt to NODES for it. - (while (re-search-forward "^\\* Menu:" nil t) - (let (beg nodename end) - (forward-line 1) - (setq beg (point)) - (search-backward "\n\^_") - (search-forward "Node: ") - (setq nodename (Info-following-node-name)) - (search-forward "\n\^_" nil 'move) - (beginning-of-line) - (setq end (point)) - (setq nodes (cons (list nodename other beg end) nodes)))))) - (setq others (cdr others))) - ;; Add to the main menu a menu item for each other node. - (re-search-forward "^\\* Menu:") - (forward-line 1) - (let ((menu-items '("top")) - (nodes nodes) - (case-fold-search t) - (end (save-excursion (search-forward "\^_" nil t) (point)))) - (while nodes - (let ((nodename (car (car nodes)))) - (save-excursion - (or (member (downcase nodename) menu-items) - (re-search-forward (concat "^\\* " - (regexp-quote nodename) - "::") - end t) - (progn - (insert "* " nodename "::" "\n") - (setq menu-items (cons nodename menu-items)))))) - (setq nodes (cdr nodes)))) - ;; Now take each node of each of the other buffers - ;; and merge it into the main buffer. - (while nodes - (let ((nodename (car (car nodes)))) - (goto-char (point-min)) - ;; Find the like-named node in the main buffer. - (if (re-search-forward (concat "\n\^_.*\n.*Node: " - (regexp-quote nodename) - "[,\n\t]") - nil t) - (progn - (search-forward "\n\^_" nil 'move) - (beginning-of-line) - (insert "\n")) - ;; If none exists, add one. - (goto-char (point-max)) - (insert "\^_\nFile: dir\tNode: " nodename "\n\n* Menu:\n\n")) - ;; Merge the text from the other buffer's menu - ;; into the menu in the like-named node in the main buffer. - (apply 'insert-buffer-substring (cdr (car nodes)))) - (setq nodes (cdr nodes))) - ;; Kill all the buffers we just made. - (while buffers - (kill-buffer (car buffers)) - (setq buffers (cdr buffers))) - (message "Composing main Info directory...done")) - (setq Info-dir-contents (buffer-string))) - (setq default-directory Info-dir-contents-directory)) - -(defun Info-read-subfile (nodepos) - (set-buffer (marker-buffer Info-tag-table-marker)) - (goto-char (point-min)) - (search-forward "\n\^_") - (let (lastfilepos - lastfilename) - (forward-line 2) - (catch 'foo - (while (not (looking-at "\^_")) - (if (not (eolp)) - (let ((beg (point)) - thisfilepos thisfilename) - (search-forward ": ") - (setq thisfilename (buffer-substring beg (- (point) 2))) - (setq thisfilepos (read (current-buffer))) - ;; read in version 19 stops at the end of number. - ;; Advance to the next line. - (forward-line 1) - (if (> thisfilepos nodepos) - (throw 'foo t)) - (setq lastfilename thisfilename) - (setq lastfilepos thisfilepos)) - (forward-line 1)))) - (set-buffer (get-buffer "*info*")) - (or (equal Info-current-subfile lastfilename) - (let ((buffer-read-only nil)) - (setq buffer-file-name nil) - (widen) - (erase-buffer) - (info-insert-file-contents lastfilename) - (set-buffer-modified-p nil) - (setq Info-current-subfile lastfilename))) - (goto-char (point-min)) - (search-forward "\n\^_") - (+ (- nodepos lastfilepos) (point)))) - -;; Select the info node that point is in. -(defun Info-select-node () - (save-excursion - ;; Find beginning of node. - (search-backward "\n\^_") - (forward-line 2) - ;; Get nodename spelled as it is in the node. - (re-search-forward "Node:[ \t]*") - (setq Info-current-node - (buffer-substring (point) - (progn - (skip-chars-forward "^,\t\n") - (point)))) - (Info-set-mode-line) - ;; Find the end of it, and narrow. - (beginning-of-line) - (let (active-expression) - (narrow-to-region (point) - (if (re-search-forward "\n[\^_\f]" nil t) - (prog1 - (1- (point)) - (if (looking-at "[\n\^_\f]*execute: ") - (progn - (goto-char (match-end 0)) - (setq active-expression - (read (current-buffer)))))) - (point-max))) - (if Info-enable-active-nodes (eval active-expression)) - (if Info-fontify (Info-fontify-node)) - (run-hooks 'Info-selection-hook)))) - -(defun Info-set-mode-line () - (setq mode-line-buffer-identification - (concat - "Info: (" - (if Info-current-file - (file-name-nondirectory Info-current-file) - "") - ")" - (or Info-current-node "")))) - -;; Go to an info node specified with a filename-and-nodename string -;; of the sort that is found in pointers in nodes. - -(defun Info-goto-node (nodename) - "Go to info node named NAME. Give just NODENAME or (FILENAME)NODENAME." - (interactive (list (Info-read-node-name "Goto node: "))) - (let (filename) - (string-match "\\s *\\((\\s *\\([^\t)]*\\)\\s *)\\s *\\|\\)\\(.*\\)" - nodename) - (setq filename (if (= (match-beginning 1) (match-end 1)) - "" - (substring nodename (match-beginning 2) (match-end 2))) - nodename (substring nodename (match-beginning 3) (match-end 3))) - (let ((trim (string-match "\\s *\\'" filename))) - (if trim (setq filename (substring filename 0 trim)))) - (let ((trim (string-match "\\s *\\'" nodename))) - (if trim (setq nodename (substring nodename 0 trim)))) - (Info-find-node (if (equal filename "") nil filename) - (if (equal nodename "") "Top" nodename)))) - -(defun Info-read-node-name (prompt &optional default) - (let* ((completion-ignore-case t) - (nodename (completing-read prompt (Info-build-node-completions)))) - (if (equal nodename "") - (or default - (Info-read-node-name prompt)) - nodename))) - -(defun Info-build-node-completions () - (or Info-current-file-completions - (let ((compl nil)) - (save-excursion - (save-restriction - (if (marker-buffer Info-tag-table-marker) - (progn - (set-buffer (marker-buffer Info-tag-table-marker)) - (widen) - (goto-char Info-tag-table-marker) - (while (re-search-forward "\nNode: \\(.*\\)\177" nil t) - (setq compl - (cons (list (buffer-substring (match-beginning 1) - (match-end 1))) - compl)))) - (widen) - (goto-char (point-min)) - (while (search-forward "\n\^_" nil t) - (forward-line 1) - (let ((beg (point))) - (forward-line 1) - (if (re-search-backward "Node: *\\([^,\n]*\\) *[,\n\t]" - beg t) - (setq compl - (cons (list (buffer-substring (match-beginning 1) - (match-end 1))) - compl)))))))) - (setq Info-current-file-completions compl)))) - -(defun Info-restore-point (hl) - "If this node has been visited, restore the point value when we left." - (while hl - (if (and (equal (nth 0 (car hl)) Info-current-file) - ;; Use string-equal, not equal, to ignore text props. - (string-equal (nth 1 (car hl)) Info-current-node)) - (progn - (goto-char (nth 2 (car hl))) - (setq hl nil)) ;terminate the while at next iter - (setq hl (cdr hl))))) - -(defvar Info-last-search nil - "Default regexp for \\<Info-mode-map>\\[Info-search] command to search for.") - -(defun Info-search (regexp) - "Search for REGEXP, starting from point, and select node it's found in." - (interactive "sSearch (regexp): ") - (if (equal regexp "") - (setq regexp Info-last-search) - (setq Info-last-search regexp)) - (let ((found ()) current - (onode Info-current-node) - (ofile Info-current-file) - (opoint (point)) - (osubfile Info-current-subfile)) - (save-excursion - (save-restriction - (widen) - (if (null Info-current-subfile) - (progn (re-search-forward regexp) (setq found (point))) - (condition-case err - (progn (re-search-forward regexp) (setq found (point))) - (search-failed nil))))) - (if (not found) ;can only happen in subfile case -- else would have erred - (unwind-protect - (let ((list ())) - (set-buffer (marker-buffer Info-tag-table-marker)) - (goto-char (point-min)) - (search-forward "\n\^_\nIndirect:") - (save-restriction - (narrow-to-region (point) - (progn (search-forward "\n\^_") - (1- (point)))) - (goto-char (point-min)) - (search-forward (concat "\n" osubfile ": ")) - (beginning-of-line) - (while (not (eobp)) - (re-search-forward "\\(^.*\\): [0-9]+$") - (goto-char (+ (match-end 1) 2)) - (setq list (cons (cons (read (current-buffer)) - (buffer-substring (match-beginning 1) - (match-end 1))) - list)) - (goto-char (1+ (match-end 0)))) - (setq list (nreverse list) - current (car (car list)) - list (cdr list))) - (while list - (message "Searching subfile %s..." (cdr (car list))) - (Info-read-subfile (car (car list))) - (setq list (cdr list)) -;; (goto-char (point-min)) - (if (re-search-forward regexp nil t) - (setq found (point) list ()))) - (if found - (message "") - (signal 'search-failed (list regexp)))) - (if (not found) - (progn (Info-read-subfile opoint) - (goto-char opoint) - (Info-select-node))))) - (widen) - (goto-char found) - (Info-select-node) - ;; Use string-equal, not equal, to ignore text props. - (or (and (string-equal onode Info-current-node) - (equal ofile Info-current-file)) - (setq Info-history (cons (list ofile onode opoint) - Info-history))))) - -;; Extract the value of the node-pointer named NAME. -;; If there is none, use ERRORNAME in the error message; -;; if ERRORNAME is nil, just return nil. -(defun Info-extract-pointer (name &optional errorname) - (save-excursion - (goto-char (point-min)) - (forward-line 1) - (if (re-search-backward (concat name ":") nil t) - (progn - (goto-char (match-end 0)) - (Info-following-node-name)) - (if (eq errorname t) - nil - (error (concat "Node has no " (capitalize (or errorname name)))))))) - -;; Return the node name in the buffer following point. -;; ALLOWEDCHARS, if non-nil, goes within [...] to make a regexp -;; saying which chas may appear in the node name. -(defun Info-following-node-name (&optional allowedchars) - (skip-chars-forward " \t") - (buffer-substring - (point) - (progn - (while (looking-at (concat "[" (or allowedchars "^,\t\n") "]")) - (skip-chars-forward (concat (or allowedchars "^,\t\n") "(")) - (if (looking-at "(") - (skip-chars-forward "^)"))) - (skip-chars-backward " ") - (point)))) - -(defun Info-next () - "Go to the next node of this node." - (interactive) - (Info-goto-node (Info-extract-pointer "next"))) - -(defun Info-prev () - "Go to the previous node of this node." - (interactive) - (Info-goto-node (Info-extract-pointer "prev[ious]*" "previous"))) - -(defun Info-up () - "Go to the superior node of this node." - (interactive) - (Info-goto-node (Info-extract-pointer "up")) - (Info-restore-point Info-history)) - -(defun Info-last () - "Go back to the last node visited." - (interactive) - (or Info-history - (error "This is the first Info node you looked at")) - (let (filename nodename opoint) - (setq filename (car (car Info-history))) - (setq nodename (car (cdr (car Info-history)))) - (setq opoint (car (cdr (cdr (car Info-history))))) - (setq Info-history (cdr Info-history)) - (Info-find-node filename nodename) - (setq Info-history (cdr Info-history)) - (goto-char opoint))) - -(defun Info-directory () - "Go to the Info directory node." - (interactive) - (Info-find-node "dir" "top")) - -(defun Info-follow-reference (footnotename) - "Follow cross reference named NAME to the node it refers to. -NAME may be an abbreviation of the reference name." - (interactive - (let ((completion-ignore-case t) - completions default alt-default (start-point (point)) str i bol eol) - (save-excursion - ;; Store end and beginning of line. - (end-of-line) - (setq eol (point)) - (beginning-of-line) - (setq bol (point)) - - (goto-char (point-min)) - (while (re-search-forward "\\*note[ \n\t]*\\([^:]*\\):" nil t) - (setq str (buffer-substring - (match-beginning 1) - (1- (point)))) - ;; See if this one should be the default. - (and (null default) - (<= (match-beginning 0) start-point) - (<= start-point (point)) - (setq default t)) - ;; See if this one should be the alternate default. - (and (null alt-default) - (and (<= bol (match-beginning 0)) - (<= (point) eol)) - (setq alt-default t)) - (setq i 0) - (while (setq i (string-match "[ \n\t]+" str i)) - (setq str (concat (substring str 0 i) " " - (substring str (match-end 0)))) - (setq i (1+ i))) - ;; Record as a completion and perhaps as default. - (if (eq default t) (setq default str)) - (if (eq alt-default t) (setq alt-default str)) - (setq completions - (cons (cons str nil) - completions)))) - ;; If no good default was found, try an alternate. - (or default - (setq default alt-default)) - ;; If only one cross-reference found, then make it default. - (if (eq (length completions) 1) - (setq default (car (car completions)))) - (if completions - (let ((input (completing-read (if default - (concat "Follow reference named: (" - default ") ") - "Follow reference named: ") - completions nil t))) - (list (if (equal input "") - default input))) - (error "No cross-references in this node")))) - (let (target beg i (str (concat "\\*note " (regexp-quote footnotename)))) - (while (setq i (string-match " " str i)) - (setq str (concat (substring str 0 i) "[ \t\n]+" (substring str (1+ i)))) - (setq i (+ i 6))) - (save-excursion - (goto-char (point-min)) - (or (re-search-forward str nil t) - (error "No cross-reference named %s" footnotename)) - (goto-char (+ (match-beginning 0) 5)) - (setq target - (Info-extract-menu-node-name "Bad format cross reference" t))) - (while (setq i (string-match "[ \t\n]+" target i)) - (setq target (concat (substring target 0 i) " " - (substring target (match-end 0)))) - (setq i (+ i 1))) - (Info-goto-node target))) - -(defun Info-extract-menu-node-name (&optional errmessage multi-line) - (skip-chars-forward " \t\n") - (let ((beg (point)) - str i) - (skip-chars-forward "^:") - (forward-char 1) - (setq str - (if (looking-at ":") - (buffer-substring beg (1- (point))) - (skip-chars-forward " \t\n") - (Info-following-node-name (if multi-line "^.,\t" "^.,\t\n")))) - (while (setq i (string-match "\n" str i)) - (aset str i ?\ )) - ;; Collapse multiple spaces. - (while (string-match " +" str) - (setq str (replace-match " " t t str))) - str)) - -;; No one calls this. -;;(defun Info-menu-item-sequence (list) -;; (while list -;; (Info-menu (car list)) -;; (setq list (cdr list)))) - -(defun Info-complete-menu-item (string predicate action) - (let ((case-fold-search t)) - (cond ((eq action nil) - (let (completions - (pattern (concat "\n\\* \\(" - (regexp-quote string) - "[^:\t\n]*\\):"))) - (save-excursion - (set-buffer Info-complete-menu-buffer) - (goto-char (point-min)) - (while (re-search-forward pattern nil t) - (setq completions (cons (cons (format "%s" - (buffer-substring - (match-beginning 1) - (match-end 1))) - (match-beginning 1)) - completions)))) - (try-completion string completions predicate))) - ((eq action t) - (let (completions - (pattern (concat "\n\\* \\(" - (regexp-quote string) - "[^:\t\n]*\\):"))) - (save-excursion - (set-buffer Info-complete-menu-buffer) - (goto-char (point-min)) - (while (re-search-forward pattern nil t) - (setq completions (cons (cons (format "%s" - (buffer-substring - (match-beginning 1) - (match-end 1))) - (match-beginning 1)) - completions)))) - (all-completions string completions predicate))) - (t - (save-excursion - (set-buffer Info-complete-menu-buffer) - (goto-char (point-min)) - (re-search-forward (concat "\n\\* " - (regexp-quote string) - ":") - nil t)))))) - - -(defun Info-menu (menu-item) - "Go to node for menu item named (or abbreviated) NAME. -Completion is allowed, and the menu item point is on is the default." - (interactive - (let ((completions '()) - ;; If point is within a menu item, use that item as the default - (default nil) - (p (point)) - beg - (last nil)) - (save-excursion - (goto-char (point-min)) - (if (not (search-forward "\n* menu:" nil t)) - (error "No menu in this node")) - (setq beg (point)) - (and (< (point) p) - (save-excursion - (goto-char p) - (end-of-line) - (re-search-backward "\n\\* \\([^:\t\n]*\\):" beg t) - (setq default (format "%s" (buffer-substring - (match-beginning 1) - (match-end 1))))))) - (let ((item nil)) - (while (null item) - (setq item (let ((completion-ignore-case t) - (Info-complete-menu-buffer (current-buffer))) - (completing-read (if default - (format "Menu item (default %s): " - default) - "Menu item: ") - 'Info-complete-menu-item nil t))) - ;; we rely on the fact that completing-read accepts an input - ;; of "" even when the require-match argument is true and "" - ;; is not a valid possibility - (if (string= item "") - (if default - (setq item default) - ;; ask again - (setq item nil)))) - (list item)))) - ;; there is a problem here in that if several menu items have the same - ;; name you can only go to the node of the first with this command. - (Info-goto-node (Info-extract-menu-item menu-item))) - -(defun Info-extract-menu-item (menu-item) - (setq menu-item (regexp-quote menu-item)) - (save-excursion - (goto-char (point-min)) - (or (search-forward "\n* menu:" nil t) - (error "No menu in this node")) - (or (re-search-forward (concat "\n\\* " menu-item ":") nil t) - (re-search-forward (concat "\n\\* " menu-item) nil t) - (error "No such item in menu")) - (beginning-of-line) - (forward-char 2) - (Info-extract-menu-node-name))) - -;; If COUNT is nil, use the last item in the menu. -(defun Info-extract-menu-counting (count) - (save-excursion - (goto-char (point-min)) - (or (search-forward "\n* menu:" nil t) - (error "No menu in this node")) - (if count - (or (search-forward "\n* " nil t count) - (error "Too few items in menu")) - (while (search-forward "\n* " nil t) - nil)) - (Info-extract-menu-node-name))) - -(defun Info-nth-menu-item () - "Go to the node of the Nth menu item. -N is the digit argument used to invoke this command." - (interactive) - (Info-goto-node - (Info-extract-menu-counting - (- (aref (this-command-keys) (1- (length (this-command-keys)))) ?0)))) - -(defun Info-top-node () - "Go to the Top node of this file." - (interactive) - (Info-goto-node "Top")) - -(defun Info-final-node () - "Go to the final node in this file." - (interactive) - (Info-goto-node "Top") - (let (Info-history) - ;; Go to the last node in the menu of Top. - (Info-goto-node (Info-extract-menu-counting nil)) - ;; If the last node in the menu is not last in pointer structure, - ;; move forward until we can't go any farther. - (while (Info-forward-node t t) nil) - ;; Then keep moving down to last subnode, unless we reach an index. - (while (and (not (string-match "\\<index\\>" Info-current-node)) - (save-excursion (search-forward "\n* Menu:" nil t))) - (Info-goto-node (Info-extract-menu-counting nil))))) - -(defun Info-forward-node (&optional not-down no-error) - "Go forward one node, considering all nodes as forming one sequence." - (interactive) - (goto-char (point-min)) - (forward-line 1) - ;; three possibilities, in order of priority: - ;; 1. next node is in a menu in this node (but not in an index) - ;; 2. next node is next at same level - ;; 3. next node is up and next - (cond ((and (not not-down) - (save-excursion (search-forward "\n* menu:" nil t)) - (not (string-match "\\<index\\>" Info-current-node))) - (Info-goto-node (Info-extract-menu-counting 1)) - t) - ((save-excursion (search-backward "next:" nil t)) - (Info-next) - t) - ((and (save-excursion (search-backward "up:" nil t)) - ;; Use string-equal, not equal, to ignore text props. - (not (string-equal (downcase (Info-extract-pointer "up")) - "top"))) - (let ((old-node Info-current-node)) - (Info-up) - (let (Info-history success) - (unwind-protect - (setq success (Info-forward-node t no-error)) - (or success (Info-goto-node old-node)))))) - (no-error nil) - (t (error "No pointer forward from this node")))) - -(defun Info-backward-node () - "Go backward one node, considering all nodes as forming one sequence." - (interactive) - (let ((prevnode (Info-extract-pointer "prev[ious]*" t)) - (upnode (Info-extract-pointer "up" t))) - (cond ((and upnode (string-match "(" upnode)) - (error "First node in file")) - ((and upnode (or (null prevnode) - ;; Use string-equal, not equal, - ;; to ignore text properties. - (string-equal (downcase prevnode) - (downcase upnode)))) - (Info-up)) - (prevnode - ;; If we move back at the same level, - ;; go down to find the last subnode*. - (Info-prev) - (let (Info-history) - (while (and (not (string-match "\\<index\\>" Info-current-node)) - (save-excursion (search-forward "\n* Menu:" nil t))) - (Info-goto-node (Info-extract-menu-counting nil))))) - (t - (error "No pointer backward from this node"))))) - -(defun Info-exit () - "Exit Info by selecting some other buffer." - (interactive) - (if Info-standalone - (save-buffers-kill-emacs) - (switch-to-buffer (prog1 (other-buffer (current-buffer)) - (bury-buffer (current-buffer)))))) - -(defun Info-next-menu-item () - (interactive) - (save-excursion - (forward-line -1) - (search-forward "\n* menu:" nil t) - (or (search-forward "\n* " nil t) - (error "No more items in menu")) - (Info-goto-node (Info-extract-menu-node-name)))) - -(defun Info-last-menu-item () - (interactive) - (save-excursion - (forward-line 1) - (let ((beg (save-excursion - (and (search-backward "\n* menu:" nil t) - (point))))) - (or (and beg (search-backward "\n* " beg t)) - (error "No previous items in menu"))) - (Info-goto-node (save-excursion - (goto-char (match-end 0)) - (Info-extract-menu-node-name))))) - -(defmacro Info-no-error (&rest body) - (list 'condition-case nil (cons 'progn (append body '(t))) '(error nil))) - -(defun Info-next-preorder () - "Go to the next subnode or the next node, or go up a level." - (interactive) - (cond ((Info-no-error (Info-next-menu-item))) - ((Info-no-error (Info-next))) - ((Info-no-error (Info-up)) - ;; Since we have already gone thru all the items in this menu, - ;; go up to the end of this node. - (goto-char (point-max))) - (t - (error "No more nodes")))) - -(defun Info-last-preorder () - "Go to the last node, popping up a level if there is none." - (interactive) - (cond ((Info-no-error - (Info-last-menu-item) - ;; If we go down a menu item, go to the end of the node - ;; so we can scroll back through it. - (goto-char (point-max))) - (recenter -1)) - ((Info-no-error (Info-prev)) - (goto-char (point-max)) - (recenter -1)) - ((Info-no-error (Info-up)) - (goto-char (point-min)) - (or (search-forward "\n* Menu:" nil t) - (goto-char (point-max)))) - (t (error "No previous nodes")))) - -(defun Info-scroll-up () - "Scroll one screenful forward in Info, considering all nodes as one sequence. -Once you scroll far enough in a node that its menu appears on the screen, -the next scroll moves into its first subnode. When you scroll past -the end of a node, that goes to the next node or back up to the parent node." - (interactive) - (if (or (< (window-start) (point-min)) - (> (window-start) (point-max))) - (set-window-start (selected-window) (point))) - (let ((virtual-end (save-excursion - (goto-char (point-min)) - (if (search-forward "\n* Menu:" nil t) - (point) - (point-max))))) - (if (or (< virtual-end (window-start)) - (pos-visible-in-window-p virtual-end)) - (Info-next-preorder) - (scroll-up)))) - -(defun Info-scroll-down () - "Scroll one screenful back in Info, considering all nodes as one sequence. -Within the menu of a node, this goes to its last subnode. -When you scroll past the beginning of a node, that goes to the -previous node or back up to the parent node." - (interactive) - (if (or (< (window-start) (point-min)) - (> (window-start) (point-max))) - (set-window-start (selected-window) (point))) - (let ((virtual-end (save-excursion - (goto-char (point-min)) - (search-forward "\n* Menu:" nil t)))) - (if (or virtual-end (pos-visible-in-window-p (point-min))) - (Info-last-preorder) - (scroll-down)))) - -(defun Info-next-reference () - "Move cursor to the next cross-reference or menu item in the node." - (interactive) - (let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:") - (old-pt (point))) - (or (eobp) (forward-char 1)) - (or (re-search-forward pat nil t) - (progn - (goto-char (point-min)) - (or (re-search-forward pat nil t) - (progn - (goto-char old-pt) - (error "No cross references in this node"))))) - (goto-char (match-beginning 0)) - (if (looking-at "\\* Menu:") - (Info-next-reference)))) - -(defun Info-prev-reference () - "Move cursor to the previous cross-reference or menu item in the node." - (interactive) - (let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:") - (old-pt (point))) - (or (re-search-backward pat nil t) - (progn - (goto-char (point-max)) - (or (re-search-backward pat nil t) - (progn - (goto-char old-pt) - (error "No cross references in this node"))))) - (goto-char (match-beginning 0)) - (if (looking-at "\\* Menu:") - (Info-prev-reference)))) - -(defun Info-index (topic) - "Look up a string in the index for this file. -The index is defined as the first node in the top-level menu whose -name contains the word \"Index\", plus any immediately following -nodes whose names also contain the word \"Index\". -If there are no exact matches to the specified topic, this chooses -the first match which is a case-insensitive substring of a topic. -Use the `,' command to see the other matches. -Give a blank topic name to go to the Index node itself." - (interactive "sIndex topic: ") - (let ((orignode Info-current-node) - (rnode nil) - (pattern (format "\n\\* \\([^\n:]*%s[^\n:]*\\):[ \t]*\\([^.\n]*\\)\\.[ \t]*\\([0-9]*\\)" - (regexp-quote topic))) - node) - (Info-goto-node "Top") - (or (search-forward "\n* menu:" nil t) - (error "No index")) - (or (re-search-forward "\n\\* \\(.*\\<Index\\>\\)" nil t) - (error "No index")) - (goto-char (match-beginning 1)) - ;; Here, and subsequently in this function, - ;; we bind Info-history to nil for internal node-switches - ;; so that we don't put junk in the history. - ;; In the first Info-goto-node call, above, we do update the history - ;; because that is what the user's previous node choice into it. - (let ((Info-history nil)) - (Info-goto-node (Info-extract-menu-node-name))) - (or (equal topic "") - (let ((matches nil) - (exact nil) - (Info-history nil) - found) - (while - (progn - (goto-char (point-min)) - (while (re-search-forward pattern nil t) - (setq matches - (cons (list (buffer-substring (match-beginning 1) - (match-end 1)) - (buffer-substring (match-beginning 2) - (match-end 2)) - Info-current-node - (string-to-int (concat "0" - (buffer-substring - (match-beginning 3) - (match-end 3))))) - matches))) - (and (setq node (Info-extract-pointer "next" t)) - (string-match "\\<Index\\>" node))) - (Info-goto-node node)) - (or matches - (progn - (Info-last) - (error "No \"%s\" in index" topic))) - ;; Here it is a feature that assoc is case-sensitive. - (while (setq found (assoc topic matches)) - (setq exact (cons found exact) - matches (delq found matches))) - (setq Info-index-alternatives (nconc exact (nreverse matches))) - (Info-index-next 0))))) - -(defun Info-index-next (num) - "Go to the next matching index item from the last `i' command." - (interactive "p") - (or Info-index-alternatives - (error "No previous `i' command in this file")) - (while (< num 0) - (setq num (+ num (length Info-index-alternatives)))) - (while (> num 0) - (setq Info-index-alternatives - (nconc (cdr Info-index-alternatives) - (list (car Info-index-alternatives))) - num (1- num))) - (Info-goto-node (nth 1 (car Info-index-alternatives))) - (if (> (nth 3 (car Info-index-alternatives)) 0) - (forward-line (nth 3 (car Info-index-alternatives))) - (forward-line 3) ; don't search in headers - (let ((name (car (car Info-index-alternatives)))) - (if (or (re-search-forward (format - "\\(Function\\|Command\\): %s\\( \\|$\\)" - (regexp-quote name)) nil t) - (search-forward (format "`%s'" name) nil t) - (and (string-match "\\`.*\\( (.*)\\)\\'" name) - (search-forward - (format "`%s'" (substring name 0 (match-beginning 1))) - nil t)) - (search-forward name nil t)) - (beginning-of-line) - (goto-char (point-min))))) - (message "Found \"%s\" in %s. %s" - (car (car Info-index-alternatives)) - (nth 2 (car Info-index-alternatives)) - (if (cdr Info-index-alternatives) - "(Press `,' for more)" - "(Only match)"))) - -(defun Info-undefined () - "Make command be undefined in Info." - (interactive) - (ding)) - -(defun Info-help () - "Enter the Info tutorial." - (interactive) - (delete-other-windows) - (Info-find-node "info" - (if (< (window-height) 23) - "Help-Small-Screen" - "Help"))) - -(defun Info-summary () - "Display a brief summary of all Info commands." - (interactive) - (save-window-excursion - (switch-to-buffer "*Help*") - (erase-buffer) - (insert (documentation 'Info-mode)) - (help-mode) - (goto-char (point-min)) - (let (ch flag) - (while (progn (setq flag (not (pos-visible-in-window-p (point-max)))) - (message (if flag "Type Space to see more" - "Type Space to return to Info")) - (if (not (eq ?\ (setq ch (read-event)))) - (progn (setq unread-command-events (list ch)) nil) - flag)) - (scroll-up))) - (bury-buffer "*Help*"))) - -(defun Info-get-token (pos start all &optional errorstring) - "Return the token around POS, -POS must be somewhere inside the token -START is a regular expression which will match the - beginning of the tokens delimited string -ALL is a regular expression with a single - parenthized subpattern which is the token to be - returned. E.g. '{\(.*\)}' would return any string - enclosed in braces around POS. -SIG optional fourth argument, controls action on no match - nil: return nil - t: beep - a string: signal an error, using that string." - (save-excursion - (goto-char pos) - (re-search-backward start (max (point-min) (- pos 200)) 'yes) - (let (found) - (while (and (re-search-forward all (min (point-max) (+ pos 200)) 'yes) - (not (setq found (and (<= (match-beginning 0) pos) - (> (match-end 0) pos)))))) - (if (and found (<= (match-beginning 0) pos) - (> (match-end 0) pos)) - (buffer-substring (match-beginning 1) (match-end 1)) - (cond ((null errorstring) - nil) - ((eq errorstring t) - (beep) - nil) - (t - (error "No %s around position %d" errorstring pos))))))) - -(defun Info-mouse-follow-nearest-node (click) - "\\<Info-mode-map>Follow a node reference near point. -Like \\[Info-menu], \\[Info-follow-reference], \\[Info-next], \\[Info-prev] or \\[Info-up] command, depending on where you click. -At end of the node's text, moves to the next node, or up if none." - (interactive "e") - (let* ((start (event-start click)) - (window (car start)) - (pos (car (cdr start)))) - (select-window window) - (goto-char pos)) - (and (not (Info-try-follow-nearest-node)) - (save-excursion (forward-line 1) (eobp)) - (Info-next-preorder))) - -(defun Info-follow-nearest-node () - "\\<Info-mode-map>Follow a node reference near point. -Like \\[Info-menu], \\[Info-follow-reference], \\[Info-next], \\[Info-prev] or \\[Info-up] command, depending on where point is. -If no reference to follow, moves to the next node, or up if none." - (interactive) - (or (Info-try-follow-nearest-node) - (Info-next-preorder))) - -;; Common subroutine. -(defun Info-try-follow-nearest-node () - "Follow a node reference near point. Return non-nil if successful." - (let (node) - (cond - ((setq node (Info-get-token (point) "\\*note[ \n]" - "\\*note[ \n]\\([^:]*\\):")) - (Info-follow-reference node)) - ((setq node (Info-get-token (point) "\\* " "\\* \\([^:]*\\)::")) - (Info-goto-node node)) - ((setq node (Info-get-token (point) "\\* " "\\* \\([^:]*\\):")) - (Info-menu node)) - ((setq node (Info-get-token (point) "Up: " "Up: \\([^,\n\t]*\\)")) - (Info-goto-node node)) - ((setq node (Info-get-token (point) "Next: " "Next: \\([^,\n\t]*\\)")) - (Info-goto-node node)) - ((setq node (Info-get-token (point) "File: " "File: \\([^,\n\t]*\\)")) - (Info-goto-node "Top")) - ((setq node (Info-get-token (point) "Prev: " "Prev: \\([^,\n\t]*\\)")) - (Info-goto-node node))) - node)) - -(defvar Info-mode-map nil - "Keymap containing Info commands.") -(if Info-mode-map - nil - (setq Info-mode-map (make-keymap)) - (suppress-keymap Info-mode-map) - (define-key Info-mode-map "." 'beginning-of-buffer) - (define-key Info-mode-map " " 'Info-scroll-up) - (define-key Info-mode-map "\C-m" 'Info-follow-nearest-node) - (define-key Info-mode-map "\t" 'Info-next-reference) - (define-key Info-mode-map "\e\t" 'Info-prev-reference) - (define-key Info-mode-map "1" 'Info-nth-menu-item) - (define-key Info-mode-map "2" 'Info-nth-menu-item) - (define-key Info-mode-map "3" 'Info-nth-menu-item) - (define-key Info-mode-map "4" 'Info-nth-menu-item) - (define-key Info-mode-map "5" 'Info-nth-menu-item) - (define-key Info-mode-map "6" 'Info-nth-menu-item) - (define-key Info-mode-map "7" 'Info-nth-menu-item) - (define-key Info-mode-map "8" 'Info-nth-menu-item) - (define-key Info-mode-map "9" 'Info-nth-menu-item) - (define-key Info-mode-map "0" 'undefined) - (define-key Info-mode-map "?" 'Info-summary) - (define-key Info-mode-map "]" 'Info-forward-node) - (define-key Info-mode-map "[" 'Info-backward-node) - (define-key Info-mode-map "<" 'Info-top-node) - (define-key Info-mode-map ">" 'Info-final-node) - (define-key Info-mode-map "b" 'beginning-of-buffer) - (define-key Info-mode-map "d" 'Info-directory) - (define-key Info-mode-map "e" 'Info-edit) - (define-key Info-mode-map "f" 'Info-follow-reference) - (define-key Info-mode-map "g" 'Info-goto-node) - (define-key Info-mode-map "h" 'Info-help) - (define-key Info-mode-map "i" 'Info-index) - (define-key Info-mode-map "l" 'Info-last) - (define-key Info-mode-map "m" 'Info-menu) - (define-key Info-mode-map "n" 'Info-next) - (define-key Info-mode-map "p" 'Info-prev) - (define-key Info-mode-map "q" 'Info-exit) - (define-key Info-mode-map "s" 'Info-search) - ;; For consistency with Rmail. - (define-key Info-mode-map "\M-s" 'Info-search) - (define-key Info-mode-map "t" 'Info-top-node) - (define-key Info-mode-map "u" 'Info-up) - (define-key Info-mode-map "," 'Info-index-next) - (define-key Info-mode-map "\177" 'Info-scroll-down) - (define-key Info-mode-map [mouse-2] 'Info-mouse-follow-nearest-node) - ) - -;; Info mode is suitable only for specially formatted data. -(put 'info-mode 'mode-class 'special) - -(defun Info-mode () - "\\<Info-mode-map> -Info mode provides commands for browsing through the Info documentation tree. -Documentation in Info is divided into \"nodes\", each of which discusses -one topic and contains references to other nodes which discuss related -topics. Info has commands to follow the references and show you other nodes. - -\\[Info-help] Invoke the Info tutorial. - -Selecting other nodes: -\\[Info-mouse-follow-nearest-node] - Follow a node reference you click on. - This works with menu items, cross references, and - the \"next\", \"previous\" and \"up\", depending on where you click. -\\[Info-next] Move to the \"next\" node of this node. -\\[Info-prev] Move to the \"previous\" node of this node. -\\[Info-up] Move \"up\" from this node. -\\[Info-menu] Pick menu item specified by name (or abbreviation). - Picking a menu item causes another node to be selected. -\\[Info-directory] Go to the Info directory node. -\\[Info-follow-reference] Follow a cross reference. Reads name of reference. -\\[Info-last] Move to the last node you were at. -\\[Info-index] Look up a topic in this file's Index and move to that node. -\\[Info-index-next] (comma) Move to the next match from a previous `i' command. - -Moving within a node: -\\[Info-scroll-up] Normally, scroll forward a full screen. If the end of the buffer is -already visible, try to go to the next menu entry, or up if there is none. -\\[Info-scroll-down] Normally, scroll backward. If the beginning of the buffer is -already visible, try to go to the previous menu entry, or up if there is none. -\\[beginning-of-buffer] Go to beginning of node. - -Advanced commands: -\\[Info-exit] Quit Info: reselect previously selected buffer. -\\[Info-edit] Edit contents of selected node. -1 Pick first item in node's menu. -2, 3, 4, 5 Pick second ... fifth item in node's menu. -\\[Info-goto-node] Move to node specified by name. - You may include a filename as well, as (FILENAME)NODENAME. -\\[universal-argument] \\[info] Move to new Info file with completion. -\\[Info-search] Search through this Info file for specified regexp, - and select the node in which the next occurrence is found. -\\[Info-next-reference] Move cursor to next cross-reference or menu item. -\\[Info-prev-reference] Move cursor to previous cross-reference or menu item." - (kill-all-local-variables) - (setq major-mode 'Info-mode) - (setq mode-name "Info") - (use-local-map Info-mode-map) - (set-syntax-table text-mode-syntax-table) - (setq local-abbrev-table text-mode-abbrev-table) - (setq case-fold-search t) - (setq buffer-read-only t) - (make-local-variable 'Info-current-file) - (make-local-variable 'Info-current-subfile) - (make-local-variable 'Info-current-node) - (make-local-variable 'Info-tag-table-marker) - (make-local-variable 'Info-history) - (make-local-variable 'Info-index-alternatives) - (if (memq (framep (selected-frame)) '(x pc)) - (progn - (make-face 'info-node) - (make-face 'info-menu-5) - (make-face 'info-xref) - (or (face-differs-from-default-p 'info-node) - (if (face-differs-from-default-p 'bold-italic) - (copy-face 'bold-italic 'info-node) - (copy-face 'bold 'info-node))) - (or (face-differs-from-default-p 'info-menu-5) - (set-face-underline-p 'info-menu-5 t)) - (or (face-differs-from-default-p 'info-xref) - (copy-face 'bold 'info-xref))) - (setq Info-fontify nil)) - (Info-set-mode-line) - (run-hooks 'Info-mode-hook)) - -(defvar Info-edit-map nil - "Local keymap used within `e' command of Info.") -(if Info-edit-map - nil - (setq Info-edit-map (nconc (make-sparse-keymap) text-mode-map)) - (define-key Info-edit-map "\C-c\C-c" 'Info-cease-edit)) - -;; Info-edit mode is suitable only for specially formatted data. -(put 'info-edit-mode 'mode-class 'special) - -(defun Info-edit-mode () - "Major mode for editing the contents of an Info node. -Like text mode with the addition of `Info-cease-edit' -which returns to Info mode for browsing. -\\{Info-edit-map}" - (use-local-map Info-edit-map) - (setq major-mode 'Info-edit-mode) - (setq mode-name "Info Edit") - (kill-local-variable 'mode-line-buffer-identification) - (setq buffer-read-only nil) - (force-mode-line-update) - (buffer-enable-undo (current-buffer)) - (run-hooks 'Info-edit-mode-hook)) - -(defun Info-edit () - "Edit the contents of this Info node. -Allowed only if variable `Info-enable-edit' is non-nil." - (interactive) - (or Info-enable-edit - (error "Editing info nodes is not enabled")) - (Info-edit-mode) - (message (substitute-command-keys - "Editing: Type \\<Info-edit-map>\\[Info-cease-edit] to return to info"))) - -(defun Info-cease-edit () - "Finish editing Info node; switch back to Info proper." - (interactive) - ;; Do this first, so nothing has changed if user C-g's at query. - (and (buffer-modified-p) - (y-or-n-p "Save the file? ") - (save-buffer)) - (use-local-map Info-mode-map) - (setq major-mode 'Info-mode) - (setq mode-name "Info") - (Info-set-mode-line) - (setq buffer-read-only t) - (force-mode-line-update) - (and (marker-position Info-tag-table-marker) - (buffer-modified-p) - (message "Tags may have changed. Use Info-tagify if necessary"))) - -(defun Info-find-emacs-command-nodes (command) - "Return a list of locations documenting COMMAND in the Emacs Info manual. -The locations are of the format used in Info-history, i.e. -\(FILENAME NODENAME BUFFERPOS\)." - (require 'info) - (let ((where '()) - (cmd-desc (concat "^\\* " (regexp-quote (symbol-name command)) - ":\\s *\\(.*\\)\\.$"))) - (save-excursion - (Info-find-node "emacs" "Command Index") - ;; Take the index node off the Info history. - (setq Info-history (cdr Info-history)) - (goto-char (point-max)) - (while (re-search-backward cmd-desc nil t) - (setq where (cons (list Info-current-file - (buffer-substring - (match-beginning 1) - (match-end 1)) - 0) - where))) - where))) - -;;;###autoload -(defun Info-goto-emacs-command-node (command) - "Go to the Info node in the Emacs manual for command COMMAND. -The command is found by looking up in Emacs manual's Command Index." - (interactive "CFind documentation for command: ") - (or (commandp command) - (signal 'wrong-type-argument (list 'commandp command))) - (let ((where (Info-find-emacs-command-nodes command))) - (if where - (let ((num-matches (length where))) - ;; Get Info running, and pop to it in another window. - (save-window-excursion - (info)) - (pop-to-buffer "*info*") - (Info-find-node (car (car where)) - (car (cdr (car where)))) - (if (> num-matches 1) - (progn - ;; Info-find-node already pushed (car where) onto - ;; Info-history. Put the other nodes that were found on - ;; the history. - (setq Info-history (nconc (cdr where) Info-history)) - (message (substitute-command-keys - "Found %d other entr%s. Use \\[Info-last] to see %s.") - (1- num-matches) - (if (> num-matches 2) "ies" "y") - (if (> num-matches 2) "them" "it"))))) - (error "Couldn't find documentation for %s." command)))) - -;;;###autoload -(defun Info-goto-emacs-key-command-node (key) - "Go to the Info node in the Emacs manual the command bound to KEY, a string. -Interactively, if the binding is execute-extended-command, a command is read. -The command is found by looking up in Emacs manual's Command Index." - (interactive "kFind documentation for key:") - (let ((command (key-binding key))) - (cond ((null command) - (message "%s is undefined" (key-description key))) - ((and (interactive-p) - (eq command 'execute-extended-command)) - (Info-goto-emacs-command-node - (read-command "Find documentation for command: "))) - (t - (Info-goto-emacs-command-node command))))) - -(defun Info-fontify-node () - (save-excursion - (let ((buffer-read-only nil)) - (goto-char (point-min)) - (if (looking-at "^File: [^,: \t]+,?[ \t]+") - (progn - (goto-char (match-end 0)) - (while - (looking-at "[ \t]*[^:, \t\n]+:[ \t]+\\([^:,\t\n]+\\),?") - (goto-char (match-end 0)) - (put-text-property (match-beginning 1) (match-end 1) - 'face 'info-xref) - (put-text-property (match-beginning 1) (match-end 1) - 'mouse-face 'highlight)))) - (goto-char (point-min)) - (while (re-search-forward "\\*Note[ \n\t]+\\([^:]*\\):" nil t) - (if (= (char-after (1- (match-beginning 0))) ?\") ; hack - nil - (put-text-property (match-beginning 1) (match-end 1) - 'face 'info-xref) - (put-text-property (match-beginning 1) (match-end 1) - 'mouse-face 'highlight))) - (goto-char (point-min)) - (if (and (search-forward "\n* Menu:" nil t) - (not (string-match "\\<Index\\>" Info-current-node)) - ;; Don't take time to annotate huge menus - (< (- (point-max) (point)) Info-fontify-maximum-menu-size)) - (let ((n 0)) - (while (re-search-forward "^\\* \\([^:\t\n]*\\):" nil t) - (setq n (1+ n)) - (if (memq n '(5 9)) ; visual aids to help with 1-9 keys - (put-text-property (match-beginning 0) - (1+ (match-beginning 0)) - 'face 'info-menu-5)) - (put-text-property (match-beginning 1) (match-end 1) - 'face 'info-node) - (put-text-property (match-beginning 1) (match-end 1) - 'mouse-face 'highlight)))) - (set-buffer-modified-p nil)))) - -(provide 'info) - -;;; info.el ends here diff --git a/gnu/usr.bin/texinfo/emacs/informat.el b/gnu/usr.bin/texinfo/emacs/informat.el deleted file mode 100644 index 2d923a1570d..00000000000 --- a/gnu/usr.bin/texinfo/emacs/informat.el +++ /dev/null @@ -1,425 +0,0 @@ -;;; informat.el --- info support functions package for Emacs - -;; Copyright (C) 1986 Free Software Foundation, Inc. - -;; Maintainer: FSF -;; Keywords: help - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - -;;; Code: - -(require 'info) - -;;;###autoload -(defun Info-tagify () - "Create or update Info-file tag table in current buffer." - (interactive) - ;; Save and restore point and restrictions. - ;; save-restrictions would not work - ;; because it records the old max relative to the end. - ;; We record it relative to the beginning. - (message "Tagifying %s ..." (file-name-nondirectory (buffer-file-name))) - (let ((omin (point-min)) - (omax (point-max)) - (nomax (= (point-max) (1+ (buffer-size)))) - (opoint (point))) - (unwind-protect - (progn - (widen) - (goto-char (point-min)) - (if (search-forward "\^_\nIndirect:\n" nil t) - (message "Cannot tagify split info file") - (let ((regexp "Node:[ \t]*\\([^,\n\t]*\\)[,\t\n]") - (case-fold-search t) - list) - (while (search-forward "\n\^_" nil t) - ;; We want the 0-origin character position of the ^_. - ;; That is the same as the Emacs (1-origin) position - ;; of the newline before it. - (let ((beg (match-beginning 0))) - (forward-line 2) - (if (re-search-backward regexp beg t) - (setq list - (cons (list (buffer-substring - (match-beginning 1) - (match-end 1)) - beg) - list))))) - (goto-char (point-max)) - (forward-line -8) - (let ((buffer-read-only nil)) - (if (search-forward "\^_\nEnd tag table\n" nil t) - (let ((end (point))) - (search-backward "\nTag table:\n") - (beginning-of-line) - (delete-region (point) end))) - (goto-char (point-max)) - (insert "\^_\f\nTag table:\n") - (move-marker Info-tag-table-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"))))) - (goto-char opoint) - (narrow-to-region omin (if nomax (1+ (buffer-size)) - (min omax (point-max)))))) - (message "Tagifying %s ... done" (file-name-nondirectory (buffer-file-name)))) - -;;;###autoload -(defun Info-split () - "Split an info file into an indirect file plus bounded-size subfiles. -Each subfile will be up to 50,000 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")) - (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")) - (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))) - (search-forward "\^_" nil 'move) - (setq subfiles - (cons (list (+ start chars-deleted) - (concat (file-name-nondirectory filename) - (format "-%d" subfile-number))) - subfiles)) - ;; Put a newline at end of split file, to make Unix happier. - (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)))) - (while subfiles - (goto-char start) - (insert (nth 1 (car subfiles)) - (format ": %d" (1- (car (car subfiles)))) - "\n") - (setq subfiles (cdr subfiles))) - (goto-char start) - (insert "\^_\nIndirect:\n") - (search-forward "\nTag Table:\n") - (insert "(Indirect)\n"))) - -;;;###autoload -(defun Info-validate () - "Check current buffer for validity as an Info file. -Check that every node pointer points to an existing node." - (interactive) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (if (search-forward "\nTag table:\n(Indirect)\n" nil t) - (error "Don't yet know how to validate indirect info files: \"%s\"" - (buffer-name (current-buffer)))) - (goto-char (point-min)) - (let ((allnodes '(("*"))) - (regexp "Node:[ \t]*\\([^,\n\t]*\\)[,\t\n]") - (case-fold-search t) - (tags-losing nil) - (lossages ())) - (while (search-forward "\n\^_" nil t) - (forward-line 1) - (let ((beg (point))) - (forward-line 1) - (if (re-search-backward regexp beg t) - (let ((name (downcase - (buffer-substring - (match-beginning 1) - (progn - (goto-char (match-end 1)) - (skip-chars-backward " \t") - (point)))))) - (if (assoc name allnodes) - (setq lossages - (cons (list name "Duplicate node-name" nil) - lossages)) - (setq allnodes - (cons (list name - (progn - (end-of-line) - (and (re-search-backward - "prev[ious]*:" beg t) - (progn - (goto-char (match-end 0)) - (downcase - (Info-following-node-name))))) - beg) - allnodes))))))) - (goto-char (point-min)) - (while (search-forward "\n\^_" nil t) - (forward-line 1) - (let ((beg (point)) - thisnode next) - (forward-line 1) - (if (re-search-backward regexp beg t) - (save-restriction - (search-forward "\n\^_" nil 'move) - (narrow-to-region beg (point)) - (setq thisnode (downcase - (buffer-substring - (match-beginning 1) - (progn - (goto-char (match-end 1)) - (skip-chars-backward " \t") - (point))))) - (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)))) - (setq lossages - (cons (list next - "should have Previous" - thisnode) - lossages)))) - (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 (re-search-forward "\n* Menu:" nil t) - (while (re-search-forward "\n\\* " nil t) - (Info-validate-node-name - (concat "invalid menu item " - (buffer-substring (point) - (save-excursion - (skip-chars-forward "^:") - (point)))) - (Info-extract-menu-node-name)))) - (goto-char (point-min)) - (while (re-search-forward "\\*note[ \n]*[^:\t]*:" nil t) - (goto-char (+ (match-beginning 0) 5)) - (skip-chars-forward " \n") - (Info-validate-node-name - (concat "invalid reference " - (buffer-substring (point) - (save-excursion - (skip-chars-forward "^:") - (point)))) - (Info-extract-menu-node-name "Bad format cross-reference"))))))) - (setq tags-losing (not (Info-validate-tags-table))) - (if (or lossages tags-losing) - (with-output-to-temp-buffer " *problems in info file*" - (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. - (save-excursion - (if (get-buffer " *problems in info file*") - (progn - (set-buffer " *problems in info file*") - (kill-buffer (current-buffer))))) - (message "File appears valid")))))) - -(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) - (setq lossages - (cons (list thisnode kind name) lossages)))) - name) - -(defun Info-validate-tags-table () - (goto-char (point-min)) - (if (not (search-forward "\^_\nEnd tag table\n" nil t)) - t - (not (catch 'losing - (let* ((end (match-beginning 0)) - (start (progn (search-backward "\nTag table:\n") - (1- (match-end 0)))) - tem) - (setq tem allnodes) - (while tem - (goto-char start) - (or (equal (car (car tem)) "*") - (search-forward (concat "Node: " - (car (car tem)) - "\177") - end t) - (throw 'losing 'x)) - (setq tem (cdr tem))) - (goto-char (1+ start)) - (while (looking-at ".*Node: \\(.*\\)\177\\([0-9]+\\)$") - (setq tem (downcase (buffer-substring - (match-beginning 1) - (match-end 1)))) - (setq tem (assoc tem allnodes)) - (if (or (not tem) - (< 1000 (progn - (goto-char (match-beginning 2)) - (setq tem (- (car (cdr (cdr tem))) - (read (current-buffer)))) - (if (> tem 0) tem (- tem))))) - (throw 'losing 'y))) - (forward-line 1)) - (or (looking-at "End tag table\n") - (throw 'losing 'z)) - nil)))) - -;;;###autoload -(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)) - (let ((error 0) - file - (files ())) - (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 (directory-files file) - (cdr command-line-args-left)))) - (t - (setq files (cons file files) - command-line-args-left (cdr command-line-args-left))))) - (while files - (setq file (car files) - files (cdr files)) - (let ((lose nil)) - (condition-case err - (progn - (if buffer-file-name (kill-buffer (current-buffer))) - (find-file file) - (buffer-disable-undo (current-buffer)) - (set-buffer-modified-p nil) - (fundamental-mode) - (let ((case-fold-search nil)) - (goto-char (point-max)) - (cond ((search-backward "\n\^_\^L\nTag table:\n" nil t) - (message "%s already tagified" file)) - ((< (point-max) 30000) - (message "%s too small to bother tagifying" file)) - (t - (Info-tagify)))) - (let ((loss-name " *problems in info file*")) - (message "Checking validity of info file %s..." file) - (if (get-buffer loss-name) - (kill-buffer loss-name)) - (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-substring (point-min) (point-max)))) - (message "----------------------------------------------------------------------") - (setq error 1 lose t))) - (if (and (buffer-modified-p) - (not lose)) - (progn (message "Saving modified %s" file) - (save-buffer)))) - (error (message ">> Error: %s" (prin1-to-string err)))))) - (kill-emacs error)))) - -;;; informat.el ends here diff --git a/gnu/usr.bin/texinfo/emacs/makeinfo.el b/gnu/usr.bin/texinfo/emacs/makeinfo.el deleted file mode 100644 index 61269de9e2c..00000000000 --- a/gnu/usr.bin/texinfo/emacs/makeinfo.el +++ /dev/null @@ -1,245 +0,0 @@ -;;;; makeinfo.el -- run makeinfo conveniently. -;;; Copyright (C) 1991, 1993 Free Software Foundation, Inc. - -;;; Author: Robert J. Chassell -;;; Maintainer: FSF - -;;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - -;;; Commentary: - -;;; The Texinfo mode `makeinfo' related commands are: - -;; makeinfo-region to run makeinfo on the current region. -;; makeinfo-buffer to run makeinfo on the current buffer, or -;; with optional prefix arg, on current region -;; kill-compilation to kill currently running makeinfo job -;; makeinfo-recenter-makeinfo-buffer to redisplay *compilation* buffer - -;;; Keybindings (defined in `texinfo.el') - -;; makeinfo bindings -; (define-key texinfo-mode-map "\C-c\C-m\C-r" 'makeinfo-region) -; (define-key texinfo-mode-map "\C-c\C-m\C-b" 'makeinfo-buffer) -; (define-key texinfo-mode-map "\C-c\C-m\C-k" 'kill-compilation) -; (define-key texinfo-mode-map "\C-c\C-m\C-l" -; 'makeinfo-recenter-compilation-buffer) - -;;; Code: - -;;; Variables used by `makeinfo' - -(require 'compile) - -(defvar makeinfo-run-command "makeinfo" - "*Command used to run `makeinfo' subjob. -The name of the file is appended to this string, separated by a space.") - -(defvar makeinfo-options "--fill-column=70" - "*String containing options for running `makeinfo'. -Do not include `--footnote-style' or `--paragraph-indent'; -the proper way to specify those is with the Texinfo commands -`@footnotestyle` and `@paragraphindent'.") - -(require 'texinfo) - -(defvar makeinfo-compilation-process nil - "Process that runs `makeinfo'. Should start out nil.") - -(defvar makeinfo-temp-file nil - "Temporary file name used for text being sent as input to `makeinfo'.") - -(defvar makeinfo-output-file-name nil - "Info file name used for text output by `makeinfo'.") - - -;;; The `makeinfo' function definitions - -(defun makeinfo-region (region-beginning region-end) - "Make Info file from region of current Texinfo file, and switch to it. - -This command does not offer the `next-error' feature since it would -apply to a temporary file, not the original; use the `makeinfo-buffer' -command to gain use of `next-error'." - - (interactive "r") - (let (filename-or-header - filename-or-header-beginning - filename-or-header-end) - ;; Cannot use `let' for makeinfo-temp-file or - ;; makeinfo-output-file-name since `makeinfo-compilation-sentinel' - ;; needs them. - - (setq makeinfo-temp-file - (concat - (make-temp-name - (substring (buffer-file-name) - 0 - (or (string-match "\\.tex" (buffer-file-name)) - (length (buffer-file-name))))) - ".texinfo")) - - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (let ((search-end (save-excursion (forward-line 100) (point)))) - ;; Find and record the Info filename, - ;; or else explain that a filename is needed. - (if (re-search-forward - "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*" - search-end t) - (setq makeinfo-output-file-name - (buffer-substring (match-beginning 1) (match-end 1))) - (error - "The texinfo file needs a line saying: @setfilename <name>")) - - ;; Find header and specify its beginning and end. - (goto-char (point-min)) - (if (and - (prog1 - (search-forward tex-start-of-header search-end t) - (beginning-of-line) - ;; Mark beginning of header. - (setq filename-or-header-beginning (point))) - (prog1 - (search-forward tex-end-of-header nil t) - (beginning-of-line) - ;; Mark end of header - (setq filename-or-header-end (point)))) - - ;; Insert the header into the temporary file. - (write-region - (min filename-or-header-beginning region-beginning) - filename-or-header-end - makeinfo-temp-file nil nil) - - ;; Else no header; insert @filename line into temporary file. - (goto-char (point-min)) - (search-forward "@setfilename" search-end t) - (beginning-of-line) - (setq filename-or-header-beginning (point)) - (forward-line 1) - (setq filename-or-header-end (point)) - (write-region - (min filename-or-header-beginning region-beginning) - filename-or-header-end - makeinfo-temp-file nil nil)) - - ;; Insert the region into the file. - (write-region - (max region-beginning filename-or-header-end) - region-end - makeinfo-temp-file t nil) - - ;; Run the `makeinfo-compile' command in the *compilation* buffer - (save-excursion - (makeinfo-compile - (concat makeinfo-run-command - " " - makeinfo-options - " " - makeinfo-temp-file) - "Use `makeinfo-buffer' to gain use of the `next-error' command" - nil))))))) - -;;; Actually run makeinfo. COMMAND is the command to run. -;;; ERROR-MESSAGE is what to say when next-error can't find another error. -;;; If PARSE-ERRORS is non-nil, do try to parse error messages. -(defun makeinfo-compile (command error-message parse-errors) - (let ((buffer - (compile-internal command error-message nil - (and (not parse-errors) - ;; If we do want to parse errors, pass nil. - ;; Otherwise, use this function, which won't - ;; ever find any errors. - '(lambda (&rest ignore) - (setq compilation-error-list nil)))))) - (set-process-sentinel (get-buffer-process buffer) - 'makeinfo-compilation-sentinel))) - -;; Delete makeinfo-temp-file after processing is finished, -;; and visit Info file. -;; This function is called when the compilation process changes state. -;; Based on `compilation-sentinel' in compile.el -(defun makeinfo-compilation-sentinel (proc msg) - (compilation-sentinel proc msg) - (if (and makeinfo-temp-file (file-exists-p makeinfo-temp-file)) - (delete-file makeinfo-temp-file)) - ;; Always use the version on disk. - (if (get-file-buffer makeinfo-output-file-name) - (progn (set-buffer makeinfo-output-file-name) - (revert-buffer t t)) - (find-file makeinfo-output-file-name)) - (goto-char (point-min))) - -(defun makeinfo-buffer () - "Make Info file from current buffer. - -Use the \\[next-error] command to move to the next error -\(if there are errors\)." - - (interactive) - (cond ((null buffer-file-name) - (error "Buffer not visiting any file")) - ((buffer-modified-p) - (if (y-or-n-p "Buffer modified; do you want to save it? ") - (save-buffer)))) - - ;; Find and record the Info filename, - ;; or else explain that a filename is needed. - (save-excursion - (goto-char (point-min)) - (let ((search-end (save-excursion (forward-line 100) (point)))) - (if (re-search-forward - "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*" - search-end t) - (setq makeinfo-output-file-name - (buffer-substring (match-beginning 1) (match-end 1))) - (error - "The texinfo file needs a line saying: @setfilename <name>")))) - - (save-excursion - (makeinfo-compile - (concat makeinfo-run-command " " makeinfo-options - " " buffer-file-name) - "No more errors." - t))) - -(defun makeinfo-recenter-compilation-buffer (linenum) - "Redisplay `*compilation*' buffer so most recent output can be seen. -The last line of the buffer is displayed on -line LINE of the window, or centered if LINE is nil." - (interactive "P") - (let ((makeinfo-buffer (get-buffer "*compilation*")) - (old-buffer (current-buffer))) - (if (null makeinfo-buffer) - (message "No *compilation* buffer") - (pop-to-buffer makeinfo-buffer) - (bury-buffer makeinfo-buffer) - (goto-char (point-max)) - (recenter (if linenum - (prefix-numeric-value linenum) - (/ (window-height) 2))) - (pop-to-buffer old-buffer) - ))) - -;;; Place `provide' at end of file. -(provide 'makeinfo) - -;;; makeinfo.el ends here - diff --git a/gnu/usr.bin/texinfo/emacs/new-useful-setqs b/gnu/usr.bin/texinfo/emacs/new-useful-setqs deleted file mode 100644 index 4241ae429ef..00000000000 --- a/gnu/usr.bin/texinfo/emacs/new-useful-setqs +++ /dev/null @@ -1,180 +0,0 @@ -;; -*- Mode: Emacs-Lisp -*- - -;; This is the `new-useful-setqs' file -;; This overrides old defvars since they were revised. - -(setq texinfmt-version "2.35 of 10 September 1996") - -(setq texinfo-master-menu-header - "\n@detailmenu\n --- The Detailed Node Listing ---\n") - -(setq texinfo-environment-regexp - (concat - "^@" - "\\(" - "cartouche\\|" - "display\\|" - "end\\|" - "enumerate\\|" - "example\\|" - "f?table\\|" - "flushleft\\|" - "flushright\\|" - "format\\|" - "group\\|" - "ifhtml\\|" - "ifinfo\\|" - "iftex\\|" - "ignore\\|" - "itemize\\|" - "lisp\\|" - "macro\\|" - "multitable\\|" - "quotation\\|" - "smallexample\\|" - "smalllisp\\|" - "tex" - "\\)") -) - -(setq texinfo-no-refill-regexp - (concat - "^@" - "\\(" - "example\\|" - "smallexample\\|" - "lisp\\|" - "smalllisp\\|" - "display\\|" - "format\\|" - "flushleft\\|" - "flushright\\|" - "menu\\|" - "multitable\\|" - "titlepage\\|" - "iftex\\|" - "ifhtml\\|" - "tex\\|" - "html" - "\\)")) - - -(setq texinfo-accent-commands - (concat - "@OE\\|" - "@oe\\|" - "@AA\\|" - "@aa\\|" - "@AE\\|" - "@ae\\|" - "@ss\\|" - "@^\\|" - "@`\\|" - "@'\\|" - "@\"\\|" - "@,\\|" - "@=\\|" - "@~\\|" - "@questiondown{\\|" - "@exclamdown{\\|" - "@L{\\|" - "@l{\\|" - "@O{\\|" - "@o{\\|" - "@dotaccent{\\|" - "@ubaraccent{\\|" - "@d{\\|" - "@H{\\|" - "@ringaccent{\\|" - "@tieaccent{\\|" - "@u{\\|" - "@v{\\|" - "@dotless{" - )) - -(setq texinfo-part-of-para-regexp - (concat - "^@" - "\\(" - "b{\\|" - "bullet{\\|" - "cite{\\|" - "code{\\|" - "emph{\\|" - "equiv{\\|" - "error{\\|" - "expansion{\\|" - "file{\\|" - "i{\\|" - "inforef{\\|" - "kbd{\\|" - "key{\\|" - "lisp{\\|" - "email{\\|" - "minus{\\|" - "point{\\|" - "print{\\|" - "pxref{\\|" - "r{\\|" - "ref{\\|" - "result{\\|" - "samp{\\|" - "sc{\\|" - "t{\\|" - "TeX{\\|" - "today{\\|" - "url{\\|" - "var{\\|" - "w{\\|" - "xref{\\|" - "@-\\|" ; @- is a descretionary hyphen (not an accent) (a noop). - texinfo-accent-commands - "\\)" - )) - -(setq texinfo-raisesections-alist - '((@chapter . @chapter) ; Cannot go higher - (@unnumbered . @unnumbered) - (@centerchap . @unnumbered) - - (@majorheading . @majorheading) - (@chapheading . @chapheading) - (@appendix . @appendix) - - (@section . @chapter) - (@unnumberedsec . @unnumbered) - (@heading . @chapheading) - (@appendixsec . @appendix) - - (@subsection . @section) - (@unnumberedsubsec . @unnumberedsec) - (@subheading . @heading) - (@appendixsubsec . @appendixsec) - - (@subsubsection . @subsection) - (@unnumberedsubsubsec . @unnumberedsubsec) - (@subsubheading . @subheading) - (@appendixsubsubsec . @appendixsubsec))) - -(setq texinfo-lowersections-alist - '((@chapter . @section) - (@unnumbered . @unnumberedsec) - (@centerchap . @unnumberedsec) - (@majorheading . @heading) - (@chapheading . @heading) - (@appendix . @appendixsec) - - (@section . @subsection) - (@unnumberedsec . @unnumberedsubsec) - (@heading . @subheading) - (@appendixsec . @appendixsubsec) - - (@subsection . @subsubsection) - (@unnumberedsubsec . @unnumberedsubsubsec) - (@subheading . @subsubheading) - (@appendixsubsec . @appendixsubsubsec) - - (@subsubsection . @subsubsection) ; Cannot go lower. - (@unnumberedsubsubsec . @unnumberedsubsubsec) - (@subsubheading . @subsubheading) - (@appendixsubsubsec . @appendixsubsubsec))) diff --git a/gnu/usr.bin/texinfo/emacs/texinfmt.el b/gnu/usr.bin/texinfo/emacs/texinfmt.el deleted file mode 100644 index d24e3d7c683..00000000000 --- a/gnu/usr.bin/texinfo/emacs/texinfmt.el +++ /dev/null @@ -1,3067 +0,0 @@ -;;;; texinfmt.el -;;; Copyright (C) 1985, 1986, 1988, 1990, 1991, -;;; 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - -;; Maintainer: Robert J. Chassell <bug-texinfo@prep.ai.mit.edu> - -;;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - -;;; Code: - -;;; Emacs lisp functions to convert Texinfo files to Info files. - -(defvar texinfmt-version "2.34 of 7 June 1995") - -;;; Variable definitions - -(require 'texinfo) ; So `texinfo-footnote-style' is defined. -(require 'texnfo-upd) ; So `texinfo-section-types-regexp' is defined. - -(defvar texinfo-format-syntax-table nil) - -(defvar texinfo-vindex) -(defvar texinfo-findex) -(defvar texinfo-cindex) -(defvar texinfo-pindex) -(defvar texinfo-tindex) -(defvar texinfo-kindex) -(defvar texinfo-last-node) -(defvar texinfo-node-names) -(defvar texinfo-enclosure-list) -(defvar texinfo-alias-list) - -(defvar texinfo-command-start) -(defvar texinfo-command-end) -(defvar texinfo-command-name) -(defvar texinfo-defun-type) -(defvar texinfo-last-node-pos) -(defvar texinfo-stack) -(defvar texinfo-short-index-cmds-alist) -(defvar texinfo-short-index-format-cmds-alist) -(defvar texinfo-format-filename) -(defvar texinfo-footnote-number) -(defvar texinfo-start-of-header) -(defvar texinfo-end-of-header) -(defvar texinfo-raisesections-alist) -(defvar texinfo-lowersections-alist) - -;;; Syntax table - -(if texinfo-format-syntax-table - nil - (setq texinfo-format-syntax-table (make-syntax-table)) - (modify-syntax-entry ?\" " " texinfo-format-syntax-table) - (modify-syntax-entry ?\\ " " texinfo-format-syntax-table) - (modify-syntax-entry ?@ "\\" texinfo-format-syntax-table) - (modify-syntax-entry ?\^q "\\" texinfo-format-syntax-table) - (modify-syntax-entry ?\[ "." texinfo-format-syntax-table) - (modify-syntax-entry ?\] "." texinfo-format-syntax-table) - (modify-syntax-entry ?\( "." texinfo-format-syntax-table) - (modify-syntax-entry ?\) "." texinfo-format-syntax-table) - (modify-syntax-entry ?{ "(}" texinfo-format-syntax-table) - (modify-syntax-entry ?} "){" texinfo-format-syntax-table) - (modify-syntax-entry ?\' "." texinfo-format-syntax-table)) - - -;;; Top level buffer and region formatting functions - -;;;###autoload -(defun texinfo-format-buffer (&optional notagify) - "Process the current buffer as texinfo code, into an Info file. -The Info file output is generated in a buffer visiting the Info file -names specified in the @setfilename command. - -Non-nil argument (prefix, if interactive) means don't make tag table -and don't split the file if large. You can use Info-tagify and -Info-split to do these manually." - (interactive "P") - (let ((lastmessage "Formatting Info file...")) - (message lastmessage) - (texinfo-format-buffer-1) - (if notagify - nil - (if (> (buffer-size) 30000) - (progn - (message (setq lastmessage "Making tags table for Info file...")) - (Info-tagify))) - (if (> (buffer-size) 100000) - (progn - (message (setq lastmessage "Splitting Info file...")) - (Info-split)))) - (message (concat lastmessage - (if (interactive-p) "done. Now save it." "done."))))) - -(defvar texinfo-region-buffer-name "*Info Region*" - "*Name of the temporary buffer used by \\[texinfo-format-region].") - -;;;###autoload -(defun texinfo-format-region (region-beginning region-end) - "Convert the current region of the Texinfo file to Info format. -This lets you see what that part of the file will look like in Info. -The command is bound to \\[texinfo-format-region]. The text that is -converted to Info is stored in a temporary buffer." - (interactive "r") - (message "Converting region to Info format...") - (let (texinfo-command-start - texinfo-command-end - texinfo-command-name - texinfo-vindex - texinfo-findex - texinfo-cindex - texinfo-pindex - texinfo-tindex - texinfo-kindex - texinfo-stack - (texinfo-format-filename "") - texinfo-example-start - texinfo-last-node-pos - texinfo-last-node - texinfo-node-names - (texinfo-footnote-number 0) - last-input-buffer - (fill-column-for-info fill-column) - (input-buffer (current-buffer)) - (input-directory default-directory) - (header-text "") - (header-beginning 1) - (header-end 1)) - -;;; Copy lines between beginning and end of header lines, -;;; if any, or else copy the `@setfilename' line, if any. - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (let ((search-end (save-excursion (forward-line 100) (point)))) - (if (or - ;; Either copy header text. - (and - (prog1 - (search-forward tex-start-of-header search-end t) - (forward-line 1) - ;; Mark beginning of header. - (setq header-beginning (point))) - (prog1 - (search-forward tex-end-of-header nil t) - (beginning-of-line) - ;; Mark end of header - (setq header-end (point)))) - ;; Or copy @filename line. - (prog2 - (goto-char (point-min)) - (search-forward "@setfilename" search-end t) - (beginning-of-line) - (setq header-beginning (point)) - (forward-line 1) - (setq header-end (point)))) - - ;; Copy header - (setq header-text - (buffer-substring - (min header-beginning region-beginning) - header-end)))))) - -;;; Find a buffer to use. - (switch-to-buffer (get-buffer-create texinfo-region-buffer-name)) - (erase-buffer) - ;; Insert the header into the buffer. - (insert header-text) - ;; Insert the region into the buffer. - (insert-buffer-substring - input-buffer - (max region-beginning header-end) - region-end) - ;; Make sure region ends in a newline. - (or (= (preceding-char) ?\n) - (insert "\n")) - - (goto-char (point-min)) - (texinfo-mode) - (message "Converting region to Info format...") - (setq fill-column fill-column-for-info) - ;; Install a syntax table useful for scanning command operands. - (set-syntax-table texinfo-format-syntax-table) - - ;; Insert @include files so `texinfo-raise-lower-sections' can - ;; work on them without losing track of multiple - ;; @raise/@lowersections commands. - (while (re-search-forward "^@include" nil t) - (setq texinfo-command-end (point)) - (let ((filename (concat input-directory - (texinfo-parse-line-arg)))) - (re-search-backward "^@include") - (delete-region (point) (save-excursion (forward-line 1) (point))) - (message "Reading included file: %s" filename) - (save-excursion - (save-restriction - (narrow-to-region - (point) - (+ (point) (car (cdr (insert-file-contents filename))))) - (goto-char (point-min)) - ;; Remove `@setfilename' line from included file, if any, - ;; so @setfilename command not duplicated. - (if (re-search-forward - "^@setfilename" (save-excursion (forward-line 100) (point)) t) - (progn - (beginning-of-line) - (delete-region - (point) (save-excursion (forward-line 1) (point))))))))) - - ;; Raise or lower level of each section, if necessary. - (goto-char (point-min)) - (texinfo-raise-lower-sections) - ;; Append @refill to appropriate paragraphs for filling. - (goto-char (point-min)) - (texinfo-append-refill) - ;; If the region includes the effective end of the data, - ;; discard everything after that. - (goto-char (point-max)) - (if (re-search-backward "^@bye" nil t) - (delete-region (point) (point-max))) - ;; Make sure buffer ends in a newline. - (or (= (preceding-char) ?\n) - (insert "\n")) - ;; Don't use a previous value of texinfo-enclosure-list. - (setq texinfo-enclosure-list nil) - (setq texinfo-alias-list nil) - - (goto-char (point-min)) - (if (looking-at "\\\\input[ \t]+texinfo") - (delete-region (point) (save-excursion (forward-line 1) (point)))) - - ;; Insert Info region title text. - (goto-char (point-min)) - (if (search-forward - "@setfilename" (save-excursion (forward-line 100) (point)) t) - (progn - (setq texinfo-command-end (point)) - (beginning-of-line) - (setq texinfo-command-start (point)) - (let ((arg (texinfo-parse-arg-discard))) - (insert " " - texinfo-region-buffer-name - " buffer for: `") - (insert (file-name-nondirectory (expand-file-name arg))) - (insert "', -*-Text-*-\n"))) - ;; Else no `@setfilename' line - (insert " " - texinfo-region-buffer-name - " buffer -*-Text-*-\n")) - (insert "produced by `texinfo-format-region'\n" - "from a region in: " - (if (buffer-file-name input-buffer) - (concat "`" - (file-name-sans-versions - (file-name-nondirectory - (buffer-file-name input-buffer))) - "'") - (concat "buffer `" (buffer-name input-buffer) "'")) - "\nusing `texinfmt.el' version " - texinfmt-version - ".\n\n") - - ;; Now convert for real. - (goto-char (point-min)) - (texinfo-format-scan) - (goto-char (point-min)) - - (message "Done."))) - - -;;; Primary internal formatting function for the whole buffer. - -(defun texinfo-format-buffer-1 () - (let (texinfo-format-filename - texinfo-example-start - texinfo-command-start - texinfo-command-end - texinfo-command-name - texinfo-last-node - texinfo-last-node-pos - texinfo-vindex - texinfo-findex - texinfo-cindex - texinfo-pindex - texinfo-tindex - texinfo-kindex - texinfo-stack - texinfo-node-names - (texinfo-footnote-number 0) - last-input-buffer - outfile - (fill-column-for-info fill-column) - (input-buffer (current-buffer)) - (input-directory default-directory)) - (setq texinfo-enclosure-list nil) - (setq texinfo-alias-list nil) - (save-excursion - (goto-char (point-min)) - (or (search-forward "@setfilename" nil t) - (error "Texinfo file needs an `@setfilename FILENAME' line.")) - (setq texinfo-command-end (point)) - (setq outfile (texinfo-parse-line-arg))) - (find-file outfile) - (texinfo-mode) - (setq fill-column fill-column-for-info) - (set-syntax-table texinfo-format-syntax-table) - (erase-buffer) - (insert-buffer-substring input-buffer) - (message "Converting %s to Info format..." (buffer-name input-buffer)) - - ;; Insert @include files so `texinfo-raise-lower-sections' can - ;; work on them without losing track of multiple - ;; @raise/@lowersections commands. - (goto-char (point-min)) - (while (re-search-forward "^@include" nil t) - (setq texinfo-command-end (point)) - (let ((filename (concat input-directory - (texinfo-parse-line-arg)))) - (re-search-backward "^@include") - (delete-region (point) (save-excursion (forward-line 1) (point))) - (message "Reading included file: %s" filename) - (save-excursion - (save-restriction - (narrow-to-region - (point) - (+ (point) (car (cdr (insert-file-contents filename))))) - (goto-char (point-min)) - ;; Remove `@setfilename' line from included file, if any, - ;; so @setfilename command not duplicated. - (if (re-search-forward - "^@setfilename" - (save-excursion (forward-line 100) (point)) t) - (progn - (beginning-of-line) - (delete-region - (point) (save-excursion (forward-line 1) (point))))))))) - ;; Raise or lower level of each section, if necessary. - (goto-char (point-min)) - (texinfo-raise-lower-sections) - ;; Append @refill to appropriate paragraphs - (goto-char (point-min)) - (texinfo-append-refill) - (goto-char (point-min)) - (search-forward "@setfilename") - (beginning-of-line) - (delete-region (point-min) (point)) - ;; Remove @bye at end of file, if it is there. - (goto-char (point-max)) - (if (search-backward "@bye" nil t) - (delete-region (point) (point-max))) - ;; Make sure buffer ends in a newline. - (or (= (preceding-char) ?\n) - (insert "\n")) - ;; Scan the whole buffer, converting to Info format. - (texinfo-format-scan) - ;; Return data for indices. - (goto-char (point-min)) - (list outfile - texinfo-vindex texinfo-findex texinfo-cindex - texinfo-pindex texinfo-tindex texinfo-kindex))) - - -;;; Perform non-@-command file conversions: quotes and hyphens - -(defun texinfo-format-convert (min max) - ;; Convert left and right quotes to typewriter font quotes. - (goto-char min) - (while (search-forward "``" max t) - (replace-match "\"")) - (goto-char min) - (while (search-forward "''" max t) - (replace-match "\"")) - ;; Convert three hyphens in a row to two. - (goto-char min) - (while (re-search-forward "\\( \\|\\w\\)\\(---\\)\\( \\|\\w\\)" max t) - (delete-region (1+ (match-beginning 2)) (+ 2 (match-beginning - 2))))) - - -;;; Handle paragraph filling - -(defvar texinfo-no-refill-regexp - "^@\\(example\\|smallexample\\|lisp\\|smalllisp\\|display\\|format\\|flushleft\\|flushright\\|menu\\|titlepage\\|iftex\\|ifhtml\\|tex\\|html\\)" - "Regexp specifying environments in which paragraphs are not filled.") - -(defvar texinfo-part-of-para-regexp - "^@\\(b{\\|bullet{\\|cite{\\|code{\\|emph{\\|equiv{\\|error{\\|expansion{\\|file{\\|i{\\|inforef{\\|kbd{\\|key{\\|lisp{\\|minus{\\|point{\\|print{\\|pxref{\\|r{\\|ref{\\|result{\\|samp{\\|sc{\\|t{\\|TeX{\\|today{\\|var{\\|w{\\|xref{\\)" - "Regexp specifying @-commands found within paragraphs.") - -(defun texinfo-append-refill () - "Append @refill at end of each paragraph that should be filled. -Do not append @refill to paragraphs within @example and similar environments. -Do not append @refill to paragraphs containing @w{TEXT} or @*." - - ;; It is necessary to append @refill before other processing because - ;; the other processing removes information that tells Texinfo - ;; whether the text should or should not be filled. - - (while (< (point) (point-max)) - (let ((refill-blank-lines "^[ \t\n]*$") - (case-fold-search nil)) ; Don't confuse @TeX and @tex.... - (beginning-of-line) - ;; 1. Skip over blank lines; - ;; skip over lines beginning with @-commands, - ;; but do not skip over lines - ;; that are no-refill environments such as @example or - ;; that begin with within-paragraph @-commands such as @code. - (while (and (looking-at (concat "^@\\|^\\\\\\|" refill-blank-lines)) - (not (looking-at - (concat - "\\(" - texinfo-no-refill-regexp - "\\|" - texinfo-part-of-para-regexp - "\\)"))) - (< (point) (point-max))) - (forward-line 1)) - ;; 2. Skip over @example and similar no-refill environments. - (if (looking-at texinfo-no-refill-regexp) - (let ((environment - (buffer-substring (match-beginning 1) (match-end 1)))) - (progn (re-search-forward (concat "^@end " environment) nil t) - (forward-line 1))) - ;; 3. Do not refill a paragraph containing @w or @* - (if (or - (>= (point) (point-max)) - (re-search-forward - "@w{\\|@\\*" (save-excursion (forward-paragraph) (point)) t)) - ;; Go to end of paragraph and do nothing. - (forward-paragraph) - ;; 4. Else go to end of paragraph and insert @refill - (forward-paragraph) - (forward-line -1) - (end-of-line) - (delete-region - (point) - (save-excursion (skip-chars-backward " \t") (point))) - ;; `looking-at-backward' not available in v. 18.57 - ;; (if (not (looking-at-backward "@refill\\|@bye")) ;) - (if (not (re-search-backward - "@refill\\|@bye" - (save-excursion (beginning-of-line) (point)) - t)) - (insert "@refill")) - (forward-line 1)))))) - - -;;; Handle `@raisesections' and `@lowersections' commands - -;; These commands change the hierarchical level of chapter structuring -;; commands. -;; -;; @raisesections changes @subsection to @section, -;; @section to @chapter, -;; etc. -;; -;; @lowersections changes @chapter to @section -;; @subsection to @subsubsection, -;; etc. -;; -;; An @raisesections/@lowersections command changes only those -;; structuring commands that follow the @raisesections/@lowersections -;; command. -;; -;; Repeated @raisesections/@lowersections continue to raise or lower -;; the heading level. -;; -;; An @lowersections command cancels an @raisesections command, and -;; vice versa. -;; -;; You cannot raise or lower "beyond" chapters or subsubsections, but -;; trying to do so does not elicit an error---you just get more -;; headings that mean the same thing as you keep raising or lowering -;; (for example, after a single @raisesections, both @chapter and -;; @section produce chapter headings). - -(defun texinfo-raise-lower-sections () - "Raise or lower the hierarchical level of chapters, sections, etc. - -This function acts according to `@raisesections' and `@lowersections' -commands in the Texinfo file. - -For example, an `@lowersections' command is useful if you wish to -include what is written as an outer or standalone Texinfo file in -another Texinfo file as an inner, included file. The `@lowersections' -command changes chapters to sections, sections to subsections and so -on. - -@raisesections changes @subsection to @section, - @section to @chapter, - @heading to @chapheading, - etc. - -@lowersections changes @chapter to @section, - @subsection to @subsubsection, - @heading to @subheading, - etc. - -An `@raisesections' or `@lowersections' command changes only those -structuring commands that follow the `@raisesections' or -`@lowersections' command. - -An `@lowersections' command cancels an `@raisesections' command, and -vice versa. - -Repeated use of the commands continue to raise or lower the hierarchical -level a step at a time. - -An attempt to raise above `chapters' reproduces chapter commands; an -attempt to lower below subsubsections reproduces subsubsection -commands." - - ;; `texinfo-section-types-regexp' is defined in `texnfo-upd.el'; - ;; it is a regexp matching chapter, section, other headings - ;; (but not the top node). - - (let (type (level 0)) - (while - (re-search-forward - (concat - "\\(\\(^@\\(raise\\|lower\\)sections\\)\\|\\(" - texinfo-section-types-regexp - "\\)\\)") - nil t) - (beginning-of-line) - (save-excursion (setq type (read (current-buffer)))) - (cond - - ;; 1. Increment level - ((eq type '@raisesections) - (setq level (1+ level)) - (delete-region - (point) (save-excursion (forward-line 1) (point)))) - - ;; 2. Decrement level - ((eq type '@lowersections) - (setq level (1- level)) - (delete-region - (point) (save-excursion (forward-line 1) (point)))) - - ;; Now handle structuring commands - ((cond - - ;; 3. Raise level when positive - ((> level 0) - (let ((count level) - (new-level type)) - (while (> count 0) - (setq new-level - (cdr (assq new-level texinfo-raisesections-alist))) - (setq count (1- count))) - (kill-word 1) - (insert (symbol-name new-level)))) - - ;; 4. Do nothing except move point when level is zero - ((= level 0) (forward-line 1)) - - ;; 5. Lower level when positive - ((< level 0) - (let ((count level) - (new-level type)) - (while (< count 0) - (setq new-level - (cdr (assq new-level texinfo-lowersections-alist))) - (setq count (1+ count))) - (kill-word 1) - (insert (symbol-name new-level)))))))))) - -(defvar texinfo-raisesections-alist - '((@chapter . @chapter) ; Cannot go higher - (@unnumbered . @unnumbered) - - (@majorheading . @majorheading) - (@chapheading . @chapheading) - (@appendix . @appendix) - - (@section . @chapter) - (@unnumberedsec . @unnumbered) - (@heading . @chapheading) - (@appendixsec . @appendix) - - (@subsection . @section) - (@unnumberedsubsec . @unnumberedsec) - (@subheading . @heading) - (@appendixsubsec . @appendixsec) - - (@subsubsection . @subsection) - (@unnumberedsubsubsec . @unnumberedsubsec) - (@subsubheading . @subheading) - (@appendixsubsubsec . @appendixsubsec)) - "*An alist of next higher levels for chapters, sections. etc. -For example, section to chapter, subsection to section. -Used by `texinfo-raise-lower-sections'. -The keys specify types of section; the values correspond to the next -higher types.") - -(defvar texinfo-lowersections-alist - '((@chapter . @section) - (@unnumbered . @unnumberedsec) - (@majorheading . @heading) - (@chapheading . @heading) - (@appendix . @appendixsec) - - (@section . @subsection) - (@unnumberedsec . @unnumberedsubsec) - (@heading . @subheading) - (@appendixsec . @appendixsubsec) - - (@subsection . @subsubsection) - (@unnumberedsubsec . @unnumberedsubsubsec) - (@subheading . @subsubheading) - (@appendixsubsec . @appendixsubsubsec) - - (@subsubsection . @subsubsection) ; Cannot go lower. - (@unnumberedsubsubsec . @unnumberedsubsubsec) - (@subsubheading . @subsubheading) - (@appendixsubsubsec . @appendixsubsubsec)) - "*An alist of next lower levels for chapters, sections. etc. -For example, chapter to section, section to subsection. -Used by `texinfo-raise-lower-sections'. -The keys specify types of section; the values correspond to the next -lower types.") - - -;;; Perform those texinfo-to-info conversions that apply to the whole input -;;; uniformly. - -(defun texinfo-format-scan () - (texinfo-format-convert (point-min) (point-max)) - ;; Scan for @-commands. - (goto-char (point-min)) - (while (search-forward "@" nil t) - (if (looking-at "[@{}^'` *\"?!]") - ;; Handle a few special @-followed-by-one-char commands. - (if (= (following-char) ?*) - (progn - ;; remove command - (delete-region (1- (point)) (1+ (point))) - ;; insert return if not at end of line; - ;; else line is already broken. - (if (not (= (following-char) ?\n)) - (insert ?\n))) - ;; The other characters are simply quoted. Delete the @. - (delete-char -1) - (forward-char 1)) - ;; @ is followed by a command-word; find the end of the word. - (setq texinfo-command-start (1- (point))) - (if (= (char-syntax (following-char)) ?w) - (forward-word 1) - (forward-char 1)) - (setq texinfo-command-end (point)) - ;; Handle let aliasing - (setq texinfo-command-name - (let (trial - (cmdname - (buffer-substring - (1+ texinfo-command-start) texinfo-command-end))) - (while (setq trial (assoc cmdname texinfo-alias-list)) - (setq cmdname (cdr trial))) - (intern cmdname))) - ;; Call the handler for this command. - (let ((enclosure-type - (assoc - (symbol-name texinfo-command-name) - texinfo-enclosure-list))) - (if enclosure-type - (progn - (insert - (car (car (cdr enclosure-type))) - (texinfo-parse-arg-discard) - (car (cdr (car (cdr enclosure-type))))) - (goto-char texinfo-command-start)) - (let ((cmd (get texinfo-command-name 'texinfo-format))) - (if cmd (funcall cmd) (texinfo-unsupported))))))) - - (cond (texinfo-stack - (goto-char (nth 2 (car texinfo-stack))) - (error "Unterminated @%s" (car (car texinfo-stack)))))) - -(put 'begin 'texinfo-format 'texinfo-format-begin) -(defun texinfo-format-begin () - (texinfo-format-begin-end 'texinfo-format)) - -(put 'end 'texinfo-format 'texinfo-format-end) -(defun texinfo-format-end () - (texinfo-format-begin-end 'texinfo-end)) - -(defun texinfo-format-begin-end (prop) - (setq texinfo-command-name (intern (texinfo-parse-line-arg))) - (let ((cmd (get texinfo-command-name prop))) - (if cmd (funcall cmd) - (texinfo-unsupported)))) - -;;; Parsing functions - -(defun texinfo-parse-line-arg () - (goto-char texinfo-command-end) - (let ((start (point))) - (cond ((looking-at " ") - (skip-chars-forward " ") - (setq start (point)) - (end-of-line) - (skip-chars-backward " ") - (delete-region (point) (progn (end-of-line) (point))) - (setq texinfo-command-end (1+ (point)))) - ((looking-at "{") - (setq start (1+ (point))) - (forward-list 1) - (setq texinfo-command-end (point)) - (forward-char -1)) - (t - (error "Invalid texinfo command arg format"))) - (prog1 (buffer-substring start (point)) - (if (eolp) (forward-char 1))))) - -(defun texinfo-parse-expanded-arg () - (goto-char texinfo-command-end) - (let ((start (point)) - marker) - (cond ((looking-at " ") - (skip-chars-forward " ") - (setq start (point)) - (end-of-line) - (setq texinfo-command-end (1+ (point)))) - ((looking-at "{") - (setq start (1+ (point))) - (forward-list 1) - (setq texinfo-command-end (point)) - (forward-char -1)) - (t - (error "Invalid texinfo command arg format"))) - (setq marker (move-marker (make-marker) texinfo-command-end)) - (texinfo-format-expand-region start (point)) - (setq texinfo-command-end (marker-position marker)) - (move-marker marker nil) - (prog1 (buffer-substring start (point)) - (if (eolp) (forward-char 1))))) - -(defun texinfo-format-expand-region (start end) - (save-restriction - (narrow-to-region start end) - (let (texinfo-command-start - texinfo-command-end - texinfo-command-name - texinfo-stack) - (texinfo-format-scan)) - (goto-char (point-max)))) - -(defun texinfo-parse-arg-discard () - (prog1 (texinfo-parse-line-arg) - (texinfo-discard-command))) - -(defun texinfo-discard-command () - (delete-region texinfo-command-start texinfo-command-end)) - -(defun texinfo-optional-braces-discard () - "Discard braces following command, if any." - (goto-char texinfo-command-end) - (let ((start (point))) - (cond ((looking-at "[ \t]*\n")) ; do nothing - ((looking-at "{") ; remove braces, if any - (forward-list 1) - (setq texinfo-command-end (point))) - (t - (error - "Invalid `texinfo-optional-braces-discard' format \(need braces?\)"))) - (delete-region texinfo-command-start texinfo-command-end))) - -(defun texinfo-format-parse-line-args () - (let ((start (1- (point))) - next beg end - args) - (skip-chars-forward " ") - (while (not (eolp)) - (setq beg (point)) - (re-search-forward "[\n,]") - (setq next (point)) - (if (bolp) (setq next (1- next))) - (forward-char -1) - (skip-chars-backward " ") - (setq end (point)) - (setq args (cons (if (> end beg) (buffer-substring beg end)) - args)) - (goto-char next) - (skip-chars-forward " ")) - (if (eolp) (forward-char 1)) - (setq texinfo-command-end (point)) - (nreverse args))) - -(defun texinfo-format-parse-args () - (let ((start (1- (point))) - next beg end - args) - (search-forward "{") - (save-excursion - (texinfo-format-expand-region - (point) - (save-excursion (up-list 1) (1- (point))))) - ;; The following does not handle cross references of the form: - ;; `@xref{bullet, , @code{@@bullet}@{@}}.' because the - ;; re-search-forward finds the first right brace after the second - ;; comma. - (while (/= (preceding-char) ?\}) - (skip-chars-forward " \t\n") - (setq beg (point)) - (re-search-forward "[},]") - (setq next (point)) - (forward-char -1) - (skip-chars-backward " \t\n") - (setq end (point)) - (cond ((< beg end) - (goto-char beg) - (while (search-forward "\n" end t) - (replace-match " ")))) - (setq args (cons (if (> end beg) (buffer-substring beg end)) - args)) - (goto-char next)) - (if (eolp) (forward-char 1)) - (setq texinfo-command-end (point)) - (nreverse args))) - -(defun texinfo-format-parse-defun-args () - (goto-char texinfo-command-end) - (let ((start (point))) - (end-of-line) - (setq texinfo-command-end (1+ (point))) - (let ((marker (move-marker (make-marker) texinfo-command-end))) - (texinfo-format-expand-region start (point)) - (setq texinfo-command-end (marker-position marker)) - (move-marker marker nil)) - (goto-char start) - (let ((args '()) - beg end) - (skip-chars-forward " ") - (while (not (eolp)) - (cond ((looking-at "{") - (setq beg (1+ (point))) - (forward-list 1) - (setq end (1- (point)))) - (t - (setq beg (point)) - (re-search-forward "[\n ]") - (forward-char -1) - (setq end (point)))) - (setq args (cons (buffer-substring beg end) args)) - (skip-chars-forward " ")) - (forward-char 1) - (nreverse args)))) - -(defun texinfo-discard-line () - (goto-char texinfo-command-end) - (skip-chars-forward " \t") - (or (eolp) - (error "Extraneous text at end of command line.")) - (goto-char texinfo-command-start) - (or (bolp) - (error "Extraneous text at beginning of command line.")) - (delete-region (point) (progn (forward-line 1) (point)))) - -(defun texinfo-discard-line-with-args () - (goto-char texinfo-command-start) - (delete-region (point) (progn (forward-line 1) (point)))) - - -;;; @setfilename - -;; Only `texinfo-format-buffer' handles @setfilename with this -;; definition; `texinfo-format-region' handles @setfilename, if any, -;; specially. -(put 'setfilename 'texinfo-format 'texinfo-format-setfilename) -(defun texinfo-format-setfilename () - (let ((arg (texinfo-parse-arg-discard))) - (message "Formatting Info file: %s" arg) - (setq texinfo-format-filename - (file-name-nondirectory (expand-file-name arg))) - (insert "Info file: " - texinfo-format-filename ", -*-Text-*-\n" - ;; Date string removed so that regression testing is easier. - ;; "produced on " - ;; (substring (current-time-string) 8 10) " " - ;; (substring (current-time-string) 4 7) " " - ;; (substring (current-time-string) -4) " " - "produced by `texinfo-format-buffer'\n" - "from file" - (if (buffer-file-name input-buffer) - (concat " `" - (file-name-sans-versions - (file-name-nondirectory - (buffer-file-name input-buffer))) - "'") - (concat "buffer `" (buffer-name input-buffer) "'")) - "\nusing `texinfmt.el' version " - texinfmt-version - ".\n\n"))) - -;;; @node, @menu - -(put 'node 'texinfo-format 'texinfo-format-node) -(put 'nwnode 'texinfo-format 'texinfo-format-node) -(defun texinfo-format-node () - (let* ((args (texinfo-format-parse-line-args)) - (name (nth 0 args)) - (next (nth 1 args)) - (prev (nth 2 args)) - (up (nth 3 args))) - (texinfo-discard-command) - (setq texinfo-last-node name) - (let ((tem (downcase name))) - (if (assoc tem texinfo-node-names) - (error "Duplicate node name: %s" name) - (setq texinfo-node-names (cons (list tem) texinfo-node-names)))) - (setq texinfo-footnote-number 0) - ;; insert "\n\^_" unconditionally since this is what info is looking for - (insert "\n\^_\nFile: " texinfo-format-filename - ", Node: " name) - (if next - (insert ", Next: " next)) - (if prev - (insert ", Prev: " prev)) - (if up - (insert ", Up: " up)) - (insert ?\n) - (setq texinfo-last-node-pos (point)))) - -(put 'menu 'texinfo-format 'texinfo-format-menu) -(defun texinfo-format-menu () - (texinfo-discard-line) - (insert "* Menu:\n\n")) - -(put 'menu 'texinfo-end 'texinfo-discard-command) - - -;;; Cross references - -; @xref {NODE, FNAME, NAME, FILE, DOCUMENT} -; -> *Note FNAME: (FILE)NODE -; If FILE is missing, -; *Note FNAME: NODE -; If FNAME is empty and NAME is present -; *Note NAME: Node -; If both NAME and FNAME are missing -; *Note NODE:: -; texinfo ignores the DOCUMENT argument. -; -> See section <xref to NODE> [NAME, else NODE], page <xref to NODE> -; If FILE is specified, (FILE)NODE is used for xrefs. -; If fifth argument DOCUMENT is specified, produces -; See section <xref to NODE> [NAME, else NODE], page <xref to NODE> -; of DOCUMENT - -; @ref a reference that does not put `See' or `see' in -; the hardcopy and is the same as @xref in Info -(put 'ref 'texinfo-format 'texinfo-format-xref) - -(put 'xref 'texinfo-format 'texinfo-format-xref) -(defun texinfo-format-xref () - (let ((args (texinfo-format-parse-args))) - (texinfo-discard-command) - (insert "*Note ") - (let ((fname (or (nth 1 args) (nth 2 args)))) - (if (null (or fname (nth 3 args))) - (insert (car args) "::") - (insert (or fname (car args)) ": ") - (if (nth 3 args) - (insert "(" (nth 3 args) ")")) - (insert (car args)))))) - -(put 'pxref 'texinfo-format 'texinfo-format-pxref) -(defun texinfo-format-pxref () - (texinfo-format-xref) - (or (save-excursion - (forward-char -2) - (looking-at "::")) - (insert "."))) - -;@inforef{NODE, FNAME, FILE} -;Like @xref{NODE, FNAME,,FILE} in texinfo. -;In Tex, generates "See Info file FILE, node NODE" -(put 'inforef 'texinfo-format 'texinfo-format-inforef) -(defun texinfo-format-inforef () - (let ((args (texinfo-format-parse-args))) - (texinfo-discard-command) - (if (nth 1 args) - (insert "*Note " (nth 1 args) ": (" (nth 2 args) ")" (car args)) - (insert "*Note " "(" (nth 2 args) ")" (car args) "::")))) - - -;;; Section headings - -(put 'majorheading 'texinfo-format 'texinfo-format-chapter) -(put 'chapheading 'texinfo-format 'texinfo-format-chapter) -(put 'ichapter 'texinfo-format 'texinfo-format-chapter) -(put 'chapter 'texinfo-format 'texinfo-format-chapter) -(put 'iappendix 'texinfo-format 'texinfo-format-chapter) -(put 'appendix 'texinfo-format 'texinfo-format-chapter) -(put 'iunnumbered 'texinfo-format 'texinfo-format-chapter) -(put 'top 'texinfo-format 'texinfo-format-chapter) -(put 'unnumbered 'texinfo-format 'texinfo-format-chapter) -(defun texinfo-format-chapter () - (texinfo-format-chapter-1 ?*)) - -(put 'heading 'texinfo-format 'texinfo-format-section) -(put 'isection 'texinfo-format 'texinfo-format-section) -(put 'section 'texinfo-format 'texinfo-format-section) -(put 'iappendixsection 'texinfo-format 'texinfo-format-section) -(put 'appendixsection 'texinfo-format 'texinfo-format-section) -(put 'iappendixsec 'texinfo-format 'texinfo-format-section) -(put 'appendixsec 'texinfo-format 'texinfo-format-section) -(put 'iunnumberedsec 'texinfo-format 'texinfo-format-section) -(put 'unnumberedsec 'texinfo-format 'texinfo-format-section) -(defun texinfo-format-section () - (texinfo-format-chapter-1 ?=)) - -(put 'subheading 'texinfo-format 'texinfo-format-subsection) -(put 'isubsection 'texinfo-format 'texinfo-format-subsection) -(put 'subsection 'texinfo-format 'texinfo-format-subsection) -(put 'iappendixsubsec 'texinfo-format 'texinfo-format-subsection) -(put 'appendixsubsec 'texinfo-format 'texinfo-format-subsection) -(put 'iunnumberedsubsec 'texinfo-format 'texinfo-format-subsection) -(put 'unnumberedsubsec 'texinfo-format 'texinfo-format-subsection) -(defun texinfo-format-subsection () - (texinfo-format-chapter-1 ?-)) - -(put 'subsubheading 'texinfo-format 'texinfo-format-subsubsection) -(put 'isubsubsection 'texinfo-format 'texinfo-format-subsubsection) -(put 'subsubsection 'texinfo-format 'texinfo-format-subsubsection) -(put 'iappendixsubsubsec 'texinfo-format 'texinfo-format-subsubsection) -(put 'appendixsubsubsec 'texinfo-format 'texinfo-format-subsubsection) -(put 'iunnumberedsubsubsec 'texinfo-format 'texinfo-format-subsubsection) -(put 'unnumberedsubsubsec 'texinfo-format 'texinfo-format-subsubsection) -(defun texinfo-format-subsubsection () - (texinfo-format-chapter-1 ?.)) - -(defun texinfo-format-chapter-1 (belowchar) - (let ((arg (texinfo-parse-arg-discard))) - (message "Formatting: %s ... " arg) ; So we can see where we are. - (insert ?\n arg ?\n "@SectionPAD " belowchar ?\n) - (forward-line -2))) - -(put 'SectionPAD 'texinfo-format 'texinfo-format-sectionpad) -(defun texinfo-format-sectionpad () - (let ((str (texinfo-parse-arg-discard))) - (forward-char -1) - (let ((column (current-column))) - (forward-char 1) - (while (> column 0) - (insert str) - (setq column (1- column)))) - (insert ?\n))) - - -;;; Space controlling commands: @. and @:, and the soft hyphen. - -(put '\. 'texinfo-format 'texinfo-format-\.) -(defun texinfo-format-\. () - (texinfo-discard-command) - (insert ".")) - -(put '\: 'texinfo-format 'texinfo-format-\:) -(defun texinfo-format-\: () - (texinfo-discard-command)) - -(put '\- 'texinfo-format 'texinfo-format-soft-hyphen) -(defun texinfo-format-soft-hyphen () - (texinfo-discard-command)) - - -;;; @center, @sp, and @br - -(put 'center 'texinfo-format 'texinfo-format-center) -(defun texinfo-format-center () - (let ((arg (texinfo-parse-expanded-arg))) - (texinfo-discard-command) - (insert arg) - (insert ?\n) - (save-restriction - (goto-char (1- (point))) - (let ((indent-tabs-mode nil)) - (center-line))))) - -(put 'sp 'texinfo-format 'texinfo-format-sp) -(defun texinfo-format-sp () - (let* ((arg (texinfo-parse-arg-discard)) - (num (read arg))) - (insert-char ?\n num))) - -(put 'br 'texinfo-format 'texinfo-format-paragraph-break) -(defun texinfo-format-paragraph-break () - "Force a paragraph break. -If used within a line, follow `@br' with braces." - (texinfo-optional-braces-discard) - ;; insert one return if at end of line; - ;; else insert two returns, to generate a blank line. - (if (= (following-char) ?\n) - (insert ?\n) - (insert-char ?\n 2))) - - -;;; @footnote and @footnotestyle - -; In Texinfo, footnotes are created with the `@footnote' command. -; This command is followed immediately by a left brace, then by the text of -; the footnote, and then by a terminating right brace. The -; template for a footnote is: -; -; @footnote{TEXT} -; -; Info has two footnote styles: -; -; * In the End of node style, all the footnotes for a single node -; are placed at the end of that node. The footnotes are -; separated from the rest of the node by a line of dashes with -; the word `Footnotes' within it. -; -; * In the Separate node style, all the footnotes for a single node -; are placed in an automatically constructed node of their own. - -; Footnote style is specified by the @footnotestyle command, either -; @footnotestyle separate -; or -; @footnotestyle end -; -; The default is separate - -(defvar texinfo-footnote-style "separate" - "Footnote style, either separate or end.") - -(put 'footnotestyle 'texinfo-format 'texinfo-footnotestyle) -(defun texinfo-footnotestyle () - "Specify whether footnotes are at end of node or in separate nodes. -Argument is either end or separate." - (setq texinfo-footnote-style (texinfo-parse-arg-discard))) - -(defvar texinfo-footnote-number) - -(put 'footnote 'texinfo-format 'texinfo-format-footnote) -(defun texinfo-format-footnote () - "Format a footnote in either end of node or separate node style. -The texinfo-footnote-style variable controls which style is used." - (setq texinfo-footnote-number (1+ texinfo-footnote-number)) - (cond ((string= texinfo-footnote-style "end") - (texinfo-format-end-node)) - ((string= texinfo-footnote-style "separate") - (texinfo-format-separate-node)))) - -(defun texinfo-format-separate-node () - "Format footnote in Separate node style, with notes in own node. -The node is constructed automatically." - (let* (start - (arg (texinfo-parse-line-arg)) - (node-name-beginning - (save-excursion - (re-search-backward - "^File: \\w+\\(\\w\\|\\s_\\|\\.\\|,\\)*[ \t]+Node:") - (match-end 0))) - (node-name - (save-excursion - (buffer-substring - (progn (goto-char node-name-beginning) ; skip over node command - (skip-chars-forward " \t") ; and over spaces - (point)) - (if (search-forward - "," - (save-excursion (end-of-line) (point)) t) ; bound search - (1- (point)) - (end-of-line) (point)))))) - (texinfo-discard-command) ; remove or insert whitespace, as needed - (delete-region (save-excursion (skip-chars-backward " \t\n") (point)) - (point)) - (insert (format " (%d) (*Note %s-Footnotes::)" - texinfo-footnote-number node-name)) - (fill-paragraph nil) - (save-excursion - (if (re-search-forward "^@node" nil 'move) - (forward-line -1)) - - ;; two cases: for the first footnote, we must insert a node header; - ;; for the second and subsequent footnotes, we need only insert - ;; the text of the footnote. - - (if (save-excursion - (re-search-backward - (concat node-name "-Footnotes, Up: ") - node-name-beginning - t)) - (progn ; already at least one footnote - (setq start (point)) - (insert (format "\n(%d) %s\n" texinfo-footnote-number arg)) - (fill-region start (point))) - ;; else not yet a footnote - (insert "\n\^_\nFile: " texinfo-format-filename - " Node: " node-name "-Footnotes, Up: " node-name "\n") - (setq start (point)) - (insert (format "\n(%d) %s\n" texinfo-footnote-number arg)) - (fill-region start (point)))))) - -(defun texinfo-format-end-node () - "Format footnote in the End of node style, with notes at end of node." - (let (start - (arg (texinfo-parse-line-arg))) - (texinfo-discard-command) ; remove or insert whitespace, as needed - (delete-region (save-excursion (skip-chars-backward " \t\n") (point)) - (point)) - (insert (format " (%d) " texinfo-footnote-number)) - (fill-paragraph nil) - (save-excursion - (if (search-forward "\n--------- Footnotes ---------\n" nil t) - (progn ; already have footnote, put new one before end of node - (if (re-search-forward "^@node" nil 'move) - (forward-line -1)) - (setq start (point)) - (insert (format "\n(%d) %s\n" texinfo-footnote-number arg)) - (fill-region start (point))) - ;; else no prior footnote - (if (re-search-forward "^@node" nil 'move) - (forward-line -1)) - (insert "\n--------- Footnotes ---------\n") - (setq start (point)) - (insert (format "\n(%d) %s\n" texinfo-footnote-number arg)))))) - - -;;; @itemize, @enumerate, and similar commands - -;; @itemize pushes (itemize "COMMANDS" STARTPOS) on texinfo-stack. -;; @enumerate pushes (enumerate 0 STARTPOS). -;; @item dispatches to the texinfo-item prop of the first elt of the list. -;; For itemize, this puts in and rescans the COMMANDS. -;; For enumerate, this increments the number and puts it in. -;; In either case, it puts a Backspace at the front of the line -;; which marks it not to be indented later. -;; All other lines get indented by 5 when the @end is reached. - -(defvar texinfo-stack-depth 0 - "Count of number of unpopped texinfo-push-stack calls. -Used by @refill indenting command to avoid indenting within lists, etc.") - -(defun texinfo-push-stack (check arg) - (setq texinfo-stack-depth (1+ texinfo-stack-depth)) - (setq texinfo-stack - (cons (list check arg texinfo-command-start) - texinfo-stack))) - -(defun texinfo-pop-stack (check) - (setq texinfo-stack-depth (1- texinfo-stack-depth)) - (if (null texinfo-stack) - (error "Unmatched @end %s" check)) - (if (not (eq (car (car texinfo-stack)) check)) - (error "@end %s matches @%s" - check (car (car texinfo-stack)))) - (prog1 (cdr (car texinfo-stack)) - (setq texinfo-stack (cdr texinfo-stack)))) - -(put 'itemize 'texinfo-format 'texinfo-itemize) -(defun texinfo-itemize () - (texinfo-push-stack - 'itemize - (progn (skip-chars-forward " \t") - (if (eolp) - "@bullet" - (texinfo-parse-line-arg)))) - (texinfo-discard-line-with-args) - (setq fill-column (- fill-column 5))) - -(put 'itemize 'texinfo-end 'texinfo-end-itemize) -(defun texinfo-end-itemize () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack 'itemize))) - (texinfo-do-itemize (nth 1 stacktop)))) - -(put 'enumerate 'texinfo-format 'texinfo-enumerate) -(defun texinfo-enumerate () - (texinfo-push-stack - 'enumerate - (progn (skip-chars-forward " \t") - (if (eolp) - 1 - (read (current-buffer))))) - (if (and (symbolp (car (cdr (car texinfo-stack)))) - (> 1 (length (symbol-name (car (cdr (car texinfo-stack))))))) - (error - "@enumerate: Use a number or letter, eg: 1, A, a, 3, B, or d." )) - (texinfo-discard-line-with-args) - (setq fill-column (- fill-column 5))) - -(put 'enumerate 'texinfo-end 'texinfo-end-enumerate) -(defun texinfo-end-enumerate () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack 'enumerate))) - (texinfo-do-itemize (nth 1 stacktop)))) - -;; @alphaenumerate never became a standard part of Texinfo -(put 'alphaenumerate 'texinfo-format 'texinfo-alphaenumerate) -(defun texinfo-alphaenumerate () - (texinfo-push-stack 'alphaenumerate (1- ?a)) - (setq fill-column (- fill-column 5)) - (texinfo-discard-line)) - -(put 'alphaenumerate 'texinfo-end 'texinfo-end-alphaenumerate) -(defun texinfo-end-alphaenumerate () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack 'alphaenumerate))) - (texinfo-do-itemize (nth 1 stacktop)))) - -;; @capsenumerate never became a standard part of Texinfo -(put 'capsenumerate 'texinfo-format 'texinfo-capsenumerate) -(defun texinfo-capsenumerate () - (texinfo-push-stack 'capsenumerate (1- ?A)) - (setq fill-column (- fill-column 5)) - (texinfo-discard-line)) - -(put 'capsenumerate 'texinfo-end 'texinfo-end-capsenumerate) -(defun texinfo-end-capsenumerate () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack 'capsenumerate))) - (texinfo-do-itemize (nth 1 stacktop)))) - -;; At the @end, indent all the lines within the construct -;; except those marked with backspace. FROM says where -;; construct started. -(defun texinfo-do-itemize (from) - (save-excursion - (while (progn (forward-line -1) - (>= (point) from)) - (if (= (following-char) ?\b) - (save-excursion - (delete-char 1) - (end-of-line) - (delete-char 6)) - (if (not (looking-at "[ \t]*$")) - (save-excursion (insert " "))))))) - -(put 'item 'texinfo-format 'texinfo-item) -(put 'itemx 'texinfo-format 'texinfo-item) -(defun texinfo-item () - (funcall (get (car (car texinfo-stack)) 'texinfo-item))) - -(put 'itemize 'texinfo-item 'texinfo-itemize-item) -(defun texinfo-itemize-item () - ;; (texinfo-discard-line) ; Did not handle text on same line as @item. - (delete-region (1+ (point)) (save-excursion (beginning-of-line) (point))) - (if (looking-at "[ \t]*[^ \t\n]+") - ;; Text on same line as @item command. - (insert "\b " (nth 1 (car texinfo-stack)) " \n") - ;; Else text on next line. - (insert "\b " (nth 1 (car texinfo-stack)) " ")) - (forward-line -1)) - -(put 'enumerate 'texinfo-item 'texinfo-enumerate-item) -(defun texinfo-enumerate-item () - (texinfo-discard-line) - (let (enumerating-symbol) - (cond ((integerp (car (cdr (car texinfo-stack)))) - (setq enumerating-symbol (car (cdr (car texinfo-stack)))) - (insert ?\b (format "%3d. " enumerating-symbol) ?\n) - (setcar (cdr (car texinfo-stack)) (1+ enumerating-symbol))) - ((symbolp (car (cdr (car texinfo-stack)))) - (setq enumerating-symbol - (symbol-name (car (cdr (car texinfo-stack))))) - (if (or (equal ?\[ (string-to-char enumerating-symbol)) - (equal ?\{ (string-to-char enumerating-symbol))) - (error - "Too many items in enumerated list; alphabet ends at Z.")) - (insert ?\b (format "%3s. " enumerating-symbol) ?\n) - (setcar (cdr (car texinfo-stack)) - (make-symbol - (char-to-string - (1+ - (string-to-char enumerating-symbol)))))) - (t - (error - "@enumerate: Use a number or letter, eg: 1, A, a, 3, B or d." ))) - (forward-line -1))) - -(put 'alphaenumerate 'texinfo-item 'texinfo-alphaenumerate-item) -(defun texinfo-alphaenumerate-item () - (texinfo-discard-line) - (let ((next (1+ (car (cdr (car texinfo-stack)))))) - (if (> next ?z) - (error "More than 26 items in @alphaenumerate; get a bigger alphabet.")) - (setcar (cdr (car texinfo-stack)) next) - (insert "\b " next ". \n")) - (forward-line -1)) - -(put 'capsenumerate 'texinfo-item 'texinfo-capsenumerate-item) -(defun texinfo-capsenumerate-item () - (texinfo-discard-line) - (let ((next (1+ (car (cdr (car texinfo-stack)))))) - (if (> next ?Z) - (error "More than 26 items in @capsenumerate; get a bigger alphabet.")) - (setcar (cdr (car texinfo-stack)) next) - (insert "\b " next ". \n")) - (forward-line -1)) - - -;;; @table - -; The `@table' command produces two-column tables. - -(put 'table 'texinfo-format 'texinfo-table) -(defun texinfo-table () - (texinfo-push-stack - 'table - (progn (skip-chars-forward " \t") - (if (eolp) - "@asis" - (texinfo-parse-line-arg)))) - (texinfo-discard-line-with-args) - (setq fill-column (- fill-column 5))) - -(put 'table 'texinfo-item 'texinfo-table-item) -(defun texinfo-table-item () - (let ((arg (texinfo-parse-arg-discard)) - (itemfont (car (cdr (car texinfo-stack))))) - (insert ?\b itemfont ?\{ arg "}\n \n")) - (forward-line -2)) - -(put 'table 'texinfo-end 'texinfo-end-table) -(defun texinfo-end-table () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack 'table))) - (texinfo-do-itemize (nth 1 stacktop)))) - -;; @description appears to be an undocumented variant on @table that -;; does not require an arg. It fails in texinfo.tex 2.58 and is not -;; part of makeinfo.c The command appears to be a relic of the past. -(put 'description 'texinfo-end 'texinfo-end-table) -(put 'description 'texinfo-format 'texinfo-description) -(defun texinfo-description () - (texinfo-push-stack 'table "@asis") - (setq fill-column (- fill-column 5)) - (texinfo-discard-line)) - - -;;; @ftable, @vtable - -; The `@ftable' and `@vtable' commands are like the `@table' command -; but they also insert each entry in the first column of the table -; into the function or variable index. - -;; Handle the @ftable and @vtable commands: - -(put 'ftable 'texinfo-format 'texinfo-ftable) -(put 'vtable 'texinfo-format 'texinfo-vtable) - -(defun texinfo-ftable () (texinfo-indextable 'ftable)) -(defun texinfo-vtable () (texinfo-indextable 'vtable)) - -(defun texinfo-indextable (table-type) - (texinfo-push-stack table-type (texinfo-parse-arg-discard)) - (setq fill-column (- fill-column 5))) - -;; Handle the @item commands within ftable and vtable: - -(put 'ftable 'texinfo-item 'texinfo-ftable-item) -(put 'vtable 'texinfo-item 'texinfo-vtable-item) - -(defun texinfo-ftable-item () (texinfo-indextable-item 'texinfo-findex)) -(defun texinfo-vtable-item () (texinfo-indextable-item 'texinfo-vindex)) - -(defun texinfo-indextable-item (index-type) - (let ((item (texinfo-parse-arg-discard)) - (itemfont (car (cdr (car texinfo-stack)))) - (indexvar index-type)) - (insert ?\b itemfont ?\{ item "}\n \n") - (set indexvar - (cons - (list item texinfo-last-node) - (symbol-value indexvar))) - (forward-line -2))) - -;; Handle @end ftable, @end vtable - -(put 'ftable 'texinfo-end 'texinfo-end-ftable) -(put 'vtable 'texinfo-end 'texinfo-end-vtable) - -(defun texinfo-end-ftable () (texinfo-end-indextable 'ftable)) -(defun texinfo-end-vtable () (texinfo-end-indextable 'vtable)) - -(defun texinfo-end-indextable (table-type) - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack table-type))) - (texinfo-do-itemize (nth 1 stacktop)))) - - -;;; @ifinfo, @iftex, @tex, @ifhtml, @html - -(put 'ifinfo 'texinfo-format 'texinfo-discard-line) -(put 'ifinfo 'texinfo-end 'texinfo-discard-command) - -(put 'iftex 'texinfo-format 'texinfo-format-iftex) -(defun texinfo-format-iftex () - (delete-region texinfo-command-start - (progn (re-search-forward "@end iftex[ \t]*\n") - (point)))) - -(put 'ifhtml 'texinfo-format 'texinfo-format-ifhtml) -(defun texinfo-format-ifhtml () - (delete-region texinfo-command-start - (progn (re-search-forward "@end ifhtml[ \t]*\n") - (point)))) - -(put 'tex 'texinfo-format 'texinfo-format-tex) -(defun texinfo-format-tex () - (delete-region texinfo-command-start - (progn (re-search-forward "@end tex[ \t]*\n") - (point)))) - -(put 'html 'texinfo-format 'texinfo-format-html) -(defun texinfo-format-html () - (delete-region texinfo-command-start - (progn (re-search-forward "@end html[ \t]*\n") - (point)))) - - -;;; @titlepage - -(put 'titlepage 'texinfo-format 'texinfo-format-titlepage) -(defun texinfo-format-titlepage () - (delete-region texinfo-command-start - (progn (re-search-forward "@end titlepage[ \t]*\n") - (point)))) - -(put 'endtitlepage 'texinfo-format 'texinfo-discard-line) - -; @titlespec an alternative titling command; ignored by Info - -(put 'titlespec 'texinfo-format 'texinfo-format-titlespec) -(defun texinfo-format-titlespec () - (delete-region texinfo-command-start - (progn (re-search-forward "@end titlespec[ \t]*\n") - (point)))) - -(put 'endtitlespec 'texinfo-format 'texinfo-discard-line) - - -;;; @today - -(put 'today 'texinfo-format 'texinfo-format-today) - -; Produces Day Month Year style of output. eg `1 Jan 1900' -; The `@today{}' command requires a pair of braces, like `@dots{}'. -(defun texinfo-format-today () - (texinfo-parse-arg-discard) - (insert (format "%s %s %s" - (substring (current-time-string) 8 10) - (substring (current-time-string) 4 7) - (substring (current-time-string) -4)))) - - -;;; @ignore - -(put 'ignore 'texinfo-format 'texinfo-format-ignore) -(defun texinfo-format-ignore () - (delete-region texinfo-command-start - (progn (re-search-forward "@end ignore[ \t]*\n") - (point)))) - -(put 'endignore 'texinfo-format 'texinfo-discard-line) - - -;;; Define the Info enclosure command: @definfoenclose - -; A `@definfoenclose' command may be used to define a highlighting -; command for Info, but not for TeX. A command defined using -; `@definfoenclose' marks text by enclosing it in strings that precede -; and follow the text. -; -; Presumably, if you define a command with `@definfoenclose` for Info, -; you will also define the same command in the TeX definitions file, -; `texinfo.tex' in a manner appropriate for typesetting. -; -; Write a `@definfoenclose' command on a line and follow it with three -; arguments separated by commas (commas are used as separators in an -; `@node' line in the same way). The first argument to -; `@definfoenclose' is the @-command name \(without the `@'\); the -; second argument is the Info start delimiter string; and the third -; argument is the Info end delimiter string. The latter two arguments -; enclose the highlighted text in the Info file. A delimiter string -; may contain spaces. Neither the start nor end delimiter is -; required. However, if you do not provide a start delimiter, you -; must follow the command name with two commas in a row; otherwise, -; the Info formatting commands will misinterpret the end delimiter -; string as a start delimiter string. -; -; If you do a @definfoenclose{} on the name of a pre-defined macro (such -; as @emph{}, @strong{}, @tt{}, or @i{}) the enclosure definition will -; override the built-in definition. -; -; An enclosure command defined this way takes one argument in braces. -; -; For example, you can write: -; -; @ifinfo -; @definfoenclose phoo, //, \\ -; @end ifinfo -; -; near the beginning of a Texinfo file at the beginning of the lines -; to define `@phoo' as an Info formatting command that inserts `//' -; before and `\\' after the argument to `@phoo'. You can then write -; `@phoo{bar}' wherever you want `//bar\\' highlighted in Info. -; -; Also, for TeX formatting, you could write -; -; @iftex -; @global@let@phoo=@i -; @end iftex -; -; to define `@phoo' as a command that causes TeX to typeset -; the argument to `@phoo' in italics. -; -; Note that each definition applies to its own formatter: one for TeX, -; the other for texinfo-format-buffer or texinfo-format-region. -; -; Here is another example: write -; -; @definfoenclose headword, , : -; -; near the beginning of the file, to define `@headword' as an Info -; formatting command that inserts nothing before and a colon after the -; argument to `@headword'. - -(put 'definfoenclose 'texinfo-format 'texinfo-define-info-enclosure) -(defun texinfo-define-info-enclosure () - (let* ((args (texinfo-format-parse-line-args)) - (command-name (nth 0 args)) - (beginning-delimiter (or (nth 1 args) "")) - (end-delimiter (or (nth 2 args) ""))) - (texinfo-discard-command) - (setq texinfo-enclosure-list - (cons - (list command-name - (list - beginning-delimiter - end-delimiter)) - texinfo-enclosure-list)))) - - -;;; @var, @code and the like - -(put 'var 'texinfo-format 'texinfo-format-var) -; @sc a small caps font for TeX; formatted as `var' in Info -(put 'sc 'texinfo-format 'texinfo-format-var) -(defun texinfo-format-var () - (insert (upcase (texinfo-parse-arg-discard))) - (goto-char texinfo-command-start)) - -; various noops - -(put 'b 'texinfo-format 'texinfo-format-noop) -(put 'i 'texinfo-format 'texinfo-format-noop) -(put 'r 'texinfo-format 'texinfo-format-noop) -(put 't 'texinfo-format 'texinfo-format-noop) -(put 'w 'texinfo-format 'texinfo-format-noop) -(put 'asis 'texinfo-format 'texinfo-format-noop) -(put 'dmn 'texinfo-format 'texinfo-format-noop) -(put 'key 'texinfo-format 'texinfo-format-noop) -(put 'math 'texinfo-format 'texinfo-format-noop) -(put 'titlefont 'texinfo-format 'texinfo-format-noop) -(defun texinfo-format-noop () - (insert (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -(put 'cite 'texinfo-format 'texinfo-format-code) -(put 'code 'texinfo-format 'texinfo-format-code) -(put 'file 'texinfo-format 'texinfo-format-code) -(put 'kbd 'texinfo-format 'texinfo-format-code) -(put 'samp 'texinfo-format 'texinfo-format-code) -(defun texinfo-format-code () - (insert "`" (texinfo-parse-arg-discard) "'") - (goto-char texinfo-command-start)) - -(put 'emph 'texinfo-format 'texinfo-format-emph) -(put 'strong 'texinfo-format 'texinfo-format-emph) -(defun texinfo-format-emph () - (insert "*" (texinfo-parse-arg-discard) "*") - (goto-char texinfo-command-start)) - -(put 'dfn 'texinfo-format 'texinfo-format-defn) -(put 'defn 'texinfo-format 'texinfo-format-defn) -(defun texinfo-format-defn () - (insert "\"" (texinfo-parse-arg-discard) "\"") - (goto-char texinfo-command-start)) - -(put 'bullet 'texinfo-format 'texinfo-format-bullet) -(defun texinfo-format-bullet () - "Insert an asterisk. -If used within a line, follow `@bullet' with braces." - (texinfo-optional-braces-discard) - (insert "*")) - - -;;; @example, @lisp, @quotation, @display, @smalllisp, @smallexample - -(put 'display 'texinfo-format 'texinfo-format-example) -(put 'example 'texinfo-format 'texinfo-format-example) -(put 'lisp 'texinfo-format 'texinfo-format-example) -(put 'quotation 'texinfo-format 'texinfo-format-example) -(put 'smallexample 'texinfo-format 'texinfo-format-example) -(put 'smalllisp 'texinfo-format 'texinfo-format-example) -(defun texinfo-format-example () - (texinfo-push-stack 'example nil) - (setq fill-column (- fill-column 5)) - (texinfo-discard-line)) - -(put 'example 'texinfo-end 'texinfo-end-example) -(put 'display 'texinfo-end 'texinfo-end-example) -(put 'lisp 'texinfo-end 'texinfo-end-example) -(put 'quotation 'texinfo-end 'texinfo-end-example) -(put 'smallexample 'texinfo-end 'texinfo-end-example) -(put 'smalllisp 'texinfo-end 'texinfo-end-example) -(defun texinfo-end-example () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack 'example))) - (texinfo-do-itemize (nth 1 stacktop)))) - -(put 'exdent 'texinfo-format 'texinfo-format-exdent) -(defun texinfo-format-exdent () - (texinfo-discard-command) - (delete-region (point) - (progn - (skip-chars-forward " ") - (point))) - (insert ?\b) - ;; Cancel out the deletion that texinfo-do-itemize - ;; is going to do at the end of this line. - (save-excursion - (end-of-line) - (insert "\n "))) - - -;;; @cartouche - -; The @cartouche command is a noop in Info; in a printed manual, -; it makes a box with rounded corners. - -(put 'cartouche 'texinfo-format 'texinfo-discard-line) -(put 'cartouche 'texinfo-end 'texinfo-discard-command) - - -;;; @flushleft and @format - -; The @flushleft command left justifies every line but leaves the -; right end ragged. As far as Info is concerned, @flushleft is a -; `do-nothing' command - -; The @format command is similar to @example except that it does not -; indent; this means that in Info, @format is similar to @flushleft. - -(put 'format 'texinfo-format 'texinfo-format-flushleft) -(put 'flushleft 'texinfo-format 'texinfo-format-flushleft) -(defun texinfo-format-flushleft () - (texinfo-discard-line)) - -(put 'format 'texinfo-end 'texinfo-end-flushleft) -(put 'flushleft 'texinfo-end 'texinfo-end-flushleft) -(defun texinfo-end-flushleft () - (texinfo-discard-command)) - - -;;; @flushright - -; The @flushright command right justifies every line but leaves the -; left end ragged. Spaces and tabs at the right ends of lines are -; removed so that visible text lines up on the right side. - -(put 'flushright 'texinfo-format 'texinfo-format-flushright) -(defun texinfo-format-flushright () - (texinfo-push-stack 'flushright nil) - (texinfo-discard-line)) - -(put 'flushright 'texinfo-end 'texinfo-end-flushright) -(defun texinfo-end-flushright () - (texinfo-discard-command) - - (let ((stacktop - (texinfo-pop-stack 'flushright))) - - (texinfo-do-flushright (nth 1 stacktop)))) - -(defun texinfo-do-flushright (from) - (save-excursion - (while (progn (forward-line -1) - (>= (point) from)) - - (beginning-of-line) - (insert - (make-string - (- fill-column - (save-excursion - (end-of-line) - (skip-chars-backward " \t") - (delete-region (point) (progn (end-of-line) (point))) - (current-column))) - ? ))))) - - -;;; @ctrl, @TeX, @copyright, @minus, @dots - -(put 'ctrl 'texinfo-format 'texinfo-format-ctrl) -(defun texinfo-format-ctrl () - (let ((str (texinfo-parse-arg-discard))) - (insert (logand 31 (aref str 0))))) - -(put 'TeX 'texinfo-format 'texinfo-format-TeX) -(defun texinfo-format-TeX () - (texinfo-parse-arg-discard) - (insert "TeX")) - -(put 'copyright 'texinfo-format 'texinfo-format-copyright) -(defun texinfo-format-copyright () - (texinfo-parse-arg-discard) - (insert "(C)")) - -(put 'minus 'texinfo-format 'texinfo-format-minus) -(defun texinfo-format-minus () - "Insert a minus sign. -If used within a line, follow `@minus' with braces." - (texinfo-optional-braces-discard) - (insert "-")) - -(put 'dots 'texinfo-format 'texinfo-format-dots) -(defun texinfo-format-dots () - (texinfo-parse-arg-discard) - (insert "...")) - -(put 'enddots 'texinfo-format 'texinfo-format-enddots) -(defun texinfo-format-enddots () - (texinfo-parse-arg-discard) - (insert "....")) - - -;;; Refilling and indenting: @refill, @paragraphindent, @noindent - -;;; Indent only those paragraphs that are refilled as a result of an -;;; @refill command. - -; * If the value is `asis', do not change the existing indentation at -; the starts of paragraphs. - -; * If the value zero, delete any existing indentation. - -; * If the value is greater than zero, indent each paragraph by that -; number of spaces. - -;;; But do not refill paragraphs with an @refill command that are -;;; preceded by @noindent or are part of a table, list, or deffn. - -(defvar texinfo-paragraph-indent "asis" - "Number of spaces for @refill to indent a paragraph; else to leave as is.") - -(put 'paragraphindent 'texinfo-format 'texinfo-paragraphindent) - -(defun texinfo-paragraphindent () - "Specify the number of spaces for @refill to indent a paragraph. -Default is to leave the number of spaces as is." - (let ((arg (texinfo-parse-arg-discard))) - (if (string= "asis" arg) - (setq texinfo-paragraph-indent "asis") - (setq texinfo-paragraph-indent (string-to-int arg))))) - -(put 'refill 'texinfo-format 'texinfo-format-refill) -(defun texinfo-format-refill () - "Refill paragraph. Also, indent first line as set by @paragraphindent. -Default is to leave paragraph indentation as is." - (texinfo-discard-command) - (forward-paragraph -1) - (if (looking-at "[ \t\n]*$") (forward-line 1)) - ;; Do not indent if an entry in a list, table, or deffn, - ;; or if paragraph is preceded by @noindent. - ;; Otherwise, indent - (cond - ;; delete a @noindent line and do not indent paragraph - ((save-excursion (forward-line -1) - (looking-at "^@noindent")) - (forward-line -1) - (delete-region (point) (progn (forward-line 1) (point)))) - ;; do nothing if "asis" - ((equal texinfo-paragraph-indent "asis")) - ;; do no indenting in list, etc. - ((> texinfo-stack-depth 0)) - ;; otherwise delete existing whitespace and indent - (t - (delete-region (point) (progn (skip-chars-forward " \t") (point))) - (insert (make-string texinfo-paragraph-indent ? )))) - (forward-paragraph 1) - (forward-line -1) - (end-of-line) - ;; Do not fill a section title line with asterisks, hyphens, etc. that - ;; are used to underline it. This could occur if the line following - ;; the underlining is not an index entry and has text within it. - (let* ((previous-paragraph-separate paragraph-separate) - (paragraph-separate - (concat paragraph-separate "\\|[-=.]+\\|\\*\\*+")) - (previous-paragraph-start paragraph-start) - (paragraph-start - (concat paragraph-start "\\|[-=.]+\\|\\*\\*+"))) - (unwind-protect - (fill-paragraph nil) - (setq paragraph-separate previous-paragraph-separate) - (setq paragraph-start previous-paragraph-start)))) - -(put 'noindent 'texinfo-format 'texinfo-noindent) -(defun texinfo-noindent () - (save-excursion - (forward-paragraph 1) - (if (search-backward "@refill" - (save-excursion (forward-line -1) (point)) t) - () ; leave @noindent command so @refill command knows not to indent - ;; else - (texinfo-discard-line)))) - - -;;; Index generation - -(put 'vindex 'texinfo-format 'texinfo-format-vindex) -(defun texinfo-format-vindex () - (texinfo-index 'texinfo-vindex)) - -(put 'cindex 'texinfo-format 'texinfo-format-cindex) -(defun texinfo-format-cindex () - (texinfo-index 'texinfo-cindex)) - -(put 'findex 'texinfo-format 'texinfo-format-findex) -(defun texinfo-format-findex () - (texinfo-index 'texinfo-findex)) - -(put 'pindex 'texinfo-format 'texinfo-format-pindex) -(defun texinfo-format-pindex () - (texinfo-index 'texinfo-pindex)) - -(put 'tindex 'texinfo-format 'texinfo-format-tindex) -(defun texinfo-format-tindex () - (texinfo-index 'texinfo-tindex)) - -(put 'kindex 'texinfo-format 'texinfo-format-kindex) -(defun texinfo-format-kindex () - (texinfo-index 'texinfo-kindex)) - -(defun texinfo-index (indexvar) - (let ((arg (texinfo-parse-expanded-arg))) - (texinfo-discard-command) - (set indexvar - (cons (list arg - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value indexvar))))) - -(defconst texinfo-indexvar-alist - '(("cp" . texinfo-cindex) - ("fn" . texinfo-findex) - ("vr" . texinfo-vindex) - ("tp" . texinfo-tindex) - ("pg" . texinfo-pindex) - ("ky" . texinfo-kindex))) - - -;;; @defindex @defcodeindex -(put 'defindex 'texinfo-format 'texinfo-format-defindex) -(put 'defcodeindex 'texinfo-format 'texinfo-format-defindex) - -(defun texinfo-format-defindex () - (let* ((index-name (texinfo-parse-arg-discard)) ; eg: `aa' - (indexing-command (intern (concat index-name "index"))) - (index-formatting-command ; eg: `texinfo-format-aaindex' - (intern (concat "texinfo-format-" index-name "index"))) - (index-alist-name ; eg: `texinfo-aaindex' - (intern (concat "texinfo-" index-name "index")))) - - (set index-alist-name nil) - - (put indexing-command ; eg, aaindex - 'texinfo-format - index-formatting-command) ; eg, texinfo-format-aaindex - - ;; eg: "aa" . texinfo-aaindex - (or (assoc index-name texinfo-indexvar-alist) - (setq texinfo-indexvar-alist - (cons - (cons index-name - index-alist-name) - texinfo-indexvar-alist))) - - (fset index-formatting-command - (list 'lambda 'nil - (list 'texinfo-index - (list 'quote index-alist-name)))))) - - -;;; @synindex @syncodeindex - -(put 'synindex 'texinfo-format 'texinfo-format-synindex) -(put 'syncodeindex 'texinfo-format 'texinfo-format-synindex) - -(defun texinfo-format-synindex () - (let* ((args (texinfo-parse-arg-discard)) - (second (cdr (read-from-string args))) - (joiner (symbol-name (car (read-from-string args)))) - (joined (symbol-name (car (read-from-string args second))))) - - (if (assoc joiner texinfo-short-index-cmds-alist) - (put - (cdr (assoc joiner texinfo-short-index-cmds-alist)) - 'texinfo-format - (or (cdr (assoc joined texinfo-short-index-format-cmds-alist)) - (intern (concat "texinfo-format-" joined "index")))) - (put - (intern (concat joiner "index")) - 'texinfo-format - (or (cdr(assoc joined texinfo-short-index-format-cmds-alist)) - (intern (concat "texinfo-format-" joined "index"))))))) - -(defconst texinfo-short-index-cmds-alist - '(("cp" . cindex) - ("fn" . findex) - ("vr" . vindex) - ("tp" . tindex) - ("pg" . pindex) - ("ky" . kindex))) - -(defconst texinfo-short-index-format-cmds-alist - '(("cp" . texinfo-format-cindex) - ("fn" . texinfo-format-findex) - ("vr" . texinfo-format-vindex) - ("tp" . texinfo-format-tindex) - ("pg" . texinfo-format-pindex) - ("ky" . texinfo-format-kindex))) - - -;;; Sort and index (for VMS) - -;; Sort an index which is in the current buffer between START and END. -;; Used on VMS, where the `sort' utility is not available. -(defun texinfo-sort-region (start end) - (require 'sort) - (save-restriction - (narrow-to-region start end) - (sort-subr nil 'forward-line 'end-of-line 'texinfo-sort-startkeyfun))) - -;; Subroutine for sorting an index. -;; At start of a line, return a string to sort the line under. -(defun texinfo-sort-startkeyfun () - (let ((line - (buffer-substring (point) (save-excursion (end-of-line) (point))))) - ;; Canonicalize whitespace and eliminate funny chars. - (while (string-match "[ \t][ \t]+\\|[^a-z0-9 ]+" line) - (setq line (concat (substring line 0 (match-beginning 0)) - " " - (substring line (match-end 0) (length line))))) - line)) - - -;;; @printindex - -(put 'printindex 'texinfo-format 'texinfo-format-printindex) - -(defun texinfo-format-printindex () - (let ((indexelts (symbol-value - (cdr (assoc (texinfo-parse-arg-discard) - texinfo-indexvar-alist)))) - opoint) - (insert "\n* Menu:\n\n") - (setq opoint (point)) - (texinfo-print-index nil indexelts) - - (if (eq system-type 'vax-vms) - (texinfo-sort-region opoint (point)) - (shell-command-on-region opoint (point) "sort -fd" 1)))) - -(defun texinfo-print-index (file indexelts) - (while indexelts - (if (stringp (car (car indexelts))) - (progn - (insert "* " (car (car indexelts)) ": " ) - (indent-to 32) - (insert - (if file (concat "(" file ")") "") - (nth 1 (car indexelts)) ".") - (indent-to 54) - (insert - (if (nth 2 (car indexelts)) - (format " %d." (nth 2 (car indexelts))) - "") - "\n")) - ;; index entries from @include'd file - (texinfo-print-index (nth 1 (car indexelts)) - (nth 2 (car indexelts)))) - (setq indexelts (cdr indexelts)))) - - -;;; Glyphs: @equiv, @error, etc - -;; @equiv to show that two expressions are equivalent -;; @error to show an error message -;; @expansion to show what a macro expands to -;; @point to show the location of point in an example -;; @print to show what an evaluated expression prints -;; @result to indicate the value returned by an expression - -(put 'equiv 'texinfo-format 'texinfo-format-equiv) -(defun texinfo-format-equiv () - (texinfo-parse-arg-discard) - (insert "==")) - -(put 'error 'texinfo-format 'texinfo-format-error) -(defun texinfo-format-error () - (texinfo-parse-arg-discard) - (insert "error-->")) - -(put 'expansion 'texinfo-format 'texinfo-format-expansion) -(defun texinfo-format-expansion () - (texinfo-parse-arg-discard) - (insert "==>")) - -(put 'point 'texinfo-format 'texinfo-format-point) -(defun texinfo-format-point () - (texinfo-parse-arg-discard) - (insert "-!-")) - -(put 'print 'texinfo-format 'texinfo-format-print) -(defun texinfo-format-print () - (texinfo-parse-arg-discard) - (insert "-|")) - -(put 'result 'texinfo-format 'texinfo-format-result) -(defun texinfo-format-result () - (texinfo-parse-arg-discard) - (insert "=>")) - - -;;; Definition formatting: @deffn, @defun, etc - -;; What definition formatting produces: -;; -;; @deffn category name args... -;; In Info, `Category: name ARGS' -;; In index: name: node. line#. -;; -;; @defvr category name -;; In Info, `Category: name' -;; In index: name: node. line#. -;; -;; @deftp category name attributes... -;; `category name attributes...' Note: @deftp args in lower case. -;; In index: name: node. line#. -;; -;; Specialized function-like or variable-like entity: -;; -;; @defun, @defmac, @defspec, @defvar, @defopt -;; -;; @defun name args In Info, `Function: name ARGS' -;; @defmac name args In Info, `Macro: name ARGS' -;; @defvar name In Info, `Variable: name' -;; etc. -;; In index: name: node. line#. -;; -;; Generalized typed-function-like or typed-variable-like entity: -;; @deftypefn category data-type name args... -;; In Info, `Category: data-type name args...' -;; @deftypevr category data-type name -;; In Info, `Category: data-type name' -;; In index: name: node. line#. -;; -;; Specialized typed-function-like or typed-variable-like entity: -;; @deftypefun data-type name args... -;; In Info, `Function: data-type name ARGS' -;; In index: name: node. line#. -;; -;; @deftypevar data-type name -;; In Info, `Variable: data-type name' -;; In index: name: node. line#. but include args after name!? -;; -;; Generalized object oriented entity: -;; @defop category class name args... -;; In Info, `Category on class: name ARG' -;; In index: name on class: node. line#. -;; -;; @defcv category class name -;; In Info, `Category of class: name' -;; In index: name of class: node. line#. -;; -;; Specialized object oriented entity: -;; @defmethod class name args... -;; In Info, `Method on class: name ARGS' -;; In index: name on class: node. line#. -;; -;; @defivar class name -;; In Info, `Instance variable of class: name' -;; In index: name of class: node. line#. - - -;;; The definition formatting functions - -(defun texinfo-format-defun () - (texinfo-push-stack 'defun nil) - (setq fill-column (- fill-column 5)) - (texinfo-format-defun-1 t)) - -(defun texinfo-end-defun () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((start (nth 1 (texinfo-pop-stack 'defun)))) - (texinfo-do-itemize start) - ;; Delete extra newline inserted after header. - (save-excursion - (goto-char start) - (delete-char -1)))) - -(defun texinfo-format-defunx () - (texinfo-format-defun-1 nil)) - -(defun texinfo-format-defun-1 (first-p) - (let ((parse-args (texinfo-format-parse-defun-args)) - (texinfo-defun-type (get texinfo-command-name 'texinfo-defun-type))) - (texinfo-discard-command) - ;; Delete extra newline inserted after previous header line. - (if (not first-p) - (delete-char -1)) - (funcall - (get texinfo-command-name 'texinfo-deffn-formatting-property) parse-args) - ;; Insert extra newline so that paragraph filling does not mess - ;; with header line. - (insert "\n\n") - (rplaca (cdr (cdr (car texinfo-stack))) (point)) - (funcall - (get texinfo-command-name 'texinfo-defun-indexing-property) parse-args))) - -;;; Formatting the first line of a definition - -;; @deffn, @defvr, @deftp -(put 'deffn 'texinfo-deffn-formatting-property 'texinfo-format-deffn) -(put 'deffnx 'texinfo-deffn-formatting-property 'texinfo-format-deffn) -(put 'defvr 'texinfo-deffn-formatting-property 'texinfo-format-deffn) -(put 'defvrx 'texinfo-deffn-formatting-property 'texinfo-format-deffn) -(put 'deftp 'texinfo-deffn-formatting-property 'texinfo-format-deffn) -(put 'deftpx 'texinfo-deffn-formatting-property 'texinfo-format-deffn) -(defun texinfo-format-deffn (parsed-args) - ;; Generalized function-like, variable-like, or generic data-type entity: - ;; @deffn category name args... - ;; In Info, `Category: name ARGS' - ;; @deftp category name attributes... - ;; `category name attributes...' Note: @deftp args in lower case. - (let ((category (car parsed-args)) - (name (car (cdr parsed-args))) - (args (cdr (cdr parsed-args)))) - (insert " -- " category ": " name) - (while args - (insert " " - (if (or (= ?& (aref (car args) 0)) - (eq (eval (car texinfo-defun-type)) 'deftp-type)) - (car args) - (upcase (car args)))) - (setq args (cdr args))))) - -;; @defun, @defmac, @defspec, @defvar, @defopt: Specialized, simple -(put 'defun 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defunx 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defmac 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defmacx 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defspec 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defspecx 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defvar 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defvarx 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defopt 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defoptx 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(defun texinfo-format-specialized-defun (parsed-args) - ;; Specialized function-like or variable-like entity: - ;; @defun name args In Info, `Function: Name ARGS' - ;; @defmac name args In Info, `Macro: Name ARGS' - ;; @defvar name In Info, `Variable: Name' - ;; Use cdr of texinfo-defun-type to determine category: - (let ((category (car (cdr texinfo-defun-type))) - (name (car parsed-args)) - (args (cdr parsed-args))) - (insert " -- " category ": " name) - (while args - (insert " " - (if (= ?& (aref (car args) 0)) - (car args) - (upcase (car args)))) - (setq args (cdr args))))) - -;; @deftypefn, @deftypevr: Generalized typed -(put 'deftypefn 'texinfo-deffn-formatting-property 'texinfo-format-deftypefn) -(put 'deftypefnx 'texinfo-deffn-formatting-property 'texinfo-format-deftypefn) -(put 'deftypevr 'texinfo-deffn-formatting-property 'texinfo-format-deftypefn) -(put 'deftypevrx 'texinfo-deffn-formatting-property 'texinfo-format-deftypefn) -(defun texinfo-format-deftypefn (parsed-args) - ;; Generalized typed-function-like or typed-variable-like entity: - ;; @deftypefn category data-type name args... - ;; In Info, `Category: data-type name args...' - ;; @deftypevr category data-type name - ;; In Info, `Category: data-type name' - ;; Note: args in lower case, unless modified in command line. - (let ((category (car parsed-args)) - (data-type (car (cdr parsed-args))) - (name (car (cdr (cdr parsed-args)))) - (args (cdr (cdr (cdr parsed-args))))) - (insert " -- " category ": " data-type " " name) - (while args - (insert " " (car args)) - (setq args (cdr args))))) - -;; @deftypefun, @deftypevar: Specialized typed -(put 'deftypefun 'texinfo-deffn-formatting-property 'texinfo-format-deftypefun) -(put 'deftypefunx 'texinfo-deffn-formatting-property - 'texinfo-format-deftypefun) -(put 'deftypevar 'texinfo-deffn-formatting-property 'texinfo-format-deftypefun) -(put 'deftypevarx 'texinfo-deffn-formatting-property - 'texinfo-format-deftypefun) -(defun texinfo-format-deftypefun (parsed-args) - ;; Specialized typed-function-like or typed-variable-like entity: - ;; @deftypefun data-type name args... - ;; In Info, `Function: data-type name ARGS' - ;; @deftypevar data-type name - ;; In Info, `Variable: data-type name' - ;; Note: args in lower case, unless modified in command line. - ;; Use cdr of texinfo-defun-type to determine category: - (let ((category (car (cdr texinfo-defun-type))) - (data-type (car parsed-args)) - (name (car (cdr parsed-args))) - (args (cdr (cdr parsed-args)))) - (insert " -- " category ": " data-type " " name) - (while args - (insert " " (car args)) - (setq args (cdr args))))) - -;; @defop: Generalized object-oriented -(put 'defop 'texinfo-deffn-formatting-property 'texinfo-format-defop) -(put 'defopx 'texinfo-deffn-formatting-property 'texinfo-format-defop) -(defun texinfo-format-defop (parsed-args) - ;; Generalized object oriented entity: - ;; @defop category class name args... - ;; In Info, `Category on class: name ARG' - ;; Note: args in upper case; use of `on' - (let ((category (car parsed-args)) - (class (car (cdr parsed-args))) - (name (car (cdr (cdr parsed-args)))) - (args (cdr (cdr (cdr parsed-args))))) - (insert " -- " category " on " class ": " name) - (while args - (insert " " (upcase (car args))) - (setq args (cdr args))))) - -;; @defcv: Generalized object-oriented -(put 'defcv 'texinfo-deffn-formatting-property 'texinfo-format-defcv) -(put 'defcvx 'texinfo-deffn-formatting-property 'texinfo-format-defcv) -(defun texinfo-format-defcv (parsed-args) - ;; Generalized object oriented entity: - ;; @defcv category class name - ;; In Info, `Category of class: name' - ;; Note: args in upper case; use of `of' - (let ((category (car parsed-args)) - (class (car (cdr parsed-args))) - (name (car (cdr (cdr parsed-args)))) - (args (cdr (cdr (cdr parsed-args))))) - (insert " -- " category " of " class ": " name) - (while args - (insert " " (upcase (car args))) - (setq args (cdr args))))) - -;; @defmethod: Specialized object-oriented -(put 'defmethod 'texinfo-deffn-formatting-property 'texinfo-format-defmethod) -(put 'defmethodx 'texinfo-deffn-formatting-property 'texinfo-format-defmethod) -(defun texinfo-format-defmethod (parsed-args) - ;; Specialized object oriented entity: - ;; @defmethod class name args... - ;; In Info, `Method on class: name ARGS' - ;; Note: args in upper case; use of `on' - ;; Use cdr of texinfo-defun-type to determine category: - (let ((category (car (cdr texinfo-defun-type))) - (class (car parsed-args)) - (name (car (cdr parsed-args))) - (args (cdr (cdr parsed-args)))) - (insert " -- " category " on " class ": " name) - (while args - (insert " " (upcase (car args))) - (setq args (cdr args))))) - -;; @defivar: Specialized object-oriented -(put 'defivar 'texinfo-deffn-formatting-property 'texinfo-format-defivar) -(put 'defivarx 'texinfo-deffn-formatting-property 'texinfo-format-defivar) -(defun texinfo-format-defivar (parsed-args) - ;; Specialized object oriented entity: - ;; @defivar class name - ;; In Info, `Instance variable of class: name' - ;; Note: args in upper case; use of `of' - ;; Use cdr of texinfo-defun-type to determine category: - (let ((category (car (cdr texinfo-defun-type))) - (class (car parsed-args)) - (name (car (cdr parsed-args))) - (args (cdr (cdr parsed-args)))) - (insert " -- " category " of " class ": " name) - (while args - (insert " " (upcase (car args))) - (setq args (cdr args))))) - - -;;; Indexing for definitions - -;; An index entry has three parts: the `entry proper', the node name, and the -;; line number. Depending on the which command is used, the entry is -;; formatted differently: -;; -;; @defun, -;; @defmac, -;; @defspec, -;; @defvar, -;; @defopt all use their 1st argument as the entry-proper -;; -;; @deffn, -;; @defvr, -;; @deftp -;; @deftypefun -;; @deftypevar all use their 2nd argument as the entry-proper -;; -;; @deftypefn, -;; @deftypevr both use their 3rd argument as the entry-proper -;; -;; @defmethod uses its 2nd and 1st arguments as an entry-proper -;; formatted: NAME on CLASS - -;; @defop uses its 3rd and 2nd arguments as an entry-proper -;; formatted: NAME on CLASS -;; -;; @defivar uses its 2nd and 1st arguments as an entry-proper -;; formatted: NAME of CLASS -;; -;; @defcv uses its 3rd and 2nd argument as an entry-proper -;; formatted: NAME of CLASS - -(put 'defun 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defunx 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defmac 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defmacx 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defspec 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defspecx 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defvar 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defvarx 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defopt 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defoptx 'texinfo-defun-indexing-property 'texinfo-index-defun) -(defun texinfo-index-defun (parsed-args) - ;; use 1st parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (car parsed-args) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - -(put 'deffn 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deffnx 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'defvr 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'defvrx 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deftp 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deftpx 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deftypefun 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deftypefunx 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deftypevar 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deftypevarx 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(defun texinfo-index-deffn (parsed-args) - ;; use 2nd parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (car (cdr parsed-args)) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - -(put 'deftypefn 'texinfo-defun-indexing-property 'texinfo-index-deftypefn) -(put 'deftypefnx 'texinfo-defun-indexing-property 'texinfo-index-deftypefn) -(put 'deftypevr 'texinfo-defun-indexing-property 'texinfo-index-deftypefn) -(put 'deftypevrx 'texinfo-defun-indexing-property 'texinfo-index-deftypefn) -(defun texinfo-index-deftypefn (parsed-args) - ;; use 3rd parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (car (cdr (cdr parsed-args))) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - -(put 'defmethod 'texinfo-defun-indexing-property 'texinfo-index-defmethod) -(put 'defmethodx 'texinfo-defun-indexing-property 'texinfo-index-defmethod) -(defun texinfo-index-defmethod (parsed-args) - ;; use 2nd on 1st parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (format "%s on %s" - (car (cdr parsed-args)) - (car parsed-args)) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - -(put 'defop 'texinfo-defun-indexing-property 'texinfo-index-defop) -(put 'defopx 'texinfo-defun-indexing-property 'texinfo-index-defop) -(defun texinfo-index-defop (parsed-args) - ;; use 3rd on 2nd parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (format "%s on %s" - (car (cdr (cdr parsed-args))) - (car (cdr parsed-args))) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - -(put 'defivar 'texinfo-defun-indexing-property 'texinfo-index-defivar) -(put 'defivarx 'texinfo-defun-indexing-property 'texinfo-index-defivar) -(defun texinfo-index-defivar (parsed-args) - ;; use 2nd of 1st parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (format "%s of %s" - (car (cdr parsed-args)) - (car parsed-args)) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - -(put 'defcv 'texinfo-defun-indexing-property 'texinfo-index-defcv) -(put 'defcvx 'texinfo-defun-indexing-property 'texinfo-index-defcv) -(defun texinfo-index-defcv (parsed-args) - ;; use 3rd of 2nd parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (format "%s of %s" - (car (cdr (cdr parsed-args))) - (car (cdr parsed-args))) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - - -;;; Properties for definitions - -;; Each definition command has six properties: -;; -;; 1. texinfo-deffn-formatting-property to format definition line -;; 2. texinfo-defun-indexing-property to create index entry -;; 3. texinfo-format formatting command -;; 4. texinfo-end end formatting command -;; 5. texinfo-defun-type type of deffn to format -;; 6. texinfo-defun-index type of index to use -;; -;; The `x' forms of each definition command are used for the second -;; and subsequent header lines. - -;; The texinfo-deffn-formatting-property and texinfo-defun-indexing-property -;; are listed just before the appropriate formatting and indexing commands. - -(put 'deffn 'texinfo-format 'texinfo-format-defun) -(put 'deffnx 'texinfo-format 'texinfo-format-defunx) -(put 'deffn 'texinfo-end 'texinfo-end-defun) -(put 'deffn 'texinfo-defun-type '('deffn-type nil)) -(put 'deffnx 'texinfo-defun-type '('deffn-type nil)) -(put 'deffn 'texinfo-defun-index 'texinfo-findex) -(put 'deffnx 'texinfo-defun-index 'texinfo-findex) - -(put 'defun 'texinfo-format 'texinfo-format-defun) -(put 'defunx 'texinfo-format 'texinfo-format-defunx) -(put 'defun 'texinfo-end 'texinfo-end-defun) -(put 'defun 'texinfo-defun-type '('defun-type "Function")) -(put 'defunx 'texinfo-defun-type '('defun-type "Function")) -(put 'defun 'texinfo-defun-index 'texinfo-findex) -(put 'defunx 'texinfo-defun-index 'texinfo-findex) - -(put 'defmac 'texinfo-format 'texinfo-format-defun) -(put 'defmacx 'texinfo-format 'texinfo-format-defunx) -(put 'defmac 'texinfo-end 'texinfo-end-defun) -(put 'defmac 'texinfo-defun-type '('defun-type "Macro")) -(put 'defmacx 'texinfo-defun-type '('defun-type "Macro")) -(put 'defmac 'texinfo-defun-index 'texinfo-findex) -(put 'defmacx 'texinfo-defun-index 'texinfo-findex) - -(put 'defspec 'texinfo-format 'texinfo-format-defun) -(put 'defspecx 'texinfo-format 'texinfo-format-defunx) -(put 'defspec 'texinfo-end 'texinfo-end-defun) -(put 'defspec 'texinfo-defun-type '('defun-type "Special form")) -(put 'defspecx 'texinfo-defun-type '('defun-type "Special form")) -(put 'defspec 'texinfo-defun-index 'texinfo-findex) -(put 'defspecx 'texinfo-defun-index 'texinfo-findex) - -(put 'defvr 'texinfo-format 'texinfo-format-defun) -(put 'defvrx 'texinfo-format 'texinfo-format-defunx) -(put 'defvr 'texinfo-end 'texinfo-end-defun) -(put 'defvr 'texinfo-defun-type '('deffn-type nil)) -(put 'defvrx 'texinfo-defun-type '('deffn-type nil)) -(put 'defvr 'texinfo-defun-index 'texinfo-vindex) -(put 'defvrx 'texinfo-defun-index 'texinfo-vindex) - -(put 'defvar 'texinfo-format 'texinfo-format-defun) -(put 'defvarx 'texinfo-format 'texinfo-format-defunx) -(put 'defvar 'texinfo-end 'texinfo-end-defun) -(put 'defvar 'texinfo-defun-type '('defun-type "Variable")) -(put 'defvarx 'texinfo-defun-type '('defun-type "Variable")) -(put 'defvar 'texinfo-defun-index 'texinfo-vindex) -(put 'defvarx 'texinfo-defun-index 'texinfo-vindex) - -(put 'defconst 'texinfo-format 'texinfo-format-defun) -(put 'defconstx 'texinfo-format 'texinfo-format-defunx) -(put 'defconst 'texinfo-end 'texinfo-end-defun) -(put 'defconst 'texinfo-defun-type '('defun-type "Constant")) -(put 'defconstx 'texinfo-defun-type '('defun-type "Constant")) -(put 'defconst 'texinfo-defun-index 'texinfo-vindex) -(put 'defconstx 'texinfo-defun-index 'texinfo-vindex) - -(put 'defcmd 'texinfo-format 'texinfo-format-defun) -(put 'defcmdx 'texinfo-format 'texinfo-format-defunx) -(put 'defcmd 'texinfo-end 'texinfo-end-defun) -(put 'defcmd 'texinfo-defun-type '('defun-type "Command")) -(put 'defcmdx 'texinfo-defun-type '('defun-type "Command")) -(put 'defcmd 'texinfo-defun-index 'texinfo-findex) -(put 'defcmdx 'texinfo-defun-index 'texinfo-findex) - -(put 'defopt 'texinfo-format 'texinfo-format-defun) -(put 'defoptx 'texinfo-format 'texinfo-format-defunx) -(put 'defopt 'texinfo-end 'texinfo-end-defun) -(put 'defopt 'texinfo-defun-type '('defun-type "User Option")) -(put 'defoptx 'texinfo-defun-type '('defun-type "User Option")) -(put 'defopt 'texinfo-defun-index 'texinfo-vindex) -(put 'defoptx 'texinfo-defun-index 'texinfo-vindex) - -(put 'deftp 'texinfo-format 'texinfo-format-defun) -(put 'deftpx 'texinfo-format 'texinfo-format-defunx) -(put 'deftp 'texinfo-end 'texinfo-end-defun) -(put 'deftp 'texinfo-defun-type '('deftp-type nil)) -(put 'deftpx 'texinfo-defun-type '('deftp-type nil)) -(put 'deftp 'texinfo-defun-index 'texinfo-tindex) -(put 'deftpx 'texinfo-defun-index 'texinfo-tindex) - -;;; Object-oriented stuff is a little hairier. - -(put 'defop 'texinfo-format 'texinfo-format-defun) -(put 'defopx 'texinfo-format 'texinfo-format-defunx) -(put 'defop 'texinfo-end 'texinfo-end-defun) -(put 'defop 'texinfo-defun-type '('defop-type nil)) -(put 'defopx 'texinfo-defun-type '('defop-type nil)) -(put 'defop 'texinfo-defun-index 'texinfo-findex) -(put 'defopx 'texinfo-defun-index 'texinfo-findex) - -(put 'defmethod 'texinfo-format 'texinfo-format-defun) -(put 'defmethodx 'texinfo-format 'texinfo-format-defunx) -(put 'defmethod 'texinfo-end 'texinfo-end-defun) -(put 'defmethod 'texinfo-defun-type '('defmethod-type "Method")) -(put 'defmethodx 'texinfo-defun-type '('defmethod-type "Method")) -(put 'defmethod 'texinfo-defun-index 'texinfo-findex) -(put 'defmethodx 'texinfo-defun-index 'texinfo-findex) - -(put 'defcv 'texinfo-format 'texinfo-format-defun) -(put 'defcvx 'texinfo-format 'texinfo-format-defunx) -(put 'defcv 'texinfo-end 'texinfo-end-defun) -(put 'defcv 'texinfo-defun-type '('defop-type nil)) -(put 'defcvx 'texinfo-defun-type '('defop-type nil)) -(put 'defcv 'texinfo-defun-index 'texinfo-vindex) -(put 'defcvx 'texinfo-defun-index 'texinfo-vindex) - -(put 'defivar 'texinfo-format 'texinfo-format-defun) -(put 'defivarx 'texinfo-format 'texinfo-format-defunx) -(put 'defivar 'texinfo-end 'texinfo-end-defun) -(put 'defivar 'texinfo-defun-type '('defmethod-type "Instance variable")) -(put 'defivarx 'texinfo-defun-type '('defmethod-type "Instance variable")) -(put 'defivar 'texinfo-defun-index 'texinfo-vindex) -(put 'defivarx 'texinfo-defun-index 'texinfo-vindex) - -;;; Typed functions and variables - -(put 'deftypefn 'texinfo-format 'texinfo-format-defun) -(put 'deftypefnx 'texinfo-format 'texinfo-format-defunx) -(put 'deftypefn 'texinfo-end 'texinfo-end-defun) -(put 'deftypefn 'texinfo-defun-type '('deftypefn-type nil)) -(put 'deftypefnx 'texinfo-defun-type '('deftypefn-type nil)) -(put 'deftypefn 'texinfo-defun-index 'texinfo-findex) -(put 'deftypefnx 'texinfo-defun-index 'texinfo-findex) - -(put 'deftypefun 'texinfo-format 'texinfo-format-defun) -(put 'deftypefunx 'texinfo-format 'texinfo-format-defunx) -(put 'deftypefun 'texinfo-end 'texinfo-end-defun) -(put 'deftypefun 'texinfo-defun-type '('deftypefun-type "Function")) -(put 'deftypefunx 'texinfo-defun-type '('deftypefun-type "Function")) -(put 'deftypefun 'texinfo-defun-index 'texinfo-findex) -(put 'deftypefunx 'texinfo-defun-index 'texinfo-findex) - -(put 'deftypevr 'texinfo-format 'texinfo-format-defun) -(put 'deftypevrx 'texinfo-format 'texinfo-format-defunx) -(put 'deftypevr 'texinfo-end 'texinfo-end-defun) -(put 'deftypevr 'texinfo-defun-type '('deftypefn-type nil)) -(put 'deftypevrx 'texinfo-defun-type '('deftypefn-type nil)) -(put 'deftypevr 'texinfo-defun-index 'texinfo-vindex) -(put 'deftypevrx 'texinfo-defun-index 'texinfo-vindex) - -(put 'deftypevar 'texinfo-format 'texinfo-format-defun) -(put 'deftypevarx 'texinfo-format 'texinfo-format-defunx) -(put 'deftypevar 'texinfo-end 'texinfo-end-defun) -(put 'deftypevar 'texinfo-defun-type '('deftypevar-type "Variable")) -(put 'deftypevarx 'texinfo-defun-type '('deftypevar-type "Variable")) -(put 'deftypevar 'texinfo-defun-index 'texinfo-vindex) -(put 'deftypevarx 'texinfo-defun-index 'texinfo-vindex) - - -;;; @set, @clear, @ifset, @ifclear - -;; If a flag is set with @set FLAG, then text between @ifset and @end -;; ifset is formatted normally, but if the flag is is cleared with -;; @clear FLAG, then the text is not formatted; it is ignored. - -;; If a flag is cleared with @clear FLAG, then text between @ifclear -;; and @end ifclear is formatted normally, but if the flag is is set with -;; @set FLAG, then the text is not formatted; it is ignored. @ifclear -;; is the opposite of @ifset. - -;; If a flag is set to a string with @set FLAG, -;; replace @value{FLAG} with the string. -;; If a flag with a value is cleared, -;; @value{FLAG} is invalid, -;; as if there had never been any @set FLAG previously. - -(put 'clear 'texinfo-format 'texinfo-clear) -(defun texinfo-clear () - "Clear the value of the flag." - (let* ((arg (texinfo-parse-arg-discard)) - (flag (car (read-from-string arg))) - (value (substring arg (cdr (read-from-string arg))))) - (put flag 'texinfo-whether-setp 'flag-cleared) - (put flag 'texinfo-set-value ""))) - -(put 'set 'texinfo-format 'texinfo-set) -(defun texinfo-set () - "Set the value of the flag, optionally to a string. -The command `@set foo This is a string.' -sets flag foo to the value: `This is a string.' -The command `@value{foo}' expands to the value." - (let* ((arg (texinfo-parse-arg-discard)) - (flag (car (read-from-string arg))) - (value (substring arg (cdr (read-from-string arg))))) - (put flag 'texinfo-whether-setp 'flag-set) - (put flag 'texinfo-set-value value))) - -(put 'value 'texinfo-format 'texinfo-value) -(defun texinfo-value () - "Insert the string to which the flag is set. -The command `@set foo This is a string.' -sets flag foo to the value: `This is a string.' -The command `@value{foo}' expands to the value." - (let ((arg (texinfo-parse-arg-discard))) - (cond ((and - (eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - 'flag-set) - (get (car (read-from-string arg)) 'texinfo-set-value)) - (insert (get (car (read-from-string arg)) 'texinfo-set-value))) - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - 'flag-cleared) - (insert (format "{No value for \"%s\"}" arg))) - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) nil) - (insert (format "{No value for \"%s\"}" arg)))))) - -(put 'ifset 'texinfo-end 'texinfo-discard-command) -(put 'ifset 'texinfo-format 'texinfo-if-set) -(defun texinfo-if-set () - "If set, continue formatting; else do not format region up to @end ifset" - (let ((arg (texinfo-parse-arg-discard))) - (cond - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - 'flag-set) - ;; Format the text (i.e., do not remove it); do nothing here. - ()) - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - 'flag-cleared) - ;; Clear region (i.e., cause the text to be ignored). - (delete-region texinfo-command-start - (progn (re-search-forward "@end ifset[ \t]*\n") - (point)))) - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - nil) - ;; In this case flag is neither set nor cleared. - ;; Act as if set, i.e. do nothing. - ())))) - -(put 'ifclear 'texinfo-end 'texinfo-discard-command) -(put 'ifclear 'texinfo-format 'texinfo-if-clear) -(defun texinfo-if-clear () - "If clear, continue formatting; if set, do not format up to @end ifset" - (let ((arg (texinfo-parse-arg-discard))) - (cond - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - 'flag-set) - ;; Clear region (i.e., cause the text to be ignored). - (delete-region texinfo-command-start - (progn (re-search-forward "@end ifclear[ \t]*\n") - (point)))) - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - 'flag-cleared) - ;; Format the text (i.e., do not remove it); do nothing here. - ()) - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - nil) - ;; In this case flag is neither set nor cleared. - ;; Act as if clear, i.e. do nothing. - ())))) - - -;;; Process included files: `@include' command - -;; Updated 19 October 1990 -;; In the original version, include files were ignored by Info but -;; incorporated in to the printed manual. To make references to the -;; included file, the Texinfo source file has to refer to the included -;; files using the `(filename)nodename' format for refering to other -;; Info files. Also, the included files had to be formatted on their -;; own. It was just like they were another file. - -;; Currently, include files are inserted into the buffer that is -;; formatted for Info. If large, the resulting info file is split and -;; tagified. For current include files to work, the master menu must -;; refer to all the nodes, and the highest level nodes in the include -;; files must have the correct next, prev, and up pointers. - -;; The included file may have an @setfilename and even an @settitle, -;; but not an `\input texinfo' line. - -;; Updated 24 March 1993 -;; In order for @raisesections and @lowersections to work, included -;; files must be inserted into the buffer holding the outer file -;; before other Info formatting takes place. So @include is no longer -;; is treated like other @-commands. -(put 'include 'texinfo-format 'texinfo-format-noop) - -; Original definition: -; (defun texinfo-format-include () -; (let ((filename (texinfo-parse-arg-discard)) -; (default-directory input-directory) -; subindex) -; (setq subindex -; (save-excursion -; (progn (find-file -; (cond ((file-readable-p (concat filename ".texinfo")) -; (concat filename ".texinfo")) -; ((file-readable-p (concat filename ".texi")) -; (concat filename ".texi")) -; ((file-readable-p (concat filename ".tex")) -; (concat filename ".tex")) -; ((file-readable-p filename) -; filename) -; (t (error "@include'd file %s not found" -; filename)))) -; (texinfo-format-buffer-1)))) -; (texinfo-subindex 'texinfo-vindex (car subindex) (nth 1 subindex)) -; (texinfo-subindex 'texinfo-findex (car subindex) (nth 2 subindex)) -; (texinfo-subindex 'texinfo-cindex (car subindex) (nth 3 subindex)) -; (texinfo-subindex 'texinfo-pindex (car subindex) (nth 4 subindex)) -; (texinfo-subindex 'texinfo-tindex (car subindex) (nth 5 subindex)) -; (texinfo-subindex 'texinfo-kindex (car subindex) (nth 6 subindex)))) -; -;(defun texinfo-subindex (indexvar file content) -; (set indexvar (cons (list 'recurse file content) -; (symbol-value indexvar)))) - -; Second definition: -; (put 'include 'texinfo-format 'texinfo-format-include) -; (defun texinfo-format-include () -; (let ((filename (concat input-directory -; (texinfo-parse-arg-discard))) -; (default-directory input-directory)) -; (message "Reading: %s" filename) -; (save-excursion -; (save-restriction -; (narrow-to-region -; (point) -; (+ (point) (car (cdr (insert-file-contents filename))))) -; (goto-char (point-min)) -; (texinfo-append-refill) -; (texinfo-format-convert (point-min) (point-max)))) -; (setq last-input-buffer input-buffer) ; to bypass setfilename -; )) - - -;;; Numerous commands do nothing in Texinfo - -;; These commands are defined in texinfo.tex for printed output. - -(put 'bye 'texinfo-format 'texinfo-discard-line) -(put 'c 'texinfo-format 'texinfo-discard-line-with-args) -(put 'comment 'texinfo-format 'texinfo-discard-line-with-args) -(put 'contents 'texinfo-format 'texinfo-discard-line-with-args) -(put 'finalout 'texinfo-format 'texinfo-discard-line) -(put 'group 'texinfo-end 'texinfo-discard-line-with-args) -(put 'group 'texinfo-format 'texinfo-discard-line-with-args) -(put 'headings 'texinfo-format 'texinfo-discard-line-with-args) -(put 'hsize 'texinfo-format 'texinfo-discard-line-with-args) -(put 'itemindent 'texinfo-format 'texinfo-discard-line-with-args) -(put 'lispnarrowing 'texinfo-format 'texinfo-discard-line-with-args) -(put 'need 'texinfo-format 'texinfo-discard-line-with-args) -(put 'nopara 'texinfo-format 'texinfo-discard-line-with-args) -(put 'page 'texinfo-format 'texinfo-discard-line-with-args) -(put 'parindent 'texinfo-format 'texinfo-discard-line-with-args) -(put 'setchapternewpage 'texinfo-format 'texinfo-discard-line-with-args) -(put 'setq 'texinfo-format 'texinfo-discard-line-with-args) -(put 'settitle 'texinfo-format 'texinfo-discard-line-with-args) -(put 'setx 'texinfo-format 'texinfo-discard-line-with-args) -(put 'shortcontents 'texinfo-format 'texinfo-discard-line-with-args) -(put 'shorttitlepage 'texinfo-format 'texinfo-discard-line-with-args) -(put 'smallbook 'texinfo-format 'texinfo-discard-line) -(put 'summarycontents 'texinfo-format 'texinfo-discard-line-with-args) - - -;;; Some commands cannot be handled - -(defun texinfo-unsupported () - (error "%s is not handled by texinfo" - (buffer-substring texinfo-command-start texinfo-command-end))) - -;;; Batch formatting - -(defun batch-texinfo-format () - "Runs texinfo-format-buffer 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 -funcall batch-texinfo-format $docs/ ~/*.texinfo\"." - (if (not noninteractive) - (error "batch-texinfo-format 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)) - (let ((error 0) - file - (files ())) - (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 (directory-files file) - (cdr command-line-args-left)))) - (t - (setq files (cons file files) - command-line-args-left (cdr command-line-args-left))))) - (while files - (setq file (car files) - files (cdr files)) - (condition-case err - (progn - (if buffer-file-name (kill-buffer (current-buffer))) - (find-file file) - (buffer-disable-undo (current-buffer)) - (set-buffer-modified-p nil) - (texinfo-mode) - (message "texinfo formatting %s..." file) - (texinfo-format-buffer nil) - (if (buffer-modified-p) - (progn (message "Saving modified %s" (buffer-file-name)) - (save-buffer)))) - (error - (message ">> Error: %s" (prin1-to-string err)) - (message ">> point at") - (let ((s (buffer-substring (point) - (min (+ (point) 100) - (point-max)))) - (tem 0)) - (while (setq tem (string-match "\n+" s tem)) - (setq s (concat (substring s 0 (match-beginning 0)) - "\n>> " - (substring s (match-end 0))) - tem (1+ tem))) - (message ">> %s" s)) - (setq error 1)))) - (kill-emacs error)))) - - -;;; Place `provide' at end of file. -(provide 'texinfmt) - -;;; texinfmt.el ends here. diff --git a/gnu/usr.bin/texinfo/emacs/texinfo.el b/gnu/usr.bin/texinfo/emacs/texinfo.el deleted file mode 100644 index 2ed5a3291d1..00000000000 --- a/gnu/usr.bin/texinfo/emacs/texinfo.el +++ /dev/null @@ -1,757 +0,0 @@ -;;;; texinfo.el--major mode for editing Texinfo files. -;; Copyright (C) 1985, '88, '89, -;; '90, '91, '92, '93 Free Software Foundation, Inc. - -;;; Author: Robert J. Chassell -;;; Maintainer: FSF - -;;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - - -;;; Autoloads: - -(autoload 'makeinfo-region - "makeinfo" - "Make Info file from region of current Texinfo file, and switch to it. - -This command does not offer the `next-error' feature since it would -apply to a temporary file, not the original; use the `makeinfo-buffer' -command to gain use of `next-error'." - t nil) - -(autoload 'makeinfo-buffer - "makeinfo" - "Make Info file from current buffer. - -Use the \\[next-error] command to move to the next error -\(if there are errors\)." - t nil) - -(autoload 'kill-compilation - "compile" - "Kill the process made by the \\[compile] command." - t nil) - -(autoload 'makeinfo-recenter-compilation-buffer - "makeinfo" - "Redisplay `*compilation*' buffer so most recent output can be seen. -The last line of the buffer is displayed on -line LINE of the window, or centered if LINE is nil." - t nil) - -(autoload 'texinfo-make-menu - "texnfo-upd" - "Without any prefix argument, make or update a menu. -Make the menu for the section enclosing the node found following point. - -Non-nil argument (prefix, if interactive) means make or update menus -for nodes within or part of the marked region. - -Whenever a menu exists, and is being updated, the descriptions that -are associated with node names in the pre-existing menu are -incorporated into the new menu. Otherwise, the nodes' section titles -are inserted as descriptions." - t nil) - -(autoload 'texinfo-all-menus-update - "texnfo-upd" - "Update every regular menu in a Texinfo file. -Remove pre-existing master menu, if there is one. - -If called with a non-nil argument, this function first updates all the -nodes in the buffer before updating the menus." - t nil) - -(autoload 'texinfo-master-menu - "texnfo-upd" - "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-exisitng master menu using the -standard `texinfo-master-menu-header'. - -The master menu has the following format, which is adapted from the -recommendation in the Texinfo Manual: - - * The first part contains the major nodes in the Texinfo file: the - nodes for the chapters, chapter-like sections, and the major - appendices. This includes the indices, so long as they are in - chapter-like sections, such as unnumbered sections. - - * The second and subsequent parts contain a listing of the other, - lower level menus, in order. This way, an inquirer can go - directly to a particular node if he or she is searching for - specific information. - -Each of the menus in the detailed node listing is introduced by the -title of the section containing the menu." - t nil) - -(autoload 'texinfo-indent-menu-description - "texnfo-upd" - "Indent every description in menu following point to COLUMN. -Non-nil argument (prefix, if interactive) means indent every -description in every menu in the region. Does not indent second and -subsequent lines of a multi-line description." - t nil) - -(autoload 'texinfo-insert-node-lines - "texnfo-upd" - "Insert missing `@node' lines in region of Texinfo file. -Non-nil argument (prefix, if interactive) means also to insert the -section titles as node names; and also to insert the section titles as -node names in pre-existing @node lines that lack names." - t nil) - -(autoload 'texinfo-start-menu-description - "texnfo-upd" - "In this menu entry, insert the node's section title as a description. -Position point at beginning of description ready for editing. -Do not insert a title if the line contains an existing description. - -You will need to edit the inserted text since a useful description -complements the node name rather than repeats it as a title does." - t nil) - -(autoload 'texinfo-multiple-files-update - "texnfo-upd" - "Update first node pointers in each file included in OUTER-FILE; -create or update main menu in the outer file that refers to such nodes. -This does not create or update menus or pointers within the included files. - -With optional MAKE-MASTER-MENU argument (prefix arg, if interactive), -insert a master menu in OUTER-FILE. This does not create or update -menus or pointers within the included files. - -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. - -The command also updates the `Top' level node pointers of OUTER-FILE. - -Notes: - - * this command does NOT save any files--you must save the - outer file and any modified, included files. - - * except for the `Top' node, this command does NOT handle any - pre-existing nodes in the outer file; hence, indices must be - enclosed in an included file. - -Requirements: - - * each of the included files must contain exactly one highest - hierarchical level node, - * this highest node must be the first node in the included file, - * each highest hierarchical level node must be of the same type. - -Thus, normally, each included file contains one, and only one, -chapter." - t nil) - - -;;; Code: - -;;; Don't you dare insert any `require' calls at top level in this file--rms. - -;;; Syntax table - -(defvar texinfo-mode-syntax-table nil) - -(if texinfo-mode-syntax-table - nil - (setq texinfo-mode-syntax-table (make-syntax-table)) - (modify-syntax-entry ?\" " " texinfo-mode-syntax-table) - (modify-syntax-entry ?\\ " " texinfo-mode-syntax-table) - (modify-syntax-entry ?@ "\\" texinfo-mode-syntax-table) - (modify-syntax-entry ?\^q "\\" texinfo-mode-syntax-table) - (modify-syntax-entry ?\[ "(]" texinfo-mode-syntax-table) - (modify-syntax-entry ?\] ")[" texinfo-mode-syntax-table) - (modify-syntax-entry ?{ "(}" texinfo-mode-syntax-table) - (modify-syntax-entry ?} "){" texinfo-mode-syntax-table) - (modify-syntax-entry ?\' "w" texinfo-mode-syntax-table)) - -(defvar texinfo-font-lock-keywords - (list - '("^\\(@c\\|@comment\\)[ \t].*" . font-lock-comment-face) ;comments - "@\\(@\\|[^}\t \n{]+\\)" ;commands - '("^\\(*.*\\)[\t ]*$" 1 font-lock-function-name-face t) ;menu items - '("@\\(emph\\|strong\\|b\\|i\\){\\([^}]+\\)" 2 font-lock-comment-face t) - '("@\\(file\\|kbd\\|key\\){\\([^}]+\\)" 2 font-lock-string-face t) - '("@\\(samp\\|code\\|var\\){\\([^}]+\\)" 2 font-lock-function-name-face t) - '("@\\(xref\\|pxref\\){\\([^}]+\\)" 2 font-lock-keyword-face t) - '("@end *\\([a-zA-Z0-9]+\\)[ \t]*$" 1 font-lock-function-name-face t) - '("@item \\(.*\\)$" 1 font-lock-function-name-face t) - '("\\$\\([^$]*\\)\\$" 1 font-lock-string-face t) - ) - "Additional expressions to highlight in TeXinfo mode.") - -;;; Keybindings -(defvar texinfo-mode-map nil) - -;;; Keys common both to Texinfo mode and to TeX shell. - -(defun texinfo-define-common-keys (keymap) - "Define the keys both in Texinfo mode and in the texinfo-tex-shell." - (define-key keymap "\C-c\C-t\C-k" 'tex-kill-job) - (define-key keymap "\C-c\C-t\C-x" 'texinfo-quit-job) - (define-key keymap "\C-c\C-t\C-l" 'tex-recenter-output-buffer) - (define-key keymap "\C-c\C-t\C-d" 'texinfo-delete-from-print-queue) - (define-key keymap "\C-c\C-t\C-q" 'tex-show-print-queue) - (define-key keymap "\C-c\C-t\C-p" 'texinfo-tex-print) - (define-key keymap "\C-c\C-t\C-i" 'texinfo-texindex) - - (define-key keymap "\C-c\C-t\C-r" 'texinfo-tex-region) - (define-key keymap "\C-c\C-t\C-b" 'texinfo-tex-buffer)) - -;; Mode documentation displays commands in reverse order -;; from how they are listed in the texinfo-mode-map. - -(if texinfo-mode-map - nil - (setq texinfo-mode-map (make-sparse-keymap)) - - ;; bindings for `texnfo-tex.el' - (texinfo-define-common-keys texinfo-mode-map) - - ;; bindings for `makeinfo.el' - (define-key texinfo-mode-map "\C-c\C-m\C-k" 'kill-compilation) - (define-key texinfo-mode-map "\C-c\C-m\C-l" - 'makeinfo-recenter-compilation-buffer) - (define-key texinfo-mode-map "\C-c\C-m\C-r" 'makeinfo-region) - (define-key texinfo-mode-map "\C-c\C-m\C-b" 'makeinfo-buffer) - - ; Bindings for texinfmt.el. - (define-key texinfo-mode-map "\C-c\C-e\C-r" 'texinfo-format-region) - (define-key texinfo-mode-map "\C-c\C-e\C-b" 'texinfo-format-buffer) - - ;; bindings for updating nodes and menus - - (define-key texinfo-mode-map "\C-c\C-um" 'texinfo-master-menu) - - (define-key texinfo-mode-map "\C-c\C-u\C-m" 'texinfo-make-menu) - (define-key texinfo-mode-map "\C-c\C-u\C-n" 'texinfo-update-node) - (define-key texinfo-mode-map "\C-c\C-u\C-e" 'texinfo-every-node-update) - (define-key texinfo-mode-map "\C-c\C-u\C-a" 'texinfo-all-menus-update) - - (define-key texinfo-mode-map "\C-c\C-s" 'texinfo-show-structure) - - (define-key texinfo-mode-map "\C-c}" 'up-list) - (define-key texinfo-mode-map "\C-c{" 'texinfo-insert-braces) - - ;; bindings for inserting strings - - (define-key texinfo-mode-map "\C-c\C-c\C-d" 'texinfo-start-menu-description) - - (define-key texinfo-mode-map "\C-c\C-cv" 'texinfo-insert-@var) - (define-key texinfo-mode-map "\C-c\C-ct" 'texinfo-insert-@table) - (define-key texinfo-mode-map "\C-c\C-cs" 'texinfo-insert-@samp) - (define-key texinfo-mode-map "\C-c\C-co" 'texinfo-insert-@noindent) - (define-key texinfo-mode-map "\C-c\C-cn" 'texinfo-insert-@node) - (define-key texinfo-mode-map "\C-c\C-ck" 'texinfo-insert-@kbd) - (define-key texinfo-mode-map "\C-c\C-ci" 'texinfo-insert-@item) - (define-key texinfo-mode-map "\C-c\C-cf" 'texinfo-insert-@file) - (define-key texinfo-mode-map "\C-c\C-cx" 'texinfo-insert-@example) - (define-key texinfo-mode-map "\C-c\C-ce" 'texinfo-insert-@end) - (define-key texinfo-mode-map "\C-c\C-cd" 'texinfo-insert-@dfn) - (define-key texinfo-mode-map "\C-c\C-cc" 'texinfo-insert-@code)) - - -;;; Texinfo mode - -(defvar texinfo-chapter-level-regexp - "chapter\\|unnumbered \\|appendix \\|majorheading\\|chapheading" - "Regular expression matching Texinfo chapter-level headings. -This does not match `@node' and does not match the `@top' command.") - -;;;###autoload -(defun texinfo-mode () - "Major mode for editing Texinfo files. - - It has these extra commands: -\\{texinfo-mode-map} - - These are files that are used as input for TeX to make printed manuals -and also to be turned into Info files with \\[makeinfo-buffer] or -the `makeinfo' program. These files must be written in a very restricted and -modified version of TeX input format. - - Editing commands are like text-mode except that the syntax table is -set up so expression commands skip Texinfo bracket groups. To see -what the Info version of a region of the Texinfo file will look like, -use \\[makeinfo-region], which runs `makeinfo' on the current region. - - You can show the structure of a Texinfo file with \\[texinfo-show-structure]. -This command shows the structure of a Texinfo file by listing the -lines with the @-sign commands for @chapter, @section, and the like. -These lines are displayed in another window called the *Occur* window. -In that window, you can position the cursor over one of the lines and -use \\[occur-mode-goto-occurrence], to jump to the corresponding spot -in the Texinfo file. - - In addition, Texinfo mode provides commands that insert various -frequently used @-sign commands into the buffer. You can use these -commands to save keystrokes. And you can insert balanced braces with -\\[texinfo-insert-braces] and later use the command \\[up-list] to -move forward past the closing brace. - -Also, Texinfo mode provides functions for automatically creating or -updating menus and node pointers. These functions - - * insert the `Next', `Previous' and `Up' pointers of a node, - * insert or update the menu for a section, and - * create a master menu for a Texinfo source file. - -Here are the functions: - - texinfo-update-node \\[texinfo-update-node] - texinfo-every-node-update \\[texinfo-every-node-update] - texinfo-sequential-node-update - - texinfo-make-menu \\[texinfo-make-menu] - texinfo-all-menus-update \\[texinfo-all-menus-update] - texinfo-master-menu - - texinfo-indent-menu-description (column &optional region-p) - -The `texinfo-column-for-description' variable specifies the column to -which menu descriptions are indented. - -Passed an argument (a prefix argument, if interactive), the -`texinfo-update-node' and `texinfo-make-menu' functions do their jobs -in the region. - -To use the updating commands, you must structure your Texinfo file -hierarchically, such that each `@node' line, with the exception of the -Top node, is accompanied by some kind of section line, such as an -`@chapter' or `@section' line. - -If the file has a `top' node, it must be called `top' or `Top' and -be the first node in the file. - -Entering Texinfo mode calls the value of text-mode-hook, and then the -value of texinfo-mode-hook." - (interactive) - (text-mode) - (setq mode-name "Texinfo") - (setq major-mode 'texinfo-mode) - (use-local-map texinfo-mode-map) - (set-syntax-table texinfo-mode-syntax-table) - (make-local-variable 'page-delimiter) - (setq page-delimiter - (concat - "^@node [ \t]*[Tt]op\\|^@\\(" - texinfo-chapter-level-regexp - "\\)")) - (make-local-variable 'require-final-newline) - (setq require-final-newline t) - (make-local-variable 'indent-tabs-mode) - (setq indent-tabs-mode nil) - (make-local-variable 'paragraph-separate) - (setq paragraph-separate (concat "\b\\|@[a-zA-Z]*[ \n]\\|" paragraph-separate)) - (make-local-variable 'paragraph-start) - (setq paragraph-start (concat "\b\\|@[a-zA-Z]*[ \n]\\|" paragraph-start)) - (make-local-variable 'fill-column) - (setq fill-column 72) - (make-local-variable 'comment-start) - (setq comment-start "@c ") - (make-local-variable 'comment-start-skip) - (setq comment-start-skip "@c +") - (make-local-variable 'words-include-escapes) - (setq words-include-escapes t) - (make-local-variable 'font-lock-defaults) - (setq font-lock-defaults '(texinfo-font-lock-keywords)) - (make-local-variable 'tex-start-of-header) - (setq tex-start-of-header "%**start") - (make-local-variable 'tex-end-of-header) - (setq tex-end-of-header "%**end") - (run-hooks 'text-mode-hook 'texinfo-mode-hook)) - - -;;; Insert string commands - -(defconst texinfo-environment-regexp - "^@\\(f?table\\|enumerate\\|itemize\ -\\|ifhtml\\|ifinfo\\|iftex\\|ifset\\|ifclear\ -\\|example\\|quotation\\|lisp\\|smallexample\\|smalllisp\\|display\\|format\ -\\|flushleft\\|flushright\\|ignore\\|group\\|tex\\|html\\|cartouche\\|menu\ -\\|titlepage\\|end\\|def[a-z]*[a-wyz]\\>\\)" - "Regexp for environment-like Texinfo list commands. -Subexpression 1 is what goes into the corresponding `@end' statement.") - -(defun texinfo-insert-@end () - "Insert the matching `@end' for the last Texinfo command that needs one." - (interactive) - (let ((depth 1) string) - (save-excursion - (while (and (> depth 0) - (re-search-backward texinfo-environment-regexp nil t) - (if (looking-at "@end") - (setq depth (1+ depth)) - (setq depth (1- depth))))) - (looking-at texinfo-environment-regexp) - (if (zerop depth) - (setq string - (buffer-substring (match-beginning 1) - (match-end 1))))) - (insert "@end ") - (if string (insert string "\n")))) - -;; The following insert commands accept a prefix arg N, which is the -;; number of words (actually s-exprs) that should be surrounded by -;; braces. Thus you can first paste a variable name into a .texinfo -;; buffer, then say C-u 1 C-c C-c v at the beginning of the just -;; pasted variable name to put @var{...} *around* the variable name. -;; Operate on previous word or words with negative arg. - -;; These commands use texinfo-insert-@-with-arg -(defun texinfo-insert-@-with-arg (string &optional arg) - (if arg - (progn - (setq arg (prefix-numeric-value arg)) - (if (< arg 0) - (progn - (skip-chars-backward " \t\n\r\f") - (save-excursion - (forward-sexp arg) - (insert "@" string "{")) - (insert "}")) - (skip-chars-forward " \t\n\r\f") - (insert "@" string "{") - (forward-sexp arg) - (insert "}"))) - (insert "@" string "{}") - (backward-char))) - -(defun texinfo-insert-braces () - "Make a pair of braces and be poised to type inside of them. -Use \\[up-list] to move forward out of the braces." - (interactive) - (insert "{}") - (backward-char)) - -(defun texinfo-insert-@code (&optional arg) - "Insert a `@code{...}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "code" arg)) - -(defun texinfo-insert-@dfn (&optional arg) - "Insert a `@dfn{...}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "dfn" arg)) - -(defun texinfo-insert-@example () - "Insert the string `@example' in a Texinfo buffer." - (interactive) - (insert "@example\n")) - -(defun texinfo-insert-@file (&optional arg) - "Insert a `@file{...}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "file" arg)) - -(defun texinfo-insert-@item () - "Insert the string `@item' in a Texinfo buffer." - (interactive) - (insert "@item") - (newline)) - -(defun texinfo-insert-@kbd (&optional arg) - "Insert a `@kbd{...}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "kbd" arg)) - -(defun texinfo-insert-@node () - "Insert the string `@node' in a Texinfo buffer. -This also inserts on the following line a comment indicating -the order of arguments to @node." - (interactive) - (insert "@node \n@comment node-name, next, previous, up") - (forward-line -1) - (forward-char 6)) - -(defun texinfo-insert-@noindent () - "Insert the string `@noindent' in a Texinfo buffer." - (interactive) - (insert "@noindent\n")) - -(defun texinfo-insert-@samp (&optional arg) - "Insert a `@samp{...}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "samp" arg)) - -(defun texinfo-insert-@table (&optional arg) - "Insert the string `@table' in a Texinfo buffer." - (interactive "P") - (insert "@table ")) - -(defun texinfo-insert-@var (&optional arg) - "Insert a `@var{}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "var" arg)) - -;;; Texinfo file structure - -(defun texinfo-show-structure (&optional nodes-too) - "Show the structure of a Texinfo file. -List the lines in the file that begin with the @-sign commands for -@chapter, @section, and the like. - -With optional argument (prefix if interactive), list both the lines -with @-sign commands for @chapter, @section, and the like, and list -@node lines. - -Lines with structuring commands beginning in them are displayed in -another buffer named `*Occur*'. In that buffer, you can move point to -one of those lines and then use \\<occur-mode-map>\\[occur-mode-goto-occurrence], -to jump to the corresponding spot in the Texinfo source file." - - (interactive "P") - (require 'texnfo-upd) - (save-excursion - (goto-char (point-min)) - (if nodes-too - (occur (concat "\\(^@node\\)\\|" texinfo-section-types-regexp)) - (occur texinfo-section-types-regexp))) - (pop-to-buffer "*Occur*") - (goto-char (point-min)) - (flush-lines "-----") - ;; Now format the "*Occur*" buffer to show the structure. - ;; Thanks to ceder@signum.se (Per Cederqvist) - (goto-char (point-max)) - (let ((margin 5)) - (while (re-search-backward "^ *[0-9]*:" nil 0) - (re-search-forward ":") - (setq margin - (cond - ((looking-at - (concat "@\\(" texinfo-chapter-level-regexp "\\)")) 5) - ;; ((looking-at "@chapter ") 5) - ;; ((looking-at "@unnumbered ") 5) - ;; ((looking-at "@appendix ") 5) - ;; ((looking-at "@majorheading ") 5) - ;; ((looking-at "@chapheading ") 5) - - ((looking-at - (concat "@\\(" texinfo-section-level-regexp "\\)")) 9) - ;; ((looking-at "@section ") 9) - ;; ((looking-at "@unnumberedsec ") 9) - ;; ((looking-at "@appendixsec ") 9) - ;; ((looking-at "@heading ") 9) - - ((looking-at - (concat "@\\(" texinfo-subsection-level-regexp "\\)")) 13) - ;; ((looking-at "@subsection ") 13) - ;; ((looking-at "@unnumberedsubsec ") 13) - ;; ((looking-at "@appendixsubsec ") 13) - ;; ((looking-at "@subheading ") 13) - - ((looking-at - (concat "@\\(" texinfo-subsubsection-level-regexp "\\)")) 17) - ;; ((looking-at "@subsubsection ") 17) - ;; ((looking-at "@unnumberedsubsubsec ") 17) - ;; ((looking-at "@appendixsubsubsec ") 17) - ;; ((looking-at "@subsubheading ") 17) - (t margin))) - (indent-to-column margin) - (beginning-of-line)))) - -;;; The tex and print function definitions: - -(defvar texinfo-texi2dvi-command "texi2dvi" - "*Command used by `texinfo-tex-buffer' to run TeX and texindex on a buffer.") - -(defvar texinfo-tex-command "tex" - "*Command used by `texinfo-tex-region' to run TeX on a region.") - -(defvar texinfo-texindex-command "texindex" - "*Command used by `texinfo-texindex' to sort unsorted index files.") - -(defvar texinfo-delete-from-print-queue-command "lprm" - "*Command string used to delete a job from the line printer queue. -Command is used by \\[texinfo-delete-from-print-queue] based on -number provided by a previous \\[tex-show-print-queue] -command.") - -(defvar texinfo-tex-trailer "@bye" - "String appended after a region sent to TeX by `texinfo-tex-region'.") - -(defun texinfo-tex-region (beg end) - "Run TeX on the current region. -This works by writing a temporary file (`tex-zap-file') in the directory -that is the value of `tex-directory', then running TeX on that file. - -The first line of the buffer is copied to the -temporary file; and if the buffer has a header, it is written to the -temporary file before the region itself. The buffer's header is all lines -between the strings defined by `tex-start-of-header' and `tex-end-of-header' -inclusive. The header must start in the first 100 lines. - -The value of `texinfo-tex-trailer' is appended to the temporary file after the region." - (interactive "r") - (require 'tex-mode) - (if (get-buffer "*tex-shell*") - (tex-kill-job) - (tex-start-shell)) - (or tex-zap-file (setq tex-zap-file (make-temp-name "#tz"))) - (let ((tex-out-file (concat tex-zap-file ".tex")) - (temp-buffer (get-buffer-create " tex-Output-Buffer")) - (zap-directory - (file-name-as-directory (expand-file-name tex-directory)))) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (forward-line 100) - (let ((search-end (point)) - (hbeg (point-min)) (hend (point-min)) - (default-directory zap-directory)) - (goto-char (point-min)) - - ;; Copy first line, the `\input texinfo' line, to temp file - (write-region (point) - (save-excursion (end-of-line) (point)) - tex-out-file nil nil) - - ;; Don't copy first line twice if region includes it. - (forward-line 1) - (if (< beg (point)) (setq beg (point))) - - ;; Initialize the temp file with either the header or nothing - (if (search-forward tex-start-of-header search-end t) - (progn - (beginning-of-line) - (setq hbeg (point)) ; Mark beginning of header. - (if (search-forward tex-end-of-header nil t) - (progn (beginning-of-line) - (setq hend (point))) ; Mark end of header. - (setq hbeg (point-min))))) ; Else no header. - - ;; Copy header to temp file. - (write-region (min hbeg beg) hend tex-out-file t nil) - - ;; Copy region to temp file. - (write-region (max beg hend) end tex-out-file t nil)) - - ;; This is a kludge to insert the tex-trailer into the tex-out-file. - ;; We have to create a special buffer in which to insert - ;; the tex-trailer first because there is no function with - ;; which to append a literal string directly to a file. - (let ((local-tex-trailer texinfo-tex-trailer)) - (set-buffer temp-buffer) - (erase-buffer) - ;; make sure trailer isn't hidden by a comment - (insert-string "\n") - (if local-tex-trailer (insert-string local-tex-trailer)) - (tex-set-buffer-directory temp-buffer zap-directory) - (write-region (point-min) (point-max) tex-out-file t nil)) - -;;; The following is sufficient in Emacs 19. -;;; (write-region (concat "\n" texinfo-tex-trailer) nil -;;; tex-out-file t nil) - )) - - (tex-set-buffer-directory "*tex-shell*" zap-directory) - (tex-send-command tex-shell-cd-command zap-directory) - (tex-send-command texinfo-tex-command tex-out-file)) - (tex-recenter-output-buffer 0)) - -(defun texinfo-tex-buffer () - "Run TeX on visited file, once or twice, to make a correct `.dvi' file." - (interactive) - - ;; Make sure TeX shell is running. - (require 'tex-mode) - (if (get-buffer "*tex-shell*") - (quit-process (get-process "tex-shell") t) - (tex-start-shell)) - - (cond ((null buffer-file-name) - (error "Buffer not visiting any file!")) - ((buffer-modified-p) - (error "Buffer has been modified since last saved!"))) - - (setq tex-zap-file buffer-file-name) - - (tex-send-command tex-shell-cd-command (file-name-directory tex-zap-file)) - - (tex-send-command texinfo-texi2dvi-command tex-zap-file) - - (tex-recenter-output-buffer 0)) - -(defun texinfo-texindex () - "Run `texindex' on unsorted index files. -The index files are made by \\[texinfo-tex-region] or \\[texinfo-tex-buffer]. -This runs the shell command defined by `texinfo-texindex-command'." - (interactive) - (require 'tex-mode) - (tex-send-command texinfo-texindex-command (concat tex-zap-file ".??")) - (tex-recenter-output-buffer nil)) - -(defun texinfo-tex-print () - "Print `.dvi' file made by \\[texinfo-tex-region] or \\[texinfo-tex-buffer]. -This runs the shell command defined by `tex-dvi-print-command'." - (interactive) - (require 'tex-mode) - (tex-send-command tex-dvi-print-command (concat tex-zap-file ".dvi")) - (tex-recenter-output-buffer nil)) - -(defun texinfo-quit-job () - "Quit currently running TeX job, by sending an `x' to it." - (interactive) - (if (not (get-process "tex-shell")) - (error "No TeX shell running")) - (tex-send-command "x")) - -(defun texinfo-delete-from-print-queue (job-number) - "Delete job from the line printer spooling queue. -You are prompted for the job number (use a number shown by a previous -\\[texinfo-show-print-queue] command)." - (interactive "nPrinter job number for deletion: ") - (require 'tex-mode) - (if (tex-shell-running) - (tex-kill-job) - (tex-start-shell)) - (tex-send-command texinfo-delete-from-print-queue-command job-number) - (tex-recenter-output-buffer nil)) - -(provide 'texinfo) - -;;; texinfo.el ends here diff --git a/gnu/usr.bin/texinfo/emacs/texnfo-upd.el b/gnu/usr.bin/texinfo/emacs/texnfo-upd.el deleted file mode 100644 index f84cdd51496..00000000000 --- a/gnu/usr.bin/texinfo/emacs/texnfo-upd.el +++ /dev/null @@ -1,2046 +0,0 @@ -;;; Texinfo mode utilities for updating nodes and menus in Texinfo files. -;;; Copyright 1989, 1990, 1991, 1992 Free Software Foundation - -;; Author: Robert J. Chassell -;; Maintainer: bug-texinfo@prep.ai.mit.edu -;; Keywords: maint, tex, docs - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - -;;; Commentary: - -;;; Known bug: update commands fail to ignore @ignore. - -;;; Summary: how to use the updating commands - -; The node and menu updating functions automatically - -; * insert missing `@node' lines, -; * insert the `Next', `Previous' and `Up' pointers of a node, -; * insert or update the menu for a section, -; * create a master menu for a Texinfo source file. -; -; Passed an argument, the `texinfo-update-node' and -; `texinfo-make-menu' functions do their jobs in the region. -; -; In brief, the functions for creating or updating nodes and menus, are: -; -; texinfo-update-node (&optional region-p) -; texinfo-every-node-update () -; texinfo-sequential-node-update (&optional region-p) -; -; texinfo-make-menu (&optional region-p) -; texinfo-all-menus-update () -; texinfo-master-menu () -; -; texinfo-insert-node-lines (&optional title-p) -; -; texinfo-indent-menu-description (column &optional region-p) - -; The `texinfo-column-for-description' variable specifies the column to -; which menu descriptions are indented. - -; Texinfo file structure -; ---------------------- - -; To use the updating commands, you must structure your Texinfo file -; hierarchically. Each `@node' line, with the exception of the top -; node, must be accompanied by some kind of section line, such as an -; `@chapter' or `@section' line. Each node-line/section-line -; combination must look like this: - -; @node Lists and Tables, Cross References, Structuring, Top -; @comment node-name, next, previous, up -; @chapter Making Lists and Tables - -; or like this (without the `@comment' line): - -; @node Lists and Tables, Cross References, Structuring, Top -; @chapter Making Lists and Tables - -; If the file has a `top' node, it must be called `top' or `Top' and -; be the first node in the file. - - -;;; The update node functions described in detail - -; The `texinfo-update-node' function without an argument inserts -; the correct next, previous and up pointers for the node in which -; point is located (i.e., for the node preceding point). - -; With an argument, the `texinfo-update-node' function inserts the -; correct next, previous and up pointers for the nodes inside the -; region. - -; It does not matter whether the `@node' line has pre-existing -; `Next', `Previous', or `Up' pointers in it. They are removed. - -; The `texinfo-every-node-update' function runs `texinfo-update-node' -; on the whole buffer. - -; The `texinfo-sequential-node-update' function inserts the -; immediately following and preceding node into the `Next' or -; `Previous' pointers regardless of their hierarchical level. This is -; only useful for certain kinds of text, like a novel, which you go -; through sequentially. - - -;;; The menu making functions described in detail - -; The `texinfo-make-menu' function without an argument creates or -; updates a menu for the section encompassing the node that follows -; point. With an argument, it makes or updates menus for the nodes -; within or part of the marked region. - -; Whenever an existing menu is updated, the descriptions from -; that menu are incorporated into the new menu. This is done by copying -; descriptions from the existing menu to the entries in the new menu -; that have the same node names. If the node names are different, the -; descriptions are not copied to the new menu. - -; Menu entries that refer to other Info files are removed since they -; are not a node within current buffer. This is a deficiency. - -; The `texinfo-all-menus-update' function runs `texinfo-make-menu' -; 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.) - -; The `texinfo-indent-menu-description' function indents every -; description in the menu following point, to the specified column. -; Non-nil argument (prefix, if interactive) means indent every -; description in every menu in the region. This function does not -; indent second and subsequent lines of a multi-line description. - -; The `texinfo-insert-node-lines' function inserts `@node' before the -; `@chapter', `@section', and such like lines of a region in a Texinfo -; file where the `@node' lines are missing. -; -; With a non-nil argument (prefix, if interactive), the function not -; only inserts `@node' lines but also inserts the chapter or section -; titles as the names of the corresponding nodes; and inserts titles -; 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. - - -;;; Code: - -;;; The menu making functions - -(defun texinfo-make-menu (&optional region-p) - "Without any prefix argument, make or update a menu. -Make the menu for the section enclosing the node found following point. - -Non-nil argument (prefix, if interactive) means make or update menus -for nodes within or part of the marked region. - -Whenever a menu exists, and is being updated, the descriptions that -are associated with node names in the pre-existing menu are -incorporated into the new menu. Otherwise, the nodes' section titles -are inserted as descriptions." - - (interactive "P") - (if (not region-p) - (let ((level (texinfo-hierarchic-level))) - (texinfo-make-one-menu level) - (message "Done...updated the menu. You may save the buffer.")) - ;; else - (message "Making or updating menus in %s... " (buffer-name)) - (let ((beginning (region-beginning)) - (region-end (region-end)) - (level (progn ; find section type following point - (goto-char (region-beginning)) - (texinfo-hierarchic-level)))) - (if (= region-end beginning) - (error "Please mark a region!")) - (save-excursion - (save-restriction - (widen) - - (while (texinfo-find-lower-level-node level region-end) - (setq level (texinfo-hierarchic-level)) ; new, lower level - (texinfo-make-one-menu level)) - - (while (and (< (point) region-end) - (texinfo-find-higher-level-node level region-end)) - (setq level (texinfo-hierarchic-level)) - (while (texinfo-find-lower-level-node level region-end) - (setq level (texinfo-hierarchic-level)) ; new, lower level - (texinfo-make-one-menu level)))))) - (message "Done...updated menus. You may save the buffer."))) - -(defun texinfo-make-one-menu (level) - "Make a menu of all the appropriate nodes in this section. -`Appropriate nodes' are those associated with sections that are -at the level specified by LEVEL. Point is left at the end of menu." - (let* - ((case-fold-search t) - (beginning - (save-excursion - (goto-char (texinfo-update-menu-region-beginning level)) - (end-of-line) - (point))) - (end (texinfo-update-menu-region-end level)) - (first (texinfo-menu-first-node beginning end)) - (node-name (progn - (goto-char beginning) - (beginning-of-line) - (texinfo-copy-node-name))) - (new-menu-list (texinfo-make-menu-list beginning end level))) - (if (texinfo-old-menu-p beginning first) - (progn - (texinfo-incorporate-descriptions new-menu-list) - (texinfo-incorporate-menu-entry-names new-menu-list) - (texinfo-delete-old-menu beginning first))) - (texinfo-insert-menu new-menu-list node-name))) - -(defun texinfo-all-menus-update (&optional update-all-nodes-p) - "Update every regular menu in a Texinfo file. -Update pre-existing master menu, if there is one. - -If called with a non-nil argument, this function first updates all the -nodes in the buffer before updating the menus." - (interactive "P") - (let ((case-fold-search t) - master-menu-p) - (save-excursion - (push-mark (point-max) t) - (goto-char (point-min)) - (message "Checking for a master menu in %s ... "(buffer-name)) - (save-excursion - (if (re-search-forward texinfo-master-menu-header nil t) - ;; Remove detailed master menu listing - (progn - (setq master-menu-p t) - (goto-char (match-beginning 0)) - (let ((end-of-detailed-menu-descriptions - (save-excursion ; beginning of end menu line - (goto-char (texinfo-menu-end)) - (beginning-of-line) (forward-char -1) - (point)))) - (delete-region (point) end-of-detailed-menu-descriptions))))) - - (if update-all-nodes-p - (progn - (message "Updating all nodes in %s ... " (buffer-name)) - (sleep-for 2) - (push-mark (point-max) t) - (goto-char (point-min)) - ;; Using the mark to pass bounds this way - ;; is kludgy, but it's not worth fixing. -- rms. - (let ((mark-active t)) - (texinfo-update-node t)))) - - (message "Updating all menus in %s ... " (buffer-name)) - (sleep-for 2) - (push-mark (point-max) t) - (goto-char (point-min)) - ;; Using the mark to pass bounds this way - ;; is kludgy, but it's not worth fixing. -- rms. - (let ((mark-active t)) - (texinfo-make-menu t)) - - (if master-menu-p - (progn - (message "Updating the master menu in %s... " (buffer-name)) - (sleep-for 2) - (texinfo-master-menu nil)))) - - (message "Done...updated all the menus. You may save the buffer."))) - -(defun texinfo-find-lower-level-node (level region-end) - "Search forward from point for node at any level lower than LEVEL. -Search is limited to the end of the marked region, REGION-END, -and to the end of the menu region for the level. - -Return t if the node is found, else nil. Leave point at the beginning -of the node if one is found; else do not move point." - (let ((case-fold-search t)) - (if (and (< (point) region-end) - (re-search-forward - (concat - "\\(^@node\\).*\n" ; match node line - "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any - "\\|" ; or - "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any - (eval (cdr (assoc level texinfo-update-menu-lower-regexps)))) - ;; the next higher level node marks the end of this - ;; section, and no lower level node will be found beyond - ;; this position even if region-end is farther off - (texinfo-update-menu-region-end level) - t)) - (goto-char (match-beginning 1))))) - -(defun texinfo-find-higher-level-node (level region-end) - "Search forward from point for node at any higher level than argument LEVEL. -Search is limited to the end of the marked region, REGION-END. - -Return t if the node is found, else nil. Leave point at the beginning -of the node if one is found; else do not move point." - (let ((case-fold-search t)) - (cond - ((or (string-equal "top" level) (string-equal "chapter" level)) - (if (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" region-end t) - (progn (beginning-of-line) t))) - (t - (if (re-search-forward - (concat - "\\(^@node\\).*\n" ; match node line - "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any - "\\|" ; or - "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any - (eval (cdr (assoc level texinfo-update-menu-higher-regexps)))) - region-end t) - (progn (beginning-of-line) t)))))) - - -;;; Making the list of new menu entries - -(defun texinfo-make-menu-list (beginning end level) - "Make a list of node names and their descriptions. -Point is left at the end of the menu region, but the menu is not inserted. - -First argument is position from which to start making menu list; -second argument is end of region in which to try to locate entries; -third argument is the level of the nodes that are the entries. - -Node names and descriptions are dotted pairs of strings. Each pair is -an element of the list. If the description does not exist, the -element consists only of the node name." - (goto-char beginning) - (let (new-menu-list) - (while (texinfo-menu-locate-entry-p level end) - (setq new-menu-list - (cons (cons - (texinfo-copy-node-name) - (prog1 "" (forward-line 1))) - ;; Use following to insert section titles automatically. - ;; (texinfo-copy-section-title)) - new-menu-list))) - (reverse new-menu-list))) - -(defun texinfo-menu-locate-entry-p (level search-end) - "Find a node that will be part of menu for this section. -First argument is a string such as \"section\" specifying the general -hierarchical level of the menu; second argument is a position -specifying the end of the search. - -The function returns t if the node is found, else nil. It searches -forward from point, and leaves point at the beginning of the node. - -The function finds entries of the same type. Thus `subsections' and -`unnumberedsubsecs' will appear in the same menu." - (let ((case-fold-search t)) - (if (re-search-forward - (concat - "\\(^@node\\).*\n" ; match node line - "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any - "\\|" ; or - "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any - (eval - (cdr (assoc level texinfo-update-menu-same-level-regexps)))) - search-end - t) - (goto-char (match-beginning 1))))) - -(defun texinfo-copy-node-name () - "Return the node name as a string. - -Start with point at the beginning of the node line; copy the text -after the node command up to the first comma on the line, if any, and -return the text as a string. Leaves point at the beginning of the -line. If there is no node name, returns an empty string." - - (save-excursion - (buffer-substring - (progn (forward-word 1) ; skip over node command - (skip-chars-forward " \t") ; and over spaces - (point)) - (if (search-forward - "," - (save-excursion (end-of-line) (point)) t) ; bound search - (1- (point)) - (end-of-line) (point))))) - -(defun texinfo-copy-section-title () - "Return the title of the section as a string. -The title is used as a description line in the menu when one does not -already exist. - -Move point to the beginning of the appropriate section line by going -to the start of the text matched by last regexp searched for, which -must have been done by `texinfo-menu-locate-entry-p'." - - ;; could use the same re-search as in `texinfo-menu-locate-entry-p' - ;; instead of using `match-beginning'; such a variation would be - ;; more general, but would waste information already collected - - (goto-char (match-beginning 7)) ; match section name - - (buffer-substring - (progn (forward-word 1) ; skip over section type - (skip-chars-forward " \t") ; and over spaces - (point)) - (progn (end-of-line) (point)))) - - -;;; Handling the old menu - -(defun texinfo-old-menu-p (beginning first) - "Move point to the beginning of the menu for this section, if any. -Otherwise move point to the end of the first node of this section. -Return t if a menu is found, nil otherwise. - -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 first -node within the section. - -If no menu is found, the function inserts two newlines just before the -end of the section, and leaves point there where a menu ought to be." - (goto-char beginning) - (if (not (re-search-forward "^@menu" first 'goto-end)) - (progn (insert "\n\n") (forward-line -2) nil) - t)) - -(defun texinfo-incorporate-descriptions (new-menu-list) - "Copy the old menu line descriptions that exist to the new menu. - -Point must be at beginning of old menu. - -If the node-name of the new menu is found in the old menu, insert the -old description into the new entry. - -For this function, the new menu is a list made up of lists of dotted -pairs in which the first element of the pair is the node name and the -second element the description. The new menu is changed destructively. -The old menu is the menu as it appears in the texinfo file." - - (let ((new-menu-list-pointer new-menu-list) - (end-of-menu (texinfo-menu-end))) - (while new-menu-list - (save-excursion ; keep point at beginning of menu - (if (re-search-forward - ;; Existing nodes can have the form - ;; * NODE NAME:: DESCRIPTION - ;; or - ;; * MENU ITEM: NODE NAME. DESCRIPTION. - ;; - ;; Recognize both when looking for the description. - (concat "\\* \\(" ; so only menu entries are found - (car (car new-menu-list)) "::" - "\\|" - ".*: " (car (car new-menu-list)) "[.,\t\n]" - "\\)" - ) ; so only complete entries are found - end-of-menu - t) - (setcdr (car new-menu-list) - (texinfo-menu-copy-old-description end-of-menu)))) - (setq new-menu-list (cdr new-menu-list))) - (setq new-menu-list new-menu-list-pointer))) - -(defun texinfo-incorporate-menu-entry-names (new-menu-list) - "Copy any old menu entry names to the new menu. - -Point must be at beginning of old menu. - -If the node-name of the new menu entry cannot be found in the old -menu, do nothing. - -For this function, the new menu is a list made up of lists of dotted -pairs in which the first element of the pair is the node name and the -second element is the description (or nil). - -If we find an existing menu entry name, we change the first element of -the pair to be another dotted pair in which the car is the menu entry -name and the cdr is the node name. - -NEW-MENU-LIST is changed destructively. The old menu is the menu as it -appears in the texinfo file." - - (let ((new-menu-list-pointer new-menu-list) - (end-of-menu (texinfo-menu-end))) - (while new-menu-list - (save-excursion ; keep point at beginning of menu - (if (re-search-forward - ;; Existing nodes can have the form - ;; * NODE NAME:: DESCRIPTION - ;; or - ;; * MENU ITEM: NODE NAME. DESCRIPTION. - ;; - ;; We're interested in the second case. - (concat "\\* " ; so only menu entries are found - "\\(.*\\): " (car (car new-menu-list)) "[.,\t\n]") - end-of-menu - t) - (setcar - (car new-menu-list) ; replace the node name - (cons (buffer-substring (match-beginning 1) (match-end 1)) - (car (car new-menu-list))))) - (setq new-menu-list (cdr new-menu-list)))) - (setq new-menu-list new-menu-list-pointer))) - -(defun texinfo-menu-copy-old-description (end-of-menu) - "Return description field of old menu line as string. -Point must be located just after the node name. Point left before description. -Single argument, END-OF-MENU, is position limiting search." - (skip-chars-forward "[:.,\t\n ]+") - ;; don't copy a carriage return at line beginning with asterisk! - ;; do copy a description that begins with an `@'! - ;; !! Known bug: does not copy descriptions starting with ^|\{?* etc. - (if (and (looking-at "\\(\\w+\\|@\\)") - (not (looking-at "\\(^\\* \\|^@end menu\\)"))) - (buffer-substring - (point) - (save-excursion - (re-search-forward "\\(^\\* \\|^@end menu\\)" end-of-menu t) - (forward-line -1) - (end-of-line) ; go to end of last description line - (point))) - "")) - -(defun texinfo-menu-end () - "Return position of end of menu. Does not change location of point. -Signal an error if not end of menu." - (save-excursion - (if (re-search-forward "^@end menu" nil t) - (point) - (error "Menu does not have an end.")))) - -(defun texinfo-delete-old-menu (beginning first) - "Delete the old menu. Point must be in or after menu. -First argument is position of the beginning of the section in which -the menu will be located; second argument is the position of the first -node within the section." - ;; No third arg to search, so error if search fails. - (re-search-backward "^@menu" beginning) - (delete-region (point) - (save-excursion - (re-search-forward "^@end menu" first) - (point)))) - - -;;; Inserting new menu - -;; try 32, but perhaps 24 is better -(defvar texinfo-column-for-description 32 - "*Column at which descriptions start in a Texinfo menu.") - -(defun texinfo-insert-menu (menu-list node-name) - "Insert formatted menu at point. -Indents the first line of the description, if any, to the value of -texinfo-column-for-description. - -MENU-LIST has form: - - \(\(\"node-name1\" . \"description\"\) - \(\"node-name2\" . \"description\"\) ... \) - -However, the description field might be nil. - -Also, the node-name field might itself be a dotted pair (call it P) of -strings instead of just a string. In that case, the car of P -is the menu entry name, and the cdr of P is the node name." - - (insert "@menu\n") - (while menu-list - ;; Every menu entry starts with a star and a space. - (insert "* ") - - ;; Insert the node name (and menu entry name, if present). - (let ((node-part (car (car menu-list)))) - (if (stringp node-part) - ;; "Double colon" entry line; menu entry and node name are the same, - (insert (format "%s::" node-part)) - ;; "Single colon" entry line; menu entry and node name are different. - (insert (format "%s: %s." (car node-part) (cdr node-part))))) - - ;; Insert the description, if present. - (if (cdr (car menu-list)) - (progn - ;; Move to right place. - (indent-to texinfo-column-for-description 2) - ;; Insert description. - (insert (format "%s" (cdr (car menu-list)))))) - - (insert "\n") ; end this menu entry - (setq menu-list (cdr menu-list))) - (insert "@end menu") - (message - "Updated \"%s\" level menu following node: %s ... " level node-name)) - - -;;; Starting menu descriptions by inserting titles - -(defun texinfo-start-menu-description () - "In this menu entry, insert the node's section title as a description. -Position point at beginning of description ready for editing. -Do not insert a title if the line contains an existing description. - -You will need to edit the inserted text since a useful description -complements the node name rather than repeats it as a title does." - - (interactive) - (let (beginning end node-name title) - (save-excursion - (beginning-of-line) - (if (search-forward "* " (save-excursion (end-of-line) (point)) 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) - (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) - (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) - (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) - (skip-chars-backward " \t\n") - (setq node-name (buffer-substring beginning (point))) - (if (= 0 (length node-name)) - (error "No node name on this line.") - (insert ".")))) - (t (error "No node name on this line."))) - ;; Search for node that matches node name, and copy the section title. - (if (re-search-forward - (concat - "^@node[ \t]+" - node-name - ".*\n" ; match node line - "\\(" - "\\(\\(^@c \\|^@comment\\).*\n\\)" ; match comment line, if any - "\\|" ; or - "\\(^@ifinfo[ ]*\n\\)" ; ifinfo line, if any - "\\)?") - nil t) - (progn - (setq title - (buffer-substring - ;; skip over section type - (progn (forward-word 1) - ;; and over spaces - (skip-chars-forward " \t") - (point)) - (progn (end-of-line) - (skip-chars-backward " \t") - (point))))) - (error "Cannot find node to match node name in menu entry."))) - ;; Return point to the menu and insert the title. - (end-of-line) - (delete-region - (point) - (save-excursion (skip-chars-backward " \t") (point))) - (indent-to texinfo-column-for-description 2) - (save-excursion (insert title)))) - - -;;; Handling description indentation - -; Since the make-menu functions indent descriptions, these functions -; are useful primarily for indenting a single menu specially. - -(defun texinfo-indent-menu-description (column &optional region-p) - "Indent every description in menu following point to COLUMN. -Non-nil argument (prefix, if interactive) means indent every -description in every menu in the region. Does not indent second and -subsequent lines of a multi-line description." - - (interactive - "nIndent menu descriptions to (column number): \nP") - (save-excursion - (save-restriction - (widen) - (if (not region-p) - (progn - (re-search-forward "^@menu") - (texinfo-menu-indent-description column) - (message - "Indented descriptions in menu. You may save the buffer.")) - ;;else - (message "Indenting every menu description in region... ") - (goto-char (region-beginning)) - (while (and (< (point) (region-end)) - (texinfo-locate-menu-p)) - (forward-line 1) - (texinfo-menu-indent-description column)) - (message "Indenting done. You may save the buffer."))))) - -(defun texinfo-menu-indent-description (to-column-number) - "Indent the Texinfo file menu description to TO-COLUMN-NUMBER. -Start with point just after the word `menu' in the `@menu' line and -leave point on the line before the `@end menu' line. Does not indent -second and subsequent lines of a multi-line description." - (let* ((beginning-of-next-line (point))) - (while (< beginning-of-next-line - (save-excursion ; beginning of end menu line - (goto-char (texinfo-menu-end)) - (beginning-of-line) - (point))) - - (if (re-search-forward "\\* \\(.*::\\|.*: [^.,\t\n]+[.,\t]\\)" - (texinfo-menu-end) - t) - (progn - (let ((beginning-white-space (point))) - (skip-chars-forward " \t") ; skip over spaces - (if (looking-at "\\(@\\|\\w\\)+") ; if there is text - (progn - ;; remove pre-existing indentation - (delete-region beginning-white-space (point)) - (indent-to-column to-column-number)))))) - ;; position point at beginning of next line - (forward-line 1) - (setq beginning-of-next-line (point))))) - - -;;; Making the master menu - -(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-exisitng master menu using the -standard `texinfo-master-menu-header'. - -The master menu has the following format, which is adapted from the -recommendation in the Texinfo Manual: - - * The first part contains the major nodes in the Texinfo file: the - nodes for the chapters, chapter-like sections, and the major - appendices. This includes the indices, so long as they are in - chapter-like sections, such as unnumbered sections. - - * The second and subsequent parts contain a listing of the other, - lower level menus, in order. This way, an inquirer can go - directly to a particular node if he or she is searching for - specific information. - -Each of the menus in the detailed node listing is introduced by the -title of the section containing the menu." - - (interactive "P") - (let ((case-fold-search t)) - (widen) - (goto-char (point-min)) - - ;; Move point to location after `top'. - (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t)) - (error "This buffer needs a Top node!")) - - (let ((first-chapter - (save-excursion - (or (re-search-forward "^@node" nil t) - (error "Too few nodes for a master menu!")) - (point)))) - (if (re-search-forward texinfo-master-menu-header first-chapter t) - ;; Remove detailed master menu listing - (progn - (goto-char (match-beginning 0)) - (let ((end-of-detailed-menu-descriptions - (save-excursion ; beginning of end menu line - (goto-char (texinfo-menu-end)) - (beginning-of-line) (forward-char -1) - (point)))) - (delete-region (point) end-of-detailed-menu-descriptions))))) - - (if update-all-nodes-menus-p - (progn - (message "Making a master menu in %s ...first updating all nodes... " - (buffer-name)) - (sleep-for 2) - (push-mark (point-max) t) - (goto-char (point-min)) - (texinfo-update-node t) - - (message "Updating all menus in %s ... " (buffer-name)) - (sleep-for 2) - (push-mark (point-max) t) - (goto-char (point-min)) - (texinfo-make-menu t))) - - (message "Now making the master menu in %s... " (buffer-name)) - (sleep-for 2) - (goto-char (point-min)) - (texinfo-insert-master-menu-list - (texinfo-master-menu-list)) - - ;; Remove extra newlines that texinfo-insert-master-menu-list - ;; may have inserted. - - (save-excursion - (goto-char (point-min)) - - (if (re-search-forward texinfo-master-menu-header nil t) - (progn - (goto-char (match-beginning 0)) - (insert "\n") - (delete-blank-lines) - (goto-char (point-min)))) - - (re-search-forward "^@menu") - (forward-line -1) - (delete-blank-lines) - - (re-search-forward "^@end menu") - (forward-line 1) - (delete-blank-lines)) - - (message - "Done...completed making master menu. You may save the buffer."))) - -(defun texinfo-master-menu-list () - "Return a list of menu entries and header lines for the master menu. - -Start with the menu for chapters and indices and then find each -following menu and the title of the node preceding that menu. - -The master menu list has this form: - - \(\(\(... \"entry-1-2\" \"entry-1\"\) \"title-1\"\) - \(\(... \"entry-2-2\" \"entry-2-1\"\) \"title-2\"\) - ...\) - -However, there does not need to be a title field." - - (let (master-menu-list) - (while (texinfo-locate-menu-p) - (setq master-menu-list - (cons (list - (texinfo-copy-menu) - (texinfo-copy-menu-title)) - master-menu-list))) - (reverse master-menu-list))) - -(defun texinfo-insert-master-menu-list (master-menu-list) - "Format and insert the master menu in the current buffer." - (goto-char (point-min)) - ;; Insert a master menu only after `Top' node and before next node - ;; \(or include file if there is no next node\). - (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t)) - (error "This buffer needs a Top node!")) - (let ((first-chapter - (save-excursion (re-search-forward "^@node\\|^@include") (point)))) - (if (not (re-search-forward "^@menu" first-chapter t)) - (error - "Buffer lacks ordinary `Top' menu in which to insert master."))) - (beginning-of-line) - (delete-region ; buffer must have ordinary top menu - (point) - (save-excursion (re-search-forward "^@end menu") (point))) - - (save-excursion ; leave point at beginning of menu - ;; Handle top of menu - (insert "\n@menu\n") - ;; Insert chapter menu entries - (setq this-very-menu-list (reverse (car (car master-menu-list)))) - ;; Tell user what is going on. - (message "Inserting chapter menu entry: %s ... " this-very-menu-list) - (while this-very-menu-list - (insert "* " (car this-very-menu-list) "\n") - (setq this-very-menu-list (cdr this-very-menu-list))) - - (setq master-menu-list (cdr master-menu-list)) - - ;; Only insert detailed master menu if there is one.... - (if (car (car master-menu-list)) - (insert texinfo-master-menu-header)) - - ;; Now, insert all the other menus - - ;; The menu master-menu-list has a form like this: - ;; ((("beta" "alpha") "title-A") - ;; (("delta" "gamma") "title-B")) - - (while master-menu-list - - (message - "Inserting menu for %s .... " (car (cdr (car master-menu-list)))) - ;; insert title of menu section - (insert "\n" (car (cdr (car master-menu-list))) "\n\n") - - ;; insert each menu entry - (setq this-very-menu-list (reverse (car (car master-menu-list)))) - (while this-very-menu-list - (insert "* " (car this-very-menu-list) "\n") - (setq this-very-menu-list (cdr this-very-menu-list))) - - (setq master-menu-list (cdr master-menu-list))) - - ;; Finish menu - (insert "@end menu\n\n"))) - -(defvar texinfo-master-menu-header - "\n --- The Detailed Node Listing ---\n" - "String inserted before lower level entries in Texinfo master menu. -It comes after the chapter-level menu entries.") - -(defun texinfo-locate-menu-p () - "Find the next menu in the texinfo file. -If found, leave point after word `menu' on the `@menu' line, and return t. -If a menu is not found, do not move point and return nil." - (re-search-forward "\\(^@menu\\)" nil t)) - -(defun texinfo-copy-menu-title () - "Return the title of the section preceding the menu as a string. -If such a title cannot be found, return an empty string. Do not move -point." - (let ((case-fold-search t)) - (save-excursion - (if (re-search-backward - (concat - "\\(^@top" - "\\|" ; or - texinfo-section-types-regexp ; all other section types - "\\)") - nil - t) - (progn - (beginning-of-line) - (forward-word 1) ; skip over section type - (skip-chars-forward " \t") ; and over spaces - (buffer-substring - (point) - (progn (end-of-line) (point)))) - "")))) - -(defun texinfo-copy-menu () - "Return the entries of an existing menu as a list. -Start with point just after the word `menu' in the `@menu' line -and leave point on the line before the `@end menu' line." - (let* (this-menu-list - (end-of-menu (texinfo-menu-end)) ; position of end of `@end menu' - (last-entry (save-excursion ; position of beginning of - ; last `* ' entry - (goto-char end-of-menu) - ;; handle multi-line description - (if (not (re-search-backward "^\* " nil t)) - (error "No entries in menu.")) - (point)))) - (while (< (point) last-entry) - (if (re-search-forward "^\* " end-of-menu t) - (progn - (setq this-menu-list - (cons - (buffer-substring - (point) - ;; copy multi-line descriptions - (save-excursion - (re-search-forward "\\(^\* \\|^@e\\)" nil t) - (- (point) 3))) - this-menu-list))))) - this-menu-list)) - - -;;; Determining the hierarchical level in the texinfo file - -(defun texinfo-specific-section-type () - "Return the specific type of next section, as a string. -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 -;;; (save-excursion -;;; (end-of-line) -;;; (point)) - nil - t) - "top") - ((re-search-forward texinfo-section-types-regexp nil t) - (buffer-substring (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.")))))) - -(defun texinfo-hierarchic-level () - "Return the general hierarchal level of the next node in a texinfo file. -Thus, a subheading or appendixsubsec is of type subsection." - (let ((case-fold-search t)) - (cdr (assoc - (texinfo-specific-section-type) - texinfo-section-to-generic-alist)))) - - -;;; Locating the major positions - -(defun texinfo-update-menu-region-beginning (level) - "Locate beginning of higher level section this section is within. -Return position of the beginning of the node line; do not move point. -Thus, if this level is subsection, searches backwards for section node. -Only argument is a string of the general type of section." - (let ((case-fold-search t)) - ;; !! Known bug: if section immediately follows top node, this - ;; returns the beginning of the buffer as the beginning of the - ;; higher level section. - (cond - ((or (string-equal "top" level) - (string-equal "chapter" level)) - (save-excursion - (goto-char (point-min)) - (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t) - (beginning-of-line) - (point))) - (t - (save-excursion - (re-search-backward - (concat - "\\(^@node\\).*\n" ; match node line - "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any - "\\|" ; or - "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any - (eval - (cdr (assoc level texinfo-update-menu-higher-regexps)))) - nil - 'goto-beginning) - (point)))))) - -(defun texinfo-update-menu-region-end (level) - "Locate end of higher level section this section is within. -Return position; do not move point. Thus, if this level is a -subsection, find the node for the section this subsection is within. -If level is top or chapter, returns end of file. Only argument is a -string of the general type of section." - (let ((case-fold-search t)) - (save-excursion - (if (re-search-forward - (concat - "\\(^@node\\).*\n" ; match node line - "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any - "\\|" ; or - "\\(^@ifinfo[ ]*\n\\)\\)?" ; ifinfo line, if any - (eval - ;; Never finds end of level above chapter so goes to end. - (cdr (assoc level texinfo-update-menu-higher-regexps)))) - nil - 'goto-end) - (match-beginning 1) - (point-max))))) - -(defun texinfo-menu-first-node (beginning end) - "Locate first node of the section the menu will be placed in. -Return position; do not move point. -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))) - - -;;; Alists and regular expressions for defining hierarchical levels - -(defvar texinfo-section-to-generic-alist - '(("top" . "top") - - ("chapter" . "chapter") - ("unnumbered" . "chapter") - ("majorheading" . "chapter") - ("chapheading" . "chapter") - ("appendix" . "chapter") - - ("section" . "section") - ("unnumberedsec" . "section") - ("heading" . "section") - ("appendixsec" . "section") - - ("subsection" . "subsection") - ("unnumberedsubsec" . "subsection") - ("subheading" . "subsection") - ("appendixsubsec" . "subsection") - - ("subsubsection" . "subsubsection") - ("unnumberedsubsubsec" . "subsubsection") - ("subsubheading" . "subsubsection") - ("appendixsubsubsec" . "subsubsection")) - "*An alist of specific and corresponding generic Texinfo section types. -The keys are strings specifying specific types of section; the values -are strings of their corresponding general types.") - -;; We used to look for just sub, but that found @subtitle. -(defvar texinfo-section-types-regexp - "^@\\(chapter \\|sect\\|subs\\|subh\\|unnum\\|major\\|chapheading \\|heading \\|appendix\\)" - "Regexp matching chapter, section, other headings (but not the top node).") - -(defvar texinfo-chapter-level-regexp - "chapter\\|unnumbered \\|appendix \\|majorheading\\|chapheading" - "Regular expression matching just the Texinfo chapter level headings.") - -(defvar texinfo-section-level-regexp - "section\\|unnumberedsec\\|heading \\|appendixsec" - "Regular expression matching just the Texinfo section level headings.") - -(defvar texinfo-subsection-level-regexp - "subsection\\|unnumberedsubsec\\|subheading\\|appendixsubsec" - "Regular expression matching just the Texinfo subsection level headings.") - -(defvar texinfo-subsubsection-level-regexp - "subsubsection\\|unnumberedsubsubsec\\|subsubheading\\|appendixsubsubsec" - "Regular expression matching just the Texinfo subsubsection level headings.") - -(defvar texinfo-update-menu-same-level-regexps - '(("top" . "top[ \t]+") - ("chapter" . - (concat "\\(^@\\)\\(" texinfo-chapter-level-regexp "\\)[ \t]*")) - ("section" . - (concat "\\(^@\\)\\(" texinfo-section-level-regexp "\\)[ \t]*")) - ("subsection" . - (concat "\\(^@\\)\\(" texinfo-subsection-level-regexp "\\)[ \t]+")) - ("subsubsection" . - (concat "\\(^@\\)\\(" texinfo-subsubsection-level-regexp "\\)[ \t]+"))) - "*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.") - -(defvar texinfo-update-menu-higher-regexps - '(("top" . "^@node [ \t]*DIR") - ("chapter" . "^@node [ \t]*top[ \t]*\\(,\\|$\\)") - ("section" . - (concat - "\\(^@\\(" - texinfo-chapter-level-regexp - "\\)[ \t]*\\)")) - ("subsection" . - (concat - "\\(^@\\(" - texinfo-section-level-regexp - "\\|" - texinfo-chapter-level-regexp - "\\)[ \t]*\\)")) - ("subsubsection" . - (concat - "\\(^@\\(" - texinfo-subsection-level-regexp - "\\|" - texinfo-section-level-regexp - "\\|" - texinfo-chapter-level-regexp - "\\)[ \t]*\\)"))) - "*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.") - -(defvar texinfo-update-menu-lower-regexps - '(("top" . - (concat - "\\(^@\\(" - texinfo-chapter-level-regexp - "\\|" - texinfo-section-level-regexp - "\\|" - texinfo-subsection-level-regexp - "\\|" - texinfo-subsubsection-level-regexp - "\\)[ \t]*\\)")) - ("chapter" . - (concat - "\\(^@\\(" - texinfo-section-level-regexp - "\\|" - texinfo-subsection-level-regexp - "\\|" - texinfo-subsubsection-level-regexp - "\\)[ \t]*\\)")) - ("section" . - (concat - "\\(^@\\(" - texinfo-subsection-level-regexp - "\\|" - texinfo-subsubsection-level-regexp - "\\)[ \t]+\\)")) - ("subsection" . - (concat - "\\(^@\\(" - texinfo-subsubsection-level-regexp - "\\)[ \t]+\\)")) - ("subsubsection" . "nothing lower")) - "*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.") - - -;;; Updating a node - -;;;###autoload -(defun texinfo-update-node (&optional region-p) - "Without any prefix argument, update the node in which point is located. -Non-nil argument (prefix, if interactive) means update the nodes in the -marked region. - -The functions for creating or updating nodes and menus, and their -keybindings, are: - - texinfo-update-node (&optional region-p) \\[texinfo-update-node] - texinfo-every-node-update () \\[texinfo-every-node-update] - texinfo-sequential-node-update (&optional region-p) - - texinfo-make-menu (&optional region-p) \\[texinfo-make-menu] - texinfo-all-menus-update () \\[texinfo-all-menus-update] - texinfo-master-menu () - - texinfo-indent-menu-description (column &optional region-p) - -The `texinfo-column-for-description' variable specifies the column to -which menu descriptions are indented. Its default value is 32." - - (interactive "P") - (if (not region-p) - ;; update a single node - (let ((auto-fill-function nil) (auto-fill-hook nil)) - (if (not (re-search-backward "^@node" (point-min) t)) - (error "Node line not found before this position.")) - (texinfo-update-the-node) - (message "Done...updated the node. You may save the buffer.")) - ;; else - (let ((auto-fill-function nil) - (auto-fill-hook nil) - (beginning (region-beginning)) - (end (region-end))) - (if (= end beginning) - (error "Please mark a region!")) - (save-restriction - (narrow-to-region beginning end) - (goto-char beginning) - (push-mark (point) t) - (while (re-search-forward "^@node" (point-max) t) - (beginning-of-line) - (texinfo-update-the-node)) - (message "Done...updated nodes in region. You may save the buffer."))))) - -;;;###autoload -(defun texinfo-every-node-update () - "Update every node in a Texinfo file." - (interactive) - (save-excursion - (push-mark (point-max) t) - (goto-char (point-min)) - ;; Using the mark to pass bounds this way - ;; is kludgy, but it's not worth fixing. -- rms. - (let ((mark-active t)) - (texinfo-update-node t)) - (message "Done...updated every node. You may save the buffer."))) - -(defun texinfo-update-the-node () - "Update one node. Point must be at the beginning of node line. -Leave point at the end of the node line." - (texinfo-check-for-node-name) - (texinfo-delete-existing-pointers) - (message "Updating node: %s ... " (texinfo-copy-node-name)) - (save-restriction - (widen) - (let* - ((case-fold-search t) - (level (texinfo-hierarchic-level)) - (beginning (texinfo-update-menu-region-beginning level)) - (end (texinfo-update-menu-region-end level))) - (if (string-equal level "top") - (texinfo-top-pointer-case) - ;; else - (texinfo-insert-pointer beginning end level 'next) - (texinfo-insert-pointer beginning end level 'previous) - (texinfo-insert-pointer beginning end level 'up) - (texinfo-clean-up-node-line))))) - -(defun texinfo-top-pointer-case () - "Insert pointers in the Top node. This is a special case. - -The `Next' pointer is a pointer to a chapter or section at a lower -hierarchical level in the file. The `Previous' and `Up' pointers are -to `(dir)'. Point must be at the beginning of the node line, and is -left at the end of the node line." - - (texinfo-clean-up-node-line) - (insert ", " - (save-excursion - ;; There may be an @chapter or other such command between - ;; the top node line and the next node line, as a title - ;; for an `ifinfo' section. This @chapter command must - ;; must be skipped. So the procedure is to search for - ;; the next `@node' line, and then copy its name. - (if (re-search-forward "^@node" nil t) - (progn - (beginning-of-line) - (texinfo-copy-node-name)) - " ")) - ", (dir), (dir)")) - -(defun texinfo-check-for-node-name () - "Determine whether the node has a node name. Prompt for one if not. -Point must be at beginning of node line. Does not move point." - (save-excursion - (let ((initial (texinfo-copy-next-section-title))) - ;; This is not clean. Use `interactive' to read the arg. - (forward-word 1) ; skip over node command - (skip-chars-forward " \t") ; and over spaces - (if (not (looking-at "[^,\t\n ]+")) ; regexp based on what Info looks for - ; alternatively, use "[a-zA-Z]+" - (let ((node-name - (read-from-minibuffer - "Node name (use no @, commas, colons, or apostrophes): " - initial))) - (insert " " node-name)))))) - -(defun texinfo-delete-existing-pointers () - "Delete `Next', `Previous', and `Up' pointers. -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)))) - (if (search-forward "," eol-point t) - (delete-region (1- (point)) eol-point))) - (beginning-of-line)) - -(defun texinfo-find-pointer (beginning end level direction) - "Move point to section associated with next, previous, or up pointer. -Return type of pointer (either 'normal or 'no-pointer). - -The first and second arguments bound the search for a pointer to the -beginning and end, respectively, of the enclosing higher level -section. The third argument is a string specifying the general kind -of section such as \"chapter\ or \"section\". When looking for the -`Next' pointer, the section found will be at the same hierarchical -level in the Texinfo file; when looking for the `Previous' pointer, -the section found will be at the same or higher hierarchical level in -the Texinfo file; when looking for the `Up' pointer, the section found -will be at some level higher in the Texinfo file. The fourth argument -\(one of 'next, 'previous, or 'up\) specifies whether to find the -`Next', `Previous', or `Up' pointer." - (let ((case-fold-search t)) - (cond ((eq direction 'next) - (forward-line 3) ; skip over current node - ;; Search for section commands accompanied by node lines; - ;; ignore section commands in the middle of nodes. - (if (re-search-forward - ;; A `Top' node is never a next pointer, so won't find it. - (concat - ;; Match node line. - "\\(^@node\\).*\n" - ;; Match comment or ifinfo line, if any - "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?" - (eval - (cdr (assoc level texinfo-update-menu-same-level-regexps)))) - end - t) - 'normal - 'no-pointer)) - ((eq direction 'previous) - (if (re-search-backward - (concat - "\\(" - ;; Match node line. - "\\(^@node\\).*\n" - ;; Match comment or ifinfo line, if any - "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?" - (eval - (cdr (assoc level texinfo-update-menu-same-level-regexps))) - "\\|" - ;; Match node line. - "\\(^@node\\).*\n" - ;; Match comment or ifinfo line, if any - "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?" - (eval - (cdr (assoc level texinfo-update-menu-higher-regexps))) - "\\|" - ;; Handle `Top' node specially. - "^@node [ \t]*top[ \t]*\\(,\\|$\\)" - "\\)") - beginning - t) - 'normal - 'no-pointer)) - ((eq direction 'up) - (if (re-search-backward - (concat - "\\(" - ;; Match node line. - "\\(^@node\\).*\n" - ;; Match comment or ifinfo line, if any - "\\(\\(\\(^@c\\).*\n\\)\\|\\(^@ifinfo[ ]*\n\\)\\)?" - (eval (cdr (assoc level texinfo-update-menu-higher-regexps))) - "\\|" - ;; Handle `Top' node specially. - "^@node [ \t]*top[ \t]*\\(,\\|$\\)" - "\\)") - (save-excursion - (goto-char beginning) - (beginning-of-line) - (point)) - t) - 'normal - 'no-pointer)) - (t - (error "texinfo-find-pointer: lack proper arguments"))))) - -(defun texinfo-pointer-name (kind) - "Return the node name preceding the section command. -The argument is the kind of section, either normal or no-pointer." - (let (name) - (cond ((eq kind 'normal) - (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)) - t) - (setq name (texinfo-copy-node-name))) - ((eq kind 'no-pointer) - (setq name " "))) ; put a blank in the pointer slot - name)) - -(defun texinfo-insert-pointer (beginning end level direction) - "Insert the `Next', `Previous' or `Up' node name at point. -Move point forward. - -The first and second arguments bound the search for a pointer to the -beginning and end, respectively, of the enclosing higher level -section. The third argument is the hierarchical level of the Texinfo -file, a string such as \"section\". The fourth argument is direction -towards which the pointer is directed, one of `next, `previous, or -'up." - - (end-of-line) - (insert - ", " - (save-excursion - (texinfo-pointer-name - (texinfo-find-pointer beginning end level direction))))) - -(defun texinfo-clean-up-node-line () - "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)))) - - -;;; Updating nodes sequentially -; These sequential update functions insert `Next' or `Previous' -; pointers that point to the following or preceding nodes even if they -; are at higher or lower hierarchical levels. This means that if a -; section contains one or more subsections, the section's `Next' -; pointer will point to the subsection and not the following section. -; (The subsection to which `Next' points will most likely be the first -; item on the section's menu.) - -;;;###autoload -(defun texinfo-sequential-node-update (&optional region-p) - "Update one node (or many) in a Texinfo file with sequential pointers. - -This function causes the `Next' or `Previous' pointer to point to the -immediately preceding or following node, even if it is at a higher or -lower hierarchical level in the document. Continually pressing `n' or -`p' takes you straight through the file. - -Without any prefix argument, update the node in which point is located. -Non-nil argument (prefix, if interactive) means update the nodes in the -marked region. - -This command makes it awkward to navigate among sections and -subsections; it should be used only for those documents that are meant -to be read like a novel rather than a reference, and for which the -Info `g*' command is inadequate." - - (interactive "P") - (if (not region-p) - ;; update a single node - (let ((auto-fill-function nil) (auto-fill-hook nil)) - (if (not (re-search-backward "^@node" (point-min) t)) - (error "Node line not found before this position.")) - (texinfo-sequentially-update-the-node) - (message - "Done...sequentially updated the node . You may save the buffer.")) - ;; else - (let ((auto-fill-function nil) - (auto-fill-hook nil) - (beginning (region-beginning)) - (end (region-end))) - (if (= end beginning) - (error "Please mark a region!")) - (save-restriction - (narrow-to-region beginning end) - (goto-char beginning) - (push-mark (point) t) - (while (re-search-forward "^@node" (point-max) t) - (beginning-of-line) - (texinfo-sequentially-update-the-node)) - (message - "Done...updated the nodes in sequence. You may save the buffer."))))) - -(defun texinfo-sequentially-update-the-node () - "Update one node such that the pointers are sequential. -A `Next' or `Previous' pointer points to any preceding or following node, -regardless of its hierarchical level." - - (texinfo-check-for-node-name) - (texinfo-delete-existing-pointers) - (message - "Sequentially updating node: %s ... " (texinfo-copy-node-name)) - (save-restriction - (widen) - (let* - ((case-fold-search t) - (level (texinfo-hierarchic-level))) - (if (string-equal level "top") - (texinfo-top-pointer-case) - ;; else - (texinfo-sequentially-insert-pointer level 'next) - (texinfo-sequentially-insert-pointer level 'previous) - (texinfo-sequentially-insert-pointer level 'up) - (texinfo-clean-up-node-line))))) - -(defun texinfo-sequentially-find-pointer (level direction) - "Find next or previous pointer sequentially in Texinfo file, or up pointer. -Move point to section associated with the pointer. Find point even if -it is in a different section. - -Return type of pointer (either 'normal or 'no-pointer). - -The first argument is a string specifying the general kind of section -such as \"chapter\ or \"section\". The section found will be at the -same hierarchical level in the Texinfo file, or, in the case of the up -pointer, some level higher. The second argument (one of 'next, -'previous, or 'up) specifies whether to find the `Next', `Previous', -or `Up' pointer." - (let ((case-fold-search t)) - (cond ((eq direction 'next) - (forward-line 3) ; skip over current node - (if (re-search-forward - texinfo-section-types-regexp - (point-max) - t) - 'normal - 'no-pointer)) - ((eq direction 'previous) - (if (re-search-backward - texinfo-section-types-regexp - (point-min) - t) - 'normal - 'no-pointer)) - ((eq direction 'up) - (if (re-search-backward - (eval (cdr (assoc level texinfo-update-menu-higher-regexps))) - beginning - t) - 'normal - 'no-pointer)) - (t - (error "texinfo-sequential-find-pointer: lack proper arguments"))))) - -(defun texinfo-sequentially-insert-pointer (level direction) - "Insert the `Next', `Previous' or `Up' node name at point. -Move point forward. - -The first argument is the hierarchical level of the Texinfo file, a -string such as \"section\". The second argument is direction, one of -`next, `previous, or 'up." - - (end-of-line) - (insert - ", " - (save-excursion - (texinfo-pointer-name - (texinfo-sequentially-find-pointer level direction))))) - - -;;; Inserting `@node' lines -; The `texinfo-insert-node-lines' function inserts `@node' lines as needed -; before the `@chapter', `@section', and such like lines of a region -; in a Texinfo file. - -(defun texinfo-insert-node-lines (beginning end &optional title-p) - "Insert missing `@node' lines in region of Texinfo file. -Non-nil argument (prefix, if interactive) means also to insert the -section titles as node names; and also to insert the section titles as -node names in pre-existing @node lines that lack names." - (interactive "r\nP") - - ;; Use marker; after inserting node lines, leave point at end of - ;; region and mark at beginning. - - (let (beginning-marker end-marker title last-section-position) - - ;; Save current position on mark ring and set mark to end. - (push-mark end t) - (setq end-marker (mark-marker)) - - (goto-char beginning) - (while (re-search-forward - texinfo-section-types-regexp - end-marker - 'end) - ;; Copy title if desired. - (if title-p - (progn - (beginning-of-line) - (forward-word 1) - (skip-chars-forward " \t") - (setq title (buffer-substring - (point) - (save-excursion (end-of-line) (point)))))) - ;; 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) - ;; @node is present, and point at beginning of that line - (forward-word 1) ; Leave point just after @node. - ;; Else @node missing; insert one. - (beginning-of-line) ; Beginning of `@section' line. - (insert "@node\n") - (backward-char 1)) ; Leave point just after `@node'. - ;; Insert title if desired. - (if title-p - (progn - (skip-chars-forward " \t") - ;; Use regexp based on what info looks for - ;; (alternatively, use "[a-zA-Z]+"); - ;; this means we only insert a title if none exists. - (if (not (looking-at "[^,\t\n ]+")) - (progn - (beginning-of-line) - (forward-word 1) - (insert " " title) - (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) - (setq last-section-position (point)) - (forward-line 1)) - - ;; Leave point at end of region, mark at beginning. - (set-mark beginning) - - (if title-p - (message - "Done inserting node lines and titles. You may save the buffer.") - (message "Done inserting node lines. You may save the buffer.")))) - - -;;; Update and create menus for multi-file Texinfo sources - -;; 1. M-x texinfo-multiple-files-update -;; -;; Read the include file list of an outer Texinfo file and -;; update all highest level nodes in the files listed and insert a -;; main menu in the outer file after its top node. - -;; 2. C-u M-x texinfo-multiple-files-update -;; -;; Same as 1, but insert a master menu. (Saves reupdating lower -;; level menus and nodes.) This command simply reads every menu, -;; so if the menus are wrong, the master menu will be wrong. -;; Similarly, if the lower level node pointers are wrong, they -;; will stay wrong. - -;; 3. C-u 2 M-x texinfo-multiple-files-update -;; -;; Read the include file list of an outer Texinfo file and -;; update all nodes and menus in the files listed and insert a -;; master menu in the outer file after its top node. - -;;; Note: these functions: -;;; -;;; * Do not save or delete any buffers. You may fill up your memory. -;;; * Do not handle any pre-existing nodes in outer file. -;;; Hence, you may need a file for indices. - - -;;; Auxiliary functions for multiple file updating - -(defun texinfo-multi-file-included-list (outer-file) - "Return a list of the included files in OUTER-FILE." - (let ((included-file-list (list outer-file)) - start) - (save-excursion - (switch-to-buffer (find-file-noselect outer-file)) - (widen) - (goto-char (point-min)) - (while (re-search-forward "^@include" nil t) - (skip-chars-forward " \t") - (setq start (point)) - (end-of-line) - (skip-chars-backward " \t") - (setq included-file-list - (cons (buffer-substring start (point)) - included-file-list))) - (nreverse included-file-list)))) - -(defun texinfo-copy-next-section-title () - "Return the name of the immediately following section as a string. - -Start with point at the beginning of the node line. Leave point at the -same place. If there is no title, returns an empty string." - - (save-excursion - (end-of-line) - (let ((node-end (or - (save-excursion - (if (re-search-forward "\\(^@node\\)" nil t) - (match-beginning 0))) - (point-max)))) - (if (re-search-forward texinfo-section-types-regexp node-end t) - (progn - (beginning-of-line) - ;; copy title - (let ((title - (buffer-substring - (progn (forward-word 1) ; skip over section type - (skip-chars-forward " \t") ; and over spaces - (point)) - (progn (end-of-line) (point))))) - title)) - "")))) - -(defun texinfo-multi-file-update (files &optional update-everything) - "Update first node pointers in each file in FILES. -Return a list of the node names. - -The first file in the list is an outer file; the remaining are -files included in the outer file with `@include' commands. - -If optional arg UPDATE-EVERYTHING non-nil, update every menu and -pointer in each of the included files. - -Also update the `Top' level node pointers of the outer file. - -Requirements: - - * the first file in the FILES list must be the outer file, - * each of the included files must contain exactly one highest - hierarchical level node, - * this node must be the first node in the included file, - * each highest hierarchical level node must be of the same type. - -Thus, normally, each included file contains one, and only one, -chapter." - -; The menu-list has the form: -; -; \(\(\"node-name1\" . \"title1\"\) -; \(\"node-name2\" . \"title2\"\) ... \) -; -; However, there does not need to be a title field and this function -; does not fill it; however a comment tells you how to do so. -; You would use the title field if you wanted to insert titles in the -; description slot of a menu as a description. - - (let ((case-fold-search t) - menu-list) - - ;; Find the name of the first node of the first included file. - (switch-to-buffer (find-file-noselect (car (cdr files)))) - (widen) - (goto-char (point-min)) - (if (not (re-search-forward "^@node" nil t)) - (error "No `@node' line found in %s !" (buffer-name))) - (beginning-of-line) - (texinfo-check-for-node-name) - (setq next-node-name (texinfo-copy-node-name)) - - (setq menu-list - (cons (cons - next-node-name - (prog1 "" (forward-line 1))) - ;; Use following to insert section titles automatically. - ;; (texinfo-copy-next-section-title) - menu-list)) - - ;; Go to outer file - (switch-to-buffer (find-file-noselect (car files))) - (goto-char (point-min)) - (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t)) - (error "This buffer needs a Top node!")) - (beginning-of-line) - (texinfo-delete-existing-pointers) - (end-of-line) - (insert ", " next-node-name ", (dir), (dir)") - (beginning-of-line) - (setq previous-node-name "Top") - (setq files (cdr files)) - - (while files - - (if (not (cdr files)) - ;; No next file - (setq next-node-name "") - ;; Else, - ;; find the name of the first node in the next file. - (switch-to-buffer (find-file-noselect (car (cdr files)))) - (widen) - (goto-char (point-min)) - (if (not (re-search-forward "^@node" nil t)) - (error "No `@node' line found in %s !" (buffer-name))) - (beginning-of-line) - (texinfo-check-for-node-name) - (setq next-node-name (texinfo-copy-node-name)) - (setq menu-list - (cons (cons - next-node-name - (prog1 "" (forward-line 1))) - ;; Use following to insert section titles automatically. - ;; (texinfo-copy-next-section-title) - menu-list))) - - ;; Go to node to be updated. - (switch-to-buffer (find-file-noselect (car files))) - (goto-char (point-min)) - (if (not (re-search-forward "^@node" nil t)) - (error "No `@node' line found in %s !" (buffer-name))) - (beginning-of-line) - - ;; Update other menus and nodes if requested. - (if update-everything (texinfo-all-menus-update t)) - - (beginning-of-line) - (texinfo-delete-existing-pointers) - (end-of-line) - (insert ", " next-node-name ", " previous-node-name ", " up-node-name) - - (beginning-of-line) - (setq previous-node-name (texinfo-copy-node-name)) - - (setq files (cdr files))) - (nreverse menu-list))) - -(defun texinfo-multi-files-insert-main-menu (menu-list) - "Insert formatted main menu at point. -Indents the first line of the description, if any, to the value of -texinfo-column-for-description." - - (insert "@menu\n") - (while menu-list - ;; Every menu entry starts with a star and a space. - (insert "* ") - - ;; Insert the node name (and menu entry name, if present). - (let ((node-part (car (car menu-list)))) - (if (stringp node-part) - ;; "Double colon" entry line; menu entry and node name are the same, - (insert (format "%s::" node-part)) - ;; "Single colon" entry line; menu entry and node name are different. - (insert (format "%s: %s." (car node-part) (cdr node-part))))) - - ;; Insert the description, if present. - (if (cdr (car menu-list)) - (progn - ;; Move to right place. - (indent-to texinfo-column-for-description 2) - ;; Insert description. - (insert (format "%s" (cdr (car menu-list)))))) - - (insert "\n") ; end this menu entry - (setq menu-list (cdr menu-list))) - (insert "@end menu")) - -(defun texinfo-multi-file-master-menu-list (files-list) - "Return master menu list from files in FILES-LIST. -Menu entries in each file collected using `texinfo-master-menu-list'. - -The first file in FILES-LIST must be the outer file; the others must -be the files included within it. A main menu must already exist." - (save-excursion - (let (master-menu-list) - (while files-list - (switch-to-buffer (find-file-noselect (car files-list))) - (message "Working on: %s " (current-buffer)) - (goto-char (point-min)) - (setq master-menu-list - (append master-menu-list (texinfo-master-menu-list))) - (setq files-list (cdr files-list))) - master-menu-list))) - - -;;; The multiple-file update function - -(defun texinfo-multiple-files-update - (outer-file &optional update-everything make-master-menu) - "Update first node pointers in each file included in OUTER-FILE; -create or update the `Top' level node pointers and the main menu in -the outer file that refers to such nodes. This does not create or -update menus or pointers within the included files. - -With optional MAKE-MASTER-MENU argument (prefix arg, if interactive), -insert a master menu in OUTER-FILE in addition to creating or updating -pointers in the first @node line in each included file and creating or -updating the `Top' level node pointers of the outer file. This does -not create or update other menus and pointers within the included -files. - -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. - -Notes: - - * this command does NOT save any files--you must save the - outer file and any modified, included files. - - * except for the `Top' node, this command does NOT handle any - pre-existing nodes in the outer file; hence, indices must be - enclosed in an included file. - -Requirements: - - * each of the included files must contain exactly one highest - hierarchical level node, - * this highest node must be the first node in the included file, - * each highest hierarchical level node must be of the same type. - -Thus, normally, each included file contains one, and only one, -chapter." - - (interactive (cons - (read-string - "Name of outer `include' file: " - (buffer-file-name)) - (cond ((not current-prefix-arg) - '(nil nil)) - ((listp current-prefix-arg) - '(t nil)) ; make-master-menu - ((numberp current-prefix-arg) - '(t t)) ; update-everything - ))) - - (let* ((included-file-list (texinfo-multi-file-included-list outer-file)) - (files included-file-list) - main-menu-list - next-node-name - previous-node-name - (up-node-name "Top")) - -;;; Update the pointers -;;; and collect the names of the nodes and titles - (setq main-menu-list (texinfo-multi-file-update files update-everything)) - -;;; Insert main menu - - ;; Go to outer file - (switch-to-buffer (find-file-noselect (car included-file-list))) - (if (texinfo-old-menu-p - (point-min) - (save-excursion - (re-search-forward "^@include") - (beginning-of-line) - (point))) - - ;; If found, leave point after word `menu' on the `@menu' line. - (progn - (texinfo-incorporate-descriptions main-menu-list) - ;; Delete existing menu. - (beginning-of-line) - (delete-region - (point) - (save-excursion (re-search-forward "^@end menu") (point))) - ;; Insert main menu - (texinfo-multi-files-insert-main-menu main-menu-list)) - - ;; Else no current menu; insert it before `@include' - (texinfo-multi-files-insert-main-menu main-menu-list)) - -;;; Insert master menu - - (if make-master-menu - (progn - ;; First, removing detailed part of any pre-existing master menu - (goto-char (point-min)) - (if (re-search-forward texinfo-master-menu-header nil t) - ;; Remove detailed master menu listing - (progn - (goto-char (match-beginning 0)) - (let ((end-of-detailed-menu-descriptions - (save-excursion ; beginning of end menu line - (goto-char (texinfo-menu-end)) - (beginning-of-line) (forward-char -1) - (point)))) - (delete-region (point) end-of-detailed-menu-descriptions)))) - - ;; Create a master menu and insert it - (texinfo-insert-master-menu-list - (texinfo-multi-file-master-menu-list - included-file-list))))) - - ;; Remove unwanted extra lines. - (save-excursion - (goto-char (point-min)) - - (re-search-forward "^@menu") - (forward-line -1) - (insert "\n") ; Ensure at least one blank line. - (delete-blank-lines) - - (re-search-forward "^@end menu") - (forward-line 1) - (insert "\n") ; Ensure at least one blank line. - (delete-blank-lines)) - - (message "Multiple files updated.")) - - -;;; Place `provide' at end of file. -(provide 'texnfo-upd) - -;;; texnfo-upd.el ends here |