% \iffalse meta-comment
%
% Copyright 1993 1994 1995 The LaTeX3 Project and any individual
% authors listed elsewhere in this file. 
% 
% For further copyright information, and conditions for modification
% and distribution, see the file legal.txt, and any other copyright
% notices in this file.
% 
% This file is part of the LaTeX2e system.
% ----------------------------------------
%   This system is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% 
%   For error reports concerning UNCHANGED versions of this file no
%   more than one year old, see bugs.txt.
% 
%   Please do not request updates from us directly.  Primary
%   distribution is through the CTAN archives.
% 
% 
% IMPORTANT COPYRIGHT NOTICE:
% 
% You are NOT ALLOWED to distribute this file alone.
% 
% You are allowed to distribute this file under the condition that it
% is distributed together with all the files listed in manifest.txt.
% 
% If you receive only some of these files from someone, complain!
% 
% 
% Permission is granted to copy this file to another file with a
% clearly different name and to customize the declarations in that
% copy to serve the needs of your installation, provided that you
% comply with the conditions in the file legal.txt.
% 
% However, NO PERMISSION is granted to produce or to distribute a
% modified version of this file under its original name.
%  
% You are NOT ALLOWED to change this file.
% 
% 
% 
% \fi
\def\filename{docstrip.dtx}
\def\fileversion{2.3d}
\def\filedate{1995/11/17}
\def\docdate {1995/11/18}
% \CheckSum{1844}
%% \CharacterTable
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \<
%%   Equals        \=     Greater than  \>     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~}
%%
%
%\iffalse
%
%% The docstrip program for use with TeX.
%% Copyright (C) 1989-1991 Frank Mittelbach
%% Copyright (C) 1992-1995 Johannes Braams, Denys Duchier, 
%%                         Frank Mittelbach
%% Copyright (C) 1995 Marcin Woli\'nski
%% All rights are reserved.
%%
%
% \fi
%
% \changes{2.0b}{1991/05/29}{Added bugfix from Denys}
% \changes{2.0c}{1991/05/29}{Allow almost all characters in guard (DD)}
% \changes{2.0d}{1991/05/31}{Started merging in some of Franks code}
% \changes{2.0j}{1992/03/05}{Wrote introduction}
% \changes{2.0m}{1992/04/21}{Renamed all macros that deal with the
%                           parsing of boolean expressions}
% \changes{2.0m}{1992/04/25}{Removed dependency from ltugboat,
%                          incorporated driver file into source.}
% \changes{2.0m}{1992/04/25}{Added some missing percents; corrected some
%                          typos}
% \changes{2.0m-DL}{1992/05/08}{Various small corrections to English and
%                           typos}
% \changes{2.0q}{1992/07/01}{Changed all dates to yy/mm/dd for better
%                          sorting}
% \changes{2.2a}{1993/12/02}{Update for LaTeX2e}
% \changes{2.2c}{1993/12/17}{Renamed texsys.tex to texsys.cfg.}
% \changes{2.3a}{1995/08/17}{Swapped Primary with Secondary since
%                        expressions are generally described bottom-up}
% \changes{2.3b}{1995/08/22}{Completely changed expressions parser}
% \changes{2.3b}{1995/08/23}{Removed mechanism for checking if  previous
%                      one-line guard is same as current
%                      (\cs{testOption},\cs{closeOption})---this is
%                      not a common case and testing complicates things
%                        unnecessarily} 
% \changes{2.3c}{1995/08/24}{When file is multiply listed in \cs{file}
% clause it \emph{is} multiply read}
%
% \DoNotIndex{\#,\$,\%,\&,\@,\\,\{,\},\^,\_,\~,\ }
% \DoNotIndex{\@ne}
% \DoNotIndex{\advance,\begingroup,\catcode,\closein,\closeout}
% \DoNotIndex{\day,\def,\edef,\else,\empty,\endgroup,\errmessage}
% \DoNotIndex{\expandafter,\fi,\futurelet,\gdef,\global,\if,\ifeof}
% \DoNotIndex{\ifx,\immediate,\let,\loop,\m@ne,\message,\month}
% \DoNotIndex{\newcount}
% \DoNotIndex{\newif,\newlinechar,\newread,\newtoks,\newwrite}
% \DoNotIndex{\noexpand,\openin,\openout,\par,\read,\relax,\repeat}
% \DoNotIndex{\space,\the,\undefined,\write,\xdef,\year,\z@}
%
% ^^A some definitions for this documentation
%
% \newcommand{\ds}{\textsf{DocStrip}} ^^A maybe?
% \newcommand{\bsl}{\protect\bslash}
% \newcommand{\note}[1]{\marginpar{\textbf{#1}}}
% \newcommand{\netaddress}[1]{\texttt{#1}}
%
% ^^A override the default in doc.sty
% \makeatletter
% \renewenvironment{theglossary}{%
%    \glossary@prologue%
%    \GlossaryParms \let\item\@idxitem \ignorespaces}%
%   {}
% \makeatother
%
%
% \changes{2.1c}{1993/02/25}{Added a setting for StandardModuleDepth}
% \setcounter{StandardModuleDepth}{1}
%
% \title{The \ds{} program%
%         \thanks{This file has version number \fileversion,
%                 last revised \filedate,
%                 documentation dated \docdate.}}
%
% \changes{2.1b}{1993/02/23}{modified mailaddress of Johannes}
% \author{%
%   Frank Mittelbach \\
%   \netaddress{Mittelbach@mzdmza.zdv.uni-mainz.de}
%  \and
%   Denys Duchier \\
%   \netaddress{duchier-denys@cs.yale.edu}
%  \and
%   Johannes Braams \\
%   TeXniek \\
%          Kooienswater 62 \\
%          2715 AJ Zoetermeer\\
%   \netaddress{JLBraams@cistron.nl}
%  \and
%   Marcin Woli\'nski \\
%   \netaddress{wolinski@bull.mimuw.edu.pl}}
%
% \date{Printed \today}
%
% \maketitle
% 
% \begin{abstract}
%    This document describes the implementation of the \ds{} program.
%    The original version of this program was developed by Frank
%    Mittelbach to accompany his \texttt{doc.sty} which enables literate
%    programming in \LaTeX\@. Denys Duchier rewrote it to run either
%    with \TeX\ or with \LaTeX, and to allow full boolean expressions in
%    conditional guards instead of just comma-separated lists.
%    Johannes Braams re-united the two implementations, documented and
%    debugged the code.
% \end{abstract}
%
% \section{Preface to version 2.3}
%    Basically this version is just faster than previous ones.
%    It is easy to observe that while installing
%    large  packages  \ds{}  reads some files more than once. This is
%    done when several output files are  to  be  generated  from  one
%    input.  But \TeX{} can write to up to 16 files on the same time.
%    Version 2.3 takes advantage of this to speed things up.
%
%    A short example: 12 of \LaTeXe\ files are  generated  from  file
%    \texttt{classes.dtx}. All of them can be generated while reading
%    source once. New version of \ds{} uses one fourth of time needed
%    by  older versions to do this. However when installing whole
%    \LaTeXe\ most of the time is spent on generating file
%    \texttt{latex.ltx} which is just one, so installation of 
%    \LaTeX\ takes about half the previous time.
%
%    The bad news is that \ds's interface had to be changed somewhat
%    to be able to specify which files can be generated concurrently.
%
% \section{Introduction}
%
% \subsection{Why the \ds{} program?} When Frank Mittelbach created
%    the \texttt{doc} package, he invented a way to combine \TeX\ code
%    and its documentation. From then on it was more or less possible
%    to do literate programming in \TeX.
%
%    This way of writing \TeX\ programs obviously has great
%    advantages, especially when the program becomes larger than a
%    couple of macros.  There is one drawback however, and that is
%    that such programs may take longer than expected to run because
%    \TeX\ is an interpreter and has to decide for each line of the
%    program file what it has to do with it. Therefore, \TeX\ programs
%    may be speeded up by removing all comments from them.
%
%    By removing the comments from a \TeX\ program a new problem is
%    introduced. We now have two versions of the program and both of
%    them {\em have\/} to be maintained. Therefore it would be nice to
%    have a possibility to remove the comments automatically, instead
%    of doing it by hand. So we need a program to remove comments from
%    \TeX\ programs. This could be programmed in any high level
%    language, but maybe not everybody has the right compiler to
%    compile the program.  Everybody who wants to remove comments from
%    \TeX\ programs has \TeX\@.  Therefore the \ds{} program is
%    implemented entirely in \TeX.
%
% \subsection{Functions of the \ds{} program} 
%
%    Having created the \ds{} program to remove comment lines from
%    \TeX\ programs\footnote{Note that only comment lines, that is
%    lines that start with a single \texttt{\%} character, are removed;
%    all other comments st in the code.} it became feasible to do more
%    than just strip comments.\\ Wouldn't it be nice to have a way to
%    include parts of the code only when some condition is set true?
%    Wouldn't it be as nice to have the possibility to split the
%    source of a \TeX\ program into several smaller files and combine
%    them later into one `executable'?\\ Both these wishes have been
%    implemented in the \ds{} program.
%
%  \subsection{How to use the \ds{} program}
%    A number of ways exist to use the \ds{} program:
%    \begin{enumerate}
%    \item The easiest way is to instruct \TeX\ to read the file
%        \texttt{docstrip.tex} and to see what happens. \TeX\ will ask
%        you a few questions about the file you would like to be
%        processed. When you have answered these questions it does
%        its job and strips the comments from your \TeX\ code.
%    \item When you would like to be able to process more than one
%        file with one command, or you would like to add a couple of
%        lines to the beginning (or end) of the stripped file you can
%        write a `batch file' for \ds{}. The default name for such a
%        file is \texttt{docstrip.cmd}. When a file by that name
%        exists in your current directory when you instruct \TeX\ to
%        read \texttt{docstrip.tex} it will verify (by asking you)
%        that you want to use {\em that\/} file and if so, will
%        process the commands in it.
%
%        You do not need to use the default name, however. You can
%        give a batch file any name you like such as, say, 
%        \texttt{foo.bar} and then run \TeX\ by using a command such as:
%    \begin{verbatim}
%    TeX \def\batchfile{foo.bar}\input docstrip
%    \end{verbatim}
%
% \item You may use yet another way that is only slightly different
%        from the previous method. You can write a batch file in such
%        a way that it can be directly processed by \TeX{}. This
%        allows you to set up a distribution where you can instruct
%        the user to simply run
%      \begin{quote}
%        \texttt{TEX} \meta{batch file}
%      \end{quote}
%        to generate the executable versions of your files from the
%        distribution sources. All distributions from Mainz are set up
%        in this way (also this one); look, for example, at the
%        installation file for this distribution.  To produce such a
%        batch file include a statement in your `batch file' that
%        instructs \TeX\ to read \texttt{docstrip.tex}. You should then
%        also define |\batchfile| to contain the name of that
%        `batch file'. The beginning of such a file would look like:
%    \begin{verbatim}
%    \def\batchfile{install.me}
%    \input docstrip
%    ...
%    \end{verbatim}
%    \end{enumerate}
%
% \section{The user interface}
%
% \subsection{The main program}
% \DescribeMacro{\processbatchFile} The `main program' starts with
%    trying to process a batch file, this is accomplished by calling
%    the macro |\processbatchFile|. It counts the number of batch
%    files it processes, so that when the number of files processed is
%    still zero after the call to |\processbatchFile| appropriate
%    action can be taken.
%
% \DescribeMacro{\interactive} When no batch files have been processed
%    the macro |\interactive| is called. It prompts the user for
%    information. First the extensions of the input and output files
%    is determined. Then a question about optional code is asked and
%    finally the user can give a list of files that have to be
%    processed.
%
% \DescribeMacro{\ReportTotals} When the \texttt{stats} option is
%    included in the \ds{}-program it keeps a record of the number of
%    files and lines that are processed.  Also the number of comments
%    removed and passed as well as the number of code lines that were
%    passed to the output are accounted. The macro |\ReportTotals|
%    shows a summary of this information.
%
% \subsection{Batchfile commands}
%
%    The commands described in this section are available to build a
%    batch file.
%  \subsubsection{Old interface}
%
% \DescribeMacro{\showprogress}
% \DescribeMacro{\keepsilent}
%    When the option \texttt{stats} is included in \ds{} it can
%    write message to the terminal as each line of the input file(s) is
%    processed. This message consists of a single character, indicating
%    kind of that particular line. We use the
%    following characters:
%    \begin{itemize}
% \item[\texttt{\%}] Whenever an input line is a comment
%        \texttt{\%}-character is written to the terminal.
% \item[\texttt{.}] Whenever a code line is encountered
%        a \texttt{.}-character is written on the terminal.
% \item[\texttt{/}] When a number of empty lines appear in a row in the
%        input file, at most one of them is retained. The \ds{}
%        program signals the removal of an empty line with the 
%        \texttt{/}-character.
% \item[\texttt{<}] When a `guard line' is found in the input and it
%        starts a block of optionally included code, this is signalled
%        on the terminal by showing the \texttt{<}-character, together
%        with the boolean expression of the guard.
% \item[\texttt{>}] The end of a conditionally included block of code is
%        indicated by showing the \texttt{>}-character.
%    \end{itemize}
%    This feature is turned on by default when the option
%    \texttt{stats} is included, otherwise it is turned of. The
%    feature can be toggled with the commands |\showprogress| and
%    |\keepsilent|.
%
% \DescribeMacro{\preamble}
% \DescribeMacro{\endpreamble}
% \DescribeMacro{\postamble}
% \DescribeMacro{\endpostamble}
%    It is possible to add a number of lines to the output of
%    the \ds{} program. The information you want to add to the
%    start of the output file should be listed between the |\preamble|
%    and |\endpreamble| commands; the lines you want to add to the end
%    of the output file should be listed between the |\postamble| and
%    |\endpostamble| commands. Everything that \ds{} finds
%    for both the pre- and postamble it writes to the output file, but
%    preceded with two \%-characters. If you include a |^^M| character
%    in one of these lines, everything that follows it on the same line
%    is written to a new line in the output file.
%    This `feature' can be used to add a |\typeout| or |\message| to the
%    the stripped file.
%
%
% \DescribeMacro{\generateFile}
%    The main reason for constructing a \ds{} command file is that
%    one doesn't want to type in the instructions for \TeX\ each time
%    a macro file is stripped of its comments. The macro |\generateFile|
%    is used to tell \TeX\ what to do. Its syntax is:
%    \begin{quote}
%    |\generateFile{|\meta{output}|}{|\meta{ask}|}{|[|\from{|^^A
%                    \meta{input}|}{|\meta{optionlist}|}|]*|}|
%    \end{quote}
%    The \meta{output} and \meta{input} are normal file specifications
%    as are appropriate for your computer system. The \meta{optionlist}
%    is a comma separated list of `options' that specify which
%    optional code fragments in \meta{input} should be included in
%    \meta{output}.  With \meta{ask} you can instruct \TeX\ to either
%    silently overwrite a previously existing file (|f|) or to issue a
%    warning and ask you if it should overwrite the existing file
%    (|t|).
%
%    It is possible to specify multiple input files, each with its own
%    \meta{optionlist}. This is indicated by the notation [\ldots]*.
%
% \DescribeMacro{\include}
% \DescribeMacro{\processFile}
%    The earlier version of the \ds{} program supported a
%    different kind of command to tell \TeX\ what to do. This command
%    is less powerful than |\generateFile|; it can be used when
%    \meta{output} is created from one \meta{input}. The syntax is:
%    \begin{quote}
%    |\include{|\meta{optionlist}|}|
%
%    |\processFile{|\meta{name}|}{|\meta{inext}^^A
%                              |}{|\meta{outext}^^A
%                              |}{|\meta{ask}|}|
%    \end{quote}
%    This command is based on environments where filenames are
%    constructed of two parts, the name and the extension, separated
%    with a dot. The syntax of this command assumes that the
%    \meta{input} and \meta{output} share the same name and only
%    differ in their extension. This command is retained to be
%    backwards compatible with the older version of \ds{}, but its use
%    is not encouraged.
%
% \DescribeMacro{\input}
% \DescribeMacro{\batchinput} 
%    The batch file commands can be put into several batch files which
%    are then executed from a master batch file. This is, for example,
%    useful if a distribution consists of several distinct parts. You
%    can then write individual batch files for every part and in
%    addition a master file that simply calls the batch files for the
%    parts.  For this, call the individual batch files from the master
%    file with the command |\batchinput{|\meta{file}|}|. You can nest
%    batch files up to a nesting level of ten which is more than
%    sufficient. Don't use |\input| for this purpose, this command
%    should be used only for calling the \ds{} program as explained
%    above and is ignored when used for any other purpose.
%
% \DescribeMacro{\ifToplevel} 
%    When batch files are nested you may want to suppress certain
%    commands in the lower-level batch files such as terminal
%    messages. For this purpose you can use the |\ifToplevel| command
%    which executes its argument only if the current batch file is the
%    outermost one. Make sure that you put the opening brace of the
%    argument into the same line as the command itself, otherwise the
%    \ds{} program will get confused.
%
%  \subsubsection{New interface}
%    These are new commands added in version 2.3. They can be mixed
%    freely with all old commands.
%
% \DescribeMacro{\generate}
% \DescribeMacro{\file}
% \DescribeMacro{\from}
%    Here is the new syntax for specifing  what  files  are  to  be
%    generated:
%    \begin{quote}
%    |\generate{|[|\file{|\meta{output}|}{|[|\from{|^^A
%                    \meta{input}|}{|\meta{optionlist}|}|]*|}|]*|}|
%    \end{quote}
%     The    meaning    of    \meta{output},    \meta{input}   and
%     \meta{optionslist} is just as for |\generateFile|. But there
%     can  be  many  |\file|  specifications  in  one  |\generate|
%     clause. This means that all these \meta{output} files should
%     be  generated while reading each of \meta{input} files once.
%     Input files  are  read  in  order  of  first  appearance  in
%     this clause. E.g.
%     \begin{verbatim}
%     \generate{\file{p1.sty}{\from{s1.dtx}{foo,bar}}
%               \file{p2.sty}{\from{s2.dtx}{baz}
%                             \from{s3.dtx}{baz}}
%               \file{p3.sty}{\from{s1.dtx}{zip}
%                             \from{s2.dtx}{zip}}
%              }
%     \end{verbatim}
%     will    cause   \ds{}   to   read   files   \texttt{s1.dtx},
%     \texttt{s2.dtx}, \texttt{s3.dtx} (in that order) and produce
%     files \texttt{p1.sty}, \texttt{p2.sty}, \texttt{p3.sty}.
%
%     Restriction  to  at  most  16 output streams open in a while
%     does not mean that you can produce at most 16 files with one
%     |\generate|. In the example above only 2 streams are needed,
%     since    while    \texttt{s1.dtx}    is    processed    only
%     \texttt{p1.sty}  and  \texttt{p3.sty}  are  being generated;
%     while  reading  \texttt{s2.dtx}  only  \texttt{p2.sty}   and 
%     \texttt{p3.sty};  and  while  reading  \texttt{s3.dtx}  file
%     \texttt{p2.sty} . However example below needs 3 streams:  
%     \begin{verbatim}
%     \generate{\file{p1.sty}{\from{s1.dtx}{foo,bar}}
%               \file{p2.sty}{\from{s2.dtx}{baz}
%                             \from{s3.dtx}{baz}}
%               \file{p3.sty}{\from{s1.dtx}{zip}
%                             \from{s3.dtx}{zip}}
%              }
%     \end{verbatim}
%     Although while reading \texttt{s2.dtx}  file \texttt{p3.sty}
%     is  not  written  it  must  remain  open since some parts of
%     \texttt{s3.dtx} will go to it later.
%
%     Sometimes it is not possible to create a file by reading  all
%     sources once. Consider the following example:
%     \begin{verbatim}
%     \generate{\file{p1.sty}{\from{s1.dtx}{head}
%                             \from{s2.dtx}{foo}
%                             \from{s1.dtx}{tail}}
%               \file{s1.drv}{\from{s1.dtx}{driver}}
%              }
%     \end{verbatim}
%     To generate \texttt{p1.sty} file \texttt{s1.dtx} must be read
%     twice:  first  time  with  option  \texttt{head},  then  file
%     \texttt{s2.dtx}  is  read and then \texttt{s1.dtx} again this
%     time with  option  \texttt{tail}.  \ds{}  handles  this  case
%     correctly:  if  inside  one  |\file|  declaration  there  are
%     multiple  |\from|es  with  the  same  input  file  this  file
%     \emph{is} read multiple times.
%
%     If order of |\from|s  specified  in one  of  your  |\file|
%     specifications  does  not  match  the  order  of input files
%     established by previous |\file|s \ds{} will raise  an  error
%     and abort. Then you may either read one of next sections or
%     give up and put that file in separate |\generate| (but then
%     sources will be read again just for that file).
%
%     \paragraph{For impatient.} Try  following  algorithm:   Find
%     file that is generated from largest number of sources, start
%     writing |\generate| clause with this file and its sources in
%     proper  order. Take other files that are to be generated and
%     add  them checking if they don't contradict order of sources
%     for the first one. If this doesn't work read next sections.
%
%     \paragraph{For mathematicians.} Relation ``file $A$ must  be
%     read  before file $B$'' is a partial order on the set of all
%     your source files.  Each |\from| clause adds a chain to this
%     order.  What you have to do is to perform a topological sort
%     i.e. to extend partial order to linear one.  When  you  have
%     done it just list your source files in |\generate| in such a
%     way that order of  their  first  appearance  in  the  clause
%     matches linear order. If this cannot be achieved  read  next
%     paragraph. (Maybe future versions of \ds{} will perform this
%     sort automatically, so all these troubles will disappear.)
%
%     \paragraph{For that who must know that all.} There  is  a
%     diverse  case when it's not possible to achieve proper
%     order of reading source files. Suppose you have to  generate
%     two  files,  first  from \texttt{s1.dtx} and \texttt{s3.dtx}
%     (in  that  order)  and  second  from   \texttt{s2.dtx}   and
%     \texttt{s3.dtx}.  Whatever  way  you  specify this the files
%     will be read in either as \texttt{s1 s3 s2} or \texttt{s2 s3
%     s1}.  The  key  to  solution is magical macro |\needed| that
%     marks a file as needed to be input but  not  directing  any
%     output  from  it  to  current |\file|. In our example proper
%     specification is:
%     \begin{verbatim}
%     \generate{\file{p1.sty}{\from{s1.dtx}{foo}
%                             \needed{s2.dtx}
%                             \from{s3.dtx}{bar}}
%               \file{p2.sty}{\from{s2.dtx}{zip}
%                             \from{s3.dtx}{zap}}
%              }
%     \end{verbatim}
%
%     Argument  to  |\generate|  is  executed inside a group, so all
%     local declarations are undone when |\generate| concludes.
%
%  \DescribeMacro{\askforoverwritetrue}
%  \DescribeMacro{\askforoverwritefalse}
%     As you can see in the syntax above there  is  no  place  for
%     \meta{ask} specifier. Since in all installation scripts I've
%     seen all settings  for  that  were  the  same  (|t|  or  |f|
%     depending  on  an  author)  I  thought  that it will be more
%     convenient  to  specify  if  user  should   be   asked   for
%     overwriting  files  just  in  one  place. These switches are
%     local and can be issued in any place in the file even inside
%     |\generate| clause (between |\file|s however).
%     
%
% \DescribeMacro{\declarepreamble}
% \DescribeMacro{\declarepostamble}
% \DescribeMacro{\usepreamble}
% \DescribeMacro{\usepostamble}
%    Sometimes it is desirable to have different preambles for different
%    files  of  a  larger  package  (e.g.  because  some  of them are
%    customisable  configuration  files and they should be marked as
%    such).   In  such case one can say |\declarepreamble\somename|,
%    then type in his/her preamble, end it with |\endpreamble|,
%    and  later  on  |\usepreamble\somename|  to  switch   to   this
%    preamble.  The  same  mechanism works for postambles, |\use...|
%    declarations are local and can appear inside |\generate|.
%
%    Commands   |\preamble|   and   |\postamble| define and  activate
%    pre(post)ambles named |\defaultpreamble| and |\defaultpostamble|. 
%
% \section{Conditional inclusion of code}
%
%    When you use the \ds{} program to strip comments out of
%    \TeX\ macro files you have the possibility to make more than one
%    stripped macro file from one documented file. This is achieved by
%    the support for optional code. The optional code is marked
%    in the documented file with a `guard'.
%
%    A guard is a boolean expression that is enclosed in |<| and |>|.
%    It also {\em has\/} to follow the |%| at the beginning of the line.
%    For example:
%\begin{verbatim}
%    ...
%    %<bool>\TeX code
%    ...
%\end{verbatim}
%    In this example the line of code will be included in \meta{output}
%    if the option \texttt{bool} is present in the \meta{optionlist} of
%    the |\generateFile| command.
%
%    The syntax for the boolean expressions is:
%
%\DeleteShortVerb\|
%    \begin{tabular}{lcl}
%    \meta{Expression} & $::=$ & \meta{Secondary}
%                            [\{\texttt{|}, \texttt{,}\} 
%                            \meta{Secondary}]*\\
%    \meta{Secondary}    & $::=$ & 
%                        \meta{Primary} [\texttt{\&}
%                         \meta{Primary}]*\\
%    \meta{Primary}  & $::=$ & 
%                        \meta{Terminal} $|$ \texttt{!}\meta{Primary}
%                        $|$ \texttt{(}\meta{Expression}\texttt{)}\\
%    \end{tabular}
%
%    The \texttt{|} stands for disjunction, the \texttt{\&} stands for
%    conjunction and the \texttt{!}\ stands for negation. The
%    \meta{Terminal} is any sequence of letters and evaluates to
%    \meta{true} iff\footnote{iff stands for `if and only if'} it
%    occurs in the list of options that have to be included.
%\MakeShortVerb\|
%
%    Two kinds of optional code are supported: one can either have
%    optional code that `fits' on one line of text, like the example
%    above, or one can have blocks of optional code.
%
%    To distinguish both kinds of optional code the `guard modifier'
%    has been introduced. The `guard modifier' is one character that
%    immediately follows the |<| of the guard. It can be either |*|
%    for the beginning of a block of code, or |/| for the end of a
%    block of code\footnote{To be compatible with the earlier version
%    of \ds{} also \texttt{+} and \texttt{-} are supported as `guard
%    modifiers'.  However, there is an incompatibility with the
%    earlier version since a line with a \texttt{+}-modified guard is
%    not included inside a block with a guard that evaluates to false,
%    in contrast to the previous behaviour.}.  The beginning and
%    ending guards for a block of code have to be on a line by
%    themselves.
%
%    When a block of code is {\em not\/} included, any guards that occur
%    within that block are {\em not\/} evaluated.
%
%\StopEventually{%
%^^A \section{Conclusion}
%  \PrintIndex
%  \PrintChanges
%^^A \makesignature
% }
%
% \section{Producing the documentation}
%
%    We provide a short driver file that can be extracted by the
%    \ds{} program using the the conditional `\textsf{driver}'.  To
%    allow the use of \texttt{docstrip.dtx} as a program at Ini\TeX{}
%    time (e.g., to strip
%    off its own comments) we need to add a bit of primitive code.
%    With this extra checking it is still possible to process this
%    file with \LaTeXe{} to typeset the documentation.
% \changes{2.1b}{1993/02/23}{Added fontdefinitions for doc to the driver
%                          file, in order to get the layout of the code
%                          right; also added the layout definitions
%                          that are in effect in \texttt{doc.drv}}
% \changes{2.1c}{1993/02/23}{Remove definitions for fonts again}
% \changes{2.2f}{1994/02/26}{Allow direct processing of source}
%    \begin{macrocode}
%<*driver>
%    \end{macrocode}
%    If |\documentclass| is undefined, e.g., if Ini\TeX{} or plain
%    \TeX{} is used for formatting, we bypass the driver file.
%
% \changes{2.3a}{1995/08/20}{Changed driver}
%    We use some trickery to avoid issuing |\end{document}| when
%    the |\ifx| construction is unfinished. If condition below is
%    true a |\fi| is constructed on the fly, the |\ifx| is completed,
%    and the real |\fi| will never be seen as it comes after 
%    |\end{document}|. On the other hand if condition is false
%    \TeX\ skips over |\csname fi\endcsname| having no idea that
%    this could stand for |\fi|, driver is skipped and only then
%    the condition completed.
%
%    Additional guard |gobble| prevents \ds\ from extracting
%    these tricks to real driver file.
%    \begin{macrocode}
%<*gobble>
\ifx\documentclass\undefined
\else \csname fi\endcsname
%</gobble>
%    \end{macrocode}
%    Otherwise we process the following lines which will result in
%    formatting the documentation.
%    \begin{macrocode}
\documentclass{ltxdoc}
    \EnableCrossrefs
 %    \DisableCrossrefs    % use \DisableCrossrefs if the
                           % index is ready
   \RecordChanges
 %   \OnlyDescription
   \typeout{Expect some Under- and overfull boxes}
\begin{document}
  \DocInput{docstrip.dtx}
\end{document}
%<*gobble>
\fi
%</gobble>
%</driver>
%    \end{macrocode}
%
%
% \section{The implementation}
%
% \subsection{Declarations and initializations}
%
%    In order to be able to include the \texttt{@}-sign in control
%    sequences its category code is changed to \meta{letter}.  The
%    `program' guard here allows most of the code to be excluded when
%    extracting the driver file.
%    \begin{macrocode}
%<*program>
\catcode`\@=11
%    \end{macrocode}
%
%    When we want to write multiple lines to the terminal with one
%    statement, we need a character that tells \TeX\ to break the lines.
%    We use \verb=^^J= for this purpose.
%    \begin{macrocode}
\newlinechar=`\^^J
%    \end{macrocode}
%
% \subsubsection{Switches}
% \begin{macro}{\ifGenerate}
%    The program will check if a
%    file of the same name as the file it would be creating already
%    exists. The switch |\ifGenerate| is used to indicate if the
%    stripped file has to be generated.
%    \begin{macrocode}
\newif\ifGenerate
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifContinue}
%    The switch |\ifContinue| is used in various places in the
%    program to indicate if a |\loop| has to end.
%    \begin{macrocode}
\newif\ifContinue
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifForlist}
% \changes{2.0g}{1991/06/05}{Macro added.}
%    The program contains an implementation of a for-loop, based on
%    plain \TeX{}'s |\loop| macros. The implementation needs a
%    switch to terminate the loop.
%    \begin{macrocode}
\newif\ifForlist
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifDefault}
%    The switch |\ifDefault| is used to indicate whether the
%    default batch file has to be used.
% \changes{2.0f}{1991/06/04}{Macro added.} 
%    \begin{macrocode}
\newif\ifDefault
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifMoreFiles}
%    The switch |\ifMoreFiles| is used to decide if the user
%    wants more files to be processed. It is used only in interactive
%    mode; initially it evaluates to \meta{true}.
% \changes{2.0h}{1991/06/19}{Macro added.}
%    \begin{macrocode}
\newif\ifMoreFiles \MoreFilestrue
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\ifaskforoverwrite}
%    The switch |\askforoverwrite| is used to  decide  if  the  user
%    should be asked when a file is to be overwritten.
%    \begin{macrocode}
\newif\ifaskforoverwrite \askforoverwritetrue
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Count registers}
% \begin{macro}{\blockLevel}
%    Optionally included blocks of code can be nested. The counter
%    |\blockLevel| will be used to keep track of the level of
%    nesting.  Its initial value is zero.
%    \begin{macrocode}
\newcount\blockLevel \blockLevel\z@
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\emptyLines}
%    The count register |\emptyLines| is used to count the number
%    of consecutive empty input lines. Only the first will be copied
%    to the output file.
% \changes{2.0i}{1990/06/27}{Macro added}
%    \begin{macrocode}
\newcount\emptyLines \emptyLines \z@
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\processedLines}
% \begin{macro}{\commentsRemoved}
% \begin{macro}{\commentsPassed}
% \begin{macro}{\codeLinesPassed}
%    To be able to provide the user with some statistics about the
%    stripping process four counters are allocated if the statistics
%    have been included when this program was \ds{}ped.  The number of
%    lines processed is stored in the counter |\processedLines|.
%    The number of lines containing comments that are not written on
%    the output file is stored in the counter |\commentsRemoved|;
%    the number of comments copied to the output file is stored in the
%    counter |\commentsPassed|.  The number of lines containing
%    macro code that are copied to the output file is stored in the
%    counter |\codeLinesPassed|.
%    \begin{macrocode}
%<*stats>
\newcount\processedLines   \processedLines  \z@
\newcount\commentsRemoved  \commentsRemoved \z@
\newcount\commentsPassed   \commentsPassed  \z@
\newcount\codeLinesPassed  \codeLinesPassed \z@
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\NumberOfFiles}
%    When more than one file is processed, the number of files is
%    stored in the count register |\NumberOfFiles| when
%    statistics are included.
%    \begin{macrocode}
\newcount\NumberOfFiles \NumberOfFiles\z@
%    \end{macrocode}
% \end{macro}
%
% \changes{2.0e}{1991/05/31}{Added counter allocation for the processing
%                           of multiple files}
% \begin{macro}{\TotalprocessedLines}
% \begin{macro}{\TotalcommentsRemoved}
% \begin{macro}{\TotalcommentsPassed}
% \begin{macro}{\TotalcodeLinesPassed}
%    When more than one file is processed and when statistics have
%    been included we provide the user also with information about the
%    total amount of lines processed. For this purpose four more count
%    registers are allocated here.
%    \begin{macrocode}
\newcount\TotalprocessedLines   \TotalprocessedLines  \z@
\newcount\TotalcommentsRemoved  \TotalcommentsRemoved \z@
\newcount\TotalcommentsPassed   \TotalcommentsPassed  \z@
\newcount\TotalcodeLinesPassed  \TotalcodeLinesPassed \z@
%</stats>
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsubsection{I/O streams}
% \begin{macro}{\inFile}
%    For reading the file with documented \TeX-code, an input stream
%    |\inFile| is allocated.
%    \begin{macrocode}
\newread\inFile
%    \end{macrocode}
% \end{macro}
%
% \changes{2.3a}{1995/08/18}{No allocated streams for console}
% \begin{macro}{\ttyin}
% \begin{macro}{\ttyout}
%    Communication with the user goes through (nonexistent) stream 16.
%    \begin{macrocode}
\chardef\ttyin16
\chardef\ttyout16
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\currbatchFile}
% \changes{2.0e}{1991/05/31}{Added allocation of extra input stream
%                          for batch files}
% \changes{2.1a}{1993/02/22}{Renamed from \cs{batchFile} to
% \cs{currbatchFile}.}
% \changes{2.1a}{1993/02/22}{Logic changed}
%    For batch file processing we need a number of input streams so
%    that a batch file can open further batch files using
%    |\batchinput|.
%
%    We begin by allocating ten anonymous read streams.
%    \begin{macrocode}
\newread\@tempa 
%    \end{macrocode}
% \begin{macro}{\lowestbatchFile}
%    We save the lowest number allocated in |\lowestbatchFile|, of
%    course this code highly depends on the implementation of the
%    plain allocation routines.
%    \begin{macrocode}
\let\lowestbatchFile\@tempa
\newread\@tempa \newread\@tempa \newread\@tempa \newread\@tempa
\newread\@tempa \newread\@tempa \newread\@tempa \newread\@tempa
\newread\@tempa
%    \end{macrocode}
% \begin{macro}{\highestbatchFile}
%    Same for the highest number.
%    \begin{macrocode}
\let\highestbatchFile\@tempa
%    \end{macrocode}
%    Now we allocate a count register which is supposed to hold the
%    the number of the batch file stream we are currently reading
%    from. Initially this will contain the number for the first read
%    stream allocated for this reason.
%    \begin{macrocode}
\newcount\currbatchFile
\currbatchFile=\highestbatchFile
\advance\currbatchFile by -9
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%  \begin{macro}{\ifToplevel}
%    Execute the argument if current batch file is the outermost one.
%    Otherwise suppress it.
%    \begin{macrocode}
\def\ifToplevel{\relax\ifnum\currbatchFile=\lowestbatchFile
   \expandafter\iden \else \expandafter\@gobble\fi}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\batchinput}
