[comp.emacs] GNU Emacs Lisp Documentation

eric@nova.laic.uucp (Eric A. Raymond) (06/21/88)

Has there ever been any documentation published about the Lisp used in
GNU Emacs.  The GNU Emacs doc sez that a Lisp manual will be available
real soon now.  I suppose were stuck with apropos until then.

Eric A. Raymond  - ...ucbvax!sun!sunncal!leadsv!laic!eric

blackje@sunspot.steinmetz (emmett black) (06/23/88)

In article <269@laic.UUCP> eric@nova.laic.uucp (Eric A. Raymond) writes:
>Has there ever been any documentation published about the Lisp used in
>GNU Emacs.  The GNU Emacs doc sez that a Lisp manual will be available
>real soon now.  I suppose were stuck with apropos until then.
>
>Eric A. Raymond  - ...ucbvax!sun!sunncal!leadsv!laic!eric

I've generated a Scribe manuscript that makes a reasonable
manual for GNU Emacs Lisp...

It already makes about 40 pages of double column output
including an index.

If there is sufficient interest I can post it to the net.

--Emmett

J. Emmett Black			ARPA  : BlackJE@GE-CRD.ARPA
GE Corporate Research		uucp  : uunet!steinmetz!crd!blackje
Schenectady, NY 12345		phone : 518/387-5583

--Emmett
	BlackJE@GE-CRD.ARPA
	...!steinmetz!crd!blackje

	GE Corporate Research & Development
	Schenectady, NY         12345

andyc@omepd (T. Andrew Crump) (06/23/88)

In article <11323@steinmetz.ge.com> blackje@sunspot.UUCP (emmett black) writes:
>I've generated a Scribe manuscript that makes a reasonable
>manual for GNU Emacs Lisp...
>
>It already makes about 40 pages of double column output
>including an index.
>
>If there is sufficient interest I can post it to the net.
>
>--Emmett
>
>J. Emmett Black			ARPA  : BlackJE@GE-CRD.ARPA

Post It! Post It!  or send it to me please.

- Andy Crump   ...!tektronix!ogcvax!inteloa!andyc

ugwiles@sunybcs.UUCP (Dale Wiles) (06/24/88)

  I'm sufficently interested.


	****************************************************
	* Dale 		  * Any opinion that can be put    *
	*     (ug) Wiles  * in a nut shell, belongs there. *
	****************************************************

msb@ho5cad (Mike Balenger) (06/24/88)

We'd all be interested.  RTFM doesn't work if there isn't a FM to R.
Any help is always appreciated.  
--
-- 

babu@AI.CEL.FMC.COM (Babu Srinivasan) (06/26/88)

Please post the GNU Emacs Lisp Documentation and/or mail it to me.

Thanks,

Babu Srinivasan

dana@dino.bellcore.com (Dana A. Chee) (06/27/88)

OK, OK!  Here's the scoop.  There are at least 3 DOC file greppers (2
of which I have) that will produce a lisp listing with the
documetation that is in the doc file.  It is sorted alphabetically,
not by function type.  This document prints out at about 80-100 pages,
depending on your setting in your text processor.  Below I have posted
the versions for latex and troff.  I here there is one for scribe, but
I don't have it.

Now, there is also a document put out by Bil Lewis and the gnu-manual
list.  This is really nice since it actually explains what is what and
how emacs lisp works, BUT it prints out to 400 pages, so you can
forget about it being posted (at least to this news group).  But for
those of you with ftp access, it is available anonymous ftp from
a.cs.uiuc.edu (10.3.0.37) in ~ftp/pub/gnuemacs/elisp.  For those
without, maybe someone nearby can uucp it to you (the compressed .dvi
file is 316Kbytes).

Well hope this clears some things up.  Below are the DOC greppers (2
files, remove signature from bottom).

====================  docroff.el (troff version)  ====================
;;; Grind GNU Emacs DOC file into troff input.
;;; Copyright (C) 1987 Kyle E. Jones

;;; This file may be redistributed provided the above copyright
;;; notice appears on all copies and that the further free redistribution
;;; of this file is not in any way restricted by those who
;;; redistribute it.

;;; This software is distributed 'as is', without warranties of any kind.

;;; This file is not part of GNU Emacs.

;;; The document that is the output from the (grind-DOC) function is
;;; part of GNU Emacs.


