18-Apr-88 16:15:34-PDT,23015;000000000000 Return-Path: Received: from mitre-bedford.ARPA by SCORE.STANFORD.EDU with TCP; Mon 18 Apr 88 16:15:02-PDT Posted-From: The MITRE Corp., Bedford, MA Received: by linus.MENET (3.2/4.7) id AA03984; Mon, 18 Apr 88 15:04:06 EDT Date: Mon, 18 Apr 88 15:04:06 EDT From: John D. Ramsdell Posted-Date: Mon, 18 Apr 88 15:04:06 EDT Message-Id: <8804181904.AA03984@linus.MENET> To: texhax@score.stanford.edu Subject: SchemeTeX for bitnet folk. Please replace the version of SchemeTeX I sent earlier today with this version. 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: # st # This archive created: Thu Mar 31 08:17:02 1988 export PATH; PATH=/bin:$PATH if test ! -d 'st' then mkdir 'st' fi cd 'st' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else cat << \SHAR_EOF > 'Makefile' # schemeTeX Makefile @(#)Makefile 1.2 88/03/31. CMDS = st schemeTeX DOCS = st.dvi reader.dvi TEXSTY = astyped.sty DEST = $(HOME)/bin TEXDEST = $(HOME)/sty # 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) # Specific commands. schemeTeX: schemeTeX.l lex -t $? > schemeTeX.c cc -O -o $@ schemeTeX.c -ll rm schemeTeX.c st: st.sh cp $? $@ chmod +x $@ SHAR_EOF fi # end of overwriting check if test -f 'README' then echo shar: will not over-write existing file "'README'" else cat << \SHAR_EOF > 'README' 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 "st.t", a schemeTeX for the T dialect of Scheme. 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.2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ASTYPED DOCUMENT-STYLE OPTION - released 88/03/29 % 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 '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.2 88/03/29 \title{{\tt read-st}} \author{John D. Ramsdell} \date{ 88/03/29 } \begin{document} \maketitle \verb;read-st; converts Scheme\TeX{} representations of Scheme objects into the objects themselves much as \verb;read; does. It uses the non-standard, but generally available routine \verb;peek-char;. (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 ; Lines of a Scheme\TeX{} file (((text-mode-and-saw-newline) ; 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 (text-mode-within-a-line))))) ; it is a comment. ((text-mode-within-a-line) (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 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 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.2 88/03/29"; static char copyright[] = "Copyright 1988 by The MITRE Corporation. All rights reserved."; /* 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.2 88/03/29 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.t' then echo shar: will not over-write existing file "'st.t'" else cat << \SHAR_EOF > 'st.t' (herald st) ; @(#)st.t 1.2 88/03/29 ;;; SchemeTeX --- Simple support for literate programming in Scheme. ;;; February 1988, John D. Ramsdell. ;;; ;;; Copyright 1988 by The MITRE Corporation. All rights reserved. ;;; 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: load-st, compile-st, and TeX-st. ;;; (load-st filespec optional-load-env) Loads Scheme TeX source. ;;; (compile-st filespec) Compiles Scheme TeX source. ;;; (tex-st filespec) Makes LaTeX input. (define st-extension 'st) (define src-extension 't) (define tex-extension 'tex) (define (load-st filespec . options) (let ((t-filename (tangle filespec))) (and t-filename (apply load t-filename options)))) (define (compile-st filespec) (let ((t-filename (tangle filespec))) (and t-filename (compile-file t-filename)))) (define (tex-st st-filespec) (let* ((st-filename (st-filespec->st-filename st-filespec)) (tex-filename (st-filename->filename st-filename tex-extension))) (with-open-streams ((st-port (open st-filename '(in))) (tex-port (open tex-filename '(out)))) (if (weave-port st-port tex-port) 'done 'failed)))) (define (tangle st-filespec) ; => t-filename or false. (let* ((st-filename (st-filespec->st-filename st-filespec)) (t-filename (st-filename->filename st-filename src-extension))) (if (and (file-exists? t-filename) (file-newer? t-filename st-filename)) t-filename ; No need to tangle. (with-open-streams ((st-port (open st-filename '(in))) (t-port (open t-filename '(out)))) (and (tangle-port st-port t-port) t-filename))))) (define (st-filespec->st-filename st-filespec) (->filename (cond ((symbol? st-filespec) (list '() st-filespec st-extension)) ((and (pair? st-filespec) (= (length st-filespec) 2)) (append st-filespec (list st-extension))) (else st-filespec)))) (define (st-filename->filename st-filename default-type) (make-filename (filename-fs st-filename) (filename-dir st-filename) (filename-name st-filename) (if (eq? default-type (filename-type st-filename)) '() default-type) ;;broken? (filename-generation st-filename) )) (define (tangle-port st-port t-port) ; => false on failure. (labels (((tex-mode-and-saw-newline) (let ((ch (read-char st-port))) (cond ((eof? ch) '#t) ((char= ch #\left-paren) (unread-char st-port) (t-mode)) ((char= ch #\newline) (tex-mode-and-saw-newline)) (else (tex-mode-within-a-line))))) ((tex-mode-within-a-line) (if (eof? (read-line st-port)) '#t (tex-mode-and-saw-newline))) ((t-mode) ; This routine should return (print (read-refusing-eof st-port) t-port) (newline t-port) ; #f when read-refusing-eof (tex-mode-within-a-line))) ; obtains an error. (tex-mode-and-saw-newline))) (define begin-code "\\begin{astyped}") (define end-code "\\end{astyped}") (define begin-comment "\\notastyped{") (define (weave-port st-port tex-port) (let ((spaces 0) ; Expansion of tabs into spaces. (hpos 0)) ; Used in get-char and get-line. (catch leave ; Exit with leave when EOF is found. (labels ; All input is read with (((get-char eof-value) ; get-char and get-line. (if (fx> spaces 0) (block (set spaces (fx- spaces 1)) #\space) (let ((ch (read-char st-port))) (cond ((eof? ch) (leave eof-value)) ((char= ch #\tab) (set spaces (fx- 8 (logand 7 hpos))) (set hpos (fx+ hpos spaces)) (get-char eof-value)) ((char= ch #\newline) (set hpos 0) ch) (else (set hpos (fx+ hpos 1)) ch))))) ((get-line eof-value) (set hpos 0) (let ((ch (read-line st-port))) (if (eof? ch) (leave eof-value) ch))) ((tex-write-char 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 #\~)) (format tex-port "\\verb-~a-" ch) (write-char tex-port ch))) ((tex-mode-and-saw-newline) ; State at which decision must (let ((ch (get-char '#t))) ; be made if to go into T code (if (char= ch #\left-paren) ; mode or stay in TeX mode. (t-mode) (block (if (not (char= ch #\semicolon)) ; For those who want (write-char tex-port ch)) ; to use regular load. (if (char= ch #\newline) (tex-mode-and-saw-newline) (tex-mode-within-a-line)))))) ((tex-mode-within-a-line) ; Copy out TeX line. (let ((line (get-line '#t))) (write-line tex-port line) (tex-mode-and-saw-newline))) ((t-mode) ; Change from TeX mode (write-line tex-port begin-code) ; to T code mode. (write-char tex-port #\() (sexpr 1)) ((sexpr parens) ; parens is used to watch (let ((ch (get-char '#f))) ; for the closing paren (cond ((char= ch #\semicolon) ; used to detect the (copy-comment '#f) ; end of T code mode. (sexpr parens)) (else (sexpr-write-char parens ch))))) ((copy-comment eof-value) ; Handle comment. (let ((line (get-line eof-value))) (write-string tex-port begin-comment) (write-char tex-port #\semicolon) (write-string tex-port line) (write-char tex-port #\}) (newline tex-port))) ((sexpr-write-char parens ch) (tex-write-char ch) (cond ((char= ch #\left-paren) (sexpr (fx+ parens 1))) ((char= ch #\right-paren) (if (fx= 1 parens) ; Done reading sexpr. (t-mode-after-sexpr) (sexpr (fx- parens 1)))) ((char= ch #\") (copy-out-string parens)) ((char= ch #\#) ; Worrying about #\( and #\). (maybe-char-syntax parens)) (else (sexpr parens)))) ((copy-out-string parens) (let ((ch (get-char '#f))) (tex-write-char ch) (cond ((char= ch #\\) (let ((ch (get-char '#f))) (tex-write-char ch) (copy-out-string parens))) ((char= ch #\") (sexpr parens)) (else (copy-out-string parens))))) ((maybe-char-syntax parens) (let ((ch (get-char '#f))) (cond ((char= ch #\backslash) (tex-write-char ch) (let ((ch (get-char '#f))) (tex-write-char ch) (sexpr parens))) (else (unread-char st-port) (sexpr parens))))) ((t-mode-after-sexpr) (let ((ch (get-char '#t))) (cond ((char= ch #\semicolon) (copy-comment '#t) (t-mode-merge)) ((char= ch #\newline) (newline tex-port) (t-mode-merge)) ((char= ch #\space) (tex-write-char ch) (t-mode-after-sexpr)) (else (read-error st-port "Bad text following code"))))) ((t-mode-merge) (let ((ch (get-char '#t))) (cond ((char= ch #\left-paren) (write-char tex-port ch) (sexpr 1)) (else (write-line tex-port end-code) (write-char tex-port ch) (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.2 88/03/29 \title{Scheme\TeX{}} \author{John D. Ramsdell} \date{ 88/03/29 } \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. Some users prefer not modifying the \verb-LOAD- function in their Lisp system. To support those users, the rule that text lines must be unmodified \LaTeX{} code has been relaxed. Text lines that begin with ``;'' are copied without the initial ``;''. \newpage{} \section*{Usage under Unix} The extension for Scheme\TeX{} files is ``\verb;.st;''. For T, the file \verb;st.t; contains two programs used to obtain code from an ``\verb;.st;'' file. The T expression \begin{center} \verb;(LOAD-ST; {\it filespec environment\/}{\tt )} \end{center} loads a Scheme\TeX{} file by creating a T source file if no T source file exists which is younger than the Scheme\TeX{} file. The T source file is then loaded using the usual \verb;LOAD; procedure. \verb;COMPILE-ST; is like \verb;LOAD-ST; except it compiles the file instead of loading it. A \LaTeX{} file is produced from a file with the ``\verb;.st;'' extension 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 cd .. # End of shell archive exit 0 -------