home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.unix
- From: ramsdell@linus.mitre.org (John D. Ramsdell)
- Subject: v26i082: schemeweb - simple support for literate programming in Lisp, Part01/01
- Sender: unix-sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: ramsdell@linus.mitre.org (John D. Ramsdell)
- Posting-Number: Volume 26, Issue 82
- Archive-Name: schemeweb/part01
-
- 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.
-
- 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.
-
- John D. Ramsdell
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: MANIFEST Makefile README astyped.sty reader.sw sweb.c
- # sweb.scm sweb.tex
- # Wrapped by vixie@cognition.pa.dec.com on Mon Dec 28 10:04:21 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(362 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X MANIFEST 1 This shipping list
- X Makefile 1
- X README 1
- X astyped.sty 1
- X reader.sw 1
- X sweb.c 1
- X sweb.scm 1
- X sweb.tex 1
- END_OF_FILE
- if test 362 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(859 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X# SchemeWEB Makefile
- X# $Header: Makefile,v 1.1 90/07/12 08:57:32 ramsdell Exp $
- X
- CFLAGS = -O
- X
- SRCS = README Makefile astyped.sty sweb.c \
- X sweb.scm sweb.tex reader.sw
- X
- CMDS = sweave stangle
- X
- DOCS = sweb.dvi reader.dvi
- X
- TEXSTY = astyped.sty
- X
- X#DEST = /usr/local/bin
- DEST = $(HOME)/bin
- X
- X#TEXDEST = /usr/local/lib/tex/inputs
- TEXDEST = $(HOME)/tex/inputs
- X
- X# Generic rules
- X.SUFFIXES: .dvi .tex .scm .sw
- X
- X.sw.dvi:
- X make $*.tex && make $*.dvi
- X
- X.sw.tex:
- X sweave $*.sw $*.tex
- X
- X.tex.dvi:
- X latex $*
- X
- X.sw.scm:
- X stangle $*.sw $*.scm
- X
- X# Generic commands.
- X
- all: $(CMDS)
- X
- doc: $(DOCS) $(CMDS)
- X
- install: $(CMDS) $(TEXSTY)
- X mv $(CMDS) $(DEST)
- X cp $(TEXSTY) $(TEXDEST)
- X
- clean:
- X -rm $(CMDS)
- X
- dist: schemeweb.sh
- X
- X# Specific commands.
- X
- sweave: sweb.c
- X $(CC) $(CFLAGS) -o $@ $?
- X
- stangle: sweb.c
- X $(CC) -DTANGLE $(CFLAGS) -o $@ $?
- X
- schemeweb.sh: $(SRCS)
- X shar $(SRCS) > $@
- END_OF_FILE
- if test 859 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(758 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- SchemeWEB---Simple support for literate programming in Lisp.
- X
- 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.
- X
- Installation:
- X
- X1) Processes the file "sweb.tex" with LaTeX and read that one page
- document.
- X
- X2) Edit "Makefile" to reflect the correct destination of the
- executables(DEST) and the correct destination of the style
- file(TEXDEST).
- X
- X3) The command "make install" installs SchemeWEB.
- X
- X4) 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.
- X
- X$Header: README,v 1.1 90/07/12 08:57:33 ramsdell Exp $
- END_OF_FILE
- if test 758 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'astyped.sty' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'astyped.sty'\"
- else
- echo shar: Extracting \"'astyped.sty'\" \(918 characters\)
- sed "s/^X//" >'astyped.sty' <<'END_OF_FILE'
- X%%%% $Header: astyped.sty,v 1.1 90/07/12 08:57:35 ramsdell Exp $ %%%%
- X%
- X% ASTYPED DOCUMENT-STYLE OPTION
- X% for LaTeX version 2.09
- X% Based on Leslie Lamport's verbatim environment in latex.tex.
- X
- X% Defines the `astyped' environment, which is like the `verbatim'
- X% environment except most of the special characters have their usual meanings.
- X% Space, ^K, and ^A are the only specials changed.
- X
- X\def\astyped{\trivlist \item[]\if@minipage\else\vskip\parskip\fi
- X\leftskip\@totalleftmargin\rightskip\z@
- X\parindent\z@\parfillskip\@flushglue\parskip\z@
- X\@tempswafalse \def\par{\if@tempswa\hbox{}\fi\@tempswatrue\@@par}
- X\obeylines \tt \catcode``=13 \@noligs \let\do\@makeother \do\ \do\^^K\do\^^A
- X \frenchspacing\@vobeyspaces}
- X
- X\let\endastyped=\endtrivlist
- X
- X% Used inside astyped environments for normal formatting of a line.
- X% I wish I could give space its normal catcode within \notastyped.
- X\def\notastyped#1{\mbox{\rm #1}}
- END_OF_FILE
- if test 918 -ne `wc -c <'astyped.sty'`; then
- echo shar: \"'astyped.sty'\" unpacked with wrong size!
- fi
- # end of 'astyped.sty'
- fi
- if test -f 'reader.sw' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'reader.sw'\"
- else
- echo shar: Extracting \"'reader.sw'\" \(1591 characters\)
- sed "s/^X//" >'reader.sw' <<'END_OF_FILE'
- X\documentstyle[astyped]{article}
- X% $Header: reader.sw,v 1.1 90/07/12 08:57:36 ramsdell Exp $
- X\title{{\tt read-sw}}
- X\author{John D. Ramsdell}
- X\date{\verb$Date: 90/07/12 08:57:36 $}
- X
- X\newcommand{\WEB}{{\tt WEB}}
- X
- X\begin{document}
- X
- X\maketitle
- X
- X\verb;read-sw; converts Scheme\WEB{} representations of Scheme objects
- into the objects themselves much as \verb;read; does.
- X(define (read-sw . rest) ; Returns what \verb;read; returns.
- X (let ((port (if (pair? rest) ; \verb;read-sw; arguments are
- X (car rest) ; the same as \verb;read;'s.
- X (current-input-port))))
- X (letrec
- X ((text-mode-and-saw-newline ; Lines of a Scheme\WEB{} file
- X (lambda () ; beginning with ``{\tt(}'',
- X (let ((ch (peek-char port))) ; start a code section.
- X (cond ((eof-object? ch) ch)
- X ((char=? ch #\() ; If code section, then use
- X (got-code (read port))) ; \verb;read; to get code,
- X (else ; else skip this line as it
- X (text-mode-within-a-line)))))) ; is a comment.
- X (text-mode-within-a-line
- X (lambda () ; Ignore comments.
- X (let ((ch (read-char port)))
- X (cond ((eof-object? ch) ch)
- X ((char=? ch #\newline)
- X (text-mode-and-saw-newline))
- X (else (text-mode-within-a-line))))))
- X (got-code
- X (lambda (code) ; Ignore the remainder of the
- X (let ((ch (read-char port))) ; last code line and return
- X (cond ((eof-object? ch) code) ; the results of \verb;read;.
- X ((char=? ch #\newline)
- X code)
- X (else (got-code code)))))))
- X (text-mode-and-saw-newline) ; Start by looking
- X ))) ; for a code line.
- X\end{document}
- END_OF_FILE
- if test 1591 -ne `wc -c <'reader.sw'`; then
- echo shar: \"'reader.sw'\" unpacked with wrong size!
- fi
- # end of 'reader.sw'
- fi
- if test -f 'sweb.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sweb.c'\"
- else
- echo shar: Extracting \"'sweb.c'\" \(8301 characters\)
- sed "s/^X//" >'sweb.c' <<'END_OF_FILE'
- X/* SchemeWEB -- WEB for Scheme. John D. Ramsdell.
- X * Simple support for literate programming in Scheme.
- X * This file generates both a Scheme weave program and
- X * a Scheme tangle program depending on if TANGLE is defined.
- X */
- X
- X#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.";
- X#endif
- X/*
- X * Copyright 1990 by The MITRE Corporation
- X *
- X * This program is free software; you can redistribute it and/or modify
- X * it under the terms of the GNU General Public License as published by
- X * the Free Software Foundation; either version 1, or (at your option)
- X * any later version.
- X *
- X * This program is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * For a copy of the GNU General Public License, write to the
- X * Free Software Foundation, Inc., 675 Mass Ave,
- X * Cambridge, MA 02139, USA.
- X */
- X
- X/* 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. */
- X
- X/* Define TANGLE to make a program which translates SchemeWEB source
- into Scheme source. */
- X
- X/* Define SAVE_LEADING_SEMICOLON if you want text lines to be copied
- with any leading semicolon. */
- X
- X#include <stdio.h>
- X
- typedef enum {FALSE, TRUE} bool;
- X
- X#define putstring(s) (fputs(s, stdout))
- X
- X#if defined TANGLE
- X#define sweb_putchar(c) (putchar(c))
- X#else
- X/* Modify the following for use with something other than LaTeX. */
- X#define BEGIN_COMMENT "\\notastyped{"
- X#define BEGIN_CODE "\\begin{astyped}"
- X#define END_CODE "\\end{astyped}"
- void sweb_putchar (c)
- X int c;
- X{ /* Raps \verb around characters */
- X switch (c) { /* which LaTeX handles specially. */
- X case '\\':
- X case '{':
- X case '}':
- X case '$':
- X case '&':
- X case '#':
- X case '^':
- X case '_':
- X case '%':
- X case '~':
- X putstring("\\verb-");
- X putchar(c);
- X putchar('-');
- X break;
- X default: putchar(c);
- X }
- X}
- X#endif
- X
- X/* Error message for end of file found in code. */
- bool report_eof_in_code()
- X{
- X fprintf(stderr, "End of file within a code section.\n");
- X return TRUE;
- X}
- X
- X/* 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;
- X
- X#undef getchar()
- int getchar()
- X{
- X int c;
- X static int spaces = 0; /* Spaces left to print a TAB. */
- X static int column = 0; /* Current input column. */
- X if (buf_used) {
- X buf_used = FALSE;
- X return ch_buf;
- X }
- X if (spaces > 0) {
- X spaces--;
- X return ' ';
- X }
- X switch (c = getc(stdin)) {
- X case '\t':
- X spaces = 7 - (7&column); /* Maybe this should be 7&(~column). */
- X column += spaces + 1;
- X return ' ';
- X case '\n':
- X lineno++;
- X column = 0;
- X return c;
- X default:
- X column++;
- X return c;
- X }
- X}
- X
- void ungetchar(c)
- X int c;
- X{
- X buf_used = TRUE;
- X ch_buf = c;
- X}
- X
- bool copy_text_saw_eof()
- X{
- X int c;
- X while (1) {
- X c = getchar();
- X if (c == EOF) return TRUE;
- X if (c == '\n') return FALSE;
- X#if !defined TANGLE
- X putchar(c);
- X#endif
- X }
- X}
- X
- bool copy_comment_saw_eof() /* This copies comments */
- X{ /* within code sections. */
- X#if !defined TANGLE
- X putstring(BEGIN_COMMENT);
- X putchar(';');
- X#endif
- X if (copy_text_saw_eof()) return TRUE;
- X#if !defined TANGLE
- X putchar('}');
- X#endif
- X putchar('\n');
- X return FALSE;
- X}
- X
- bool after_sexpr_failed() /* Copies comments in a code */
- X{ /* section that follow a */
- X int c; /* complete S-expr. */
- X while (1) /* It fails when there is */
- X switch (c = getchar()) { /* something other than */
- X case EOF: /* white space or a comment, */
- X return report_eof_in_code(); /* such as an extra ')'. */
- X case ';':
- X#if !defined TANGLE
- X putstring(BEGIN_COMMENT);
- X putchar(c);
- X#endif
- X if (copy_text_saw_eof()) return report_eof_in_code();
- X#if !defined TANGLE
- X putchar('}');
- X#endif
- X putchar('\n');
- X return FALSE;
- X case '\n':
- X putchar(c);
- X return FALSE;
- X case ' ':
- X#if !defined TANGLE
- X putchar(c);
- X#endif
- X break;
- X default:
- X fprintf(stderr,
- X "Found \"%c\" after an S-expr finished.\n",
- X c);
- X return TRUE;
- X }
- X}
- X
- bool copy_string_saw_eof()
- X{
- X int c;
- X while (1) {
- X c = getchar();
- X if (c == EOF) return TRUE;
- X sweb_putchar(c);
- X switch (c) {
- X case '"': return FALSE;
- X case '\\':
- X c = getchar();
- X if (c == EOF) return TRUE;
- X sweb_putchar(c);
- X }
- X }
- X}
- X
- bool maybe_char_syntax_saw_eof()
- X{ /* Makes sure that the character */
- X int c; /* #\( does not get counted in */
- X c = getchar(); /* balancing parentheses. */
- X if (c == EOF) return TRUE;
- X if (c != '\\') {
- X ungetchar(c);
- X return FALSE;
- X }
- X sweb_putchar(c);
- X c = getchar();
- X if (c == EOF) return TRUE;
- X sweb_putchar(c);
- X return FALSE;
- X}
- X
- bool copy_code_failed() /* Copies a code section */
- X{ /* containing one S-expr. */
- X int parens = 1; /* Used to balance parentheses. */
- X int c;
- X while (1) { /* While parens are not balanced, */
- X c = getchar();
- X if (c == EOF) /* report failure on EOF and */
- X return report_eof_in_code();
- X if (c == ';') /* report failure on EOF in a comment. */
- X if (copy_comment_saw_eof()) return report_eof_in_code();
- X else continue;
- X sweb_putchar(c); /* Write the character and then see */
- X switch (c) { /* if it requires special handling. */
- X case '(':
- X parens++;
- X break;
- X case ')':
- X parens--;
- X if (parens == 0) /* Parentheses balance! */
- X return after_sexpr_failed(); /* Report the result of */
- X break; /* post S-expr processing. */
- X case '"': /* Report failure on EOF in a string. */
- X if (copy_string_saw_eof()) {
- X fprintf(stderr, "End of file found within a string.\n");
- X return TRUE;
- X }
- X break;
- X case '#': /* Report failure on EOF in a character. */
- X if (maybe_char_syntax_saw_eof()) return report_eof_in_code();
- X break;
- X }
- X }
- X}
- X
- int filter()
- X{
- X int c;
- X while (1) { /* At loop start it's in text mode */
- X c = getchar(); /* and at the begining of a line. */
- X if (c == '(') { /* text mode changed to code mode. */
- X#if !defined TANGLE
- X putstring(BEGIN_CODE); putchar('\n');
- X#endif
- X do { /* Copy code. */
- X putchar(c);
- X if (copy_code_failed()) {
- X fprintf(stderr,
- X "Error in the code section containing line %d.\n",
- X lineno);
- X return 1;
- X }
- X c = getchar(); /* Repeat when there is code */
- X } while (c == '('); /* immediately after some code. */
- X#if !defined TANGLE
- X fputs(END_CODE, stdout); putc('\n', stdout);
- X#endif
- X }
- X /* Found a text line--now in text mode. */
- X#if !defined SAVE_LEADING_SEMICOLON
- X if (c == ';') c = getchar();
- X#endif
- X ungetchar(c);
- X if (copy_text_saw_eof()) return 0; /* Copy a text line. */
- X#if !defined TANGLE
- X putchar('\n');
- X#endif
- X }
- X}
- X
- int main (argc, argv) /* For machines which do not */
- X int argc; /* support argc and argv, */
- X char *argv[]; /* just change main. */
- X{
- X switch (argc) {
- X case 3:
- X if (NULL == freopen(argv[2], "w", stdout)) {
- X fprintf(stderr, "Cannot open %s for writing.\n", argv[2]);
- X break;
- X }
- X case 2:
- X if (NULL == freopen(argv[1], "r", stdin)) {
- X fprintf(stderr, "Cannot open %s for reading.\n", argv[1]);
- X break;
- X }
- X case 1:
- X return filter();
- X }
- X fprintf(stderr,
- X#if defined TANGLE
- X "Usage: %s [SchemeWEB file] [Scheme file]\n",
- X#else
- X "Usage: %s [SchemeWEB file] [LaTeX file]\n",
- X#endif
- X argv[0]);
- X return 1;
- X}
- END_OF_FILE
- if test 8301 -ne `wc -c <'sweb.c'`; then
- echo shar: \"'sweb.c'\" unpacked with wrong size!
- fi
- # end of 'sweb.c'
- fi
- if test -f 'sweb.scm' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sweb.scm'\"
- else
- echo shar: Extracting \"'sweb.scm'\" \(11561 characters\)
- sed "s/^X//" >'sweb.scm' <<'END_OF_FILE'
- X;;; SchemeWEB --- Simple support for literate programming in Scheme.
- X;;; $Header: sweb.scm,v 1.1 90/07/12 08:57:38 ramsdell Exp $
- X;;; John D. Ramsdell.
- X;;;
- X;;; Copyright 1990 by The MITRE Corporation
- X;;;
- X;;; This program is free software; you can redistribute it and/or modify
- X;;; it under the terms of the GNU General Public License as published by
- X;;; the Free Software Foundation; either version 1, or (at your option)
- X;;; any later version.
- X;;;
- X;;; This program is distributed in the hope that it will be useful,
- X;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- X;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X;;; GNU General Public License for more details.
- X;;;
- X;;; For a copy of the GNU General Public License, write to the
- X;;; Free Software Foundation, Inc., 675 Mass Ave,
- X;;; Cambridge, MA 02139, USA.
- X;;;
- X;;; SchemeWEB
- X;;; defines a new source file format in which source lines are divided
- X;;; into text and code. Lines of code start with a line beginning with
- X;;; '(', and continue until the line that contains the matching ')'. The
- X;;; text lines remain, and they are treated as comments. When producing
- X;;; a document, both the text lines and the code lines are copied into
- X;;; the document source file, but the code lines are surrounded by a pair
- X;;; of formatting commands. The formatting commands are in begin-code
- X;;; and end-code. SchemeWEB is currently set up for use with LaTeX.
- X;;;
- X;;; Exports: tangle and weave.
- X;;; (tangle sw-file scheme-file) Makes scheme file from SchemeWEB source.
- X;;; (weave sw-file tex-file) Makes LaTeX file from SchemeWEB source.
- X
- X(define (tangle sw-filename scheme-filename) ; => scheme-filename or false.
- X (if (call-with-input-file sw-filename
- X (lambda (sw-port)
- X (call-with-output-file scheme-filename
- X (lambda (scheme-port)
- X (tangle-port sw-port scheme-port)))))
- X scheme-filename
- X (begin ; Put a call to error here.
- X (display "tangle failed.") (newline)
- X #f)))
- X
- X(define (weave sw-filename tex-filename) ; => tex-filename or false.
- X (if (call-with-input-file sw-filename
- X (lambda (sw-port)
- X (call-with-output-file tex-filename
- X (lambda (tex-port)
- X (weave-port sw-port tex-port)))))
- X tex-filename
- X (begin ; Put a call to error here.
- X (display "weave failed.") (newline)
- X #f)))
- X
- X(define (tangle-port sw-port scheme-port) ; => false on failure.
- X (letrec
- X ((tex-mode-and-saw-newline ; Decide if input is code
- X (lambda ()
- X (let ((ch (peek-char sw-port))) ; or tex source.
- X (cond ((eof-object? ch) #t)
- X ((char=? ch #\()
- X (scheme-mode))
- X (else (tex-mode-within-a-line))))))
- X (tex-mode-within-a-line ; Strip comments.
- X (lambda ()
- X (let ((ch (read-char sw-port)))
- X (cond ((eof-object? ch) #t)
- X ((char=? ch #\newline)
- X (tex-mode-and-saw-newline))
- X (else (tex-mode-within-a-line))))))
- X (scheme-mode ; This routine should use
- X (lambda ()
- X (write (read sw-port) scheme-port)
- X (newline scheme-port) ; read-refusing-eof if
- X (tex-mode-within-a-line)))) ; available.
- X (tex-mode-and-saw-newline)))
- X
- X(define begin-code "\\begin{astyped}") ; TeX code surrounding
- X(define end-code "\\end{astyped}") ; code and comments
- X(define begin-comment "\\notastyped{") ; within code.
- X
- X(define (weave-port sw-port tex-port)
- X (let ((spaces 0) ; Used in get-char and get-line during
- X (hpos 0) ; the expansion of tabs into spaces.
- X (ch-buf #f)) ; One char buffer.
- X (letrec
- X ((get-char
- X (lambda () ; Get-char expands tabs into spaces,
- X (cond (ch-buf ; and implements a one character
- X (let ((ch ch-buf)) ; buffer.
- X (set! ch-buf #f)
- X ch))
- X ((> spaces 0)
- X (set! spaces (- spaces 1))
- X #\space)
- X (else
- X (let ((ch (read-char sw-port)))
- X (cond ((eof-object? ch) ch)
- X ((char=? ch #\tab) ; Expand tabs here.
- X (set! spaces (- 8 (modulo hpos 8)))
- X (set! hpos (+ hpos spaces))
- X (get-char))
- X ((char=? ch #\newline)
- X (set! hpos 0)
- X ch)
- X (else
- X (set! hpos (+ hpos 1))
- X ch)))))))
- X (unget-char
- X (lambda (ch)
- X (set! ch-buf ch)))
- X (copy-line-saw-eof
- X (lambda ()
- X (let ((ch (get-char)))
- X (cond ((eof-object? ch) #t)
- X ((char=? ch #\newline) #f)
- X (else
- X (write-char ch tex-port)
- X (copy-line-saw-eof))))))
- X (tex-write-char
- X (lambda (ch) ; Write to TeX file
- X (if (or (char=? ch #\\) ; escaping TeX's special
- X (char=? ch #\{) ; characters.
- X (char=? ch #\})
- X (char=? ch #\$)
- X (char=? ch #\&)
- X (char=? ch #\#)
- X (char=? ch #\^)
- X (char=? ch #\_)
- X (char=? ch #\%)
- X (char=? ch #\~))
- X (begin
- X (display "\\verb-" tex-port)
- X (write-char ch tex-port)
- X (write-char #\- tex-port))
- X (write-char ch tex-port))))
- X
- X ;; TeX mode
- X (tex-mode-and-saw-newline ; State at which it is
- X (lambda () ; decided whether to go
- X (let ((ch (get-char))) ; into Scheme code mode
- X (cond ((eof-object? ch) #t) ; or stay in TeX mode.
- X ((char=? ch #\() (scheme-mode))
- X (else
- X ;; Strip leading semicolon for those who
- X ;; want to use regular load.
- X (if (not (char=? ch #\;))
- X (write-char ch tex-port))
- X (if (char=? ch #\newline)
- X (tex-mode-and-saw-newline)
- X (tex-mode-within-a-line)))))))
- X (tex-mode-within-a-line ; Copy out TeX line.
- X (lambda ()
- X (let ((saw-eof (copy-line-saw-eof)))
- X (newline tex-port)
- X (or saw-eof (tex-mode-and-saw-newline)))))
- X
- X ;; Scheme mode
- X (scheme-mode ; Change from TeX mode
- X (lambda () ; to scheme code mode.
- X (display begin-code tex-port)
- X (newline tex-port)
- X (write-char #\( tex-port)
- X (sexpr 1)))
- X (sexpr ; parens is used to watch
- X (lambda (parens) ; for the closing paren
- X (let ((ch (get-char))) ; used to detect the end
- X (cond ((eof-object? ch) #f) ; of scheme code mode.
- X ((char=? ch #\;)
- X (copy-comment-within-sexpr parens))
- X (else
- X (sexpr-write-char parens ch))))))
- X (copy-comment-within-sexpr
- X (lambda (parens) ; Handle comment.
- X (display begin-comment tex-port)
- X (write-char #\; tex-port)
- X (let ((saw-eof (copy-line-saw-eof)))
- X (write-char #\} tex-port)
- X (newline tex-port)
- X (and (not saw-eof) (sexpr parens)))))
- X (sexpr-write-char
- X (lambda (parens ch) ; Write a char and
- X (tex-write-char ch) ; figure out what to
- X (cond ((char=? ch #\() ; do next.
- X (sexpr (+ parens 1)))
- X ((char=? ch #\))
- X (if (= 1 parens) ; Done reading sexpr.
- X (scheme-mode-after-sexpr)
- X (sexpr (- parens 1))))
- X ((char=? ch #\")
- X (copy-out-string parens))
- X ((char=? ch #\#) ; Worrying about #\( and #\).
- X (maybe-char-syntax parens))
- X (else (sexpr parens)))))
- X (copy-out-string
- X (lambda (parens)
- X (let ((ch (get-char)))
- X (and (not (eof-object? ch))
- X (begin
- X (tex-write-char ch)
- X (cond ((char=? ch #\\)
- X (let ((ch (get-char)))
- X (and (not (eof-object? ch))
- X (begin
- X (tex-write-char ch)
- X (copy-out-string parens)))))
- X ((char=? ch #\")
- X (sexpr parens))
- X (else (copy-out-string parens))))))))
- X (maybe-char-syntax ; What out for
- X (lambda (parens) ; #\( and #\).
- X (let ((ch (get-char)))
- X (cond ((eof-object? ch) #f)
- X ((char=? ch #\\)
- X (tex-write-char ch)
- X (let ((ch (get-char)))
- X (and (not (eof-object? ch))
- X (begin
- X (tex-write-char ch)
- X (sexpr parens)))))
- X (else
- X (unget-char ch)
- X (sexpr parens))))))
- X (scheme-mode-after-sexpr
- X (lambda ()
- X (let ((ch (get-char)))
- X (cond ((eof-object? ch) #t)
- X ((char=? ch #\;)
- X (copy-comment-after-sexpr))
- X ((char=? ch #\newline)
- X (newline tex-port)
- X (scheme-mode-merge))
- X ((char=? ch #\space)
- X (tex-write-char ch)
- X (scheme-mode-after-sexpr))
- X (else #f))))) ; Call to error should go here.
- X (copy-comment-after-sexpr
- X (lambda () ; Handle trailing comment.
- X (display begin-comment tex-port)
- X (write-char #\; tex-port)
- X (let ((saw-eof (copy-line-saw-eof)))
- X (write-char #\} tex-port)
- X (newline tex-port)
- X (and (not saw-eof) (scheme-mode-merge)))))
- X (scheme-mode-merge ; Don't change mode if next
- X (lambda () ; line is code.
- X (let ((ch (get-char)))
- X (cond ((eof-object? ch) #t)
- X ((char=? ch #\() ; Stay in scheme mode.
- X (write-char ch tex-port)
- X (sexpr 1))
- X (else ; Enter tex mode.
- X (display end-code tex-port)
- X (newline tex-port)
- X (write-char ch tex-port)
- X (if (char=? ch #\newline)
- X (tex-mode-and-saw-newline)
- X (tex-mode-within-a-line))))))))
- X (tex-mode-and-saw-newline))))
- END_OF_FILE
- if test 11561 -ne `wc -c <'sweb.scm'`; then
- echo shar: \"'sweb.scm'\" unpacked with wrong size!
- fi
- # end of 'sweb.scm'
- fi
- if test -f 'sweb.tex' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sweb.tex'\"
- else
- echo shar: Extracting \"'sweb.tex'\" \(3170 characters\)
- sed "s/^X//" >'sweb.tex' <<'END_OF_FILE'
- X\documentstyle[proc]{article}
- X% $Header: sweb.tex,v 1.1 90/07/12 11:38:57 ramsdell Exp $
- X\title{Scheme\WEB{}}
- X\author{John D. Ramsdell}
- X\date{\verb$Date: 90/07/12 11:38:57 $}
- X
- X\newcommand{\WEB}{{\tt WEB}}
- X
- X\begin{document}
- X
- X\maketitle
- X
- 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.
- X
- 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.
- X
- 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
- X\verb-astyped- environment is available. An example:
- X\begin{quote}
- X\verb-\documentstyle[astyped]{article}-
- X\end{quote}
- X
- 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
- X\LaTeX{} code.
- X
- XFor 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
- X``;'' are copied without the initial ``;''.
- X
- X\section*{Usage in Scheme}
- The file \verb;sweb.scm; contains programs used to obtain code or
- X\LaTeX{} from a Scheme\WEB{} source file. The Scheme expression
- X\begin{quote}\tt
- X(TANGLE "{\it Scheme\WEB{} file}" "{\it Scheme file}")
- X\end{quote}
- creates Scheme source from a Scheme\WEB{} file, and the expression
- X\begin{quote}\tt
- X(WEAVE "{\it Scheme\WEB{} file}" "{\it \LaTeX{} file}")
- X\end{quote}
- creates \LaTeX{} source.
- X
- 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.
- X
- X\begin{figure}
- X\begin{verbatim}
- X.SUFFIXES: .dvi .tex .scm .sw
- X
- X.sw.dvi:
- X make $*.tex && make $*.dvi
- X
- X.sw.tex:
- X sweave $*.sw $*.tex
- X
- X.tex.dvi:
- X latex $*
- X
- X.sw.scm:
- X stangle $*.sw $*.scm
- X\end{verbatim}
- X\caption{A Scheme\WEB{} Makefile}\label{makefile}
- X\end{figure}
- X
- X\section*{Usage in a Unix shell}
- XFiles are produced from Scheme\WEB{} source
- using the Unix shell commands
- X\begin{quote}\tt
- sweave [{\it Scheme\WEB{} file}] [{\it \LaTeX{} file}] \\
- stangle [{\it Scheme\WEB{} file}] [{\it Scheme file}]
- X\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;.''
- X
- X\end{document}
- END_OF_FILE
- if test 3170 -ne `wc -c <'sweb.tex'`; then
- echo shar: \"'sweb.tex'\" unpacked with wrong size!
- fi
- # end of 'sweb.tex'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-