#! /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
#	sweb.c
#	sweb.scm
#	sweb.tex
#	reader.sw
# This archive created: Tue Jul 17 07:30:21 1990
export PATH; PATH=/bin:$PATH
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
cat << \SHAR_EOF > 'README'
SchemeWEB---Simple support for literate programming in Lisp.

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

Installation:

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

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

3) The command "make install" installs SchemeWEB.

4) If you plan to modify your Lisp system's standard LOAD, follow the
model given in "reader.sw", a reader of SchemeWEB source for the R4RS
dialect of Scheme.

$Header: README,v 1.1 90/07/12 08:57:33 ramsdell Exp $
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'
# SchemeWEB Makefile 
# $Header: Makefile,v 1.1 90/07/12 08:57:32 ramsdell Exp $

CFLAGS		= -O

SRCS		= README Makefile astyped.sty sweb.c \
		  sweb.scm sweb.tex reader.sw

CMDS		= sweave stangle

DOCS		= sweb.dvi reader.dvi

TEXSTY		= astyped.sty

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

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

# Generic rules
.SUFFIXES:	.dvi .tex .scm .sw

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

.sw.tex:
	sweave $*.sw $*.tex

.tex.dvi:
	latex $*

.sw.scm:
	stangle $*.sw $*.scm

# Generic commands.

all:	$(CMDS)

doc:	$(DOCS) $(CMDS)

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

clean:
	-rm $(CMDS)

dist:	schemeweb.sh

# Specific commands.

sweave:	sweb.c
	$(CC) $(CFLAGS) -o $@ $?

stangle:	sweb.c
	$(CC) -DTANGLE $(CFLAGS) -o $@ $?

schemeweb.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'
%%%% $Header: astyped.sty,v 1.1 90/07/12 08:57:35 ramsdell Exp $ %%%%
%
% ASTYPED DOCUMENT-STYLE OPTION
%    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 'sweb.c'
then
	echo shar: will not over-write existing file "'sweb.c'"
else
cat << \SHAR_EOF > 'sweb.c'
/* SchemeWEB -- WEB for Scheme.  John D. Ramsdell.
 * Simple support for literate programming in Scheme.
 * This file generates both a Scheme weave program and
 * a Scheme tangle program depending on if TANGLE is defined.
 */

#if !defined lint
static char ID[] = "$Header: sweb.c,v 1.2 90/07/17 07:25:01 ramsdell Exp $";
static char copyright[] = "Copyright 1990 by The MITRE Corporation.";
#endif
/*
 * Copyright 1990 by The MITRE Corporation
 *
 * 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 1, 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.
 * 
 * For a copy of the GNU General Public License, write to the 
 * Free Software Foundation, Inc., 675 Mass Ave, 
 * Cambridge, MA 02139, USA.
 */

/* SchemeWEB 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.  SchemeWEB is currently set up for use with LaTeX. */

/* Define TANGLE to make a program which translates SchemeWEB source
into Scheme source. */

/* Define SAVE_LEADING_SEMICOLON if you want text lines to be copied 
with any leading semicolon. */

#include <stdio.h>

typedef enum {FALSE, TRUE} bool;

#define putstring(s) (fputs(s, stdout))

#if defined TANGLE
#define sweb_putchar(c) (putchar(c))
#else
/* Modify the following for use with something other than LaTeX. */
#define BEGIN_COMMENT	"\\notastyped{"
#define BEGIN_CODE	"\\begin{astyped}"
#define END_CODE	"\\end{astyped}"
void sweb_putchar (c)
      int c;
{				/* Raps \verb around characters */
  switch (c) {			/* which LaTeX handles specially. */
  case '\\': 
  case  '{': 
  case  '}': 
  case  '$': 
  case  '&': 
  case  '#': 
  case  '^': 
  case  '_': 
  case  '%': 
  case  '~': 
    putstring("\\verb-");
    putchar(c);
    putchar('-');
    break;
  default: putchar(c);
  }
}
#endif

/* Error message for end of file found in code. */
bool report_eof_in_code()
{
  fprintf(stderr, "End of file within a code section.\n");
  return TRUE;
}

/* 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. */
int ch_buf;
bool buf_used = FALSE;
int lineno = 1;

#undef getchar()
int getchar()
{
  int c;
  static int spaces = 0;	/* Spaces left to print a TAB. */
  static int column = 0;	/* Current input column. */
  if (buf_used) {
    buf_used = FALSE;
    return ch_buf;
  }
  if (spaces > 0) {
    spaces--;
    return ' ';
  }
  switch (c = getc(stdin)) {
  case '\t':
    spaces = 7 - (7&column);	/* Maybe this should be 7&(~column). */
    column += spaces + 1;
    return ' ';
  case '\n':
    lineno++;
    column = 0;
    return c;
  default:
    column++;
    return c;
  }
}

void ungetchar(c)
     int c;
{
  buf_used = TRUE;
  ch_buf = c;
}

