[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

SchemeTeX



I got so many requests for SchemeTeX I decided to send it to the news
group.  Since my last message, I modified the Scheme source to
SchemeTeX so that it contains no TAB characters for you Mac users.
Please update to this version even if you recently received a version
by mail from me.
John

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	README
#	Makefile
#	astyped.sty
#	schemeTeX.l
#	st.sh
#	st.scm
#	st.tex
#	reader.st
# This archive created: Fri Oct 27 11:35:30 1989
export PATH; PATH=/bin:$PATH
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
cat << \SHAR_EOF > 'README'
@(#)README	1.1 89/10/25

SchemeTeX---Simple support for literate programming in Lisp.

SchemeTeX is a Unix filter that translates schemeTeX source into LaTeX
source.  Originally developed for the Scheme dialect of Lisp, it can
easily be used with most other dialects.

Installation:

1) Processes the file "st.tex" with LaTeX and read that one page
document.

2) Decide if you plan to use your Lisp system's standard LOAD
procedure or a modified one.  I recommend you start by using your Lisp
system's LOAD, which means all text lines must begin with ";".

3) Assuming you do use the standard LOAD, edit "st.sh" so that it
contains the correct extension, i.e. ".scm", ".lisp", or ".clisp".
Otherwise do not modify "st.sh".

4) Edit "Makefile" to reflect the correct destination of the
executables(DEST) and the correct destination of the style
file(TEXDEST). 

5) The command "make install" installs schemeTeX.

6) If you plan to modify your Lisp system's standard LOAD, follow the
model given in "reader.st", a reader of schemeTeX source for the R4RS
dialect of Scheme.
SHAR_EOF
fi # end of overwriting check
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
# schemeTeX Makefile @(#)Makefile	1.4 89/10/25.

SRCS		= README Makefile astyped.sty schemeTeX.l st.sh\
		  st.scm st.tex reader.st

CMDS		= st schemeTeX

DOCS		= st.dvi reader.dvi

TEXSTY		= astyped.sty

#DEST		= /usr/local/bin
DEST		= $(HOME)/bin

#TEXDEST	= /usr/local/lib/tex/inputs
TEXDEST	= $(HOME)/doc/inputs

# Generic rules
.SUFFIXES:	.dvi .tex .st

.st.dvi:
	make $*.tex && make $*.dvi

.st.tex:
	st $*

.tex.dvi:
	latex $*

# Generic commands.
	
all:	$(CMDS)

doc:	$(DOCS) $(CMDS)

install:	$(CMDS) $(TEXSTY)
	mv $(CMDS) $(DEST)
	cp $(TEXSTY) $(TEXDEST)

clean:
	-rm $(CMDS)

dist:	schemeTeX.sh

# Specific commands.

schemeTeX:	schemeTeX.l
	lex -t $? > schemeTeX.c
	cc -O -o $@ schemeTeX.c -ll
	rm schemeTeX.c

st:	st.sh
	cp $? $@
	chmod +x $@

schemeTeX.sh:	$(SRCS)
	shar $(SRCS) > $@
SHAR_EOF
fi # end of overwriting check
if test -f 'astyped.sty'
then
	echo shar: will not over-write existing file "'astyped.sty'"
