% 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