bool copy_text_saw_eof()
{
  int c;
  while (1) {
    c = getchar();
    if (c == EOF) return TRUE;
    if (c == '\n') return FALSE;
#if !defined TANGLE    
    putchar(c);
#endif
  }
}

bool copy_comment_saw_eof()	/* This copies comments */
{				/* within code sections. */
#if !defined TANGLE  
  putstring(BEGIN_COMMENT);
  putchar(';');
#endif  
  if (copy_text_saw_eof()) return TRUE;
#if !defined TANGLE  
  putchar('}');
#endif  
  putchar('\n');
  return FALSE;
}

bool after_sexpr_failed()	/* Copies comments in a code */
{				/* section that follow a */
  int c;			/* complete S-expr. */
  while (1)			/* It fails when there is */
    switch (c = getchar()) {	/* something other than */ 
    case EOF:			/* white space or a comment, */
      return report_eof_in_code(); /* such as an extra ')'. */
    case ';': 
#if !defined TANGLE  
      putstring(BEGIN_COMMENT);
      putchar(c);
#endif  
      if (copy_text_saw_eof()) return report_eof_in_code();
#if !defined TANGLE  
      putchar('}');
#endif  
      putchar('\n');
      return FALSE;
    case '\n':
      putchar(c);
      return FALSE;
    case ' ':
#if !defined TANGLE
      putchar(c);
#endif
      break;
    default:
      fprintf(stderr,
	      "Found \"%c\"  after an S-expr finished.\n",
	      c);
      return TRUE;
    }
}

bool copy_string_saw_eof()
{
  int c;
  while (1) {
    c = getchar();
    if (c == EOF) return TRUE;
    sweb_putchar(c);
    switch (c) {
    case '"': return FALSE;
    case '\\':
      c = getchar();
      if (c == EOF) return TRUE;
      sweb_putchar(c);
    }
  }
}

bool maybe_char_syntax_saw_eof()
{				/* Makes sure that the character */
  int c;			/* #\( does not get counted in */
  c = getchar();		/* balancing parentheses. */
  if (c == EOF) return TRUE;
  if (c != '\\') {
    ungetchar(c);
    return FALSE;
  }
  sweb_putchar(c);
  c = getchar();
  if (c == EOF) return TRUE;
  sweb_putchar(c);
  return FALSE;
}

bool copy_code_failed()		/* Copies a code section */
{				/* containing one S-expr. */
  int parens = 1;		/* Used to balance parentheses. */
  int c;
  while (1) {			/* While parens are not balanced, */
    c = getchar();
    if (c == EOF)		/* report failure on EOF and */
      return report_eof_in_code();
    if (c == ';')		/* report failure on EOF in a comment. */
      if (copy_comment_saw_eof()) return report_eof_in_code();
      else continue;
    sweb_putchar(c);		/* Write the character and then see */
    switch (c) {		/* if it requires special handling. */
    case '(':
      parens++;
      break;
    case ')':
      parens--;			
      if (parens == 0)		/* Parentheses balance! */
	return after_sexpr_failed(); /* Report the result of */
      break;			/* post S-expr processing. */
    case '"':			/* Report failure on EOF in a string. */
      if (copy_string_saw_eof()) {
	fprintf(stderr, "End of file found within a string.\n");
	return TRUE;
      }
      break;
    case '#':			/* Report failure on EOF in a character. */
      if (maybe_char_syntax_saw_eof()) return report_eof_in_code();
      break;
    }
  }
}

int filter()
{
  int c;
  while (1) {			/* At loop start it's in text mode */
    c = getchar();		/* and at the begining of a line. */
    if (c == '(') {		/* text mode changed to code mode. */
#if !defined TANGLE
      putstring(BEGIN_CODE); putchar('\n');
#endif
      do {			/* Copy code. */
	putchar(c);
	if (copy_code_failed()) {
	  fprintf(stderr,
		  "Error in the code section containing line %d.\n",
		  lineno);
	  return 1;
	}
	c = getchar();		/* Repeat when there is code */
      } while (c == '(');	/* immediately after some code. */
#if !defined TANGLE
      fputs(END_CODE, stdout); putc('\n', stdout);
#endif
    }
    /* Found a text line--now in text mode. */
#if !defined SAVE_LEADING_SEMICOLON
    if (c == ';') c = getchar();
#endif
    ungetchar(c);
    if (copy_text_saw_eof()) return 0; /* Copy a text line. */
#if !defined TANGLE
    putchar('\n');
#endif
  }
}

int main (argc, argv)		/* For machines which do not */
     int argc;			/* support argc and argv, */
     char *argv[];		/* just change main. */
{
  switch (argc) {
  case 3:
    if (NULL == freopen(argv[2], "w", stdout)) {
      fprintf(stderr, "Cannot open %s for writing.\n", argv[2]);
      break;
    }
  case 2:
    if (NULL == freopen(argv[1], "r", stdin)) {
      fprintf(stderr, "Cannot open %s for reading.\n", argv[1]);
      break;
    }
  case 1:
    return filter();
  }
  fprintf(stderr, 
#if defined TANGLE
	  "Usage: %s [SchemeWEB file] [Scheme file]\n",
#else
	  "Usage: %s [SchemeWEB file] [LaTeX file]\n", 
#endif
	  argv[0]);
  return 1;
}
SHAR_EOF
fi # end of overwriting check
if test -f 'sweb.scm'
then
	echo shar: will not over-write existing file "'sweb.scm'"