else
cat << \SHAR_EOF > 'astyped.sty'
%%%%%%%%%%%%%%%%%%%%%% @(#)astyped.sty	1.3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ASTYPED DOCUMENT-STYLE OPTION - released 88/06/30
%    for LaTeX version 2.09
% Based on Leslie Lamport's verbatim environment in latex.tex.

% Defines the `astyped' environment, which is like the `verbatim'
% environment except most of the special characters have their usual meanings.
% Space, ^K, and ^A are the only specials changed.

\def\astyped{\trivlist \item[]\if@minipage\else\vskip\parskip\fi
\leftskip\@totalleftmargin\rightskip\z@
\parindent\z@\parfillskip\@flushglue\parskip\z@
\@tempswafalse \def\par{\if@tempswa\hbox{}\fi\@tempswatrue\@@par}
\obeylines \tt \catcode``=13 \@noligs \let\do\@makeother \do\ \do\^^K\do\^^A
 \frenchspacing\@vobeyspaces}

\let\endastyped=\endtrivlist

% Used inside astyped environments for normal formatting of a line.
% I wish I could give space its normal catcode within \notastyped.
\def\notastyped#1{\mbox{\rm #1}}

SHAR_EOF
fi # end of overwriting check
if test -f 'schemeTeX.l'
then
	echo shar: will not over-write existing file "'schemeTeX.l'"
else
cat << \SHAR_EOF > 'schemeTeX.l'
%{
/* schemeTeX -- Scheme to TeX.  John D. Ramsdell.
 * Simple support for literate programming in Scheme.
 * Usage:   schemeTeX < {Scheme TeX file} > {TeX file}
 */

#if !defined lint
static char ID[] = "@(#)schemeTeX.l	1.3	88/06/30";
static char copyright[] = "Copyright 1988 by The MITRE Corporation."; 
/* Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies.  The
MITRE Corporation makes no representations about the suitability of
this software for any purpose.  It is provided "as is" without express
or implied warranty. */
#endif

/* SchemeTeX defines a new source file format in which source lines
are divided into text and code.  Lines of code start with a line
beginning with '(', and continue until the line that contains the
matching ')'.  The text lines remain, and they are treated as
comments.  If the first character of a text line is ';', it is
stripped from the output.  This is provided for those who want to use
an unmodified version of their Scheme system's LOAD.  When producing a
document, both the text lines and the code lines are copied into the
document source file, but the code lines are surrounded by a pair of
formatting commands, as is comments beginning with ';' within code
lines.  SchemeTeX is currently set up for use with LaTeX. */

/* Define STRIP if you want to remove all comments in a Scheme TeX
file. */

/* Modify the following for use with something other than LaTeX. 
Also see tex_verbatim_echo.  */
#define BEGIN_COMMENT	"\\notastyped{"
#define BEGIN_CODE	"\\begin{astyped}"
#define END_CODE	"\\end{astyped}"
#define TEX_ECHO	tex_verbatim_echo(yytext, stdout)
/* Lex is used for identifying code in an Scheme TeX file. */
int parens;			/* Used to balance parenthesis. */

/* All input occurs in the following routines so that TAB characters
can be expanded. TeX treats TAB characters as a space--not what is
wanted. */
#undef getc()
#define getc(STREAM) expanding_getc(STREAM)
int spaces = 0;			/* Spaces left to print a TAB. */
int column = 0;			/* Current input column. */
int expanding_getc(stream)
  FILE *stream;
{
  int c;
  if (spaces > 0) {
    spaces--;
    return ' ';
  }
  switch (c = fgetc(stream)) {
  case '\t':
    spaces = 8 - (7&column);
    column += spaces;
    return expanding_getc(stream);
  case '\n':
    column = 0;
    return c;
  default:
    column++;
    return c;
  }
}
%}
%%
#\\\(		{
#if defined STRIP		   
		  ECHO;
#else
		  TEX_ECHO;
#endif
		}
#\\\)		{
#if defined STRIP		   
		  ECHO;
#else
		  TEX_ECHO;
#endif
		}
\(		{ ECHO; parens++; }
\)		{ ECHO; parens--;
		  if (parens == 0) { /* End of code. */
		    char c;	/* Check that nothing follows. */
		    while ((c = input()) == ' ') output(c);
		    if (c == '\000') return 0; /* EOF */
		    if (c != '\n' && c != ';') return -1;
		    unput(c);
		  }
		}
\"[^"]*\"	{
		  if ((yyleng > 1) && (yytext[yyleng-2] == '\\'))
		    yymore();
		  else 
#if defined STRIP
		    ECHO;
#else
		    TEX_ECHO;
#endif
		}
;[^\n]*$	{
#if defined STRIP
                  ;
#else
                  fputs(BEGIN_COMMENT, stdout);
                  ECHO;
                  fputs("}", stdout);
#endif
		}
\n		{ ECHO; if (parens <= 0) return 0; }
.		{
#if defined STRIP		   
		  ECHO;
#else
		  TEX_ECHO;
#endif
		}
%%

fatal (s)
      char *s;
{
  fprintf(stderr, "On line %d, %s\n", yylineno, s);
  exit(1);
}

tex_verbatim_echo (s, f)
      char *s; FILE *f;
{
  for (; *s != '\000'; s++) 
    switch (*s) {
    case '\\': 
    case  '{': 
    case  '}': 
    case  '$': 
    case  '&': 
    case  '#': 
    case  '^': 
    case  '_': 
    case  '%': 
    case  '~': 
      fputs("\\verb-", f);
      putc(*s, f);
      putc('-', f);
      break;
    default: putc(*s, f);
    }
}