(defvar grind-DOC-macro-package 'me
  "*Should be bound to a symbol indicating what troff macro package
should be used to format the DOC file.  If this variable is set to nil
only basic troff commands will be used.  Since the author isn't a troff
expert the document will look terrible without macros.  Currently only
me macros are supported.")

(defvar grind-DOC-point-size 10 "*The point size for the formatted DOC file.")

(defvar grind-DOC-double-sided t
  "*Should be non-nil if the formatted DOC will be printed on both sides
of the pages.  This will cause the appropriate changes to the headers and
footers.")

(defconst grind-DOC-known-macros '(me)
  "A list of symbols representing the troff macro packages that
(grind-DOC) knows how to use.")

(defconst grind-DOC-title-tag "The Pleasure Principle")

(defun abs (n) (cond ((< n 0) (- n)) (t n)))

(defun grind-DOC () (interactive)
  "Reads the etc/DOC-xx.xx.x file into a buffer and converts it to a form
suitable as troff or nroff input."
  ;
  ; Make sure we can deal with the macro package and the point size.
  ;
  (cond
   ((not (symbolp grind-DOC-macro-package))
    (error "grind-DOC-macro-package must be a symbol"))
  ((and grind-DOC-macro-package
	(not (memq grind-DOC-macro-package grind-DOC-known-macros)))
   (error "I don't know how to use %s %s"
	  (symbol-name grind-DOC-macro-package) "macros"))
  ((not (numberp grind-DOC-point-size))
   (error "grind-DOC-point-size must be a number"))
  ((not (memq grind-DOC-point-size '(6 7 8 9 10 11 12 14 16 18 20 24 28 36)))
   (error "point size must be 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, or 36")))
  ;
  ; Select the DOC file.
  ;
  (find-file (expand-file-name (concat "DOC-" emacs-version) exec-directory))
  (setq buffer-read-only nil)
  (auto-save-mode 0)
  (set-visited-file-name (concat (buffer-file-name) "."
				 (cond
				  ((null grind-DOC-macro-package) "t")
				  (t (symbol-name grind-DOC-macro-package)))))
  (delete-other-windows)
  ;
  ; Save-excursion just in case the DOC file was already selected.
  ;
  (save-excursion
    (let (case-fold-search mode-line-format varstart-point bufstring name odot)
      ;
      ; The first thing we must do is convert the \[COMMAND] sequences
      ; into the keys that the COMMANDs are bound to.
      ;
      (setq mode-line-format
	    "                     Grinding the DOC file... be patient.")
      (sit-for 0)
      (setq bufstring (substitute-command-keys (buffer-string)))
      (erase-buffer)
      (insert bufstring)
      ;
      ; Here we make each docstring begin and end with C-_ for
      ; easier manipulation.  This is undone later.
      ;
      (goto-char (1+ (point-min)))
      (replace-string "\C-_" "\C-_\C-_" nil)
      (goto-char (point-max))
      (insert "\C-_")
      ;
      ; Sort the docstrings.  This implicitly separates function
      ; documentation from the variable documentation.
      ;
      (sort-regexp-fields nil "\C-_\\([FV].*\\)[^\C-_]*\C-_" "\\1"
			  (point-min) (point-max))
      ;
      ; now add the indentation commands and put ( ...) around the functions
      ;
      (save-restriction
	(goto-char (point-min))
	(search-forward "\C-_V" (point-max) nil 1)
	(backward-char 2)
	(narrow-to-region (point-min) (dot))
	(goto-char (point-min))
	(while (search-forward "\C-_F" (point-max) t 1)
	  (delete-char -2)
	  (insert ".ul\n(")
	  (end-of-line 1)
	  (insert "...)\n.in +5")
	  (search-forward "\C-_" (point-max) nil 1)
	  (delete-char -1)
	  (insert "\n.in -5\n"))
	(insert ".bp\n"))
      (while (search-forward "\C-_V" (point-max) t 1)
	(delete-char -2)
	(insert ".ul\n")
	(end-of-line 1)
	(insert "\n.in +5")
	(search-forward "\C-_" (point-max) nil 1)
	(delete-char -1)
	(insert "\n.in -5\n"))
      ;
      ; try to make those parameters that are in all-caps look better
      ;
      (goto-char (point-min))
      (replace-regexp "[A-Z][A-Z]+" "\\\\fB\\\\s-2\\&\\\\s+2\\\\fR" nil)
      ;
      ; Handle point size.  Vertical spacing should be 1.2 * point size.
      ; Since Emacs Lisp has no floating point we multiply by 12,
      ; add 5 (for rounding). and divide by 10.
      ;
      (goto-char (point-min))
      (insert ".ps " (int-to-string grind-DOC-point-size) "\n")
      (insert ".vs "
	      (int-to-string (/ (+ (* grind-DOC-point-size 12) 5) 10)) "\n")
      ;
      ; Insert a tag so that the macro specific functions know where to
      ; put the title page.
      ;
      (insert grind-DOC-title-tag "\n")
      ;
      ; Insert the GNU Emacs copyright notice.
      ;
      (insert
       ".bp\n.ce 2\n.fi\n.ul 1000\n\\(co " (substring emacs-build-time 20)
       " Free Software Foundation, Inc.

This document is part of GNU Emacs.

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the GNU Emacs General Public
License for full details.

Everyone is granted permission to copy, modify and redistribute
GNU Emacs, but only under the conditions described in the
GNU Emacs General Public License.   A copy of this license is
supposed to have been given to you along with GNU Emacs so you
can know your rights and responsibilities.  It should be in a
file named COPYING.  Among other things, the copyright notice
and this notice must be preserved on all copies.\n.ul 0\n.pn 1\n")
      ;
      ; header for function documentation
      ;
      (insert ".bp\n")
      (insert ".nf\n.ce\n\\fBGNU Emacs Functions\\fR\n.sp\n")
      ;
      ; add header and info for variable documentation
      ;
      (search-forward ".bp\n" (point-max))
      (insert ".ce\n\\fBGNU Emacs Variables\\fR\n"
	      ".sp\n.fi\nVariables whose documentation begins with an\n"
	      "asterisk `*' are user definable options.  These variables are\n"
	      "used to customize Emacs.  Other variables are generally of\n"
	      "interest only to Emacs Lisp programmers.\n.nf\n.sp\n")
      ;
      ; Now do macro-package specific things
      ;
      (cond
       ((eq grind-DOC-macro-package 'me) (grind-DOC-for-me))
       (t (grind-DOC-no-macros)))
      (message "Grinding completed.  Behold!"))))

(defun grind-DOC-for-me ()
  "Adds -me macro commands to the formatted DOC.  Should only be called
from (grind-DOC).  In particular -me macros make possible the building
of an index."
  (random t)
  ;
  ; Title page
  ;
  (goto-char (point-min))
  (search-forward grind-DOC-title-tag (point-max))
  (delete-char 1)				; delete the newline
  (delete-char (- (length grind-DOC-title-tag))); delete the tag
  (insert ".tp\n")
  (insert ".ps 28\n.vs 34\n.sv 2.5i\n.ce\nGNU EMACS Lisp Reference\n.sp\n"
	  ".ps\n.vs\n"
	  ".ce 5\n\\s-2(gouged with a blunt instrument from "
	  (concat "DOC-" emacs-version)
	  ")\\s+2\n.sp\n"
	  "\\s-1writing by\\s+1\n"
	  ".bi \"Richard M. Stallman\"\n.sp\n"
	  "\\s-1gouging by\\s+1\n"
	  ".bi \"Kyle E. Jones\"\n")

  ;
  ; Origins
  ;
  (search-forward "\n.pn 1" (point-max))
  (beginning-of-line)
  (insert ".sp\nThis document is a reformatted version of the GNU Emacs "
	  emacs-version " online documentation.\nThe program that gouges this document from the etc/DOC-" emacs-version " file was written by\n"
	  (nth (% (abs (random)) 6)
	       '("a mild mannered youth"
		 "a singularly handsome man"
		 "a moody and arrogant surrealist"
		 "a 60's rabblerouser"
		 "a lout"
		 "several caribou, oddly enough, all"))
	  " named Kyle Jones, currently living in exile.\n")
  ;
  ; Headers and footers
  ;
  (forward-line 1)
  (if grind-DOC-double-sided
      (insert ".oh 'Version " emacs-version "'GNU EMACS Lisp Reference'%'\n"
	      ".eh '%'GNU EMACS Lisp Reference'Version " emacs-version "'\n")
    (insert ".he 'GNU EMACS Lisp Reference''Version " emacs-version "'\n"
	    ".fo ''- % -''\n"))
  ;
  ; Use bold-italics on variable and function names and wrap docstrings
  ; in a keep.
  ;
  (goto-char (point-min))
  (let (name odot)
    (while (search-forward "\n.in +5\n" (point-max) t 1)
      (search-backward ".ul\n" (point-min))
      (delete-char 4)
      (insert ".(b\n.bi \"")
      (setq odot (dot))
      (if (looking-at "(") (forward-char 1))
      (setq name (symbol-name (read (current-buffer))))
      (goto-char odot)
      (end-of-line 1)
      (insert "\"")
      (search-forward "\n.in -5\n" (point-max))
      (insert ".)b\n.(x\n\t" name "\n.)x\n")))

  ;
  ; Make index entries where the variable and function documentation
  ; sections are.
  ;
  (goto-char (point-min))
  (search-forward "\n.bp\n" (point-max) nil 2)
  (insert ".(x\nFunction Documentation\n.)x\n")
  (search-forward "\\fBGNU Emacs" (point-max) nil 2)
  (beginning-of-line)
  (insert ".(x\nVariable Documentation\n.)x\n")

  ;
  ; Force out index.
  ;
  (goto-char (point-max))
  (insert ".he ''''\n.eh ''''\n.oh ''''\n.fo ''''\n"
	  (cond (grind-DOC-double-sided ".bp\n.bp\n")
		(t ".bp\n"))
	  ".ce\n\\fB\\(if INDEX \\(if\\fR\n.xp\n.bp\n"))

(defun grind-DOC-no-macros ()
  "Add title page to formatted DOC using straight troff commands.  Should
only be called from (grind-DOC)."
  ;
  ; Title page
  ;
  (goto-char (point-min))
  (search-forward grind-DOC-title-tag (point-max))
  (delete-char 1)				; delete the newline
  (delete-char (- (length grind-DOC-title-tag))); delete the tag
  (insert ".ps 28\n.vs 34\n.sv 2.5i\n.ce\nGNU EMACS Lisp Reference\n.sp\n"
	  ".ps\n.vs\n"
	  ".ce 5\n\\s-2(gouged with a blunt instrument from "
	  (concat "DOC-" emacs-version)
	  ")\\s+2\n.sp\n"
	  "\\s-1writing by\\s+1\n"
	  "\\fBRichard M. Stallman\\fR\n.sp\n"
	  "\\s-1gouging by\\s+1\n"
	  "\\fBKyle E. Jones\\fR\n"))
====================  doctex.el  (latex version)  ====================
;;; Grind GNU Emacs DOC file into LaTeX input
;;; Copyright (C) 1987 Kyle E. Jones, Tor Lillqvist

;;; This file may be redistributed provided the above copyright
;;; notice appears on all copies and that the further free redistribution
;;; of this file is not in any way restricted by those who
;;; redistribute it.

;;; Based on Kyle E. Jones's grind-DOC package.

;;; This software is distributed 'as is', without warranties of any kind.

;;; This file is not part of GNU Emacs.

;;; The document that is the output from the (LaTeXify-DOC) function is
;;; part of GNU Emacs.


(defvar LaTeXify-DOC-style "report"
  "*Should be bound to a string indicating what LaTeX document style
should be used to format the DOC file.  If this variable is set to nil
the report style will be used.")

(defvar LaTeXify-DOC-style-options ""
  "*A string containing a list of document style options for LaTeX")

(defun LaTeXify-DOC () (interactive)
  "Reads the etc/DOC-xx.xx.x file into a buffer and converts it to a form
suitable as LaTeX input."
  ;
  ; Make sure we can deal with the macro package and the point size.
  ;
  (cond
   ((not (stringp LaTeXify-DOC-style))
    (error "LaTeXify-DOC-style must be a string")))
  ;
  ; Select the DOC file.
  ;
  (find-file (expand-file-name
	      (if (fboundp 'dump-emacs)
		  (concat "DOC-" emacs-version)
		"DOC")
	      exec-directory))
  (setq buffer-read-only nil)
  (auto-save-mode 0)
  (set-visited-file-name (concat (buffer-file-name) ".tex"))
  (delete-other-windows)
  ;
  ; Save-excursion just in case the DOC file was already selected.
  ;
  (save-excursion
    (let (case-fold-search mode-line-format varstart-point bufstring name odot)
      ;
      ; The first thing we must do is convert the \[COMMAND] sequences
      ; into the keys that the COMMANDs are bound to.
      ;
      (setq mode-line-format
	    "                     Grinding the DOC file... be patient.")
      (sit-for 0)
      (replace-regexp "\\\\{\\(\\s_\\|\\sw\\)*}"
		      "]]bgroup]]obeylines\\&]]egroup")
      (setq bufstring (substitute-command-keys (buffer-string)))
      (erase-buffer)
      (insert bufstring)
      ;
      ; Here we make each docstring begin and end with C-_ for
      ; easier manipulation.  This is undone later.
      ;
      (goto-char (1+ (point-min)))
      (replace-string "\C-_" "\C-_\C-_" nil)
      (goto-char (point-max))
      (insert "\C-_")
      ;
      ; Sort the docstrings.  This implicitly separates function
      ; documentation from the variable documentation.
      ;
      (sort-regexp-fields nil "\C-_\\([FV].*\\)[^\C-_]*\C-_" "\\1"
			  (point-min) (point-max))
      ;
      ; Handle TeX special characters
      ;
      (goto-char (point-min))
      (mapcar
       '(lambda (x) (save-excursion (eval x)))
       '((replace-string "#" "]]#")
         (replace-string "$" "]]$")
	 (replace-string "%" "]]%")
	 (replace-string "&" "]]&")
         (replace-string "~" "]]verb+~+")
	 (replace-string "_" "]]verb+_+")
	 (replace-string "^" "]]verb+^+")
	 (replace-string "\\" "]]verb+]]+")
	 (replace-string "{" "]]{")
	 (replace-string "}" "]]}")
	 (replace-string "<" "]]verb+<+")
	 (replace-string ">" "]]verb+>+")
	 (replace-string "]]" "\\")))
      ;
      ; Now add the indentation commands and put ( ...) around the functions
      ;
      (save-restriction
	(goto-char (point-min))
	(search-forward "\C-_V" (point-max) nil 1)
	(backward-char 2)
	(narrow-to-region (point-min) (dot))
	(goto-char (point-min))
	(insert "\\section*{Functions}\n"
		"\\begin{description}\n")
	(while (search-forward "\C-_F" (point-max) t 1)
	  (delete-char -2)
	  (insert "\n\\item[\\sf(")
	  (end-of-line 1)
	  (insert " ...)]")
	  (search-forward "\C-_" (point-max) nil 1)
	  (delete-char -1))
	(insert "\\end{description}\n"))
      (insert "\\section*{Variables}
Variables whose documentation begins with an
asterisk `*' are user definable options.  These variables are
used to customize Emacs.  Other variables are generally of
interest only to Emacs Lisp programmers.
\\begin{description}\n")
      (while (search-forward "\C-_V" (point-max) t 1)
	(delete-char -2)
	(insert "\n\\item[\\sf ")
	(end-of-line 1)
	(insert "]")
	(search-forward "\C-_" (point-max) nil 1)
	(delete-char -1))
      (insert "\\end{description}\n"
	      "\\end{document}\n")
      ;
      ; Try to make those parameters that are in all-caps look better
      ;
      (goto-char (point-min))
      (mapcar
       '(lambda (x) (save-excursion (eval x)))
       '((replace-regexp "[A-Z][A-Z]+" "\n{\\\\lowercase{\\\\sf \\&}}" nil)
	 (replace-string "\\lowercase{\\sf TAB}" "{\\tt TAB}")
	 (replace-string "\\lowercase{\\sf LFD}" "{\\tt LFD}")
	 (replace-string "\\lowercase{\\sf RET}" "{\\tt RET}")
	 (replace-string "\\lowercase{\\sf ESC}" "{\\tt ESC}")
	 (replace-string "\\lowercase{\\sf SPC}" "{\\tt SPC}")
	 (replace-string "\\lowercase{\\sf DEL}" "{\\tt DEL}")))
      ;
      ; Handle document style and front matter
      ;
      (goto-char (point-min))
      (insert "\\documentstyle["
	      LaTeXify-DOC-style-options
	      "]{" LaTeXify-DOC-style "}\n"
	      "\\begin{document}\n"
	      "\\title{GNU Emacs Lisp Reference \\\\\n"
	      "Version " emacs-version " \\\\\n"
	      "\\large (gouged with a blunt instrument from the DOC file)}\n"
	      "\\author{Richard M. Stallman}\n"
	      "\\date{" (substring emacs-build-time 4 8)
	      (substring emacs-build-time 20) "}\n"
	      "\\maketitle\n")
      ;
      ; Insert the GNU Emacs copyright notice.
      ;
      (insert
       "\\begin{centering}\n"
       "Copyright \\copyright" (substring emacs-build-time 20)
       " Free Software Foundation, Inc. \\\\\n"
       "\\end{centering}
\\vspace{\\baselineskip}
\\noindent
This document is part of GNU Emacs.

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the GNU Emacs General Public
License for full details.

Everyone is granted permission to copy, modify and redistribute
GNU Emacs, but only under the conditions described in the
GNU Emacs General Public License.   A copy of this license is
supposed to have been given to you along with GNU Emacs so you
can know your rights and responsibilities.  It should be in a
file named COPYING.  Among other things, the copyright notice
and this notice must be preserved on all copies.
\\newpage\\sloppy\n")
      ;
      ; That's it
      ;
      (message "Grinding completed.  Behold!"))))
====================  end of files  ====================
--
+*************************************************************************+
*  Dana Chee				(201) 829-4488			  *
*  Bellcore								  *
*  Room 2Q-250								  *
*  445 South Street			ARPA: dana@bellcore.com		  *
*  Morristown,  NJ  07960-1910		UUCP: {gateways}!bellcore!dana	  *
+*************************************************************************+

bhagwan@voodoo.UUCP (The Bhagwan) (06/30/88)

In article <11323@steinmetz.ge.com> blackje@sunspot.UUCP (emmett black) writes:
>
>I've generated a Scribe manuscript that makes a reasonable
>manual for GNU Emacs Lisp...
>
>If there is sufficient interest I can post it to the net.
Please post a PostScript file if possible - some of us don't have Scribe.
Thanks,
-- 
Al McPherson		     Field Service Engineering Systems
Boeing Computer Services     ...uw-beaver!ssc-vax!voodoo!bhagwan
P.O. Box 24346   MS: 6M-17   Seattle, WA  98124	   (206) 234-7723

edward@csvaxa.UUCP (Edward Wilkinson) (07/01/88)

Newsgroups: comp.emacs
Subject: Re: GNU Emacs Lisp Documentation
Summary: TeX or roff please!
Expires: 
References: <269@laic.UUCP> <11323@steinmetz.ge.com> <909@td2cad.intel.com>
Sender: E.Wilkinson@massey.ac.nz
Reply-To: E.Wilkinson@massey.ac.nz
Followup-To: 
Distribution: 
Organization: Computer Centre, Massey University, Palmerston North, NZ.
Keywords: TeX, [nt]roff

> << stuff about a Scribe Emacs lisp manual deleted >>
>
>I'd be really interested. (You wouldn't happen to have a TeX or roff 
>version would you?)
>

Here, here  for  the  TeX  version. If not   TeX then  maybe [nt]roff.
Thanks. Perhaps someone has some general Scribe <-> TeX filters? There
are already ones for TeX  <-> nroff,  so the above should be possible.
Ta.

Please post instead of mail.
-- 
Ed Wilkinson @ Computer Centre, Massey University, Palmerston North, NZ
uucp: {uunet,watmath!cantuar}!vuwcomp!csvaxa!edward   DTE: 530163000005
Janet/Greybook: E.Wilkinson@nz.ac.massey      Phone: +64 63 69099 x8587
CSnet/ACSnet/Internet: E.Wilkinson@massey.ac.nz    New Zealand = GMT+12

brw@jim.odr.oz (Brian Wallis) (07/05/88)

From article <269@laic.UUCP>, by eric@nova.laic.uucp (Eric A. Raymond):
> Has there ever been any documentation published about the Lisp used in
> GNU Emacs.  The GNU Emacs doc sez that a Lisp manual will be available
> real soon now.  I suppose were stuck with apropos until then.
> 
> Eric A. Raymond  - ...ucbvax!sun!sunncal!leadsv!laic!eric

Jon Wells and I wrote a function that extracts documentation strings
from emacs and produces a latex file of that including a table of
contents and index on key words. I have found this an invaluable
reference, particularly the index when looking for that function that
you can't quit remember the name of...

The document is formated to fill as much of an A4 page as possible and
should be printed double sided.

NOTE: this has only been tested with Emacs 17.49, which is all we have
for now.

-------------------------------- Cut Here --------------------------------
#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#	Packed Tue Jul  5 13:19:44 EST 1988 by jim!brw
#	from directory /usr/brw/src/emacs/lisp
#
#	Run the following text with /bin/sh to create:
#	  README
#	  gendoc.el
#	  makeindex
#
if test -f README; then echo "File README exists"; else
echo "x - extracting README (Text)"
sed 's/^X//' << 'SHAR_EOF' > README &&
X
XExtracting emacs lisp function and variable documentation.
X
XThere are two files included here gendoc.el, the lisp to extract the
Xdocumentation strings and Makeindex a shell script which uses perl 1.0
X(patch level 29) to sort the index.
X
XTo extract the basic emacs lisp documentation run emacs in batch mode
Xthus:
X
X42% emacs -batch -l gendoc.el -f make-documentation -kill
X
X(this will take about 15 minutes)
X
XIf you run make-documentation interactively you may get extra
Xfunctions loaded by your .emacs or by any commands you have run before
Xmake-documentation, which you may want. The above command will give
Xthe documentation for the basic set of lisp functions in your emacs.
XThis will produce two files 'doc-info.tex' and 'doc-info.sty'.
X'doc-info.tex' is about 340K with emacs 17.49.
X
XNext, latex the file 'doc-info.tex' _TWICE_ so that the size of the
Xtable of contents is taken into account in the index and in the table
Xof contents. (I suppose I could number the table of contents i, ii,
Xetc.) The latex will produce LOTS of underfull hbox messages, nothing
Xto worry about! Then run makeindex to produce doc-info.ind from
Xdoc-info.idx and run latex on doc-info.tex one more time!
X
XYou will now have a dvi file suitable for printing on A4 paper (about
X40 sheets double sided). You will have to adjust the lisp that
Xgenerates doc-info.sty for other paper sizes.
X
XWritten by Jon Wells originally, index added and latex format changed
Xby B.Wallis.
SHAR_EOF
chmod 0640 README || echo "restore of README fails"
set `wc -c README`;Sum=$1
if test "$Sum" != "1452"
then echo original size 1452, current size $Sum;fi
fi
if test -f gendoc.el; then echo "File gendoc.el exists"; else
echo "x - extracting gendoc.el (Text)"
sed 's/^X//' << 'SHAR_EOF' > gendoc.el &&
X(defun caseless-string< (arg1 arg2) "GENDOC"
X  (string< (downcase arg1) (downcase arg2)))
X
X(defun  make-documentation () "GENDOC"
X  (interactive nil)
X  (let ((functions
X	 (progn
X	   (message "sorting functions...")
X	   (sort (all-completions "" obarray 'fboundp ) 'caseless-string<)))
X	(variables
X	 (progn
X	   (message "sorting variables...")
X	   (sort (all-completions "" obarray 'boundp ) 'caseless-string<))))
X    (get-buffer-create "doc-info.tex")
X    (with-output-to-temp-buffer "doc-info.tex"
X      (switch-to-buffer "doc-info.tex")
X      (erase-buffer)
X      (message "%s" "generating function info")
X      (insert "\\documentstyle[twoside,twocolumn,doc-info]{article}
X\\makeindex
X\\title{Emacs Variables and Functions\\\\" (emacs-version) "}
X\\author{gendoc.el}
X\\begin{document}
X\\maketitle
X\\clearpage
X\\footnotesize
X\\tableofcontents
X\\clearpage
X\\sloppy
X
X\\section{Functions}
X")
X      (while functions
X	(if (car functions)
X	    (print-doc (car functions)))
X	(setq functions (cdr functions)))
X      (terpri)
X      (insert "
X\\newpage
X
X\\index{-----}
X
X\\section{Variables}
X")
X      (message "%s" "generating variable info")
X      (while variables
X	(if (car variables)
X	    (print-var-doc (car variables)))
X	(setq variables (cdr variables)))
X      (insert "
X\\input{doc-info.ind}
X
X\\end{document}
X")
X      (message "%s" "running replace-regexp")
X      (goto-char 1)
X      (while (re-search-forward
X	      "^\\\\\\(subsection\\|index\\){.*[$%<>].*$" nil t)
X	(save-restriction
X	  (narrow-to-region (match-beginning 0) (match-end 0))
X	  (replace-string "$" "\\$")(goto-char (point-min))
X	  (replace-string "%" "\\%")(goto-char (point-min))
X	  (replace-string ">" "$>$")(goto-char (point-min))
X	  (replace-string "<" "$<$"))
X	(goto-char (match-end 0)))
X      (write-file "doc-info.tex")
X;;
X;; create a file doc-info.sty for our latex option `doc-info' which gives a bit
X;; more room for the `section.subsection' number before the text of
X;; the section heading in the index. When we had `x.xxx' the text
X;; was hard up against the last number. We changed the 2.3em to 2.8em
X;; for extra space.
X;; Also set the margins to mostly fill an A4 page.
X;;
X      (get-buffer-create "doc-info.sty")
X      (with-output-to-temp-buffer "doc-info.sty"
X	(switch-to-buffer "doc-info.sty")
X	(erase-buffer)
X	(insert "\\def\\l@subsection{\\@dottedtocline{2}{1.5em}{2.8em}}
X\\oddsidemargin -16pt
X\\evensidemargin -36pt
X\\topmargin -60pt
X\\textheight 707pt
X\\textwidth 500pt
X")
X	(write-file "doc-info.sty")))))
X
X
X(defun print-doc (func) "GENDOC"
X  (interactive nil)
X  (let ((Func (intern func)))
X    (let ((doc-str (documentation Func)))
X      (if (equal doc-str "GENDOC")
X	  (message "Discarding Function %s..." func)
X	(message "Function %s..." func)
X	(insert "\\subsection{" func "}
X")
X	(index-entry func)
X	(insert "
X\\begin{verbatim}
X")
X	(if (setq keys (where-is-internal Func))
X	    (let ((next-key (car keys)))
X	      (insert "Key-Mapping: ")
X	      (while next-key
X		(insert " `" (key-description next-key) "'")
X		(setq next-key (car (setq keys (cdr keys)))))
X	      (insert "
X
X")))
X	(insert
X	 (if doc-str
X	     (if (equal doc-str "")
X		 "I don't know about this one"
X	       doc-str)
X	   "undocumented")
X	 "
X\\end{verbatim}
X
X")
X	nil))))
X
X(defun pretty-string (str) "GENDOC"
X  (let ((newstr "")(a 0)(len (length str)))
X    (while (/= len a)
X      (setq newstr (concat
X		    newstr
X		    (text-char-description
X		     (string-to-char (substring str a (1+ a))))))
X      (setq a (1+ a)))
X    newstr))
X
X(defun print-var-doc (var) "GENDOC"
X  (interactive nil)
X  (let ((Var (intern var)))
X    (let ((doc-str (substitute-command-keys
X		    (get Var 'variable-documentation))))
X      (message "Variable %s..." var)
X      (insert "\\subsection{" var "}
X")
X      (index-entry var)
X      (insert "
X\\begin{verbatim}
XValue: "
X	      (let ((valstr (prin1-to-string (eval Var))))
X		(if (> (length valstr) 100)
X		    "..."
X		  (pretty-string valstr))) "
X
X"
X		  (if doc-str
X		      (if (equal doc-str "")
X			  "I don't know about this one!"
X			doc-str)
X		    "variable not documented.")
X		  "
X\\end{verbatim}
X
X")
X    nil)))
X  
X(defun index-entry (name) "GENDOC"
X  (interactive nil)
X;;
X;; do a couple of special cases first
X;;
X  (if (or (string-equal name "1-") (string-equal name "-"))
X      (insert "\\index{" name " " name "}
X")
X;;
X;; OK general case of "xx-yy" ignore trailing '-'s and double '--'s
X;; and produce index entries for 'xx' and 'yy'.
X;;
X    (let ((func-name name) end)
X      (while (and func-name (> (length func-name) 0))
X	(if (not (setq end (string-match "-" func-name)))
X	    (setq end (length func-name)))
X	(if (not (= 0 (length (setq substr (substring func-name 0 end)))))
X	    (insert "\\index{" substr " " name "}
X"))
X	(setq func-name (if (not (= end (length func-name)))
X			    (substring func-name (1+ end) nil)))))))
SHAR_EOF
chmod 0640 gendoc.el || echo "restore of gendoc.el fails"
set `wc -c gendoc.el`;Sum=$1
if test "$Sum" != "4817"
then echo original size 4817, current size $Sum;fi
fi
if test -f makeindex; then echo "File makeindex exists"; else
echo "x - extracting makeindex (Text)"
sed 's/^X//' << 'SHAR_EOF' > makeindex &&
X#!/bin/sh
X
Xif ( [ ! \( $# -eq 1 -o $# -eq 2 \) ] ) then
X  echo Usage: $0 \<\'.idx\' filename\>
X  exit 1;
Xfi
Xif ( [ ! -r $1 ] ) then
X  echo Can\'t open \"$1\"
X  exit 1
Xfi
XDEST=''
Xif ( [ $# -eq 2 ] ) then
X  if ( [ $1 = $2 ] ) then
X    echo Infile \"$1\" and Outfile \"$2\" can\'t be the same
X    exit 1
X  fi
X  if ( touch $2 ) then
X    echo -n
X  else
X    echo Can\'t write \"$2\"
X    exit 1
X  fi
X  DEST=$2
Xfi
X
X
Xperl \
X-e '$varpage = 0;' \
X-e 'while(<>) {' \
X-e '  if(/\\indexentry{-----}{(.*)}$/) {' \
X-e '    $varpage = $1;' \
X-e '    next;' \
X-e '  }' \
X-e '  elsif($varpage == 0) {' \
X-e '    if(! s/^\\indexentry{((.).*) (..*)}{([0-9]+)}$/$2:$1:$3:$4:B/) {' \
X-e '      next;' \
X-e '    }' \
X-e '  }' \
X-e '  else {' \
X-e '    if(! s/^\\indexentry{((.).*) (..*)}{([0-9]+)}$/$2:$1:$3:$4:I/) {' \
X-e '      next;' \
X-e '    }' \
X-e '  }' \
X-e '  s/^\\:(.(.))/$2:$1/;' \
X-e '  print;' \
X-e '}' $1 \
X| sort -u -t: +1f -2 +1 -2 +2f -3 +2 -3 +3n -4 | perl \
X-e '$cur_topic = 0;' \
X-e 'print "\\begin{theindex}";' \
X-e 'while(<stdin>) {' \
X-e '  chop;' \
X-e '  if(! /^(.):(.+):(.+):(.+):(.)$/) {die "bad file after sort, line \"$_\"";}' \
X-e '  $F1 = $1; $F2 = $2; $F3 = $3; $F4 = $4; $F5 = $5;' \
X-e '  if($cur_topic eq $F2) {' \
X-e '    printf "\\subitem %s {\\dotfill\\%s %s}\n",$F3,($F5 eq "B")?"bf":"em",$F4;' \
X-e '  }' \
X-e '  else {' \
X-e '    print "\n";' \
X-e '    if(($F1 =~ /^[a-zA-Z]/ || $cur_topic =~ /^[a-zA-Z]/) &&' \
X-e '        $cur_topic !~ /^$F1/i) {' \
X-e '      print "\\indexspace\n";' \
X-e '    }' \
X-e '    printf "\\item %s\n",$F2;' \
X-e '    printf "\\subitem %s {\\dotfill\\%s %s}\n",$F3,($F5 eq "B")?"bf":"em",$F4;' \
X-e '    $cur_topic = $F2;' \
X-e '  }' \
X-e '}' \
X-e 'print "\n\\end{theindex}\n";' > $DEST
SHAR_EOF
chmod 0750 makeindex || echo "restore of makeindex fails"
set `wc -c makeindex`;Sum=$1
if test "$Sum" != "1732"
then echo original size 1732, current size $Sum;fi
fi
exit 0
-- 
Brian Wallis (brw@jim.odr.oz)		    O'Dowd Research P/L.
	(03) 562-0100 Fax: (03) 562-0616,
	Telex: Jacobs Radio (Bayswater) 152093