% \changes{2.0n}{1992/04/26}{Added macro}
% \changes{2.1a}{1993/02/22}{Completely redefined (so that it works)}
%
%    When the file \texttt{docstrip.tex} is read because of an
%    |\input| statement in a batch file we have to prevent an
%    endless loop (well, limited by \TeX's stack). Therefore we save
%    the original primitive |\input| and define a new macro with
%    an argument delimited by \verb*= = (i.e.\ a space) that just
%    gobbles the argument.  Since the end-of-line character is
%    converted by \TeX{} to a space.  This means that |\input| is not
%    available as a command within batch files. In fact it would be
%    dangerous to use it anyway, since it would mean mixing line for
%    line reading with unlimited file reading.
%
% \begin{macro}{\@@input}
% \changes{2.1a}{1993/02/22}{Macro added}
%    We therefore keep a copy of the original under the name
%    |\@@input| for internal use. If \ds{} runs under \LaTeX{} this
%    command is already defined, so we make a quick test.
%    \begin{macrocode}
\ifx\undefined\@@input \let\@@input\input\fi
%    \end{macrocode}
% \end{macro}
%    
%    To allow the nesting of batch files the |\batchinput| command is
%    provided it takes one argument, the name of the batch file to
%    switch to.
%    \begin{macrocode}
\def\batchinput#1{%
%    \end{macrocode}
%    We start a new group and locally redefine |\batchFile| to hold
%    the new batch file name and advance |\currbatchFile| by one to
%    get a new read stream. If the batch files are too deeply nested
%    there may be no further stream available so we better check for
%    this. The currently supported number is 10 which is generous
%    enough even for large installation procedures.
%    \begin{macrocode}
   \begingroup
     \def\batchfile{#1}%
     \advance\currbatchFile\@ne
     \ifnum\currbatchFile>\highestbatchFile
        \errhelp{Only up to ten levels of nesting for
                 \noexpand\batchinput commands are supported}%
        \errmessage{Batchfiles too deeply nested}%
     \fi
%    \end{macrocode}
%    After this test we can simply call |\processbatchFile| which will
%    open the new batch file and does a line for line reading until it
%    is exhausted. Note that if the batch file is not available, or
%    misspelled this routine will produce a warning and returns.
%    \begin{macrocode}
     \processbatchFile
%    \end{macrocode}
%    The values of |\batchfile| and |\currbatchFile| will be restored
%    at this  closing |\endgroup|, so that further processing
%    continues in the calling batch file.
%    \begin{macrocode}
   \endgroup
}
%    \end{macrocode}
% \begin{macro}{\skip@input}
% \changes{2.0j}{1992/03/03}{Added macro}
% \changes{2.0n}{1992/04/26}{Argument delimited by space not \cs{relax}}
% \changes{2.0n}{1992/04/26}{Macro renamed from \cs{skipinput}} 
%    And here is the promised redefinition of |\input|:
%    \begin{macrocode}
\def\skip@input#1 {}
\let\input\skip@input
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsubsection{Empty macros and macros that expand to a string}
% \begin{macro}{\guardStack}
%    \changes{2.0k}{1992/04/06}{Renamed from \texttt{\bsl blockStack}}
%    Because blocks of code that will conditionally be included in the
%    output can be nested, a stack is maintained to keep track of
%    these blocks. The main reason for this is that we want to be able
%    to check if the blocks are properly nested. The stack itself is
%    stored in |\guardStack|.
%    \begin{macrocode}
\def\guardStack{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\blockHead}
%    The macro |\blockHead| is used for storing and retrieving
%    the boolean expression that starts a block.
%    \begin{macrocode}
\def\blockHead{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\yes}
% \begin{macro}{\y}
%    When the user is asked a question that he has to answer with either
%    \meta{yes} or \meta{no}, his response has to be evaluated. For this
%    reason the macros |\yes| and |\y| are defined.
%    \begin{macrocode}
\def\yes{yes}
\def\y{y}
%    \end{macrocode}
% \begin{macro}{\n}
%    We also define |\n| for use in \ds{} command files.
% \changes{2.1e}{1993/03/09}{Macro added}
%    \begin{macrocode}
\def\n{n}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\Defaultbatchile}
% \changes{2.0f}{1991/06/04}{Macro added.}
%    When the \ds{} program has to process a batch file it
%    can look for a batch file with a default name. This name
%    is stored in |\DefaultbatchFile|.
%    \begin{macrocode}
\def\DefaultbatchFile{docstrip.cmd}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\perCent}
% \begin{macro}{\DoubleperCent}
%    To be able to display percent-signs on the terminal, a \texttt{\%}
%    with category code 12 is stored in |\perCent|. The macro
%    |\DoubleperCent| is used to write two percent-signs when
%    writing the preamble of the output file.
%    \begin{macrocode}
{\catcode`\%=12
 \gdef\perCent{%}
 \gdef\DoubleperCent{%% }
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%    In order to allow formfeeds in the input we define a one-character
%    control sequence \verb=^^L=.
%    \begin{macrocode}
\def^^L{ }
%    \end{macrocode}
%
%    The only result of using |\Name| is slowing down execution since
%    its typical use (e.g. |\Name\def{foo bar}...|) has exactly the
%    same number of tokens as its expansion. However I think that it's
%    easier to read. The meaning of |\Name| as a black box is:
%    ``construct a name from second parameter and then pass it to your
%    first parameter as a parameter''.
%
%    |\@stripstring| is used to get tokens building name of a macro
%    without leading backslash.
%    \begin{macrocode}
\def\Name#1#2{\expandafter#1\csname#2\endcsname}
\def\@stripstring{\expandafter\@gobble\string}
%    \end{macrocode}
%
% \subsubsection{Miscellaneous variables}
% \begin{macro}{\sourceFileName}
%    The macro |\sourceFileName| is used to store the name of the
%    current input file.
% \end{macro}
% \begin{macro}{\batchfile}
%    The macro |\batchfile| is used to store the name of the
%    batch file.
% \end{macro}
% \begin{macro}{\inLine}
%    The macro |\inLine| is used to store the lines, read from
%    the input file, before further processing.
% \end{macro}
% \begin{macro}{\batchLine}
%    The macro |\batchLine| is used to store the lines, read from
%    the batch file, before further processing.
% \end{macro}
% \begin{macro}{\answer}
%    When some interaction with the user is needed the macro
%    |\answer| is used to store his response.
% \end{macro}
% \begin{macro}{\tmp}
%    Sometimes something has to be temporarily stored in a control
%    sequence.  For these purposes the control sequence |\tmp| is
%    used.
% \end{macro}
%
% \subsection{Support macros}
%    \subsubsection{The stack mechanism}
%
%    It is possible to have `nested guards'. This means that within a
%    block of optionally included code a subgroup is only included
%    when an additional option is specified. To keep track of the
%    nesting of the guards the currently `open' guard can be pushed on
%    the stack |\guardStack| and later popped off the stack again. The
%    macros that implement this stack mechanism are loosely based on
%    code that is developed in the context of the \LaTeX3 project.
%
%    To be able to implement a stack mechanism we need a couple of
%    support macros.
% \begin{macro}{\eltStart}
%    \changes{2.0k}{1992/04/06}{Macro added}
% \begin{macro}{\eltEnd}
%    \changes{2.0k}{1992/04/06}{Macro added}
%    The macros |\eltStart| and |\eltEnd| are used to delimit a stack
%    element. They are both empty.
%    \begin{macrocode}
\def\eltStart{}
\def\eltEnd{}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\qStop}
%    \changes{2.0k}{1992/04/06}{Macro added}
%    The macro |\qStop| is a so-called `quark', a macro that expands to
%    itself\footnote{The concept of `quarks' is developed for the
%    \LaTeX3 project.}.
%    \begin{macrocode}
\def\qStop{\qStop}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pop}
%    \changes{2.0k}{1992/04/06}{Macro added} The macro
%    |\pop|\meta{stack}\meta{cs} `pops' the top element from the
%    stack. It assigns the value of the top element to \meta{cs} and
%    removes it from \meta{stack}. When \meta{stack} is empty a
%    warning is issued and \meta{cs} is assigned an empty value.
%    \begin{macrocode}
\def\pop#1#2{%
  \ifx#1\empty
    \Msg{Warning: Found end guard without matching begin}%
    \let#2\empty
  \else
%    \end{macrocode}
%    To be able to `peel' off the first guard we use an extra macro
%    |\popX| that receives both the expanded and the unexpanded stack
%    in its arguments. The expanded stack is delimited with the quark
%    |\qStop|.
%    \begin{macrocode}
    \def\tmp{\expandafter\popX #1\qStop #1#2}%
    \expandafter\tmp\fi}
%    \end{macrocode}
% \begin{macro}{\popX}
%    \changes{2.0k}{1992/04/06}{Macro added} When the stack is expanded
%    the elements are surrounded with |\eltStart| and |\eltEnd|. The
%    first element of the stack is assigned to |#4|.
%    \begin{macrocode}
\def\popX\eltStart #1\eltEnd #2\qStop #3#4{\def#3{#2}\def#4{#1}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\push}
%    \changes{2.0k}{1992/04/06}{Macro added}
%    Guards can be pushed on the stack using the macro
%    |\push|\meta{stack}\meta{guard}. Again we need a secondary macro
%    (|\pushX|) that has both the expanded and the unexpanded stack as
%    arguments.
%    \begin{macrocode}
\def\push#1#2{\expandafter\pushX #1\qStop #1{\eltStart #2\eltEnd}}
%    \end{macrocode}
% \begin{macro}{\pushX}
%    \changes{2.0k}{1992/04/06}{Macro added}
%    The macro |\pushX| picks up the complete expansion of the stack as
%    its first argument and places the guard in |#3| on the `top'.
%    \begin{macrocode}
\def\pushX #1\qStop #2#3{\def #2{#3#1}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsubsection{Programming structures}
%
% \begin{macro}{\forlist}
% \changes{2.0g}{1991/06/05}{Macro added.}
%    When the program is used in interactive mode the
%    user can supply a list of files that have to be processed.
%    In order to process this list a for-loop is needed. This
%    implementation of such a programming construct is based on the
%    use of the \verb=\loop{=\meta{body}\verb=}\repeat= macro that
%    is defined in plain \TeX\@. The syntax for this loop is:
%    \begin{flushleft}
%    |\for|\meta{control sequence} |:=| \meta{list} 
%    |\do|\\
%    \meta{body}\\
%    |\od|
%    \end{flushleft}
%    The \meta{list} should be a comma separated list.
%
%    The first actions that have to be taken are to set the switch
%    |\ifForlist| to \meta{true} and to store the loop condition
%    in the macro |\ListCondition|. This is done using an
%    |\edef| to allow for a control sequence that contains a
%    \meta{list}.
%    \begin{macrocode}
\def\forlist#1:=#2\do#3\od{%
    \edef\ListCondition{#2}%
    \Forlisttrue
%    \end{macrocode}
%    Then we start the loop.
%    We store the first element from the |\ListCondition| in the
%    macro that was supplied as the first argument to |\forlist|.
%    This element is then removed from the |\ListCondition|.
%    \begin{macrocode}
    \loop
      \edef#1{\expandafter\FirstElt\ListCondition,\empty.}%
      \edef\ListCondition{\expandafter\OtherElts\ListCondition,\empty.}%
%    \end{macrocode}
%    When the first element from the \meta{list} is empty, we are done
%    processing, so we switch |\ifForlist| to \meta{false}.
%    When it is not empty we execute the third argument that should
%    contain \TeX\ commands to execute.
%    \begin{macrocode}
      \ifx#1\empty \Forlistfalse \else#3\fi
%    \end{macrocode}
%    Finally we test the switch |\ifForlist| to decide whether the
%    loop has to be continued.
%    \begin{macrocode}
      \ifForlist
    \repeat}
%    \end{macrocode}
% \begin{macro}{\FirstElt}
% \changes{2.0g}{1991/06/05}{Macro added.}
%    The macro |\FirstElt| is used to get the first element from a
%    comma-separated list.
%    \begin{macrocode}
\def\FirstElt#1,#2.{#1}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\OtherElts}
% \changes{2.0g}{1991/06/05}{Macro added.}
%    The macro |\OtherElts| is used to get all elements {\em but\/}
%    the first element from a comma-separated list.
%    \begin{macrocode}
\def\OtherElts#1,#2.{#2}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\whileswitch}
% \changes{2.0h}{1991/06/19}{Macro added.} When the program is used in
%    interactive mode the user might want to process several files
%    with different options or extensions.  This goal could be reached
%    by running the program several times, but it is more
%    user-friendly to ask if he would like to process more files when
%    we are done processing his last request.  To accomplish this we
%    need the implementation of a \texttt{while}-loop.  Again plain
%    \TeX's \verb=\loop{=\meta{body}\verb=}\repeat= is used to
%    implement this programming structure.
%
%    The syntax for this loop is:
%    \begin{flushleft}
%    |\whileswitch|\meta{switch} \verb|\fi| \meta{list}
%    \verb={=\meta{body}\verb=}=\\
%    \end{flushleft}
%    The first argument to this macro has to be a switch, defined
%    using |\newif|; the second argument contains the statements
%    to execute while the switch evaluates to \meta{true}.
%    \begin{macrocode}
\def\whileswitch#1\fi#2{#1\loop#2#1\repeat\fi}
%    \end{macrocode}
% \end{macro}
%
% \changes{2.3a}{1995/08/18}{New mechanism: output streams allocation}
% 
% \subsubsection{Output streams allocator}
% 
% For each of sixteen output streams  available  we  have  a  macro
% named |\s@0| through |\s@15| saying if the stream is assigned to a
% file~(1) or not~(0). Initially all streams are not assigned.
%
% We also declare 16 counters which will be needed by the conditional
% code inclusion algorithm.
% 
%    \begin{macrocode}
\ifx\@tempcnta\undefined \newcount\@tempcnta \fi
\@tempcnta=0
\loop
\Name\chardef{s@\number\@tempcnta}=0
\csname newcount\expandafter\endcsname%
  \csname off@\number\@tempcnta\endcsname
\advance\@tempcnta1
\ifnum\@tempcnta<16\repeat
%    \end{macrocode}
% 
% We will use \emph{The \TeX book} style list to search through streams.
% 
%    \begin{macrocode}
\let\s@do\relax
\edef\@outputstreams{%
  \s@do\Name\noexpand{s@0}\s@do\Name\noexpand{s@1}
  \s@do\Name\noexpand{s@2}\s@do\Name\noexpand{s@3}
  \s@do\Name\noexpand{s@4}\s@do\Name\noexpand{s@5}
  \s@do\Name\noexpand{s@6}\s@do\Name\noexpand{s@7}
  \s@do\Name\noexpand{s@8}\s@do\Name\noexpand{s@9}
  \s@do\Name\noexpand{s@10}\s@do\Name\noexpand{s@11}
  \s@do\Name\noexpand{s@12}\s@do\Name\noexpand{s@13}
  \s@do\Name\noexpand{s@14}\s@do\Name\noexpand{s@15}
  \noexpand\@nostreamerror
  }
%    \end{macrocode}
%
% \begin{macro}{\@nostreamerror}\begin{macro}{\@streamfound}
% When |\@outputstreams| is executed |\s@do| is defined to do
% something on condition   of   some   test.    If   condition
% always   fails   macro |\@nostreamerror| on the end of the list
% causes an error. When condition succeeds  |\@streamfound|  is
% called,  which  gobbles  rest of the list including the ending
% |\@nostreamerror|. It also gobbles |\fi| ending the condition, so
% the |\fi| is reinserted.
% 
%    \begin{macrocode}
\def\@nostreamerror{\errmessage{No more output streams!}}
\def\@streamfound#1\@nostreamerror{\fi}
%    \end{macrocode}
% \end{macro}\end{macro}
% 
% |\@stripstr| is auxiliary macro eating characters |\s@|
% (backslash,s,@). It is defined in somewhat strange way since |\s@|
% must have all category code  12  (other).  This  macro  is  used to
% extract stream numbers from stream names.
% 
%    \begin{macrocode}
\bgroup\edef\x{\egroup
 \def\noexpand\@stripstr\string\s@{}}
\x
%    \end{macrocode}
%
% \begin{macro}{\StreamOpen}\begin{macro}{\StreamPut}
% \begin{macro}{\StreamClose}
% Here is stream opening operator. Its parameter should be a  macro
% named the  same  as  the  external  file  being  opened. E.g. to
% write to file |foo.tex|   use    |\StreamOpen\foo|,    then
% |\StreamPut\foo|    and |\StreamClose\foo|.
% 
%    \begin{macrocode}
\def\StreamOpen#1{%
  \chardef#1=16 
  \def\s@do##1{\ifnum##1=0
    \chardef#1=\expandafter\@stripstr\string##1 %
    \global\chardef##1=1 %
    \immediate\openout#1=\WriteToDir\@stripstring#1 %
    \@streamfound
    \fi}
  \@outputstreams
  }