main()
{
  char c;
  do {				/* TeX mode and saw newline */
    c = input();
    if (c == '(') {		/* TeX mode changed to code mode. */
      unput(c);
#if !defined STRIP
      fputs(BEGIN_CODE,stdout); putc('\n', stdout);
#endif
      do {			/* Copy out code using yylex. */
	parens = 0;
	if (0 != yylex()) fatal("Bad code section.");
	if (parens != 0) fatal("Premature EOF.");
	c = input();
	unput(c);		/* Repeat when there is code */
      } while (c == '(');	/* immediately after copied code. */
#if !defined STRIP
      fputs(END_CODE, stdout); putc('\n', stdout);
#endif
    }
    else {			/* Found a text line. */
      if (c == ';') c = input(); /* For those who want to use bare load. */
      while (c != '\n') {
	if (c == '\000') exit(0);	/* EOF. */
#if !defined STRIP
	output(c);
#endif
	c = input();
      }
#if !defined STRIP
      output(c);
#endif
    }
  } while (1);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'st.sh'
then
	echo shar: will not over-write existing file "'st.sh'"
else
cat << \SHAR_EOF > 'st.sh'
#! /bin/sh
# schemeTeX @(#)st.sh	1.3 88/06/30
EXT=.st
DIR=`dirname $1`
BASE=`basename $1 ${EXT}`

case $# in
0) schemeTeX ;;
1) schemeTeX < ${DIR}/${BASE}${EXT} > ${DIR}/${BASE}.tex ;;
2) schemeTeX < $1 > $2 ;;
*) echo "usage: $0 file-name"; exit 1;;
esac

SHAR_EOF
fi # end of overwriting check
if test -f 'st.scm'
then
	echo shar: will not over-write existing file "'st.scm'"
