diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /web/latexspider |
Initial commit
Diffstat (limited to 'web/latexspider')
-rw-r--r-- | web/latexspider/awkmake | 5 | ||||
-rw-r--r-- | web/latexspider/cmake | 5 | ||||
-rw-r--r-- | web/latexspider/cspider.dif | 17 | ||||
-rw-r--r-- | web/latexspider/docstrip.cmd | 11 | ||||
-rw-r--r-- | web/latexspider/latexweb.tex | 80 | ||||
-rw-r--r-- | web/latexspider/readme | 69 | ||||
-rw-r--r-- | web/latexspider/spider.ltx | 107 | ||||
-rw-r--r-- | web/latexspider/tangle.ltx | 78 | ||||
-rw-r--r-- | web/latexspider/tie.web | 1276 | ||||
-rw-r--r-- | web/latexspider/tiedoc.tex | 138 | ||||
-rw-r--r-- | web/latexspider/weave.ltx | 700 | ||||
-rw-r--r-- | web/latexspider/web.doc | 955 | ||||
-rw-r--r-- | web/latexspider/web.sty | 277 | ||||
-rw-r--r-- | web/latexspider/web.tex | 13 | ||||
-rw-r--r-- | web/latexspider/webmakefile | 172 |
15 files changed, 3903 insertions, 0 deletions
diff --git a/web/latexspider/awkmake b/web/latexspider/awkmake new file mode 100644 index 0000000000..02cc270328 --- /dev/null +++ b/web/latexspider/awkmake @@ -0,0 +1,5 @@ +/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\ + THETANGLE=awktangle THEWEAVE=awkweave SPIDER=awk.spider \ +SPIDERCHANGEFILE=../master/spider.ltx WEAVECHANGEFILE=../master/weave.ltx \ +TANGLECHANGEFILE=../master/tangle.ltx \ +CFLAGS='-O1 -DC_FLOATING_POINT -DLaTeX' LaTeX=1 $* diff --git a/web/latexspider/cmake b/web/latexspider/cmake new file mode 100644 index 0000000000..d2853dbaa1 --- /dev/null +++ b/web/latexspider/cmake @@ -0,0 +1,5 @@ +#!/bin/csh -f +/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\ +CFLAGS="-O1 -DC_FLOATING_POINT -DLaTeX" LaTeX=1 THETANGLE=ceetangle \ +THEWEAVE=ceeweave SPIDER=c.spider TANGLECHANGEFILE=../master/tangle.ltx \ +WEAVECHANGEFILE=../master/weave.ltx SPIDERCHANGEFILE=../master/spider.ltx $* diff --git a/web/latexspider/cspider.dif b/web/latexspider/cspider.dif new file mode 100644 index 0000000000..1ed829d428 --- /dev/null +++ b/web/latexspider/cspider.dif @@ -0,0 +1,17 @@ +*** c/c.spider Mon Feb 19 03:47:06 1990 +--- /home/users0/fx/ltxspiderweb/c/c.spider Wed Mar 13 11:58:35 1991 +*************** +*** 326,330 **** + + # control sequence \8 puts things on the left margin +! <force-"\\8"> sharp <"{\\let\\\\=\\bf"-space> (simp|if|else) <"}"-indent-"{}"-space> --> preproc + preproc backslash <force-"\\8\\hskip1em"-space> newline --> preproc + preproc <force-outdent> newline --> ignore_scrap +--- 326,332 ---- + + # control sequence \8 puts things on the left margin +! #<force-"\\8"> sharp <"{\\let\\\\=\\bf"-space> (simp|if|else) <"}"-indent-"{}"-space> --> preproc +! # changed to work with LaTeX as well: +! <force-"\\8"> sharp <"{\\let\\idfont=\\reservedfont"-space> (simp|if|else) <"}"-indent-"{}"-space> --> preproc + preproc backslash <force-"\\8\\hskip1em"-space> newline --> preproc + preproc <force-outdent> newline --> ignore_scrap diff --git a/web/latexspider/docstrip.cmd b/web/latexspider/docstrip.cmd new file mode 100644 index 0000000000..6997d1251a --- /dev/null +++ b/web/latexspider/docstrip.cmd @@ -0,0 +1,11 @@ +\preamble +You are not allowed to distribute this file without the corresponding +`.doc' version containing the documentation. + +\endpreamble + +\postamble +\string\endinput +\endpostamble + +%\generatefile{web.sty}{f}{\from{web.doc}} diff --git a/web/latexspider/latexweb.tex b/web/latexspider/latexweb.tex new file mode 100644 index 0000000000..325ba5dae0 --- /dev/null +++ b/web/latexspider/latexweb.tex @@ -0,0 +1,80 @@ +\documentstyle[ltugboat]{article} + +\let\tensl=\sl +\title{\WEB{} Adapted to \LaTeX{} --- a First Attempt} +\author{David Love} +\netaddress{d.love@daresbury.ac.uk} +\begin{document} +\maketitle +\noindent +Following Knuth's original Pascal/TeX{} \WEB{} system a number of +\WEB-like systems have been developed. Mostly these use the same +plain \TeX{} formatting system and differ in the languages supported +(although Thimbleby's CWEB system uses Troff and there are non-\WEB{} +literate programming systems like Scheme\TeX{} and {\tt doc.sty} that +use \LaTeX)\footnote{For a \WEB{} bibliography, see Lisa M. C. Smith +and Mansur Samadzadeh, {\sl SIGPLAN Notices\/} {\bf 26} (1991) 14}\@. +There are two advantages to using \LaTeX{} rather than plain \TeX{} +for formatting: +\begin{itemize} +\item greater accessibility for many (familiarity and ease of use) +which may encourage more people to use it; +\item the availability of extra intrinsic \LaTeX{} facilities and +especially style options. These might, for instance, support setting +your formal specification material as well as the code refined from +it, and in non-CM fonts. +\end{itemize} +This note describes a first attempt at integrating \LaTeX{} with +\WEB\ (actually Ramsey's Spider system for +`language-independent' \WEB s\footnote{Sometimes Spider doesn't do the +whole job for you: non-Algol-like languages may need the lexing +routines hacking. This gives the complication of +amalgamating the basic \WEAVE{} change file for \LaTeX{} formatting +with changes for the lexical routines etc.}). + +I have made minimal changes necessary for Spidery \WEB s to work with +\LaTeX\@. These take the form of change files for the base {\tt +weave.web}, {\tt tangle.web} and {\tt spider.web} (which generates the +language-dependent parts), conversion of the {\tt webkernel.tex} macro +file to a \LaTeX{} sub-style and trivial updates to the make files. A +trivial change to the {\tt c.spider} file that describes the +prettyprinting grammar for C was also necessary. The result of +merging the change files with the original webs would be a {\tt +weave.web} that can be built for use with either plain \TeX\ or +\LaTeX\ using a makefile flag and a {\tt spider.web} that produces a +{\tt spider.awk} with a run-time switch to determine the formatter. +(\WEAVE\ cannot change the formatter assumed at run time, although it +would not be difficult to make it do so.) \WEB\ files can be woven +with either a plain or \LaTeX\ \WEAVE\ if they avoid using +incompatible macros or define them appropriately in limbo +according to whether the \LaTeX\ macros are present. + +The changes to {\tt spider.web} are minor; changes to {\tt weave.web} +and the macros are more extensive. Many of the original \WEB{} macros +clash with \LaTeX{} names or conventions and have been changed +appropriately, but only where necessary. The formatting style is +essentially unchanged apart from the use of the \LaTeX\ page headers +and contents list. {\tt web.sty} is documented with {\tt doc.sty} +since it is a pity not to use literate techniques to build literate +programming tools---the bulk of the work! There are some remaining +infelicities, such as floats being disrupted by the way the sectioning +code avoids page breaks and a lot of messiness due to the assumptions +of existing Spider descriptions. + +This hack could be developed in other directions, for instance: +\begin{itemize} +\item proper parameterisation of the formatting commands, perhaps +modelled after {\tt makeindex}; +\item adapting the formatting macros more to the \LaTeX{} style; +\item inclusion of a proper multi-level sectioning scheme. I think +the extra structure would be helpful in large webs, but implementing +it would require considerable attention to the guts of \TANGLE{} and +\WEAVE\@. (It affects \TANGLE{} through the comments it writes in the +code); +\item replacing the index processing with {\tt makeindex}. +\end{itemize} + +The changes should be available from the Aston archive as {\tt +[.web.spiderweb]latexmods.shar}. + +\makesignature diff --git a/web/latexspider/readme b/web/latexspider/readme new file mode 100644 index 0000000000..c5fcd13e33 --- /dev/null +++ b/web/latexspider/readme @@ -0,0 +1,69 @@ +This is a collection of files to enable you to use Spidery Web with +LaTeX as the formatter rather than plain TeX. It is copyright D.Love, +SERC Daresbury Laboratory 1991 under the same conditions as the Spider +distribution. + +-------------------------------------------------------------------- +#include <disclaimer.h> +Snail mail: | JANET: d.love@uk.ac.dl +Dr. David Love, | modern BIT/INTERNET: d.love@dl.ac.uk +SERC Daresbury Laboratory, | old UUCP: ...!ukc!daresbury!d.love +Warrington WA4 4AD, | alternative BITNET: d.love%dl@ukacrl +UK | alternative ARPA: d.love%dl@nsfnet-relay.ac.uk + 'Phone: (+44/0)925 603573, Telex: ...925 629609, FAX: ...925 603173 + + +Here is a contents list. You will need to copy the files to the +correct sub-directories of the spider source (once you are sure you +want to) and invoke, for instance, `make weave' in the C directory to +make a LaTeX version of weave. See web.doc for definitive information +on the TeX aspect of things. + +* README This file; + +* latexweb.tex A short LaTeX document describing this stuff, + intended for submission to TUGboat; + +* weave.ltx A change file for $MASTER/weave.web which + inserts #defines to allow it to be compiled + for LaTeX-compatible output; + +* tangle.ltx Trivial change file for $MASTER/tangle.web to + allow woven output from it to be printed with + either LaTeX or plain; + +* spider.ltx Change file for $MASTER/spider.web to allow it + to produce output for a plain or LaTeX weave; + +* WebMakefile Changed version of $MASTER/WebMakefile + to cope with the change files above and the + different possible versions (also with my + filenames wired in); + +* web.doc Self-documenting LaTeX sub-style for use + instead of webkernel.tex. Probably needs + Mittelbach's newdoc.sty, v1.6d or later to + produce documentation -- instructions at the + front of it; + +* web.sty web.doc with comments stripped; + +* web.tex Driver file to print web.doc; + +* docstrip.cmd Used by the .doc->.sty process; + +* cmake Changed version of $SPIDER/c/make to produce + LaTeX ceeweave; + +* awkmake Changed version of $SPIDER/awk/make to produce + LaTeX awkweave; + +* cspider.dif Trivial diff from $SPIDER/c/c.spider to allow + it to work with LaTeX or plain; + +* tie.web Translation of the TIE processor to spidery + C-web. This allows you to merge change files + with the original or with other change files, + which may be useful for combining the LaTeX + changes with any you already have; + diff --git a/web/latexspider/spider.ltx b/web/latexspider/spider.ltx new file mode 100644 index 0000000000..6e26a5304e --- /dev/null +++ b/web/latexspider/spider.ltx @@ -0,0 +1,107 @@ +% this is spider.ch $Header: /home/users0/fx/ltxspiderweb/master/spider.ltx,v 1.3 91/03/22 11:19:54 fx Exp $ +% for a LaTeX version of spider +% d.love@daresbury.ac.uk + +l 5 (don't want batchmode for debugging; only print changes; for + LaTeX: want \documentstyle and fix use of \. and \title) +#x +\message{OK, entering \string\batchmode...} +\batchmode +#y +\ifx\enddocument\undefined \else % check for LaTeX + \documentstyle[web]{article} + \let\maybe\iffalse + \let\.=\str + \def\LaTeX{{\rm L\kern-.36em\raise.3ex\hbox{\sc a}\kern-.15em + T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}} +\fi +#z + +l 13 (change title page stuff) +#x +\def\title{SPIDER} + +\def\topofcontents{\null\vfill + \titlefalse % include headline on the contents page + \def\rheader{\hfil} + \centerline{\titlefont The {\ttitlefont SPIDER} processor} + \vfill} +#y +\ifx\enddocument\undefined % check for LaTeX +\def\title{SPIDER} + +\def\topofcontents{\null\vfill + \titlefalse % include headline on the contents page + \def\rheader{\hfil} + \centerline{\titlefont The {\ttitlefont SPIDER} processor} + \vfill} +\else + \title{The {\tt SPIDER} processor} \date{} +\fi +#z + +l 39 +#x +The unusual lexical requirements of FORTRAN are probably beyond it, at +least until the lexical analysis is modernized.) +#y +The unusual lexical requirements of FORTRAN are probably beyond it, at +least until the lexical analysis is modernized.) + +This version of Spider has been changed to be able to produce a +\.{WEAVE} suitable for use with \LaTeX{} rather than plain \TeX{}. +The changes are minor and can be found by looking up ``LaTeX'' in the +index. You get the \LaTeX{} version by defining |LaTeX=1| or +something (the variable |LaTeX| should be non-null) on +the \.{awk} command line when you run Spider. The limbo part will sort +itself out for \LaTeX{} or plain when you weave this file. +#z + +l 188 (bug fix) +#x +#<Set init...#>= + scrapfile = "scraps.web" + print "@*Scrap code generated by {\tt SPIDER}." > scrapfile + ttokfile = "outtoks.web" + print "@*Token code generated by {\tt SPIDER}." > scrapfile +#y +#<Set init...#>= + scrapfile = "scraps.web" + print "@*Scrap code generated by {\\tt SPIDER}." > scrapfile + ttokfile = "outtoks.web" + print "@*Token code generated by {\\tt SPIDER}." > scrapfile +#z + +l 211 (bug fix) +#x + grammarfile = "grammar.web" + print "@*Grammar code generated by {\tt SPIDER}." > grammarfile +#y + grammarfile = "grammar.web" + print "@*Grammar code generated by {\\tt SPIDER}." > grammarfile +#z + +l 2108 (change for LaTeX) +#x + printf "*out_ptr='x'; tex_printf(\"\\\\input %sweb.te\");\n", \ + extension > wlang +#y + if (LaTeX=="") { #^LaTeX#> + printf "*out_ptr='x'; tex_printf(\"\\\\input %sweb.te\");\n", \ + extension > wlang + }else{ + printf "*out_ptr='}'; tex_printf(\"\\\\def\\\\webmacs{%sweb.tex\");\n", \ + extension > wlang + } +#z + +l 2121 (change for LaTeX) +#x +#<Write the first line of the macro file#>= + macrofile = extension "web.tex" + print "\\input webkernel.tex" > macrofile +#y +#<Write the first line of the macro file#>= + macrofile = extension "web.tex" + if (LaTeX=="") print "\\input webkernel.tex" > macrofile #^LaTeX#> +#z diff --git a/web/latexspider/tangle.ltx b/web/latexspider/tangle.ltx new file mode 100644 index 0000000000..f603f8769b --- /dev/null +++ b/web/latexspider/tangle.ltx @@ -0,0 +1,78 @@ +this is tangle.latex-ch to fix tangle.web so that it can be woven with +the LaTeX version of weave +$Header: /home/users0/fx/ltxspiderweb/master/tangle.ltx,v 1.1 91/03/22 11:32:59 fx Exp $ +d.love@daresbury.ac.uk + +l 12 (fix for use with LaTeX or plain) +@x +% Here is TeX material that gets inserted after \input webmac + +\message{OK, entering \string\batchmode...} +\batchmode + +\def\hang{\hangindent 3em\indent\ignorespaces} +\font\ninerm=cmr9 +\let\mc=\ninerm % medium caps +\def\cee{C} +\def\pb{$\.|\ldots\.|$} % C brackets (|...|) +\def\v{\char'174} % vertical (|) in typewriter font +\def\ceeref{{\it The C Reference Manual}} +\mathchardef\RA="3221 % right arrow +\mathchardef\BA="3224 % double arrow + +\def\title{Spidery TANGLE} +\def\contentspagenumber{1} % should be odd +\def\topofcontents{\null\vfill + \titlefalse % include headline on the contents page + \def\rheader{\hfil} + \centerline{\titlefont The {\ttitlefont Spidery TANGLE} processor} + \vfill +} +@y +% Here is TeX material that gets inserted after \documentstyle + +% \message{OK, entering \string\batchmode...} +% \batchmode + +\ifx\enddocument\undefined % LaTeX? +\font\ninerm=cmr9 % no... +\let\mc=\ninerm % medium caps (not actually used) +\def\title{Spidery TANGLE} +\def\contentspagenumber{1} % should be odd +\def\topofcontents{\null\vfill + \titlefalse % include headline on the contents page + \def\rheader{\hfil} + \centerline{\titlefont The {\ttitlefont Spidery TANGLE} processor} + \vfill +} +\else % yes... +\documentstyle[web]{article} +\title{Spidery TANGLE}\date{} +\let\.=\str +\fi + +\def\hang{\hangindent 3em\indent\ignorespaces} +\def\cee{C} +\def\pb{$\.|\ldots\.|$} % C brackets (|...|) +\def\v{\char'174} % vertical (|) in typewriter font +\def\ceeref{{\it The C Reference Manual}} +\mathchardef\RA="3221 % right arrow +\mathchardef\BA="3224 % double arrow +@z + +l 1296 (fix \item) +@x +\yskip \item{a)}Module names are not allowed in macros; +in fact, the appearance of a module name terminates such macros and denotes +the name of the current module. + +\item{b)}The symbols \.{@@d} and \.{@@f} and \.{@@u} are not allowed after +module names, while they terminate macro definitions. +@y +\begin{itemize} + \item[a)]Module names are not allowed in macros; +in fact, the appearance of a module name terminates such macros and denotes +the name of the current module. +\item[b)]The symbols \.{@@d} and \.{@@f} and \.{@@u} are not allowed after +module names, while they terminate macro definitions. +\end{itemize} diff --git a/web/latexspider/tie.web b/web/latexspider/tie.web new file mode 100644 index 0000000000..3739558e19 --- /dev/null +++ b/web/latexspider/tie.web @@ -0,0 +1,1276 @@ +% This is TIE.CWB as of 25 Oct 89 +%--------------------------------------------------------- +% (c) 1989 by THD/ITI. Put into the public domain. + +% +% Version 1.7 was built alike TIE.WEB Version 1.6 (89-01-27) +% but used a command line interface only +% Version 2.0 was revised to include optional tab expansion (89-02-01) +% Version 2.1 deleted WEB relicts. (-js) (89-10-25) +% + +% Converted to spidery web Dave Love Feb 91 & bug fixed at line 990 +% and took out a couple of `@+' after `*' which break spidery weave + +% Here is TeX material that gets inserted after \input cwebmac + +\def\hang{\hangindent 3em\indent\ignorespaces} +\font\mc=cmr9 +\def\PASCAL{Pascal} +\def\Cl{{\rm C}} +\def\ASCII{{\mc ASCII}} + +\def\title{TIE} +\def\topofcontents{\null\vfill + \centerline{\titlefont The {\ttitlefont TIE} processor} + \vskip 15pt + \centerline{(CWEB Version 2.1)} + \vfill} +\def\botofcontents{ +\null\vfill +\item{$\copyright$}1989 + by Technische Hochschule Darmstadt,\hfill\break +Fachbereich Informatik, Institut f\"ur Theoretische Informatik\hfill\break +All rights reserved.\hfill\break +This program is put into the public domain and may be used freely +for any non commercial purposes. +} + + + + + +@* Introduction. + +\noindent Whenever a programmer wants to change a given +\.{WEB} or \.{CWEB} program (referred to as a \.{WEB} program throughout +this program) because of system dependencies, he will +create a new change file. In addition there may be a second +change file to modify system independent modules of the +program. But the \.{WEB} file cannot be tangled and weaved +with more than one change file simultaneously. Therefore, +we introduce the present program to merge a \.{WEB} file and +several change files producing a new \.{WEB} file. Since +the input files are tied together, the program is called +\.{TIE}. Furthermore, the program can be used to merge +several change files giving a new single change file. This +method seems to be more important because it doesn't modify +the original source file. The use of \.{TIE} can be +expanded to other programming languages since this processor +only knows about the structure of change files and does not +interpret the master file at all. + +The program \.{TIE} has to read lines from several input +files to bring them in some special ordering. For this +purpose an algorithm is used which looks a little bit +complicated. But the method used only needs one buffer line +for each input file. Thus the storage requirement of +\.{TIE} does not depend on the input data. + +The program is written in \Cl\ and uses only few features of a +particular environment that may need to be changed in other +installations. +E.g.\ it will not use the |enum| type declarations. +The changes needed may refer to the access of the command line +if this can be not supported by any \Cl\ compiler. + +The ``banner line'' defined here should be changed whenever +\.{TIE} is modified. This program is put into the public +domain. Nevertheless the copyright notice must not be +replaced or modified. + +@d banner="This is TIE, CWEB Version 2.1." +@d copyright= + "Copyright (c) 1989 by THD/ITI. All rights reserved." + + +@ The main outline of the program is given in the next section. +This can be used more or less for any \Cl\ program. +@c +@<Global |#include|s@> +@<Global constants@> +@<Global types@> +@<Global variables@> +@<Error handling functions@> +@<Internal functions@> +@<The main function@> + +@ Here are some macros for common programming idioms. + +@d incr(a) = a+=1 /* increase a variable by unity */ +@d decr(a) = a-=1 /* decrease a variable by unity */ +@d loop = @+ while (1)@+ /* repeat over and over until a |break| happens */ +@d do_nothing = /* empty statement */ +@f loop repeat + + +@ Furthermore we include the additional types |boolean| and |string|. + +@<Global types@>= +#define @!false 0 +#define @!true 1 +typedef int @!boolean; +typedef char* string; + + +@ The following parameters should be sufficient for most +applications of \.{TIE}. +@^system dependencies@> + +@<Global constants@>= +#define @!buf_size 512 /* maximum length of one input line */ +#define @!max_file_index 9 +/* we don't think that anyone needs more than 9 change files, + but \dots\ just change it */ + + +@ We introduce a history variable that allows us to set a +return code if the operating system can use it. +First we introduce the coded values for the history. +This variable must be initialized. +(We do this even if the value given may be the default for +variables, just to document the need for the initial value.) +@d spotless=0 +@d troublesome=1 +@d fatal=2 + +@<Global variables@>= +int @!history=spotless; + + + +@* The character set. + +\noindent One of the main goals in the design of \.{TIE} has +been to make it readily portable between a wide variety of +computers. Yet \.{TIE} by its very nature must use a +greater variety of characters than most computer programs +deal with, and character encoding is one of the areas in +which existing machines differ most widely from each other. + +To resolve this problem, all input to \.{TIE} is converted to an +internal seven-bit code that is essentially standard \ASCII{}, the +``American Standard Code for Information Interchange.'' The conversion +is done immediately when each character is read in. Conversely, +characters are converted from \ASCII{} to the user's external +representation just before they are output. But the algorithm is +prepared for the usage of eight-bit data. + +\noindent Here is a table of the standard visible \ASCII{} codes: +$$\def\:{\char\count255\global\advance\count255 by 1} +\count255='40 +\vbox{ +\hbox{\hbox to 40pt{\it\hfill0\/\hfill}% +\hbox to 40pt{\it\hfill1\/\hfill}% +\hbox to 40pt{\it\hfill2\/\hfill}% +\hbox to 40pt{\it\hfill3\/\hfill}% +\hbox to 40pt{\it\hfill4\/\hfill}% +\hbox to 40pt{\it\hfill5\/\hfill}% +\hbox to 40pt{\it\hfill6\/\hfill}% +\hbox to 40pt{\it\hfill7\/\hfill}} +\vskip 4pt +\hrule +\def\^{\vrule height 10.5pt depth 4.5pt} +\halign{\hbox to 0pt{\hskip -24pt\O{#0}\hfill}&\^ +\hbox to 40pt{\tt\hfill#\hfill\^}& +&\hbox to 40pt{\tt\hfill#\hfill\^}\cr +04&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule} +05&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule} +06&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule} +07&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule} +10&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule} +11&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule} +12&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule} +13&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule} +14&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule} +15&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule} +16&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule} +17&\:&\:&\:&\:&\:&\:&\:\cr} +\hrule width 280pt}$$ +(Actually, of course, code @'040 is an invisible blank space.) Code @'136 +was once an upward arrow (\.{\char'13}), and code @'137 was +once a left arrow (\.^^X), in olden times when the first draft +of ASCII code was prepared; but \.{TIE} works with today's standard +ASCII in which those codes represent circumflex and underline as shown. +The maximum value used is also defined, it must be changed if an +extended \ASCII{} is used. + +If the \Cl\ compiler is not able to process \&{unsigned char}'s, you +should define |ASCII_Code| as \&{short}. +@^system dependencies@> + +@<Global types@>= +#define max_ASCII @`~'+1 +typedef unsigned char @!ASCII_Code; + /* eight-bit numbers, a subrange of the integers */ + + +@ \Cl\ was first implemented on a machine that uses the +\ASCII{} representation for characters. But to make it readily +available also for other machines (big brother is watching?)\ +we add a conversion that may be undone for most installations. +\.{TIE} assumes that it is being used +with a character set that contains at least the +characters of standard \ASCII{} as listed above. + +In order to accommodate this difference, we shall use the +name |text_char| to stand for the data type of the +characters in the input and output files. We shall also +assume that |text_char| consists of the elements +|first_text_char| through |last_text_char|, +inclusive. The following definitions should be adjusted if +necessary. +@^system dependencies@> + +@d text_char = @+ unsigned char /* the data type of characters in text files */ +@d first_text_char=0 /* ordinal number of the smallest element of |text_char|*/ +@d last_text_char=255 /* ordinal number of the largest element of |text_char|*/ +@f FILE int + +@<Global types@>= +typedef FILE* @!text_file; + + +@ The \.{TIE} processor converts between \ASCII{} code and +the user's external character set by means of arrays |xord| +and |xchr| that are analogous to \PASCAL's |ord| and |chr| +functions. + +The mapping may be disabled by changing the following macro +definitions to just a cast. If your \Cl\ compiler does not support +\&{unsigned char}'s, you should incorporate a binary and with @"ff. +@^system dependencies@> + +@d map_xchr(a)=xchr[a] + /* change this to |(text_char)(a)| on \ASCII{} machines */ +@d map_xord(a)=xord[a] + /* change this to |(ASCII_Code)(a)| on \ASCII{} machines */ + +@<Global variables@>= +ASCII_Code @!xord[last_text_char+1]; + /* specifies conversion of input characters */ +text_char @!xchr[max_ASCII+1]; + /* specifies conversion of output characters */ + + +@ If we assume that every system using \.{WEB} is able to +read and write the visible characters of standard \ASCII{} +(although not necessarily using the \ASCII{} codes to +represent them), the following assignment statements +initialize most of the |xchr| array properly, without +needing any system-dependent changes. For example, the +statement |xchr[@`A']='A'| that appears in the present +\.{WEB} file might be encoded in, say, {\mc EBCDIC} code on +the external medium on which it resides, but \.{CTANGLE} will +convert from this external code to \ASCII{} and back again. +Therefore the assignment statement |xchr[65]='A'| will +appear in the corresponding \Cl\ file, and \Cl\ will +compile this statement so that |xchr[65]| receives the +character \.A in the external code. Note that it +would be quite incorrect to say |xchr[@`A']=@`A'|, because +|@`A'| is a constant of type |int| not \&{char}, and +because we have |@`A'==65| regardless of the external +character set. + +@<Set initial values@>= +xchr[@` ']=' '; +xchr[@`!']='!'; +xchr[@`"']='"'; +xchr[@`#']='#';@/ +xchr[@`$']='$'; +xchr[@`%']='%'; +xchr[@`&']='&'; +xchr[@`'']='\'';@/ +xchr[@`(']='('; +xchr[@`)']=')'; +xchr[@`*']='*'; +xchr[@`+']='+';@/ +xchr[@`,']=','; +xchr[@`-']='-'; +xchr[@`.']='.'; +xchr[@`/']='/';@/ +xchr[@`0']='0'; +xchr[@`1']='1'; +xchr[@`2']='2'; +xchr[@`3']='3';@/ +xchr[@`4']='4'; +xchr[@`5']='5'; +xchr[@`6']='6'; +xchr[@`7']='7';@/ +xchr[@`8']='8'; +xchr[@`9']='9'; +xchr[@`:']=':'; +xchr[@`;']=';';@/ +xchr[@`<']='<'; +xchr[@`=']='='; +xchr[@`>']='>'; +xchr[@`?']='?';@/ +xchr[@`@@']='@@'; +xchr[@`A']='A'; +xchr[@`B']='B'; +xchr[@`C']='C';@/ +xchr[@`D']='D'; +xchr[@`E']='E'; +xchr[@`F']='F'; +xchr[@`G']='G';@/ +xchr[@`H']='H'; +xchr[@`I']='I'; +xchr[@`J']='J'; +xchr[@`K']='K';@/ +xchr[@`L']='L'; +xchr[@`M']='M'; +xchr[@`N']='N'; +xchr[@`O']='O';@/ +xchr[@`P']='P'; +xchr[@`Q']='Q'; +xchr[@`R']='R'; +xchr[@`S']='S';@/ +xchr[@`T']='T'; +xchr[@`U']='U'; +xchr[@`V']='V'; +xchr[@`W']='W';@/ +xchr[@`X']='X'; +xchr[@`Y']='Y'; +xchr[@`Z']='Z'; +xchr[@`[']='[';@/ +xchr[@`\\']='\\'; +xchr[@`]']=']'; +xchr[@`^']='^'; +xchr[@`_']='_';@/ +xchr[@`'']='`'; +xchr[@`a']='a'; +xchr[@`b']='b'; +xchr[@`c']='c';@/ +xchr[@`d']='d'; +xchr[@`e']='e'; +xchr[@`f']='f'; +xchr[@`g']='g';@/ +xchr[@`h']='h'; +xchr[@`i']='i'; +xchr[@`j']='j'; +xchr[@`k']='k';@/ +xchr[@`l']='l'; +xchr[@`m']='m'; +xchr[@`n']='n'; +xchr[@`o']='o';@/ +xchr[@`p']='p'; +xchr[@`q']='q'; +xchr[@`r']='r'; +xchr[@`s']='s';@/ +xchr[@`t']='t'; +xchr[@`u']='u'; +xchr[@`v']='v'; +xchr[@`w']='w';@/ +xchr[@`x']='x'; +xchr[@`y']='y'; +xchr[@`z']='z'; +xchr[@`{']='{';@/ +xchr[@`|']='|'; +xchr[@`}']='}'; +xchr[@`~']='~';@/ +xchr[0]=' '; xchr[@"7F]=' '; /* these \ASCII{} codes are not used */ + + +@ Some of the \ASCII{} codes below @"20 have been given a +symbolic name in \.{TIE} because they are used with a special +meaning. + +@d tab_mark = @"09 /* \ASCII{} code used as tab-skip */ +@d nl_mark = @"0A /* \ASCII{} code used as line end marker */ +@d form_feed = @"0C /* \ASCII{} code used as page eject */ + + +@ When we initialize the |xord| array and the remaining +parts of |xchr|, it will be convenient to make use of an +index variable, |i|. + +@<Local variables for initialisation@>= +int i; + + +@ Here now is the system-dependent part of the character +set. If \.{TIE} is being implemented on a garden-variety +\Cl\ for which only standard \ASCII{} codes will appear +in the input and output files, you don't need to make any +changes here. +@^system dependencies@> + +Changes to the present module will make \.{TIE} more +friendly on computers that have an extended character set, +so that one can type things like \.^^Z. If you have an +extended set of characters that are easily incorporated into +text files, you can assign codes arbitrarily here, giving an +|xchr| equivalent to whatever characters the users of +\.{TIE} are allowed to have in their input files, provided +that unsuitable characters do not correspond to special +codes like |tab_mark| that are listed above. + +@<Set init...@>= +for (i=1;i<@` ';xchr[i++]=' '); +xchr[tab_mark]='\t'; +xchr[form_feed]='\f'; +xchr[nl_mark]='\n'; + + +@ The following system-independent code makes the |xord| +array contain a suitable inverse to the information in +|xchr|. + +@<Set init...@>= +for ( i=first_text_char ; i<=last_text_char ; xord[i++]=@` ' ) do_nothing; +for ( i=1 ; i<=@`~' ; i++ ) xord[xchr[i]] = i; + + + + + +@* Input and output. + +\noindent Output for the user is done by writing on file |term_out|, +which is assumed to consist of characters of type \&{text\_char}. It +should be linked to |stdout| usually. Terminal input is not needed in +this version of \.{TIE}. |stdin| and |stdout| are predefined if we +include the \.{stdio.h} definitions. Although I/O redirection for +|stdout| is usually available you may lead output to another file if +you change the definition of |term_out|. Also we define some macros +for terminating an output line and writing strings to the user. These +distinguish the number of parameters used to ease translation with a +\.{CWEB} like Sylvio Levy's that does not support a variable number of +parameters for macros. + +@^system dependencies@> +@d term_out=stdout +@d print(a)=fprintf(term_out,a) /* `|print|' means write on the terminal */ +@d print2(a)=fprintf(term_out,a) /* same with two arguments */ +@d print3(a)=fprintf(term_out,a) /* same with three arguments */ +@d print_c(a)=fputc(a,term_out); /* print a single character */ +@d new_line(a)=fputc('\n',a) /* start new line */ +@d term_new_line=new_line(term_out) /* start new line of the terminal */ +@d print_ln(a)={fprintf(term_out,a);term_new_line;} + /* `|print|' and then start new line */ +@d print2_ln(a)={print2(a);term_new_line;} /* same with two arguments */ +@d print3_ln(a)={print3(a);term_new_line;} /* same with three arguments */ +@d print_nl(a)= /* print information starting on a new line */ + {term_new_line; print(a);} +@d print2_nl(a)= /* same for two arguments */ + {term_new_line; print2(a);} + +@<Global |#include|s@>= +#include <stdio.h> + + +@ And we need dynamic memory allocation. +This should cause no trouble in any \Cl\ program. +@^system dependencies@> + +@<Global |#include|s@>= +extern char *malloc(); + + +@ The |update_terminal| function is called when we want to +make sure that everything we have output to the terminal so +far has actually left the computer's internal buffers and +been sent. +@^system dependencies@> + +@d update_terminal = fflush(term_out) /* empty the terminal output buffer */ + + + + + +@* Data structures. + +\noindent The multiple input files (master file and change +files) are treated the same way. To organize the +simultaneous usage of several input files, we introduce the +data type \&{in\_file\_modes}. + +The mode |search| indicates that \.{TIE} searches for a +match of the input line with any line of an input file in +|reading| mode. |test| is used whenever a match is found +and it has to be tested if the next input lines do match +also. |reading| describes that the lines can be read without +any check for matching other lines. |ignore| denotes +that the file cannot be used. This may happen because an +error has been detected or because the end of the file has +been found. + +\leavevmode |file_types| is used to describe whether a file +is a master file or a change file. The value |unknown| is added +to this type to set an initial mode for the output file. +This enables us to check whether any option was used to select +the kind of output. (this would even be necessary if we +would assume a default action for missing options.) + +@<Global types@>= +#define search 0 +#define test 1 +#define reading 2 +#define ignore 3 +typedef int @!in_file_modes; /* should be |enum(search,test,reading,ignore)| */ +#define unknown 0 +#define master 1 +#define chf 2 +typedef int @!file_types; /* should be |enum(unknown,master,chf)| */ + + +@ A variable of type |out_md_type| will tell us in what state the output +change file is during processing. |normal| will be the state, when we +did not yet start a change, |pre| will be set when we write the lines +to be changes and |post| will indicate that the replacement lines are +written. + +@<Global types@>= +#define normal 0 +#define pre 1 +#define post 2 +typedef int @!out_md_type; /* should be |enum(normal,pre,post)| */ + + +@ Two more types will indicate variables used as an index into either +the file buffer or the file table. + +@<Global types@>= +typedef int @!buffer_index; /* |-1..buf_size| */ +typedef int @!file_index; /* |-1..max_file_index+1| */ + + +@ The following data structure joins all informations needed to use +these input files. + +@<Global types@>= +typedef struct _idsc{ + string @!name_of_file; + ASCII_Code @!buffer[buf_size]; + in_file_modes @!mode; + long @!line; + file_types @!type_of_file; + buffer_index @!limit; + text_file the_file; + } @!input_description; + + +@ These data types are used in the global variable section. +They refer to the files in action, the number of change files, +the mode of operation and the current output state. + +@<Global variables@>= +file_index @!actual_input,@!test_input,@!no_ch; +file_types @!prod_chf=unknown; +out_md_type @!out_mode; + + +@ All input files (including the master file) are recorded +in the following structure. +Mostly the components are accessed through a local pointer variable. +This corresponds to \PASCAL's \&{with}-statement +and results in a one-time-computation of the index expression. + +@f input_description int + +@<Global variables@>= +input_description *@!input_organization[max_file_index+1]; + + + + + +@* File I/O. + +\noindent The basic function |get_line| can be used to get a line from +an input file. The line is stored in the |buffer| part of the +descriptor. The components |limit| and |line| are updated. If the +end of the file is reached |mode| is set to |ignore|. On some systems +it might be useful to replace tab characters by a proper number of +spaces since several editors used to create change files insert tab +characters into a source file not under control of the user. So it +might be a problem to create a matching change file. +@^tab character expansion@> + +We define |get_line| to read a line from a file specified by +the corresponding file descriptor. + +@<Internal functions@>= +@h void get_line(i) + file_index i; +{register input_description *inp_desc=input_organization[i]; + if (inp_desc->mode==ignore) return; + if (feof(inp_desc->the_file)) + @<Handle end of file and return@>; + @<Get line into buffer@>; +} + + +@ End of file is special if this file is the master file. +Then we set the global flag variable |input_has_ended|. + +@<Handle end of file ...@>= +{ + inp_desc->mode=ignore; + inp_desc->limit=-1; /* mark end-of-file */ + if (inp_desc->type_of_file==master) input_has_ended=true; + return; +} + + +@ This variable must be declared for global access. + +@<Global variables@>= +static boolean input_has_ended=false; + + +@ Lines must fit into the buffer completely. +We read all characters sequentially until an end of line is found +(but do not forget to check for |EOF|!). +Too long input lines will be truncated. +This will result in a damaged output if they occur in the +replacement part of a change file, or in an incomplerte check if the +matching part is concerned. +Tab character expansion might be done here. +@^tab character expansion@> + +@<Get line into buffer@>= +{int final_limit; /* used to delete trailing spaces */ + int c; /* the actual character read */ + @<Increment the line number and print a progess report at + certain times@> + inp_desc->limit=final_limit=0; + while (inp_desc->limit<buf_size) { + c=fgetc(inp_desc->the_file); + @<Check |c| for |EOF|, |return| if line was empty, otherwise + |break| to process last line@> + inp_desc->buffer[inp_desc->limit++]=c=map_xord(c); + if (c==nl_mark) break; /* end of line found */ + if (c!=@` ' && c!=tab_mark) + final_limit=inp_desc->limit; + } + @<Test for truncated line, skip to end of line@> + inp_desc->limit=final_limit; +} + + +@ This section does what its name says. Every 100 lines +in the master file we print a dot, every 500 lines the number +of lines is shown. + +@<Increment the line number and print ...@>= +incr(inp_desc->line); +if (inp_desc->type_of_file==master && inp_desc->line % 100==0) { + if (inp_desc->line % 500 == 0) print2("%ld",inp_desc->line); + else print_c('.'); + update_terminal; +} + + +@ There may be incomplete lines of the editor used does +not make sure that the last character before end of file +is an end of line. In such a case we must process the +final line. Of the current line is empty, we just can \&{return}. +Note that this test must be done {\sl before} the character read +is translated. +@^system dependencies@> + +@<Check |c| for |EOF|...@>= + if (c==EOF) { + if (inp_desc->limit<=0) { + inp_desc->mode=ignore; + inp_desc->limit=-1; /* mark end-of-file */ + if (inp_desc->type_of_file==master) input_has_ended=true; + return; + } else { /* add end of line mark */ + c=nl_mark; + break; + } + } + + +@ If the line is truncated we must skip the rest +(and still watch for |EOF|!). +@<Test for truncated line, skip to end of line@>= +if (c!=nl_mark) { + err_print("! Input line too long")(i); +@.Input line too long@> + while ( (c=fgetc(inp_desc->the_file)) != EOF && map_xord(c) != nl_mark ) + do_nothing; /* skip to end */ + } + + + + + +@* Reporting errors to the user. + +\noindent There may be errors if a line in a given change +file does not match a line in the master file or a +replacement in a previous change file. Such errors are +reported to the user by saying +$$ + \hbox{|err_print("! Error message")(file_no)|;} +$$ +where |file_no| is the number of the file which is concerned by the +error. Please note that no trailing dot is supplied by the error +message because it is appended by |err_print|. + +This function is implemented as a macro. It gives a message and an +indication of the offending file. The actions to determine the error +location are provided by a function called |err_loc|. + +@d error_loc(a) = err_loc(a); history=troublesome; @+ } +@d err_print(a) = { @+ print_nl(a); error_loc + +@<Error handling...@>= +@h void err_loc(i) /* prints location of error */ + int i; +{ + print3_ln(" (file %s, l.%ld).", + input_organization[i]->name_of_file, + input_organization[i]->line); +} + + +@ Non recoverable errors are handled by calling |fatal_error| that +outputs a message and then calls `|jump_out|'. |err_print| will print +the error message followed by an indication of where the error was +spotted in the source files. |fatal_error| cannot state any files +because the problem is usually to access these. + +@d fatal_error(a) = { + print(a); print_c('.'); history=fatal; + term_new_line; jump_out(); + } + + +@ |jump_out| just cuts across all active procedure levels and jumps +out of the program. It is used when no recovery from a particular +error has been provided. The return code from this program should be +regarded by the caller. + +@d jump_out(a) = exit(1) + + + + + +@* Handling multiple change files. + +\noindent In the standard version we take the name of the +files from the command line. +It is assumed that filenames can be used as given in the +command line without changes. + +First there are some sections to open all files. +If a file is not accessible, the run will be aborted. +Otherwise the name of the open file will be displayed. + +@<Prepare the output file@>= +{ + out_file=fopen(out_name,"w"); + if (out_file==NULL) { + fatal_error("! Could not open/create output file"); +@.Could not open/create output file@> + } +} + + +@ The name of the file and the file desciptor are stored in +global variables. + +@<Global variables@>= +text_file @!out_file; +string @!out_name; + + +@ For the master file we start just reading its first line +into the buffer, if we could open it. + +@<Get the master file started@>= +{ input_organization[0]->the_file= + fopen(input_organization[0]->name_of_file,"r"); + if (input_organization[0]->the_file==NULL) + fatal_error("! Could not open master file"); +@.Could not open master file@> + print2("(%s)",input_organization[0]->name_of_file); + term_new_line; + input_organization[0]->type_of_file=master; + get_line(0); +} + +@ For the change files we must skip the comment part and +see, whether we can find any change in it. +This is done by |init_change_file|. + +@<Prepare the change files@>= +{file_index i; + i=1; + while (i<no_ch) { + input_organization[i]->the_file= + fopen(input_organization[i]->name_of_file,"r"); + if (input_organization[i]->the_file==NULL) + fatal_error("!Could not open change file"); +@.Could not open change file@> + print2("(%s)",input_organization[i]->name_of_file); + term_new_line; + init_change_file(i,true); + incr(i); + } +} + + + + + +@*Input/output organization. + +\noindent Here's a simple function that checks if two lines +are different. + +@<Internal functions@>= +@h boolean lines_dont_match(i,j) + file_index i,j; +{ + buffer_index k,lmt; + if (input_organization[i]->limit != input_organization[j]->limit) + return(true); + lmt=input_organization[i]->limit; + for ( k=0 ; k<lmt ; k++ ) + if (input_organization[i]->buffer[k] != input_organization[j]->buffer[k]) + return(true); + return(false); +} + + +@ Function |init_change_file(i,b)| is used to ignore all +lines of the input file with index |i| until the next change +module is found. The boolean parameter |b| indicates +whether we do not want to see \.{@@x} or \.{@@y} entries during +our skip. + +@<Internal functions@>= +@h void init_change_file(i,b) + file_index i; boolean b; +{register input_description *inp_desc=input_organization[i]; + @<Skip over comment lines; |return| if end of file@>; + @<Skip to the next nonblank line; |return| if end of file@>; +} + + +@ While looking for a line that begins with \.{@@x} in the +change file, we allow lines that begin with \.{@@}, as long +as they don't begin with \.{@@y} or \.{@@z} (which would +probably indicate that the change file is fouled up). + +@<Skip over comment lines...@>= +loop@+ {ASCII_Code c; + get_line(i); + if (inp_desc->mode==ignore) return; + if (inp_desc->limit<2) continue; + if (inp_desc->buffer[0] != @`@@') continue; + c=inp_desc->buffer[1]; + if (c>=@`X' && c<=@`Z') + c+=@`z'-@`Z'; /*lowercasify*/ + if (c==@`x') break; + if (c==@`y' || c==@`z') + if (b) /* scanning for start of change */ + err_print("! Where is the matching @@x?")(i); +@.Where is the match...@> +} + + +@ Here we are looking at lines following the \.{@@x}. + +@<Skip to the next nonblank line...@>= +do{ + get_line(i); + if (inp_desc->mode==ignore) { + err_print("! Change file ended after @@x")(i); +@.Change file ended...@> + return; + } +} while (inp_desc->limit<=0); + + +@ The |put_line| function is used to write a line from +input buffer |j| to the output file. + +@<Internal functions@>= +@h void put_line(j) + file_index j; +{buffer_index i; /* index into the buffer */ + buffer_index lmt; /* line length */ + string p; /* output pointer */ + lmt=input_organization[j]->limit; + p=input_organization[j]->buffer; + for (i=0;i<lmt;i++) fputc(map_xchr(*p++),out_file); + new_line(out_file); +} + + +@ The function |e_of_ch_module| returns true if the input +line from file |i| starts with \.{@@z}. + +@<Internal functions@>= +@h boolean e_of_ch_module(i) + file_index i; +{register input_description *inp_desc=input_organization[i]; + if (inp_desc->limit<0) { + print_nl("! At the end of change file missing @@z "); +@.At the end of change file...@> + print2("%s",input_organization[i]->name_of_file); + term_new_line; + return(true); + } else if (inp_desc->limit>=2) if (inp_desc->buffer[0]==@`@@' && + (inp_desc->buffer[1]==@`Z' || inp_desc->buffer[1]==@`z')) + return(true); + return(false); +} + + +@ The function |e_of_ch_preamble| returns |true| if the input +line from file |i| starts with \.{@@y}. + +@<Internal functions@>= +@h boolean e_of_ch_preamble(i) + file_index i; +{register input_description *inp_desc=input_organization[i]; + if (inp_desc->limit>=2 && inp_desc->buffer[0]==@`@@') + if (inp_desc->buffer[1]==@`Y'||inp_desc->buffer[1]==@`y') return(true); + return(false); +} + + + +@ To process the input file the next section +reads a line of the actual input file and updates the +|input_organization| for all files with index |test_file| greater +|actual_input|. + +@<Process a line, |break| when end of source reached@>= +{file_index test_file; + @<Check the current files for any ends of changes@> + if (input_has_ended && actual_input==0) break; /* all done */ + @<Scan all other files for changes to be done@> + @<Handle output@> + @<Step to next line@> +} + + +@ Any of the current change files may have reached the end of change. +In such a case intermediate lines must be skipped and the next start +of change is to be found. This may make a change file inactive if +it reaches end of file. + +@<Check the...@>= +{register input_description *inp_desc; +while (e_of_ch_module(actual_input)) { + inp_desc=input_organization[actual_input]; + if (inp_desc->type_of_file==master) { + /* emergency exit, everything mixed up!*/ + fatal_error("! This can't happen: change file is master file"); +@.This can't happen...@> + } + inp_desc->mode=search; + init_change_file(actual_input,true); + while ((input_organization[actual_input]->mode!=reading + && actual_input>0)) decr(actual_input); +} +} + + +@ Now we will set |test_input| to the file that has another match +for the current line. This depends on the state of the other +change files. If no other file matches, |actual_input| refers to +a line to write and |test_input| ist set to |none|. + +@d none = (max_file_index+1) + +@<Scan all other files...@>= +test_input=none; +test_file=actual_input; +while (test_input==none && test_file</*no\_ch*/no_ch-1) { /* bug fix DL */ + incr(test_file); + switch (input_organization[test_file]->mode) { + case search: if (lines_dont_match(actual_input,test_file)==false) { + input_organization[test_file]->mode=test; + test_input=test_file; + } + break; + case test: if (lines_dont_match(actual_input, test_file)==true) { + /* error, sections do not match */ + input_organization[test_file]->mode=search; + err_print("! Sections do not match")(actual_input); +@.Sections do not match@> + err_loc(test_file); + init_change_file(test_file,false); + } else test_input=test_file; + break; + case reading: do_nothing; /* this can't happen */ + break; + case ignore: do_nothing; /* nothing to do */ + break; + } +} + + +@ For the output we must distinguish whether we create a new change +file or a new master file. The change file creation needs some closer +inspection because we may be before a change, in the pattern part or +in the replacement part. For a master file we have to write the line +from the current actual input. + +@<Handle output@>= +if (prod_chf==chf) { + loop @+ { + @<Test for normal, |break| when done@> + @<Test for pre, |break| when done@> + @<Test for post, |break| when done@> + } +} else +if (test_input==none) put_line(actual_input); + + +@ Check whether we have to start a change file entry. +Without a match nothing must be done. + +@<Test for normal...@>= +if (out_mode==normal) { + if (test_input!=none) { + fputc(map_xchr(@`@@'),out_file); fputc(map_xchr(@`x'),out_file); + new_line(out_file); + out_mode=pre; + } else break; +} + + +@ Check whether we have to start the replacement text. +This is the case when we have no more matching line. +Otherwise the master file source line must be copied to the +change file. +@<Test for pre...@>= + + if (out_mode==pre) { + if (test_input==none) { + fputc(map_xchr(@`@@'),out_file); fputc(map_xchr(@`y'),out_file); + new_line(out_file); + out_mode=post; + } else { + if (input_organization[actual_input]->type_of_file==master) + put_line(actual_input); + break; + } + } + + +@ Check whether an entry from a change file is complete. +If the current change was a change for a change file in effect, +then this change file line must be written. +If the actual input has been reset to the master file we +can finish this change. + +@<Test for post...@>= + if (out_mode==post) { + if (input_organization[actual_input]->type_of_file==chf) { + if (test_input==none) put_line(actual_input); + break; + } else { + fputc(map_xchr(@`@@'),out_file); fputc(map_xchr(@`z'),out_file); + new_line(out_file); + new_line(out_file); + out_mode=normal; + } + } + + +@ If we had a change, we must proceed in the actual file +to be changed and in the change file in effect. + +@<Step to next line@>= +get_line(actual_input); +if (test_input!=none) { + get_line(test_input); + if (e_of_ch_preamble(test_input)==true) { + get_line(test_input); /* update current changing file */ + input_organization[test_input]->mode=reading; + actual_input=test_input; + test_input=none; + } +} + + +@ To create the new output file we have to scan the whole +master file and all changes in effect when it ends. +At the very end it is wise to check for all changes +to have completed--in case the last line of the master file +was to be changed. + +@<Process the input@>= +actual_input=0; +input_has_ended=false; +while (input_has_ended==false||actual_input!=0) + @<Process a line...@> +if (out_mode==post) { /* last line has been changed */ + fputc(map_xchr(@`@@'),out_file); fputc(map_xchr(@`z'),out_file); + new_line(out_file); + } + + +@ At the end of the program, we will tell the user if the +change file had a line that didn't match any relevant line +in the master file or any of the change files. + +@<Check that all changes have been read@>= +{file_index i; +for (i=1;i<no_ch;i++) {/* all change files */ + if (input_organization[i]->mode!=ignore) + err_print("! Change file entry did not match")(i); +@.Change file entry ...@> + } +} + + +@ We want to tell the user about our command line options. This is +done by the |usage()| function. It contains merely the necessary +print statement and exits afterwards. + +@<Intern...@>= +@h void usage() +{ + print("Usage: tie -[mc] outfile master changefile(s)"); + term_new_line; + jump_out(); +} + + +@ We must scan through the list of parameters, given in |argv|. The +number is in |argc|. We must pay attention to the flag parameter. We +need at least 5~parameters and can handle up to |max_file_index| +change files. The names fo the file parameters will be inserted into +the structure of |input_organization|. The first file is special. It +indicates the output file. When we allow flags at any position, we +must find out which name is for what purpose. The master file is +already part of the |input_organization| structure (index~0). As long +as the number of files found (counted in |no_ch|) is |-1| we have not +yet found the output file name. + +@<Scan the parameters@>= +{int act_arg,act_orgpart; + if ( argc < 5 || argc > max_file_index+4-1 ) usage(); + no_ch = -1; /* fill this part of |input_organization| */ + for ( act_arg=1 ; act_arg<argc ; act_arg++ ) { + if (argv[act_arg][0]=='-') @<Set a flag@> + else @<Get a file name@> + } + if (no_ch<=0|| prod_chf==unknown) usage(); +} + + +@ The flag is about to determine the processing mode. +We must make sure that this flag has not been set before. +Further flags might be introduced to avoid/force overwriting of +output files. +Currently we just have to set the processing flag properly. + +@<Set a flag@>= +if (prod_chf!=unknown) usage(); +else + switch (argv[act_arg][1]) { + case 'c': + case 'C': prod_chf=chf; break; + case 'm': + case 'M': prod_chf=master; break; + default: usage(); + } + + +@ We have to distinguish whether this is the very first file name +(known if |no_ch==(-1)|) or if the next element of |input_organization| +must be filled. + +@<Get a file name@>= +{ if (no_ch==(-1)) { + out_name=argv[act_arg]; + } else { register input_description *inp_desc; + inp_desc=(input_description *) + malloc(sizeof(input_description)); + if (inp_desc==NULL) + fatal_error("! No memory for descriptor"); +@.No memory for descriptor@> + inp_desc->mode=search; + inp_desc->line=0; + inp_desc->type_of_file=chf; + inp_desc->limit=0; + inp_desc->name_of_file=argv[act_arg]; + input_organization[no_ch]=inp_desc; + } + incr(no_ch); +} + + +@* The main program. + +\noindent Here is where \.{TIE} starts, and where it ends. + +@<The main function@>= +@h main(argc,argv) + int argc; string *argv; +{{@<Local variables for initialisation@> + @<Set initial...@> + } + print_ln(banner); /* print a ``banner line'' */ + print_ln(copyright); /* include the copyright notice */ + actual_input=0; + out_mode=normal; + @<Scan the parameters@> + @<Prepare the output file@> + @<Get the master file started@>; + @<Prepare the change files@> + @<Process the input@>; + @<Check that all changes have been read@>; + @<Print the job |history|@>; +} + +@ We want to pass the |history| value to the operating system so that +it can be used to govern whether or not other programs are started. +Additionaly we report the history to the user, although this may not +be ``{\mc UNIX}'' style---but we are in best companion: \.{WEB} and +\TeX{} do the same. +@^system dependencies@> + +@<Print the job |history|@>= +{string msg; + switch (history) { + case spotless: msg="No errors were found"; break; + case troublesome: msg="Pardon me, but I think I spotted something wrong."; + break; + case fatal: msg="That was a fatal error, my friend"; break; + } /* there are no other cases */ + print2_nl("(%s.)",msg); term_new_line; + exit ( history == spotless ? 0 : 1 ); +} + + + + + +@* System-dependent changes. + +\noindent This section should be replaced, if necessary, by +changes to the program that are necessary to make \.{TIE} +work at a particular installation. It is usually best to +design your change file so that all changes to previous +modules preserve the module numbering; then everybody's +version will be consistent with the printed program. More +extensive changes, which introduce new modules, can be +inserted here; then only the index itself will get a new +module number. +@^system dependencies@> + + + + + +@* Index. + +\noindent Here is the cross-reference table for the \.{TIE} +processor. + diff --git a/web/latexspider/tiedoc.tex b/web/latexspider/tiedoc.tex new file mode 100644 index 0000000000..525ae60b4e --- /dev/null +++ b/web/latexspider/tiedoc.tex @@ -0,0 +1,138 @@ +% tiedoc.tex 25 Oct 89 + +% adapted to CWEB by J.Schrod on 89-10-25 + +\documentstyle[a4]{article} +\font\mc=cmcsc10 +\def\TANGLE{{\tt TANGLE}} +\def\TIE{{\tt TIE}} +\def\WEAVE{{\tt WEAVE}} +\def\WEB{{\tt WEB}} +\def\CWEB{{\mc cweb}} +\def\PASCAL{{\mc Pascal}} +\title{The TIE Processor} +\author{Klaus Guntermann\\ +TH Darmstadt\\ +Fachbereich Informatik\\ +Institut f\"ur Theoretische Informatik} + +\date{October 1989} +\begin{document} +\maketitle +\section{Introduction} + +To install a program on a computer usually +system dependent changes are needed. +The \WEB\ system allows to describe these changes in a +so called change file. +To incorporate the changes into the program \TANGLE\ processes +the original source file and inserts the changes into the proper places. + +Sometimes it is good practice to develop a set of change files to be able to +distinguish between different changes like +program enhancements, bug fixes, system dependent changes +and output device dependent modifications. +Additionally this allows combinations of changes that can be used with a set of +programs that share some common features. + +The processors \TANGLE\ and \WEAVE\ can handle only one change file. +The combination of change files is done best in another preprocessing step. +\TIE\ is able to create either a new master file or a single change file that +comprises the effect of all change files. + +Since \TIE\ does not know anything about \WEB\ programs but only about the +structure of change files, it is possible to use this program for other +programming languages as well. +You just pretend that you want to create a new master file and \TIE\ will go +and insert all the changes from your change files. + + + +\section{Application} + +The current version of \TIE\ accepts a master file and up to 9 change files. +Because in general it is important to use the changes in their proper sequence +the order of the files must be chosen carefully. + +The CWEB version of \TIE{} may be called with the following command +line interface: +% +\begin{verbatim} + tie -[mc] output_file master_file changefile(s) +\end{verbatim} +% +The option \verb|-m| results in the creation of a new master file, +\verb|-c| yields a new changefile. Usually wildcards may be used for +the filenames. + +The multiple change files are used as if the single change files were merged +into the master files step by step. +Thus more than 9 change files might be incorporated by repeated application of +\TIE. + +Please note that even when multiple change files are processed each of the +files is read only once. +For each of the change files and for the master file there is only one line in +memory at a time (neglecting operating system buffering). +Thus the storage requirement of \TIE\ does not depend on the size of the change +files or the size of a single changed section. + +\vfill\eject +\def\eof{$\langle$EOF$\rangle$} +\section{Example} + +To illustrate the actions \TIE\ performs you may inspect the following example +that exercises some of the border line cases. + +$$\vbox{ +\halign{#\hfill\qquad\quad&#\hfill\qquad\quad&#\hfill\qquad\quad&#\hfill\cr +``master'' &{\tt CF1} &{\tt CF2} &{\tt CF3}\cr +line 1 &@x &@x &@x\cr +line 2 &line 2 &line 1 &changed line 4\cr +line 3 &line 3 &changed line 2 &@y\cr +line 4 &@y &changed line 3 &final line 4\cr +line 5 &changed line 2 &inserted line &@z\cr +line 6 &changed line 3 &line 4 &\eof\cr +line 7 &inserted line &@y\cr +line 8 &@z &final line 2\cr +line 9 & &final line 3\cr +line 10 &@x &changed line 4\cr +\eof &line 7 &@z\cr + &@y\cr + &changed line 7 &@x\cr + &@z &changed line 7\cr + &\eof &line 8\cr + & &@y\cr + & &final line 7\cr + & &final line 8\cr + & &@z\cr + & &\eof\cr} +}$$ +\vfill\eject +Using these input files and running \TIE\ twice to create a new master file +and a new change file will result in the following output files: + +$$\vbox{ +\halign{#\hfill\qquad\quad&&#\hfill\qquad\quad\cr +``master'' &``change''\cr +final line 2 &@x\cr +final line 3 &line 1\cr +final line 4 &line 2\cr +line 5 &line 3\cr +line 6 &line 4\cr +final line 7 &@y\cr +final line 8 &final line 2\cr +line 9 &final line 3\cr +line 10 &final line 4\cr +\eof &@z\cr + &\cr + &@x\cr + &line 7\cr + &line 8\cr + &@y\cr + &final line 7\cr + &final line 8\cr + &@z\cr + &\eof\cr} +}$$ +\end{document} diff --git a/web/latexspider/weave.ltx b/web/latexspider/weave.ltx new file mode 100644 index 0000000000..7b5454fee6 --- /dev/null +++ b/web/latexspider/weave.ltx @@ -0,0 +1,700 @@ +% This is `weave.ltx' to fix spidery weave for LaTeX. See +% `web.doc' for some comments about how it works. + +% changes copyright D.Love, SERC Daresbury Laboratory +% (d.love@daresbury.ac.uk) under the same conditions as the Spider +% distribution. + +%$Header: /home/users0/fx/ltxspiderweb/master/weave.ltx,v 1.4 91/03/22 11:24:35 fx Exp $ + + l 11 (remove \batchmode so we can see what's happening) +@x +% Here is TeX material that gets inserted after \input webmac + +\message{Entering \string\batchmode...} +\batchmode +@y +% Here is TeX material that gets inserted after \documentstyle[web]... + +% we turn off batch mode for debugging purposes + +%\message{Entering \string\batchmode...} +%\batchmode +@z + + l 16 (swicth for LaTeX or plain) +@x +\def\hang{\hangindent 3em\indent\ignorespaces} +\font\ninerm=cmr9 +\let\mc=\ninerm % medium caps +\def\cee{C} +\def\Pascal{Pascal} +\def\PASCAL{Ada} +\def\pb{$\.|\ldots\.|$} % C brackets (|...|) +\def\v{\.{\char'174}} % vertical (|) in typewriter font +\def\dleft{[\![} \def\dright{]\!]} % double brackets +\mathchardef\RA="3221 % right arrow +\mathchardef\BA="3224 % double arrow +\def\({} % kludge for alphabetizing certain module names + +\def\title{Spidery WEAVE} +\def\contentspagenumber{1} % should be odd +\def\topofcontents{\null\vfill + \titlefalse % include headline on the contents page + \def\rheader{\hfil} + \centerline{\titlefont The {\ttitlefont Spidery WEAVE} processor} + \vfill} +\pageno=\contentspagenumber \advance\pageno by 1 +\let\maybe=\iftrue +@y +\ifx \enddocument\undefined % are we using LaTeX? + \font\ninerm=cmr9 % no... + \let\mc=\ninerm % medium caps + +\def\title{Spidery WEAVE} +\def\contentspagenumber{1} % should be odd +\def\topofcontents{\null\vfill + \titlefalse % include headline on the contents page + \def\rheader{\hfil} + \centerline{\titlefont The {\ttitlefont Spidery WEAVE} processor} + \vfill} + \pageno=\contentspagenumber \advance\pageno by 1 +\def\LaTeX{{\rm L\kern-.36em\raise.3ex\hbox{\sc a}\kern-.15em + T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}}% +\else % yes... + \documentstyle[web]{article} + \let\.=\str % new name + \title{Spidery WEAVE} \date{} +\fi + +\def\hang{\hangindent 3em\indent\ignorespaces} +\def\cee{C} +\def\Pascal{Pascal} +\def\PASCAL{Ada} +\def\pb{$\.|\ldots\.|$} % C brackets (|...|) +\def\v{\.{\char'174}} % vertical (|) in typewriter font +\def\dleft{[\![} \def\dright{]\!]} % double brackets +\mathchardef\RA="3221 % right arrow +\mathchardef\BA="3224 % double arrow +\def\({} % kludge for alphabetizing certain module names + +\let\maybe=\iffalse % only changed sections -- perhaps you + % want to change this if you're + % weaving WEAVE for the first time + +@z + + l 39 +@x +@* Introduction. +\.{CWEAVE} has a fairly straightforward outline. It operates in +three phases: first it inputs the source file and stores cross-reference +data, then it inputs the source once again and produces the \TeX\ output +file, and finally it sorts and outputs the index. It can be compiled +with certain optional flags, |DEBUG| and |STAT|, the latter being used +to keep track of how much of \.{WEAVE}'s resources were actually used. +@y +@* Introduction. +\.{CWEAVE} has a fairly straightforward outline. It operates in +three phases: first it inputs the source file and stores cross-reference +data, then it inputs the source once again and produces the \TeX\ output +file, and finally it sorts and outputs the index. It can be compiled +with certain optional flags, |DEBUG| and |STAT|, the latter being used +to keep track of how much of \.{WEAVE}'s resources were actually used. + +This version has changes to make it work with \LaTeX{} as the +formatter, rather than plain \TeX\@@. The sections which are changed +for \LaTeX{} are indicated by |#ifdef LaTeX|, so you can define the +|LaTeX| switch when you compile it. You could generate a new +\.{weave.web} using \.{wmerge} or \.{tie} which you could use for +either plain or \LaTeX, since the limbo section will check for the +existence of \.{\\enddocument} (which presumably indicates \LaTeX). +@z + + l 361 +@x +@d underline = @'176 /* this code will be intercepted without confusion */ +@d param = @'177 /* ASCII delete will not appear */ +/* identifier =200 or octal @'310 */ +@#/* following three must be conseccutive for indexing to work */ +@d xref_roman = (identifier+roman) /* control code for `\.{@@\^}' */ +@y +@d underline = @'176 /* this code will be intercepted without confusion */ +@d param = @'177 /* ASCII delete will not appear */ +/* identifier =200 or octal |@'310| */ +@#/* following three must be consecutive for indexing to work */ +@d xref_roman = (identifier+roman) /* control code for `\.{@@\^}' */ +@z + + l 1140 +@x + for (k=p->byte_start; k<k_end; k++) { + if (*k=='$') {out('\\'); out('D'); out('O'); out(' ');} + else if (*k=='&') {out('\\'); out('a'); out('m'); out('p');} + else { + if (*k=='_' || *k=='%' || *k=='#' || *k=='^' || *k=='{' || *k=='}') +@y + for (k=p->byte_start; k<k_end; k++) { + if (*k=='$') {out('\\'); out('D'); out('O'); out(' ');} + else if (*k=='&') {out('\\'); out('a'); out('m'); out('p'); out(' ');} + else { + if (*k=='_' || *k=='%' || *k=='#' || *k=='^' || *k=='{' || *k=='}') +@z + + l 1159 +@x +No `\.{@@}' signs should occur in such material except in `\.{@@@@}' +pairs; such pairs are replaced by singletons. + +@u copy_limbo() +@y +No `\.{@@}' signs should occur in such material except in `\.{@@@@}' +pairs; such pairs are replaced by singletons. +For \LaTeX{} we have to introduce the start of the {\tt document} +environment.@^LaTeX{}@> + +@u copy_limbo() +@z + + l 1172 +@x + if (c!='z' && c!='Z') { + out(at_sign); + if (c!=at_sign) err_print("! Double @@ required outside of sections"); +@.Double \AT! required...@> + } + } + } +} +@y + if (c!='z' && c!='Z') { + out(at_sign); + if (c!=at_sign) err_print("! Double @@ required outside of sections"); +@.Double \AT! required...@> + } + } + } +#ifdef LaTeX + out_str("\n\\begin{document}\\maketitle\n"); +#endif LaTeX +} +@z + + l 1368 +@x +\.{\\mathrel\{} and \.{\\mathbin\{}, respectively. +Also |math_op| to \.{\\mathop\{}. +Other control sequences in the \TeX\ output will be `\.{\\\\\{}$\,\ldots\,$\.\}' +surrounding identifiers, `\.{\\\&\{}$\,\ldots\,$\.\}' surrounding +reserved words, `\.{\\.\{}$\,\ldots\,$\.\}' surrounding strings, +@y +\.{\\mathrel\{} and \.{\\mathbin\{}, respectively. +Also |math_op| to \.{\\mathop\{}. +Other control sequences in the plain \TeX\ output will be `\.{\\\\\{}$\,\ldots\,$\.\}' +surrounding identifiers, `\.{\\\&\{}$\,\ldots\,$\.\}' surrounding +reserved words, `\.{\\.\{}$\,\ldots\,$\.\}' surrounding strings, +@z + + l 1374 +@x +`\.{\\X$n$:}$\,\ldots\,$\.{\\X}' surrounding module names, where +|n| is the module number. + +@d math_bin = @'205 /* should these be octal or decimal? */ +@y +`\.{\\X$n$:}$\,\ldots\,$\.{\\X}' surrounding module names, where +|n| is the module number. +@^\LaTeX{}@> +In the \LaTeX\ output we'll have `\.{\\id\{}$\,\ldots\,$\.\}' +surrounding identifiers, `\.{\\res\{}$\,\ldots\,$\.\}' surrounding +reserved words, `\.{\\str\{}$\,\ldots\,$\.\}' surrounding strings, +`\.{\\cee\{}$\,\ldots\,$\.\}$\,$|force|' surrounding comments, and +`\.{\\X$n$:}$\,\ldots\,$\.{\\X}' surrounding module names, where +|n| is the module number. +@.\\id@>@.\\res@>@.\\str@> + +@d math_bin = @'205 /* should these be octal or decimal? */ +@z + + l 1472 +@x +\yskip\item{$\bullet$}ASCII codes and special codes like |force| and +|math_rel| represent themselves; + +\item{$\bullet$}|id_flag+p| represents \.{\\\\\{{\rm identifier $p$}\}}; + +\item{$\bullet$}|res_flag+p| represents \.{\\\&\{{\rm identifier $p$}\}}; + +\item{$\bullet$}|mod_flag+p| represents module name |p|; + +\item{$\bullet$}|tok_flag+p| represents token list number |p|; + +\item{$\bullet$}|inner_tok_flag+p| represents token list number |p|, to be +translated without line-break controls. +@y +\begin{itemize} +\item ASCII codes and special codes like |force| and +|math_rel| represent themselves; + +\item |id_flag+p| represents \.{\\\\\{{\rm identifier $p$}\}} in the +plain \TeX\ version or \.{\\str\{{\rm identifier $p$}\}} in the \LaTeX\ +version; + +\item |res_flag+p| represents \.{\\\&\{{\rm identifier $p$}\}} in +plain or \.{\\id\{{\rm identifier $p$}\}}; + +\item |mod_flag+p| represents module name |p|; + +\item |tok_flag+p| represents token list number |p|; + +\item |inner_tok_flag+p| represents token list number |p|, to be +translated without line-break controls. +\end{itemize} +@z + + l 1501 +@x + else for (j=*p; j<*(p+1); j++) { + r=*j%id_flag; + switch (*j/id_flag) { + case 1: printf("\\{"); print_id((name_dir+r)); printf("}"); break; + /* |id_flag| */ +@y + else for (j=*p; j<*(p+1); j++) { + r=*j%id_flag; +#ifdef LaTeX + switch (*j/id_flag) { + case 1: printf("\id{"); print_id((name_dir+r)); printf("}"); break; + /* |id_flag| */ + case 2: printf("\res{"); print_id((name_dir+r)); printf("}"); break; + /* |res_flag| */ + case 3: printf("<"); print_id((name_dir+r)); printf(">"); break; + /* |mod_flag| */ + case 4: printf("[[%d]]",r); break; /* |tok_flag| */ + case 5: printf("|[[%d]]|",r); break; /* |inner_tok_flag| */ + default: @<Print token |r| in symbolic form@>; + } +@.\\id@>@.\\res@> +#else + switch (*j/id_flag) { + case 1: printf("\\{"); print_id((name_dir+r)); printf("}"); break; + /* |id_flag| */ +@z + + l 1512 +@x + default: @<Print token |r| in symbolic form@>; + } + } +} +@y + default: @<Print token |r| in symbolic form@>; + } +#endif LaTeX + } +} +@z + + l 2075 +@x + +@<Append a string or...@>= +if (next_control==constant) app_str("\\O{"); +@.\\O@> +@y + +@<Append a string or...@>= +#ifdef LaTeX +if (next_control==constant) app_str("\\const{"); +@.\\const@> +else if (next_control==string) app_str("\\str{"); +@.\\str@> +else app_str("\\vstr{"); +@.\\vstr@> +#else +if (next_control==constant) app_str("\\O{"); +@.\\O@> +@z + + l 2079 +@x +@.\\.@> +else app_str("\\={"); +@.\\=@> +while (id_first<id_loc) { + if (*id_first==at_sign) { +@y +@.\\.@> +else app_str("\\={"); +@.\\=@> /* verbatim string */ +#endif LaTeX +while (id_first<id_loc) { + if (*id_first==at_sign) { +@z + + l 2197 +@x +breaks are inserted after the result of tokens like |break_space| and +|force|. (d) The final line break should be suppressed, and there should +be no |force| token output immediately after `\.{\\Y\\P}'. + +@ The output process uses a stack to keep track of what is going on at +@y +breaks are inserted after the result of tokens like |break_space| and +|force|. (d) The final line break should be suppressed, and there should +be no |force| token output immediately after `\.{\\Y\\P}' (or `\.{\\Y\\code}' +with \LaTeX{}).@^\LaTeX@> + +@ The output process uses a stack to keep track of what is going on at +@z + + l 2394 +@x +looks slightly better if set in a math-italic font instead of a (slightly +narrower) text-italic font. Thus we output `\.{\\\char'174a}' but +`\.{\\\\\{aa\}}'. + +@<Output an identifier@>= +out('\\'); +if (a==identifier) + if (length(cur_name)==1) out('|')@; +@.\\|@> +@y +looks slightly better if set in a math-italic font instead of a (slightly +narrower) text-italic font. Thus we output `\.{\\\char'174a}' but +`\.{\\\\\{aa\}}'. In \LaTeX\ we use `\.{\\ida a}' and `\.{\\id\{aa\}}'. +@^\LaTeX{}@> + +@<Output an identifier@>= +#ifdef LaTeX +out('\\'); +if (a==identifier) + if (length(cur_name)==1) out_str("ida "); +@.\\ida@> + else out_str("id"); +@.\\id@> +else out_str("res"); /* |a==res_word| */ +@.\\res@> +#else +out('\\'); +if (a==identifier) + if (length(cur_name)==1) out('|')@; +@.\\|@> +@z + + l 2045 +@x +else out('&')@; /* |a==res_word| */ +@.\\\&@> +if (length(cur_name)==1) out((cur_name->byte_start)[0])@; +else out_name(cur_name); +@y +else out('&')@; /* |a==res_word| */ +@.\\\&@> +#endif LaTeX +if (length(cur_name)==1) out((cur_name->byte_start)[0])@; +else out_name(cur_name); +@z + + l 2430 +@x +the largest one is used. A line break also occurs in the output file, +except at the very end of the translation. The very first line break +is suppressed (i.e., a line break that follows `\.{\\Y\\P}'). + +@<Look ahead for st...@>= { +@y +the largest one is used. A line break also occurs in the output file, +except at the very end of the translation. The very first line break +is suppressed (i.e., a line break that follows `\.{\\Y\\code}'). +@^\LaTeX{}@> + +@<Look ahead for st...@>= { +@z + + l 2442 +@x + if ((a!=' ' && a<indent) || a==backup || a>big_force) { + if (save_mode==outer) { + if (out_ptr>out_buf+3 && strncmp(out_ptr-3,"\\Y\\P",4)==0) + goto reswitch; + @<Output saved |indent| or |outdent| tokens@>; +@y + if ((a!=' ' && a<indent) || a==backup || a>big_force) { + if (save_mode==outer) { +#ifdef LaTeX + if (out_ptr>out_buf+3 && strncmp(out_ptr-3,"\\Y\\code",4)==0)@^\LaTeX{}@>@.\\code@> +#else + if (out_ptr>out_buf+3 && strncmp(out_ptr-3,"\\Y\\P",4)==0) +#endif LaTeX + goto reswitch; + @<Output saved |indent| or |outdent| tokens@>; +@z + + l 2632 +@x + +@ @<Translate an octal constant appearing in \TeX\ text@>= { +out_str("\\O{\\~"); + while ('0'<=*loc && *loc<'8') out(*loc++); +out('}'); +@y + +@ @<Translate an octal constant appearing in \TeX\ text@>= { +#ifdef LaTeX +out_str("\\code{\\~"); /* this occurrence of \.{\~} is OK for \LaTeX\ since +the control sequence is only defined within the scope of the \.{\\code} +macro */@^\LaTeX{}@>@.\\code@> +#else +out_str("\\O{\\~"); +#endif LaTeX + while ('0'<=*loc && *loc<'8') out(*loc++); +out('}'); +@z + + l 2638 +@x + +@ @<Translate a hex constant appearing in \TeX\ text@>= { +out_str("\\O{\\^"); + while (isxdigit(*loc)) { + out(islower(*loc) ? toupper(*loc):*loc); +@y + +@ @<Translate a hex constant appearing in \TeX\ text@>= { +#ifdef LaTeX +out_str("\\code{\\^"); /* OK for \LaTeX{} as above */ +@^\LaTeX{}@>@.\\code@> +#else +out_str("\\O{\\^"); +#endif LaTeX + while (isxdigit(*loc)) { + out(islower(*loc) ? toupper(*loc):*loc); +@z + + l 2662 +@x + +@ The |finish_C| procedure outputs the translation of the current +scraps, preceded by the control sequence `\.{\\P}' and followed by the +control sequence `\.{\\par}'. It also restores the token and scrap +memories to their initial empty state. +@y + +@ The |finish_C| procedure outputs the translation of the current +scraps, preceded by the control sequence `\.{\\P}' (`\.{\\code}' in +\LaTeX{}) and followed by the@^\LaTeX{}@> +control sequence `\.{\\par}'. It also restores the token and scrap +memories to their initial empty state. +@z + + l 2674 +@x +{ + text_pointer p; /* translation of the scraps */ + out_str("\\P"); app_tok(force); app_scrap(SP_ignore_scrap,no_math); + p=translate(); +@.\\P@> +@y +{ + text_pointer p; /* translation of the scraps */ +#ifdef LaTeX + out_str("\\code"); app_tok(force); app_scrap(SP_ignore_scrap,no_math); +@.\\code@>@^\LaTeX{}@> +#else + out_str("\\P"); app_tok(force); app_scrap(SP_ignore_scrap,no_math); +#endif LaTeX + p=translate(); +@.\\P@> +@z + + l 2710 +@x + token following the parameter list@>; + if (next_control==@`=') { + small_app('\\'); small_app('S'); /* equivalence sign */ + @<Set |next_control| to the first non-newline token@>@; + } else { +@y + token following the parameter list@>; + if (next_control==@`=') { +#ifdef LaTeX +@^\LaTeX{}@>@.\\equiv@> + small_app('\\'); app_str("equiv"); +#else + small_app('\\'); small_app('S'); /* equivalence sign */ +#endif LaTeX + @<Set |next_control| to the first non-newline token@>@; + } else { +@z + + l 2823 +@x + this_module=name_dir; /*so we won't give cross-reference info here*/ +} +app_str("\\S"); /* output an equivalence sign */ +@.\\S@> +app_str("{}$"); +small_app(force); +@y + this_module=name_dir; /*so we won't give cross-reference info here*/ +} +#ifdef LaTeX +app_str("\\equiv");@^\LaTeX{}@>@.\\equiv@> +#else +app_str("\\S"); /* output an equivalence sign */ +@.\\S@> +#endif LaTeX +app_str("{}$"); +small_app(force); +@z + + l 2950 +@x +if (no_xref) { + finish_line(); + out_str("\\vfill\\end"); + finish_line(); +} +@y +if (no_xref) { + finish_line(); +#ifdef LaTeX + out_str("\\end{document}");@^\LaTeX{}@>@.\\end{document}@> +#else + out_str("\\vfill\\end"); +#endif LaTeX + finish_line(); +} +@z + + l 2958 +@x + finish_line(); @<Tell about changed modules@>; + } + finish_line(); out_str("\\inx"); finish_line(); +@.\\inx@> + @<Do the first pass of sorting@>; + @<Sort and output the index@>; + out_str("\\fin"); finish_line(); +@.\\fin@> + @<Output all the module names@>; + out_str("\\con"); finish_line(); +@.\\con@> +} +@y + finish_line(); @<Tell about changed modules@>; + } +#if 0 + finish_line(); out_str("\\begin{theindex}"); finish_line(); +#endif + finish_line(); out_str("\\inx"); finish_line(); +@.\\inx@> + @<Do the first pass of sorting@>; + @<Sort and output the index@>; +#if 0 + out_str("\\end{theindex}\\fin"); finish_line(); +#endif + out_str("\\fin"); finish_line(); +@.\\fin@> + @<Output all the module names@>; + out_str("\\con\\end{document}"); finish_line(); +@.\\con@> +} +@z + + l 3137 +@x +@ @<Output the name...@>= +switch (cur_name->ilk) { + case normal: if (length(cur_name)==1) out_str("\\|"); + else out_str("\\\\"); break; +@y +@ @<Output the name...@>= +switch (cur_name->ilk) { +#ifdef LaTeX# + case normal: if (length(cur_name)==1) out_str("\\ida "); + else out_str("\\id"); break; +@^\LaTeX{}@>@.\\ida@>@.\\id@> +#else + case normal: if (length(cur_name)==1) out_str("\\|"); + else out_str("\\\\"); break; +@z + + l 3141 +@x +@.\\|@> +@.\\\\@> + case roman: break; + case wildcard: out_str("\\9"); break; +@.\\9@> + case typewriter: out_str("\\."); break; +@.\\.@> +@y +@.\\|@> +@.\\\\@> +#endif LaTeX + case roman: break; + case wildcard: out_str("\\9"); break; +@.\\9@> +#ifdef LaTeX + case typewriter: out_str("\\str"); break; +@.\\str@> + default: out_str("\\res"); +@.\\res@>@^\LaTeX{}@> +#else + case typewriter: out_str("\\."); break; +@.\\.@> +@z + + l 3148 +@x + default: out_str("\\&"); +@.\\\&@> +} +out_name(cur_name); +@y + default: out_str("\\&"); +@.\\\&@> +#endif LaTeX +} +out_name(cur_name); +@z + + l 3152 +@x + +@ Section numbers that are to be underlined are enclosed in +`\.{\\[}$\,\ldots\,$\.]'. + +@<Output the cross-references...@>= +@y + +@ Section numbers that are to be underlined are enclosed in +`\.{\\[}$\,\ldots\,$\.]' or `\.{\\underline}$\,\ldots\,$\.\}' in \LaTeX{}. +@^\LaTeX{}@> + +@<Output the cross-references...@>= +@z + + l 3159 +@x + out_str(", "); cur_val=cur_xref->num; + if (cur_val<def_flag) out_mod(cur_val); + else {out_str("\\["); out_mod(cur_val%def_flag); out(']');} +@.\\[@> + cur_xref=cur_xref->xlink; +} while (cur_xref!=xmem); +@y + out_str(", "); cur_val=cur_xref->num; + if (cur_val<def_flag) out_mod(cur_val); +#ifdef LaTeX + else {out_str("\\underline{"); out_mod(cur_val%def_flag); out('}');} +@.\\underline@>@^\LaTeX{}@> +#else + else {out_str("\\["); out_mod(cur_val%def_flag); out(']');} +@.\\[@> +#endif LaTeX + cur_xref=cur_xref->xlink; +} while (cur_xref!=xmem); +@z diff --git a/web/latexspider/web.doc b/web/latexspider/web.doc new file mode 100644 index 0000000000..65d9df1ca6 --- /dev/null +++ b/web/latexspider/web.doc @@ -0,0 +1,955 @@ +\iffalse % -*-latex-*- + +%% Copyright D.Love, SERC Daresbury Laboratory, 1991 +%% The `doc' version of this style is re-distributable and usuable +%% under conditions of the GNU copyleft, but please mark any changes, +%% list them here and report any major enhancements to the author. + +% This is a self-documenting style. To produce the documentation you +% might use a driver file like this: +% \def\webmacs{null} \documentstyle[a4,makeidx,newdoc,web]{article} +% \EnableCrossrefs \CodelineIndex +% \begin{document} \DocInput{web.sty} \PrintIndex +% \end{document} +% and run `makeindex -s gind.ist doc' in between passes. You need +% Mittelbach's newdoc.sty at v1.6d or later. + +% To produce the .sty file use `latex docstrip' to remove most of the +% comments. Please don't distribute the .sty file without the .doc +% file. +\fi + +\iffalse % hack RCS info into a sensible form: +\fi +\def\next$#1: #2/#3/#4 #5 ${\def\filedate{#4/#3/#2}\def\filetime{#5}} +\next$Date: 1991/06/19 10:28:40 $ + +\def\next$#1: #2 ${\def\fileversion{#2}} +\next$Revision: 1.2 $ + +% \title{A a \web{} style file for \LaTeX{}\thanks{This file is version +% \fileversion\ of \filedate}} +% \author{David Love\\[2ex]{\it SERC Daresbury Laboratory, Warrington +% WA4 4AD, UK}\\ \tt d.love@daresbury.ac.uk} +% \date{} +% +% \newcommand{\web}{{\tt WEB}} +% \newcommand{\weave}{{\tt WEAVE}} +% \newcommand{\tangle}{{\tt tangle}} +% \newcommand{\spider}{Spider} +% \MakeShortVerb{\"} + +% \DoNotIndex{\/,\@date,\@ifundefined,\@makefnmark,\@starttoc} +% \DoNotIndex{\@topnum,\addpenalty,addvspace,\advance,aftergroup} +% \DoNotIndex{\begin,\begingroup,\bgroup,\char,\def,\egroup,\else,\end} +% \DoNotIndex{\endgroup,\fi,\fnsymbol,\hfil,\hfill,\hfilneg,\hss,\kern} +% \DoNotIndex{\let,\lineskip,\newcommand,\protect,\qquad,\quad,\relax} +% \DoNotIndex{\thanks,\thefootnote,\z@,\@M,\@thanks,\@thefnmark,\hbox} +% \DoNotIndex{\empty,\mbox} + +% \maketitle +% +% \begin{abstract} \noindent +% This style file is for use with a version of the Spidery \weave\ system +% that has been adapted to use \LaTeX\ rather than plain \TeX\ for the +% formatting. It is a first attempt. +% \end{abstract} +% +% \section{Assumptions of \weave{} and the {\tt .web} file} +% +% We assume we're using the version of Spidery \weave{} \cite{spider} +% changed for \LaTeX\@. This will write out +% \begin{quote}"\def\webmacs{"\meta{ext}"web.tex}",\end{quote} +% (where \meta{ext} is +% the \spider{} {\tt extension}), then the limbo section, then +% \begin{quote}"\begin{document}\maketitle" \end{quote} +% the latter to stop you forgetting it. The "\webmacs" file will be +% included at the end of this style. +% After the index (if any), we get +% "\end{document}". The user thus has to put the "\documentstyle" +% command in the limbo part and include "web" in the style options to +% get this stuff and can use other options as appropriate. You're +% meant to use the "article" main style, although I think "report" +% would work too. +% +% \section{Strategy} +% +% The idea was to change the original \spider{} \TeX{} stuff as little +% as possible, although it has actually been changed quite +% substantially. Changes are forced where there is a clash of macro +% names; most of the original one-character control sequences are +% already used by \LaTeX, for instance. Some features have been +% converted to a \LaTeX{} equivalent, +% notably the table of contents mechanism, the title page, running +% header and double-columning for the index. For safety, "\def"s have +% been replaced by "\newcommands" where possible since there are +% probably plenty of possibilities for name clashes. +% User-visible differences from the plain version are given in +% appendix~\ref{changes}. +% +% \section{Use with old webs} +% +% Examples of the use of this style with old webs using the plain +% conventions can be found in the accompanying changes files for +% {\tt weave.web} and {\tt spider.web}. You can use the limbo section +% to check whether the generated ".tex" file is being run through +% \LaTeX\ or plain \TeX\ by doing something like this: +% \begin{quote} +% \begin{verbatim} +% \ifx\enddocument\undefined +% % plain things +% \else +% % LaTeX things +% \fi +% \end{verbatim} +% \end{quote} +% +% \section{Bugs} +% +% Floats +% don't always come out where you'd expect due to interaction with +% \web's attempts to keep all of a module on one page if possible. +% "\str" and "\vstr", which +% might well get used in a moving argument, are +% fragile. Module titles (after "@*") are moving arguments. I think +% if you use \web's "|"\dots"|" construction in a +% moving argument it will break and there's not much you can do about +% it. +% +% \section{Code} +% \subsection{Preliminaries --- page layout} +% +% Let's announce ourselves as usual: +% \begin{macrocode} +\typeout{Sub-style `web', version \fileversion\space of \filedate} +% \end{macrocode} +% We don't want stretch between paragraphs. +% \begin{macrocode} +\parskip \z@ +% \end{macrocode} +% \begin{macro}{\textwidth}\begin{macro}{\textheight} +% \begin{macro}{\oddsidemargin} \begin{macro}{\evensidemargin} +% The default page width should be large for \web\@. This is for +% non-Americans (A4)---if you want to alter the page dimensions with a +% suitable style option put it {\em after\/} "web" in the +% "\documentstyle" list. The width here is too big for decently +% readable text, but is +% still less than the $6.5''$ of the original. Note that there's no +% point in trying to use "\marginpar" at +% this width since the margins have disappeared! The "twoside" option +% will work sensibly if you care to use it.\DescribeMacro{twoside} We +% want to avoid doing this when typesetting the documenttation, hence +% the test for "\DocInput". +% \begin{macrocode} +\ifx\DocInput\undefined +\ifcase \@ptsize + \textheight = 53 \baselineskip +\or + \textheight = 47 \baselineskip +\or + \textheight = 43 \baselineskip +\fi \advance \textheight by \topskip +\textwidth=6.27in \oddsidemargin=\z@ \evensidemargin=\z@ +\fi +% \end{macrocode} +% \end{macro}\end{macro}\end{macro}\end{macro} +% We use the "myheadings" page style with headings containing module +% information (see below). +% \begin{macrocode} +\pagestyle{myheadings} +% \end{macrocode} +% If we start off with a "\sectionmark" we won't miss the running +% header off the first page where it should appear. +% \begin{macrocode} +\ifx\DocInput\undefined \sectionmark{1} \fi +% \end{macrocode} +% +% \subsubsection{Font selection} +% +% \begin{macro}{\normal@font} +% We have to check whether we're in the old or new font selection scheme +% and set up appropriately. "\normal@font" is invoked before the font +% changes for identifiers, reserved words and strings to make sure +% that they use the default series and shape in the new scheme. This +% is actually only necessary if "\id", "\res" or "\str" is used in +% \TeX\ text that is being set in a different shape or series, not +% normally in the code. If you use the new selection scheme you can +% do things like using Concrete or PostScript fonts easily. +% \begin{macrocode} +\@ifundefined{selectfont}{% + \let\normal@font=\relax} % old scheme + {% new scheme + \def\normal@font{\series \mediumseriesdefault + \shape \normalshapedefault}} +% \end{macrocode} +% \end{macro} +% +% \subsection{Front matter} +% +% We depart from the plain version here. The first page (or pages, if +% the contents are very long) is produced with the "titlepage" +% environment. The "\author", "\date" and +% "\title" \DescribeMacro{\title} can be specified +% as usual in \LaTeX\@. Note that you now say +% "\title{"\meta{title}"}" rather than "\def\title{"\meta{title}"}" as +% in the plain version and this title will be used in the running +% header. +% +% \begin{macro}{\@maketitle} +% We'll re-define "\@maketitle" to include the "\topofcontents" and +% "\botofcontents" information, with the contents information in the +% middle. The normal title, author and date will be put automatically +% at the top---"\topofcontents" is extra. You get the titling and +% contents information automatically, since "\maketitle" is inserted +% by \weave{} immediately after "\begin{document}". If you want to +% suppress it, "\let\maketitle=\relax" in the limbo part. +% +% Of course, you have to make two +% passes to get the contents printed, unlike the original plain +% system. This should not be much hardship as one usually reckons on +% running \LaTeX{} at least twice. (Putting the titlepage at the back +% won't help, since the ".toc" file only exists after the ".aux" file +% has been read on the secind pass. One could change the standard +% behaviour so that the ".toc" file was created at the end of the +% first pass, I guess.) +% We first test for "\DocInput" as above to +% avoid messing things up when typesetting the documentation. +% \begin{macrocode} +\ifx\DocInput\undefined +\def\@maketitle{% + \newpage \thispagestyle{empty} \null + \begin{center} + {\LARGE \@title \par} \vskip 1.5em + {\large \lineskip .5em + \begin{tabular}[t]{c} \@author \end{tabular} \par} + \vskip 1em {\large \@date} + \end{center} + \par \vskip 1.5em + \topofcontents \tableofcontents \par \botofcontents \newpage } +\fi +% \end{macrocode} +% \end{macro} +% \begin{macro}{\maketitle} +% We change "\maketitle" to avoid the "\thispagestyle{plain}" that it +% otherwise contains, to set the page number to 1 at the end and to +% avoid losing the definitions of "\@title" and "\@author". +% ("\@title" is used in the running header.) +% \begin{macrocode} +\ifx\DocInput\undefined +\def\maketitle{% + \par \begingroup + \pagenumbering{roman} \setcounter{page}{0} + \def\thefootnote{\fnsymbol{footnote}} + \def\@makefnmark{\hbox to \z@ {$^{\@thefnmark}$\hss}} + \if@twocolumn \twocolumn[\@maketitle] + \else \newpage \global\@topnum\z@ \@maketitle \fi + \@thanks + \endgroup + \setcounter{footnote}{0} \pagenumbering{arabic} + \let\maketitle\relax \let\@maketitle\relax + \gdef\@thanks{}\let\thanks\relax} +\fi +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@title} \begin{macro}{\@author} +% We better define these in case they're not supplied: +% \begin{macrocode} +\let\@title=\empty \let\@author=\empty +% \end{macrocode} +% \end{macro} \end{macro} +% \begin{macro}{\tableofcontents} +% "\tableofcontents" is re-defined to produce a header saying +% ``Section'' and ``Page'' a bit like the plain version, although the +% section (module) number is at the left. +% \begin{macrocode} +\def\tableofcontents{% + \noindent Section \hfill Page \par \@starttoc{toc}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\topofcontents} \begin{macro}{\botofcontents} +% The "\topofcontents" material that comes between the title\slash author +% information and the contents list and the "\botofcontents" stuff +% that comes after the contents list are empty initially. I'm not +% sure it's worth preserving them. +% \begin{macrocode} +\def\topofcontents{} \def\botofcontents{} +% \end{macrocode} +% \end{macro} \end{macro} +% \begin{macro}{\ttitlefont} \begin{macro}{\titlefont} +% These are just for compatibility with the plain version---they +% should probably go. +% \begin{macrocode} +\let\ttitlefont=\tt \let\titlefont=\rm +% \end{macrocode} +% \end{macro} \end{macro} +% +% \subsection{Prettyprinting stuff} +% \subsubsection{Identifiers, reserved words and strings} +% +% \begin{macro}{\id}\begin{macro}{\ida}\begin{macro}{\idfont} +% Multi-letter identifiers are set by the macro "\id" in font "\idfont", +% which is italic by default i.e., \id{identifier}. +% One-letter identifiers are +% actually set by "\ida" in math italic as they are supposed to look +% better that way (\ida{a} rather than \id{a}). +% \begin{macrocode} +\newcommand{\id}[1]{\mbox{\idfont #1\/\kern.05em}} +\newcommand{\ida}[1]{\mbox{$ #1 $}} +\newcommand{\idfont}{\normal@font \it} +% \end{macrocode} +% \end{macro} \end{macro} \end{macro} +% \begin{macro}{\reservedfont}\begin{macro}{\res} +% Reserved words are set by macro "\res", using "\reservedfont" which +% is bold by default i.e., \res{reserved}. +% \begin{macrocode} +\newcommand{\reservedfont}{\normal@font \bf} +\newcommand{\res}[1]{\mbox{\reservedfont#1\/}} +% \end{macrocode} +% \end{macro}\end{macro} +% +% \begin{macro}{\str} +% Typewriter type is used for strings, set by "\str" i.e., +% \str{string}. The definitions of the escaped characters +% are given below. I don't understand why the ampersand is treated +% like this, since "\&" is defined anyway, but quotes and "^" are +% escaped to avoid +% ligatures.\footnote{{\tt \char`\^} and {\tt \char`\~} form ligatures +% in PostScript virtual fonts as well as "'".} It's necessary to do a +% "\def" of "\^" rather than just +% "\let\^\CF" to avoid an error with the use of "\^" not matching its +% definition. Note the use of "\@tempa" below rather than "\XX" as +% used in the same situation elsewhere---using "\XX", "\str" breaks if +% it is used in, say, a comment. +% \begin{macrocode} +\def\str#1{% + \ifmmode \gdef\@tempa{\null$\null}\else \gdef\@tempa{}\fi + \@tempa {% + \let\\=\BS \let\'=\RQ \let\`=\LQ \let\{=\LB \let\}=\RB + \let\~=\TL \let\ =\SP \let\&=\AM \def\^{{\tt \char`\^}}% + \leavevmode \normal@font\tt #1}\@tempa} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\AM} \begin{macro}{\BS} \begin{macro}{\LB} +% \begin{macro}{\LQ} \begin{macro}{\RB} \begin{macro}{\UL} +% \begin{macro}{\TL} +% Here are the definitions of the control sequences for strings. The +% plain version redefined "\#", "\$", "\%" and "\^" globally. "\$" +% isn't used by awk or C \web s, and has been removed. The others are +% done only in code, using "\startcodehook" (below). +% \begin{macrocode} +\chardef\AM=`\& % ampersand +\chardef\BS=`\\ % backslash +\chardef\LB=`\{ % left brace +\def\LQ{{\tt\char'22}} % left quote +\chardef\RB=`\} % right brace +\def\RQ{{\tt\char'23}} % right quote +\def\UL{{\tt\char`\_}} % underline character in a string +\def\TL{{\tt\char`\~}} % tilde +% \end{macrocode} +% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro} +% \end{macro} +% \begin{macro}{\SP} +% Strings may be rather long and we want some way of breaking +% them, so +% "\SP" produces a visible space (\str{\SP}) and also adds a discretionary +% break afterwords. If a break occurs, the line is ended with a +% backslash. Spaces are probably the most sensible place to break +% strings, especially if they are messages, but one could consider +% doing the same thing for other of the macros above e.g., "\BS" might +% check if the next character was "n" and insert a discretionary break +% after that. +% \begin{macrocode} +\newcommand{\SP}{\char`\ \discretionary{\hbox{\char`\\}}{}{}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\vstr} +% This does a verbatim string (from "@=") using the existing \LaTeX +% nology rather than the original definition to put a frame around it +% (\vstr{string}). +% \begin{macrocode} +\newcommand{\vstr}[1]{\kern 2pt \fbox{\str{#1}}\kern 2pt} +\setlength{\fboxsep}{2pt} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\const} +% This looks after setting octal, hex or decimal constants. The first +% thing in its argument may be one of the control sequences in the +% example on the left, +% producing the result in the middle: +% \[\begin{tabular}{lll} +% "\const{\$10}" & $\const{\$10}$ & (long) \\ +% "\const{\_10}" & $\const{\_10}$ & (power of ten)\\ +% "\const{\~10}" & $\const{\~10}$ & (octal) \\ +% "\const{\^AB10}" & $\const{\^AB10}$ & (hex) \\ +% \end{tabular}\] +% \DeleteShortVerb{\"} +% \begin{macrocode} +\def\const#1{{% + \def\?{\kern.2em}% + \def\${\ell}% long + \def\_{\RealConstFormat{\aftergroup}}% power of ten + \def\~{\hbox{\rm \char'23\kern-.2em \it \aftergroup\?\aftergroup}}% octal +% \end{macrocode} +% The \verb+"+ here was originally \verb+\char'175+ which, +% unfortunately, is different in PostScript virtual fonts and Computer +% Modern: +% \begin{macrocode} + \def\^{\hbox{\rm "\tt \aftergroup}}% hex + #1}} % (\def{\const}) +% \end{macrocode} +% \end{macro} +% \MakeShortVerb{\"} +% \begin{macro}{\RealConstFormat} +% I prefer to re-define the decimal style +% to print as the more code-like `$\mbox{\rm e}10$'. You can +% do this by using the hook "\RealConstFormat" in your Spider "macros" +% section: +% \begin{quote} "\newcommand{\RealConstFormat}{\mbox{\rm e}}" .\end{quote} +% For a go at a Fortran web, I hacked the lexing so that an "e" or "d" in +% a real or double-precision constant was transmitted verbatim into the +% argument of "\const" instead of "\_" and re-defined "\const" to ensure +% this was set in roman. +% \begin{macrocode} +\newcommand{\RealConstFormat}{\cdot 10^} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Indentation and breaks} +% +% \begin{macro}{\ind} +% This counter stores the current indentation in ems. +% \begin{macrocode} +\newcount\ind +% \end{macrocode} +% \end{macro} +% \begin{macro}{\bak} \begin{macro}{\bakk} +% These backspace one and two ems respectively. +% \begin{macrocode} +\newbox\bak \setbox\bak=\hbox to \m@ne em{} +\newbox\bakk \setbox\bakk=\hbox to -2em{} +% \end{macrocode} +% \end{macro}\end{macro} +% \begin{macro}{\0} +% A forced break, as from "@/": +% \begin{macrocode} +\def\0{% + \ifmmode + \ifinner$\par\hangindent\ind em\noindent\kern\ind em\ignorespaces$\fi + \else + \par\hangindent\ind em\noindent \kern\ind em\ignorespaces + \fi} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\1} +% Indent one more notch: +% \begin{macrocode} +\newcommand{\1}{\global\advance\ind by 1 \hangindent\ind em} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\2} +% Indent one less notch: +% \begin{macrocode} +\newcommand{\2}{\global\advance\ind by \m@ne } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\3} +% An optional break within a statement, as from "@|": +% \begin{macrocode} +\newcommand{\3}[1]{\hfil \penalty#10 \hfilneg} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\4} +% Backspace one notch: +% \begin{macrocode} +\newcommand{\4}{\copy\bak} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\5} +% Optional break: +% \begin{macrocode} +\newcommand{\5}{\hfil \penalty \m@ne \hfilneg \kern 2.5em \copy\bakk + \ignorespaces} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\6} +% A forced break with no indentation: +% \begin{macrocode} +\def\6{\ifmmode \else \par + \hangindent\ind em\startline \ignorespaces \fi} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\startline} +% This is used by "\code" as well as "\6" above. +% \begin{macrocode} +\def\startline{\noindent \count255=\ind \advance\count255 by -2 + \hskip\count255 em} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\7} +% A forced break and a little extra vertical space, as from "@#": +% \begin{macrocode} +\newcommand{\7}{\Y\6} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\8} +% No indentation. It works only in code, not in "|"\dots"|". +% \begin{macrocode} +\newcommand{\8}{\unskip} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\J} +% \tangle's join operation ("@&"): +% \begin{macrocode} +\newcommand{\J}{\str{@\&}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\C} +% This looks after comments. The hooks are inserted because comments +% aren't code (see below). +% \begin{macrocode} +\def\C#1{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi + \XX \hfil \penalty \m@ne\hfilneg\quad % original spider + $\commentbegin\,$\endcodehook{#1}\startcodehook$\, + \commentend$\XX} +% \end{macrocode} +% \end{macro} +% +% \subsection{Modules} +% +% \begin{macro}{\onmaybe} \begin{macro}{\maybe} \begin{macro}{\ifon} +% These switches are concerned with only printing changed sections if +% so desired. +% \begin{macrocode} +\def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue \newif\ifon +% \end{macrocode} +% \end{macro}\end{macro}\end{macro} +% \begin{macro}{\M} +% Beginning of an un-starred section: +% \begin{macrocode} +\outer\def\M#1.{% + \MN#1.\ifon\vfil\penalty-100\vfilneg + \vskip12ptminus3pt \startsection \ignorespaces} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\startsection} \begin{macro}{\lapstar} +% Some auxilliary definitions: +% \begin{macrocode} +\def\startsection{\Q \noindent {\let\*=\lapstar \bf \modstar.\quad }} +\newcommand{\lapstar}{\rlap{*}} +% \end{macrocode} +% \end{macro} \end{macro} +% \begin{macro}{\N} +% This introduces a starred section (where "#2" is the title). We +% have to check the title with "\headcheck" for a leading +% character indicating a subsection. Then we write a contents entry, +% change the running header and set the title in bold. "\old@S" is +% used in the header rather than "\S" since "\S" is probably +% wrongly-defined at this point (see below). +% \begin{macrocode} +\outer\def\N#1.#2.{% + \MN#1.\headcheck#2\headcheck + \typeout{*\modno} % progress report + \addcontentsline{toc}{\headcheck@type} + {\hbox to 2em{\modno\hfill} \quad \theopen \relax \themodtitle} + \markboth{% running headline + {\protect\small \qquad\uppercase{\ignorespaces\themodtitle}} + \hfill {\protect\small \@title}\qquad{\rm \old@S \modno}} + {\rm \old@S \modno\qquad {\protect\small \@title}\hfill + {\protect\small \uppercase{\ignorespaces\themodtitle\qquad}}} + \ifon\startsection {\bf \ignorespaces \themodtitle.\quad }\ignorespaces} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\MN} + +% Here is some common code for "\M" and "\N"\@. +% It sets +% "\sectionmark" for the headers and defines cross-referencing +% information for the current module. +% It also +% looks after the decision about whether or not to set this module if it +% is not starred. +% \begin{macrocode} +\def\MN#1.{% + \par {\xdef\modstar{#1}\let\*=\empty\xdef\modno{#1}}% + \ifx\modno\modstar \onmaybe \else \ontrue \fi + \sectionmark{\modno} +% \end{macrocode} +% The following code for setting the currentlabel to the module number +% is a variation on that in {\tt latex.tex}. +% \begin{macrocode} + \let\@tempa\protect + \def\protect{\noexpand\protect\noexpand}% + \def\@currentlabel{#1}% + \let\protect\@tempa} % def\MN +% \end{macrocode} +% \end{macro} +% \begin{macro}{\note} \begin{macro}{\A} +% Auxilliary macros. "\A" is for cross-references for multiply +% defined section names. +% \begin{macrocode} +\def\note#1#2.{\Y \noindent {\hangindent 2em \footnotesize + \baselineskip 10pt#1 #2.\par}} +\newcommand{\A}{\note{See also}} +% \end{macrocode} +% \end{macro} \end{macro} +% +% \subsubsection{Processing special section headings} +% +% This complicated stuff, introduced with \spider{} and modified for the +% \LaTeX{} version, is to allow an inital =, 1, 2, 3 or 4 in +% starred module titles to indicate a hierarchy. Their effect is as follows: +% \[ \begin{tabular}{c|c|c} +% Introduction & Page eject? & Indentation in contents\\ \hline +% "@*=" & yes & 0 \\ +% "@*1" & yes & 2 em \\ +% "@*2" & no & 2 em \\ +% "@*3" & yes & 4 em \\ +% "@*4" & no & 4 em \\ +% \end{tabular} \] +% "@*=" also suppresses a following page eject and emboldens the +% table of contents entry and puts some extra vertical space before +% it. Normal starred sections have no indentation in the contents and +% don't do anything special about page breaks. +% +% \begin{macro}{\l@part} \begin{macro}{\l@norm} \begin{macro}{\l@num} +% Two new sorts of contents entry are defined here and the `part' +% type re-defined. (See "latex.tex" for details of how this works.) +% "\l@part" determines the t.o.c.\ entry for a "@*=" section, +% "\l@norm" the entry for a normal starred section and "\l@num" that +% for a numbered section. Some penalties are inserted (the normal +% values for the main style) in case the t.o.c.\ extends over more +% than one page. The "\headcheck@type" definition is used in the +% sectioning commands to write the t.o.c.\ entry. +% \begin{macrocode} +\def\l@part{\addpenalty{\@secpenalty} + \addvspace{3pt plus 1pt} % space above part line + \@dottedtocline{0}{\z@ }{4em}} +\def\l@norm{\addpenalty{\@secpenalty} + \@dottedtocline{0}{\z@ }{4em}} +\def\l@num{\@dottedtocline{0}{0em}{4em}} +% \end{macrocode} +% \end{macro}\end{macro}\end{macro} +% \begin{macro}{\ifcancel} \begin{macro}{\ifnextchar} +% \begin{macro}{\ifnch} \begin{macro}{\makethechar} +% Here's the tricky stuff, presented without further comment! +% \begin{macrocode} +\newif\ifcancel \cancelfalse +\def\ifnextchar#1#2#3{% + \let\@tempe=#1\def\@tempa{#2}\def\@tempb{#3}\@ifnch} +\def\@ifnch{% + \ifx \@tempc \@tempe\let\@tempd\@tempa + \else \let\@tempd\@tempb + \fi + \@tempd} +\def\makethechar#1{\let\@tempc=#1} +% \end{macrocode} +% \end{macro} \end{macro} \end{macro} \end{macro} +% \begin{macro}{\headcheck} +% ~ +% \begin{macrocode} +\def\headcheck#1#2\headcheck{% + \makethechar{#1}% + \def\theskipper{\vfil\penalty-100 % skip before new module + \vfilneg\vskip12ptminus3pt}% + \def\theopen{}% opening skip in toc entry + \def\thetocskip{}% vertical skip before toc entry + \def\themodtitle{{#2}}% + \def\headcheck@type{num}% + \ifnextchar={% + \def\theskipper{\newpage} \canceltrue + \def\headcheck@type{part} \def\theopen{\bf}% + \def\thetocskip{\vskip 3pt plus 1in \penalty-100 + \vskip \z@ plus -1in}% + }{\ifnextchar1{% + \cancelfalse \def\theskipper{\newpage}% + \def\theopen{\hskip2em}% + }{\ifnextchar2{% + \cancelfalse \def\theopen{\hskip2em}% + }{\ifnextchar3{% + \cancelfalse \def\theskipper{\newpage}% + \def\theopen{\hskip4em}% + }{\ifnextchar4{% + \cancelfalse \def\theopen{\hskip4em}% + }{% else + \ifcancel\else \def\theskipper{\newpage}\fi + \cancelfalse \def\headcheck@type{norm}% + \def\themodtitle{#1{#2}}% + }}}}}% + \theskipper } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Starting and ending code sections} +% +% \begin{macro}{\code} +% This takes us into code mode. The old version used infinite hyphen +% penalty which stopped the discretionary breaks in strings. Extra +% space is put after ";" with the "\sfcode". +% \begin{macrocode} +\newcommand{\code}{% + \rightskip=\z@ plus 100pt minus 10pt + \sfcode`;=3000 \pretolerance \@M + \hyphenpenalty 9999 \exhyphenpenalty \@M + \global\ind=2 \1 \startline +% \end{macrocode} +% \DescribeMacro{\@} +% The original says that every web must define "\?", where "?" is the +% at-sign. Since "\@" is used for end-of-sentence space in \LaTeX, we +% make sure this is only done in code mode. We need the old and new +% definitions, "\old@" and "\code@", between which to switch. +% \spider{} unfortunately uses "\S" instead of "\equiv" and the awk +% and C \web s assume that "\%" and "\#" translate to typewriter +% versions, so we have to define these properly in code mode too. +% \DescribeMacro{\startcodehook} \DescribeMacro{\endcodehook} +% For convenience, we define token registers +% "\startcodehook" and "\endcodehook" for this sort of purpose when we +% go into and out of code mode. These might be altered by the +% \spider\ description if appropriate. +% \begin{macrocode} + \startcodehook} % \def\code +% \end{macrocode} +% \end{macro} +% \begin{macro}{\old@}\begin{macro}{\code@}\begin{macro}{\old@S} +% \begin{macro}{\old@percent} \begin{macro}{\old@hash} +% Let's store the original definitions of these: +% \begin{macrocode} +\let\old@=\@ \let\old@S=\S \let\old@percent=\% +\let\old@hash=\# +% \end{macrocode} +% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro} +% \begin{macro}{\code@}\begin{macro}{\tt@percent}\begin{macro}{\tt@hash} +% And here are replacements for use in code mode. +% \begin{macrocode} +\chardef\code@=`\@ +\def\tt@percent{\hbox{\tt\char`\%}} \def\tt@hash{\hbox{\tt\char`\#}} +% \end{macrocode} +% \end{macro}\end{macro}\end{macro} +% \begin{macro}{\startcodehook}\begin{macro}{\endcodehook} +% Here are the hooks. Should these be token registers? +% \begin{macrocode} +\def\startcodehook{\let\@=\code@ \let\S=\equiv \let\%=\tt@percent + \let\#=\tt@hash \def\^{\hbox{\tt\char`\^}}} +\def\endcodehook{\let\@=\old@ \let\S=\old@S \let\%=\old@percent + \let\#=\old@hash \def\^##1{{\accent94 ##1}}} +% \end{macrocode} +% \end{macro}\end{macro} +% \begin{macro}{\Q} +% This gets us out of code mode, setting things back to normal. +% \begin{macrocode} +\def\Q{\rightskip=\z@ \sfcode`;=1500 \pretolerance 200 + \endcodehook} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\CD} \begin{macro}{\DC} +% Web text in "|"\dots"|" is woven into text surrounded by +% "\CD"\dots"\DC"\@. The original definition didn't bother with the +% grouping if not in math mode, but it's convenient now that the hooks +% need to be added. +% \begin{macrocode} +\def\DC{\endcodehook \egroup} +\def\CD{\relax + \ifmmode \hbox\fi \bgroup \startcodehook} +% \end{macrocode} +% \end{macro}\end{macro} +% \begin{macro}{\U} +% This provides a cross-reference for uses of sections. +% \begin{macrocode} +\newcommand{\U}{\note{This code is used in}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\X} +% This does modules which introduce the code. Note the usage: +% "\X"\meta{module number}":"\meta{module name}"\X". +% \begin{macrocode} +\def\X#1:#2\X{% + \ifmmode \gdef\XX{\null$\null}\else \gdef\XX{}\fi + \XX$\langle\,$#2{\footnotesize \kern.5em #1}$\,\rangle$\XX } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\XF} +% This is for a file module (from "@("): +% \begin{macrocode} +\def\XF#1:#2\XF{% + \ifmmode \gdef\XX{\null$\null}\else \gdef\XX{}\fi + \XX {\tt (#2{\footnotesize \kern.5em #1})}\XX} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\Y} \begin{macro}{\yskip} +% This does a vertical skip by "\yskip", used in "\note" and "\7". +% \begin{macrocode} +\newcommand{\Y}{\par\yskip} +\let\yskip=\smallskip +% \end{macrocode} +% \end{macro}\end{macro} +% +% \subsection{Definitions and formats} +% +% \begin{macro}{\D} \begin{macro}{\F} \begin{macro}{\defin} +% "\D" and "\F" deal with macro and format definitions from "@d" and +% "@f" respectively. +% \begin{macrocode} +\newcommand{\D}{\defin{define}} % macro definition +\newcommand{\F}{\defin{format}} % format definition +\newcommand{\defin}[1]{\global\advance\ind by 2 \1\res{#1 }} +% \end{macrocode} +% \end{macro}\end{macro}\end{macro} +% +% \subsection{Miscellaneous symbols} +% +% \begin{macro}{\DO} \begin{macro}{\G} \begin{macro}{\I} +% \begin{macro}{\K} \begin{macro}{\L} \begin{macro}{\R} +% \begin{macro}{\TI} \begin{macro}{\V} \begin{macro}{\W} +% Here are some miscellaneous symbols. I think these should really be +% defined in the \spider\ descriptions that need them, but they are +% assumed by the current webs. +% \begin{macrocode} +\newcommand{\DO}{\hbox{\sl\char'044}} % slant dollar sign (used by awkweb) +\let\G=\ge % greater than or equal sign +\let\I=\ne % unequal sign +\let\K=\gets % left arrow +\let\L=\le % less than or equal sign +\let\R=\lnot % logical not +\let\TI=\sim % tilde +\let\V=\lor % logical or +\let\W=\land % logical and +% \end{macrocode} +% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro} +% \end{macro}\end{macro}\end{macro} +% \begin{macro}{\vert} \begin{macro}{\amp} \begin{macro}{\PP} +% \begin{macro}{\*} +% And some more: (n.b., the plain \TeX{} definitions of "\vert" +% and "\*" are over-written, as expected by spidery \weave---maybe this +% should be changed). +% \begin{macrocode} +\def\vert{|} \let\amp=\& \let\PP=\P \let\*=* +% \end{macrocode} +% \end{macro}\end{macro}\end{macro}\end{macro} +% \begin{macro}{\AT!} +% \changes{v1.2}{10/6/91}{Re-instate trailing !.} +% This is the `at sign in control +% text'. I dn't know why it has the trailing "!", but it apears to +% have bene intentional in the plain version. +% \begin{macrocode} +\def\AT!{@} +% \end{macrocode} +% \end{macro} +% +% \subsection{Indexing} +% +% \begin{macro}{\ch} +% This is used trivially at the start of the index in the case of +% changes: +% \begin{macrocode} +\def\ch{\note{The following sections were changed by the change file:} + \let\*=\relax} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\inx} \begin{macro}{\:} +% The index is set in two-column mode. +% Each item in each index is introduced by "\:". This is a \LaTeX{} +% macro but is unlikely to get used in the index and so is preserved +% from the original. +% \begin{macrocode} +\def\inx{% + \typeout{Index:} + \begin{multicols}{2} + \parskip \z@ plus .5pt + \parfillskip \z@ plus .6\hsize % try to avoid almost empty lines + \outer\def\:##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry + \rm \tolerance \@M \let\*=\lapstar + \hyphenpenalty \@M \parindent=\z@ } +% \end{macrocode} +% \end{macro}\end{macro} +% \begin{macro}{\fin} +% This finishes off the name index and starts off the module index. +% "\:" acts as in "\inx". The modules may be +% qualified with "\U", which cross-references section uses. The page +% header is changed appropriately. +% \begin{macrocode} +\def\fin{% + \end{multicols} \newpage + \parfillskip \z@ plus 1fil + \markboth{{\protect\small NAMES OF THE SECTIONS}\hfill + {\protect\small\@title}} + {{\protect\small\@title}\hfill + {\protect\small NAMES OF THE SECTIONS\quad}} + \typeout{Section names:} + \def\note##1##2.{\quad{\footnotesize##1 ##2.}} + \def\U{\note{Used in}}% + \def\:{\par\hangindent 2em}\let\*=*} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\con} +% This finishes everything off, rather trivially. (It used to make +% the contents page.) +% \begin{macrocode} +\newcommand{\con}{\end{document}} +% \end{macrocode} +% \end{macro} +% +% \subsection{Including other files} +% +% \DescribeEnv{multicols} +% We need the {\tt multicols} environment to make a two-column index +% without a forced page break. +% \begin{macrocode} +\input{multicol.sty} +% \end{macrocode} +% \DescribeMacro{\webmacs} +% Finally we include the macros defined by \spider. Doing things this way +% means that \spider{} can override things done in this file for the +% \web{} system of a particular language (like the +% definition of "\res", for instance) and the limbo section can do +% further overriding for a particular web file. If we're using this +% file to document itself, "\webmacs" should have been defined in the +% driver file to be "null"! +% \begin{macrocode} +\input{\webmacs} +% \end{macrocode} +% "\webmacs" is no further use and we might as well save the space. +% \begin{macrocode} +\let\webmacs=\empty +% \end{macrocode} +% +% \appendix +% \section{Changes from the plain version}\label{changes} +% +% \begin{description} +% \item[{\tt \BS.}] becomes "\str"; +% \item[{\tt \BS\char`\^}] has been removed from the global +% definitions (where it was assumed by the "c.spider" translation for +% "^") and put in limbo in "weave.ch"; +% \item[{\tt \BS\%}, {\tt \BS\#} and {\tt \BS\$}] also removed from global +% definitions and put in "\startcodehook"; +% \item[{\tt \BS\char`\~}] removed globally since it doesn't seem to be used; +% \item[{\tt \BS\BS} and {\tt \BS|}] become "\id" and "\ida" respectively; +% \item[{\tt \BS\&}] becomes "\res"; +% \item[{\tt \BS B} and {\tt \BS T}] (for controlled comments) removed +% since no controlled comments in \spider; +% \item[{\tt \BS)}] (string pool check sum) removed; +% \item[{\tt \BS]}] (sign for forced line break) appears not be be +% used, so removed; +% \item[{\tt \BS=}] becomes "\vstr"; +% \item[{\tt \BS H}] (hat) removed since it seems not to be used and +% clashes with \LaTeX; +% \item[{\tt \BS Z}] replaced by \LaTeX{} contents stuff; +% \item[{\tt \BS lheader} and {\tt \BS rheader}] replaced by \LaTeX{} marks; +% \item[output routine stuff] all gone; +% \item[{\tt \BS rhead}] no longer relevant---use the \LaTeX{} mark +% mechanism; +% \item[{\tt \BS title}] should be called as a macro with the title as +% its argument rather than "\def"ed; +% \item[{\tt \BS contentspagenumber}, {\tt \BS contentsfile} and {\tt +% \BS readcontents}] no longer relevant; +% \item[{\tt \BS pagewidth}, {\tt \BS pageheight} and {\tt \BS +% fullpageheight}] no longer relevant---use the \LaTeX\ equivalents; +% \item[{\tt \BS pageshift}] no longer relevant---use "twoside" option; +% \item[verbatim macros] no longer relevant; +% \item[{\tt \BS iftitle}] removed---use "\pagestyle{empty}" to +% suppress page header. +% \end{description} +% +% \begin{thebibliography}{1} +% \bibitem{spider} N. Ramsey, {\sl Comm. ACM}, {\bf 32} (1989) 1051 +% \end{thebibliography} diff --git a/web/latexspider/web.sty b/web/latexspider/web.sty new file mode 100644 index 0000000000..00b93d0cb3 --- /dev/null +++ b/web/latexspider/web.sty @@ -0,0 +1,277 @@ +%% +%% This is file `web.sty' generated +%% on <1991/6/19> with the docstrip utility (v1.1l test). +%% +%% The original source file was `web.doc'. +%% +%% You are not allowed to distribute this file without the corresponding +%% `.doc' version containing the documentation. +%% +\iffalse % -*-latex-*- + +%% Copyright D.Love, SERC Daresbury Laboratory, 1991 +%% The `doc' version of this style is re-distributable and usuable +%% under conditions of the GNU copyleft, but please mark any changes, +%% list them here and report any major enhancements to the author. + + +\fi + +\iffalse % hack RCS info into a sensible form: +\fi +\def\next$#1: #2/#3/#4 #5 ${\def\filedate{#4/#3/#2}\def\filetime{#5}} +\next$Date: 91/04/30 19:30:11 $ + +\def\next$#1: #2 ${\def\fileversion{#2}} +\next$Revision: 1.1 $ + + + +\typeout{Sub-style `web', version \fileversion\space of \filedate} +\parskip \z@ +\ifx\DocInput\undefined +\ifcase \@ptsize + \textheight = 53 \baselineskip +\or + \textheight = 47 \baselineskip +\or + \textheight = 43 \baselineskip +\fi \advance \textheight by \topskip +\textwidth=6.27in \oddsidemargin=\z@ \evensidemargin=\z@ +\fi +\pagestyle{myheadings} +\ifx\DocInput\undefined \sectionmark{1} \fi +\@ifundefined{selectfont}{% + \let\normal@font=\relax} % old scheme + {% new scheme + \def\normal@font{\series \mediumseriesdefault + \shape \normalshapedefault}} +\ifx\DocInput\undefined +\def\@maketitle{% + \newpage \thispagestyle{empty} \null + \begin{center} + {\LARGE \@title \par} \vskip 1.5em + {\large \lineskip .5em + \begin{tabular}[t]{c} \@author \end{tabular} \par} + \vskip 1em {\large \@date} + \end{center} + \par \vskip 1.5em + \topofcontents \tableofcontents \par \botofcontents \newpage } +\fi +\ifx\DocInput\undefined +\def\maketitle{% + \par \begingroup + \pagenumbering{roman} \setcounter{page}{0} + \def\thefootnote{\fnsymbol{footnote}} + \def\@makefnmark{\hbox to \z@ {$^{\@thefnmark}$\hss}} + \if@twocolumn \twocolumn[\@maketitle] + \else \newpage \global\@topnum\z@ \@maketitle \fi + \@thanks + \endgroup + \setcounter{footnote}{0} \pagenumbering{arabic} + \let\maketitle\relax \let\@maketitle\relax + \gdef\@thanks{}\let\thanks\relax} +\fi +\let\@title=\empty \let\@author=\empty +\def\tableofcontents{% + \noindent Section \hfill Page \par \@starttoc{toc}} +\def\topofcontents{} \def\botofcontents{} +\let\ttitlefont=\tt \let\titlefont=\rm +\newcommand{\id}[1]{\mbox{\idfont #1\/\kern.05em}} +\newcommand{\ida}[1]{\mbox{$ #1 $}} +\newcommand{\idfont}{\normal@font \it} +\newcommand{\reservedfont}{\normal@font \bf} +\newcommand{\res}[1]{\mbox{\reservedfont#1\/}} +\def\str#1{% + \ifmmode \gdef\@tempa{\null$\null}\else \gdef\@tempa{}\fi + \@tempa {% + \let\\=\BS \let\'=\RQ \let\`=\LQ \let\{=\LB \let\}=\RB + \let\~=\TL \let\ =\SP \let\&=\AM \def\^{{\tt \char`\^}}% + \leavevmode \normal@font\tt #1}\@tempa} +\chardef\AM=`\& % ampersand +\chardef\BS=`\\ % backslash +\chardef\LB=`\{ % left brace +\def\LQ{{\tt\char'22}} % left quote +\chardef\RB=`\} % right brace +\def\RQ{{\tt\char'23}} % right quote +\def\UL{{\tt\char`\_}} % underline character in a string +\def\TL{{\tt\char`\~}} % tilde +\newcommand{\SP}{\char`\ \discretionary{\hbox{\char`\\}}{}{}} +\newcommand{\vstr}[1]{\kern 2pt \fbox{\str{#1}}\kern 2pt} +\setlength{\fboxsep}{2pt} +\def\const#1{{% + \def\?{\kern.2em}% + \def\${\ell}% long + \def\_{\RealConstFormat{\aftergroup}}% power of ten + \def\~{\hbox{\rm \char'23\kern-.2em \it \aftergroup\?\aftergroup}}% octal + \def\^{\hbox{\rm "\tt \aftergroup}}% hex + #1}} % (\def{\const}) +\newcommand{\RealConstFormat}{\cdot 10^} +\newcount\ind +\newbox\bak \setbox\bak=\hbox to \m@ne em{} +\newbox\bakk \setbox\bakk=\hbox to -2em{} +\def\0{% + \ifmmode + \ifinner$\par\hangindent\ind em\noindent\kern\ind em\ignorespaces$\fi + \else + \par\hangindent\ind em\noindent \kern\ind em\ignorespaces + \fi} +\newcommand{\1}{\global\advance\ind by 1 \hangindent\ind em} +\newcommand{\2}{\global\advance\ind by \m@ne } +\newcommand{\3}[1]{\hfil \penalty#10 \hfilneg} +\newcommand{\4}{\copy\bak} +\newcommand{\5}{\hfil \penalty \m@ne \hfilneg \kern 2.5em \copy\bakk + \ignorespaces} +\def\6{\ifmmode \else \par + \hangindent\ind em\startline \ignorespaces \fi} +\def\startline{\noindent \count255=\ind \advance\count255 by -2 + \hskip\count255 em} +\newcommand{\7}{\Y\6} +\newcommand{\8}{\unskip} +\newcommand{\J}{\str{@\&}} +\def\C#1{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi + \XX \hfil \penalty \m@ne\hfilneg\quad % original spider + $\commentbegin\,$\endcodehook{#1}\startcodehook$\, + \commentend$\XX} +\def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue \newif\ifon +\outer\def\M#1.{% + \MN#1.\ifon\vfil\penalty-100\vfilneg + \vskip12ptminus3pt \startsection \ignorespaces} +\def\startsection{\Q \noindent {\let\*=\lapstar \bf \modstar.\quad }} +\newcommand{\lapstar}{\rlap{*}} +\outer\def\N#1.#2.{% + \MN#1.\headcheck#2\headcheck + \typeout{*\modno} % progress report + \addcontentsline{toc}{\headcheck@type} + {\hbox to 2em{\modno\hfill} \quad \theopen \relax \themodtitle} + \markboth{% running headline + {\protect\small \qquad\uppercase{\ignorespaces\themodtitle}} + \hfill {\protect\small \@title}\qquad{\rm \old@S \modno}} + {\rm \old@S \modno\qquad {\protect\small \@title}\hfill + {\protect\small \uppercase{\ignorespaces\themodtitle\qquad}}} + \ifon\startsection {\bf \ignorespaces \themodtitle.\quad }\ignorespaces} + +\def\MN#1.{% + \par {\xdef\modstar{#1}\let\*=\empty\xdef\modno{#1}}% + \ifx\modno\modstar \onmaybe \else \ontrue \fi + \sectionmark{\modno} + \let\@tempa\protect + \def\protect{\noexpand\protect\noexpand}% + \def\@currentlabel{#1}% + \let\protect\@tempa} % def\MN +\def\note#1#2.{\Y \noindent {\hangindent 2em \footnotesize + \baselineskip 10pt#1 #2.\par}} +\newcommand{\A}{\note{See also}} +\def\l@part{\addpenalty{\@secpenalty} + \addvspace{3pt plus 1pt} % space above part line + \@dottedtocline{0}{\z@ }{4em}} +\def\l@norm{\addpenalty{\@secpenalty} + \@dottedtocline{0}{\z@ }{4em}} +\def\l@num{\@dottedtocline{0}{0em}{4em}} +\newif\ifcancel \cancelfalse +\def\ifnextchar#1#2#3{% + \let\@tempe=#1\def\@tempa{#2}\def\@tempb{#3}\@ifnch} +\def\@ifnch{% + \ifx \@tempc \@tempe\let\@tempd\@tempa + \else \let\@tempd\@tempb + \fi + \@tempd} +\def\makethechar#1{\let\@tempc=#1} +\def\headcheck#1#2\headcheck{% + \makethechar{#1}% + \def\theskipper{\vfil\penalty-100 % skip before new module + \vfilneg\vskip12ptminus3pt}% + \def\theopen{}% opening skip in toc entry + \def\thetocskip{}% vertical skip before toc entry + \def\themodtitle{{#2}}% + \def\headcheck@type{num}% + \ifnextchar={% + \def\theskipper{\newpage} \canceltrue + \def\headcheck@type{part} \def\theopen{\bf}% + \def\thetocskip{\vskip 3pt plus 1in \penalty-100 + \vskip \z@ plus -1in}% + }{\ifnextchar1{% + \cancelfalse \def\theskipper{\newpage}% + \def\theopen{\hskip2em}% + }{\ifnextchar2{% + \cancelfalse \def\theopen{\hskip2em}% + }{\ifnextchar3{% + \cancelfalse \def\theskipper{\newpage}% + \def\theopen{\hskip4em}% + }{\ifnextchar4{% + \cancelfalse \def\theopen{\hskip4em}% + }{% else + \ifcancel\else \def\theskipper{\newpage}\fi + \cancelfalse \def\headcheck@type{norm}% + \def\themodtitle{#1{#2}}% + }}}}}% + \theskipper } +\newcommand{\code}{% + \rightskip=\z@ plus 100pt minus 10pt + \sfcode`;=3000 \pretolerance \@M + \hyphenpenalty 9999 \exhyphenpenalty \@M + \global\ind=2 \1 \startline + \startcodehook} % \def\code +\let\old@=\@ \let\old@S=\S \let\old@percent=\% +\let\old@hash=\# +\chardef\code@=`\@ +\def\tt@percent{\hbox{\tt\char`\%}} \def\tt@hash{\hbox{\tt\char`\#}} +\def\startcodehook{\let\@=\code@ \let\S=\equiv \let\%=\tt@percent + \let\#=\tt@hash \def\^{\hbox{\tt\char`\^}}} +\def\endcodehook{\let\@=\old@ \let\S=\old@S \let\%=\old@percent + \let\#=\old@hash \def\^##1{{\accent94 ##1}}} +\def\Q{\rightskip=\z@ \sfcode`;=1500 \pretolerance 200 + \endcodehook} +\def\DC{\endcodehook \egroup} +\def\CD{\relax + \ifmmode \hbox\fi \bgroup \startcodehook} +\newcommand{\U}{\note{This code is used in}} +\def\X#1:#2\X{% + \ifmmode \gdef\XX{\null$\null}\else \gdef\XX{}\fi + \XX$\langle\,$#2{\footnotesize \kern.5em #1}$\,\rangle$\XX } +\def\XF#1:#2\XF{% + \ifmmode \gdef\XX{\null$\null}\else \gdef\XX{}\fi + \XX {\tt (#2{\footnotesize \kern.5em #1})}\XX} +\newcommand{\Y}{\par\yskip} +\let\yskip=\smallskip +\newcommand{\D}{\defin{define}} % macro definition +\newcommand{\F}{\defin{format}} % format definition +\newcommand{\defin}[1]{\global\advance\ind by 2 \1\res{#1 }} +\newcommand{\DO}{\hbox{\sl\char'044}} % slant dollar sign (used by awkweb) +\let\G=\ge % greater than or equal sign +\let\I=\ne % unequal sign +\let\K=\gets % left arrow +\let\L=\le % less than or equal sign +\let\R=\lnot % logical not +\let\TI=\sim % tilde +\let\V=\lor % logical or +\let\W=\land % logical and +\def\vert{|} \let\amp=\& \let\PP=\P \let\*=* +\def\AT!{@} +\def\ch{\note{The following sections were changed by the change file:} + \let\*=\relax} +\def\inx{% + \typeout{Index:} + \begin{multicols}{2} + \parskip \z@ plus .5pt + \parfillskip \z@ plus .6\hsize % try to avoid almost empty lines + \outer\def\:##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry + \rm \tolerance \@M \let\*=\lapstar + \hyphenpenalty \@M \parindent=\z@ } +\def\fin{% + \end{multicols} \newpage + \parfillskip \z@ plus 1fil + \markboth{{\protect\small NAMES OF THE SECTIONS}\hfill + {\protect\small\@title}} + {{\protect\small\@title}\hfill + {\protect\small NAMES OF THE SECTIONS\quad}} + \typeout{Section names:} + \def\note##1##2.{\quad{\footnotesize##1 ##2.}} + \def\U{\note{Used in}}% + \def\:{\par\hangindent 2em}\let\*=*} +\newcommand{\con}{\end{document}} +\input{multicol.sty} +\input{\webmacs} +\let\webmacs=\empty + +%% \endinput diff --git a/web/latexspider/web.tex b/web/latexspider/web.tex new file mode 100644 index 0000000000..0154639cf1 --- /dev/null +++ b/web/latexspider/web.tex @@ -0,0 +1,13 @@ +\def\webmacs{null} +\documentstyle[a4,% +%times,% +makeidx,% +newdoc,web]{article} +\EnableCrossrefs +\CodelineIndex +\begin{document} +\DocInput{web.doc} +\PrintIndex +\end{document} + + diff --git a/web/latexspider/webmakefile b/web/latexspider/webmakefile new file mode 100644 index 0000000000..42070774db --- /dev/null +++ b/web/latexspider/webmakefile @@ -0,0 +1,172 @@ +# Copyright 1989 by Norman Ramsey, Odyssey Research Associates +# To be used for research purposes only +# For more information, see file COPYRIGHT in the parent directory +# Modified by Dave Love, Daresbury Lab (d.love@daresbury.ac.uk) for local +# setup and to incorporate change files, particularly for LaTeX mods. +# To make LaTeX versions of weave, set WEAVECHANGEFILE=$(MASTER)/weave.ltx +# and include -DLaTeX in CFLAGS. To get a version of spider.awk usable for +# LaTeX or plain, define SPIDERCHANGEFILE=$(MASTER)/spider.ltx and define +# LaTeX=1 so that spider.awk generates LaTeX-compatible webs. I'm sure all +# this could be tidied up. + +#HOME=/home/users0/fx# # Make no longer inherits environment vars +# (it does inherit env vars on my system!) +THETANGLE=tangle +THEWEAVE=weave +SPIDER=any.spider +WEAVECHANGEFILE= +TANGLECHANGEFILE= +SPIDERCHANGEFILE= + +# +DVI=dvi +CFLAGS=-DDEBUG -DSTAT + +# CPUTYPE is a grim hack that attempts to solve the problem of multiple +# cpus sharing a file system. In my environment I have to have different +# copies of object and executable for vax, sun3, next, iris, and other +# cpu types. If you will be using Spidery WEB in a homogenous processor +# environment, you can just set CPUTYPE to a constant, or eliminate it +# entirely. +# +# In my environment, the 'cputype' program returns a string that +# describes the current processor. That means that the easiest thing +# for you to do is to define a 'cputype' program that does something +# sensible. A shell script that says 'echo "vax"' is fine. + +#CPUTYPE=`cputype` +CPUTYPE=`arch` + +# Change the following three directories to match your installation +# +# the odd placement of # is to prevent any trailing spaces from slipping in + +WEBROOT=$(HOME)/ltxspiderweb# # root of the WEB source distribution +DEST=$(HOME)/bin# # place where the executables go +MACROS=$(HOME)/tex/inputs# # place where the macros go + +MASTER=$(WEBROOT)/master# # master source directory +OBDIR=$(MASTER)/$(CPUTYPE)# # common object files + +TANGLESRC=tangle +CTANGLE=ceetangle -I$(MASTER) +CWEAVE=ceeweave -I$(MASTER) +AWKTANGLE=awktangle -I$(MASTER) +COMMONOBJS=$(OBDIR)/common.o $(OBDIR)/pathopen.o +COMMONC=$(MASTER)/common.c $(MASTER)/pathopen.c +COMMONSRC=$(COMMONC) $(MASTER)/spider.awk + + + +# Our purpose is to make tangle and weave + +web: tangle weave + +tangle: $(COMMONOBJS) $(TANGLESRC).o + cc $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o + +weave: $(COMMONOBJS) weave.o + cc $(CFLAGS) -o $(DEST)/$(THEWEAVE) $(COMMONOBJS) weave.o + + +source: $(TANGLESRC).c $(COMMONSRC) # make tangle.c and common src, then clean + if [ -f WebMakefile ]; then exit 1; fi # don't clean the master! + if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual + -rm -f tangle.web weave.* common.* # remove links that may be obsolete + -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web + -rm -f cycle.test spider.slog + -rm -f *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog + +# Here is how we make the common stuff + +$(MASTER)/common.c: $(MASTER)/common.web $(MASTER)/common.ch + $(CTANGLE) $(MASTER)/common $(MASTER)/common + +$(OBDIR)/common.o: $(MASTER)/common.c + cc $(CFLAGS) -c $(MASTER)/common.c + mv common.o $(OBDIR) + + +$(MASTER)/pathopen.c: $(MASTER)/pathopen.web $(MASTER)/pathopen.ch + $(CTANGLE) $(MASTER)/pathopen $(MASTER)/pathopen + mv pathopen.h $(MASTER) + +$(OBDIR)/pathopen.o: $(MASTER)/pathopen.c + cc $(CFLAGS) -c $(MASTER)/pathopen.c + mv pathopen.o $(OBDIR) + + +## Now we make the tangle and weave source locally + +$(TANGLESRC).c: $(MASTER)/$(TANGLESRC).web $(MASTER)/common.h grammar.web \ + $(TANGLECHANGEFILE) + -/bin/rm -f $(TANGLESRC).web + ln $(MASTER)/$(TANGLESRC).web $(TANGLESRC).web +# chmod -w $(TANGLESRC).web + $(CTANGLE) $(TANGLESRC) $(TANGLECHANGEFILE) + +weave.c: $(MASTER)/weave.web $(MASTER)/common.h grammar.web $(WEAVECHANGEFILE) + -/bin/rm -f weave.web + ln $(MASTER)/weave.web weave.web +# chmod -w weave.web + $(CTANGLE) weave $(WEAVECHANGEFILE) + +## Here's where we run SPIDER to create the source + +grammar.web: $(MASTER)/cycle.awk $(MASTER)/spider.awk $(SPIDER) + echo "date" `date` | cat - $(SPIDER) | awk -f $(MASTER)/spider.awk \ + LaTeX=$(LaTeX) - + cat $(MASTER)/transcheck.list trans_keys.unsorted | awk -f \ + $(MASTER)/transcheck.awk + awk -f $(MASTER)/cycle.awk < cycle.test + sort *.unsorted | awk -f $(MASTER)/nodups.awk + mv *web.tex $(MACROS) + +## We might have to make spider first. + +$(MASTER)/spider.awk: $(MASTER)/spider.web $(SPIDERCHANGEFILE) + $(AWKTANGLE) $(MASTER)/spider $(SPIDERCHANGEFILE) + mv cycle.awk nodups.awk transcheck.awk $(MASTER) + rm junk.list + +# $(MASTER)/cycle.awk: $(MASTER)/cycle.web # making spider also makes cycle +# $(AWKTANGLE) $(MASTER)/cycle + +# Weaving: + +weave.tex: $(MASTER)/weave.web grammar.web $(WEAVECHANGEFILE) + ceeweave -I$(MASTER) $(MASTER)/weave.web $(WEAVECHANGEFILE) + mv $(MASTER)/weave.tex . + +tangle.tex: $(MASTER)/tangle.web $(TANGLECHANGEFILE) + ceeweave -I$(MASTER) $(MASTER)/tangle.web $(TANGLECHANGEFILE) + mv $(MASTER)/tangle.tex . + +spider.tex: $(MASTER)/spider.web $(SPIDERCHANGEFILE) + awkweave -I$(MASTER) $(MASTER)/spider.web $(SPIDERCHANGEFILE) + mv $(MASTER)/spider.tex . + +# This cleanup applies to every language + +clean: + if [ -f WebMakefile ]; then exit 1; fi # don't clean the master! + if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual + -rm -f tangle.web weave.web common.* # remove links that may be obsolete + -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web + -rm -f cycle.test spider.slog +# vital bootstrap files are kept as SAVE..., hence only remove .c files whose +# names start with lower case + -rm -f [a-z]*.c *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog + + + +# booting the new distribution +boot: + cd ../master; rm -f *.o; for i in $(COMMONC); do \ + cc $(CFLAGS) -c $$i; \ + mv *.o $(OBDIR) ; \ + done; cd ../c + cc $(CFLAGS) -c $(TANGLESRC).c; \ + cc $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o + + |