\def\StreamClose#1{
  \immediate\closeout#1%
  \def\s@do##1{\ifnum#1=\expandafter\@stripstr\string##1 %
    \global\chardef##1=0 %
    \@streamfound
    \fi}
  \@outputstreams
  \chardef#1=16
  }
\def\StreamPut{\immediate\write}
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}
% 
% \subsubsection{Input and Output}
%
% \begin{macro}{\maybeMsg}
% \begin{macro}{\showprogress}
% \begin{macro}{\keepsilent}
%    When this program is used it can optionally show its progress on
%    the terminal. In that case it will write a special character to
%    the terminal (and the transcript file) for each input line. This
%    option is on by default when statistics are included in 
%    \texttt{docstrip.tex}. It is off when statistics are excluded. The
%    commands |\showprogress| and |\keepsilent| can be used
%    to choose otherwise.
%    \begin{macrocode}
\def\showprogress{\let\maybeMsg\message}
\def\keepsilent{\let\maybeMsg\@gobble}
%<*stats>
\showprogress
%</stats>
%<-stats>\keepsilent
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\Msg}
%    For displaying messages on the terminal the macro |\Msg| is
%    defined to write {\em immediately\/} to |\ttyout|.
%    \begin{macrocode}
\def\Msg{\immediate\write\ttyout}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\Ask}
%    The macro
%    \verb=\Ask{=\meta{cs}\verb=}{=\meta{string}\verb=}= is a
%    slightly modified copy of the \LaTeX\ macro |\typein|. It is
%    used to ask the user a question.  The \meta{string} will be
%    displayed on his terminal and the response will be stored in the
%    \meta{cs}. The trailing space left over from the carriage return
%    is stripped off by the macro |\strip|. If the user just
%    types a carriage return, the result will be an empty macro.
% \changes{2.0i}{1991/06/27}{Added check for just \protect\meta{CR}}
%    \begin{macrocode}
\def\iden#1{#1}
\def\strip#1#2 \@gobble{\def #1{#2}}
\def\@defpar{\par}
\def\Ask#1#2{%
    \message{#2}\read\ttyin to #1\ifx#1\@defpar\def#1{}\else
    \iden{\expandafter\strip
       \expandafter#1#1\@gobble\@gobble} \@gobble\fi}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Miscellaneous}
%
% \begin{macro}{\@gobble}
% \changes{2.0a}{1991/05/25}{Macro added.}
%    A macro that has an argument and puts it in the bitbucket.
%    \begin{macrocode}
\def\@gobble#1{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\Endinput}
% \changes{2.0f}{1991/06/04}{Macro added.} When a \texttt{doc} file
%    contains a \verb+\endinput+ on a line by itself this normally
%    means that anything following in this file should be ignored.
%    Therefore we need a macro containing |\endinput| as its
%    replacement text to check this against |\inLine| (the
%    current line from the current input file). Of course the
%    backslash has to have the correct |\catcode|. One way of
%    doing this is feeding \verb=\\= to the |\string| operation
%    and afterwards removing one of the |\| characters.
%    \begin{macrocode}
\edef\Endinput{\expandafter\@gobble\string\\endinput}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\makeOther}
%    During the process of reading a file with \TeX\ code the category
%    code of all special characters has to be changed to \meta{other}.
%    The macro |\makeOther| serves this purpose.
%    \begin{macrocode}
\def\makeOther#1{\catcode`#1=12\relax}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\end}
% \changes{2.0h}{1991/06/19}{Macro added.} For now we want the \ds{}
%    program to be compatible with both plain \TeX\ and \LaTeX\@.
%    \LaTeX\ version 2.09 hides plain \TeX{}'s |\end| command and
%    calls it |\@@end|. We unhide it here.
%    \begin{macrocode}
\ifx\undefined\@@end\else\let\end\@@end\fi
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@addto}
%    A macro extending macro's definition. The trick with |\csname|
%    is necessary to get around |\newtoks| being outer in plain \TeX{}
%    and \LaTeX\ version 2.09.
%    \begin{macrocode}
\ifx\@temptokena\undefined \csname newtoks\endcsname\@temptokena\fi