else
cat << \SHAR_EOF > 'st.scm'
;;; @(#)st.scm	1.2 89/10/27
;;; SchemeTeX --- Simple support for literate programming in Scheme.
;;; October 1989, John D. Ramsdell.
;;;
;;; Copyright 1989 by The MITRE Corporation.
;;; Permission to use, copy, modify, and distribute this
;;; software and its documentation for any purpose and without
;;; fee is hereby granted, provided that the above copyright
;;; notice appear in all copies.  The MITRE Corporation
;;; makes no representations about the suitability of this
;;; software for any purpose.  It is provided "as is" without
;;; express or implied warranty.
;;;
;;; SchemeTeX
;;; defines a new source file format in which source lines are divided
;;; into text and code.  Lines of code start with a line beginning with
;;; '(', and continue until the line that contains the matching ')'.  The
;;; text lines remain, and they are treated as comments.  When producing
;;; a document, both the text lines and the code lines are copied into
;;; the document source file, but the code lines are surrounded by a pair
;;; of formatting commands.  The formatting commands are in begin-code
;;; and end-code.  SchemeTeX is currently set up for use with LaTeX.
;;;
;;; Exports: tangle and weave.
;;; (tangle st-file scheme-file)  Makes scheme file from schemeTeX source.
;;; (weave st-file tex-file)      Makes LaTeX file from schemeTeX source.

(define (tangle st-filename scheme-filename) ; => scheme-filename or false.
  (if (call-with-input-file st-filename
        (lambda (st-port)
          (call-with-output-file scheme-filename
            (lambda (scheme-port)
              (tangle-port st-port scheme-port)))))
      scheme-filename
      (begin                            ; Put a call to error here.
       (display "tangle failed.") (newline)
       '#f)))

(define (weave st-filename tex-filename) ; => tex-filename or false.
  (if (call-with-input-file st-filename
        (lambda (st-port)
          (call-with-output-file tex-filename
            (lambda (tex-port)
              (weave-port st-port tex-port)))))
      tex-filename
      (begin                            ; Put a call to error here.
       (display "weave failed.") (newline)
       '#f)))

(define (tangle-port st-port scheme-port) ; => false on failure.
  (letrec
      ((tex-mode-and-saw-newline        ; Decide if input is code
        (lambda ()
          (let ((ch (peek-char st-port))) ; or tex source.
            (cond ((eof-object? ch) '#t)
                  ((char=? ch #\()
                   (scheme-mode))
                  (else (tex-mode-within-a-line))))))
       (tex-mode-within-a-line          ; Strip comments.
        (lambda ()
          (let ((ch (read-char st-port)))
            (cond ((eof-object? ch) '#t)
                  ((char=? ch #\newline)
                   (tex-mode-and-saw-newline))
                  (else (tex-mode-within-a-line))))))
       (scheme-mode                     ; This routine should use
        (lambda ()
          (write (read st-port) scheme-port)
          (newline scheme-port)         ; read-refusing-eof if
          (tex-mode-within-a-line))))   ; available.
    (tex-mode-and-saw-newline)))

(define begin-code "\\begin{astyped}")  ; TeX code surrounding 
(define end-code "\\end{astyped}")      ; code and comments
(define begin-comment "\\notastyped{")  ; within code.
              
(define (weave-port st-port tex-port)
  (let ((spaces 0)                      ; Used in get-char and get-line during
        (hpos 0)                        ; the expansion of tabs into spaces.
        (ch-buf '#f))                   ; One char buffer.
    (letrec                             
        ((get-char
          (lambda ()                    ; Get-char expands tabs into spaces,
            (cond (ch-buf               ; and implements a one character
                   (let ((ch ch-buf))   ; buffer.
                     (set! ch-buf '#f)
                     ch))
                  ((> spaces 0)
                   (set! spaces (- spaces 1))
                   #\space)
                  (else
                   (let ((ch (read-char st-port)))
                     (cond ((eof-object? ch) ch)
                           ((char=? ch #\tab) ; Expand tabs here.
                            (set! spaces (- 8 (modulo hpos 8)))
                            (set! hpos (+ hpos spaces))
                            (get-char))
                           ((char=? ch #\newline)
                            (set! hpos 0)
                            ch)
                           (else
                            (set! hpos (+ hpos 1))
                            ch)))))))
         (unget-char
          (lambda (ch)
            (set! ch-buf ch)))
         (copy-line-saw-eof
          (lambda ()
            (let ((ch (get-char)))
              (cond ((eof-object? ch) '#t)
                    ((char=? ch #\newline) '#f)
                    (else
                     (write-char ch tex-port)
                     (copy-line-saw-eof))))))
         (tex-write-char
          (lambda (ch)                  ; Write to TeX file
            (if (or (char=? ch #\\)     ; escaping TeX's special
                    (char=? ch #\{)     ; characters.
                    (char=? ch #\})
                    (char=? ch #\$)
                    (char=? ch #\&)
                    (char=? ch #\#)
                    (char=? ch #\^)
                    (char=? ch #\_)
                    (char=? ch #\%)
                    (char=? ch #\~))
                (begin
                  (display "\\verb-" tex-port)
                  (write-char ch tex-port)
                  (write-char #\- tex-port))
                (write-char ch tex-port))))

         ;; TeX mode
         (tex-mode-and-saw-newline      ; State at which it is 
          (lambda ()                    ; decided whether to go 
            (let ((ch (get-char)))      ; into Scheme code mode
              (cond ((eof-object? ch) '#t) ; or stay in TeX mode.
                    ((char=? ch #\() (scheme-mode))
                    (else       
                     ;; Strip leading semicolon for those who
                     ;; want to use regular load.
                     (if (not (char=? ch #\;))
                         (write-char ch tex-port))
                     (if (char=? ch #\newline)
                         (tex-mode-and-saw-newline)
                         (tex-mode-within-a-line)))))))
         (tex-mode-within-a-line        ; Copy out TeX line.
          (lambda ()
            (let ((saw-eof (copy-line-saw-eof)))
              (newline tex-port)
              (or saw-eof (tex-mode-and-saw-newline)))))

         ;; Scheme mode
         (scheme-mode                   ; Change from TeX mode 
          (lambda ()                    ; to scheme code mode.
            (display begin-code tex-port)
            (newline tex-port)
            (write-char #\( tex-port)
            (sexpr 1)))
         (sexpr                         ; parens is used to watch
          (lambda (parens)              ; for the closing paren
            (let ((ch (get-char)))      ; used to detect the end
              (cond ((eof-object? ch) '#f) ; of scheme code mode.
                    ((char=? ch #\;)
                     (copy-comment-within-sexpr parens))
                    (else       
                     (sexpr-write-char parens ch))))))
         (copy-comment-within-sexpr
          (lambda (parens)              ; Handle comment.
            (display begin-comment tex-port)
            (write-char #\; tex-port)
            (let ((saw-eof (copy-line-saw-eof)))
              (write-char #\} tex-port)
              (newline tex-port)
              (and (not saw-eof) (sexpr parens)))))
         (sexpr-write-char
          (lambda (parens ch)           ; Write a char and
            (tex-write-char ch)         ; figure out what to
            (cond ((char=? ch #\()      ; do next.
                   (sexpr (+ parens 1)))
                  ((char=? ch #\))
                   (if (= 1 parens)     ; Done reading sexpr.
                       (scheme-mode-after-sexpr)
                       (sexpr (- parens 1))))
                  ((char=? ch #\")
                   (copy-out-string parens))
                  ((char=? ch #\#)      ; Worrying about #\( and #\).
                   (maybe-char-syntax parens))
                  (else (sexpr parens)))))
         (copy-out-string
          (lambda (parens)
            (let ((ch (get-char)))
              (and (not (eof-object? ch))
                   (begin
                     (tex-write-char ch)
                     (cond ((char=? ch #\\)
                            (let ((ch (get-char)))
                              (and (not (eof-object? ch))
                                   (begin
                                     (tex-write-char ch)
                                     (copy-out-string parens)))))
                           ((char=? ch #\")
                            (sexpr parens))
                           (else (copy-out-string parens))))))))
         (maybe-char-syntax             ; What out for
          (lambda (parens)              ; #\( and #\).
            (let ((ch (get-char)))
              (cond ((eof-object? ch) '#f)
                    ((char=? ch #\\)
                     (tex-write-char ch)
                     (let ((ch (get-char)))
                       (and (not (eof-object? ch))
                            (begin
                              (tex-write-char ch)
                              (sexpr parens)))))
                    (else
                     (unget-char st-port)
                     (sexpr parens))))))
         (scheme-mode-after-sexpr
          (lambda ()
            (let ((ch (get-char)))
              (cond ((eof-object? ch) '#t)
                    ((char=? ch #\;)
                     (copy-comment-after-sexpr))
                    ((char=? ch #\newline)
                     (newline tex-port)
                     (scheme-mode-merge))
                    ((char=? ch #\space)
                     (tex-write-char ch)
                     (scheme-mode-after-sexpr))
                    (else '#f)))))      ; Call to error should go here.
         (copy-comment-after-sexpr
          (lambda ()                    ; Handle trailing comment.
            (display begin-comment tex-port)
            (write-char #\; tex-port)
            (let ((saw-eof (copy-line-saw-eof)))
              (write-char #\} tex-port)
              (newline tex-port)
              (and (not saw-eof) (scheme-mode-merge)))))
         (scheme-mode-merge             ; Don't change mode if next
          (lambda ()                    ; line is code.
            (let ((ch (get-char)))
              (cond ((eof-object? ch) '#t)
                    ((char=? ch #\()    ; Stay in scheme mode.
                     (write-char ch tex-port)
                     (sexpr 1))
                    (else               ; Enter tex mode.
                     (display end-code tex-port)
                     (newline tex-port)
                     (write-char ch tex-port)
                     (if (char=? ch #\newline)
                         (tex-mode-and-saw-newline)
                         (tex-mode-within-a-line))))))))
      (tex-mode-and-saw-newline))))
SHAR_EOF
fi # end of overwriting check
if test -f 'st.tex'
then
	echo shar: will not over-write existing file "'st.tex'"
else
cat << \SHAR_EOF > 'st.tex'
\documentstyle[proc]{article}
% @(#)st.tex	1.4 89/10/25
\title{Scheme\TeX{}}
\author{John D. Ramsdell}
\date{
89/10/25
}

\begin{document}

\maketitle

Scheme\TeX{} provides simple support for literate programming in any
dialect of Lisp.  Originally created for use with Scheme, it defines a
new source file format which may be used to produce \LaTeX{} input or
Lisp code.

Scheme\TeX{} source lines are divided into text and code.  Lines of code
start with a line beginning with ``('', and continue until the line
containing the matching ``)''.  The remaining lines are text lines,
and they are treated as comments.

When producing a \LaTeX{} document, both the text lines and the code
lines are copied into the document source file, but the code lines are
surrounded by a pair of formatting commands (\verb-\begin{astyped}-
and \verb-\end{astyped}-).  This \LaTeX{} environment formats the code
as written, in typewriter font.  A Lisp comment within a code line is
formatted in an \verb-\mbox- in Roman font.  A Scheme\TeX{} style
command should include the \verb-astyped- style option, so that the
\verb-astyped- environment is available.  An example:
\begin{center}
\verb-\documentstyle[astyped]{article}-
\end{center}

Scheme\TeX{} was designed under the constraint that code lines must be
unmodified Lisp code, and text lines must be unmodified \LaTeX{} code.
Text editors with support for Lisp and \LaTeX{}, such as Emacs, may be
used for Scheme\TeX{} code much as they are used for Lisp code and
\LaTeX{} code.

For those who prefer not to modify the reader used by their Lisp
system's loader and compiler, the rule that text lines must be
unmodified \LaTeX{} code has been relaxed.  Text lines that begin with
``;'' are copied without the initial ``;''.

\section*{Usage in Scheme}
The file \verb;st.scm; contains programs used to obtain code or
\LaTeX{} from a Scheme\TeX{} source file.  The Scheme expression
\begin{center}
\verb;(TANGLE; {\it st-filespec Scheme-filespec\/}{\tt )}
\end{center}
creates Scheme source from a Scheme\TeX{} file, and the expression
\begin{center}
\verb;(WEAVE; {\it st-filespec \LaTeX{}-filespec\/}{\tt )}
\end{center}
creates LaTeX{} source.

The file \verb-reader.st- contains a Scheme\TeX{} reader in R$^4$R Scheme.
Use that reader with your Scheme system's loader and compiler to
avoid running \verb-TANGLE- and creating a temporary file.

\section*{Usage in a Unix shell}
The extension for Scheme\TeX{} files is ``\verb;.st;''.  
A \LaTeX{} file is produced from Scheme\TeX{} source
using the Unix shell command 
\begin{center}
{\tt st} {\it file-name}
\end{center}
It will produce a file with the ``\verb;.tex;'' extension.  The
obvious make file is in Figure~\ref{makefile}.
\begin{figure}
\begin{verbatim}
.SUFFIXES:      .dvi .tex .st

.st.dvi:
        make $*.tex && make $*.dvi

.st.tex:
        st $*

.tex.dvi:       
        latex $*
\end{verbatim}
\caption{A Scheme\TeX{} Makefile}\label{makefile}
\end{figure}
\end{document}
SHAR_EOF
fi # end of overwriting check
if test -f 'reader.st'
then
	echo shar: will not over-write existing file "'reader.st'"
else
cat << \SHAR_EOF > 'reader.st'
\documentstyle[astyped]{article}
% @(#)reader.st	1.4 89/10/25
\title{{\tt read-st}}
\author{John D. Ramsdell}
\date{
89/10/25
}

\begin{document}

\maketitle

\verb;read-st; converts Scheme\TeX{} representations of Scheme objects
into the objects themselves much as \verb;read; does.  
(define (read-st . rest)		; Returns what \verb;read; returns.
  (let ((port (if (pair? rest)		; \verb;read-st; arguments are
		  (car rest)		; the same as \verb;read;'s.
		  (current-input-port))))
    (letrec				
	((text-mode-and-saw-newline	; Lines of a Scheme\TeX{} file
	  (lambda ()			; beginning with ``{\tt(}'', 
	    (let ((ch (peek-char port))) ; start a code section.
	      (cond ((eof-object? ch) ch)
		    ((char=? ch #\()	; If code section, then use
		     (got-code (read port))) ; \verb;read; to get code,
		    (else		; else skip this line as it
		     (text-mode-within-a-line)))))) ; is a comment.
	 (text-mode-within-a-line
	  (lambda ()			; Ignore comments.
	    (let ((ch (read-char port)))
	      (cond ((eof-object? ch) ch)
		    ((char=? ch #\newline)
		     (text-mode-and-saw-newline))
		    (else (text-mode-within-a-line))))))
	 (got-code
	  (lambda (code)		; Ignore the remainder of the 
	    (let ((ch (read-char port))) ; last code line and return
	      (cond ((eof-object? ch) code) ;  the results of \verb;read;.
		    ((char=? ch #\newline)
		     code)
		    (else (got-code code)))))))
    (text-mode-and-saw-newline)		; Start by looking 
    )))					; for a code line.
\end{document}

SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0