else
cat << \SHAR_EOF > 'sweb.scm'
;;; SchemeWEB --- Simple support for literate programming in Scheme.
;;; $Header: sweb.scm,v 1.1 90/07/12 08:57:38 ramsdell Exp $
;;; John D. Ramsdell.
;;;
;;; Copyright 1990 by The MITRE Corporation
;;;
;;; 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 1, 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.
;;; 
;;; For a copy of the GNU General Public License, write to the 
;;; Free Software Foundation, Inc., 675 Mass Ave, 
;;; Cambridge, MA 02139, USA.
;;;
;;; SchemeWEB
;;; 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.  SchemeWEB is currently set up for use with LaTeX.
;;;
;;; Exports: tangle and weave.
;;; (tangle sw-file scheme-file)  Makes scheme file from SchemeWEB source.
;;; (weave sw-file tex-file)      Makes LaTeX file from SchemeWEB source.

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

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

(define (tangle-port sw-port scheme-port) ; => false on failure.
  (letrec
      ((tex-mode-and-saw-newline        ; Decide if input is code
        (lambda ()
          (let ((ch (peek-char sw-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 sw-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 sw-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 sw-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 sw-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 ch)
                     (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 'sweb.tex'
then
	echo shar: will not over-write existing file "'sweb.tex'"
else
cat << \SHAR_EOF > 'sweb.tex'
\documentstyle[proc]{article}
% $Header: sweb.tex,v 1.1 90/07/12 11:38:57 ramsdell Exp $
\title{Scheme\WEB{}}
\author{John D. Ramsdell}
\date{\verb$Date: 90/07/12 11:38:57 $}

\newcommand{\WEB}{{\tt WEB}}

\begin{document}

\maketitle

Scheme\WEB{} 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\WEB{} 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\WEB{} style
command should include the \verb-astyped- style option, so that the
\verb-astyped- environment is available.  An example:
\begin{quote}
\verb-\documentstyle[astyped]{article}-
\end{quote}

Scheme\WEB{} 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\WEB{} 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;sweb.scm; contains programs used to obtain code or
\LaTeX{} from a Scheme\WEB{} source file.  The Scheme expression
\begin{quote}\tt
(TANGLE "{\it Scheme\WEB{} file}" "{\it Scheme file}")
\end{quote}
creates Scheme source from a Scheme\WEB{} file, and the expression
\begin{quote}\tt
(WEAVE "{\it Scheme\WEB{} file}" "{\it \LaTeX{} file}")
\end{quote}
creates \LaTeX{} source.

The file \verb-reader.sw- contains a Scheme\WEB{} 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.

\begin{figure}
\begin{verbatim}
.SUFFIXES:      .dvi .tex .scm .sw

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

.sw.tex:
        sweave $*.sw $*.tex

.tex.dvi:       
        latex $*

.sw.scm:
        stangle $*.sw $*.scm
\end{verbatim}
\caption{A Scheme\WEB{} Makefile}\label{makefile}
\end{figure}

\section*{Usage in a Unix shell}
Files are produced from Scheme\WEB{} source
using the Unix shell commands
\begin{quote}\tt
sweave [{\it Scheme\WEB{} file}] [{\it \LaTeX{} file}] \\
stangle [{\it Scheme\WEB{} file}] [{\it Scheme file}]
\end{quote}
The obvious make file is in Figure~\ref{makefile}.
It uses the convention that the extension for Scheme\WEB{} 
files is ``\verb;.sw;.'' 

\end{document}
SHAR_EOF
fi # end of overwriting check
if test -f 'reader.sw'
then
	echo shar: will not over-write existing file "'reader.sw'"
else
cat << \SHAR_EOF > 'reader.sw'
\documentstyle[astyped]{article}
% $Header: reader.sw,v 1.1 90/07/12 08:57:36 ramsdell Exp $
\title{{\tt read-sw}}
\author{John D. Ramsdell}
\date{\verb$Date: 90/07/12 08:57:36 $}

\newcommand{\WEB}{{\tt WEB}}

\begin{document}

\maketitle

\verb;read-sw; converts Scheme\WEB{} representations of Scheme objects
into the objects themselves much as \verb;read; does.  
(define (read-sw . rest)		; Returns what \verb;read; returns.
  (let ((port (if (pair? rest)		; \verb;read-sw; arguments are
		  (car rest)		; the same as \verb;read;'s.
		  (current-input-port))))
    (letrec				
	((text-mode-and-saw-newline	; Lines of a Scheme\WEB{} 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