\def\@addto#1#2{%
  \@temptokena=\expandafter{#1}
  \edef#1{\the\@temptokena#2}}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\@ifpresent}
%    This macro checks if its first argument  is  present  on  a
%    list passed as the second argument. Depending on the result
%    it executes either its third or fourth argument.
% 
%    \begin{macrocode}
\def\@ifpresent#1#2#3#4{%
  \def\tmp##1#1##2\qStop{\ifx!##2!}%
  \expandafter\tmp#2#1\qStop #4\else #3\fi
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tospaces}
%    This macro converts its argument delimited with |\secapsot| to
%    appropriate number of spaces. We need this for smart displaying
%    messages on the screen.
%
%    |\@spaces| are used when we need many spaces in a row.
%    \begin{macrocode}
\def\tospaces#1{%
  \ifx#1\secapsot\secapsot\fi\space\tospaces}
\def\secapsot\fi\space\tospaces{\fi}
\def\@spaces{\space\space\space\space\space}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\uptospace}
% \changes{2.3c}{1995/08/24}{Macro added}
%    This  macro extracts from its argument delimited with |\qStop|
%    part up to first occurence of space.
%    \begin{macrocode}
\def\uptospace#1 #2\qStop{#1}
%    \end{macrocode}
% \end{macro}
%
%    The  names  of  these  macros  are  as  descriptive  as  their
%    definitions.
%    \begin{macrocode}
\def\@firstoftwo#1#2{#1}
\def\@secondoftwo#1#2{#2}
\def\@firstofthree#1#2#3{#1}
\def\@secondofthree#1#2#3{#2}
\def\@thirdofthree#1#2#3{#3}
%    \end{macrocode}
%
%
% \subsection{The evaluation of boolean expressions}
% 
%    For clarity we repeat here the syntax for the boolean expressions
%    in somewhat changed but equivalent way:
% 
% \DeleteShortVerb\|
%    \begin{tabular}{lcl}
%    \meta{Expression} & $::=$ & \meta{Secondary} $|$
%                            \meta{Secondary} \{\texttt{|}, \texttt{,}\}
%                              \meta{Expression}\\
%    \meta{Secondary}    & $::=$ & \meta{Primary} $|$
%                         \meta{Primary} \texttt{\&}
%                              \meta{Secondary}\\
%    \meta{Primary}  & $::=$ & 
%                         \meta{Terminal} $|$ \texttt{!}\meta{Primary}
%                                  $|$ 
%                         \texttt{(}\meta{Expression}\texttt{)}\\
%    \end{tabular}
% 
%    The \texttt{|} stands for disjunction, the \texttt{\&} stands for
%    conjunction and the \texttt{!}\ stands for negation. The
%    \meta{Terminal} is any sequence of letters and evaluates to
%    \meta{true} iff it occurs in the list of options that have to be
%    included.
% \MakeShortVerb\|
% 
%    Since we can generate multiple output files  from  one  input,
%    same  guard  expressions  can  be  computed several times with
%    different options. For that reason we  first  ``compile''  the
%    expression   to  the  form  of  one  parameter  macro  |\Expr|
%    expanding to nested |\if|s that when  given  current  list  of
%    options  produces  1  or  0  as  a  result. The idea is to say
%    |\if1\Expr{|\meta{current set  of  options}|}...\fi|  for  all
%    output files.
% 
%    Here is a table recursively defining  translations  for  right
%    sides  of the grammar. $\tau(X)$ denotes translation of~$X$.
%    
% \DeleteShortVerb\|
% \MakeShortVerb\"
%    \begingroup
%     \addtolength\arraycolsep{-2.1pt}
%    \begin{eqnarray*}
%    \tau(\meta{Terminal})&=&"\t@<Terminal>,#1,<Terminal>,\qStop"\\
%   \tau(!\meta{Primary})&=&"\if1"\,\tau(\meta{Primary})\,"0\else1\fi"\\
%    \tau(\mbox{\texttt{(}\meta{Expression}\texttt{)}})
%                         &=&\tau(\meta{Expression})\\
%    \tau(\mbox{\meta{Primary}\texttt{\&}\meta{Secondary}})
%                         &=&"\if0"\,\tau(\meta{Primary})\,"0\else"
%                             \,\tau(\meta{Secondary})\,"\fi"\\
%    \tau(\mbox{\meta{Secondary}\texttt{|}\meta{Expression}})
%                         &=&"\if1"\,\tau(\meta{Secondary})\,"1\else"
%                            \,\tau(\meta{Expression})\,"\fi"
%    \end{eqnarray*}
%    \endgroup
% \DeleteShortVerb\"
% \MakeShortVerb\|
%    |\t@<Terminal>|  denotes macro with name constructed from |t@|
%    with appended tokens of terminal. E.g. for terminal |foo|  the
%    translation would be
%    \begin{verbatim}
%    \t@foo,#1,foo,\qStop
%    \end{verbatim}
%    This will  end up in definition of |\Expr|,  so |#1| here will
%    be substituted by current list  of  options  when  |\Expr|  is
%    called. Macro |\t@foo| would be defined as
%    \begin{verbatim}
%    \def\t@foo#1,foo,#2\qStop{\ifx>#2>0\else1\fi}
%    \end{verbatim}
%    When  called  as  above  this  will  expand to |1| if |foo| is
%    present on current list of options and to |0| otherwise.
% 
%    Macros  below  work  in  ``almost  expand-only''   mode   i.e.
%    expression is analyzed only by expansion but we have to define
%    some macros on the way (e.g. |\Expr| and |\t@foo|).
% 
%    The   first   parameter   of   each   of   these   macros   is
%    ``continuation''   (in  the  sense  similar  to  the  language
%    \textsc{Scheme}). Continuation is a function of at  least  one
%    argument  (parameter)  being  the  value  of previous steps of
%    computation.   For   example   macro   |\Primary|   constructs
%    translation of \meta{Primary} expression. When it decides that
%    expression is completed it calls its continuation  (its  first
%    argument)   passing   to  it  whole  constructed  translation.
%    Continuation may expect more arguments if it wants to see what
%    comes next on the input.
% 
%    We  will perform recursive descent parse, but definitions will
%    be presented in bottom-up order.
% 
% \begin{macro}{\Terminal}
% 
%    \meta{Terminal}s are  recognized  by  macro  |\Terminal|.  The
%    proper   way   of   calling  it  is  |\Terminal{|\meta{current
%    continuation}|}{}|.     Parameters     are:      continuation,
%    \meta{Terminal}  so  far  and  next  character from the input.
%    Macro checks if |#3| is one of terminal-ending characters  and
%    then  takes  appropriate  actions.  Since  there  are 7 ending
%    chars  and probably one |\csname| costs  less  than  7  nested
%    |\if|s we construct a name and check if it is defined.
% 
%    We must expand |\ifx| completely before taking next actions so
%    the following trickery happens:
%    \begin{macrocode}
\def\Terminal#1#2#3{%
  \expandafter\ifx\csname eT@#3\endcsname\relax
    \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
