feat: 9.5.9
This commit is contained in:
parent
cb1753732b
commit
35f43a7909
1084 changed files with 558985 additions and 0 deletions
3
stex/.gitignore
vendored
Normal file
3
stex/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
*~
|
||||
.*.sw?
|
||||
.sw?
|
58
stex/Makefile
Normal file
58
stex/Makefile
Normal file
|
@ -0,0 +1,58 @@
|
|||
VERSION=1.2
|
||||
|
||||
# override PREFIX, Scheme, and LIB as necessary
|
||||
PREFIX=/usr
|
||||
|
||||
# scheme executable
|
||||
Scheme=$(PREFIX)/bin/scheme
|
||||
|
||||
# target location for stex
|
||||
LIB=$(PREFIX)/lib/stex$(VERSION)
|
||||
|
||||
m := $(shell echo '(machine-type)' | $(Scheme) -q)
|
||||
|
||||
Install=./sbin/install
|
||||
|
||||
exec = $m/scheme-prep $m/html-prep $m/fixbibtex
|
||||
|
||||
all: $(exec)
|
||||
|
||||
$m/scheme-prep: src/dsm.ss src/preplib.ss src/script.ss src/scheme-prep.ss
|
||||
if [ ! -d $m ] ; then mkdir $m ; fi
|
||||
sed -e 's;^#! /usr/bin/scheme --program;#! $(Scheme) --program;' src/scheme-prep.ss > $m/scheme-prep.ss
|
||||
echo '(reset-handler abort) (library-directories (quote "src::$m")) (compile-imported-libraries #t) (generate-wpo-files #t) (compile-program "$m/scheme-prep.ss") (compile-whole-program "$m/scheme-prep.wpo" "$m/scheme-prep")' | $(Scheme) -q
|
||||
chmod 755 $m/scheme-prep
|
||||
|
||||
$m/html-prep: src/dsm.ss src/preplib.ss src/script.ss src/html-prep.ss
|
||||
if [ ! -d $m ] ; then mkdir $m ; fi
|
||||
sed -e 's;^#! /usr/bin/scheme --program;#! $(Scheme) --program;' src/html-prep.ss > $m/html-prep.ss
|
||||
echo '(reset-handler abort) (library-directories (quote "src::$m")) (compile-imported-libraries #t) (generate-wpo-files #t) (compile-program "$m/html-prep.ss") (compile-whole-program "$m/html-prep.wpo" "$m/html-prep")' | $(Scheme) -q
|
||||
chmod 755 $m/html-prep
|
||||
|
||||
$m/fixbibtex: src/fixbibtex.ss
|
||||
-if [ ! -d $m ] ; then mkdir $m ; fi
|
||||
sed -e 's;^#! /usr/bin/scheme --program;#! $(Scheme) --program;' src/fixbibtex.ss > $m/fixbibtex.ss
|
||||
echo '(reset-handler abort) (library-directories (quote "src::$m")) (compile-imported-libraries #t) (generate-wpo-files #t) (compile-program "$m/fixbibtex.ss") (compile-whole-program "$m/fixbibtex.wpo" "$m/fixbibtex")' | $(Scheme) -q
|
||||
chmod 755 $m/fixbibtex
|
||||
|
||||
install: $(exec)
|
||||
$(Install) -o root -g root -m 755 -d $(LIB)
|
||||
$(Install) -o root -g root -m 755 -d $(LIB)/inputs
|
||||
$(Install) -o root -g root -m 644 inputs/* $(LIB)/inputs
|
||||
$(Install) -o root -g root -m 755 -d $(LIB)/gifs
|
||||
$(Install) -o root -g root -m 644 gifs/* $(LIB)/gifs
|
||||
$(Install) -o root -g root -m 755 -d $(LIB)/math
|
||||
$(Install) -o root -g root -m 644 math/* $(LIB)/math
|
||||
$(Install) -o root -g root -m 755 -d $(LIB)/$m
|
||||
$(Install) -o root -g root -m 644 $(exec) $(LIB)/$m
|
||||
(umask 022; sed -e 's;^LIB=.*;LIB=$(LIB);' Mf-stex > $(LIB)/Mf-stex)
|
||||
(umask 022; sed -e 's;include ~/stex/Mf-stex;include $(LIB)/Mf-stex;' Makefile.template > $(LIB)/Makefile.template)
|
||||
|
||||
uninstall:
|
||||
/bin/rm -rf $(LIB)
|
||||
|
||||
clean:
|
||||
/bin/rm -f Make.out
|
||||
|
||||
distclean: clean
|
||||
/bin/rm -rf $m
|
35
stex/Makefile.template
Normal file
35
stex/Makefile.template
Normal file
|
@ -0,0 +1,35 @@
|
|||
VERSION=1.2
|
||||
Scheme=scheme
|
||||
STEXLIB=/usr/lib/stex$(VERSION)
|
||||
|
||||
# define default document pathname here
|
||||
# override on command line with 'make x=newdoc'
|
||||
x = ???
|
||||
|
||||
# define latex processor: latex or pdflatex
|
||||
latex = pdflatex
|
||||
|
||||
# define stex macro files here
|
||||
stexmacrofiles =
|
||||
|
||||
# list bibliography files here
|
||||
bib =
|
||||
|
||||
# define index if an index is to be generated
|
||||
# index=yes
|
||||
|
||||
include $(STEXLIB)/Mf-stex
|
||||
|
||||
# define or override suffixes here
|
||||
|
||||
# define any additional targets here
|
||||
|
||||
# define any dependencies here
|
||||
|
||||
# define cleanup targets here:
|
||||
|
||||
$(x).clean:
|
||||
|
||||
$(x).reallyclean:
|
||||
|
||||
$(x).reallyreallyclean:
|
150
stex/Mf-stex
Normal file
150
stex/Mf-stex
Normal file
|
@ -0,0 +1,150 @@
|
|||
# Mf-stex expects to be included in a make file that defines:
|
||||
# Scheme the path of the Chez Scheme executable
|
||||
# STEXLIB the path to the stex library (the library containing this file)
|
||||
|
||||
m := $(shell echo '(machine-type)' | $(Scheme) -q)
|
||||
|
||||
TEXINPUTS:=.:$(STEXLIB)/inputs:
|
||||
export TEXINPUTS
|
||||
|
||||
ifeq ($(wildcard $(STEXLIB)/$m/scheme-prep),)
|
||||
Sprep = $(Scheme) --libdirs "$(STEXLIB)/src" --program $(STEXLIB)/src/scheme-prep.ss
|
||||
else
|
||||
Sprep = $(STEXLIB)/$m/scheme-prep
|
||||
endif
|
||||
|
||||
ifeq ($(wildcard $(STEXLIB)/$m/html-prep),)
|
||||
Hprep = $(Scheme) --libdirs "$(STEXLIB)/src" --program $(STEXLIB)/src/html-prep.ss
|
||||
else
|
||||
Hprep = $(STEXLIB)/$m/html-prep
|
||||
endif
|
||||
|
||||
ifeq ($(wildcard $(STEXLIB)/$m/fixbibtex),)
|
||||
fixbibtex = $(Scheme) --libdirs "$(STEXLIB)/src" --program $(STEXLIB)/src/fixbibtex.ss
|
||||
else
|
||||
fixbibtex = $(STEXLIB)/$m/fixbibtex
|
||||
endif
|
||||
|
||||
mathdir=math/$(x)
|
||||
mathfiles=$(mathdir)/mathfiles
|
||||
|
||||
# solaris /bin/sh doesn't support '!' in test
|
||||
SHELL=bash
|
||||
|
||||
stexsrc = $(x).stex
|
||||
texsrc = $(x).tex
|
||||
spellobj = $(x).spell
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .stex .tex .spell .fig .ps .png .pdf .eps
|
||||
.stex.tex:
|
||||
$(Sprep) $(stexmacrofiles) $*
|
||||
chmod -w $*.tex
|
||||
.tex.spell:
|
||||
latexspell $*.tex
|
||||
.fig.ps:
|
||||
fig2dev -Leps $*.fig $*.ps
|
||||
.fig.png:
|
||||
fig2dev -Lppm $*.fig | pnmcrop | pnmtopng -transparent white > $*.png
|
||||
chmod go=r $*.png
|
||||
.ps.png:
|
||||
echo | gs -q -dNOPAUSE -dSAFER -sDEVICE=ppmraw -sOutputFile=- -r90x90 $*.ps | pnmcrop | pnmtopng -transparent white > $*.png
|
||||
# need to generate eps first to compute bounding box
|
||||
# need --gs on my machine at home or it fails to find bounding box
|
||||
.ps.eps:
|
||||
ps2epsi $*.ps $*.eps
|
||||
.eps.pdf:
|
||||
epstopdf --gs $*.eps
|
||||
.fig.pdf:
|
||||
fig2dev -Leps $*.fig | epstopdf --filter > $*.pdf
|
||||
|
||||
ifeq "$(latex)" "latex"
|
||||
doitformebaby: $(x).ps $(x).html
|
||||
|
||||
$(x).ps: $(x).thirdrun
|
||||
dvips -o $(x).ps $(x).dvi
|
||||
|
||||
$(x).pdf: $(x).ps
|
||||
ps2pdf $*.ps $*.pdf
|
||||
chmod 644 $*.pdf
|
||||
else
|
||||
doitformebaby: $(x).pdf $(x).html
|
||||
|
||||
$(x).pdf: $(x).thirdrun
|
||||
chmod 644 $(x).pdf
|
||||
endif
|
||||
|
||||
$(x).dvi: $(x).thirdrun
|
||||
|
||||
$(x).thirdrun: $(x).secondrun
|
||||
ifdef index
|
||||
makeindex $(x)
|
||||
endif
|
||||
$(latex) $(x)
|
||||
touch $(x).thirdrun
|
||||
|
||||
$(x).secondrun: $(x).firstrun $(bib)
|
||||
ifneq ($(strip $(bib)),)
|
||||
bibtex $(x)
|
||||
$(fixbibtex) $(x).bbl
|
||||
endif
|
||||
ifdef index
|
||||
makeindex $(x)
|
||||
endif
|
||||
$(latex) $(x)
|
||||
touch $(x).secondrun
|
||||
|
||||
$(x).firstrun: $(texsrc)
|
||||
touch $(x).htoc
|
||||
$(latex) $(x)
|
||||
touch $(x).firstrun
|
||||
|
||||
all.tex: $(texsrc)
|
||||
|
||||
$(x).html: $(x).mathrun
|
||||
|
||||
$(x).mathrun: gifs $(mathfiles)
|
||||
@(cd $(mathdir); make)
|
||||
touch $(x).mathrun
|
||||
|
||||
gifs:
|
||||
(cd $(STEXLIB); tar -cf - gifs) | tar -xpf -
|
||||
|
||||
math:
|
||||
(cd $(STEXLIB); tar -cf - math) | tar -xpf -
|
||||
|
||||
$(mathfiles): $(x).hthirdrun $(figps)
|
||||
echo -n gifs= > $(mathfiles)
|
||||
(cd $(mathdir); echo *.tex | sed -e "s/\.tex/.gif/g") >> $(mathfiles)
|
||||
|
||||
$(x).hthirdrun: $(x).hsecondrun
|
||||
$(Hprep) --mathdir $(mathdir) $(x)
|
||||
chmod 444 *.html
|
||||
touch $(x).hthirdrun
|
||||
|
||||
$(x).hsecondrun: $(x).hfirstrun
|
||||
$(Hprep) --mathdir $(mathdir) $(x)
|
||||
chmod 444 *.html
|
||||
touch $(x).hsecondrun
|
||||
|
||||
$(x).hfirstrun: math $(x).thirdrun
|
||||
(if [ ! -e $(mathdir) ] ; then mkdir -p -m u=rwx,g=srx,o=rx $(mathdir); ln -s ../Makefile ../mathmacros $(mathdir); fi)
|
||||
$(Hprep) --mathdir $(mathdir) $(x)
|
||||
touch $(x).hfirstrun
|
||||
|
||||
spell: $(spellobj)
|
||||
|
||||
$(x).spell: $(x).bbl $(x).tex
|
||||
latexspell $(x).bbl
|
||||
latexspell $(x).tex
|
||||
|
||||
clean: $(x).clean
|
||||
-/bin/rm -f *.log *.dvi *.aux *.out *.toc *.tmp *.idx *.ilg *.ind *.blg *.bbl *.rfm *.sfm *.firstrun *.secondrun *.thirdrun
|
||||
-/bin/rm -f *.haux *.htoc *.hidx *.hfirstrun *.hsecondrun *.hthirdrun *.mathrun
|
||||
-/bin/rm -f *.tex
|
||||
|
||||
reallyclean: clean $(x).reallyclean
|
||||
-/bin/rm -f *.html *.ps *.pdf *.png
|
||||
|
||||
reallyreallyclean: reallyclean $(x).reallyreallyclean
|
||||
-/bin/rm -rf $(mathdir)
|
39
stex/ReadMe
Normal file
39
stex/ReadMe
Normal file
|
@ -0,0 +1,39 @@
|
|||
stex: stex => latex and latex => html converters and associated tools
|
||||
|
||||
Copyright (c) 1998-2016 R. Kent Dybvig and Oscar Waddell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
This directory contains the following files and subdirectories as of
|
||||
April 2016:
|
||||
|
||||
doc a short stex overview
|
||||
gifs/ support for building 'ghost' right arrows
|
||||
inputs/ sample class files, style files, etc.
|
||||
Makefile for compiling stex itself
|
||||
Makefile.template template make file for stex-based docs
|
||||
Mf-stex common (included) makefile for stex-based docs
|
||||
math/ base math subdirectory for stex-based docs
|
||||
ReadMe this file
|
||||
sbin/ helper scripts
|
||||
src/ stex sources
|
||||
|
||||
See doc/stex.html for a brief overview of stex and how to use it.
|
32
stex/doc/Makefile
Normal file
32
stex/doc/Makefile
Normal file
|
@ -0,0 +1,32 @@
|
|||
# define default document pathname here
|
||||
# override on command line with 'make x=newdoc'
|
||||
x = stex
|
||||
|
||||
# define latex processor: latex or pdflatex
|
||||
latex = pdflatex
|
||||
|
||||
# define stex macro files here
|
||||
stexmacrofiles =
|
||||
|
||||
# list bibliography files here
|
||||
bib =
|
||||
|
||||
# define index if an index is to be generated
|
||||
# index=yes
|
||||
|
||||
include ~/stex/Mf-stex
|
||||
|
||||
# define or override suffixes here
|
||||
|
||||
# define any additional targets here
|
||||
|
||||
# define any dependencies here
|
||||
|
||||
# define cleanup targets here:
|
||||
|
||||
$(x).clean:
|
||||
-rm -f $x.rawsst
|
||||
|
||||
$(x).reallyclean:
|
||||
|
||||
$(x).reallyreallyclean:
|
35
stex/doc/stex.css
Normal file
35
stex/doc/stex.css
Normal file
|
@ -0,0 +1,35 @@
|
|||
BODY {background-color: #FFFFFF}
|
||||
|
||||
a:link, a:active, a:visited { color:#6d380b; text-decoration:underline }
|
||||
a:hover { color:white; text-decoration:underline; background:#6d380b }
|
||||
|
||||
a.plain:link, a.plain:active, a.plain:visited { color:#6d380b; text-decoration:none }
|
||||
a.plain:hover { color:white; text-decoration:none; background:#6d380b }
|
||||
|
||||
a.toc:link, a.toc:active, a.toc:visited {font-family: sans-serif; color:#6d380b; text-decoration:none}
|
||||
a.toc:hover {font-family: sans-serif; color:white; text-decoration:none; background:#6d380b}
|
||||
|
||||
a.image:link, a.image:active, a.image:visited, a.image:hover {
|
||||
color: #6d380b;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
ul.tocchapter { list-style: none; }
|
||||
ul.tocsection { list-style: circle; color: #923a3a }
|
||||
|
||||
hr.copyright { width: 50% }
|
||||
|
||||
input.default { background: #ffffff; color: #000000; vertical-align: middle}
|
||||
|
||||
h1, h2, h3, h4 {font-family: sans-serif; color: #6d380b}
|
||||
h1 {font-size: 2em}
|
||||
h2 {margin-top: 30px; font-size: 1.5em}
|
||||
h3 {margin-top: 30px; font-size: 1.17em}
|
||||
h1, h2, h3, h4 {font-weight: bold}
|
||||
|
||||
.title { font-family: sans-serif; font-weight: bold; font-size: 2.5em; color: #6d380b; white-space: nowrap}
|
||||
|
||||
.formdef { color: #6d380b }
|
||||
|
||||
table.indent {margin-left: 20px}
|
||||
|
967
stex/doc/stex.html
Normal file
967
stex/doc/stex.html
Normal file
|
@ -0,0 +1,967 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd"><!-- DO NOT EDIT THIS FILE-->
|
||||
<!-- Edit the .tex version instead-->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Introduction to stex</title>
|
||||
<link href="stex.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
|
||||
<h1>Introduction to stex</h1>
|
||||
<h2>R. Kent Dybvig and Oscar Waddell</h2>
|
||||
<h3>April 2016</h3>
|
||||
|
||||
|
||||
<p>
|
||||
|
||||
<table cellpadding=0 cellspacing=0>
|
||||
|
||||
|
||||
|
||||
<tr><td align="right"><b>1. </b><td><b><a class=plain href="./stex.html#g0">Overview</a></b></td></tr>
|
||||
|
||||
|
||||
|
||||
<tr><td align="right"><b>2. </b><td><b><a class=plain href="./stex.html#g1">Installation</a></b></td></tr>
|
||||
|
||||
|
||||
|
||||
<tr><td align="right"><b>3. </b><td><b><a class=plain href="./stex.html#g2">Usage notes</a></b></td></tr>
|
||||
|
||||
|
||||
|
||||
<tr><td align="right"><b>4. </b><td><b><a class=plain href="./stex.html#g3">Basic stex commands</a></b></td></tr>
|
||||
|
||||
|
||||
<tr><td></td><td><table cellpadding=0 cellspacing=0>
|
||||
<tr><td><b>4.1. </b></td><td><b><a class=plain href="./stex.html#g4">Inline code</a></b></td></tr>
|
||||
|
||||
|
||||
|
||||
<tr><td><b>4.2. </b></td><td><b><a class=plain href="./stex.html#g5">Code displays</a></b></td></tr>
|
||||
|
||||
|
||||
|
||||
<tr><td><b>4.3. </b></td><td><b><a class=plain href="./stex.html#g6">Variables</a></b></td></tr>
|
||||
|
||||
|
||||
|
||||
<tr><td><b>4.4. </b></td><td><b><a class=plain href="./stex.html#g7">Raw text in code</a></b></td></tr>
|
||||
|
||||
|
||||
|
||||
<tr><td><b>4.5. </b></td><td><b><a class=plain href="./stex.html#g8">Generated output</a></b></td></tr>
|
||||
|
||||
|
||||
|
||||
<tr><td><b>4.6. </b></td><td><b><a class=plain href="./stex.html#g9">Verbatim Scheme displays</a></b></td></tr>
|
||||
|
||||
|
||||
</table></td></tr>
|
||||
<tr><td align="right"><b>5. </b><td><b><a class=plain href="./stex.html#g10">Scheme transcripts</a></b></td></tr>
|
||||
|
||||
|
||||
<tr><td></td><td><table cellpadding=0 cellspacing=0>
|
||||
<tr><td><b>5.1. </b></td><td><b><a class=plain href="./stex.html#g11">Automatic transcript generation</a></b></td></tr>
|
||||
|
||||
|
||||
|
||||
<tr><td><b>5.2. </b></td><td><b><a class=plain href="./stex.html#g12">Loading initialization code</a></b></td></tr>
|
||||
|
||||
|
||||
</table></td></tr>
|
||||
<tr><td align="right"><b>6. </b><td><b><a class=plain href="./stex.html#g13">html-prep support for the <tt>tabular</tt> environment</a></b></td></tr>
|
||||
|
||||
|
||||
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<p>
|
||||
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g0"></a>
|
||||
|
||||
|
||||
<h3><a name="./stex:h0"></a>1. Overview</h3>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
The <i>stex</i> package consists of two main programs and some supporting
|
||||
items, such as make files, make-file templates, class files, and style
|
||||
files.
|
||||
The two main programs are <b>scheme-prep</b> and <b>html-prep</b>.
|
||||
<b>scheme-prep</b> performs a conversion from "stex"-formatted files
|
||||
into latex-formatted files, while <b>html-prep</b> converts (some)
|
||||
latex-formatted files into html-formatted files.
|
||||
|
||||
<p>
|
||||
An stex file is really just a latex file extended with a handful of
|
||||
commands for including Scheme code (or pretty much any other kind of code,
|
||||
as long as you don't plan to use the Scheme-specific transcript support)
|
||||
in a document, plus a couple of additional features rather arbitrarily
|
||||
thrown in.
|
||||
|
||||
<p>
|
||||
The subset of latex-formatted files <b>html-prep</b> is capable of
|
||||
handling is rather small but has nevertheless been useful for our
|
||||
purposes, which include producing html versions of a couple of books
|
||||
(<i>The Scheme Programming Language</i>, Editions 2-4 and the Chez Scheme
|
||||
User's Guides for Versions 6-9), the scheme.com web site, class websites,
|
||||
class assignments, and various other documents.
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g1"></a>
|
||||
|
||||
|
||||
<h3><a name="./stex:h1"></a>2. Installation</h3>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
A prerequisite to building and using stex is to have Chez Scheme or
|
||||
Petite Chez Scheme installed on your system.
|
||||
You'll also need pdflatex, dvips, ghostscript, and netbpm.
|
||||
We've run stex under Linux and OS X but have not tried to run it under
|
||||
Windows.
|
||||
|
||||
<p>
|
||||
The simplest way to install stex for your personal use is to clone the
|
||||
stex directory into your home directory, cd into the stex directory,
|
||||
and run make:
|
||||
|
||||
<p>
|
||||
|
||||
<p><tt>make BIN=<i>bindir</i></tt>
|
||||
<p>where <tt><i>bindir</i></tt> is the directory where make will find the scheme or
|
||||
petite executables.
|
||||
|
||||
<p>
|
||||
This will create a subdirectory, named for the installed Chez Scheme
|
||||
machine type, containing binary versions of the programs.
|
||||
|
||||
<p>
|
||||
You can also use "make install" to make stex available for other users.
|
||||
|
||||
<p>
|
||||
|
||||
<p><tt>sudo make install BIN=<i>bindir</i> LIB=<i>libdir</i></tt>
|
||||
<p>where <tt><i>bindir</i></tt> is as described above, and <tt><i>libdir</i></tt> is the
|
||||
directory where the stex library directory should be installed.
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g2"></a>
|
||||
|
||||
|
||||
<h3><a name="./stex:h2"></a>3. Usage notes</h3>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
The simplest way to get started with stex is to get this document to
|
||||
build (in the doc directory) and create your own document by cloning
|
||||
this document's source file (stex.stex) and make file (Makefile).
|
||||
If you've installed stex in your home directory, you should be able to
|
||||
build this document by running "make" without arguments in the doc
|
||||
directory.
|
||||
If you've installed stex elsewhere, you'll first have to modify the
|
||||
include for Mf-stex to reflect its installed location.
|
||||
|
||||
<p>
|
||||
Makefile is where you declare your stex sources and various other things,
|
||||
like bibtex and graphics files.
|
||||
If you don't have anything much more complicated than this document,
|
||||
you might just need to change the line that declares the main stex entry
|
||||
point, i.e., the line that reads <tt>x = stex</tt>, to reflect the name
|
||||
of your document.
|
||||
|
||||
<p>
|
||||
The make is orchestrated by Mf-stex, which knows how to run
|
||||
<b>scheme-prep</b>, <b>html-prep</b>, <b>pdflatex</b> (multiple
|
||||
times), and various other commands to produce both pdf and html versions
|
||||
of the stex document.
|
||||
|
||||
<p>
|
||||
You can also consult the more elaborate stex source and make files for the
|
||||
Chez Scheme User's Guide in the csug directory of a Chez Scheme release.
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g3"></a>
|
||||
|
||||
|
||||
<h3><a name="./stex:h3"></a>4. Basic stex commands</h3>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g4"></a>
|
||||
|
||||
|
||||
<h4><a name="./stex:h4"></a>4.1. Inline code</h4>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
An stex document includes inline Scheme (or other) code via the
|
||||
<tt>\scheme</tt> command, e.g.:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
When called with two arguments, \scheme{cons} creates a pair of the two
|
||||
arguments, e.g., \scheme{(cons 3 4)} produces \scheme{(3 . 4)}.
|
||||
</pre>
|
||||
|
||||
|
||||
<p>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
produces:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
When called with two arguments, <tt>cons</tt> creates a pair of the two
|
||||
arguments, e.g., <tt>(cons 3 4)</tt> produces <tt>(3 . 4)</tt>.
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g5"></a>
|
||||
|
||||
|
||||
<h4><a name="./stex:h5"></a>4.2. Code displays</h4>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
An stex document includes out-of-line Scheme (or other) code via
|
||||
<tt>\schemedisplay</tt> and <tt>\endschemedisplay</tt>, e.g.:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
\schemedisplay
|
||||
(define fact
|
||||
(lambda (x)
|
||||
"a light year is a measure of distance"))
|
||||
|
||||
(define fib
|
||||
(lambda (x)
|
||||
"a light year is a measure of time"))
|
||||
\endschemedisplay
|
||||
</pre>
|
||||
|
||||
|
||||
<p>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
produces:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
|
||||
<p><tt>(define fact<br>
|
||||
|
||||
(lambda (x)<br>
|
||||
|
||||
"a light year is a measure of distance"))
|
||||
<br>
|
||||
<br>
|
||||
(define fib<br>
|
||||
|
||||
(lambda (x)<br>
|
||||
|
||||
"a light year is a measure of time"))</tt>
|
||||
<p></blockquote>
|
||||
|
||||
<p>
|
||||
Within a Scheme display, <tt>;=></tt> is converted into a double right arrow
|
||||
(<img src="math/stex/0.gif" alt="<graphic>">), <tt>;-></tt> into a single right arrow (<img src="math/stex/1.gif" alt="<graphic>">), and
|
||||
<tt>;==</tt> into a phantom of the same size.
|
||||
This is useful for showing what a piece of code translates or evaluates to,
|
||||
e.g.:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
A \scheme{let} expression expands into a call to a \scheme{lambda}
|
||||
expression, e.g.:
|
||||
\schemedisplay
|
||||
(let ([a 17]) ;-> ((lambda (a) (+ a a))
|
||||
(+ a a)) ;== 17)
|
||||
\endschemedisplay
|
||||
|
||||
A \scheme{let} expression first evaluates the right-hand-side
|
||||
expression, then evaluates the body in an environment that binds
|
||||
the left-hand-side variable to the resulting value, e.g.:
|
||||
\schemedisplay
|
||||
(let ([a 17]) ;=> 17
|
||||
(+ a a))
|
||||
\endschemedisplay
|
||||
</pre>
|
||||
|
||||
|
||||
<p>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
produces
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
A <tt>let</tt> expression expands into a call to a <tt>lambda</tt>
|
||||
expression, e.g.:
|
||||
|
||||
<p><tt>(let ([a 17]) <img src="math/stex/1.gif" alt="<graphic>"> ((lambda (a) (+ a a))<br>
|
||||
|
||||
(+ a a)) <img src="gifs/ghostRightarrow.gif"> 17)</tt>
|
||||
<p>A <tt>let</tt> expression first evaluates the right-hand-side
|
||||
expression, then evaluates the body in an environment that binds
|
||||
the left-hand-side variable to the resulting value, e.g.:
|
||||
|
||||
<p><tt>(let ([a 17]) <img src="math/stex/0.gif" alt="<graphic>"> 17<br>
|
||||
|
||||
(+ a a))</tt>
|
||||
<p></blockquote>
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g6"></a>
|
||||
|
||||
|
||||
<h4><a name="./stex:h6"></a>4.3. Variables</h4>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
Code can include emphasized variables via the <tt>\var</tt> command, e.g.:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
\scheme{(let ([\var{x} \var{e}]) \var{body})} binds the variable \var{x} to
|
||||
the value of \var{e} in \var{body}.
|
||||
</pre>
|
||||
|
||||
|
||||
<p>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
produces:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<tt>(let ([<i>x</i> <i>e</i>]) <i>body</i>)</tt> binds the variable <tt><i>x</i></tt> to
|
||||
the value of <tt><i>e</i></tt> in <tt><i>body</i></tt>.
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
If the text within a <tt>\var</tt> form contains an underscore, the
|
||||
following character or bracketed subform is converted into a subscript,
|
||||
e.g., <tt>\var{abc_3}</tt>
|
||||
produces <tt><i>abc<sub>3</sub></i></tt>, and <tt>\var{7e5_16}</tt>
|
||||
produces <tt><i>7e5<sub>16</sub></i></tt>.
|
||||
|
||||
<p>
|
||||
<tt>\var</tt> forms may appear within a <tt>\scheme</tt> form, within a Scheme display
|
||||
formed by <tt>\schemedisplay</tt> and <tt>\endschemedisplay</tt> commands,
|
||||
or by itself outside of either.
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g7"></a>
|
||||
|
||||
|
||||
<h4><a name="./stex:h7"></a>4.4. Raw text in code</h4>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
Raw text can be included in code via the <tt>\raw</tt> command.
|
||||
For example:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
\schemedisplay
|
||||
(sqrt \raw{$x$}) \is \raw{$\sqrt{x}$}.
|
||||
\endschemedisplay
|
||||
</pre>
|
||||
|
||||
|
||||
<p>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
produces:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
|
||||
<p><tt>(sqrt <i>x</i>) <img src="math/stex/0.gif" alt="<graphic>"> <img src="math/stex/2.gif" alt="<graphic>">.</tt>
|
||||
<p></blockquote>
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g8"></a>
|
||||
|
||||
|
||||
<h4><a name="./stex:h8"></a>4.5. Generated output</h4>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
Output generated by a Scheme program can be inserted into the output via
|
||||
<tt>\generated</tt> and <tt>\endgenerated</tt> commands, e.g.:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
\generated
|
||||
(let ()
|
||||
(define fibs
|
||||
(lambda (x y n)
|
||||
(if (= n 0)
|
||||
'()
|
||||
(cons x (fibs y (+ x y) (- n 1))))))
|
||||
(let ([n 5])
|
||||
(printf "first ~r primes: ~{~s~^, ~}\n" n (fibs 0 1 n))))
|
||||
\endgenerated
|
||||
</pre>
|
||||
|
||||
|
||||
<p>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
produces:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
first five primes: 0, 1, 1, 2, 3
|
||||
|
||||
<p>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g9"></a>
|
||||
|
||||
|
||||
<h4><a name="./stex:h9"></a>4.6. Verbatim Scheme displays</h4>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
When special features, like <tt>\var</tt> forms, need to be
|
||||
suppressed within a Scheme display, a document can use
|
||||
<tt>\schemeverbatim</tt> and <tt>\endschemeverbatim</tt> instead of
|
||||
<tt>\schemedisplay</tt> and <tt>\endschemedisplay</tt>.
|
||||
This document makes extensive use of this feature.
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g10"></a>
|
||||
|
||||
|
||||
<h3><a name="./stex:h10"></a>5. Scheme transcripts</h3>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g11"></a>
|
||||
|
||||
|
||||
<h4><a name="./stex:h11"></a>5.1. Automatic transcript generation</h4>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
The <b>scheme-prep</b> package supports a
|
||||
<tt>\transcript</tt> command for automatically generating Scheme transcripts
|
||||
from input supplied in the document source.
|
||||
All text from the <tt>\transcript</tt> marker up to and including the
|
||||
<tt>\endtranscript</tt> marker is replaced with a transcript generated
|
||||
by supplying the intervening text as the input to a Scheme café (REPL).
|
||||
If the Scheme transcript needs to contain the sequence
|
||||
<tt>\endtranscript</tt>, a different terminator may be specified as an
|
||||
optional argument to <tt>\transcript</tt>.
|
||||
The terminator must be a backslash followed by one or more alphabetic
|
||||
characters, and is specified without the backslash in the optional argument.
|
||||
|
||||
<p>
|
||||
Three pairs of commands may be redefined to customize the typesetting
|
||||
of different elements within generated transcripts.
|
||||
To modify the typesetting of error messages, redefine <tt>\transerr</tt>
|
||||
and <tt>\endtranserr</tt>.
|
||||
To modify the typesetting of user input read from the current input port
|
||||
of the café, redefine <tt>\transin</tt> and <tt>\endtransin</tt>.
|
||||
To modify the typesetting of program output written to the current
|
||||
output port of new café, redefine <tt>\transout</tt> and
|
||||
<tt>\endtransout</tt>.
|
||||
|
||||
<p>
|
||||
For example, the following:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
\transcript
|
||||
(define f
|
||||
(lambda (x) ; indentation and comments are
|
||||
(if (zero? x) ; preserved in the transcript
|
||||
1
|
||||
(* x (f (- x 1))))))
|
||||
(values f (f 0) (f 5) (f 20))
|
||||
(trace f)
|
||||
(f 4)
|
||||
\endtranscript
|
||||
</pre>
|
||||
|
||||
|
||||
<p>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
produces:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
|
||||
<p><tt>> (define f<br>
|
||||
|
||||
(lambda (x) ; indentation and comments are<br>
|
||||
|
||||
(if (zero? x) ; preserved in the transcript<br>
|
||||
|
||||
1<br>
|
||||
|
||||
(* x (f (- x 1))))))<br>
|
||||
|
||||
> (values f (f 0) (f 5) (f 20))<br>
|
||||
|
||||
#<procedure f><br>
|
||||
|
||||
1<br>
|
||||
|
||||
120<br>
|
||||
|
||||
2432902008176640000<br>
|
||||
|
||||
> (trace f)<br>
|
||||
|
||||
(f)<br>
|
||||
|
||||
> (f 4)<br>
|
||||
|
||||
<font color="#0000ff">|(f 4)<br>
|
||||
|
||||
| (f 3)<br>
|
||||
|
||||
| |(f 2)<br>
|
||||
|
||||
| | (f 1)<br>
|
||||
|
||||
| | |(f 0)<br>
|
||||
|
||||
| | |1<br>
|
||||
|
||||
| | 1<br>
|
||||
|
||||
| |2<br>
|
||||
|
||||
| 6<br>
|
||||
|
||||
|24<br>
|
||||
|
||||
</font>24</tt>
|
||||
<p></blockquote>
|
||||
|
||||
<p>
|
||||
The following example shows how to specify a different transcript
|
||||
terminator and shows the default formatting imposed by <tt>\transerr</tt>,
|
||||
<tt>\transin</tt>, and <tt>\transout</tt>.
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
\transcript[\stopthistranscript]
|
||||
#e4.5
|
||||
(begin (display "Enter a character: ") (read-char))
|
||||
(begin (display "Enter a character: ") (read-char))Z
|
||||
(begin (clear-input-port) (display "Enter a character: ") (read-char))
|
||||
Z
|
||||
(list (read-char) (read-char) (read-char))abc def
|
||||
(define silly-repl
|
||||
(lambda (prompt)
|
||||
(display prompt)
|
||||
(let ([x (read)])
|
||||
(unless (eof-object? x)
|
||||
(let ([result (eval x)])
|
||||
(unless (eq? result (void))
|
||||
(pretty-print result))
|
||||
(silly-repl prompt))))))
|
||||
(silly-repl "Enter a Scheme expression: ")
|
||||
(list 1
|
||||
2
|
||||
3)
|
||||
(silly-repl "Now what? ")
|
||||
(define interview
|
||||
(lambda ()
|
||||
(let* ([fname (begin (display "First name: ") (read))]
|
||||
[lname (begin (display "Last name: ") (read))])
|
||||
(printf "Hello ~a ~a!~%" fname lname))))
|
||||
(interview)
|
||||
john
|
||||
doe
|
||||
#!eof
|
||||
(printf "good to be back~%")
|
||||
#!eof
|
||||
\stopthistranscript
|
||||
</pre>
|
||||
|
||||
|
||||
<p>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
produces:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
|
||||
<p><tt>> #e4.5<br>
|
||||
|
||||
9/2<br>
|
||||
|
||||
> (begin (display "Enter a character: ") (read-char))<font color="#ff0000"><br>
|
||||
|
||||
</font><font color="#0000ff">Enter a character: </font>#\newline<br>
|
||||
|
||||
> (begin (display "Enter a character: ") (read-char))<font color="#ff0000">Z</font><br>
|
||||
|
||||
<font color="#0000ff">Enter a character: </font>#\Z<br>
|
||||
|
||||
> (begin (clear-input-port) (display "Enter a character: ") (read-char))<br>
|
||||
|
||||
<font color="#0000ff">Enter a character: </font><font color="#ff0000">Z</font><br>
|
||||
|
||||
#\Z<br>
|
||||
|
||||
> (list (read-char) (read-char) (read-char))<font color="#ff0000">abc</font> def<br>
|
||||
|
||||
(#\b #\c #\a)<br>
|
||||
|
||||
> <br>
|
||||
|
||||
Exception: variable def is not bound<br>
|
||||
|
||||
Type (debug) to enter the debugger.<br>
|
||||
|
||||
> (define silly-repl<br>
|
||||
|
||||
(lambda (prompt)<br>
|
||||
|
||||
(display prompt)<br>
|
||||
|
||||
(let ([x (read)])<br>
|
||||
|
||||
(unless (eof-object? x)<br>
|
||||
|
||||
(let ([result (eval x)])<br>
|
||||
|
||||
(unless (eq? result (void))<br>
|
||||
|
||||
(pretty-print result))<br>
|
||||
|
||||
(silly-repl prompt))))))<br>
|
||||
|
||||
> (silly-repl "Enter a Scheme expression: ")<font color="#ff0000"><br>
|
||||
|
||||
</font><font color="#0000ff">Enter a Scheme expression: </font><font color="#ff0000">(list 1<br>
|
||||
|
||||
</font> <font color="#ff0000"> 2<br>
|
||||
|
||||
</font> <font color="#ff0000"> 3)<br>
|
||||
|
||||
</font><font color="#0000ff">(1 2 3)<br>
|
||||
|
||||
Enter a Scheme expression: </font><font color="#ff0000">(silly-repl "Now what? ")<br>
|
||||
|
||||
</font><font color="#0000ff">Now what? </font><font color="#ff0000">(define interview<br>
|
||||
|
||||
</font> <font color="#ff0000"> (lambda ()<br>
|
||||
|
||||
</font> <font color="#ff0000"> (let* ([fname (begin (display "First name: ") (read))]<br>
|
||||
|
||||
</font> <font color="#ff0000"> [lname (begin (display "Last name: ") (read))])<br>
|
||||
|
||||
</font> <font color="#ff0000"> (printf "Hello ~a ~a!~%" fname lname))))<br>
|
||||
|
||||
</font><font color="#0000ff">Now what? </font><font color="#ff0000">(interview)<br>
|
||||
|
||||
</font><font color="#0000ff">First name: </font><font color="#ff0000">john<br>
|
||||
|
||||
</font><font color="#0000ff">Last name: </font><font color="#ff0000"> doe<br>
|
||||
|
||||
</font><font color="#0000ff">Hello john doe!<br>
|
||||
|
||||
Now what? </font><font color="#ff0000">#!eof<br>
|
||||
|
||||
</font><font color="#0000ff">Enter a Scheme expression: </font><font color="#ff0000">(printf "good to be back~%")<br>
|
||||
|
||||
</font><font color="#0000ff">good to be back<br>
|
||||
|
||||
Enter a Scheme expression: </font><font color="#ff0000">#!eof</font></tt>
|
||||
<p></blockquote>
|
||||
|
||||
<p>
|
||||
Transcripts do not include a trailing prompt by design.
|
||||
This is done in such a way that an explicitly displayed string that
|
||||
happens to look like the prompt is not suppressed.
|
||||
For example:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
\transcript
|
||||
(begin (display "> \n") (exit))
|
||||
\endtranscript
|
||||
</pre>
|
||||
|
||||
|
||||
<p>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
should leave the apparent prompt alone since it is generated as program
|
||||
output.
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
|
||||
<p><tt>> (begin (display "> \n") (exit))<br>
|
||||
|
||||
<font color="#0000ff">> <br>
|
||||
|
||||
</font></tt>
|
||||
<p></blockquote>
|
||||
|
||||
<p>
|
||||
Prompt suppression works even with
|
||||
changes to <tt>waiter-prompt-string</tt>.
|
||||
For example:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
\transcript
|
||||
(waiter-prompt-string "antelope? ")
|
||||
"no thanks"
|
||||
\endtranscript
|
||||
</pre>
|
||||
|
||||
|
||||
<p>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
produces no trailing "antelope? " prompt:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
|
||||
<p><tt>> (waiter-prompt-string "antelope? ")<br>
|
||||
|
||||
antelope? "no thanks"<br>
|
||||
|
||||
"no thanks"</tt>
|
||||
<p></blockquote>
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g12"></a>
|
||||
|
||||
|
||||
<h4><a name="./stex:h12"></a>5.2. Loading initialization code</h4>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
The <tt>stex</tt> commands <tt>\schemeinit</tt> and <tt>\endschemeinit</tt>
|
||||
are used to bracket Scheme expressions that should be evaluated without
|
||||
generating a transcript of the results.
|
||||
This is useful, for example, when writing the description of a programming
|
||||
assignment. The solutions can be loaded via <tt>\schemeinit</tt> and a
|
||||
transcript showing how the solutions behave can be generated using the
|
||||
<tt>\transcript</tt> command.
|
||||
|
||||
<p>
|
||||
For example, the following text:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
\schemeinit
|
||||
(waiter-prompt-string ">") ; restore the original prompt setting so we
|
||||
; don't get "antelope?" as the prompt
|
||||
(define compute-length
|
||||
(lambda (x)
|
||||
(cond
|
||||
[(list? x) (length x)]
|
||||
[(vector? x) (vector-length x)]
|
||||
[(string? x) (string-length x)]
|
||||
[else (errorf 'compute-length "cannot handle ~s" ls)])))
|
||||
\endschemeinit
|
||||
\emph{The \scheme{compute-length} procedure behaves as follows:}
|
||||
\transcript
|
||||
(compute-length '())
|
||||
(compute-length '(a b c))
|
||||
(compute-length "abcd")
|
||||
(compute-length (vector 1 2 3 4 5 6))
|
||||
(compute-length compute-length)
|
||||
\endtranscript
|
||||
</pre>
|
||||
|
||||
|
||||
<p>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
produces the output shown below.
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
|
||||
<p>
|
||||
<i>The <tt>compute-length</tt> procedure behaves as follows:</i>
|
||||
|
||||
<p><tt>> (compute-length '())<br>
|
||||
|
||||
0<br>
|
||||
|
||||
> (compute-length '(a b c))<br>
|
||||
|
||||
3<br>
|
||||
|
||||
> (compute-length "abcd")<br>
|
||||
|
||||
4<br>
|
||||
|
||||
> (compute-length (vector 1 2 3 4 5 6))<br>
|
||||
|
||||
6<br>
|
||||
|
||||
> (compute-length compute-length)
|
||||
<br>
|
||||
<br>
|
||||
Exception in compute-length: cannot handle #<procedure compute-length><br>
|
||||
|
||||
Type (debug) to enter the debugger.</tt>
|
||||
<p></blockquote>
|
||||
|
||||
<p>
|
||||
the last line of input intentionally causes an error, which is
|
||||
displayed just as it would be displayed in a café.
|
||||
|
||||
<p>
|
||||
|
||||
<a name="g13"></a>
|
||||
|
||||
|
||||
<h3><a name="./stex:h13"></a>6. html-prep support for the <tt>tabular</tt> environment</h3>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
Support for tables comes with a few caveats:
|
||||
|
||||
<p>
|
||||
<ol>
|
||||
<a name="g14"></a><li><tt>@{}</tt> directives within <tt>tabular</tt>
|
||||
column specifiers are flat-out ignored for the time being.
|
||||
<a name="g15"></a><li><tt>|</tt> directives within <tt>tabular</tt>
|
||||
column specifiers are essentially ignored. Their only effect is
|
||||
to globally enable borders for the entire HTML table.
|
||||
<a name="g16"></a><li><tt>\hrule</tt> and <tt>\cline</tt> are not yet implemented.
|
||||
<a name="g17"></a><li>no warranty is expressed or implied.
|
||||
</ol>
|
||||
<p>
|
||||
|
||||
<p>
|
||||
The following code:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
\begin{tabular}{rcl|r}
|
||||
y &=& f(x) & without loss of generality \\
|
||||
z & \multicolumn{2}{r}{whee} & this is fun? \\
|
||||
\multicolumn{4}{c}{
|
||||
\begin{tabular}{cc}
|
||||
1 & 2 \\
|
||||
3 & 4
|
||||
\end{tabular}
|
||||
} \\
|
||||
a & b & c & d \\
|
||||
12345 & z & \multicolumn{2}{l}{\scheme{(define~x~"foo")}}
|
||||
\end{tabular}
|
||||
</pre>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
generates this table:
|
||||
|
||||
<p>
|
||||
<blockquote>
|
||||
<TABLE border="1"><TR><TD nowrap align="right">
|
||||
y </TD><TD nowrap align="center">=</TD><TD nowrap align="left"> f(x) </TD><TD nowrap align="right"> without loss of generality </TD></TR><TR><TD nowrap align="right">
|
||||
z </TD><TD nowrap colspan="2" align="right"> whee </TD><TD nowrap align="left"> this is fun? </TD></TR><TR><TD nowrap colspan="4" align="center">
|
||||
|
||||
<TABLE><TR><TD nowrap align="center">
|
||||
1 </TD><TD nowrap align="center"> 2 </TD></TR><TR><TD nowrap align="center">
|
||||
3 </TD><TD nowrap align="center"> 4
|
||||
</TD></TR></TABLE>
|
||||
</TD></TR><TR><TD nowrap align="right">
|
||||
a </TD><TD nowrap align="center"> b </TD><TD nowrap align="left"> c </TD><TD nowrap align="right"> d </TD></TR><TR><TD nowrap align="right">
|
||||
12345 </TD><TD nowrap align="center"> z </TD><TD nowrap colspan="2" align="left"> <tt>(define x "foo")</tt>
|
||||
</TD></TR></TABLE>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
|
||||
|
||||
© 1998-2016 R. Kent Dybvig and Oscar Waddell</body>
|
||||
</html>
|
BIN
stex/doc/stex.pdf
Normal file
BIN
stex/doc/stex.pdf
Normal file
Binary file not shown.
603
stex/doc/stex.stex
Normal file
603
stex/doc/stex.stex
Normal file
|
@ -0,0 +1,603 @@
|
|||
\documentclass{monograph}
|
||||
|
||||
\usepackage{scheme}
|
||||
|
||||
\iflatex
|
||||
\usepackage{fullpage}
|
||||
\pagestyle{plain}
|
||||
\fi
|
||||
|
||||
\ifhtml
|
||||
\documenttitle[stex.css]{Introduction to stex}
|
||||
\fi
|
||||
|
||||
\begin{document}
|
||||
\title{Introduction to stex}
|
||||
\author{R. Kent Dybvig and Oscar Waddell}
|
||||
\date{April 2016}
|
||||
\maketitle
|
||||
\def\copyrightnotice{\copyright~1998--2016 R. Kent Dybvig and Oscar Waddell}
|
||||
|
||||
\ifhtml
|
||||
\tableofcontents
|
||||
\fi
|
||||
|
||||
\iflatex
|
||||
% block paragraphs
|
||||
\setlength\parskip{4pt plus 1pt}
|
||||
\setlength\parindent{0pt}
|
||||
\renewenvironment{quotation}
|
||||
{\list{}{\listparindent 1.5em%
|
||||
\itemindent 0pt%
|
||||
\rightmargin \leftmargin
|
||||
\parsep 0pt plus 1pt}%
|
||||
\item\relax}
|
||||
{\endlist}
|
||||
\fi
|
||||
|
||||
\section{Overview}
|
||||
|
||||
The \emph{stex} package consists of two main programs and some supporting
|
||||
items, such as make files, make-file templates, class files, and style
|
||||
files.
|
||||
The two main programs are \textbf{scheme-prep} and \textbf{html-prep}.
|
||||
\textbf{scheme-prep} performs a conversion from ``stex''-formatted files
|
||||
into latex-formatted files, while \textbf{html-prep} converts (some)
|
||||
latex-formatted files into html-formatted files.
|
||||
|
||||
An stex file is really just a latex file extended with a handful of
|
||||
commands for including Scheme code (or pretty much any other kind of code,
|
||||
as long as you don't plan to use the Scheme-specific transcript support)
|
||||
in a document, plus a couple of additional features rather arbitrarily
|
||||
thrown in.
|
||||
|
||||
The subset of latex-formatted files \textbf{html-prep} is capable of
|
||||
handling is rather small but has nevertheless been useful for our
|
||||
purposes, which include producing html versions of a couple of books
|
||||
(\emph{The Scheme Programming Language}, Editions 2--4 and the Chez Scheme
|
||||
User's Guides for Versions 6--9), the scheme.com web site, class websites,
|
||||
class assignments, and various other documents.
|
||||
|
||||
\section{Installation}
|
||||
|
||||
A prerequisite to building and using stex is to have Chez Scheme or
|
||||
Petite Chez Scheme installed on your system.
|
||||
You'll also need pdflatex, dvips, ghostscript, and netbpm.
|
||||
We've run stex under Linux and OS X but have not tried to run it under
|
||||
Windows.
|
||||
|
||||
The simplest way to install stex for your personal use is to clone the
|
||||
stex directory into your home directory, cd into the stex directory,
|
||||
and run make:
|
||||
|
||||
\schemedisplay
|
||||
make BIN=\var{bindir}
|
||||
\endschemedisplay
|
||||
|
||||
where \var{bindir} is the directory where make will find the scheme or
|
||||
petite executables.
|
||||
|
||||
This will create a subdirectory, named for the installed Chez Scheme
|
||||
machine type, containing binary versions of the programs.
|
||||
|
||||
You can also use ``make install'' to make stex available for other users.
|
||||
|
||||
\schemedisplay
|
||||
sudo make install BIN=\var{bindir} LIB=\var{libdir}
|
||||
\endschemedisplay
|
||||
|
||||
where \var{bindir} is as described above, and \var{libdir} is the
|
||||
directory where the stex library directory should be installed.
|
||||
|
||||
\section{Usage notes}
|
||||
|
||||
The simplest way to get started with stex is to get this document to
|
||||
build (in the doc directory) and create your own document by cloning
|
||||
this document's source file (stex.stex) and make file (Makefile).
|
||||
If you've installed stex in your home directory, you should be able to
|
||||
build this document by running ``make'' without arguments in the doc
|
||||
directory.
|
||||
If you've installed stex elsewhere, you'll first have to modify the
|
||||
include for Mf-stex to reflect its installed location.
|
||||
|
||||
Makefile is where you declare your stex sources and various other things,
|
||||
like bibtex and graphics files.
|
||||
If you don't have anything much more complicated than this document,
|
||||
you might just need to change the line that declares the main stex entry
|
||||
point, i.e., the line that reads \scheme{x = stex}, to reflect the name
|
||||
of your document.
|
||||
|
||||
The make is orchestrated by Mf-stex, which knows how to run
|
||||
\textbf{scheme-prep}, \textbf{html-prep}, \textbf{pdflatex} (multiple
|
||||
times), and various other commands to produce both pdf and html versions
|
||||
of the stex document.
|
||||
|
||||
You can also consult the more elaborate stex source and make files for the
|
||||
Chez Scheme User's Guide in the csug directory of a Chez Scheme release.
|
||||
|
||||
\section{Basic stex commands}
|
||||
|
||||
\subsection{Inline code}
|
||||
|
||||
An stex document includes inline Scheme (or other) code via the
|
||||
\scheme{\scheme} command, e.g.:
|
||||
|
||||
\begin{quotation}
|
||||
\schemeverbatim
|
||||
When called with two arguments, \scheme{cons} creates a pair of the two
|
||||
arguments, e.g., \scheme{(cons 3 4)} produces \scheme{(3 . 4)}.
|
||||
\endschemeverbatim
|
||||
\end{quotation}
|
||||
|
||||
produces:
|
||||
|
||||
\begin{quotation}
|
||||
When called with two arguments, \scheme{cons} creates a pair of the two
|
||||
arguments, e.g., \scheme{(cons 3 4)} produces \scheme{(3 . 4)}.
|
||||
\end{quotation}
|
||||
|
||||
\subsection{Code displays}
|
||||
|
||||
An stex document includes out-of-line Scheme (or other) code via
|
||||
\scheme{\schemedisplay} and \scheme{\endschemedisplay}, e.g.:
|
||||
|
||||
\begin{quotation}
|
||||
\schemeverbatim
|
||||
\schemedisplay
|
||||
(define fact
|
||||
(lambda (x)
|
||||
"a light year is a measure of distance"))
|
||||
|
||||
(define fib
|
||||
(lambda (x)
|
||||
"a light year is a measure of time"))
|
||||
\endschemedisplay
|
||||
\endschemeverbatim
|
||||
\end{quotation}
|
||||
|
||||
produces:
|
||||
|
||||
\begin{quotation}
|
||||
\schemedisplay
|
||||
(define fact
|
||||
(lambda (x)
|
||||
"a light year is a measure of distance"))
|
||||
|
||||
(define fib
|
||||
(lambda (x)
|
||||
"a light year is a measure of time"))
|
||||
\endschemedisplay
|
||||
\end{quotation}
|
||||
|
||||
Within a Scheme display, \scheme{;=>} is converted into a double right arrow
|
||||
($\Rightarrow$), \scheme{;->} into a single right arrow ($\rightarrow$), and
|
||||
\scheme{;==} into a phantom of the same size.
|
||||
This is useful for showing what a piece of code translates or evaluates to,
|
||||
e.g.:
|
||||
|
||||
\begin{quotation}
|
||||
\schemeverbatim
|
||||
A \scheme{let} expression expands into a call to a \scheme{lambda}
|
||||
expression, e.g.:
|
||||
\schemedisplay
|
||||
(let ([a 17]) ;-> ((lambda (a) (+ a a))
|
||||
(+ a a)) ;== 17)
|
||||
\endschemedisplay
|
||||
|
||||
A \scheme{let} expression first evaluates the right-hand-side
|
||||
expression, then evaluates the body in an environment that binds
|
||||
the left-hand-side variable to the resulting value, e.g.:
|
||||
\schemedisplay
|
||||
(let ([a 17]) ;=> 17
|
||||
(+ a a))
|
||||
\endschemedisplay
|
||||
\endschemeverbatim
|
||||
\end{quotation}
|
||||
|
||||
produces
|
||||
|
||||
\begin{quotation}
|
||||
A \scheme{let} expression expands into a call to a \scheme{lambda}
|
||||
expression, e.g.:
|
||||
\schemedisplay
|
||||
(let ([a 17]) ;-> ((lambda (a) (+ a a))
|
||||
(+ a a)) ;== 17)
|
||||
\endschemedisplay
|
||||
|
||||
A \scheme{let} expression first evaluates the right-hand-side
|
||||
expression, then evaluates the body in an environment that binds
|
||||
the left-hand-side variable to the resulting value, e.g.:
|
||||
\schemedisplay
|
||||
(let ([a 17]) ;=> 17
|
||||
(+ a a))
|
||||
\endschemedisplay
|
||||
\end{quotation}
|
||||
|
||||
\subsection{Variables}
|
||||
|
||||
Code can include emphasized variables via the \scheme{\raw{{\schbackslash}var}} command, e.g.:
|
||||
|
||||
\begin{quotation}
|
||||
\schemeverbatim
|
||||
\scheme{(let ([\var{x} \var{e}]) \var{body})} binds the variable \var{x} to
|
||||
the value of \var{e} in \var{body}.
|
||||
\endschemeverbatim
|
||||
\end{quotation}
|
||||
|
||||
produces:
|
||||
|
||||
\begin{quotation}
|
||||
\scheme{(let ([\var{x} \var{e}]) \var{body})} binds the variable \var{x} to
|
||||
the value of \var{e} in \var{body}.
|
||||
\end{quotation}
|
||||
|
||||
If the text within a \scheme{\raw{{\schbackslash}var}} form contains an underscore, the
|
||||
following character or bracketed subform is converted into a subscript,
|
||||
e.g., \scheme{\raw{{\schbackslash}var{\schlbrace}abc\_3{\schrbrace}}}
|
||||
produces \var{abc_3}, and \scheme{\raw{{\schbackslash}var{\schlbrace}7e5\_{16}{\schrbrace}}}
|
||||
produces \var{7e5_{16}}.
|
||||
|
||||
\scheme{\raw{{\schbackslash}var}} forms may appear within a \scheme{\scheme} form, within a Scheme display
|
||||
formed by \scheme{\schemedisplay} and \scheme{\endschemedisplay} commands,
|
||||
or by itself outside of either.
|
||||
|
||||
\subsection{Raw text in code}
|
||||
|
||||
Raw text can be included in code via the \scheme{\raw{{\schbackslash}raw}} command.
|
||||
For example:
|
||||
|
||||
\begin{quotation}
|
||||
\schemeverbatim
|
||||
\schemedisplay
|
||||
(sqrt \raw{$x$}) \is \raw{$\sqrt{x}$}.
|
||||
\endschemedisplay
|
||||
\endschemeverbatim
|
||||
\end{quotation}
|
||||
|
||||
produces:
|
||||
|
||||
\begin{quotation}
|
||||
\schemedisplay
|
||||
(sqrt \raw{$x$}) ;=> \raw{$\sqrt{x}$}.
|
||||
\endschemedisplay
|
||||
\end{quotation}
|
||||
|
||||
\subsection{Generated output}
|
||||
|
||||
Output generated by a Scheme program can be inserted into the output via
|
||||
\scheme{\generated} and \scheme{\endgenerated} commands, e.g.:
|
||||
|
||||
\begin{quotation}
|
||||
\schemeverbatim
|
||||
\generated
|
||||
(let ()
|
||||
(define fibs
|
||||
(lambda (x y n)
|
||||
(if (= n 0)
|
||||
'()
|
||||
(cons x (fibs y (+ x y) (- n 1))))))
|
||||
(let ([n 5])
|
||||
(printf "first ~r primes: ~{~s~^, ~}\n" n (fibs 0 1 n))))
|
||||
\endgenerated
|
||||
\endschemeverbatim
|
||||
\end{quotation}
|
||||
|
||||
produces:
|
||||
|
||||
\begin{quotation}
|
||||
\generated
|
||||
(let ()
|
||||
(define fibs
|
||||
(lambda (x y n)
|
||||
(if (= n 0)
|
||||
'()
|
||||
(cons x (fibs y (+ x y) (- n 1))))))
|
||||
(let ([n 5])
|
||||
(printf "first ~r primes: ~{~s~^, ~}\n" n (fibs 0 1 n))))
|
||||
\endgenerated
|
||||
\end{quotation}
|
||||
|
||||
\subsection{Verbatim Scheme displays}
|
||||
|
||||
When special features, like \scheme{\raw{{\schbackslash}var}} forms, need to be
|
||||
suppressed within a Scheme display, a document can use
|
||||
\scheme{\schemeverbatim} and \scheme{\endschemeverbatim} instead of
|
||||
\scheme{\schemedisplay} and \scheme{\endschemedisplay}.
|
||||
This document makes extensive use of this feature.
|
||||
|
||||
\section{Scheme transcripts}
|
||||
|
||||
\subsection{Automatic transcript generation}
|
||||
|
||||
The \textbf{scheme-prep} package supports a
|
||||
\scheme{\transcript} command for automatically generating Scheme transcripts
|
||||
from input supplied in the document source.
|
||||
All text from the \scheme{\transcript} marker up to and including the
|
||||
\scheme{\endtranscript} marker is replaced with a transcript generated
|
||||
by supplying the intervening text as the input to a Scheme caf\'e (REPL).
|
||||
If the Scheme transcript needs to contain the sequence
|
||||
\scheme{\endtranscript}, a different terminator may be specified as an
|
||||
optional argument to \scheme{\transcript}.
|
||||
The terminator must be a backslash followed by one or more alphabetic
|
||||
characters, and is specified without the backslash in the optional argument.
|
||||
|
||||
Three pairs of commands may be redefined to customize the typesetting
|
||||
of different elements within generated transcripts.
|
||||
To modify the typesetting of error messages, redefine \scheme{\transerr}
|
||||
and \scheme{\endtranserr}.
|
||||
To modify the typesetting of user input read from the current input port
|
||||
of the caf\'e, redefine \scheme{\transin} and \scheme{\endtransin}.
|
||||
To modify the typesetting of program output written to the current
|
||||
output port of new caf\'e, redefine \scheme{\transout} and
|
||||
\scheme{\endtransout}.
|
||||
|
||||
For example, the following:
|
||||
|
||||
\begin{quotation}
|
||||
\schemeverbatim
|
||||
\transcript
|
||||
(define f
|
||||
(lambda (x) ; indentation and comments are
|
||||
(if (zero? x) ; preserved in the transcript
|
||||
1
|
||||
(* x (f (- x 1))))))
|
||||
(values f (f 0) (f 5) (f 20))
|
||||
(trace f)
|
||||
(f 4)
|
||||
\endtranscript
|
||||
\endschemeverbatim
|
||||
\end{quotation}
|
||||
|
||||
produces:
|
||||
|
||||
\begin{quotation}
|
||||
\transcript
|
||||
(define f
|
||||
(lambda (x) ; indentation and comments are
|
||||
(if (zero? x) ; preserved in the transcript
|
||||
1
|
||||
(* x (f (- x 1))))))
|
||||
(values f (f 0) (f 5) (f 20))
|
||||
(trace f)
|
||||
(f 4)
|
||||
\endtranscript
|
||||
\end{quotation}
|
||||
|
||||
The following example shows how to specify a different transcript
|
||||
terminator and shows the default formatting imposed by \scheme{\transerr},
|
||||
\scheme{\transin}, and \scheme{\transout}.
|
||||
|
||||
\begin{quotation}
|
||||
\schemeverbatim
|
||||
\transcript[\stopthistranscript]
|
||||
#e4.5
|
||||
(begin (display "Enter a character: ") (read-char))
|
||||
(begin (display "Enter a character: ") (read-char))Z
|
||||
(begin (clear-input-port) (display "Enter a character: ") (read-char))
|
||||
Z
|
||||
(list (read-char) (read-char) (read-char))abc def
|
||||
(define silly-repl
|
||||
(lambda (prompt)
|
||||
(display prompt)
|
||||
(let ([x (read)])
|
||||
(unless (eof-object? x)
|
||||
(let ([result (eval x)])
|
||||
(unless (eq? result (void))
|
||||
(pretty-print result))
|
||||
(silly-repl prompt))))))
|
||||
(silly-repl "Enter a Scheme expression: ")
|
||||
(list 1
|
||||
2
|
||||
3)
|
||||
(silly-repl "Now what? ")
|
||||
(define interview
|
||||
(lambda ()
|
||||
(let* ([fname (begin (display "First name: ") (read))]
|
||||
[lname (begin (display "Last name: ") (read))])
|
||||
(printf "Hello ~a ~a!~%" fname lname))))
|
||||
(interview)
|
||||
john
|
||||
doe
|
||||
#!eof
|
||||
(printf "good to be back~%")
|
||||
#!eof
|
||||
\stopthistranscript
|
||||
\endschemeverbatim
|
||||
\end{quotation}
|
||||
|
||||
produces:
|
||||
|
||||
\begin{quotation}
|
||||
\transcript[\stopthistranscript]
|
||||
#e4.5
|
||||
(begin (display "Enter a character: ") (read-char))
|
||||
(begin (display "Enter a character: ") (read-char))Z
|
||||
(begin (clear-input-port) (display "Enter a character: ") (read-char))
|
||||
Z
|
||||
(list (read-char) (read-char) (read-char))abc def
|
||||
(define silly-repl
|
||||
(lambda (prompt)
|
||||
(display prompt)
|
||||
(let ([x (read)])
|
||||
(unless (eof-object? x)
|
||||
(let ([result (eval x)])
|
||||
(unless (eq? result (void))
|
||||
(pretty-print result))
|
||||
(silly-repl prompt))))))
|
||||
(silly-repl "Enter a Scheme expression: ")
|
||||
(list 1
|
||||
2
|
||||
3)
|
||||
(silly-repl "Now what? ")
|
||||
(define interview
|
||||
(lambda ()
|
||||
(let* ([fname (begin (display "First name: ") (read))]
|
||||
[lname (begin (display "Last name: ") (read))])
|
||||
(printf "Hello ~a ~a!~%" fname lname))))
|
||||
(interview)
|
||||
john
|
||||
doe
|
||||
#!eof
|
||||
(printf "good to be back~%")
|
||||
#!eof
|
||||
\stopthistranscript
|
||||
\end{quotation}
|
||||
|
||||
Transcripts do not include a trailing prompt by design.
|
||||
This is done in such a way that an explicitly displayed string that
|
||||
happens to look like the prompt is not suppressed.
|
||||
For example:
|
||||
|
||||
\begin{quotation}
|
||||
\schemeverbatim
|
||||
\transcript
|
||||
(begin (display "> \n") (exit))
|
||||
\endtranscript
|
||||
\endschemeverbatim
|
||||
\end{quotation}
|
||||
|
||||
should leave the apparent prompt alone since it is generated as program
|
||||
output.
|
||||
|
||||
\begin{quotation}
|
||||
\transcript
|
||||
(begin (display "> \n") (exit))
|
||||
\endtranscript
|
||||
\end{quotation}
|
||||
|
||||
Prompt suppression works even with
|
||||
changes to \scheme{waiter-prompt-string}.
|
||||
For example:
|
||||
|
||||
\begin{quotation}
|
||||
\schemeverbatim
|
||||
\transcript
|
||||
(waiter-prompt-string "antelope? ")
|
||||
"no thanks"
|
||||
\endtranscript
|
||||
\endschemeverbatim
|
||||
\end{quotation}
|
||||
|
||||
produces no trailing "antelope? " prompt:
|
||||
|
||||
\begin{quotation}
|
||||
\transcript
|
||||
(waiter-prompt-string "antelope? ")
|
||||
"no thanks"
|
||||
\endtranscript
|
||||
\end{quotation}
|
||||
|
||||
\subsection{Loading initialization code}
|
||||
|
||||
The \scheme{stex} commands \scheme{\schemeinit} and \scheme{\endschemeinit}
|
||||
are used to bracket Scheme expressions that should be evaluated without
|
||||
generating a transcript of the results.
|
||||
This is useful, for example, when writing the description of a programming
|
||||
assignment. The solutions can be loaded via \scheme{\schemeinit} and a
|
||||
transcript showing how the solutions behave can be generated using the
|
||||
\scheme{\transcript} command.
|
||||
|
||||
For example, the following text:
|
||||
|
||||
\begin{quotation}
|
||||
\schemeverbatim
|
||||
\schemeinit
|
||||
(waiter-prompt-string ">") ; restore the original prompt setting so we
|
||||
; don't get "antelope?" as the prompt
|
||||
(define compute-length
|
||||
(lambda (x)
|
||||
(cond
|
||||
[(list? x) (length x)]
|
||||
[(vector? x) (vector-length x)]
|
||||
[(string? x) (string-length x)]
|
||||
[else (errorf 'compute-length "cannot handle ~s" ls)])))
|
||||
\endschemeinit
|
||||
\emph{The \scheme{compute-length} procedure behaves as follows:}
|
||||
\transcript
|
||||
(compute-length '())
|
||||
(compute-length '(a b c))
|
||||
(compute-length "abcd")
|
||||
(compute-length (vector 1 2 3 4 5 6))
|
||||
(compute-length compute-length)
|
||||
\endtranscript
|
||||
\endschemeverbatim
|
||||
\end{quotation}
|
||||
|
||||
produces the output shown below.
|
||||
|
||||
\begin{quotation}
|
||||
\schemeinit
|
||||
(waiter-prompt-string ">") ; restore the original prompt setting so we
|
||||
; don't get "antelope?" as the prompt
|
||||
(define compute-length
|
||||
(lambda (x)
|
||||
(cond
|
||||
[(list? x) (length x)]
|
||||
[(vector? x) (vector-length x)]
|
||||
[(string? x) (string-length x)]
|
||||
[else (errorf 'compute-length "cannot handle ~s" x)])))
|
||||
\endschemeinit
|
||||
\emph{The \scheme{compute-length} procedure behaves as follows:}
|
||||
\transcript
|
||||
(compute-length '())
|
||||
(compute-length '(a b c))
|
||||
(compute-length "abcd")
|
||||
(compute-length (vector 1 2 3 4 5 6))
|
||||
(compute-length compute-length)
|
||||
\endtranscript
|
||||
\end{quotation}
|
||||
|
||||
the last line of input intentionally causes an error, which is
|
||||
displayed just as it would be displayed in a caf\'e.
|
||||
|
||||
\section{html-prep support for the \texttt{tabular} environment}
|
||||
|
||||
Support for tables comes with a few caveats:
|
||||
|
||||
\begin{enumerate}
|
||||
\item \scheme{@\schlbrace\schrbrace} directives within \scheme{tabular}
|
||||
column specifiers are flat-out ignored for the time being.
|
||||
\item \scheme{|} directives within \scheme{tabular}
|
||||
column specifiers are essentially ignored. Their only effect is
|
||||
to globally enable borders for the entire HTML table.
|
||||
\item \scheme{\hrule} and \scheme{\cline} are not yet implemented.
|
||||
\item no warranty is expressed or implied.
|
||||
\end{enumerate}
|
||||
|
||||
The following code:
|
||||
|
||||
\begin{quotation}
|
||||
\begin{verbatim}
|
||||
\begin{tabular}{rcl|r}
|
||||
y &=& f(x) & without loss of generality \\
|
||||
z & \multicolumn{2}{r}{whee} & this is fun? \\
|
||||
\multicolumn{4}{c}{
|
||||
\begin{tabular}{cc}
|
||||
1 & 2 \\
|
||||
3 & 4
|
||||
\end{tabular}
|
||||
} \\
|
||||
a & b & c & d \\
|
||||
12345 & z & \multicolumn{2}{l}{\scheme{(define x "foo")}}
|
||||
\end{tabular}
|
||||
\end{verbatim}
|
||||
\end{quotation}
|
||||
|
||||
generates this table:
|
||||
|
||||
\begin{quotation}
|
||||
\begin{tabular}{rcl|r}
|
||||
y &=& f(x) & without loss of generality \\
|
||||
z & \multicolumn{2}{r}{whee} & this is fun? \\
|
||||
\multicolumn{4}{c}{
|
||||
\begin{tabular}{cc}
|
||||
1 & 2 \\
|
||||
3 & 4
|
||||
\end{tabular}
|
||||
} \\
|
||||
a & b & c & d \\
|
||||
12345 & z & \multicolumn{2}{l}{\scheme{(define x "foo")}}
|
||||
\end{tabular}
|
||||
\end{quotation}
|
||||
|
||||
\end{document}
|
54
stex/gifs/Makefile
Normal file
54
stex/gifs/Makefile
Normal file
|
@ -0,0 +1,54 @@
|
|||
gifs = ghostRightarrow.gif
|
||||
|
||||
density=-r90x90
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .tex .gif
|
||||
|
||||
# translate ps file to ppm, crop to minimum background, and translate ppm
|
||||
# to gif with white (background) transparent
|
||||
#
|
||||
.tex.gif:
|
||||
echo | latex $* &&\
|
||||
dvips -f < $*.dvi |\
|
||||
gs -q -dNOPAUSE -dSAFER -sDEVICE=ppmraw -sOutputFile=-\
|
||||
${density} - |\
|
||||
pnmcrop |\
|
||||
ppmtogif -transparent white > $*.gif
|
||||
/bin/rm -f $*.dvi $*.log *.aux
|
||||
test -f $*.gif && chmod 644 $*.gif
|
||||
|
||||
all: ${gifs}
|
||||
|
||||
# make ghostRightarrow.gif a completely transparent version of Rightarrow.ps
|
||||
#
|
||||
# translate ps to gif as above but w/o making white transparent, map black
|
||||
# to white, convert to ppm, and convert back to gif with white transparent
|
||||
#
|
||||
# could skip intermediate conversion to gif if we could map black to white
|
||||
# with some ppm tool
|
||||
#
|
||||
# it seems like should be able to replace last three steps with
|
||||
# giftrans -g '#000000=#ffffff' -t '#ffffff'
|
||||
# or at least
|
||||
# giftrans -g '#000000=#ffffff' | giftrans -t '#ffffff'
|
||||
# but giftrans changes only the first white color it sees, not all
|
||||
#
|
||||
ghostRightarrow.gif: Rightarrow.tex
|
||||
echo | latex Rightarrow &&\
|
||||
dvips -f < Rightarrow.dvi |\
|
||||
gs -q -dNOPAUSE -dSAFER -sDEVICE=ppmraw -sOutputFile=-\
|
||||
${density} - |\
|
||||
pnmcrop |\
|
||||
ppmtogif |\
|
||||
giftrans -g '#000000=#ffffff' |\
|
||||
giftopnm |\
|
||||
ppmtogif -transparent white > $*.gif
|
||||
/bin/rm -f Rightarrow.dvi Rightarrow.log Rightarrow.aux
|
||||
test -f $*.gif && chmod 644 $*.gif
|
||||
|
||||
clean:
|
||||
rm -f *.log *.aux *.dvi Make.out
|
||||
|
||||
distclean: clean
|
||||
rm -f *.gif
|
5
stex/gifs/Rightarrow.tex
Normal file
5
stex/gifs/Rightarrow.tex
Normal file
|
@ -0,0 +1,5 @@
|
|||
\documentclass[12pt]{article}
|
||||
\begin{document}
|
||||
\pagestyle{empty}
|
||||
$\Rightarrow$
|
||||
\end{document}
|
BIN
stex/gifs/ghostRightarrow.gif
Normal file
BIN
stex/gifs/ghostRightarrow.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 B |
2
stex/inputs/assign-prep.stex
Normal file
2
stex/inputs/assign-prep.stex
Normal file
|
@ -0,0 +1,2 @@
|
|||
\xdef\selfstudy#1{%
|
||||
\xedef\studylab{\genlab}\raw{\selfstudy}{#1}{\studylab}\label{\studylab}}
|
1119
stex/inputs/assignment.bst
Normal file
1119
stex/inputs/assignment.bst
Normal file
File diff suppressed because it is too large
Load diff
233
stex/inputs/assignment.cls
Normal file
233
stex/inputs/assignment.cls
Normal file
|
@ -0,0 +1,233 @@
|
|||
%%% assignment.cls
|
||||
|
||||
\ProvidesClass{assignment}
|
||||
|
||||
\def\ProvidesClass#1[#2]{\relax}
|
||||
|
||||
% \input article.cls
|
||||
\LoadClass{article}
|
||||
|
||||
\def\copyrightnotice{\ifauthor\copyright~\number\year~\theauthor\fi}
|
||||
\def\ps@plain{\let\@mkboth\@gobbletwo
|
||||
\let\@oddhead\@empty\def\@oddfoot{\reset@font
|
||||
\footer}\let\@evenhead\@empty\let\@evenfoot\@oddfoot}
|
||||
\def\footer{\hfil\ifnum\c@page =1 \copyrightnotice\else\thepage\fi\hfil}
|
||||
\let\trueenddocument=\enddocument
|
||||
\def\enddocument{
|
||||
\theselfstudy
|
||||
\trueenddocument}
|
||||
|
||||
\newif\iftitle\titlefalse
|
||||
\newif\ifauthor\authorfalse
|
||||
\newif\ifdate\datefalse
|
||||
\def\title#1{\def\thetitle{#1}\titletrue}
|
||||
\def\author#1{\def\theauthor{#1}\authortrue}
|
||||
\def\date#1{\def\thedate{#1}\datetrue}
|
||||
\def\maketitle{
|
||||
\begin{flushleft}
|
||||
\iftitle{\LARGE\textbf{\thetitle}} \\[6pt]\fi
|
||||
\ifauthor{\Large\textbf{\theauthor}} \\\fi
|
||||
\ifdate{\vskip 3pt\Large\textbf{\thedate}} \\\fi
|
||||
\end{flushleft}}
|
||||
|
||||
%%% to support hypertext index entries
|
||||
\def\hindex#1{\index} % ignore the label here---no links in printed version
|
||||
|
||||
\newcommand{\hyperlink}[3][]{#3}
|
||||
\newcommand{\href}[3][]{#3}
|
||||
\newcommand{\hpageref}[3][]{#3}
|
||||
\let\true@ref=\ref\renewcommand{\ref}[2][]{\true@ref{#2}}
|
||||
\let\true@pageref=\pageref\renewcommand{\pageref}[2][]{\true@pageref{#2}}
|
||||
|
||||
\newif\iflatex\latextrue
|
||||
\newif\ifhtml\htmlfalse
|
||||
|
||||
%%% table of contents
|
||||
\renewcommand{\@pnumwidth}{1.55em}
|
||||
\renewcommand{\@tocrmarg} {2.55em}
|
||||
\renewcommand{\@dotsep}{4.5}
|
||||
\setcounter{tocdepth}{2}
|
||||
\newcommand*{\l@chapter}[2]{%
|
||||
\ifnum \c@tocdepth >\m@ne
|
||||
\addpenalty{-\@highpenalty}%
|
||||
\vskip 1.0em \@plus\p@
|
||||
\setlength\@tempdima{1.5em}%
|
||||
\begingroup
|
||||
\parindent \z@ \rightskip \@pnumwidth
|
||||
\parfillskip -\@pnumwidth
|
||||
\leavevmode \bfseries
|
||||
\advance\leftskip\@tempdima
|
||||
\hskip -\leftskip
|
||||
#1\nobreak\hfil \nobreak\hbox to\@pnumwidth{\hss #2}\par
|
||||
\penalty\@highpenalty
|
||||
\endgroup
|
||||
\fi}
|
||||
\renewcommand*{\l@section}[2]{\expandafter\l@xection#1\hobbes{#2}}
|
||||
\renewcommand*{\l@subsection}[2]{\expandafter\l@subxection#1\hobbes{#2}}
|
||||
\renewcommand*{\l@subsubsection}[2]{\expandafter\l@subsubxection#1\hobbes{#2}}
|
||||
\def\lead{\leaders\hbox to .3em{{\footnotesize \hss.\hss}}\hfil}
|
||||
\def\l@xection#1\calvin#2\hobbes#3{%
|
||||
\strut#1.&\multispan{3}{#2~}\lead&~#3\cr
|
||||
&\multispan{3}{\hphantom{#2~\hspace{2em}}}\hfil&\cr
|
||||
}
|
||||
\def\l@subxection#1\calvin#2\hobbes#3{%
|
||||
\strut.&\multispan{2}{#2~}\lead&~#3\cr
|
||||
&&\multispan{2}{\hphantom{#2~\hspace{2em}}}\hfil&\cr
|
||||
}
|
||||
\def\l@subsubxection#1\calvin#2\hobbes#3{%
|
||||
\strut&.&\multispan{1}{#2~}\lead&~#3\cr
|
||||
&&&\multispan{1}{\hphantom{#2~\hspace{2em}}}\hfil&\cr
|
||||
}
|
||||
\def\inserttoc{
|
||||
\bigskip{\bfseries Contents}\medskip
|
||||
\begingroup\offinterlineskip
|
||||
\halign{\hfil##\hspace{.5em}&##\hfil\hspace{.5em}&##\hfil\hspace{.5em}&##\hfil\hspace{.5em}&\hfil##\cr
|
||||
\input{\jobname.toc}
|
||||
}\endgroup}
|
||||
\renewcommand{\tableofcontents}{%
|
||||
\def\numberline ##1{##1\calvin}
|
||||
\IfFileExists{\jobname.toc}{\inserttoc}{\typeout{No file \jobname.toc}}
|
||||
\begingroup
|
||||
\def\contentsline##1##2##3{\relax}
|
||||
\@starttoc{toc}
|
||||
\endgroup
|
||||
}
|
||||
|
||||
\newcounter{exercise}
|
||||
\renewcommand{\theexercise}{\arabic{exercise}}
|
||||
\def\@startexercise{\par\bigskip
|
||||
\refstepcounter{exercise}\goodbreak
|
||||
\par\hrule width \hsize{\hfil}\\\nobreak
|
||||
\textbf{Exercise \theexercise. }\ignorespaces}
|
||||
\newenvironment{exercise}
|
||||
{\begingroup
|
||||
\def\afterschemedisplay{\removelastskip\penalty10000\vskip5pt}
|
||||
\let\newexercise=\@startexercise\newexercise}
|
||||
{\par\removelastskip\penalty10000\kern6pt\hrule width \hsize{\hfil}\endgroup}
|
||||
\newcounter{subexercise}[exercise]
|
||||
\renewcommand{\thesubexercise}{\theexercise\alph{subexercise}}
|
||||
\newcommand{\subexercise}{\par\refstepcounter{subexercise}\medskip\textbf{\thesubexercise. }}
|
||||
|
||||
%%% self study questions
|
||||
%%% we'd like to create the self study file and load it all on the same
|
||||
%%% pass, but this is not TeXnically feasible if we want to include page
|
||||
%%% numbers. TeX delays file writing and closing until its output
|
||||
%%% routines run so that it can get the page numbers correct, so the file
|
||||
%%% may not be complete by the time we input it. If we use \immediate
|
||||
%%% to get the writing and closing done earlier, the page numbers won't
|
||||
%%% be correct. so we create \jobname.rawsst and count on the make file to
|
||||
%%% copy it to \jobname.sst before the next run. We will need to do something
|
||||
%%% even more elaborate once we start generating a book with self-study
|
||||
%%% questions in each chapter.
|
||||
\newwrite\sstudy
|
||||
\newcounter{selfstudycounter}
|
||||
\renewcommand{\theselfstudycounter}{\arabic{selfstudycounter}}
|
||||
\openout\sstudy=\jobname.rawsst
|
||||
\newif\ifselfstudy\selfstudyfalse
|
||||
\def\selfstudy{\stepcounter{selfstudycounter}\selfstudytrue
|
||||
\begingroup\@sanitize\addselfstudy}
|
||||
\def\addselfstudy#1#2{\endgroup
|
||||
\edef\sstudyhead{\write\sstudy}%
|
||||
\edef\sstudyentry{{\string\sstudyentry{#1}{#2}{\theselfstudycounter}}}%
|
||||
\expandafter\sstudyhead\sstudyentry}
|
||||
\def\theselfstudy{\ifselfstudy\realselfstudy\fi}
|
||||
\def\realselfstudy{\begingroup
|
||||
\def\sstudyentry##1##2##3{\par\bigskip\textbf{##3. } ##1 [Page \pageref{##2}]}
|
||||
\section{Questions for self study}\label{section:selfstudy}
|
||||
\input \jobname.sst
|
||||
\endgroup}
|
||||
|
||||
%%% bibliography
|
||||
\newdimen\bibindent \bibindent=1.5em
|
||||
\renewcommand{\newblock}{}
|
||||
\renewenvironment{thebibliography}[1]
|
||||
{\chapter{Bibliography}
|
||||
\list{\@biblabel{\arabic{enumiv}}}%
|
||||
{\settowidth\labelwidth{\@biblabel{#1}}%
|
||||
\leftmargin\labelwidth
|
||||
\advance\leftmargin\labelsep
|
||||
\usecounter{enumiv}%
|
||||
\let\p@enumiv\@empty
|
||||
\renewcommand{\theenumiv}{\arabic{enumiv}}}%
|
||||
\renewcommand{\newblock}{\hskip .11em \@plus.33em \@minus.07em}%
|
||||
\sloppy\clubpenalty4000\widowpenalty4000%
|
||||
\sfcode`\.=\@m}
|
||||
{\def\@noitemerr
|
||||
{\@latex@warning{Empty `thebibliography' environment}}%
|
||||
\endlist}
|
||||
|
||||
%%% index
|
||||
\def\notsupposedtobehereindexname{\indexname}
|
||||
\renewenvironment{theindex}
|
||||
{\if@openright\cleardoublepage\else\clearpage\fi
|
||||
\raggedright
|
||||
\columnseprule \z@
|
||||
\columnsep 35\p@
|
||||
\twocolumn[\plainchapterhead{\indexname}]%
|
||||
\addcontentsline{toc}{chapter}{\indexname}%
|
||||
\chaptermark{\indexname}{\notsupposedtobehereindexname}%
|
||||
\thispagestyle{plain}\parindent\z@
|
||||
\parskip\z@ \@plus .3\p@\relax
|
||||
\let\item\@idxitem}
|
||||
{\clearpage}
|
||||
\renewcommand{\@idxitem} {\par\hangindent 40\p@}
|
||||
\renewcommand{\subitem} {\par\hangindent 40\p@ \hspace*{20\p@}}
|
||||
\renewcommand{\subsubitem}{\par\hangindent 40\p@ \hspace*{30\p@}}
|
||||
\renewcommand{\indexspace}{\par \vskip 10\p@ \@plus5\p@ \@minus3\p@\relax}
|
||||
|
||||
%%% latex.ltx redefinitions
|
||||
%% leave padding page blank (no header)
|
||||
\def\cleardoublepage{\clearpage\if@twoside \ifodd\c@page\else
|
||||
{\pagestyle{empty}\hbox{}\newpage\if@twocolumn\hbox{}\newpage\fi}\fi\fi}
|
||||
%% change section headers to "1.1. foo" instead of "1.1 foo"
|
||||
\def\@seccntformat#1{\csname the#1\endcsname. }
|
||||
%% change numbered table of contents lines to "1.1. foo" instead of "1.1 foo"
|
||||
\def\numberline#1{#1. }
|
||||
|
||||
\renewenvironment{description}
|
||||
{\list{}{\labelwidth\z@ \itemindent-\leftmargin
|
||||
\let\makelabel\descriptionlabel}}
|
||||
{\endlist}
|
||||
\renewcommand*\descriptionlabel[1]{\hspace\labelsep #1}
|
||||
|
||||
\def\itemvdots{\item[] \mbox{\vdots}}
|
||||
|
||||
\def\parheader#1 {\medskip\noindent{\bf #1.}~~}
|
||||
|
||||
%%% grammar support
|
||||
\newenvironment{grammar}
|
||||
{\begingroup
|
||||
\def\orbar{&\bar&}
|
||||
\def\nobar{&&}
|
||||
\def\longis{&$\longrightarrow$&}
|
||||
\penalty-100\vskip 4pt\begin{tabular}{lcl}}
|
||||
{\end{tabular}\penalty-200\vskip 4pt\endgroup}
|
||||
\def\bar{$\vert$}
|
||||
\def\ang#1{$\langle${\small\rm{}#1}$\rangle$}
|
||||
\def\kstar{\raise.5ex\hbox{\scheme{*}}}
|
||||
\def\kplus{\raise.5ex\hbox{\scheme{+}}}
|
||||
|
||||
\newcounter{alphacount}
|
||||
\def\alphalabel{\textit{\alph{alphacount}}.}
|
||||
\newenvironment{alphalist}
|
||||
{\begingroup\let\beforeschemedisplay=\relax\let\afterschemedisplay=\relax
|
||||
\begin{list}{\alphalabel}{\usecounter{alphacount}\itemsep=0pt\parsep=0pt%
|
||||
\topsep=0pt}}
|
||||
{\end{list}\endgroup}
|
||||
|
||||
%%% final set up
|
||||
\renewcommand{\contentsname}{Contents}
|
||||
\newcommand{\bibname}{Bibliography}
|
||||
\renewcommand{\indexname}{Index}
|
||||
\renewcommand{\today}{\ifcase\month\or
|
||||
January\or February\or March\or April\or May\or June\or
|
||||
July\or August\or September\or October\or November\or December\fi
|
||||
\space\number\day, \number\year}
|
||||
\setlength\columnsep{10\p@}
|
||||
\setlength\columnseprule{0\p@}
|
||||
\pagestyle{headings}
|
||||
\pagenumbering{arabic}
|
||||
|
||||
\if@twoside\else\raggedbottom\fi
|
||||
\endinput
|
||||
%%% end of assignment.cls
|
173
stex/inputs/assignment.hcls
Normal file
173
stex/inputs/assignment.hcls
Normal file
|
@ -0,0 +1,173 @@
|
|||
%%% assignment.hcls
|
||||
|
||||
\newif\iflatex\latexfalse
|
||||
\newif\ifhtml\htmltrue
|
||||
|
||||
% should be built in
|
||||
\newenvironment{center}
|
||||
{\raw{<center>}}
|
||||
{\raw{</center>}}
|
||||
|
||||
\def\copyrightnotice{\ifauthor\par\raw{<hr>}\copyright~\year~\theauthor\par\fi}
|
||||
\let\trueenddocument=\enddocument
|
||||
\def\enddocument{
|
||||
\theselfstudy
|
||||
\begin{divertoutput}[toc]
|
||||
\ifsubsubsec\raw{</table></td></tr>}\fi
|
||||
\ifsubsec\raw{</table></td></tr>}\fi
|
||||
\end{divertoutput}
|
||||
\copyrightnotice\trueenddocument}
|
||||
|
||||
\newif\iftitle\titlefalse
|
||||
\newif\ifdate\datefalse
|
||||
\newif\ifauthor\authorfalse
|
||||
\def\title#1{\def\thetitle{#1}\titletrue}
|
||||
\def\date#1{\def\thedate{#1}\datetrue}
|
||||
\def\author#1{\def\theauthor{#1}\authortrue}
|
||||
\def\maketitle{%
|
||||
\iftitle\raw{<h1>}\thetitle\raw{</h1>}\fi
|
||||
\ifauthor
|
||||
\ifdate
|
||||
\raw{<h2>}\theauthor\\\thedate\raw{</h2>}%
|
||||
\else
|
||||
\raw{<h2>}\theauthor\raw{</h2>}%
|
||||
\fi
|
||||
\else
|
||||
\ifdate\raw{<h2>}\thedate\raw{</h2>}\fi
|
||||
\fi}
|
||||
|
||||
%%% table of contents
|
||||
\newif\ifsubsec\subsecfalse
|
||||
\newif\ifsubsubsec\subsubsecfalse
|
||||
\newcommand{\tableofcontents}{
|
||||
\raw{<table cellpadding=0 cellspacing=0>}
|
||||
\rawinput{\jobname.htoc}
|
||||
\raw{</table>}
|
||||
\openrawfile{toc}{\jobname.htoc}}
|
||||
|
||||
% we \let\label=\nolabel within toc entries to avoid inserting
|
||||
% labels that belong with the labeled entity, not the toc
|
||||
\def\nolabel#1{}
|
||||
|
||||
%%% \section
|
||||
\newcounter{section}
|
||||
\renewcommand{\thesection}{\arabic{section}}
|
||||
\newcommand{\section}[1]{
|
||||
\refstepcounter{section}
|
||||
\edef\templabel{\genlab}
|
||||
\raw{<h3><br>}\label{\templabel}\thesection. #1\raw{</h3>}
|
||||
\begin{divertoutput}[toc]
|
||||
\ifsubsubsec\raw{</table></td></tr>}\fi
|
||||
\subsubsecfalse
|
||||
\ifsubsec\raw{</table></td></tr>}\fi
|
||||
\subsecfalse
|
||||
\raw{<tr><td align="right">}\textbf{\thesection.~}\raw{<td>}\textbf{\href[plain]{\templabel}{{\let\label=\nolabel #1}}}\raw{</td></tr>}
|
||||
\end{divertoutput}
|
||||
}
|
||||
|
||||
%%% \subsection
|
||||
\newcounter{subsection}[section]
|
||||
\renewcommand{\thesubsection}{\thesection.\arabic{subsection}}
|
||||
\newcommand{\subsection}[1]{
|
||||
\refstepcounter{subsection}
|
||||
\edef\templabel{\genlab}
|
||||
\raw{<h4><br>}\label{\templabel}\thesubsection. #1\raw{</h4>}
|
||||
\begin{divertoutput}[toc]
|
||||
\ifsubsubsec\raw{</table></td></tr>}\fi
|
||||
\subsubsecfalse
|
||||
\ifsubsec\else\raw{<tr><td></td><td><table cellpadding=0 cellspacing=0>}\fi
|
||||
\subsectrue
|
||||
\raw{<tr><td>}\textbf{\thesubsection.~}\raw{</td><td>}\textbf{\href[plain]{\templabel}{{\let\label=\nolabel #1}}}\raw{</td></tr>}
|
||||
\end{divertoutput}
|
||||
}
|
||||
|
||||
%%% \subsubsection
|
||||
\newcounter{subsubsection}[subsection]
|
||||
\renewcommand{\thesubsubsection}{\thesubsection.\arabic{subsubsection}}
|
||||
\newcommand{\subsubsection}[1]{
|
||||
\refstepcounter{subsubsection}
|
||||
\edef\templabel{\genlab}
|
||||
\raw{<h4><br>}\label{\templabel}\thesubsubsection. #1\raw{</h4>}
|
||||
\begin{divertoutput}[toc]
|
||||
\ifsubsubsec\else\raw{<tr><td></td><td><table cellpadding=0 cellspacing=0>}\fi
|
||||
\subsubsectrue
|
||||
\raw{<tr><td>}\textbf{\thesubsubsection.~}\raw{</td><td>}\textbf{\href[plain]{\templabel}{{\let\label=\nolabel #1}}}\raw{</td></tr>}
|
||||
\end{divertoutput}
|
||||
}
|
||||
|
||||
%%% figure
|
||||
\newcounter{figure}
|
||||
\renewcommand{\thefigure}{\arabic{figure}}
|
||||
\newcommand{\caption}[1]{\\ Figure \thefigure.~#1}
|
||||
\newenvironment{figure}
|
||||
{\begingroup\refstepcounter{figure}}
|
||||
{\endgroup}
|
||||
|
||||
%%% exercise
|
||||
\newcounter{exercise}
|
||||
\renewcommand{\theexercise}{\arabic{exercise}}
|
||||
\def\@startexercise{\refstepcounter{exercise}
|
||||
\raw{<hr>}
|
||||
\textbf{Exercise \theexercise. }}
|
||||
\newenvironment{exercise}
|
||||
{\begingroup\def\newexercise{\@startexercise}\newexercise}
|
||||
{\raw{<hr>}}
|
||||
\newcounter{subexercise}[exercise]
|
||||
\renewcommand{\thesubexercise}{\theexercise\alph{subexercise}}
|
||||
\newcommand{\subexercise}{\par\refstepcounter{subexercise}\textbf{\thesubexercise. }}
|
||||
|
||||
%%% self-study
|
||||
\newif\ifselfstudy\selfstudyfalse
|
||||
\def\selfstudy#1#2{\selfstudytrue}
|
||||
\def\theselfstudy{\ifselfstudy\realselfstudy\fi}
|
||||
\def\realselfstudy{\begingroup
|
||||
\def\sstudyentry##1##2##3{\raw{<p>}\textbf{##3.} ##1 [see \hyperlink{######2}{here}]\raw{</p>}}
|
||||
\section{Questions for self study}\label{section:selfstudy}
|
||||
\input{\jobname.sst}
|
||||
\endgroup}
|
||||
|
||||
%%% alphalist
|
||||
\newcounter{alphalist}
|
||||
\def\alphalist{\begingroup\setcounter{alphalist}{0}
|
||||
\def\endalphalistitem{}%
|
||||
\renewcommand{\item}{\endalphalistitem
|
||||
\def\endalphalistiem{\raw{</td></tr>}}%
|
||||
\stepcounter{alphalist}%
|
||||
\raw{<tr valign=top><td>}\alph{alphalist}.\raw{</td><td>}}
|
||||
\raw{<table>}}
|
||||
\def\endalphalist{\endalphalistitem\raw{</table>}\endgroup}
|
||||
|
||||
%%% define our own (compact) description environment
|
||||
\def\description{\begingroup
|
||||
\renewcommand{\item}[1][]{\raw{<dt>}##1\raw{<dd>}}\raw{<dl compact>}}
|
||||
\def\enddescription{\raw{</dl>}\endgroup}
|
||||
|
||||
%%% index
|
||||
\newcommand{\see}[2]{\emph{see} #1}
|
||||
\newenvironment{theindex}
|
||||
{\begingroup\newcommand{\itemindent}{\raw{<tt> </tt>}}
|
||||
\renewcommand{\item}{\raw{<br>}}
|
||||
\newcommand{\subitem}{\raw{<br>}\itemindent}
|
||||
\newcommand{\subsubitem}{\raw{<br>}\itemindent\itemindent}}
|
||||
{\par\endgroup}
|
||||
|
||||
\def\parheader#1 {\medskip\noindent{\bf #1.}~~}
|
||||
|
||||
%%% grammar support
|
||||
\newenvironment{grammar}
|
||||
{\begingroup
|
||||
\def\orbar{&\bar&}
|
||||
\def\nobar{&&}
|
||||
\def\longis{&$\longrightarrow$&}
|
||||
\begin{tabular}{lcl}}
|
||||
{\end{tabular}\endgroup}
|
||||
\def\bar{\raw{|}}
|
||||
\def\kplus{\raw{<sup>+</sup>}}
|
||||
\def\kstar{\raw{*}}
|
||||
\def\ang#1{\raw{<}#1\raw{>}}
|
||||
|
||||
\def\mbox#1{#1}
|
||||
|
||||
%%% hyperlink support
|
||||
\newcommand{\hyperlink}[3][]{\raw{<a #1 href="}\url{#2}\raw{">}#3\raw{</a>}}
|
||||
|
92
stex/inputs/exam.cls
Normal file
92
stex/inputs/exam.cls
Normal file
|
@ -0,0 +1,92 @@
|
|||
%%% exam.cls
|
||||
|
||||
\ProvidesClass{exam}
|
||||
|
||||
\def\ProvidesClass#1[#2]{\relax}
|
||||
|
||||
\input article.cls
|
||||
|
||||
\newif\iftitle\titlefalse
|
||||
\newif\ifauthor\authorfalse
|
||||
\def\title#1{\def\thetitle{#1}\titletrue}
|
||||
\def\author#1{\def\theauthor{#1}\authortrue}
|
||||
\def\maketitle{
|
||||
\begin{flushleft}
|
||||
\iftitle{\LARGE\textbf{\thetitle}} \\[6pt]\fi
|
||||
\ifauthor{\Large\textbf{\theauthor}} \\\fi
|
||||
\end{flushleft}}
|
||||
|
||||
\newcounter{quiz}
|
||||
\renewcommand{\thequiz}{\arabic{quiz}}
|
||||
\newenvironment{quiz}
|
||||
{\refstepcounter{quiz}
|
||||
\ifnum\thequiz>1\pagebreak\fi
|
||||
\centerline{\baselineskip=18pt
|
||||
\hbox to 3in{\vtop{\noindent \quizname\\\quizdate}}
|
||||
\hfill
|
||||
\hbox to 3in{\vtop{\noindent Name:\\Network ID:\\Lab section:\\Lecture section:}}}
|
||||
\bigskip}
|
||||
{}
|
||||
|
||||
\newcounter{problem}[quiz]
|
||||
\renewcommand{\theproblem}{\arabic{problem}}
|
||||
\newenvironment{problem}
|
||||
{\par\bigskip\refstepcounter{problem}
|
||||
\goodbreak
|
||||
\par\nobreak
|
||||
\textbf{Problem \theproblem. }}
|
||||
{\removelastskip\bigskip\vfill}
|
||||
\newcounter{subproblem}[problem]
|
||||
\renewcommand{\thesubproblem}{\alph{subproblem}}
|
||||
\newcommand{\subproblem}{\par\refstepcounter{subproblem}\medskip\textbf{\theproblem\thesubproblem. }}
|
||||
|
||||
%%% latex.ltx redefinitions
|
||||
%% change section headers to "1.1. foo" instead of "1.1 foo"
|
||||
\def\@seccntformat#1{\csname the#1\endcsname. }
|
||||
|
||||
\renewenvironment{description}
|
||||
{\list{}{\labelwidth\z@ \itemindent-\leftmargin
|
||||
\let\makelabel\descriptionlabel}}
|
||||
{\endlist}
|
||||
\renewcommand*\descriptionlabel[1]{\hspace\labelsep #1}
|
||||
|
||||
\def\itemvdots{\item[] \mbox{\vdots}}
|
||||
|
||||
\def\parheader#1 {\medskip\noindent{\bf #1.}~~}
|
||||
|
||||
\newenvironment{grammar}
|
||||
{\begingroup
|
||||
\def\orbar{\hbox to 2em{\hfil}$\vert$\hbox to .75em{\hfil}}
|
||||
\def\longis{ $\longrightarrow$\hbox to .75em{\hfil}}
|
||||
\penalty-100\vskip 6pt plus 1pt\parindent=0pt\interlinepenalty=5000}
|
||||
{\penalty-200\vskip6pt plus 1pt\endgroup}
|
||||
|
||||
\def\bar{$\vert$}
|
||||
\def\ang#1{$\langle${\small\rm{}#1}$\rangle$}
|
||||
\def\kstar{\raise.5ex\hbox{\scheme{*}}}
|
||||
\def\kplus{\raise.5ex\hbox{\scheme{+}}}
|
||||
|
||||
\newcounter{alphacount}
|
||||
\def\alphalabel{\textit{\alph{alphacount}}.}
|
||||
\newenvironment{alphalist}
|
||||
{\begingroup\let\beforeschemedisplay=\relax\let\afterschemedisplay=\relax
|
||||
\begin{list}{\alphalabel}{\usecounter{alphacount}\itemsep=0pt\parsep=0pt%
|
||||
\topsep=0pt}}
|
||||
{\end{list}\endgroup}
|
||||
|
||||
%%% final set up
|
||||
\renewcommand{\contentsname}{Contents}
|
||||
\newcommand{\bibname}{Bibliography}
|
||||
\renewcommand{\indexname}{Index}
|
||||
\renewcommand{\today}{\ifcase\month\or
|
||||
January\or February\or March\or April\or May\or June\or
|
||||
July\or August\or September\or October\or November\or December\fi
|
||||
\space\number\day, \number\year}
|
||||
\setlength\columnsep{10\p@}
|
||||
\setlength\columnseprule{0\p@}
|
||||
\pagestyle{headings}
|
||||
\pagenumbering{arabic}
|
||||
|
||||
\if@twoside\else\raggedbottom\fi
|
||||
\endinput
|
||||
%%% end of assignment.cls
|
29
stex/inputs/fullpage.sty
Normal file
29
stex/inputs/fullpage.sty
Normal file
|
@ -0,0 +1,29 @@
|
|||
% This is FULLPAGE.STY by H.Partl, Version 2 as of 15 Dec 1988.
|
||||
% Document Style Option to fill the paper just like Plain TeX.
|
||||
|
||||
\typeout{Style Option FULLPAGE Version 2 as of 15 Dec 1988}
|
||||
|
||||
\topmargin 0pt
|
||||
\advance \topmargin by -\headheight
|
||||
\advance \topmargin by -\headsep
|
||||
|
||||
\textheight 8.9in
|
||||
|
||||
\oddsidemargin 0pt
|
||||
\evensidemargin \oddsidemargin
|
||||
\marginparwidth 0.5in
|
||||
|
||||
\textwidth 6.5in
|
||||
|
||||
|
||||
% For users of A4 paper: The above values are suited for american 8.5x11in
|
||||
% paper. If your output driver performs a conversion for A4 paper, keep
|
||||
% those values. If your output driver conforms to the TeX standard (1in/1in),
|
||||
% then you should add the following commands to center the text on A4 paper:
|
||||
|
||||
% \advance\hoffset by -3mm % A4 is narrower.
|
||||
% \advance\voffset by 8mm % A4 is taller.
|
||||
|
||||
\endinput
|
||||
|
||||
|
15
stex/inputs/grammar.hsty
Normal file
15
stex/inputs/grammar.hsty
Normal file
|
@ -0,0 +1,15 @@
|
|||
%%% grammar support
|
||||
\newenvironment{grammar}
|
||||
{\begingroup
|
||||
\def\orbar{\raw{</td><td align=center>|</td><td nowrap>}}
|
||||
\def\nobar{\raw{</td><td align=center></td><td nowrap>}}
|
||||
\def\longis{\raw{</td><td align=center>}$\longrightarrow$\raw{</td><td nowrap>}}
|
||||
\def\\{\raw{</td></tr><tr><td nowrap>}}
|
||||
\raw{<table><tr><td nowrap>}}
|
||||
{\raw{</td></tr></table>}\endgroup}
|
||||
|
||||
\def\bar{\raw{|}}
|
||||
\def\kplus{\raw{<sup>+</sup>}}
|
||||
\def\kstar{\raw{*}}
|
||||
\def\ang#1{\raw{<}#1\raw{>}}
|
||||
|
12
stex/inputs/grammar.sty
Normal file
12
stex/inputs/grammar.sty
Normal file
|
@ -0,0 +1,12 @@
|
|||
\newenvironment{grammar}
|
||||
{\begingroup
|
||||
\def\orbar{\hbox to 2em{\hfil}$\vert$\hbox to .75em{\hfil}}
|
||||
\def\nobar{\hbox to 2em{\hfil}\phantom{$\vert$}\hbox to .75em{\hfil}}
|
||||
\def\longis{ $\longrightarrow$\hbox to .75em{\hfil}}
|
||||
\penalty-100\vskip 6pt plus 1pt\parindent=0pt\interlinepenalty=5000}
|
||||
{\penalty-200\vskip6pt plus 1pt\endgroup}
|
||||
|
||||
\def\bar{$\vert$}
|
||||
\def\ang#1{$\langle${\small\rm{}#1}$\rangle$}
|
||||
\def\kstar{\raise.5ex\hbox{\scheme{*}}}
|
||||
\def\kplus{\raise.5ex\hbox{\scheme{+}}}
|
49
stex/inputs/html-prep.tex
Normal file
49
stex/inputs/html-prep.tex
Normal file
|
@ -0,0 +1,49 @@
|
|||
%%% html-prep.tex
|
||||
|
||||
%%% /* these don't handle nesting properly, i.e., nested \emph */
|
||||
\def\emph#1{\raw{<i>}#1\raw{</i>}}
|
||||
\def\textit#1{\raw{<i>}#1\raw{</i>}}
|
||||
\def\textsl#1{\raw{<i>}#1\raw{</i>}} % really want slant font
|
||||
\def\textbf#1{\raw{<b>}#1\raw{</b>}}
|
||||
\def\texttt#1{\raw{<tt>}#1\raw{</tt>}}
|
||||
|
||||
\def\copyright{\raw{©}}
|
||||
|
||||
\def\protect{}
|
||||
\def\bigskip{\raw{<p>}}
|
||||
\def\medskip{\raw{<p>}}
|
||||
\def\smallskip{\raw{<p>}}
|
||||
\def\nobreak{}
|
||||
\def\noindent{}
|
||||
\def\_{\raw{_}}
|
||||
\def\par{\raw{
|
||||
<p>}}
|
||||
\def\dots{\raw{...}}
|
||||
\def\vdots{$\vdots$}
|
||||
\def\null{}
|
||||
\def\${\raw{$}}
|
||||
\def\&{\raw{&}}
|
||||
\def\%{\raw{%}}
|
||||
\def\#{\raw{##}}
|
||||
|
||||
\newcommand{\item}[1][]{\itemoutsideoflist}
|
||||
\def\itemize{\begingroup
|
||||
\renewcommand{\item}[1][]{\raw{<li>}##1}\raw{<ul>}}
|
||||
\def\enditemize{\raw{</ul>}\endgroup\par}
|
||||
\newcounter{enumeratecounter}
|
||||
\def\enumerate{\begingroup\setcounter{enumeratecounter}{0}%
|
||||
\renewcommand{\item}[1][]{\refstepcounter{enumeratecounter}\raw{<li>}##1}\raw{<ol>}}
|
||||
\def\endenumerate{\raw{</ol>}\endgroup\par}
|
||||
\def\description{\begingroup
|
||||
\renewcommand{\item}[1][]{\raw{<dt>}##1\raw{<dd>}}\raw{<dl>}}
|
||||
\def\enddescription{\raw{</dl>}\endgroup\par}
|
||||
|
||||
\newenvironment{flushleft}{}{}
|
||||
\newenvironment{thebibliography}[1]
|
||||
{\begingroup\def\newblock{}}
|
||||
{\endgroup}
|
||||
|
||||
\newenvironment{quotation}
|
||||
{\raw{<blockquote>}}
|
||||
{\raw{</blockquote>}}
|
||||
|
158
stex/inputs/monograph.cls
Normal file
158
stex/inputs/monograph.cls
Normal file
|
@ -0,0 +1,158 @@
|
|||
%%% monograph.cls
|
||||
|
||||
\ProvidesClass{monograph}
|
||||
|
||||
\def\ProvidesClass#1[#2]{\relax}
|
||||
|
||||
\input article.cls
|
||||
|
||||
\def\copyrightnotice{\ifauthor\copyright~\number\year~\theauthor\fi}
|
||||
\def\ps@plain{\let\@mkboth\@gobbletwo
|
||||
\let\@oddhead\@empty\def\@oddfoot{\reset@font
|
||||
\footer}\let\@evenhead\@empty\let\@evenfoot\@oddfoot}
|
||||
\def\footer{\hfil\ifnum\c@page =1 \copyrightnotice\else\thepage\fi\hfil}
|
||||
|
||||
\newif\iftitle\titlefalse
|
||||
\newif\ifauthor\authorfalse
|
||||
\newif\ifdate\datefalse
|
||||
\def\title#1{\def\thetitle{#1}\titletrue}
|
||||
\def\author#1{\def\theauthor{#1}\authortrue}
|
||||
\def\date#1{\def\thedate{#1}\datetrue}
|
||||
\def\maketitle{
|
||||
\begin{flushleft}
|
||||
\iftitle{\LARGE\textbf{\thetitle} \\[6pt]}\fi
|
||||
\ifauthor{\Large\textbf{\theauthor} \\[6pt]}\fi
|
||||
\ifdate{\large\textbf{\thedate} \\}\fi
|
||||
\end{flushleft}}
|
||||
|
||||
%%% to support hypertext index entries
|
||||
\def\hindex#1{\index} % ignore the label here---no links in printed version
|
||||
|
||||
\newcommand{\hyperlink}[3][]{#3}
|
||||
\newcommand{\href}[3][]{#3}
|
||||
\newcommand{\hpageref}[3][]{#3}
|
||||
|
||||
\newif\iflatex\latextrue
|
||||
\newif\ifhtml\htmlfalse
|
||||
|
||||
%%% table of contents
|
||||
\renewcommand{\@pnumwidth}{1.55em}
|
||||
\renewcommand{\@tocrmarg} {2.55em}
|
||||
\renewcommand{\@dotsep}{4.5}
|
||||
\setcounter{tocdepth}{2}
|
||||
\newcommand*{\l@chapter}[2]{%
|
||||
\ifnum \c@tocdepth >\m@ne
|
||||
\addpenalty{-\@highpenalty}%
|
||||
\vskip 1.0em \@plus\p@
|
||||
\setlength\@tempdima{1.5em}%
|
||||
\begingroup
|
||||
\parindent \z@ \rightskip \@pnumwidth
|
||||
\parfillskip -\@pnumwidth
|
||||
\leavevmode \bfseries
|
||||
\advance\leftskip\@tempdima
|
||||
\hskip -\leftskip
|
||||
#1\nobreak\hfil \nobreak\hbox to\@pnumwidth{\hss #2}\par
|
||||
\penalty\@highpenalty
|
||||
\endgroup
|
||||
\fi}
|
||||
\renewcommand*{\l@section}[2] {\vspace{4pt}\hbox to \hsize{\bf #1\hfil#2}}
|
||||
\renewcommand*{\l@subsection}[2] {\vspace{2pt}\hbox to \hsize{\rm #1\hfill#2}}
|
||||
\def\numberline#1{#1}
|
||||
\renewcommand{\tableofcontents}{%
|
||||
\thispagestyle{plain}%
|
||||
\global\@topnum\z@
|
||||
\section*{\contentsname}%
|
||||
\@starttoc{toc}}
|
||||
|
||||
\newcounter{exercise}
|
||||
\renewcommand{\theexercise}{\arabic{exercise}}
|
||||
\def\@startexercise{\par\bigskip
|
||||
\refstepcounter{exercise}\goodbreak
|
||||
\par\hrule width \hsize{\hfil}\\\nobreak
|
||||
\textbf{Exercise \theexercise. }\ignorespaces}
|
||||
\newenvironment{exercise}
|
||||
{\begingroup
|
||||
\def\afterschemedisplay{\removelastskip\penalty10000\vskip5pt}
|
||||
\let\newexercise=\@startexercise\newexercise}
|
||||
{\par\removelastskip\penalty10000\kern6pt\hrule width \hsize{\hfil}\endgroup}
|
||||
\newcounter{subexercise}[exercise]
|
||||
\renewcommand{\thesubexercise}{\theexercise\alph{subexercise}}
|
||||
\newcommand{\subexercise}{\par\refstepcounter{subexercise}\medskip\textbf{\thesubexercise. }}
|
||||
|
||||
%%% bibliography
|
||||
\newdimen\bibindent \bibindent=1.5em
|
||||
\renewcommand{\newblock}{}
|
||||
\renewenvironment{thebibliography}[1]
|
||||
{\section{\bibname}
|
||||
\list{\@biblabel{\arabic{enumiv}}}%
|
||||
{\settowidth\labelwidth{\@biblabel{#1}}%
|
||||
\leftmargin\labelwidth
|
||||
\advance\leftmargin\labelsep
|
||||
\usecounter{enumiv}%
|
||||
\let\p@enumiv\@empty
|
||||
\renewcommand{\theenumiv}{\arabic{enumiv}}}%
|
||||
\renewcommand{\newblock}{\hskip .11em \@plus.33em \@minus.07em}%
|
||||
\sloppy\clubpenalty4000\widowpenalty4000%
|
||||
\sfcode`\.=\@m}
|
||||
{\def\@noitemerr
|
||||
{\@latex@warning{Empty `thebibliography' environment}}%
|
||||
\endlist}
|
||||
|
||||
%%% index
|
||||
\def\notsupposedtobehereindexname{\indexname}
|
||||
\renewenvironment{theindex}
|
||||
{\if@openright\cleardoublepage\else\clearpage\fi
|
||||
\raggedright
|
||||
\columnseprule \z@
|
||||
\columnsep 35\p@
|
||||
\twocolumn[\plainchapterhead{\indexname}]%
|
||||
\addcontentsline{toc}{chapter}{\indexname}%
|
||||
\chaptermark{\indexname}{\notsupposedtobehereindexname}%
|
||||
\thispagestyle{plain}\parindent\z@
|
||||
\parskip\z@ \@plus .3\p@\relax
|
||||
\let\item\@idxitem}
|
||||
{\clearpage}
|
||||
\renewcommand{\@idxitem} {\par\hangindent 40\p@}
|
||||
\renewcommand{\subitem} {\par\hangindent 40\p@ \hspace*{20\p@}}
|
||||
\renewcommand{\subsubitem}{\par\hangindent 40\p@ \hspace*{30\p@}}
|
||||
\renewcommand{\indexspace}{\par \vskip 10\p@ \@plus5\p@ \@minus3\p@\relax}
|
||||
|
||||
%%% latex.ltx redefinitions
|
||||
%% leave padding page blank (no header)
|
||||
\def\cleardoublepage{\clearpage\if@twoside \ifodd\c@page\else
|
||||
{\pagestyle{empty}\hbox{}\newpage\if@twocolumn\hbox{}\newpage\fi}\fi\fi}
|
||||
%% change section headers to "1.1. foo" instead of "1.1 foo"
|
||||
\def\@seccntformat#1{\csname the#1\endcsname. }
|
||||
%% change numbered table of contents lines to "1.1. foo" instead of "1.1 foo"
|
||||
\def\numberline#1{#1. }
|
||||
|
||||
\renewenvironment{description}
|
||||
{\list{}{\labelwidth\z@ \itemindent-\leftmargin
|
||||
\let\makelabel\descriptionlabel}}
|
||||
{\endlist}
|
||||
\renewcommand*\descriptionlabel[1]{\hspace\labelsep #1}
|
||||
|
||||
\def\itemvdots{\item[] \mbox{\vdots}}
|
||||
|
||||
\newcommand{\parheader}[2][.~\ignorespaces]{\medskip\noindent{\bf #2#1}}
|
||||
|
||||
\newcommand{\sectionstar}[1]{\section*{#1}}
|
||||
\newcommand{\subsectionstar}[1]{\subsection*{#1}}
|
||||
\newcommand{\subsubsectionstar}[1]{\subsubsection*{#1}}
|
||||
|
||||
%%% final set up
|
||||
\renewcommand{\contentsname}{Contents}
|
||||
\newcommand{\bibname}{Bibliography}
|
||||
\renewcommand{\indexname}{Index}
|
||||
\renewcommand{\today}{\ifcase\month\or
|
||||
January\or February\or March\or April\or May\or June\or
|
||||
July\or August\or September\or October\or November\or December\fi
|
||||
\space\number\day, \number\year}
|
||||
\setlength\columnsep{10\p@}
|
||||
\setlength\columnseprule{0\p@}
|
||||
\pagestyle{headings}
|
||||
\pagenumbering{arabic}
|
||||
|
||||
\if@twoside\else\raggedbottom\fi
|
||||
\endinput
|
||||
%%% end of monograph.cls
|
149
stex/inputs/monograph.hcls
Normal file
149
stex/inputs/monograph.hcls
Normal file
|
@ -0,0 +1,149 @@
|
|||
%%% monograph.hcls
|
||||
|
||||
\newif\iflatex\latexfalse
|
||||
\newif\ifhtml\htmltrue
|
||||
|
||||
% should be built in
|
||||
\newenvironment{center}
|
||||
{\raw{<center>}}
|
||||
{\raw{</center>}}
|
||||
|
||||
\def\copyrightnotice{\ifauthor\par\raw{<hr>}\copyright~\year~\theauthor\par\fi}
|
||||
\let\trueenddocument=\enddocument
|
||||
\def\enddocument{
|
||||
\begin{divertoutput}[toc]
|
||||
\ifsubsubsec\raw{</table></td></tr>}\fi
|
||||
\ifsubsec\raw{</table></td></tr>}\fi
|
||||
\end{divertoutput}
|
||||
\copyrightnotice\trueenddocument}
|
||||
|
||||
\newif\iftitle\titlefalse
|
||||
\newif\ifdate\datefalse
|
||||
\newif\ifauthor\authorfalse
|
||||
\def\title#1{\def\thetitle{#1}\titletrue}
|
||||
\def\date#1{\def\thedate{#1}\datetrue}
|
||||
\def\author#1{\def\theauthor{#1}\authortrue}
|
||||
\def\maketitle{%
|
||||
\iftitle\raw{<h1>}\thetitle\raw{</h1>}\fi
|
||||
\ifauthor\raw{<h2>}\theauthor\raw{</h2>}\fi
|
||||
\ifdate\raw{<h3>}\thedate\raw{</h3>}\fi
|
||||
}
|
||||
|
||||
%%% table of contents
|
||||
\newif\ifsubsec\subsecfalse
|
||||
\newif\ifsubsubsec\subsubsecfalse
|
||||
\newcommand{\tableofcontents}{
|
||||
\raw{<table cellpadding=0 cellspacing=0>}
|
||||
\rawinput{\jobname.htoc}
|
||||
\raw{</table>}
|
||||
\openrawfile{toc}{\jobname.htoc}}
|
||||
\newcommand{\notableofcontents}{
|
||||
\openrawfile{toc}{\jobname.htoc}}
|
||||
|
||||
%%% \section
|
||||
\newcounter{section}
|
||||
\renewcommand{\thesection}{\arabic{section}}
|
||||
\newcommand{\section}[1]{
|
||||
\refstepcounter{section}
|
||||
\edef\templabel{\genlab}
|
||||
\sectionstar{\label{\templabel}\thesection. #1}
|
||||
\begin{divertoutput}[toc]
|
||||
\ifsubsubsec\raw{</table></td></tr>}\fi
|
||||
\subsubsecfalse
|
||||
\ifsubsec\raw{</table></td></tr>}\fi
|
||||
\subsecfalse
|
||||
\raw{<tr><td align="right">}\textbf{\thesection.~}\raw{<td>}\textbf{\href[plain]{\templabel}{#1}}\raw{</td></tr>}
|
||||
\end{divertoutput}
|
||||
}
|
||||
\newcommand{\sectionstar}[1]{
|
||||
\raw{<h3>}#1\raw{</h3>}
|
||||
}
|
||||
|
||||
%%% \subsection
|
||||
\newcounter{subsection}[section]
|
||||
\renewcommand{\thesubsection}{\thesection.\arabic{subsection}}
|
||||
\newcommand{\subsection}[1]{
|
||||
\refstepcounter{subsection}
|
||||
\edef\templabel{\genlab}
|
||||
\subsectionstar{\label{\templabel}\thesubsection. #1}
|
||||
\begin{divertoutput}[toc]
|
||||
\ifsubsubsec\raw{</table></td></tr>}\fi
|
||||
\subsubsecfalse
|
||||
\ifsubsec\else\raw{<tr><td></td><td><table cellpadding=0 cellspacing=0>}\fi
|
||||
\subsectrue
|
||||
\raw{<tr><td>}\textbf{\thesubsection.~}\raw{</td><td>}\textbf{\href[plain]{\templabel}{#1}}\raw{</td></tr>}
|
||||
\end{divertoutput}
|
||||
}
|
||||
\newcommand{\subsectionstar}[1]{
|
||||
\raw{<h4>}#1\raw{</h4>}
|
||||
}
|
||||
|
||||
%%% \subsubsection
|
||||
\newcounter{subsubsection}[subsection]
|
||||
\renewcommand{\thesubsubsection}{\thesubsection.\arabic{subsubsection}}
|
||||
\newcommand{\subsubsection}[1]{
|
||||
\refstepcounter{subsubsection}
|
||||
\edef\templabel{\genlab}
|
||||
\subsubsectionstar{\label{\templabel}\thesubsubsection. #1}
|
||||
\begin{divertoutput}[toc]
|
||||
\ifsubsubsec\else\raw{<tr><td></td><td><table cellpadding=0 cellspacing=0>}\fi
|
||||
\subsubsectrue
|
||||
\raw{<tr><td>}\textbf{\thesubsubsection.~}\raw{</td><td>}\textbf{\href[plain]{\templabel}{#1}}\raw{</td></tr>}
|
||||
\end{divertoutput}
|
||||
}
|
||||
\newcommand{\subsubsectionstar}[1]{
|
||||
\raw{<h4>}#1\raw{</h4>}
|
||||
}
|
||||
|
||||
%%% figure
|
||||
\newcounter{figure}
|
||||
\renewcommand{\thefigure}{\arabic{figure}}
|
||||
\newcommand{\caption}[1]{\\ Figure \thefigure.~#1}
|
||||
\newenvironment{figure}[1][]
|
||||
{\begingroup\refstepcounter{figure}}
|
||||
{\endgroup}
|
||||
|
||||
%%% exercise
|
||||
\newcounter{exercise}
|
||||
\renewcommand{\theexercise}{\arabic{exercise}}
|
||||
\def\@startexercise{\refstepcounter{exercise}
|
||||
\raw{<hr>}
|
||||
\textbf{Exercise \theexercise. }}
|
||||
\newenvironment{exercise}
|
||||
{\begingroup\def\newexercise{\@startexercise}\newexercise}
|
||||
{\raw{<hr>}}
|
||||
\newcounter{subexercise}[exercise]
|
||||
\renewcommand{\thesubexercise}{\theexercise\alph{subexercise}}
|
||||
\newcommand{\subexercise}{\par\refstepcounter{subexercise}\textbf{\thesubexercise. }}
|
||||
|
||||
%%% alphalist
|
||||
\newcounter{alphalist}
|
||||
\def\alphalist{\begingroup\setcounter{alphalist}{0}
|
||||
\def\endalphalistitem{}%
|
||||
\renewcommand{\item}{\endalphalistitem
|
||||
\def\endalphalistiem{\raw{</td></tr>}}%
|
||||
\stepcounter{alphalist}%
|
||||
\raw{<tr valign=top><td>}\alph{alphalist}.\raw{</td><td>}}
|
||||
\raw{<table>}}
|
||||
\def\endalphalist{\endalphalistitem\raw{</table>}\endgroup}
|
||||
|
||||
%%% define our own (compact) description environment
|
||||
\def\description{\begingroup
|
||||
\renewcommand{\item}[1][]{\raw{<dt>}##1\raw{<dd>}}\raw{<dl compact>}}
|
||||
\def\enddescription{\raw{</dl>}\endgroup}
|
||||
|
||||
%%% index
|
||||
\newcommand{\see}[2]{\emph{see} #1}
|
||||
\newenvironment{theindex}
|
||||
{\begingroup\newcommand{\itemindent}{\raw{<tt> </tt>}}
|
||||
\renewcommand{\item}{\raw{<br>}}
|
||||
\newcommand{\subitem}{\raw{<br>}\itemindent}
|
||||
\newcommand{\subsubitem}{\raw{<br>}\itemindent\itemindent}}
|
||||
{\par\endgroup}
|
||||
|
||||
\newcommand{\parheader}[2][. ]{\medskip\noindent{\bf #2#1}}
|
||||
|
||||
\def\mbox#1{#1}
|
||||
|
||||
%%% hyperlink support
|
||||
\newcommand{\hyperlink}[3][ref]{\raw{<a class=#1 href="#2">}#3\raw{</a>}}
|
94
stex/inputs/quiz.cls
Normal file
94
stex/inputs/quiz.cls
Normal file
|
@ -0,0 +1,94 @@
|
|||
%%% quiz.cls
|
||||
|
||||
\ProvidesClass{quiz}
|
||||
|
||||
\def\ProvidesClass#1[#2]{\relax}
|
||||
|
||||
\input article.cls
|
||||
|
||||
\newif\iflatex\latextrue
|
||||
\newif\ifhtml\htmlfalse
|
||||
|
||||
\newif\iftitle\titlefalse
|
||||
\newif\ifauthor\authorfalse
|
||||
\def\title#1{\def\thetitle{#1}\titletrue}
|
||||
\def\author#1{\def\theauthor{#1}\authortrue}
|
||||
\def\maketitle{
|
||||
\begin{flushleft}
|
||||
\iftitle{\LARGE\textbf{\thetitle}} \\[6pt]\fi
|
||||
\ifauthor{\Large\textbf{\theauthor}} \\\fi
|
||||
\end{flushleft}}
|
||||
|
||||
\newcounter{quiz}
|
||||
\renewcommand{\thequiz}{\arabic{quiz}}
|
||||
\newenvironment{quiz}[1]
|
||||
{\refstepcounter{quiz}
|
||||
\ifnum\thequiz>1\pagebreak\fi
|
||||
\hbox to \hsize{\quizname \hfill
|
||||
\hbox to 3in{\vtop{\noindent Name:\\Lab section: #1\\Lecture section:}}}
|
||||
\bigskip}
|
||||
{}
|
||||
|
||||
\newcounter{problem}[quiz]
|
||||
\renewcommand{\theproblem}{\arabic{problem}}
|
||||
\newenvironment{problem}[1][\relax]
|
||||
{\par\bigskip\refstepcounter{problem}
|
||||
\goodbreak
|
||||
\par\nobreak
|
||||
\textbf{Problem \theproblem\ifx#1\relax\else~[#1 minutes].\fi~\ignorespaces}}
|
||||
{\removelastskip\bigskip\vfill}
|
||||
\newcounter{subproblem}[problem]
|
||||
\renewcommand{\thesubproblem}{\alph{subproblem}}
|
||||
\newcommand{\subproblem}{\par\refstepcounter{subproblem}\medskip\textbf{\theproblem\thesubproblem. }}
|
||||
|
||||
%%% latex.ltx redefinitions
|
||||
%% change section headers to "1.1. foo" instead of "1.1 foo"
|
||||
\def\@seccntformat#1{\csname the#1\endcsname. }
|
||||
|
||||
\renewenvironment{description}
|
||||
{\list{}{\labelwidth\z@ \itemindent-\leftmargin
|
||||
\let\makelabel\descriptionlabel}}
|
||||
{\endlist}
|
||||
\renewcommand*\descriptionlabel[1]{\hspace\labelsep #1}
|
||||
|
||||
\def\itemvdots{\item[] \mbox{\vdots}}
|
||||
|
||||
\def\parheader#1 {\medskip\noindent{\bf #1.}~~}
|
||||
|
||||
%%% grammar support
|
||||
\newenvironment{grammar}
|
||||
{\begingroup
|
||||
\def\orbar{&\bar&}
|
||||
\def\nobar{&&}
|
||||
\def\longis{&$\longrightarrow$&}
|
||||
\penalty-100\vskip 4pt\begin{tabular}{lcl}}
|
||||
{\end{tabular}\penalty-200\vskip 4pt\endgroup}
|
||||
\def\bar{$\vert$}
|
||||
\def\ang#1{$\langle${\small\rm{}#1}$\rangle$}
|
||||
\def\kstar{\raise.5ex\hbox{\scheme{*}}}
|
||||
\def\kplus{\raise.5ex\hbox{\scheme{+}}}
|
||||
|
||||
\newcounter{alphacount}
|
||||
\def\alphalabel{\textit{\alph{alphacount}}.}
|
||||
\newenvironment{alphalist}
|
||||
{\begingroup\let\beforeschemedisplay=\relax\let\afterschemedisplay=\relax
|
||||
\begin{list}{\alphalabel}{\usecounter{alphacount}\itemsep=0pt\parsep=0pt%
|
||||
\topsep=0pt}}
|
||||
{\end{list}\endgroup}
|
||||
|
||||
%%% final set up
|
||||
\renewcommand{\contentsname}{Contents}
|
||||
\newcommand{\bibname}{Bibliography}
|
||||
\renewcommand{\indexname}{Index}
|
||||
\renewcommand{\today}{\ifcase\month\or
|
||||
January\or February\or March\or April\or May\or June\or
|
||||
July\or August\or September\or October\or November\or December\fi
|
||||
\space\number\day, \number\year}
|
||||
\setlength\columnsep{10\p@}
|
||||
\setlength\columnseprule{0\p@}
|
||||
\pagestyle{headings}
|
||||
\pagenumbering{arabic}
|
||||
|
||||
\if@twoside\else\raggedbottom\fi
|
||||
\endinput
|
||||
%%% end of assignment.cls
|
42
stex/inputs/scheme.hsty
Normal file
42
stex/inputs/scheme.hsty
Normal file
|
@ -0,0 +1,42 @@
|
|||
\def\transerr#1{\raw{<i>}}
|
||||
\def\transin#1{\raw{<font color="##ff0000">}}
|
||||
\def\transout#1{\raw{<font color="##0000ff">}}
|
||||
\def\traceout#1{\raw{<font color="##0000ff">}}
|
||||
\def\endtranserr#1{\raw{</i>}}
|
||||
\def\endtransin#1{\raw{</font>}}
|
||||
\def\endtransout#1{\raw{</font>}}
|
||||
\def\endtraceout#1{\raw{</font>}}
|
||||
|
||||
\def\schemeblankline{{\\\\}}
|
||||
\def\schemelinestart{}
|
||||
%%% handle numbered lines in scheme.sty and scheme.hsty
|
||||
%%% ---have scheme-prep produce only \schemelinestart
|
||||
% following is probably broken until we have tables, I suspect.
|
||||
% Actually, the right way to fix this may be to use CSS
|
||||
\def\schemelinestartnumbered#1{\raw{<table><tr width=20><td>}#1\raw{</td></tr></table>}}
|
||||
|
||||
\def\scheme#1{{\tt #1}}
|
||||
\def\longcode\schemedisplay{\schemedisplay}
|
||||
\def\noskip\schemedisplay{\schemedisplay}
|
||||
\def\schemedisplay{\par\begingroup\tt\hardspaces}
|
||||
\def\endschemedisplay{\endgroup\par}
|
||||
\def\schemeindent{}
|
||||
\def\schatsign{\raw{@}}
|
||||
\def\schbackslash{\raw{\}}
|
||||
\def\schcarat{\raw{^}}
|
||||
\def\schdot{\raw{.}}
|
||||
\def\schlbrace{\raw{&##123;}}
|
||||
\def\schrbrace{\raw{&##125;}}
|
||||
\def\schtilde{\raw{~}}
|
||||
\def\schunderscore{\raw{_}}
|
||||
\def\becomes{$\rightarrow$}
|
||||
\def\is{$\Rightarrow$}
|
||||
\def\si{\raw{<img src="gifs/ghostRightarrow.gif">}}
|
||||
\def\var#1{\emph{#1}}
|
||||
|
||||
% frame="border" rules="all" makes mozilla do it right
|
||||
% border="1" makes konqueror do it right
|
||||
\def\startrepl{\raw{<table width="95%"><tr valign=top><td>}}
|
||||
\def\endrepl{\raw{</td>}}
|
||||
\def\startinteraction{\raw{<td align="right"><table rules="all" border="1"><tr><td>}}
|
||||
\def\endinteraction{\raw{</td></tr></table></td></tr></table>}}
|
56
stex/inputs/scheme.sty
Normal file
56
stex/inputs/scheme.sty
Normal file
|
@ -0,0 +1,56 @@
|
|||
\usepackage{color}
|
||||
\def\transerr#1{\begingroup\slshape}
|
||||
\def\transin#1{\begingroup\color{red}}
|
||||
\def\transout#1{\begingroup\color{blue}}
|
||||
\def\traceout#1{\begingroup\color{blue}}
|
||||
\def\endtranserr#1{\endgroup}
|
||||
\def\endtransin#1{\endgroup}
|
||||
\def\endtransout#1{\endgroup}
|
||||
\def\endtraceout#1{\endgroup}
|
||||
|
||||
% this didn't work --- screwed up indentation:
|
||||
\long\def\showinteraction#1#2{\begin{minipage}[t]{4.375in}#1\end{minipage}\hfill\fbox{\begin{minipage}[t]{2in}#2\end{minipage}}}
|
||||
% so I resorted to this:
|
||||
\def\startrepl{\begin{minipage}[t]{4.3in}} % was 4.375 and 2 when interactionwindow = 28
|
||||
\def\endrepl{\end{minipage}}
|
||||
\def\startinteraction{\begin{minipage}[t]{2.2in}\vrule\begin{minipage}[t]{2.2in}\hrule\schemeindent=2pt}
|
||||
\def\endinteraction{\hrule\end{minipage}\vrule\end{minipage}}
|
||||
|
||||
\newskip\ttglue
|
||||
\ttglue=.5em plus .25em minus .15em
|
||||
\newskip\schemeindent
|
||||
\schemeindent=0pt
|
||||
{\obeyspaces\global\let =\ }
|
||||
\def\schtilde{\raisebox{-.5ex}{\hbox{\char`\~}}}
|
||||
\def\schdot{.}
|
||||
\def\schcarat{\char`\^}
|
||||
\def\schbackslash{\char`\\}
|
||||
\def\schatsign{\char`\@}
|
||||
\def\schunderscore{\char`\_}
|
||||
\def\schlbrace{\char`\{}
|
||||
\def\schrbrace{\char`\}}
|
||||
\def\scheme#1{\mbox{\ttfamily\frenchspacing\spaceskip=\ttglue#1}}
|
||||
|
||||
\def\schemeblankline{\par\penalty-100\vskip .7\baselineskip}
|
||||
\def\schemelinestart{{\leavevmode\hbox{\hskip \schemeindent\relax}}}
|
||||
%%% handle numbered lines in scheme.sty and scheme.hsty
|
||||
%%% ---have scheme-prep produce only \schemelinestart
|
||||
\def\schemelinestartnumbered#1{{\leavevmode\hbox{\hbox to 1em {\hfil{\rm #1}} \hskip .5\schemeindent\relax}}}
|
||||
|
||||
\def\noskip\schemedisplay{\begingroup%
|
||||
\parindent=0pt%
|
||||
\parskip=0pt%
|
||||
\def\becomes{\hbox to 2em{\hfil$\rightarrow$\hfil}}%
|
||||
\def\is{\hbox to 2em{\hfil$\Rightarrow$\hfil}}%
|
||||
\def\si{\hbox to 2em{\hfil}}%
|
||||
\interlinepenalty=2000%
|
||||
\tt\obeyspaces\frenchspacing}
|
||||
\def\schemedisplay{\beforeschemedisplay\noskip\schemedisplay}
|
||||
\def\longcode\schemedisplay{\penalty-200\vskip 8pt plus 4pt%
|
||||
\kern3pt\hrule\kern5pt\nobreak\noskip\schemedisplay}
|
||||
\def\endschemedisplay{\par\endgroup\afterschemedisplay}
|
||||
\def\var#1{{\normalsize\textrm{\textit{#1}}}}
|
||||
\def\raw#1{#1}
|
||||
\def\beforeschemedisplay{\penalty-100\vskip\parskip\vskip5pt}
|
||||
\def\afterschemedisplay{\penalty-200\vskip5pt}
|
||||
|
88
stex/inputs/website.cls
Normal file
88
stex/inputs/website.cls
Normal file
|
@ -0,0 +1,88 @@
|
|||
%%% website.cls
|
||||
%%% Kent Dybvig and Oscar Waddell
|
||||
%%% August 2003
|
||||
|
||||
\ProvidesClass{website}
|
||||
\def\ProvidesClass#1[#2]{\relax}
|
||||
\LoadClass{article}
|
||||
|
||||
\def\ps@plain{\let\@mkboth\@gobbletwo
|
||||
\let\@oddhead\@empty\def\@oddfoot{\reset@font
|
||||
\footer}\let\@evenhead\@empty\let\@evenfoot\@oddfoot}
|
||||
\def\footer{\hfil\ifnum\c@page =1 \copyrightnotice\else\thepage\fi\hfil}
|
||||
|
||||
\newcommand{\webpage}[2][]{
|
||||
\def\thetitle{#2}
|
||||
}
|
||||
|
||||
\newcommand{\documenttitle}[2][]{
|
||||
\def\thetitle{#2}
|
||||
}
|
||||
|
||||
\def\maketitle{
|
||||
\begin{flushleft}
|
||||
\LARGE\textbf{\thetitle}
|
||||
\end{flushleft}}
|
||||
|
||||
\newcommand{\hr}[1][]{\bigskip\hrule}
|
||||
|
||||
\newcommand{\copyrightnotice}{}
|
||||
|
||||
%%% to support hypertext index entries
|
||||
\def\hindex#1{\index} % ignore the label here---no links in printed version
|
||||
|
||||
\newcommand{\hyperlink}[3][]{#3}
|
||||
\newcommand{\href}[3][]{#3}
|
||||
\newcommand{\hpageref}[3][]{#3}
|
||||
\let\true@ref=\ref\renewcommand{\ref}[2][]{\true@ref{#2}}
|
||||
\let\true@pageref=\pageref\renewcommand{\pageref}[2][]{\true@pageref{#2}}
|
||||
|
||||
%%% \mailto{id}{name}
|
||||
\newcommand{\mailto}[3][]{#3}
|
||||
|
||||
%%% forms
|
||||
\newenvironment{form}[1]{}{}
|
||||
\newcommand{\formtextarea}[1]{\strut}
|
||||
\newcommand{\forminput}[1]{\strut}
|
||||
\newcommand{\formselect}[2]{\strut}
|
||||
\newcommand{\formoption}[2][]{\strut}
|
||||
|
||||
\newif\iflatex\latextrue
|
||||
\newif\ifhtml\htmlfalse
|
||||
|
||||
\newenvironment{DIV}[1]
|
||||
{\relax}
|
||||
{\relax}
|
||||
|
||||
\def\span#1#2{#2}
|
||||
\newcommand{\img}[3][]{#2}
|
||||
|
||||
%%% \parheader{title}
|
||||
\def\parheader#1 {\medskip\noindent{\bf #1.}~~}
|
||||
|
||||
\newcounter{alphacount}
|
||||
\def\alphalabel{\textit{\alph{alphacount}}.}
|
||||
\newenvironment{alphalist}
|
||||
{\begingroup\let\beforeschemedisplay=\relax\let\afterschemedisplay=\relax
|
||||
\begin{list}{\alphalabel}{\usecounter{alphacount}\itemsep=0pt\parsep=0pt%
|
||||
\topsep=0pt}}
|
||||
{\end{list}\endgroup}
|
||||
|
||||
%%% final set up
|
||||
\renewcommand{\contentsname}{Contents}
|
||||
\newcommand{\bibname}{Bibliography}
|
||||
\renewcommand{\indexname}{Index}
|
||||
\renewcommand{\today}{\ifcase\month\or
|
||||
January\or February\or March\or April\or May\or June\or
|
||||
July\or August\or September\or October\or November\or December\fi
|
||||
\space\number\day, \number\year}
|
||||
\setlength\columnsep{10\p@}
|
||||
\setlength\columnseprule{0\p@}
|
||||
\pagestyle{headings}
|
||||
\pagenumbering{arabic}
|
||||
\parindent=0pt
|
||||
\parskip=4pt
|
||||
|
||||
\if@twoside\else\raggedbottom\fi
|
||||
\endinput
|
||||
%%% end of website.cls
|
93
stex/inputs/website.hcls
Normal file
93
stex/inputs/website.hcls
Normal file
|
@ -0,0 +1,93 @@
|
|||
%%% website.hcls
|
||||
%%% Kent Dybvig and Oscar Waddell
|
||||
%%% August 2003
|
||||
|
||||
\newif\iflatex\latexfalse
|
||||
\newif\ifhtml\htmltrue
|
||||
|
||||
\def\thetitleattributes{}
|
||||
|
||||
%%% \webpage{title}
|
||||
\newcommand{\webpage}[2][]{
|
||||
\endwebpage
|
||||
\def\thetitleattributes{#1}
|
||||
\def\thetitle{#2}
|
||||
\begingroup\renewcommand{\hyperlink}[3][]{##3}\openhtmlfile{#2}\endgroup
|
||||
\renewcommand{\endwebpage}{\copyrightnotice
|
||||
\closehtmlfile\renewcommand{\endwebpage}{}}}
|
||||
\newcommand{\endwebpage}{}
|
||||
|
||||
\def\maketitle{\raw{<h1} \thetitleattributes\raw{>}\thetitle\raw{</h1>}}
|
||||
|
||||
\newcommand{\hr}[1][]{\raw{<hr #1>}}
|
||||
|
||||
\def\copyright{\raw{©}}
|
||||
\newcommand{\copyrightnotice}{}
|
||||
|
||||
\let\trueenddocument=\enddocument
|
||||
\def\enddocument{
|
||||
\endwebpage
|
||||
\trueenddocument}
|
||||
|
||||
%%% \section{title}
|
||||
\newcommand{\section}[1]{
|
||||
\raw{<h2>}#1\raw{</h2>}
|
||||
}
|
||||
|
||||
%%% \subsection{title}
|
||||
\newcommand{\subsection}[1]{
|
||||
\raw{<h3>}#1\raw{</h3>}
|
||||
}
|
||||
|
||||
%%% \subsection{title}
|
||||
\newcommand{\subsubsection}[1]{
|
||||
\raw{<h4>}#1\raw{</h4>}
|
||||
}
|
||||
|
||||
\newenvironment{DIV}[1]
|
||||
{\raw{<div #1>}}
|
||||
{\raw{</div>}}
|
||||
|
||||
\def\span#1#2{\raw{<span #1>}#2\raw{</span>}}
|
||||
|
||||
\newcommand{\img}[3][]{\raw{<img alt="#2" #1 src="#3">}}
|
||||
|
||||
%%% \parheader{title}
|
||||
\def\parheader#1 {\medskip\noindent{\bf #1.}~~}
|
||||
|
||||
%%% center: should be built in
|
||||
\newenvironment{center}
|
||||
{\raw{<div align=center>}}
|
||||
{\raw{</div>}}
|
||||
|
||||
%%% alphalist
|
||||
\newcounter{alphalist}
|
||||
\def\alphalist{\begingroup\setcounter{alphalist}{0}
|
||||
\def\endalphalistitem{}%
|
||||
\renewcommand{\item}{\endalphalistitem
|
||||
\def\endalphalistiem{\raw{</td></tr>}}%
|
||||
\stepcounter{alphalist}%
|
||||
\raw{<tr valign=top><td>}\textit{~~\alph{alphalist}}.\raw{</td><td>}}
|
||||
\raw{<table>}}
|
||||
\def\endalphalist{\endalphalistitem\raw{</table>}\endgroup}
|
||||
|
||||
%%% define our own (compact) description environment
|
||||
\def\description{\begingroup
|
||||
\renewcommand{\item}[1][]{\raw{<dt>}##1\raw{<dd>}}\raw{<dl compact>}}
|
||||
\def\enddescription{\raw{</dl>}\endgroup}
|
||||
|
||||
%%% hyperlink support
|
||||
\newcommand{\hyperlink}[3][]{\raw{<a #1 href="}\url{#2}\raw{">}#3\raw{</a>}}
|
||||
|
||||
%%% \mailto{id}{name}
|
||||
\newcommand{\mailto}[3][]{\raw{<a #1 href="/cgi-bin/tomail.cgi?name=#2">}{#3}\raw{</a>}}
|
||||
|
||||
%%% colors
|
||||
\def\textcolor#1#2{\raw{<span style="color: #1;">}#2\raw{</span>}}
|
||||
|
||||
%%% forms
|
||||
\newenvironment{form}[1]{\raw{<form #1>}}{\raw{</form>}}
|
||||
\newcommand{\formtextarea}[2]{\raw{<textarea #1>}#2\raw{</textarea>}}
|
||||
\newcommand{\forminput}[1]{\raw{<input #1>}}
|
||||
\newcommand{\formselect}[2]{\raw{<select #1>}#2\raw{</select>}}
|
||||
\newcommand{\formoption}[2][]{\raw{<option #1>}#2\raw{</option>}}
|
26
stex/math/Makefile
Normal file
26
stex/math/Makefile
Normal file
|
@ -0,0 +1,26 @@
|
|||
include mathfiles
|
||||
|
||||
density=-r90x90
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .tex .gif
|
||||
|
||||
# translate ps file to ppm, crop to minimum background, and translate ppm
|
||||
# to gif with white (background) transparent
|
||||
#
|
||||
.tex.gif:
|
||||
TEXINPUTS=.:../..:$(TEXINPUTS);\
|
||||
echo | latex $* &&\
|
||||
dvips -f < $*.dvi |\
|
||||
gs -q -dNOPAUSE -dSAFER -sDEVICE=ppmraw -sOutputFile=-\
|
||||
${density} - |\
|
||||
pnmcrop |\
|
||||
ppmtogif -transparent white > $*.gif
|
||||
/bin/rm -f $*.dvi $*.log $*.aux
|
||||
test -f $*.gif && chmod 644 $*.gif
|
||||
|
||||
all: ${gifs}
|
||||
|
||||
${gifs}: mathmacros
|
||||
|
||||
clean: ; /bin/rm -f *.gif Make.out
|
21
stex/math/mathmacros
Normal file
21
stex/math/mathmacros
Normal file
|
@ -0,0 +1,21 @@
|
|||
\usepackage{scheme}
|
||||
|
||||
\catcode`@=11 % borrow the private macros of PLAIN (with care)
|
||||
\def\W#1{W_{\!\!#1}}
|
||||
\def\fftcases#1{\left\{\,\vcenter{\m@th\baselineskip=18pt
|
||||
\ialign{$##\hfil$&\quad##\hfil\crcr#1\crcr}}\right.}
|
||||
\input epsf
|
||||
|
||||
\usepackage{graphicx}
|
||||
|
||||
\setlength\fboxrule{.4\p@}
|
||||
\newlength{\chpicsize}
|
||||
\setlength{\chpicsize}{30pc}
|
||||
\addtolength{\chpicsize}{-\fboxrule}
|
||||
\addtolength{\chpicsize}{-\fboxrule}
|
||||
\def\chpic#1{\begingroup%
|
||||
\def\epsfsize##1##2{##1}
|
||||
\fboxsep=0pt
|
||||
\vbox{\noindent%
|
||||
\fbox{\vbox{\hbox to \chpicsize{\hfil\vbox to \chpicsize{\vfil%
|
||||
\epsfbox{#1}\vfil}\hfil}}}}\endgroup}
|
73
stex/sbin/install
Executable file
73
stex/sbin/install
Executable file
|
@ -0,0 +1,73 @@
|
|||
#! /bin/sh
|
||||
# follows symbolic links. to do otherwise is painful.
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [ -o owner] [ -g group ] [ -m mode ] -d dir ..."
|
||||
echo " $0 [ -o owner] [ -g group ] [ -m mode ] file destfile"
|
||||
echo " $0 [ -o owner] [ -g group ] [ -m mode ] file file ... destdir"
|
||||
exit 1
|
||||
}
|
||||
|
||||
installone() {
|
||||
cp -f -p $1 $2
|
||||
if [ "$owner" != "" ] ; then chown $owner $2; fi
|
||||
if [ "$group" != "" ] ; then chgrp $group $2; fi
|
||||
if [ "$mode" != "" ] ; then chmod $mode $2; fi
|
||||
}
|
||||
|
||||
mkdir=0
|
||||
|
||||
while [ $# -ge 0 ] ; do
|
||||
case $1 in
|
||||
-d) mkdir=1 ;;
|
||||
-o) shift; owner=$1 ;;
|
||||
-g) shift; group=$1 ;;
|
||||
-m) shift; mode=$1 ;;
|
||||
-*) usage ;;
|
||||
*) break ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ $mkdir -eq 1 ] ; then
|
||||
dirs=$*
|
||||
|
||||
for dir in $dirs ; do
|
||||
case $dir in
|
||||
/*) ;;
|
||||
*) echo "directory name must begin with /; $dir does not" ; exit 1 ;;
|
||||
esac
|
||||
|
||||
stack="$dir"
|
||||
while [ "$dir" != "/" ] ; do
|
||||
stack="$dir $stack"
|
||||
dir=`dirname $dir`
|
||||
done
|
||||
|
||||
for dir in $stack ; do
|
||||
if [ ! -e $dir ] ; then
|
||||
mkdir $dir
|
||||
if [ "$owner" != "" ] ; then chown $owner $dir ; fi
|
||||
if [ "$group" != "" ] ; then chgrp $group $dir ; fi
|
||||
if [ "$mode" != "" ] ; then chmod $mode $dir ; fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
elif [ $# -eq 2 -a ! -d $2 ] ; then
|
||||
installone $1 $2
|
||||
elif [ $# -ge 2 ] ; then
|
||||
files=""
|
||||
while [ $# -ne 1 ] ; do
|
||||
files="$files $1"
|
||||
shift
|
||||
done
|
||||
dest=$1
|
||||
|
||||
if [ ! -d $dest ]; then usage; fi
|
||||
|
||||
for file in $files ; do
|
||||
installone $file $dest/`basename $file`
|
||||
done
|
||||
else
|
||||
usage
|
||||
fi
|
54
stex/src/dsm.ss
Normal file
54
stex/src/dsm.ss
Normal file
|
@ -0,0 +1,54 @@
|
|||
;;; dsm.ss
|
||||
;;;
|
||||
;;; Copyright (c) 1998-2016 R. Kent Dybvig and Oscar Waddell
|
||||
;;;
|
||||
;;; Permission is hereby granted, free of charge, to any person obtaining a
|
||||
;;; copy of this software and associated documentation files (the "Software"),
|
||||
;;; to deal in the Software without restriction, including without limitation
|
||||
;;; the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
;;; and/or sell copies of the Software, and to permit persons to whom the
|
||||
;;; Software is furnished to do so, subject to the following conditions:
|
||||
;;;
|
||||
;;; The above copyright notice and this permission notice shall be included in
|
||||
;;; all copies or substantial portions of the Software.
|
||||
;;;
|
||||
;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
;;; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
;;; DEALINGS IN THE SOFTWARE.
|
||||
|
||||
;;; authors: R. Kent Dybvig and Oscar Waddell
|
||||
|
||||
(library (dsm) (export define-syntactic-monad) (import (chezscheme))
|
||||
(define-syntax define-syntactic-monad
|
||||
(syntax-rules ()
|
||||
[(_ name formal ...)
|
||||
(andmap identifier? #'(name formal ...))
|
||||
(define-syntax name
|
||||
(lambda (x)
|
||||
(syntax-case x (lambda case-lambda)
|
||||
[(key lambda more-formals . body)
|
||||
(with-implicit (key formal ...)
|
||||
#'(lambda (formal ... . more-formals) . body))]
|
||||
[(key case-lambda (more-formals . body) (... ...))
|
||||
(with-implicit (key formal ...)
|
||||
#'(case-lambda ((formal ... . more-formals) . body) (... ...)))]
|
||||
[(key proc ((x e) (... ...)) arg (... ...))
|
||||
(andmap identifier? #'(x (... ...)))
|
||||
(with-implicit (key formal ...)
|
||||
(for-each
|
||||
(lambda (x)
|
||||
(unless (let mem ((ls #'(formal ...)))
|
||||
(and (not (null? ls))
|
||||
(or (free-identifier=? x (car ls))
|
||||
(mem (cdr ls)))))
|
||||
(syntax-error x (format "in syntactic monad ~s, unrecognized identifier" 'name))))
|
||||
#'(x (... ...)))
|
||||
(with-syntax ([(t (... ...)) (generate-temporaries #'(arg (... ...)))])
|
||||
#'(let ((p proc) (x e) (... ...) (t arg) (... ...))
|
||||
(p formal ... t (... ...)))))]
|
||||
[(key proc) #'(key proc ())])))]))
|
||||
)
|
34
stex/src/fixbibtex.ss
Executable file
34
stex/src/fixbibtex.ss
Executable file
|
@ -0,0 +1,34 @@
|
|||
#! /usr/bin/scheme --program
|
||||
|
||||
;;; fixbibtex.ss
|
||||
|
||||
;;; fixbibtex removes the line breaks inserted by bibtex, sometimes
|
||||
;;; in the middle of tex commands or urls.
|
||||
|
||||
(import (chezscheme))
|
||||
(unless (= (length (command-line-arguments)) 1)
|
||||
(printf "usage: fixbibtex <filename>\n")
|
||||
(exit 1))
|
||||
(define fn (car (command-line-arguments)))
|
||||
|
||||
(let ([s (call-with-port (open-input-file fn) get-string-all)])
|
||||
(with-input-from-string s
|
||||
(lambda ()
|
||||
(with-output-to-file fn
|
||||
(lambda ()
|
||||
(define (s0 c)
|
||||
(unless (eof-object? c)
|
||||
(case c
|
||||
[(#\\) (write-char c) (s1 (read-char))]
|
||||
[(#\%) (s2 (read-char))]
|
||||
[else (write-char c) (s0 (read-char))])))
|
||||
(define (s1 c) ; seen \
|
||||
(unless (eof-object? c)
|
||||
(write-char c)
|
||||
(s0 (read-char))))
|
||||
(define (s2 c) ; seen %
|
||||
(case c
|
||||
[(#\newline) (s0 (read-char))]
|
||||
[else (write-char #\%) (s0 c)]))
|
||||
(s0 (read-char)))
|
||||
'replace))))
|
1942
stex/src/html-prep.ss
Executable file
1942
stex/src/html-prep.ss
Executable file
File diff suppressed because it is too large
Load diff
469
stex/src/preplib.ss
Normal file
469
stex/src/preplib.ss
Normal file
|
@ -0,0 +1,469 @@
|
|||
;;; preplib.ss
|
||||
;;;
|
||||
;;; Copyright (c) 1998-2016 R. Kent Dybvig and Oscar Waddell
|
||||
;;;
|
||||
;;; Permission is hereby granted, free of charge, to any person obtaining a
|
||||
;;; copy of this software and associated documentation files (the "Software"),
|
||||
;;; to deal in the Software without restriction, including without limitation
|
||||
;;; the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
;;; and/or sell copies of the Software, and to permit persons to whom the
|
||||
;;; Software is furnished to do so, subject to the following conditions:
|
||||
;;;
|
||||
;;; The above copyright notice and this permission notice shall be included in
|
||||
;;; all copies or substantial portions of the Software.
|
||||
;;;
|
||||
;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
;;; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
;;; DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#!chezscheme
|
||||
(library (preplib)
|
||||
(export current-ifile genlab-prefix genlab-counters
|
||||
state-case read-alpha-command read-command
|
||||
command-symbol? read-back-slash read-open-brace read-close-brace
|
||||
read-bracketed-text read-optional-arg push-ifile pop-ifile input-error
|
||||
unexpected-eof unexpected-command genlab read-integer read-def-pattern
|
||||
read-args expand-template suppress-white-space parse-index global-def
|
||||
set-def! get-def conditional? populate-source-directories anchored-filename? find-filename
|
||||
open-input-file)
|
||||
|
||||
(import (except (chezscheme) open-input-file))
|
||||
|
||||
(define current-ifile (make-parameter #f))
|
||||
(define genlab-prefix (make-parameter #f))
|
||||
(define genlab-counters (make-parameter #f))
|
||||
|
||||
(define-syntax state-case
|
||||
(syntax-rules ()
|
||||
[(_ (var exp) c1 c2 ...)
|
||||
(identifier? (syntax var))
|
||||
(let ([var exp]) (state-case-help var c1 c2 ...))]))
|
||||
|
||||
(define-syntax state-case-help
|
||||
(syntax-rules (else)
|
||||
[(_ var (else e1 e2 ...)) (begin e1 e2 ...)]
|
||||
[(_ var ((k ...) e1 e2 ...) c ...)
|
||||
(if (or (state-case-test var k) ...)
|
||||
(begin e1 e2 ...)
|
||||
(state-case-help var c ...))]))
|
||||
|
||||
(define-syntax state-case-test
|
||||
(syntax-rules (eof -)
|
||||
[(_ var eof)
|
||||
(eof-object? var)]
|
||||
[(_ var (char1 - char2))
|
||||
(and (char? var) (char<=? char1 var char2))]
|
||||
[(_ var char)
|
||||
(and (char? var) (char=? var char))]))
|
||||
|
||||
; doesn't allow @ even in document class or style files. this won't
|
||||
; work for us anyway because we use character-based rather than
|
||||
; token-based substitution, so macros that insert @ symbols into
|
||||
; their output won't work outside of the original context
|
||||
(define read-alpha-command
|
||||
; return symbol representing command; assume \ already seen and scan
|
||||
; maximal string of alphabetic chars, e.g., \scheme => symbol scheme
|
||||
; returns || when no command is recognized
|
||||
(let ([buf (open-output-string)])
|
||||
(lambda (ip)
|
||||
(state-case (c (peek-char ip))
|
||||
[((#\a - #\z) (#\A - #\Z))
|
||||
(let loop ()
|
||||
(write-char (read-char ip) buf)
|
||||
(state-case (c (peek-char ip))
|
||||
[((#\a - #\z) (#\A - #\Z)) (loop)]
|
||||
[else (string->symbol (get-output-string buf))]))]
|
||||
[else '||]))))
|
||||
|
||||
(define read-command
|
||||
; like read-alpha-command, but allows single nonalphabetic char
|
||||
; commands, e.g., \' => |'|
|
||||
(let ([buf (open-output-string)])
|
||||
(lambda (ip)
|
||||
(state-case (c (peek-char ip))
|
||||
[((#\a - #\z) (#\A - #\Z))
|
||||
(let loop ()
|
||||
(write-char (read-char ip) buf)
|
||||
(state-case (c (peek-char ip))
|
||||
[((#\a - #\z) (#\A - #\Z)) (loop)]
|
||||
[else (string->symbol (get-output-string buf))]))]
|
||||
[(eof) '||]
|
||||
[else (read-char ip) (string->symbol (string c))]))))
|
||||
|
||||
(define command-symbol?
|
||||
(lambda (cmd) ; true iff command is one character, nonalpabetic
|
||||
(let ([s (symbol->string cmd)])
|
||||
(and (fx= (string-length s) 1)
|
||||
(state-case (c (string-ref s 0))
|
||||
[((#\a - #\z) (#\A - #\Z)) #f]
|
||||
[else #t])))))
|
||||
|
||||
(define read-back-slash
|
||||
(lambda (ip)
|
||||
(if (eqv? (peek-char ip) #\\)
|
||||
(read-char ip)
|
||||
(input-error "back slash expected"))))
|
||||
|
||||
(define read-open-brace
|
||||
(lambda (ip)
|
||||
(if (eqv? (peek-char ip) #\{)
|
||||
(read-char ip)
|
||||
(input-error "open brace expected"))))
|
||||
|
||||
(define read-close-brace
|
||||
(lambda (ip)
|
||||
(if (eqv? (peek-char ip) #\})
|
||||
(read-char ip)
|
||||
(input-error "close brace expected"))))
|
||||
|
||||
(define read-bracketed-text
|
||||
(let ([buf (open-output-string)])
|
||||
(case-lambda
|
||||
[(ip) (read-open-brace ip) (read-bracketed-text ip 1)]
|
||||
[(ip depth)
|
||||
(state-case (c (read-char ip))
|
||||
[(#\}) (if (= depth 1)
|
||||
(get-output-string buf)
|
||||
(begin (write-char #\} buf)
|
||||
(read-bracketed-text ip (- depth 1))))]
|
||||
[(#\{) (write-char #\{ buf) (read-bracketed-text ip (+ depth 1))]
|
||||
[(eof) (input-error "file ended within bracketed text")]
|
||||
[else (write-char c buf) (read-bracketed-text ip depth)])])))
|
||||
|
||||
(define read-optional-arg
|
||||
(let ([buf (open-output-string)])
|
||||
(lambda (ip)
|
||||
(state-case (c (peek-char ip))
|
||||
[(#\[)
|
||||
(read-char ip)
|
||||
(let loop ([depth 0])
|
||||
(state-case (c (read-char ip))
|
||||
[(#\]) (if (= depth 0)
|
||||
(get-output-string buf)
|
||||
(begin (write-char c buf) (loop depth)))]
|
||||
[(#\{) (write-char c buf) (loop (+ depth 1))]
|
||||
[(#\}) (write-char c buf) (loop (- depth 1))]
|
||||
[(eof) (input-error "file ended within optional argument")]
|
||||
[else (write-char c buf) (loop depth)]))]
|
||||
[else #f]))))
|
||||
|
||||
(define push-ifile
|
||||
(lambda (ip ifiles)
|
||||
(current-ifile ip)
|
||||
(cons ip ifiles)))
|
||||
|
||||
(define pop-ifile
|
||||
(lambda (ifiles)
|
||||
(let ([ifiles (cdr ifiles)])
|
||||
(current-ifile (and (not (null? ifiles)) (car ifiles)))
|
||||
ifiles)))
|
||||
|
||||
(define input-error
|
||||
(lambda (msg . args)
|
||||
(define file-coordinates
|
||||
(lambda (ip)
|
||||
(let ([n (file-position ip)])
|
||||
(file-position ip 0)
|
||||
(let f ([n n] [line 1] [char 1] [return? #f])
|
||||
(if (= n 0)
|
||||
(values line char)
|
||||
(state-case (c (read-char ip))
|
||||
[(#\newline) (f (- n 1) (if return? line (+ line 1)) 1 #f)]
|
||||
[(#\return) (f (- n 1) (+ line 1) 1 #t)]
|
||||
[(eof) (values line char)]
|
||||
[else (f (- n 1) line (+ char 1) #f)]))))))
|
||||
(let ([ip (current-ifile)])
|
||||
(call-with-values (lambda () (file-coordinates ip))
|
||||
(lambda (line char)
|
||||
(errorf #f "~a on line ~d, character ~d of ~s"
|
||||
(apply format msg args)
|
||||
line char
|
||||
(port-name ip)))))))
|
||||
|
||||
(define unexpected-eof
|
||||
(lambda (where)
|
||||
(input-error "unexpected end-of-input ~a" where)))
|
||||
|
||||
(define unexpected-command
|
||||
(lambda (cmd)
|
||||
(input-error "unexpected command '\\~a'" cmd)))
|
||||
|
||||
(define genlab
|
||||
(lambda ()
|
||||
(define next-count
|
||||
(lambda (fn)
|
||||
(cond
|
||||
[(assoc fn (genlab-counters)) =>
|
||||
(lambda (a)
|
||||
(let ([n (+ (cdr a) 1)])
|
||||
(set-cdr! a n)
|
||||
n))]
|
||||
[else
|
||||
(genlab-counters (cons (cons fn 0) (genlab-counters)))
|
||||
0])))
|
||||
(let ([name (path-root (port-name (current-ifile)))])
|
||||
(string->symbol
|
||||
(format "~a:~a~d" name (genlab-prefix) (next-count name))))))
|
||||
|
||||
(define read-integer ; return integer or #f if none found
|
||||
(lambda (ip)
|
||||
(string->number
|
||||
(list->string
|
||||
(let loop ()
|
||||
(state-case (c (peek-char ip))
|
||||
[((#\0 - #\9)) (read-char ip) (cons c (loop))]
|
||||
[else '()]))))))
|
||||
|
||||
(define read-def-pattern
|
||||
(lambda (ip)
|
||||
(let loop ([i 1])
|
||||
(state-case (c (peek-char ip))
|
||||
[(#\{) '()]
|
||||
[(#\#)
|
||||
(read-char ip)
|
||||
(state-case (c1 (peek-char ip))
|
||||
[(#\#) (read-char ip) (list* c1 c (loop i))]
|
||||
[else
|
||||
(let ([n (read-integer ip)])
|
||||
(if (eq? n i)
|
||||
(cons n (loop (+ i 1)))
|
||||
(input-error "invalid \\def argument specifier")))])]
|
||||
[(eof) (unexpected-eof "after \\def")]
|
||||
[else (read-char ip) (cons c (loop i))]))))
|
||||
|
||||
(define read-args
|
||||
(lambda (ip pattern cmd)
|
||||
(define read-arg
|
||||
(lambda (ip cmd)
|
||||
(state-case (c (read-char ip))
|
||||
[(#\\) (format "\\~a" (read-command ip))]
|
||||
[(#\{) (read-bracketed-text ip 1)]
|
||||
[(eof) (unexpected-eof (format "reading ~a arguments" cmd))]
|
||||
[else (string c)])))
|
||||
(let loop ([pattern pattern])
|
||||
(if (null? pattern)
|
||||
'()
|
||||
(let ([x (car pattern)])
|
||||
(cond
|
||||
[(integer? x)
|
||||
(let ([arg (read-arg ip cmd)])
|
||||
(cons arg (loop (cdr pattern))))]
|
||||
[(string? x)
|
||||
(let ([arg (read-optional-arg ip)])
|
||||
(cons (or arg x) (loop (cdr pattern))))]
|
||||
[(eqv? x #\space)
|
||||
(suppress-white-space ip)
|
||||
(loop (cdr pattern))]
|
||||
[(eqv? (read-char ip) x) (loop (cdr pattern))]
|
||||
[else (input-error "~a use does not match pattern" cmd)]))))))
|
||||
|
||||
(define expand-template
|
||||
(let ([buf (open-output-string)])
|
||||
(lambda (template args cmd)
|
||||
(let ([sip (open-input-string template)])
|
||||
(let loop ()
|
||||
(state-case (c (read-char sip))
|
||||
[(#\\)
|
||||
(write-char c buf)
|
||||
(state-case (c (peek-char sip))
|
||||
[(#\#) (read-char sip) (write-char c buf)]
|
||||
[else (void)])
|
||||
(loop)]
|
||||
[(#\#)
|
||||
(state-case (c (peek-char sip))
|
||||
[(#\#) (read-char sip) (write-char #\# buf)]
|
||||
[else (let ([n (read-integer sip)])
|
||||
(let ([n (and n (- n 1))])
|
||||
(unless (and n (< -1 n (length args)))
|
||||
(input-error "invalid argument specifier in ~a template" cmd))
|
||||
(display (list-ref args n) buf)))])
|
||||
(loop)]
|
||||
[(eof) (get-output-string buf)]
|
||||
[else (write-char c buf) (loop)]))))))
|
||||
|
||||
(define (suppress-white-space ip)
|
||||
(state-case (c (peek-char ip))
|
||||
[(#\space #\tab #\newline) (read-char ip) (suppress-white-space ip)]
|
||||
[(#\%)
|
||||
(read-char ip)
|
||||
(let loop ()
|
||||
(state-case (c (read-char ip))
|
||||
[(eof #\newline) (void)]
|
||||
[else (loop)]))]
|
||||
[else (void)]))
|
||||
|
||||
(define parse-index
|
||||
(let ([buf (open-output-string)])
|
||||
; if proper-nesting? is true, the characters ", @, !, and | lose their
|
||||
; special meaning within nested groups.
|
||||
(lambda (ip proper-nesting?)
|
||||
(define nested-group
|
||||
(lambda (depth)
|
||||
(state-case (c (read-char ip))
|
||||
[(#\{)
|
||||
(write-char c buf)
|
||||
(nested-group (+ depth 1))]
|
||||
[(#\})
|
||||
(write-char c buf)
|
||||
(unless (= depth 0) (nested-group (- depth 1)))]
|
||||
[(#\@ #\! #\|)
|
||||
(if proper-nesting?
|
||||
(write-char c buf)
|
||||
(input-error "unquoted ~c within nested group in index entry" c))
|
||||
(nested-group depth)]
|
||||
[(#\")
|
||||
(if proper-nesting?
|
||||
(write-char c buf)
|
||||
(state-case (c (read-char ip))
|
||||
[(eof) (input-error "file ended within \\index{}")]
|
||||
[else (write-char c buf)]))
|
||||
(nested-group depth)]
|
||||
[(#\")
|
||||
(write-char c buf)
|
||||
(unless proper-nesting?
|
||||
(state-case (c (peek-char ip))
|
||||
[(#\") (read-char ip) (write-char c buf)]
|
||||
[else (void)]))
|
||||
(nested-group depth)]
|
||||
[else (write-char c buf) (nested-group depth)])))
|
||||
(define before@
|
||||
(lambda (ls)
|
||||
; ls is list of levels seen so far
|
||||
(state-case (c (read-char ip))
|
||||
[(#\})
|
||||
(let ([s (get-output-string buf)])
|
||||
(values (reverse (cons (cons #f s) ls)) ""))]
|
||||
[(#\{)
|
||||
(write-char c buf)
|
||||
(nested-group 0)
|
||||
(before@ ls)]
|
||||
[(#\|)
|
||||
(let ([s (get-output-string buf)])
|
||||
(values (reverse (cons (cons #f s) ls))
|
||||
(read-bracketed-text ip 1)))]
|
||||
[(#\@) (after@ ls (get-output-string buf))]
|
||||
[(#\!)
|
||||
(let ([s (get-output-string buf)])
|
||||
(before@ (cons (cons #f s) ls)))]
|
||||
[(#\")
|
||||
(state-case (c (read-char ip))
|
||||
[(eof) (input-error "file ended within \\index{}")]
|
||||
[else
|
||||
(write-char c buf)
|
||||
(before@ ls)])]
|
||||
[(#\\)
|
||||
(write-char c buf)
|
||||
(state-case (c (peek-char ip))
|
||||
[(#\") (read-char ip) (write-char c buf)]
|
||||
[else (void)])
|
||||
(before@ ls)]
|
||||
[(eof) (input-error "file ended within \\index{}")]
|
||||
[else (write-char c buf) (before@ ls)])))
|
||||
(define after@
|
||||
(lambda (ls sort-key)
|
||||
; ls is list of levels seen so far
|
||||
; sort-key is sort key part of current level
|
||||
(state-case (c (read-char ip))
|
||||
[(#\})
|
||||
(let ([s (get-output-string buf)])
|
||||
(values (reverse (cons (cons sort-key s) ls)) ""))]
|
||||
[(#\{)
|
||||
(write-char c buf)
|
||||
(nested-group 0)
|
||||
(after@ ls sort-key)]
|
||||
[(#\|)
|
||||
(let ([s (get-output-string buf)])
|
||||
(values (reverse (cons (cons sort-key s) ls))
|
||||
(read-bracketed-text ip 1)))]
|
||||
[(#\@) (input-error "at sign seen after at sign in \\index{}")]
|
||||
[(#\!)
|
||||
(let ([s (get-output-string buf)])
|
||||
(before@ (cons (cons sort-key s) ls)))]
|
||||
[(#\")
|
||||
(state-case (c (read-char ip))
|
||||
[(eof) (input-error "file ended within \\index{}")]
|
||||
[else
|
||||
; leave out quote; reinsert later
|
||||
(write-char c buf)
|
||||
(after@ ls sort-key)])]
|
||||
[(#\\)
|
||||
(write-char c buf)
|
||||
(state-case (c (peek-char ip))
|
||||
[(#\") (read-char ip) (write-char c buf)]
|
||||
[else (void)])
|
||||
(after@ ls sort-key)]
|
||||
[(eof) (input-error "file ended within \\index{}")]
|
||||
[else (write-char c buf) (after@ ls sort-key)])))
|
||||
(before@ '()))))
|
||||
|
||||
;; support for definitions
|
||||
(define-syntax global-def
|
||||
(syntax-rules ()
|
||||
[(_ name expr)
|
||||
(set-def! 'name '() #f expr)]))
|
||||
|
||||
(define set-def!
|
||||
(lambda (cmd env conditional? proc)
|
||||
(if (null? env)
|
||||
(putprop cmd 'def (cons conditional? proc))
|
||||
(set-car! env (cons (list* cmd conditional? proc) (car env))))))
|
||||
|
||||
(module (get-def conditional?)
|
||||
(define lookup-env
|
||||
(lambda (cmd env)
|
||||
(cond
|
||||
[(null? env) (getprop cmd 'def '(#f . #f))]
|
||||
[(assq cmd (car env)) => cdr]
|
||||
[else (lookup-env cmd (cdr env))])))
|
||||
|
||||
(define get-def
|
||||
(lambda (cmd env)
|
||||
(cdr (lookup-env cmd env))))
|
||||
|
||||
(define conditional?
|
||||
(lambda (cmd env)
|
||||
(car (lookup-env cmd env)))))
|
||||
|
||||
(define (populate-source-directories)
|
||||
(let ([inputs (or (getenv "TEXINPUTS") "")])
|
||||
(unless (equal? inputs "")
|
||||
(let ([ip (open-input-string inputs)] [op (open-output-string)])
|
||||
(source-directories
|
||||
(let loop ([ls '()])
|
||||
(let ([c (read-char ip)])
|
||||
(case c
|
||||
[(#\:) (loop (cons (get-output-string op) ls))]
|
||||
[(#!eof) (append (reverse ls) (source-directories))]
|
||||
[else (write-char c op) (loop ls)]))))))))
|
||||
|
||||
(define anchored-filename?
|
||||
(lambda (s)
|
||||
(and (> (string-length s) 0)
|
||||
(memv (string-ref s 0) '(#\/ #\.)))))
|
||||
|
||||
(define find-filename
|
||||
(lambda (fn)
|
||||
(if (anchored-filename? fn)
|
||||
fn
|
||||
(ormap
|
||||
(lambda (p)
|
||||
(let ([path (string-append p "/" fn)])
|
||||
(and (file-exists? path) path)))
|
||||
(source-directories)))))
|
||||
|
||||
(define open-input-file
|
||||
(lambda (fn . flags)
|
||||
(import scheme)
|
||||
(let ([path (find-filename fn)])
|
||||
(unless path
|
||||
(errorf #f
|
||||
(if (anchored-filename? fn)
|
||||
"unable to find file ~a"
|
||||
"unable to find file ~a in search path")
|
||||
fn))
|
||||
(apply open-input-file path flags))))
|
||||
)
|
1166
stex/src/scheme-prep.ss
Executable file
1166
stex/src/scheme-prep.ss
Executable file
File diff suppressed because it is too large
Load diff
710
stex/src/script.ss
Normal file
710
stex/src/script.ss
Normal file
|
@ -0,0 +1,710 @@
|
|||
;;; script.ss
|
||||
;;;
|
||||
;;; Copyright (c) 2005 R. Kent Dybvig
|
||||
;;;
|
||||
;;; Permission is hereby granted, free of charge, to any person obtaining a
|
||||
;;; copy of this software and associated documentation files (the "Software"),
|
||||
;;; to deal in the Software without restriction, including without limitation
|
||||
;;; the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
;;; and/or sell copies of the Software, and to permit persons to whom the
|
||||
;;; Software is furnished to do so, subject to the following conditions:
|
||||
;;;
|
||||
;;; The above copyright notice and this permission notice shall be included in
|
||||
;;; all copies or substantial portions of the Software.
|
||||
;;;
|
||||
;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
;;; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
;;; DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#!chezscheme
|
||||
(library (script)
|
||||
(export command-line-case run-script)
|
||||
(import (chezscheme))
|
||||
|
||||
#|
|
||||
|
||||
(command-line-case command-line [(<cmdspec>) <body>]*)
|
||||
|
||||
<cmdspec> -> (keyword <kwd> <required-arg>* <possible-action>]) <cmdspec>
|
||||
| (flags [<kwd> <flag-arg>* <possible-action>]*) <cmdspec>
|
||||
| <argspec>
|
||||
<possible-action> -> <empty> | $ <action>
|
||||
<flag-arg> -> <var> | (<type> <var>) | (<type> <var> <default>)
|
||||
<argspec> -> <required-arg>* <optional-arg>*
|
||||
| <required-arg>* <optional-arg>* <required-arg> ...
|
||||
<required-arg> -> <var> | (<type> <var>)
|
||||
<optional-arg> -> (optional <var>)
|
||||
| (optional <type> <var>)
|
||||
| (optional <type> <var> <default>)
|
||||
<kwd> -> <id> | (<id>+)
|
||||
<var> -> <id>
|
||||
<type> -> <id>
|
||||
<action> -> <expr>
|
||||
<default> -> <expr>
|
||||
|
||||
Each <var> must be unique.
|
||||
|
||||
If any <type> is not specified, it defaults to string.
|
||||
|
||||
If any <default> is not specified, it defaults to #f. Each <default>
|
||||
is scoped outside of the command-line-case form.
|
||||
|
||||
Command-line arguments are processed from left to right.
|
||||
|
||||
Command-line elements must appear in the order specified by <cmdspec>,
|
||||
except that each the flags in a single flags section may appear in
|
||||
any order and any flag may occur more than once.
|
||||
|
||||
For kewyword and flag clauses, the value of the <action>, if specified,
|
||||
is evaluated for effect. Each <action> is scoped where each of the <var>s
|
||||
is visible and each <var>'s current value is based on the specified or
|
||||
implicit defaults and the arguments seen so far.
|
||||
|
||||
If a flag occurs more than once on a command line, the final value of
|
||||
each corresponding <var> is its last specified value.
|
||||
|
||||
If <type> is not string, the procedure string-><type> is applied to the
|
||||
string argument to cast the string argument the actual value; it should
|
||||
return #f if the cast fails, in which case the clause doesn't match.
|
||||
A string-><type> routine should not cause side effects since it may be
|
||||
called even for clauses that don't match.
|
||||
|
||||
For flag clauses, variable ?id, where <kwd> = id or <kwd> = (id id1 ...),
|
||||
is bound to #t if the argument is specified at least once, otherwise #f.
|
||||
|
||||
Within each <body>, the variable usage is bound to a thunk that prints
|
||||
usage information. usage information is also printed if a command
|
||||
line cannot be parsed to fit any of the clauses.
|
||||
|
||||
consider:
|
||||
* instead of one keyword, have multiple keywords ALL of which must be
|
||||
provided in some order. use syntax (all (keyword ...) ...), and use
|
||||
(some (keyword ...) ...) instead of current "flags" syntax.
|
||||
|
||||
* add a prefix before <kwd> in flags section to allow multiple
|
||||
occurrences of the given flag and listification of the flag
|
||||
arguments
|
||||
|
||||
* option to print more verbose information when certain matches fail,
|
||||
for example, when a keyword or flag argument requires more additional
|
||||
arguments than are provided.
|
||||
|
||||
* allowing optional arguments after keywords and flags. leads to
|
||||
ambiguity in some cases.
|
||||
|
||||
Testing:
|
||||
|
||||
scheme
|
||||
(import (script))
|
||||
(define (exit . args) (void))
|
||||
|
||||
> (command-line-case '("a" "-q" "-v" "-v" "-b" "c")
|
||||
[((flags [-b c] [-q $ (write-char #\q)] [-v $ (write-char #\v)]))
|
||||
(list ?-b c)])
|
||||
qvv(#t "c")
|
||||
|
||||
> (let ()
|
||||
(define (bar cl)
|
||||
(command-line-case cl
|
||||
[((keyword --foo (number n))
|
||||
(flags [-b (number b)] [-q $ (write-char #\q)] [-v $ (write-char #\v)]))
|
||||
(pretty-print (list ?-b b))]))
|
||||
(bar '("a" "--foo" "32" "-q" "-v" "-v" "-b" "45"))
|
||||
(bar '("a" "--foo" "foo" "-q" "-v" "-v" "-b" "45"))
|
||||
(bar '("a" "--foo" "32" "-q" "-v" "-v" "-b" "b")))
|
||||
qvv(#t 45)
|
||||
usage: a --foo n [ -b b ] [ -q ] [ -v ]
|
||||
usage: a --foo n [ -b b ] [ -q ] [ -v ]
|
||||
|
||||
(define (foo cl)
|
||||
(define compact? #t)
|
||||
(define (register-boot-file x) (printf "registering boot file ~s\n" x))
|
||||
(define (register-heap-file x) (printf "registering boot file ~s\n" x))
|
||||
(command-line-case cl
|
||||
[((keyword --version))
|
||||
(print-version)]
|
||||
[((keyword --help (number helplevel)))
|
||||
(printf "here's your help: ~s\n" helplevel)]
|
||||
[((keyword --help))
|
||||
(print-help)]
|
||||
[((flags [(--boot -b) bootpath $ (register-boot-file bootpath)]
|
||||
[(--compact -c) $ (set! compact? (not compact?))]
|
||||
[(--heap -h) heappath $ (register-heap-file heappath)]
|
||||
[(--quiet -q)]
|
||||
[(--saveheap -s) (number level 0) savepath]
|
||||
[--verbose])
|
||||
(flags [--])
|
||||
a (optional b) (optional number c 666) (number d) ...)
|
||||
(let-syntax ([pr (syntax-rules ()
|
||||
[(_ x ...) (begin (printf " ~s = ~s\n" 'x x) ...)])])
|
||||
(pr ?--boot bootpath ?--compact ?--heap heappath ?--quiet
|
||||
?--saveheap level savepath ?--verbose ?--
|
||||
compact?
|
||||
a b c d))]))
|
||||
|
||||
> (foo '("/usr/local/bin/foo" "--help" "3"))
|
||||
here's your help: 3
|
||||
> (foo '("/usr/local/bin/foo" "aaa"))
|
||||
?--boot = #f
|
||||
bootpath = #f
|
||||
?--compact = #f
|
||||
?--heap = #f
|
||||
heappath = #f
|
||||
?--quiet = #f
|
||||
?--saveheap = #f
|
||||
level = 0
|
||||
savepath = #f
|
||||
?--verbose = #f
|
||||
?-- = #f
|
||||
compact? = #t
|
||||
a = "aaa"
|
||||
b = #f
|
||||
c = 666
|
||||
d = ()
|
||||
> (foo '("/usr/local/bin/foo" "aaa" "bbb"))
|
||||
?--boot = #f
|
||||
bootpath = #f
|
||||
?--compact = #f
|
||||
?--heap = #f
|
||||
heappath = #f
|
||||
?--quiet = #f
|
||||
?--saveheap = #f
|
||||
level = 0
|
||||
savepath = #f
|
||||
?--verbose = #f
|
||||
?-- = #f
|
||||
compact? = #t
|
||||
a = "aaa"
|
||||
b = "bbb"
|
||||
c = 666
|
||||
d = ()
|
||||
> (foo '("/usr/local/bin/foo" "aaa" "bbb" "#xccc"))
|
||||
?--boot = #f
|
||||
bootpath = #f
|
||||
?--compact = #f
|
||||
?--heap = #f
|
||||
heappath = #f
|
||||
?--quiet = #f
|
||||
?--saveheap = #f
|
||||
level = 0
|
||||
savepath = #f
|
||||
?--verbose = #f
|
||||
?-- = #f
|
||||
compact? = #t
|
||||
a = "aaa"
|
||||
b = "bbb"
|
||||
c = 3276
|
||||
d = ()
|
||||
> (foo '("/usr/local/bin/foo" "aaa" "bbb" "#xccc" "3" "4" "5"))
|
||||
?--boot = #f
|
||||
bootpath = #f
|
||||
?--compact = #f
|
||||
?--heap = #f
|
||||
heappath = #f
|
||||
?--quiet = #f
|
||||
?--saveheap = #f
|
||||
level = 0
|
||||
savepath = #f
|
||||
?--verbose = #f
|
||||
?-- = #f
|
||||
compact? = #t
|
||||
a = "aaa"
|
||||
b = "bbb"
|
||||
c = 3276
|
||||
d = (3 4 5)
|
||||
> (foo '("/usr/local/bin/foo" "aaa" "bbb" "ccc"))
|
||||
usage: foo --version
|
||||
foo --help helplevel
|
||||
foo --help
|
||||
foo [ --boot|-b bootpath ] [ --compact|-c ] [ --heap|-h heappath ] [ --quiet|-q ] [ --saveheap|-s level savepath ] [ --verbose ] [ -- ] a [ b ] [ c ] d ...
|
||||
> (foo '("/usr/local/bin/foo" "aaa" "bbb" "#xccc" "3" "4" "5" "ddd"))
|
||||
usage: foo --version
|
||||
foo --help helplevel
|
||||
foo --help
|
||||
foo [ --boot|-b bootpath ] [ --compact|-c ] [ --heap|-h heappath ] [ --quiet|-q ] [ --saveheap|-s level savepath ] [ --verbose ] [ -- ] a [ b ] [ c ] d ...
|
||||
> (foo '("/usr/local/bin/foo" "-q" "--boot" "foo.boot" "aaa"))
|
||||
registering boot file "foo.boot"
|
||||
?--boot = #t
|
||||
bootpath = "foo.boot"
|
||||
?--compact = #f
|
||||
?--heap = #f
|
||||
heappath = #f
|
||||
?--quiet = #t
|
||||
?--saveheap = #f
|
||||
level = 0
|
||||
savepath = #f
|
||||
?--verbose = #f
|
||||
?-- = #f
|
||||
compact? = #t
|
||||
a = "aaa"
|
||||
b = #f
|
||||
c = 666
|
||||
d = ()
|
||||
> (foo '("/usr/local/bin/foo" "-q" "--boot" "foo.boot" "-b"
|
||||
"--heap" "-h" "foo.heap" "-s" "7" "foo7.heap" "-c" "-c" "-c"
|
||||
"--verbose" "aaa"))
|
||||
registering boot file "foo.boot"
|
||||
registering boot file "--heap"
|
||||
registering boot file "foo.heap"
|
||||
?--boot = #t
|
||||
bootpath = "--heap"
|
||||
?--compact = #t
|
||||
?--heap = #t
|
||||
heappath = "foo.heap"
|
||||
?--quiet = #t
|
||||
?--saveheap = #t
|
||||
level = 7
|
||||
savepath = "foo7.heap"
|
||||
?--verbose = #t
|
||||
?-- = #f
|
||||
compact? = #f
|
||||
a = "aaa"
|
||||
b = #f
|
||||
c = 666
|
||||
d = ()
|
||||
|
||||
(command-line-case (cons "/usr/local/bin/foo" (command-line-arguments))
|
||||
[((keyword --build ifn)
|
||||
(flags [--verify] [(--output -o) (string ofn "a.out")])
|
||||
lib* ...)
|
||||
---]
|
||||
[((keyword (--query -q) ifn))
|
||||
---]
|
||||
[((flags [(--verify -v)] [(--output -o) (string ofn "a.out")])
|
||||
(string x*) ...)
|
||||
---]
|
||||
[((flags [(--verify -v)] [(--output -o) ofn])
|
||||
(flags [--])
|
||||
x* ...)
|
||||
---]
|
||||
[(x (optional integer y 0))
|
||||
---]
|
||||
[(x (optional integer y) x* ...)
|
||||
---]
|
||||
)
|
||||
|
||||
|#
|
||||
|
||||
(define-syntax command-line-case
|
||||
(lambda (x)
|
||||
;; Internal representation:
|
||||
;; ({ keyword | flags }* reqarg* optarg* restarg?)
|
||||
;; kwd's are strings
|
||||
;; vars's are syntax objects (identifiers)
|
||||
;; defaults are syntax objects
|
||||
;; actions are syntax objects or #f
|
||||
(define-record pkeyword ((immutable kwd*)
|
||||
(immutable reqarg*)
|
||||
(immutable action)))
|
||||
(define-record pflags ((immutable flag*)))
|
||||
(define-record pflag ((immutable kwd*)
|
||||
(immutable ?var)
|
||||
(immutable optarg*)
|
||||
(immutable action)))
|
||||
(define-record preqarg ((immutable type)
|
||||
(immutable var)))
|
||||
(define-record poptarg ((immutable type)
|
||||
(immutable var)
|
||||
(immutable default)))
|
||||
(define-record prestarg ((immutable reqarg)))
|
||||
(define-record pend ())
|
||||
|
||||
(module (parse-cmdspec)
|
||||
(define (parse-cmdspec cmdspec)
|
||||
(unless (syntax-case cmdspec () [(x ...) #t] [_ #f])
|
||||
(syntax-error cmdspec "improper argument declaration list"))
|
||||
(let parse-cmdspec ([cmdspec cmdspec])
|
||||
(syntax-case cmdspec (keyword flags $)
|
||||
[((keyword kwd reqarg ... $ actionexpr) . cmdspec)
|
||||
(cons (make-pkeyword
|
||||
(map id->string (parse-kwd #'kwd))
|
||||
(map parse-reqarg
|
||||
(syntax->list
|
||||
#'(reqarg ...)))
|
||||
#'actionexpr)
|
||||
(parse-cmdspec #'cmdspec))]
|
||||
[((keyword kwd reqarg ...) . cmdspec)
|
||||
(cons (make-pkeyword
|
||||
(map id->string (parse-kwd #'kwd))
|
||||
(map parse-reqarg
|
||||
(syntax->list
|
||||
#'(reqarg ...)))
|
||||
#f)
|
||||
(parse-cmdspec #'cmdspec))]
|
||||
[((keyword . ignore1) . ignore2)
|
||||
(syntax-error (syntax-case cmdspec () [(x . r) #'x])
|
||||
"invalid keyword declaration")]
|
||||
[((flags flagdecl ...) . cmdspec)
|
||||
(cons (make-pflags
|
||||
(map (lambda (flagdecl)
|
||||
(syntax-case flagdecl ($)
|
||||
[(kwd flagarg ... $ actionexpr)
|
||||
(let ([kwd* (parse-kwd #'kwd)])
|
||||
(make-pflag
|
||||
(map id->string kwd*)
|
||||
(make-?var (car kwd*))
|
||||
(map parse-flagarg
|
||||
(syntax->list #'(flagarg ...)))
|
||||
#'actionexpr))]
|
||||
[(kwd flagarg ...)
|
||||
(let ([kwd* (parse-kwd #'kwd)])
|
||||
(make-pflag
|
||||
(map id->string kwd*)
|
||||
(make-?var (car kwd*))
|
||||
(map parse-flagarg
|
||||
(syntax->list #'(flagarg ...)))
|
||||
#f))]
|
||||
[_ (syntax-error flagdecl
|
||||
"invalid flag declaration")]))
|
||||
(syntax->list #'(flagdecl ...))))
|
||||
(parse-cmdspec #'cmdspec))]
|
||||
[((flags . ignore1) . ignore2)
|
||||
(syntax-error (syntax-case cmdspec () [(x . r) #'x])
|
||||
"invalid flags declaration")]
|
||||
[argspec (parse-argspec #'argspec)])))
|
||||
(define (parse-kwd kwd)
|
||||
(syntax-case kwd ()
|
||||
[id (identifier? #'id) (list #'id)]
|
||||
[(id1 id2 ...) (syntax->list #'(id1 id2 ...))]
|
||||
[_ (syntax-error kwd "invalid kwd specifier")]))
|
||||
(define (parse-argspec argspec)
|
||||
(define (dots? x)
|
||||
(and (identifier? x)
|
||||
(literal-identifier=? x #'(... ...))))
|
||||
(syntax-case argspec ()
|
||||
[() (list (make-pend))]
|
||||
[(reqarg dots)
|
||||
(dots? #'dots)
|
||||
(list (make-prestarg (parse-reqarg #'reqarg)))]
|
||||
[(arg . argspec)
|
||||
(cons (parse-arg #'arg) (parse-argspec #'argspec))]
|
||||
[(x . r) (syntax-error #'x "invalid argument declaration")]))
|
||||
(define (parse-arg arg)
|
||||
(syntax-case arg (optional)
|
||||
[(optional . stuff) (parse-optarg arg)]
|
||||
[_ (parse-reqarg arg)]))
|
||||
(define (parse-reqarg reqarg)
|
||||
(syntax-case reqarg ()
|
||||
[var (identifier? #'var) (make-preqarg #'string #'var)]
|
||||
[(type var)
|
||||
(and (identifier? #'type) (identifier? #'var))
|
||||
(make-preqarg #'type #'var)]
|
||||
[x (syntax-error reqarg "invalid argument specifier")]))
|
||||
(define (parse-optarg optarg)
|
||||
(syntax-case optarg (optional)
|
||||
[(optional var)
|
||||
(identifier? #'var)
|
||||
(make-poptarg #'string #'var #'#f)]
|
||||
[(optional type var)
|
||||
(and (identifier? #'type) (identifier? #'var))
|
||||
(make-poptarg #'type #'var #'#f)]
|
||||
[(optional type var default)
|
||||
(and (identifier? #'type) (identifier? #'var))
|
||||
(make-poptarg #'type #'var #'default)]
|
||||
[x (syntax-error optarg "invalid optional argument specifier")]))
|
||||
(define (parse-flagarg flagarg)
|
||||
(syntax-case flagarg ()
|
||||
[var (identifier? #'var) (make-poptarg #'string #'var #'#f)]
|
||||
[(type var)
|
||||
(and (identifier? #'type) (identifier? #'var))
|
||||
(make-poptarg #'type #'var #'#f)]
|
||||
[(type var default)
|
||||
(and (identifier? #'type) (identifier? #'var))
|
||||
(make-poptarg #'type #'var #'default)]
|
||||
[x (syntax-error flagarg "invalid flag argument specifier")]))
|
||||
(define (id->string x) (symbol->string (syntax-object->datum x)))
|
||||
(define (make-?var x)
|
||||
(datum->syntax-object x
|
||||
(string->symbol (format "?~a" (id->string x))))))
|
||||
|
||||
(module (usage-printer)
|
||||
(define (usage-printer cmdspec+)
|
||||
#`(lambda (cl)
|
||||
(let ([who (path-last (car cl))])
|
||||
#,(usage-cmdspec "usage:" (car cmdspec+))
|
||||
#,@(map (lambda (cmdspec) (usage-cmdspec " " cmdspec)) (cdr cmdspec+)))))
|
||||
(define (usage-cmdspec leader cmdspec)
|
||||
(define cmdspec-printer
|
||||
(lambda (s*)
|
||||
#`(printf #,(format "~a ~~a~~a\n" leader) who #,(apply string-append s*))))
|
||||
(let-values ([(s* flag**) (usage-cmdspec-helper #t cmdspec)])
|
||||
(assert (null? flag**))
|
||||
(if (< (apply + (string-length leader) (map string-length s*)) 80)
|
||||
(cmdspec-printer s*)
|
||||
(let-values ([(s* flag**) (usage-cmdspec-helper #f cmdspec)])
|
||||
(fold-left
|
||||
(lambda (expr flag*)
|
||||
(let ([flag-header (car flag*)] [flag* (cdr flag*)])
|
||||
#`(begin
|
||||
#,expr
|
||||
(display-string #,(format " where each ~a is one of:\n~{ ~a\n~}"
|
||||
flag-header
|
||||
(map (lambda (kwd* optarg*)
|
||||
(format " ~a~{~a~}"
|
||||
(usage-kwd* kwd*)
|
||||
(map usage-optarg optarg*)))
|
||||
(map pflag-kwd* flag*)
|
||||
(map pflag-optarg* flag*)))))))
|
||||
(cmdspec-printer s*)
|
||||
flag**)))))
|
||||
(define (usage-cmdspec-helper inline-flags? cmdspec)
|
||||
(let loop ([cmdspec cmdspec]
|
||||
[rs* '()]
|
||||
[rflag** '()]
|
||||
[flagsno (and (not inline-flags?)
|
||||
(cond [(memp pflags? cmdspec) => (lambda (cmdspec) (memp pflags? (cdr cmdspec)))] [else #f])
|
||||
1)])
|
||||
(if (null? cmdspec)
|
||||
(values (reverse rs*) (reverse rflag**))
|
||||
(let ([x (car cmdspec)])
|
||||
(if (pflags? x)
|
||||
(if inline-flags?
|
||||
(loop (cdr cmdspec)
|
||||
(cons (let ([flag* (pflags-flag* x)])
|
||||
(format "~{~a~}"
|
||||
(map (lambda (kwd* optarg*)
|
||||
(format " [ ~a~{~a~} ]"
|
||||
(usage-kwd* kwd*)
|
||||
(map usage-optarg optarg*)))
|
||||
(map pflag-kwd* flag*)
|
||||
(map pflag-optarg* flag*))))
|
||||
rs*)
|
||||
rflag**
|
||||
flagsno)
|
||||
(let ([flag-header (if flagsno (format "flag~s" flagsno) "flag")])
|
||||
(loop (cdr cmdspec)
|
||||
(cons (format " ~a ..." flag-header) rs*)
|
||||
(cons (cons flag-header (pflags-flag* x)) rflag**)
|
||||
(and flagsno (+ flagsno 1)))))
|
||||
(loop (cdr cmdspec)
|
||||
(cons (cond
|
||||
[(pkeyword? x)
|
||||
(format " ~a~{~a~}"
|
||||
(usage-kwd* (pkeyword-kwd* x))
|
||||
(map usage-reqarg (pkeyword-reqarg* x)))]
|
||||
[(preqarg? x) (usage-reqarg x)]
|
||||
[(poptarg? x) (format " [~a ]" (usage-optarg x))]
|
||||
[(prestarg? x) (format "~a ..." (usage-reqarg (prestarg-reqarg x)))]
|
||||
[(pend? x) ""]
|
||||
[else (errorf 'usage-cmdspec "unrecognized cmdspec ~s" x)])
|
||||
rs*)
|
||||
rflag**
|
||||
flagsno))))))
|
||||
(define (usage-kwd* kwd*) (format "~a~{|~a~}" (car kwd*) (cdr kwd*)))
|
||||
(define (usage-reqarg x)
|
||||
(format " ~a" (syntax-object->datum (preqarg-var x))))
|
||||
(define (usage-optarg x)
|
||||
(format " ~a" (syntax-object->datum (poptarg-var x)))))
|
||||
|
||||
(define (xmap p ls tail)
|
||||
(if (null? ls)
|
||||
tail
|
||||
(p (car ls) (xmap p (cdr ls) tail))))
|
||||
|
||||
(module (findvars)
|
||||
(define (findvars cmdspec)
|
||||
(findvars-cmdspec cmdspec '()))
|
||||
(define (findvars-cmdspec cmdspec tail)
|
||||
(xmap
|
||||
(lambda (x tail)
|
||||
(cond
|
||||
[(pkeyword? x) (xmap findvars-reqarg (pkeyword-reqarg* x) tail)]
|
||||
[(pflags? x)
|
||||
(xmap (lambda (flag tail)
|
||||
(cons (pflag-?var flag)
|
||||
(xmap findvars-optarg (pflag-optarg* flag) tail)))
|
||||
(pflags-flag* x)
|
||||
tail)]
|
||||
[(preqarg? x) (findvars-reqarg x tail)]
|
||||
[(poptarg? x) (findvars-optarg x tail)]
|
||||
[(prestarg? x) (findvars-reqarg (prestarg-reqarg x) tail)]
|
||||
[(pend? x) tail]
|
||||
[else (errorf 'findvars-cmdspec "unrecognized cmdspec ~s" x)]))
|
||||
cmdspec
|
||||
tail))
|
||||
(define (findvars-reqarg x tail)
|
||||
(cons (preqarg-var x) tail))
|
||||
(define (findvars-optarg x tail)
|
||||
(cons (poptarg-var x) tail)))
|
||||
|
||||
(module (finddefaults)
|
||||
(define (finddefaults cmdspec)
|
||||
(finddefaults-cmdspec cmdspec '()))
|
||||
(define (finddefaults-cmdspec cmdspec tail)
|
||||
(xmap
|
||||
(lambda (x tail)
|
||||
(cond
|
||||
[(pkeyword? x)
|
||||
(xmap finddefaults-reqarg (pkeyword-reqarg* x) tail)]
|
||||
[(pflags? x)
|
||||
(xmap (lambda (flag tail)
|
||||
(cons #'#f
|
||||
(xmap finddefaults-optarg (pflag-optarg* flag) tail)))
|
||||
(pflags-flag* x)
|
||||
tail)]
|
||||
[(preqarg? x) (finddefaults-reqarg x tail)]
|
||||
[(poptarg? x) (finddefaults-optarg x tail)]
|
||||
[(prestarg? x) (cons #''() tail)]
|
||||
[(pend? x) tail]
|
||||
[else (errorf 'finddefaults-cmdspec "unrecognized cmdspec ~s" x)]))
|
||||
cmdspec
|
||||
tail))
|
||||
(define (finddefaults-reqarg x tail)
|
||||
(cons #'(void) tail))
|
||||
(define (finddefaults-optarg x tail)
|
||||
(cons (poptarg-default x) tail)))
|
||||
|
||||
(module (build-clause)
|
||||
(define (type->converter x)
|
||||
(if (and x (not (literal-identifier=? x #'string)))
|
||||
(datum->syntax-object x
|
||||
(string->symbol
|
||||
(format "string->~a" (syntax-object->datum x))))
|
||||
#'values))
|
||||
(define (build-clause-body var* cmdspec body)
|
||||
(with-syntax ([(var ...) var*])
|
||||
(let ([x (car cmdspec)])
|
||||
(cond
|
||||
[(pkeyword? x)
|
||||
(let ([reqarg* (pkeyword-reqarg* x)])
|
||||
(with-syntax ([(kwd ...) (pkeyword-kwd* x)]
|
||||
[(reqvar ...) (map preqarg-var reqarg*)]
|
||||
[(convert ...)
|
||||
(map type->converter (map preqarg-type reqarg*))]
|
||||
[action (or (pkeyword-action x) #'(#2%void))]
|
||||
[finish (build-clause-body var* (cdr cmdspec) body)]
|
||||
[n (length reqarg*)])
|
||||
#'(cond
|
||||
[(and (> (length cl) n) (member (car cl) '(kwd ...)))
|
||||
(let ([cl (cdr cl)])
|
||||
(apply (lambda (reqvar ... . ignore)
|
||||
; performs unnecessary tests if convert
|
||||
; is values; doesn't shortcut out as
|
||||
; soon as one convert returns false
|
||||
(let ([reqvar (convert reqvar)] ...)
|
||||
(if (and reqvar ...)
|
||||
(let ([cl (list-tail cl n)]
|
||||
[act! (lambda () (act!) action)])
|
||||
finish)
|
||||
(next orig-cl))))
|
||||
cl))]
|
||||
[else (next orig-cl)])))]
|
||||
[(pflags? x)
|
||||
(let* ([flag* (pflags-flag* x)]
|
||||
[optarg** (map pflag-optarg* flag*)])
|
||||
(with-syntax ([((kwd ...) ...) (map pflag-kwd* flag*)]
|
||||
[(?var ...) (map pflag-?var flag*)]
|
||||
[((optvar ...) ...)
|
||||
(map (lambda (optarg*)
|
||||
(map poptarg-var optarg*))
|
||||
optarg**)]
|
||||
[((convert ...) ...)
|
||||
(map (lambda (optarg*)
|
||||
(map type->converter
|
||||
(map poptarg-type optarg*)))
|
||||
optarg**)]
|
||||
[(action ...)
|
||||
(map (lambda (flag)
|
||||
(or (pflag-action flag) #'(#2%void)))
|
||||
flag*)]
|
||||
[finish (build-clause-body var* (cdr cmdspec) body)]
|
||||
[(n ...) (map length optarg**)])
|
||||
#'(let ([t (lambda (cl act! ?var ... optvar ... ...) finish)])
|
||||
(let f ([cl cl]
|
||||
[act! act!]
|
||||
[?var ?var] ...
|
||||
[optvar optvar] ... ...)
|
||||
(cond
|
||||
[(null? cl) (t cl act! ?var ... optvar ... ...)]
|
||||
[(and (> (length cl) n) (member (car cl) '(kwd ...)))
|
||||
(let ([cl (cdr cl)])
|
||||
(apply (lambda (optvar ... . ignore)
|
||||
; performs unnecessary tests if convert
|
||||
; is values; doesn't shortcut out as
|
||||
; soon as one convert returns false
|
||||
(let ([optvar (convert optvar)] ...)
|
||||
(if (and optvar ...)
|
||||
(let ([?var #t])
|
||||
(f (list-tail cl n)
|
||||
(lambda () (act!) action)
|
||||
?var ...
|
||||
optvar ... ...))
|
||||
(next orig-cl))))
|
||||
cl))]
|
||||
...
|
||||
[else (t cl act! ?var ... optvar ... ...)])))))]
|
||||
[(preqarg? x)
|
||||
(with-syntax ([reqvar (preqarg-var x)]
|
||||
[convert (type->converter (preqarg-type x))]
|
||||
[finish (build-clause-body var* (cdr cmdspec) body)])
|
||||
#'(cond
|
||||
; performs unnecessary test if convert is values
|
||||
[(and (not (null? cl)) (convert (car cl))) =>
|
||||
(lambda (reqvar) (let ([cl (cdr cl)]) finish))]
|
||||
[else (next orig-cl)]))]
|
||||
[(poptarg? x)
|
||||
(with-syntax ([optvar (poptarg-var x)]
|
||||
[convert (type->converter (poptarg-type x))]
|
||||
[finish (build-clause-body var* (cdr cmdspec) body)])
|
||||
#'(let ([t (lambda (optvar cl) finish)])
|
||||
(cond
|
||||
[(null? cl) (t optvar cl)]
|
||||
; performs unnecessary test if convert is values
|
||||
[(convert (car cl)) => (lambda (optvar) (t optvar (cdr cl)))]
|
||||
[else (next orig-cl)])))]
|
||||
[(prestarg? x)
|
||||
(let ([reqarg (prestarg-reqarg x)])
|
||||
(with-syntax ([restvar (preqarg-var reqarg)]
|
||||
[convert (type->converter (preqarg-type reqarg))]
|
||||
[body body])
|
||||
#'(let f ([cl cl] [rrestvar '()])
|
||||
(cond
|
||||
[(null? cl)
|
||||
(let ([restvar (reverse rrestvar)])
|
||||
(let () (act!) . body))]
|
||||
; performs unnecessary test if convert is values
|
||||
[(convert (car cl)) =>
|
||||
(lambda (x) (f (cdr cl) (cons x rrestvar)))]
|
||||
[else (next orig-cl)]))))]
|
||||
[(pend? x)
|
||||
(with-syntax ([body body])
|
||||
#'(if (null? cl)
|
||||
(let () (act!) . body)
|
||||
(next orig-cl)))]
|
||||
[else (errorf 'build-clause-body "unrecognized cmdspec ~s" x)]))))
|
||||
(define (build-clause cmdspec body next-expr)
|
||||
(let ([var* (findvars cmdspec)])
|
||||
(with-syntax ([next-expr next-expr]
|
||||
[(var ...) var*]
|
||||
[(default ...) (finddefaults cmdspec)]
|
||||
[clause-body (build-clause-body var* cmdspec body)])
|
||||
#'(let ([next next-expr])
|
||||
(lambda (orig-cl)
|
||||
(let ([cl (cdr orig-cl)] [act! #2%void] [var default] ...)
|
||||
clause-body)))))))
|
||||
|
||||
(syntax-case x ()
|
||||
[(k clexpr [cmdspeca b1a b2a ...] [cmdspec b1 b2 ...] ...)
|
||||
(let ([all-cmdspec* (map parse-cmdspec
|
||||
(cons #'cmdspeca
|
||||
(syntax->list #'(cmdspec ...))))]
|
||||
[body* #'((b1a b2a ...) (b1 b2 ...) ...)])
|
||||
(with-implicit (k usage)
|
||||
#`(let ([usage-proc #,(usage-printer all-cmdspec*)] [cl clexpr])
|
||||
(let ([usage (lambda () (usage-proc cl))])
|
||||
#,(with-syntax ([p (let f ([cmdspec* all-cmdspec*] [body* body*])
|
||||
(if (null? cmdspec*)
|
||||
#'(lambda (cl) (usage-proc cl) (exit 1))
|
||||
(build-clause (car cmdspec*) (car body*)
|
||||
(f (cdr cmdspec*) (cdr body*)))))])
|
||||
#'(p cl))))))])))
|
||||
|
||||
;;; (run-script script arg ...) runs named script in same process
|
||||
(define (run-script script . arg*)
|
||||
(command-line-arguments arg*)
|
||||
(load script))
|
||||
)
|
Reference in a new issue