%    \end{macrocode}
%    If condition is true |#3| belongs to  current  \meta{Terminal}
%    so we append it to \meta{Terminal}-so-far and call |\Terminal|
%    again. 
%    \begin{macrocode}
  {\Terminal{#1}{#2#3}}%
%    \end{macrocode}
%    When condition is false it's time to end  the  \meta{Terminal}
%    so we call macro |\TerminalX|. Next character is reinserted to
%    the input.
% 
%    In both cases continuation is passed unchanged.
%    \begin{macrocode}
  {\TerminalX{#1}{#2}#3}%
  }
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\eT@}
%    Here we define macros marking characters  that  cannot  appear
%    inside  terminal.  The value is not important as long as it is
%    different from |\relax|.
%    \begin{macrocode}
\Name\let{eT@>}=1
\Name\let{eT@&}=1 \Name\let{eT@!}=1
\Name\let{eT@|}=1 \Name\let{eT@,}=1
\Name\let{eT@(}=1 \Name\let{eT@)}=1
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\TerminalX}
%    This macro should end scanning of \meta{Terminal}.  Parameters
%    are continuation and gathered tokens of \meta{Terminal}.
% 
%    Macro starts by issuing an error message if \meta{Terminal} is
%    empty.
%    \begin{macrocode}
\def\TerminalX#1#2{%
  \ifx>#2> \errmessage{Error in expression: empty terminal}\fi
%    \end{macrocode}
%    Then  a  macro  is  constructed  for  checking   presence   of
%    \meta{Terminal} in options list.
%    \begin{macrocode}
  \Name\def{t@#2}##1,#2,##2\qStop{\ifx>##2>0\else1\fi}%
%    \end{macrocode}
%    And  then  current  continuation is called with translation of
%    \meta{Terminal} according to formula
%    $$\tau(\meta{Terminal})=|\t@<Terminal>,#1,<Terminal>,\qStop|$$
%    \begin{macrocode}
  #1{\Name\noexpand{t@#2},##1,#2,\noexpand\qStop}%
  }
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\Primary}
%    Parameters are continuation and next character from the input.
%    
%    According to the syntax \meta{Primari}es can have three forms.
%    This  makes us use even more dirty tricks than usual. Note the
%    |\space| after a series of |\ifx|s. This  series  produces  an
%    one  digit  number of case to be executed. The number is given
%    to  |\ifcase|  and  |\space|  stops  \TeX{}  scanning  for   a
%    \meta{number}.  Use of |\ifcase| gives possibility to jump out
%    of conditions with just one |\expandafter|.
%    \begin{macrocode}
\def\Primary#1#2{%
  \ifcase \ifx!#20\else\ifx(#21\else2\fi\fi\space 
    \expandafter\@firstofthree\or
    \expandafter\@secondofthree\or
    \expandafter\@thirdofthree\fi
%    \end{macrocode}
%    First case is for |!| i.e.  negated \meta{Primary}.   In  this
%    case   we  call  |\Primary|  recursively  but  we  create  new
%    continuation:   macro  |\NPrimary|  that  will  negate  result
%    passed  by  |\Primary|  and  pass  it  to current continuation
%    (|#1|).
%    \begin{macrocode}
  {\Primary{\NPrimary{#1}}}%
%    \end{macrocode}
%    When next character is |(| we call |\Expression| giving it  as
%    continuation  macro  |\PExpression|  which  will just pass the
%    result up but ensuring first that a |)| comes next.
%    \begin{macrocode}
  {\Expression{\PExpression{#1}}}%
%    \end{macrocode}
%    Otherwise we start a \meta{Terminal}. |#2| is  not  passed  as
%    \meta{Terminal}-so-far  but reinserted to input since we didn't
%    check if it can appear in a \meta{Terminal}.
%    \begin{macrocode}
  {\Terminal{#1}{}#2}%
  }
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\NPrimary}
%    Parameters    are   continuation   and   previously   computed
%    \meta{Primary}.
%    
%    This macro negates result of previous  computations  according
%    to the rule
%    $$\tau(!\meta{Primary})
%         =|\if1|\,\tau(\meta{Primary})\,|0\else1\fi|$$
%    \begin{macrocode}
\def\NPrimary#1#2{%
  #1{\noexpand\if1#20\noexpand\else1\noexpand\fi}%
  }
%    \end{macrocode}   
% \end{macro}
% 
% \begin{macro}{\PExpression}
%    Parameters: continuation,  \meta{Expression},  next  character
%    from  input. We are checking if character is |)| and then pass
%    unchanged result to our continuation.
%    \begin{macrocode}
\def\PExpression#1#2#3{% 
  \ifx)#3\else
    \errmessage{Error in expression: expected right parenthesis}\fi
  #1{#2}}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\Secondary}
%    Each \meta{Secondary} expression starts  with  \meta{Primary}.
%    Next checks will be performed by |\SecondaryX|.
%    \begin{macrocode}
\def\Secondary#1{%
  \Primary{\SecondaryX{#1}}}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\SecondaryX}
%    Parameters:  continuation, translation of \meta{Primary}, next
%    character. We start by checking if next character is |&|.
%    \begin{macrocode}
\bgroup\catcode`\&=12
\gdef\SecondaryX#1#2#3{%
  \ifx&#3%
    \expandafter\@firstoftwo\else
    \expandafter\@secondoftwo\fi
%    \end{macrocode}
%    If it is  we  should  parse  next  \meta{Secondary}  and  then
%    combine  it with results so far. Note that |\SecondaryXX| will
%    have 3 parameters.
%    \begin{macrocode}
  {\Secondary{\SecondaryXX{#1}{#2}}}%
%    \end{macrocode}
%    Otherwise   \meta{Secondary}   turned   out   to    be    just
%    \meta{Primary}. We call continuation passing to it translation
%    of that \meta{Primary} not forgetting to reinsert |#3| to  the
%    input as it does not belong here.
%    \begin{macrocode}
  {#1{#2}#3}%
  }
\egroup
%    \end{macrocode}   
% \end{macro}
% 
% \begin{macro}{\SecondaryXX}
%    Parameters:   continuation,   translation  of  \meta{Primary},
%    translation of \meta{Secondary}. We construct  translation  of
%    whole construction according to the rule:
%    $$\tau(\mbox{\meta{Primary}\texttt{\&}\meta{Secondary}})
%                         =|\if0|\,\tau(\meta{Primary})\,|0\else|
%                             \,\tau(\meta{Secondary})\,|\fi| $$
%    and pass it to our continuation.
%    \begin{macrocode}
\def\SecondaryXX#1#2#3{%
  #1{\noexpand\if0#20\noexpand\else#3\noexpand\fi}}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\Expression}
%    Every   \meta{Expression}  starts  with  \meta{Secondary}.  We
%    construct new continuation and pass it to |\Secondary|.
%    \begin{macrocode}
\def\Expression#1{%
  \Secondary{\ExpressionX{#1}}}
%    \end{macrocode}   
% \end{macro}
% 
% \begin{macro}{\ExpressionX}
%    Parameters:  continuation,  translation  of  \meta{Secondary},
%    next   character.   We   perform   check   if   character   is
%    \texttt{\char`\|} or |,|.
%    \begin{macrocode}
\def\ExpressionX#1#2#3{%
  \if0\ifx|#31\else\ifx,#31\fi\fi0
    \expandafter\@firstoftwo\else
    \expandafter\@secondoftwo\fi
%    \end{macrocode}
%    If it is not \meta{Expression} is just a \meta{Secondary}.  We
%    pass its translation to continuation and reinsert |#3|.
%    \begin{macrocode}
  {#1{#2}#3}%
%    \end{macrocode}
%    If  we  are  dealing  with complex \meta{Expression} we should
%    parse another |\Expression| now.
%    \begin{macrocode}
  {\Expression{\ExpressionXX{#1}{#2}}}%
  }
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\ExpressionXX}
%    Parameters:  continuation,  translation  of  \meta{Secondary},
%    translation of \meta{Expression}.
%    We finish up translating  of  \meta{Expression}  according  to   
%    the formula:
%    $$\tau(\mbox{\meta{Secondary}\texttt{\char`\|}\meta{Expression}})
%                         =|\if1|\,\tau(\meta{Secondary})\,|1\else|
%                            \,\tau(\meta{Expression})\,|\fi|$$
%    \begin{macrocode}
\def\ExpressionXX#1#2#3{%
  #1{\noexpand\if1#21\noexpand\else#3\noexpand\fi}}
%    \end{macrocode}   
% \end{macro}
% 
% \begin{macro}{\StopParse}
%    Here is initial continuation for whole parse process. It  will
%    be  used  by  |\Evaluate|. Note that we assume that expression
%    has |>| on its end.  This macro  eventually  defines  |\Expr|.
%    Parameters:   translation  of whole \meta{Expression} and next
%    character from input.
%    \begin{macrocode}
\def\StopParse#1#2{%
  \ifx>#2 \else\errmessage{Error in expression: spurious #2}\fi
  \edef\Expr##1{#1}}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\Evaluate}   
%    This macro is used to start  parsing.  We  call  |\Expression|
%    with  continuation  defined  above.   On  end of expression we
%    append a |>|.
%    \begin{macrocode}
\def\Evaluate#1{%
  \Expression\StopParse#1>}
%    \end{macrocode}
% \end{macro}
%
%  \subsection{Processing the input lines}
%
% \begin{macro}{\normalLine}
%    The macro |\normalLine| writes its argument (which has to be
%    delimited with |\endLine|) on all active output files i.e.
%    those with off-counters equal to zero.
%    If statistics are included, the counter
%    |\codeLinesPassed| is incremented by $1$.
%    \begin{macrocode}
\def\normalLine#1\endLine{%
%<*stats>
  \advance\codeLinesPassed\@ne
%</stats>
  \maybeMsg{.}%
  \def\inLine{#1}%
  \let\do\putline@do
  \activefiles
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\putline@do}
% \changes{2.3b}{1995/08/22}{Change for pre-constructed
%                            off-counters' names}
%    This is a value for |\do| when copying line to output files.
%    \begin{macrocode}
\def\putline@do#1#2#3{%
  \StreamPut#1{\inLine}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\removeComment}
%    The macro |\removeComment| throws its argument (which has to be
%    delimited with |\endLine|) away. When statistics are included
%    in the program the removed comment is counted.
%    \begin{macrocode}
%
\def\removeComment#1\endLine{%
%<*stats>
    \advance\commentsRemoved\@ne
%</stats>
    \maybeMsg{\perCent}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\putMetaComment}
%    If a line starts with two consecutive percent signs, it is
%    considered to be a {\em MetaComment\/}. Such a comment line is
%    passed on to the output file unmodified.
%    \begin{macrocode}
\def\putMetaComment#1\endLine{%
%    \end{macrocode}
%    If statistics are included the line is counted.
%    \begin{macrocode}
%<*stats>
  \advance\commentsPassed\@ne
%</stats>
%    \end{macrocode}
%    The macro |\putMetaComment| has one argument, delimited with
%    |\endLine|. But because of earlier processing the argument
%    is discarded and |\inLine|, which contains the complete line
%    as it was read from |\inFile|, is written on
%    all output files.
%    \begin{macrocode}
  \let\do\putline@do
  \outputfiles
  }
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\processLine}
% \changes{2.3a}{1995/08/18}{Adaptation for concurrent version}
% \changes{2.3a}{1995/08/20}{Trying to avoid assignments}
%    Each line that is read from the input stream has to be processed
%    to see if it has to be written on the output stream. This task
%    is performed by calling the macro |\processLine|.
%    In order to do
%    that, it needs to check whether the line starts with a
%    `\texttt{\%}'.  Therefore the macro is globally defined within a
%    group. Within this group the category code of `\texttt{\%}' is
%    changed to 12 (other).  Because a comment character is needed,
%    the category code of `\texttt{*}' is changed to 14 (comment
%    character).
%
%    The macro increments counter |\processedLines| by $1$ if
%    statistics are included. We cannot include this line with
%    |%<*stats>| since the category of \texttt{\%}, so the whole
%    definition is repeated embedded in guards.
%
%    The next token from
%    the input stream is passed in |#1|. If it is a `\texttt{\%}'
%    further processing has to be done by |\processLineX|;
%    otherwise this is normal (not commented out) line.
%    
%    In either case the character read is reinserted to the input
%    as it may have to be written out.
%    \begin{macrocode}
%<*!stats>
\begingroup
\catcode`\%=12 \catcode`\*=14
\gdef\processLine#1{*
  \ifx%#1
    \expandafter\processLineX
  \else
    \expandafter\normalLine
  \fi
  #1}
\endgroup
%</!stats>
%<*stats>
\begingroup
\catcode`\%=12 \catcode`\*=14
\gdef\processLine#1{*
  \advance\processedLines\@ne
  \ifx%#1
    \expandafter\processLineX
  \else
    \expandafter\normalLine
  \fi
  #1}
\endgroup
%</stats>
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\processLineX}
% \changes{2.3a}{1995/08/20}{Trying to avoid assignments}
%    This macro is also defined within a group, 
%    because it also has to check if the next
%    token in the input stream is a `\texttt{\%}' character.
%
%    If the second token in the current line happens to be a
%    `\texttt{\%}', a \meta{MetaComment} has been found. This has to
%    be copied in its entirety to the output.  Another possible second
%    character is `\texttt{<}', which introduces a guard expression.
%    The processing of such an expression is started by calling
%    |\checkOption|.
%
%    When the token was neither a `\texttt{\%}' nor a `\texttt{<}',
%    the line contains a normal comment that has to be removed.
%
%    We express conditions in such a way that all actions appear
%    on first nesting level of |\if|s. In such conditions just one
%    expandafter pushes us outside whole construction. A thing to
%    watch here is |\relax|. It stops search for numeric constant.
%    If it wasn't here \TeX\ would expand the first case of |\ifcase|
%    before knowing the value.
%
%    \begin{macrocode}
\begingroup
\catcode`\%=12 \catcode`\*=14
\gdef\processLineX%#1{*
  \ifcase\ifx%#10\else
         \ifx<#11\else 2\fi\fi\relax
    \expandafter\putMetaComment\or
    \expandafter\checkOption\or
    \expandafter\removeComment\fi
  #1}
\endgroup
%    \end{macrocode}
% \end{macro}
%
%  \subsection{The handling of options}
%
% \begin{macro}{\checkOption}
%    \changes{2.3a}{1995/08/18}{Adapted to concurrent version}
%  \changes{2.3a}{1995/08/20}{Trying to avoid assignments}
%    When the macros that process a line have found that the line
%    starts with `\texttt{\%<}', a guard line has been encountered.
%    The first character of a guard can be an asterisk (\texttt{*}), a
%    slash (\texttt{/}) a plus (\texttt{+}), a minus (\texttt{-}) or
%    any other character that can be found in an option name. This
%    means that we have to peek at the next token and 
%    decide what kind of guard we have. 
%    
%    We reinsert |#1| as it may be needed by |\doOption|.
%    \begin{macrocode}
\def\checkOption<#1{%
  \ifcase
    \ifx*#10\else \ifx/#11\else
    \ifx+#12\else \ifx-#13\else 4\fi\fi\fi\fi\relax
  \expandafter\starOption\or
  \expandafter\slashOption\or
  \expandafter\plusOption\or
  \expandafter\minusOption\or
  \expandafter\doOption\fi
  #1}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\doOption}
%    When no guard modifier is found by |\checkOptions|, the
%    macro |\doOption| is called. It evaluates a boolean
%    expression. The result of this evaluation is stored in 
%    |\Expr|. The guard only affects the current
%    line,  so  |\do|  is  defined in such a way that depending on the
%    result of the  test |\if1\Expr{|\meta{options}|}|,  the  current
%    line is either copied to the output stream or removed. Then
%    the test is computed for all active output files.
%    \begin{macrocode}
\def\doOption#1>#2\endLine{%
  \maybeMsg{<#1 . >}%
  \Evaluate{#1}%
  \def\do##1##2##3{%
    \if1\Expr{##2}\StreamPut##1{#2}\fi
    }%
  \activefiles
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\plusOption}
%    When a `\texttt{+}' is found as a guard modifier,
%    |\plusOption| is called. This macro is very similar to
%    |\doOption|, the only difference being that displayed
%    message now contains `\texttt{+}'.
%    \begin{macrocode}
\def\plusOption+#1>#2\endLine{%
  \maybeMsg{<+#1 . >}%
  \Evaluate{#1}%
  \def\do##1##2##3{%
    \if1\Expr{##2}\StreamPut##1{#2}\fi
    }%
  \activefiles
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\minusOption}
%    When a `\texttt{-}' is found as a guard modifier,
%    |\minusOption| is called. This macro is very similar to
%    |\plusOption|, the difference is that condition is negated.
%    \begin{macrocode}
\def\minusOption-#1>#2\endLine{%
  \maybeMsg{<-#1 . >}%
  \Evaluate{#1}%
  \def\do##1##2##3{%
    \if1\Expr{##2}\else \StreamPut##1{#2}\fi
    }%
  \activefiles
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\starOption}
%    \changes{2.3a}{1995/08/18}{Adapted to concurrent version}
%    When a `\texttt{*}' is found as a guard modifier,
%    |\starOption| is called. In this case a block of code will
%    be included in the output on the condition that the guard
%    expression evaluates to \meta{true}.
%
%    The current line is gobbled as |#2|, because it only contains
%    the guard and possibly a comment.
%
%    \begin{macrocode}
\def\starOption*#1>#2\endLine{%
%    \end{macrocode}
%    First we optionally write
%    a message to the terminal to indicate that a new option starts
%    here.
%    \begin{macrocode}
  \maybeMsg{<*#1}%
%    \end{macrocode}
%    Then we push the current contents of |\blockHead| on the
%    stack of blocks, |\guardStack| and increment  the counter
%    |\blockLevel| to indicate that we are now one level of
%    nesting deeper.
% \changes{2.0k}{1992/04/06}{Use new stack mechanism}
% \changes{2.0k}{1992/04/09}{The macro that holds the guard needs to be
%    expanded}
%    \begin{macrocode}
  \expandafter\push\expandafter\guardStack\expandafter{\blockHead}%
  \advance\blockLevel\@ne
%    \end{macrocode}
%    The guard for this block of code is now stored in
%    |\blockHead|.
%    \begin{macrocode}
  \def\blockHead{#1}%
%    \end{macrocode}
%    Now we evaluate guard expression for all output files 
%    updating off-counters. Then we create new list of active
%    output files. Only files that were active in the outer block
%    can remain active now.
%    \begin{macrocode}
  \Evaluate{#1}%
  \let\do\checkguard@do
  \outputfiles
  \let\do\findactive@do
  \edef\activefiles{\activefiles}
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\checkguard@do}
% \changes{2.3b}{1995/08/22}{Change for pre-constructed
%                            off-counters' names}
%    This form of |\do| updates off-counts according to the value of
%    guard expression.
%    \begin{macrocode}
\def\checkguard@do#1#2#3{%
%    \end{macrocode}
%    If this block of code occurs inside another block of code that is
%    {\em not\/} included in the output, we increment the off counter.
%    In that case the guard expression will not be
%    evaluated, because a block inside another block that is excluded
%    from the output will also be excluded, regardless of the
%    evaluation of its guard.
%    \begin{macrocode}
  \ifnum#3>0
    \advance#3\@ne
%    \end{macrocode}
%    When the off count has  value 0, we have
%    to evaluate the guard expression. If the result is \meta{false}
%    we increase the off-counter.
%    \begin{macrocode}
  \else
    \if1\Expr{#2}\else
      \advance#3\@ne\fi
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\findactive@do}
% \changes{2.3b}{1995/08/22}{Change for pre-constructed
%                            off-counters' names}
%    This form of |\do| picks elements of output files list which
%    have off-counters equal to zero.
%    \begin{macrocode}
\def\findactive@do#1#2#3{%
  \ifnum#3=0
    \noexpand\do#1{#2}#3\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\slashOption}
%    \changes{2.3a}{1995/08/18}{Adapted for concurrent version}
%    The macro |\slashOption| is the counter part to
%    |\starOption|.  It indicates the end of a block of
%    conditionally included code.  We store the argument in the
%    temporary control sequence |\tmp|.
%    \begin{macrocode}
\def\slashOption/#1>#2\endLine{%
  \def\tmp{#1}%
%    \end{macrocode}
%    When the counter |\blockLevel| has a value less than $1$,
%    this `end-of-block' line has no corresponding `start-of-block'.
%    Therefore we signal an error and ignore this end of block.
%    \begin{macrocode}
  \ifnum\blockLevel<\@ne
    \errmessage{Spurious end block </\tmp> ignored}%
%    \end{macrocode}
%    Next we compare the contents of |\tmp| with the contents
%    of |\blockHead|. The latter macro contains the last guard for
%    a block of code that was encountered. If the contents match, we
%    pop the previous guard from the stack.
%    \changes{2.0k}{1992/04/06}{Use new stack mechanism}
%    \begin{macrocode}
  \else
    \ifx\tmp\blockHead
      \pop\guardStack\blockHead
%    \end{macrocode}
%    When the contents of the two macros don't match something is
%    amiss. We signal this to the user, but accept the `end-of-block'.
%\note{Is this the desired behaviour??}
%    \begin{macrocode}
    \else
      \errmessage{Found </\tmp> instead of </\blockHead>}%
    \fi
%    \end{macrocode}
%    When the end of a block of optionally included code is encountered
%    we optionally signal this on the terminal and decrement the counter
%    |\blockLevel|.
%    \begin{macrocode}
    \maybeMsg{>}%
    \advance\blockLevel\m@ne
%    \end{macrocode}
%    The last thing that has to be done is to decrement off-counters and
%    make new list of active files. Now whole list of output files has
%    to be searched since some inactive files could have been
%    reactivated.
%    \begin{macrocode}
  \let\do\closeguard@do
  \outputfiles
  \let\do\findactive@do
  \edef\activefiles{\outputfiles}
  \fi
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\closeguard@do}
% \changes{2.3b}{1995/08/22}{Change for pre-constructed
%                            off-counters' names}
%    This macro decrements non-zero off-counters.
%    \begin{macrocode}
\def\closeguard@do#1#2#3{%
  \ifnum#3>0
    \advance#3\m@ne
  \fi}
%    \end{macrocode}
% \end{macro}
%
%
%    \subsection{Batchfile commands}
%
% \begin{macro}{\generate}
% \changes{2.3a}{1995/08/20}{Messages changed}
%    This macro executes its argument in a group. |\inputfiles| is
%    a list of files to be read, |\filestogenerate| list of names
%    of output files (needed for the message below). |\file|s
%    contained in |#1| define |\inputfiles| in such a way that all
%    that has to be done when the parameter is executed is to call
%    this macro.
%    \begin{macrocode}
\def\generate#1{\begingroup
  \let\inputfiles\empty \let\filestogenerate\empty
  \let\file\@file
  #1
  \Msg{^^JGenerating file(s) \filestogenerate}%
  \inputfiles
  \endgroup}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\file}
%    The first argument is the file to produce, the second
%    argument contains the list of input files. Each entry should have
%    the format
%    \verb=\from{=\meta{filename.ext}\verb=}{=\meta{options}\verb=}=.
%
% \changes{2.3a}{1995/08/20}{Messages changed}
% ^^A   The macro starts by displaying a message on the terminal to
% ^^A   indicate which file is going to be made.
%    The switch |\ifGenerate| is initially set to \meta{true}.
%    \begin{macrocode}
\def\file#1#2{\errmessage{Command `\string\file' only allowed in
                          argument to `\string\generate'}}
\def\@file#1{%
  \Generatetrue
%    \end{macrocode}
%    Next we decide if we have to be careful about overwriting
%    existing files. If the user specified |\askforoverwritetrue|
%    we will ask him
%    if he wants to overwrite an existing file. Otherwise
%    we simply go ahead.
%    \begin{macrocode}
  \ifaskforoverwrite
%    \end{macrocode}
%    We try to open a file with the name of the output file for
%    reading.  If this succeeds the file exists and we ask the user if
%    he wants to overwrite the file.
% \changes{2.0p}{1992/06/26}{Added \cs{WriteToDir} (FMi).}
% \changes{2.3a}{1995/08/18}{Changed \cs{@empty} (which was undefined)
%                            to \cs{empty}}
%    \begin{macrocode}
    \immediate\openin\inFile\WriteToDir#1\relax
    \ifeof\inFile\else
      \Ask\answer{File \WriteToDir#1 already exists 
                  \ifx\empty\WriteToDir somewhere \fi
                  on the system.^^J% 
                  Overwrite it%
                  \ifx\empty\WriteToDir\space if necessary\fi
                  ? [y/n]}%
%    \end{macrocode}
%    We set the switch |\ifGenerate| according to his answer. We
%    allow for both ``\texttt{y}'' and ``\texttt{yes}''.
%    \begin{macrocode}
      \ifx\y  \answer \else
      \ifx\yes\answer \else
                      \Generatefalse\fi\fi\fi
%    \end{macrocode}
%    Don't forget to close the file just opened as we want to write
%    to it.
%    \begin{macrocode}
    \immediate\closein\inFile
  \fi
%    \end{macrocode}
%   If file is to be generated we pass control to macro |\@fileX|.
%   Note that file name is turned into control sequence and |\else|
%   branch is skipped before calling |\@fileX|.
%    \begin{macrocode}
  \ifGenerate
  \@addto\filestogenerate{\WriteToDir#1 }%
  \Name\@fileX{#1\expandafter}%
  \else
%    \end{macrocode}
%    In case we were not allowed to overwrite an existing file
%    we inform the user that we are {\em not\/} generating his file
%    and we gobble |\from| specifications.
%    \begin{macrocode}
    \Msg{Not generating file #1^^J}%
  \expandafter\@gobble
  \fi
  }
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\WriteToDir}
%    The macro |\WriteToDir| is either empty or holds the prefix
%    necessary to read a file from the current directory. Under UNIX
%    this is |./| but a lot of other systems adopted this concept.
% \changes{2.0p}{1992/06/26}{Macro added (FMi).}
% \changes{2.2a}{1993/12/02}{check texsys file}
% \changes{2.2d}{1994/01/20}{do not read dircheck/texsys file}
%    \begin{macrocode}
\ifx\@currdir\@undefined
  \def\WriteToDir{}
\else
  \let\WriteToDir\@currdir
\fi
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\@fileX}
%    We put name of current output file in |\curout| and initialize
%    |\curinfiles|  (the list of source files for this output file)
%    to empty---these will be needed  by  |\from|.  Then  we  start
%    defining preamble for the current file.
%    \begin{macrocode}
\def\@fileX#1#2{%
  \chardef#1=16
  \def\curout{#1}\let\curinfiles\empty
  \edef\curpre{\Name\noexpand{pre@\@stripstring#1}}
  \edef\curinnames{\Name\noexpand{in@\@stripstring#1}}
  \expandafter\def\curpre{\DoubleperCent ^^J%
                  \DoubleperCent The original source files were:^^J%
                  \DoubleperCent ^^J}%
  \expandafter\def\curinnames{}
%    \end{macrocode}
%    Next we execute second parameter. |\from|s will add reference
%    lines to the preamble.
%    \begin{macrocode}
  \let\from\@from \let\needed\@needed
  #2%
  \let\from\err@from \let\needed\err@needed
%    \end{macrocode}
%    We check order of input files.  
%    \begin{macrocode}
  \checkorder
%    \end{macrocode}
%    Each |\from| clause defines |\curin| to be its first parameter.
%    So now |\curin| holds name of last input file for current output
%    file. This means that current output file should be closed after
%    processing |\curin|. We add |#1| to proper `close list'.
%    \begin{macrocode}
  \Name\@addto{e@\curin}{\noexpand\closeoutput{#1}}%
%    \end{macrocode}
%    We append name of currently active preamble to preamble for
%    current file and mark current postamble as postamble for
%    current file.
%    \begin{macrocode}
  \expandafter\@addto\curpre{\expandafter\noexpand\currentpreamble}
  \Name\let{post@\@stripstring#1\expandafter}\currentpostamble
  }
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\checkorder}
%    This macro checks  if  the order  of  files  in  |\curinfiles|
%    agrees  with that of |\inputfiles|. The coding is somewhat
%    clumsy.
%    \begin{macrocode}
\def\checkorder{%
  \expandafter\expandafter\expandafter
  \checkorderX\expandafter\curinfiles
  \expandafter\qStop\inputfiles\qStop
  }
\def\checkorderX(#1)#2\qStop#3\qStop{%
  \def\tmp##1\readsource(#1)##2\qStop{%
    \ifx!##2! \order@error
    \else\ifx!#2!\else 
       \checkorderXX##2%
    \fi\fi}%
  \def\checkorderXX##1\readsource(#1)\fi\fi{\fi\fi
    \checkorderX#2\qStop##1\qStop}%
  \tmp#3\readsource(#1)\qStop
  }
\def\order@error#1\fi\fi{\fi
  \errmessage{DOCSTRIP error: Incompatible order of input
              files specified for file
              `\iden{\expandafter\uptospace\curin} \qStop'.^^J
              Read DOCSTRIP documentation for explanation.^^J
              This is a serious problem, I'm exiting}\end
  }
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\needed}
% \changes{2.3c}{1995/08/24}{Macro added}     
% \begin{macro}{\@needed}
%    This  macro  uniquizes  name  of  an  input  file  passed as a
%    parameter and marks it as needed to  be  input.  It  is  used
%    internally  by  |\from|, but can also be issued in argument to
%    |\file| to influence the order in which files are read.
%    \begin{macrocode}
\def\needed#1{\errmessage{\string\needed\space can only be used in
               argument to \string\file}}
\let\err@needed\needed
\def\@needed#1{%
  \@ifpresent{(#1)}\curinfiles
%    \end{macrocode}
%    If  |#1|  is present on list of input files for current output
%    file we add a space on end of its name and try again. The idea
%    is  to construct a name that will look different for \TeX\ but
%    will lead to the same file when seen by operating system.
%    \begin{macrocode}
    {\@needed{#1 }}%
%    \end{macrocode}
%    When it is not we check if |#1| is  present  in  the  list  of
%    files to be processed. If not we add it and initialize list of
%    output files for that input and  list  of  output  files  that
%    should   be  closed  when  this  file  closes.   We  also  add
%    constructed name to |\curinfiles| and define  |\curin|  to  be
%    able to access constructed name from |\@from|.
%    \begin{macrocode}
    {\@ifpresent{\readsource(#1)}\inputfiles
       {}{\@addto\inputfiles{\noexpand\readsource(#1)}%
       \Name\let{o@#1}\empty\Name\let{e@#1}\empty}%
     \@addto\curinfiles{(#1)}%
     \def\curin{#1}}%
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\from}
% \changes{2.3c}{1995/08/24}{part of code moved to \cs{needed}}     
%    |\from| starts by adding a line to  preamble for output file.
%    \begin{macrocode}
\def\from#1#2{\errmessage{Command `\string\from' only allowed in
                          argument to `\string\file'}}
\let\err@from\from
\def\@from#1#2{%
  \expandafter\@addto\curpre{\DoubleperCent #1 \if>#2>\else
                              \space (with options: `#2')\fi^^J}%
  \expandafter\@addto\curinnames{ #1}%
%    \end{macrocode}
%    Then we mark the file as needed input file.
%    \begin{macrocode}
  \needed{#1}%
%    \end{macrocode}
%    And add |\do|\meta{current output}|{|\meta{options}|}|
%    to the list of output files for current input file.
%    \begin{macrocode}
  \Name\@addto{o@\curin}{\noexpand\do\curout{#2}}
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\readsource}
% \changes{2.3a}{1995/08/18}{Renamed to \cs{readsource}; adaptation for
%                            concurrent version}
% \changes{2.0f}{1991/06/04}{Added check for lines with \texttt{\bsl
%    endinput}} This macro is called for each input file that
%    is to be processed.
%
%    First we have to establish local environment for current
%    input file by assigning to |\outputfiles| list of output files
%    for this (|#1|) input file.
%    \begin{macrocode}
\def\readsource(#1){%
  \expandafter\let\expandafter\outputfiles\csname o@#1\endcsname
%    \end{macrocode}
%    A message is displayed on the terminal telling the user what we are
%    about to do. For each output file we display one line saying with
%    what options it is generated. First line contains also name of
%    input file.
%    \begin{macrocode}
  \Msg{} \def\@msg{Processing file \uptospace#1 \qStop}
  \def\change@msg{%
    \edef\@msg{\@spaces\@spaces\@spaces\space
      \expandafter\tospaces\uptospace#1 \qStop\secapsot}
    \let\change@msg\relax}
  \def\do##1##2{%
    \Msg{\@msg
         \ifx>##2>\else\space(##2)\fi
         \space -> \@stripstring##1}
    \change@msg}%
  \outputfiles
%    \end{macrocode}
%    Then we try to open the input file. If this doesn't succeed, we
%    tell the user so and nothing else happens.
%    \begin{macrocode}
  \immediate\openin\inFile\uptospace#1 \qStop\relax
  \ifeof\inFile
    \errmessage{Cannot find file \uptospace#1 \qStop}%
  \else
%    \end{macrocode}
%    If statistics are included we nullify line counters
%    \begin{macrocode}
%<*stats>
    \processedLines\z@
    \commentsRemoved\z@
    \commentsPassed\z@
    \codeLinesPassed\z@
%</stats>
%    \end{macrocode}
% \changes{2.3b}{1995/08/22}{Change for pre-constructed
%                            off-counters' names}
%    When the input file was successfully opened, we ensure that all
%    needed output files are open. Then we redefine |\outputfiles|
%    again to construct off-counters names. Now |\do|s will have 3
%    parameters! All output files become active.
%    \begin{macrocode}
    \let\do\ensureopen@do
    \outputfiles
    \let\do\makeoutlist@do
    \edef\outputfiles{\outputfiles}%
    \let\activefiles\outputfiles
%    \end{macrocode}
%    Now we change the category
%    code of a lot of characters to \meta{other} and make sure that
%    no extra spaces appear in the lines read by setting the
%    |\endlinechar| to $-1$.
%    \begin{macrocode}
    \makeOther\ \makeOther\\\makeOther\$%
    \makeOther\#\makeOther\^\makeOther\^^K%
    \makeOther\_\makeOther\^^A\makeOther\%%
    \makeOther\~\makeOther\{\makeOther\}\makeOther\&%
    \endlinechar-1\relax
%    \end{macrocode}
%    Then we start a loop to process the lines in the file one by one.
%    \begin{macrocode}
    \loop
      \read\inFile to\inLine
%    \end{macrocode}
%    The first thing we check is whether the current line
%    contains an |\endinput|. To allow also real |\endinput|
%    commands in the source file, |\endinput| is only recognized
%    when it occurs directly at the beginning of a line.
%    \begin{macrocode}
      \ifx\inLine\Endinput
%    \end{macrocode}
%    In this case we output a message to inform the programmer (in
%    case this was a mistake) and end the loop immediately by setting
%    \verb=Continue= to \meta{false}. Note that |\endinput| is
%    not placed into the output file. This is important in cases where
%    the output file is generated from several \texttt{doc} files.
%    \begin{macrocode}
        \Msg{File #1 ended by \string\endinput.}%
        \Continuefalse
      \else
%    \end{macrocode}
% \changes{2.0j}{1992/03/03}{First check for end of file before check
%    for empty lines} When the end of the file is found we have to
%    interrupt the loop.
%    \begin{macrocode}
       \ifeof\inFile
         \Continuefalse
%    \end{macrocode}
% \changes{2.0i}{1991/06/27}{Added check for consecutive empty lines}
%    If the file did not end we check if the input line is empty.
%    If it is, the counter |\emptyLines| is incremented.
%    \begin{macrocode}
       \else
         \Continuetrue
         \ifx\inLine\empty
            \advance\emptyLines\@ne
          \else
            \emptyLines\z@
          \fi
%    \end{macrocode}
%    When the number of empty lines seen so far exceeds 1, we skip them.
%    If it doesn't, the expansion of |\inLine| is fed to |\processLine|
%    with |\endLine| appended to indicate the end of the line.
%    \begin{macrocode}
          \ifnum \emptyLines<2
            \expandafter\processLine\inLine\endLine
          \else
            \maybeMsg{/}%
          \fi
       \fi
      \fi
%    \end{macrocode}
%    When the processing of the line is finished, we check if there is
%    more to do, in which case we repeat the loop.
%    \begin{macrocode}
    \ifContinue
    \repeat
%    \end{macrocode}
%    The input file is closed.
%    \begin{macrocode}
    \immediate\closein\inFile
%    \end{macrocode}
%    We close output files for which this was the last input file.
%    \begin{macrocode}
  \csname e@#1\endcsname
%    \end{macrocode}
%    If the user was interested in statistics, we inform him of the
%    number of lines processed, the number of comments that were
%    either removed or passed and the number of codelines that were
%    written to the output file. Also the totals are updated.
%    \begin{macrocode}
%<*stats>
    \Msg{Lines \space processed: \the\processedLines^^J%
         Comments removed: \the\commentsRemoved^^J%
         Comments \space passed: \the\commentsPassed^^J%
         Codelines passed: \the\codeLinesPassed^^J}%
      \global\advance\TotalprocessedLines  by \processedLines
      \global\advance\TotalcommentsRemoved by \commentsRemoved
      \global\advance\TotalcommentsPassed  by \commentsPassed
      \global\advance\TotalcodeLinesPassed by \codeLinesPassed
      \global\advance\NumberOfFiles by \@ne
%</stats>
    \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ensureopen@do}
%    This macro opens output streams and zeroes off-counters
%    associated with them.
%    \begin{macrocode}
\def\ensureopen@do#1#2{%
  \ifnum#1=16
    \StreamOpen#1%
    \WritePreamble#1%
    \fi
  \csname off@\number#1\endcsname=0
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\makeoutlist@do}
% \changes{2.3b}{1995/08/22}{Macro added --- pre-constructed
%                            off-counters' names}
%   This   macro   performs   simple  task  of  constructing  names  for
%   off-counters.
%    \begin{macrocode}
\def\makeoutlist@do#1#2{%
  \noexpand\do#1{#2}\csname off@\number#1\endcsname}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\closeoutput}
%    This macro closes output stream when it is no longer needed.
%    \begin{macrocode}
\def\closeoutput#1{%
  \WritePostamble#1%
  \StreamClose#1%
  }
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Preamble and postamble}
% \begin{macro}{\declarepreamble}
% \changes{2.3a}{1995/08/18}{renamed to \cs{declarepreamble};
%                            interface changed}
% \changes{2.0e}{1991/06/01}{Macro added.} 
%    When a batch file is used the
%    user can specify a preamble of his own that will be written to
%    each file that is created. This can be useful to include an extra
%    copyright notice in the stripped version of a file.  Also a
%    warning that both versions of a file should {\em always\/} be
%    distributed together could be written to a stripped file by
%    including it in such a preamble.
%
%    Every line that is written to |\outFile| that belongs to the
%    preamble is preceded by two percent characters. This will prevent
%    \ds{} from stripping these lines off the file.
%
%    The preamble should be started with the macro
%    |\declarepreamble|; it is ended by |\endpreamble|. All
%    processing is done within a group in order to be able to locally
%    redefine some macros.
%    \begin{macrocode}
\def\declarepreamble#1{\begingroup
%    \end{macrocode}
% \changes{2.3c}{1995/11/16}{\cs{(in/out)FileName}}
%    If the preamble contains an empty line this will end up in
%    the macro |\batchLine| as |\par|. To be able to
%    recognize a |\par| we define |\tmp| to contain
%    |\par|. The macro |\Endpreamble| is defined to contain
%    |\endpreamble|, which ends the processing of preamble lines.
%    We also make |\(in/out)FileName| unexpandable.
%    \begin{macrocode}
    \def\tmp{\par}%
    \def\Endpreamble{\endpreamble}%
    \let\inFileName\relax \let\outFileName\relax 
%    \end{macrocode}
%    The preamble lines will be read inside a |\loop|. When
%    a line is found that contains |\endpreamble| the processing
%    has to stop. This is controlled by the switch |\ifContinue|.
%    We initialize it to \meta{true}.
%    \begin{macrocode}
    \Continuetrue
%    \end{macrocode}
%    The first argument to |\declarepreamble| will be defined to contain
%    all preamble lines supplied by the user.
%    \begin{macrocode}
    \global\let#1\empty
%    \end{macrocode}%
%    Each line in the preamble has to be added to
%    |#1|, therefore we start a |\loop| to
%    |\read| the lines. The control sequence |\batchLine|
%    is used to store each line.
%    \begin{macrocode}
    \loop
        \read\currbatchFile to \batchLine
%    \end{macrocode}
%    We check to see if the end of the preamble has been found. In that
%    case the |\loop| has to come to an end, so we set the switch
%    |\ifContinue| to \meta{false}.
%    \begin{macrocode}
        \ifx\batchLine\Endpreamble \Continuefalse
        \else
%    \end{macrocode}
%    If an extra line has been read we add it to |#1|.
%    If the |\batchLine| was
%    empty, we write just the two percent characters; otherwise the
%    complete line is written, preceded by the two percent characters.
%    \begin{macrocode}
              {\globaldefs1
              \@addto#1{%
                \ifx#1\empty\else^^J\fi
                \DoubleperCent 
                \ifx\batchLine\tmp\else\batchLine\fi}}%
        \fi
%    \end{macrocode}
%    The setting of the switch |\ifContinue| will decide if the
%    |\loop| continues. If we end the |\loop|, we also have to
%    close the group.
%    \begin{macrocode}
    \ifContinue\repeat
    \endgroup}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\declarepostamble}
% \changes{2.0e}{1991/06/01}{Macro added.}
%    Just as a preamble can be
%    specified in a batch file, the same can be done for a {\em
%    post\/}amble.
%
%    The definition of |\declarepostamble| is very much like the
%    definition above of |\declarepreamble|; the processing takes place
%    inside a group and the switch |\ifContinue| is used to
%    control the |\loop|.
%    \begin{macrocode}
\def\declarepostamble#1{\begingroup
    \Continuetrue
%    \end{macrocode}
% \changes{2.3c}{1995/11/16}{\cs{(in/out)FileName}}
%    The end of the postamble is indicated by |\endpostamble| and
%    the postamble can contain empty lines so we have to be able
%    to check if |\batchLine| contains a |\par|.
%    \begin{macrocode}
    \def\Endpostamble{\endpostamble}%
    \def\tmp{\par}%
    \let\inFileName\relax \let\outFileName\relax 
%    \end{macrocode}
%    We initially define |#1| as an empty macro.
%    Commands will be added to it as we go along.
%    \begin{macrocode}
    \global\let#1\empty
%    \end{macrocode}
%    We start a loop to read lines from the batch file until
%    |\endpostamble| is encountered.
%    \begin{macrocode}
    \loop
        \read\currbatchFile to \batchLine
        \ifx\batchLine\Endpostamble \Continuefalse
%    \end{macrocode}
%    The line just read will be written to output file prepended
%    with two percent characters.
%    \begin{macrocode}
        \else
            {\globaldefs1 
            \@addto#1{%
               \ifx#1\empty\else^^J\fi
               \DoubleperCent 
               \ifx\batchLine\tmp\else\batchLine\fi}}%
        \fi
%    \end{macrocode}
%    The setting of the switch |\ifContinue| decides if we have
%    to stop the |\loop|.
%    \begin{macrocode}
    \ifContinue\repeat
    \endgroup}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\usepreamble}
% \begin{macro}{\usepostamble}
%    Macros for selecting [pre/post]amble to be used.
%    \begin{macrocode}
\def\usepreamble#1{\def\currentpreamble{#1}}
\def\usepostamble#1{\def\currentpostamble{#1}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\preamble}
% \changes{2.3c}{1995/08/28}{Bug fixed: default preamble is now selected
%                             not only defined}
% \begin{macro}{\postamble}
% \changes{2.3c}{1995/08/28}{As for \cs{preamble}}
%    For backward compatibility we provide these macros defining
%    default preamble and postamble.
%    \begin{macrocode}
\def\preamble{\usepreamble\defaultpreamble
  \declarepreamble\defaultpreamble}
\def\postamble{\usepostamble\defaultpostamble
  \declarepostamble\defaultpostamble}
%    \end{macrocode}   
% \end{macro}
% \end{macro}
% \begin{macro}{\defaultpreamble}
%  \changes{2.3a}{1995/08/18}{Macro added}
% \changes{2.3c}{1995/11/16}{With \cs{inFileName} again}
% \begin{macro}{\defaultpostamble}
%  \changes{2.3a}{1995/08/18}{Macro added}
%    Default values to use if nothing different is provided.
% \changes{2.2j}{1995/08/06}{Updated default preamble}
%    \begin{macrocode}
\def\defaultpreamble{%
     \DoubleperCent ^^J%
     \DoubleperCent IMPORTANT NOTICE:^^J%
     \DoubleperCent ^^J%
     \DoubleperCent For the copyright see the source file.^^J%
     \DoubleperCent ^^J%
     \DoubleperCent You are *not* allowed to modify this file.^^J%
     \DoubleperCent ^^J%
     \DoubleperCent You are *not* allowed to distribute this file.^^J%
     \DoubleperCent For distribution of the original source see^^J%
     \DoubleperCent the terms for copying and modification
                       in the file \inFileName.^^J%
     \DoubleperCent}
\def\defaultpostamble{\string\endinput}
\usepreamble\defaultpreamble
\usepostamble\defaultpostamble
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\WritePreamble}
% \changes{2.0e}{1991/06/01}{Macro added.}
% \changes{2.3c}{1995/11/16}{Added definitions of \cs{inFileName} and
%                            \cs{outFileName}}
% \changes{2.3d}{1995/11/17}{(DPC) Macro added.}
%    First a couple of lines, stating what file it is and how it was
%    created. If |\AddGenerationDate| is given in the batch file
%    then the creation date and version of docstrip are also added.
%    \begin{macrocode}
\def\WritePreamble#1{%
    \edef\outFileName{\@stripstring#1}%
    \edef\inFileName{\csname in@\outFileName\endcsname}%
    \StreamPut#1{%
        \DoubleperCent ^^J%
        \DoubleperCent This is file `\outFileName',^^J%
        \DoubleperCent  generated with the docstrip utility.%
             }%
%    \end{macrocode}
%    Then the reference lines that tell from what source file(s) the
%    stripped file was created and user supplied preamble.
%    \begin{macrocode}
    \StreamPut#1{\csname pre@\@stripstring#1\endcsname}}
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\AddGenerationDate}
% \changes{2.3d}{1995/11/17}{(DPC) Macro added.}
%  Older versions of \ds{} added the date that any file was generated
% and the version number of \ds{}. This confused some people as they
% mistook this for the version/date of the file that was being
% written. So now this information is not normally written, but
% a batch file may call this to get an old style header.
%    \begin{macrocode}
\def\AddGenerationDate{%
\def\WritePreamble##1{%
    \edef\outFileName{\@stripstring##1}%
    \edef\inFileName{\csname in@\outFileName\endcsname}%
    \StreamPut##1{%
        \DoubleperCent ^^J%
        \DoubleperCent This is file `\outFileName', generated %
                        on <\the\year/\the\month/\the\day> ^^J%
        \DoubleperCent with the docstrip utility (\fileversion).%
             }%
    \StreamPut##1{\csname pre@\@stripstring##1\endcsname}}}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\WritePostamble}
% \changes{2.0e}{1991/06/01}{Macro added.}
% \changes{2.3c}{1995/11/16}{Added defs of \cs{inFileName} and
%                            \cs{outFileName}}
%    Postamble attributed to |#1| is written out. The
%    last line written identifies the file again.
%    \begin{macrocode}
\def\WritePostamble#1{%
    \edef\outFileName{\@stripstring#1}%
    \edef\inFileName{\csname in@\outFileName\endcsname}%
    \StreamPut#1{\csname post@\@stripstring#1\endcsname}%
    \StreamPut#1{\DoubleperCent ^^J%
              \DoubleperCent End of file `\outFileName'.}}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Compatibility with older versions}
%
% \begin{macro}{\generateFile}
%    Main macro of previous versions of \ds.
%    \begin{macrocode}
\def\generateFile#1#2#3{{
  \ifx t#2\askforoverwritetrue
  \else\askforoverwritefalse\fi
  \generate{\file{#1}{#3}}%
  }}    
%    \end{macrocode}
% \end{macro}
%
%    To support command files that were written for the first version
%    of \ds{} the commands |\include| and |\processFile|
%    are defined here. The use of this interface is not recommended
%    as it may be removed in a future release of \ds{}.
%
% \begin{macro}{\include}
% \changes{2.0f}{1991/06/04}{Macro added} To provide the \ds{} program
%    with a list of options that should be included in the output the
%    command \verb=\include{=\meta{Options}\verb=}= can be used. This
%    macro is meant to be used in conjunction with the
%    |\processFile| command.
%    \begin{macrocode}
\def\include#1{\def\Options{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\processFile}
% \changes{2.0f}{1991/06/04}{Supply \texttt{\bsl generateFile} with
%                          \texttt{\bsl Options}}
%\DeleteShortVerb\|
%    The macro
%    \verb=\processFile{=\meta{filename}\verb=}{=\meta{inext}\verb=}{=%
%\unskip\meta{outext}\verb=}{=\meta{t{\fontshape{n}\ttfamily|}f}\verb=}=
%    can be used when a single input file is used to produce
%    a single output file. The macro is also used in the interactive
%    mode of the \ds{} program.
%\MakeShortVerb\|
%
%    The arguments \meta{inext} and \meta{outext} denote the
%    extensions of the input and output files respectively. The fourth
%    argument can be used to specify if an existing file should be
%    overwritten without asking. If \meta{t} is specified the program
%    will ask for permission before overwriting an existing file.
%
%    This macro is defined using the more generic macro |\generateFile|.
%    \begin{macrocode}
\def\processFile#1#2#3#4{%
  \generateFile{#1.#3}{#4}{\from{#1.#2}{\Options}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\processfile}
% \begin{macro}{\generatefile}
% \changes{2.0m}{1991/04/23}{Now issue a warning when \cs{processfile}
%     or \cs{generatefile} are used}
%    Early
%    versions of \ds{} defined |\processfile| and
%    |\generatefile| instead of the commands as they are defined in
%    this version. To remain upwards compatible, we still provide
%    these commands, but issue a warning when they are used.
%    \begin{macrocode}
\def\processfile{\Msg{%
    ^^Jplease use \string\processFile\space instead of 
       \string\processfile!^^J}%
    \processFile}
\def\generatefile{\Msg{%
    ^^Jplease use \string\generateFile\space instead of 
      \string\generatefile!^^J}%
    \generateFile}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%    \subsection{Interaction with the user}
%
% \begin{macro}{\processbatchFile}
% \changes{2.0f}{1991/06/04}{Macro added.}
%    When \ds{} is run it always tries to use a batch file.
%    For this purpose it calls the macro |\processbatchFile|. The first
%    thing this macro does, is check whether the user has defined the
%    control sequence |\batchfile|. If he did, it should contain the
%    name of the file to process. If he didn't a default name is tried.
%    Whether or not the default batch file is used is remembered by
%    setting the switch |\ifDefault| to \meta{true} or \meta{false}.
%    \begin{macrocode}
\def\processbatchFile{%
    \ifx\undefined\batchfile
      \let\batchfile\DefaultbatchFile
      \Defaulttrue
    \else
      \Defaultfalse
    \fi
%    \end{macrocode}
%    Now we try to open the batch file for reading.
%    \begin{macrocode}
    \openin\currbatchFile \batchfile\relax
    \ifeof\currbatchFile
%    \end{macrocode}
%    If we didn't succeed in opening the file, we assume that it does
%    not exist. If we tried the default filename, we silently
%    continue; the \ds{} program will switch to interactive mode in
%    this case.
%    \begin{macrocode}
      \ifDefault
      \else
%    \end{macrocode}
%    If we failed to open the user-supplied file, something is wrong
%    and we warn him about it. This will also result in a switch to
%    interactive mode.
%    \begin{macrocode}
        \Msg{**************************************************^^J%
             * Could not find your \string\batchfile=\batchfile^^J%
             * Try to continue without it^^J%
             **************************************************}%
      \fi
    \else
%    \end{macrocode}
%    When we were successful in opening a file, we again have to check
%    whether it was the default file. In that case we tell the user
%    we found that file and ask him if he wants to use it.
%    \begin{macrocode}
      \ifDefault
        \Msg{**************************************************^^J%
             * Batchfile \DefaultbatchFile\space found Use it? (y/n)?}%
        \Ask\answer{%
             **************************************************}%
      \else
%    \end{macrocode}
%    When it was the user-supplied file we can safely assume he wants
%    to use it so we set |\answer| to \texttt{y}.
%    \begin{macrocode}
        \let\answer\y
      \fi
%    \end{macrocode}
%    At this point we have successfully opened a batch file for
%    reading.  If the macro |\answer| contains a \texttt{y} we can
%    proceed. We do that by setting the switch |\ifContinue| to true.
%    When the batch file contains an |\endinput| we shouldn't
%    continue, so we make it switch |\ifContinue| to \meta{false}.
%    \begin{macrocode}
      \ifx\answer\y
        \Continuetrue
        \let\endinput\Continuefalse
%    \end{macrocode}
%    The contents of the batch file are read in a loop, line by line.
%    When the end of the file is found processing should stop.
%    \begin{macrocode}
        \loop
          \ifeof\currbatchFile
            \Continuefalse
          \else
%    \end{macrocode}
%    A line is read into the macro |\batchLine|, which is subsequently
%    executed.
%    \begin{macrocode}
            \read\currbatchFile to \batchLine
            \batchLine
          \fi
%    \end{macrocode}
%    When the execution of |\batchLine| is finished we check the switch
%    |\ifContinue| to see if have to continue reading.
%    \begin{macrocode}
        \ifContinue \repeat
      \fi
    \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ReportTotals}
% \changes{2.0g}{1991/06/05}{Macro added.} The macro
%    |\ReportTotals| can be used to report total statistics for
%    all files processed. This code is only included in the program if
%    the option \texttt{stats} is included.
%    \begin{macrocode}
%<*stats>
\def\ReportTotals{%
  \ifnum\NumberOfFiles>\@ne
    \Msg{Overall statistics:^^J%
         Files \space processed: \the\NumberOfFiles^^J%
         Lines \space processed: \the\TotalprocessedLines^^J%
         Comments removed: \the\TotalcommentsRemoved^^J%
         Comments \space passed: \the\TotalcommentsPassed^^J%
         Codelines passed: \the\TotalcodeLinesPassed}%
  \fi}
%</stats>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SetFileNames}
%    The macro |\SetFileNames| is used when the program runs in
%    interactive mode and the user was asked to supply extensions and
%    a list of filenames.
%    \begin{macrocode}
\def\SetFileNames{%
    \edef\sourceFileName{\MainFileName.\infileext}%
    \edef\destFileName{\MainFileName.\outfileext}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\CheckFileNames}
%    In interactive mode, the user gets asked for the extensions for
%    the input and output files. Also the name or names of the input
%    files (without extension) is asked for. Then the names of the
%    input and output files are constructed from this information by
%    |\SetFileNames|. This assumes that the name of the input file is
%    the same as the name of the output file. But we should not write
%    to the same file we're reading from so the extensions should
%    differ.
%
%    The macro |\CheckFileNames| makes sure that the output goes to a
%    different file to the one where the input comes from.
%    \begin{macrocode}
\def\CheckFileNames{%
    \ifx\sourceFileName\destFileName
%    \end{macrocode}
%    If input and output files are the same we signal an error and stop
%    processing.
%    \begin{macrocode}
      \Msg{^^J%
     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J%
     ! It is not possible to read from and write to the same file !^^J%
     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J}%
      \Continuefalse
    \else
%    \end{macrocode}
%    If they are not the same we check if the input file exists by
%    trying to open it for reading.
%    \begin{macrocode}
      \Continuetrue
      \immediate\openin\inFile \sourceFileName\relax
      \ifeof\inFile
%    \end{macrocode}
%    If an end of file was found, the file couldn't be opened, so we
%    signal an error and stop processing.
%    \begin{macrocode}
        \Msg{^^J%
              !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J%
              ! Your input file `\sourceFileName' was not found !^^J%
              !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J}%
        \Continuefalse
      \else
%    \end{macrocode}
%    The last check we have to make is if the output file already
%    exists.  Therefore we try to open it for reading.
%    As a precaution we first close the input stream.
% \changes{2.0p}{1992/06/26}{Added \cs{WriteToDir} (FMi).}
% \changes{2.0r}{1992/08/17}{Use \cs{inFile} for reading}
% \changes{2.0r}{1992/08/17}{Moved \cs{closein} statements}
%    \begin{macrocode}
        \immediate\closein\inFile
        \immediate\openin\inFile\WriteToDir \destFileName\relax
        \ifeof\inFile
%    \end{macrocode}
%    If this fails, it didn't exist and all is well.
%    \begin{macrocode}
          \Continuetrue
        \else
%    \end{macrocode}
%    If opening of the output file for reading succeeded we have to
%    ask the user if he wants to overwrite it. We assume he doesn't
%    want to overwrite it, so the switch |\ifContinue| is initially
%    set to \meta{false}. Only if he answers the question positively
%    with `\texttt{y}' or `\texttt{yes}' we set the switch back to
%    \meta{true}.
% \changes{2.0p}{1992/06/26}{Changed question about overwriting.}
%    \begin{macrocode}
          \Continuefalse
          \Ask\answer{File \WriteToDir\destFileName\space already 
                      exists 
                      \ifx\empty\WriteToDir somewhere \fi
                      on the system.^^J% 
                      Overwrite it%
                      \ifx\empty\WriteToDir\space if necessary\fi
                      ? [y/n]}%
          \ifx\y  \answer \Continuetrue \else
          \ifx\yes\answer \Continuetrue \else
          \fi\fi
        \fi
%    \end{macrocode}
%    All checks have been performed now, so we can close any file that
%    was opened just for this purpose.
%    \begin{macrocode}
      \fi
    \fi
    \immediate\closein\inFile}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\interactive}
%    The macro |\interactive| implements the interactive mode of the
%    \ds{} program. The macro is implemented using the
%    \meta{while} construction. While the switch |\ifMoreFiles| remains
%    true, we continue processing.
%    \begin{macrocode}
\def\interactive{%
  \whileswitch\ifMoreFiles\fi%
%    \end{macrocode}
%    To keep macro redefinitions local we start a group and ask the
%    user some questions about what he wants us to do.
%    \begin{macrocode}
   {\begingroup
      \AskQuestions
%    \end{macrocode}
%    The names of the files that have to be processed are stored as a
%    comma-separated list in the macro |\filelist| by |\AskQuestions|.
%    We use a \meta{for} loop to process the files one by one.
%    \begin{macrocode}
      \forlist\MainFileName:=\filelist
      \do
%    \end{macrocode}
%    First the names of the input and output files are constructed
%    and a check is made if all filename information is correct.
%    \begin{macrocode}
        \SetFileNames
        \CheckFileNames
        \ifContinue
%    \end{macrocode}
%    If everything was well, produce output file.
% \changes{2.0q}{1992/07/01}{Preceded filename by \cs{WriteToDir}}
%    \begin{macrocode}
        \generateFile{\destFileName}{f}%
                     {\from{\sourceFileName}{\Options}}
        \fi%
%    \end{macrocode}
%    This process is repeated until |\filelist| is exhausted.
%    \begin{macrocode}
      \od
    \endgroup
%    \end{macrocode}
%    Maybe the user wants more files to be processed, possibly with
%    another set of options, so we give him the opportunity.
%    \begin{macrocode}
    \Ask\answer{More files to process (y/n)?}%
    \ifx\y  \answer\MoreFilestrue \else
    \ifx\yes\answer\MoreFilestrue \else
%    \end{macrocode}
%    If he didn't want to process any more files, the switch
%    |\ifMoreFiles| is set to \meta{false} in order to interrupt the
%    \meta{while} loop.
%    \begin{macrocode}
                   \MoreFilesfalse\fi\fi
   }}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\AskQuestions}
% \changes{2.0e}{1991/06/01}{Macro added.}
%    The macro |\AskQuestions| is called by |\interactive| to get
%    some information from the user concerning the files that need
%    to be processed.
%    \begin{macrocode}
\def\AskQuestions{%
    \Msg{^^J%
         ****************************************************}%
%    \end{macrocode}
%    We want to know the extension of the input files,
%    \begin{macrocode}
    \Ask\infileext{%
         * First type the extension of your input file(s): \space  *}%
    \Msg{****************************************************^^J^^J%
         ****************************************************}%
%    \end{macrocode}
%    the extension of the output files,
%    \begin{macrocode}
    \Ask\outfileext{%
         * Now type the extension of your output file(s) \space: *}%
    \Msg{****************************************************^^J^^J%
         ****************************************************}%
%    \end{macrocode}
%    if options are to be included and
%    \begin{macrocode}
    \Ask\Options{%
       * Now type the name(s) of option(s) to include \space\space: *}%
    \Msg{****************************************************^^J^^J%
         ****************************************************^^J%
       * Finally give the list of input file(s) without \space\space*}%
%    \end{macrocode}
%    the name of the input file or a list of names, separated by commas.
%    \begin{macrocode}
    \Ask\filelist{%
         * extension seperated by commas if necessary %
                                  \space\space\space\space: *}%
    \Msg{****************************************************^^J}}%
%    \end{macrocode}
% \end{macro}
%
% \subsection{The main program}
%    When \TeX\ processes the \ds{} program it displays
%    a message about the version of the program and its function
%    on the terminal.
%    \begin{macrocode}
\Msg{Utility: `docstrip' \fileversion\space <\filedate>^^J%
     English documentation \space\space\space <\docdate>}%
\Msg{^^J%
     **********************************************************^^J%
     * This program converts documented macro-files into fast *^^J%
     * loadable files by stripping off (nearly) all comments! *^^J%
     **********************************************************^^J}%
%    \end{macrocode}
%
%    First we try to process a batch file.
%    \begin{macrocode}
\processbatchFile
%    \end{macrocode}
%
%    When the number of files processed is still zero,
%    no batch file was specified and the default
%    batch file was not found, so we try interactive mode.
%    \begin{macrocode}
  \ifnum\NumberOfFiles=\z@
    \interactive
  \fi
%    \end{macrocode}
%    When we're done and statistics are included we provide a statistics
%    report about the complete run. Then we |\end| the \TeX-run.
%    \begin{macrocode}
%<*stats>
\ReportTotals
%</stats>
\end
%</program>
%    \end{macrocode}
%
%
%
% \Finale
\endinput
